CMS 3D CMS Logo

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