Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-20 23:56:40

0001 from __future__ import absolute_import
0002 from .Mixins import _ConfigureComponent, saveOrigin
0003 from .Mixins import _Unlabelable, _Labelable
0004 from .Mixins import _TypedParameterizable, _Parameterizable, PrintOptions, specialImportRegistry
0005 from .SequenceTypes import _SequenceLeaf
0006 from .Types import vstring, EDAlias
0007 
0008 
0009 import copy
0010 from .ExceptionHandling import *
0011 class Service(_ConfigureComponent,_TypedParameterizable,_Unlabelable):
0012     def __init__(self,type_,*arg,**kargs):
0013         super(Service,self).__init__(type_,*arg,**kargs)
0014         self._inProcess = False
0015     def _placeImpl(self,name,proc):
0016         self._inProcess = True
0017         proc._placeService(self.type_(),self)
0018     def insertInto(self, processDesc):
0019         newpset = processDesc.newPSet()
0020         newpset.addString(True, "@service_type", self.type_())
0021         self.insertContentsInto(newpset)
0022         processDesc.addService(newpset)
0023     def dumpSequencePython(self, options=PrintOptions()):
0024         return "process." + self.type_()
0025     def _isTaskComponent(self):
0026         return True
0027     def isLeaf(self):
0028         return True
0029     def __str__(self):
0030         return str(self.type_())
0031 
0032 class ESSource(_ConfigureComponent,_TypedParameterizable,_Unlabelable,_Labelable):
0033     def __init__(self,type_,*arg,**kargs):
0034         super(ESSource,self).__init__(type_,*arg,**kargs)
0035         saveOrigin(self, 1)
0036     def _placeImpl(self,name,proc):
0037         if name == '':
0038             name=self.type_()
0039         proc._placeESSource(name,self)
0040     def moduleLabel_(self,myname):
0041        result = myname
0042        if self.type_() == myname:
0043            result = ""
0044        return result
0045     def nameInProcessDesc_(self, myname):
0046        result = self.type_() + "@" + self.moduleLabel_(myname)
0047        return result
0048     def _isTaskComponent(self):
0049         return True
0050     def isLeaf(self):
0051         return True
0052 
0053 class ESProducer(_ConfigureComponent,_TypedParameterizable,_Unlabelable,_Labelable):
0054     def __init__(self,type_,*arg,**kargs):
0055         super(ESProducer,self).__init__(type_,*arg,**kargs)
0056     def _placeImpl(self,name,proc):
0057         if name == '':
0058             name=self.type_()
0059         proc._placeESProducer(name,self)
0060     def moduleLabel_(self,myname):
0061        result = myname
0062        if self.type_() == myname:
0063            result = ''
0064        return result
0065     def nameInProcessDesc_(self, myname):
0066        result = self.type_() + "@" + self.moduleLabel_(myname)
0067        return result
0068     def _isTaskComponent(self):
0069         return True
0070     def isLeaf(self):
0071         return True
0072 
0073 class ESPrefer(_ConfigureComponent,_TypedParameterizable,_Unlabelable,_Labelable):
0074     """Used to set which EventSetup provider should provide a particular data item
0075     in the case where multiple providers are capable of delivering the data.
0076     The first argument specifies the C++ class type of the prodiver.
0077     If the provider has been given a label, you must specify that label as the second argument.
0078     Additional 'vstring' arguments maybe used to specify exactly which EventSetup Records
0079     are being preferred and optionally which data items within that Record.
0080     E.g.,
0081         #prefer all data in record 'OrangeRecord' from 'juicer'
0082         ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring())
0083     or
0084         #prefer only "Orange" data in "OrangeRecord" from "juicer" 
0085         ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("ExtraPulp"))
0086     or 
0087         #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer" 
0088         ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
0089     """
0090     def __init__(self,type_,targetLabel='',*arg,**kargs):
0091         super(ESPrefer,self).__init__(type_,*arg,**kargs)
0092         self._targetLabel = targetLabel
0093         if targetLabel is None:
0094             self._targetLabel = str('')
0095         if kargs:
0096             for k,v in kargs.items():
0097                 if not isinstance(v,vstring):
0098                     raise RuntimeError('ESPrefer only allows vstring attributes. "'+k+'" is a '+str(type(v)))
0099     def _placeImpl(self,name,proc):
0100         proc._placeESPrefer(name,self)
0101     def nameInProcessDesc_(self, myname):
0102         # the C++ parser can give it a name like "label@prefer".  Get rid of that.
0103         return "esprefer_" + self.type_() + "@" + self._targetLabel
0104     def copy(self):
0105         returnValue = ESPrefer.__new__(type(self))
0106         returnValue.__init__(self.type_(), self._targetLabel)
0107         return returnValue
0108     def moduleLabel_(self, myname):
0109         return self._targetLabel
0110     def targetLabel_(self):
0111         return self._targetLabel
0112     def dumpPythonAs(self, label, options=PrintOptions()):
0113        result = options.indentation()
0114        basename = self._targetLabel
0115        if basename == '':
0116            basename = self.type_()
0117        if options.isCfg:
0118            # do either type or label
0119            result += 'process.prefer("'+basename+'"'
0120            if self.parameterNames_():
0121                result += ",\n"+_Parameterizable.dumpPython(self,options)+options.indentation()
0122            result +=')\n'
0123        else:
0124            # use the base class Module
0125            result += 'es_prefer_'+basename+' = cms.ESPrefer("'+self.type_()+'"'
0126            if self._targetLabel != '':
0127               result += ',"'+self._targetLabel+'"'
0128            if self.parameterNames_():
0129                result += ",\n"+_Parameterizable.dumpPython(self,options)+options.indentation()
0130            result += ')\n'
0131        return result
0132 
0133 class _Module(_ConfigureComponent,_TypedParameterizable,_Labelable,_SequenceLeaf):
0134     """base class for classes which denote framework event based 'modules'"""
0135     __isStrict__ = False  
0136     def __init__(self,type_,*arg,**kargs):
0137         super(_Module,self).__init__(type_,*arg,**kargs)
0138         if _Module.__isStrict__:
0139             self.setIsFrozen()
0140         saveOrigin(self, 2)    
0141     def _clonesequence(self, lookuptable):
0142         try:
0143             return lookuptable[id(self)]
0144         except:
0145             raise ModuleCloneError(self._errorstr())
0146     def _errorstr(self):
0147          # return something like "EDAnalyzer("foo", ...)"
0148         typename = format_typename(self)
0149         return "%s('%s', ...)" %(typename, self.type_())
0150     
0151     def setPrerequisites(self, *libs):
0152         self.__dict__["libraries_"] = libs
0153 
0154     def insertInto(self, parameterSet, myname):
0155         if "libraries_" in self.__dict__:
0156             from ctypes import LibraryLoader, CDLL
0157             import platform
0158             loader = LibraryLoader(CDLL)
0159             ext = platform.uname()[0] == "Darwin" and "dylib" or "so"
0160             [loader.LoadLibrary("lib%s.%s" % (l, ext)) for l in self.libraries_]
0161         super(_Module,self).insertInto(parameterSet,myname)
0162 
0163 class EDProducer(_Module):
0164     def __init__(self,type_,*arg,**kargs):
0165         super(EDProducer,self).__init__(type_,*arg,**kargs)
0166     def _placeImpl(self,name,proc):
0167         proc._placeProducer(name,self)
0168     def _isTaskComponent(self):
0169         return True
0170 
0171 class EDFilter(_Module):
0172     def __init__(self,type_,*arg,**kargs):
0173         super(EDFilter,self).__init__(type_,*arg,**kargs)
0174     def _placeImpl(self,name,proc):
0175         proc._placeFilter(name,self)
0176     def _isTaskComponent(self):
0177         return True
0178 
0179 class EDAnalyzer(_Module):
0180     def __init__(self,type_,*arg,**kargs):
0181         super(EDAnalyzer,self).__init__(type_,*arg,**kargs)
0182     def _placeImpl(self,name,proc):
0183         proc._placeAnalyzer(name,self)
0184 
0185 
0186 class OutputModule(_Module):
0187     def __init__(self,type_,*arg,**kargs):
0188         super(OutputModule,self).__init__(type_,*arg,**kargs)
0189     def _placeImpl(self,name,proc):
0190         proc._placeOutputModule(name,self)
0191 
0192 
0193 class Source(_ConfigureComponent,_TypedParameterizable):
0194     def __init__(self,type_,*arg,**kargs):
0195         super(Source,self).__init__(type_,*arg,**kargs)
0196     def _placeImpl(self,name,proc):
0197         proc._placeSource(name,self)
0198     def moduleLabel_(self,myname):
0199         return "@main_input"
0200     def nameInProcessDesc_(self,myname):
0201         return "@main_input"
0202 
0203 
0204 class Looper(_ConfigureComponent,_TypedParameterizable):
0205     def __init__(self,type_,*arg,**kargs):
0206         super(Looper,self).__init__(type_,*arg,**kargs)
0207     def _placeImpl(self,name,proc):
0208         proc._placeLooper(name,self)
0209     def moduleLabel_(self,myname):
0210         return "@main_looper"
0211     def nameInProcessDesc_(self, myname):
0212         return "@main_looper"
0213 
0214 
0215 # Need to be a module-level function for the configuration with a
0216 # SwitchProducer to be pickleable.
0217 def _switch_cpu(accelerators):
0218     return (True, 1)
0219 
0220 class SwitchProducer(EDProducer):
0221     """This purpose class is to provide a switch of EDProducers for a single module/product label.
0222 
0223     The decision is done at the time when the python configuration is
0224     translated to C++. This class is generic, and intended to be
0225     inherited for concrete switches. Example:
0226 
0227     class SwitchProducerFoo(SwitchProducer):
0228         def __init__(self, **kargs):
0229             super(SwitchProducerFoo,self).__init__(
0230                 dict(case1 = case1Func, case2 = case2Func),
0231                 **kargs
0232             )
0233 
0234     foo = SwitchProducerFoo(
0235         case1 = EDProducer("Producer1"),
0236         case2 = EDProducer("Producer2")
0237     )
0238 
0239     Here case1Func and case2Func are functions that return a (bool,
0240     int) tuple, where the bool tells whether that case is enabled or
0241     not, and the int tells the priority of that case. The case with
0242     the highest priority among those that are enabled will get chosen.
0243 
0244     The end result is that the product(s) labeled as "foo" will be
0245     produced with one of the producers. It would be good if their
0246     output product types and instance names would be the same (or very
0247     close).
0248     """
0249     def __init__(self, caseFunctionDict, **kargs):
0250         super(SwitchProducer,self).__init__(None)
0251         self._caseFunctionDict = copy.copy(caseFunctionDict)
0252         self.__setParameters(kargs)
0253         self._isModified = False
0254 
0255     def setLabel(self, label):
0256         super().setLabel(label)
0257         # SwitchProducer owns the contained modules, and therefore
0258         # need to set / unset the label for them explicitly here
0259         for case in self.parameterNames_():
0260             producer = self.__dict__[case]
0261             producer.setLabel(self.caseLabel_(label, case) if label is not None else None)
0262 
0263     @staticmethod
0264     def getCpu():
0265         """Returns a function that returns the priority for a CPU "computing device". Intended to be used by deriving classes."""
0266         return _switch_cpu
0267 
0268     def _chooseCase(self, accelerators):
0269         """Returns the name of the chosen case."""
0270         cases = self.parameterNames_()
0271         bestCase = None
0272         for case in cases:
0273             (enabled, priority) = self._caseFunctionDict[case](accelerators)
0274             if enabled and (bestCase is None or bestCase[0] < priority):
0275                 bestCase = (priority, case)
0276         if bestCase is None:
0277             raise RuntimeError("All cases '%s' were disabled" % (str(cases)))
0278         return bestCase[1]
0279 
0280     def _getProducer(self, accelerators):
0281         """Returns the EDroducer of the chosen case"""
0282         return self.__dict__[self._chooseCase(accelerators)]
0283 
0284     @staticmethod
0285     def __typeIsValid(typ):
0286         return (isinstance(typ, EDProducer) and not isinstance(typ, SwitchProducer)) or isinstance(typ, EDAlias)
0287 
0288     def __addParameter(self, name, value):
0289         if not self.__typeIsValid(value):
0290             raise TypeError(name+" does not already exist, so it can only be set to a cms.EDProducer or cms.EDAlias")
0291         if name not in self._caseFunctionDict:
0292             raise ValueError("Case '%s' is not allowed (allowed ones are %s)" % (name, ",".join(self._caseFunctionDict.keys())))
0293         if name in self.__dict__:
0294             message = "Duplicate insert of member " + name
0295             message += "\nThe original parameters are:\n"
0296             message += self.dumpPython() + '\n'
0297             raise ValueError(message)
0298         self.__dict__[name]=value
0299         if self.hasLabel_():
0300             value.setLabel(self.caseLabel_(self.label_(), name))
0301         self._Parameterizable__parameterNames.append(name)
0302         self._isModified = True
0303 
0304     def __setParameters(self, parameters):
0305         for name, value in parameters.items():
0306             self.__addParameter(name, value)
0307 
0308     def __setattr__(self, name, value):
0309         # Following snippet copied and customized from
0310         # _Parameterizable in order to support Modifier.toModify
0311         #
0312         #since labels are not supposed to have underscores at the beginning
0313         # I will assume that if we have such then we are setting an internal variable
0314         if self.isFrozen() and not (name in ["_Labelable__label","_isFrozen"] or name.startswith('_')):
0315             message = "Object already added to a process. It is read only now\n"
0316             message +=  "    %s = %s" %(name, value)
0317             message += "\nThe original parameters are:\n"
0318             message += self.dumpPython() + '\n'
0319             raise ValueError(message)
0320         # underscored names bypass checking for _ParameterTypeBase
0321         if name[0]=='_':
0322             super(SwitchProducer, self).__setattr__(name,value)
0323         elif not name in self.__dict__:
0324             self.__addParameter(name, value)
0325             self._isModified = True
0326         else:
0327             if not self.__typeIsValid(value):
0328                 raise TypeError(name+" can only be set to a cms.EDProducer or cms.EDAlias")
0329             # We should always receive an cms.EDProducer
0330             self.__dict__[name] = value
0331             if self.hasLabel_():
0332                 value.setLabel(self.caseLabel_(self.label_(), name))
0333             self._isModified = True
0334 
0335     def clone(self, **params):
0336         returnValue = SwitchProducer.__new__(type(self))
0337 
0338         # Need special treatment as cms.EDProducer is not a valid parameter type (except in this case)
0339         myparams = dict()
0340         for name, value in params.items():
0341             if value is None:
0342                 continue
0343             elif isinstance(value, dict):
0344                 myparams[name] = self.__dict__[name].clone(**value)
0345             else: # value is an EDProducer
0346                 myparams[name] = value.clone()
0347 
0348         # Add the ones that were not customized
0349         for name in self.parameterNames_():
0350             if name not in params:
0351                 myparams[name] = self.__dict__[name].clone()
0352         returnValue.__init__(**myparams)
0353         returnValue._isModified = False
0354         returnValue._isFrozen = False
0355         saveOrigin(returnValue, 1)
0356         return returnValue
0357 
0358     def dumpPython(self, options=PrintOptions()):
0359         # Note that if anyone uses the generic SwitchProducer instead
0360         # of a derived-one, the information on the functions for the
0361         # producer decision is lost
0362         specialImportRegistry.registerUse(self)
0363         result = "%s(" % self.__class__.__name__ # not including cms. since the deriving classes are not in cms "namespace"
0364         options.indent()
0365         for resource in sorted(self.parameterNames_()):
0366             result += "\n" + options.indentation() + resource + " = " + getattr(self, resource).dumpPython(options).rstrip() + ","
0367         if result[-1] == ",":
0368             result = result.rstrip(",")
0369         options.unindent()
0370         result += "\n)\n"
0371         return result
0372 
0373     def directDependencies(self):
0374         # XXX FIXME handle SwitchProducer dependencies
0375         return []
0376 
0377     def nameInProcessDesc_(self, myname):
0378         return myname
0379     def moduleLabel_(self, myname):
0380         return myname
0381     def caseLabel_(self, name, case):
0382         return name+"@"+case
0383     def modulesForConditionalTask_(self):
0384         # Need the contained modules (not EDAliases) for ConditionalTask
0385         ret = []
0386         for case in self.parameterNames_():
0387             caseobj = self.__dict__[case]
0388             if not isinstance(caseobj, EDAlias):
0389                 ret.append(caseobj)
0390         return ret
0391     def appendToProcessDescLists_(self, modules, aliases, myname):
0392         # This way we can insert the chosen EDProducer to @all_modules
0393         # so that we get easily a worker for it
0394         modules.append(myname)
0395         for case in self.parameterNames_():
0396             if isinstance(self.__dict__[case], EDAlias):
0397                 aliases.append(self.caseLabel_(myname, case))
0398             else:
0399                 modules.append(self.caseLabel_(myname, case))
0400 
0401     def insertInto(self, parameterSet, myname, accelerators):
0402         for case in self.parameterNames_():
0403             producer = self.__dict__[case]
0404             producer.insertInto(parameterSet, self.caseLabel_(myname, case))
0405         newpset = parameterSet.newPSet()
0406         newpset.addString(True, "@module_label", self.moduleLabel_(myname))
0407         newpset.addString(True, "@module_type", "SwitchProducer")
0408         newpset.addString(True, "@module_edm_type", "EDProducer")
0409         newpset.addVString(True, "@all_cases", [self.caseLabel_(myname, p) for p in self.parameterNames_()])
0410         newpset.addString(False, "@chosen_case", self.caseLabel_(myname, self._chooseCase(accelerators)))
0411         parameterSet.addPSet(True, self.nameInProcessDesc_(myname), newpset)
0412 
0413     def _placeImpl(self,name,proc):
0414         proc._placeSwitchProducer(name,self)
0415 #        for case in self.parameterNames_():
0416 #            caseLabel = self.caseLabel_(name, case)
0417 #            caseObj = self.__dict__[case]
0418 #
0419 #            if isinstance(caseObj, EDAlias):
0420 #                # EDAliases end up in @all_aliases automatically
0421 #                proc._placeAlias(caseLabel, caseObj)
0422 #            else:
0423 #                # Note that these don't end up in @all_modules
0424 #                # automatically because they're not part of any
0425 #                # Task/Sequence/Path
0426 #                proc._placeProducer(caseLabel, caseObj)
0427 
0428     def _clonesequence(self, lookuptable):
0429         try:
0430             return lookuptable[id(self)]
0431         except:
0432             raise ModuleCloneError(self._errorstr())
0433     def _errorstr(self):
0434         return "SwitchProducer"
0435 
0436 
0437 if __name__ == "__main__":
0438     import unittest
0439     from .Types import *
0440     from .SequenceTypes import *
0441 
0442     class SwitchProducerTest(SwitchProducer):
0443         def __init__(self, **kargs):
0444             super(SwitchProducerTest,self).__init__(
0445                 dict(
0446                     test1 = lambda accelerators: ("test1" in accelerators, -10),
0447                     test2 = lambda accelerators: ("test2" in accelerators, -9),
0448                     test3 = lambda accelerators: ("test3" in accelerators, -8)
0449                 ), **kargs)
0450     class SwitchProducerPickleable(SwitchProducer):
0451         def __init__(self, **kargs):
0452             super(SwitchProducerPickleable,self).__init__(
0453                 dict(cpu = SwitchProducer.getCpu()), **kargs)
0454 
0455     class TestModules(unittest.TestCase):
0456         def testEDAnalyzer(self):
0457             empty = EDAnalyzer("Empty")
0458             withParam = EDAnalyzer("Parameterized",foo=untracked(int32(1)), bar = untracked(string("it")))
0459             self.assertEqual(withParam.foo.value(), 1)
0460             self.assertEqual(withParam.bar.value(), "it")
0461             aCopy = withParam.copy()
0462             self.assertEqual(aCopy.foo.value(), 1)
0463             self.assertEqual(aCopy.bar.value(), "it")
0464             withType = EDAnalyzer("Test",type = int32(1))
0465             self.assertEqual(withType.type.value(),1)
0466             block = PSet(i = int32(9))
0467             m = EDProducer("DumbProducer", block, j = int32(10))
0468             self.assertEqual(9, m.i.value())
0469             self.assertEqual(10, m.j.value())
0470         def testESPrefer(self):
0471             juicer = ESPrefer("JuiceProducer")
0472             options = PrintOptions()
0473             options.isCfg = True
0474             self.assertEqual(juicer.dumpPythonAs("juicer", options), "process.prefer(\"JuiceProducer\")\n")
0475             options.isCfg = False
0476             self.assertEqual(juicer.dumpPythonAs("juicer", options), "es_prefer_JuiceProducer = cms.ESPrefer(\"JuiceProducer\")\n")
0477 
0478             juicer = ESPrefer("JuiceProducer","juicer")
0479             options = PrintOptions()
0480             options.isCfg = True
0481             self.assertEqual(juicer.dumpPythonAs("juicer", options), 'process.prefer("juicer")\n')
0482             options.isCfg = False
0483             self.assertEqual(juicer.dumpPythonAs("juicer", options), 'es_prefer_juicer = cms.ESPrefer("JuiceProducer","juicer")\n')
0484             juicer = ESPrefer("JuiceProducer",fooRcd=vstring())
0485             self.assertEqual(juicer.dumpConfig(options),
0486 """JuiceProducer { 
0487     vstring fooRcd = {
0488     }
0489 
0490 }
0491 """)
0492             options = PrintOptions()
0493             options.isCfg = True
0494             self.assertEqual(juicer.dumpPythonAs("juicer"),
0495 """process.prefer("JuiceProducer",
0496     fooRcd = cms.vstring()
0497 )
0498 """)
0499             options.isCfg = False
0500             self.assertEqual(juicer.dumpPythonAs("juicer", options),
0501 """es_prefer_JuiceProducer = cms.ESPrefer("JuiceProducer",
0502     fooRcd = cms.vstring()
0503 )
0504 """)
0505         
0506         def testService(self):
0507             empty = Service("Empty")
0508             withParam = Service("Parameterized",foo=untracked(int32(1)), bar = untracked(string("it")))
0509             self.assertEqual(withParam.foo.value(), 1)
0510             self.assertEqual(withParam.bar.value(), "it")
0511             self.assertEqual(empty.dumpPython(), "cms.Service(\"Empty\")\n")
0512             self.assertEqual(withParam.dumpPython(), "cms.Service(\"Parameterized\",\n    bar = cms.untracked.string(\'it\'),\n    foo = cms.untracked.int32(1)\n)\n")
0513         def testSequences(self):
0514             m = EDProducer("MProducer")
0515             n = EDProducer("NProducer")
0516             m.setLabel("m")
0517             n.setLabel("n")
0518             s1 = Sequence(m*n)
0519             options = PrintOptions()
0520 
0521         def testIsTaskComponent(self):
0522             m = EDProducer("x")
0523             self.assertTrue(m._isTaskComponent())
0524             self.assertTrue(m.isLeaf())
0525             m = SwitchProducerTest(test1=EDProducer("x"))
0526             self.assertTrue(m._isTaskComponent())
0527             self.assertTrue(m.isLeaf())
0528             m = EDFilter("x")
0529             self.assertTrue(m._isTaskComponent())
0530             self.assertTrue(m.isLeaf())
0531             m = OutputModule("x")
0532             self.assertFalse(m._isTaskComponent())
0533             self.assertTrue(m.isLeaf())
0534             m = EDAnalyzer("x")
0535             self.assertFalse(m._isTaskComponent())
0536             self.assertTrue(m.isLeaf())
0537             m = Service("x")
0538             self.assertTrue(m._isTaskComponent())
0539             self.assertTrue(m.isLeaf())
0540             m = ESProducer("x")
0541             self.assertTrue(m._isTaskComponent())
0542             self.assertTrue(m.isLeaf())
0543             m = ESSource("x")
0544             self.assertTrue(m._isTaskComponent())
0545             self.assertTrue(m.isLeaf())
0546             m = Sequence()
0547             self.assertFalse(m._isTaskComponent())
0548             self.assertFalse(m.isLeaf())
0549             m = Path()
0550             self.assertFalse(m._isTaskComponent())
0551             m = EndPath()
0552             self.assertFalse(m._isTaskComponent())
0553             m = Task()
0554             self.assertTrue(m._isTaskComponent())
0555             self.assertFalse(m.isLeaf())
0556 
0557         def testSwitchProducer(self):
0558             # Constructor
0559             sp = SwitchProducerTest(test1 = EDProducer("Foo"), test2 = EDProducer("Bar"))
0560             self.assertEqual(sp.test1.type_(), "Foo")
0561             self.assertEqual(sp.test2.type_(), "Bar")
0562             self.assertRaises(ValueError, lambda: SwitchProducerTest(nonexistent = EDProducer("Foo")))
0563             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = EDAnalyzer("Foo")))
0564             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = EDFilter("Foo")))
0565             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = Source("Foo")))
0566             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = OutputModule("Foo")))
0567             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = Looper("Foo")))
0568             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = Service("Foo")))
0569             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = ESSource("Foo")))
0570             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = ESProducer("Foo")))
0571             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = ESPrefer("Foo")))
0572             self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = SwitchProducerTest(test1 = EDProducer("Foo"))))
0573 
0574             # Label
0575             sp.setLabel("sp")
0576             self.assertEqual(sp.label_(), "sp")
0577             self.assertEqual(sp.test1.label_(), "sp@test1")
0578             self.assertEqual(sp.test2.label_(), "sp@test2")
0579             sp.test3 = EDProducer("Xyzzy")
0580             self.assertEqual(sp.test3.label_(), "sp@test3")
0581             sp.test1 = EDProducer("Fred")
0582             self.assertEqual(sp.test1.label_(), "sp@test1")
0583             del sp.test1
0584             sp.test1 = EDProducer("Wilma")
0585             self.assertEqual(sp.test1.label_(), "sp@test1")
0586             sp.setLabel(None)
0587             sp.setLabel("other")
0588             self.assertEqual(sp.label_(), "other")
0589             self.assertEqual(sp.test1.label_(), "other@test1")
0590             self.assertEqual(sp.test2.label_(), "other@test2")
0591 
0592             # Case decision
0593             accelerators = ["test1", "test2", "test3"]
0594             sp = SwitchProducerTest(test1 = EDProducer("Foo"), test2 = EDProducer("Bar"))
0595             self.assertEqual(sp._getProducer(["test1", "test2", "test3"]).type_(), "Bar")
0596             self.assertEqual(sp._getProducer(["test2", "test3"]).type_(), "Bar")
0597             self.assertEqual(sp._getProducer(["test1", "test3"]).type_(), "Foo")
0598             sp = SwitchProducerTest(test1 = EDProducer("Bar"))
0599             self.assertEqual(sp._getProducer(["test1", "test2", "test3"]).type_(), "Bar")
0600             self.assertRaises(RuntimeError, sp._getProducer, ["test2", "test3"])
0601 
0602             # Mofications
0603             from .Types import int32, string, PSet
0604             sp = SwitchProducerTest(test1 = EDProducer("Foo",
0605                                                        a = int32(1),
0606                                                        b = PSet(c = int32(2))),
0607                                     test2 = EDProducer("Bar",
0608                                                        aa = int32(11),
0609                                                        bb = PSet(cc = int32(12))))
0610             # Simple clone
0611             cl = sp.clone()
0612             self.assertEqual(cl.test1.type_(), "Foo")
0613             self.assertEqual(cl.test1.a.value(), 1)
0614             self.assertEqual(cl.test1.b.c.value(), 2)
0615             self.assertEqual(cl.test2.type_(), "Bar")
0616             self.assertEqual(cl.test2.aa.value(), 11)
0617             self.assertEqual(cl.test2.bb.cc.value(), 12)
0618             self.assertEqual(sp._getProducer(accelerators).type_(), "Bar")
0619             # Modify clone
0620             cl.test1.a = 3
0621             self.assertEqual(cl.test1.a.value(), 3)
0622             cl.test1 = EDProducer("Fred")
0623             self.assertEqual(cl.test1.type_(), "Fred")
0624             def _assignEDAnalyzer():
0625                 cl.test1 = EDAnalyzer("Foo")
0626             self.assertRaises(TypeError, _assignEDAnalyzer)
0627             def _assignSwitchProducer():
0628                 cl.test1 = SwitchProducerTest(test1 = SwitchProducerTest(test1 = EDProducer("Foo")))
0629             self.assertRaises(TypeError, _assignSwitchProducer)
0630             # Modify values with a dict
0631             cl = sp.clone(test1 = dict(a = 4, b = dict(c = None)),
0632                           test2 = dict(aa = 15, bb = dict(cc = 45, dd = string("foo"))))
0633             self.assertEqual(cl.test1.a.value(), 4)
0634             self.assertEqual(cl.test1.b.hasParameter("c"), False)
0635             self.assertEqual(cl.test2.aa.value(), 15)
0636             self.assertEqual(cl.test2.bb.cc.value(), 45)
0637             self.assertEqual(cl.test2.bb.dd.value(), "foo")
0638             # Replace/add/remove EDProducers
0639             cl = sp.clone(test1 = EDProducer("Fred", x = int32(42)),
0640                           test3 = EDProducer("Wilma", y = int32(24)),
0641                           test2 = None)
0642             self.assertEqual(cl.test1.type_(), "Fred")
0643             self.assertEqual(cl.test1.x.value(), 42)
0644             self.assertEqual(cl.test3.type_(), "Wilma")
0645             self.assertEqual(cl.test3.y.value(), 24)
0646             self.assertEqual(hasattr(cl, "test2"), False)
0647             self.assertRaises(TypeError, lambda: sp.clone(test1 = EDAnalyzer("Foo")))
0648             self.assertRaises(TypeError, lambda: sp.clone(test1 = SwitchProducerTest(test1 = SwitchProducerTest(test1 = EDProducer("Foo")))))
0649 
0650             # Dump
0651             sp = SwitchProducerTest(test2 = EDProducer("Foo",
0652                                                        a = int32(1),
0653                                                        b = PSet(c = int32(2))),
0654                                     test1 = EDProducer("Bar",
0655                                                        aa = int32(11),
0656                                                        bb = PSet(cc = int32(12))))
0657             self.assertEqual(sp.dumpPython(),
0658 """SwitchProducerTest(
0659     test1 = cms.EDProducer("Bar",
0660         aa = cms.int32(11),
0661         bb = cms.PSet(
0662             cc = cms.int32(12)
0663         )
0664     ),
0665     test2 = cms.EDProducer("Foo",
0666         a = cms.int32(1),
0667         b = cms.PSet(
0668             c = cms.int32(2)
0669         )
0670     )
0671 )
0672 """)
0673             # Pickle
0674             import pickle
0675             sp = SwitchProducerPickleable(cpu = EDProducer("Foo"))
0676             pkl = pickle.dumps(sp)
0677             unpkl = pickle.loads(pkl)
0678             self.assertEqual(unpkl.cpu.type_(), "Foo")
0679 
0680         def testSwithProducerWithAlias(self):
0681             # Constructor
0682             sp = SwitchProducerTest(test1 = EDProducer("Foo"), test2 = EDAlias())
0683             self.assertEqual(sp.test1.type_(), "Foo")
0684             self.assertTrue(isinstance(sp.test2, EDAlias))
0685 
0686             # Modifications
0687             from .Types import int32, string, PSet, VPSet
0688             sp = SwitchProducerTest(test1 = EDProducer("Foo"),
0689                                     test2 = EDAlias(foo = VPSet(PSet(type = string("Foo2")))))
0690 
0691             # Simple clone
0692             cl = sp.clone()
0693             self.assertTrue(hasattr(cl.test2, "foo"))
0694             # Modify clone
0695             cl.test2.foo[0].type = "Foo3"
0696             self.assertEqual(cl.test2.foo[0].type, "Foo3")
0697             # Modify values with a dict
0698             cl = sp.clone(test2 = dict(foo = {0: dict(type = "Foo4")}))
0699             self.assertEqual(cl.test2.foo[0].type, "Foo4")
0700             # Replace or add EDAlias
0701             cl = sp.clone(test1 = EDAlias(foo = VPSet(PSet(type = string("Foo5")))),
0702                           test3 = EDAlias(foo = VPSet(PSet(type = string("Foo6")))))
0703             self.assertEqual(cl.test1.foo[0].type, "Foo5")
0704             self.assertEqual(cl.test3.foo[0].type, "Foo6")
0705             # Modify clone
0706             cl.test1 = EDProducer("Xyzzy")
0707             self.assertEqual(cl.test1.type_(), "Xyzzy")
0708             cl.test1 = EDAlias(foo = VPSet(PSet(type = string("Foo7"))))
0709             self.assertEqual(cl.test1.foo[0].type, "Foo7")
0710 
0711 
0712             # Dump
0713             from .Types import int32, string, PSet, VPSet
0714             sp = SwitchProducerTest(test1 = EDProducer("Foo"),
0715                                     test2 = EDAlias(foo = VPSet(PSet(type = string("Foo2")))))
0716 
0717             self.assertEqual(sp.dumpPython(),
0718 """SwitchProducerTest(
0719     test1 = cms.EDProducer("Foo"),
0720     test2 = cms.EDAlias(
0721         foo = cms.VPSet(cms.PSet(
0722             type = cms.string('Foo2')
0723         ))
0724     )
0725 )
0726 """)
0727 
0728             # Pickle
0729             import pickle
0730             sp = SwitchProducerPickleable(cpu = EDAlias(foo = VPSet(PSet(type = string("Foo2")))))
0731             pkl = pickle.dumps(sp)
0732             unpkl = pickle.loads(pkl)
0733             self.assertEqual(sp.cpu.foo[0].type, "Foo2")
0734     unittest.main()