Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration parameter copy and modify functions extended #13224

Merged
merged 1 commit into from
Feb 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 33 additions & 3 deletions FWCore/ParameterSet/python/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

## imports
import sys
from Mixins import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable, _Unlabelable, _ValidatingListBase
from Mixins import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable, _Unlabelable, _ValidatingListBase, _modifyParametersFromDict
from Mixins import *
from Types import *
from Modules import *
Expand Down Expand Up @@ -1107,8 +1107,18 @@ class _ParameterModifier(object):
def __init__(self,args):
self.__args = args
def __call__(self,obj):
for k,v in self.__args.iteritems():
setattr(obj,k,v)
params = {}
for k in self.__args.iterkeys():
params[k] = getattr(obj,k)
_modifyParametersFromDict(params, self.__args, self._raiseUnknownKey)
for k in self.__args.iterkeys():
if k in params:
setattr(obj,k,params[k])
else:
#the parameter must have been removed
delattr(obj,k)
def _raiseUnknownKey(key):
raise KeyError("Unknown parameter name "+k+" specified while calling Modifier")

class _AndModifier(object):
"""A modifier which only applies if multiple Modifiers are chosen"""
Expand Down Expand Up @@ -1155,6 +1165,12 @@ def toModify(self,obj, func=None,**kw):
that will be the object passed in as the first argument.
Form 2: A list of parameter name, value pairs can be passed
mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
This form can also be used to remove a parameter by passing the value of None
#remove the parameter foo.fred
mod.toModify(foo, fred = None)
Additionally, parameters embedded within PSets can also be modified using a dictionary
#change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
"""
if func is not None and len(kw) != 0:
raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
Expand Down Expand Up @@ -1976,6 +1992,20 @@ def _mod_fred(obj):
self.assertEqual(p.a.wilma.value(),1)
self.assertEqual(p.b.fred.value(),2)
self.assertEqual(p.b.wilma.value(),3)
#test removal of parameter
m1 = Modifier()
p = Process("test",m1)
p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
m1.toModify(p.a, fred = None)
self.assertEqual(hasattr(p.a, "fred"), False)
self.assertEqual(p.a.wilma.value(),1)
#test setting of value in PSet
m1 = Modifier()
p = Process("test",m1)
p.a = EDAnalyzer("MyAnalyzer", flintstones = PSet(fred = int32(1), wilma = int32(1)))
m1.toModify(p.a, flintstones = dict(fred = int32(2)))
self.assertEqual(p.a.flintstones.fred.value(),2)
self.assertEqual(p.a.flintstones.wilma.value(),1)
#test that load causes process wide methods to run
def _rem_a(proc):
del proc.a
Expand Down
75 changes: 60 additions & 15 deletions FWCore/ParameterSet/python/Mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,24 +335,19 @@ def clone(self, *args, **params):
New parameters may be added by specify the exact type
Modifying existing parameters can be done by just specifying the new
value without having to specify the type.
A parameter may be removed from the clone using the value None.
#remove the parameter foo.fred
mod.toModify(foo, fred = None)
A parameter embedded within a PSet may be changed via a dictionary
#change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
"""
returnValue =_TypedParameterizable.__new__(type(self))
myparams = self.parameters_()
if len(myparams) == 0 and len(params) and len(args):
args.append(None)
if len(params):
#need to treat items both in params and myparams specially
for key,value in params.iteritems():
if key in myparams:
if isinstance(value,_ParameterTypeBase):
myparams[key] =value
else:
myparams[key].setValue(value)
else:
if isinstance(value,_ParameterTypeBase):
myparams[key]=value
else:
self._Parameterizable__raiseBadSetAttr(key)

_modifyParametersFromDict(myparams, params, self._Parameterizable__raiseBadSetAttr)

returnValue.__init__(self.__type,*args,
**myparams)
Expand Down Expand Up @@ -615,6 +610,35 @@ def saveOrigin(obj, level):
obj._filename = frame[0]
obj._lineNumber = frame[1]

def _modifyParametersFromDict(params, newParams, errorRaiser, keyDepth=""):
if len(newParams):
#need to treat items both in params and myparams specially
for key,value in newParams.iteritems():
if key in params:
if value is None:
del params[key]
elif isinstance(value, dict):
if isinstance(params[key],_Parameterizable):
pset = params[key]
p =pset.parameters_()
_modifyParametersFromDict(p,
value,errorRaiser,
keyDepth+"."+key)
for k,v in p.iteritems():
setattr(pset,k,v)
else:
raise ValueError("Attempted to change non PSet value "+keyDepth+" using a dictionary")
elif isinstance(value,_ParameterTypeBase):
params[key] =value
else:
params[key].setValue(value)
else:
if isinstance(value,_ParameterTypeBase):
params[key]=value
else:
errorRaiser(key)


if __name__ == "__main__":

import unittest
Expand Down Expand Up @@ -681,13 +705,34 @@ class __Test(_TypedParameterizable):
class __TestType(_SimpleParameterTypeBase):
def _isValid(self,value):
return True
a = __Test("MyType",t=__TestType(1), u=__TestType(2))
b = a.clone(t=3, v=__TestType(4))
class __PSet(_ParameterTypeBase,_Parameterizable):
def __init__(self,*arg,**args):
#need to call the inits separately
_ParameterTypeBase.__init__(self)
_Parameterizable.__init__(self,*arg,**args)
a = __Test("MyType",
t=__TestType(1),
u=__TestType(2),
w = __TestType(3),
x = __PSet(a = __TestType(4),
b = __TestType(6),
c = __PSet(gamma = __TestType(5))))
b = a.clone(t=3,
v=__TestType(4),
w= None,
x = dict(a = 7,
c = dict(gamma = 8),
d = __TestType(9)))
self.assertEqual(a.t.value(),1)
self.assertEqual(a.u.value(),2)
self.assertEqual(b.t.value(),3)
self.assertEqual(b.u.value(),2)
self.assertEqual(b.v.value(),4)
self.assertEqual(b.x.a.value(),7)
self.assertEqual(b.x.b.value(),6)
self.assertEqual(b.x.c.gamma.value(),8)
self.assertEqual(b.x.d.value(),9)
self.assertEqual(hasattr(b,"w"), False)
self.assertRaises(TypeError,a.clone,None,**{"v":1})
def testModified(self):
class __TestType(_SimpleParameterTypeBase):
Expand Down