CMS 3D CMS Logo

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