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