CMS 3D CMS Logo

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