CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Config.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 ### command line options helper
4 from Options import Options
5 options = Options()
6 
7 
8 ## imports
9 import sys
10 from Mixins import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable, _Unlabelable, _ValidatingListBase
11 from Mixins import *
12 from Types import *
13 from Modules import *
14 from Modules import _Module
15 from SequenceTypes import *
16 from SequenceTypes import _ModuleSequenceType, _Sequenceable #extend needs it
17 from SequenceVisitors import PathValidator, EndPathValidator
18 from Utilities import *
19 import DictTypes
20 
21 from ExceptionHandling import *
22 
23 #when building RECO paths we have hit the default recursion limit
24 if sys.getrecursionlimit()<5000:
25  sys.setrecursionlimit(5000)
26 
27 def checkImportPermission(minLevel = 2, allowedPatterns = []):
28  """
29  Raise an exception if called by special config files. This checks
30  the call or import stack for the importing file. An exception is raised if
31  the importing module is not in allowedPatterns and if it is called too deeply:
32  minLevel = 2: inclusion by top lvel cfg only
33  minLevel = 1: No inclusion allowed
34  allowedPatterns = ['Module1','Module2/SubModule1'] allows import
35  by any module in Module1 or Submodule1
36  """
37 
38  import inspect
39  import os
40 
41  ignorePatterns = ['FWCore/ParameterSet/Config.py','<string>']
42  CMSSWPath = [os.environ['CMSSW_BASE'],os.environ['CMSSW_RELEASE_BASE']]
43 
44  # Filter the stack to things in CMSSWPath and not in ignorePatterns
45  trueStack = []
46  for item in inspect.stack():
47  inPath = False
48  ignore = False
49 
50  for pattern in CMSSWPath:
51  if item[1].find(pattern) != -1:
52  inPath = True
53  break
54  if item[1].find('/') == -1: # The base file, no path
55  inPath = True
56 
57  for pattern in ignorePatterns:
58  if item[1].find(pattern) != -1:
59  ignore = True
60  break
61 
62  if inPath and not ignore:
63  trueStack.append(item[1])
64 
65  importedFile = trueStack[0]
66  importedBy = ''
67  if len(trueStack) > 1:
68  importedBy = trueStack[1]
69 
70  for pattern in allowedPatterns:
71  if importedBy.find(pattern) > -1:
72  return True
73 
74  if len(trueStack) <= minLevel: # Imported directly
75  return True
76 
77  raise ImportError("Inclusion of %s is allowed only by cfg or specified cfi files."
78  % importedFile)
79 
80 def findProcess(module):
81  """Look inside the module and find the Processes it contains"""
82  class Temp(object):
83  pass
84  process = None
85  if isinstance(module,dict):
86  if 'process' in module:
87  p = module['process']
88  module = Temp()
89  module.process = p
90  if hasattr(module,'process'):
91  if isinstance(module.process,Process):
92  process = module.process
93  else:
94  raise RuntimeError("The attribute named 'process' does not inherit from the Process class")
95  else:
96  raise RuntimeError("no 'process' attribute found in the module, please add one")
97  return process
98 
99 
101  """Root class for a CMS configuration process"""
102  def __init__(self,name):
103  """The argument 'name' will be the name applied to this Process"""
104  self.__dict__['_Process__name'] = name
105  if not name.isalnum():
106  raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters")
107  self.__dict__['_Process__filters'] = {}
108  self.__dict__['_Process__producers'] = {}
109  self.__dict__['_Process__source'] = None
110  self.__dict__['_Process__looper'] = None
111  self.__dict__['_Process__subProcess'] = None
112  self.__dict__['_Process__schedule'] = None
113  self.__dict__['_Process__analyzers'] = {}
114  self.__dict__['_Process__outputmodules'] = {}
115  self.__dict__['_Process__paths'] = DictTypes.SortedKeysDict() # have to keep the order
116  self.__dict__['_Process__endpaths'] = DictTypes.SortedKeysDict() # of definition
117  self.__dict__['_Process__sequences'] = {}
118  self.__dict__['_Process__services'] = {}
119  self.__dict__['_Process__essources'] = {}
120  self.__dict__['_Process__esproducers'] = {}
121  self.__dict__['_Process__esprefers'] = {}
122  self.__dict__['_Process__aliases'] = {}
123  self.__dict__['_Process__psets']={}
124  self.__dict__['_Process__vpsets']={}
125  self.__dict__['_cloneToObjectDict'] = {}
126  # policy switch to avoid object overwriting during extend/load
127  self.__dict__['_Process__InExtendCall'] = False
128  self.__dict__['_Process__partialschedules'] = {}
129  self.__isStrict = False
130 
131  def setStrict(self, value):
132  self.__isStrict = value
133  _Module.__isStrict__ = True
134 
135  # some user-friendly methods for command-line browsing
136  def producerNames(self):
137  """Returns a string containing all the EDProducer labels separated by a blank"""
138  return ' '.join(self.producers_().keys())
139  def analyzerNames(self):
140  """Returns a string containing all the EDAnalyzer labels separated by a blank"""
141  return ' '.join(self.analyzers_().keys())
142  def filterNames(self):
143  """Returns a string containing all the EDFilter labels separated by a blank"""
144  return ' '.join(self.filters_().keys())
145  def pathNames(self):
146  """Returns a string containing all the Path names separated by a blank"""
147  return ' '.join(self.paths_().keys())
148 
149  def __setstate__(self, pkldict):
150  """
151  Unpickling hook.
152 
153  Since cloneToObjectDict stores a hash of objects by their
154  id() it needs to be updated when unpickling to use the
155  new object id values instantiated during the unpickle.
156 
157  """
158  self.__dict__.update(pkldict)
159  tmpDict = {}
160  for value in self._cloneToObjectDict.values():
161  tmpDict[id(value)] = value
162  self.__dict__['_cloneToObjectDict'] = tmpDict
163 
164 
165 
166  def filters_(self):
167  """returns a dict of the filters which have been added to the Process"""
168  return DictTypes.FixedKeysDict(self.__filters)
169  filters = property(filters_, doc="dictionary containing the filters for the process")
170  def name_(self):
171  return self.__name
172  def setName_(self,name):
173  if not name.isalnum():
174  raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters")
175  self.__dict__['_Process__name'] = name
176  process = property(name_,setName_, doc="name of the process")
177  def producers_(self):
178  """returns a dict of the producers which have been added to the Process"""
179  return DictTypes.FixedKeysDict(self.__producers)
180  producers = property(producers_,doc="dictionary containing the producers for the process")
181  def source_(self):
182  """returns the source which has been added to the Process or None if none have been added"""
183  return self.__source
184  def setSource_(self,src):
185  self._placeSource('source',src)
186  source = property(source_,setSource_,doc='the main source or None if not set')
187  def looper_(self):
188  """returns the looper which has been added to the Process or None if none have been added"""
189  return self.__looper
190  def setLooper_(self,lpr):
191  self._placeLooper('looper',lpr)
192  looper = property(looper_,setLooper_,doc='the main looper or None if not set')
193  def subProcess_(self):
194  """returns the sub-process which has been added to the Process or None if none have been added"""
195  return self.__subProcess
196  def setSubProcess_(self,lpr):
197  self._placeSubProcess('subProcess',lpr)
198  subProcess = property(subProcess_,setSubProcess_,doc='the SubProcess or None if not set')
199  def analyzers_(self):
200  """returns a dict of the analyzers which have been added to the Process"""
201  return DictTypes.FixedKeysDict(self.__analyzers)
202  analyzers = property(analyzers_,doc="dictionary containing the analyzers for the process")
203  def outputModules_(self):
204  """returns a dict of the output modules which have been added to the Process"""
205  return DictTypes.FixedKeysDict(self.__outputmodules)
206  outputModules = property(outputModules_,doc="dictionary containing the output_modules for the process")
207  def paths_(self):
208  """returns a dict of the paths which have been added to the Process"""
209  return DictTypes.SortedAndFixedKeysDict(self.__paths)
210  paths = property(paths_,doc="dictionary containing the paths for the process")
211  def endpaths_(self):
212  """returns a dict of the endpaths which have been added to the Process"""
213  return DictTypes.SortedAndFixedKeysDict(self.__endpaths)
214  endpaths = property(endpaths_,doc="dictionary containing the endpaths for the process")
215  def sequences_(self):
216  """returns a dict of the sequences which have been added to the Process"""
217  return DictTypes.FixedKeysDict(self.__sequences)
218  sequences = property(sequences_,doc="dictionary containing the sequences for the process")
219  def schedule_(self):
220  """returns the schedule which has been added to the Process or None if none have been added"""
221  return self.__schedule
222  def setPartialSchedule_(self,sch,label):
223  if label == "schedule":
224  self.setSchedule_(sch)
225  else:
226  self._place(label, sch, self.__partialschedules)
227  def setSchedule_(self,sch):
228  # See if every module has been inserted into the process
229  index = 0
230  try:
231  for p in sch:
232  p.label_()
233  index +=1
234  except:
235  raise RuntimeError("The path at index "+str(index)+" in the Schedule was not attached to the process.")
236 
237  self.__dict__['_Process__schedule'] = sch
238  schedule = property(schedule_,setSchedule_,doc='the schedule or None if not set')
239  def services_(self):
240  """returns a dict of the services which have been added to the Process"""
241  return DictTypes.FixedKeysDict(self.__services)
242  services = property(services_,doc="dictionary containing the services for the process")
243  def es_producers_(self):
244  """returns a dict of the esproducers which have been added to the Process"""
245  return DictTypes.FixedKeysDict(self.__esproducers)
246  es_producers = property(es_producers_,doc="dictionary containing the es_producers for the process")
247  def es_sources_(self):
248  """returns a the es_sources which have been added to the Process"""
249  return DictTypes.FixedKeysDict(self.__essources)
250  es_sources = property(es_sources_,doc="dictionary containing the es_sources for the process")
251  def es_prefers_(self):
252  """returns a dict of the es_prefers which have been added to the Process"""
253  return DictTypes.FixedKeysDict(self.__esprefers)
254  es_prefers = property(es_prefers_,doc="dictionary containing the es_prefers for the process")
255  def aliases_(self):
256  """returns a dict of the aliases that have been added to the Process"""
257  return DictTypes.FixedKeysDict(self.__aliases)
258  aliases = property(aliases_,doc="dictionary containing the aliases for the process")
259  def psets_(self):
260  """returns a dict of the PSets which have been added to the Process"""
261  return DictTypes.FixedKeysDict(self.__psets)
262  psets = property(psets_,doc="dictionary containing the PSets for the process")
263  def vpsets_(self):
264  """returns a dict of the VPSets which have been added to the Process"""
265  return DictTypes.FixedKeysDict(self.__vpsets)
266  vpsets = property(vpsets_,doc="dictionary containing the PSets for the process")
267 
268  def __setObjectLabel(self, object, newLabel) :
269  if not object.hasLabel_() :
270  object.setLabel(newLabel)
271  return
272  if newLabel == object.label_() :
273  return
274  if newLabel is None :
275  object.setLabel(None)
276  return
277  if (hasattr(self, object.label_()) and id(getattr(self, object.label_())) == id(object)) :
278  msg100 = "Attempting to change the label of an attribute of the Process\n"
279  msg101 = "Old label = "+object.label_()+" New label = "+newLabel+"\n"
280  msg102 = "Type = "+str(type(object))+"\n"
281  msg103 = "Some possible solutions:\n"
282  msg104 = " 1. Clone modules instead of using simple assignment. Cloning is\n"
283  msg105 = " also preferred for other types when possible.\n"
284  msg106 = " 2. Declare new names starting with an underscore if they are\n"
285  msg107 = " for temporaries you do not want propagated into the Process. The\n"
286  msg108 = " underscore tells \"from x import *\" and process.load not to import\n"
287  msg109 = " the name.\n"
288  msg110 = " 3. Reorganize so the assigment is not necessary. Giving a second\n"
289  msg111 = " name to the same object usually causes confusion and problems.\n"
290  msg112 = " 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
291  raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
292  object.setLabel(None)
293  object.setLabel(newLabel)
294 
295  def __setattr__(self,name,value):
296  # check if the name is well-formed (only _ and alphanumerics are allowed)
297  if not name.replace('_','').isalnum():
298  raise ValueError('The label '+name+' contains forbiden characters')
299 
300  # private variable exempt from all this
301  if name.startswith('_Process__'):
302  self.__dict__[name]=value
303  return
304  if not isinstance(value,_ConfigureComponent):
305  raise TypeError("can only assign labels to an object which inherits from '_ConfigureComponent'\n"
306  +"an instance of "+str(type(value))+" will not work")
307  if not isinstance(value,_Labelable) and not isinstance(value,Source) and not isinstance(value,Looper) and not isinstance(value,Schedule):
308  if name == value.type_():
309  self.add_(value)
310  return
311  else:
312  raise TypeError("an instance of "+str(type(value))+" can not be assigned the label '"+name+"'.\n"+
313  "Please either use the label '"+value.type_()+" or use the 'add_' method instead.")
314  #clone the item
315  if self.__isStrict:
316  newValue =value.copy()
317  try:
318  newValue._filename = value._filename
319  except:
320  pass
321  value.setIsFrozen()
322  else:
323  newValue =value
324  if not self._okToPlace(name, value, self.__dict__):
325  newFile='top level config'
326  if hasattr(value,'_filename'):
327  newFile = value._filename
328  oldFile='top level config'
329  oldValue = getattr(self,name)
330  if hasattr(oldValue,'_filename'):
331  oldFile = oldValue._filename
332  msg = "Trying to override definition of process."+name
333  msg += "\n new object defined in: "+newFile
334  msg += "\n existing object defined in: "+oldFile
335  raise ValueError(msg)
336  # remove the old object of the name (if there is one)
337  if hasattr(self,name) and not (getattr(self,name)==newValue):
338  # Compain if items in sequences from load() statements have
339  # degeneratate names, but if the user overwrites a name in the
340  # main config, replace it everywhere
341  if isinstance(newValue, _Sequenceable):
342  if not self.__InExtendCall:
343  self._replaceInSequences(name, newValue)
344  else:
345  #should check to see if used in sequence before complaining
346  newFile='top level config'
347  if hasattr(value,'_filename'):
348  newFile = value._filename
349  oldFile='top level config'
350  oldValue = getattr(self,name)
351  if hasattr(oldValue,'_filename'):
352  oldFile = oldValue._filename
353  msg1 = "Trying to override definition of "+name+" while it is used by the sequence "
354  msg2 = "\n new object defined in: "+newFile
355  msg2 += "\n existing object defined in: "+oldFile
356  s = self.__findFirstSequenceUsingModule(self.sequences,oldValue)
357  if s is not None:
358  raise ValueError(msg1+s.label_()+msg2)
359  s = self.__findFirstSequenceUsingModule(self.paths,oldValue)
360  if s is not None:
361  raise ValueError(msg1+s.label_()+msg2)
362  s = self.__findFirstSequenceUsingModule(self.endpaths,oldValue)
363  if s is not None:
364  raise ValueError(msg1+s.label_()+msg2)
365  self.__delattr__(name)
366  self.__dict__[name]=newValue
367  if isinstance(newValue,_Labelable):
368  self.__setObjectLabel(newValue, name)
369  self._cloneToObjectDict[id(value)] = newValue
370  self._cloneToObjectDict[id(newValue)] = newValue
371  #now put in proper bucket
372  newValue._place(name,self)
373  def __findFirstSequenceUsingModule(self,seqs,mod):
374  """Given a container of sequences, find the first sequence containing mod
375  and return the sequence. If no sequence is found, return None"""
376  from FWCore.ParameterSet.SequenceTypes import ModuleNodeVisitor
377  for sequenceable in seqs.itervalues():
378  l = list()
379  v = ModuleNodeVisitor(l)
380  sequenceable.visit(v)
381  if mod in l:
382  return sequenceable
383  return None
384  def __delattr__(self,name):
385  if not hasattr(self,name):
386  raise KeyError('process does not know about '+name)
387  elif name.startswith('_Process__'):
388  raise ValueError('this attribute cannot be deleted')
389  else:
390  # we have to remove it from all dictionaries/registries
391  dicts = [item for item in self.__dict__.values() if (type(item)==dict or type(item)==DictTypes.SortedKeysDict)]
392  for reg in dicts:
393  if reg.has_key(name): del reg[name]
394  # if it was a labelable object, the label needs to be removed
395  obj = getattr(self,name)
396  if isinstance(obj,_Labelable):
397  getattr(self,name).setLabel(None)
398  # now remove it from the process itself
399  try:
400  del self.__dict__[name]
401  except:
402  pass
403 
404  def add_(self,value):
405  """Allows addition of components which do not have to have a label, e.g. Services"""
406  if not isinstance(value,_ConfigureComponent):
407  raise TypeError
408  if not isinstance(value,_Unlabelable):
409  raise TypeError
410  #clone the item
411  #clone the item
412  if self.__isStrict:
413  newValue =value.copy()
414  value.setIsFrozen()
415  else:
416  newValue =value
417  newValue._place('',self)
418 
419  def _okToPlace(self, name, mod, d):
420  if not self.__InExtendCall:
421  # if going
422  return True
423  elif not self.__isStrict:
424  return True
425  elif name in d:
426  # if there's an old copy, and the new one
427  # hasn't been modified, we're done. Still
428  # not quite safe if something has been defined twice.
429  # Need to add checks
430  if mod._isModified:
431  if d[name]._isModified:
432  return False
433  else:
434  return True
435  else:
436  return True
437  else:
438  return True
439 
440  def _place(self, name, mod, d):
441  if self._okToPlace(name, mod, d):
442  if self.__isStrict and isinstance(mod, _ModuleSequenceType):
443  d[name] = mod._postProcessFixup(self._cloneToObjectDict)
444  else:
445  d[name] = mod
446  if isinstance(mod,_Labelable):
447  self.__setObjectLabel(mod, name)
448  def _placeOutputModule(self,name,mod):
449  self._place(name, mod, self.__outputmodules)
450  def _placeProducer(self,name,mod):
451  self._place(name, mod, self.__producers)
452  def _placeFilter(self,name,mod):
453  self._place(name, mod, self.__filters)
454  def _placeAnalyzer(self,name,mod):
455  self._place(name, mod, self.__analyzers)
456  def _placePath(self,name,mod):
457  self._validateSequence(mod, name)
458  try:
459  self._place(name, mod, self.__paths)
460  except ModuleCloneError, msg:
461  context = format_outerframe(4)
462  raise Exception("%sThe module %s in path %s is unknown to the process %s." %(context, msg, name, self._Process__name))
463  def _placeEndPath(self,name,mod):
464  self._validateSequence(mod, name)
465  try:
466  self._place(name, mod, self.__endpaths)
467  except ModuleCloneError, msg:
468  context = format_outerframe(4)
469  raise Exception("%sThe module %s in endpath %s is unknown to the process %s." %(context, msg, name, self._Process__name))
470  def _placeSequence(self,name,mod):
471  self._validateSequence(mod, name)
472  self._place(name, mod, self.__sequences)
473  def _placeESProducer(self,name,mod):
474  self._place(name, mod, self.__esproducers)
475  def _placeESPrefer(self,name,mod):
476  self._place(name, mod, self.__esprefers)
477  def _placeESSource(self,name,mod):
478  self._place(name, mod, self.__essources)
479  def _placeAlias(self,name,mod):
480  self._place(name, mod, self.__aliases)
481  def _placePSet(self,name,mod):
482  self._place(name, mod, self.__psets)
483  def _placeVPSet(self,name,mod):
484  self._place(name, mod, self.__vpsets)
485  def _placeSource(self,name,mod):
486  """Allow the source to be referenced by 'source' or by type name"""
487  if name != 'source':
488  raise ValueError("The label '"+name+"' can not be used for a Source. Only 'source' is allowed.")
489  if self.__dict__['_Process__source'] is not None :
490  del self.__dict__[self.__dict__['_Process__source'].type_()]
491  self.__dict__['_Process__source'] = mod
492  self.__dict__[mod.type_()] = mod
493  def _placeLooper(self,name,mod):
494  if name != 'looper':
495  raise ValueError("The label '"+name+"' can not be used for a Looper. Only 'looper' is allowed.")
496  self.__dict__['_Process__looper'] = mod
497  self.__dict__[mod.type_()] = mod
498  def _placeSubProcess(self,name,mod):
499  if name != 'subProcess':
500  raise ValueError("The label '"+name+"' can not be used for a SubProcess. Only 'subProcess' is allowed.")
501  self.__dict__['_Process__subProcess'] = mod
502  self.__dict__[mod.type_()] = mod
503  def _placeService(self,typeName,mod):
504  self._place(typeName, mod, self.__services)
505  self.__dict__[typeName]=mod
506  def load(self, moduleName):
507  moduleName = moduleName.replace("/",".")
508  module = __import__(moduleName)
509  self.extend(sys.modules[moduleName])
510  def extend(self,other,items=()):
511  """Look in other and find types which we can use"""
512  # enable explicit check to avoid overwriting of existing objects
513  self.__dict__['_Process__InExtendCall'] = True
514 
515  seqs = dict()
516  for name in dir(other):
517  #'from XX import *' ignores these, and so should we.
518  if name.startswith('_'):
519  continue
520  item = getattr(other,name)
521  if name == "source" or name == "looper" or name == "subProcess":
522  self.__setattr__(name,item)
523  elif isinstance(item,_ModuleSequenceType):
524  seqs[name]=item
525  elif isinstance(item,_Labelable):
526  self.__setattr__(name,item)
527  if not item.hasLabel_() :
528  item.setLabel(name)
529  elif isinstance(item,Schedule):
530  self.__setattr__(name,item)
531  elif isinstance(item,_Unlabelable):
532  self.add_(item)
533 
534  #now create a sequence which uses the newly made items
535  for name in seqs.iterkeys():
536  seq = seqs[name]
537  #newSeq = seq.copy()
538  #
539  if id(seq) not in self._cloneToObjectDict:
540  self.__setattr__(name,seq)
541  else:
542  newSeq = self._cloneToObjectDict[id(seq)]
543  self.__dict__[name]=newSeq
544  self.__setObjectLabel(newSeq, name)
545  #now put in proper bucket
546  newSeq._place(name,self)
547  self.__dict__['_Process__InExtendCall'] = False
548  def _dumpConfigNamedList(self,items,typeName,options):
549  returnValue = ''
550  for name,item in items:
551  returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
552  return returnValue
553  def _dumpConfigUnnamedList(self,items,typeName,options):
554  returnValue = ''
555  for name,item in items:
556  returnValue +=options.indentation()+typeName+' = '+item.dumpConfig(options)
557  return returnValue
558  def _dumpConfigOptionallyNamedList(self,items,typeName,options):
559  returnValue = ''
560  for name,item in items:
561  if name == item.type_():
562  name = ''
563  returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
564  return returnValue
565  def dumpConfig(self, options=PrintOptions()):
566  """return a string containing the equivalent process defined using the old configuration language"""
567  config = "process "+self.__name+" = {\n"
568  options.indent()
569  if self.source_():
570  config += options.indentation()+"source = "+self.source_().dumpConfig(options)
571  if self.looper_():
572  config += options.indentation()+"looper = "+self.looper_().dumpConfig(options)
573  if self.subProcess_():
574  config += options.indentation()+"subProcess = "+self.subProcess_().dumpConfig(options)
575 
576  config+=self._dumpConfigNamedList(self.producers_().iteritems(),
577  'module',
578  options)
579  config+=self._dumpConfigNamedList(self.filters_().iteritems(),
580  'module',
581  options)
582  config+=self._dumpConfigNamedList(self.analyzers_().iteritems(),
583  'module',
584  options)
585  config+=self._dumpConfigNamedList(self.outputModules_().iteritems(),
586  'module',
587  options)
588  config+=self._dumpConfigNamedList(self.sequences_().iteritems(),
589  'sequence',
590  options)
591  config+=self._dumpConfigNamedList(self.paths_().iteritems(),
592  'path',
593  options)
594  config+=self._dumpConfigNamedList(self.endpaths_().iteritems(),
595  'endpath',
596  options)
597  config+=self._dumpConfigUnnamedList(self.services_().iteritems(),
598  'service',
599  options)
600  config+=self._dumpConfigNamedList(self.aliases_().iteritems(),
601  'alias',
602  options)
603  config+=self._dumpConfigOptionallyNamedList(
604  self.es_producers_().iteritems(),
605  'es_module',
606  options)
607  config+=self._dumpConfigOptionallyNamedList(
608  self.es_sources_().iteritems(),
609  'es_source',
610  options)
611  config += self._dumpConfigESPrefers(options)
612  for name,item in self.psets.iteritems():
613  config +=options.indentation()+item.configTypeName()+' '+name+' = '+item.configValue(options)
614  for name,item in self.vpsets.iteritems():
615  config +=options.indentation()+'VPSet '+name+' = '+item.configValue(options)
616  if self.schedule:
617  pathNames = [p.label_() for p in self.schedule]
618  config +=options.indentation()+'schedule = {'+','.join(pathNames)+'}\n'
619 
620 # config+=self._dumpConfigNamedList(self.vpsets.iteritems(),
621 # 'VPSet',
622 # options)
623  config += "}\n"
624  options.unindent()
625  return config
626  def _dumpConfigESPrefers(self, options):
627  result = ''
628  for item in self.es_prefers_().itervalues():
629  result +=options.indentation()+'es_prefer '+item.targetLabel_()+' = '+item.dumpConfig(options)
630  return result
631  def _dumpPythonList(self, d, options):
632  returnValue = ''
633  if isinstance(d, DictTypes.SortedKeysDict):
634  for name,item in d.items():
635  returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
636  else:
637  for name,item in sorted(d.items()):
638  returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
639  return returnValue
640  def _validateSequence(self, sequence, label):
641  # See if every module has been inserted into the process
642  try:
643  l = set()
644  nameVisitor = NodeNameVisitor(l)
645  sequence.visit(nameVisitor)
646  except:
647  raise RuntimeError("An entry in sequence "+label + ' has no label')
649  #for each sequence, see what other sequences it depends upon
650  returnValue=DictTypes.SortedKeysDict()
651  dependencies = {}
652  for label,seq in self.sequences.iteritems():
653  d = []
654  v = SequenceVisitor(d)
655  seq.visit(v)
656  dependencies[label]=[dep.label_() for dep in d if dep.hasLabel_()]
657  resolvedDependencies=True
658  #keep looping until we can no longer get rid of all dependencies
659  # if that happens it means we have circular dependencies
660  iterCount = 0
661  while resolvedDependencies:
662  iterCount += 1
663  resolvedDependencies = (0 != len(dependencies))
664  oldDeps = dict(dependencies)
665  for label,deps in oldDeps.iteritems():
666  # don't try too hard
667  if len(deps)==0 or iterCount > 100:
668  iterCount = 0
669  resolvedDependencies=True
670  returnValue[label]=self.sequences[label]
671  #remove this as a dependency for all other sequences
672  del dependencies[label]
673  for lb2,deps2 in dependencies.iteritems():
674  while deps2.count(label):
675  deps2.remove(label)
676  if len(dependencies):
677  raise RuntimeError("circular sequence dependency discovered \n"+
678  ",".join([label for label,junk in dependencies.iteritems()]))
679  return returnValue
680  def _dumpPython(self, d, options):
681  result = ''
682  for name, value in d.iteritems():
683  result += value.dumpPythonAs(name,options)+'\n'
684  return result
685  def dumpPython(self, options=PrintOptions()):
686  """return a string containing the equivalent process defined using python"""
687  result = "import FWCore.ParameterSet.Config as cms\n\n"
688  result += "process = cms.Process(\""+self.__name+"\")\n\n"
689  if self.source_():
690  result += "process.source = "+self.source_().dumpPython(options)
691  if self.looper_():
692  result += "process.looper = "+self.looper_().dumpPython()
693  if self.subProcess_():
694  result += self.subProcess_().dumpPython(options)
695  result+=self._dumpPythonList(self.producers_(), options)
696  result+=self._dumpPythonList(self.filters_() , options)
697  result+=self._dumpPythonList(self.analyzers_(), options)
698  result+=self._dumpPythonList(self.outputModules_(), options)
699  result+=self._dumpPythonList(self._sequencesInDependencyOrder(), options)
700  result+=self._dumpPythonList(self.paths_(), options)
701  result+=self._dumpPythonList(self.endpaths_(), options)
702  result+=self._dumpPythonList(self.services_(), options)
703  result+=self._dumpPythonList(self.es_producers_(), options)
704  result+=self._dumpPythonList(self.es_sources_(), options)
705  result+=self._dumpPython(self.es_prefers_(), options)
706  result+=self._dumpPythonList(self.aliases_(), options)
707  result+=self._dumpPythonList(self.psets, options)
708  result+=self._dumpPythonList(self.vpsets, options)
709  if self.schedule:
710  pathNames = ['process.'+p.label_() for p in self.schedule]
711  result +='process.schedule = cms.Schedule(*[ ' + ', '.join(pathNames) + ' ])\n'
712 
713  return result
714  def _replaceInSequences(self, label, new):
715  old = getattr(self,label)
716  #TODO - replace by iterator concatenation
717  for sequenceable in self.sequences.itervalues():
718  sequenceable.replace(old,new)
719  for sequenceable in self.paths.itervalues():
720  sequenceable.replace(old,new)
721  for sequenceable in self.endpaths.itervalues():
722  sequenceable.replace(old,new)
723  def globalReplace(self,label,new):
724  """ Replace the item with label 'label' by object 'new' in the process and all sequences/paths"""
725  if not hasattr(self,label):
726  raise LookupError("process has no item of label "+label)
727  self._replaceInSequences(label, new)
728  setattr(self,label,new)
729  def _insertInto(self, parameterSet, itemDict):
730  for name,value in itemDict.iteritems():
731  value.insertInto(parameterSet, name)
732  def _insertOneInto(self, parameterSet, label, item, tracked):
733  vitems = []
734  if not item == None:
735  newlabel = item.nameInProcessDesc_(label)
736  vitems = [newlabel]
737  item.insertInto(parameterSet, newlabel)
738  parameterSet.addVString(tracked, label, vitems)
739  def _insertManyInto(self, parameterSet, label, itemDict, tracked):
740  l = []
741  for name,value in itemDict.iteritems():
742  newLabel = value.nameInProcessDesc_(name)
743  l.append(newLabel)
744  value.insertInto(parameterSet, name)
745  # alphabetical order is easier to compare with old language
746  l.sort()
747  parameterSet.addVString(tracked, label, l)
748  def _insertPaths(self, processPSet):
749  scheduledPaths = []
750  triggerPaths = []
751  endpaths = []
752  if self.schedule_() == None:
753  # make one from triggerpaths & endpaths
754  for name,value in self.paths_().iteritems():
755  scheduledPaths.append(name)
756  triggerPaths.append(name)
757  for name,value in self.endpaths_().iteritems():
758  scheduledPaths.append(name)
759  endpaths.append(name)
760  else:
761  for path in self.schedule_():
762  pathname = path.label_()
763  scheduledPaths.append(pathname)
764  if self.endpaths_().has_key(pathname):
765  endpaths.append(pathname)
766  else:
767  triggerPaths.append(pathname)
768  processPSet.addVString(True, "@end_paths", endpaths)
769  processPSet.addVString(True, "@paths", scheduledPaths)
770  # trigger_paths are a little different
771  p = processPSet.newPSet()
772  p.addVString(True, "@trigger_paths", triggerPaths)
773  processPSet.addPSet(True, "@trigger_paths", p)
774  # add all these paths
775  pathValidator = PathValidator()
776  endpathValidator = EndPathValidator()
777  for triggername in triggerPaths:
778  #self.paths_()[triggername].insertInto(processPSet, triggername, self.sequences_())
779  pathValidator.setLabel(triggername)
780  self.paths_()[triggername].visit(pathValidator)
781  self.paths_()[triggername].insertInto(processPSet, triggername, self.__dict__)
782  for endpathname in endpaths:
783  #self.endpaths_()[endpathname].insertInto(processPSet, endpathname, self.sequences_())
784  endpathValidator.setLabel(endpathname)
785  self.endpaths_()[endpathname].visit(endpathValidator)
786  self.endpaths_()[endpathname].insertInto(processPSet, endpathname, self.__dict__)
787  processPSet.addVString(False, "@filters_on_endpaths", endpathValidator.filtersOnEndpaths)
788 
789  def prune(self,verbose=False):
790  """ Remove clutter from the process which we think is unnecessary:
791  tracked PSets, VPSets and unused modules and sequences. If a Schedule has been set, then Paths and EndPaths
792  not in the schedule will also be removed, along with an modules and sequences used only by
793  those removed Paths and EndPaths."""
794  for name in self.psets_():
795  if getattr(self,name).isTracked():
796  delattr(self, name)
797  for name in self.vpsets_():
798  delattr(self, name)
799  #first we need to resolve any SequencePlaceholders being used
800  for x in self.paths.itervalues():
801  x.resolve(self.__dict__)
802  for x in self.endpaths.itervalues():
803  x.resolve(self.__dict__)
804  usedModules = set()
805  unneededPaths = set()
806  if self.schedule_():
807  usedModules=set(self.schedule_().moduleNames())
808  #get rid of unused paths
809  schedNames = set(( x.label_() for x in self.schedule_()))
810  names = set(self.paths)
811  names.update(set(self.endpaths))
812  unneededPaths = names - schedNames
813  for n in unneededPaths:
814  delattr(self,n)
815  else:
816  pths = list(self.paths.itervalues())
817  pths.extend(self.endpaths.itervalues())
818  temp = Schedule(*pths)
819  usedModules=set(temp.moduleNames())
820  unneededModules = self._pruneModules(self.producers_(), usedModules)
821  unneededModules.update(self._pruneModules(self.filters_(), usedModules))
822  unneededModules.update(self._pruneModules(self.analyzers_(), usedModules))
823  #remove sequences that do not appear in remaining paths and endpaths
824  seqs = list()
825  sv = SequenceVisitor(seqs)
826  for p in self.paths.itervalues():
827  p.visit(sv)
828  for p in self.endpaths.itervalues():
829  p.visit(sv)
830  keepSeqSet = set(( s for s in seqs if s.hasLabel_()))
831  availableSeqs = set(self.sequences.itervalues())
832  unneededSeqs = availableSeqs-keepSeqSet
833  unneededSeqLabels = []
834  for s in unneededSeqs:
835  unneededSeqLabels.append(s.label_())
836  delattr(self,s.label_())
837  if verbose:
838  print "prune removed the following:"
839  print " modules:"+",".join(unneededModules)
840  print " sequences:"+",".join(unneededSeqLabels)
841  print " paths/endpaths:"+",".join(unneededPaths)
842  def _pruneModules(self, d, scheduledNames):
843  moduleNames = set(d.keys())
844  junk = moduleNames - scheduledNames
845  for name in junk:
846  delattr(self, name)
847  return junk
848 
849  def fillProcessDesc(self, processPSet):
850  """Used by the framework to convert python to C++ objects"""
851  class ServiceInjectorAdaptor(object):
852  def __init__(self,ppset,thelist):
853  self.__thelist = thelist
854  self.__processPSet = ppset
855  def addService(self,pset):
856  self.__thelist.append(pset)
857  def newPSet(self):
858  return self.__processPSet.newPSet()
859  #This adaptor is used to 'add' the method 'getTopPSet_'
860  # to the ProcessDesc and PythonParameterSet C++ classes.
861  # This method is needed for the PSet refToPSet_ functionality.
862  class TopLevelPSetAcessorAdaptor(object):
863  def __init__(self,ppset,process):
864  self.__ppset = ppset
865  self.__process = process
866  def __getattr__(self,attr):
867  return getattr(self.__ppset,attr)
868  def getTopPSet_(self,label):
869  return getattr(self.__process,label)
870  def newPSet(self):
871  return TopLevelPSetAcessorAdaptor(self.__ppset.newPSet(),self.__process)
872  def addPSet(self,tracked,name,ppset):
873  return self.__ppset.addPSet(tracked,name,self.__extractPSet(ppset))
874  def addVPSet(self,tracked,name,vpset):
875  return self.__ppset.addVPSet(tracked,name,[self.__extractPSet(x) for x in vpset])
876  def __extractPSet(self,pset):
877  if isinstance(pset,TopLevelPSetAcessorAdaptor):
878  return pset.__ppset
879  return pset
880 
881  self.validate()
882  processPSet.addString(True, "@process_name", self.name_())
883  all_modules = self.producers_().copy()
884  all_modules.update(self.filters_())
885  all_modules.update(self.analyzers_())
886  all_modules.update(self.outputModules_())
887  adaptor = TopLevelPSetAcessorAdaptor(processPSet,self)
888  self._insertInto(adaptor, self.psets_())
889  self._insertInto(adaptor, self.vpsets_())
890  self._insertManyInto(adaptor, "@all_modules", all_modules, True)
891  self._insertOneInto(adaptor, "@all_sources", self.source_(), True)
892  self._insertOneInto(adaptor, "@all_loopers", self.looper_(), True)
893  self._insertOneInto(adaptor, "@all_subprocesses", self.subProcess_(), False)
894  self._insertManyInto(adaptor, "@all_esmodules", self.es_producers_(), True)
895  self._insertManyInto(adaptor, "@all_essources", self.es_sources_(), True)
896  self._insertManyInto(adaptor, "@all_esprefers", self.es_prefers_(), True)
897  self._insertManyInto(adaptor, "@all_aliases", self.aliases_(), True)
898  self._insertPaths(adaptor)
899  #handle services differently
900  services = []
901  for n in self.services_():
902  getattr(self,n).insertInto(ServiceInjectorAdaptor(adaptor,services))
903  adaptor.addVPSet(False,"services",services)
904  return processPSet
905 
906  def validate(self):
907  # check if there's some input
908  # Breaks too many unit tests for now
909  #if self.source_() == None and self.looper_() == None:
910  # raise RuntimeError("No input source was found for this process")
911  pass
912 
913  def prefer(self, esmodule,*args,**kargs):
914  """Prefer this ES source or producer. The argument can
915  either be an object label, e.g.,
916  process.prefer(process.juicerProducer) (not supported yet)
917  or a name of an ESSource or ESProducer
918  process.prefer("juicer")
919  or a type of unnamed ESSource or ESProducer
920  process.prefer("JuicerProducer")
921  In addition, you can pass as a labelled arguments the name of the Record you wish to
922  prefer where the type passed is a cms.vstring and that vstring can contain the
923  name of the C++ types in the Record which are being preferred, e.g.,
924  #prefer all data in record 'OrangeRecord' from 'juicer'
925  process.prefer("juicer", OrangeRecord=cms.vstring())
926  or
927  #prefer only "Orange" data in "OrangeRecord" from "juicer"
928  process.prefer("juicer", OrangeRecord=cms.vstring("Orange"))
929  or
930  #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer"
931  ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
932  """
933  # see if this refers to a named ESProducer
934  if isinstance(esmodule, ESSource) or isinstance(esmodule, ESProducer):
935  raise RuntimeError("Syntax of process.prefer(process.esmodule) not supported yet")
936  elif self._findPreferred(esmodule, self.es_producers_(),*args,**kargs) or \
937  self._findPreferred(esmodule, self.es_sources_(),*args,**kargs):
938  pass
939  else:
940  raise RuntimeError("Cannot resolve prefer for "+repr(esmodule))
941 
942  def _findPreferred(self, esname, d,*args,**kargs):
943  # is esname a name in the dictionary?
944  if esname in d:
945  typ = d[esname].type_()
946  if typ == esname:
947  self.__setattr__( esname+"_prefer", ESPrefer(typ,*args,**kargs) )
948  else:
949  self.__setattr__( esname+"_prefer", ESPrefer(typ, esname,*args,**kargs) )
950  return True
951  else:
952  # maybe it's an unnamed ESModule?
953  found = False
954  for name, value in d.iteritems():
955  if value.type_() == esname:
956  if found:
957  raise RuntimeError("More than one ES module for "+esname)
958  found = True
959  self.__setattr__(esname+"_prefer", ESPrefer(d[esname].type_()) )
960  return found
961 
963  """a dictionary with fixed keys"""
965  raise AttributeError, "An FilteredStream defintion cannot be modified after creation."
966  _blocked_attribute = property(_blocked_attribute)
967  __setattr__ = __delitem__ = __setitem__ = clear = _blocked_attribute
968  pop = popitem = setdefault = update = _blocked_attribute
969  def __new__(cls, *args, **kw):
970  new = dict.__new__(cls)
971  dict.__init__(new, *args, **kw)
972  keys = kw.keys()
973  keys.sort()
974  if keys != ['content', 'dataTier', 'name', 'paths', 'responsible', 'selectEvents']:
975  raise ValueError("The needed parameters are: content, dataTier, name, paths, responsible, selectEvents")
976  if not isinstance(kw['name'],str):
977  raise ValueError("name must be of type string")
978  if not isinstance(kw['content'], vstring) and not isinstance(kw['content'],str):
979  raise ValueError("content must be of type vstring or string")
980  if not isinstance(kw['dataTier'], string):
981  raise ValueError("dataTier must be of type string")
982  if not isinstance(kw['selectEvents'], PSet):
983  raise ValueError("selectEvents must be of type PSet")
984  if not isinstance(kw['paths'],(tuple, Path)):
985  raise ValueError("'paths' must be a tuple of paths")
986  return new
987  def __init__(self, *args, **kw):
988  pass
989  def __repr__(self):
990  return "FilteredStream object: %s" %self["name"]
991  def __getattr__(self,attr):
992  return self[attr]
993 
995  """Allows embedding another process within a parent process. This allows one to
996  chain processes together directly in one cmsRun job rather than having to run
997  separate jobs which are connected via a temporary file.
998  """
999  def __init__(self,process, SelectEvents = untracked.PSet(), outputCommands = untracked.vstring()):
1000  """
1001  """
1002  if not isinstance(process, Process):
1003  raise ValueError("the 'process' argument must be of type cms.Process")
1004  if not isinstance(SelectEvents,PSet):
1005  raise ValueError("the 'SelectEvents' argument must be of type cms.untracked.PSet")
1006  if not isinstance(outputCommands,vstring):
1007  raise ValueError("the 'outputCommands' argument must be of type cms.untracked.vstring")
1008  self.__process = process
1009  self.__SelectEvents = SelectEvents
1010  self.__outputCommands = outputCommands
1011  def dumpPython(self,options):
1012  out = "parentProcess"+str(hash(self))+" = process\n"
1013  out += self.__process.dumpPython()
1014  out += "childProcess = process\n"
1015  out += "process = parentProcess"+str(hash(self))+"\n"
1016  out += "process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = "+self.__SelectEvents.dumpPython(options) +", outputCommands = "+self.__outputCommands.dumpPython(options) +")\n"
1017  return out
1018  def type_(self):
1019  return 'subProcess'
1020  def nameInProcessDesc_(self,label):
1021  return '@sub_process'
1022  def _place(self,label,process):
1023  process._placeSubProcess('subProcess',self)
1024  def insertInto(self,parameterSet, newlabel):
1025  topPSet = parameterSet.newPSet()
1026  self.__process.fillProcessDesc(topPSet)
1027  subProcessPSet = parameterSet.newPSet()
1028  self.__SelectEvents.insertInto(subProcessPSet,"SelectEvents")
1029  self.__outputCommands.insertInto(subProcessPSet,"outputCommands")
1030  subProcessPSet.addPSet(False,"process",topPSet)
1031  parameterSet.addPSet(False,self.nameInProcessDesc_("subProcess"), subProcessPSet)
1032 
1034  """Helper class for Modifier which takes key/value pairs and uses them to reset parameters of the object"""
1035  def __init__(self,args):
1036  self.__args = args
1037  def __call__(self,obj):
1038  for k,v in self.__args.iteritems():
1039  setattr(obj,k,v)
1040 
1042  """This class is used to define standard modifications to a Process.
1043  An instance of this class is declared to denote a specific modification,e.g. era2017 could
1044  reconfigure items in a process to match our expectation of running in 2017. Once declared,
1045  these Modifier instances are imported into a configuration and items which need to be modified
1046  are then associated with the Modifier and with the action to do the modification.
1047  The registered modifications will only occur if the modify() method is called.
1048  """
1049  def __init__(self):
1052  def toModifyProcess(self,func):
1053  """This is used to register actions to be performed on the process as a whole.
1054  This takes as argument a callable object (e.g. function) which takes as its sole argument an instance of Process"""
1055  self.__processModifiers.append(func)
1056  def toModify(self,obj, func=None,**kw):
1057  """This is used to register an action to be performed on the specific object. Two different forms are allowed
1058  Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1059  which will be the object passed in as the first argument.
1060  Form 2: A list of parameter name, value pairs can be passed
1061  mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1062  """
1063  if func is not None and len(kw) != 0:
1064  raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
1065  if func is not None:
1066  self.__objectToModifiers.append( (obj,func))
1067  else:
1068  self.__objectToModifiers.append( (obj, _ParameterModifier(kw)))
1069  def modify(self,process):
1070  """This applies all the registered modifiers to the passed in process"""
1071  for m in self.__processModifiers:
1072  m(process)
1073  for o,m in self.__objectToModifiers:
1074  if isinstance(o,_Labelable):
1075  if o.hasLabel_():
1076  m(o)
1077  else:
1078  m(o)
1079  return process
1080  def __call__(self,process):
1081  """Forwards to modify call. The presence of a __call__ allows Modifiers to be chained together.
1082  E.g. Have bar inherit all modifiers of foo
1083  foo = Modifier()
1084  bar = Modifier()
1085  foo.toModifyProcess(bar)
1086  """
1087  self.modify(process)
1088 
1089 if __name__=="__main__":
1090  import unittest
1091  import copy
1092 
1094  """Has same interface as the C++ object which creates PSets
1095  """
1096  def __init__(self):
1097  self.values = dict()
1098  def __insertValue(self,tracked,label,value):
1099  self.values[label]=(tracked,value)
1100  def addInt32(self,tracked,label,value):
1101  self.__insertValue(tracked,label,value)
1102  def addVInt32(self,tracked,label,value):
1103  self.__insertValue(tracked,label,value)
1104  def addUInt32(self,tracked,label,value):
1105  self.__insertValue(tracked,label,value)
1106  def addVUInt32(self,tracked,label,value):
1107  self.__insertValue(tracked,label,value)
1108  def addInt64(self,tracked,label,value):
1109  self.__insertValue(tracked,label,value)
1110  def addVInt64(self,tracked,label,value):
1111  self.__insertValue(tracked,label,value)
1112  def addUInt64(self,tracked,label,value):
1113  self.__insertValue(tracked,label,value)
1114  def addVUInt64(self,tracked,label,value):
1115  self.__insertValue(tracked,label,value)
1116  def addDouble(self,tracked,label,value):
1117  self.__insertValue(tracked,label,value)
1118  def addVDouble(self,tracked,label,value):
1119  self.__insertValue(tracked,label,value)
1120  def addBool(self,tracked,label,value):
1121  self.__insertValue(tracked,label,value)
1122  def addString(self,tracked,label,value):
1123  self.__insertValue(tracked,label,value)
1124  def addVString(self,tracked,label,value):
1125  self.__insertValue(tracked,label,value)
1126  def addInputTag(self,tracked,label,value):
1127  self.__insertValue(tracked,label,value)
1128  def addVInputTag(self,tracked,label,value):
1129  self.__insertValue(tracked,label,value)
1130  def addESInputTag(self,tracked,label,value):
1131  self.__insertValue(tracked,label,value)
1132  def addVESInputTag(self,tracked,label,value):
1133  self.__insertValue(tracked,label,value)
1134  def addEventID(self,tracked,label,value):
1135  self.__insertValue(tracked,label,value)
1136  def addVEventID(self,tracked,label,value):
1137  self.__insertValue(tracked,label,value)
1138  def addLuminosityBlockID(self,tracked,label,value):
1139  self.__insertValue(tracked,label,value)
1140  def addLuminosityBlockID(self,tracked,label,value):
1141  self.__insertValue(tracked,label,value)
1142  def addEventRange(self,tracked,label,value):
1143  self.__insertValue(tracked,label,value)
1144  def addVEventRange(self,tracked,label,value):
1145  self.__insertValue(tracked,label,value)
1146  def addPSet(self,tracked,label,value):
1147  self.__insertValue(tracked,label,value)
1148  def addVPSet(self,tracked,label,value):
1149  self.__insertValue(tracked,label,value)
1150  def addFileInPath(self,tracked,label,value):
1151  self.__insertValue(tracked,label,value)
1152  def newPSet(self):
1153  return TestMakePSet()
1154 
1155  class TestModuleCommand(unittest.TestCase):
1156  def setUp(self):
1157  """Nothing to do """
1158  None
1160  p = _Parameterizable()
1161  self.assertEqual(len(p.parameterNames_()),0)
1162  p.a = int32(1)
1163  self.assert_('a' in p.parameterNames_())
1164  self.assertEqual(p.a.value(), 1)
1165  p.a = 10
1166  self.assertEqual(p.a.value(), 10)
1167  p.a = untracked(int32(1))
1168  self.assertEqual(p.a.value(), 1)
1169  self.failIf(p.a.isTracked())
1170  p.a = untracked.int32(1)
1171  self.assertEqual(p.a.value(), 1)
1172  self.failIf(p.a.isTracked())
1173  p = _Parameterizable(foo=int32(10), bar = untracked(double(1.0)))
1174  self.assertEqual(p.foo.value(), 10)
1175  self.assertEqual(p.bar.value(),1.0)
1176  self.failIf(p.bar.isTracked())
1177  self.assertRaises(TypeError,setattr,(p,'c',1))
1178  p = _Parameterizable(a=PSet(foo=int32(10), bar = untracked(double(1.0))))
1179  self.assertEqual(p.a.foo.value(),10)
1180  self.assertEqual(p.a.bar.value(),1.0)
1181  p.b = untracked(PSet(fii = int32(1)))
1182  self.assertEqual(p.b.fii.value(),1)
1183  self.failIf(p.b.isTracked())
1184  #test the fact that values can be shared
1185  v = int32(10)
1186  p=_Parameterizable(a=v)
1187  v.setValue(11)
1188  self.assertEqual(p.a.value(),11)
1189  p.a = 12
1190  self.assertEqual(p.a.value(),12)
1191  self.assertEqual(v.value(),12)
1193  p = _TypedParameterizable("blah", b=int32(1))
1194  #see if copy works deeply
1195  other = p.copy()
1196  other.b = 2
1197  self.assertNotEqual(p.b,other.b)
1198 
1200  p = Process("test")
1201  p.a = EDAnalyzer("MyAnalyzer")
1202  self.assert_( 'a' in p.analyzers_() )
1203  self.assert_( 'a' in p.analyzers)
1204  p.add_(Service("MessageLogger"))
1205  self.assert_('MessageLogger' in p.services_())
1206  self.assertEqual(p.MessageLogger.type_(), "MessageLogger")
1207  p.Tracer = Service("Tracer")
1208  self.assert_('Tracer' in p.services_())
1209  self.assertRaises(TypeError, setattr, *(p,'b',"this should fail"))
1210  self.assertRaises(TypeError, setattr, *(p,'bad',Service("MessageLogger")))
1211  self.assertRaises(ValueError, setattr, *(p,'bad',Source("PoolSource")))
1212  p.out = OutputModule("Outer")
1213  self.assertEqual(p.out.type_(), 'Outer')
1214  self.assert_( 'out' in p.outputModules_() )
1215 
1216  p.geom = ESSource("GeomProd")
1217  self.assert_('geom' in p.es_sources_())
1218  p.add_(ESSource("ConfigDB"))
1219  self.assert_('ConfigDB' in p.es_sources_())
1220 
1221  p.aliasfoo1 = EDAlias(foo1 = VPSet(PSet(type = string("Foo1"))))
1222  self.assert_('aliasfoo1' in p.aliases_())
1223 
1225  class FromArg(object):
1226  def __init__(self,*arg,**args):
1227  for name in args.iterkeys():
1228  self.__dict__[name]=args[name]
1229 
1230  a=EDAnalyzer("MyAnalyzer")
1231  t=EDAnalyzer("MyAnalyzer")
1232  t.setLabel("foo")
1233  s1 = Sequence(a)
1234  s2 = Sequence(s1)
1235  s3 = Sequence(s2)
1236  d = FromArg(
1237  a=a,
1238  b=Service("Full"),
1239  c=Path(a),
1240  d=s2,
1241  e=s1,
1242  f=s3,
1243  g=Sequence(s1+s2+s3)
1244  )
1245  p = Process("Test")
1246  p.extend(d)
1247  self.assertEqual(p.a.type_(),"MyAnalyzer")
1248  self.assertEqual(p.a.label_(),"a")
1249  self.assertRaises(AttributeError,getattr,p,'b')
1250  self.assertEqual(p.Full.type_(),"Full")
1251  self.assertEqual(str(p.c),'a')
1252  self.assertEqual(str(p.d),'a')
1253 
1254  z1 = FromArg(
1255  a=a,
1256  b=Service("Full"),
1257  c=Path(a),
1258  d=s2,
1259  e=s1,
1260  f=s3,
1261  s4=s3,
1262  g=Sequence(s1+s2+s3)
1263  )
1264 
1265  p1 = Process("Test")
1266  #p1.extend(z1)
1267  self.assertRaises(ValueError, p1.extend, z1)
1268 
1269  z2 = FromArg(
1270  a=a,
1271  b=Service("Full"),
1272  c=Path(a),
1273  d=s2,
1274  e=s1,
1275  f=s3,
1276  aaa=copy.deepcopy(a),
1277  s4=copy.deepcopy(s3),
1278  g=Sequence(s1+s2+s3),
1279  t=t
1280  )
1281  p2 = Process("Test")
1282  p2.extend(z2)
1283  #self.assertRaises(ValueError, p2.extend, z2)
1284  self.assertEqual(p2.s4.label_(),"s4")
1285  #p2.s4.setLabel("foo")
1286  self.assertRaises(ValueError, p2.s4.setLabel, "foo")
1287  p2.s4.setLabel("s4")
1288  p2.s4.setLabel(None)
1289  p2.s4.setLabel("foo")
1290  p2._Process__setObjectLabel(p2.s4, "foo")
1291  p2._Process__setObjectLabel(p2.s4, None)
1292  p2._Process__setObjectLabel(p2.s4, "bar")
1293 
1295  p = Process("test")
1296  p.a = EDAnalyzer("MyAnalyzer")
1297  p.p = Path(p.a)
1298  p.s = Sequence(p.a)
1299  p.r = Sequence(p.s)
1300  p.p2 = Path(p.s)
1301  p.schedule = Schedule(p.p2,p.p)
1302  d=p.dumpPython()
1303  self.assertEqual(d,
1304 """import FWCore.ParameterSet.Config as cms
1305 
1306 process = cms.Process("test")
1307 
1308 process.a = cms.EDAnalyzer("MyAnalyzer")
1309 
1310 
1311 process.s = cms.Sequence(process.a)
1312 
1313 
1314 process.r = cms.Sequence(process.s)
1315 
1316 
1317 process.p = cms.Path(process.a)
1318 
1319 
1320 process.p2 = cms.Path(process.s)
1321 
1322 
1323 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1324 """)
1325  #Reverse order of 'r' and 's'
1326  p = Process("test")
1327  p.a = EDAnalyzer("MyAnalyzer")
1328  p.p = Path(p.a)
1329  p.r = Sequence(p.a)
1330  p.s = Sequence(p.r)
1331  p.p2 = Path(p.r)
1332  p.schedule = Schedule(p.p2,p.p)
1333  p.b = EDAnalyzer("YourAnalyzer")
1334  d=p.dumpPython()
1335  self.assertEqual(d,
1336 """import FWCore.ParameterSet.Config as cms
1337 
1338 process = cms.Process("test")
1339 
1340 process.a = cms.EDAnalyzer("MyAnalyzer")
1341 
1342 
1343 process.b = cms.EDAnalyzer("YourAnalyzer")
1344 
1345 
1346 process.r = cms.Sequence(process.a)
1347 
1348 
1349 process.s = cms.Sequence(process.r)
1350 
1351 
1352 process.p = cms.Path(process.a)
1353 
1354 
1355 process.p2 = cms.Path(process.r)
1356 
1357 
1358 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1359 """)
1360  #use an anonymous sequence
1361  p = Process("test")
1362  p.a = EDAnalyzer("MyAnalyzer")
1363  p.p = Path(p.a)
1364  s = Sequence(p.a)
1365  p.r = Sequence(s)
1366  p.p2 = Path(p.r)
1367  p.schedule = Schedule(p.p2,p.p)
1368  d=p.dumpPython()
1369  self.assertEqual(d,
1370  """import FWCore.ParameterSet.Config as cms
1371 
1372 process = cms.Process("test")
1373 
1374 process.a = cms.EDAnalyzer("MyAnalyzer")
1375 
1376 
1377 process.r = cms.Sequence((process.a))
1378 
1379 
1380 process.p = cms.Path(process.a)
1381 
1382 
1383 process.p2 = cms.Path(process.r)
1384 
1385 
1386 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1387 """)
1388 
1389  def testSecSource(self):
1390  p = Process('test')
1391  p.a = SecSource("MySecSource")
1392  self.assertEqual(p.dumpPython().replace('\n',''),'import FWCore.ParameterSet.Config as cmsprocess = cms.Process("test")process.a = cms.SecSource("MySecSource")')
1393 
1395  p = Process('test')
1396  p.a = EDAnalyzer("MyAnalyzer")
1397  p.b = EDAnalyzer("YourAnalyzer")
1398  p.c = EDAnalyzer("OurAnalyzer")
1399  p.s = Sequence(p.a*p.b)
1400  p.p = Path(p.c+p.s+p.a)
1401  new = EDAnalyzer("NewAnalyzer")
1402  p.globalReplace("a",new)
1403 
1404  def testSequence(self):
1405  p = Process('test')
1406  p.a = EDAnalyzer("MyAnalyzer")
1407  p.b = EDAnalyzer("YourAnalyzer")
1408  p.c = EDAnalyzer("OurAnalyzer")
1409  p.s = Sequence(p.a*p.b)
1410  self.assertEqual(str(p.s),'a+b')
1411  self.assertEqual(p.s.label_(),'s')
1412  path = Path(p.c+p.s)
1413  self.assertEqual(str(path),'c+a+b')
1414  p._validateSequence(path, 'p1')
1415  notInProcess = EDAnalyzer('NotInProcess')
1416  p2 = Path(p.c+p.s*notInProcess)
1417  self.assertRaises(RuntimeError, p._validateSequence, p2, 'p2')
1418 
1419  def testSequence2(self):
1420  p = Process('test')
1421  p.a = EDAnalyzer("MyAnalyzer")
1422  p.b = EDAnalyzer("YourAnalyzer")
1423  p.c = EDAnalyzer("OurAnalyzer")
1424  testseq = Sequence(p.a*p.b)
1425  p.s = testseq
1426  #p.y = testseq
1427  self.assertRaises(ValueError, p.__setattr__, "y", testseq)
1428 
1429  def testPath(self):
1430  p = Process("test")
1431  p.a = EDAnalyzer("MyAnalyzer")
1432  p.b = EDAnalyzer("YourAnalyzer")
1433  p.c = EDAnalyzer("OurAnalyzer")
1434  path = Path(p.a)
1435  path *= p.b
1436  path += p.c
1437  self.assertEqual(str(path),'a+b+c')
1438  path = Path(p.a*p.b+p.c)
1439  self.assertEqual(str(path),'a+b+c')
1440 # path = Path(p.a)*p.b+p.c #This leads to problems with sequences
1441 # self.assertEqual(str(path),'((a*b)+c)')
1442  path = Path(p.a+ p.b*p.c)
1443  self.assertEqual(str(path),'a+b+c')
1444  path = Path(p.a*(p.b+p.c))
1445  self.assertEqual(str(path),'a+b+c')
1446  path = Path(p.a*(p.b+~p.c))
1447  self.assertEqual(str(path),'a+b+~c')
1448  p.es = ESProducer("AnESProducer")
1449  self.assertRaises(TypeError,Path,p.es)
1450 
1452  p = Process("test")
1453  a = EDAnalyzer("MyAnalyzer")
1454  p.a = a
1455  a.setLabel("a")
1456  b = EDAnalyzer("YOurAnalyzer")
1457  p.b = b
1458  b.setLabel("b")
1459  path = Path(a * b)
1460  p.path = Path(p.a*p.b)
1461  lookuptable = {id(a): p.a, id(b): p.b}
1462  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1463  #lookuptable = p._cloneToObjectDict
1464  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1465  self.assertEqual(str(path),str(p.path))
1466 
1467  def testSchedule(self):
1468  p = Process("test")
1469  p.a = EDAnalyzer("MyAnalyzer")
1470  p.b = EDAnalyzer("YourAnalyzer")
1471  p.c = EDAnalyzer("OurAnalyzer")
1472  p.d = EDAnalyzer("OurAnalyzer")
1473  p.path1 = Path(p.a)
1474  p.path2 = Path(p.b)
1475  p.path3 = Path(p.d)
1476 
1477  s = Schedule(p.path1,p.path2)
1478  self.assertEqual(s[0],p.path1)
1479  self.assertEqual(s[1],p.path2)
1480  p.schedule = s
1481  self.assert_('b' in p.schedule.moduleNames())
1482  self.assert_(hasattr(p, 'b'))
1483  self.assert_(hasattr(p, 'c'))
1484  self.assert_(hasattr(p, 'd'))
1485  self.assert_(hasattr(p, 'path1'))
1486  self.assert_(hasattr(p, 'path2'))
1487  self.assert_(hasattr(p, 'path3'))
1488  p.prune()
1489  self.assert_('b' in p.schedule.moduleNames())
1490  self.assert_(hasattr(p, 'b'))
1491  self.assert_(not hasattr(p, 'c'))
1492  self.assert_(not hasattr(p, 'd'))
1493  self.assert_(hasattr(p, 'path1'))
1494  self.assert_(hasattr(p, 'path2'))
1495  self.assert_(not hasattr(p, 'path3'))
1496 
1497  #adding a path not attached to the Process should cause an exception
1498  p = Process("test")
1499  p.a = EDAnalyzer("MyAnalyzer")
1500  path1 = Path(p.a)
1501  s = Schedule(path1)
1502  self.assertRaises(RuntimeError, lambda : p.setSchedule_(s) )
1503 
1504  #make sure anonymous sequences work
1505  p = Process("test")
1506  p.a = EDAnalyzer("MyAnalyzer")
1507  p.b = EDAnalyzer("MyOtherAnalyzer")
1508  p.c = EDProducer("MyProd")
1509  path1 = Path(p.c*Sequence(p.a+p.b))
1510  s = Schedule(path1)
1511  self.assert_('a' in s.moduleNames())
1512  self.assert_('b' in s.moduleNames())
1513  self.assert_('c' in s.moduleNames())
1514  p.path1 = path1
1515  p.schedule = s
1516  p.prune()
1517  self.assert_('a' in s.moduleNames())
1518  self.assert_('b' in s.moduleNames())
1519  self.assert_('c' in s.moduleNames())
1520 
1522  p = Process("test")
1523  p.a = EDAnalyzer("MyAnalyzer")
1524  p.b = EDAnalyzer("YourAnalyzer")
1525  p.c = EDAnalyzer("OurAnalyzer")
1526  p.path1 = Path(p.a)
1527  p.path2 = Path(p.b)
1528  self.assert_(p.schedule is None)
1529  pths = p.paths
1530  keys = pths.keys()
1531  self.assertEqual(pths[keys[0]],p.path1)
1532  self.assertEqual(pths[keys[1]],p.path2)
1533  p.prune()
1534  self.assert_(hasattr(p, 'a'))
1535  self.assert_(hasattr(p, 'b'))
1536  self.assert_(not hasattr(p, 'c'))
1537  self.assert_(hasattr(p, 'path1'))
1538  self.assert_(hasattr(p, 'path2'))
1539 
1540 
1541  p = Process("test")
1542  p.a = EDAnalyzer("MyAnalyzer")
1543  p.b = EDAnalyzer("YourAnalyzer")
1544  p.c = EDAnalyzer("OurAnalyzer")
1545  p.path2 = Path(p.b)
1546  p.path1 = Path(p.a)
1547  self.assert_(p.schedule is None)
1548  pths = p.paths
1549  keys = pths.keys()
1550  self.assertEqual(pths[keys[1]],p.path1)
1551  self.assertEqual(pths[keys[0]],p.path2)
1552 
1553 
1554  def testUsing(self):
1555  p = Process('test')
1556  p.block = PSet(a = int32(1))
1557  p.modu = EDAnalyzer('Analyzer', p.block, b = int32(2))
1558  self.assertEqual(p.modu.a.value(),1)
1559  self.assertEqual(p.modu.b.value(),2)
1560 
1561  def testOverride(self):
1562  p = Process('test')
1563  a = EDProducer("A", a1=int32(0))
1564  self.assert_(not a.isModified())
1565  a.a1 = 1
1566  self.assert_(a.isModified())
1567  p.a = a
1568  self.assertEqual(p.a.a1.value(), 1)
1569  # try adding an unmodified module.
1570  # should accept it
1571  p.a = EDProducer("A", a1=int32(2))
1572  self.assertEqual(p.a.a1.value(), 2)
1573  # try adding a modified module. Should throw
1574  # no longer, since the same (modified) say, geometry
1575  # could come from more than one cff
1576  b = EDProducer("A", a1=int32(3))
1577  b.a1 = 4
1578  #self.assertRaises(RuntimeError, setattr, *(p,'a',b))
1579  ps1 = PSet(a = int32(1))
1580  ps2 = PSet(a = int32(2))
1581  self.assertRaises(ValueError, EDProducer, 'C', ps1, ps2)
1582  self.assertRaises(ValueError, EDProducer, 'C', ps1, a=int32(3))
1583 
1584  def testExamples(self):
1585  p = Process("Test")
1586  p.source = Source("PoolSource",fileNames = untracked(string("file:reco.root")))
1587  p.foos = EDProducer("FooProducer")
1588  p.bars = EDProducer("BarProducer", foos=InputTag("foos"))
1589  p.out = OutputModule("PoolOutputModule",fileName=untracked(string("file:foos.root")))
1590  p.bars.foos = 'Foosball'
1591  self.assertEqual(p.bars.foos, InputTag('Foosball'))
1592  p.p = Path(p.foos*p.bars)
1593  p.e = EndPath(p.out)
1594  p.add_(Service("MessageLogger"))
1595 
1596  def testPrefers(self):
1597  p = Process("Test")
1598  p.add_(ESSource("ForceSource"))
1599  p.juicer = ESProducer("JuicerProducer")
1600  p.prefer("ForceSource")
1601  p.prefer("juicer")
1602  self.assertEqual(p.dumpConfig(),
1603 """process Test = {
1604  es_module juicer = JuicerProducer {
1605  }
1606  es_source = ForceSource {
1607  }
1608  es_prefer = ForceSource {
1609  }
1610  es_prefer juicer = JuicerProducer {
1611  }
1612 }
1613 """)
1614  p.prefer("juicer",fooRcd=vstring("Foo"))
1615  self.assertEqual(p.dumpConfig(),
1616 """process Test = {
1617  es_module juicer = JuicerProducer {
1618  }
1619  es_source = ForceSource {
1620  }
1621  es_prefer = ForceSource {
1622  }
1623  es_prefer juicer = JuicerProducer {
1624  vstring fooRcd = {
1625  'Foo'
1626  }
1627 
1628  }
1629 }
1630 """)
1631  self.assertEqual(p.dumpPython(),
1632 """import FWCore.ParameterSet.Config as cms
1633 
1634 process = cms.Process("Test")
1635 
1636 process.juicer = cms.ESProducer("JuicerProducer")
1637 
1638 
1639 process.ForceSource = cms.ESSource("ForceSource")
1640 
1641 
1642 process.prefer("ForceSource")
1643 
1644 process.prefer("juicer",
1645  fooRcd = cms.vstring('Foo')
1646 )
1647 
1648 """)
1649 
1650  def testFreeze(self):
1651  process = Process("Freeze")
1652  m = EDProducer("M", p=PSet(i = int32(1)))
1653  m.p.i = 2
1654  process.m = m
1655  # should be frozen
1656  #self.assertRaises(ValueError, setattr, m.p, 'i', 3)
1657  #self.assertRaises(ValueError, setattr, m, 'p', PSet(i=int32(1)))
1658  #self.assertRaises(ValueError, setattr, m.p, 'j', 1)
1659  #self.assertRaises(ValueError, setattr, m, 'j', 1)
1660  # But OK to change through the process
1661  process.m.p.i = 4
1662  self.assertEqual(process.m.p.i.value(), 4)
1663  process.m.p = PSet(j=int32(1))
1664  # should work to clone it, though
1665  m2 = m.clone(p = PSet(i = int32(5)), j = int32(8))
1666  m2.p.i = 6
1667  m2.j = 8
1668  def testSubProcess(self):
1669  process = Process("Parent")
1670  subProcess = Process("Child")
1671  subProcess.a = EDProducer("A")
1672  subProcess.p = Path(subProcess.a)
1673  subProcess.add_(Service("Foo"))
1674  process.add_( SubProcess(subProcess) )
1675  d = process.dumpPython()
1676  equalD ="""import FWCore.ParameterSet.Config as cms
1677 
1678 process = cms.Process("Parent")
1679 
1680 parentProcess = process
1681 import FWCore.ParameterSet.Config as cms
1682 
1683 process = cms.Process("Child")
1684 
1685 process.a = cms.EDProducer("A")
1686 
1687 
1688 process.p = cms.Path(process.a)
1689 
1690 
1691 process.Foo = cms.Service("Foo")
1692 
1693 
1694 childProcess = process
1695 process = parentProcess
1696 process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = cms.untracked.PSet(
1697 
1698 ), outputCommands = cms.untracked.vstring())
1699 """
1700  equalD = equalD.replace("parentProcess","parentProcess"+str(hash(process.subProcess)))
1701  self.assertEqual(d,equalD)
1702  p = TestMakePSet()
1703  process.subProcess.insertInto(p,"dummy")
1704  self.assertEqual((True,['a']),p.values["@sub_process"][1].values["process"][1].values['@all_modules'])
1705  self.assertEqual((True,['p']),p.values["@sub_process"][1].values["process"][1].values['@paths'])
1706  self.assertEqual({'@service_type':(True,'Foo')}, p.values["@sub_process"][1].values["process"][1].values["services"][1][0].values)
1707  def testRefToPSet(self):
1708  proc = Process("test")
1709  proc.top = PSet(a = int32(1))
1710  proc.ref = PSet(refToPSet_ = string("top"))
1711  proc.ref2 = PSet( a = int32(1), b = PSet( refToPSet_ = string("top")))
1712  proc.ref3 = PSet(refToPSet_ = string("ref"))
1713  proc.ref4 = VPSet(PSet(refToPSet_ = string("top")),
1714  PSet(refToPSet_ = string("ref2")))
1715  p = TestMakePSet()
1716  proc.fillProcessDesc(p)
1717  self.assertEqual((True,1),p.values["ref"][1].values["a"])
1718  self.assertEqual((True,1),p.values["ref3"][1].values["a"])
1719  self.assertEqual((True,1),p.values["ref2"][1].values["a"])
1720  self.assertEqual((True,1),p.values["ref2"][1].values["b"][1].values["a"])
1721  self.assertEqual((True,1),p.values["ref4"][1][0].values["a"])
1722  self.assertEqual((True,1),p.values["ref4"][1][1].values["a"])
1723  def testPrune(self):
1724  p = Process("test")
1725  p.a = EDAnalyzer("MyAnalyzer")
1726  p.b = EDAnalyzer("YourAnalyzer")
1727  p.c = EDAnalyzer("OurAnalyzer")
1728  p.d = EDAnalyzer("OurAnalyzer")
1729  p.s = Sequence(p.d)
1730  p.path1 = Path(p.a)
1731  p.path2 = Path(p.b)
1732  self.assert_(p.schedule is None)
1733  pths = p.paths
1734  keys = pths.keys()
1735  self.assertEqual(pths[keys[0]],p.path1)
1736  self.assertEqual(pths[keys[1]],p.path2)
1737  p.pset1 = PSet(parA = string("pset1"))
1738  p.pset2 = untracked.PSet(parA = string("pset2"))
1739  p.vpset1 = VPSet()
1740  p.vpset2 = untracked.VPSet()
1741  p.prune()
1742  self.assert_(hasattr(p, 'a'))
1743  self.assert_(hasattr(p, 'b'))
1744  self.assert_(not hasattr(p, 'c'))
1745  self.assert_(not hasattr(p, 'd'))
1746  self.assert_(not hasattr(p, 's'))
1747  self.assert_(hasattr(p, 'path1'))
1748  self.assert_(hasattr(p, 'path2'))
1749  self.assert_(not hasattr(p, 'pset1'))
1750  self.assert_(hasattr(p, 'pset2'))
1751  self.assert_(not hasattr(p, 'vpset1'))
1752  self.assert_(not hasattr(p, 'vpset2'))
1753 
1754  p = Process("test")
1755  p.a = EDAnalyzer("MyAnalyzer")
1756  p.b = EDAnalyzer("YourAnalyzer")
1757  p.c = EDAnalyzer("OurAnalyzer")
1758  p.d = EDAnalyzer("OurAnalyzer")
1759  p.e = EDAnalyzer("OurAnalyzer")
1760  p.s = Sequence(p.d)
1761  p.s2 = Sequence(p.b)
1762  p.s3 = Sequence(p.e)
1763  p.path1 = Path(p.a)
1764  p.path2 = Path(p.b)
1765  p.path3 = Path(p.b+p.s2)
1766  p.path4 = Path(p.b+p.s3)
1767  p.schedule = Schedule(p.path1,p.path2,p.path3)
1768  pths = p.paths
1769  keys = pths.keys()
1770  self.assertEqual(pths[keys[0]],p.path1)
1771  self.assertEqual(pths[keys[1]],p.path2)
1772  p.prune()
1773  self.assert_(hasattr(p, 'a'))
1774  self.assert_(hasattr(p, 'b'))
1775  self.assert_(not hasattr(p, 'c'))
1776  self.assert_(not hasattr(p, 'd'))
1777  self.assert_(not hasattr(p, 'e'))
1778  self.assert_(not hasattr(p, 's'))
1779  self.assert_(hasattr(p, 's2'))
1780  self.assert_(not hasattr(p, 's3'))
1781  self.assert_(hasattr(p, 'path1'))
1782  self.assert_(hasattr(p, 'path2'))
1783  self.assert_(hasattr(p, 'path3'))
1784  self.assert_(not hasattr(p, 'path4'))
1785  #test SequencePlaceholder
1786  p = Process("test")
1787  p.a = EDAnalyzer("MyAnalyzer")
1788  p.b = EDAnalyzer("YourAnalyzer")
1789  p.s = Sequence(SequencePlaceholder("a")+p.b)
1790  p.pth = Path(p.s)
1791  p.prune()
1792  self.assert_(hasattr(p, 'a'))
1793  self.assert_(hasattr(p, 'b'))
1794  self.assert_(hasattr(p, 's'))
1795  self.assert_(hasattr(p, 'pth'))
1796  def testModifier(self):
1797  m1 = Modifier()
1798  p = Process("test")
1799  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1800  def _mod_fred(obj):
1801  obj.fred = 2
1802  m1.toModify(p.a,_mod_fred)
1803  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1804  m1.toModify(p.b, wilma = 2)
1805  self.assertEqual(p.a.fred.value(),1)
1806  self.assertEqual(p.b.wilma.value(),1)
1807  m1.modify(p)
1808  self.assertEqual(p.a.fred.value(),2)
1809  self.assertEqual(p.b.wilma.value(),2)
1810  #check that items not attached to process are unchanged
1811  m1 = Modifier()
1812  p = Process("test")
1813  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1814  m1.toModify(p.a,_mod_fred)
1815  b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1816  m1.toModify(b, wilma = 2)
1817  self.assertEqual(p.a.fred.value(),1)
1818  self.assertEqual(b.wilma.value(),1)
1819  m1.modify(p)
1820  self.assertEqual(p.a.fred.value(),2)
1821  self.assertEqual(b.wilma.value(),1)
1822  #make sure chains of modifiers work
1823  m1 = Modifier()
1824  m2 = Modifier()
1825  m2.toModifyProcess(m1)
1826  p = Process("test")
1827  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1828  m1.toModify(p.a,_mod_fred)
1829  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1830  m1.toModify(p.b, wilma = 2)
1831  m2.toModify(p.b, wilma = 3)
1832  m2.modify(p)
1833  self.assertEqual(p.a.fred.value(),2)
1834  self.assertEqual(p.b.wilma.value(),3)
1835 
1836  unittest.main()
def __setObjectLabel
Definition: Config.py:268
def filterNames
Definition: Config.py:142
def es_sources_
Definition: Config.py:247
def _replaceInSequences
Definition: Config.py:714
def setSchedule_
Definition: Config.py:227
def subProcess_
Definition: Config.py:193
def _insertManyInto
Definition: Config.py:739
def __delattr__
Definition: Config.py:384
def _validateSequence
Definition: Config.py:640
def _dumpConfigUnnamedList
Definition: Config.py:553
def _placeEndPath
Definition: Config.py:463
def setSource_
Definition: Config.py:184
def _findPreferred
Definition: Config.py:942
def toModifyProcess
Definition: Config.py:1052
def es_producers_
Definition: Config.py:243
def aliases_
Definition: Config.py:255
def _dumpConfigESPrefers
Definition: Config.py:626
def _placeSequence
Definition: Config.py:470
def _dumpConfigOptionallyNamedList
Definition: Config.py:558
def _placeOutputModule
Definition: Config.py:448
def setLooper_
Definition: Config.py:190
def _placePSet
Definition: Config.py:481
def filters_
Definition: Config.py:166
def _placeProducer
Definition: Config.py:450
def _okToPlace
Definition: Config.py:419
def dumpPython
Definition: Config.py:685
def es_prefers_
Definition: Config.py:251
def _placePath
Definition: Config.py:456
def _insertPaths
Definition: Config.py:748
def visit
Retrieve data from a perf suite output (sub) directory, only examines TimeSize at the moment...
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
def _sequencesInDependencyOrder
Definition: Config.py:648
def outputModules_
Definition: Config.py:203
def producers_
Definition: Config.py:177
def __findFirstSequenceUsingModule
Definition: Config.py:373
def fillProcessDesc
Definition: Config.py:849
def __init__
Definition: Config.py:102
def _insertInto
Definition: Config.py:729
def analyzers_
Definition: Config.py:199
def addLuminosityBlockID
Definition: Config.py:1138
def _placeVPSet
Definition: Config.py:483
def setPartialSchedule_
Definition: Config.py:222
def setStrict
Definition: Config.py:131
def globalReplace
Definition: Config.py:723
def __setattr__
Definition: Config.py:295
def _placeLooper
Definition: Config.py:493
def dumpConfig
Definition: Config.py:565
def nameInProcessDesc_
Definition: Config.py:1020
def services_
Definition: Config.py:239
def validate
Definition: Config.py:906
def sequences_
Definition: Config.py:215
def schedule_
Definition: Config.py:219
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def setName_
Definition: Config.py:172
def __setstate__
Definition: Config.py:149
def analyzerNames
Definition: Config.py:139
def _placeAnalyzer
Definition: Config.py:454
def _pruneModules
Definition: Config.py:842
def _placeAlias
Definition: Config.py:479
def _insertOneInto
Definition: Config.py:732
def _dumpConfigNamedList
Definition: Config.py:548
list object
Definition: dbtoconf.py:77
def pathNames
Definition: Config.py:145
def _placeFilter
Definition: Config.py:452
def _dumpPythonList
Definition: Config.py:631
def findProcess
Definition: Config.py:80
def checkImportPermission
Definition: Config.py:27
def setSubProcess_
Definition: Config.py:196
dbl *** dir
Definition: mlp_gen.cc:35
def producerNames
Definition: Config.py:136
def _placeSource
Definition: Config.py:485
def _placeSubProcess
Definition: Config.py:498
tuple untracked
Definition: Types.py:27
def _placeESSource
Definition: Config.py:477
def _placeESPrefer
Definition: Config.py:475
def _dumpPython
Definition: Config.py:680
def endpaths_
Definition: Config.py:211
def _placeService
Definition: Config.py:503
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
def _placeESProducer
Definition: Config.py:473