4 from Options
import Options
10 from Mixins
import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable, _Unlabelable, _ValidatingListBase
14 from Modules
import _Module
15 from SequenceTypes
import *
16 from SequenceTypes
import _ModuleSequenceType, _Sequenceable
17 from SequenceVisitors
import PathValidator, EndPathValidator
18 from Utilities
import *
21 from ExceptionHandling
import *
24 if sys.getrecursionlimit()<5000:
25 sys.setrecursionlimit(5000)
29 Raise an exception if called by special config files. This checks
30 the call or import stack for the importing file. An exception is raised if
31 the importing module is not in allowedPatterns and if it is called too deeply:
32 minLevel = 2: inclusion by top lvel cfg only
33 minLevel = 1: No inclusion allowed
34 allowedPatterns = ['Module1','Module2/SubModule1'] allows import
35 by any module in Module1 or Submodule1
41 ignorePatterns = [
'FWCore/ParameterSet/Config.py',
'<string>']
42 CMSSWPath = [os.environ[
'CMSSW_BASE'],os.environ[
'CMSSW_RELEASE_BASE']]
46 for item
in inspect.stack():
50 for pattern
in CMSSWPath:
51 if item[1].
find(pattern) != -1:
54 if item[1].
find(
'/') == -1:
57 for pattern
in ignorePatterns:
58 if item[1].
find(pattern) != -1:
62 if inPath
and not ignore:
63 trueStack.append(item[1])
65 importedFile = trueStack[0]
67 if len(trueStack) > 1:
68 importedBy = trueStack[1]
70 for pattern
in allowedPatterns:
71 if importedBy.find(pattern) > -1:
74 if len(trueStack) <= minLevel:
77 raise ImportError(
"Inclusion of %s is allowed only by cfg or specified cfi files."
81 """Look inside the module and find the Processes it contains"""
85 if isinstance(module,dict):
86 if 'process' in module:
90 if hasattr(module,
'process'):
91 if isinstance(module.process,Process):
92 process = module.process
94 raise RuntimeError(
"The attribute named 'process' does not inherit from the Process class")
96 raise RuntimeError(
"no 'process' attribute found in the module, please add one")
101 """Root class for a CMS configuration process"""
103 """The argument 'name' will be the name applied to this Process"""
104 self.__dict__[
'_Process__name'] = name
105 if not name.isalnum():
106 raise RuntimeError(
"Error: The process name is an empty string or contains non-alphanumeric characters")
107 self.__dict__[
'_Process__filters'] = {}
108 self.__dict__[
'_Process__producers'] = {}
109 self.__dict__[
'_Process__source'] =
None
110 self.__dict__[
'_Process__looper'] =
None
111 self.__dict__[
'_Process__subProcess'] =
None
112 self.__dict__[
'_Process__schedule'] =
None
113 self.__dict__[
'_Process__analyzers'] = {}
114 self.__dict__[
'_Process__outputmodules'] = {}
117 self.__dict__[
'_Process__sequences'] = {}
118 self.__dict__[
'_Process__services'] = {}
119 self.__dict__[
'_Process__essources'] = {}
120 self.__dict__[
'_Process__esproducers'] = {}
121 self.__dict__[
'_Process__esprefers'] = {}
122 self.__dict__[
'_Process__aliases'] = {}
123 self.__dict__[
'_Process__psets']={}
124 self.__dict__[
'_Process__vpsets']={}
125 self.__dict__[
'_cloneToObjectDict'] = {}
127 self.__dict__[
'_Process__InExtendCall'] =
False
128 self.__dict__[
'_Process__partialschedules'] = {}
133 _Module.__isStrict__ =
True
137 """Returns a string containing all the EDProducer labels separated by a blank"""
140 """Returns a string containing all the EDAnalyzer labels separated by a blank"""
143 """Returns a string containing all the EDFilter labels separated by a blank"""
146 """Returns a string containing all the Path names separated by a blank"""
153 Since cloneToObjectDict stores a hash of objects by their
154 id() it needs to be updated when unpickling to use the
155 new object id values instantiated during the unpickle.
158 self.__dict__.update(pkldict)
160 for value
in self._cloneToObjectDict.values():
161 tmpDict[id(value)] = value
162 self.__dict__[
'_cloneToObjectDict'] = tmpDict
167 """returns a dict of the filters which have been added to the Process"""
169 filters = property(filters_, doc=
"dictionary containing the filters for the process")
173 if not name.isalnum():
174 raise RuntimeError(
"Error: The process name is an empty string or contains non-alphanumeric characters")
175 self.__dict__[
'_Process__name'] = name
176 process = property(name_,setName_, doc=
"name of the process")
178 """returns a dict of the producers which have been added to the Process"""
180 producers = property(producers_,doc=
"dictionary containing the producers for the process")
182 """returns the source which has been added to the Process or None if none have been added"""
186 source = property(source_,setSource_,doc=
'the main source or None if not set')
188 """returns the looper which has been added to the Process or None if none have been added"""
192 looper = property(looper_,setLooper_,doc=
'the main looper or None if not set')
194 """returns the sub-process which has been added to the Process or None if none have been added"""
195 return self.__subProcess
198 subProcess = property(subProcess_,setSubProcess_,doc=
'the SubProcess or None if not set')
200 """returns a dict of the analyzers which have been added to the Process"""
202 analyzers = property(analyzers_,doc=
"dictionary containing the analyzers for the process")
204 """returns a dict of the output modules which have been added to the Process"""
206 outputModules = property(outputModules_,doc=
"dictionary containing the output_modules for the process")
208 """returns a dict of the paths which have been added to the Process"""
210 paths = property(paths_,doc=
"dictionary containing the paths for the process")
212 """returns a dict of the endpaths which have been added to the Process"""
214 endpaths = property(endpaths_,doc=
"dictionary containing the endpaths for the process")
216 """returns a dict of the sequences which have been added to the Process"""
218 sequences = property(sequences_,doc=
"dictionary containing the sequences for the process")
220 """returns the schedule which has been added to the Process or None if none have been added"""
221 return self.__schedule
223 if label ==
"schedule":
226 self.
_place(label, sch, self.__partialschedules)
235 raise RuntimeError(
"The path at index "+str(index)+
" in the Schedule was not attached to the process.")
237 self.__dict__[
'_Process__schedule'] = sch
238 schedule = property(schedule_,setSchedule_,doc=
'the schedule or None if not set')
240 """returns a dict of the services which have been added to the Process"""
242 services = property(services_,doc=
"dictionary containing the services for the process")
244 """returns a dict of the esproducers which have been added to the Process"""
246 es_producers = property(es_producers_,doc=
"dictionary containing the es_producers for the process")
248 """returns a the es_sources which have been added to the Process"""
250 es_sources = property(es_sources_,doc=
"dictionary containing the es_sources for the process")
252 """returns a dict of the es_prefers which have been added to the Process"""
254 es_prefers = property(es_prefers_,doc=
"dictionary containing the es_prefers for the process")
256 """returns a dict of the aliases that have been added to the Process"""
258 aliases = property(aliases_,doc=
"dictionary containing the aliases for the process")
260 """returns a dict of the PSets which have been added to the Process"""
262 psets = property(psets_,doc=
"dictionary containing the PSets for the process")
264 """returns a dict of the VPSets which have been added to the Process"""
266 vpsets = property(vpsets_,doc=
"dictionary containing the PSets for the process")
269 if not object.hasLabel_() :
270 object.setLabel(newLabel)
272 if newLabel == object.label_() :
274 if newLabel
is None :
275 object.setLabel(
None)
277 if (hasattr(self, object.label_())
and id(getattr(self, object.label_())) == id(object)) :
278 msg100 =
"Attempting to change the label of an attribute of the Process\n"
279 msg101 =
"Old label = "+object.label_()+
" New label = "+newLabel+
"\n"
280 msg102 =
"Type = "+str(type(object))+
"\n"
281 msg103 =
"Some possible solutions:\n"
282 msg104 =
" 1. Clone modules instead of using simple assignment. Cloning is\n"
283 msg105 =
" also preferred for other types when possible.\n"
284 msg106 =
" 2. Declare new names starting with an underscore if they are\n"
285 msg107 =
" for temporaries you do not want propagated into the Process. The\n"
286 msg108 =
" underscore tells \"from x import *\" and process.load not to import\n"
287 msg109 =
" the name.\n"
288 msg110 =
" 3. Reorganize so the assigment is not necessary. Giving a second\n"
289 msg111 =
" name to the same object usually causes confusion and problems.\n"
290 msg112 =
" 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
291 raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
292 object.setLabel(
None)
293 object.setLabel(newLabel)
297 if not name.replace(
'_',
'').isalnum():
298 raise ValueError(
'The label '+name+
' contains forbiden characters')
301 if name.startswith(
'_Process__'):
302 self.__dict__[name]=value
304 if not isinstance(value,_ConfigureComponent):
305 raise TypeError(
"can only assign labels to an object which inherits from '_ConfigureComponent'\n"
306 +
"an instance of "+str(type(value))+
" will not work")
307 if not isinstance(value,_Labelable)
and not isinstance(value,Source)
and not isinstance(value,Looper)
and not isinstance(value,Schedule):
308 if name == value.type_():
312 raise TypeError(
"an instance of "+str(type(value))+
" can not be assigned the label '"+name+
"'.\n"+
313 "Please either use the label '"+value.type_()+
" or use the 'add_' method instead.")
316 newValue =value.copy()
318 newValue._filename = value._filename
324 if not self.
_okToPlace(name, value, self.__dict__):
325 newFile=
'top level config'
326 if hasattr(value,
'_filename'):
327 newFile = value._filename
328 oldFile=
'top level config'
329 oldValue = getattr(self,name)
330 if hasattr(oldValue,
'_filename'):
331 oldFile = oldValue._filename
332 msg =
"Trying to override definition of process."+name
333 msg +=
"\n new object defined in: "+newFile
334 msg +=
"\n existing object defined in: "+oldFile
335 raise ValueError(msg)
337 if hasattr(self,name)
and not (getattr(self,name)==newValue):
341 if isinstance(newValue, _Sequenceable):
342 if not self.__InExtendCall:
346 newFile=
'top level config'
347 if hasattr(value,
'_filename'):
348 newFile = value._filename
349 oldFile=
'top level config'
350 oldValue = getattr(self,name)
351 if hasattr(oldValue,
'_filename'):
352 oldFile = oldValue._filename
353 msg1 =
"Trying to override definition of "+name+
" while it is used by the sequence "
354 msg2 =
"\n new object defined in: "+newFile
355 msg2 +=
"\n existing object defined in: "+oldFile
358 raise ValueError(msg1+s.label_()+msg2)
361 raise ValueError(msg1+s.label_()+msg2)
364 raise ValueError(msg1+s.label_()+msg2)
366 self.__dict__[name]=newValue
367 if isinstance(newValue,_Labelable):
369 self._cloneToObjectDict[id(value)] = newValue
370 self._cloneToObjectDict[id(newValue)] = newValue
372 newValue._place(name,self)
374 """Given a container of sequences, find the first sequence containing mod
375 and return the sequence. If no sequence is found, return None"""
377 for sequenceable
in seqs.itervalues():
380 sequenceable.visit(v)
385 if not hasattr(self,name):
386 raise KeyError(
'process does not know about '+name)
387 elif name.startswith(
'_Process__'):
388 raise ValueError(
'this attribute cannot be deleted')
393 if reg.has_key(name): del reg[name]
395 obj = getattr(self,name)
396 if isinstance(obj,_Labelable):
397 getattr(self,name).setLabel(
None)
400 del self.__dict__[name]
405 """Allows addition of components which do not have to have a label, e.g. Services"""
406 if not isinstance(value,_ConfigureComponent):
408 if not isinstance(value,_Unlabelable):
413 newValue =value.copy()
417 newValue._place(
'',self)
420 if not self.__InExtendCall:
431 if d[name]._isModified:
442 if self.
__isStrict and isinstance(mod, _ModuleSequenceType):
443 d[name] = mod._postProcessFixup(self._cloneToObjectDict)
446 if isinstance(mod,_Labelable):
449 self.
_place(name, mod, self.__outputmodules)
451 self.
_place(name, mod, self.__producers)
453 self.
_place(name, mod, self.__filters)
455 self.
_place(name, mod, self.__analyzers)
459 self.
_place(name, mod, self.__paths)
460 except ModuleCloneError, msg:
462 raise Exception(
"%sThe module %s in path %s is unknown to the process %s." %(context, msg, name, self._Process__name))
466 self.
_place(name, mod, self.__endpaths)
467 except ModuleCloneError, msg:
469 raise Exception(
"%sThe module %s in endpath %s is unknown to the process %s." %(context, msg, name, self._Process__name))
472 self.
_place(name, mod, self.__sequences)
474 self.
_place(name, mod, self.__esproducers)
476 self.
_place(name, mod, self.__esprefers)
478 self.
_place(name, mod, self.__essources)
480 self.
_place(name, mod, self.__aliases)
482 self.
_place(name, mod, self.__psets)
484 self.
_place(name, mod, self.__vpsets)
486 """Allow the source to be referenced by 'source' or by type name"""
488 raise ValueError(
"The label '"+name+
"' can not be used for a Source. Only 'source' is allowed.")
489 if self.__dict__[
'_Process__source']
is not None :
490 del self.__dict__[self.__dict__[
'_Process__source'].type_()]
491 self.__dict__[
'_Process__source'] = mod
492 self.__dict__[mod.type_()] = mod
495 raise ValueError(
"The label '"+name+
"' can not be used for a Looper. Only 'looper' is allowed.")
496 self.__dict__[
'_Process__looper'] = mod
497 self.__dict__[mod.type_()] = mod
499 if name !=
'subProcess':
500 raise ValueError(
"The label '"+name+
"' can not be used for a SubProcess. Only 'subProcess' is allowed.")
501 self.__dict__[
'_Process__subProcess'] = mod
502 self.__dict__[mod.type_()] = mod
504 self.
_place(typeName, mod, self.__services)
505 self.__dict__[typeName]=mod
507 moduleName = moduleName.replace(
"/",
".")
508 module = __import__(moduleName)
509 self.
extend(sys.modules[moduleName])
511 """Look in other and find types which we can use"""
513 self.__dict__[
'_Process__InExtendCall'] =
True
516 for name
in dir(other):
518 if name.startswith(
'_'):
520 item = getattr(other,name)
521 if name ==
"source" or name ==
"looper" or name ==
"subProcess":
523 elif isinstance(item,_ModuleSequenceType):
525 elif isinstance(item,_Labelable):
527 if not item.hasLabel_() :
529 elif isinstance(item,Schedule):
531 elif isinstance(item,_Unlabelable):
535 for name
in seqs.iterkeys():
539 if id(seq)
not in self._cloneToObjectDict:
542 newSeq = self._cloneToObjectDict[id(seq)]
543 self.__dict__[name]=newSeq
546 newSeq._place(name,self)
547 self.__dict__[
'_Process__InExtendCall'] =
False
550 for name,item
in items:
551 returnValue +=options.indentation()+typeName+
' '+name+
' = '+item.dumpConfig(options)
555 for name,item
in items:
556 returnValue +=options.indentation()+typeName+
' = '+item.dumpConfig(options)
560 for name,item
in items:
561 if name == item.type_():
563 returnValue +=options.indentation()+typeName+
' '+name+
' = '+item.dumpConfig(options)
566 """return a string containing the equivalent process defined using the old configuration language"""
567 config =
"process "+self.__name+
" = {\n"
612 for name,item
in self.psets.iteritems():
613 config +=options.indentation()+item.configTypeName()+
' '+name+
' = '+item.configValue(options)
614 for name,item
in self.vpsets.iteritems():
615 config +=options.indentation()+
'VPSet '+name+
' = '+item.configValue(options)
617 pathNames = [p.label_()
for p
in self.
schedule]
618 config +=options.indentation()+
'schedule = {'+
','.
join(pathNames)+
'}\n'
629 result +=options.indentation()+
'es_prefer '+item.targetLabel_()+
' = '+item.dumpConfig(options)
634 for name,item
in d.items():
635 returnValue +=
'process.'+name+
' = '+item.dumpPython(options)+
'\n\n'
637 for name,item
in sorted(d.items()):
638 returnValue +=
'process.'+name+
' = '+item.dumpPython(options)+
'\n\n'
645 sequence.visit(nameVisitor)
647 raise RuntimeError(
"An entry in sequence "+label +
' has no label')
652 for label,seq
in self.sequences.iteritems():
656 dependencies[label]=[dep.label_()
for dep
in d
if dep.hasLabel_()]
657 resolvedDependencies=
True
661 while resolvedDependencies:
663 resolvedDependencies = (0 != len(dependencies))
664 oldDeps =
dict(dependencies)
665 for label,deps
in oldDeps.iteritems():
667 if len(deps)==0
or iterCount > 100:
669 resolvedDependencies=
True
672 del dependencies[label]
673 for lb2,deps2
in dependencies.iteritems():
674 while deps2.count(label):
676 if len(dependencies):
677 raise RuntimeError(
"circular sequence dependency discovered \n"+
678 ",".
join([label
for label,junk
in dependencies.iteritems()]))
682 for name, value
in d.iteritems():
683 result += value.dumpPythonAs(name,options)+
'\n'
686 """return a string containing the equivalent process defined using python"""
687 result =
"import FWCore.ParameterSet.Config as cms\n\n"
688 result +=
"process = cms.Process(\""+self.__name+
"\")\n\n"
710 pathNames = [
'process.'+p.label_()
for p
in self.
schedule]
711 result +=
'process.schedule = cms.Schedule(*[ ' +
', '.
join(pathNames) +
' ])\n'
715 old = getattr(self,label)
717 for sequenceable
in self.sequences.itervalues():
718 sequenceable.replace(old,new)
719 for sequenceable
in self.paths.itervalues():
720 sequenceable.replace(old,new)
721 for sequenceable
in self.endpaths.itervalues():
722 sequenceable.replace(old,new)
724 """ Replace the item with label 'label' by object 'new' in the process and all sequences/paths"""
725 if not hasattr(self,label):
726 raise LookupError(
"process has no item of label "+label)
728 setattr(self,label,new)
730 for name,value
in itemDict.iteritems():
731 value.insertInto(parameterSet, name)
735 newlabel = item.nameInProcessDesc_(label)
737 item.insertInto(parameterSet, newlabel)
738 parameterSet.addVString(tracked, label, vitems)
741 for name,value
in itemDict.iteritems():
742 newLabel = value.nameInProcessDesc_(name)
744 value.insertInto(parameterSet, name)
747 parameterSet.addVString(tracked, label, l)
754 for name,value
in self.
paths_().iteritems():
755 scheduledPaths.append(name)
756 triggerPaths.append(name)
757 for name,value
in self.
endpaths_().iteritems():
758 scheduledPaths.append(name)
759 endpaths.append(name)
762 pathname = path.label_()
763 scheduledPaths.append(pathname)
765 endpaths.append(pathname)
767 triggerPaths.append(pathname)
768 processPSet.addVString(
True,
"@end_paths", endpaths)
769 processPSet.addVString(
True,
"@paths", scheduledPaths)
771 p = processPSet.newPSet()
772 p.addVString(
True,
"@trigger_paths", triggerPaths)
773 processPSet.addPSet(
True,
"@trigger_paths", p)
777 for triggername
in triggerPaths:
779 pathValidator.setLabel(triggername)
781 self.
paths_()[triggername].insertInto(processPSet, triggername, self.__dict__)
782 for endpathname
in endpaths:
784 endpathValidator.setLabel(endpathname)
786 self.
endpaths_()[endpathname].insertInto(processPSet, endpathname, self.__dict__)
787 processPSet.addVString(
False,
"@filters_on_endpaths", endpathValidator.filtersOnEndpaths)
790 """ Remove clutter from the process which we think is unnecessary:
791 tracked PSets, VPSets and unused modules and sequences. If a Schedule has been set, then Paths and EndPaths
792 not in the schedule will also be removed, along with an modules and sequences used only by
793 those removed Paths and EndPaths."""
794 for name
in self.
psets_():
795 if getattr(self,name).isTracked():
800 for x
in self.paths.itervalues():
801 x.resolve(self.__dict__)
802 for x
in self.endpaths.itervalues():
803 x.resolve(self.__dict__)
805 unneededPaths = set()
807 usedModules=set(self.
schedule_().moduleNames())
809 schedNames = set(( x.label_()
for x
in self.
schedule_()))
810 names = set(self.
paths)
812 unneededPaths = names - schedNames
813 for n
in unneededPaths:
816 pths =
list(self.paths.itervalues())
817 pths.extend(self.endpaths.itervalues())
819 usedModules=set(temp.moduleNames())
826 for p
in self.paths.itervalues():
828 for p
in self.endpaths.itervalues():
830 keepSeqSet = set(( s
for s
in seqs
if s.hasLabel_()))
831 availableSeqs = set(self.sequences.itervalues())
832 unneededSeqs = availableSeqs-keepSeqSet
833 unneededSeqLabels = []
834 for s
in unneededSeqs:
835 unneededSeqLabels.append(s.label_())
836 delattr(self,s.label_())
838 print "prune removed the following:"
839 print " modules:"+
",".
join(unneededModules)
840 print " sequences:"+
",".
join(unneededSeqLabels)
841 print " paths/endpaths:"+
",".
join(unneededPaths)
843 moduleNames = set(d.keys())
844 junk = moduleNames - scheduledNames
850 """Used by the framework to convert python to C++ objects"""
851 class ServiceInjectorAdaptor(
object):
855 def addService(self,pset):
856 self.__thelist.append(pset)
858 return self.__processPSet.newPSet()
860 processPSet.addString(
True,
"@process_name", self.
name_())
879 getattr(self,n).insertInto(ServiceInjectorAdaptor(processPSet,services))
880 processPSet.addVPSet(
False,
"services",services)
890 def prefer(self, esmodule,*args,**kargs):
891 """Prefer this ES source or producer. The argument can
892 either be an object label, e.g.,
893 process.prefer(process.juicerProducer) (not supported yet)
894 or a name of an ESSource or ESProducer
895 process.prefer("juicer")
896 or a type of unnamed ESSource or ESProducer
897 process.prefer("JuicerProducer")
898 In addition, you can pass as a labelled arguments the name of the Record you wish to
899 prefer where the type passed is a cms.vstring and that vstring can contain the
900 name of the C++ types in the Record which are being preferred, e.g.,
901 #prefer all data in record 'OrangeRecord' from 'juicer'
902 process.prefer("juicer", OrangeRecord=cms.vstring())
904 #prefer only "Orange" data in "OrangeRecord" from "juicer"
905 process.prefer("juicer", OrangeRecord=cms.vstring("Orange"))
907 #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer"
908 ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
911 if isinstance(esmodule, ESSource)
or isinstance(esmodule, ESProducer):
912 raise RuntimeError(
"Syntax of process.prefer(process.esmodule) not supported yet")
913 elif self._findPreferred(esmodule, self.es_producers_(),*args,**kargs)
or \
914 self._findPreferred(esmodule, self.es_sources_(),*args,**kargs):
917 raise RuntimeError(
"Cannot resolve prefer for "+repr(esmodule))
922 typ = d[esname].type_()
931 for name, value
in d.iteritems():
932 if value.type_() == esname:
934 raise RuntimeError(
"More than one ES module for "+esname)
940 """a dictionary with fixed keys"""
942 raise AttributeError,
"An FilteredStream defintion cannot be modified after creation."
943 _blocked_attribute = property(_blocked_attribute)
944 __setattr__ = __delitem__ = __setitem__ = clear = _blocked_attribute
945 pop = popitem = setdefault = update = _blocked_attribute
947 new = dict.__new__(cls)
948 dict.__init__(new, *args, **kw)
951 if keys != [
'content',
'dataTier',
'name',
'paths',
'responsible',
'selectEvents']:
952 raise ValueError(
"The needed parameters are: content, dataTier, name, paths, responsible, selectEvents")
953 if not isinstance(kw[
'name'],str):
954 raise ValueError(
"name must be of type string")
955 if not isinstance(kw[
'content'], vstring)
and not isinstance(kw[
'content'],str):
956 raise ValueError(
"content must be of type vstring or string")
957 if not isinstance(kw[
'dataTier'], string):
958 raise ValueError(
"dataTier must be of type string")
959 if not isinstance(kw[
'selectEvents'], PSet):
960 raise ValueError(
"selectEvents must be of type PSet")
961 if not isinstance(kw[
'paths'],(tuple, Path)):
962 raise ValueError(
"'paths' must be a tuple of paths")
967 return "FilteredStream object: %s" %self[
"name"]
972 """Allows embedding another process within a parent process. This allows one to
973 chain processes together directly in one cmsRun job rather than having to run
974 separate jobs which are connected via a temporary file.
976 def __init__(self,process, SelectEvents = untracked.PSet(), outputCommands = untracked.vstring()):
979 if not isinstance(process, Process):
980 raise ValueError(
"the 'process' argument must be of type cms.Process")
981 if not isinstance(SelectEvents,PSet):
982 raise ValueError(
"the 'SelectEvents' argument must be of type cms.untracked.PSet")
983 if not isinstance(outputCommands,vstring):
984 raise ValueError(
"the 'outputCommands' argument must be of type cms.untracked.vstring")
989 out =
"parentProcess"+str(
hash(self))+
" = process\n"
990 out += self.__process.dumpPython()
991 out +=
"childProcess = process\n"
992 out +=
"process = parentProcess"+str(
hash(self))+
"\n"
993 out +=
"process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = "+self.__SelectEvents.dumpPython(options) +
", outputCommands = "+self.__outputCommands.dumpPython(options) +
")\n"
998 return '@sub_process'
1000 process._placeSubProcess(
'subProcess',self)
1002 topPSet = parameterSet.newPSet()
1003 self.__process.fillProcessDesc(topPSet)
1004 subProcessPSet = parameterSet.newPSet()
1005 self.__SelectEvents.insertInto(subProcessPSet,
"SelectEvents")
1006 self.__outputCommands.insertInto(subProcessPSet,
"outputCommands")
1007 subProcessPSet.addPSet(
False,
"process",topPSet)
1011 """Helper class for Modifier which takes key/value pairs and uses them to reset parameters of the object"""
1015 for k,v
in self.__args.iteritems():
1019 """This class is used to define standard modifications to a Process.
1020 An instance of this class is declared to denote a specific modification,e.g. era2017 could
1021 reconfigure items in a process to match our expectation of running in 2017. Once declared,
1022 these Modifier instances are imported into a configuration and items which need to be modified
1023 are then associated with the Modifier and with the action to do the modification.
1024 The registered modifications will only occur if the modify() method is called.
1030 """This is used to register actions to be performed on the process as a whole.
1031 This takes as argument a callable object (e.g. function) which takes as its sole argument an instance of Process"""
1032 self.__processModifiers.append(func)
1034 """This is used to register an action to be performed on the specific object. Two different forms are allowed
1035 Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1036 which will be the object passed in as the first argument.
1037 Form 2: A list of parameter name, value pairs can be passed
1038 mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1040 if func
is not None and len(kw) != 0:
1041 raise TypeError(
"toModify takes either two arguments or one argument and key/value pairs")
1042 if func
is not None:
1043 self.__objectToModifiers.append( (obj,func))
1047 """This applies all the registered modifiers to the passed in process"""
1051 if isinstance(o,_Labelable):
1058 """Forwards to modify call. The presence of a __call__ allows Modifiers to be chained together.
1059 E.g. Have bar inherit all modifiers of foo
1062 foo.toModifyProcess(bar)
1066 if __name__==
"__main__":
1071 """Has same interface as the C++ object which creates PSets
1076 self.
values[label]=(tracked,value)
1134 """Nothing to do """
1138 self.assertEqual(len(p.parameterNames_()),0)
1140 self.assert_(
'a' in p.parameterNames_())
1141 self.assertEqual(p.a.value(), 1)
1143 self.assertEqual(p.a.value(), 10)
1145 self.assertEqual(p.a.value(), 1)
1146 self.failIf(p.a.isTracked())
1147 p.a = untracked.int32(1)
1148 self.assertEqual(p.a.value(), 1)
1149 self.failIf(p.a.isTracked())
1151 self.assertEqual(p.foo.value(), 10)
1152 self.assertEqual(p.bar.value(),1.0)
1153 self.failIf(p.bar.isTracked())
1154 self.assertRaises(TypeError,setattr,(p,
'c',1))
1156 self.assertEqual(p.a.foo.value(),10)
1157 self.assertEqual(p.a.bar.value(),1.0)
1159 self.assertEqual(p.b.fii.value(),1)
1160 self.failIf(p.b.isTracked())
1165 self.assertEqual(p.a.value(),11)
1167 self.assertEqual(p.a.value(),12)
1168 self.assertEqual(v.value(),12)
1174 self.assertNotEqual(p.b,other.b)
1179 self.assert_(
'a' in p.analyzers_() )
1180 self.assert_(
'a' in p.analyzers)
1181 p.add_(
Service(
"MessageLogger"))
1182 self.assert_(
'MessageLogger' in p.services_())
1183 self.assertEqual(p.MessageLogger.type_(),
"MessageLogger")
1185 self.assert_(
'Tracer' in p.services_())
1186 self.assertRaises(TypeError, setattr, *(p,
'b',
"this should fail"))
1187 self.assertRaises(TypeError, setattr, *(p,
'bad',
Service(
"MessageLogger")))
1188 self.assertRaises(ValueError, setattr, *(p,
'bad',
Source(
"PoolSource")))
1190 self.assertEqual(p.out.type_(),
'Outer')
1191 self.assert_(
'out' in p.outputModules_() )
1194 self.assert_(
'geom' in p.es_sources_())
1196 self.assert_(
'ConfigDB' in p.es_sources_())
1199 self.assert_(
'aliasfoo1' in p.aliases_())
1204 for name
in args.iterkeys():
1205 self.__dict__[name]=args[name]
1224 self.assertEqual(p.a.type_(),
"MyAnalyzer")
1225 self.assertEqual(p.a.label_(),
"a")
1226 self.assertRaises(AttributeError,getattr,p,
'b')
1227 self.assertEqual(p.Full.type_(),
"Full")
1228 self.assertEqual(str(p.c),
'a')
1229 self.assertEqual(str(p.d),
'a')
1244 self.assertRaises(ValueError, p1.extend, z1)
1253 aaa=copy.deepcopy(a),
1254 s4=copy.deepcopy(s3),
1261 self.assertEqual(p2.s4.label_(),
"s4")
1263 self.assertRaises(ValueError, p2.s4.setLabel,
"foo")
1264 p2.s4.setLabel(
"s4")
1265 p2.s4.setLabel(
None)
1266 p2.s4.setLabel(
"foo")
1267 p2._Process__setObjectLabel(p2.s4,
"foo")
1268 p2._Process__setObjectLabel(p2.s4,
None)
1269 p2._Process__setObjectLabel(p2.s4,
"bar")
1281 """import FWCore.ParameterSet.Config as cms
1283 process = cms.Process("test")
1285 process.a = cms.EDAnalyzer("MyAnalyzer")
1288 process.s = cms.Sequence(process.a)
1291 process.r = cms.Sequence(process.s)
1294 process.p = cms.Path(process.a)
1297 process.p2 = cms.Path(process.s)
1300 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1313 """import FWCore.ParameterSet.Config as cms
1315 process = cms.Process("test")
1317 process.a = cms.EDAnalyzer("MyAnalyzer")
1320 process.b = cms.EDAnalyzer("YourAnalyzer")
1323 process.r = cms.Sequence(process.a)
1326 process.s = cms.Sequence(process.r)
1329 process.p = cms.Path(process.a)
1332 process.p2 = cms.Path(process.r)
1335 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1347 """import FWCore.ParameterSet.Config as cms
1349 process = cms.Process("test")
1351 process.a = cms.EDAnalyzer("MyAnalyzer")
1354 process.r = cms.Sequence((process.a))
1357 process.p = cms.Path(process.a)
1360 process.p2 = cms.Path(process.r)
1363 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1369 self.assertEqual(p.dumpPython().
replace(
'\n',
''),
'import FWCore.ParameterSet.Config as cmsprocess = cms.Process("test")process.a = cms.SecSource("MySecSource")')
1377 p.p =
Path(p.c+p.s+p.a)
1379 p.globalReplace(
"a",new)
1387 self.assertEqual(str(p.s),
'a+b')
1388 self.assertEqual(p.s.label_(),
's')
1389 path =
Path(p.c+p.s)
1390 self.assertEqual(str(path),
'c+a+b')
1391 p._validateSequence(path,
'p1')
1393 p2 =
Path(p.c+p.s*notInProcess)
1394 self.assertRaises(RuntimeError, p._validateSequence, p2,
'p2')
1404 self.assertRaises(ValueError, p.__setattr__,
"y", testseq)
1414 self.assertEqual(str(path),
'a+b+c')
1415 path =
Path(p.a*p.b+p.c)
1416 self.assertEqual(str(path),
'a+b+c')
1419 path =
Path(p.a+ p.b*p.c)
1420 self.assertEqual(str(path),
'a+b+c')
1421 path =
Path(p.a*(p.b+p.c))
1422 self.assertEqual(str(path),
'a+b+c')
1423 path =
Path(p.a*(p.b+~p.c))
1424 self.assertEqual(str(path),
'a+b+~c')
1426 self.assertRaises(TypeError,Path,p.es)
1437 p.path =
Path(p.a*p.b)
1438 lookuptable = {id(a): p.a, id(b): p.b}
1442 self.assertEqual(str(path),str(p.path))
1455 self.assertEqual(s[0],p.path1)
1456 self.assertEqual(s[1],p.path2)
1458 self.assert_(
'b' in p.schedule.moduleNames())
1459 self.assert_(hasattr(p,
'b'))
1460 self.assert_(hasattr(p,
'c'))
1461 self.assert_(hasattr(p,
'd'))
1462 self.assert_(hasattr(p,
'path1'))
1463 self.assert_(hasattr(p,
'path2'))
1464 self.assert_(hasattr(p,
'path3'))
1466 self.assert_(
'b' in p.schedule.moduleNames())
1467 self.assert_(hasattr(p,
'b'))
1468 self.assert_(
not hasattr(p,
'c'))
1469 self.assert_(
not hasattr(p,
'd'))
1470 self.assert_(hasattr(p,
'path1'))
1471 self.assert_(hasattr(p,
'path2'))
1472 self.assert_(
not hasattr(p,
'path3'))
1479 self.assertRaises(RuntimeError,
lambda : p.setSchedule_(s) )
1488 self.assert_(
'a' in s.moduleNames())
1489 self.assert_(
'b' in s.moduleNames())
1490 self.assert_(
'c' in s.moduleNames())
1494 self.assert_(
'a' in s.moduleNames())
1495 self.assert_(
'b' in s.moduleNames())
1496 self.assert_(
'c' in s.moduleNames())
1505 self.assert_(p.schedule
is None)
1508 self.assertEqual(pths[keys[0]],p.path1)
1509 self.assertEqual(pths[keys[1]],p.path2)
1511 self.assert_(hasattr(p,
'a'))
1512 self.assert_(hasattr(p,
'b'))
1513 self.assert_(
not hasattr(p,
'c'))
1514 self.assert_(hasattr(p,
'path1'))
1515 self.assert_(hasattr(p,
'path2'))
1524 self.assert_(p.schedule
is None)
1527 self.assertEqual(pths[keys[1]],p.path1)
1528 self.assertEqual(pths[keys[0]],p.path2)
1535 self.assertEqual(p.modu.a.value(),1)
1536 self.assertEqual(p.modu.b.value(),2)
1541 self.assert_(
not a.isModified())
1543 self.assert_(a.isModified())
1545 self.assertEqual(p.a.a1.value(), 1)
1549 self.assertEqual(p.a.a1.value(), 2)
1558 self.assertRaises(ValueError, EDProducer,
'C', ps1, ps2)
1559 self.assertRaises(ValueError, EDProducer,
'C', ps1, a=
int32(3))
1567 p.bars.foos =
'Foosball'
1568 self.assertEqual(p.bars.foos,
InputTag(
'Foosball'))
1569 p.p =
Path(p.foos*p.bars)
1571 p.add_(
Service(
"MessageLogger"))
1577 p.prefer(
"ForceSource")
1579 self.assertEqual(p.dumpConfig(),
1581 es_module juicer = JuicerProducer {
1583 es_source = ForceSource {
1585 es_prefer = ForceSource {
1587 es_prefer juicer = JuicerProducer {
1591 p.prefer(
"juicer",fooRcd=
vstring(
"Foo"))
1592 self.assertEqual(p.dumpConfig(),
1594 es_module juicer = JuicerProducer {
1596 es_source = ForceSource {
1598 es_prefer = ForceSource {
1600 es_prefer juicer = JuicerProducer {
1608 self.assertEqual(p.dumpPython(),
1609 """import FWCore.ParameterSet.Config as cms
1611 process = cms.Process("Test")
1613 process.juicer = cms.ESProducer("JuicerProducer")
1616 process.ForceSource = cms.ESSource("ForceSource")
1619 process.prefer("ForceSource")
1621 process.prefer("juicer",
1622 fooRcd = cms.vstring('Foo')
1639 self.assertEqual(process.m.p.i.value(), 4)
1649 subProcess.p =
Path(subProcess.a)
1650 subProcess.add_(
Service(
"Foo"))
1652 d = process.dumpPython()
1653 equalD =
"""import FWCore.ParameterSet.Config as cms
1655 process = cms.Process("Parent")
1657 parentProcess = process
1658 import FWCore.ParameterSet.Config as cms
1660 process = cms.Process("Child")
1662 process.a = cms.EDProducer("A")
1665 process.p = cms.Path(process.a)
1668 process.Foo = cms.Service("Foo")
1671 childProcess = process
1672 process = parentProcess
1673 process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = cms.untracked.PSet(
1675 ), outputCommands = cms.untracked.vstring())
1677 equalD = equalD.replace(
"parentProcess",
"parentProcess"+str(
hash(process.subProcess)))
1678 self.assertEqual(d,equalD)
1680 process.subProcess.insertInto(p,
"dummy")
1681 self.assertEqual((
True,[
'a']),p.values[
"@sub_process"][1].values[
"process"][1].values[
'@all_modules'])
1682 self.assertEqual((
True,[
'p']),p.values[
"@sub_process"][1].values[
"process"][1].values[
'@paths'])
1683 self.assertEqual({
'@service_type':(
True,
'Foo')}, p.values[
"@sub_process"][1].values[
"process"][1].values[
"services"][1][0].values)
1693 self.assert_(p.schedule
is None)
1696 self.assertEqual(pths[keys[0]],p.path1)
1697 self.assertEqual(pths[keys[1]],p.path2)
1699 p.pset2 = untracked.PSet(parA =
string(
"pset2"))
1701 p.vpset2 = untracked.VPSet()
1703 self.assert_(hasattr(p,
'a'))
1704 self.assert_(hasattr(p,
'b'))
1705 self.assert_(
not hasattr(p,
'c'))
1706 self.assert_(
not hasattr(p,
'd'))
1707 self.assert_(
not hasattr(p,
's'))
1708 self.assert_(hasattr(p,
'path1'))
1709 self.assert_(hasattr(p,
'path2'))
1710 self.assert_(
not hasattr(p,
'pset1'))
1711 self.assert_(hasattr(p,
'pset2'))
1712 self.assert_(
not hasattr(p,
'vpset1'))
1713 self.assert_(
not hasattr(p,
'vpset2'))
1726 p.path3 =
Path(p.b+p.s2)
1727 p.path4 =
Path(p.b+p.s3)
1728 p.schedule =
Schedule(p.path1,p.path2,p.path3)
1731 self.assertEqual(pths[keys[0]],p.path1)
1732 self.assertEqual(pths[keys[1]],p.path2)
1734 self.assert_(hasattr(p,
'a'))
1735 self.assert_(hasattr(p,
'b'))
1736 self.assert_(
not hasattr(p,
'c'))
1737 self.assert_(
not hasattr(p,
'd'))
1738 self.assert_(
not hasattr(p,
'e'))
1739 self.assert_(
not hasattr(p,
's'))
1740 self.assert_(hasattr(p,
's2'))
1741 self.assert_(
not hasattr(p,
's3'))
1742 self.assert_(hasattr(p,
'path1'))
1743 self.assert_(hasattr(p,
'path2'))
1744 self.assert_(hasattr(p,
'path3'))
1745 self.assert_(
not hasattr(p,
'path4'))
1753 self.assert_(hasattr(p,
'a'))
1754 self.assert_(hasattr(p,
'b'))
1755 self.assert_(hasattr(p,
's'))
1756 self.assert_(hasattr(p,
'pth'))
1763 m1.toModify(p.a,_mod_fred)
1765 m1.toModify(p.b, wilma = 2)
1766 self.assertEqual(p.a.fred.value(),1)
1767 self.assertEqual(p.b.wilma.value(),1)
1769 self.assertEqual(p.a.fred.value(),2)
1770 self.assertEqual(p.b.wilma.value(),2)
1775 m1.toModify(p.a,_mod_fred)
1777 m1.toModify(b, wilma = 2)
1778 self.assertEqual(p.a.fred.value(),1)
1779 self.assertEqual(b.wilma.value(),1)
1781 self.assertEqual(p.a.fred.value(),2)
1782 self.assertEqual(b.wilma.value(),1)
1786 m2.toModifyProcess(m1)
1789 m1.toModify(p.a,_mod_fred)
1791 m1.toModify(p.b, wilma = 2)
1792 m2.toModify(p.b, wilma = 3)
1794 self.assertEqual(p.a.fred.value(),2)
1795 self.assertEqual(p.b.wilma.value(),3)
def _dumpConfigUnnamedList
def testProcessDumpPython
def _dumpConfigOptionallyNamedList
def visit
Retrieve data from a perf suite output (sub) directory, only examines TimeSize at the moment...
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
def _sequencesInDependencyOrder
def __findFirstSequenceUsingModule
static std::string join(char **cmd)
def checkImportPermission
def testTypedParameterizable
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run