CMS 3D CMS Logo

EnablePSetHistory.py
Go to the documentation of this file.
1 from __future__ import print_function
2 from builtins import range
3 from copy import deepcopy
4 import inspect
5 import six
6 
7 ACTIVATE_INSPECTION=True
8 
9 #### helpers for inspection ####
10 
12  if not ACTIVATE_INSPECTION:
13  return [("unknown","unknown","unknown")]
14  stack = inspect.stack()
15  while len(stack)>=1 and len(stack[0])>=2 and ('FWCore/ParameterSet' in stack[0][1] or 'FWCore/GuiBrowsers' in stack[0][1]):
16  stack = stack[1:]
17  if len(stack)>=1 and len(stack[0])>=3:
18  return stack
19  else:
20  return [("unknown","unknown","unknown")]
21 
22 #### patches needed for deepcopy of process ####
23 
24 import FWCore.ParameterSet.DictTypes as typ
25 
27  return self.__class__(self)
28 typ.SortedKeysDict.__copy__ = new_SortedKeysDict__copy__
29 
30 def new_SortedKeysDict__deepcopy__(self, memo=None):
31  from copy import deepcopy
32  if memo is None:
33  memo = {}
34  d = memo.get(id(self), None)
35  if d is not None:
36  return d
37  memo[id(self)] = d = self.__class__()
38  d.__init__(deepcopy(self.items(), memo))
39  return d
40 typ.SortedKeysDict.__deepcopy__ = new_SortedKeysDict__deepcopy__
41 
42 #### process history ####
43 
44 import FWCore.ParameterSet.Config as cms
45 
46 def new___init__(self,*l,**k):
47  self.old___init__(*l,**k)
48  self.__dict__['_Process__history'] = []
49  self.__dict__['_Process__enableRecording'] = 0
50  self.__dict__['_Process__modifiedobjects'] = []
51  self.__dict__['_Process__modifiedcheckpoint'] = None
52  self.__dict__['_Process__modifications'] = []
53 cms.Process.old___init__=cms.Process.__init__
54 cms.Process.__init__=new___init__
55 
57  return self.__dict__['_Process__modifiedobjects']
58 cms.Process.modifiedObjects=new_modifiedObjects
59 
61  self.__dict__['_Process__modifiedobjects'] = []
62 cms.Process.resetModifiedObjects=new_resetModifiedObjects
63 
64 def new__place(self, name, mod, d):
65  self.old__place(name, mod, d)
66  if self._okToPlace(name, mod, d):
67  self.__dict__['_Process__modifiedobjects'].append(mod)
68 cms.Process.old__place=cms.Process._place
69 cms.Process._place=new__place
70 
71 def new__placeSource(self, name, mod):
72  self.old__placeSource(name, mod)
73  self.__dict__['_Process__modifiedobjects'].append(mod)
74 cms.Process.old__placeSource=cms.Process._placeSource
75 cms.Process._placeSource=new__placeSource
76 
77 def new__placeLooper(self, name, mod):
78  self.old__placeLooper(name, mod)
79  self.__dict__['_Process__modifiedobjects'].append(mod)
80 cms.Process.old__placeLooper=cms.Process._placeLooper
81 cms.Process._placeLooper=new__placeLooper
82 
83 def new__placeService(self, typeName, mod):
84  self.old__placeService(typeName, mod)
85  self.__dict__['_Process__modifiedobjects'].append(mod)
86 cms.Process.old__placeService=cms.Process._placeService
87 cms.Process._placeService=new__placeService
88 
89 def new_setSchedule_(self, sch):
90  self.old_setSchedule_(sch)
91  self.__dict__['_Process__modifiedobjects'].append(sch)
92 cms.Process.old_setSchedule_=cms.Process.setSchedule_
93 cms.Process.setSchedule_=new_setSchedule_
94 
95 def new_setLooper_(self, lpr):
96  self.old_setLooper_(lpr)
97  self.__dict__['_Process__modifiedobjects'].append(lpr)
98 cms.Process.old_setLooper_=cms.Process.setLooper_
99 cms.Process.setLooper_=new_setLooper_
100 
101 def new_history(self, removeDuplicates=False):
102  return self.__dict__['_Process__history']+self.dumpModificationsWithObjects(removeDuplicates)
103 cms.Process.history=new_history
104 
106  self.__dict__['_Process__history'] = []
107  self.resetModified()
108  self.resetModifiedObjects()
109 cms.Process.resetHistory=new_resetHistory
110 
111 def new_dumpHistory(self,withImports=True):
112  dumpHistory=[]
113  for item,objects in self.history():
114  if isinstance(item,(str,unicode)):
115  dumpHistory.append(item +"\n")
116  else: # isTool
117  print(item)
118  dump=item.dumpPython()
119  if isinstance(dump,tuple):
120  if withImports and dump[0] not in dumpHistory:
121  dumpHistory.append(dump[0])
122  dumpHistory.append(dump[1] +"\n")
123  else:
124  dumpHistory.append(dump +"\n")
125 
126  return ''.join(dumpHistory)
127 cms.Process.dumpHistory=new_dumpHistory
128 
129 def new_addAction(self,tool):
130  if self.__dict__['_Process__enableRecording'] == 0:
131  modifiedObjects=self.modifiedObjects()
132  for m,o in self.dumpModificationsWithObjects():
133  modifiedObjects+=o
134  self.__dict__['_Process__history'].append((tool,modifiedObjects))
135  self.resetModified()
136  self.resetModifiedObjects()
137 cms.Process.addAction=new_addAction
138 
139 def new_deleteAction(self,i):
140  del self.__dict__['_Process__history'][i]
141 cms.Process.deleteAction=new_deleteAction
142 
144  if self.__dict__['_Process__enableRecording'] == 0:
145  # remember modifications in history
146  self.__dict__['_Process__history']+=self.dumpModificationsWithObjects()
147  self.resetModified()
148  self.resetModifiedObjects()
149  self.__dict__['_Process__enableRecording'] += 1
150 cms.Process.disableRecording=new_disableRecording
151 
153  self.__dict__['_Process__enableRecording'] -= 1
154 cms.Process.enableRecording=new_enableRecording
155 
157  return self.__dict__['_Process__enableRecording']==0
158 cms.Process.checkRecording=new_checkRecording
159 
160 def new_setattr(self, name, value):
161  """
162  This catches modifications that occur during process.load,
163  and only records a modification if there was an existing object
164  and the version after __setattr__ has a different id().
165  This does not mean that the object is different, only redefined.
166  We still really need a recursive-comparison function for parameterizeable
167  objects to determine if a real change has been made.
168  """
169  old = None
170  existing = False
171  if not name.startswith('_Process__'):
172  existing = hasattr(self, name)
173  if existing:
174  old = getattr(self, name)
175  self.old__setattr__(name, value)
176  if existing:
177  if id(getattr(self, name)) != id(old):
178  stack = auto_inspect()
179  self.__dict__['_Process__modifications'] += [{'name': name,
180  'old': deepcopy(old),
181  'new': deepcopy(getattr(self, name)),
182  'file':stack[0][1],'line':stack[0][2],
183  'action': 'replace'}]
184 cms.Process.old__setattr__ = cms.Process.__setattr__
185 cms.Process.__setattr__ = new_setattr
186 
188  """
189  Empty all the _modifications lists for
190  all objects beneath this one.
191  """
192  properties = []
193  if isinstance(o, cms._ModuleSequenceType):
194  o.resetModified()
195  if isinstance(o, cms._Parameterizable):
196  o.resetModified()
197  for key in o.parameterNames_():
198  value = getattr(o,key)
199  self.recurseResetModified_(value)
200  if isinstance(o, cms._ValidatingListBase):
201  for index,item in enumerate(o):
202  self.recurseResetModified_(item)
203 cms.Process.recurseResetModified_=new_recurseResetModified_
204 
205 def new_recurseDumpModifications_(self, name, o):
206  """
207  Recursively return a standardised list of modifications
208  from the object hierarchy.
209  """
210  modifications = []
211  if isinstance(o, cms._ModuleSequenceType):
212  if o._isModified:
213  for mod in o._modifications:
214  modifications.append({'name':name,
215  'action':mod['action'],
216  'old': mod['old'],
217  'new': mod['new'],
218  'file': mod['file'],
219  'line': mod['line'],
220  'dump': o.dumpPython({}),
221  'type': 'seq'})
222 
223  if isinstance(o, cms._Parameterizable):
224  for mod in o._modifications:
225  paramname = mod['name']
226  if hasattr(o, paramname):
227  paramvalue = getattr(o, paramname)
228  else:
229  paramvalue = None
230  if isinstance(paramvalue,cms._ParameterTypeBase):
231  dump = paramvalue.dumpPython()
232  else:
233  dump = paramvalue
234  modifications.append({'name': '%s.%s' %(name, paramname),
235  'old': mod['old'],
236  'new': mod['new'],
237  'file': mod['file'],
238  'line': mod['line'],
239  'action': mod['action'],
240  'dump': dump,
241  'type': 'param'})
242 
243  # Loop over any child elements
244  for key in o.parameterNames_():
245  value = getattr(o,key)
246  modifications += self.recurseDumpModifications_("%s.%s" % (name, key), value)
247 
248  if isinstance(o, cms._ValidatingListBase):
249  for index, item in enumerate(o):
250  modifications += self.recurseDumpModifications_("%s[%s]" % (name, index), item)
251  if isinstance(o, cms.Process):
252  for mod in o.__dict__['_Process__modifications']:
253  if hasattr(o, mod['name']) and hasattr(getattr(o, mod['name']), 'dumpPython'):
254  dump = getattr(o, mod['name']).dumpPython()
255  else:
256  dump = None
257  modifications.append({'name': mod['name'],
258  'action': mod['action'],
259  'old': mod['old'],
260  'new': mod['new'],
261  'dump': dump,
262  'file': mod['file'],
263  'line': mod['line'],
264  'type': 'process'})
265  return modifications
266 cms.Process.recurseDumpModifications_=new_recurseDumpModifications_
267 
269  """
270  Set a checkpoint, ie get the current list of all known
271  top-level names and store them. Later, when we print out
272  modifications we ignore any modifications that do not affect
273  something in this list.
274 
275  There is currently no way of clearing this, but I think this
276  is generally a use-once feature.
277  """
278  existing_names = set()
279  for item in self.items_():
280  existing_names.add(item[0])
281  self.__dict__['_Process__modifiedcheckpoint'] = list(existing_names)
282 cms.Process.modificationCheckpoint=new_modificationCheckpoint
283 
285  """
286  Empty out all the modification lists, so we only see changes that
287  happen from now onwards.
288  """
289  self.__dict__['_Process__modified'] = []
290  for name, o in self.items_():
291  self.recurseResetModified_(o)
292 cms.Process.resetModified=new_resetModified
293 
294 def new_dumpModifications(self, comments=True, process=True, module=False, sequence=True, value=True, sort=True, group=True):
295  """
296  Return some text describing all the modifications that have been made.
297 
298  * comments: print out comments describing the file and line which triggered
299  the modification, if determined.
300  * process: print "process." in front of every name
301  * module: only print out one entry per top-level module that has been
302  changed, rather than the details
303  * sequence: include changes to sequences
304  * value: print out the latest value of each name
305  * sort: whether to sort all the names before printing (otherwise they're in
306  more-or-less time order, within each category)
307  """
308  modifications = self.recurseDumpModifications_('', self)
309  text = []
310  for name, o in self.items_():
311  modifications += self.recurseDumpModifications_(name, o)
312  if not sequence:
313  modifications = [x for x in modifications if not x['type'] == 'seq']
314  checkpoint = self.__dict__['_Process__modifiedcheckpoint']
315  if not checkpoint == None:
316  modifications = [x for x in modifications if any([x['name'].startswith(check) for check in checkpoint])]
317  if module:
318  value = False
319  comments = False
320  modules = list(set([m['name'].split('.')[0] for m in modifications]))
321  if sort:
322  modules = sorted(modules)
323  if process:
324  text = ['process.%s' % m for m in modules]
325  else:
326  text = modules
327  else:
328  if sort:
329  modifications = sorted(modifications, key=lambda x: x['name'])
330  for i, m in enumerate(modifications):
331  t = ''
332  if comments:
333  if m['action'] == 'replace':
334  t += '# %(file)s:%(line)s replace %(old)s->%(new)s\n' % m
335  elif m['action'] == 'remove':
336  t += '# %(file)s:%(line)s remove %(old)s\n' % m
337  elif m['action'] == 'append':
338  t += '# %(file)s:%(line)s append %(new)s\n' % m
339  if not group or i==len(modifications)-1 or not modifications[i+1]['name'] == m['name']:
340  if process and value:
341  t += 'process.%s = %s' % (m['name'], m['dump'])
342  elif value:
343  t += '%s = %s' % (m['name'], m['dump'])
344  elif process:
345  t += 'process.%s' % (m['name'])
346  else:
347  t += '%s' % (m['name'])
348  text += [t]
349  return '\n'.join(text)+'\n'
350 cms.Process.dumpModifications=new_dumpModifications
351 
352 def new_dumpModificationsWithObjects(self, removeDuplicates=False):
353  modifications = []
354  last_modification=""
355  for name, o in self.items_():
356  for m in self.recurseDumpModifications_(name, o):
357  # remove duplicate modifications
358  if removeDuplicates and last_modification==m['name']:
359  modifications.pop()
360  last_modification=m['name']
361  # add changes
362  text = 'process.%s = %s' % (m['name'], m['dump'])
363  modifications += [(text,[o])]
364  return modifications
365 cms.Process.dumpModificationsWithObjects=new_dumpModificationsWithObjects
366 
368  items = []
369  items += self.producers.items()
370  items += self.filters.items()
371  items += self.analyzers.items()
372  return tuple(items)
373 cms.Process.moduleItems_=new_moduleItems_
374 
375 def new_items_(self):
376  items = []
377  if self.source:
378  items += [("source", self.source)]
379  if self.looper:
380  items += [("looper", self.looper)]
381  items += self.moduleItems_()
382  items += self.outputModules.items()
383  items += self.sequences.items()
384  items += six.iteritems(self.paths)
385  items += self.endpaths.items()
386  items += self.services.items()
387  items += self.es_producers.items()
388  items += self.es_sources.items()
389  items += self.es_prefers.items()
390  items += self.psets.items()
391  items += self.vpsets.items()
392  if self.schedule:
393  items += [("schedule", self.schedule)]
394  return tuple(items)
395 cms.Process.items_=new_items_
396 
397 #### parameterizable history ####
398 
399 def new_Parameterizable_init(self,*a,**k):
400  self.__dict__['_modifications'] = []
401  self.old__init__(*a,**k)
402  self._modifications = []
403 cms._Parameterizable.old__init__ = cms._Parameterizable.__init__
404 cms._Parameterizable.__init__ = new_Parameterizable_init
405 
406 def new_Parameterizable_addParameter(self, name, value):
407  self.old__addParameter(name,value)
408  stack = auto_inspect()
409  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':None,'new':deepcopy(value),'action':'add'})
410 cms._Parameterizable.old__addParameter = cms._Parameterizable._Parameterizable__addParameter
411 cms._Parameterizable._Parameterizable__addParameter = new_Parameterizable_addParameter
412 
413 def new_Parameterizable_setattr(self, name, value):
414  if (not self.isFrozen()) and (not name.startswith('_')) and (name in self.__dict__):
415  stack = auto_inspect()
416  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':deepcopy(self.__dict__[name]),'new':deepcopy(value),'action':'replace'})
417  self._isModified = True
418  self.old__setattr__(name,value)
419 cms._Parameterizable.old__setattr__ = cms._Parameterizable.__setattr__
420 cms._Parameterizable.__setattr__ = new_Parameterizable_setattr
421 
423  if not self.isFrozen():
424  stack = auto_inspect()
425  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':deepcopy(self.__dict__[name]), 'new':None,'action':'delete'})
426  self.old__delattr__(name)
427 cms._Parameterizable.old__delattr__ = cms._Parameterizable.__delattr__
428 cms._Parameterizable.__delattr__ = new_Parameterizeable_delattr
429 
430 
432  self._isModified=False
433  self._modifications = []
434  for name in self.parameterNames_():
435  param = self.__dict__[name]
436  if isinstance(param, cms._Parameterizable):
437  param.resetModified()
438 cms._Parameterizable.resetModified = new_Parameterizable_resetModified
439 
441  self._isModified=False
442  self._modifications = []
443 cms._ParameterTypeBase.resetModified = new_ParameterTypeBase_resetModified
444 
445 #### sequence history ####
446 
448  return ''
449 cms._Sequenceable._name_ = new__Sequenceable_name
450 
451 try:
452  # for backwards-compatibility with CMSSW_3_10_X
453  from FWCore.ParameterSet.SequenceTypes import _SequenceOperator
454 
455  def new__SequenceOperator_name(self):
456  return str(self._left._name_())+str(self._pySymbol)+str(self._right._name_())
457  _SequenceOperator._name_ = new__SequenceOperator_name
458 except:
459  pass
460 
461 from FWCore.ParameterSet.SequenceTypes import _SequenceNegation, _SequenceIgnore, SequencePlaceholder
462 
464  return self._name
465 SequencePlaceholder._name_ = new__SequencePlaceholder_name
466 
468  if self._operand:
469  return '~'+str(self._operand._name_())
470  else:
471  return '~()'
472 _SequenceNegation._name_ = new__SequenceNegation_name
473 
475  if self._operand:
476  return '-'+str(self._operand._name_())
477  else:
478  return '-()'
479 _SequenceIgnore._name_ = new__SequenceIgnore_name
480 
482  if self._seq:
483  return '('+str(self._seq._name_())+')'
484  else:
485  return '()'
486 cms.Sequence._name_ = new_Sequence_name
487 
489  if hasattr(self,'_Labelable__label'):
490  return getattr(self,'_Labelable__label')
491  elif hasattr(self,'_TypedParameterizable__type'):
492  return 'unnamed(%s)'%getattr(self,'_TypedParameterizable__type')
493  return type(self).__name__
494 cms._Module._name_ = new__Module_name
495 
496 def new__ModuleSequenceType__init__(self,*arg,**argv):
497  self._modifications = []
498  self.old__init__(*arg,**argv)
499 cms._ModuleSequenceType.old__init__ = cms._ModuleSequenceType.__init__
500 cms._ModuleSequenceType.__init__ = new__ModuleSequenceType__init__
501 
503  self._isModified=False
504  self._modifications = []
505 cms._ModuleSequenceType.resetModified = new__ModuleSequenceType_resetModified
506 
508  return self._isModified
509 cms._ModuleSequenceType.isModified = new__ModuleSequenceType_isModified
510 
512  returnValue = cms._ModuleSequenceType.__new__(type(self))
513  returnValue.__init__(self._seq)
514  returnValue._isModified = self._isModified
515  returnValue._modifications = deepcopy(self._modifications)
516  return returnValue
517 cms._ModuleSequenceType.copy = new__ModuleSequenceType_copy
518 
519 def new__ModuleSequenceType_replace(self, original, replacement):
520  stack = auto_inspect()
521  self._isModified=True
522  if replacement is None:
523  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'replace','old':original._name_(),'new':None})
524  else:
525  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'replace','old':original._name_(),'new':replacement._name_()})
526  return self.old_replace(original, replacement)
527 cms._ModuleSequenceType.old_replace = cms._ModuleSequenceType.replace
528 cms._ModuleSequenceType.replace = new__ModuleSequenceType_replace
529 
530 def new__ModuleSequenceType_remove(self, original):
531  stack = auto_inspect()
532  self._isModified=True
533  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'remove','old':original._name_(),'new':None})
534  return self.old_remove(original)
535 cms._ModuleSequenceType.old_remove = cms._ModuleSequenceType.remove
536 cms._ModuleSequenceType.remove = new__ModuleSequenceType_remove
537 
539  stack = auto_inspect()
540  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'append','new':other._name_(),'old':None})
541  self._isModified=True
542  return self.old__iadd__(other)
543 cms._ModuleSequenceType.old__imul__ = cms._ModuleSequenceType.__imul__
544 cms._ModuleSequenceType.__imul__ = new__ModuleSequenceType__imul__
545 
547  stack = auto_inspect()
548  self._isModified=True
549  self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'append','new':other._name_(),'old':None})
550  return self.old__iadd__(other)
551 cms._ModuleSequenceType.old__iadd__ = cms._ModuleSequenceType.__iadd__
552 cms._ModuleSequenceType.__iadd__ = new__ModuleSequenceType__iadd__
553 
554 from FWCore.ParameterSet.Modules import Source
555 from FWCore.GuiBrowsers.editorTools import changeSource
556 
557 if __name__=='__main__':
558  import unittest
559  class TestModificationTracking(unittest.TestCase):
560  def setUp(self):
561  pass
562  def testPSet(self):
563  ex = cms.EDAnalyzer("Example",
564  one = cms.double(0),
565  two = cms.bool(True),
566  ps = cms.PSet(
567  three = cms.int32(10),
568  four = cms.string('abc')
569  ),
570  vps = cms.VPSet(
571  cms.PSet(
572  five = cms.InputTag('alpha')
573  ),
574  cms.PSet(
575  six = cms.vint32(1,2,3)
576  )
577  ),
578  seven = cms.vstring('alpha','bravo','charlie'),
579  eight = cms.vuint32(list(range(10))),
580  nine = cms.int32(0)
581  )
582  ex.zero = cms.string('hello')
583  self.assertEqual(ex._modifications[-1]['name'],'zero')
584  ex.one = cms.double(1)
585  ex.one = cms.double(2)
586  ex.one = cms.double(3)
587  self.assertEqual(ex._modifications[-1]['name'],'one')
588  self.assertEqual(ex._modifications[-2]['name'],'one')
589  self.assertEqual(ex._modifications[-3]['name'],'one')
590  ex.two = False
591  self.assertEqual(ex._modifications[-1]['name'],'two')
592  ex.ps.three.setValue(100) # MISSED
593  #self.assertEqual(ex.ps._modifications.pop()['name'],'three')
594  ex.ps.four = 'def'
595  self.assertEqual(ex.ps._modifications[-1]['name'],'four')
596  ex.vps[0].five = cms.string('beta')
597  self.assertEqual(ex.vps[0]._modifications[-1]['name'],'five')
598  ex.vps[1].__dict__['six'] = cms.vint32(1,4,9) # MISSED
599  #self.assertEqual(ex.vps[1]._modifications[-1]['name'],'six')
600  ex.seven[0] = 'delta' # MISSED
601  #self.assertEqual(ex._modifications[-1]['name'],'seven')
602  ex.eight.pop() # MISSED
603  #self.assertEqual(ex._modifications[-1]['name'],'eight')
604  del ex.nine
605  #self.assertEqual(ex._modifications[-1]['name'],'nine')
606  ex.newvpset = cms.VPSet()
607  self.assertEqual(ex._modifications[-1]['name'],'newvpset')
608 
609  process = cms.Process('unittest')
610  process.ex = ex
611  mods = process.dumpModifications()
612  self.assert_('process.ex.zero' in mods)
613  self.assert_('process.ex.one' in mods)
614  self.assert_('process.ex.two' in mods)
615  #self.assert_('process.ex.three' in mods)
616  self.assert_('process.ex.ps.four' in mods)
617  self.assert_('process.ex.vps[0].five' in mods)
618  #self.assert_('process.ex.vps[1].six' in mods)
619  #self.assert_('process.ex.seven[0]' in mods)
620  #self.assert_('process.ex.eight' in mods)
621  self.assert_('process.ex.nine' in mods)
622  self.assert_('process.ex.newvpset' in mods)
623 
624 
625 
626  def testSeq(self):
627  process = cms.Process('unittest')
628  for i in range(10):
629  setattr(process,'f%s'%i,cms.EDFilter('f%s'%i))
630  process.seq1 = cms.Sequence(process.f1*process.f2*process.f3)
631  self.assertEqual(process.seq1._modifications,[])
632  process.seq2 = cms.Sequence(process.f4+process.f5+process.f6)
633  self.assertEqual(process.seq2._modifications,[])
634 
635  process.seq1.replace(process.f1,process.f0*process.f1)
636  self.assertEqual(process.seq1._modifications[-1]['action'],'replace')
637 
638  process.seq2.remove(process.f5)
639  self.assertEqual(process.seq2._modifications[-1]['action'],'remove')
640 
641  process.path = cms.Path(process.seq1*process.f7)
642  self.assertEqual(process.path._modifications,[])
643 
644  process.path *= process.seq2
645  self.assertEqual(process.path._modifications[-1]['action'],'append')
646  process.path.remove(process.f6)
647  self.assertEqual(process.path._modifications[-1]['action'],'remove')
648  process.path.replace(process.f2,~process.f2)
649  self.assertEqual(process.path._modifications[-1]['action'],'replace')
650 
651  mods = process.dumpModifications()
652  self.assert_('process.seq1' in mods)
653  self.assert_('process.seq2' in mods)
654  self.assert_('process.path' in mods)
655 
656  def testdumpHistory(self):
657  process = cms.Process('unittest')
658  process.source=Source("PoolSource",fileNames = cms.untracked.string("file:file.root"))
659 
660  changeSource(process,"file:filename.root")
661  self.assertEqual(changeSource._parameters['source'].value,"file:filename.root")
662 
663  changeSource(process,"file:filename2.root")
664  self.assertEqual(changeSource._parameters['source'].value,"file:filename2.root")
665 
666  changeSource(process,"file:filename3.root")
667  self.assertEqual(changeSource._parameters['source'].value,"file:filename3.root")
668 
669  self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\n")
670 
671  process.source.fileNames=cms.untracked.vstring("file:replacedfile.root")
672  self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\nprocess.source.fileNames = cms.untracked.vstring('file:replacedfile.root')\n")
673 
674  process.disableRecording()
675  changeSource.setParameter('source',"file:filename4.root")
676  action=changeSource.__copy__()
677  process.addAction(action)
678  self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\nprocess.source.fileNames = cms.untracked.vstring('file:replacedfile.root')\n")
679 
680  process.enableRecording()
681  changeSource.setParameter('source',"file:filename5.root")
682  action=changeSource.__copy__()
683  process.addAction(action)
684  process.deleteAction(3)
685  self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\n\nchangeSource(process , 'file:filename5.root')\n\n")
686 
687  process.deleteAction(0)
688  self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\n\nchangeSource(process , 'file:filename5.root')\n\n")
689 
691  process = cms.Process('unittest')
692  process.source=Source("PoolSource",fileNames = cms.untracked.string("file:file.root"))
693 
694  changeSource(process,"file:filename.root")
695  self.assertEqual(len(process.history()[0][1]),1)
696 
697  process.source.fileNames=cms.untracked.vstring("file:replacedfile.root")
698  self.assertEqual(len(process.history()[0][1]),1)
699  self.assertEqual(len(process.history()[1][1]),1)
700 
701  process.source.fileNames=["test2"]
702  self.assertEqual(len(process.history()[0][1]),1)
703  self.assertEqual(len(process.history()[1][1]),1)
704 
705  changeSource(process,"file:filename2.root")
706  self.assertEqual(len(process.history()[0][1]),1)
707  self.assertEqual(len(process.history()[1][1]),1)
708  self.assertEqual(len(process.history()[2][1]),1)
709 
710  process.source.fileNames=cms.untracked.vstring("file:replacedfile2.root")
711  self.assertEqual(len(process.history()[0][1]),1)
712  self.assertEqual(len(process.history()[1][1]),1)
713  self.assertEqual(len(process.history()[2][1]),1)
714  self.assertEqual(len(process.history()[3][1]),1)
715 
716  unittest.main()
717 
def new__placeLooper(self, name, mod)
def new__ModuleSequenceType_resetModified(self)
std::vector< std::string_view > split(std::string_view, const char *)
def new_modificationCheckpoint(self)
def new__ModuleSequenceType__iadd__(self, other)
def new__Sequenceable_name(self)
sequence history ####
def new_dumpModifications(self, comments=True, process=True, module=False, sequence=True, value=True, sort=True, group=True)
def new_Parameterizeable_delattr(self, name)
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:40
def new_modifiedObjects(self)
def new__ModuleSequenceType_copy(self)
def new_SortedKeysDict__copy__(self)
def new_Parameterizable_setattr(self, name, value)
def new_Parameterizable_resetModified(self)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def new_SortedKeysDict__deepcopy__(self, memo=None)
def new__ModuleSequenceType_replace(self, original, replacement)
def new_setLooper_(self, lpr)
def new_Parameterizable_init(self, a, k)
parameterizable history ####
def new__SequencePlaceholder_name(self)
def new__SequenceNegation_name(self)
def new_enableRecording(self)
def new_recurseResetModified_(self, o)
def new_resetModifiedObjects(self)
def new_history(self, removeDuplicates=False)
def new_setSchedule_(self, sch)
def new__ModuleSequenceType__imul__(self, other)
def new__SequenceIgnore_name(self)
def new_deleteAction(self, i)
def new__placeService(self, typeName, mod)
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
def new__ModuleSequenceType_isModified(self)
def new_addAction(self, tool)
def new_disableRecording(self)
def new_checkRecording(self)
def dumpPython(process, name)
def new__ModuleSequenceType__init__(self, arg, argv)
def new_recurseDumpModifications_(self, name, o)
def new_ParameterTypeBase_resetModified(self)
def new_dumpModificationsWithObjects(self, removeDuplicates=False)
def new__ModuleSequenceType_remove(self, original)
def new_setattr(self, name, value)
def auto_inspect()
helpers for inspection ####
#define str(s)
def new__placeSource(self, name, mod)
def new_dumpHistory(self, withImports=True)
def new___init__(self, l, k)
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 new_Parameterizable_addParameter(self, name, value)
def new__place(self, name, mod, d)