CMS 3D CMS Logo

Config.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 ### command line options helper
4 from __future__ import print_function
5 from __future__ import absolute_import
6 import six
7 from .Options import Options
8 options = Options()
9 
10 
11 ## imports
12 import sys
13 from .Mixins import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable, _Unlabelable, _ValidatingListBase, _modifyParametersFromDict
14 from .Mixins import *
15 from .Types import *
16 from .Modules import *
17 from .Modules import _Module
18 from .SequenceTypes import *
19 from .SequenceTypes import _ModuleSequenceType, _Sequenceable #extend needs it
20 from .SequenceVisitors import PathValidator, EndPathValidator, ScheduleTaskValidator, NodeVisitor, CompositeVisitor, ModuleNamesFromGlobalsVisitor
21 from . import DictTypes
22 
23 from .ExceptionHandling import *
24 
25 #when building RECO paths we have hit the default recursion limit
26 if sys.getrecursionlimit()<5000:
27  sys.setrecursionlimit(5000)
28 
29 def checkImportPermission(minLevel = 2, allowedPatterns = []):
30  """
31  Raise an exception if called by special config files. This checks
32  the call or import stack for the importing file. An exception is raised if
33  the importing module is not in allowedPatterns and if it is called too deeply:
34  minLevel = 2: inclusion by top lvel cfg only
35  minLevel = 1: No inclusion allowed
36  allowedPatterns = ['Module1','Module2/SubModule1'] allows import
37  by any module in Module1 or Submodule1
38  """
39 
40  import inspect
41  import os
42 
43  ignorePatterns = ['FWCore/ParameterSet/Config.py','<string>','<frozen ']
44  CMSSWPath = [os.environ['CMSSW_BASE'],os.environ['CMSSW_RELEASE_BASE']]
45 
46  # Filter the stack to things in CMSSWPath and not in ignorePatterns
47  trueStack = []
48  for item in inspect.stack():
49  inPath = False
50  ignore = False
51 
52  for pattern in CMSSWPath:
53  if item[1].find(pattern) != -1:
54  inPath = True
55  break
56  if item[1].find('/') == -1: # The base file, no path
57  inPath = True
58 
59  for pattern in ignorePatterns:
60  if item[1].find(pattern) != -1:
61  ignore = True
62  break
63 
64  if inPath and not ignore:
65  trueStack.append(item[1])
66 
67  importedFile = trueStack[0]
68  importedBy = ''
69  if len(trueStack) > 1:
70  importedBy = trueStack[1]
71 
72  for pattern in allowedPatterns:
73  if importedBy.find(pattern) > -1:
74  return True
75 
76  if len(trueStack) <= minLevel: # Imported directly
77  return True
78 
79  raise ImportError("Inclusion of %s is allowed only by cfg or specified cfi files."
80  % importedFile)
81 
82 def findProcess(module):
83  """Look inside the module and find the Processes it contains"""
84  class Temp(object):
85  pass
86  process = None
87  if isinstance(module,dict):
88  if 'process' in module:
89  p = module['process']
90  module = Temp()
91  module.process = p
92  if hasattr(module,'process'):
93  if isinstance(module.process,Process):
94  process = module.process
95  else:
96  raise RuntimeError("The attribute named 'process' does not inherit from the Process class")
97  else:
98  raise RuntimeError("no 'process' attribute found in the module, please add one")
99  return process
100 
102  """Root class for a CMS configuration process"""
103  def __init__(self,name,*Mods):
104  """The argument 'name' will be the name applied to this Process
105  Can optionally pass as additional arguments cms.Modifier instances
106  that will be used to modify the Process as it is built
107  """
108  self.__dict__['_Process__name'] = name
109  if not name.isalnum():
110  raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters")
111  self.__dict__['_Process__filters'] = {}
112  self.__dict__['_Process__producers'] = {}
113  self.__dict__['_Process__switchproducers'] = {}
114  self.__dict__['_Process__source'] = None
115  self.__dict__['_Process__looper'] = None
116  self.__dict__['_Process__subProcesses'] = []
117  self.__dict__['_Process__schedule'] = None
118  self.__dict__['_Process__analyzers'] = {}
119  self.__dict__['_Process__outputmodules'] = {}
120  self.__dict__['_Process__paths'] = DictTypes.SortedKeysDict() # have to keep the order
121  self.__dict__['_Process__endpaths'] = DictTypes.SortedKeysDict() # of definition
122  self.__dict__['_Process__sequences'] = {}
123  self.__dict__['_Process__tasks'] = {}
124  self.__dict__['_Process__services'] = {}
125  self.__dict__['_Process__essources'] = {}
126  self.__dict__['_Process__esproducers'] = {}
127  self.__dict__['_Process__esprefers'] = {}
128  self.__dict__['_Process__aliases'] = {}
129  self.__dict__['_Process__psets']={}
130  self.__dict__['_Process__vpsets']={}
131  self.__dict__['_cloneToObjectDict'] = {}
132  # policy switch to avoid object overwriting during extend/load
133  self.__dict__['_Process__InExtendCall'] = False
134  self.__dict__['_Process__partialschedules'] = {}
135  self.__isStrict = False
136  self.__dict__['_Process__modifiers'] = Mods
137  for m in self.__modifiers:
138  m._setChosen()
139 
140  def setStrict(self, value):
141  self.__isStrict = value
142  _Module.__isStrict__ = True
143 
144  # some user-friendly methods for command-line browsing
145  def producerNames(self):
146  """Returns a string containing all the EDProducer labels separated by a blank"""
147  return ' '.join(self.producers_().keys())
149  """Returns a string containing all the SwitchProducer labels separated by a blank"""
150  return ' '.join(self.switchProducers_().keys())
151  def analyzerNames(self):
152  """Returns a string containing all the EDAnalyzer labels separated by a blank"""
153  return ' '.join(self.analyzers_().keys())
154  def filterNames(self):
155  """Returns a string containing all the EDFilter labels separated by a blank"""
156  return ' '.join(self.filters_().keys())
157  def pathNames(self):
158  """Returns a string containing all the Path names separated by a blank"""
159  return ' '.join(self.paths_().keys())
160 
161  def __setstate__(self, pkldict):
162  """
163  Unpickling hook.
164 
165  Since cloneToObjectDict stores a hash of objects by their
166  id() it needs to be updated when unpickling to use the
167  new object id values instantiated during the unpickle.
168 
169  """
170  self.__dict__.update(pkldict)
171  tmpDict = {}
172  for value in self._cloneToObjectDict.values():
173  tmpDict[id(value)] = value
174  self.__dict__['_cloneToObjectDict'] = tmpDict
175 
176 
177 
178  def filters_(self):
179  """returns a dict of the filters that have been added to the Process"""
180  return DictTypes.FixedKeysDict(self.__filters)
181  filters = property(filters_, doc="dictionary containing the filters for the process")
182  def name_(self):
183  return self.__name
184  def setName_(self,name):
185  if not name.isalnum():
186  raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters")
187  self.__dict__['_Process__name'] = name
188  process = property(name_,setName_, doc="name of the process")
189  def producers_(self):
190  """returns a dict of the producers that have been added to the Process"""
191  return DictTypes.FixedKeysDict(self.__producers)
192  producers = property(producers_,doc="dictionary containing the producers for the process")
193  def switchProducers_(self):
194  """returns a dict of the SwitchProducers that have been added to the Process"""
195  return DictTypes.FixedKeysDict(self.__switchproducers)
196  switchProducers = property(switchProducers_,doc="dictionary containing the SwitchProducers for the process")
197  def source_(self):
198  """returns the source that has been added to the Process or None if none have been added"""
199  return self.__source
200  def setSource_(self,src):
201  self._placeSource('source',src)
202  source = property(source_,setSource_,doc='the main source or None if not set')
203  def looper_(self):
204  """returns the looper that has been added to the Process or None if none have been added"""
205  return self.__looper
206  def setLooper_(self,lpr):
207  self._placeLooper('looper',lpr)
208  looper = property(looper_,setLooper_,doc='the main looper or None if not set')
209  def subProcesses_(self):
210  """returns a list of the subProcesses that have been added to the Process"""
211  return self.__subProcesses
212  subProcesses = property(subProcesses_,doc='the SubProcesses that have been added to the Process')
213  def analyzers_(self):
214  """returns a dict of the analyzers that have been added to the Process"""
215  return DictTypes.FixedKeysDict(self.__analyzers)
216  analyzers = property(analyzers_,doc="dictionary containing the analyzers for the process")
217  def outputModules_(self):
218  """returns a dict of the output modules that have been added to the Process"""
219  return DictTypes.FixedKeysDict(self.__outputmodules)
220  outputModules = property(outputModules_,doc="dictionary containing the output_modules for the process")
221  def paths_(self):
222  """returns a dict of the paths that have been added to the Process"""
223  return DictTypes.SortedAndFixedKeysDict(self.__paths)
224  paths = property(paths_,doc="dictionary containing the paths for the process")
225  def endpaths_(self):
226  """returns a dict of the endpaths that have been added to the Process"""
227  return DictTypes.SortedAndFixedKeysDict(self.__endpaths)
228  endpaths = property(endpaths_,doc="dictionary containing the endpaths for the process")
229  def sequences_(self):
230  """returns a dict of the sequences that have been added to the Process"""
231  return DictTypes.FixedKeysDict(self.__sequences)
232  sequences = property(sequences_,doc="dictionary containing the sequences for the process")
233  def tasks_(self):
234  """returns a dict of the tasks that have been added to the Process"""
235  return DictTypes.FixedKeysDict(self.__tasks)
236  tasks = property(tasks_,doc="dictionary containing the tasks for the process")
237  def schedule_(self):
238  """returns the schedule that has been added to the Process or None if none have been added"""
239  return self.__schedule
240  def setPartialSchedule_(self,sch,label):
241  if label == "schedule":
242  self.setSchedule_(sch)
243  else:
244  self._place(label, sch, self.__partialschedules)
245  def setSchedule_(self,sch):
246  # See if every path and endpath has been inserted into the process
247  index = 0
248  try:
249  for p in sch:
250  p.label_()
251  index +=1
252  except:
253  raise RuntimeError("The path at index "+str(index)+" in the Schedule was not attached to the process.")
254  self.__dict__['_Process__schedule'] = sch
255  schedule = property(schedule_,setSchedule_,doc='the schedule or None if not set')
256  def services_(self):
257  """returns a dict of the services that have been added to the Process"""
258  return DictTypes.FixedKeysDict(self.__services)
259  services = property(services_,doc="dictionary containing the services for the process")
260  def es_producers_(self):
261  """returns a dict of the esproducers that have been added to the Process"""
262  return DictTypes.FixedKeysDict(self.__esproducers)
263  es_producers = property(es_producers_,doc="dictionary containing the es_producers for the process")
264  def es_sources_(self):
265  """returns a the es_sources that have been added to the Process"""
266  return DictTypes.FixedKeysDict(self.__essources)
267  es_sources = property(es_sources_,doc="dictionary containing the es_sources for the process")
268  def es_prefers_(self):
269  """returns a dict of the es_prefers that have been added to the Process"""
270  return DictTypes.FixedKeysDict(self.__esprefers)
271  es_prefers = property(es_prefers_,doc="dictionary containing the es_prefers for the process")
272  def aliases_(self):
273  """returns a dict of the aliases that have been added to the Process"""
274  return DictTypes.FixedKeysDict(self.__aliases)
275  aliases = property(aliases_,doc="dictionary containing the aliases for the process")
276  def psets_(self):
277  """returns a dict of the PSets that have been added to the Process"""
278  return DictTypes.FixedKeysDict(self.__psets)
279  psets = property(psets_,doc="dictionary containing the PSets for the process")
280  def vpsets_(self):
281  """returns a dict of the VPSets that have been added to the Process"""
282  return DictTypes.FixedKeysDict(self.__vpsets)
283  vpsets = property(vpsets_,doc="dictionary containing the PSets for the process")
284 
285  def isUsingModifier(self,mod):
286  """returns True if the Modifier is in used by this Process"""
287  if mod._isChosen():
288  for m in self.__modifiers:
289  if m._isOrContains(mod):
290  return True
291  return False
292 
293  def __setObjectLabel(self, object, newLabel) :
294  if not object.hasLabel_() :
295  object.setLabel(newLabel)
296  return
297  if newLabel == object.label_() :
298  return
299  if newLabel is None :
300  object.setLabel(None)
301  return
302  if (hasattr(self, object.label_()) and id(getattr(self, object.label_())) == id(object)) :
303  msg100 = "Attempting to change the label of an attribute of the Process\n"
304  msg101 = "Old label = "+object.label_()+" New label = "+newLabel+"\n"
305  msg102 = "Type = "+str(type(object))+"\n"
306  msg103 = "Some possible solutions:\n"
307  msg104 = " 1. Clone modules instead of using simple assignment. Cloning is\n"
308  msg105 = " also preferred for other types when possible.\n"
309  msg106 = " 2. Declare new names starting with an underscore if they are\n"
310  msg107 = " for temporaries you do not want propagated into the Process. The\n"
311  msg108 = " underscore tells \"from x import *\" and process.load not to import\n"
312  msg109 = " the name.\n"
313  msg110 = " 3. Reorganize so the assigment is not necessary. Giving a second\n"
314  msg111 = " name to the same object usually causes confusion and problems.\n"
315  msg112 = " 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
316  raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
317  object.setLabel(None)
318  object.setLabel(newLabel)
319 
320  def __setattr__(self,name,value):
321  # check if the name is well-formed (only _ and alphanumerics are allowed)
322  if not name.replace('_','').isalnum():
323  raise ValueError('The label '+name+' contains forbiden characters')
324 
325  # private variable exempt from all this
326  if name.startswith('_Process__'):
327  self.__dict__[name]=value
328  return
329  if not isinstance(value,_ConfigureComponent):
330  raise TypeError("can only assign labels to an object that inherits from '_ConfigureComponent'\n"
331  +"an instance of "+str(type(value))+" will not work - requested label is "+name)
332  if not isinstance(value,_Labelable) and not isinstance(value,Source) and not isinstance(value,Looper) and not isinstance(value,Schedule):
333  if name == value.type_():
334  # Only Services get handled here
335  self.add_(value)
336  return
337  else:
338  raise TypeError("an instance of "+str(type(value))+" can not be assigned the label '"+name+"'.\n"+
339  "Please either use the label '"+value.type_()+" or use the 'add_' method instead.")
340  #clone the item
341  if self.__isStrict:
342  newValue =value.copy()
343  try:
344  newValue._filename = value._filename
345  except:
346  pass
347  value.setIsFrozen()
348  else:
349  newValue =value
350  if not self._okToPlace(name, value, self.__dict__):
351  newFile='top level config'
352  if hasattr(value,'_filename'):
353  newFile = value._filename
354  oldFile='top level config'
355  oldValue = getattr(self,name)
356  if hasattr(oldValue,'_filename'):
357  oldFile = oldValue._filename
358  msg = "Trying to override definition of process."+name
359  msg += "\n new object defined in: "+newFile
360  msg += "\n existing object defined in: "+oldFile
361  raise ValueError(msg)
362  # remove the old object of the name (if there is one)
363  if hasattr(self,name) and not (getattr(self,name)==newValue):
364  # Complain if items in sequences or tasks from load() statements have
365  # degenerate names, but if the user overwrites a name in the
366  # main config, replace it everywhere
367  if newValue._isTaskComponent():
368  if not self.__InExtendCall:
369  self._replaceInTasks(name, newValue)
370  self._replaceInSchedule(name, newValue)
371  else:
372  if not isinstance(newValue, Task):
373  #should check to see if used in task before complaining
374  newFile='top level config'
375  if hasattr(value,'_filename'):
376  newFile = value._filename
377  oldFile='top level config'
378  oldValue = getattr(self,name)
379  if hasattr(oldValue,'_filename'):
380  oldFile = oldValue._filename
381  msg1 = "Trying to override definition of "+name+" while it is used by the task "
382  msg2 = "\n new object defined in: "+newFile
383  msg2 += "\n existing object defined in: "+oldFile
384  s = self.__findFirstUsingModule(self.tasks,oldValue)
385  if s is not None:
386  raise ValueError(msg1+s.label_()+msg2)
387 
388  if isinstance(newValue, _Sequenceable) or newValue._isTaskComponent():
389  if not self.__InExtendCall:
390  self._replaceInSequences(name, newValue)
391  else:
392  #should check to see if used in sequence before complaining
393  newFile='top level config'
394  if hasattr(value,'_filename'):
395  newFile = value._filename
396  oldFile='top level config'
397  oldValue = getattr(self,name)
398  if hasattr(oldValue,'_filename'):
399  oldFile = oldValue._filename
400  msg1 = "Trying to override definition of "+name+" while it is used by the "
401  msg2 = "\n new object defined in: "+newFile
402  msg2 += "\n existing object defined in: "+oldFile
403  s = self.__findFirstUsingModule(self.sequences,oldValue)
404  if s is not None:
405  raise ValueError(msg1+"sequence "+s.label_()+msg2)
406  s = self.__findFirstUsingModule(self.paths,oldValue)
407  if s is not None:
408  raise ValueError(msg1+"path "+s.label_()+msg2)
409  s = self.__findFirstUsingModule(self.endpaths,oldValue)
410  if s is not None:
411  raise ValueError(msg1+"endpath "+s.label_()+msg2)
412  self._delattrFromSetattr(name)
413  self.__dict__[name]=newValue
414  if isinstance(newValue,_Labelable):
415  self.__setObjectLabel(newValue, name)
416  self._cloneToObjectDict[id(value)] = newValue
417  self._cloneToObjectDict[id(newValue)] = newValue
418  #now put in proper bucket
419  newValue._place(name,self)
420  def __findFirstUsingModule(self, seqsOrTasks, mod):
421  """Given a container of sequences or tasks, find the first sequence or task
422  containing mod and return it. If none is found, return None"""
423  from FWCore.ParameterSet.SequenceTypes import ModuleNodeVisitor
424  l = list()
425  for seqOrTask in six.itervalues(seqsOrTasks):
426  l[:] = []
427  v = ModuleNodeVisitor(l)
428  seqOrTask.visit(v)
429  if mod in l:
430  return seqOrTask
431  return None
432 
433  def _delHelper(self,name):
434  if not hasattr(self,name):
435  raise KeyError('process does not know about '+name)
436  elif name.startswith('_Process__'):
437  raise ValueError('this attribute cannot be deleted')
438 
439  # we have to remove it from all dictionaries/registries
440  dicts = [item for item in self.__dict__.values() if (isinstance(item, dict) or isinstance(item, DictTypes.SortedKeysDict))]
441  for reg in dicts:
442  if name in reg: del reg[name]
443  # if it was a labelable object, the label needs to be removed
444  obj = getattr(self,name)
445  if isinstance(obj,_Labelable):
446  obj.setLabel(None)
447  if isinstance(obj,Service):
448  obj._inProcess = False
449 
450  def __delattr__(self,name):
451  self._delHelper(name)
452  obj = getattr(self,name)
453  if not obj is None:
454  if not isinstance(obj, Sequence) and not isinstance(obj, Task):
455  # For modules, ES modules and services we can also remove
456  # the deleted object from Sequences, Paths, EndPaths, and
457  # Tasks. Note that for Sequences and Tasks that cannot be done
458  # reliably as the places where the Sequence or Task was used
459  # might have been expanded so we do not even try. We considered
460  # raising an exception if a Sequences or Task was explicitly
461  # deleted, but did not because when done carefully deletion
462  # is sometimes OK (for example in the prune function where it
463  # has been checked that the deleted Sequence is not used).
464  if obj._isTaskComponent():
465  self._replaceInTasks(name, None)
466  self._replaceInSchedule(name, None)
467  if isinstance(obj, _Sequenceable) or obj._isTaskComponent():
468  self._replaceInSequences(name, None)
469  # now remove it from the process itself
470  try:
471  del self.__dict__[name]
472  except:
473  pass
474 
475  def _delattrFromSetattr(self,name):
476  """Similar to __delattr__ but we need different behavior when called from __setattr__"""
477  self._delHelper(name)
478  # now remove it from the process itself
479  try:
480  del self.__dict__[name]
481  except:
482  pass
483 
484  def add_(self,value):
485  """Allows addition of components that do not have to have a label, e.g. Services"""
486  if not isinstance(value,_ConfigureComponent):
487  raise TypeError
488  if not isinstance(value,_Unlabelable):
489  raise TypeError
490  #clone the item
491  #clone the item
492  if self.__isStrict:
493  newValue =value.copy()
494  value.setIsFrozen()
495  else:
496  newValue =value
497  newValue._place('',self)
498 
499  def _okToPlace(self, name, mod, d):
500  if not self.__InExtendCall:
501  # if going
502  return True
503  elif not self.__isStrict:
504  return True
505  elif name in d:
506  # if there's an old copy, and the new one
507  # hasn't been modified, we're done. Still
508  # not quite safe if something has been defined twice.
509  # Need to add checks
510  if mod._isModified:
511  if d[name]._isModified:
512  return False
513  else:
514  return True
515  else:
516  return True
517  else:
518  return True
519 
520  def _place(self, name, mod, d):
521  if self._okToPlace(name, mod, d):
522  if self.__isStrict and isinstance(mod, _ModuleSequenceType):
523  d[name] = mod._postProcessFixup(self._cloneToObjectDict)
524  else:
525  d[name] = mod
526  if isinstance(mod,_Labelable):
527  self.__setObjectLabel(mod, name)
528  def _placeOutputModule(self,name,mod):
529  self._place(name, mod, self.__outputmodules)
530  def _placeProducer(self,name,mod):
531  self._place(name, mod, self.__producers)
532  def _placeSwitchProducer(self,name,mod):
533  self._place(name, mod, self.__switchproducers)
534  def _placeFilter(self,name,mod):
535  self._place(name, mod, self.__filters)
536  def _placeAnalyzer(self,name,mod):
537  self._place(name, mod, self.__analyzers)
538  def _placePath(self,name,mod):
539  self._validateSequence(mod, name)
540  try:
541  self._place(name, mod, self.__paths)
542  except ModuleCloneError as msg:
543  context = format_outerframe(4)
544  raise Exception("%sThe module %s in path %s is unknown to the process %s." %(context, msg, name, self._Process__name))
545  def _placeEndPath(self,name,mod):
546  self._validateSequence(mod, name)
547  try:
548  self._place(name, mod, self.__endpaths)
549  except ModuleCloneError as msg:
550  context = format_outerframe(4)
551  raise Exception("%sThe module %s in endpath %s is unknown to the process %s." %(context, msg, name, self._Process__name))
552  def _placeSequence(self,name,mod):
553  self._validateSequence(mod, name)
554  self._place(name, mod, self.__sequences)
555  def _placeESProducer(self,name,mod):
556  self._place(name, mod, self.__esproducers)
557  def _placeESPrefer(self,name,mod):
558  self._place(name, mod, self.__esprefers)
559  def _placeESSource(self,name,mod):
560  self._place(name, mod, self.__essources)
561  def _placeTask(self,name,task):
562  self._validateTask(task, name)
563  self._place(name, task, self.__tasks)
564  def _placeAlias(self,name,mod):
565  self._place(name, mod, self.__aliases)
566  def _placePSet(self,name,mod):
567  self._place(name, mod, self.__psets)
568  def _placeVPSet(self,name,mod):
569  self._place(name, mod, self.__vpsets)
570  def _placeSource(self,name,mod):
571  """Allow the source to be referenced by 'source' or by type name"""
572  if name != 'source':
573  raise ValueError("The label '"+name+"' can not be used for a Source. Only 'source' is allowed.")
574  if self.__dict__['_Process__source'] is not None :
575  del self.__dict__[self.__dict__['_Process__source'].type_()]
576  self.__dict__['_Process__source'] = mod
577  self.__dict__[mod.type_()] = mod
578  def _placeLooper(self,name,mod):
579  if name != 'looper':
580  raise ValueError("The label '"+name+"' can not be used for a Looper. Only 'looper' is allowed.")
581  self.__dict__['_Process__looper'] = mod
582  self.__dict__[mod.type_()] = mod
583  def _placeSubProcess(self,name,mod):
584  self.__dict__['_Process__subProcess'] = mod
585  self.__dict__[mod.type_()] = mod
586  def addSubProcess(self,mod):
587  self.__subProcesses.append(mod)
588  def _placeService(self,typeName,mod):
589  self._place(typeName, mod, self.__services)
590  if typeName in self.__dict__:
591  self.__dict__[typeName]._inProcess = False
592  self.__dict__[typeName]=mod
593  def load(self, moduleName):
594  moduleName = moduleName.replace("/",".")
595  module = __import__(moduleName)
596  self.extend(sys.modules[moduleName])
597  def extend(self,other,items=()):
598  """Look in other and find types that we can use"""
599  # enable explicit check to avoid overwriting of existing objects
600  self.__dict__['_Process__InExtendCall'] = True
601 
602  seqs = dict()
603  tasksToAttach = dict()
604  mods = []
605  for name in dir(other):
606  #'from XX import *' ignores these, and so should we.
607  if name.startswith('_'):
608  continue
609  item = getattr(other,name)
610  if name == "source" or name == "looper":
611  # In these cases 'item' could be None if the specific object was not defined
612  if item is not None:
613  self.__setattr__(name,item)
614  elif isinstance(item,_ModuleSequenceType):
615  seqs[name]=item
616  elif isinstance(item,Task):
617  tasksToAttach[name] = item
618  elif isinstance(item,_Labelable):
619  self.__setattr__(name,item)
620  if not item.hasLabel_() :
621  item.setLabel(name)
622  elif isinstance(item,Schedule):
623  self.__setattr__(name,item)
624  elif isinstance(item,_Unlabelable):
625  self.add_(item)
626  elif isinstance(item,ProcessModifier):
627  mods.append(item)
628  elif isinstance(item,ProcessFragment):
629  self.extend(item)
630 
631  #now create a sequence that uses the newly made items
632  for name,seq in six.iteritems(seqs):
633  if id(seq) not in self._cloneToObjectDict:
634  self.__setattr__(name,seq)
635  else:
636  newSeq = self._cloneToObjectDict[id(seq)]
637  self.__dict__[name]=newSeq
638  self.__setObjectLabel(newSeq, name)
639  #now put in proper bucket
640  newSeq._place(name,self)
641 
642  for name, task in six.iteritems(tasksToAttach):
643  self.__setattr__(name, task)
644 
645  #apply modifiers now that all names have been added
646  for item in mods:
647  item.apply(self)
648 
649  self.__dict__['_Process__InExtendCall'] = False
650 
651  def _dumpConfigNamedList(self,items,typeName,options):
652  returnValue = ''
653  for name,item in items:
654  returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
655  return returnValue
656  def _dumpConfigUnnamedList(self,items,typeName,options):
657  returnValue = ''
658  for name,item in items:
659  returnValue +=options.indentation()+typeName+' = '+item.dumpConfig(options)
660  return returnValue
661  def _dumpConfigOptionallyNamedList(self,items,typeName,options):
662  returnValue = ''
663  for name,item in items:
664  if name == item.type_():
665  name = ''
666  returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
667  return returnValue
668  def dumpConfig(self, options=PrintOptions()):
669  """return a string containing the equivalent process defined using the old configuration language"""
670  config = "process "+self.__name+" = {\n"
671  options.indent()
672  if self.source_():
673  config += options.indentation()+"source = "+self.source_().dumpConfig(options)
674  if self.looper_():
675  config += options.indentation()+"looper = "+self.looper_().dumpConfig(options)
676 
677  config+=self._dumpConfigNamedList(self.subProcesses_(),
678  'subProcess',
679  options)
680  config+=self._dumpConfigNamedList(six.iteritems(self.producers_()),
681  'module',
682  options)
683  config+=self._dumpConfigNamedList(six.iteritems(self.switchProducers_()),
684  'module',
685  options)
686  config+=self._dumpConfigNamedList(six.iteritems(self.filters_()),
687  'module',
688  options)
689  config+=self._dumpConfigNamedList(six.iteritems(self.analyzers_()),
690  'module',
691  options)
692  config+=self._dumpConfigNamedList(six.iteritems(self.outputModules_()),
693  'module',
694  options)
695  config+=self._dumpConfigNamedList(six.iteritems(self.sequences_()),
696  'sequence',
697  options)
698  config+=self._dumpConfigNamedList(six.iteritems(self.paths_()),
699  'path',
700  options)
701  config+=self._dumpConfigNamedList(six.iteritems(self.endpaths_()),
702  'endpath',
703  options)
704  config+=self._dumpConfigUnnamedList(six.iteritems(self.services_()),
705  'service',
706  options)
707  config+=self._dumpConfigNamedList(six.iteritems(self.aliases_()),
708  'alias',
709  options)
710  config+=self._dumpConfigOptionallyNamedList(
711  six.iteritems(self.es_producers_()),
712  'es_module',
713  options)
714  config+=self._dumpConfigOptionallyNamedList(
715  six.iteritems(self.es_sources_()),
716  'es_source',
717  options)
718  config += self._dumpConfigESPrefers(options)
719  for name,item in six.iteritems(self.psets):
720  config +=options.indentation()+item.configTypeName()+' '+name+' = '+item.configValue(options)
721  for name,item in six.iteritems(self.vpsets):
722  config +=options.indentation()+'VPSet '+name+' = '+item.configValue(options)
723  if self.schedule:
724  pathNames = [p.label_() for p in self.schedule]
725  config +=options.indentation()+'schedule = {'+','.join(pathNames)+'}\n'
726 
727 # config+=self._dumpConfigNamedList(six.iteritems(self.vpsets),
728 # 'VPSet',
729 # options)
730  config += "}\n"
731  options.unindent()
732  return config
733  def _dumpConfigESPrefers(self, options):
734  result = ''
735  for item in six.itervalues(self.es_prefers_()):
736  result +=options.indentation()+'es_prefer '+item.targetLabel_()+' = '+item.dumpConfig(options)
737  return result
738  def _dumpPythonSubProcesses(self, l, options):
739  returnValue = ''
740  for item in l:
741  returnValue += item.dumpPython(options)+'\n\n'
742  return returnValue
743  def _dumpPythonList(self, d, options):
744  returnValue = ''
745  if isinstance(d, DictTypes.SortedKeysDict):
746  for name,item in d.items():
747  returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
748  else:
749  for name,item in sorted(d.items()):
750  returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
751  return returnValue
752  def _validateSequence(self, sequence, label):
753  # See if every module has been inserted into the process
754  try:
755  l = set()
756  visitor = NodeNameVisitor(l)
757  sequence.visit(visitor)
758  except:
759  raise RuntimeError("An entry in sequence "+label + ' has no label')
760  def _validateTask(self, task, label):
761  # See if every module and service has been inserted into the process
762  try:
763  l = set()
764  visitor = NodeNameVisitor(l)
765  task.visit(visitor)
766  except:
767  raise RuntimeError("An entry in task " + label + ' has not been attached to the process')
768  def _itemsInDependencyOrder(self, processDictionaryOfItems):
769  # The items can be Sequences or Tasks and the input
770  # argument should either be the dictionary of sequences
771  # or the dictionary of tasks from the process.
772 
773  returnValue=DictTypes.SortedKeysDict()
774 
775  # For each item, see what other items it depends upon
776  # For our purpose here, an item depends on the items it contains.
777  dependencies = {}
778  for label,item in six.iteritems(processDictionaryOfItems):
779  containedItems = []
780  if isinstance(item, Task):
781  v = TaskVisitor(containedItems)
782  else:
783  v = SequenceVisitor(containedItems)
784  try:
785  item.visit(v)
786  except RuntimeError:
787  if isinstance(item, Task):
788  raise RuntimeError("Failed in a Task visitor. Probably " \
789  "a circular dependency discovered in Task with label " + label)
790  else:
791  raise RuntimeError("Failed in a Sequence visitor. Probably a " \
792  "circular dependency discovered in Sequence with label " + label)
793  for containedItem in containedItems:
794  # Check for items that both have labels and are not in the process.
795  # This should not normally occur unless someone explicitly assigns a
796  # label without putting the item in the process (which should not ever
797  # be done). We check here because this problem could cause the code
798  # in the 'while' loop below to go into an infinite loop.
799  if containedItem.hasLabel_():
800  testItem = processDictionaryOfItems.get(containedItem.label_())
801  if testItem is None or containedItem != testItem:
802  if isinstance(item, Task):
803  raise RuntimeError("Task has a label, but using its label to get an attribute" \
804  " from the process yields a different object or None\n"+
805  "label = " + containedItem.label_())
806  else:
807  raise RuntimeError("Sequence has a label, but using its label to get an attribute" \
808  " from the process yields a different object or None\n"+
809  "label = " + containedItem.label_())
810  dependencies[label]=[dep.label_() for dep in containedItems if dep.hasLabel_()]
811 
812  # keep looping until we get rid of all dependencies
813  while dependencies:
814  oldDeps = dict(dependencies)
815  for label,deps in six.iteritems(oldDeps):
816  if len(deps)==0:
817  returnValue[label]=processDictionaryOfItems[label]
818  #remove this as a dependency for all other tasks
819  del dependencies[label]
820  for lb2,deps2 in six.iteritems(dependencies):
821  while deps2.count(label):
822  deps2.remove(label)
823  return returnValue
824  def _dumpPython(self, d, options):
825  result = ''
826  for name, value in sorted(six.iteritems(d)):
827  result += value.dumpPythonAs(name,options)+'\n'
828  return result
829  def dumpPython(self, options=PrintOptions()):
830  """return a string containing the equivalent process defined using python"""
831  specialImportRegistry._reset()
832  header = "import FWCore.ParameterSet.Config as cms"
833  result = "process = cms.Process(\""+self.__name+"\")\n\n"
834  if self.source_():
835  result += "process.source = "+self.source_().dumpPython(options)
836  if self.looper_():
837  result += "process.looper = "+self.looper_().dumpPython()
838  result+=self._dumpPythonList(self.psets, options)
839  result+=self._dumpPythonList(self.vpsets, options)
840  result+=self._dumpPythonSubProcesses(self.subProcesses_(), options)
841  result+=self._dumpPythonList(self.producers_(), options)
842  result+=self._dumpPythonList(self.switchProducers_(), options)
843  result+=self._dumpPythonList(self.filters_() , options)
844  result+=self._dumpPythonList(self.analyzers_(), options)
845  result+=self._dumpPythonList(self.outputModules_(), options)
846  result+=self._dumpPythonList(self.services_(), options)
847  result+=self._dumpPythonList(self.es_producers_(), options)
848  result+=self._dumpPythonList(self.es_sources_(), options)
849  result+=self._dumpPython(self.es_prefers_(), options)
850  result+=self._dumpPythonList(self._itemsInDependencyOrder(self.tasks), options)
851  result+=self._dumpPythonList(self._itemsInDependencyOrder(self.sequences), options)
852  result+=self._dumpPythonList(self.paths_(), options)
853  result+=self._dumpPythonList(self.endpaths_(), options)
854  result+=self._dumpPythonList(self.aliases_(), options)
855  if not self.schedule_() == None:
856  result += 'process.schedule = ' + self.schedule.dumpPython(options)
857  imports = specialImportRegistry.getSpecialImports()
858  if len(imports) > 0:
859  header += "\n" + "\n".join(imports)
860  header += "\n\n"
861  return header+result
862  def _replaceInSequences(self, label, new):
863  old = getattr(self,label)
864  #TODO - replace by iterator concatenation
865  for sequenceable in six.itervalues(self.sequences):
866  sequenceable.replace(old,new)
867  for sequenceable in six.itervalues(self.paths):
868  sequenceable.replace(old,new)
869  for sequenceable in six.itervalues(self.endpaths):
870  sequenceable.replace(old,new)
871  def _replaceInTasks(self, label, new):
872  old = getattr(self,label)
873  for task in six.itervalues(self.tasks):
874  task.replace(old, new)
875  def _replaceInSchedule(self, label, new):
876  if self.schedule_() == None:
877  return
878  old = getattr(self,label)
879  for task in self.schedule_()._tasks:
880  task.replace(old, new)
881  def globalReplace(self,label,new):
882  """ Replace the item with label 'label' by object 'new' in the process and all sequences/paths/tasks"""
883  if not hasattr(self,label):
884  raise LookupError("process has no item of label "+label)
885  setattr(self,label,new)
886  def _insertInto(self, parameterSet, itemDict):
887  for name,value in six.iteritems(itemDict):
888  value.insertInto(parameterSet, name)
889  def _insertOneInto(self, parameterSet, label, item, tracked):
890  vitems = []
891  if not item == None:
892  newlabel = item.nameInProcessDesc_(label)
893  vitems = [newlabel]
894  item.insertInto(parameterSet, newlabel)
895  parameterSet.addVString(tracked, label, vitems)
896  def _insertManyInto(self, parameterSet, label, itemDict, tracked):
897  l = []
898  for name,value in six.iteritems(itemDict):
899  value.appendToProcessDescList_(l, name)
900  value.insertInto(parameterSet, name)
901  # alphabetical order is easier to compare with old language
902  l.sort()
903  parameterSet.addVString(tracked, label, l)
904  def _insertSwitchProducersInto(self, parameterSet, labelModules, labelAliases, itemDict, tracked):
905  modules = parameterSet.getVString(tracked, labelModules)
906  aliases = parameterSet.getVString(tracked, labelAliases)
907  for name,value in six.iteritems(itemDict):
908  value.appendToProcessDescLists_(modules, aliases, name)
909  value.insertInto(parameterSet, name)
910  modules.sort()
911  aliases.sort()
912  parameterSet.addVString(tracked, labelModules, modules)
913  parameterSet.addVString(tracked, labelAliases, aliases)
914  def _insertSubProcessesInto(self, parameterSet, label, itemList, tracked):
915  l = []
916  subprocs = []
917  for value in itemList:
918  name = value.getProcessName()
919  newLabel = value.nameInProcessDesc_(name)
920  l.append(newLabel)
921  pset = value.getSubProcessPSet(parameterSet)
922  subprocs.append(pset)
923  # alphabetical order is easier to compare with old language
924  l.sort()
925  parameterSet.addVString(tracked, label, l)
926  parameterSet.addVPSet(False,"subProcesses",subprocs)
927  def _insertPaths(self, processPSet, nodeVisitor):
928  scheduledPaths = []
929  triggerPaths = []
930  endpaths = []
931  if self.schedule_() == None:
932  # make one from triggerpaths & endpaths
933  for name in self.paths_():
934  scheduledPaths.append(name)
935  triggerPaths.append(name)
936  for name in self.endpaths_():
937  scheduledPaths.append(name)
938  endpaths.append(name)
939  else:
940  for path in self.schedule_():
941  pathname = path.label_()
942  scheduledPaths.append(pathname)
943  if pathname in self.endpaths_():
944  endpaths.append(pathname)
945  else:
946  triggerPaths.append(pathname)
947  for task in self.schedule_()._tasks:
948  task.resolve(self.__dict__)
949  scheduleTaskValidator = ScheduleTaskValidator()
950  task.visit(scheduleTaskValidator)
951  task.visit(nodeVisitor)
952  processPSet.addVString(True, "@end_paths", endpaths)
953  processPSet.addVString(True, "@paths", scheduledPaths)
954  # trigger_paths are a little different
955  p = processPSet.newPSet()
956  p.addVString(True, "@trigger_paths", triggerPaths)
957  processPSet.addPSet(True, "@trigger_paths", p)
958  # add all these paths
959  pathValidator = PathValidator()
960  endpathValidator = EndPathValidator()
961  decoratedList = []
962  lister = DecoratedNodeNameVisitor(decoratedList)
963  pathCompositeVisitor = CompositeVisitor(pathValidator, nodeVisitor, lister)
964  endpathCompositeVisitor = CompositeVisitor(endpathValidator, nodeVisitor, lister)
965  for triggername in triggerPaths:
966  iPath = self.paths_()[triggername]
967  iPath.resolve(self.__dict__)
968  pathValidator.setLabel(triggername)
969  lister.initialize()
970  iPath.visit(pathCompositeVisitor)
971  iPath.insertInto(processPSet, triggername, decoratedList)
972  for endpathname in endpaths:
973  iEndPath = self.endpaths_()[endpathname]
974  iEndPath.resolve(self.__dict__)
975  endpathValidator.setLabel(endpathname)
976  lister.initialize()
977  iEndPath.visit(endpathCompositeVisitor)
978  iEndPath.insertInto(processPSet, endpathname, decoratedList)
979  processPSet.addVString(False, "@filters_on_endpaths", endpathValidator.filtersOnEndpaths)
980 
981  def resolve(self,keepUnresolvedSequencePlaceholders=False):
982  for x in six.itervalues(self.paths):
983  x.resolve(self.__dict__,keepUnresolvedSequencePlaceholders)
984  for x in six.itervalues(self.endpaths):
985  x.resolve(self.__dict__,keepUnresolvedSequencePlaceholders)
986  if not self.schedule_() == None:
987  for task in self.schedule_()._tasks:
988  task.resolve(self.__dict__,keepUnresolvedSequencePlaceholders)
989 
990  def prune(self,verbose=False,keepUnresolvedSequencePlaceholders=False):
991  """ Remove clutter from the process that we think is unnecessary:
992  tracked PSets, VPSets and unused modules and sequences. If a Schedule has been set, then Paths and EndPaths
993  not in the schedule will also be removed, along with an modules and sequences used only by
994  those removed Paths and EndPaths."""
995 # need to update this to only prune psets not on refToPSets
996 # but for now, remove the delattr
997 # for name in self.psets_():
998 # if getattr(self,name).isTracked():
999 # delattr(self, name)
1000  for name in self.vpsets_():
1001  delattr(self, name)
1002  #first we need to resolve any SequencePlaceholders being used
1003  self.resolve(keepUnresolvedSequencePlaceholders)
1004  usedModules = set()
1005  unneededPaths = set()
1006  if self.schedule_():
1007  usedModules=set(self.schedule_().moduleNames())
1008  #get rid of unused paths
1009  schedNames = set(( x.label_() for x in self.schedule_()))
1010  names = set(self.paths)
1011  names.update(set(self.endpaths))
1012  unneededPaths = names - schedNames
1013  for n in unneededPaths:
1014  delattr(self,n)
1015  else:
1016  pths = list(six.itervalues(self.paths))
1017  pths.extend(six.itervalues(self.endpaths))
1018  temp = Schedule(*pths)
1019  usedModules=set(temp.moduleNames())
1020  unneededModules = self._pruneModules(self.producers_(), usedModules)
1021  unneededModules.update(self._pruneModules(self.switchProducers_(), usedModules))
1022  unneededModules.update(self._pruneModules(self.filters_(), usedModules))
1023  unneededModules.update(self._pruneModules(self.analyzers_(), usedModules))
1024  #remove sequences that do not appear in remaining paths and endpaths
1025  seqs = list()
1026  sv = SequenceVisitor(seqs)
1027  for p in six.itervalues(self.paths):
1028  p.visit(sv)
1029  for p in six.itervalues(self.endpaths):
1030  p.visit(sv)
1031  keepSeqSet = set(( s for s in seqs if s.hasLabel_()))
1032  availableSeqs = set(six.itervalues(self.sequences))
1033  unneededSeqs = availableSeqs-keepSeqSet
1034  unneededSeqLabels = []
1035  for s in unneededSeqs:
1036  unneededSeqLabels.append(s.label_())
1037  delattr(self,s.label_())
1038  if verbose:
1039  print("prune removed the following:")
1040  print(" modules:"+",".join(unneededModules))
1041  print(" sequences:"+",".join(unneededSeqLabels))
1042  print(" paths/endpaths:"+",".join(unneededPaths))
1043  def _pruneModules(self, d, scheduledNames):
1044  moduleNames = set(d.keys())
1045  junk = moduleNames - scheduledNames
1046  for name in junk:
1047  delattr(self, name)
1048  return junk
1049 
1050  def fillProcessDesc(self, processPSet):
1051  """Used by the framework to convert python to C++ objects"""
1052  class ServiceInjectorAdaptor(object):
1053  def __init__(self,ppset,thelist):
1054  self.__thelist = thelist
1055  self.__processPSet = ppset
1056  def addService(self,pset):
1057  self.__thelist.append(pset)
1058  def newPSet(self):
1059  return self.__processPSet.newPSet()
1060  #This adaptor is used to 'add' the method 'getTopPSet_'
1061  # to the ProcessDesc and PythonParameterSet C++ classes.
1062  # This method is needed for the PSet refToPSet_ functionality.
1063  class TopLevelPSetAcessorAdaptor(object):
1064  def __init__(self,ppset,process):
1065  self.__ppset = ppset
1066  self.__process = process
1067  def __getattr__(self,attr):
1068  return getattr(self.__ppset,attr)
1069  def getTopPSet_(self,label):
1070  return getattr(self.__process,label)
1071  def newPSet(self):
1072  return TopLevelPSetAcessorAdaptor(self.__ppset.newPSet(),self.__process)
1073  def addPSet(self,tracked,name,ppset):
1074  return self.__ppset.addPSet(tracked,name,self.__extractPSet(ppset))
1075  def addVPSet(self,tracked,name,vpset):
1076  return self.__ppset.addVPSet(tracked,name,[self.__extractPSet(x) for x in vpset])
1077  def __extractPSet(self,pset):
1078  if isinstance(pset,TopLevelPSetAcessorAdaptor):
1079  return pset.__ppset
1080  return pset
1081 
1082  self.validate()
1083  processPSet.addString(True, "@process_name", self.name_())
1084  all_modules = self.producers_().copy()
1085  all_modules.update(self.filters_())
1086  all_modules.update(self.analyzers_())
1087  all_modules.update(self.outputModules_())
1088  adaptor = TopLevelPSetAcessorAdaptor(processPSet,self)
1089  self._insertInto(adaptor, self.psets_())
1090  self._insertInto(adaptor, self.vpsets_())
1091  self._insertOneInto(adaptor, "@all_sources", self.source_(), True)
1092  self._insertOneInto(adaptor, "@all_loopers", self.looper_(), True)
1093  self._insertSubProcessesInto(adaptor, "@all_subprocesses", self.subProcesses_(), False)
1094  self._insertManyInto(adaptor, "@all_esprefers", self.es_prefers_(), True)
1095  self._insertManyInto(adaptor, "@all_aliases", self.aliases_(), True)
1096  # This will visit all the paths and endpaths that are scheduled to run,
1097  # as well as the Tasks associated to them and the schedule. It remembers
1098  # the modules, ESSources, ESProducers, and services it visits.
1099  nodeVisitor = NodeVisitor()
1100  self._insertPaths(adaptor, nodeVisitor)
1101  all_modules_onTasksOrScheduled = { key:value for key, value in six.iteritems(all_modules) if value in nodeVisitor.modules }
1102  self._insertManyInto(adaptor, "@all_modules", all_modules_onTasksOrScheduled, True)
1103  all_switches = self.switchProducers_().copy()
1104  all_switches_onTasksOrScheduled = {key:value for key, value in six.iteritems(all_switches) if value in nodeVisitor.modules }
1105  self._insertSwitchProducersInto(adaptor, "@all_modules", "@all_aliases", all_switches_onTasksOrScheduled, True)
1106  # Same as nodeVisitor except this one visits all the Tasks attached
1107  # to the process.
1108  processNodeVisitor = NodeVisitor()
1109  for pTask in six.itervalues(self.tasks):
1110  pTask.visit(processNodeVisitor)
1111  esProducersToEnable = {}
1112  for esProducerName, esProducer in six.iteritems(self.es_producers_()):
1113  if esProducer in nodeVisitor.esProducers or not (esProducer in processNodeVisitor.esProducers):
1114  esProducersToEnable[esProducerName] = esProducer
1115  self._insertManyInto(adaptor, "@all_esmodules", esProducersToEnable, True)
1116  esSourcesToEnable = {}
1117  for esSourceName, esSource in six.iteritems(self.es_sources_()):
1118  if esSource in nodeVisitor.esSources or not (esSource in processNodeVisitor.esSources):
1119  esSourcesToEnable[esSourceName] = esSource
1120  self._insertManyInto(adaptor, "@all_essources", esSourcesToEnable, True)
1121  #handle services differently
1122  services = []
1123  for serviceName, serviceObject in six.iteritems(self.services_()):
1124  if serviceObject in nodeVisitor.services or not (serviceObject in processNodeVisitor.services):
1125  serviceObject.insertInto(ServiceInjectorAdaptor(adaptor,services))
1126  adaptor.addVPSet(False,"services",services)
1127  return processPSet
1128 
1129  def validate(self):
1130  # check if there's some input
1131  # Breaks too many unit tests for now
1132  #if self.source_() == None and self.looper_() == None:
1133  # raise RuntimeError("No input source was found for this process")
1134  pass
1135 
1136  def prefer(self, esmodule,*args,**kargs):
1137  """Prefer this ES source or producer. The argument can
1138  either be an object label, e.g.,
1139  process.prefer(process.juicerProducer) (not supported yet)
1140  or a name of an ESSource or ESProducer
1141  process.prefer("juicer")
1142  or a type of unnamed ESSource or ESProducer
1143  process.prefer("JuicerProducer")
1144  In addition, you can pass as a labelled arguments the name of the Record you wish to
1145  prefer where the type passed is a cms.vstring and that vstring can contain the
1146  name of the C++ types in the Record that are being preferred, e.g.,
1147  #prefer all data in record 'OrangeRecord' from 'juicer'
1148  process.prefer("juicer", OrangeRecord=cms.vstring())
1149  or
1150  #prefer only "Orange" data in "OrangeRecord" from "juicer"
1151  process.prefer("juicer", OrangeRecord=cms.vstring("Orange"))
1152  or
1153  #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer"
1154  ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
1155  """
1156  # see if this refers to a named ESProducer
1157  if isinstance(esmodule, ESSource) or isinstance(esmodule, ESProducer):
1158  raise RuntimeError("Syntax of process.prefer(process.esmodule) not supported yet")
1159  elif self._findPreferred(esmodule, self.es_producers_(),*args,**kargs) or \
1160  self._findPreferred(esmodule, self.es_sources_(),*args,**kargs):
1161  pass
1162  else:
1163  raise RuntimeError("Cannot resolve prefer for "+repr(esmodule))
1164 
1165  def _findPreferred(self, esname, d,*args,**kargs):
1166  # is esname a name in the dictionary?
1167  if esname in d:
1168  typ = d[esname].type_()
1169  if typ == esname:
1170  self.__setattr__( esname+"_prefer", ESPrefer(typ,*args,**kargs) )
1171  else:
1172  self.__setattr__( esname+"_prefer", ESPrefer(typ, esname,*args,**kargs) )
1173  return True
1174  else:
1175  # maybe it's an unnamed ESModule?
1176  found = False
1177  for name, value in six.iteritems(d):
1178  if value.type_() == esname:
1179  if found:
1180  raise RuntimeError("More than one ES module for "+esname)
1181  found = True
1182  self.__setattr__(esname+"_prefer", ESPrefer(d[esname].type_()) )
1183  return found
1184 
1185 
1187  def __init__(self, process):
1188  if isinstance(process, Process):
1189  self.__process = process
1190  elif isinstance(process, str):
1191  self.__process = Process(process)
1192  else:
1193  raise TypeError('a ProcessFragment can only be constructed from an existig Process or from process name')
1194  def __dir__(self):
1195  return [ x for x in dir(self.__process) if isinstance(getattr(self.__process, x), _ConfigureComponent) ]
1196  def __getattribute__(self, name):
1197  if name == '_ProcessFragment__process':
1198  return object.__getattribute__(self, '_ProcessFragment__process')
1199  else:
1200  return getattr(self.__process, name)
1201  def __setattr__(self, name, value):
1202  if name == '_ProcessFragment__process':
1203  object.__setattr__(self, name, value)
1204  else:
1205  setattr(self.__process, name, value)
1206  def __delattr__(self, name):
1207  if name == '_ProcessFragment__process':
1208  pass
1209  else:
1210  return delattr(self.__process, name)
1211 
1212 
1214  """a dictionary with fixed keys"""
1216  raise AttributeError("An FilteredStream defintion cannot be modified after creation.")
1217  _blocked_attribute = property(_blocked_attribute)
1218  __setattr__ = __delitem__ = __setitem__ = clear = _blocked_attribute
1219  pop = popitem = setdefault = update = _blocked_attribute
1220  def __new__(cls, *args, **kw):
1221  new = dict.__new__(cls)
1222  dict.__init__(new, *args, **kw)
1223  keys = sorted(kw.keys())
1224  if keys != ['content', 'dataTier', 'name', 'paths', 'responsible', 'selectEvents']:
1225  raise ValueError("The needed parameters are: content, dataTier, name, paths, responsible, selectEvents")
1226  if not isinstance(kw['name'],str):
1227  raise ValueError("name must be of type string")
1228  if not isinstance(kw['content'], vstring) and not isinstance(kw['content'],str):
1229  raise ValueError("content must be of type vstring or string")
1230  if not isinstance(kw['dataTier'], string):
1231  raise ValueError("dataTier must be of type string")
1232  if not isinstance(kw['selectEvents'], PSet):
1233  raise ValueError("selectEvents must be of type PSet")
1234  if not isinstance(kw['paths'],(tuple, Path)):
1235  raise ValueError("'paths' must be a tuple of paths")
1236  return new
1237  def __init__(self, *args, **kw):
1238  pass
1239  def __repr__(self):
1240  return "FilteredStream object: %s" %self["name"]
1241  def __getattr__(self,attr):
1242  return self[attr]
1243 
1245  """Allows embedding another process within a parent process. This allows one to
1246  chain processes together directly in one cmsRun job rather than having to run
1247  separate jobs that are connected via a temporary file.
1248  """
1249  def __init__(self,process, SelectEvents = untracked.PSet(), outputCommands = untracked.vstring()):
1250  """
1251  """
1252  if not isinstance(process, Process):
1253  raise ValueError("the 'process' argument must be of type cms.Process")
1254  if not isinstance(SelectEvents,PSet):
1255  raise ValueError("the 'SelectEvents' argument must be of type cms.untracked.PSet")
1256  if not isinstance(outputCommands,vstring):
1257  raise ValueError("the 'outputCommands' argument must be of type cms.untracked.vstring")
1258  self.__process = process
1259  self.__SelectEvents = SelectEvents
1260  self.__outputCommands = outputCommands
1261  def dumpPython(self,options=PrintOptions()):
1262  out = "parentProcess"+str(hash(self))+" = process\n"
1263  out += self.__process.dumpPython()
1264  out += "childProcess = process\n"
1265  out += "process = parentProcess"+str(hash(self))+"\n"
1266  out += "process.addSubProcess(cms.SubProcess(process = childProcess, SelectEvents = "+self.__SelectEvents.dumpPython(options) +", outputCommands = "+self.__outputCommands.dumpPython(options) +"))"
1267  return out
1268  def getProcessName(self):
1269  return self.__process.name_()
1270  def process(self):
1271  return self.__process
1272  def SelectEvents(self):
1273  return self.__SelectEvents
1274  def outputCommands(self):
1275  return self.__outputCommands
1276  def type_(self):
1277  return 'subProcess'
1278  def nameInProcessDesc_(self,label):
1279  return label
1280  def _place(self,label,process):
1281  process._placeSubProcess('subProcess',self)
1282  def getSubProcessPSet(self,parameterSet):
1283  topPSet = parameterSet.newPSet()
1284  self.__process.fillProcessDesc(topPSet)
1285  subProcessPSet = parameterSet.newPSet()
1286  self.__SelectEvents.insertInto(subProcessPSet,"SelectEvents")
1287  self.__outputCommands.insertInto(subProcessPSet,"outputCommands")
1288  subProcessPSet.addPSet(False,"process",topPSet)
1289  return subProcessPSet
1290 
1292  """Helper class for Modifier that takes key/value pairs and uses them to reset parameters of the object"""
1293  def __init__(self,args):
1294  self.__args = args
1295  def __call__(self,obj):
1296  params = {}
1297  for k in six.iterkeys(self.__args):
1298  if hasattr(obj,k):
1299  params[k] = getattr(obj,k)
1301  for k in six.iterkeys(self.__args):
1302  if k in params:
1303  setattr(obj,k,params[k])
1304  else:
1305  #the parameter must have been removed
1306  delattr(obj,k)
1307  @staticmethod
1309  raise KeyError("Unknown parameter name "+key+" specified while calling Modifier")
1310 
1312  """A helper base class for _AndModifier, _InvertModifier, and _OrModifier to contain the common code"""
1313  def __init__(self, lhs, rhs=None):
1314  self._lhs = lhs
1315  if rhs is not None:
1316  self._rhs = rhs
1317  def toModify(self,obj, func=None,**kw):
1318  Modifier._toModifyCheck(obj,func,**kw)
1319  if not self._isChosen():
1320  return
1321  Modifier._toModify(obj,func,**kw)
1322  def toReplaceWith(self,toObj,fromObj):
1323  Modifier._toReplaceWithCheck(toObj,fromObj)
1324  if not self._isChosen():
1325  return
1326  Modifier._toReplaceWith(toObj,fromObj)
1327  def makeProcessModifier(self,func):
1328  """This is used to create a ProcessModifer that can perform actions on the process as a whole.
1329  This takes as argument a callable object (e.g. function) that takes as its sole argument an instance of Process.
1330  In order to work, the value returned from this function must be assigned to a uniquely named variable."""
1331  return ProcessModifier(self,func)
1332  def __and__(self, other):
1333  return _AndModifier(self,other)
1334  def __invert__(self):
1335  return _InvertModifier(self)
1336  def __or__(self, other):
1337  return _OrModifier(self,other)
1338 
1340  """A modifier which only applies if multiple Modifiers are chosen"""
1341  def __init__(self, lhs, rhs):
1342  super(_AndModifier,self).__init__(lhs, rhs)
1343  def _isChosen(self):
1344  return self._lhs._isChosen() and self._rhs._isChosen()
1345 
1347  """A modifier which only applies if a Modifier is not chosen"""
1348  def __init__(self, lhs):
1349  super(_InvertModifier,self).__init__(lhs)
1350  def _isChosen(self):
1351  return not self._lhs._isChosen()
1352 
1354  """A modifier which only applies if at least one of multiple Modifiers is chosen"""
1355  def __init__(self, lhs, rhs):
1356  super(_OrModifier,self).__init__(lhs, rhs)
1357  def _isChosen(self):
1358  return self._lhs._isChosen() or self._rhs._isChosen()
1359 
1360 
1362  """This class is used to define standard modifications to a Process.
1363  An instance of this class is declared to denote a specific modification,e.g. era2017 could
1364  reconfigure items in a process to match our expectation of running in 2017. Once declared,
1365  these Modifier instances are imported into a configuration and items that need to be modified
1366  are then associated with the Modifier and with the action to do the modification.
1367  The registered modifications will only occur if the Modifier was passed to
1368  the cms.Process' constructor.
1369  """
1370  def __init__(self):
1372  self.__chosen = False
1373  def makeProcessModifier(self,func):
1374  """This is used to create a ProcessModifer that can perform actions on the process as a whole.
1375  This takes as argument a callable object (e.g. function) that takes as its sole argument an instance of Process.
1376  In order to work, the value returned from this function must be assigned to a uniquely named variable.
1377  """
1378  return ProcessModifier(self,func)
1379  @staticmethod
1380  def _toModifyCheck(obj,func,**kw):
1381  if func is not None and len(kw) != 0:
1382  raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
1383  def toModify(self,obj, func=None,**kw):
1384  """This is used to register an action to be performed on the specific object. Two different forms are allowed
1385  Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1386  that will be the object passed in as the first argument.
1387  Form 2: A list of parameter name, value pairs can be passed
1388  mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1389  This form can also be used to remove a parameter by passing the value of None
1390  #remove the parameter foo.fred
1391  mod.toModify(foo, fred = None)
1392  Additionally, parameters embedded within PSets can also be modified using a dictionary
1393  #change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
1394  mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
1395  """
1396  Modifier._toModifyCheck(obj,func,**kw)
1397  if not self._isChosen():
1398  return
1399  Modifier._toModify(obj,func,**kw)
1400  @staticmethod
1401  def _toModify(obj,func,**kw):
1402  if func is not None:
1403  func(obj)
1404  else:
1405  temp =_ParameterModifier(kw)
1406  temp(obj)
1407  @staticmethod
1408  def _toReplaceWithCheck(toObj,fromObj):
1409  if not isinstance(fromObj, type(toObj)):
1410  raise TypeError("toReplaceWith requires both arguments to be the same class type")
1411  def toReplaceWith(self,toObj,fromObj):
1412  """If the Modifier is chosen the internals of toObj will be associated with the internals of fromObj
1413  """
1414  Modifier._toReplaceWithCheck(toObj,fromObj)
1415  if not self._isChosen():
1416  return
1417  Modifier._toReplaceWith(toObj,fromObj)
1418  @staticmethod
1419  def _toReplaceWith(toObj,fromObj):
1420  if isinstance(fromObj,_ModuleSequenceType):
1421  toObj._seq = fromObj._seq
1422  toObj._tasks = fromObj._tasks
1423  elif isinstance(fromObj,Task):
1424  toObj._collection = fromObj._collection
1425  elif isinstance(fromObj,_Parameterizable):
1426  #clear old items just incase fromObj is not a complete superset of toObj
1427  for p in toObj.parameterNames_():
1428  delattr(toObj,p)
1429  for p in fromObj.parameterNames_():
1430  setattr(toObj,p,getattr(fromObj,p))
1431  if isinstance(fromObj,_TypedParameterizable):
1432  toObj._TypedParameterizable__type = fromObj._TypedParameterizable__type
1433 
1434  else:
1435  raise TypeError("toReplaceWith does not work with type "+str(type(toObj)))
1436 
1437  def _setChosen(self):
1438  """Should only be called by cms.Process instances"""
1439  self.__chosen = True
1440  def _isChosen(self):
1441  return self.__chosen
1442  def __and__(self, other):
1443  return _AndModifier(self,other)
1444  def __invert__(self):
1445  return _InvertModifier(self)
1446  def __or__(self, other):
1447  return _OrModifier(self,other)
1448  def _isOrContains(self, other):
1449  return self == other
1450 
1451 
1453  """A Modifier made up of a list of Modifiers
1454  """
1455  def __init__(self, *chainedModifiers):
1456  self.__chosen = False
1457  self.__chain = chainedModifiers
1458  def _applyNewProcessModifiers(self,process):
1459  """Should only be called by cms.Process instances
1460  applies list of accumulated changes to the process"""
1461  for m in self.__chain:
1462  m._applyNewProcessModifiers(process)
1463  def _setChosen(self):
1464  """Should only be called by cms.Process instances"""
1465  self.__chosen = True
1466  for m in self.__chain:
1467  m._setChosen()
1468  def _isChosen(self):
1469  return self.__chosen
1470  def copyAndExclude(self, toExclude):
1471  """Creates a new ModifierChain which is a copy of
1472  this ModifierChain but excludes any Modifier or
1473  ModifierChain in the list toExclude.
1474  The exclusion is done recursively down the chain.
1475  """
1476  newMods = []
1477  for m in self.__chain:
1478  if m not in toExclude:
1479  s = m
1480  if isinstance(m,ModifierChain):
1481  s = m.__copyIfExclude(toExclude)
1482  newMods.append(s)
1483  return ModifierChain(*newMods)
1484  def __copyIfExclude(self,toExclude):
1485  shouldCopy = False
1486  for m in toExclude:
1487  if self._isOrContains(m):
1488  shouldCopy = True
1489  break
1490  if shouldCopy:
1491  return self.copyAndExclude(toExclude)
1492  return self
1493  def _isOrContains(self, other):
1494  if self is other:
1495  return True
1496  for m in self.__chain:
1497  if m._isOrContains(other):
1498  return True
1499  return False
1500 
1502  """A class used by a Modifier to affect an entire Process instance.
1503  When a Process 'loads' a module containing a ProcessModifier, that
1504  ProcessModifier will be applied to the Process if and only if the
1505  Modifier passed to the constructor has been chosen.
1506  """
1507  def __init__(self, modifier, func):
1508  self.__modifier = modifier
1509  self.__func = func
1510  self.__seenProcesses = set()
1511  def apply(self,process):
1512  if self.__modifier._isChosen():
1513  if process not in self.__seenProcesses:
1514  self.__func(process)
1515  self.__seenProcesses.add(process)
1516 
1517 if __name__=="__main__":
1518  import unittest
1519  import copy
1520 
1522  """Has same interface as the C++ object that creates PSets
1523  """
1524  def __init__(self):
1525  self.values = dict()
1526  def __insertValue(self,tracked,label,value):
1527  self.values[label]=(tracked,value)
1528  def __getValue(self,tracked,label):
1529  pair = self.values[label]
1530  if pair[0] != tracked:
1531  raise Exception("Asked for %s parameter '%s', but it is %s" % ("tracked" if tracked else "untracked",
1532  label,
1533  "tracked" if pair[0] else "untracked"))
1534  return pair[1]
1535  def addInt32(self,tracked,label,value):
1536  self.__insertValue(tracked,label,value)
1537  def addVInt32(self,tracked,label,value):
1538  self.__insertValue(tracked,label,value)
1539  def addUInt32(self,tracked,label,value):
1540  self.__insertValue(tracked,label,value)
1541  def addVUInt32(self,tracked,label,value):
1542  self.__insertValue(tracked,label,value)
1543  def addInt64(self,tracked,label,value):
1544  self.__insertValue(tracked,label,value)
1545  def addVInt64(self,tracked,label,value):
1546  self.__insertValue(tracked,label,value)
1547  def addUInt64(self,tracked,label,value):
1548  self.__insertValue(tracked,label,value)
1549  def addVUInt64(self,tracked,label,value):
1550  self.__insertValue(tracked,label,value)
1551  def addDouble(self,tracked,label,value):
1552  self.__insertValue(tracked,label,value)
1553  def addVDouble(self,tracked,label,value):
1554  self.__insertValue(tracked,label,value)
1555  def addBool(self,tracked,label,value):
1556  self.__insertValue(tracked,label,value)
1557  def addString(self,tracked,label,value):
1558  self.__insertValue(tracked,label,value)
1559  def addVString(self,tracked,label,value):
1560  self.__insertValue(tracked,label,value)
1561  def getVString(self,tracked,label):
1562  return self.__getValue(tracked, label)
1563  def addInputTag(self,tracked,label,value):
1564  self.__insertValue(tracked,label,value)
1565  def addVInputTag(self,tracked,label,value):
1566  self.__insertValue(tracked,label,value)
1567  def addESInputTag(self,tracked,label,value):
1568  self.__insertValue(tracked,label,value)
1569  def addVESInputTag(self,tracked,label,value):
1570  self.__insertValue(tracked,label,value)
1571  def addEventID(self,tracked,label,value):
1572  self.__insertValue(tracked,label,value)
1573  def addVEventID(self,tracked,label,value):
1574  self.__insertValue(tracked,label,value)
1575  def addLuminosityBlockID(self,tracked,label,value):
1576  self.__insertValue(tracked,label,value)
1577  def addLuminosityBlockID(self,tracked,label,value):
1578  self.__insertValue(tracked,label,value)
1579  def addEventRange(self,tracked,label,value):
1580  self.__insertValue(tracked,label,value)
1581  def addVEventRange(self,tracked,label,value):
1582  self.__insertValue(tracked,label,value)
1583  def addPSet(self,tracked,label,value):
1584  self.__insertValue(tracked,label,value)
1585  def addVPSet(self,tracked,label,value):
1586  self.__insertValue(tracked,label,value)
1587  def addFileInPath(self,tracked,label,value):
1588  self.__insertValue(tracked,label,value)
1589  def newPSet(self):
1590  return TestMakePSet()
1591 
1593  def __init__(self, **kargs):
1594  super(SwitchProducerTest,self).__init__(
1595  dict(
1596  test1 = lambda: (True, -10),
1597  test2 = lambda: (True, -9),
1598  test3 = lambda: (True, -8),
1599  test4 = lambda: (True, -7)
1600  ), **kargs)
1601  specialImportRegistry.registerSpecialImportForType(SwitchProducerTest, "from test import SwitchProducerTest")
1602 
1603  class TestModuleCommand(unittest.TestCase):
1604  def setUp(self):
1605  """Nothing to do """
1606  None
1608  p = _Parameterizable()
1609  self.assertEqual(len(p.parameterNames_()),0)
1610  p.a = int32(1)
1611  self.assert_('a' in p.parameterNames_())
1612  self.assertEqual(p.a.value(), 1)
1613  p.a = 10
1614  self.assertEqual(p.a.value(), 10)
1615  p.a = untracked(int32(1))
1616  self.assertEqual(p.a.value(), 1)
1617  self.failIf(p.a.isTracked())
1618  p.a = untracked.int32(1)
1619  self.assertEqual(p.a.value(), 1)
1620  self.failIf(p.a.isTracked())
1621  p = _Parameterizable(foo=int32(10), bar = untracked(double(1.0)))
1622  self.assertEqual(p.foo.value(), 10)
1623  self.assertEqual(p.bar.value(),1.0)
1624  self.failIf(p.bar.isTracked())
1625  self.assertRaises(TypeError,setattr,(p,'c',1))
1626  p = _Parameterizable(a=PSet(foo=int32(10), bar = untracked(double(1.0))))
1627  self.assertEqual(p.a.foo.value(),10)
1628  self.assertEqual(p.a.bar.value(),1.0)
1629  p.b = untracked(PSet(fii = int32(1)))
1630  self.assertEqual(p.b.fii.value(),1)
1631  self.failIf(p.b.isTracked())
1632  #test the fact that values can be shared
1633  v = int32(10)
1634  p=_Parameterizable(a=v)
1635  v.setValue(11)
1636  self.assertEqual(p.a.value(),11)
1637  p.a = 12
1638  self.assertEqual(p.a.value(),12)
1639  self.assertEqual(v.value(),12)
1641  p = _TypedParameterizable("blah", b=int32(1))
1642  #see if copy works deeply
1643  other = p.copy()
1644  other.b = 2
1645  self.assertNotEqual(p.b,other.b)
1646 
1648  p = Process("test")
1649  p.a = EDAnalyzer("MyAnalyzer")
1650  self.assert_( 'a' in p.analyzers_() )
1651  self.assert_( 'a' in p.analyzers)
1652  p.add_(Service("MessageLogger"))
1653  self.assert_('MessageLogger' in p.services_())
1654  self.assertEqual(p.MessageLogger.type_(), "MessageLogger")
1655  p.Tracer = Service("Tracer")
1656  self.assert_('Tracer' in p.services_())
1657  self.assertRaises(TypeError, setattr, *(p,'b',"this should fail"))
1658  self.assertRaises(TypeError, setattr, *(p,'bad',Service("MessageLogger")))
1659  self.assertRaises(ValueError, setattr, *(p,'bad',Source("PoolSource")))
1660  p.out = OutputModule("Outer")
1661  self.assertEqual(p.out.type_(), 'Outer')
1662  self.assert_( 'out' in p.outputModules_() )
1663 
1664  p.geom = ESSource("GeomProd")
1665  self.assert_('geom' in p.es_sources_())
1666  p.add_(ESSource("ConfigDB"))
1667  self.assert_('ConfigDB' in p.es_sources_())
1668 
1669  p.aliasfoo1 = EDAlias(foo1 = VPSet(PSet(type = string("Foo1"))))
1670  self.assert_('aliasfoo1' in p.aliases_())
1671 
1673  class FromArg(object):
1674  def __init__(self,*arg,**args):
1675  for name in six.iterkeys(args):
1676  self.__dict__[name]=args[name]
1677 
1678  a=EDAnalyzer("MyAnalyzer")
1679  t=EDAnalyzer("MyAnalyzer")
1680  t.setLabel("foo")
1681  s1 = Sequence(a)
1682  s2 = Sequence(s1)
1683  s3 = Sequence(s2)
1684  d = FromArg(
1685  a=a,
1686  b=Service("Full"),
1687  c=Path(a),
1688  d=s2,
1689  e=s1,
1690  f=s3,
1691  g=Sequence(s1+s2+s3)
1692  )
1693  p = Process("Test")
1694  p.extend(d)
1695  self.assertEqual(p.a.type_(),"MyAnalyzer")
1696  self.assertEqual(p.a.label_(),"a")
1697  self.assertRaises(AttributeError,getattr,p,'b')
1698  self.assertEqual(p.Full.type_(),"Full")
1699  self.assertEqual(str(p.c),'a')
1700  self.assertEqual(str(p.d),'a')
1701 
1702  z1 = FromArg(
1703  a=a,
1704  b=Service("Full"),
1705  c=Path(a),
1706  d=s2,
1707  e=s1,
1708  f=s3,
1709  s4=s3,
1710  g=Sequence(s1+s2+s3)
1711  )
1712 
1713  p1 = Process("Test")
1714  #p1.extend(z1)
1715  self.assertRaises(ValueError, p1.extend, z1)
1716 
1717  z2 = FromArg(
1718  a=a,
1719  b=Service("Full"),
1720  c=Path(a),
1721  d=s2,
1722  e=s1,
1723  f=s3,
1724  aaa=copy.deepcopy(a),
1725  s4=copy.deepcopy(s3),
1726  g=Sequence(s1+s2+s3),
1727  t=t
1728  )
1729  p2 = Process("Test")
1730  p2.extend(z2)
1731  #self.assertRaises(ValueError, p2.extend, z2)
1732  self.assertEqual(p2.s4.label_(),"s4")
1733  #p2.s4.setLabel("foo")
1734  self.assertRaises(ValueError, p2.s4.setLabel, "foo")
1735  p2.s4.setLabel("s4")
1736  p2.s4.setLabel(None)
1737  p2.s4.setLabel("foo")
1738  p2._Process__setObjectLabel(p2.s4, "foo")
1739  p2._Process__setObjectLabel(p2.s4, None)
1740  p2._Process__setObjectLabel(p2.s4, "bar")
1741 
1743  p = Process("test")
1744  p.a = EDAnalyzer("MyAnalyzer")
1745  p.p = Path(p.a)
1746  p.s = Sequence(p.a)
1747  p.r = Sequence(p.s)
1748  p.p2 = Path(p.s)
1749  p.schedule = Schedule(p.p2,p.p)
1750  d=p.dumpPython()
1751  self.assertEqual(d,
1752 """import FWCore.ParameterSet.Config as cms
1753 
1754 process = cms.Process("test")
1755 
1756 process.a = cms.EDAnalyzer("MyAnalyzer")
1757 
1758 
1759 process.s = cms.Sequence(process.a)
1760 
1761 
1762 process.r = cms.Sequence(process.s)
1763 
1764 
1765 process.p = cms.Path(process.a)
1766 
1767 
1768 process.p2 = cms.Path(process.s)
1769 
1770 
1771 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1772 """)
1773  #Reverse order of 'r' and 's'
1774  p = Process("test")
1775  p.a = EDAnalyzer("MyAnalyzer")
1776  p.p = Path(p.a)
1777  p.r = Sequence(p.a)
1778  p.s = Sequence(p.r)
1779  p.p2 = Path(p.r)
1780  p.schedule = Schedule(p.p2,p.p)
1781  p.b = EDAnalyzer("YourAnalyzer")
1782  d=p.dumpPython()
1783  self.assertEqual(d,
1784 """import FWCore.ParameterSet.Config as cms
1785 
1786 process = cms.Process("test")
1787 
1788 process.a = cms.EDAnalyzer("MyAnalyzer")
1789 
1790 
1791 process.b = cms.EDAnalyzer("YourAnalyzer")
1792 
1793 
1794 process.r = cms.Sequence(process.a)
1795 
1796 
1797 process.s = cms.Sequence(process.r)
1798 
1799 
1800 process.p = cms.Path(process.a)
1801 
1802 
1803 process.p2 = cms.Path(process.r)
1804 
1805 
1806 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1807 """)
1808  #use an anonymous sequence
1809  p = Process("test")
1810  p.a = EDAnalyzer("MyAnalyzer")
1811  p.p = Path(p.a)
1812  s = Sequence(p.a)
1813  p.r = Sequence(s)
1814  p.p2 = Path(p.r)
1815  p.schedule = Schedule(p.p2,p.p)
1816  d=p.dumpPython()
1817  self.assertEqual(d,
1818  """import FWCore.ParameterSet.Config as cms
1819 
1820 process = cms.Process("test")
1821 
1822 process.a = cms.EDAnalyzer("MyAnalyzer")
1823 
1824 
1825 process.r = cms.Sequence((process.a))
1826 
1827 
1828 process.p = cms.Path(process.a)
1829 
1830 
1831 process.p2 = cms.Path(process.r)
1832 
1833 
1834 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1835 """)
1836 
1837  # include some tasks
1838  p = Process("test")
1839  p.a = EDAnalyzer("MyAnalyzer")
1840  p.b = EDProducer("bProducer")
1841  p.c = EDProducer("cProducer")
1842  p.d = EDProducer("dProducer")
1843  p.e = EDProducer("eProducer")
1844  p.f = EDProducer("fProducer")
1845  p.g = EDProducer("gProducer")
1846  p.task5 = Task()
1847  p.task3 = Task()
1848  p.task2 = Task(p.c, p.task3)
1849  p.task4 = Task(p.f, p.task2)
1850  p.task1 = Task(p.task5)
1851  p.task3.add(p.task1)
1852  p.p = Path(p.a)
1853  s = Sequence(p.a)
1854  p.r = Sequence(s)
1855  p.p2 = Path(p.r, p.task1, p.task2)
1856  p.schedule = Schedule(p.p2,p.p,tasks=[p.task3,p.task4, p.task5])
1857  d=p.dumpPython()
1858  self.assertEqual(d,
1859  """import FWCore.ParameterSet.Config as cms
1860 
1861 process = cms.Process("test")
1862 
1863 process.b = cms.EDProducer("bProducer")
1864 
1865 
1866 process.c = cms.EDProducer("cProducer")
1867 
1868 
1869 process.d = cms.EDProducer("dProducer")
1870 
1871 
1872 process.e = cms.EDProducer("eProducer")
1873 
1874 
1875 process.f = cms.EDProducer("fProducer")
1876 
1877 
1878 process.g = cms.EDProducer("gProducer")
1879 
1880 
1881 process.a = cms.EDAnalyzer("MyAnalyzer")
1882 
1883 
1884 process.task5 = cms.Task()
1885 
1886 
1887 process.task1 = cms.Task(process.task5)
1888 
1889 
1890 process.task3 = cms.Task(process.task1)
1891 
1892 
1893 process.task2 = cms.Task(process.c, process.task3)
1894 
1895 
1896 process.task4 = cms.Task(process.f, process.task2)
1897 
1898 
1899 process.r = cms.Sequence((process.a))
1900 
1901 
1902 process.p = cms.Path(process.a)
1903 
1904 
1905 process.p2 = cms.Path(process.r, process.task1, process.task2)
1906 
1907 
1908 process.schedule = cms.Schedule(*[ process.p2, process.p ], tasks=[process.task3, process.task4, process.task5])
1909 """)
1910  # only tasks
1911  p = Process("test")
1912  p.d = EDProducer("dProducer")
1913  p.e = EDProducer("eProducer")
1914  p.f = EDProducer("fProducer")
1915  p.g = EDProducer("gProducer")
1916  p.task1 = Task(p.d, p.e)
1917  task2 = Task(p.f, p.g)
1918  p.schedule = Schedule(tasks=[p.task1,task2])
1919  d=p.dumpPython()
1920  self.assertEqual(d,
1921  """import FWCore.ParameterSet.Config as cms
1922 
1923 process = cms.Process("test")
1924 
1925 process.d = cms.EDProducer("dProducer")
1926 
1927 
1928 process.e = cms.EDProducer("eProducer")
1929 
1930 
1931 process.f = cms.EDProducer("fProducer")
1932 
1933 
1934 process.g = cms.EDProducer("gProducer")
1935 
1936 
1937 process.task1 = cms.Task(process.d, process.e)
1938 
1939 
1940 process.schedule = cms.Schedule(tasks=[cms.Task(process.f, process.g), process.task1])
1941 """)
1942  # empty schedule
1943  p = Process("test")
1944  p.schedule = Schedule()
1945  d=p.dumpPython()
1946  self.assertEqual(d,
1947  """import FWCore.ParameterSet.Config as cms
1948 
1949 process = cms.Process("test")
1950 
1951 process.schedule = cms.Schedule()
1952 """)
1953 
1954  s = Sequence()
1955  a = EDProducer("A")
1956  s2 = Sequence(a)
1957  s2 += s
1958  process = Process("DUMP")
1959  process.a = a
1960  process.s2 = s2
1961  d=process.dumpPython()
1962  self.assertEqual(d,
1963  """import FWCore.ParameterSet.Config as cms
1964 
1965 process = cms.Process("DUMP")
1966 
1967 process.a = cms.EDProducer("A")
1968 
1969 
1970 process.s2 = cms.Sequence(process.a)
1971 
1972 
1973 """)
1974  s = Sequence()
1975  s1 = Sequence(s)
1976  a = EDProducer("A")
1977  s3 = Sequence(a+a)
1978  s2 = Sequence(a+s3)
1979  s2 += s1
1980  process = Process("DUMP")
1981  process.a = a
1982  process.s2 = s2
1983  d=process.dumpPython()
1984  self.assertEqual(d,
1985  """import FWCore.ParameterSet.Config as cms
1986 
1987 process = cms.Process("DUMP")
1988 
1989 process.a = cms.EDProducer("A")
1990 
1991 
1992 process.s2 = cms.Sequence(process.a+(process.a+process.a))
1993 
1994 
1995 """)
1996 
1997  def testSecSource(self):
1998  p = Process('test')
1999  p.a = SecSource("MySecSource")
2000  self.assertEqual(p.dumpPython().replace('\n',''),'import FWCore.ParameterSet.Config as cmsprocess = cms.Process("test")process.a = cms.SecSource("MySecSource")')
2001 
2003  p = Process('test')
2004  p.a = EDAnalyzer("MyAnalyzer")
2005  old = p.a
2006  p.b = EDAnalyzer("YourAnalyzer")
2007  p.c = EDAnalyzer("OurAnalyzer")
2008  p.d = EDProducer("MyProducer")
2009  old2 = p.d
2010  p.t1 = Task(p.d)
2011  t2 = Task(p.d)
2012  t3 = Task(p.d)
2013  t4 = Task(p.d)
2014  t5 = Task(p.d)
2015  t6 = Task(p.d)
2016  s = Sequence(p.a*p.b)
2017  p.s4 = Sequence(p.a*p.b)
2018  s.associate(t2)
2019  p.s4.associate(t2)
2020  p.p = Path(p.c+s+p.a)
2021  p.e3 = EndPath(p.c+s+p.a)
2022  new = EDAnalyzer("NewAnalyzer")
2023  new2 = EDProducer("NewProducer")
2024  visitor1 = NodeVisitor()
2025  p.p.visit(visitor1)
2026  self.assertTrue(visitor1.modules == set([old,old2,p.b,p.c]))
2027  p.schedule = Schedule(tasks=[t6])
2028  p.globalReplace("a",new)
2029  p.globalReplace("d",new2)
2030  visitor2 = NodeVisitor()
2031  p.p.visit(visitor2)
2032  self.assertTrue(visitor2.modules == set([new,new2,p.b,p.c]))
2033  visitor3 = NodeVisitor()
2034  p.e3.visit(visitor3)
2035  self.assertTrue(visitor3.modules == set([new,new2,p.b,p.c]))
2036  visitor4 = NodeVisitor()
2037  p.s4.visit(visitor4)
2038  self.assertTrue(visitor4.modules == set([new,new2,p.b]))
2039  visitor5 = NodeVisitor()
2040  p.t1.visit(visitor5)
2041  self.assertTrue(visitor5.modules == set([new2]))
2042  visitor6 = NodeVisitor()
2043  listOfTasks = list(p.schedule._tasks)
2044  listOfTasks[0].visit(visitor6)
2045  self.assertTrue(visitor6.modules == set([new2]))
2046 
2047  def testSequence(self):
2048  p = Process('test')
2049  p.a = EDAnalyzer("MyAnalyzer")
2050  p.b = EDAnalyzer("YourAnalyzer")
2051  p.c = EDAnalyzer("OurAnalyzer")
2052  p.s = Sequence(p.a*p.b)
2053  self.assertEqual(str(p.s),'a+b')
2054  self.assertEqual(p.s.label_(),'s')
2055  path = Path(p.c+p.s)
2056  self.assertEqual(str(path),'c+a+b')
2057  p._validateSequence(path, 'p1')
2058  notInProcess = EDAnalyzer('NotInProcess')
2059  p2 = Path(p.c+p.s*notInProcess)
2060  self.assertRaises(RuntimeError, p._validateSequence, p2, 'p2')
2061 
2062  def testSequence2(self):
2063  p = Process('test')
2064  p.a = EDAnalyzer("MyAnalyzer")
2065  p.b = EDAnalyzer("YourAnalyzer")
2066  p.c = EDAnalyzer("OurAnalyzer")
2067  testseq = Sequence(p.a*p.b)
2068  p.s = testseq
2069  #p.y = testseq
2070  self.assertRaises(ValueError, p.__setattr__, "y", testseq)
2071 
2073  service = Service("d")
2074  self.assertFalse(service._inProcess)
2075  process = Process("test")
2076  process.d = service
2077  self.assertTrue(service._inProcess)
2078  service2 = Service("d")
2079  process.d = service2
2080  self.assertFalse(service._inProcess)
2081  self.assertTrue(service2._inProcess)
2082  del process.d
2083  self.assertFalse(service2._inProcess)
2084 
2085  def testTask(self):
2086 
2087  # create some objects to use in tests
2088  edanalyzer = EDAnalyzer("a")
2089  edproducer = EDProducer("b")
2090  edproducer2 = EDProducer("b2")
2091  edproducer3 = EDProducer("b3")
2092  edproducer4 = EDProducer("b4")
2093  edproducer8 = EDProducer("b8")
2094  edproducer9 = EDProducer("b9")
2095  edfilter = EDFilter("c")
2096  service = Service("d")
2097  service3 = Service("d")
2098  essource = ESSource("e")
2099  esproducer = ESProducer("f")
2100  testTask2 = Task()
2101 
2102  # test adding things to Tasks
2103  testTask1 = Task(edproducer, edfilter)
2104  self.assertRaises(RuntimeError, testTask1.add, edanalyzer)
2105  testTask1.add(essource, service)
2106  testTask1.add(essource, esproducer)
2107  testTask1.add(testTask2)
2108  coll = testTask1._collection
2109  self.assertTrue(edproducer in coll)
2110  self.assertTrue(edfilter in coll)
2111  self.assertTrue(service in coll)
2112  self.assertTrue(essource in coll)
2113  self.assertTrue(esproducer in coll)
2114  self.assertTrue(testTask2 in coll)
2115  self.assertTrue(len(coll) == 6)
2116  self.assertTrue(len(testTask2._collection) == 0)
2117 
2118  taskContents = []
2119  for i in testTask1:
2120  taskContents.append(i)
2121  self.assertTrue(taskContents == [edproducer, edfilter, essource, service, esproducer, testTask2])
2122 
2123  # test attaching Task to Process
2124  process = Process("test")
2125 
2126  process.mproducer = edproducer
2127  process.mproducer2 = edproducer2
2128  process.mfilter = edfilter
2129  process.messource = essource
2130  process.mesproducer = esproducer
2131  process.d = service
2132 
2133  testTask3 = Task(edproducer, edproducer2)
2134  testTask1.add(testTask3)
2135  process.myTask1 = testTask1
2136 
2137  # test the validation that occurs when attaching a Task to a Process
2138  # first a case that passes, then one the fails on an EDProducer
2139  # then one that fails on a service
2140  l = set()
2141  visitor = NodeNameVisitor(l)
2142  testTask1.visit(visitor)
2143  self.assertTrue(l == set(['mesproducer', 'mproducer', 'mproducer2', 'mfilter', 'd', 'messource']))
2144  l2 = testTask1.moduleNames
2145  self.assertTrue(l == set(['mesproducer', 'mproducer', 'mproducer2', 'mfilter', 'd', 'messource']))
2146 
2147  testTask4 = Task(edproducer3)
2148  l.clear()
2149  self.assertRaises(RuntimeError, testTask4.visit, visitor)
2150  try:
2151  process.myTask4 = testTask4
2152  self.assertTrue(False)
2153  except RuntimeError:
2154  pass
2155 
2156  testTask5 = Task(service3)
2157  l.clear()
2158  self.assertRaises(RuntimeError, testTask5.visit, visitor)
2159  try:
2160  process.myTask5 = testTask5
2161  self.assertTrue(False)
2162  except RuntimeError:
2163  pass
2164 
2165  process.d = service3
2166  process.myTask5 = testTask5
2167 
2168  # test placement into the Process and the tasks property
2169  expectedDict = { 'myTask1' : testTask1, 'myTask5' : testTask5 }
2170  expectedFixedDict = DictTypes.FixedKeysDict(expectedDict);
2171  self.assertTrue(process.tasks == expectedFixedDict)
2172  self.assertTrue(process.tasks['myTask1'] == testTask1)
2173  self.assertTrue(process.myTask1 == testTask1)
2174 
2175  # test replacing an EDProducer in a Task when calling __settattr__
2176  # for the EDProducer on the Process.
2177  process.mproducer2 = edproducer4
2178  process.d = service
2179  l = list()
2180  visitor1 = ModuleNodeVisitor(l)
2181  testTask1.visit(visitor1)
2182  l.sort()
2183  expectedList = sorted([edproducer,essource,esproducer,service,edfilter,edproducer,edproducer4])
2184  self.assertTrue(expectedList == l)
2185 
2186  process.myTask6 = Task()
2187  process.myTask7 = Task()
2188  process.mproducer8 = edproducer8
2189  process.myTask8 = Task(process.mproducer8)
2190  process.myTask6.add(process.myTask7)
2191  process.myTask7.add(process.myTask8)
2192  process.myTask1.add(process.myTask6)
2193  process.myTask8.add(process.myTask5)
2194 
2195  testDict = process._itemsInDependencyOrder(process.tasks)
2196  expectedLabels = ["myTask5", "myTask8", "myTask7", "myTask6", "myTask1"]
2197  expectedTasks = [process.myTask5, process.myTask8, process.myTask7, process.myTask6, process.myTask1]
2198  index = 0
2199  for testLabel, testTask in testDict.items():
2200  self.assertTrue(testLabel == expectedLabels[index])
2201  self.assertTrue(testTask == expectedTasks[index])
2202  index += 1
2203 
2204  pythonDump = testTask1.dumpPython(PrintOptions())
2205 
2206 
2207  expectedPythonDump = 'cms.Task(process.d, process.mesproducer, process.messource, process.mfilter, process.mproducer, process.mproducer2, process.myTask6)\n'
2208  self.assertTrue(pythonDump == expectedPythonDump)
2209 
2210  process.myTask5 = Task()
2211  process.myTask100 = Task()
2212  process.mproducer9 = edproducer9
2213  sequence1 = Sequence(process.mproducer8, process.myTask1, process.myTask5, testTask2, testTask3)
2214  sequence2 = Sequence(process.mproducer8 + process.mproducer9)
2215  process.sequence3 = Sequence((process.mproducer8 + process.mfilter))
2216  sequence4 = Sequence()
2217  process.path1 = Path(process.mproducer+process.mproducer8+sequence1+sequence2+process.sequence3+sequence4)
2218  process.path1.associate(process.myTask1, process.myTask5, testTask2, testTask3)
2219  process.path11 = Path(process.mproducer+process.mproducer8+sequence1+sequence2+process.sequence3+ sequence4,process.myTask1, process.myTask5, testTask2, testTask3, process.myTask100)
2220  process.path2 = Path(process.mproducer)
2221  process.path3 = Path(process.mproducer9+process.mproducer8,testTask2)
2222 
2223  self.assertTrue(process.path1.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)\n')
2224 
2225  self.assertTrue(process.path11.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask100, process.myTask5)\n')
2226 
2227  # test NodeNameVisitor and moduleNames
2228  l = set()
2229  nameVisitor = NodeNameVisitor(l)
2230  process.path1.visit(nameVisitor)
2231  self.assertTrue(l == set(['mproducer', 'd', 'mesproducer', None, 'mproducer9', 'mproducer8', 'messource', 'mproducer2', 'mfilter']))
2232  self.assertTrue(process.path1.moduleNames() == set(['mproducer', 'd', 'mesproducer', None, 'mproducer9', 'mproducer8', 'messource', 'mproducer2', 'mfilter']))
2233 
2234  # test copy
2235  process.mproducer10 = EDProducer("b10")
2236  process.path21 = process.path11.copy()
2237  process.path21.replace(process.mproducer, process.mproducer10)
2238 
2239  self.assertTrue(process.path11.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask100, process.myTask5)\n')
2240 
2241  # Some peculiarities of the way things work show up here. dumpPython sorts tasks and
2242  # removes duplication at the level of strings. The Task and Sequence objects themselves
2243  # remove duplicate tasks in their contents if the instances are the same (exact same python
2244  # object id which is not the same as the string representation being the same).
2245  # Also note that the mutating visitor replaces sequences and tasks that have
2246  # modified contents with their modified contents, it does not modify the sequence
2247  # or task itself.
2248  self.assertTrue(process.path21.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer10+process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer10), cms.Task(process.d, process.mesproducer, process.messource, process.mfilter, process.mproducer10, process.mproducer2, process.myTask6), process.myTask100, process.myTask5)\n')
2249 
2250  process.path22 = process.path21.copyAndExclude([process.d, process.mesproducer, process.mfilter])
2251  self.assertTrue(process.path22.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer10+process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer10), cms.Task(process.messource, process.mproducer10, process.mproducer2, process.myTask6), process.myTask100, process.myTask5)\n')
2252 
2253  process.path23 = process.path22.copyAndExclude([process.messource, process.mproducer10])
2254  self.assertTrue(process.path23.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.mproducer8, cms.Task(), cms.Task(process.None), cms.Task(process.mproducer2, process.myTask6), process.myTask100, process.myTask5)\n')
2255 
2256  process.a = EDAnalyzer("MyAnalyzer")
2257  process.b = OutputModule("MyOutputModule")
2258  process.c = EDFilter("MyFilter")
2259  process.d = EDProducer("MyProducer")
2260  process.e = ESProducer("MyESProducer")
2261  process.f = ESSource("MyESSource")
2262  process.g = ESProducer("g")
2263  process.path24 = Path(process.a+process.b+process.c+process.d)
2264  process.path25 = process.path24.copyAndExclude([process.a,process.b,process.c])
2265  self.assertTrue(process.path25.dumpPython(None) == 'cms.Path(process.d)\n')
2266  #print process.path3
2267  #print process.dumpPython()
2268 
2269  process.path200 = EndPath(Sequence(process.c,Task(process.e)))
2270  process.path200.replace(process.c,process.b)
2271  process.path200.replace(process.e,process.f)
2272  self.assertEqual(process.path200.dumpPython(None), "cms.EndPath(process.b, cms.Task(process.f))\n")
2273  process.path200.replace(process.b,process.c)
2274  process.path200.replace(process.f,process.e)
2275  self.assertEqual(process.path200.dumpPython(None), "cms.EndPath(process.c, cms.Task(process.e))\n")
2276  process.path200.replace(process.c,process.a)
2277  process.path200.replace(process.e,process.g)
2278  self.assertEqual(process.path200.dumpPython(None), "cms.EndPath(process.a, cms.Task(process.g))\n")
2279  process.path200.replace(process.a,process.c)
2280  process.path200.replace(process.g,process.e)
2281  self.assertEqual(process.path200.dumpPython(None), "cms.EndPath(process.c, cms.Task(process.e))\n")
2282 
2283 
2284  def testPath(self):
2285  p = Process("test")
2286  p.a = EDAnalyzer("MyAnalyzer")
2287  p.b = EDAnalyzer("YourAnalyzer")
2288  p.c = EDAnalyzer("OurAnalyzer")
2289  path = Path(p.a)
2290  path *= p.b
2291  path += p.c
2292  self.assertEqual(str(path),'a+b+c')
2293  path = Path(p.a*p.b+p.c)
2294  self.assertEqual(str(path),'a+b+c')
2295 # path = Path(p.a)*p.b+p.c #This leads to problems with sequences
2296 # self.assertEqual(str(path),'((a*b)+c)')
2297  path = Path(p.a+ p.b*p.c)
2298  self.assertEqual(str(path),'a+b+c')
2299  path = Path(p.a*(p.b+p.c))
2300  self.assertEqual(str(path),'a+b+c')
2301  path = Path(p.a*(p.b+~p.c))
2302  pathx = Path(p.a*(p.b+ignore(p.c)))
2303  self.assertEqual(str(path),'a+b+~c')
2304  p.es = ESProducer("AnESProducer")
2305  self.assertRaises(TypeError,Path,p.es)
2306 
2307  t = Path()
2308  self.assertTrue(t.dumpPython(PrintOptions()) == 'cms.Path()\n')
2309 
2310  t = Path(p.a)
2311  self.assertTrue(t.dumpPython(PrintOptions()) == 'cms.Path(process.a)\n')
2312 
2313  t = Path(Task())
2314  self.assertTrue(t.dumpPython(PrintOptions()) == 'cms.Path(cms.Task())\n')
2315 
2316  t = Path(p.a, Task())
2317  self.assertTrue(t.dumpPython(PrintOptions()) == 'cms.Path(process.a, cms.Task())\n')
2318 
2319  p.prod = EDProducer("prodName")
2320  p.t1 = Task(p.prod)
2321  t = Path(p.a, p.t1, Task(), p.t1)
2322  self.assertTrue(t.dumpPython(PrintOptions()) == 'cms.Path(process.a, cms.Task(), process.t1)\n')
2323 
2325  p = Process("test")
2326  a = EDAnalyzer("MyAnalyzer")
2327  p.a = a
2328  a.setLabel("a")
2329  b = EDAnalyzer("YOurAnalyzer")
2330  p.b = b
2331  b.setLabel("b")
2332  path = Path(a * b)
2333  p.path = Path(p.a*p.b)
2334  lookuptable = {id(a): p.a, id(b): p.b}
2335  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
2336  #lookuptable = p._cloneToObjectDict
2337  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
2338  self.assertEqual(str(path),str(p.path))
2339 
2340  def testContains(self):
2341 
2342  a = EDProducer("a")
2343  b = EDProducer("b")
2344  c = EDProducer("c")
2345  d = EDProducer("d")
2346  e = EDProducer("e")
2347  f = EDProducer("f")
2348  g = EDProducer("g")
2349  h = EDProducer("h")
2350  i = EDProducer("i")
2351  j = EDProducer("j")
2352  k = EDProducer("k")
2353  l = EDProducer("l")
2354  m = EDProducer("m")
2355  n = EDProducer("n")
2356 
2357  seq1 = Sequence(e)
2358  task1 = Task(g)
2359  path = Path(a * c * seq1, task1)
2360 
2361  self.assertTrue(path.contains(a))
2362  self.assertFalse(path.contains(b))
2363  self.assertTrue(path.contains(c))
2364  self.assertFalse(path.contains(d))
2365  self.assertTrue(path.contains(e))
2366  self.assertFalse(path.contains(f))
2367  self.assertTrue(path.contains(g))
2368 
2369  endpath = EndPath(h * i)
2370  self.assertFalse(endpath.contains(b))
2371  self.assertTrue(endpath.contains(i))
2372 
2373  seq = Sequence(a * c)
2374  self.assertFalse(seq.contains(b))
2375  self.assertTrue(seq.contains(c))
2376 
2377  task2 = Task(l)
2378  task = Task(j, k, task2)
2379  self.assertFalse(task.contains(b))
2380  self.assertTrue(task.contains(j))
2381  self.assertTrue(task.contains(k))
2382  self.assertTrue(task.contains(l))
2383 
2384  task3 = Task(m)
2385  path2 = Path(n)
2386  sch = Schedule(path, path2, tasks=[task,task3])
2387  self.assertFalse(sch.contains(b))
2388  self.assertTrue(sch.contains(a))
2389  self.assertTrue(sch.contains(c))
2390  self.assertTrue(sch.contains(e))
2391  self.assertTrue(sch.contains(g))
2392  self.assertTrue(sch.contains(n))
2393  self.assertTrue(sch.contains(j))
2394  self.assertTrue(sch.contains(k))
2395  self.assertTrue(sch.contains(l))
2396  self.assertTrue(sch.contains(m))
2397 
2398  def testSchedule(self):
2399  p = Process("test")
2400  p.a = EDAnalyzer("MyAnalyzer")
2401  p.b = EDAnalyzer("YourAnalyzer")
2402  p.c = EDAnalyzer("OurAnalyzer")
2403  p.d = EDAnalyzer("OurAnalyzer")
2404  p.path1 = Path(p.a)
2405  p.path2 = Path(p.b)
2406  p.path3 = Path(p.d)
2407 
2408  s = Schedule(p.path1,p.path2)
2409  self.assertEqual(s[0],p.path1)
2410  self.assertEqual(s[1],p.path2)
2411  p.schedule = s
2412  self.assert_('b' in p.schedule.moduleNames())
2413  self.assert_(hasattr(p, 'b'))
2414  self.assert_(hasattr(p, 'c'))
2415  self.assert_(hasattr(p, 'd'))
2416  self.assert_(hasattr(p, 'path1'))
2417  self.assert_(hasattr(p, 'path2'))
2418  self.assert_(hasattr(p, 'path3'))
2419  p.prune()
2420  self.assert_('b' in p.schedule.moduleNames())
2421  self.assert_(hasattr(p, 'b'))
2422  self.assert_(not hasattr(p, 'c'))
2423  self.assert_(not hasattr(p, 'd'))
2424  self.assert_(hasattr(p, 'path1'))
2425  self.assert_(hasattr(p, 'path2'))
2426  self.assert_(not hasattr(p, 'path3'))
2427 
2428  self.assertTrue(len(p.schedule._tasks) == 0)
2429 
2430  p = Process("test")
2431  p.a = EDAnalyzer("MyAnalyzer")
2432  p.b = EDAnalyzer("YourAnalyzer")
2433  p.c = EDAnalyzer("OurAnalyzer")
2434  p.d = EDAnalyzer("dAnalyzer")
2435  p.e = EDProducer("eProducer")
2436  p.f = EDProducer("fProducer")
2437  p.Tracer = Service("Tracer")
2438  p.path1 = Path(p.a)
2439  p.path2 = Path(p.b)
2440  p.path3 = Path(p.d)
2441  p.task1 = Task(p.e)
2442  p.task2 = Task(p.f, p.Tracer)
2443  s = Schedule(p.path1,p.path2,tasks=[p.task1,p.task2,p.task1])
2444  self.assertEqual(s[0],p.path1)
2445  self.assertEqual(s[1],p.path2)
2446  self.assertTrue(len(s._tasks) == 2)
2447  self.assertTrue(p.task1 in s._tasks)
2448  self.assertTrue(p.task2 in s._tasks)
2449  listOfTasks = list(s._tasks)
2450  self.assertTrue(len(listOfTasks) == 2)
2451  self.assertTrue(p.task1 == listOfTasks[0])
2452  self.assertTrue(p.task2 == listOfTasks[1])
2453  p.schedule = s
2454  self.assert_('b' in p.schedule.moduleNames())
2455 
2456  process2 = Process("test")
2457  process2.a = EDAnalyzer("MyAnalyzer")
2458  process2.e = EDProducer("eProducer")
2459  process2.path1 = Path(process2.a)
2460  process2.task1 = Task(process2.e)
2461  process2.schedule = Schedule(process2.path1,tasks=process2.task1)
2462  listOfTasks = list(process2.schedule._tasks)
2463  self.assertTrue(listOfTasks[0] == process2.task1)
2464 
2465  # test Schedule copy
2466  s2 = s.copy()
2467  self.assertEqual(s2[0],p.path1)
2468  self.assertEqual(s2[1],p.path2)
2469  self.assertTrue(len(s2._tasks) == 2)
2470  self.assertTrue(p.task1 in s2._tasks)
2471  self.assertTrue(p.task2 in s2._tasks)
2472  listOfTasks = list(s2._tasks)
2473  self.assertTrue(len(listOfTasks) == 2)
2474  self.assertTrue(p.task1 == listOfTasks[0])
2475  self.assertTrue(p.task2 == listOfTasks[1])
2476 
2477  names = s.moduleNames()
2478  self.assertTrue(names == set(['a', 'b', 'e', 'Tracer', 'f']))
2479  #adding a path not attached to the Process should cause an exception
2480  p = Process("test")
2481  p.a = EDAnalyzer("MyAnalyzer")
2482  path1 = Path(p.a)
2483  s = Schedule(path1)
2484  self.assertRaises(RuntimeError, lambda : p.setSchedule_(s) )
2485 
2486  #make sure anonymous sequences work
2487  p = Process("test")
2488  p.a = EDAnalyzer("MyAnalyzer")
2489  p.b = EDAnalyzer("MyOtherAnalyzer")
2490  p.c = EDProducer("MyProd")
2491  path1 = Path(p.c*Sequence(p.a+p.b))
2492  s = Schedule(path1)
2493  self.assert_('a' in s.moduleNames())
2494  self.assert_('b' in s.moduleNames())
2495  self.assert_('c' in s.moduleNames())
2496  p.path1 = path1
2497  p.schedule = s
2498  p.prune()
2499  self.assert_('a' in s.moduleNames())
2500  self.assert_('b' in s.moduleNames())
2501  self.assert_('c' in s.moduleNames())
2502 
2504  p = Process("test")
2505  p.a = EDAnalyzer("MyAnalyzer")
2506  p.b = EDAnalyzer("YourAnalyzer")
2507  p.c = EDAnalyzer("OurAnalyzer")
2508  p.path1 = Path(p.a)
2509  p.path2 = Path(p.b)
2510  self.assert_(p.schedule is None)
2511  pths = p.paths
2512  keys = pths.keys()
2513  self.assertEqual(pths[keys[0]],p.path1)
2514  self.assertEqual(pths[keys[1]],p.path2)
2515  p.prune()
2516  self.assert_(hasattr(p, 'a'))
2517  self.assert_(hasattr(p, 'b'))
2518  self.assert_(not hasattr(p, 'c'))
2519  self.assert_(hasattr(p, 'path1'))
2520  self.assert_(hasattr(p, 'path2'))
2521 
2522 
2523  p = Process("test")
2524  p.a = EDAnalyzer("MyAnalyzer")
2525  p.b = EDAnalyzer("YourAnalyzer")
2526  p.c = EDAnalyzer("OurAnalyzer")
2527  p.path2 = Path(p.b)
2528  p.path1 = Path(p.a)
2529  self.assert_(p.schedule is None)
2530  pths = p.paths
2531  keys = pths.keys()
2532  self.assertEqual(pths[keys[1]],p.path1)
2533  self.assertEqual(pths[keys[0]],p.path2)
2534 
2535 
2536  def testUsing(self):
2537  p = Process('test')
2538  p.block = PSet(a = int32(1))
2539  p.modu = EDAnalyzer('Analyzer', p.block, b = int32(2))
2540  self.assertEqual(p.modu.a.value(),1)
2541  self.assertEqual(p.modu.b.value(),2)
2542 
2543  def testOverride(self):
2544  p = Process('test')
2545  a = EDProducer("A", a1=int32(0))
2546  self.assert_(not a.isModified())
2547  a.a1 = 1
2548  self.assert_(a.isModified())
2549  p.a = a
2550  self.assertEqual(p.a.a1.value(), 1)
2551  # try adding an unmodified module.
2552  # should accept it
2553  p.a = EDProducer("A", a1=int32(2))
2554  self.assertEqual(p.a.a1.value(), 2)
2555  # try adding a modified module. Should throw
2556  # no longer, since the same (modified) say, geometry
2557  # could come from more than one cff
2558  b = EDProducer("A", a1=int32(3))
2559  b.a1 = 4
2560  #self.assertRaises(RuntimeError, setattr, *(p,'a',b))
2561  ps1 = PSet(a = int32(1))
2562  ps2 = PSet(a = int32(2))
2563  self.assertRaises(ValueError, EDProducer, 'C', ps1, ps2)
2564  self.assertRaises(ValueError, EDProducer, 'C', ps1, a=int32(3))
2565 
2566  def testExamples(self):
2567  p = Process("Test")
2568  p.source = Source("PoolSource",fileNames = untracked(string("file:reco.root")))
2569  p.foos = EDProducer("FooProducer")
2570  p.bars = EDProducer("BarProducer", foos=InputTag("foos"))
2571  p.out = OutputModule("PoolOutputModule",fileName=untracked(string("file:foos.root")))
2572  p.bars.foos = 'Foosball'
2573  self.assertEqual(p.bars.foos, InputTag('Foosball'))
2574  p.p = Path(p.foos*p.bars)
2575  p.e = EndPath(p.out)
2576  p.add_(Service("MessageLogger"))
2577 
2578  def testPrefers(self):
2579  p = Process("Test")
2580  p.add_(ESSource("ForceSource"))
2581  p.juicer = ESProducer("JuicerProducer")
2582  p.prefer("ForceSource")
2583  p.prefer("juicer")
2584  self.assertEqual(p.dumpConfig(),
2585 """process Test = {
2586  es_module juicer = JuicerProducer {
2587  }
2588  es_source = ForceSource {
2589  }
2590  es_prefer = ForceSource {
2591  }
2592  es_prefer juicer = JuicerProducer {
2593  }
2594 }
2595 """)
2596  p.prefer("juicer",fooRcd=vstring("Foo"))
2597  self.assertEqual(p.dumpConfig(),
2598 """process Test = {
2599  es_module juicer = JuicerProducer {
2600  }
2601  es_source = ForceSource {
2602  }
2603  es_prefer = ForceSource {
2604  }
2605  es_prefer juicer = JuicerProducer {
2606  vstring fooRcd = {
2607  'Foo'
2608  }
2609 
2610  }
2611 }
2612 """)
2613  self.assertEqual(p.dumpPython(),
2614 """import FWCore.ParameterSet.Config as cms
2615 
2616 process = cms.Process("Test")
2617 
2618 process.juicer = cms.ESProducer("JuicerProducer")
2619 
2620 
2621 process.ForceSource = cms.ESSource("ForceSource")
2622 
2623 
2624 process.prefer("ForceSource")
2625 
2626 process.prefer("juicer",
2627  fooRcd = cms.vstring('Foo')
2628 )
2629 
2630 """)
2631 
2632  def testFreeze(self):
2633  process = Process("Freeze")
2634  m = EDProducer("M", p=PSet(i = int32(1)))
2635  m.p.i = 2
2636  process.m = m
2637  # should be frozen
2638  #self.assertRaises(ValueError, setattr, m.p, 'i', 3)
2639  #self.assertRaises(ValueError, setattr, m, 'p', PSet(i=int32(1)))
2640  #self.assertRaises(ValueError, setattr, m.p, 'j', 1)
2641  #self.assertRaises(ValueError, setattr, m, 'j', 1)
2642  # But OK to change through the process
2643  process.m.p.i = 4
2644  self.assertEqual(process.m.p.i.value(), 4)
2645  process.m.p = PSet(j=int32(1))
2646  # should work to clone it, though
2647  m2 = m.clone(p = PSet(i = int32(5)), j = int32(8))
2648  m2.p.i = 6
2649  m2.j = 8
2650  def testSubProcess(self):
2651  process = Process("Parent")
2652  subProcess = Process("Child")
2653  subProcess.a = EDProducer("A")
2654  subProcess.p = Path(subProcess.a)
2655  subProcess.add_(Service("Foo"))
2656  process.addSubProcess(SubProcess(subProcess))
2657  d = process.dumpPython()
2658  equalD ="""import FWCore.ParameterSet.Config as cms
2659 
2660 process = cms.Process("Parent")
2661 
2662 parentProcess = process
2663 import FWCore.ParameterSet.Config as cms
2664 
2665 process = cms.Process("Child")
2666 
2667 process.a = cms.EDProducer("A")
2668 
2669 
2670 process.Foo = cms.Service("Foo")
2671 
2672 
2673 process.p = cms.Path(process.a)
2674 
2675 
2676 childProcess = process
2677 process = parentProcess
2678 process.addSubProcess(cms.SubProcess(process = childProcess, SelectEvents = cms.untracked.PSet(
2679 
2680 ), outputCommands = cms.untracked.vstring()))
2681 
2682 """
2683  equalD = equalD.replace("parentProcess","parentProcess"+str(hash(process.subProcesses_()[0])))
2684  self.assertEqual(d,equalD)
2685  p = TestMakePSet()
2686  process.fillProcessDesc(p)
2687  self.assertEqual((True,['a']),p.values["subProcesses"][1][0].values["process"][1].values['@all_modules'])
2688  self.assertEqual((True,['p']),p.values["subProcesses"][1][0].values["process"][1].values['@paths'])
2689  self.assertEqual({'@service_type':(True,'Foo')}, p.values["subProcesses"][1][0].values["process"][1].values["services"][1][0].values)
2690  def testRefToPSet(self):
2691  proc = Process("test")
2692  proc.top = PSet(a = int32(1))
2693  proc.ref = PSet(refToPSet_ = string("top"))
2694  proc.ref2 = PSet( a = int32(1), b = PSet( refToPSet_ = string("top")))
2695  proc.ref3 = PSet(refToPSet_ = string("ref"))
2696  proc.ref4 = VPSet(PSet(refToPSet_ = string("top")),
2697  PSet(refToPSet_ = string("ref2")))
2698  p = TestMakePSet()
2699  proc.fillProcessDesc(p)
2700  self.assertEqual((True,1),p.values["ref"][1].values["a"])
2701  self.assertEqual((True,1),p.values["ref3"][1].values["a"])
2702  self.assertEqual((True,1),p.values["ref2"][1].values["a"])
2703  self.assertEqual((True,1),p.values["ref2"][1].values["b"][1].values["a"])
2704  self.assertEqual((True,1),p.values["ref4"][1][0].values["a"])
2705  self.assertEqual((True,1),p.values["ref4"][1][1].values["a"])
2707  proc = Process("test")
2708  proc.sp = SwitchProducerTest(test2 = EDProducer("Foo",
2709  a = int32(1),
2710  b = PSet(c = int32(2))),
2711  test1 = EDProducer("Bar",
2712  aa = int32(11),
2713  bb = PSet(cc = int32(12))))
2714  proc.a = EDProducer("A")
2715  proc.s = Sequence(proc.a + proc.sp)
2716  proc.t = Task(proc.a, proc.sp)
2717  proc.p = Path()
2718  proc.p.associate(proc.t)
2719  p = TestMakePSet()
2720  proc.fillProcessDesc(p)
2721  self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"])
2722  self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"])
2723  self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"])
2724  self.assertEqual((True, ["sp@test1", "sp@test2"]), p.values["sp"][1].values["@all_cases"])
2725  self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
2726  self.assertEqual(["a", "sp", "sp@test1", "sp@test2"], p.values["@all_modules"][1])
2727  self.assertEqual((True,"EDProducer"), p.values["sp@test1"][1].values["@module_edm_type"])
2728  self.assertEqual((True,"Bar"), p.values["sp@test1"][1].values["@module_type"])
2729  self.assertEqual((True,"EDProducer"), p.values["sp@test2"][1].values["@module_edm_type"])
2730  self.assertEqual((True,"Foo"), p.values["sp@test2"][1].values["@module_type"])
2731  dump = proc.dumpPython()
2732  self.assertEqual(dump.find('@'), -1)
2733  self.assertEqual(specialImportRegistry.getSpecialImports(), ["from test import SwitchProducerTest"])
2734  self.assertTrue(dump.find("\nfrom test import SwitchProducerTest\n") != -1)
2735 
2736  # EDAlias as non-chosen case
2737  proc = Process("test")
2738  proc.sp = SwitchProducerTest(test2 = EDProducer("Foo",
2739  a = int32(1),
2740  b = PSet(c = int32(2))),
2741  test1 = EDAlias(a = VPSet(PSet(type = string("Bar")))))
2742  proc.a = EDProducer("A")
2743  proc.s = Sequence(proc.a + proc.sp)
2744  proc.t = Task(proc.a, proc.sp)
2745  proc.p = Path()
2746  proc.p.associate(proc.t)
2747  p = TestMakePSet()
2748  proc.fillProcessDesc(p)
2749  self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"])
2750  self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"])
2751  self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"])
2752  self.assertEqual((True, ["sp@test1", "sp@test2"]), p.values["sp"][1].values["@all_cases"])
2753  self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
2754  self.assertEqual(["a", "sp", "sp@test2"], p.values["@all_modules"][1])
2755  self.assertEqual(["sp@test1"], p.values["@all_aliases"][1])
2756  self.assertEqual((True,"EDProducer"), p.values["sp@test2"][1].values["@module_edm_type"])
2757  self.assertEqual((True,"Foo"), p.values["sp@test2"][1].values["@module_type"])
2758  self.assertEqual((True,"EDAlias"), p.values["sp@test1"][1].values["@module_edm_type"])
2759  self.assertEqual((True,"Bar"), p.values["sp@test1"][1].values["a"][1][0].values["type"])
2760 
2761  # EDAlias as chosen case
2762  proc = Process("test")
2763  proc.sp = SwitchProducerTest(test1 = EDProducer("Foo",
2764  a = int32(1),
2765  b = PSet(c = int32(2))),
2766  test2 = EDAlias(a = VPSet(PSet(type = string("Bar")))))
2767  proc.a = EDProducer("A")
2768  proc.s = Sequence(proc.a + proc.sp)
2769  proc.t = Task(proc.a, proc.sp)
2770  proc.p = Path()
2771  proc.p.associate(proc.t)
2772  p = TestMakePSet()
2773  proc.fillProcessDesc(p)
2774  self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"])
2775  self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"])
2776  self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"])
2777  self.assertEqual((True, ["sp@test1", "sp@test2"]), p.values["sp"][1].values["@all_cases"])
2778  self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
2779  self.assertEqual(["a", "sp", "sp@test1"], p.values["@all_modules"][1])
2780  self.assertEqual(["sp@test2"], p.values["@all_aliases"][1])
2781  self.assertEqual((True,"EDProducer"), p.values["sp@test1"][1].values["@module_edm_type"])
2782  self.assertEqual((True,"Foo"), p.values["sp@test1"][1].values["@module_type"])
2783  self.assertEqual((True,"EDAlias"), p.values["sp@test2"][1].values["@module_edm_type"])
2784  self.assertEqual((True,"Bar"), p.values["sp@test2"][1].values["a"][1][0].values["type"])
2785 
2786  def testPrune(self):
2787  p = Process("test")
2788  p.a = EDAnalyzer("MyAnalyzer")
2789  p.b = EDAnalyzer("YourAnalyzer")
2790  p.c = EDAnalyzer("OurAnalyzer")
2791  p.d = EDAnalyzer("OurAnalyzer")
2792  p.s = Sequence(p.d)
2793  p.path1 = Path(p.a)
2794  p.path2 = Path(p.b)
2795  self.assert_(p.schedule is None)
2796  pths = p.paths
2797  keys = pths.keys()
2798  self.assertEqual(pths[keys[0]],p.path1)
2799  self.assertEqual(pths[keys[1]],p.path2)
2800  p.pset1 = PSet(parA = string("pset1"))
2801  p.pset2 = untracked.PSet(parA = string("pset2"))
2802  p.vpset1 = VPSet()
2803  p.vpset2 = untracked.VPSet()
2804  p.prune()
2805  self.assert_(hasattr(p, 'a'))
2806  self.assert_(hasattr(p, 'b'))
2807  self.assert_(not hasattr(p, 'c'))
2808  self.assert_(not hasattr(p, 'd'))
2809  self.assert_(not hasattr(p, 's'))
2810  self.assert_(hasattr(p, 'path1'))
2811  self.assert_(hasattr(p, 'path2'))
2812 # self.assert_(not hasattr(p, 'pset1'))
2813 # self.assert_(hasattr(p, 'pset2'))
2814 # self.assert_(not hasattr(p, 'vpset1'))
2815 # self.assert_(not hasattr(p, 'vpset2'))
2816 
2817  p = Process("test")
2818  p.a = EDAnalyzer("MyAnalyzer")
2819  p.b = EDAnalyzer("YourAnalyzer")
2820  p.c = EDAnalyzer("OurAnalyzer")
2821  p.d = EDAnalyzer("OurAnalyzer")
2822  p.e = EDAnalyzer("OurAnalyzer")
2823  p.s = Sequence(p.d)
2824  p.s2 = Sequence(p.b)
2825  p.s3 = Sequence(p.e)
2826  p.path1 = Path(p.a)
2827  p.path2 = Path(p.b)
2828  p.path3 = Path(p.b+p.s2)
2829  p.path4 = Path(p.b+p.s3)
2830  p.schedule = Schedule(p.path1,p.path2,p.path3)
2831  pths = p.paths
2832  keys = pths.keys()
2833  self.assertEqual(pths[keys[0]],p.path1)
2834  self.assertEqual(pths[keys[1]],p.path2)
2835  p.prune()
2836  self.assert_(hasattr(p, 'a'))
2837  self.assert_(hasattr(p, 'b'))
2838  self.assert_(not hasattr(p, 'c'))
2839  self.assert_(not hasattr(p, 'd'))
2840  self.assert_(not hasattr(p, 'e'))
2841  self.assert_(not hasattr(p, 's'))
2842  self.assert_(hasattr(p, 's2'))
2843  self.assert_(not hasattr(p, 's3'))
2844  self.assert_(hasattr(p, 'path1'))
2845  self.assert_(hasattr(p, 'path2'))
2846  self.assert_(hasattr(p, 'path3'))
2847  self.assert_(not hasattr(p, 'path4'))
2848  #test SequencePlaceholder
2849  p = Process("test")
2850  p.a = EDAnalyzer("MyAnalyzer")
2851  p.b = EDAnalyzer("YourAnalyzer")
2852  p.s = Sequence(SequencePlaceholder("a")+p.b)
2853  p.pth = Path(p.s)
2854  p.prune()
2855  self.assert_(hasattr(p, 'a'))
2856  self.assert_(hasattr(p, 'b'))
2857  self.assert_(hasattr(p, 's'))
2858  self.assert_(hasattr(p, 'pth'))
2859  #test unresolved SequencePlaceholder
2860  p = Process("test")
2861  p.b = EDAnalyzer("YourAnalyzer")
2862  p.s = Sequence(SequencePlaceholder("a")+p.b)
2863  p.pth = Path(p.s)
2864  p.prune(keepUnresolvedSequencePlaceholders=True)
2865  self.assert_(hasattr(p, 'b'))
2866  self.assert_(hasattr(p, 's'))
2867  self.assert_(hasattr(p, 'pth'))
2868  self.assertEqual(p.s.dumpPython(''),'cms.Sequence(cms.SequencePlaceholder("a")+process.b)\n')
2870  p = Process("test")
2871  p.a = EDProducer("ma")
2872  p.b = EDAnalyzer("mb")
2873  p.t1 = Task(TaskPlaceholder("c"))
2874  p.t2 = Task(p.a, TaskPlaceholder("d"), p.t1)
2875  p.t3 = Task(TaskPlaceholder("e"))
2876  p.path1 = Path(p.b, p.t2, p.t3)
2877  p.t5 = Task(p.a, TaskPlaceholder("g"), TaskPlaceholder("t4"))
2878  p.t4 = Task(TaskPlaceholder("f"))
2879  p.endpath1 = EndPath(p.b, p.t5)
2880  p.t6 = Task(TaskPlaceholder("h"))
2881  p.t7 = Task(p.a, TaskPlaceholder("i"), p.t6)
2882  p.t8 = Task(TaskPlaceholder("j"))
2883  p.schedule = Schedule(p.path1, p.endpath1,tasks=[p.t7,p.t8])
2884  p.c = EDProducer("mc")
2885  p.d = EDProducer("md")
2886  p.e = EDProducer("me")
2887  p.f = EDProducer("mf")
2888  p.g = EDProducer("mg")
2889  p.h = EDProducer("mh")
2890  p.i = EDProducer("mi")
2891  p.j = EDProducer("mj")
2892  self.assertEqual(p.dumpPython(),
2893 """import FWCore.ParameterSet.Config as cms
2894 
2895 process = cms.Process("test")
2896 
2897 process.a = cms.EDProducer("ma")
2898 
2899 
2900 process.c = cms.EDProducer("mc")
2901 
2902 
2903 process.d = cms.EDProducer("md")
2904 
2905 
2906 process.e = cms.EDProducer("me")
2907 
2908 
2909 process.f = cms.EDProducer("mf")
2910 
2911 
2912 process.g = cms.EDProducer("mg")
2913 
2914 
2915 process.h = cms.EDProducer("mh")
2916 
2917 
2918 process.i = cms.EDProducer("mi")
2919 
2920 
2921 process.j = cms.EDProducer("mj")
2922 
2923 
2924 process.b = cms.EDAnalyzer("mb")
2925 
2926 
2927 process.t8 = cms.Task(cms.TaskPlaceholder("j"))
2928 
2929 
2930 process.t6 = cms.Task(cms.TaskPlaceholder("h"))
2931 
2932 
2933 process.t7 = cms.Task(cms.TaskPlaceholder("i"), process.a, process.t6)
2934 
2935 
2936 process.t4 = cms.Task(cms.TaskPlaceholder("f"))
2937 
2938 
2939 process.t5 = cms.Task(cms.TaskPlaceholder("g"), cms.TaskPlaceholder("t4"), process.a)
2940 
2941 
2942 process.t3 = cms.Task(cms.TaskPlaceholder("e"))
2943 
2944 
2945 process.t1 = cms.Task(cms.TaskPlaceholder("c"))
2946 
2947 
2948 process.t2 = cms.Task(cms.TaskPlaceholder("d"), process.a, process.t1)
2949 
2950 
2951 process.path1 = cms.Path(process.b, process.t2, process.t3)
2952 
2953 
2954 process.endpath1 = cms.EndPath(process.b, process.t5)
2955 
2956 
2957 process.schedule = cms.Schedule(*[ process.path1, process.endpath1 ], tasks=[process.t7, process.t8])
2958 """)
2959  p.resolve()
2960  self.assertEqual(p.dumpPython(),
2961 """import FWCore.ParameterSet.Config as cms
2962 
2963 process = cms.Process("test")
2964 
2965 process.a = cms.EDProducer("ma")
2966 
2967 
2968 process.c = cms.EDProducer("mc")
2969 
2970 
2971 process.d = cms.EDProducer("md")
2972 
2973 
2974 process.e = cms.EDProducer("me")
2975 
2976 
2977 process.f = cms.EDProducer("mf")
2978 
2979 
2980 process.g = cms.EDProducer("mg")
2981 
2982 
2983 process.h = cms.EDProducer("mh")
2984 
2985 
2986 process.i = cms.EDProducer("mi")
2987 
2988 
2989 process.j = cms.EDProducer("mj")
2990 
2991 
2992 process.b = cms.EDAnalyzer("mb")
2993 
2994 
2995 process.t8 = cms.Task(process.j)
2996 
2997 
2998 process.t6 = cms.Task(process.h)
2999 
3000 
3001 process.t7 = cms.Task(process.a, process.i, process.t6)
3002 
3003 
3004 process.t4 = cms.Task(process.f)
3005 
3006 
3007 process.t5 = cms.Task(process.a, process.g, process.t4)
3008 
3009 
3010 process.t3 = cms.Task(process.e)
3011 
3012 
3013 process.t1 = cms.Task(process.c)
3014 
3015 
3016 process.t2 = cms.Task(process.a, process.d, process.t1)
3017 
3018 
3019 process.path1 = cms.Path(process.b, process.t2, process.t3)
3020 
3021 
3022 process.endpath1 = cms.EndPath(process.b, process.t5)
3023 
3024 
3025 process.schedule = cms.Schedule(*[ process.path1, process.endpath1 ], tasks=[process.t7, process.t8])
3026 """)
3027 
3028  def testDelete(self):
3029  p = Process("test")
3030  p.a = EDAnalyzer("MyAnalyzer")
3031  p.b = EDAnalyzer("YourAnalyzer")
3032  p.c = EDAnalyzer("OurAnalyzer")
3033  p.d = EDAnalyzer("OurAnalyzer")
3034  p.e = EDAnalyzer("OurAnalyzer")
3035  p.f = EDAnalyzer("OurAnalyzer")
3036  p.g = EDProducer("OurProducer")
3037  p.h = EDProducer("YourProducer")
3038  p.t1 = Task(p.g, p.h)
3039  t2 = Task(p.g, p.h)
3040  t3 = Task(p.g, p.h)
3041  p.s = Sequence(p.d+p.e)
3042  p.path1 = Path(p.a+p.f+p.s,t2)
3043  p.endpath1 = EndPath(p.b+p.f)
3044  p.schedule = Schedule(tasks=[t3])
3045  self.assertTrue(hasattr(p, 'f'))
3046  self.assertTrue(hasattr(p, 'g'))
3047  del p.e
3048  del p.f
3049  del p.g
3050  self.assertFalse(hasattr(p, 'f'))
3051  self.assertFalse(hasattr(p, 'g'))
3052  self.assertTrue(p.t1.dumpPython(None) == 'cms.Task(process.h)\n')
3053  self.assertTrue(p.s.dumpPython(None) == 'cms.Sequence(process.d)\n')
3054  self.assertTrue(p.path1.dumpPython(None) == 'cms.Path(process.a+process.s, cms.Task(process.h))\n')
3055  self.assertTrue(p.endpath1.dumpPython(None) == 'cms.EndPath(process.b)\n')
3056  del p.s
3057  self.assertTrue(p.path1.dumpPython(None) == 'cms.Path(process.a+(process.d), cms.Task(process.h))\n')
3058  self.assertTrue(p.schedule_().dumpPython(None) == 'cms.Schedule(tasks=[cms.Task(process.h)])\n')
3059  def testModifier(self):
3060  m1 = Modifier()
3061  p = Process("test",m1)
3062  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
3063  def _mod_fred(obj):
3064  obj.fred = 2
3065  m1.toModify(p.a,_mod_fred)
3066  self.assertEqual(p.a.fred.value(),2)
3067  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
3068  m1.toModify(p.b, wilma = 2)
3069  self.assertEqual(p.b.wilma.value(),2)
3070  self.assert_(p.isUsingModifier(m1))
3071  #check that Modifier not attached to a process doesn't run
3072  m1 = Modifier()
3073  p = Process("test")
3074  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
3075  m1.toModify(p.a,_mod_fred)
3076  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
3077  m1.toModify(p.b, wilma = 2)
3078  self.assertEqual(p.a.fred.value(),1)
3079  self.assertEqual(p.b.wilma.value(),1)
3080  self.assertEqual(p.isUsingModifier(m1),False)
3081  #make sure clones get the changes
3082  m1 = Modifier()
3083  p = Process("test",m1)
3084  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3085  m1.toModify(p.a, fred = int32(2))
3086  p.b = p.a.clone(wilma = int32(3))
3087  self.assertEqual(p.a.fred.value(),2)
3088  self.assertEqual(p.a.wilma.value(),1)
3089  self.assertEqual(p.b.fred.value(),2)
3090  self.assertEqual(p.b.wilma.value(),3)
3091  #test removal of parameter
3092  m1 = Modifier()
3093  p = Process("test",m1)
3094  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1), fintstones = PSet(fred = int32(1)))
3095  m1.toModify(p.a, fred = None, fintstones = dict(fred = None))
3096  self.assertEqual(hasattr(p.a, "fred"), False)
3097  self.assertEqual(hasattr(p.a.fintstones, "fred"), False)
3098  self.assertEqual(p.a.wilma.value(),1)
3099  #test adding a parameter
3100  m1 = Modifier()
3101  p = Process("test",m1)
3102  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
3103  m1.toModify(p.a, wilma = int32(2))
3104  self.assertEqual(p.a.fred.value(), 1)
3105  self.assertEqual(p.a.wilma.value(),2)
3106  #test setting of value in PSet
3107  m1 = Modifier()
3108  p = Process("test",m1)
3109  p.a = EDAnalyzer("MyAnalyzer", flintstones = PSet(fred = int32(1), wilma = int32(1)))
3110  m1.toModify(p.a, flintstones = dict(fred = int32(2)))
3111  self.assertEqual(p.a.flintstones.fred.value(),2)
3112  self.assertEqual(p.a.flintstones.wilma.value(),1)
3113  #test proper exception from nonexisting parameter name
3114  m1 = Modifier()
3115  p = Process("test",m1)
3116  p.a = EDAnalyzer("MyAnalyzer", flintstones = PSet(fred = PSet(wilma = int32(1))))
3117  self.assertRaises(KeyError, lambda: m1.toModify(p.a, flintstones = dict(imnothere = dict(wilma=2))))
3118  self.assertRaises(KeyError, lambda: m1.toModify(p.a, foo = 1))
3119  #test setting a value in a VPSet
3120  m1 = Modifier()
3121  p = Process("test",m1)
3122  p.a = EDAnalyzer("MyAnalyzer", flintstones = VPSet(PSet(fred = int32(1)), PSet(wilma = int32(1))))
3123  m1.toModify(p.a, flintstones = {1:dict(wilma = int32(2))})
3124  self.assertEqual(p.a.flintstones[0].fred.value(),1)
3125  self.assertEqual(p.a.flintstones[1].wilma.value(),2)
3126  #test setting a value in a list of values
3127  m1 = Modifier()
3128  p = Process("test",m1)
3129  p.a = EDAnalyzer("MyAnalyzer", fred = vuint32(1,2,3))
3130  m1.toModify(p.a, fred = {1:7})
3131  self.assertEqual(p.a.fred[0],1)
3132  self.assertEqual(p.a.fred[1],7)
3133  self.assertEqual(p.a.fred[2],3)
3134  #test IndexError setting a value in a list to an item key not in the list
3135  m1 = Modifier()
3136  p = Process("test",m1)
3137  p.a = EDAnalyzer("MyAnalyzer", fred = vuint32(1,2,3))
3138  raised = False
3139  try: m1.toModify(p.a, fred = {5:7})
3140  except IndexError as e: raised = True
3141  self.assertEqual(raised, True)
3142  #test TypeError setting a value in a list using a key that is not an int
3143  m1 = Modifier()
3144  p = Process("test",m1)
3145  p.a = EDAnalyzer("MyAnalyzer", flintstones = VPSet(PSet(fred = int32(1)), PSet(wilma = int32(1))))
3146  raised = False
3147  try: m1.toModify(p.a, flintstones = dict(bogus = int32(37)))
3148  except TypeError as e: raised = True
3149  self.assertEqual(raised, True)
3150  #test that load causes process wide methods to run
3151  def _rem_a(proc):
3152  del proc.a
3153  class ProcModifierMod(object):
3154  def __init__(self,modifier,func):
3155  self.proc_mod_ = modifier.makeProcessModifier(func)
3156  class DummyMod(object):
3157  def __init__(self):
3158  self.a = EDAnalyzer("Dummy")
3159  testMod = DummyMod()
3160  p.extend(testMod)
3161  self.assert_(hasattr(p,"a"))
3162  m1 = Modifier()
3163  p = Process("test",m1)
3164  testProcMod = ProcModifierMod(m1,_rem_a)
3165  p.extend(testMod)
3166  p.extend(testProcMod)
3167  self.assert_(not hasattr(p,"a"))
3168  #test ModifierChain
3169  m1 = Modifier()
3170  mc = ModifierChain(m1)
3171  p = Process("test",mc)
3172  self.assert_(p.isUsingModifier(m1))
3173  self.assert_(p.isUsingModifier(mc))
3174  testMod = DummyMod()
3175  p.b = EDAnalyzer("Dummy2", fred = int32(1))
3176  m1.toModify(p.b, fred = int32(3))
3177  p.extend(testMod)
3178  testProcMod = ProcModifierMod(m1,_rem_a)
3179  p.extend(testProcMod)
3180  self.assert_(not hasattr(p,"a"))
3181  self.assertEqual(p.b.fred.value(),3)
3182  #check cloneAndExclude
3183  m1 = Modifier()
3184  m2 = Modifier()
3185  mc = ModifierChain(m1,m2)
3186  mclone = mc.copyAndExclude([m2])
3187  self.assert_(not mclone._isOrContains(m2))
3188  self.assert_(mclone._isOrContains(m1))
3189  m3 = Modifier()
3190  mc2 = ModifierChain(mc,m3)
3191  mclone = mc2.copyAndExclude([m2])
3192  self.assert_(not mclone._isOrContains(m2))
3193  self.assert_(mclone._isOrContains(m1))
3194  self.assert_(mclone._isOrContains(m3))
3195  #check combining
3196  m1 = Modifier()
3197  m2 = Modifier()
3198  p = Process("test",m1)
3199  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3200  (m1 & m2).toModify(p.a, fred = int32(2))
3201  self.assertRaises(TypeError, lambda: (m1 & m2).toModify(p.a, 1, wilma=2))
3202  self.assertEqual(p.a.fred, 1)
3203  m1 = Modifier()
3204  m2 = Modifier()
3205  p = Process("test",m1,m2)
3206  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3207  (m1 & m2).toModify(p.a, fred = int32(2))
3208  self.assertEqual(p.a.fred, 2)
3209  m1 = Modifier()
3210  m2 = Modifier()
3211  m3 = Modifier()
3212  p = Process("test",m1,m2,m3)
3213  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3214  (m1 & m2 & m3).toModify(p.a, fred = int32(2))
3215  self.assertEqual(p.a.fred, 2)
3216  (m1 & (m2 & m3)).toModify(p.a, fred = int32(3))
3217  self.assertEqual(p.a.fred, 3)
3218  ((m1 & m2) & m3).toModify(p.a, fred = int32(4))
3219  self.assertEqual(p.a.fred, 4)
3220  #check inverse
3221  m1 = Modifier()
3222  m2 = Modifier()
3223  p = Process("test", m1)
3224  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3225  (~m1).toModify(p.a, fred=2)
3226  self.assertEqual(p.a.fred, 1)
3227  (~m2).toModify(p.a, wilma=2)
3228  self.assertEqual(p.a.wilma, 2)
3229  self.assertRaises(TypeError, lambda: (~m1).toModify(p.a, 1, wilma=2))
3230  self.assertRaises(TypeError, lambda: (~m2).toModify(p.a, 1, wilma=2))
3231  # check or
3232  m1 = Modifier()
3233  m2 = Modifier()
3234  m3 = Modifier()
3235  p = Process("test", m1)
3236  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3237  (m1 | m2).toModify(p.a, fred=2)
3238  self.assertEqual(p.a.fred, 2)
3239  (m1 | m2 | m3).toModify(p.a, fred=3)
3240  self.assertEqual(p.a.fred, 3)
3241  (m3 | m2 | m1).toModify(p.a, fred=4)
3242  self.assertEqual(p.a.fred, 4)
3243  ((m1 | m2) | m3).toModify(p.a, fred=5)
3244  self.assertEqual(p.a.fred, 5)
3245  (m1 | (m2 | m3)).toModify(p.a, fred=6)
3246  self.assertEqual(p.a.fred, 6)
3247  (m2 | m3).toModify(p.a, fred=7)
3248  self.assertEqual(p.a.fred, 6)
3249  self.assertRaises(TypeError, lambda: (m1 | m2).toModify(p.a, 1, wilma=2))
3250  self.assertRaises(TypeError, lambda: (m2 | m3).toModify(p.a, 1, wilma=2))
3251  # check combinations
3252  m1 = Modifier()
3253  m2 = Modifier()
3254  m3 = Modifier()
3255  m4 = Modifier()
3256  p = Process("test", m1, m2)
3257  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3258  (m1 & ~m2).toModify(p.a, fred=2)
3259  self.assertEqual(p.a.fred, 1)
3260  (m1 & ~m3).toModify(p.a, fred=2)
3261  self.assertEqual(p.a.fred, 2)
3262  (m1 | ~m2).toModify(p.a, fred=3)
3263  self.assertEqual(p.a.fred, 3)
3264  (~m1 | ~m2).toModify(p.a, fred=4)
3265  self.assertEqual(p.a.fred, 3)
3266  (~m3 & ~m4).toModify(p.a, fred=4)
3267  self.assertEqual(p.a.fred, 4)
3268  ((m1 & m3) | ~m4).toModify(p.a, fred=5)
3269  self.assertEqual(p.a.fred, 5)
3270  #check toReplaceWith
3271  m1 = Modifier()
3272  p = Process("test",m1)
3273  p.a =EDAnalyzer("MyAnalyzer", fred = int32(1))
3274  m1.toReplaceWith(p.a, EDAnalyzer("YourAnalyzer", wilma = int32(3)))
3275  self.assertRaises(TypeError, lambda: m1.toReplaceWith(p.a, EDProducer("YourProducer")))
3276  p.b =EDAnalyzer("BAn")
3277  p.c =EDProducer("c")
3278  p.d =EDProducer("d")
3279  p.tc = Task(p.c)
3280  p.td = Task(p.d)
3281  p.s = Sequence(p.a, p.tc)
3282  m1.toReplaceWith(p.s, Sequence(p.a+p.b, p.td))
3283  self.assertEqual(p.a.wilma.value(),3)
3284  self.assertEqual(p.a.type_(),"YourAnalyzer")
3285  self.assertEqual(hasattr(p,"fred"),False)
3286  self.assertTrue(p.s.dumpPython("") == "cms.Sequence(process.a+process.b, process.td)\n")
3287  p.e =EDProducer("e")
3288  m1.toReplaceWith(p.td, Task(p.e))
3289  self.assertTrue(p.td._collection == OrderedSet([p.e]))
3290  #check toReplaceWith doesn't activate not chosen
3291  m1 = Modifier()
3292  p = Process("test")
3293  p.a =EDAnalyzer("MyAnalyzer", fred = int32(1))
3294  m1.toReplaceWith(p.a, EDAnalyzer("YourAnalyzer", wilma = int32(3)))
3295  self.assertEqual(p.a.type_(),"MyAnalyzer")
3296  #check toReplaceWith and and/not/or combinations
3297  m1 = Modifier()
3298  m2 = Modifier()
3299  m3 = Modifier()
3300  m4 = Modifier()
3301  p = Process("test", m1, m2)
3302  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
3303  self.assertRaises(TypeError, lambda: (m1 & m2).toReplaceWith(p.a, EDProducer("YourProducer")))
3304  self.assertRaises(TypeError, lambda: (m3 & m4).toReplaceWith(p.a, EDProducer("YourProducer")))
3305  self.assertRaises(TypeError, lambda: (~m3).toReplaceWith(p.a, EDProducer("YourProducer")))
3306  self.assertRaises(TypeError, lambda: (~m1).toReplaceWith(p.a, EDProducer("YourProducer")))
3307  self.assertRaises(TypeError, lambda: (m1 | m3).toReplaceWith(p.a, EDProducer("YourProducer")))
3308  self.assertRaises(TypeError, lambda: (m3 | m4).toReplaceWith(p.a, EDProducer("YourProducer")))
3309  (m1 & m2).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer1"))
3310  self.assertEqual(p.a.type_(), "YourAnalyzer1")
3311  (m1 & m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer2"))
3312  self.assertEqual(p.a.type_(), "YourAnalyzer1")
3313  (~m1).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer2"))
3314  self.assertEqual(p.a.type_(), "YourAnalyzer1")
3315  (~m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer2"))
3316  self.assertEqual(p.a.type_(), "YourAnalyzer2")
3317  (m1 | m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer3"))
3318  self.assertEqual(p.a.type_(), "YourAnalyzer3")
3319  (m3 | m4).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer4"))
3320  self.assertEqual(p.a.type_(), "YourAnalyzer3")
3321 
3322  # EDAlias
3323  a = EDAlias(foo2 = VPSet(PSet(type = string("Foo2"))))
3324  m = Modifier()
3325  m._setChosen()
3326  # Modify parameters
3327  m.toModify(a, foo2 = {0: dict(type = "Foo3")})
3328  self.assertEqual(a.foo2[0].type, "Foo3")
3329  # Add an alias
3330  m.toModify(a, foo4 = VPSet(PSet(type = string("Foo4"))))
3331  self.assertEqual(a.foo2[0].type, "Foo3")
3332  self.assertEqual(a.foo4[0].type, "Foo4")
3333  # Remove an alias
3334  m.toModify(a, foo2 = None)
3335  self.assertFalse(hasattr(a, "foo2"))
3336  self.assertEqual(a.foo4[0].type, "Foo4")
3337  # Replace (doesn't work out of the box because EDAlias is not _Parameterizable
3338  m.toReplaceWith(a, EDAlias(bar = VPSet(PSet(type = string("Bar")))))
3339  self.assertFalse(hasattr(a, "foo2"))
3340  self.assertFalse(hasattr(a, "foo4"))
3341  self.assertTrue(hasattr(a, "bar"))
3342  self.assertEqual(a.bar[0].type, "Bar")
3343 
3344  # SwitchProducer
3345  sp = SwitchProducerTest(test1 = EDProducer("Foo",
3346  a = int32(1),
3347  b = PSet(c = int32(2))),
3348  test2 = EDProducer("Bar",
3349  aa = int32(11),
3350  bb = PSet(cc = int32(12))))
3351  m = Modifier()
3352  m._setChosen()
3353  # Modify parameters
3354  m.toModify(sp,
3355  test1 = dict(a = 4, b = dict(c = None)),
3356  test2 = dict(aa = 15, bb = dict(cc = 45, dd = string("foo"))))
3357  self.assertEqual(sp.test1.a.value(), 4)
3358  self.assertEqual(sp.test1.b.hasParameter("c"), False)
3359  self.assertEqual(sp.test2.aa.value(), 15)
3360  self.assertEqual(sp.test2.bb.cc.value(), 45)
3361  self.assertEqual(sp.test2.bb.dd.value(), "foo")
3362  # Replace a producer
3363  m.toReplaceWith(sp.test1, EDProducer("Fred", x = int32(42)))
3364  self.assertEqual(sp.test1.type_(), "Fred")
3365  self.assertEqual(sp.test1.x.value(), 42)
3366  self.assertRaises(TypeError, lambda: m.toReplaceWith(sp.test1, EDAnalyzer("Foo")))
3367  # Alternative way (only to be allow same syntax to be used as for adding)
3368  m.toModify(sp, test2 = EDProducer("Xyzzy", x = int32(24)))
3369  self.assertEqual(sp.test2.type_(), "Xyzzy")
3370  self.assertEqual(sp.test2.x.value(), 24)
3371  self.assertRaises(TypeError, lambda: m.toModify(sp, test2 = EDAnalyzer("Foo")))
3372  # Add a producer
3373  m.toModify(sp, test3 = EDProducer("Wilma", y = int32(24)))
3374  self.assertEqual(sp.test3.type_(), "Wilma")
3375  self.assertEqual(sp.test3.y.value(), 24)
3376  self.assertRaises(TypeError, lambda: m.toModify(sp, test4 = EDAnalyzer("Foo")))
3377  # Remove a producer
3378  m.toModify(sp, test2 = None)
3379  self.assertEqual(hasattr(sp, "test2"), False)
3380  # Add an alias
3381  m.toModify(sp, test2 = EDAlias(foo = VPSet(PSet(type = string("int")))))
3382  self.assertTrue(hasattr(sp.test2, "foo"))
3383  # Replace an alias
3384  m.toReplaceWith(sp.test2, EDAlias(bar = VPSet(PSet(type = string("int")))))
3385  self.assertTrue(hasattr(sp.test2, "bar"))
3386  # Alternative way
3387  m.toModify(sp, test2 = EDAlias(xyzzy = VPSet(PSet(type = string("int")))))
3388  self.assertTrue(hasattr(sp.test2, "xyzzy"))
3389  # Replace an alias with EDProducer
3390  self.assertRaises(TypeError, lambda: m.toReplaceWith(sp.test2, EDProducer("Foo")))
3391  m.toModify(sp, test2 = EDProducer("Foo"))
3392 
3393 
3394  unittest.main()
def __setstate__(self, pkldict)
Definition: Config.py:161
def addVString(self, tracked, label, value)
Definition: Config.py:1559
def _dumpConfigOptionallyNamedList(self, items, typeName, options)
Definition: Config.py:661
def addEventRange(self, tracked, label, value)
Definition: Config.py:1579
def __init__(self, lhs, rhs)
Definition: Config.py:1355
def testExamples(self)
Definition: Config.py:2566
def __getattribute__(self, name)
Definition: Config.py:1196
def _place(self, label, process)
Definition: Config.py:1280
def getProcessName(self)
Definition: Config.py:1268
def testServiceInProcess(self)
Definition: Config.py:2072
def __or__(self, other)
Definition: Config.py:1446
def outputCommands(self)
Definition: Config.py:1274
def _setChosen(self)
Definition: Config.py:1463
def producerNames(self)
Definition: Config.py:145
def _dumpConfigUnnamedList(self, items, typeName, options)
Definition: Config.py:656
def newPSet(self)
Definition: Config.py:1589
def _placeAnalyzer(self, name, mod)
Definition: Config.py:536
def addString(self, tracked, label, value)
Definition: Config.py:1557
def __findFirstUsingModule(self, seqsOrTasks, mod)
Definition: Config.py:420
def subProcesses_(self)
Definition: Config.py:209
def __repr__(self)
Definition: Config.py:1239
def _pruneModules(self, d, scheduledNames)
Definition: Config.py:1043
def _modifyParametersFromDict(params, newParams, errorRaiser, keyDepth="")
Definition: Mixins.py:665
def vpsets_(self)
Definition: Config.py:280
def setName_(self, name)
Definition: Config.py:184
def copy(args, dbName)
def _placeESPrefer(self, name, mod)
Definition: Config.py:557
def testSequence2(self)
Definition: Config.py:2062
def _placeSwitchProducer(self, name, mod)
Definition: Config.py:532
def _insertPaths(self, processPSet, nodeVisitor)
Definition: Config.py:927
def es_producers_(self)
Definition: Config.py:260
def _placeESProducer(self, name, mod)
Definition: Config.py:555
def __invert__(self)
Definition: Config.py:1444
def pathNames(self)
Definition: Config.py:157
def addVESInputTag(self, tracked, label, value)
Definition: Config.py:1569
def __and__(self, other)
Definition: Config.py:1442
def _placeSequence(self, name, mod)
Definition: Config.py:552
def __call__(self, obj)
Definition: Config.py:1295
def _setChosen(self)
Definition: Config.py:1437
def _validateSequence(self, sequence, label)
Definition: Config.py:752
def __getattr__(self, attr)
Definition: Config.py:1241
def tasks_(self)
Definition: Config.py:233
def setStrict(self, value)
Definition: Config.py:140
def addDouble(self, tracked, label, value)
Definition: Config.py:1551
def producers_(self)
Definition: Config.py:189
def _findPreferred(self, esname, d, args, kargs)
Definition: Config.py:1165
def replace(string, replacements)
def testModifier(self)
Definition: Config.py:3059
def _insertOneInto(self, parameterSet, label, item, tracked)
Definition: Config.py:889
def _isChosen(self)
Definition: Config.py:1350
def filterNames(self)
Definition: Config.py:154
def __delattr__(self, name)
Definition: Config.py:450
def _placePath(self, name, mod)
Definition: Config.py:538
def addVUInt64(self, tracked, label, value)
Definition: Config.py:1549
def _isChosen(self)
Definition: Config.py:1343
def _placeEndPath(self, name, mod)
Definition: Config.py:545
def es_sources_(self)
Definition: Config.py:264
def __init__(self, name, Mods)
Definition: Config.py:103
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
def testTypedParameterizable(self)
Definition: Config.py:1640
def addUInt64(self, tracked, label, value)
Definition: Config.py:1547
def _itemsInDependencyOrder(self, processDictionaryOfItems)
Definition: Config.py:768
def source_(self)
Definition: Config.py:197
def addVPSet(self, tracked, label, value)
Definition: Config.py:1585
def nameInProcessDesc_(self, label)
Definition: Config.py:1278
def psets_(self)
Definition: Config.py:276
def testSecSource(self)
Definition: Config.py:1997
def __init__(self, args)
Definition: Config.py:1293
def format_outerframe(number)
def __init__(self, args, kw)
Definition: Config.py:1237
def load(self, moduleName)
Definition: Config.py:593
def _insertSubProcessesInto(self, parameterSet, label, itemList, tracked)
Definition: Config.py:914
def addUInt32(self, tracked, label, value)
Definition: Config.py:1539
def _dumpConfigESPrefers(self, options)
Definition: Config.py:733
def __setattr__(self, name, value)
Definition: Config.py:1201
def setLooper_(self, lpr)
Definition: Config.py:206
def setSource_(self, src)
Definition: Config.py:200
def __init__(self, process)
Definition: Config.py:1187
def extend(self, other, items=())
Definition: Config.py:597
def _okToPlace(self, name, mod, d)
Definition: Config.py:499
def __or__(self, other)
Definition: Config.py:1336
def visit(visitdir)
Retrieve data from a perf suite output (sub) directory, only examines TimeSize at the moment...
def _replaceInTasks(self, label, new)
Definition: Config.py:871
def addVInt32(self, tracked, label, value)
Definition: Config.py:1537
def _placeFilter(self, name, mod)
Definition: Config.py:534
def schedule_(self)
Definition: Config.py:237
def validate(self)
Definition: Config.py:1129
def addVInputTag(self, tracked, label, value)
Definition: Config.py:1565
def _applyNewProcessModifiers(self, process)
Definition: Config.py:1458
def analyzerNames(self)
Definition: Config.py:151
def testSchedule(self)
Definition: Config.py:2398
def addLuminosityBlockID(self, tracked, label, value)
Definition: Config.py:1575
def addESInputTag(self, tracked, label, value)
Definition: Config.py:1567
def __init__(self, lhs)
Definition: Config.py:1348
def __new__(cls, args, kw)
Definition: Config.py:1220
def testContains(self)
Definition: Config.py:2340
def endpaths_(self)
Definition: Config.py:225
def toModify(self, obj, func=None, kw)
Definition: Config.py:1317
def SelectEvents(self)
Definition: Config.py:1272
def __setattr__(self, name, value)
Definition: Config.py:320
def _placeESSource(self, name, mod)
Definition: Config.py:559
def addVInt64(self, tracked, label, value)
Definition: Config.py:1545
def addVEventID(self, tracked, label, value)
Definition: Config.py:1573
def toModify(self, obj, func=None, kw)
Definition: Config.py:1383
def testGlobalReplace(self)
Definition: Config.py:2002
def testSwitchProducer(self)
Definition: Config.py:2706
def getVString(self, tracked, label)
Definition: Config.py:1561
def toReplaceWith(self, toObj, fromObj)
Definition: Config.py:1322
def _placeOutputModule(self, name, mod)
Definition: Config.py:528
def addFileInPath(self, tracked, label, value)
Definition: Config.py:1587
def testRefToPSet(self)
Definition: Config.py:2690
def testOverride(self)
Definition: Config.py:2543
def _placeSource(self, name, mod)
Definition: Config.py:570
def __init__(self)
Definition: Config.py:1370
def __init__(self, lhs, rhs=None)
Definition: Config.py:1313
def _dumpPythonSubProcesses(self, l, options)
Definition: Config.py:738
def _insertSwitchProducersInto(self, parameterSet, labelModules, labelAliases, itemDict, tracked)
Definition: Config.py:904
def checkImportPermission(minLevel=2, allowedPatterns=[])
Definition: Config.py:29
def ignore(seq)
def _toModify(obj, func, kw)
Definition: Config.py:1401
def __init__(self, modifier, func)
Definition: Config.py:1507
def _toReplaceWith(toObj, fromObj)
Definition: Config.py:1419
def _toModifyCheck(obj, func, kw)
Definition: Config.py:1380
def isUsingModifier(self, mod)
Definition: Config.py:285
def dumpPython(self, options=PrintOptions())
Definition: Config.py:1261
def __copyIfExclude(self, toExclude)
Definition: Config.py:1484
def sequences_(self)
Definition: Config.py:229
def _validateTask(self, task, label)
Definition: Config.py:760
def testParameterizable(self)
Definition: Config.py:1607
def testSubProcess(self)
Definition: Config.py:2650
def _placeSubProcess(self, name, mod)
Definition: Config.py:583
def setPartialSchedule_(self, sch, label)
Definition: Config.py:240
def addPSet(self, tracked, label, value)
Definition: Config.py:1583
def testProcessDumpPython(self)
Definition: Config.py:1742
def _placeService(self, typeName, mod)
Definition: Config.py:588
def resolve(self, keepUnresolvedSequencePlaceholders=False)
Definition: Config.py:981
def looper_(self)
Definition: Config.py:203
def es_prefers_(self)
Definition: Config.py:268
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def _isChosen(self)
Definition: Config.py:1440
def _isOrContains(self, other)
Definition: Config.py:1448
def getSubProcessPSet(self, parameterSet)
Definition: Config.py:1282
def copyAndExclude(self, toExclude)
Definition: Config.py:1470
def addVUInt32(self, tracked, label, value)
Definition: Config.py:1541
def addVEventRange(self, tracked, label, value)
Definition: Config.py:1581
def __init__(self, lhs, rhs)
Definition: Config.py:1341
def filters_(self)
Definition: Config.py:178
def dumpPython(process, name)
def __setObjectLabel(self, object, newLabel)
Definition: Config.py:293
def _delHelper(self, name)
Definition: Config.py:433
def _placeAlias(self, name, mod)
Definition: Config.py:564
def dumpPython(self, options=PrintOptions())
Definition: Config.py:829
def _replaceInSequences(self, label, new)
Definition: Config.py:862
def setSchedule_(self, sch)
Definition: Config.py:245
def analyzers_(self)
Definition: Config.py:213
def _toReplaceWithCheck(toObj, fromObj)
Definition: Config.py:1408
def testSequence(self)
Definition: Config.py:2047
def switchProducerNames(self)
Definition: Config.py:148
def toReplaceWith(self, toObj, fromObj)
Definition: Config.py:1411
def _placeProducer(self, name, mod)
Definition: Config.py:530
def prefer(self, esmodule, args, kargs)
Definition: Config.py:1136
def __delattr__(self, name)
Definition: Config.py:1206
def _dumpConfigNamedList(self, items, typeName, options)
Definition: Config.py:651
def addInputTag(self, tracked, label, value)
Definition: Config.py:1563
def add_(self, value)
Definition: Config.py:484
def _isChosen(self)
Definition: Config.py:1357
def _insertManyInto(self, parameterSet, label, itemDict, tracked)
Definition: Config.py:896
def dumpConfig(self, options=PrintOptions())
Definition: Config.py:668
def apply(self, process)
Definition: Config.py:1511
def testCloneSequence(self)
Definition: Config.py:2324
def process(self)
Definition: Config.py:1270
def _placeTask(self, name, task)
Definition: Config.py:561
def makeProcessModifier(self, func)
Definition: Config.py:1327
def addSubProcess(self, mod)
Definition: Config.py:586
def switchProducers_(self)
Definition: Config.py:193
def _placePSet(self, name, mod)
Definition: Config.py:566
def _isOrContains(self, other)
Definition: Config.py:1493
def addInt64(self, tracked, label, value)
Definition: Config.py:1543
def name_(self)
Definition: Config.py:182
def _place(self, name, mod, d)
Definition: Config.py:520
def testProcessExtend(self)
Definition: Config.py:1672
def _dumpPythonList(self, d, options)
Definition: Config.py:743
dbl *** dir
Definition: mlp_gen.cc:35
def __insertValue(self, tracked, label, value)
Definition: Config.py:1526
def __init__(self, kargs)
Definition: Config.py:1593
def __getValue(self, tracked, label)
Definition: Config.py:1528
def _placeVPSet(self, name, mod)
Definition: Config.py:568
def __and__(self, other)
Definition: Config.py:1332
def globalReplace(self, label, new)
Definition: Config.py:881
#define str(s)
def addBool(self, tracked, label, value)
Definition: Config.py:1555
def paths_(self)
Definition: Config.py:221
def addEventID(self, tracked, label, value)
Definition: Config.py:1571
def outputModules_(self)
Definition: Config.py:217
def _placeLooper(self, name, mod)
Definition: Config.py:578
def testImplicitSchedule(self)
Definition: Config.py:2503
def prune(self, verbose=False, keepUnresolvedSequencePlaceholders=False)
Definition: Config.py:990
def addVDouble(self, tracked, label, value)
Definition: Config.py:1553
def _insertInto(self, parameterSet, itemDict)
Definition: Config.py:886
def _delattrFromSetattr(self, name)
Definition: Config.py:475
def makeProcessModifier(self, func)
Definition: Config.py:1373
def __init__(self, process, SelectEvents=untracked.PSet(), outputCommands=untracked.vstring())
Definition: Config.py:1249
def type_(self)
Definition: Config.py:1276
def __init__(self, chainedModifiers)
Definition: Config.py:1455
def testTaskPlaceholder(self)
Definition: Config.py:2869
def services_(self)
Definition: Config.py:256
def _replaceInSchedule(self, label, new)
Definition: Config.py:875
def _dumpPython(self, d, options)
Definition: Config.py:824
def addInt32(self, tracked, label, value)
Definition: Config.py:1535
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
def _isChosen(self)
Definition: Config.py:1468
def fillProcessDesc(self, processPSet)
Definition: Config.py:1050
def findProcess(module)
Definition: Config.py:82
def testProcessInsertion(self)
Definition: Config.py:1647
def __init__(self)
Definition: Config.py:1524
def aliases_(self)
Definition: Config.py:272