Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-01 23:40:19

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