CMS 3D CMS Logo

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