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 type_(self):
1062  return 'subProcess'
1063  def nameInProcessDesc_(self,label):
1064  return '@sub_process'
1065  def _place(self,label,process):
1066  process._placeSubProcess('subProcess',self)
1067  def insertInto(self,parameterSet, newlabel):
1068  topPSet = parameterSet.newPSet()
1069  self.__process.fillProcessDesc(topPSet)
1070  subProcessPSet = parameterSet.newPSet()
1071  self.__SelectEvents.insertInto(subProcessPSet,"SelectEvents")
1072  self.__outputCommands.insertInto(subProcessPSet,"outputCommands")
1073  subProcessPSet.addPSet(False,"process",topPSet)
1074  parameterSet.addPSet(False,self.nameInProcessDesc_("subProcess"), subProcessPSet)
1075 
1077  """Helper class for Modifier which takes key/value pairs and uses them to reset parameters of the object"""
1078  def __init__(self,args):
1079  self.__args = args
1080  def __call__(self,obj):
1081  for k,v in self.__args.iteritems():
1082  setattr(obj,k,v)
1083 
1085  """This class is used to define standard modifications to a Process.
1086  An instance of this class is declared to denote a specific modification,e.g. era2017 could
1087  reconfigure items in a process to match our expectation of running in 2017. Once declared,
1088  these Modifier instances are imported into a configuration and items which need to be modified
1089  are then associated with the Modifier and with the action to do the modification.
1090  The registered modifications will only occur if the Modifier was passed to
1091  the cms.Process' constructor.
1092  """
1093  def __init__(self):
1095  self.__chosen = False
1096  def makeProcessModifier(self,func):
1097  """This is used to create a ProcessModifer which can perform actions on the process as a whole.
1098  This takes as argument a callable object (e.g. function) which takes as its sole argument an instance of Process.
1099  In order to work, the value returned from this function must be assigned to a uniquely named variable.
1100  """
1101  return ProcessModifier(self,func)
1102  def toModify(self,obj, func=None,**kw):
1103  """This is used to register an action to be performed on the specific object. Two different forms are allowed
1104  Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1105  which will be the object passed in as the first argument.
1106  Form 2: A list of parameter name, value pairs can be passed
1107  mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1108  """
1109  if func is not None and len(kw) != 0:
1110  raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
1111  if not self.isChosen():
1112  return
1113  if func is not None:
1114  func(obj)
1115  else:
1116  temp =_ParameterModifier(kw)
1117  temp(obj)
1118  def _setChosen(self):
1119  """Should only be called by cms.Process instances"""
1120  self.__chosen = True
1121  def isChosen(self):
1122  return self.__chosen
1123 
1125  """A Modifier made up of a list of Modifiers
1126  """
1127  def __init__(self, *chainedModifiers):
1128  self.__chosen = False
1129  self.__chain = chainedModifiers
1130  def _applyNewProcessModifiers(self,process):
1131  """Should only be called by cms.Process instances
1132  applies list of accumulated changes to the process"""
1133  for m in self.__chain:
1134  m._applyNewProcessModifiers(process)
1135  def _setChosen(self):
1136  """Should only be called by cms.Process instances"""
1137  self.__chosen = True
1138  for m in self.__chain:
1139  m._setChosen()
1140  def isChosen(self):
1141  return self.__chosen
1142 
1144  """A class used by a Modifier to affect an entire Process instance.
1145  When a Process 'loads' a module containing a ProcessModifier, that
1146  ProcessModifier will be applied to the Process if and only if the
1147  Modifier passed to the constructor has been chosen.
1148  """
1149  def __init__(self, modifier, func):
1150  self.__modifier = modifier
1151  self.__func = func
1152  self.__seenProcesses = set()
1153  def apply(self,process):
1154  if self.__modifier.isChosen():
1155  if process not in self.__seenProcesses:
1156  self.__func(process)
1157  self.__seenProcesses.add(process)
1158 
1159 if __name__=="__main__":
1160  import unittest
1161  import copy
1162 
1164  """Has same interface as the C++ object which creates PSets
1165  """
1166  def __init__(self):
1167  self.values = dict()
1168  def __insertValue(self,tracked,label,value):
1169  self.values[label]=(tracked,value)
1170  def addInt32(self,tracked,label,value):
1171  self.__insertValue(tracked,label,value)
1172  def addVInt32(self,tracked,label,value):
1173  self.__insertValue(tracked,label,value)
1174  def addUInt32(self,tracked,label,value):
1175  self.__insertValue(tracked,label,value)
1176  def addVUInt32(self,tracked,label,value):
1177  self.__insertValue(tracked,label,value)
1178  def addInt64(self,tracked,label,value):
1179  self.__insertValue(tracked,label,value)
1180  def addVInt64(self,tracked,label,value):
1181  self.__insertValue(tracked,label,value)
1182  def addUInt64(self,tracked,label,value):
1183  self.__insertValue(tracked,label,value)
1184  def addVUInt64(self,tracked,label,value):
1185  self.__insertValue(tracked,label,value)
1186  def addDouble(self,tracked,label,value):
1187  self.__insertValue(tracked,label,value)
1188  def addVDouble(self,tracked,label,value):
1189  self.__insertValue(tracked,label,value)
1190  def addBool(self,tracked,label,value):
1191  self.__insertValue(tracked,label,value)
1192  def addString(self,tracked,label,value):
1193  self.__insertValue(tracked,label,value)
1194  def addVString(self,tracked,label,value):
1195  self.__insertValue(tracked,label,value)
1196  def addInputTag(self,tracked,label,value):
1197  self.__insertValue(tracked,label,value)
1198  def addVInputTag(self,tracked,label,value):
1199  self.__insertValue(tracked,label,value)
1200  def addESInputTag(self,tracked,label,value):
1201  self.__insertValue(tracked,label,value)
1202  def addVESInputTag(self,tracked,label,value):
1203  self.__insertValue(tracked,label,value)
1204  def addEventID(self,tracked,label,value):
1205  self.__insertValue(tracked,label,value)
1206  def addVEventID(self,tracked,label,value):
1207  self.__insertValue(tracked,label,value)
1208  def addLuminosityBlockID(self,tracked,label,value):
1209  self.__insertValue(tracked,label,value)
1210  def addLuminosityBlockID(self,tracked,label,value):
1211  self.__insertValue(tracked,label,value)
1212  def addEventRange(self,tracked,label,value):
1213  self.__insertValue(tracked,label,value)
1214  def addVEventRange(self,tracked,label,value):
1215  self.__insertValue(tracked,label,value)
1216  def addPSet(self,tracked,label,value):
1217  self.__insertValue(tracked,label,value)
1218  def addVPSet(self,tracked,label,value):
1219  self.__insertValue(tracked,label,value)
1220  def addFileInPath(self,tracked,label,value):
1221  self.__insertValue(tracked,label,value)
1222  def newPSet(self):
1223  return TestMakePSet()
1224 
1225  class TestModuleCommand(unittest.TestCase):
1226  def setUp(self):
1227  """Nothing to do """
1228  None
1230  p = _Parameterizable()
1231  self.assertEqual(len(p.parameterNames_()),0)
1232  p.a = int32(1)
1233  self.assert_('a' in p.parameterNames_())
1234  self.assertEqual(p.a.value(), 1)
1235  p.a = 10
1236  self.assertEqual(p.a.value(), 10)
1237  p.a = untracked(int32(1))
1238  self.assertEqual(p.a.value(), 1)
1239  self.failIf(p.a.isTracked())
1240  p.a = untracked.int32(1)
1241  self.assertEqual(p.a.value(), 1)
1242  self.failIf(p.a.isTracked())
1243  p = _Parameterizable(foo=int32(10), bar = untracked(double(1.0)))
1244  self.assertEqual(p.foo.value(), 10)
1245  self.assertEqual(p.bar.value(),1.0)
1246  self.failIf(p.bar.isTracked())
1247  self.assertRaises(TypeError,setattr,(p,'c',1))
1248  p = _Parameterizable(a=PSet(foo=int32(10), bar = untracked(double(1.0))))
1249  self.assertEqual(p.a.foo.value(),10)
1250  self.assertEqual(p.a.bar.value(),1.0)
1251  p.b = untracked(PSet(fii = int32(1)))
1252  self.assertEqual(p.b.fii.value(),1)
1253  self.failIf(p.b.isTracked())
1254  #test the fact that values can be shared
1255  v = int32(10)
1256  p=_Parameterizable(a=v)
1257  v.setValue(11)
1258  self.assertEqual(p.a.value(),11)
1259  p.a = 12
1260  self.assertEqual(p.a.value(),12)
1261  self.assertEqual(v.value(),12)
1263  p = _TypedParameterizable("blah", b=int32(1))
1264  #see if copy works deeply
1265  other = p.copy()
1266  other.b = 2
1267  self.assertNotEqual(p.b,other.b)
1268 
1270  p = Process("test")
1271  p.a = EDAnalyzer("MyAnalyzer")
1272  self.assert_( 'a' in p.analyzers_() )
1273  self.assert_( 'a' in p.analyzers)
1274  p.add_(Service("MessageLogger"))
1275  self.assert_('MessageLogger' in p.services_())
1276  self.assertEqual(p.MessageLogger.type_(), "MessageLogger")
1277  p.Tracer = Service("Tracer")
1278  self.assert_('Tracer' in p.services_())
1279  self.assertRaises(TypeError, setattr, *(p,'b',"this should fail"))
1280  self.assertRaises(TypeError, setattr, *(p,'bad',Service("MessageLogger")))
1281  self.assertRaises(ValueError, setattr, *(p,'bad',Source("PoolSource")))
1282  p.out = OutputModule("Outer")
1283  self.assertEqual(p.out.type_(), 'Outer')
1284  self.assert_( 'out' in p.outputModules_() )
1285 
1286  p.geom = ESSource("GeomProd")
1287  self.assert_('geom' in p.es_sources_())
1288  p.add_(ESSource("ConfigDB"))
1289  self.assert_('ConfigDB' in p.es_sources_())
1290 
1291  p.aliasfoo1 = EDAlias(foo1 = VPSet(PSet(type = string("Foo1"))))
1292  self.assert_('aliasfoo1' in p.aliases_())
1293 
1295  class FromArg(object):
1296  def __init__(self,*arg,**args):
1297  for name in args.iterkeys():
1298  self.__dict__[name]=args[name]
1299 
1300  a=EDAnalyzer("MyAnalyzer")
1301  t=EDAnalyzer("MyAnalyzer")
1302  t.setLabel("foo")
1303  s1 = Sequence(a)
1304  s2 = Sequence(s1)
1305  s3 = Sequence(s2)
1306  d = FromArg(
1307  a=a,
1308  b=Service("Full"),
1309  c=Path(a),
1310  d=s2,
1311  e=s1,
1312  f=s3,
1313  g=Sequence(s1+s2+s3)
1314  )
1315  p = Process("Test")
1316  p.extend(d)
1317  self.assertEqual(p.a.type_(),"MyAnalyzer")
1318  self.assertEqual(p.a.label_(),"a")
1319  self.assertRaises(AttributeError,getattr,p,'b')
1320  self.assertEqual(p.Full.type_(),"Full")
1321  self.assertEqual(str(p.c),'a')
1322  self.assertEqual(str(p.d),'a')
1323 
1324  z1 = FromArg(
1325  a=a,
1326  b=Service("Full"),
1327  c=Path(a),
1328  d=s2,
1329  e=s1,
1330  f=s3,
1331  s4=s3,
1332  g=Sequence(s1+s2+s3)
1333  )
1334 
1335  p1 = Process("Test")
1336  #p1.extend(z1)
1337  self.assertRaises(ValueError, p1.extend, z1)
1338 
1339  z2 = FromArg(
1340  a=a,
1341  b=Service("Full"),
1342  c=Path(a),
1343  d=s2,
1344  e=s1,
1345  f=s3,
1346  aaa=copy.deepcopy(a),
1347  s4=copy.deepcopy(s3),
1348  g=Sequence(s1+s2+s3),
1349  t=t
1350  )
1351  p2 = Process("Test")
1352  p2.extend(z2)
1353  #self.assertRaises(ValueError, p2.extend, z2)
1354  self.assertEqual(p2.s4.label_(),"s4")
1355  #p2.s4.setLabel("foo")
1356  self.assertRaises(ValueError, p2.s4.setLabel, "foo")
1357  p2.s4.setLabel("s4")
1358  p2.s4.setLabel(None)
1359  p2.s4.setLabel("foo")
1360  p2._Process__setObjectLabel(p2.s4, "foo")
1361  p2._Process__setObjectLabel(p2.s4, None)
1362  p2._Process__setObjectLabel(p2.s4, "bar")
1363 
1365  p = Process("test")
1366  p.a = EDAnalyzer("MyAnalyzer")
1367  p.p = Path(p.a)
1368  p.s = Sequence(p.a)
1369  p.r = Sequence(p.s)
1370  p.p2 = Path(p.s)
1371  p.schedule = Schedule(p.p2,p.p)
1372  d=p.dumpPython()
1373  self.assertEqual(d,
1374 """import FWCore.ParameterSet.Config as cms
1375 
1376 process = cms.Process("test")
1377 
1378 process.a = cms.EDAnalyzer("MyAnalyzer")
1379 
1380 
1381 process.s = cms.Sequence(process.a)
1382 
1383 
1384 process.r = cms.Sequence(process.s)
1385 
1386 
1387 process.p = cms.Path(process.a)
1388 
1389 
1390 process.p2 = cms.Path(process.s)
1391 
1392 
1393 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1394 """)
1395  #Reverse order of 'r' and 's'
1396  p = Process("test")
1397  p.a = EDAnalyzer("MyAnalyzer")
1398  p.p = Path(p.a)
1399  p.r = Sequence(p.a)
1400  p.s = Sequence(p.r)
1401  p.p2 = Path(p.r)
1402  p.schedule = Schedule(p.p2,p.p)
1403  p.b = EDAnalyzer("YourAnalyzer")
1404  d=p.dumpPython()
1405  self.assertEqual(d,
1406 """import FWCore.ParameterSet.Config as cms
1407 
1408 process = cms.Process("test")
1409 
1410 process.a = cms.EDAnalyzer("MyAnalyzer")
1411 
1412 
1413 process.b = cms.EDAnalyzer("YourAnalyzer")
1414 
1415 
1416 process.r = cms.Sequence(process.a)
1417 
1418 
1419 process.s = cms.Sequence(process.r)
1420 
1421 
1422 process.p = cms.Path(process.a)
1423 
1424 
1425 process.p2 = cms.Path(process.r)
1426 
1427 
1428 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1429 """)
1430  #use an anonymous sequence
1431  p = Process("test")
1432  p.a = EDAnalyzer("MyAnalyzer")
1433  p.p = Path(p.a)
1434  s = Sequence(p.a)
1435  p.r = Sequence(s)
1436  p.p2 = Path(p.r)
1437  p.schedule = Schedule(p.p2,p.p)
1438  d=p.dumpPython()
1439  self.assertEqual(d,
1440  """import FWCore.ParameterSet.Config as cms
1441 
1442 process = cms.Process("test")
1443 
1444 process.a = cms.EDAnalyzer("MyAnalyzer")
1445 
1446 
1447 process.r = cms.Sequence((process.a))
1448 
1449 
1450 process.p = cms.Path(process.a)
1451 
1452 
1453 process.p2 = cms.Path(process.r)
1454 
1455 
1456 process.schedule = cms.Schedule(*[ process.p2, process.p ])
1457 """)
1458 
1459  def testSecSource(self):
1460  p = Process('test')
1461  p.a = SecSource("MySecSource")
1462  self.assertEqual(p.dumpPython().replace('\n',''),'import FWCore.ParameterSet.Config as cmsprocess = cms.Process("test")process.a = cms.SecSource("MySecSource")')
1463 
1465  p = Process('test')
1466  p.a = EDAnalyzer("MyAnalyzer")
1467  p.b = EDAnalyzer("YourAnalyzer")
1468  p.c = EDAnalyzer("OurAnalyzer")
1469  p.s = Sequence(p.a*p.b)
1470  p.p = Path(p.c+p.s+p.a)
1471  new = EDAnalyzer("NewAnalyzer")
1472  p.globalReplace("a",new)
1473 
1474  def testSequence(self):
1475  p = Process('test')
1476  p.a = EDAnalyzer("MyAnalyzer")
1477  p.b = EDAnalyzer("YourAnalyzer")
1478  p.c = EDAnalyzer("OurAnalyzer")
1479  p.s = Sequence(p.a*p.b)
1480  self.assertEqual(str(p.s),'a+b')
1481  self.assertEqual(p.s.label_(),'s')
1482  path = Path(p.c+p.s)
1483  self.assertEqual(str(path),'c+a+b')
1484  p._validateSequence(path, 'p1')
1485  notInProcess = EDAnalyzer('NotInProcess')
1486  p2 = Path(p.c+p.s*notInProcess)
1487  self.assertRaises(RuntimeError, p._validateSequence, p2, 'p2')
1488 
1489  def testSequence2(self):
1490  p = Process('test')
1491  p.a = EDAnalyzer("MyAnalyzer")
1492  p.b = EDAnalyzer("YourAnalyzer")
1493  p.c = EDAnalyzer("OurAnalyzer")
1494  testseq = Sequence(p.a*p.b)
1495  p.s = testseq
1496  #p.y = testseq
1497  self.assertRaises(ValueError, p.__setattr__, "y", testseq)
1498 
1499  def testPath(self):
1500  p = Process("test")
1501  p.a = EDAnalyzer("MyAnalyzer")
1502  p.b = EDAnalyzer("YourAnalyzer")
1503  p.c = EDAnalyzer("OurAnalyzer")
1504  path = Path(p.a)
1505  path *= p.b
1506  path += p.c
1507  self.assertEqual(str(path),'a+b+c')
1508  path = Path(p.a*p.b+p.c)
1509  self.assertEqual(str(path),'a+b+c')
1510 # path = Path(p.a)*p.b+p.c #This leads to problems with sequences
1511 # self.assertEqual(str(path),'((a*b)+c)')
1512  path = Path(p.a+ p.b*p.c)
1513  self.assertEqual(str(path),'a+b+c')
1514  path = Path(p.a*(p.b+p.c))
1515  self.assertEqual(str(path),'a+b+c')
1516  path = Path(p.a*(p.b+~p.c))
1517  self.assertEqual(str(path),'a+b+~c')
1518  p.es = ESProducer("AnESProducer")
1519  self.assertRaises(TypeError,Path,p.es)
1520 
1522  p = Process("test")
1523  a = EDAnalyzer("MyAnalyzer")
1524  p.a = a
1525  a.setLabel("a")
1526  b = EDAnalyzer("YOurAnalyzer")
1527  p.b = b
1528  b.setLabel("b")
1529  path = Path(a * b)
1530  p.path = Path(p.a*p.b)
1531  lookuptable = {id(a): p.a, id(b): p.b}
1532  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1533  #lookuptable = p._cloneToObjectDict
1534  #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
1535  self.assertEqual(str(path),str(p.path))
1536 
1537  def testSchedule(self):
1538  p = Process("test")
1539  p.a = EDAnalyzer("MyAnalyzer")
1540  p.b = EDAnalyzer("YourAnalyzer")
1541  p.c = EDAnalyzer("OurAnalyzer")
1542  p.d = EDAnalyzer("OurAnalyzer")
1543  p.path1 = Path(p.a)
1544  p.path2 = Path(p.b)
1545  p.path3 = Path(p.d)
1546 
1547  s = Schedule(p.path1,p.path2)
1548  self.assertEqual(s[0],p.path1)
1549  self.assertEqual(s[1],p.path2)
1550  p.schedule = s
1551  self.assert_('b' in p.schedule.moduleNames())
1552  self.assert_(hasattr(p, 'b'))
1553  self.assert_(hasattr(p, 'c'))
1554  self.assert_(hasattr(p, 'd'))
1555  self.assert_(hasattr(p, 'path1'))
1556  self.assert_(hasattr(p, 'path2'))
1557  self.assert_(hasattr(p, 'path3'))
1558  p.prune()
1559  self.assert_('b' in p.schedule.moduleNames())
1560  self.assert_(hasattr(p, 'b'))
1561  self.assert_(not hasattr(p, 'c'))
1562  self.assert_(not hasattr(p, 'd'))
1563  self.assert_(hasattr(p, 'path1'))
1564  self.assert_(hasattr(p, 'path2'))
1565  self.assert_(not hasattr(p, 'path3'))
1566 
1567  #adding a path not attached to the Process should cause an exception
1568  p = Process("test")
1569  p.a = EDAnalyzer("MyAnalyzer")
1570  path1 = Path(p.a)
1571  s = Schedule(path1)
1572  self.assertRaises(RuntimeError, lambda : p.setSchedule_(s) )
1573 
1574  #make sure anonymous sequences work
1575  p = Process("test")
1576  p.a = EDAnalyzer("MyAnalyzer")
1577  p.b = EDAnalyzer("MyOtherAnalyzer")
1578  p.c = EDProducer("MyProd")
1579  path1 = Path(p.c*Sequence(p.a+p.b))
1580  s = Schedule(path1)
1581  self.assert_('a' in s.moduleNames())
1582  self.assert_('b' in s.moduleNames())
1583  self.assert_('c' in s.moduleNames())
1584  p.path1 = path1
1585  p.schedule = s
1586  p.prune()
1587  self.assert_('a' in s.moduleNames())
1588  self.assert_('b' in s.moduleNames())
1589  self.assert_('c' in s.moduleNames())
1590 
1592  p = Process("test")
1593  p.a = EDAnalyzer("MyAnalyzer")
1594  p.b = EDAnalyzer("YourAnalyzer")
1595  p.c = EDAnalyzer("OurAnalyzer")
1596  p.path1 = Path(p.a)
1597  p.path2 = Path(p.b)
1598  self.assert_(p.schedule is None)
1599  pths = p.paths
1600  keys = pths.keys()
1601  self.assertEqual(pths[keys[0]],p.path1)
1602  self.assertEqual(pths[keys[1]],p.path2)
1603  p.prune()
1604  self.assert_(hasattr(p, 'a'))
1605  self.assert_(hasattr(p, 'b'))
1606  self.assert_(not hasattr(p, 'c'))
1607  self.assert_(hasattr(p, 'path1'))
1608  self.assert_(hasattr(p, 'path2'))
1609 
1610 
1611  p = Process("test")
1612  p.a = EDAnalyzer("MyAnalyzer")
1613  p.b = EDAnalyzer("YourAnalyzer")
1614  p.c = EDAnalyzer("OurAnalyzer")
1615  p.path2 = Path(p.b)
1616  p.path1 = Path(p.a)
1617  self.assert_(p.schedule is None)
1618  pths = p.paths
1619  keys = pths.keys()
1620  self.assertEqual(pths[keys[1]],p.path1)
1621  self.assertEqual(pths[keys[0]],p.path2)
1622 
1623 
1624  def testUsing(self):
1625  p = Process('test')
1626  p.block = PSet(a = int32(1))
1627  p.modu = EDAnalyzer('Analyzer', p.block, b = int32(2))
1628  self.assertEqual(p.modu.a.value(),1)
1629  self.assertEqual(p.modu.b.value(),2)
1630 
1631  def testOverride(self):
1632  p = Process('test')
1633  a = EDProducer("A", a1=int32(0))
1634  self.assert_(not a.isModified())
1635  a.a1 = 1
1636  self.assert_(a.isModified())
1637  p.a = a
1638  self.assertEqual(p.a.a1.value(), 1)
1639  # try adding an unmodified module.
1640  # should accept it
1641  p.a = EDProducer("A", a1=int32(2))
1642  self.assertEqual(p.a.a1.value(), 2)
1643  # try adding a modified module. Should throw
1644  # no longer, since the same (modified) say, geometry
1645  # could come from more than one cff
1646  b = EDProducer("A", a1=int32(3))
1647  b.a1 = 4
1648  #self.assertRaises(RuntimeError, setattr, *(p,'a',b))
1649  ps1 = PSet(a = int32(1))
1650  ps2 = PSet(a = int32(2))
1651  self.assertRaises(ValueError, EDProducer, 'C', ps1, ps2)
1652  self.assertRaises(ValueError, EDProducer, 'C', ps1, a=int32(3))
1653 
1654  def testExamples(self):
1655  p = Process("Test")
1656  p.source = Source("PoolSource",fileNames = untracked(string("file:reco.root")))
1657  p.foos = EDProducer("FooProducer")
1658  p.bars = EDProducer("BarProducer", foos=InputTag("foos"))
1659  p.out = OutputModule("PoolOutputModule",fileName=untracked(string("file:foos.root")))
1660  p.bars.foos = 'Foosball'
1661  self.assertEqual(p.bars.foos, InputTag('Foosball'))
1662  p.p = Path(p.foos*p.bars)
1663  p.e = EndPath(p.out)
1664  p.add_(Service("MessageLogger"))
1665 
1666  def testPrefers(self):
1667  p = Process("Test")
1668  p.add_(ESSource("ForceSource"))
1669  p.juicer = ESProducer("JuicerProducer")
1670  p.prefer("ForceSource")
1671  p.prefer("juicer")
1672  self.assertEqual(p.dumpConfig(),
1673 """process Test = {
1674  es_module juicer = JuicerProducer {
1675  }
1676  es_source = ForceSource {
1677  }
1678  es_prefer = ForceSource {
1679  }
1680  es_prefer juicer = JuicerProducer {
1681  }
1682 }
1683 """)
1684  p.prefer("juicer",fooRcd=vstring("Foo"))
1685  self.assertEqual(p.dumpConfig(),
1686 """process Test = {
1687  es_module juicer = JuicerProducer {
1688  }
1689  es_source = ForceSource {
1690  }
1691  es_prefer = ForceSource {
1692  }
1693  es_prefer juicer = JuicerProducer {
1694  vstring fooRcd = {
1695  'Foo'
1696  }
1697 
1698  }
1699 }
1700 """)
1701  self.assertEqual(p.dumpPython(),
1702 """import FWCore.ParameterSet.Config as cms
1703 
1704 process = cms.Process("Test")
1705 
1706 process.juicer = cms.ESProducer("JuicerProducer")
1707 
1708 
1709 process.ForceSource = cms.ESSource("ForceSource")
1710 
1711 
1712 process.prefer("ForceSource")
1713 
1714 process.prefer("juicer",
1715  fooRcd = cms.vstring('Foo')
1716 )
1717 
1718 """)
1719 
1720  def testFreeze(self):
1721  process = Process("Freeze")
1722  m = EDProducer("M", p=PSet(i = int32(1)))
1723  m.p.i = 2
1724  process.m = m
1725  # should be frozen
1726  #self.assertRaises(ValueError, setattr, m.p, 'i', 3)
1727  #self.assertRaises(ValueError, setattr, m, 'p', PSet(i=int32(1)))
1728  #self.assertRaises(ValueError, setattr, m.p, 'j', 1)
1729  #self.assertRaises(ValueError, setattr, m, 'j', 1)
1730  # But OK to change through the process
1731  process.m.p.i = 4
1732  self.assertEqual(process.m.p.i.value(), 4)
1733  process.m.p = PSet(j=int32(1))
1734  # should work to clone it, though
1735  m2 = m.clone(p = PSet(i = int32(5)), j = int32(8))
1736  m2.p.i = 6
1737  m2.j = 8
1738  def testSubProcess(self):
1739  process = Process("Parent")
1740  subProcess = Process("Child")
1741  subProcess.a = EDProducer("A")
1742  subProcess.p = Path(subProcess.a)
1743  subProcess.add_(Service("Foo"))
1744  process.add_( SubProcess(subProcess) )
1745  d = process.dumpPython()
1746  equalD ="""import FWCore.ParameterSet.Config as cms
1747 
1748 process = cms.Process("Parent")
1749 
1750 parentProcess = process
1751 import FWCore.ParameterSet.Config as cms
1752 
1753 process = cms.Process("Child")
1754 
1755 process.a = cms.EDProducer("A")
1756 
1757 
1758 process.p = cms.Path(process.a)
1759 
1760 
1761 process.Foo = cms.Service("Foo")
1762 
1763 
1764 childProcess = process
1765 process = parentProcess
1766 process.subProcess = cms.SubProcess( process = childProcess, SelectEvents = cms.untracked.PSet(
1767 
1768 ), outputCommands = cms.untracked.vstring())
1769 """
1770  equalD = equalD.replace("parentProcess","parentProcess"+str(hash(process.subProcess)))
1771  self.assertEqual(d,equalD)
1772  p = TestMakePSet()
1773  process.subProcess.insertInto(p,"dummy")
1774  self.assertEqual((True,['a']),p.values["@sub_process"][1].values["process"][1].values['@all_modules'])
1775  self.assertEqual((True,['p']),p.values["@sub_process"][1].values["process"][1].values['@paths'])
1776  self.assertEqual({'@service_type':(True,'Foo')}, p.values["@sub_process"][1].values["process"][1].values["services"][1][0].values)
1777  def testRefToPSet(self):
1778  proc = Process("test")
1779  proc.top = PSet(a = int32(1))
1780  proc.ref = PSet(refToPSet_ = string("top"))
1781  proc.ref2 = PSet( a = int32(1), b = PSet( refToPSet_ = string("top")))
1782  proc.ref3 = PSet(refToPSet_ = string("ref"))
1783  proc.ref4 = VPSet(PSet(refToPSet_ = string("top")),
1784  PSet(refToPSet_ = string("ref2")))
1785  p = TestMakePSet()
1786  proc.fillProcessDesc(p)
1787  self.assertEqual((True,1),p.values["ref"][1].values["a"])
1788  self.assertEqual((True,1),p.values["ref3"][1].values["a"])
1789  self.assertEqual((True,1),p.values["ref2"][1].values["a"])
1790  self.assertEqual((True,1),p.values["ref2"][1].values["b"][1].values["a"])
1791  self.assertEqual((True,1),p.values["ref4"][1][0].values["a"])
1792  self.assertEqual((True,1),p.values["ref4"][1][1].values["a"])
1793  def testPrune(self):
1794  p = Process("test")
1795  p.a = EDAnalyzer("MyAnalyzer")
1796  p.b = EDAnalyzer("YourAnalyzer")
1797  p.c = EDAnalyzer("OurAnalyzer")
1798  p.d = EDAnalyzer("OurAnalyzer")
1799  p.s = Sequence(p.d)
1800  p.path1 = Path(p.a)
1801  p.path2 = Path(p.b)
1802  self.assert_(p.schedule is None)
1803  pths = p.paths
1804  keys = pths.keys()
1805  self.assertEqual(pths[keys[0]],p.path1)
1806  self.assertEqual(pths[keys[1]],p.path2)
1807  p.pset1 = PSet(parA = string("pset1"))
1808  p.pset2 = untracked.PSet(parA = string("pset2"))
1809  p.vpset1 = VPSet()
1810  p.vpset2 = untracked.VPSet()
1811  p.prune()
1812  self.assert_(hasattr(p, 'a'))
1813  self.assert_(hasattr(p, 'b'))
1814  self.assert_(not hasattr(p, 'c'))
1815  self.assert_(not hasattr(p, 'd'))
1816  self.assert_(not hasattr(p, 's'))
1817  self.assert_(hasattr(p, 'path1'))
1818  self.assert_(hasattr(p, 'path2'))
1819 # self.assert_(not hasattr(p, 'pset1'))
1820 # self.assert_(hasattr(p, 'pset2'))
1821 # self.assert_(not hasattr(p, 'vpset1'))
1822 # self.assert_(not hasattr(p, 'vpset2'))
1823 
1824  p = Process("test")
1825  p.a = EDAnalyzer("MyAnalyzer")
1826  p.b = EDAnalyzer("YourAnalyzer")
1827  p.c = EDAnalyzer("OurAnalyzer")
1828  p.d = EDAnalyzer("OurAnalyzer")
1829  p.e = EDAnalyzer("OurAnalyzer")
1830  p.s = Sequence(p.d)
1831  p.s2 = Sequence(p.b)
1832  p.s3 = Sequence(p.e)
1833  p.path1 = Path(p.a)
1834  p.path2 = Path(p.b)
1835  p.path3 = Path(p.b+p.s2)
1836  p.path4 = Path(p.b+p.s3)
1837  p.schedule = Schedule(p.path1,p.path2,p.path3)
1838  pths = p.paths
1839  keys = pths.keys()
1840  self.assertEqual(pths[keys[0]],p.path1)
1841  self.assertEqual(pths[keys[1]],p.path2)
1842  p.prune()
1843  self.assert_(hasattr(p, 'a'))
1844  self.assert_(hasattr(p, 'b'))
1845  self.assert_(not hasattr(p, 'c'))
1846  self.assert_(not hasattr(p, 'd'))
1847  self.assert_(not hasattr(p, 'e'))
1848  self.assert_(not hasattr(p, 's'))
1849  self.assert_(hasattr(p, 's2'))
1850  self.assert_(not hasattr(p, 's3'))
1851  self.assert_(hasattr(p, 'path1'))
1852  self.assert_(hasattr(p, 'path2'))
1853  self.assert_(hasattr(p, 'path3'))
1854  self.assert_(not hasattr(p, 'path4'))
1855  #test SequencePlaceholder
1856  p = Process("test")
1857  p.a = EDAnalyzer("MyAnalyzer")
1858  p.b = EDAnalyzer("YourAnalyzer")
1859  p.s = Sequence(SequencePlaceholder("a")+p.b)
1860  p.pth = Path(p.s)
1861  p.prune()
1862  self.assert_(hasattr(p, 'a'))
1863  self.assert_(hasattr(p, 'b'))
1864  self.assert_(hasattr(p, 's'))
1865  self.assert_(hasattr(p, 'pth'))
1866  #test unresolved SequencePlaceholder
1867  p = Process("test")
1868  p.b = EDAnalyzer("YourAnalyzer")
1869  p.s = Sequence(SequencePlaceholder("a")+p.b)
1870  p.pth = Path(p.s)
1871  p.prune(keepUnresolvedSequencePlaceholders=True)
1872  self.assert_(hasattr(p, 'b'))
1873  self.assert_(hasattr(p, 's'))
1874  self.assert_(hasattr(p, 'pth'))
1875  self.assertEqual(p.s.dumpPython(''),'cms.Sequence(cms.SequencePlaceholder("a")+process.b)\n')
1876  def testModifier(self):
1877  m1 = Modifier()
1878  p = Process("test",m1)
1879  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1880  def _mod_fred(obj):
1881  obj.fred = 2
1882  m1.toModify(p.a,_mod_fred)
1883  self.assertEqual(p.a.fred.value(),2)
1884  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1885  m1.toModify(p.b, wilma = 2)
1886  self.assertEqual(p.b.wilma.value(),2)
1887  #check that Modifier not attached to a process doesn't run
1888  m1 = Modifier()
1889  p = Process("test")
1890  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
1891  m1.toModify(p.a,_mod_fred)
1892  p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
1893  m1.toModify(p.b, wilma = 2)
1894  self.assertEqual(p.a.fred.value(),1)
1895  self.assertEqual(p.b.wilma.value(),1)
1896  #make sure clones get the changes
1897  m1 = Modifier()
1898  p = Process("test",m1)
1899  p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
1900  m1.toModify(p.a, fred = int32(2))
1901  p.b = p.a.clone(wilma = int32(3))
1902  self.assertEqual(p.a.fred.value(),2)
1903  self.assertEqual(p.a.wilma.value(),1)
1904  self.assertEqual(p.b.fred.value(),2)
1905  self.assertEqual(p.b.wilma.value(),3)
1906  #test that load causes process wide methods to run
1907  def _rem_a(proc):
1908  del proc.a
1909  class ProcModifierMod(object):
1910  def __init__(self,modifier,func):
1911  self.proc_mod_ = modifier.makeProcessModifier(func)
1912  class DummyMod(object):
1913  def __init__(self):
1914  self.a = EDAnalyzer("Dummy")
1915  testMod = DummyMod()
1916  p.extend(testMod)
1917  self.assert_(hasattr(p,"a"))
1918  m1 = Modifier()
1919  p = Process("test",m1)
1920  testProcMod = ProcModifierMod(m1,_rem_a)
1921  p.extend(testMod)
1922  p.extend(testProcMod)
1923  self.assert_(not hasattr(p,"a"))
1924  #test ModifierChain
1925  m1 = Modifier()
1926  mc = ModifierChain(m1)
1927  p = Process("test",mc)
1928  testMod = DummyMod()
1929  p.b = EDAnalyzer("Dummy2", fred = int32(1))
1930  m1.toModify(p.b, fred = int32(3))
1931  p.extend(testMod)
1932  testProcMod = ProcModifierMod(m1,_rem_a)
1933  p.extend(testProcMod)
1934  self.assert_(not hasattr(p,"a"))
1935  self.assertEqual(p.b.fred.value(),3)
1936 
1937 
1938  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:1208
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:1063
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:1130
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:1096
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