CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/FWCore/GuiBrowsers/python/EnablePSetHistory.py

Go to the documentation of this file.
00001 from copy import deepcopy
00002 import inspect
00003 
00004 ACTIVATE_INSPECTION=True
00005 
00006 #### helpers for inspection ####
00007 
00008 def auto_inspect():
00009     if not ACTIVATE_INSPECTION:
00010         return [("unknown","unknown","unknown")]
00011     stack = inspect.stack()
00012     while len(stack)>=1 and len(stack[0])>=2 and ('FWCore/ParameterSet' in stack[0][1] or 'FWCore/GuiBrowsers' in stack[0][1]):
00013         stack = stack[1:]
00014     if len(stack)>=1 and len(stack[0])>=3:
00015        return stack
00016     else:
00017        return [("unknown","unknown","unknown")]
00018 
00019 #### patches needed for deepcopy of process ####
00020 
00021 import FWCore.ParameterSet.DictTypes as typ
00022     
00023 def new_SortedKeysDict__copy__(self):
00024     return self.__class__(self)
00025 typ.SortedKeysDict.__copy__ = new_SortedKeysDict__copy__
00026 
00027 def new_SortedKeysDict__deepcopy__(self, memo=None):
00028     from copy import deepcopy
00029     if memo is None:
00030         memo = {}
00031     d = memo.get(id(self), None)
00032     if d is not None:
00033         return d
00034     memo[id(self)] = d = self.__class__()
00035     d.__init__(deepcopy(self.items(), memo))
00036     return d
00037 typ.SortedKeysDict.__deepcopy__ = new_SortedKeysDict__deepcopy__
00038 
00039 #### process history ####
00040 
00041 import FWCore.ParameterSet.Config as cms
00042 
00043 def new___init__(self,name):
00044     self.old___init__(name)
00045     self.__dict__['_Process__history'] = []
00046     self.__dict__['_Process__enableRecording'] = 0
00047     self.__dict__['_Process__modifiedobjects'] = []
00048     self.__dict__['_Process__modifiedcheckpoint'] = None
00049     self.__dict__['_Process__modifications'] = []
00050 cms.Process.old___init__=cms.Process.__init__
00051 cms.Process.__init__=new___init__
00052 
00053 def new_modifiedObjects(self):
00054     return self.__dict__['_Process__modifiedobjects']
00055 cms.Process.modifiedObjects=new_modifiedObjects
00056 
00057 def new_resetModifiedObjects(self):
00058     self.__dict__['_Process__modifiedobjects'] = []
00059 cms.Process.resetModifiedObjects=new_resetModifiedObjects
00060 
00061 def new__place(self, name, mod, d):
00062     self.old__place(name, mod, d)
00063     if self._okToPlace(name, mod, d):
00064         self.__dict__['_Process__modifiedobjects'].append(mod)
00065 cms.Process.old__place=cms.Process._place
00066 cms.Process._place=new__place
00067 
00068 def new__placeSource(self, name, mod):
00069     self.old__placeSource(name, mod)
00070     self.__dict__['_Process__modifiedobjects'].append(mod)
00071 cms.Process.old__placeSource=cms.Process._placeSource
00072 cms.Process._placeSource=new__placeSource
00073 
00074 def new__placeLooper(self, name, mod):
00075     self.old__placeLooper(name, mod)
00076     self.__dict__['_Process__modifiedobjects'].append(mod)
00077 cms.Process.old__placeLooper=cms.Process._placeLooper
00078 cms.Process._placeLooper=new__placeLooper
00079 
00080 def new__placeService(self, typeName, mod):
00081     self.old__placeService(typeName, mod)
00082     self.__dict__['_Process__modifiedobjects'].append(mod)
00083 cms.Process.old__placeService=cms.Process._placeService
00084 cms.Process._placeService=new__placeService
00085 
00086 def new_setSchedule_(self, sch):
00087     self.old_setSchedule_(sch)
00088     self.__dict__['_Process__modifiedobjects'].append(sch)
00089 cms.Process.old_setSchedule_=cms.Process.setSchedule_
00090 cms.Process.setSchedule_=new_setSchedule_
00091 
00092 def new_setLooper_(self, lpr):
00093     self.old_setLooper_(lpr)
00094     self.__dict__['_Process__modifiedobjects'].append(lpr)
00095 cms.Process.old_setLooper_=cms.Process.setLooper_
00096 cms.Process.setLooper_=new_setLooper_
00097 
00098 def new_history(self, removeDuplicates=False):
00099     return self.__dict__['_Process__history']+self.dumpModificationsWithObjects(removeDuplicates)
00100 cms.Process.history=new_history
00101 
00102 def new_resetHistory(self):
00103     self.__dict__['_Process__history'] = []
00104     self.resetModified()
00105     self.resetModifiedObjects()
00106 cms.Process.resetHistory=new_resetHistory
00107 
00108 def new_dumpHistory(self,withImports=True):
00109     dumpHistory=[]
00110     for item,objects in self.history():
00111         if isinstance(item,str):
00112             dumpHistory.append(item +"\n")
00113         else: # isTool
00114             dump=item.dumpPython()
00115             if isinstance(dump,tuple):
00116                 if withImports and dump[0] not in dumpHistory:
00117                     dumpHistory.append(dump[0])
00118                 dumpHistory.append(dump[1] +"\n")
00119             else:
00120                 dumpHistory.append(dump +"\n")
00121            
00122     return ''.join(dumpHistory)
00123 cms.Process.dumpHistory=new_dumpHistory
00124 
00125 def new_addAction(self,tool):
00126     if self.__dict__['_Process__enableRecording'] == 0:
00127         modifiedObjects=self.modifiedObjects()
00128         for m,o in self.dumpModificationsWithObjects():
00129             modifiedObjects+=o
00130         self.__dict__['_Process__history'].append((tool,modifiedObjects))
00131         self.resetModified()
00132         self.resetModifiedObjects()
00133 cms.Process.addAction=new_addAction
00134 
00135 def new_deleteAction(self,i):
00136     del self.__dict__['_Process__history'][i]
00137 cms.Process.deleteAction=new_deleteAction
00138 
00139 def new_disableRecording(self):
00140     if self.__dict__['_Process__enableRecording'] == 0:
00141         # remember modifications in history
00142         self.__dict__['_Process__history']+=self.dumpModificationsWithObjects()
00143         self.resetModified()
00144         self.resetModifiedObjects()
00145     self.__dict__['_Process__enableRecording'] += 1
00146 cms.Process.disableRecording=new_disableRecording
00147 
00148 def new_enableRecording(self):
00149     self.__dict__['_Process__enableRecording'] -= 1
00150 cms.Process.enableRecording=new_enableRecording
00151 
00152 def new_checkRecording(self):
00153     return self.__dict__['_Process__enableRecording']==0
00154 cms.Process.checkRecording=new_checkRecording
00155 
00156 def new_setattr(self, name, value):
00157     """
00158     This catches modifications that occur during process.load,
00159     and only records a modification if there was an existing object
00160     and the version after __setattr__ has a different id().
00161     This does not mean that the object is different, only redefined.
00162     We still really need a recursive-comparison function for parameterizeable
00163     objects to determine if a real change has been made.
00164     """
00165     old = None
00166     existing = False
00167     if not name.startswith('_Process__'):
00168         existing = hasattr(self, name)
00169         if existing:
00170             old = getattr(self, name)
00171     self.old__setattr__(name, value)
00172     if existing:
00173         if id(getattr(self, name)) != id(old):
00174             stack = auto_inspect()
00175             self.__dict__['_Process__modifications'] += [{'name': name,
00176                                                           'old': deepcopy(old), 
00177                                                           'new': deepcopy(getattr(self, name)),
00178                                                           'file':stack[0][1],'line':stack[0][2],
00179                                                           'action': 'replace'}]
00180 cms.Process.old__setattr__ = cms.Process.__setattr__
00181 cms.Process.__setattr__ = new_setattr
00182 
00183 def new_recurseResetModified_(self, o):
00184     """
00185     Empty all the _modifications lists for
00186     all objects beneath this one.
00187     """
00188     properties = []
00189     if isinstance(o, cms._ModuleSequenceType):
00190         o.resetModified()
00191     if isinstance(o, cms._Parameterizable):
00192         o.resetModified()
00193         for key in o.parameterNames_():
00194             value = getattr(o,key)
00195             self.recurseResetModified_(value)
00196     if isinstance(o, cms._ValidatingListBase):
00197         for index,item in enumerate(o):
00198             self.recurseResetModified_(item)
00199 cms.Process.recurseResetModified_=new_recurseResetModified_
00200 
00201 def new_recurseDumpModifications_(self, name, o):
00202     """
00203     Recursively return a standardised list of modifications
00204     from the object hierarchy.
00205     """
00206     modifications = []
00207     if isinstance(o, cms._ModuleSequenceType):
00208         if o._isModified:
00209             for mod in o._modifications:
00210                 modifications.append({'name':name,
00211                                       'action':mod['action'],
00212                                       'old': mod['old'],
00213                                       'new': mod['new'],
00214                                       'file': mod['file'],
00215                                       'line': mod['line'],
00216                                       'dump': o.dumpPython({}),
00217                                       'type': 'seq'})
00218     
00219     if isinstance(o, cms._Parameterizable):
00220         for mod in o._modifications:
00221             paramname = mod['name']
00222             if hasattr(o, paramname):
00223                 paramvalue = getattr(o, paramname)
00224             else:
00225                 paramvalue = None
00226             if isinstance(paramvalue,cms._ParameterTypeBase):
00227                 dump = paramvalue.dumpPython()
00228             else:
00229                 dump = paramvalue
00230             modifications.append({'name': '%s.%s' %(name, paramname),
00231                                   'old': mod['old'],
00232                                   'new': mod['new'],
00233                                   'file': mod['file'],
00234                                   'line': mod['line'],
00235                                   'action': mod['action'],
00236                                   'dump': dump,
00237                                   'type': 'param'})
00238             
00239         # Loop over any child elements
00240         for key in o.parameterNames_():
00241             value = getattr(o,key)
00242             modifications += self.recurseDumpModifications_("%s.%s" % (name, key), value)
00243     
00244     if isinstance(o, cms._ValidatingListBase):
00245         for index, item in enumerate(o):
00246             modifications += self.recurseDumpModifications_("%s[%s]" % (name, index), item)
00247     if isinstance(o, cms.Process):
00248         for mod in o.__dict__['_Process__modifications']:
00249             if hasattr(o, mod['name']) and hasattr(getattr(o, mod['name']), 'dumpPython'):
00250                 dump = getattr(o, mod['name']).dumpPython()
00251             else:
00252                 dump = None
00253             modifications.append({'name': mod['name'],
00254                                   'action': mod['action'],
00255                                   'old': mod['old'],
00256                                   'new': mod['new'],
00257                                   'dump': dump,
00258                                   'file': mod['file'],
00259                                   'line': mod['line'],
00260                                   'type': 'process'})
00261     return modifications
00262 cms.Process.recurseDumpModifications_=new_recurseDumpModifications_
00263 
00264 def new_modificationCheckpoint(self):
00265     """
00266     Set a checkpoint, ie get the current list of all known
00267     top-level names and store them. Later, when we print out
00268     modifications we ignore any modifications that do not affect
00269     something in this list.
00270 
00271     There is currently no way of clearing this, but I think this
00272     is generally a use-once feature.
00273     """
00274     existing_names = set()
00275     for item in self.items_():
00276         existing_names.add(item[0])
00277     self.__dict__['_Process__modifiedcheckpoint'] = list(existing_names)
00278 cms.Process.modificationCheckpoint=new_modificationCheckpoint
00279 
00280 def new_resetModified(self):
00281     """
00282     Empty out all the modification lists, so we only see changes that
00283     happen from now onwards.
00284     """
00285     self.__dict__['_Process__modified'] = []
00286     for name, o in self.items_():
00287         self.recurseResetModified_(o)
00288 cms.Process.resetModified=new_resetModified
00289 
00290 def new_dumpModifications(self, comments=True, process=True, module=False, sequence=True, value=True, sort=True, group=True):
00291     """
00292     Return some text describing all the modifications that have been made.
00293 
00294     * comments: print out comments describing the file and line which triggered
00295                 the modification, if determined.
00296     * process: print "process." in front of every name
00297     * module: only print out one entry per top-level module that has been
00298               changed, rather than the details
00299     * sequence: include changes to sequences
00300     * value: print out the latest value of each name
00301     * sort: whether to sort all the names before printing (otherwise they're in
00302             more-or-less time order, within each category)
00303     """
00304     modifications = self.recurseDumpModifications_('', self)
00305     text = []
00306     for name, o in self.items_():
00307         modifications += self.recurseDumpModifications_(name, o)
00308     if not sequence:
00309         modifications = filter(lambda x: not x['type'] == 'seq', modifications)
00310     checkpoint = self.__dict__['_Process__modifiedcheckpoint']
00311     if not checkpoint == None:
00312         modifications = filter(lambda x: any([x['name'].startswith(check) for check in checkpoint]), modifications)
00313     if module:
00314         value = False
00315         comments = False
00316         modules = list(set([m['name'].split('.')[0] for m in modifications]))
00317         if sort:
00318             modules = sorted(modules)
00319         if process:
00320             text = ['process.%s' % m for m in modules]
00321         else:
00322             text = modules
00323     else:
00324         if sort:
00325             modifications = sorted(modifications, key=lambda x: x['name'])
00326         for i, m in enumerate(modifications):
00327             t = ''
00328             if comments:
00329                 if m['action'] == 'replace':
00330                     t += '# %(file)s:%(line)s replace %(old)s->%(new)s\n' % m
00331                 elif m['action'] == 'remove':
00332                     t += '# %(file)s:%(line)s remove %(old)s\n' % m
00333                 elif m['action'] == 'append':
00334                     t += '# %(file)s:%(line)s append %(new)s\n' % m
00335             if not group or i==len(modifications)-1 or not modifications[i+1]['name'] == m['name']:
00336                 if process and value:
00337                     t += 'process.%s = %s' % (m['name'], m['dump'])
00338                 elif value:
00339                     t += '%s = %s' % (m['name'], m['dump'])
00340                 elif process:
00341                     t += 'process.%s' % (m['name'])
00342                 else:
00343                     t += '%s' % (m['name'])
00344             text += [t]
00345     return '\n'.join(text)+'\n'
00346 cms.Process.dumpModifications=new_dumpModifications
00347 
00348 def new_dumpModificationsWithObjects(self, removeDuplicates=False):
00349     modifications = []
00350     last_modification=""
00351     for name, o in self.items_():
00352         for m in self.recurseDumpModifications_(name, o):
00353             # remove duplicate modifications
00354             if removeDuplicates and last_modification==m['name']:
00355                 modifications.pop()
00356             last_modification=m['name']
00357             # add changes
00358             text = 'process.%s = %s' % (m['name'], m['dump'])
00359             modifications += [(text,[o])]
00360     return modifications
00361 cms.Process.dumpModificationsWithObjects=new_dumpModificationsWithObjects
00362 
00363 def new_moduleItems_(self):
00364     items = []
00365     items += self.producers.items()
00366     items += self.filters.items()
00367     items += self.analyzers.items()
00368     return tuple(items)
00369 cms.Process.moduleItems_=new_moduleItems_
00370 
00371 def new_items_(self):
00372     items = []
00373     if self.source:
00374         items += [("source", self.source)]
00375     if self.looper:
00376         items += [("looper", self.looper)]
00377     items += self.moduleItems_()
00378     items += self.outputModules.items()
00379     items += self.sequences.items()
00380     items += self.paths.iteritems()
00381     items += self.endpaths.items()
00382     items += self.services.items()
00383     items += self.es_producers.items()
00384     items += self.es_sources.items()
00385     items += self.es_prefers.items()
00386     items += self.psets.items()
00387     items += self.vpsets.items()
00388     if self.schedule:
00389         items += [("schedule", self.schedule)]
00390     return tuple(items)
00391 cms.Process.items_=new_items_
00392 
00393 #### parameterizable history ####
00394 
00395 def new_Parameterizable_init(self,*a,**k):
00396   self.__dict__['_modifications'] = []
00397   self.old__init__(*a,**k)
00398   self._modifications = []
00399 cms._Parameterizable.old__init__ = cms._Parameterizable.__init__
00400 cms._Parameterizable.__init__ = new_Parameterizable_init
00401 
00402 def new_Parameterizable_addParameter(self, name, value):
00403   self.old__addParameter(name,value)
00404   stack = auto_inspect()
00405   self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':None,'new':deepcopy(value),'action':'add'})
00406 cms._Parameterizable.old__addParameter = cms._Parameterizable._Parameterizable__addParameter
00407 cms._Parameterizable._Parameterizable__addParameter = new_Parameterizable_addParameter
00408 
00409 def new_Parameterizable_setattr(self, name, value):
00410   if (not self.isFrozen()) and (not name.startswith('_')) and (name in self.__dict__):
00411     stack = auto_inspect()
00412     self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':deepcopy(self.__dict__[name]),'new':deepcopy(value),'action':'replace'})
00413     self._isModified = True
00414   self.old__setattr__(name,value)
00415 cms._Parameterizable.old__setattr__ = cms._Parameterizable.__setattr__
00416 cms._Parameterizable.__setattr__ = new_Parameterizable_setattr
00417 
00418 def new_Parameterizeable_delattr(self, name):
00419     if not self.isFrozen():
00420         stack = auto_inspect()
00421         self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':deepcopy(self.__dict__[name]), 'new':None,'action':'delete'})
00422     self.old__delattr__(name)
00423 cms._Parameterizable.old__delattr__ = cms._Parameterizable.__delattr__
00424 cms._Parameterizable.__delattr__ = new_Parameterizeable_delattr
00425 
00426 
00427 def new_Parameterizable_resetModified(self):
00428     self._isModified=False
00429     self._modifications = []
00430     for name in self.parameterNames_():
00431         param = self.__dict__[name]
00432         if isinstance(param, cms._Parameterizable):
00433             param.resetModified()
00434 cms._Parameterizable.resetModified = new_Parameterizable_resetModified
00435 
00436 def new_ParameterTypeBase_resetModified(self):
00437     self._isModified=False
00438     self._modifications = []
00439 cms._ParameterTypeBase.resetModified = new_ParameterTypeBase_resetModified
00440 
00441 #### sequence history ####
00442 
00443 def new__Sequenceable_name(self):
00444     return ''
00445 cms._Sequenceable._name = new__Sequenceable_name
00446 
00447 try:
00448     # for backwards-compatibility with CMSSW_3_10_X
00449     from FWCore.ParameterSet.SequenceTypes import _SequenceOperator
00450 
00451     def new__SequenceOperator_name(self):
00452         return str(self._left._name())+str(self._pySymbol)+str(self._right._name())
00453     _SequenceOperator._name = new__SequenceOperator_name    
00454 except:
00455     pass
00456 
00457 from FWCore.ParameterSet.SequenceTypes import _SequenceNegation, _SequenceIgnore
00458 
00459 def new__SequenceNegation_name(self):
00460     if self._operand:
00461         return '~'+str(self._operand._name())
00462     else:
00463         return '~()'
00464 _SequenceNegation._name = new__SequenceNegation_name    
00465 
00466 def new__SequenceIgnore_name(self):
00467     if self._operand:
00468         return '-'+str(self._operand._name())
00469     else:
00470         return '-()'
00471 _SequenceIgnore._name = new__SequenceIgnore_name
00472 
00473 def new_Sequence_name(self):
00474     if self._seq:
00475         return '('+str(self._seq._name())+')'
00476     else:
00477         return '()'
00478 cms.Sequence._name = new_Sequence_name
00479 
00480 def new__Module_name(self):
00481   if hasattr(self,'_Labelable__label'):
00482     return getattr(self,'_Labelable__label')
00483   elif hasattr(self,'_TypedParameterizable__type'):
00484     return 'unnamed(%s)'%getattr(self,'_TypedParameterizable__type')
00485   return type(self).__name__
00486 cms._Module._name = new__Module_name
00487 
00488 def new__ModuleSequenceType__init__(self,*arg,**argv):
00489     self._modifications = []
00490     self.old__init__(*arg,**argv)
00491 cms._ModuleSequenceType.old__init__ = cms._ModuleSequenceType.__init__
00492 cms._ModuleSequenceType.__init__ = new__ModuleSequenceType__init__
00493     
00494 def new__ModuleSequenceType_resetModified(self):
00495     self._isModified=False
00496     self._modifications = []
00497 cms._ModuleSequenceType.resetModified = new__ModuleSequenceType_resetModified
00498 
00499 def new__ModuleSequenceType_isModified(self):
00500     return self._isModified
00501 cms._ModuleSequenceType.isModified = new__ModuleSequenceType_isModified
00502 
00503 def new__ModuleSequenceType_copy(self):
00504     returnValue = cms._ModuleSequenceType.__new__(type(self))
00505     returnValue.__init__(self._seq)
00506     returnValue._isModified = self._isModified
00507     returnValue._modifications = deepcopy(self._modifications)
00508     return returnValue
00509 cms._ModuleSequenceType.copy = new__ModuleSequenceType_copy
00510 
00511 def new__ModuleSequenceType_replace(self, original, replacement):
00512     stack = auto_inspect()
00513     self._isModified=True
00514     self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'replace','old':original._name(),'new':replacement._name()})
00515     return self.old_replace(original, replacement)
00516 cms._ModuleSequenceType.old_replace = cms._ModuleSequenceType.replace
00517 cms._ModuleSequenceType.replace = new__ModuleSequenceType_replace
00518 
00519 def new__ModuleSequenceType_remove(self, original):
00520     stack = auto_inspect()
00521     self._isModified=True
00522     self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'remove','old':original._name(),'new':None})
00523     return self.old_remove(original)
00524 cms._ModuleSequenceType.old_remove = cms._ModuleSequenceType.remove
00525 cms._ModuleSequenceType.remove = new__ModuleSequenceType_remove
00526 
00527 def new__ModuleSequenceType__imul__(self,other):
00528     stack = auto_inspect()
00529     self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'append','new':other._name(),'old':None})
00530     self._isModified=True
00531     return self.old__iadd__(other)
00532 cms._ModuleSequenceType.old__imul__ = cms._ModuleSequenceType.__imul__
00533 cms._ModuleSequenceType.__imul__ = new__ModuleSequenceType__imul__
00534 
00535 def new__ModuleSequenceType__iadd__(self,other):
00536     stack = auto_inspect()
00537     self._isModified=True
00538     self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'append','new':other._name(),'old':None})
00539     return self.old__iadd__(other)
00540 cms._ModuleSequenceType.old__iadd__ = cms._ModuleSequenceType.__iadd__
00541 cms._ModuleSequenceType.__iadd__ = new__ModuleSequenceType__iadd__
00542 
00543 from FWCore.ParameterSet.Modules  import Source
00544 from FWCore.GuiBrowsers.editorTools import changeSource
00545             
00546 if __name__=='__main__':
00547     import unittest
00548     class TestModificationTracking(unittest.TestCase):
00549         def setUp(self):
00550             pass
00551         def testPSet(self):
00552             ex = cms.EDAnalyzer("Example",
00553                 one = cms.double(0),
00554                 two = cms.bool(True),
00555                 ps = cms.PSet(
00556                     three = cms.int32(10),
00557                     four = cms.string('abc')
00558                 ),
00559                 vps = cms.VPSet(
00560                     cms.PSet(
00561                         five = cms.InputTag('alpha')
00562                     ),
00563                     cms.PSet(
00564                         six = cms.vint32(1,2,3)
00565                     )
00566                 ),
00567                 seven = cms.vstring('alpha','bravo','charlie'),
00568                 eight = cms.vuint32(range(10)),
00569                 nine = cms.int32(0)
00570             )
00571             ex.zero = cms.string('hello')
00572             self.assertEqual(ex._modifications[-1]['name'],'zero')
00573             ex.one = cms.double(1)
00574             ex.one = cms.double(2)
00575             ex.one = cms.double(3)
00576             self.assertEqual(ex._modifications[-1]['name'],'one')
00577             self.assertEqual(ex._modifications[-2]['name'],'one')
00578             self.assertEqual(ex._modifications[-3]['name'],'one')
00579             ex.two = False
00580             self.assertEqual(ex._modifications[-1]['name'],'two')
00581             ex.ps.three.setValue(100) # MISSED
00582             #self.assertEqual(ex.ps._modifications.pop()['name'],'three')
00583             ex.ps.four = 'def'
00584             self.assertEqual(ex.ps._modifications[-1]['name'],'four')
00585             ex.vps[0].five = cms.string('beta')
00586             self.assertEqual(ex.vps[0]._modifications[-1]['name'],'five')
00587             ex.vps[1].__dict__['six'] = cms.vint32(1,4,9) # MISSED
00588             #self.assertEqual(ex.vps[1]._modifications[-1]['name'],'six')
00589             ex.seven[0] = 'delta' # MISSED
00590             #self.assertEqual(ex._modifications[-1]['name'],'seven')
00591             ex.eight.pop() # MISSED
00592             #self.assertEqual(ex._modifications[-1]['name'],'eight')
00593             del ex.nine
00594             #self.assertEqual(ex._modifications[-1]['name'],'nine')
00595             ex.newvpset = cms.VPSet()
00596             self.assertEqual(ex._modifications[-1]['name'],'newvpset')
00597             
00598             process = cms.Process('unittest')
00599             process.ex = ex
00600             mods = process.dumpModifications()
00601             self.assert_('process.ex.zero' in mods)
00602             self.assert_('process.ex.one' in mods)
00603             self.assert_('process.ex.two' in mods)
00604             #self.assert_('process.ex.three' in mods)
00605             self.assert_('process.ex.ps.four' in mods)
00606             self.assert_('process.ex.vps[0].five' in mods)
00607             #self.assert_('process.ex.vps[1].six' in mods)
00608             #self.assert_('process.ex.seven[0]' in mods)
00609             #self.assert_('process.ex.eight' in mods)
00610             self.assert_('process.ex.nine' in mods)
00611             self.assert_('process.ex.newvpset' in mods)
00612             
00613             
00614 
00615         def testSeq(self):
00616             process = cms.Process('unittest')
00617             for i in range(10):
00618               setattr(process,'f%s'%i,cms.EDFilter('f%s'%i))
00619             process.seq1 = cms.Sequence(process.f1*process.f2*process.f3)
00620             self.assertEqual(process.seq1._modifications,[])
00621             process.seq2 = cms.Sequence(process.f4+process.f5+process.f6)
00622             self.assertEqual(process.seq2._modifications,[])
00623             
00624             process.seq1.replace(process.f1,process.f0*process.f1)
00625             self.assertEqual(process.seq1._modifications[-1]['action'],'replace')
00626             
00627             process.seq2.remove(process.f5)
00628             self.assertEqual(process.seq2._modifications[-1]['action'],'remove')
00629             
00630             process.path = cms.Path(process.seq1*process.f7)
00631             self.assertEqual(process.path._modifications,[])
00632             
00633             process.path *= process.seq2
00634             self.assertEqual(process.path._modifications[-1]['action'],'append')
00635             process.path.remove(process.f6)
00636             self.assertEqual(process.path._modifications[-1]['action'],'remove')
00637             process.path.replace(process.f2,~process.f2)
00638             self.assertEqual(process.path._modifications[-1]['action'],'replace')
00639             
00640             mods = process.dumpModifications()
00641             self.assert_('process.seq1' in mods)
00642             self.assert_('process.seq2' in mods)
00643             self.assert_('process.path' in mods)
00644             
00645         def testdumpHistory(self):
00646             process = cms.Process('unittest')
00647             process.source=Source("PoolSource",fileNames = cms.untracked.string("file:file.root"))
00648             
00649             changeSource(process,"file:filename.root")
00650             self.assertEqual(changeSource._parameters['source'].value,"file:filename.root")
00651             
00652             changeSource(process,"file:filename2.root")
00653             self.assertEqual(changeSource._parameters['source'].value,"file:filename2.root")
00654             
00655             changeSource(process,"file:filename3.root")
00656             self.assertEqual(changeSource._parameters['source'].value,"file:filename3.root")
00657     
00658             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")
00659             
00660             process.source.fileNames=cms.untracked.vstring("file:replacedfile.root") 
00661             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")
00662             
00663             process.disableRecording()
00664             changeSource.setParameter('source',"file:filename4.root")
00665             action=changeSource.__copy__()
00666             process.addAction(action)
00667             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")
00668             
00669             process.enableRecording()
00670             changeSource.setParameter('source',"file:filename5.root")
00671             action=changeSource.__copy__()
00672             process.addAction(action)
00673             process.deleteAction(3)
00674             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")
00675 
00676             process.deleteAction(0)
00677             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")
00678             
00679         def testModifiedObjectsHistory(self):
00680             process = cms.Process('unittest')
00681             process.source=Source("PoolSource",fileNames = cms.untracked.string("file:file.root"))
00682             
00683             changeSource(process,"file:filename.root")
00684             self.assertEqual(len(process.history()[0][1]),1)
00685             
00686             process.source.fileNames=cms.untracked.vstring("file:replacedfile.root") 
00687             self.assertEqual(len(process.history()[0][1]),1)
00688             self.assertEqual(len(process.history()[1][1]),1)
00689 
00690             process.source.fileNames=["test2"]
00691             self.assertEqual(len(process.history()[0][1]),1)
00692             self.assertEqual(len(process.history()[1][1]),1)
00693 
00694             changeSource(process,"file:filename2.root")
00695             self.assertEqual(len(process.history()[0][1]),1)
00696             self.assertEqual(len(process.history()[1][1]),1)
00697             self.assertEqual(len(process.history()[2][1]),1)
00698             
00699             process.source.fileNames=cms.untracked.vstring("file:replacedfile2.root") 
00700             self.assertEqual(len(process.history()[0][1]),1)
00701             self.assertEqual(len(process.history()[1][1]),1)
00702             self.assertEqual(len(process.history()[2][1]),1)
00703             self.assertEqual(len(process.history()[3][1]),1)
00704             
00705     unittest.main()
00706