CMS 3D CMS Logo

SequenceTypes.py
Go to the documentation of this file.
1 from __future__ import absolute_import
2 
3 from builtins import range
4 from .Mixins import _ConfigureComponent, PrintOptions
5 from .Mixins import _Labelable, _Unlabelable
6 from .Mixins import _ValidatingParameterListBase
7 from .ExceptionHandling import *
8 from .OrderedSet import OrderedSet
9 
11  """Information relevant for when a hard dependency,
12  which uses the * operator, is found"""
13  def __init__(self, sequenceName, depSet):
14  self.sequenceName = sequenceName
15  self.depSet = depSet
16 
18  """Denotes an object which can be placed in a sequence"""
19  def __init__(self):
20  pass
21  def __mul__(self,rhs):
22  return _SequenceCollection(self,rhs)
23  def __add__(self,rhs):
24  return _SequenceCollection(self,rhs)
25  def __invert__(self):
26  return _SequenceNegation(self)
27  def _clonesequence(self, lookuptable):
28  try:
29  return lookuptable[id(self)]
30  except:
31  raise KeyError("no "+str(type(self))+" with id "+str(id(self))+" found")
32  def resolve(self, processDict,keepIfCannotResolve=False):
33  return self
34  def isOperation(self):
35  """Returns True if the object is an operator (e.g. *,+ or !) type"""
36  return False
37  def isLeaf(self):
38  return False
39  def _visitSubNodes(self,visitor):
40  pass
41  def visitNode(self,visitor):
42  visitor.enter(self)
43  self._visitSubNodes(visitor)
44  visitor.leave(self)
45  def _appendToCollection(self,collection):
46  collection.append(self)
47  def _errorstr(self):
48  return "A Sequenceable type"
49 
50 def _checkIfSequenceable(caller, v):
51  if not isinstance(v,_Sequenceable):
52  typename = format_typename(caller)
53  msg = format_outerframe(2)
54  msg += "%s only takes arguments of types which are allowed in a sequence, but was given:\n" %typename
55  msg +=format_typename(v)
56  msg +="\nPlease remove the problematic object from the argument list"
57  raise TypeError(msg)
58 
60  if not isinstance(v,_BooleanLogicSequenceable):
61  typename = format_typename(caller)
62  msg = format_outerframe(2)
63  msg += "%s only takes arguments of types which are allowed in a boolean logic sequence, but was given:\n" %typename
64  msg +=format_typename(v)
65  msg +="\nPlease remove the problematic object from the argument list"
66  raise TypeError(msg)
67 
69  """Denotes an object which can be used in a boolean logic sequence"""
70  def __init__(self):
71  super(_BooleanLogicSequenceable,self).__init__()
72  def __or__(self,other):
73  return _BooleanLogicExpression(_BooleanLogicExpression.OR,self,other)
74  def __and__(self,other):
75  return _BooleanLogicExpression(_BooleanLogicExpression.AND,self,other)
76 
77 
79  """Contains the operation of a boolean logic expression"""
80  OR = 0
81  AND = 1
82  def __init__(self,op,left,right):
85  self._op = op
86  self._items = list()
87  #if either the left or right side are the same kind of boolean expression
88  # then we can just add their items to our own. This keeps the expression
89  # tree more compact
90  if isinstance(left,_BooleanLogicExpression) and left._op == self._op:
91  self._items.extend(left._items)
92  else:
93  self._items.append(left)
94  if isinstance(right,_BooleanLogicExpression) and right._op == self._op:
95  self._items.extend(right._items)
96  else:
97  self._items.append(right)
98  def isOperation(self):
99  return True
100  def _visitSubNodes(self,visitor):
101  for i in self._items:
102  i.visitNode(visitor)
103  def dumpSequencePython(self, options=PrintOptions()):
104  returnValue = ''
105  join = ''
106  operatorJoin =self.operatorString()
107  for m in self._items:
108  returnValue +=join
109  join = operatorJoin
110  if not isinstance(m,_BooleanLogicSequenceLeaf):
111  returnValue += '('+m.dumpSequencePython(options)+')'
112  else:
113  returnValue += m.dumpSequencePython(options)
114  return returnValue
115  def operatorString(self):
116  returnValue ='|'
117  if self._op == self.AND:
118  returnValue = '&'
119  return returnValue
120 
121 
123  def __init__(self):
124  pass
125  def isLeaf(self):
126  return True
127 
128 
130  def __init__(self):
131  pass
132  def isLeaf(self):
133  return True
134 
136  """Holds representation of the operations without having to use recursion.
137  Operations are added to the beginning of the list and their operands are
138  added to the end of the list, with the left added before the right
139  """
140  def __init__(self,*seqList):
141  self._collection = list()
142  for s in seqList:
143  _checkIfSequenceable(self,s)
144  s._appendToCollection(self._collection)
145  def __mul__(self,rhs):
146  _checkIfSequenceable(self,rhs)
147  rhs._appendToCollection(self._collection)
148  return self
149  def __add__(self,rhs):
150  _checkIfSequenceable(self,rhs)
151  rhs._appendToCollection(self._collection)
152  return self
153  def __str__(self):
154  sep = ''
155  returnValue = ''
156  for m in self._collection:
157  if m is not None:
158  returnValue += sep+str(m)
159  sep = '+'
160  return returnValue
161  def _appendToCollection(self,collection):
162  collection.extend(self._collection)
163  def dumpSequencePython(self, options=PrintOptions()):
164  returnValue = ''
165  separator = ''
166  for item in self._collection:
167  itemDump = item.dumpSequencePython(options)
168  if itemDump:
169  returnValue += (separator + itemDump)
170  separator = '+'
171  return returnValue
173  returnValue = self._collection[0].dumpSequenceConfig()
174  for m in self._collection[1:]:
175  returnValue += '&'+m.dumpSequenceConfig()
176  return returnValue
177  def visitNode(self,visitor):
178  for m in self._collection:
179  m.visitNode(visitor)
180  def resolve(self, processDict,keepIfCannotResolve=False):
181  self._collection = [x.resolve(processDict,keepIfCannotResolve) for x in self._collection]
182  return self
183  def index(self,item):
184  return self._collection.index(item)
185  def insert(self,index,item):
186  self._collection.insert(index,item)
187 
188 
189 
191  """Base class for classes which define a sequence of modules"""
192  def __init__(self,*arg, **argv):
193  self.__dict__["_isFrozen"] = False
194  self._seq = None
195  if (len(arg) > 1 and not isinstance(arg[1], Task)) or (len(arg) > 0 and not isinstance(arg[0],_Sequenceable) and not isinstance(arg[0],Task)):
196  typename = format_typename(self)
197  msg = format_outerframe(2)
198  msg += "The %s constructor takes zero or one sequenceable argument followed by zero or more arguments of type Task. But the following types are given:\n" %typename
199  for item,i in zip(arg, range(1,20)):
200  try:
201  msg += " %i) %s \n" %(i, item._errorstr())
202  except:
203  msg += " %i) Not sequenceable and not a Task\n" %(i)
204  if len(arg) > 1 and isinstance(arg[0],_Sequenceable) and isinstance(arg[1], _Sequenceable):
205  msg += "Maybe you forgot to combine the sequenceable arguments via '*' or '+'."
206  raise TypeError(msg)
207  tasks = arg
208  if len(arg) > 0 and isinstance(arg[0], _Sequenceable):
209  self._seq = _SequenceCollection()
210  arg[0]._appendToCollection(self._seq._collection)
211  tasks = arg[1:]
212  self._isModified = False
213 
215 
216  if len(tasks) > 0:
217  self.associate(*tasks)
218  def associate(self,*tasks):
219  for task in tasks:
220  if not isinstance(task, Task):
221  raise TypeError("associate only works with objects of type Task")
222  self._tasks.add(task)
223  def isFrozen(self):
224  return self._isFrozen
225  def setIsFrozen(self):
226  self._isFrozen = True
227  def _place(self,name,proc):
228  self._placeImpl(name,proc)
229  def __imul__(self,rhs):
230  _checkIfSequenceable(self, rhs)
231  if self._seq is None:
232  self.__dict__["_seq"] = _SequenceCollection()
233  self._seq+=rhs
234  return self
235  def __iadd__(self,rhs):
236  _checkIfSequenceable(self, rhs)
237  if self._seq is None:
238  self.__dict__["_seq"] = _SequenceCollection()
239  self._seq += rhs
240  return self
241  def __str__(self):
242  v = ExpandVisitor(type(self))
243  self.visit(v)
244  return v.resultString()
245  def dumpConfig(self, options):
246  s = ''
247  if self._seq is not None:
248  s = self._seq.dumpSequenceConfig()
249  return '{'+s+'}\n'
250  def dumpPython(self, options=PrintOptions()):
251  """Returns a string which is the python representation of the object"""
252  s = self.dumpPythonNoNewline(options)
253  return s + "\n"
254  def dumpPythonNoNewline(self, options=PrintOptions()):
255  s=''
256  if self._seq is not None:
257  s =self._seq.dumpSequencePython(options)
258  associationContents = set()
259  for task in self._tasks:
260  if task.hasLabel_():
261  associationContents.add(_Labelable.dumpSequencePython(task, options))
262  else:
263  associationContents.add(task.dumpPythonNoNewline(options))
264  for iString in sorted(associationContents):
265  if s:
266  s += ", "
267  s += iString
268  if len(associationContents) > 254:
269  return 'cms.'+type(self).__name__+'(*['+s+'])'
270  return 'cms.'+type(self).__name__+'('+s+')'
271  def dumpSequencePython(self, options=PrintOptions()):
272  """Returns a string which contains the python representation of just the internal sequence"""
273  # only dump the label, if possible
274  if self.hasLabel_():
275  return _Labelable.dumpSequencePython(self, options)
276  elif len(self._tasks) == 0:
277  if self._seq is None:
278  return ''
279  s = self._seq.dumpSequencePython(options)
280  if s:
281  return '('+s+')'
282  return ''
283  return self.dumpPythonNoNewline(options)
285  """Returns a string which contains the old config language representation of just the internal sequence"""
286  # only dump the label, if possible
287  if self.hasLabel_():
288  return _Labelable.dumpSequenceConfig(self)
289  else:
290  # dump it verbose
291  if self._seq is None:
292  return ''
293  return '('+self._seq.dumpSequenceConfig()+')'
294  def __repr__(self):
295  s = ''
296  if self._seq is not None:
297  s = str(self._seq)
298  return "cms."+type(self).__name__+'('+s+')\n'
299  def moduleNames(self):
300  """Returns a set containing the names of all modules being used"""
301  result = set()
302  visitor = NodeNameVisitor(result)
303  self.visit(visitor)
304  return result
305  def contains(self, mod):
306  visitor = ContainsModuleVisitor(mod)
307  self.visit(visitor)
308  return visitor.result()
309  def copy(self):
310  returnValue =_ModuleSequenceType.__new__(type(self))
311  if self._seq is not None:
312  returnValue.__init__(self._seq)
313  else:
314  returnValue.__init__()
315  returnValue._tasks = OrderedSet(self._tasks)
316  return returnValue
317  def copyAndExclude(self,listOfModulesToExclude):
318  """Returns a copy of the sequence which excludes those module in 'listOfModulesToExclude'"""
319  # You can exclude instances of these types EDProducer, EDFilter, OutputModule,
320  # EDAnalyzer, ESSource, ESProducer, Service, Sequence, SequencePlaceholder, Task,
321  # _SequenceNegation, and _SequenceIgnore.
322  # Mostly this is very intuitive, but there are some complications in cases
323  # where objects that contain other objects are involved. See the comments
324  # for the _MutatingSequenceVisitor.
325  v = _CopyAndExcludeSequenceVisitor(listOfModulesToExclude)
326  self.visit(v)
327  result = self.__new__(type(self))
328  result.__init__(v.result(self)[0], *v.result(self)[1])
329  return result
330  def expandAndClone(self):
331  # Name of this function is not very good. It makes a shallow copy with all
332  # the subTasks and subSequences flattened out (removed), but keeping all the
333  # modules that were in those subSequences and subTasks as well as the top level
334  # ones. Note this will also remove placeholders so one should probably
335  # call resolve before using this if the sequence contains any placeholders.
336  visitor = ExpandVisitor(type(self))
337  self.visit(visitor)
338  return visitor.result()
339  def _postProcessFixup(self,lookuptable):
340  self._seq = self._seq._clonesequence(lookuptable)
341  return self
342  def replace(self, original, replacement):
343  """Finds all instances of 'original' and substitutes 'replacement' for them.
344  Returns 'True' if a replacement occurs."""
345  # This works for either argument being of type EDProducer, EDFilter, OutputModule,
346  # EDAnalyzer, ESProducer, ESSource, Service, Sequence, SequencePlaceHolder,
347  # Task, _SequenceNegation, _SequenceIgnore. Although it will fail with a
348  # raised exception if the replacement actually hits a case where a
349  # non-Sequenceable object is placed in the sequenced part of a Sequence
350  # or a type not allowed on a Task is put on a Task.
351  # There is one special case where we need an explicit check to prevent
352  # the algorithm from getting confused, either both or neither can be Tasks
353  #
354  # Mostly this is very intuitive, but there are some complications in cases
355  # where objects that contain other objects are involved. See the comments
356  # for the _MutatingSequenceVisitor.
357 
358  if isinstance(original,Task) != isinstance(replacement,Task):
359  raise TypeError("replace only works if both arguments are Tasks or neither")
360  v = _CopyAndReplaceSequenceVisitor(original,replacement)
361  self.visit(v)
362  if v.didReplace():
363  self._seq = v.result(self)[0]
364  self._tasks.clear()
365  self.associate(*v.result(self)[1])
366  return v.didReplace()
367  def index(self,item):
368  """Returns the index at which the item is found or raises an exception"""
369  if self._seq is not None:
370  return self._seq.index(item)
371  raise ValueError(str(item)+" is not in the sequence")
372  def insert(self,index,item):
373  """Inserts the item at the index specified"""
374  _checkIfSequenceable(self, item)
375  if self._seq is None:
376  self.__dict__["_seq"] = _SequenceCollection()
377  self._seq.insert(index,item)
378  def remove(self, something):
379  """Remove the first occurrence of 'something' (a sequence or a module)
380  Returns 'True' if the module has been removed, False if it was not found"""
381  # You can remove instances of these types EDProducer, EDFilter, OutputModule,
382  # EDAnalyzer, ESSource, ESProducer, Service, Sequence, SequencePlaceholder, Task,
383  # _SequenceNegation, and _SequenceIgnore.
384  # Mostly this is very intuitive, but there are some complications in cases
385  # where objects that contain other objects are involved. See the comments
386  # for the _MutatingSequenceVisitor.
387  #
388  # Works very similar to copyAndExclude, there are 2 differences. This changes
389  # the object itself instead of making a copy and second it only removes
390  # the first instance of the argument instead of all of them.
392  self.visit(v)
393  if v.didRemove():
394  self._seq = v.result(self)[0]
395  self._tasks.clear()
396  self.associate(*v.result(self)[1])
397  return v.didRemove()
398  def resolve(self, processDict,keepIfCannotResolve=False):
399  if self._seq is not None:
400  self._seq = self._seq.resolve(processDict,keepIfCannotResolve)
401  for task in self._tasks:
402  task.resolve(processDict,keepIfCannotResolve)
403  return self
404  def __setattr__(self,name,value):
405  if not name.startswith("_"):
406  raise AttributeError("You cannot set parameters for sequence like objects.")
407  else:
408  self.__dict__[name] = value
409  #def replace(self,old,new):
410  #"""Find all instances of old and replace with new"""
411  #def insertAfter(self,which,new):
412  #"""new will depend on which but nothing after which will depend on new"""
413  #((a*b)*c) >> insertAfter(b,N) >> ((a*b)*(N+c))
414  #def insertBefore(self,which,new):
415  #"""new will be independent of which"""
416  #((a*b)*c) >> insertBefore(b,N) >> ((a*(N+b))*c)
417  #def __contains__(self,item):
418  #"""returns whether or not 'item' is in the sequence"""
419  #def modules_(self):
420  def nameInProcessDesc_(self, myname):
421  return myname
422  def insertInto(self, parameterSet, myname, decoratedList):
423  parameterSet.addVString(True, myname, decoratedList)
424  def visit(self,visitor):
425  """Passes to visitor's 'enter' and 'leave' method each item describing the module sequence.
426  If the item contains 'sub' items then visitor will see those 'sub' items between the
427  item's 'enter' and 'leave' calls.
428  """
429  if self._seq is not None:
430  self._seq.visitNode(visitor)
431  for item in self._tasks:
432  visitor.enter(item)
433  item.visit(visitor)
434  visitor.leave(item)
435 
437  """For ~ and - operators"""
438  def __init__(self, operand):
439  self._operand = operand
440  if isinstance(operand, _ModuleSequenceType):
441  raise RuntimeError("This operator cannot accept a sequence")
442  if not isinstance(operand, _Sequenceable):
443  raise RuntimeError("This operator cannot accept a non sequenceable type")
444  def __eq__(self, other):
445  # allows replace(~a, b)
446  return isinstance(self, type(other)) and self._operand==other._operand
447  def __ne__(self, other):
448  return not self.__eq__(other)
449  def _findDependencies(self,knownDeps, presentDeps):
450  self._operand._findDependencies(knownDeps, presentDeps)
451  def _clonesequence(self, lookuptable):
452  return type(self)(self._operand._clonesequence(lookuptable))
453  def _replace(self, original, replacement):
454  if self._operand == original:
455  self._operand = replacement
456  else:
457  self._operand._replace(original, replacement)
458  def _remove(self, original):
459  if (self._operand == original): return (None, True)
460  (self._operand, found) = self._operand._remove(original)
461  if self._operand == None: return (None, True)
462  return (self, found)
463  def resolve(self, processDict,keepIfCannotResolve=False):
464  self._operand = self._operand.resolve(processDict,keepIfCannotResolve)
465  return self
466  def isOperation(self):
467  return True
468  def _visitSubNodes(self,visitor):
469  self._operand.visitNode(visitor)
470  def decoration(self):
471  self._operand.decoration()
472 
473 
475  """Used in the expression tree for a sequence as a stand in for the '!' operator"""
476  def __init__(self, operand):
477  super(_SequenceNegation,self).__init__(operand)
478  def __str__(self):
479  return '~%s' %self._operand
481  return '!%s' %self._operand.dumpSequenceConfig()
482  def dumpSequencePython(self, options=PrintOptions()):
483  if self._operand.isOperation():
484  return '~(%s)' %self._operand.dumpSequencePython(options)
485  return '~%s' %self._operand.dumpSequencePython(options)
486  def decoration(self):
487  return '!'
488 
490  """Used in the expression tree for a sequence as a stand in for the '-' operator"""
491  def __init__(self, operand):
492  super(_SequenceIgnore,self).__init__(operand)
493  def __str__(self):
494  return 'ignore(%s)' %self._operand
496  return '-%s' %self._operand.dumpSequenceConfig()
497  def dumpSequencePython(self, options=PrintOptions()):
498  return 'cms.ignore(%s)' %self._operand.dumpSequencePython(options)
499  def decoration(self):
500  return '-'
501 
502 def ignore(seq):
503  """The EDFilter passed as an argument will be run but its filter value will be ignored
504  """
505  return _SequenceIgnore(seq)
506 
508  def __init__(self,*arg,**argv):
509  super(Path,self).__init__(*arg,**argv)
510  def _placeImpl(self,name,proc):
511  proc._placePath(name,self)
512 
514  def __init__(self,*arg,**argv):
515  super(EndPath,self).__init__(*arg,**argv)
516  def _placeImpl(self,name,proc):
517  proc._placeEndPath(name,self)
518 
520  def __init__(self,*arg,**argv):
521  super(Sequence,self).__init__(*arg,**argv)
522  def _placeImpl(self,name,proc):
523  proc._placeSequence(name,self)
524  def _clonesequence(self, lookuptable):
525  if id(self) not in lookuptable:
526  #for sequences held by sequences we need to clone
527  # on the first reference
528  if self._seq is not None:
529  clone = type(self)(self._seq._clonesequence(lookuptable))
530  else:
531  clone = type(self)()
532  lookuptable[id(self)]=clone
533  lookuptable[id(clone)]=clone
534  return lookuptable[id(self)]
535  def _visitSubNodes(self,visitor):
536  self.visit(visitor)
538  def __init__(self, name):
539  self._name = name
540  def _placeImpl(self,name,proc):
541  pass
542  def __str__(self):
543  return self._name
544  def insertInto(self, parameterSet, myname):
545  raise RuntimeError("The SequencePlaceholder "+self._name
546  +" was never overridden")
547  def resolve(self, processDict,keepIfCannotResolve=False):
548  if not self._name in processDict:
549  #print str(processDict.keys())
550  if keepIfCannotResolve:
551  return self
552  raise RuntimeError("The SequencePlaceholder "+self._name+ " cannot be resolved.\n Known keys are:"+str(processDict.keys()))
553  o = processDict[self._name]
554  if not isinstance(o,_Sequenceable):
555  raise RuntimeError("The SequencePlaceholder "+self._name+ " refers to an object type which is not allowed to be on a sequence: "+str(type(o)))
556  return o.resolve(processDict)
557 
558  def _clonesequence(self, lookuptable):
559  if id(self) not in lookuptable:
560  #for sequences held by sequences we need to clone
561  # on the first reference
562  clone = type(self)(self._name)
563  lookuptable[id(self)]=clone
564  lookuptable[id(clone)]=clone
565  return lookuptable[id(self)]
566  def copy(self):
567  returnValue =SequencePlaceholder.__new__(type(self))
568  returnValue.__init__(self._name)
569  return returnValue
571  return 'cms.SequencePlaceholder("%s")' %self._name
572  def dumpSequencePython(self, options=PrintOptions()):
573  return 'cms.SequencePlaceholder("%s")'%self._name
574  def dumpPython(self, options=PrintOptions()):
575  result = 'cms.SequencePlaceholder(\"'
576  if options.isCfg:
577  result += 'process.'
578  result += +self._name+'\")\n'
579 
580 
582 
583  def __init__(self,*arg,**argv):
584  super(Schedule,self).__init__(*arg)
586  theKeys = list(argv.keys())
587  if theKeys:
588  if len(theKeys) > 1 or theKeys[0] != "tasks":
589  raise RuntimeError("The Schedule constructor can only have one keyword argument after its Path and\nEndPath arguments and it must use the keyword 'tasks'")
590  taskList = argv["tasks"]
591  # Normally we want a list of tasks, but we let it also work if the value is one Task
592  if isinstance(taskList,Task):
593  self.associate(taskList)
594  else:
595  try:
596  # Call this just to check that taskList is a list or other iterable object
597  self.__dummy(*taskList)
598  except:
599  raise RuntimeError("The Schedule constructor argument with keyword 'tasks' must have a\nlist (or other iterable object) as its value")
600  if taskList:
601  self.associate(*taskList)
602 
603  def __dummy(self, *args):
604  pass
605 
606  def associate(self,*tasks):
607  for task in tasks:
608  if not isinstance(task, Task):
609  raise TypeError("The associate function in the class Schedule only works with arguments of type Task")
610  self._tasks.add(task)
611  @staticmethod
612  def _itemIsValid(item):
613  return isinstance(item,Path) or isinstance(item,EndPath)
614  def copy(self):
615  import copy
616  aCopy = copy.copy(self)
617  aCopy._tasks = OrderedSet(self._tasks)
618  return aCopy
619  def _place(self,label,process):
620  process.setPartialSchedule_(self,label)
621  def moduleNames(self):
622  result = set()
623  visitor = NodeNameVisitor(result)
624  for seq in self:
625  seq.visit(visitor)
626  for t in self._tasks:
627  t.visit(visitor)
628  return result
629  def contains(self, mod):
630  visitor = ContainsModuleVisitor(mod)
631  for seq in self:
632  seq.visit(visitor)
633  if visitor.result():
634  return True
635  for t in self._tasks:
636  t.visit(visitor)
637  if visitor.result():
638  return True
639  return visitor.result()
640  def dumpPython(self, options=PrintOptions()):
641  pathNames = ['process.'+p.label_() for p in self]
642  if pathNames:
643  s=', '.join(pathNames)
644  else:
645  s = ''
646  associationContents = set()
647  for task in self._tasks:
648  if task.hasLabel_():
649  associationContents.add(_Labelable.dumpSequencePython(task, options))
650  else:
651  associationContents.add(task.dumpPythonNoNewline(options))
652  taskStrings = list()
653  for iString in sorted(associationContents):
654  taskStrings.append(iString)
655  if taskStrings and s:
656  return 'cms.Schedule(*[ ' + s + ' ], tasks=[' + ', '.join(taskStrings) + '])\n'
657  elif s:
658  return 'cms.Schedule(*[ ' + s + ' ])\n'
659  elif taskStrings:
660  return 'cms.Schedule(tasks=[' + ', '.join(taskStrings) + '])\n'
661  else:
662  return 'cms.Schedule()\n'
663 
664  def __str__(self):
665  return self.dumpPython()
666 
667 # Fills a list of all Sequences visited
668 # Can visit a Sequence, Path, or EndPath
670  def __init__(self,d):
671  self.deps = d
672  def enter(self,visitee):
673  if isinstance(visitee,Sequence):
674  self.deps.append(visitee)
675  pass
676  def leave(self,visitee):
677  pass
678 
679 # Fills a list of all Tasks visited
680 # Can visit a Task, Sequence, Path, or EndPath
681 class TaskVisitor(object):
682  def __init__(self,d):
683  self.deps = d
684  def enter(self,visitee):
685  if isinstance(visitee,Task):
686  self.deps.append(visitee)
687  pass
688  def leave(self,visitee):
689  pass
690 
691 # Fills a list of all modules visited.
692 # Can visit a Sequence, Path, EndPath, or Task
693 # For purposes of this visitor, a module is considered
694 # to be an object that is one of these types: EDProducer,
695 # EDFilter, EDAnalyzer, OutputModule, ESProducer, ESSource,
696 # Service. The last three of these can only appear on a
697 # Task, they are not sequenceable. An object of one
698 # of these types is also called a leaf.
699 class ModuleNodeVisitor(object):
700  def __init__(self,l):
701  self.l = l
702  def enter(self,visitee):
703  if visitee.isLeaf():
704  self.l.append(visitee)
705  pass
706  def leave(self,visitee):
707  pass
708 
709 # Should not be used on Tasks.
710 # Similar to ModuleNodeVisitor with the following
711 # differences. It only lists the modules that were
712 # contained inside a Task. It should only be used
713 # on Sequences, Paths, and EndPaths.
714 class ModuleNodeOnTaskVisitor(object):
715  def __init__(self,l):
716  self.l = l
717  self._levelInTasks = 0
718  def enter(self,visitee):
719  if isinstance(visitee, Task):
720  self._levelInTasks += 1
721  if self._levelInTasks == 0:
722  return
723  if visitee.isLeaf():
724  self.l.append(visitee)
725  pass
726  def leave(self,visitee):
727  if self._levelInTasks > 0:
728  if isinstance(visitee, Task):
729  self._levelInTasks -= 1
730 
731 # Should not be used on Tasks.
732 # Similar to ModuleNodeVisitor with the following
733 # differences. It only lists the modules that were
734 # outside a Task, in the sequenced part of the sequence.
735 # It should only be used on Sequences, Paths, and
736 # EndPaths.
738  def __init__(self,l):
739  self.l = l
740  self._levelInTasks = 0
741  def enter(self,visitee):
742  if isinstance(visitee, Task):
743  self._levelInTasks += 1
744  if self._levelInTasks > 0:
745  return
746  if visitee.isLeaf():
747  self.l.append(visitee)
748  pass
749  def leave(self,visitee):
750  if self._levelInTasks > 0:
751  if isinstance(visitee, Task):
752  self._levelInTasks -= 1
753 
754 # Can visit Tasks, Sequences, Paths, and EndPaths
755 # result will be set to True if and only if
756 # the module is in the object directly or
757 # indirectly through contained Sequences or
758 # associated Tasks.
760  def __init__(self,mod):
761  self._mod = mod
762  self._result = False
763 
764  def result(self):
765  return self._result
766 
767  def enter(self,visitee):
768  if self._mod is visitee:
769  self._result = True
770 
771  def leave(self,visitee):
772  pass
773 
774 # Can visit Tasks, Sequences, Paths, and EndPaths
775 # Fills a set of the names of the visited leaves.
776 # For the labelable ones the name is the label.
777 # For a Service the name is the type.
778 # It raises an exception if a labelable object
779 # does not have a label at all. It will return
780 # 'None' if the label attribute exists but was set
781 # to None. If a Service is not attached to the process
782 # it will also raise an exception.
783 class NodeNameVisitor(object):
784  """ takes a set as input"""
785  def __init__(self,l):
786  self.l = l
787  def enter(self,visitee):
788  if visitee.isLeaf():
789  if isinstance(visitee, _Labelable):
790  self.l.add(visitee.label_())
791  else:
792  if visitee._inProcess:
793  self.l.add(visitee.type_())
794  else:
795  raise RuntimeError("Service not attached to process")
796  def leave(self,visitee):
797  pass
798 
799 # This visitor works only with Sequences, Paths and EndPaths
800 # It will not work on Tasks
801 class ExpandVisitor(object):
802  """ Expands the sequence into leafs and UnaryOperators """
803  def __init__(self, type):
804  self._type = type
805  self.l = []
806  self.taskLeaves = []
807  self._levelInTasks = 0
808  def enter(self,visitee):
809  if isinstance(visitee, Task):
810  self._levelInTasks += 1
811  return
812  if visitee.isLeaf():
813  if self._levelInTasks > 0:
814  self.taskLeaves.append(visitee)
815  else:
816  self.l.append(visitee)
817  def leave(self, visitee):
818  if self._levelInTasks > 0:
819  if isinstance(visitee, Task):
820  self._levelInTasks -= 1
821  return
822  if isinstance(visitee,_UnarySequenceOperator):
823  self.l[-1] = visitee
824  def result(self):
825  tsk = Task(*self.taskLeaves)
826  if len(self.l) > 0:
827  # why doesn't (sum(self.l) work?
828  seq = self.l[0]
829  for el in self.l[1:]:
830  seq += el
831  return self._type(seq, tsk)
832  else:
833  return self._type(tsk)
834  def resultString(self):
835  sep = ''
836  returnValue = ''
837  for m in self.l:
838  if m is not None:
839  returnValue += sep+str(m)
840  sep = '+'
841  if returnValue:
842  sep = ','
843  for n in self.taskLeaves:
844  if n is not None:
845  returnValue += sep+str(n)
846  sep = ','
847  return returnValue
848 
849 
850 # This visitor is only meant to run on Sequences, Paths, and EndPaths
851 # It intentionally ignores nodes on Tasks when it does this.
853  """ Adds any '!' or '-' needed. Takes a list """
854  def __init__(self,l):
855  self.l = l
856  self._decoration =''
857  self._levelInTasks = 0
858 
859  def initialize(self):
860  self.l[:] = []
861  self._decoration =''
862  self._levelInTasks = 0
863 
864  def enter(self,visitee):
865  if isinstance(visitee, Task):
866  self._levelInTasks += 1
867  if self._levelInTasks > 0:
868  return
869  if visitee.isLeaf():
870  if hasattr(visitee, "_Labelable__label"):
871  self.l.append(self._decoration+visitee.label_())
872  else:
873  error = "An object in a sequence was not found in the process\n"
874  if hasattr(visitee, "_filename"):
875  error += "From file " + visitee._filename
876  else:
877  error += "Dump follows\n" + repr(visitee)
878  raise RuntimeError(error)
879  if isinstance(visitee,_BooleanLogicExpression):
880  self.l.append(self._decoration+visitee.operatorString())
881  if isinstance(visitee,_UnarySequenceOperator):
882  self._decoration=visitee.decoration()
883  else:
884  self._decoration=''
885 
886  def leave(self,visitee):
887  # Ignore if this visitee is inside a Task
888  if self._levelInTasks > 0:
889  if isinstance(visitee, Task):
890  self._levelInTasks -= 1
891  return
892  if isinstance(visitee,_BooleanLogicExpression):
893  #need to add the 'go back' command to keep track of where we are in the tree
894  self.l.append('@')
895 
896 # This visitor is only meant to run on Sequences, Paths, and EndPaths
897 # Similar to DecoratedNodeNameVistor. The only difference
898 # is it also builds a separate list of leaves on Tasks.
900  """ Adds any '!' or '-' needed. Takes a list """
901  def __init__(self,l):
902  self.l = l
903  self._decoration =''
904  self._levelInTasks = 0
905  self._leavesOnTasks = []
906 
907  def initialize(self):
908  self.l[:] = []
909  self._decoration =''
910  self._levelInTasks = 0
911  self._leavesOnTasks[:] = []
912 
913  def enter(self,visitee):
914  if isinstance(visitee, Task):
915  self._levelInTasks += 1
916  if self._levelInTasks > 0:
917  if visitee.isLeaf():
918  self._leavesOnTasks.append(visitee)
919  return
920  if visitee.isLeaf():
921  if hasattr(visitee, "_Labelable__label"):
922  self.l.append(self._decoration+visitee.label_())
923  else:
924  error = "An object in a sequence was not found in the process\n"
925  if hasattr(visitee, "_filename"):
926  error += "From file " + visitee._filename
927  else:
928  error += "Dump follows\n" + repr(visitee)
929  raise RuntimeError(error)
930  if isinstance(visitee,_BooleanLogicExpression):
931  self.l.append(self._decoration+visitee.operatorString())
932  if isinstance(visitee,_UnarySequenceOperator):
933  self._decoration=visitee.decoration()
934  else:
935  self._decoration=''
936 
937  def leave(self,visitee):
938  # Ignore if this visitee is inside a Task
939  if self._levelInTasks > 0:
940  if isinstance(visitee, Task):
941  self._levelInTasks -= 1
942  return
943  if isinstance(visitee,_BooleanLogicExpression):
944  #need to add the 'go back' command to keep track of where we are in the tree
945  self.l.append('@')
946 
947  def leavesOnTasks(self):
948  return self._leavesOnTasks
949 
951  """Traverses a Sequence and constructs a new sequence which does not contain modules from the specified list"""
952  def __init__(self,modulesToRemove):
953  self.__modulesToIgnore = modulesToRemove
954  self.__stack = list()
955  self.__stack.append(list())
956  self.__result = None
957  self.__didExclude = False
958  def enter(self,visitee):
959  if len(self.__stack) > 0:
960  #add visitee to its parent's stack entry
961  self.__stack[-1].append([visitee,False])
962  if visitee.isLeaf():
963  if visitee in self.__modulesToIgnore:
964  self.__didExclude = True
965  self.__stack[-1][-1]=[None,True]
966  elif isinstance(visitee, Sequence):
967  if visitee in self.__modulesToIgnore:
968  self.__didExclude = True
969  self.__stack[-1][-1]=[None,True]
970  self.__stack.append(list())
971  else:
972  #need to add a stack entry to keep track of children
973  self.__stack.append(list())
974  def leave(self,visitee):
975  node = visitee
976  if not visitee.isLeaf():
977  #were any children changed?
978  l = self.__stack[-1]
979  changed = False
980  countNulls = 0
981  nonNulls = list()
982  for c in l:
983  if c[1] == True:
984  changed = True
985  if c[0] is None:
986  countNulls +=1
987  else:
988  nonNulls.append(c[0])
989  if changed:
990  self.__didExclude = True
991  if countNulls != 0:
992  #this node must go away
993  if len(nonNulls) == 0:
994  #all subnodes went away
995  node = None
996  else:
997  node = nonNulls[0]
998  for n in nonNulls[1:]:
999  node = node+n
1000  else:
1001  #some child was changed so we need to clone
1002  # this node and replace it with one that holds
1003  # the new child(ren)
1004  children = [x[0] for x in l ]
1005  if not isinstance(visitee,Sequence):
1006  node = visitee.__new__(type(visitee))
1007  node.__init__(*children)
1008  else:
1009  node = nonNulls[0]
1010  if node != visitee:
1011  #we had to replace this node so now we need to
1012  # change parent's stack entry as well
1013  if len(self.__stack) > 1:
1014  p = self.__stack[-2]
1015  #find visitee and replace
1016  for i,c in enumerate(p):
1017  if c[0]==visitee:
1018  c[0]=node
1019  c[1]=True
1020  break
1021  if not visitee.isLeaf():
1022  self.__stack = self.__stack[:-1]
1023  def result(self):
1024  result = None
1025  for n in (x[0] for x in self.__stack[0]):
1026  if n is None:
1027  continue
1028  if result is None:
1029  result = n
1030  else:
1031  result = result+n
1032  return result
1033  def didExclude(self):
1034  return self.__didExclude
1035 
1036 
1037 # This visitor can also be used on Tasks.
1039  """Traverses a Sequence and constructs a new sequence by applying the operator to each element of the sequence"""
1040 
1041  # In many cases this operates in an intuitive manner that needs
1042  # no explanation, but there are some complex cases and I will try to
1043  # explain these in the following comments.
1044  #
1045  # First of all the top level Sequence or Task being visited may contain
1046  # many objects of different types. These contained objects are never
1047  # modified. If they are not left the same, they are instead replaced
1048  # by other instances, replaced by new instances or removed.
1049  # Contained objects are only replaced or removed when they were directly
1050  # modified or if they contain something that was modified.
1051  # If all the contents of a Sequence, Task, _SequenceNegation or _SequenceIgnore
1052  # object that is not at the top level are removed, then the containing
1053  # object is also removed.
1054  # If the contents of a Sequence other than the top level sequence are
1055  # modified, then the sequence elements and Task objects it contains get
1056  # passed up to be included in the top level sequence. If the contents of
1057  # a Task are modified, a new Task object is created and passed up to be
1058  # included in the top level Sequence or Task. If it is a _SequenceNegation
1059  # or _SequenceIgnore instance it will simply be removed completely if its
1060  # operand is removed. If the operand is replaced then a new object of the
1061  # same type will be constructed replacing the old.
1062  #
1063  # Note that if a Sequence contains a SequencePlaceholder, the future contents
1064  # of that placeholder are not affected by the changes. If that is an issue,
1065  # then you probably want to resolve the placeholders before using this
1066  # class.
1067  #
1068  # If this is used multiple times on the same sequence or task, the consequences
1069  # might interfere with one another in unusual cases.
1070  #
1071  # One example, the matching to find objects to modify is based on instances
1072  # (the python id) being the same. So if you modify the contents of a Task or
1073  # Sequence and then subsequently try to modify that Sequence or Task, then
1074  # it will either no longer exist or be a different instance and so nothing
1075  # would get modified. Note that the one exception to this matching by instance
1076  # is _SequenceIgnore and _SequenceNegation. In that case, two objects are
1077  # recognized as matching if the contained module is the same instance instead
1078  # of requiring the _SequenceNegation or _SequenceIgnore object to be the same
1079  # instance.
1080  #
1081  # Another example. There is an input operator that removes the first instance
1082  # of an object. Applying this visitor with that operation might give unexpected
1083  # results if another operation previously changed the number of times the
1084  # that instance appears or the order it appears in the visitation. This
1085  # should only be an issue if the item is on a Task and even then only in
1086  # unusual circumstances.
1087 
1088  def __init__(self,operator):
1089  self.__operator = operator
1090  # You add a list to the __stack when entering any non-Leaf object
1091  # and pop the last element when leaving any non-Leaf object
1092  self.__stack = list()
1093  self.__stack.append(list())
1094  self.__didApply = False
1096  def enter(self,visitee):
1097  # Ignore the content of replaced or removed Sequences,
1098  # Tasks, and operators.
1099  if self.__levelInModifiedNonLeaf > 0:
1100  if not visitee.isLeaf():
1101  self.__levelInModifiedNonLeaf += 1
1102  return
1103 
1104  # Just a sanity check
1105  if not len(self.__stack) > 0:
1106  raise RuntimeError("LogicError Empty stack in MutatingSequenceVisitor.\n"
1107  "This should never happen. Contact a Framework developer.")
1108 
1109  # The most important part.
1110  # Apply the operator that might change things, The rest
1111  # of the class is just dealing with side effects of these changes.
1112  v = self.__operator(visitee)
1113 
1114  if v is visitee:
1115  # the operator did not change the visitee
1116  # The 3 element list being appended has the following contents
1117  # element 0 - either the unmodified object, the modified object, or
1118  # a sequence collection when it is a Sequence whose contents have
1119  # been modified.
1120  # element 1 - Indicates whether the object was modified.
1121  # element 2 - None or a list of tasks for a Sequence
1122  # whose contents have been modified.
1123  self.__stack[-1].append([visitee, False, None])
1124  if not visitee.isLeaf():
1125  # need to add a list to keep track of the contents
1126  # of the Sequence, Task, or operator we just entered.
1127  self.__stack.append(list())
1128  else:
1129  # the operator changed the visitee
1130  self.__didApply = True
1131  self.__stack[-1].append([v, True, None])
1132  if not visitee.isLeaf():
1133  # Set flag to indicate modified Sequence, Task, or operator
1134  self.__levelInModifiedNonLeaf = 1
1135  def leave(self,visitee):
1136 
1137  # nothing to do for leaf types because they do not have contents
1138  if visitee.isLeaf():
1139  return
1140 
1141  # Ignore if this visitee is inside something that was already removed
1142  # or replaced.
1143  if self.__levelInModifiedNonLeaf > 0:
1144  self.__levelInModifiedNonLeaf -= 1
1145  return
1146 
1147  # Deal with visitees which have contents (Sequence, Task, _SequenceIgnore,
1148  # or _SequenceNegation) and although we know the visitee itself did not get
1149  # changed by the operator, the contents of the visitee might have been changed.
1150 
1151  # did any object inside the visitee change?
1152  contents = self.__stack[-1]
1153  changed = False
1154  allNull = True
1155  for c in contents:
1156  if c[1] == True:
1157  changed = True
1158  if c[0] is not None:
1159  allNull = False
1160  if changed:
1161  if allNull:
1162  self.__stack[-2][-1] = [None, True, None]
1163 
1164  elif isinstance(visitee, _UnarySequenceOperator):
1165  node = visitee.__new__(type(visitee))
1166  node.__init__(contents[0][0])
1167  self.__stack[-2][-1] = [node, True, None]
1168 
1169  elif isinstance(visitee, Task):
1170  nonNull = []
1171  for c in contents:
1172  if c[0] is not None:
1173  nonNull.append(c[0])
1174  self.__stack[-2][-1] = [Task(*nonNull), True, None]
1175  elif isinstance(visitee, Sequence):
1176  seq = _SequenceCollection()
1177  tasks = list()
1178  for c in contents:
1179  if c[0] is None:
1180  continue
1181  if isinstance(c[0], Task):
1182  tasks.append(c[0])
1183  else:
1184  seq = seq + c[0]
1185  if c[2] is not None:
1186  tasks.extend(c[2])
1187 
1188  self.__stack[-2][-1] = [seq, True, tasks]
1189 
1190  # When you exit the Sequence, Task, or operator,
1191  # drop the list which holds information about
1192  # its contents.
1193  if not visitee.isLeaf():
1194  self.__stack = self.__stack[:-1]
1195 
1196  def result(self, visitedContainer):
1197 
1198  if isinstance(visitedContainer, Task):
1199  result = list()
1200  for n in (x[0] for x in self.__stack[0]):
1201  if n is not None:
1202  result.append(n)
1203  return result
1204 
1205  seq = _SequenceCollection()
1206  tasks = list()
1207  for c in self.__stack[0]:
1208  if c[0] is None:
1209  continue
1210  if isinstance(c[0], Task):
1211  tasks.append(c[0])
1212  else:
1213  seq = seq + c[0]
1214  if c[2] is not None:
1215  tasks.extend(c[2])
1216  return [seq, tasks]
1217 
1218  def _didApply(self):
1219  return self.__didApply
1220 
1221 # This visitor can also be used on Tasks.
1223  """Traverses a Sequence and constructs a new sequence which does not contain modules from the specified list"""
1224  def __init__(self,moduleToRemove):
1225  class _RemoveFirstOperator(object):
1226  def __init__(self,moduleToRemove):
1227  self.__moduleToRemove = moduleToRemove
1228  self.__found = False
1229  def __call__(self,test):
1230  if not self.__found and test is self.__moduleToRemove:
1231  self.__found = True
1232  return None
1233  return test
1234  super(type(self),self).__init__(_RemoveFirstOperator(moduleToRemove))
1235  def didRemove(self):
1236  return self._didApply()
1237 
1238 # This visitor can also be used on Tasks.
1240  """Traverses a Sequence and constructs a new sequence which does not contain the module specified"""
1241  def __init__(self,modulesToRemove):
1242  class _ExcludeOperator(object):
1243  def __init__(self,modulesToRemove):
1244  self.__modulesToIgnore = modulesToRemove
1245  def __call__(self,test):
1246  if test in modulesToRemove:
1247  return None
1248  return test
1249  super(type(self),self).__init__(_ExcludeOperator(modulesToRemove))
1250  def didExclude(self):
1251  return self._didApply()
1252 
1253 # This visitor can also be used on Tasks.
1255  """Traverses a Sequence and constructs a new sequence which replaces a specified module with a different module"""
1256  def __init__(self,target,replace):
1257  class _ReplaceOperator(object):
1258  def __init__(self,target,replace):
1259  self.__target = target
1260  self.__replace = replace
1261  def __call__(self,test):
1262  if test == self.__target:
1263  return self.__replace
1264  return test
1265  super(type(self),self).__init__(_ReplaceOperator(target,replace))
1266  def didReplace(self):
1267  return self._didApply()
1268 
1270  """Holds EDProducers, EDFilters, ESProducers, ESSources, Services, and Tasks.
1271  A Task can be associated with Sequences, Paths, EndPaths and the Schedule.
1272  An EDProducer or EDFilter will be enabled to run unscheduled if it is on
1273  a task associated with the Schedule or any scheduled Path or EndPath (directly
1274  or indirectly through Sequences) and not be on any scheduled Path or EndPath.
1275  ESSources, ESProducers, and Services will be enabled to run if they are on
1276  a Task associated with the Schedule or a scheduled Path or EndPath. In other
1277  cases, they will be enabled to run if and only if they are not on a Task attached
1278  to the process.
1279  """
1280 
1281  def __init__(self, *items):
1283  self.add(*items)
1284 
1285  def __setattr__(self,name,value):
1286  if not name.startswith("_"):
1287  raise AttributeError("You cannot set parameters for Task objects.")
1288  else:
1289  self.__dict__[name] = value
1290 
1291  def add(self, *items):
1292  for item in items:
1293  if not isinstance(item, _ConfigureComponent) or not item._isTaskComponent():
1294  if not isinstance(item, TaskPlaceholder):
1295  raise RuntimeError("Adding an entry of type '" + type(item).__name__ + "'to a Task.\n"
1296  "It is illegal to add this type to a Task.")
1297  self._collection.add(item)
1298 
1299  def _place(self, name, proc):
1300  proc._placeTask(name,self)
1301 
1302  def fillContents(self, taskContents, options=PrintOptions()):
1303  # only dump the label, if possible
1304  if self.hasLabel_():
1305  taskContents.add(_Labelable.dumpSequencePython(self, options))
1306  else:
1307  for i in self._collection:
1308  if isinstance(i, Task):
1309  i.fillContents(taskContents, options)
1310  else:
1311  taskContents.add(i.dumpSequencePython(options))
1312 
1313  def dumpPython(self, options=PrintOptions()):
1314  s = self.dumpPythonNoNewline(options)
1315  return s + "\n"
1316 
1317  def dumpPythonNoNewline(self, options=PrintOptions()):
1318  """Returns a string which is the python representation of the object"""
1319  taskContents = set()
1320  for i in self._collection:
1321  if isinstance(i, Task):
1322  i.fillContents(taskContents, options)
1323  else:
1324  taskContents.add(i.dumpSequencePython(options))
1325  s=''
1326  iFirst = True
1327  for item in sorted(taskContents):
1328  if not iFirst:
1329  s += ", "
1330  iFirst = False
1331  s += item
1332  if len(taskContents) > 255:
1333  return "cms.Task(*[" + s + "])"
1334  return "cms.Task(" + s + ")"
1335 
1336  def _isTaskComponent(self):
1337  return True
1338 
1339  def isLeaf(self):
1340  return False
1341 
1342  def visit(self,visitor):
1343  for i in self._collection:
1344  visitor.enter(i)
1345  if not i.isLeaf():
1346  i.visit(visitor)
1347  visitor.leave(i)
1348 
1349  def _errorstr(self):
1350  return "Task(...)"
1351 
1352  def __iter__(self):
1353  for key in self._collection:
1354  yield key
1355 
1356  def __str__(self):
1357  l = []
1358  v = ModuleNodeVisitor(l)
1359  self.visit(v)
1360  s = ''
1361  for i in l:
1362  if s:
1363  s += ', '
1364  s += str (i)
1365  return s
1366 
1367  def __repr__(self):
1368  s = str(self)
1369  return "cms."+type(self).__name__+'('+s+')\n'
1370 
1371  def moduleNames(self):
1372  """Returns a set containing the names of all modules being used"""
1373  result = set()
1374  visitor = NodeNameVisitor(result)
1375  self.visit(visitor)
1376  return result
1377  def contains(self, mod):
1378  visitor = ContainsModuleVisitor(mod)
1379  self.visit(visitor)
1380  return visitor.result()
1381  def copy(self):
1382  return Task(*self._collection)
1383  def copyAndExclude(self,listOfModulesToExclude):
1384  """Returns a copy of the sequence which excludes those module in 'listOfModulesToExclude'"""
1385  # You can exclude instances of these types EDProducer, EDFilter, ESSource, ESProducer,
1386  # Service, or Task.
1387  # Mostly this is very intuitive, but there are some complications in cases
1388  # where objects that contain other objects are involved. See the comments
1389  # for the _MutatingSequenceVisitor.
1390  for i in listOfModulesToExclude:
1391  if not i._isTaskComponent():
1392  raise TypeError("copyAndExclude can only exclude objects that can be placed on a Task")
1393  v = _CopyAndExcludeSequenceVisitor(listOfModulesToExclude)
1394  self.visit(v)
1395  return Task(*v.result(self))
1396  def expandAndClone(self):
1397  # Name of this function is not very good. It makes a shallow copy with all
1398  # the subTasks flattened out (removed), but keeping all the
1399  # modules that were in those subTasks as well as the top level
1400  # ones.
1401  l = []
1402  v = ModuleNodeVisitor(l)
1403  self.visit(v)
1404  return Task(*l)
1405  def replace(self, original, replacement):
1406  """Finds all instances of 'original' and substitutes 'replacement' for them.
1407  Returns 'True' if a replacement occurs."""
1408  # This works for either argument being of type EDProducer, EDFilter, ESProducer,
1409  # ESSource, Service, or Task.
1410  #
1411  # Mostly this is very intuitive, but there are some complications in cases
1412  # where objects that contain other objects are involved. See the comments
1413  # for the _MutatingSequenceVisitor.
1414 
1415  if not original._isTaskComponent() or (not replacement is None and not replacement._isTaskComponent()):
1416  raise TypeError("The Task replace function only works with objects that can be placed on a Task\n" + \
1417  " replace was called with original type = " + str(type(original)) + "\n" + \
1418  " and replacement type = " + str(type(replacement)) + "\n")
1419  else:
1420  v = _CopyAndReplaceSequenceVisitor(original,replacement)
1421  self.visit(v)
1422  if v.didReplace():
1423  self._collection.clear()
1424  self.add(*v.result(self))
1425  return v.didReplace()
1426 
1427  def remove(self, something):
1428  """Remove the first occurrence of a module
1429  Returns 'True' if the module has been removed, False if it was not found"""
1430  # You can remove instances of these types EDProducer, EDFilter, ESSource,
1431  # ESProducer, Service, or Task,
1432  #
1433  # Mostly this is very intuitive, but there are some complications in cases
1434  # where objects that contain other objects are involved. See the comments
1435  # for the _MutatingSequenceVisitor.
1436  #
1437  # Works very similar to copyAndExclude, there are 2 differences. This changes
1438  # the object itself instead of making a copy and second it only removes
1439  # the first instance of the argument instead of all of them.
1440  if not something._isTaskComponent():
1441  raise TypeError("remove only works with objects that can be placed on a Task")
1442  v = _CopyAndRemoveFirstSequenceVisitor(something)
1443  self.visit(v)
1444  if v.didRemove():
1445  self._collection.clear()
1446  self.add(*v.result(self))
1447  return v.didRemove()
1448 
1449  def resolve(self, processDict,keepIfCannotResolve=False):
1450  temp = OrderedSet()
1451  for i in self._collection:
1452  if isinstance(i, Task) or isinstance(i, TaskPlaceholder):
1453  temp.add(i.resolve(processDict,keepIfCannotResolve))
1454  else:
1455  temp.add(i)
1456  self._collection = temp
1457  return self
1458 
1460  def __init__(self, name):
1461  self._name = name
1462  def _isTaskComponent(self):
1463  return True
1464  def isLeaf(self):
1465  return False
1466  def visit(self,visitor):
1467  pass
1468  def __str__(self):
1469  return self._name
1470  def insertInto(self, parameterSet, myname):
1471  raise RuntimeError("The TaskPlaceholder "+self._name
1472  +" was never overridden")
1473  def resolve(self, processDict,keepIfCannotResolve=False):
1474  if not self._name in processDict:
1475  if keepIfCannotResolve:
1476  return self
1477  raise RuntimeError("The TaskPlaceholder "+self._name+ " cannot be resolved.\n Known keys are:"+str(processDict.keys()))
1478  o = processDict[self._name]
1479  if not o._isTaskComponent():
1480  raise RuntimeError("The TaskPlaceholder "+self._name+ " refers to an object type which is not allowed to be on a task: "+str(type(o)))
1481  if isinstance(o, Task):
1482  return o.resolve(processDict)
1483  return o
1484  def copy(self):
1485  returnValue =TaskPlaceholder.__new__(type(self))
1486  returnValue.__init__(self._name)
1487  return returnValue
1488  def dumpSequencePython(self, options=PrintOptions()):
1489  return 'cms.TaskPlaceholder("%s")'%self._name
1490  def dumpPython(self, options=PrintOptions()):
1491  result = 'cms.TaskPlaceholder(\"'
1492  if options.isCfg:
1493  result += 'process.'
1494  result += +self._name+'\")\n'
1495 
1496 if __name__=="__main__":
1497  import unittest
1499  def __init__(self,name):
1500  self.setLabel(name)
1501  def _isTaskComponent(self):
1502  return True
1503  def __repr__(self):
1504  return self.label_()
1506  def __init__(self,name):
1507  self.setLabel(name)
1508  class TestModuleCommand(unittest.TestCase):
1509  def setUp(self):
1510  """Nothing to do """
1511  pass
1512  def testBoolean(self):
1513  a = DummyBooleanModule("a")
1514  b = DummyBooleanModule("b")
1515  p = Path( a & b)
1516  self.assertEqual(p.dumpPython(None),"cms.Path(process.a&process.b)\n")
1517  l = list()
1518  namesVisitor = DecoratedNodeNameVisitor(l)
1519  p.visit(namesVisitor)
1520  self.assertEqual(l,['&','a','b','@'])
1521  p2 = Path( a | b)
1522  self.assertEqual(p2.dumpPython(None),"cms.Path(process.a|process.b)\n")
1523  l[:]=[]
1524  p2.visit(namesVisitor)
1525  self.assertEqual(l,['|','a','b','@'])
1526  c = DummyBooleanModule("c")
1527  d = DummyBooleanModule("d")
1528  p3 = Path(a & b & c & d)
1529  self.assertEqual(p3.dumpPython(None),"cms.Path(process.a&process.b&process.c&process.d)\n")
1530  l[:]=[]
1531  p3.visit(namesVisitor)
1532  self.assertEqual(l,['&','a','b','c','d','@'])
1533  p3 = Path(((a & b) & c) & d)
1534  self.assertEqual(p3.dumpPython(None),"cms.Path(process.a&process.b&process.c&process.d)\n")
1535  p3 = Path(a & (b & (c & d)))
1536  self.assertEqual(p3.dumpPython(None),"cms.Path(process.a&process.b&process.c&process.d)\n")
1537  p3 = Path((a & b) & (c & d))
1538  self.assertEqual(p3.dumpPython(None),"cms.Path(process.a&process.b&process.c&process.d)\n")
1539  p3 = Path(a & (b & c) & d)
1540  self.assertEqual(p3.dumpPython(None),"cms.Path(process.a&process.b&process.c&process.d)\n")
1541  p4 = Path(a | b | c | d)
1542  self.assertEqual(p4.dumpPython(None),"cms.Path(process.a|process.b|process.c|process.d)\n")
1543  p5 = Path(a | b & c & d )
1544  self.assertEqual(p5.dumpPython(None),"cms.Path(process.a|(process.b&process.c&process.d))\n")
1545  l[:]=[]
1546  p5.visit(namesVisitor)
1547  self.assertEqual(l,['|','a','&','b','c','d','@','@'])
1548  p5 = Path(a & b | c & d )
1549  self.assertEqual(p5.dumpPython(None),"cms.Path((process.a&process.b)|(process.c&process.d))\n")
1550  l[:]=[]
1551  p5.visit(namesVisitor)
1552  self.assertEqual(l,['|','&','a','b','@','&','c','d','@','@'])
1553  p5 = Path(a & (b | c) & d )
1554  self.assertEqual(p5.dumpPython(None),"cms.Path(process.a&(process.b|process.c)&process.d)\n")
1555  l[:]=[]
1556  p5.visit(namesVisitor)
1557  self.assertEqual(l,['&','a','|','b','c','@','d','@'])
1558  p5 = Path(a & b & c | d )
1559  self.assertEqual(p5.dumpPython(None),"cms.Path((process.a&process.b&process.c)|process.d)\n")
1560  l[:]=[]
1561  p5.visit(namesVisitor)
1562  self.assertEqual(l,['|','&','a','b','c','@','d','@'])
1563  p6 = Path( a & ~b)
1564  self.assertEqual(p6.dumpPython(None),"cms.Path(process.a&(~process.b))\n")
1565  l[:]=[]
1566  p6.visit(namesVisitor)
1567  self.assertEqual(l,['&','a','!b','@'])
1568  p6 = Path( a & ignore(b))
1569  self.assertEqual(p6.dumpPython(None),"cms.Path(process.a&(cms.ignore(process.b)))\n")
1570  l[:]=[]
1571  p6.visit(namesVisitor)
1572  self.assertEqual(l,['&','a','-b','@'])
1573  p6 = Path(~(a&b))
1574  self.assertEqual(p6.dumpPython(None),"cms.Path(~(process.a&process.b))\n")
1575  l[:]=[]
1576  p6.visit(namesVisitor)
1577  self.assertEqual(l,['!&','a','b','@'])
1578 
1579  def testDumpPython(self):
1580  a = DummyModule("a")
1581  b = DummyModule('b')
1582  p = Path((a*b))
1583  #print p.dumpConfig('')
1584  self.assertEqual(p.dumpPython(None),"cms.Path(process.a+process.b)\n")
1585  p2 = Path((b+a))
1586  #print p2.dumpConfig('')
1587  self.assertEqual(p2.dumpPython(None),"cms.Path(process.b+process.a)\n")
1588  c = DummyModule('c')
1589  p3 = Path(c*(a+b))
1590  #print p3.dumpConfig('')
1591  self.assertEqual(p3.dumpPython(None),"cms.Path(process.c+process.a+process.b)\n")
1592  p4 = Path(c*a+b)
1593  #print p4.dumpConfig('')
1594  self.assertEqual(p4.dumpPython(None),"cms.Path(process.c+process.a+process.b)\n")
1595  p5 = Path(a+ignore(b))
1596  #print p5.dumpConfig('')
1597  self.assertEqual(p5.dumpPython(None),"cms.Path(process.a+cms.ignore(process.b))\n")
1598  p6 = Path(c+a*b)
1599  #print p6.dumpConfig('')
1600  self.assertEqual(p6.dumpPython(None),"cms.Path(process.c+process.a+process.b)\n")
1601  p7 = Path(a+~b)
1602  self.assertEqual(p7.dumpPython(None),"cms.Path(process.a+~process.b)\n")
1603  p8 = Path((a+b)*c)
1604  self.assertEqual(p8.dumpPython(None),"cms.Path(process.a+process.b+process.c)\n")
1605  t1 = Task(a)
1606  t2 = Task(c, b)
1607  t3 = Task()
1608  p9 = Path((a+b)*c, t1)
1609  self.assertEqual(p9.dumpPython(None),"cms.Path(process.a+process.b+process.c, cms.Task(process.a))\n")
1610  p10 = Path((a+b)*c, t2, t1)
1611  self.assertEqual(p10.dumpPython(None),"cms.Path(process.a+process.b+process.c, cms.Task(process.a), cms.Task(process.b, process.c))\n")
1612  p11 = Path(t1, t2, t3)
1613  self.assertEqual(p11.dumpPython(None),"cms.Path(cms.Task(), cms.Task(process.a), cms.Task(process.b, process.c))\n")
1614  d = DummyModule("d")
1615  e = DummyModule('e')
1616  f = DummyModule('f')
1617  t4 = Task(d, Task(f))
1618  s = Sequence(e, t4)
1619  p12 = Path(a+b+s+c,t1)
1620  self.assertEqual(p12.dumpPython(None),"cms.Path(process.a+process.b+cms.Sequence(process.e, cms.Task(process.d, process.f))+process.c, cms.Task(process.a))\n")
1621  l = list()
1622  namesVisitor = DecoratedNodeNameVisitor(l)
1623  p.visit(namesVisitor)
1624  self.assertEqual(l, ['a', 'b'])
1625  l[:] = []
1626  p5.visit(namesVisitor)
1627  self.assertEqual(l, ['a', '-b'])
1628  l[:] = []
1629  p7.visit(namesVisitor)
1630  self.assertEqual(l, ['a', '!b'])
1631  l[:] = []
1632  p10.visit(namesVisitor)
1633  self.assertEqual(l, ['a', 'b', 'c'])
1634  l[:] = []
1635  p12.visit(namesVisitor)
1636  self.assertEqual(l, ['a', 'b', 'e', 'c'])
1637  l[:] = []
1638  moduleVisitor = ModuleNodeVisitor(l)
1639  p8.visit(moduleVisitor)
1640  names = [m.label_() for m in l]
1641  self.assertEqual(names, ['a', 'b', 'c'])
1642  def testDumpConfig(self):
1643  a = DummyModule("a")
1644  b = DummyModule('b')
1645  p = Path((a*b))
1646  #print p.dumpConfig('')
1647  self.assertEqual(p.dumpConfig(None),"{a&b}\n")
1648  p2 = Path((b+a))
1649  #print p2.dumpConfig('')
1650  self.assertEqual(p2.dumpConfig(None),"{b&a}\n")
1651  c = DummyModule('c')
1652  p3 = Path(c*(a+b))
1653  #print p3.dumpConfig('')
1654  self.assertEqual(p3.dumpConfig(None),"{c&a&b}\n")
1655  p4 = Path(c*a+b)
1656  #print p4.dumpConfig('')
1657  self.assertEqual(p4.dumpConfig(None),"{c&a&b}\n")
1658  p5 = Path(a+ignore(b))
1659  #print p5.dumpConfig('')
1660  self.assertEqual(p5.dumpConfig(None),"{a&-b}\n")
1661  p6 = Path(c+a*b)
1662  #print p6.dumpConfig('')
1663  self.assertEqual(p6.dumpConfig(None),"{c&a&b}\n")
1664  p7 = Path(a+~b)
1665  self.assertEqual(p7.dumpConfig(None),"{a&!b}\n")
1666  p8 = Path((a+b)*c)
1667  self.assertEqual(p8.dumpConfig(None),"{a&b&c}\n")
1668  def testVisitor(self):
1669  class TestVisitor(object):
1670  def __init__(self, enters, leaves):
1671  self._enters = enters
1672  self._leaves = leaves
1673  def enter(self,visitee):
1674  #print visitee.dumpSequencePython()
1675  if self._enters[0] != visitee:
1676  raise RuntimeError("wrong node ("+str(visitee)+") on 'enter'")
1677  else:
1678  self._enters = self._enters[1:]
1679  def leave(self,visitee):
1680  if self._leaves[0] != visitee:
1681  raise RuntimeError("wrong node ("+str(visitee)+") on 'leave'\n expected ("+str(self._leaves[0])+")")
1682  else:
1683  self._leaves = self._leaves[1:]
1684  a = DummyModule("a")
1685  b = DummyModule('b')
1686  multAB = a*b
1687  p = Path(multAB)
1688  t = TestVisitor(enters=[a,b],
1689  leaves=[a,b])
1690  p.visit(t)
1691 
1692  plusAB = a+b
1693  p = Path(plusAB)
1694  t = TestVisitor(enters=[a,b],
1695  leaves=[a,b])
1696  p.visit(t)
1697 
1698  c=DummyModule("c")
1699  d=DummyModule("d")
1700  e=DummyModule("e")
1701  f=DummyModule("f")
1702  g=DummyModule("g")
1703  t1 = Task(d)
1704  t2 = Task(e, t1)
1705  t3 = Task(f, g, t2)
1706  s=Sequence(plusAB, t3, t2)
1707  multSC = s*c
1708  p=Path(multSC, t1, t2)
1709 
1710  l = []
1711  v = ModuleNodeVisitor(l)
1712  p.visit(v)
1713  expected = [a,b,f,g,e,d,e,d,c,d,e,d]
1714 
1715  l[:] = []
1717  p.visit(v)
1718  expected = [f,g,e,d,e,d,d,e,d]
1719  self.assertEqual(expected,l)
1720 
1721  l[:] = []
1723  p.visit(v)
1724  expected = [a,b,c]
1725  self.assertEqual(expected,l)
1726 
1727 
1728  t=TestVisitor(enters=[s,a,b,t3,f,g,t2,e,t1,d,t2,e,t1,d,c,t1,d,t2,e,t1,d],
1729  leaves=[a,b,f,g,e,d,t1,t2,t3,e,d,t1,t2,s,c,d,t1,e,d,t1,t2])
1730  p.visit(t)
1731 
1732  notA= ~a
1733  p=Path(notA)
1734  t=TestVisitor(enters=[notA,a],leaves=[a,notA])
1735  p.visit(t)
1736  def testResolve(self):
1737  m1 = DummyModule("m1")
1738  m2 = DummyModule("m2")
1739  s1 = Sequence(m1)
1740  s2 = SequencePlaceholder("s3")
1741  s3 = Sequence(m2)
1742  p = Path(s1*s2)
1743  l = list()
1744  d = dict()
1745  d['s1'] = s1
1746  d['s2'] = s2
1747  d['s3'] = s3
1748  #resolver = ResolveVisitor(d)
1749  #p.visit(resolver)
1750  namesVisitor = DecoratedNodeNameVisitor(l)
1751  p.visit(namesVisitor)
1752  self.assertEqual(l, ['m1'])
1753  p.resolve(d)
1754  l[:] = []
1755  p.visit(namesVisitor)
1756  self.assertEqual(l, ['m1', 'm2'])
1757  l[:]=[]
1758  s1 = Sequence(m1)
1759  s2 = SequencePlaceholder("s3")
1760  s3 = Sequence(m2)
1761  s4 = SequencePlaceholder("s2")
1762  p=Path(s1+s4)
1763  p.resolve(d)
1764  p.visit(namesVisitor)
1765  self.assertEqual(l, ['m1', 'm2'])
1766  def testReplace(self):
1767  m1 = DummyModule("m1")
1768  m2 = DummyModule("m2")
1769  m3 = DummyModule("m3")
1770  m4 = DummyModule("m4")
1771  m5 = DummyModule("m5")
1772 
1773  s1 = Sequence(m1*~m2*m1*m2*ignore(m2))
1774  s2 = Sequence(m1*m2)
1775  l = []
1776  namesVisitor = DecoratedNodeNameVisitor(l)
1777  s1.visit(namesVisitor)
1778  self.assertEqual(l,['m1', '!m2', 'm1', 'm2', '-m2'])
1779 
1780  s3 = Sequence(~m1*s2)
1781  s3.replace(~m1, m2)
1782  l[:] = []
1783  s3.visit(namesVisitor)
1784  self.assertEqual(l, ['m2', 'm1', 'm2'])
1785  s3.replace(m2, ~m1)
1786  l[:] = []
1787  s3.visit(namesVisitor)
1788  self.assertEqual(l, ['!m1', 'm1', '!m1'])
1789 
1790  s3 = Sequence(ignore(m1)*s2)
1791  s3.replace(ignore(m1), m2)
1792  l[:] = []
1793  s3.visit(namesVisitor)
1794  self.assertEqual(l, ['m2', 'm1', 'm2'])
1795  s3.replace(m2, ignore(m1))
1796  l[:] = []
1797  s3.visit(namesVisitor)
1798  self.assertEqual(l, ['-m1', 'm1', '-m1'])
1799 
1800  ph = SequencePlaceholder('x')
1801  s4 = Sequence(Sequence(ph))
1802  s4.replace(ph,m2)
1803  self.assertEqual(s4.dumpPython(None), "cms.Sequence(process.m2)\n")
1804 
1805  s1.replace(m2,m3)
1806  l[:] = []
1807  s1.visit(namesVisitor)
1808  self.assertEqual(l,['m1', '!m3', 'm1', 'm3', '-m3'])
1809  s2 = Sequence(m1*m2)
1810  s3 = Sequence(~m1*s2)
1811  l[:] = []
1812  s3.visit(namesVisitor)
1813  self.assertEqual(l,['!m1', 'm1', 'm2'])
1814  l[:] = []
1815  s3.replace(s2,m1)
1816  s3.visit(namesVisitor)
1817  self.assertEqual(l,['!m1', 'm1'])
1818 
1819  s1 = Sequence(m1+m2)
1820  s2 = Sequence(m3+m4)
1821  s3 = Sequence(s1+s2)
1822  s3.replace(m3,m5)
1823  l[:] = []
1824  s3.visit(namesVisitor)
1825  self.assertEqual(l,['m1','m2','m5','m4'])
1826 
1827  m6 = DummyModule("m6")
1828  m7 = DummyModule("m7")
1829  m8 = DummyModule("m8")
1830  m9 = DummyModule("m9")
1831 
1832  t6 = Task(m6)
1833  t7 = Task(m7)
1834  t89 = Task(m8, m9)
1835 
1836  s1 = Sequence(m1+m2, t6)
1837  s2 = Sequence(m3+m4, t7)
1838  s3 = Sequence(s1+s2, t89)
1839  s3.replace(m3,m5)
1840  l[:] = []
1841  s3.visit(namesVisitor)
1842  self.assertEqual(l,['m1','m2','m5','m4'])
1843 
1844  s3.replace(m8,m1)
1845  self.assertTrue(s3.dumpPython(None) == "cms.Sequence(cms.Sequence(process.m1+process.m2, cms.Task(process.m6))+process.m5+process.m4, cms.Task(process.m1, process.m9), cms.Task(process.m7))\n")
1846 
1847  s3.replace(m1,m7)
1848  self.assertTrue(s3.dumpPython(None) == "cms.Sequence(process.m7+process.m2+process.m5+process.m4, cms.Task(process.m6), cms.Task(process.m7), cms.Task(process.m7, process.m9))\n")
1849  result = s3.replace(t7, t89)
1850  self.assertTrue(s3.dumpPython(None) == "cms.Sequence(process.m7+process.m2+process.m5+process.m4, cms.Task(process.m6), cms.Task(process.m7, process.m9), cms.Task(process.m8, process.m9))\n")
1851  self.assertTrue(result)
1852  result = s3.replace(t7, t89)
1853  self.assertFalse(result)
1854 
1855  t1 = Task()
1856  t1.replace(m1,m2)
1857  self.assertTrue(t1.dumpPython(None) == "cms.Task()\n")
1858 
1859  t1 = Task(m1)
1860  t1.replace(m1,m2)
1861  self.assertTrue(t1.dumpPython(None) == "cms.Task(process.m2)\n")
1862 
1863  t1 = Task(m1,m2, m2)
1864  t1.replace(m2,m3)
1865  self.assertTrue(t1.dumpPython(None) == "cms.Task(process.m1, process.m3)\n")
1866 
1867  t1 = Task(m1,m2)
1868  t2 = Task(m1,m3,t1)
1869  t2.replace(m1,m4)
1870  self.assertTrue(t2.dumpPython(None) == "cms.Task(process.m2, process.m3, process.m4)\n")
1871 
1872  t1 = Task(m2)
1873  t2 = Task(m1,m3,t1)
1874  t2.replace(m1,m4)
1875  self.assertTrue(t2.dumpPython(None) == "cms.Task(process.m2, process.m3, process.m4)\n")
1876 
1877  t1 = Task(m2)
1878  t2 = Task(m1,m3,t1)
1879  t2.replace(t1,m4)
1880  self.assertTrue(t2.dumpPython(None) == "cms.Task(process.m1, process.m3, process.m4)\n")
1881 
1882  t1 = Task(m2)
1883  t2 = Task(m1,m3,t1)
1884  t3 = Task(m5)
1885  t2.replace(m2,t3)
1886  self.assertTrue(t2.dumpPython(None) == "cms.Task(process.m1, process.m3, process.m5)\n")
1887 
1888  def testIndex(self):
1889  m1 = DummyModule("a")
1890  m2 = DummyModule("b")
1891  m3 = DummyModule("c")
1892 
1893  s = Sequence(m1+m2+m3)
1894  self.assertEqual(s.index(m1),0)
1895  self.assertEqual(s.index(m2),1)
1896  self.assertEqual(s.index(m3),2)
1897 
1898  def testInsert(self):
1899  m1 = DummyModule("a")
1900  m2 = DummyModule("b")
1901  m3 = DummyModule("c")
1902  s = Sequence(m1+m3)
1903  s.insert(1,m2)
1904  self.assertEqual(s.index(m1),0)
1905  self.assertEqual(s.index(m2),1)
1906  self.assertEqual(s.index(m3),2)
1907 
1908  s = Sequence()
1909  s.insert(0, m1)
1910  self.assertEqual(s.index(m1),0)
1911 
1912  p = Path()
1913  p.insert(0, m1)
1914  self.assertEqual(s.index(m1),0)
1915 
1917  m1 = DummyModule("m1")
1918  m2 = DummyModule("m2")
1919  m3 = DummyModule("m3")
1920  m4 = DummyModule("m4")
1921  m5 = DummyModule("m5")
1922 
1923  s1 = Sequence(m1*~m2*m1*m2*ignore(m2))
1924  s2 = Sequence(m1*m2)
1925  s3 = Sequence(~m1*s2)
1926 
1927  p = Path(s1+s3)
1928  p2 = p.expandAndClone()
1929  l = []
1930  namesVisitor = DecoratedNodeNameVisitor(l)
1931  p2.visit(namesVisitor)
1932  self.assertEqual(l, ['m1', '!m2', 'm1', 'm2', '-m2', '!m1', 'm1', 'm2'])
1933 
1934  m6 = DummyModule("m6")
1935  m7 = DummyModule("m7")
1936  m8 = DummyModule("m8")
1937  m9 = DummyModule("m9")
1938  p = Path(s1+s3, Task(m6))
1939  p2 = p.expandAndClone()
1940  l[:] = []
1941  p2.visit(namesVisitor)
1942  self.assertEqual(l, ['m1', '!m2', 'm1', 'm2', '-m2', '!m1', 'm1', 'm2'])
1943  self.assertTrue(p2.dumpPython(None) == "cms.Path(process.m1+~process.m2+process.m1+process.m2+cms.ignore(process.m2)+~process.m1+process.m1+process.m2, cms.Task(process.m6))\n")
1944 
1945  s2 = Sequence(m1*m2, Task(m9))
1946  s3 = Sequence(~m1*s2)
1947  t8 = Task(m8)
1948  t8.setLabel("t8")
1949  p = Path(s1+s3, Task(m6, Task(m7, t8)))
1950  p2 = p.expandAndClone()
1951  l[:] = []
1952  p2.visit(namesVisitor)
1953  self.assertEqual(l, ['m1', '!m2', 'm1', 'm2', '-m2', '!m1', 'm1', 'm2'])
1954  self.assertTrue(p2.dumpPython(None) == "cms.Path(process.m1+~process.m2+process.m1+process.m2+cms.ignore(process.m2)+~process.m1+process.m1+process.m2, cms.Task(process.m6, process.m7, process.m8, process.m9))\n")
1955 
1956  t1 = Task(m1,m2,m3)
1957  s1 = Sequence(t1)
1958  s2 = s1.expandAndClone()
1959  l[:] = []
1960  s2.visit(namesVisitor)
1961  self.assertEqual(l, [])
1962  self.assertTrue(s2.dumpPython(None) == "cms.Sequence(cms.Task(process.m1, process.m2, process.m3))\n")
1963 
1964  t1 = Task(m1,m2)
1965  t2 = Task(m1,m3,t1)
1966  t3 = t2.expandAndClone()
1967  self.assertTrue(t3.dumpPython(None) == "cms.Task(process.m1, process.m2, process.m3)\n")
1968  t4 = Task()
1969  t5 = t4.expandAndClone()
1970  self.assertTrue(t5.dumpPython(None) == "cms.Task()\n")
1971  def testAdd(self):
1972  m1 = DummyModule("m1")
1973  m2 = DummyModule("m2")
1974  m3 = DummyModule("m3")
1975  m4 = DummyModule("m4")
1976  s1 = Sequence(m1)
1977  s3 = Sequence(m3+ignore(m4))
1978  p = Path(s1)
1979  p += ~m2
1980  p *= s3
1981 
1982  l = []
1983  namesVisitor = DecoratedNodeNameVisitor(l)
1984  p.visit(namesVisitor)
1985  self.assertEqual(l, ['m1', '!m2', 'm3', '-m4'])
1986 
1987  s4 = Sequence()
1988  s4 +=m1
1989  l[:]=[]; s1.visit(namesVisitor); self.assertEqual(l,['m1'])
1990  self.assertEqual(s4.dumpPython(None),"cms.Sequence(process.m1)\n")
1991  s4 = Sequence()
1992  s4 *=m1
1993  l[:]=[]; s1.visit(namesVisitor); self.assertEqual(l,['m1'])
1994  self.assertEqual(s4.dumpPython(None),"cms.Sequence(process.m1)\n")
1995 
1996 
1997  def testRemove(self):
1998  m1 = DummyModule("m1")
1999  m2 = DummyModule("m2")
2000  m3 = DummyModule("m3")
2001  m4 = DummyModule("m4")
2002  s1 = Sequence(m1*m2+~m3)
2003  s2 = Sequence(m1*s1)
2004  l = []
2005  namesVisitor = DecoratedNodeNameVisitor(l)
2006  d = {'m1':m1 ,'m2':m2, 'm3':m3,'s1':s1, 's2':s2}
2007  l[:] = []; s1.visit(namesVisitor); self.assertEqual(l,['m1', 'm2', '!m3'])
2008  l[:] = []; s2.visit(namesVisitor); self.assertEqual(l,['m1', 'm1', 'm2', '!m3'])
2009  s1.remove(m2)
2010  l[:] = []; s1.visit(namesVisitor); self.assertEqual(l,['m1', '!m3'])
2011  l[:] = []; s2.visit(namesVisitor); self.assertEqual(l,['m1', 'm1', '!m3'])
2012  s2.remove(m3)
2013  l[:] = []; s1.visit(namesVisitor); self.assertEqual(l,['m1', '!m3'])
2014  l[:] = []; s2.visit(namesVisitor); self.assertEqual(l,['m1', 'm1'])
2015  s1 = Sequence( m1 + m2 + m1 + m2 )
2016  l[:] = []; s1.visit(namesVisitor); self.assertEqual(l,['m1', 'm2', 'm1', 'm2'])
2017  s1.remove(m2)
2018  l[:] = []; s1.visit(namesVisitor); self.assertEqual(l,['m1', 'm1', 'm2'])
2019  s1 = Sequence( m1 + m3 )
2020  s2 = Sequence( m2 + ignore(m3) + s1 + m3 )
2021  l[:] = []; s2.visit(namesVisitor); self.assertEqual(l,['m2', '-m3', 'm1', 'm3', 'm3'])
2022  s2.remove(s1)
2023  l[:] = []; s2.visit(namesVisitor); self.assertEqual(l,['m2', '-m3', 'm3'])
2024  s2.remove(m3)
2025  l[:] = []; s2.visit(namesVisitor); self.assertEqual(l,['m2','m3'])
2026  s1 = Sequence(m1*m2*m3)
2027  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m2+process.m3)\n")
2028  s1.remove(m2)
2029  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m3)\n")
2030  s1 = Sequence(m1+m2+m3)
2031  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m2+process.m3)\n")
2032  s1.remove(m2)
2033  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m3)\n")
2034  s1 = Sequence(m1*m2+m3)
2035  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m2+process.m3)\n")
2036  s1.remove(m2)
2037  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m3)\n")
2038  s1 = Sequence(m1+m2*m3)
2039  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m2+process.m3)\n")
2040  s1.remove(m2)
2041  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m3)\n")
2042  s1.remove(m1)
2043  s1.remove(m3)
2044  l[:]=[]; s1.visit(namesVisitor); self.assertEqual(l,[])
2045  self.assertEqual(s1.dumpPython(None), "cms.Sequence()\n")
2046  s3 = Sequence(m1)
2047  s3.remove(m1)
2048  l[:]=[]; s3.visit(namesVisitor); self.assertEqual(l,[])
2049  self.assertEqual(s3.dumpPython(None), "cms.Sequence()\n")
2050  s3 = Sequence(m1)
2051  s4 = Sequence(s3)
2052  s4.remove(m1)
2053  l[:]=[]; s4.visit(namesVisitor); self.assertEqual(l,[])
2054  self.assertEqual(s4.dumpPython(None), "cms.Sequence()\n")
2055  s1 = Sequence(m1+m2, Task(m3), Task(m4))
2056  s1.remove(m4)
2057  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m2, cms.Task(process.m3))\n")
2058  s1 = Sequence(m1+m2+Sequence(Task(m3,m4), Task(m3), Task(m4)))
2059  s1.remove(m4)
2060  self.assertEqual(s1.dumpPython(None), "cms.Sequence(process.m1+process.m2, cms.Task(process.m3), cms.Task(process.m4))\n")
2061  t1 = Task(m1)
2062  t1.setLabel("t1")
2063  t2 = Task(m2,t1)
2064  t2.setLabel("t2")
2065  t3 = Task(t1,t2,m1)
2066  t3.remove(m1)
2067  self.assertTrue(t3.dumpPython(None) == "cms.Task(process.m1, process.t2)\n")
2068  t3.remove(m1)
2069  self.assertTrue(t3.dumpPython(None) == "cms.Task(process.m1, process.m2)\n")
2070  t3.remove(m1)
2071  self.assertTrue(t3.dumpPython(None) == "cms.Task(process.m2)\n")
2072  t3.remove(m2)
2073  self.assertTrue(t3.dumpPython(None) == "cms.Task()\n")
2074 
2076  a = DummyModule("a")
2077  b = DummyModule("b")
2078  c = DummyModule("c")
2079  d = DummyModule("d")
2080  s = Sequence(a+b+c)
2081  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c)\n")
2082  s = Sequence(a+b+c+d)
2083  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2084  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2085  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+process.d)\n")
2086  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c)\n")
2087  s=Sequence(a*b+c+d)
2088  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2089  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2090  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+process.d)\n")
2091  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c)\n")
2092  s = Sequence(a+b*c+d)
2093  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2094  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2095  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+process.d)\n")
2096  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c)\n")
2097  s2 = Sequence(a+b)
2098  s = Sequence(c+s2+d)
2099  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.c+process.b+process.d)\n")
2100  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.c+process.a+process.d)\n")
2101  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence((process.a+process.b)+process.d)\n")
2102  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.c+(process.a+process.b))\n")
2103  self.assertEqual(s.copyAndExclude([a,b]).dumpPython(None),"cms.Sequence(process.c+process.d)\n")
2104  s3 = s.copyAndExclude([c])
2105  s2.remove(a)
2106  self.assertEqual(s3.dumpPython(None),"cms.Sequence((process.b)+process.d)\n")
2107  s4 = s.copyAndExclude([a,b])
2108  seqs = []
2109  sequenceVisitor = SequenceVisitor(seqs)
2110  s.visit(sequenceVisitor)
2111  self.assertEqual(len(seqs),1)
2112  seqs[:] = []
2113  s4.visit(sequenceVisitor)
2114  self.assertEqual(len(seqs),0)
2115  self.assertEqual(s4.dumpPython(None),"cms.Sequence(process.c+process.d)\n")
2116  holder = SequencePlaceholder("x")
2117  s3 = Sequence(b+d,Task(a))
2118  s2 = Sequence(a+b+holder+s3)
2119  s = Sequence(c+s2+d)
2120  seqs[:] = []
2121  s.visit(sequenceVisitor)
2122  self.assertTrue(seqs == [s2,s3])
2123  s2 = Sequence(a+b+holder)
2124  s = Sequence(c+s2+d)
2125  self.assertEqual(s.copyAndExclude([holder]).dumpPython(None),"cms.Sequence(process.c+process.a+process.b+process.d)\n")
2126  s2 = Sequence(a+b+c)
2127  s = Sequence(s2+d)
2128  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2129  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2130  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+process.d)\n")
2131  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence((process.a+process.b+process.c))\n")
2132  self.assertEqual(s.copyAndExclude([s2]).dumpPython(None),"cms.Sequence(process.d)\n")
2133  s2 = Sequence(a+b+c)
2134  s = Sequence(s2*d)
2135  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2136  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2137  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+process.d)\n")
2138  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence((process.a+process.b+process.c))\n")
2139  self.assertEqual(s.copyAndExclude([a,b,c]).dumpPython(None),"cms.Sequence(process.d)\n")
2140  s = Sequence(ignore(a)+b+c+d)
2141  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2142  self.assertEqual(s.copyAndExclude([ignore(a)]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2143  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(cms.ignore(process.a)+process.c+process.d)\n")
2144  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(cms.ignore(process.a)+process.b+process.d)\n")
2145  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(cms.ignore(process.a)+process.b+process.c)\n")
2146  s = Sequence(a+ignore(b)+c+d)
2147  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(cms.ignore(process.b)+process.c+process.d)\n")
2148  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2149  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+cms.ignore(process.b)+process.d)\n")
2150  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+cms.ignore(process.b)+process.c)\n")
2151  s = Sequence(a+b+c+ignore(d))
2152  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+cms.ignore(process.d))\n")
2153  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+cms.ignore(process.d))\n")
2154  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+cms.ignore(process.d))\n")
2155  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c)\n")
2156  s = Sequence(~a+b+c+d)
2157  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+process.d)\n")
2158  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(~process.a+process.c+process.d)\n")
2159  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(~process.a+process.b+process.d)\n")
2160  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(~process.a+process.b+process.c)\n")
2161  s = Sequence(a+~b+c+d)
2162  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(~process.b+process.c+process.d)\n")
2163  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2164  self.assertEqual(s.copyAndExclude([~b]).dumpPython(None),"cms.Sequence(process.a+process.c+process.d)\n")
2165  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+~process.b+process.d)\n")
2166  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+~process.b+process.c)\n")
2167  s = Sequence(a+b+c+~d)
2168  self.assertEqual(s.copyAndExclude([a]).dumpPython(None),"cms.Sequence(process.b+process.c+~process.d)\n")
2169  self.assertEqual(s.copyAndExclude([b]).dumpPython(None),"cms.Sequence(process.a+process.c+~process.d)\n")
2170  self.assertEqual(s.copyAndExclude([c]).dumpPython(None),"cms.Sequence(process.a+process.b+~process.d)\n")
2171  self.assertEqual(s.copyAndExclude([d]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c)\n")
2172  self.assertEqual(s.copyAndExclude([a,b,c,d]).dumpPython(None),"cms.Sequence()\n")
2173 
2174  e = DummyModule("e")
2175  f = DummyModule("f")
2176  g = DummyModule("g")
2177  h = DummyModule("h")
2178  t1 = Task(h)
2179  s = Sequence(a+b+c+~d, Task(e,f,Task(g,t1)))
2180  self.assertEqual(s.copyAndExclude([a,h]).dumpPython(None),"cms.Sequence(process.b+process.c+~process.d, cms.Task(process.e, process.f, process.g))\n")
2181  self.assertEqual(s.copyAndExclude([a,h]).dumpPython(None),"cms.Sequence(process.b+process.c+~process.d, cms.Task(process.e, process.f, process.g))\n")
2182  self.assertEqual(s.copyAndExclude([a,e,h]).dumpPython(None),"cms.Sequence(process.b+process.c+~process.d, cms.Task(process.f, process.g))\n")
2183  self.assertEqual(s.copyAndExclude([a,e,f,g,h]).dumpPython(None),"cms.Sequence(process.b+process.c+~process.d)\n")
2184  self.assertEqual(s.copyAndExclude([a,b,c,d]).dumpPython(None),"cms.Sequence(cms.Task(process.e, process.f, process.g, process.h))\n")
2185  self.assertEqual(s.copyAndExclude([t1]).dumpPython(None),"cms.Sequence(process.a+process.b+process.c+~process.d, cms.Task(process.e, process.f, process.g))\n")
2186  taskList = []
2187  taskVisitor = TaskVisitor(taskList)
2188  s.visit(taskVisitor)
2189  self.assertEqual(len(taskList),3)
2190  s2 = s.copyAndExclude([g,h])
2191  taskList[:] = []
2192  s2.visit(taskVisitor)
2193  self.assertEqual(len(taskList),1)
2194  t2 = Task(t1)
2195  taskList[:] = []
2196  t2.visit(taskVisitor)
2197  self.assertEqual(taskList[0],t1)
2198  s3 = Sequence(s)
2199  self.assertEqual(s3.copyAndExclude([a,h]).dumpPython(None),"cms.Sequence(process.b+process.c+~process.d, cms.Task(process.e, process.f, process.g))\n")
2200  s4 = Sequence(s)
2201  self.assertEqual(s4.copyAndExclude([a,b,c,d,e,f,g,h]).dumpPython(None),"cms.Sequence()\n")
2202  t1 = Task(e,f)
2203  t11 = Task(a)
2204  t11.setLabel("t11")
2205  t2 = Task(g,t1,h,t11)
2206  t3 = t2.copyAndExclude([e,h])
2207  self.assertTrue(t3.dumpPython(None) == "cms.Task(process.f, process.g, process.t11)\n")
2208  t4 = t2.copyAndExclude([e,f,g,h,a])
2209  self.assertTrue(t4.dumpPython(None) == "cms.Task()\n")
2211  m1 = DummyModule("m1")
2212  m2 = DummyModule("m2")
2213  s1 = Sequence(m1*m2)
2214  def testRaise():
2215  s1.something = 1
2216  self.assertRaises(AttributeError,testRaise)
2217  def testRaise2():
2218  s2 = Sequence(m1*None)
2219  self.assertRaises(TypeError,testRaise2)
2220  def testCopy(self):
2221  a = DummyModule("a")
2222  b = DummyModule("b")
2223  c = DummyModule("c")
2224  p1 = Path(a+b+c)
2225  p2 = p1.copy()
2226  e = DummyModule("e")
2227  p2.replace(b,e)
2228  self.assertEqual(p1.dumpPython(None),"cms.Path(process.a+process.b+process.c)\n")
2229  self.assertEqual(p2.dumpPython(None),"cms.Path(process.a+process.e+process.c)\n")
2230  p1 = Path(a+b+c)
2231  p2 = p1.copy()
2232  p1 += e
2233  self.assertEqual(p1.dumpPython(None),"cms.Path(process.a+process.b+process.c+process.e)\n")
2234  self.assertEqual(p2.dumpPython(None),"cms.Path(process.a+process.b+process.c)\n")
2235  t1 = Task(a, b)
2236  t2 = t1.copy()
2237  self.assertTrue(t1.dumpPython(None) == t2.dumpPython(None))
2238  t1Contents = list(t1._collection)
2239  t2Contents = list(t2._collection)
2240  self.assertTrue(id(t1Contents[0]) == id(t2Contents[0]))
2241  self.assertTrue(id(t1Contents[1]) == id(t2Contents[1]))
2242  self.assertTrue(id(t1._collection) != id(t2._collection))
2243  def testInsertInto(self):
2244  from FWCore.ParameterSet.Types import vstring
2245  class TestPSet(object):
2246  def __init__(self):
2247  self._dict = dict()
2248  def addVString(self,isTracked,label,value):
2249  self._dict[label]=value
2250  a = DummyModule("a")
2251  b = DummyModule("b")
2252  c = DummyModule("c")
2253  d = DummyModule("d")
2254  p = Path(a+b+c+d)
2255  decoratedList = []
2256  lister = DecoratedNodeNameVisitor(decoratedList)
2257  p.visit(lister)
2258  ps = TestPSet()
2259  p.insertInto(ps,"p",decoratedList)
2260  self.assertEqual(ps._dict, {"p":vstring("a","b","c","d")})
2261  s = Sequence(b+c)
2262  p = Path(a+s+d)
2263  decoratedList[:] = []
2264  p.visit(lister)
2265  ps = TestPSet()
2266  p.insertInto(ps,"p",decoratedList)
2267  self.assertEqual(ps._dict, {"p":vstring("a","b","c","d")})
2268 
2269  unittest.main()
def __init__(self, arg, argv)
def _postProcessFixup(self, lookuptable)
def dumpSequencePython(self, options=PrintOptions())
def enter(self, visitee)
def replace(self, original, replacement)
def __init__(self, arg, argv)
def label_(self)
Definition: Mixins.py:489
def dumpPython(self, options=PrintOptions())
Definition: Mixins.py:72
def dumpSequencePython(self, options=PrintOptions())
def __init__(self, arg, argv)
def fillContents(self, taskContents, options=PrintOptions())
def dumpSequencePython(self, options=PrintOptions())
def associate(self, tasks)
def _findDependencies(self, knownDeps, presentDeps)
def insertInto(self, parameterSet, myname)
def insertInto(self, parameterSet, myname, decoratedList)
def dumpSequencePython(self, options=PrintOptions())
def _replace(self, original, replacement)
def _clonesequence(self, lookuptable)
def dumpPython(self, options=PrintOptions())
def dumpSequencePython(self, options=PrintOptions())
def dumpSequencePython(self, options=PrintOptions())
def dumpPython(self, options=PrintOptions())
def insertInto(self, parameterSet, myname)
def resolve(self, processDict, keepIfCannotResolve=False)
def __init__(self, operand)
def nameInProcessDesc_(self, myname)
def _isTaskComponent(self)
def setLabel(self, label)
Definition: Mixins.py:495
def _place(self, label, process)
def _visitSubNodes(self, visitor)
def format_typename(object)
def resolve(self, processDict, keepIfCannotResolve=False)
def remove(self, something)
def _place(self, name, proc)
def format_outerframe(number)
def add(self, items)
def _visitSubNodes(self, visitor)
def _clonesequence(self, lookuptable)
def _placeImpl(self, name, proc)
def resolve(self, processDict, keepIfCannotResolve=False)
def dumpPython(self, options=PrintOptions())
def resolve(self, processDict, keepIfCannotResolve=False)
def leave(self, visitee)
def expandAndClone(self)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def __init__(self, arg, argv)
def __dummy(self, args)
def dumpSequencePython(self, options=PrintOptions())
def ignore(seq)
def _placeImpl(self, name, proc)
def replace(self, original, replacement)
def leave(self, visitee)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def _appendToCollection(self, collection)
def __init__(self, op, left, right)
def enter(self, visitee)
def copyAndExclude(self, listOfModulesToExclude)
def _appendToCollection(self, collection)
def resolve(self, processDict, keepIfCannotResolve=False)
def resolve(self, processDict, keepIfCannotResolve=False)
def dumpPython(self, options=PrintOptions())
def dumpPython(process, name)
def insert(self, index, item)
def visit(self, visitor)
def result(self, visitedContainer)
def dumpPythonNoNewline(self, options=PrintOptions())
def _clonesequence(self, lookuptable)
def _placeImpl(self, name, proc)
def __setattr__(self, name, value)
def __setattr__(self, name, value)
def hasLabel_(self)
Definition: Mixins.py:493
def dumpPython(self, options=PrintOptions())
def __init__(self, items)
def _placeImpl(self, name, proc)
def copyAndExclude(self, listOfModulesToExclude)
def _checkIfSequenceable(caller, v)
def visitNode(self, visitor)
def resolve(self, processDict, keepIfCannotResolve=False)
def insert(self, index, item)
def __init__(self, sequenceName, depSet)
#define str(s)
def _checkIfBooleanLogicSequenceable(caller, v)
def contains(self, mod)
def contains(self, mod)
def _clonesequence(self, lookuptable)
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 _place(self, name, proc)
def dumpPythonNoNewline(self, options=PrintOptions())