CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/HLTriggerOffline/Egamma/python/EgammaHLTValidationUtils.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import FWCore.ParameterSet.Config as cms
00003 import sys, os
00004 
00005 # prefix for printouts
00006 msgPrefix = "[" + os.path.basename(__file__) + "]"
00007 
00008 
00009 #----------------------------------------------------------------------
00010 
00011 def getPathsOfDataSet(process, datasetName):
00012     """ returns the names of the trigger paths contained in the
00013         given (primary) dataset """
00014 
00015     return list(getattr(process.datasets, datasetName))
00016 
00017 #----------------------------------------------------------------------
00018 
00019 
00020 def getProcessName(pdgGen, requiredNumberOfGeneratedObjects):
00021     """ returns a process name (such as 'Zee') which can be
00022      used in various places (e.g. module names etc.) """
00023 
00024     if pdgGen == 11:
00025 
00026         # electron paths
00027         if requiredNumberOfGeneratedObjects == 1:
00028             return "Wenu"
00029         elif requiredNumberOfGeneratedObjects == 2:
00030             return "Zee"
00031         else:
00032             raise Exception("unsupported case, can't guess type of process")
00033 
00034     elif pdgGen == 22:
00035 
00036         # photon paths
00037         if requiredNumberOfGeneratedObjects == 1:
00038             return 'GammaJet'
00039         elif requiredNumberOfGeneratedObjects == 2:
00040             return 'DiGamma'
00041         else:
00042             raise Exception("unsupported case, can't guess type of process")
00043     else:
00044         raise Exception("unsupported case, can't guess type of process")
00045 
00046 
00047 #----------------------------------------------------------------------
00048 
00049 def makeGeneratedParticleAndFiducialVolumeFilter(process, pdgGen, requiredNumberOfGeneratedObjects):
00050     """
00051     adds the needed modules to the process object and
00052     returns a sequence made of the two filters.
00053 
00054     returns the name of the created module
00055 
00056     if process is not None, are added to the process.
00057 
00058     When using this function from a _cff file, one
00059     has to manually add the modules of the returned
00060     sequence to globals() (in the calling module, not
00061     here, globals() live in a different name space here)
00062     
00063     """
00064 
00065     # name of the physics process
00066     procName = getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
00067 
00068     #--------------------
00069     # create a module producing a collection with the 
00070     # desired generated particles
00071     #--------------------
00072 
00073     genPartModuleName = 'genpart' + procName
00074 
00075 
00076     genPartModule = cms.EDFilter("PdgIdAndStatusCandViewSelector",
00077                                  status = cms.vint32(3),
00078                                  src = cms.InputTag("genParticles"),
00079                                  pdgId = cms.vint32(pdgGen),
00080                                  )
00081 
00082     # genPartModule.setLabel(genPartModuleName)
00083     if process != None:
00084         setattr(process, genPartModuleName, genPartModule)
00085 
00086     genPartModule.setLabel(genPartModuleName)
00087 
00088     #--------------------
00089     # create a module requiring the number
00090     # of generated particles
00091     #--------------------
00092 
00093     selectorModuleName = "fiducial" + procName
00094 
00095     selectorModule = cms.EDFilter("EtaPtMinCandViewSelector",
00096                                   src = cms.InputTag(genPartModuleName),
00097                                   etaMin = cms.double(-2.5),  
00098                                   etaMax = cms.double(2.5),   
00099                                   ptMin = cms.double(2.0)
00100                                   )
00101 
00102     if process != None:
00103         setattr(process, selectorModuleName, selectorModule)
00104 
00105     # this is needed if we don't have a process to attach this module to
00106     selectorModule.setLabel(selectorModuleName)
00107 
00108     #--------------------
00109     # create the sequence
00110     #--------------------
00111 
00112     return cms.Sequence(
00113         # getattr(process, genPartModuleName)
00114         genPartModule 
00115 
00116         *
00117 
00118         # getattr(process, selectorModuleName)
00119         selectorModule
00120         )
00121 #----------------------------------------------------------------------
00122 
00123 import HLTriggerOffline.Egamma.TriggerTypeDefs_cfi as TriggerTypeDefs_cfi
00124 
00125 class EgammaDQMModuleMaker:
00126     """ a class which can be used to produce an analysis path
00127         for the EmDQM analyzer """
00128 
00129     #----------------------------------------
00130 
00131     def __init__(self, process, pathName, pdgGen, requiredNumberOfGeneratedObjects, cutCollection = None):
00132         """
00133         pathName is the HLT path to be validated.
00134 
00135         pdgGen is the PDG id of the corersponding generated particles
00136           (11 for electrons, 22 for photons)
00137 
00138         requiredNumberOfGeneratedObjects should be 1 for single triggers,
00139         and 2 for double triggers (e.g. double photon triggers)
00140 
00141         cutCollection is the name of the collection which should be used
00142           to define the acceptance region (at reconstruction level ?).
00143           typical values are 'fiducialZee'. If this is set to None,
00144           will be determined automatically from pdgGen and requiredNumberOfGeneratedObjects
00145 
00146         """
00147 
00148         self.process = process
00149         self.pathName = pathName
00150 
00151         self.path = getattr(process,pathName)
00152 
00153         # the process whose products should be analyzed
00154         self.processName = "HLT"
00155 
00156         #--------------------
00157         # guess the collection for the fiducial volume cut
00158         #--------------------
00159 
00160         if cutCollection == None:
00161             cutCollection = "fiducial" + getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
00162 
00163         #--------------------
00164         # initialize the analyzer we put together here
00165         #--------------------
00166         self.__result = cms.EDAnalyzer("EmDQM",
00167                                      triggerobject = cms.InputTag("hltTriggerSummaryRAW","","HLT"),                            
00168                                      genEtaAcc = cms.double(2.5),
00169                                      genEtAcc = cms.double(2.0),
00170                                      reqNum = cms.uint32(requiredNumberOfGeneratedObjects),
00171                                      filters = cms.VPSet(), # will be added later
00172                                      PtMax = cms.untracked.double(100.0),
00173                                      pdgGen = cms.int32(pdgGen),
00174                                      cutcollection = cms.InputTag(cutCollection),
00175 
00176                                      # is this a requirement on reconstructed or generated number of objects ?
00177                                      cutnum = cms.int32(requiredNumberOfGeneratedObjects),
00178 
00179 
00180                                        
00181                                        )
00182 
00183         #--------------------
00184         # get all modules of this path.
00185         # dirty hack: assumes that all modules
00186         #   are concatenated by '+'
00187         # but easier than to use a node visitor
00188         # and order the modules ourselves afterwards..
00189 
00190         moduleNames = str(self.path).split('+')
00191 
00192         # now find out which of these are EDFilters
00193         # and what CMSSW class type they are
00194 
00195         # example:
00196         #
00197         # CMSSW type                               module name
00198         # --------------------------------------------------------------------------------------------------------------------
00199         # HLTTriggerTypeFilter                     hltTriggerType 
00200         # HLTLevel1GTSeed                          hltL1sL1SingleEG8 
00201         # HLTPrescaler                             hltPreEle17SWTighterEleIdIsolL1R 
00202         # HLTEgammaL1MatchFilterRegional           hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolL1MatchFilterRegional 
00203         # HLTEgammaEtFilter                        hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolEtFilter 
00204         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolR9ShapeFilter 
00205         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolClusterShapeFilter 
00206         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TIghterEleIdIsolEcalIsolFilter 
00207         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHEFilter 
00208         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHcalIsolFilter 
00209         # HLTElectronPixelMatchFilter              hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolPixelMatchFilter 
00210         # HLTElectronOneOEMinusOneOPFilterRegional hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolOneOEMinusOneOPFilter 
00211         # HLTElectronGenericFilter                 hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDetaFilter 
00212         # HLTElectronGenericFilter                 hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDphiFilter 
00213         # HLTElectronGenericFilter                 hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolTrackIsolFilter 
00214         # HLTBool                                  hltBoolEnd 
00215 
00216         # it looks like in the MC menu, all modules have a name containing 'L1NonIso' and then
00217         # have a parameter IsoCollections (which is mostly cms.Input("none")...)
00218 
00219         import FWCore.ParameterSet.Modules
00220 
00221         for moduleName in moduleNames:
00222 
00223             # add protection to avoid accessing non-existing modules
00224             # (not understood why this is needed but happens
00225             # in some cases...).
00226             #
00227             # should also cover the special cases listed afterwards
00228             # (i.e. the check after this one could be removed
00229             # at some point)
00230             if not hasattr(self.process, moduleName):
00231                 continue
00232 
00233             # protection for FastSim HLT menu
00234             # which seems to reference certain modules in some
00235             # paths but these modules are not defined when just
00236             # loading the HLT menu into a process object.
00237             #
00238             # this seems not to happen for the fullsim menu for some
00239             # reason...
00240             if moduleName in ('simulation',
00241                               'offlineBeamSpot',
00242                               'HLTEndSequence'):
00243                 continue
00244 
00245             
00246 
00247             module = getattr(self.process,moduleName)
00248 
00249             if not isinstance(module, FWCore.ParameterSet.Modules.EDFilter):
00250                 continue
00251 
00252             # ignore certain EDFilters
00253             if module.type_() in ('HLTTriggerTypeFilter',
00254                                   'HLTPrescaler',
00255                                   'HLTBool'):
00256                 continue
00257 
00258             # print "XX", module.type_(), moduleName
00259 
00260             #--------------------
00261             if module.type_() == 'HLTLevel1GTSeed':
00262                 # L1 seed
00263                 self.__result.filters.append(self.makePSetForL1SeedFilter(moduleName))
00264                 continue
00265 
00266             #--------------------
00267             if module.type_() == 'HLTEgammaL1MatchFilterRegional':
00268                 # L1 seed to supercluster match
00269                 self.__result.filters.append(self.makePSetForL1SeedToSuperClusterMatchFilter(moduleName))
00270                 continue
00271 
00272             #--------------------
00273 
00274             if module.type_() == "HLTEgammaEtFilter":
00275                 # minimum Et requirement
00276                 self.__result.filters.append(self.makePSetForEtFilter(moduleName))
00277                 continue
00278 
00279             #--------------------
00280 
00281             if module.type_() == "HLTElectronOneOEMinusOneOPFilterRegional":
00282                 self.__result.filters.append(self.makePSetForOneOEMinusOneOPFilter(moduleName))
00283                 continue
00284 
00285             #--------------------
00286             if module.type_() == "HLTElectronPixelMatchFilter":
00287                 self.__result.filters.append(self.makePSetForPixelMatchFilter(moduleName))
00288                 continue
00289 
00290             #--------------------
00291             # generic filters: the module types
00292             # aren't enough, we must check on which
00293             # input collections they filter on
00294             #--------------------
00295 
00296             if module.type_() == "HLTEgammaGenericFilter":
00297 
00298                 pset = self.makePSetForEgammaGenericFilter(module, moduleName)
00299                 if pset != None:
00300                     self.__result.filters.append(pset)
00301                     continue
00302 
00303             #--------------------
00304 
00305             if module.type_() == "HLTElectronGenericFilter":
00306 
00307                 pset = self.makePSetForElectronGenericFilter(module, moduleName)
00308                 if pset != None:
00309                     self.__result.filters.append(pset)
00310                     continue
00311 
00312             #--------------------
00313 
00314 ##            print >> sys.stderr,msgPrefix,"WARNING: unknown module type", module.type_(), " with name " + moduleName + " in path " + pathName
00315                                          
00316     #----------------------------------------
00317     
00318     def makePSetForL1SeedFilter(self,moduleName):
00319         """ generates a PSet to analyze the behaviour of an L1 seed.
00320 
00321             moduleName is the name of the HLT module which filters
00322             on the L1 seed.
00323         """
00324 
00325         return cms.PSet(
00326             PlotBounds = cms.vdouble(0.0, 0.0),
00327             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00328             IsoCollections = cms.VInputTag(cms.InputTag("none")),
00329             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerL1NoIsoEG)
00330         ) 
00331 
00332     #----------------------------------------
00333 
00334     def makePSetForL1SeedToSuperClusterMatchFilter(self,moduleName):
00335         """ generates a PSet to analyze the behaviour of L1 to supercluster match filter.
00336 
00337             moduleName is the name of the HLT module which requires the match
00338             between supercluster and L1 seed.
00339         """
00340 
00341         return cms.PSet(
00342             PlotBounds = cms.vdouble(0.0, 0.0),
00343             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00344             IsoCollections = cms.VInputTag(cms.InputTag("none")),
00345             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
00346         ) 
00347 
00348     #----------------------------------------
00349 
00350     def makePSetForEtFilter(self, moduleName):
00351         """ generates a PSet for the Egamma DQM analyzer for the Et filter """
00352 
00353         return cms.PSet(
00354             PlotBounds = cms.vdouble(0.0, 0.0),
00355             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00356             IsoCollections = cms.VInputTag(cms.InputTag("none")),
00357             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
00358         )
00359 
00360     #----------------------------------------
00361 
00362     def makePSetForOneOEMinusOneOPFilter(self, moduleName):
00363 
00364         return cms.PSet(
00365             PlotBounds = cms.vdouble(0.0, 0.0),
00366             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00367             IsoCollections = cms.VInputTag(cms.InputTag("none")),
00368             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerElectron)
00369             )
00370 
00371     #----------------------------------------
00372 
00373     def makePSetForPixelMatchFilter(self, moduleName):
00374         return cms.PSet(
00375             PlotBounds = cms.vdouble(0.0, 0.0),
00376             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00377             IsoCollections = cms.VInputTag(cms.InputTag("none")),
00378             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
00379             )
00380 
00381     #----------------------------------------
00382 
00383     def makePSetForEgammaGenericFilter(self, module, moduleName):
00384 
00385         # example usages of HLTEgammaGenericFilter are:
00386         #   R9 shape filter                        hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolR9ShapeFilter 
00387         #   cluster shape filter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolClusterShapeFilter 
00388         #   Ecal isolation filter                  hltL1NonIsoHLTNonIsoSingleElectronEt17TIghterEleIdIsolEcalIsolFilter
00389         #   H/E filter                             hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHEFilter
00390         #   HCAL isolation filter                  hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHcalIsolFilter
00391 
00392         # the type of object to look for seems to be the
00393         # same for all uses of HLTEgammaGenericFilter
00394         theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
00395 
00396         # infer the type of filter by the type of the producer which
00397         # generates the collection used to cut on this
00398         inputCollectionLabel = module.isoTag.moduleLabel
00399 
00400         inputType = getattr(self.process, inputCollectionLabel).type_()
00401         # print >> sys.stderr, "inputType=",inputType,moduleName
00402 
00403         #--------------------
00404         # sanity check: non-isolated path should be produced by the
00405         # same type of module
00406         #
00407         # first check that the non-iso tag is non-empty
00408         assert(module.nonIsoTag.moduleLabel != "")
00409 
00410         assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
00411 
00412         #--------------------
00413 
00414 
00415         # the following cases seem to have identical PSets ?
00416 
00417         #--------------------
00418         # R9 shape
00419         #--------------------
00420 
00421         if inputType == 'EgammaHLTR9Producer':
00422             return cms.PSet(
00423                 PlotBounds = cms.vdouble(0.0, 0.0),
00424                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00425                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
00426                 theHLTOutputTypes = theHLTOutputTypes
00427                 )
00428 
00429         #--------------------
00430         # cluster shape
00431         #--------------------
00432         if inputType == 'EgammaHLTClusterShapeProducer':
00433             return cms.PSet(
00434                 PlotBounds = cms.vdouble(0.0, 0.0),
00435                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00436                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
00437                 theHLTOutputTypes = theHLTOutputTypes
00438                 )
00439 
00440         #--------------------
00441         # ecal isolation
00442         #--------------------
00443         if inputType == 'EgammaHLTEcalRecIsolationProducer':
00444             return cms.PSet(
00445                 PlotBounds = cms.vdouble(0.0, 0.0),
00446                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00447                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
00448                 theHLTOutputTypes = theHLTOutputTypes
00449                 )
00450 
00451         #--------------------
00452         # HCAL isolation and HE
00453         #--------------------
00454 
00455         if inputType == 'EgammaHLTHcalIsolationProducersRegional':
00456             return cms.PSet(
00457                 PlotBounds = cms.vdouble(0.0, 0.0),
00458                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00459                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
00460                 theHLTOutputTypes = theHLTOutputTypes
00461                 )
00462             
00463         
00464         raise Exception("can't determine what the HLTEgammaGenericFilter '" + moduleName + "' should do: uses a collection produced by a module of C++ type '" + inputType + "'")
00465 
00466     #----------------------------------------
00467 
00468     def makePSetForElectronGenericFilter(self, module, moduleName):
00469 
00470         # example usages of HLTElectronGenericFilter are:
00471 
00472         # deta filter      hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDetaFilter
00473         # dphi filter      hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDphiFilter
00474         # track isolation  hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolTrackIsolFilter
00475 
00476         # the type of object to look for seems to be the
00477         # same for all uses of HLTEgammaGenericFilter
00478         theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerElectron)
00479 
00480         # infer the type of filter by the type of the producer which
00481         # generates the collection used to cut on this
00482         inputCollectionLabel = module.isoTag.moduleLabel
00483 
00484         inputType = getattr(self.process, inputCollectionLabel).type_()
00485         # print >> sys.stderr, "inputType=",inputType,moduleName
00486 
00487         # sanity check: non-isolated path should be produced by the
00488         # same type of module
00489         assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
00490 
00491         # the following cases seem to have identical PSets ?
00492 
00493         #--------------------
00494         # deta and dphi filter
00495         #--------------------
00496 
00497         # note that whether deta or dphi is used is determined from
00498         # the product instance (not the module label)
00499         if inputType == 'EgammaHLTElectronDetaDphiProducer':
00500 
00501             return cms.PSet(
00502                 PlotBounds = cms.vdouble(0.0, 0.0),
00503                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00504                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
00505                 theHLTOutputTypes = theHLTOutputTypes
00506                 )
00507 
00508         #--------------------
00509         # track isolation
00510         #--------------------
00511 
00512         if inputType == 'EgammaHLTElectronTrackIsolationProducers':
00513 
00514             return cms.PSet(
00515                 PlotBounds = cms.vdouble(0.0, 0.0),
00516                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
00517                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
00518                 theHLTOutputTypes = theHLTOutputTypes
00519                 )
00520         raise Exception("can't determine what the HLTElectronGenericFilter '" + moduleName + "' should do: uses a collection produced by a module of C++ type '" + inputType + "'")
00521 
00522     #----------------------------------------
00523 
00524     def getResult(self):
00525         """ returns the composed analyzer module """
00526         return self.__result
00527 
00528     #----------------------------------------    
00529 
00530 #----------------------------------------------------------------------
00531 # main
00532 #----------------------------------------------------------------------
00533 if __name__ == "__main__":
00534 
00535     import FWCore.ParameterSet.Config as cms
00536     process = cms.Process("MYTEST")
00537     process.load("HLTrigger.Configuration.HLT_GRun_cff")
00538 
00539     moduleMaker = EgammaDQMModuleMaker(process, "HLT_Ele17_SW_TighterEleIdIsol_L1R_v3", 11, 1)
00540 
00541     # print "# ----------------------------------------------------------------------"
00542 
00543     print moduleMaker.getResult().dumpPython()
00544 
00545 #----------------------------------------------------------------------
00546 
00547 def findEgammaPaths(process):
00548     """
00549     returns a dict:
00550 
00551      {
00552        "singleElectron": [ list of single electron path objects ],
00553        "doubleElectron": [ list of double electron path objects ],
00554        "singlePhoton":   [ list of single photon path objects ],
00555        "doublePhoton":   [ list of double photon path objects ],
00556      }
00557 
00558      Note that the elements in the lists are path objects, not path names.
00559 
00560      Note also that this is based on the name of the paths using some
00561      heuristics.
00562      """
00563 
00564     retval = { "singleElectron": [],
00565                "doubleElectron": [],
00566                "singlePhoton":   [],
00567                "doublePhoton":   [],
00568                }
00569     
00570     for path_name, path in process.paths.items():
00571 
00572         # print "XX",path_name.__class__,path.__class__
00573 
00574         if path_name.startswith("AlCa_"):
00575             continue
00576 
00577         if path_name.startswith("DQM_"):
00578             continue
00579 
00580         if not path_name.startswith("HLT_"):
00581             continue
00582 
00583         if path_name.startswith("HLT_Ele"):
00584             retval['singleElectron'].append(path)
00585             continue
00586         
00587         if path_name.startswith("HLT_Photon"):
00588             retval['singlePhoton'].append(path)
00589             continue
00590 
00591         if path_name.startswith("HLT_DoublePhoton"):
00592             retval['doublePhoton'].append(path)
00593             continue
00594 
00595         if path_name.startswith("HLT_DoubleEle"):
00596             retval['doubleElectron'].append(path)
00597             continue
00598 
00599     # end of loop over paths
00600     return retval
00601 
00602 #----------------------------------------------------------------------
00603 
00604 def getModuleNamesOfPath(path):
00605     """ returns the names of the modules found in the given path.
00606 
00607     Note that these are not guaranteed to be in any particular
00608     order.
00609     """
00610 
00611     # this function could actually call getModulesOfSequence(..)
00612     # and then produce a set with the unique names of
00613     # the modules
00614 
00615     import FWCore.ParameterSet.Modules
00616     class Visitor:
00617 
00618         #----------------------------------------
00619         def __init__(self):
00620             self.module_names_found = set()
00621 
00622         #----------------------------------------
00623         def enter(self,visitee):
00624 
00625             if isinstance(visitee, FWCore.ParameterSet.Modules._Module):
00626                 self.module_names_found.add(visitee.label_())
00627 
00628         #----------------------------------------
00629         def leave(self,visitee):
00630             pass
00631 
00632         #----------------------------------------
00633                 
00634     visitor = Visitor()
00635     path.visit(visitor)
00636 
00637     return visitor.module_names_found
00638 
00639 
00640 #----------------------------------------------------------------------
00641 def getCXXTypesOfPath(process, path):
00642     """ returns the names of (classes) of the C++ types of the modules
00643     found in the given path (in no particular order) """
00644 
00645     moduleNames = getModuleNamesOfPath(path)
00646 
00647     retval = set()
00648 
00649     for name in moduleNames:
00650 
00651         # skip those modules which are in the path
00652         # but not in the process object.
00653         # not understood why we need to do this
00654         # but seems to cause problems in practice...
00655         if not hasattr(process,name):
00656             continue
00657 
00658         module = getattr(process, name)
00659 
00660         retval.add(module.type_())
00661 
00662     return retval
00663 
00664 #----------------------------------------------------------------------
00665 
00666 def getModulesOfSequence(sequence):
00667     """ returns the modules found in a sequence.
00668 
00669     Note that a module can appear more than once.
00670     """
00671 
00672     import FWCore.ParameterSet.Modules
00673     class Visitor:
00674 
00675         #----------------------------------------
00676         def __init__(self):
00677             self.modules_found = []
00678 
00679         #----------------------------------------
00680         def enter(self,visitee):
00681 
00682             if isinstance(visitee, FWCore.ParameterSet.Modules._Module):
00683                 self.modules_found.append(visitee)
00684 
00685         #----------------------------------------
00686         def leave(self,visitee):
00687             pass
00688 
00689         #----------------------------------------
00690                 
00691     visitor = Visitor()
00692     sequence.visitNode(visitor)
00693 
00694     return visitor.modules_found
00695 
00696 
00697 #----------------------------------------------------------------------