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 # need to update this to only prune psets not on refToPSets
795 # but for now, remove the delattr
796 # for name in self.psets_():
797 # if getattr(self,name).isTracked():
798 # delattr(self, name)
799  for name in self.vpsets_():
800  delattr(self, name)
801  #first we need to resolve any SequencePlaceholders being used
802  for x in self.paths.itervalues():
803  x.resolve(self.__dict__)
804  for x in self.endpaths.itervalues():
805  x.resolve(self.__dict__)
806  usedModules = set()
807  unneededPaths = set()
808  if self.schedule_():
809  usedModules=set(self.schedule_().moduleNames())
810  #get rid of unused paths
811  schedNames = set(( x.label_() for x in self.schedule_()))
812  names = set(self.paths)
813  names.update(set(self.endpaths))
814  unneededPaths = names - schedNames
815  for n in unneededPaths:
816  delattr(self,n)
817  else:
818  pths = list(self.paths.itervalues())
819  pths.extend(self.endpaths.itervalues())
820  temp = Schedule(*pths)
821  usedModules=set(temp.moduleNames())
822  unneededModules = self._pruneModules(self.producers_(), usedModules)
823  unneededModules.update(self._pruneModules(self.filters_(), usedModules))
824  unneededModules.update(self._pruneModules(self.analyzers_(), usedModules))
825  #remove sequences that do not appear in remaining paths and endpaths
826  seqs = list()
827  sv = SequenceVisitor(seqs)
828  for p in self.paths.itervalues():
829  p.visit(sv)
830  for p in self.endpaths.itervalues():
831  p.visit(sv)
832  keepSeqSet = set(( s for s in seqs if s.hasLabel_()))
833  availableSeqs = set(self.sequences.itervalues())
834  unneededSeqs = availableSeqs-keepSeqSet
835  unneededSeqLabels = []
836  for s in unneededSeqs:
837  unneededSeqLabels.append(s.label_())
838  delattr(self,s.label_())
839  if verbose:
840  print "prune removed the following:"
841  print " modules:"+",".join(unneededModules)
842  print " sequences:"+",".join(unneededSeqLabels)
843  print " paths/endpaths:"+",".join(unneededPaths)
844  def _pruneModules(self, d, scheduledNames):
845  moduleNames = set(d.keys())
846  junk = moduleNames - scheduledNames
847  for name in junk:
848  delattr(self, name)
849  return junk
850 
851  def fillProcessDesc(self, processPSet):
852  """Used by the framework to convert python to C++ objects"""
853  class ServiceInjectorAdaptor(object):
854  def __init__(self,ppset,thelist):
855  self.__thelist = thelist
856  self.__processPSet = ppset
857  def addService(self,pset):
858  self.__thelist.append(pset)
859  def newPSet(self):
860  return self.__processPSet.newPSet()
861  #This adaptor is used to 'add' the method 'getTopPSet_'
862  # to the ProcessDesc and PythonParameterSet C++ classes.
863  # This method is needed for the PSet refToPSet_ functionality.
864  class TopLevelPSetAcessorAdaptor(object):
865  def __init__(self,ppset,process):
866  self.__ppset = ppset
867  self.__process = process
868  def __getattr__(self,attr):
869  return getattr(self.__ppset,attr)
870  def getTopPSet_(self,label):
871  return getattr(self.__process,label)
872  def newPSet(self):
873  return TopLevelPSetAcessorAdaptor(self.__ppset.newPSet(),self.__process)
874  def addPSet(self,tracked,name,ppset):
875  return self.__ppset.addPSet(tracked,name,self.__extractPSet(ppset))
876  def addVPSet(self,tracked,name,vpset):
877  return self.__ppset.addVPSet(tracked,name,[self.__extractPSet(x) for x in vpset])
878  def __extractPSet(self,pset):
879  if isinstance(pset,TopLevelPSetAcessorAdaptor):
880  return pset.__ppset
881  return pset
882 
883  self.validate()
884  processPSet.addString(True, "@process_name", self.name_())
885  all_modules = self.producers_().copy()
886  all_modules.update(self.filters_())
887  all_modules.update(self.analyzers_())
888  all_modules.update(self.outputModules_())
889  adaptor = TopLevelPSetAcessorAdaptor(processPSet,self)
890  self._insertInto(adaptor, self.psets_())
891  self._insertInto(adaptor, self.vpsets_())
892  self._insertManyInto(adaptor, "@all_modules", all_modules, True)
893  self._insertOneInto(adaptor, "@all_sources", self.source_(), True)
894  self._insertOneInto(adaptor, "@all_loopers", self.looper_(), True)
895  self._insertOneInto(adaptor, "@all_subprocesses", self.subProcess_(), False)
896  self._insertManyInto(adaptor, "@all_esmodules", self.es_producers_(), True)
897  self._insertManyInto(adaptor, "@all_essources", self.es_sources_(), True)
898  self._insertManyInto(adaptor, "@all_esprefers", self.es_prefers_(), True)
899  self._insertManyInto(adaptor, "@all_aliases", self.aliases_(), True)
900  self._insertPaths(adaptor)
901  #handle services differently
902  services = []
903  for n in self.services_():
904  getattr(self,n).insertInto(ServiceInjectorAdaptor(adaptor,services))
905  adaptor.addVPSet(False,"services",services)
906  return processPSet
907 
908  def validate(self):
909  # check if there's some input
910  # Breaks too many unit tests for now
911  #if self.source_() == None and self.looper_() == None:
912  # raise RuntimeError("No input source was found for this process")
913  pass
914 
915  def prefer(self, esmodule,*args,**kargs):
916  """Prefer this ES source or producer. The argument can
917  either be an object label, e.g.,
918  process.prefer(process.juicerProducer) (not supported yet)
919  or a name of an ESSource or ESProducer
920  process.prefer("juicer")
921  or a type of unnamed ESSource or ESProducer
922  process.prefer("JuicerProducer")
923  In addition, you can pass as a labelled arguments the name of the Record you wish to
924  prefer where the type passed is a cms.vstring and that vstring can contain the
925  name of the C++ types in the Record which are being preferred, e.g.,
926  #prefer all data in record 'OrangeRecord' from 'juicer'
927  process.prefer("juicer", OrangeRecord=cms.vstring())
928  or
929  #prefer only "Orange" data in "OrangeRecord" from "juicer"
930  process.prefer("juicer", OrangeRecord=cms.vstring("Orange"))
931  or
932  #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer"
933  ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
934  """
935  # see if this refers to a named ESProducer
936  if isinstance(esmodule, ESSource) or isinstance(esmodule, ESProducer):
937  raise RuntimeError("Syntax of process.prefer(process.esmodule) not supported yet")
938  elif self._findPreferred(esmodule, self.es_producers_(),*args,**kargs) or \
939  self._findPreferred(esmodule, self.es_sources_(),*args,**kargs):
940  pass
941  else:
942  raise RuntimeError("Cannot resolve prefer for "+repr(esmodule))
943 
944  def _findPreferred(self, esname, d,*args,**kargs):
945  # is esname a name in the dictionary?
946  if esname in d:
947  typ = d[esname].type_()
948  if typ == esname:
949  self.__setattr__( esname+"_prefer", ESPrefer(typ,*args,**kargs) )
950  else:
951  self.__setattr__( esname+"_prefer", ESPrefer(typ, esname,*args,**kargs) )
952  return True
953  else:
954  # maybe it's an unnamed ESModule?
955  found = False
956  for name, value in d.iteritems():
957  if value.type_() == esname:
958  if found:
959  raise RuntimeError("More than one ES module for "+esname)
960  found = True
961  self.__setattr__(esname+"_prefer", ESPrefer(d[esname].type_()) )
962  return found
963 
965  """a dictionary with fixed keys"""
967  raise AttributeError, "An FilteredStream defintion cannot be modified after creation."
968  _blocked_attribute = property(_blocked_attribute)
969  __setattr__ = __delitem__ = __setitem__ = clear = _blocked_attribute
970  pop = popitem = setdefault = update = _blocked_attribute
971  def __new__(cls, *args, **kw):
972  new = dict.__new__(cls)
973  dict.__init__(new, *args, **kw)
974  keys = kw.keys()
975  keys.sort()
976  if keys != ['content', 'dataTier', 'name', 'paths', 'responsible', 'selectEvents']:
977  raise ValueError("The needed parameters are: content, dataTier, name, paths, responsible, selectEvents")
978  if not isinstance(kw['name'],str):
979  raise ValueError("name must be of type string")
980  if not isinstance(kw['content'], vstring) and not isinstance(kw['content'],str):
981  raise ValueError("content must be of type vstring or string")
982  if not isinstance(kw['dataTier'], string):
983  raise ValueError("dataTier must be of type string")
984  if not isinstance(kw['selectEvents'], PSet):
985  raise ValueError("selectEvents must be of type PSet")
986  if not isinstance(kw['paths'],(tuple, Path)):
987  raise ValueError("'paths' must be a tuple of paths")
988  return new
989  def __init__(self, *args, **kw):
990  pass
991  def __repr__(self):
992  return "FilteredStream object: %s" %self["name"]
993  def __getattr__(self,attr):
994  return self[attr]
995 
997  """Allows embedding another process within a parent process. This allows one to
998  chain processes together directly in one cmsRun job rather than having to run
999  separate jobs which are connected via a temporary file.
1000  """
1001  def __init__(self,process, SelectEvents = untracked.PSet(), outputCommands = untracked.vstring()):
1002  """
1003  """
1004  if not isinstance(process, Process):
1005  raise ValueError("the 'process' argument must be of type cms.Process")
1006  if not isinstance(SelectEvents,PSet):
1007  raise ValueError("the 'SelectEvents' argument must be of type cms.untracked.PSet")
1008  if not isinstance(outputCommands,vstring):
1009  raise ValueError("the 'outputCommands' argument must be of type cms.untracked.vstring")
1010  self.__process = process
1011  self.__SelectEvents = SelectEvents
1012  self.__outputCommands = outputCommands
1013  def dumpPython(self,options):
1014  out = "parentProcess"+str(hash(self))+" = process\n"
1015  out += self.__process.dumpPython()
1016  out += "childProcess = process\n"
1017  out += "process = parentProcess"+str(hash(self))+"\n"
1018  out += "process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = "+self.__SelectEvents.dumpPython(options) +", outputCommands = "+self.__outputCommands.dumpPython(options) +")\n"
1019  return out
1020  def type_(self):
1021  return 'subProcess'
1022  def nameInProcessDesc_(self,label):
1023  return '@sub_process'
1024  def _place(self,label,process):
1025  process._placeSubProcess('subProcess',self)
1026  def insertInto(self,parameterSet, newlabel):
1027  topPSet = parameterSet.newPSet()
1028  self.__process.fillProcessDesc(topPSet)
1029  subProcessPSet = parameterSet.newPSet()
1030  self.__SelectEvents.insertInto(subProcessPSet,"SelectEvents")
1031  self.__outputCommands.insertInto(subProcessPSet,"outputCommands")
1032  subProcessPSet.addPSet(False,"process",topPSet)
1033  parameterSet.addPSet(False,self.nameInProcessDesc_("subProcess"), subProcessPSet)
1034 
1036  """Helper class for Modifier which takes key/value pairs and uses them to reset parameters of the object"""
1037  def __init__(self,args):
1038  self.__args = args
1039  def __call__(self,obj):
1040  for k,v in self.__args.iteritems():
1041  setattr(obj,k,v)
1042 
1044  """This class is used to define standard modifications to a Process.
1045  An instance of this class is declared to denote a specific modification,e.g. era2017 could
1046  reconfigure items in a process to match our expectation of running in 2017. Once declared,
1047  these Modifier instances are imported into a configuration and items which need to be modified
1048  are then associated with the Modifier and with the action to do the modification.
1049  The registered modifications will only occur if the modify() method is called.
1050  """
1051  def __init__(self):
1054  def toModifyProcess(self,func):
1055  """This is used to register actions to be performed on the process as a whole.
1056  This takes as argument a callable object (e.g. function) which takes as its sole argument an instance of Process"""
1057  self.__processModifiers.append(func)
1058  def toModify(self,obj, func=None,**kw):
1059  """This is used to register an action to be performed on the specific object. Two different forms are allowed
1060  Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1061  which will be the object passed in as the first argument.
1062  Form 2: A list of parameter name, value pairs can be passed
1063  mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1064  """
1065  if func is not None and len(kw) != 0:
1066  raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
1067  if func is not None:
1068  self.__objectToModifiers.append( (obj,func))
1069  else:
1070  self.__objectToModifiers.append( (obj, _ParameterModifier(kw)))
1071  def modify(self,process):
1072  """This applies all the registered modifiers to the passed in process"""
1073  for m in self.__processModifiers:
1074  m(process)
1075  for o,m in self.__objectToModifiers:
1076  if isinstance(o,_Labelable):
1077  if o.hasLabel_():
1078  m(o)
1079  else:
1080  m(o)
1081  return process
1082  def __call__(self,process):
1083  """Forwards to modify call. The presence of a __call__ allows Modifiers to be chained together.
1084  E.g. Have bar inherit all modifiers of foo
1085  foo = Modifier()
1086  bar = Modifier()
1087  foo.toModifyProcess(bar)
1088  """
1089  self.modify(process)
1090 
1091 if __name__=="__main__":
1092  import unittest
1093  import copy
1094 
1096  """Has same interface as the C++ object which creates PSets
1097  """
1098  def __init__(self):
1099  self.values = dict()
1100  def __insertValue(self,tracked,label,value):
1101  self.values[label]=(tracked,value)
1102  def addInt32(self,tracked,label,value):
1103  self.__insertValue(tracked,label,value)
1104  def addVInt32(self,tracked,label,value):
1105  self.__insertValue(tracked,label,value)
1106  def addUInt32(self,tracked,label,value):
1107  self.__insertValue(tracked,label,value)
1108  def addVUInt32(self,tracked,label,value):
1109  self.__insertValue(tracked,label,value)
1110  def addInt64(self,tracked,label,value):
1111  self.__insertValue(tracked,label,value)
1112  def addVInt64(self,tracked,label,value):
1113  self.__insertValue(tracked,label,value)
1114  def addUInt64(self,tracked,label,value):
1115  self.__insertValue(tracked,label,value)
1116  def addVUInt64(self,tracked,label,value):
1117  self.__insertValue(tracked,label,value)
1118  def addDouble(self,tracked,label,value):
1119  self.__insertValue(tracked,label,value)
1120  def addVDouble(self,tracked,label,value):
1121  self.__insertValue(tracked,label,value)
1122  def addBool(self,tracked,label,value):
1123  self.__insertValue(tracked,label,value)
1124  def addString(self,tracked,label,value):
1125  self.__insertValue(tracked,label,value)
1126  def addVString(self,tracked,label,value):
1127  self.__insertValue(tracked,label,value)
1128  def addInputTag(self,tracked,label,value):
1129  self.__insertValue(tracked,label,value)
1130  def addVInputTag(self,tracked,label,value):
1131  self.__insertValue(tracked,label,value)
1132  def addESInputTag(self,tracked,label,value):
1133  self.__insertValue(tracked,label,value)
1134  def addVESInputTag(self,tracked,label,value):
1135  self.__insertValue(tracked,label,value)
1136  def addEventID(self,tracked,label,value):
1137  self.__insertValue(tracked,label,value)
1138  def addVEventID(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 addLuminosityBlockID(self,tracked,label,value):
1143  self.__insertValue(tracked,label,value)
1144  def addEventRange(self,tracked,label,value):
1145  self.__insertValue(tracked,label,value)
1146  def addVEventRange(self,tracked,label,value):
1147  self.__insertValue(tracked,label,value)
1148  def addPSet(self,tracked,label,value):
1149  self.__insertValue(tracked,label,value)
1150  def addVPSet(self,tracked,label,value):
1151  self.__insertValue(tracked,label,value)
1152  def addFileInPath(self,tracked,label,value):
1153  self.__insertValue(tracked,label,value)
1154  def newPSet(self):
1155  return TestMakePSet()
1156 
1157  class TestModuleCommand(unittest.TestCase):
1158  def setUp(self):
1159  """Nothing to do """
1160  None
1162  p = _Parameterizable()
1163  self.assertEqual(len(p.parameterNames_()),0)
1164  p.a = int32(1)
1165  self.assert_('a' in p.parameterNames_())
1166  self.assertEqual(p.a.value(), 1)
1167  p.a = 10
1168  self.assertEqual(p.a.value(), 10)
1169  p.a = untracked(int32(1))
1170  self.assertEqual(p.a.value(), 1)
1171  self.failIf(p.a.isTracked())
1172  p.a = untracked.int32(1)
1173  self.assertEqual(p.a.value(), 1)
1174  self.failIf(p.a.isTracked())
1175  p = _Parameterizable(foo=int32(10), bar = untracked(double(1.0)))
1176  self.assertEqual(p.foo.value(), 10)
1177  self.assertEqual(p.bar.value(),1.0)
1178  self.failIf(p.bar.isTracked())
1179  self.assertRaises(TypeError,setattr,(p,'c',1))
1180  p = _Parameterizable(a=PSet(foo=int32(10), bar = untracked(double(1.0))))
1181  self.assertEqual(p.a.foo.value(),10)
1182  self.assertEqual(p.a.bar.value(),1.0)
1183  p.b = untracked(PSet(fii = int32(1)))
1184  self.assertEqual(p.b.fii.value(),1)
1185  self.failIf(p.b.isTracked())
1186  #test the fact that values can be shared
1187  v = int32(10)
1188  p=_Parameterizable(a=v)
1189  v.setValue(11)
1190  self.assertEqual(p.a.value(),11)
1191  p.a = 12
1192  self.assertEqual(p.a.value(),12)
1193  self.assertEqual(v.value(),12)
1195  p = _TypedParameterizable("blah", b=int32(1))
1196  #see if copy works deeply
1197  other = p.copy()
1198  other.b = 2
1199  self.assertNotEqual(p.b,other.b)
1200 
1202  p = Process("test")
1203  p.a = EDAnalyzer("MyAnalyzer")
1204  self.assert_( 'a' in p.analyzers_() )
1205  self.assert_( 'a' in p.analyzers)
1206  p.add_(Service("MessageLogger"))
1207  self.assert_('MessageLogger' in p.services_())
1208  self.assertEqual(p.MessageLogger.type_(), "MessageLogger")
1209  p.Tracer = Service("Tracer")
1210  self.assert_('Tracer' in p.services_())
1211  self.assertRaises(TypeError, setattr, *(p,'b',"this should fail"))
1212  self.assertRaises(TypeError, setattr, *(p,'bad',Service("MessageLogger")))
1213  self.assertRaises(ValueError, setattr, *(p,'bad',Source("PoolSource")))
1214  p.out = OutputModule("Outer")
1215  self.assertEqual(p.out.type_(), 'Outer')
1216  self.assert_( 'out' in p.outputModules_() )
1217 
1218  p.geom = ESSource("GeomProd")
1219  self.assert_('geom' in p.es_sources_())
1220  p.add_(ESSource("ConfigDB"))
1221  self.assert_('ConfigDB' in p.es_sources_())
1222 
1223  p.aliasfoo1 = EDAlias(foo1 = VPSet(PSet(type = string("Foo1"))))
1224  self.assert_('aliasfoo1' in p.aliases_())
1225 
1227  class FromArg(object):
1228  def __init__(self,*arg,**args):
1229  for name in args.iterkeys():
1230  self.__dict__[name]=args[name]
1231 
1232  a=EDAnalyzer("MyAnalyzer")
1233  t=EDAnalyzer("MyAnalyzer")
1234  t.setLabel("foo")
1235  s1 = Sequence(a)
1236  s2 = Sequence(s1)
1237  s3 = Sequence(s2)
1238  d = FromArg(
1239  a=a,
1240  b=Service("Full"),
1241  c=Path(a),
1242  d=s2,
1243  e=s1,
1244  f=s3,
1245  g=Sequence(s1+s2+s3)
1246  )
1247  p = Process("Test")
1248  p.extend(d)
1249  self.assertEqual(p.a.type_(),"MyAnalyzer")
1250  self.assertEqual(p.a.label_(),"a")
1251  self.assertRaises(AttributeError,getattr,p,'b')
1252  self.assertEqual(p.Full.type_(),"Full")
1253  self.assertEqual(str(p.c),'a')
1254  self.assertEqual(str(p.d),'a')
1255 
1256  z1 = FromArg(
1257  a=a,
1258  b=Service("Full"),
1259  c=Path(a),
1260  d=s2,
1261  e=s1,
1262  f=s3,
1263  s4=s3,
1264  g=Sequence(s1+s2+s3)
1265  )
1266 
1267  p1 = Process("Test")
1268  #p1.extend(z1)
1269  self.assertRaises(ValueError, p1.extend, z1)
1270 
1271  z2 = FromArg(
1272  a=a,
1273  b=Service("Full"),
1274  c=Path(a),
1275  d=s2,
1276  e=s1,
1277  f=s3,
1278  aaa=copy.deepcopy(a),
1279  s4=copy.deepcopy(s3),
1280  g=Sequence(s1+s2+s3),
1281  t=t
1282  )
1283  p2 = Process("Test")
1284  p2.extend(z2)
1285  #self.assertRaises(ValueError, p2.extend, z2)
1286  self.assertEqual(p2.s4.label_(),"s4")
1287  #p2.s4.setLabel("foo")
1288  self.assertRaises(ValueError, p2.s4.setLabel, "foo")
1289  p2.s4.setLabel("s4")
1290  p2.s4.setLabel(None)
1291  p2.s4.setLabel("foo")
1292  p2._Process__setObjectLabel(p2.s4, "foo")
1293  p2._Process__setObjectLabel(p2.s4, None)
1294  p2._Process__setObjectLabel(p2.s4, "bar")
1295 
1297  p = Process("test")
1298  p.a = EDAnalyzer("MyAnalyzer")
1299  p.p = Path(p.a)
1300  p.s = Sequence(p.a)
1301  p.r = Sequence(p.s)
1302  p.p2 = Path(p.s)
1303  p.schedule = Schedule(p.p2,p.p)
1304  d=p.dumpPython()
1305  self.assertEqual(d,
1306 """import FWCore.ParameterSet.Config as cms
1307 
1308 process = cms.Process("test")
1309 
1310 process.a = cms.EDAnalyzer("MyAnalyzer")
1311 
1312 
1313 process.s = cms.Sequence(process.a)
1314 
1315 
1316 process.r = cms.Sequence(process.s)
1317 
1318 
1319 process.p = cms.Path(process.a)
1320 
1321 
1322 process.p2 = cms.Path(process.s)
1323 
1324 
1325 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1326 """)
1327  #Reverse order of 'r' and 's'
1328  p = Process("test")
1329  p.a = EDAnalyzer("MyAnalyzer")
1330  p.p = Path(p.a)
1331  p.r = Sequence(p.a)
1332  p.s = Sequence(p.r)
1333  p.p2 = Path(p.r)
1334  p.schedule = Schedule(p.p2,p.p)
1335  p.b = EDAnalyzer("YourAnalyzer")
1336  d=p.dumpPython()
1337  self.assertEqual(d,
1338 """import FWCore.ParameterSet.Config as cms
1339 
1340 process = cms.Process("test")
1341 
1342 process.a = cms.EDAnalyzer("MyAnalyzer")
1343 
1344 
1345 process.b = cms.EDAnalyzer("YourAnalyzer")
1346 
1347 
1348 process.r = cms.Sequence(process.a)
1349 
1350 
1351 process.s = cms.Sequence(process.r)
1352 
1353 
1354 process.p = cms.Path(process.a)
1355 
1356 
1357 process.p2 = cms.Path(process.r)
1358 
1359 
1360 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1361 """)
1362  #use an anonymous sequence
1363  p = Process("test")
1364  p.a = EDAnalyzer("MyAnalyzer")
1365  p.p = Path(p.a)
1366  s = Sequence(p.a)
1367  p.r = Sequence(s)
1368  p.p2 = Path(p.r)
1369  p.schedule = Schedule(p.p2,p.p)
1370  d=p.dumpPython()
1371  self.assertEqual(d,
1372  """import FWCore.ParameterSet.Config as cms
1373 
1374 process = cms.Process("test")
1375 
1376 process.a = cms.EDAnalyzer("MyAnalyzer")
1377 
1378 
1379 process.r = cms.Sequence((process.a))
1380 
1381 
1382 process.p = cms.Path(process.a)
1383 
1384 
1385 process.p2 = cms.Path(process.r)
1386 
1387 
1388 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1389 """)
1390 
1391  def testSecSource(self):
1392  p = Process('test')
1393  p.a = SecSource("MySecSource")
1394  self.assertEqual(p.dumpPython().replace('\n',''),'import FWCore.ParameterSet.Config as cmsprocess = cms.Process("test")process.a = cms.SecSource("MySecSource")')
1395 
1397  p = Process('test')
1398  p.a = EDAnalyzer("MyAnalyzer")
1399  p.b = EDAnalyzer("YourAnalyzer")
1400  p.c = EDAnalyzer("OurAnalyzer")
1401  p.s = Sequence(p.a*p.b)
1402  p.p = Path(p.c+p.s+p.a)
1403  new = EDAnalyzer("NewAnalyzer")
1404  p.globalReplace("a",new)
1405 
1406  def testSequence(self):
1407  p = Process('test')
1408  p.a = EDAnalyzer("MyAnalyzer")
1409  p.b = EDAnalyzer("YourAnalyzer")
1410  p.c = EDAnalyzer("OurAnalyzer")
1411  p.s = Sequence(p.a*p.b)
1412  self.assertEqual(str(p.s),'a+b')
1413  self.assertEqual(p.s.label_(),'s')
1414  path = Path(p.c+p.s)
1415  self.assertEqual(str(path),'c+a+b')
1416  p._validateSequence(path, 'p1')
1417  notInProcess = EDAnalyzer('NotInProcess')
1418  p2 = Path(p.c+p.s*notInProcess)
1419  self.assertRaises(RuntimeError, p._validateSequence, p2, 'p2')
1420 
1421  def testSequence2(self):
1422  p = Process('test')
1423  p.a = EDAnalyzer("MyAnalyzer")
1424  p.b = EDAnalyzer("YourAnalyzer")
1425  p.c = EDAnalyzer("OurAnalyzer")
1426  testseq = Sequence(p.a*p.b)
1427  p.s = testseq
1428  #p.y = testseq
1429  self.assertRaises(ValueError, p.__setattr__, "y", testseq)
1430 
1431  def testPath(self):
1432  p = Process("test")
1433  p.a = EDAnalyzer("MyAnalyzer")
1434  p.b = EDAnalyzer("YourAnalyzer")
1435  p.c = EDAnalyzer("OurAnalyzer")
1436  path = Path(p.a)
1437  path *= p.b
1438  path += p.c
1439  self.assertEqual(str(path),'a+b+c')
1440  path = Path(p.a*p.b+p.c)
1441  self.assertEqual(str(path),'a+b+c')
1442 # path = Path(p.a)*p.b+p.c #This leads to problems with sequences
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  path = Path(p.a*(p.b+~p.c))
1449  self.assertEqual(str(path),'a+b+~c')
1450  p.es = ESProducer("AnESProducer")
1451  self.assertRaises(TypeError,Path,p.es)
1452 
1454  p = Process("test")
1455  a = EDAnalyzer("MyAnalyzer")
1456  p.a = a
1457  a.setLabel("a")
1458  b = EDAnalyzer("YOurAnalyzer")
1459  p.b = b
1460  b.setLabel("b")
1461  path = Path(a * b)
1462  p.path = Path(p.a*p.b)
1463  lookuptable = {id(a): p.a, id(b): p.b}
1464  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1465  #lookuptable = p._cloneToObjectDict
1466  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1467  self.assertEqual(str(path),str(p.path))
1468 
1469  def testSchedule(self):
1470  p = Process("test")
1471  p.a = EDAnalyzer("MyAnalyzer")
1472  p.b = EDAnalyzer("YourAnalyzer")
1473  p.c = EDAnalyzer("OurAnalyzer")
1474  p.d = EDAnalyzer("OurAnalyzer")
1475  p.path1 = Path(p.a)
1476  p.path2 = Path(p.b)
1477  p.path3 = Path(p.d)
1478 
1479  s = Schedule(p.path1,p.path2)
1480  self.assertEqual(s[0],p.path1)
1481  self.assertEqual(s[1],p.path2)
1482  p.schedule = s
1483  self.assert_('b' in p.schedule.moduleNames())
1484  self.assert_(hasattr(p, 'b'))
1485  self.assert_(hasattr(p, 'c'))
1486  self.assert_(hasattr(p, 'd'))
1487  self.assert_(hasattr(p, 'path1'))
1488  self.assert_(hasattr(p, 'path2'))
1489  self.assert_(hasattr(p, 'path3'))
1490  p.prune()
1491  self.assert_('b' in p.schedule.moduleNames())
1492  self.assert_(hasattr(p, 'b'))
1493  self.assert_(not hasattr(p, 'c'))
1494  self.assert_(not hasattr(p, 'd'))
1495  self.assert_(hasattr(p, 'path1'))
1496  self.assert_(hasattr(p, 'path2'))
1497  self.assert_(not hasattr(p, 'path3'))
1498 
1499  #adding a path not attached to the Process should cause an exception
1500  p = Process("test")
1501  p.a = EDAnalyzer("MyAnalyzer")
1502  path1 = Path(p.a)
1503  s = Schedule(path1)
1504  self.assertRaises(RuntimeError, lambda : p.setSchedule_(s) )
1505 
1506  #make sure anonymous sequences work
1507  p = Process("test")
1508  p.a = EDAnalyzer("MyAnalyzer")
1509  p.b = EDAnalyzer("MyOtherAnalyzer")
1510  p.c = EDProducer("MyProd")
1511  path1 = Path(p.c*Sequence(p.a+p.b))
1512  s = Schedule(path1)
1513  self.assert_('a' in s.moduleNames())
1514  self.assert_('b' in s.moduleNames())
1515  self.assert_('c' in s.moduleNames())
1516  p.path1 = path1
1517  p.schedule = s
1518  p.prune()
1519  self.assert_('a' in s.moduleNames())
1520  self.assert_('b' in s.moduleNames())
1521  self.assert_('c' in s.moduleNames())
1522 
1524  p = Process("test")
1525  p.a = EDAnalyzer("MyAnalyzer")
1526  p.b = EDAnalyzer("YourAnalyzer")
1527  p.c = EDAnalyzer("OurAnalyzer")
1528  p.path1 = Path(p.a)
1529  p.path2 = Path(p.b)
1530  self.assert_(p.schedule is None)
1531  pths = p.paths
1532  keys = pths.keys()
1533  self.assertEqual(pths[keys[0]],p.path1)
1534  self.assertEqual(pths[keys[1]],p.path2)
1535  p.prune()
1536  self.assert_(hasattr(p, 'a'))
1537  self.assert_(hasattr(p, 'b'))
1538  self.assert_(not hasattr(p, 'c'))
1539  self.assert_(hasattr(p, 'path1'))
1540  self.assert_(hasattr(p, 'path2'))
1541 
1542 
1543  p = Process("test")
1544  p.a = EDAnalyzer("MyAnalyzer")
1545  p.b = EDAnalyzer("YourAnalyzer")
1546  p.c = EDAnalyzer("OurAnalyzer")
1547  p.path2 = Path(p.b)
1548  p.path1 = Path(p.a)
1549  self.assert_(p.schedule is None)
1550  pths = p.paths
1551  keys = pths.keys()
1552  self.assertEqual(pths[keys[1]],p.path1)
1553  self.assertEqual(pths[keys[0]],p.path2)
1554 
1555 
1556  def testUsing(self):
1557  p = Process('test')
1558  p.block = PSet(a = int32(1))
1559  p.modu = EDAnalyzer('Analyzer', p.block, b = int32(2))
1560  self.assertEqual(p.modu.a.value(),1)
1561  self.assertEqual(p.modu.b.value(),2)
1562 
1563  def testOverride(self):
1564  p = Process('test')
1565  a = EDProducer("A", a1=int32(0))
1566  self.assert_(not a.isModified())
1567  a.a1 = 1
1568  self.assert_(a.isModified())
1569  p.a = a
1570  self.assertEqual(p.a.a1.value(), 1)
1571  # try adding an unmodified module.
1572  # should accept it
1573  p.a = EDProducer("A", a1=int32(2))
1574  self.assertEqual(p.a.a1.value(), 2)
1575  # try adding a modified module. Should throw
1576  # no longer, since the same (modified) say, geometry
1577  # could come from more than one cff
1578  b = EDProducer("A", a1=int32(3))
1579  b.a1 = 4
1580  #self.assertRaises(RuntimeError, setattr, *(p,'a',b))
1581  ps1 = PSet(a = int32(1))
1582  ps2 = PSet(a = int32(2))
1583  self.assertRaises(ValueError, EDProducer, 'C', ps1, ps2)
1584  self.assertRaises(ValueError, EDProducer, 'C', ps1, a=int32(3))
1585 
1586  def testExamples(self):
1587  p = Process("Test")
1588  p.source = Source("PoolSource",fileNames = untracked(string("file:reco.root")))
1589  p.foos = EDProducer("FooProducer")
1590  p.bars = EDProducer("BarProducer", foos=InputTag("foos"))
1591  p.out = OutputModule("PoolOutputModule",fileName=untracked(string("file:foos.root")))
1592  p.bars.foos = 'Foosball'
1593  self.assertEqual(p.bars.foos, InputTag('Foosball'))
1594  p.p = Path(p.foos*p.bars)
1595  p.e = EndPath(p.out)
1596  p.add_(Service("MessageLogger"))
1597 
1598  def testPrefers(self):
1599  p = Process("Test")
1600  p.add_(ESSource("ForceSource"))
1601  p.juicer = ESProducer("JuicerProducer")
1602  p.prefer("ForceSource")
1603  p.prefer("juicer")
1604  self.assertEqual(p.dumpConfig(),
1605 """process Test = {
1606  es_module juicer = JuicerProducer {
1607  }
1608  es_source = ForceSource {
1609  }
1610  es_prefer = ForceSource {
1611  }
1612  es_prefer juicer = JuicerProducer {
1613  }
1614 }
1615 """)
1616  p.prefer("juicer",fooRcd=vstring("Foo"))
1617  self.assertEqual(p.dumpConfig(),
1618 """process Test = {
1619  es_module juicer = JuicerProducer {
1620  }
1621  es_source = ForceSource {
1622  }
1623  es_prefer = ForceSource {
1624  }
1625  es_prefer juicer = JuicerProducer {
1626  vstring fooRcd = {
1627  'Foo'
1628  }
1629 
1630  }
1631 }
1632 """)
1633  self.assertEqual(p.dumpPython(),
1634 """import FWCore.ParameterSet.Config as cms
1635 
1636 process = cms.Process("Test")
1637 
1638 process.juicer = cms.ESProducer("JuicerProducer")
1639 
1640 
1641 process.ForceSource = cms.ESSource("ForceSource")
1642 
1643 
1644 process.prefer("ForceSource")
1645 
1646 process.prefer("juicer",
1647  fooRcd = cms.vstring('Foo')
1648 )
1649 
1650 """)
1651 
1652  def testFreeze(self):
1653  process = Process("Freeze")
1654  m = EDProducer("M", p=PSet(i = int32(1)))
1655  m.p.i = 2
1656  process.m = m
1657  # should be frozen
1658  #self.assertRaises(ValueError, setattr, m.p, 'i', 3)
1659  #self.assertRaises(ValueError, setattr, m, 'p', PSet(i=int32(1)))
1660  #self.assertRaises(ValueError, setattr, m.p, 'j', 1)
1661  #self.assertRaises(ValueError, setattr, m, 'j', 1)
1662  # But OK to change through the process
1663  process.m.p.i = 4
1664  self.assertEqual(process.m.p.i.value(), 4)
1665  process.m.p = PSet(j=int32(1))
1666  # should work to clone it, though
1667  m2 = m.clone(p = PSet(i = int32(5)), j = int32(8))
1668  m2.p.i = 6
1669  m2.j = 8
1670  def testSubProcess(self):
1671  process = Process("Parent")
1672  subProcess = Process("Child")
1673  subProcess.a = EDProducer("A")
1674  subProcess.p = Path(subProcess.a)
1675  subProcess.add_(Service("Foo"))
1676  process.add_( SubProcess(subProcess) )
1677  d = process.dumpPython()
1678  equalD ="""import FWCore.ParameterSet.Config as cms
1679 
1680 process = cms.Process("Parent")
1681 
1682 parentProcess = process
1683 import FWCore.ParameterSet.Config as cms
1684 
1685 process = cms.Process("Child")
1686 
1687 process.a = cms.EDProducer("A")
1688 
1689 
1690 process.p = cms.Path(process.a)
1691 
1692 
1693 process.Foo = cms.Service("Foo")
1694 
1695 
1696 childProcess = process
1697 process = parentProcess
1698 process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = cms.untracked.PSet(
1699 
1700 ), outputCommands = cms.untracked.vstring())
1701 """
1702  equalD = equalD.replace("parentProcess","parentProcess"+str(hash(process.subProcess)))
1703  self.assertEqual(d,equalD)
1704  p = TestMakePSet()
1705  process.subProcess.insertInto(p,"dummy")
1706  self.assertEqual((True,['a']),p.values["@sub_process"][1].values["process"][1].values['@all_modules'])
1707  self.assertEqual((True,['p']),p.values["@sub_process"][1].values["process"][1].values['@paths'])
1708  self.assertEqual({'@service_type':(True,'Foo')}, p.values["@sub_process"][1].values["process"][1].values["services"][1][0].values)
1709  def testRefToPSet(self):
1710  proc = Process("test")
1711  proc.top = PSet(a = int32(1))
1712  proc.ref = PSet(refToPSet_ = string("top"))
1713  proc.ref2 = PSet( a = int32(1), b = PSet( refToPSet_ = string("top")))
1714  proc.ref3 = PSet(refToPSet_ = string("ref"))
1715  proc.ref4 = VPSet(PSet(refToPSet_ = string("top")),
1716  PSet(refToPSet_ = string("ref2")))
1717  p = TestMakePSet()
1718  proc.fillProcessDesc(p)
1719  self.assertEqual((True,1),p.values["ref"][1].values["a"])
1720  self.assertEqual((True,1),p.values["ref3"][1].values["a"])
1721  self.assertEqual((True,1),p.values["ref2"][1].values["a"])
1722  self.assertEqual((True,1),p.values["ref2"][1].values["b"][1].values["a"])
1723  self.assertEqual((True,1),p.values["ref4"][1][0].values["a"])
1724  self.assertEqual((True,1),p.values["ref4"][1][1].values["a"])
1725  def testPrune(self):
1726  p = Process("test")
1727  p.a = EDAnalyzer("MyAnalyzer")
1728  p.b = EDAnalyzer("YourAnalyzer")
1729  p.c = EDAnalyzer("OurAnalyzer")
1730  p.d = EDAnalyzer("OurAnalyzer")
1731  p.s = Sequence(p.d)
1732  p.path1 = Path(p.a)
1733  p.path2 = Path(p.b)
1734  self.assert_(p.schedule is None)
1735  pths = p.paths
1736  keys = pths.keys()
1737  self.assertEqual(pths[keys[0]],p.path1)
1738  self.assertEqual(pths[keys[1]],p.path2)
1739  p.pset1 = PSet(parA = string("pset1"))
1740  p.pset2 = untracked.PSet(parA = string("pset2"))
1741  p.vpset1 = VPSet()
1742  p.vpset2 = untracked.VPSet()
1743  p.prune()
1744  self.assert_(hasattr(p, 'a'))
1745  self.assert_(hasattr(p, 'b'))
1746  self.assert_(not hasattr(p, 'c'))
1747  self.assert_(not hasattr(p, 'd'))
1748  self.assert_(not hasattr(p, 's'))
1749  self.assert_(hasattr(p, 'path1'))
1750  self.assert_(hasattr(p, 'path2'))
1751 # self.assert_(not hasattr(p, 'pset1'))
1752 # self.assert_(hasattr(p, 'pset2'))
1753 # self.assert_(not hasattr(p, 'vpset1'))
1754 # self.assert_(not hasattr(p, 'vpset2'))
1755 
1756  p = Process("test")
1757  p.a = EDAnalyzer("MyAnalyzer")
1758  p.b = EDAnalyzer("YourAnalyzer")
1759  p.c = EDAnalyzer("OurAnalyzer")
1760  p.d = EDAnalyzer("OurAnalyzer")
1761  p.e = EDAnalyzer("OurAnalyzer")
1762  p.s = Sequence(p.d)
1763  p.s2 = Sequence(p.b)
1764  p.s3 = Sequence(p.e)
1765  p.path1 = Path(p.a)
1766  p.path2 = Path(p.b)
1767  p.path3 = Path(p.b+p.s2)
1768  p.path4 = Path(p.b+p.s3)
1769  p.schedule = Schedule(p.path1,p.path2,p.path3)
1770  pths = p.paths
1771  keys = pths.keys()
1772  self.assertEqual(pths[keys[0]],p.path1)
1773  self.assertEqual(pths[keys[1]],p.path2)
1774  p.prune()
1775  self.assert_(hasattr(p, 'a'))
1776  self.assert_(hasattr(p, 'b'))
1777  self.assert_(not hasattr(p, 'c'))
1778  self.assert_(not hasattr(p, 'd'))
1779  self.assert_(not hasattr(p, 'e'))
1780  self.assert_(not hasattr(p, 's'))
1781  self.assert_(hasattr(p, 's2'))
1782  self.assert_(not hasattr(p, 's3'))
1783  self.assert_(hasattr(p, 'path1'))
1784  self.assert_(hasattr(p, 'path2'))
1785  self.assert_(hasattr(p, 'path3'))
1786  self.assert_(not hasattr(p, 'path4'))
1787  #test SequencePlaceholder
1788  p = Process("test")
1789  p.a = EDAnalyzer("MyAnalyzer")
1790  p.b = EDAnalyzer("YourAnalyzer")
1791  p.s = Sequence(SequencePlaceholder("a")+p.b)
1792  p.pth = Path(p.s)
1793  p.prune()
1794  self.assert_(hasattr(p, 'a'))
1795  self.assert_(hasattr(p, 'b'))
1796  self.assert_(hasattr(p, 's'))
1797  self.assert_(hasattr(p, 'pth'))
1798  def testModifier(self):
1799  m1 = Modifier()
1800  p = Process("test")
1801  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1802  def _mod_fred(obj):
1803  obj.fred = 2
1804  m1.toModify(p.a,_mod_fred)
1805  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1806  m1.toModify(p.b, wilma = 2)
1807  self.assertEqual(p.a.fred.value(),1)
1808  self.assertEqual(p.b.wilma.value(),1)
1809  m1.modify(p)
1810  self.assertEqual(p.a.fred.value(),2)
1811  self.assertEqual(p.b.wilma.value(),2)
1812  #check that items not attached to process are unchanged
1813  m1 = Modifier()
1814  p = Process("test")
1815  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1816  m1.toModify(p.a,_mod_fred)
1817  b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1818  m1.toModify(b, wilma = 2)
1819  self.assertEqual(p.a.fred.value(),1)
1820  self.assertEqual(b.wilma.value(),1)
1821  m1.modify(p)
1822  self.assertEqual(p.a.fred.value(),2)
1823  self.assertEqual(b.wilma.value(),1)
1824  #make sure chains of modifiers work
1825  m1 = Modifier()
1826  m2 = Modifier()
1827  m2.toModifyProcess(m1)
1828  p = Process("test")
1829  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1830  m1.toModify(p.a,_mod_fred)
1831  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1832  m1.toModify(p.b, wilma = 2)
1833  m2.toModify(p.b, wilma = 3)
1834  m2.modify(p)
1835  self.assertEqual(p.a.fred.value(),2)
1836  self.assertEqual(p.b.wilma.value(),3)
1837 
1838  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:944
def toModifyProcess
Definition: Config.py:1054
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:851
def __init__
Definition: Config.py:102
def _insertInto
Definition: Config.py:729
def analyzers_
Definition: Config.py:199
def addLuminosityBlockID
Definition: Config.py:1140
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:1022
def services_
Definition: Config.py:239
def validate
Definition: Config.py:908
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:844
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