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  elif isinstance(item,ProcessModifier):
540  item.apply(self)
541  elif isinstance(item,ProcessFragment):
542  self.extend(item)
543 
544  #now create a sequence which uses the newly made items
545  for name in seqs.iterkeys():
546  seq = seqs[name]
547  #newSeq = seq.copy()
548  #
549  if id(seq) not in self._cloneToObjectDict:
550  self.__setattr__(name,seq)
551  else:
552  newSeq = self._cloneToObjectDict[id(seq)]
553  self.__dict__[name]=newSeq
554  self.__setObjectLabel(newSeq, name)
555  #now put in proper bucket
556  newSeq._place(name,self)
557  self.__dict__['_Process__InExtendCall'] = False
558 
559  def _dumpConfigNamedList(self,items,typeName,options):
560  returnValue = ''
561  for name,item in items:
562  returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
563  return returnValue
564  def _dumpConfigUnnamedList(self,items,typeName,options):
565  returnValue = ''
566  for name,item in items:
567  returnValue +=options.indentation()+typeName+' = '+item.dumpConfig(options)
568  return returnValue
569  def _dumpConfigOptionallyNamedList(self,items,typeName,options):
570  returnValue = ''
571  for name,item in items:
572  if name == item.type_():
573  name = ''
574  returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
575  return returnValue
576  def dumpConfig(self, options=PrintOptions()):
577  """return a string containing the equivalent process defined using the old configuration language"""
578  config = "process "+self.__name+" = {\n"
579  options.indent()
580  if self.source_():
581  config += options.indentation()+"source = "+self.source_().dumpConfig(options)
582  if self.looper_():
583  config += options.indentation()+"looper = "+self.looper_().dumpConfig(options)
584  if self.subProcess_():
585  config += options.indentation()+"subProcess = "+self.subProcess_().dumpConfig(options)
586 
587  config+=self._dumpConfigNamedList(self.producers_().iteritems(),
588  'module',
589  options)
590  config+=self._dumpConfigNamedList(self.filters_().iteritems(),
591  'module',
592  options)
593  config+=self._dumpConfigNamedList(self.analyzers_().iteritems(),
594  'module',
595  options)
596  config+=self._dumpConfigNamedList(self.outputModules_().iteritems(),
597  'module',
598  options)
599  config+=self._dumpConfigNamedList(self.sequences_().iteritems(),
600  'sequence',
601  options)
602  config+=self._dumpConfigNamedList(self.paths_().iteritems(),
603  'path',
604  options)
605  config+=self._dumpConfigNamedList(self.endpaths_().iteritems(),
606  'endpath',
607  options)
608  config+=self._dumpConfigUnnamedList(self.services_().iteritems(),
609  'service',
610  options)
611  config+=self._dumpConfigNamedList(self.aliases_().iteritems(),
612  'alias',
613  options)
614  config+=self._dumpConfigOptionallyNamedList(
615  self.es_producers_().iteritems(),
616  'es_module',
617  options)
618  config+=self._dumpConfigOptionallyNamedList(
619  self.es_sources_().iteritems(),
620  'es_source',
621  options)
622  config += self._dumpConfigESPrefers(options)
623  for name,item in self.psets.iteritems():
624  config +=options.indentation()+item.configTypeName()+' '+name+' = '+item.configValue(options)
625  for name,item in self.vpsets.iteritems():
626  config +=options.indentation()+'VPSet '+name+' = '+item.configValue(options)
627  if self.schedule:
628  pathNames = [p.label_() for p in self.schedule]
629  config +=options.indentation()+'schedule = {'+','.join(pathNames)+'}\n'
630 
631 # config+=self._dumpConfigNamedList(self.vpsets.iteritems(),
632 # 'VPSet',
633 # options)
634  config += "}\n"
635  options.unindent()
636  return config
637  def _dumpConfigESPrefers(self, options):
638  result = ''
639  for item in self.es_prefers_().itervalues():
640  result +=options.indentation()+'es_prefer '+item.targetLabel_()+' = '+item.dumpConfig(options)
641  return result
642  def _dumpPythonList(self, d, options):
643  returnValue = ''
644  if isinstance(d, DictTypes.SortedKeysDict):
645  for name,item in d.items():
646  returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
647  else:
648  for name,item in sorted(d.items()):
649  returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
650  return returnValue
651  def _validateSequence(self, sequence, label):
652  # See if every module has been inserted into the process
653  try:
654  l = set()
655  nameVisitor = NodeNameVisitor(l)
656  sequence.visit(nameVisitor)
657  except:
658  raise RuntimeError("An entry in sequence "+label + ' has no label')
660  #for each sequence, see what other sequences it depends upon
661  returnValue=DictTypes.SortedKeysDict()
662  dependencies = {}
663  for label,seq in self.sequences.iteritems():
664  d = []
665  v = SequenceVisitor(d)
666  seq.visit(v)
667  dependencies[label]=[dep.label_() for dep in d if dep.hasLabel_()]
668  resolvedDependencies=True
669  #keep looping until we can no longer get rid of all dependencies
670  # if that happens it means we have circular dependencies
671  iterCount = 0
672  while resolvedDependencies:
673  iterCount += 1
674  resolvedDependencies = (0 != len(dependencies))
675  oldDeps = dict(dependencies)
676  for label,deps in oldDeps.iteritems():
677  # don't try too hard
678  if len(deps)==0 or iterCount > 100:
679  iterCount = 0
680  resolvedDependencies=True
681  returnValue[label]=self.sequences[label]
682  #remove this as a dependency for all other sequences
683  del dependencies[label]
684  for lb2,deps2 in dependencies.iteritems():
685  while deps2.count(label):
686  deps2.remove(label)
687  if len(dependencies):
688  raise RuntimeError("circular sequence dependency discovered \n"+
689  ",".join([label for label,junk in dependencies.iteritems()]))
690  return returnValue
691  def _dumpPython(self, d, options):
692  result = ''
693  for name, value in sorted(d.iteritems()):
694  result += value.dumpPythonAs(name,options)+'\n'
695  return result
696  def dumpPython(self, options=PrintOptions()):
697  """return a string containing the equivalent process defined using python"""
698  result = "import FWCore.ParameterSet.Config as cms\n\n"
699  result += "process = cms.Process(\""+self.__name+"\")\n\n"
700  if self.source_():
701  result += "process.source = "+self.source_().dumpPython(options)
702  if self.looper_():
703  result += "process.looper = "+self.looper_().dumpPython()
704  if self.subProcess_():
705  result += self.subProcess_().dumpPython(options)
706  result+=self._dumpPythonList(self.producers_(), options)
707  result+=self._dumpPythonList(self.filters_() , options)
708  result+=self._dumpPythonList(self.analyzers_(), options)
709  result+=self._dumpPythonList(self.outputModules_(), options)
710  result+=self._dumpPythonList(self._sequencesInDependencyOrder(), options)
711  result+=self._dumpPythonList(self.paths_(), options)
712  result+=self._dumpPythonList(self.endpaths_(), options)
713  result+=self._dumpPythonList(self.services_(), options)
714  result+=self._dumpPythonList(self.es_producers_(), options)
715  result+=self._dumpPythonList(self.es_sources_(), options)
716  result+=self._dumpPython(self.es_prefers_(), options)
717  result+=self._dumpPythonList(self.aliases_(), options)
718  result+=self._dumpPythonList(self.psets, options)
719  result+=self._dumpPythonList(self.vpsets, options)
720  if self.schedule:
721  pathNames = ['process.'+p.label_() for p in self.schedule]
722  result +='process.schedule = cms.Schedule(*[ ' + ', '.join(pathNames) + ' ])\n'
723 
724  return result
725  def _replaceInSequences(self, label, new):
726  old = getattr(self,label)
727  #TODO - replace by iterator concatenation
728  for sequenceable in self.sequences.itervalues():
729  sequenceable.replace(old,new)
730  for sequenceable in self.paths.itervalues():
731  sequenceable.replace(old,new)
732  for sequenceable in self.endpaths.itervalues():
733  sequenceable.replace(old,new)
734  def globalReplace(self,label,new):
735  """ Replace the item with label 'label' by object 'new' in the process and all sequences/paths"""
736  if not hasattr(self,label):
737  raise LookupError("process has no item of label "+label)
738  self._replaceInSequences(label, new)
739  setattr(self,label,new)
740  def _insertInto(self, parameterSet, itemDict):
741  for name,value in itemDict.iteritems():
742  value.insertInto(parameterSet, name)
743  def _insertOneInto(self, parameterSet, label, item, tracked):
744  vitems = []
745  if not item == None:
746  newlabel = item.nameInProcessDesc_(label)
747  vitems = [newlabel]
748  item.insertInto(parameterSet, newlabel)
749  parameterSet.addVString(tracked, label, vitems)
750  def _insertManyInto(self, parameterSet, label, itemDict, tracked):
751  l = []
752  for name,value in itemDict.iteritems():
753  newLabel = value.nameInProcessDesc_(name)
754  l.append(newLabel)
755  value.insertInto(parameterSet, name)
756  # alphabetical order is easier to compare with old language
757  l.sort()
758  parameterSet.addVString(tracked, label, l)
759  def _insertPaths(self, processPSet):
760  scheduledPaths = []
761  triggerPaths = []
762  endpaths = []
763  if self.schedule_() == None:
764  # make one from triggerpaths & endpaths
765  for name,value in self.paths_().iteritems():
766  scheduledPaths.append(name)
767  triggerPaths.append(name)
768  for name,value in self.endpaths_().iteritems():
769  scheduledPaths.append(name)
770  endpaths.append(name)
771  else:
772  for path in self.schedule_():
773  pathname = path.label_()
774  scheduledPaths.append(pathname)
775  if self.endpaths_().has_key(pathname):
776  endpaths.append(pathname)
777  else:
778  triggerPaths.append(pathname)
779  processPSet.addVString(True, "@end_paths", endpaths)
780  processPSet.addVString(True, "@paths", scheduledPaths)
781  # trigger_paths are a little different
782  p = processPSet.newPSet()
783  p.addVString(True, "@trigger_paths", triggerPaths)
784  processPSet.addPSet(True, "@trigger_paths", p)
785  # add all these paths
786  pathValidator = PathValidator()
787  endpathValidator = EndPathValidator()
788  for triggername in triggerPaths:
789  #self.paths_()[triggername].insertInto(processPSet, triggername, self.sequences_())
790  pathValidator.setLabel(triggername)
791  self.paths_()[triggername].visit(pathValidator)
792  self.paths_()[triggername].insertInto(processPSet, triggername, self.__dict__)
793  for endpathname in endpaths:
794  #self.endpaths_()[endpathname].insertInto(processPSet, endpathname, self.sequences_())
795  endpathValidator.setLabel(endpathname)
796  self.endpaths_()[endpathname].visit(endpathValidator)
797  self.endpaths_()[endpathname].insertInto(processPSet, endpathname, self.__dict__)
798  processPSet.addVString(False, "@filters_on_endpaths", endpathValidator.filtersOnEndpaths)
799 
800  def prune(self,verbose=False):
801  """ Remove clutter from the process which we think is unnecessary:
802  tracked PSets, VPSets and unused modules and sequences. If a Schedule has been set, then Paths and EndPaths
803  not in the schedule will also be removed, along with an modules and sequences used only by
804  those removed Paths and EndPaths."""
805 # need to update this to only prune psets not on refToPSets
806 # but for now, remove the delattr
807 # for name in self.psets_():
808 # if getattr(self,name).isTracked():
809 # delattr(self, name)
810  for name in self.vpsets_():
811  delattr(self, name)
812  #first we need to resolve any SequencePlaceholders being used
813  for x in self.paths.itervalues():
814  x.resolve(self.__dict__)
815  for x in self.endpaths.itervalues():
816  x.resolve(self.__dict__)
817  usedModules = set()
818  unneededPaths = set()
819  if self.schedule_():
820  usedModules=set(self.schedule_().moduleNames())
821  #get rid of unused paths
822  schedNames = set(( x.label_() for x in self.schedule_()))
823  names = set(self.paths)
824  names.update(set(self.endpaths))
825  unneededPaths = names - schedNames
826  for n in unneededPaths:
827  delattr(self,n)
828  else:
829  pths = list(self.paths.itervalues())
830  pths.extend(self.endpaths.itervalues())
831  temp = Schedule(*pths)
832  usedModules=set(temp.moduleNames())
833  unneededModules = self._pruneModules(self.producers_(), usedModules)
834  unneededModules.update(self._pruneModules(self.filters_(), usedModules))
835  unneededModules.update(self._pruneModules(self.analyzers_(), usedModules))
836  #remove sequences that do not appear in remaining paths and endpaths
837  seqs = list()
838  sv = SequenceVisitor(seqs)
839  for p in self.paths.itervalues():
840  p.visit(sv)
841  for p in self.endpaths.itervalues():
842  p.visit(sv)
843  keepSeqSet = set(( s for s in seqs if s.hasLabel_()))
844  availableSeqs = set(self.sequences.itervalues())
845  unneededSeqs = availableSeqs-keepSeqSet
846  unneededSeqLabels = []
847  for s in unneededSeqs:
848  unneededSeqLabels.append(s.label_())
849  delattr(self,s.label_())
850  if verbose:
851  print "prune removed the following:"
852  print " modules:"+",".join(unneededModules)
853  print " sequences:"+",".join(unneededSeqLabels)
854  print " paths/endpaths:"+",".join(unneededPaths)
855  def _pruneModules(self, d, scheduledNames):
856  moduleNames = set(d.keys())
857  junk = moduleNames - scheduledNames
858  for name in junk:
859  delattr(self, name)
860  return junk
861 
862  def fillProcessDesc(self, processPSet):
863  """Used by the framework to convert python to C++ objects"""
864  class ServiceInjectorAdaptor(object):
865  def __init__(self,ppset,thelist):
866  self.__thelist = thelist
867  self.__processPSet = ppset
868  def addService(self,pset):
869  self.__thelist.append(pset)
870  def newPSet(self):
871  return self.__processPSet.newPSet()
872  #This adaptor is used to 'add' the method 'getTopPSet_'
873  # to the ProcessDesc and PythonParameterSet C++ classes.
874  # This method is needed for the PSet refToPSet_ functionality.
875  class TopLevelPSetAcessorAdaptor(object):
876  def __init__(self,ppset,process):
877  self.__ppset = ppset
878  self.__process = process
879  def __getattr__(self,attr):
880  return getattr(self.__ppset,attr)
881  def getTopPSet_(self,label):
882  return getattr(self.__process,label)
883  def newPSet(self):
884  return TopLevelPSetAcessorAdaptor(self.__ppset.newPSet(),self.__process)
885  def addPSet(self,tracked,name,ppset):
886  return self.__ppset.addPSet(tracked,name,self.__extractPSet(ppset))
887  def addVPSet(self,tracked,name,vpset):
888  return self.__ppset.addVPSet(tracked,name,[self.__extractPSet(x) for x in vpset])
889  def __extractPSet(self,pset):
890  if isinstance(pset,TopLevelPSetAcessorAdaptor):
891  return pset.__ppset
892  return pset
893 
894  self.validate()
895  processPSet.addString(True, "@process_name", self.name_())
896  all_modules = self.producers_().copy()
897  all_modules.update(self.filters_())
898  all_modules.update(self.analyzers_())
899  all_modules.update(self.outputModules_())
900  adaptor = TopLevelPSetAcessorAdaptor(processPSet,self)
901  self._insertInto(adaptor, self.psets_())
902  self._insertInto(adaptor, self.vpsets_())
903  self._insertManyInto(adaptor, "@all_modules", all_modules, True)
904  self._insertOneInto(adaptor, "@all_sources", self.source_(), True)
905  self._insertOneInto(adaptor, "@all_loopers", self.looper_(), True)
906  self._insertOneInto(adaptor, "@all_subprocesses", self.subProcess_(), False)
907  self._insertManyInto(adaptor, "@all_esmodules", self.es_producers_(), True)
908  self._insertManyInto(adaptor, "@all_essources", self.es_sources_(), True)
909  self._insertManyInto(adaptor, "@all_esprefers", self.es_prefers_(), True)
910  self._insertManyInto(adaptor, "@all_aliases", self.aliases_(), True)
911  self._insertPaths(adaptor)
912  #handle services differently
913  services = []
914  for n in self.services_():
915  getattr(self,n).insertInto(ServiceInjectorAdaptor(adaptor,services))
916  adaptor.addVPSet(False,"services",services)
917  return processPSet
918 
919  def validate(self):
920  # check if there's some input
921  # Breaks too many unit tests for now
922  #if self.source_() == None and self.looper_() == None:
923  # raise RuntimeError("No input source was found for this process")
924  pass
925 
926  def prefer(self, esmodule,*args,**kargs):
927  """Prefer this ES source or producer. The argument can
928  either be an object label, e.g.,
929  process.prefer(process.juicerProducer) (not supported yet)
930  or a name of an ESSource or ESProducer
931  process.prefer("juicer")
932  or a type of unnamed ESSource or ESProducer
933  process.prefer("JuicerProducer")
934  In addition, you can pass as a labelled arguments the name of the Record you wish to
935  prefer where the type passed is a cms.vstring and that vstring can contain the
936  name of the C++ types in the Record which are being preferred, e.g.,
937  #prefer all data in record 'OrangeRecord' from 'juicer'
938  process.prefer("juicer", OrangeRecord=cms.vstring())
939  or
940  #prefer only "Orange" data in "OrangeRecord" from "juicer"
941  process.prefer("juicer", OrangeRecord=cms.vstring("Orange"))
942  or
943  #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer"
944  ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
945  """
946  # see if this refers to a named ESProducer
947  if isinstance(esmodule, ESSource) or isinstance(esmodule, ESProducer):
948  raise RuntimeError("Syntax of process.prefer(process.esmodule) not supported yet")
949  elif self._findPreferred(esmodule, self.es_producers_(),*args,**kargs) or \
950  self._findPreferred(esmodule, self.es_sources_(),*args,**kargs):
951  pass
952  else:
953  raise RuntimeError("Cannot resolve prefer for "+repr(esmodule))
954 
955  def _findPreferred(self, esname, d,*args,**kargs):
956  # is esname a name in the dictionary?
957  if esname in d:
958  typ = d[esname].type_()
959  if typ == esname:
960  self.__setattr__( esname+"_prefer", ESPrefer(typ,*args,**kargs) )
961  else:
962  self.__setattr__( esname+"_prefer", ESPrefer(typ, esname,*args,**kargs) )
963  return True
964  else:
965  # maybe it's an unnamed ESModule?
966  found = False
967  for name, value in d.iteritems():
968  if value.type_() == esname:
969  if found:
970  raise RuntimeError("More than one ES module for "+esname)
971  found = True
972  self.__setattr__(esname+"_prefer", ESPrefer(d[esname].type_()) )
973  return found
974 
975 
977  def __init__(self, process):
978  if isinstance(process, Process):
979  self.__process = process
980  elif isinstance(process, str):
981  self.__process = Process(process)
982  else:
983  raise TypeError('a ProcessFragment can only be constructed from an existig Process or from process name')
984  def __dir__(self):
985  return [ x for x in dir(self.__process) if isinstance(getattr(self.__process, x), _ConfigureComponent) ]
986  def __getattribute__(self, name):
987  if name == '_ProcessFragment__process':
988  return object.__getattribute__(self, '_ProcessFragment__process')
989  else:
990  return getattr(self.__process, name)
991  def __setattr__(self, name, value):
992  if name == '_ProcessFragment__process':
993  object.__setattr__(self, name, value)
994  else:
995  setattr(self.__process, name, value)
996  def __delattr__(self, name):
997  if name == '_ProcessFragment__process':
998  pass
999  else:
1000  return delattr(self.__process, name)
1001 
1002 
1004  """a dictionary with fixed keys"""
1006  raise AttributeError, "An FilteredStream defintion cannot be modified after creation."
1007  _blocked_attribute = property(_blocked_attribute)
1008  __setattr__ = __delitem__ = __setitem__ = clear = _blocked_attribute
1009  pop = popitem = setdefault = update = _blocked_attribute
1010  def __new__(cls, *args, **kw):
1011  new = dict.__new__(cls)
1012  dict.__init__(new, *args, **kw)
1013  keys = kw.keys()
1014  keys.sort()
1015  if keys != ['content', 'dataTier', 'name', 'paths', 'responsible', 'selectEvents']:
1016  raise ValueError("The needed parameters are: content, dataTier, name, paths, responsible, selectEvents")
1017  if not isinstance(kw['name'],str):
1018  raise ValueError("name must be of type string")
1019  if not isinstance(kw['content'], vstring) and not isinstance(kw['content'],str):
1020  raise ValueError("content must be of type vstring or string")
1021  if not isinstance(kw['dataTier'], string):
1022  raise ValueError("dataTier must be of type string")
1023  if not isinstance(kw['selectEvents'], PSet):
1024  raise ValueError("selectEvents must be of type PSet")
1025  if not isinstance(kw['paths'],(tuple, Path)):
1026  raise ValueError("'paths' must be a tuple of paths")
1027  return new
1028  def __init__(self, *args, **kw):
1029  pass
1030  def __repr__(self):
1031  return "FilteredStream object: %s" %self["name"]
1032  def __getattr__(self,attr):
1033  return self[attr]
1034 
1036  """Allows embedding another process within a parent process. This allows one to
1037  chain processes together directly in one cmsRun job rather than having to run
1038  separate jobs which are connected via a temporary file.
1039  """
1040  def __init__(self,process, SelectEvents = untracked.PSet(), outputCommands = untracked.vstring()):
1041  """
1042  """
1043  if not isinstance(process, Process):
1044  raise ValueError("the 'process' argument must be of type cms.Process")
1045  if not isinstance(SelectEvents,PSet):
1046  raise ValueError("the 'SelectEvents' argument must be of type cms.untracked.PSet")
1047  if not isinstance(outputCommands,vstring):
1048  raise ValueError("the 'outputCommands' argument must be of type cms.untracked.vstring")
1049  self.__process = process
1050  self.__SelectEvents = SelectEvents
1051  self.__outputCommands = outputCommands
1052  def dumpPython(self,options):
1053  out = "parentProcess"+str(hash(self))+" = process\n"
1054  out += self.__process.dumpPython()
1055  out += "childProcess = process\n"
1056  out += "process = parentProcess"+str(hash(self))+"\n"
1057  out += "process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = "+self.__SelectEvents.dumpPython(options) +", outputCommands = "+self.__outputCommands.dumpPython(options) +")\n"
1058  return out
1059  def type_(self):
1060  return 'subProcess'
1061  def nameInProcessDesc_(self,label):
1062  return '@sub_process'
1063  def _place(self,label,process):
1064  process._placeSubProcess('subProcess',self)
1065  def insertInto(self,parameterSet, newlabel):
1066  topPSet = parameterSet.newPSet()
1067  self.__process.fillProcessDesc(topPSet)
1068  subProcessPSet = parameterSet.newPSet()
1069  self.__SelectEvents.insertInto(subProcessPSet,"SelectEvents")
1070  self.__outputCommands.insertInto(subProcessPSet,"outputCommands")
1071  subProcessPSet.addPSet(False,"process",topPSet)
1072  parameterSet.addPSet(False,self.nameInProcessDesc_("subProcess"), subProcessPSet)
1073 
1075  """Helper class for Modifier which takes key/value pairs and uses them to reset parameters of the object"""
1076  def __init__(self,args):
1077  self.__args = args
1078  def __call__(self,obj):
1079  for k,v in self.__args.iteritems():
1080  setattr(obj,k,v)
1081 
1083  """This class is used to define standard modifications to a Process.
1084  An instance of this class is declared to denote a specific modification,e.g. era2017 could
1085  reconfigure items in a process to match our expectation of running in 2017. Once declared,
1086  these Modifier instances are imported into a configuration and items which need to be modified
1087  are then associated with the Modifier and with the action to do the modification.
1088  The registered modifications will only occur if the Modifier was passed to
1089  the cms.Process' constructor.
1090  """
1091  def __init__(self):
1093  self.__chosen = False
1094  def makeProcessModifier(self,func):
1095  """This is used to create a ProcessModifer which can perform actions on the process as a whole.
1096  This takes as argument a callable object (e.g. function) which takes as its sole argument an instance of Process.
1097  In order to work, the value returned from this function must be assigned to a uniquely named variable.
1098  """
1099  return ProcessModifier(self,func)
1100  def toModify(self,obj, func=None,**kw):
1101  """This is used to register an action to be performed on the specific object. Two different forms are allowed
1102  Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1103  which will be the object passed in as the first argument.
1104  Form 2: A list of parameter name, value pairs can be passed
1105  mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1106  """
1107  if func is not None and len(kw) != 0:
1108  raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
1109  if not self.isChosen():
1110  return
1111  if func is not None:
1112  func(obj)
1113  else:
1114  temp =_ParameterModifier(kw)
1115  temp(obj)
1116  def _setChosen(self):
1117  """Should only be called by cms.Process instances"""
1118  self.__chosen = True
1119  def isChosen(self):
1120  return self.__chosen
1121 
1123  """A Modifier made up of a list of Modifiers
1124  """
1125  def __init__(self, *chainedModifiers):
1126  self.__chosen = False
1127  self.__chain = chainedModifiers
1128  def _applyNewProcessModifiers(self,process):
1129  """Should only be called by cms.Process instances
1130  applies list of accumulated changes to the process"""
1131  for m in self.__chain:
1132  m._applyNewProcessModifiers(process)
1133  def _setChosen(self):
1134  """Should only be called by cms.Process instances"""
1135  self.__chosen = True
1136  for m in self.__chain:
1137  m._setChosen()
1138  def isChosen(self):
1139  return self.__chosen
1140 
1142  """A class used by a Modifier to affect an entire Process instance.
1143  When a Process 'loads' a module containing a ProcessModifier, that
1144  ProcessModifier will be applied to the Process if and only if the
1145  Modifier passed to the constructor has been chosen.
1146  """
1147  def __init__(self, modifier, func):
1148  self.__modifier = modifier
1149  self.__func = func
1150  self.__seenProcesses = set()
1151  def apply(self,process):
1152  if self.__modifier.isChosen():
1153  if process not in self.__seenProcesses:
1154  self.__func(process)
1155  self.__seenProcesses.add(process)
1156 
1157 if __name__=="__main__":
1158  import unittest
1159  import copy
1160 
1162  """Has same interface as the C++ object which creates PSets
1163  """
1164  def __init__(self):
1165  self.values = dict()
1166  def __insertValue(self,tracked,label,value):
1167  self.values[label]=(tracked,value)
1168  def addInt32(self,tracked,label,value):
1169  self.__insertValue(tracked,label,value)
1170  def addVInt32(self,tracked,label,value):
1171  self.__insertValue(tracked,label,value)
1172  def addUInt32(self,tracked,label,value):
1173  self.__insertValue(tracked,label,value)
1174  def addVUInt32(self,tracked,label,value):
1175  self.__insertValue(tracked,label,value)
1176  def addInt64(self,tracked,label,value):
1177  self.__insertValue(tracked,label,value)
1178  def addVInt64(self,tracked,label,value):
1179  self.__insertValue(tracked,label,value)
1180  def addUInt64(self,tracked,label,value):
1181  self.__insertValue(tracked,label,value)
1182  def addVUInt64(self,tracked,label,value):
1183  self.__insertValue(tracked,label,value)
1184  def addDouble(self,tracked,label,value):
1185  self.__insertValue(tracked,label,value)
1186  def addVDouble(self,tracked,label,value):
1187  self.__insertValue(tracked,label,value)
1188  def addBool(self,tracked,label,value):
1189  self.__insertValue(tracked,label,value)
1190  def addString(self,tracked,label,value):
1191  self.__insertValue(tracked,label,value)
1192  def addVString(self,tracked,label,value):
1193  self.__insertValue(tracked,label,value)
1194  def addInputTag(self,tracked,label,value):
1195  self.__insertValue(tracked,label,value)
1196  def addVInputTag(self,tracked,label,value):
1197  self.__insertValue(tracked,label,value)
1198  def addESInputTag(self,tracked,label,value):
1199  self.__insertValue(tracked,label,value)
1200  def addVESInputTag(self,tracked,label,value):
1201  self.__insertValue(tracked,label,value)
1202  def addEventID(self,tracked,label,value):
1203  self.__insertValue(tracked,label,value)
1204  def addVEventID(self,tracked,label,value):
1205  self.__insertValue(tracked,label,value)
1206  def addLuminosityBlockID(self,tracked,label,value):
1207  self.__insertValue(tracked,label,value)
1208  def addLuminosityBlockID(self,tracked,label,value):
1209  self.__insertValue(tracked,label,value)
1210  def addEventRange(self,tracked,label,value):
1211  self.__insertValue(tracked,label,value)
1212  def addVEventRange(self,tracked,label,value):
1213  self.__insertValue(tracked,label,value)
1214  def addPSet(self,tracked,label,value):
1215  self.__insertValue(tracked,label,value)
1216  def addVPSet(self,tracked,label,value):
1217  self.__insertValue(tracked,label,value)
1218  def addFileInPath(self,tracked,label,value):
1219  self.__insertValue(tracked,label,value)
1220  def newPSet(self):
1221  return TestMakePSet()
1222 
1223  class TestModuleCommand(unittest.TestCase):
1224  def setUp(self):
1225  """Nothing to do """
1226  None
1228  p = _Parameterizable()
1229  self.assertEqual(len(p.parameterNames_()),0)
1230  p.a = int32(1)
1231  self.assert_('a' in p.parameterNames_())
1232  self.assertEqual(p.a.value(), 1)
1233  p.a = 10
1234  self.assertEqual(p.a.value(), 10)
1235  p.a = untracked(int32(1))
1236  self.assertEqual(p.a.value(), 1)
1237  self.failIf(p.a.isTracked())
1238  p.a = untracked.int32(1)
1239  self.assertEqual(p.a.value(), 1)
1240  self.failIf(p.a.isTracked())
1241  p = _Parameterizable(foo=int32(10), bar = untracked(double(1.0)))
1242  self.assertEqual(p.foo.value(), 10)
1243  self.assertEqual(p.bar.value(),1.0)
1244  self.failIf(p.bar.isTracked())
1245  self.assertRaises(TypeError,setattr,(p,'c',1))
1246  p = _Parameterizable(a=PSet(foo=int32(10), bar = untracked(double(1.0))))
1247  self.assertEqual(p.a.foo.value(),10)
1248  self.assertEqual(p.a.bar.value(),1.0)
1249  p.b = untracked(PSet(fii = int32(1)))
1250  self.assertEqual(p.b.fii.value(),1)
1251  self.failIf(p.b.isTracked())
1252  #test the fact that values can be shared
1253  v = int32(10)
1254  p=_Parameterizable(a=v)
1255  v.setValue(11)
1256  self.assertEqual(p.a.value(),11)
1257  p.a = 12
1258  self.assertEqual(p.a.value(),12)
1259  self.assertEqual(v.value(),12)
1261  p = _TypedParameterizable("blah", b=int32(1))
1262  #see if copy works deeply
1263  other = p.copy()
1264  other.b = 2
1265  self.assertNotEqual(p.b,other.b)
1266 
1268  p = Process("test")
1269  p.a = EDAnalyzer("MyAnalyzer")
1270  self.assert_( 'a' in p.analyzers_() )
1271  self.assert_( 'a' in p.analyzers)
1272  p.add_(Service("MessageLogger"))
1273  self.assert_('MessageLogger' in p.services_())
1274  self.assertEqual(p.MessageLogger.type_(), "MessageLogger")
1275  p.Tracer = Service("Tracer")
1276  self.assert_('Tracer' in p.services_())
1277  self.assertRaises(TypeError, setattr, *(p,'b',"this should fail"))
1278  self.assertRaises(TypeError, setattr, *(p,'bad',Service("MessageLogger")))
1279  self.assertRaises(ValueError, setattr, *(p,'bad',Source("PoolSource")))
1280  p.out = OutputModule("Outer")
1281  self.assertEqual(p.out.type_(), 'Outer')
1282  self.assert_( 'out' in p.outputModules_() )
1283 
1284  p.geom = ESSource("GeomProd")
1285  self.assert_('geom' in p.es_sources_())
1286  p.add_(ESSource("ConfigDB"))
1287  self.assert_('ConfigDB' in p.es_sources_())
1288 
1289  p.aliasfoo1 = EDAlias(foo1 = VPSet(PSet(type = string("Foo1"))))
1290  self.assert_('aliasfoo1' in p.aliases_())
1291 
1293  class FromArg(object):
1294  def __init__(self,*arg,**args):
1295  for name in args.iterkeys():
1296  self.__dict__[name]=args[name]
1297 
1298  a=EDAnalyzer("MyAnalyzer")
1299  t=EDAnalyzer("MyAnalyzer")
1300  t.setLabel("foo")
1301  s1 = Sequence(a)
1302  s2 = Sequence(s1)
1303  s3 = Sequence(s2)
1304  d = FromArg(
1305  a=a,
1306  b=Service("Full"),
1307  c=Path(a),
1308  d=s2,
1309  e=s1,
1310  f=s3,
1311  g=Sequence(s1+s2+s3)
1312  )
1313  p = Process("Test")
1314  p.extend(d)
1315  self.assertEqual(p.a.type_(),"MyAnalyzer")
1316  self.assertEqual(p.a.label_(),"a")
1317  self.assertRaises(AttributeError,getattr,p,'b')
1318  self.assertEqual(p.Full.type_(),"Full")
1319  self.assertEqual(str(p.c),'a')
1320  self.assertEqual(str(p.d),'a')
1321 
1322  z1 = FromArg(
1323  a=a,
1324  b=Service("Full"),
1325  c=Path(a),
1326  d=s2,
1327  e=s1,
1328  f=s3,
1329  s4=s3,
1330  g=Sequence(s1+s2+s3)
1331  )
1332 
1333  p1 = Process("Test")
1334  #p1.extend(z1)
1335  self.assertRaises(ValueError, p1.extend, z1)
1336 
1337  z2 = FromArg(
1338  a=a,
1339  b=Service("Full"),
1340  c=Path(a),
1341  d=s2,
1342  e=s1,
1343  f=s3,
1344  aaa=copy.deepcopy(a),
1345  s4=copy.deepcopy(s3),
1346  g=Sequence(s1+s2+s3),
1347  t=t
1348  )
1349  p2 = Process("Test")
1350  p2.extend(z2)
1351  #self.assertRaises(ValueError, p2.extend, z2)
1352  self.assertEqual(p2.s4.label_(),"s4")
1353  #p2.s4.setLabel("foo")
1354  self.assertRaises(ValueError, p2.s4.setLabel, "foo")
1355  p2.s4.setLabel("s4")
1356  p2.s4.setLabel(None)
1357  p2.s4.setLabel("foo")
1358  p2._Process__setObjectLabel(p2.s4, "foo")
1359  p2._Process__setObjectLabel(p2.s4, None)
1360  p2._Process__setObjectLabel(p2.s4, "bar")
1361 
1363  p = Process("test")
1364  p.a = EDAnalyzer("MyAnalyzer")
1365  p.p = Path(p.a)
1366  p.s = Sequence(p.a)
1367  p.r = Sequence(p.s)
1368  p.p2 = Path(p.s)
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.s = cms.Sequence(process.a)
1380 
1381 
1382 process.r = cms.Sequence(process.s)
1383 
1384 
1385 process.p = cms.Path(process.a)
1386 
1387 
1388 process.p2 = cms.Path(process.s)
1389 
1390 
1391 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1392 """)
1393  #Reverse order of 'r' and 's'
1394  p = Process("test")
1395  p.a = EDAnalyzer("MyAnalyzer")
1396  p.p = Path(p.a)
1397  p.r = Sequence(p.a)
1398  p.s = Sequence(p.r)
1399  p.p2 = Path(p.r)
1400  p.schedule = Schedule(p.p2,p.p)
1401  p.b = EDAnalyzer("YourAnalyzer")
1402  d=p.dumpPython()
1403  self.assertEqual(d,
1404 """import FWCore.ParameterSet.Config as cms
1405 
1406 process = cms.Process("test")
1407 
1408 process.a = cms.EDAnalyzer("MyAnalyzer")
1409 
1410 
1411 process.b = cms.EDAnalyzer("YourAnalyzer")
1412 
1413 
1414 process.r = cms.Sequence(process.a)
1415 
1416 
1417 process.s = cms.Sequence(process.r)
1418 
1419 
1420 process.p = cms.Path(process.a)
1421 
1422 
1423 process.p2 = cms.Path(process.r)
1424 
1425 
1426 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1427 """)
1428  #use an anonymous sequence
1429  p = Process("test")
1430  p.a = EDAnalyzer("MyAnalyzer")
1431  p.p = Path(p.a)
1432  s = Sequence(p.a)
1433  p.r = Sequence(s)
1434  p.p2 = Path(p.r)
1435  p.schedule = Schedule(p.p2,p.p)
1436  d=p.dumpPython()
1437  self.assertEqual(d,
1438  """import FWCore.ParameterSet.Config as cms
1439 
1440 process = cms.Process("test")
1441 
1442 process.a = cms.EDAnalyzer("MyAnalyzer")
1443 
1444 
1445 process.r = cms.Sequence((process.a))
1446 
1447 
1448 process.p = cms.Path(process.a)
1449 
1450 
1451 process.p2 = cms.Path(process.r)
1452 
1453 
1454 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1455 """)
1456 
1457  def testSecSource(self):
1458  p = Process('test')
1459  p.a = SecSource("MySecSource")
1460  self.assertEqual(p.dumpPython().replace('\n',''),'import FWCore.ParameterSet.Config as cmsprocess = cms.Process("test")process.a = cms.SecSource("MySecSource")')
1461 
1463  p = Process('test')
1464  p.a = EDAnalyzer("MyAnalyzer")
1465  p.b = EDAnalyzer("YourAnalyzer")
1466  p.c = EDAnalyzer("OurAnalyzer")
1467  p.s = Sequence(p.a*p.b)
1468  p.p = Path(p.c+p.s+p.a)
1469  new = EDAnalyzer("NewAnalyzer")
1470  p.globalReplace("a",new)
1471 
1472  def testSequence(self):
1473  p = Process('test')
1474  p.a = EDAnalyzer("MyAnalyzer")
1475  p.b = EDAnalyzer("YourAnalyzer")
1476  p.c = EDAnalyzer("OurAnalyzer")
1477  p.s = Sequence(p.a*p.b)
1478  self.assertEqual(str(p.s),'a+b')
1479  self.assertEqual(p.s.label_(),'s')
1480  path = Path(p.c+p.s)
1481  self.assertEqual(str(path),'c+a+b')
1482  p._validateSequence(path, 'p1')
1483  notInProcess = EDAnalyzer('NotInProcess')
1484  p2 = Path(p.c+p.s*notInProcess)
1485  self.assertRaises(RuntimeError, p._validateSequence, p2, 'p2')
1486 
1487  def testSequence2(self):
1488  p = Process('test')
1489  p.a = EDAnalyzer("MyAnalyzer")
1490  p.b = EDAnalyzer("YourAnalyzer")
1491  p.c = EDAnalyzer("OurAnalyzer")
1492  testseq = Sequence(p.a*p.b)
1493  p.s = testseq
1494  #p.y = testseq
1495  self.assertRaises(ValueError, p.__setattr__, "y", testseq)
1496 
1497  def testPath(self):
1498  p = Process("test")
1499  p.a = EDAnalyzer("MyAnalyzer")
1500  p.b = EDAnalyzer("YourAnalyzer")
1501  p.c = EDAnalyzer("OurAnalyzer")
1502  path = Path(p.a)
1503  path *= p.b
1504  path += p.c
1505  self.assertEqual(str(path),'a+b+c')
1506  path = Path(p.a*p.b+p.c)
1507  self.assertEqual(str(path),'a+b+c')
1508 # path = Path(p.a)*p.b+p.c #This leads to problems with sequences
1509 # self.assertEqual(str(path),'((a*b)+c)')
1510  path = Path(p.a+ p.b*p.c)
1511  self.assertEqual(str(path),'a+b+c')
1512  path = Path(p.a*(p.b+p.c))
1513  self.assertEqual(str(path),'a+b+c')
1514  path = Path(p.a*(p.b+~p.c))
1515  self.assertEqual(str(path),'a+b+~c')
1516  p.es = ESProducer("AnESProducer")
1517  self.assertRaises(TypeError,Path,p.es)
1518 
1520  p = Process("test")
1521  a = EDAnalyzer("MyAnalyzer")
1522  p.a = a
1523  a.setLabel("a")
1524  b = EDAnalyzer("YOurAnalyzer")
1525  p.b = b
1526  b.setLabel("b")
1527  path = Path(a * b)
1528  p.path = Path(p.a*p.b)
1529  lookuptable = {id(a): p.a, id(b): p.b}
1530  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1531  #lookuptable = p._cloneToObjectDict
1532  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1533  self.assertEqual(str(path),str(p.path))
1534 
1535  def testSchedule(self):
1536  p = Process("test")
1537  p.a = EDAnalyzer("MyAnalyzer")
1538  p.b = EDAnalyzer("YourAnalyzer")
1539  p.c = EDAnalyzer("OurAnalyzer")
1540  p.d = EDAnalyzer("OurAnalyzer")
1541  p.path1 = Path(p.a)
1542  p.path2 = Path(p.b)
1543  p.path3 = Path(p.d)
1544 
1545  s = Schedule(p.path1,p.path2)
1546  self.assertEqual(s[0],p.path1)
1547  self.assertEqual(s[1],p.path2)
1548  p.schedule = s
1549  self.assert_('b' in p.schedule.moduleNames())
1550  self.assert_(hasattr(p, 'b'))
1551  self.assert_(hasattr(p, 'c'))
1552  self.assert_(hasattr(p, 'd'))
1553  self.assert_(hasattr(p, 'path1'))
1554  self.assert_(hasattr(p, 'path2'))
1555  self.assert_(hasattr(p, 'path3'))
1556  p.prune()
1557  self.assert_('b' in p.schedule.moduleNames())
1558  self.assert_(hasattr(p, 'b'))
1559  self.assert_(not hasattr(p, 'c'))
1560  self.assert_(not hasattr(p, 'd'))
1561  self.assert_(hasattr(p, 'path1'))
1562  self.assert_(hasattr(p, 'path2'))
1563  self.assert_(not hasattr(p, 'path3'))
1564 
1565  #adding a path not attached to the Process should cause an exception
1566  p = Process("test")
1567  p.a = EDAnalyzer("MyAnalyzer")
1568  path1 = Path(p.a)
1569  s = Schedule(path1)
1570  self.assertRaises(RuntimeError, lambda : p.setSchedule_(s) )
1571 
1572  #make sure anonymous sequences work
1573  p = Process("test")
1574  p.a = EDAnalyzer("MyAnalyzer")
1575  p.b = EDAnalyzer("MyOtherAnalyzer")
1576  p.c = EDProducer("MyProd")
1577  path1 = Path(p.c*Sequence(p.a+p.b))
1578  s = Schedule(path1)
1579  self.assert_('a' in s.moduleNames())
1580  self.assert_('b' in s.moduleNames())
1581  self.assert_('c' in s.moduleNames())
1582  p.path1 = path1
1583  p.schedule = s
1584  p.prune()
1585  self.assert_('a' in s.moduleNames())
1586  self.assert_('b' in s.moduleNames())
1587  self.assert_('c' in s.moduleNames())
1588 
1590  p = Process("test")
1591  p.a = EDAnalyzer("MyAnalyzer")
1592  p.b = EDAnalyzer("YourAnalyzer")
1593  p.c = EDAnalyzer("OurAnalyzer")
1594  p.path1 = Path(p.a)
1595  p.path2 = Path(p.b)
1596  self.assert_(p.schedule is None)
1597  pths = p.paths
1598  keys = pths.keys()
1599  self.assertEqual(pths[keys[0]],p.path1)
1600  self.assertEqual(pths[keys[1]],p.path2)
1601  p.prune()
1602  self.assert_(hasattr(p, 'a'))
1603  self.assert_(hasattr(p, 'b'))
1604  self.assert_(not hasattr(p, 'c'))
1605  self.assert_(hasattr(p, 'path1'))
1606  self.assert_(hasattr(p, 'path2'))
1607 
1608 
1609  p = Process("test")
1610  p.a = EDAnalyzer("MyAnalyzer")
1611  p.b = EDAnalyzer("YourAnalyzer")
1612  p.c = EDAnalyzer("OurAnalyzer")
1613  p.path2 = Path(p.b)
1614  p.path1 = Path(p.a)
1615  self.assert_(p.schedule is None)
1616  pths = p.paths
1617  keys = pths.keys()
1618  self.assertEqual(pths[keys[1]],p.path1)
1619  self.assertEqual(pths[keys[0]],p.path2)
1620 
1621 
1622  def testUsing(self):
1623  p = Process('test')
1624  p.block = PSet(a = int32(1))
1625  p.modu = EDAnalyzer('Analyzer', p.block, b = int32(2))
1626  self.assertEqual(p.modu.a.value(),1)
1627  self.assertEqual(p.modu.b.value(),2)
1628 
1629  def testOverride(self):
1630  p = Process('test')
1631  a = EDProducer("A", a1=int32(0))
1632  self.assert_(not a.isModified())
1633  a.a1 = 1
1634  self.assert_(a.isModified())
1635  p.a = a
1636  self.assertEqual(p.a.a1.value(), 1)
1637  # try adding an unmodified module.
1638  # should accept it
1639  p.a = EDProducer("A", a1=int32(2))
1640  self.assertEqual(p.a.a1.value(), 2)
1641  # try adding a modified module. Should throw
1642  # no longer, since the same (modified) say, geometry
1643  # could come from more than one cff
1644  b = EDProducer("A", a1=int32(3))
1645  b.a1 = 4
1646  #self.assertRaises(RuntimeError, setattr, *(p,'a',b))
1647  ps1 = PSet(a = int32(1))
1648  ps2 = PSet(a = int32(2))
1649  self.assertRaises(ValueError, EDProducer, 'C', ps1, ps2)
1650  self.assertRaises(ValueError, EDProducer, 'C', ps1, a=int32(3))
1651 
1652  def testExamples(self):
1653  p = Process("Test")
1654  p.source = Source("PoolSource",fileNames = untracked(string("file:reco.root")))
1655  p.foos = EDProducer("FooProducer")
1656  p.bars = EDProducer("BarProducer", foos=InputTag("foos"))
1657  p.out = OutputModule("PoolOutputModule",fileName=untracked(string("file:foos.root")))
1658  p.bars.foos = 'Foosball'
1659  self.assertEqual(p.bars.foos, InputTag('Foosball'))
1660  p.p = Path(p.foos*p.bars)
1661  p.e = EndPath(p.out)
1662  p.add_(Service("MessageLogger"))
1663 
1664  def testPrefers(self):
1665  p = Process("Test")
1666  p.add_(ESSource("ForceSource"))
1667  p.juicer = ESProducer("JuicerProducer")
1668  p.prefer("ForceSource")
1669  p.prefer("juicer")
1670  self.assertEqual(p.dumpConfig(),
1671 """process Test = {
1672  es_module juicer = JuicerProducer {
1673  }
1674  es_source = ForceSource {
1675  }
1676  es_prefer = ForceSource {
1677  }
1678  es_prefer juicer = JuicerProducer {
1679  }
1680 }
1681 """)
1682  p.prefer("juicer",fooRcd=vstring("Foo"))
1683  self.assertEqual(p.dumpConfig(),
1684 """process Test = {
1685  es_module juicer = JuicerProducer {
1686  }
1687  es_source = ForceSource {
1688  }
1689  es_prefer = ForceSource {
1690  }
1691  es_prefer juicer = JuicerProducer {
1692  vstring fooRcd = {
1693  'Foo'
1694  }
1695 
1696  }
1697 }
1698 """)
1699  self.assertEqual(p.dumpPython(),
1700 """import FWCore.ParameterSet.Config as cms
1701 
1702 process = cms.Process("Test")
1703 
1704 process.juicer = cms.ESProducer("JuicerProducer")
1705 
1706 
1707 process.ForceSource = cms.ESSource("ForceSource")
1708 
1709 
1710 process.prefer("ForceSource")
1711 
1712 process.prefer("juicer",
1713  fooRcd = cms.vstring('Foo')
1714 )
1715 
1716 """)
1717 
1718  def testFreeze(self):
1719  process = Process("Freeze")
1720  m = EDProducer("M", p=PSet(i = int32(1)))
1721  m.p.i = 2
1722  process.m = m
1723  # should be frozen
1724  #self.assertRaises(ValueError, setattr, m.p, 'i', 3)
1725  #self.assertRaises(ValueError, setattr, m, 'p', PSet(i=int32(1)))
1726  #self.assertRaises(ValueError, setattr, m.p, 'j', 1)
1727  #self.assertRaises(ValueError, setattr, m, 'j', 1)
1728  # But OK to change through the process
1729  process.m.p.i = 4
1730  self.assertEqual(process.m.p.i.value(), 4)
1731  process.m.p = PSet(j=int32(1))
1732  # should work to clone it, though
1733  m2 = m.clone(p = PSet(i = int32(5)), j = int32(8))
1734  m2.p.i = 6
1735  m2.j = 8
1736  def testSubProcess(self):
1737  process = Process("Parent")
1738  subProcess = Process("Child")
1739  subProcess.a = EDProducer("A")
1740  subProcess.p = Path(subProcess.a)
1741  subProcess.add_(Service("Foo"))
1742  process.add_( SubProcess(subProcess) )
1743  d = process.dumpPython()
1744  equalD ="""import FWCore.ParameterSet.Config as cms
1745 
1746 process = cms.Process("Parent")
1747 
1748 parentProcess = process
1749 import FWCore.ParameterSet.Config as cms
1750 
1751 process = cms.Process("Child")
1752 
1753 process.a = cms.EDProducer("A")
1754 
1755 
1756 process.p = cms.Path(process.a)
1757 
1758 
1759 process.Foo = cms.Service("Foo")
1760 
1761 
1762 childProcess = process
1763 process = parentProcess
1764 process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = cms.untracked.PSet(
1765 
1766 ), outputCommands = cms.untracked.vstring())
1767 """
1768  equalD = equalD.replace("parentProcess","parentProcess"+str(hash(process.subProcess)))
1769  self.assertEqual(d,equalD)
1770  p = TestMakePSet()
1771  process.subProcess.insertInto(p,"dummy")
1772  self.assertEqual((True,['a']),p.values["@sub_process"][1].values["process"][1].values['@all_modules'])
1773  self.assertEqual((True,['p']),p.values["@sub_process"][1].values["process"][1].values['@paths'])
1774  self.assertEqual({'@service_type':(True,'Foo')}, p.values["@sub_process"][1].values["process"][1].values["services"][1][0].values)
1775  def testRefToPSet(self):
1776  proc = Process("test")
1777  proc.top = PSet(a = int32(1))
1778  proc.ref = PSet(refToPSet_ = string("top"))
1779  proc.ref2 = PSet( a = int32(1), b = PSet( refToPSet_ = string("top")))
1780  proc.ref3 = PSet(refToPSet_ = string("ref"))
1781  proc.ref4 = VPSet(PSet(refToPSet_ = string("top")),
1782  PSet(refToPSet_ = string("ref2")))
1783  p = TestMakePSet()
1784  proc.fillProcessDesc(p)
1785  self.assertEqual((True,1),p.values["ref"][1].values["a"])
1786  self.assertEqual((True,1),p.values["ref3"][1].values["a"])
1787  self.assertEqual((True,1),p.values["ref2"][1].values["a"])
1788  self.assertEqual((True,1),p.values["ref2"][1].values["b"][1].values["a"])
1789  self.assertEqual((True,1),p.values["ref4"][1][0].values["a"])
1790  self.assertEqual((True,1),p.values["ref4"][1][1].values["a"])
1791  def testPrune(self):
1792  p = Process("test")
1793  p.a = EDAnalyzer("MyAnalyzer")
1794  p.b = EDAnalyzer("YourAnalyzer")
1795  p.c = EDAnalyzer("OurAnalyzer")
1796  p.d = EDAnalyzer("OurAnalyzer")
1797  p.s = Sequence(p.d)
1798  p.path1 = Path(p.a)
1799  p.path2 = Path(p.b)
1800  self.assert_(p.schedule is None)
1801  pths = p.paths
1802  keys = pths.keys()
1803  self.assertEqual(pths[keys[0]],p.path1)
1804  self.assertEqual(pths[keys[1]],p.path2)
1805  p.pset1 = PSet(parA = string("pset1"))
1806  p.pset2 = untracked.PSet(parA = string("pset2"))
1807  p.vpset1 = VPSet()
1808  p.vpset2 = untracked.VPSet()
1809  p.prune()
1810  self.assert_(hasattr(p, 'a'))
1811  self.assert_(hasattr(p, 'b'))
1812  self.assert_(not hasattr(p, 'c'))
1813  self.assert_(not hasattr(p, 'd'))
1814  self.assert_(not hasattr(p, 's'))
1815  self.assert_(hasattr(p, 'path1'))
1816  self.assert_(hasattr(p, 'path2'))
1817 # self.assert_(not hasattr(p, 'pset1'))
1818 # self.assert_(hasattr(p, 'pset2'))
1819 # self.assert_(not hasattr(p, 'vpset1'))
1820 # self.assert_(not hasattr(p, 'vpset2'))
1821 
1822  p = Process("test")
1823  p.a = EDAnalyzer("MyAnalyzer")
1824  p.b = EDAnalyzer("YourAnalyzer")
1825  p.c = EDAnalyzer("OurAnalyzer")
1826  p.d = EDAnalyzer("OurAnalyzer")
1827  p.e = EDAnalyzer("OurAnalyzer")
1828  p.s = Sequence(p.d)
1829  p.s2 = Sequence(p.b)
1830  p.s3 = Sequence(p.e)
1831  p.path1 = Path(p.a)
1832  p.path2 = Path(p.b)
1833  p.path3 = Path(p.b+p.s2)
1834  p.path4 = Path(p.b+p.s3)
1835  p.schedule = Schedule(p.path1,p.path2,p.path3)
1836  pths = p.paths
1837  keys = pths.keys()
1838  self.assertEqual(pths[keys[0]],p.path1)
1839  self.assertEqual(pths[keys[1]],p.path2)
1840  p.prune()
1841  self.assert_(hasattr(p, 'a'))
1842  self.assert_(hasattr(p, 'b'))
1843  self.assert_(not hasattr(p, 'c'))
1844  self.assert_(not hasattr(p, 'd'))
1845  self.assert_(not hasattr(p, 'e'))
1846  self.assert_(not hasattr(p, 's'))
1847  self.assert_(hasattr(p, 's2'))
1848  self.assert_(not hasattr(p, 's3'))
1849  self.assert_(hasattr(p, 'path1'))
1850  self.assert_(hasattr(p, 'path2'))
1851  self.assert_(hasattr(p, 'path3'))
1852  self.assert_(not hasattr(p, 'path4'))
1853  #test SequencePlaceholder
1854  p = Process("test")
1855  p.a = EDAnalyzer("MyAnalyzer")
1856  p.b = EDAnalyzer("YourAnalyzer")
1857  p.s = Sequence(SequencePlaceholder("a")+p.b)
1858  p.pth = Path(p.s)
1859  p.prune()
1860  self.assert_(hasattr(p, 'a'))
1861  self.assert_(hasattr(p, 'b'))
1862  self.assert_(hasattr(p, 's'))
1863  self.assert_(hasattr(p, 'pth'))
1864  def testModifier(self):
1865  m1 = Modifier()
1866  p = Process("test",m1)
1867  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1868  def _mod_fred(obj):
1869  obj.fred = 2
1870  m1.toModify(p.a,_mod_fred)
1871  self.assertEqual(p.a.fred.value(),2)
1872  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1873  m1.toModify(p.b, wilma = 2)
1874  self.assertEqual(p.b.wilma.value(),2)
1875  #check that Modifier not attached to a process doesn't run
1876  m1 = Modifier()
1877  p = Process("test")
1878  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1879  m1.toModify(p.a,_mod_fred)
1880  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1881  m1.toModify(p.b, wilma = 2)
1882  self.assertEqual(p.a.fred.value(),1)
1883  self.assertEqual(p.b.wilma.value(),1)
1884  #make sure clones get the changes
1885  m1 = Modifier()
1886  p = Process("test",m1)
1887  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
1888  m1.toModify(p.a, fred = int32(2))
1889  p.b = p.a.clone(wilma = int32(3))
1890  self.assertEqual(p.a.fred.value(),2)
1891  self.assertEqual(p.a.wilma.value(),1)
1892  self.assertEqual(p.b.fred.value(),2)
1893  self.assertEqual(p.b.wilma.value(),3)
1894  #test that load causes process wide methods to run
1895  def _rem_a(proc):
1896  del proc.a
1897  class ProcModifierMod(object):
1898  def __init__(self,modifier,func):
1899  self.proc_mod_ = modifier.makeProcessModifier(func)
1900  class DummyMod(object):
1901  def __init__(self):
1902  self.a = EDAnalyzer("Dummy")
1903  testMod = DummyMod()
1904  p.extend(testMod)
1905  self.assert_(hasattr(p,"a"))
1906  m1 = Modifier()
1907  p = Process("test",m1)
1908  testProcMod = ProcModifierMod(m1,_rem_a)
1909  p.extend(testMod)
1910  p.extend(testProcMod)
1911  self.assert_(not hasattr(p,"a"))
1912  #test ModifierChain
1913  m1 = Modifier()
1914  mc = ModifierChain(m1)
1915  p = Process("test",mc)
1916  testMod = DummyMod()
1917  p.b = EDAnalyzer("Dummy2", fred = int32(1))
1918  m1.toModify(p.b, fred = int32(3))
1919  p.extend(testMod)
1920  testProcMod = ProcModifierMod(m1,_rem_a)
1921  p.extend(testProcMod)
1922  self.assert_(not hasattr(p,"a"))
1923  self.assertEqual(p.b.fred.value(),3)
1924 
1925 
1926  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:725
def setSchedule_
Definition: Config.py:233
def subProcess_
Definition: Config.py:199
def _insertManyInto
Definition: Config.py:750
def __delattr__
Definition: Config.py:390
def _validateSequence
Definition: Config.py:651
def _dumpConfigUnnamedList
Definition: Config.py:564
def _placeEndPath
Definition: Config.py:469
def setSource_
Definition: Config.py:190
def _findPreferred
Definition: Config.py:955
def es_producers_
Definition: Config.py:249
def aliases_
Definition: Config.py:261
def _dumpConfigESPrefers
Definition: Config.py:637
def _placeSequence
Definition: Config.py:476
def _dumpConfigOptionallyNamedList
Definition: Config.py:569
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:696
def es_prefers_
Definition: Config.py:257
def _placePath
Definition: Config.py:462
def _insertPaths
Definition: Config.py:759
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:659
def outputModules_
Definition: Config.py:209
def producers_
Definition: Config.py:183
def __findFirstSequenceUsingModule
Definition: Config.py:379
def fillProcessDesc
Definition: Config.py:862
def __init__
Definition: Config.py:102
def _insertInto
Definition: Config.py:740
def analyzers_
Definition: Config.py:205
def addLuminosityBlockID
Definition: Config.py:1206
def _placeVPSet
Definition: Config.py:489
def setPartialSchedule_
Definition: Config.py:228
def setStrict
Definition: Config.py:137
def globalReplace
Definition: Config.py:734
def __setattr__
Definition: Config.py:301
def _placeLooper
Definition: Config.py:499
def dumpConfig
Definition: Config.py:576
def nameInProcessDesc_
Definition: Config.py:1061
def services_
Definition: Config.py:245
def validate
Definition: Config.py:919
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:1128
def __setstate__
Definition: Config.py:155
def analyzerNames
Definition: Config.py:145
def _placeAnalyzer
Definition: Config.py:460
def _pruneModules
Definition: Config.py:855
def _placeAlias
Definition: Config.py:485
def _insertOneInto
Definition: Config.py:743
def _dumpConfigNamedList
Definition: Config.py:559
list object
Definition: dbtoconf.py:77
def pathNames
Definition: Config.py:151
def _placeFilter
Definition: Config.py:458
def _dumpPythonList
Definition: Config.py:642
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 makeProcessModifier
Definition: Config.py:1094
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:691
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