Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:20:52

0001 #!/usr/bin/env python
0002 from __future__ import print_function
0003 import FWCore.ParameterSet.Config as cms
0004 import sys, os, re
0005 
0006 # prefix for printouts
0007 msgPrefix = "[" + os.path.basename(__file__) + "]"
0008 
0009 
0010 #----------------------------------------------------------------------
0011 
0012 def getPathsOfDataSet(process, datasetName):
0013     """ returns the names of the trigger paths contained in the
0014         given (primary) dataset """
0015 
0016     return list(getattr(process.datasets, datasetName))
0017 
0018 #----------------------------------------------------------------------
0019 
0020 
0021 def getProcessName(pdgGen, requiredNumberOfGeneratedObjects):
0022     """ returns a process name (such as 'Zee') which can be
0023      used in various places (e.g. module names etc.) """
0024 
0025     if pdgGen == 11:
0026 
0027         # electron paths
0028         if requiredNumberOfGeneratedObjects == 1:
0029             return "Wenu"
0030         elif requiredNumberOfGeneratedObjects == 2:
0031             return "Zee"
0032         else:
0033             raise Exception("unsupported case, can't guess type of process")
0034 
0035     elif pdgGen == 22:
0036 
0037         # photon paths
0038         if requiredNumberOfGeneratedObjects == 1:
0039             return 'GammaJet'
0040         elif requiredNumberOfGeneratedObjects == 2:
0041             return 'DiGamma'
0042         else:
0043             raise Exception("unsupported case, can't guess type of process")
0044     else:
0045         raise Exception("unsupported case, can't guess type of process")
0046 
0047 
0048 #----------------------------------------------------------------------
0049 
0050 def makeGeneratedParticleAndFiducialVolumeFilter(process, pdgGen, requiredNumberOfGeneratedObjects):
0051     """
0052     adds the needed modules to the process object and
0053     returns a sequence made of the two filters.
0054 
0055     returns the name of the created module
0056 
0057     if process is not None, are added to the process.
0058 
0059     When using this function from a _cff file, one
0060     has to manually add the modules of the returned
0061     sequence to globals() (in the calling module, not
0062     here, globals() live in a different name space here)
0063     
0064     """
0065 
0066     # name of the physics process
0067     procName = getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
0068 
0069     #--------------------
0070     # create a module producing a collection with the 
0071     # desired generated particles
0072     #--------------------
0073 
0074     genPartModuleName = 'genpart' + procName
0075 
0076 
0077     genPartModule = cms.EDFilter("PdgIdAndStatusCandViewSelector",
0078                                  status = cms.vint32(3),
0079                                  src = cms.InputTag("genParticles"),
0080                                  pdgId = cms.vint32(pdgGen),
0081                                  )
0082 
0083     # genPartModule.setLabel(genPartModuleName)
0084     if process != None:
0085         setattr(process, genPartModuleName, genPartModule)
0086 
0087     genPartModule.setLabel(genPartModuleName)
0088 
0089     #--------------------
0090     # create a module requiring the number
0091     # of generated particles
0092     #--------------------
0093 
0094     selectorModuleName = "fiducial" + procName
0095 
0096     selectorModule = cms.EDFilter("EtaPtMinCandViewSelector",
0097                                   src = cms.InputTag(genPartModuleName),
0098                                   etaMin = cms.double(-2.5),  
0099                                   etaMax = cms.double(2.5),   
0100                                   ptMin = cms.double(2.0)
0101                                   )
0102 
0103     if process != None:
0104         setattr(process, selectorModuleName, selectorModule)
0105 
0106     # this is needed if we don't have a process to attach this module to
0107     selectorModule.setLabel(selectorModuleName)
0108 
0109     #--------------------
0110     # create the sequence
0111     #--------------------
0112 
0113     return cms.Sequence(
0114         # getattr(process, genPartModuleName)
0115         genPartModule 
0116 
0117         *
0118 
0119         # getattr(process, selectorModuleName)
0120         selectorModule
0121         )
0122 #----------------------------------------------------------------------
0123 
0124 import HLTriggerOffline.Egamma.TriggerTypeDefs_cfi as TriggerTypeDefs_cfi
0125 
0126 class EgammaDQMModuleMaker:
0127     """ a class which can be used to produce an analysis path
0128         for the EmDQM analyzer """
0129 
0130     #----------------------------------------
0131 
0132     def __init__(self, process, pathName, pdgGen, requiredNumberOfGeneratedObjects, cutCollection = None):
0133         """
0134         pathName is the HLT path to be validated.
0135 
0136         pdgGen is the PDG id of the corersponding generated particles
0137           (11 for electrons, 22 for photons)
0138 
0139         requiredNumberOfGeneratedObjects should be 1 for single triggers,
0140         and 2 for double triggers (e.g. double photon triggers)
0141 
0142         cutCollection is the name of the collection which should be used
0143           to define the acceptance region (at reconstruction level ?).
0144           typical values are 'fiducialZee'. If this is set to None,
0145           will be determined automatically from pdgGen and requiredNumberOfGeneratedObjects
0146 
0147         """
0148 
0149         self.process = process
0150         self.pathName = pathName
0151 
0152         self.path = getattr(process,pathName)
0153 
0154         # the process whose products should be analyzed
0155         self.processName = "HLT"
0156 
0157         #--------------------
0158         # guess the collection for the fiducial volume cut
0159         #--------------------
0160 
0161         if cutCollection == None:
0162             cutCollection = "fiducial" + getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
0163 
0164         #--------------------
0165         # find Et threshold of primary object
0166         #--------------------
0167         mo = re.match("HLT_.*?(\d+).*",pathName)
0168 
0169         if mo != None:
0170             etThreshold = float(mo.group(1))
0171         else:
0172             etThreshold = -1.0
0173 
0174         #--------------------
0175         # initialize the analyzer we put together here
0176         #--------------------
0177         from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer
0178         self.__result = DQMEDAnalyzer('EmDQM',
0179                                      triggerobject = cms.InputTag("hltTriggerSummaryRAW","","HLT"),                            
0180                                      genEtaAcc = cms.double(2.5),
0181                                      genEtAcc = cms.double(2.0),
0182                                      reqNum = cms.uint32(requiredNumberOfGeneratedObjects),
0183                                      filters = cms.VPSet(), # will be added later
0184                                      PtMax = cms.untracked.double(100.0),
0185                                      genEtMin = cms.untracked.double(etThreshold),
0186                                      pdgGen = cms.int32(pdgGen),
0187                                      cutcollection = cms.InputTag(cutCollection),
0188 
0189                                      # is this a requirement on reconstructed or generated number of objects ?
0190                                      cutnum = cms.int32(requiredNumberOfGeneratedObjects),
0191 
0192 
0193                                        
0194                                        )
0195 
0196         #--------------------
0197         # get all modules of this path.
0198         # dirty hack: assumes that all modules
0199         #   are concatenated by '+'
0200         # but easier than to use a node visitor
0201         # and order the modules ourselves afterwards..
0202 
0203         moduleNames = str(self.path).split('+')
0204 
0205         # now find out which of these are EDFilters
0206         # and what CMSSW class type they are
0207 
0208         # example:
0209         #
0210         # CMSSW type                               module name
0211         # --------------------------------------------------------------------------------------------------------------------
0212         # HLTTriggerTypeFilter                     hltTriggerType 
0213         # HLTLevel1GTSeed                          hltL1sL1SingleEG8 
0214         # HLTPrescaler                             hltPreEle17SWTighterEleIdIsolL1R 
0215         # HLTEgammaL1MatchFilterRegional           hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolL1MatchFilterRegional 
0216         # HLTEgammaEtFilter                        hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolEtFilter 
0217         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolR9ShapeFilter 
0218         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolClusterShapeFilter 
0219         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TIghterEleIdIsolEcalIsolFilter 
0220         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHEFilter 
0221         # HLTEgammaGenericFilter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHcalIsolFilter 
0222         # HLTElectronPixelMatchFilter              hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolPixelMatchFilter 
0223         # HLTElectronOneOEMinusOneOPFilterRegional hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolOneOEMinusOneOPFilter 
0224         # HLTElectronGenericFilter                 hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDetaFilter 
0225         # HLTElectronGenericFilter                 hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDphiFilter 
0226         # HLTElectronGenericFilter                 hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolTrackIsolFilter 
0227         # HLTBool                                  hltBoolEnd 
0228 
0229         # it looks like in the MC menu, all modules have a name containing 'L1NonIso' and then
0230         # have a parameter IsoCollections (which is mostly cms.Input("none")...)
0231 
0232         import FWCore.ParameterSet.Modules
0233 
0234         for moduleName in moduleNames:
0235 
0236             # add protection to avoid accessing non-existing modules
0237             # (not understood why this is needed but happens
0238             # in some cases...).
0239             #
0240             # should also cover the special cases listed afterwards
0241             # (i.e. the check after this one could be removed
0242             # at some point)
0243             if not hasattr(self.process, moduleName):
0244                 continue
0245 
0246             # protection for FastSim HLT menu
0247             # which seems to reference certain modules in some
0248             # paths but these modules are not defined when just
0249             # loading the HLT menu into a process object.
0250             #
0251             # this seems not to happen for the fullsim menu for some
0252             # reason...
0253             if moduleName in ('simulation',
0254                               'offlineBeamSpot',
0255                               'HLTEndSequence'):
0256                 continue
0257 
0258             
0259 
0260             module = getattr(self.process,moduleName)
0261 
0262             if not isinstance(module, FWCore.ParameterSet.Modules.EDFilter):
0263                 continue
0264 
0265             # ignore certain EDFilters
0266             if module.type_() in ('HLTTriggerTypeFilter',
0267                                   'HLTPrescaler',
0268                                   'HLTBool'):
0269                 continue
0270 
0271             # print "XX", module.type_(), moduleName
0272 
0273             #--------------------
0274             if module.type_() == 'HLTLevel1GTSeed':
0275                 # L1 seed
0276                 self.__result.filters.append(self.makePSetForL1SeedFilter(moduleName))
0277                 continue
0278 
0279             #--------------------
0280             if module.type_() == 'HLTEgammaL1MatchFilterRegional':
0281                 # L1 seed to supercluster match
0282                 self.__result.filters.append(self.makePSetForL1SeedToSuperClusterMatchFilter(moduleName))
0283                 continue
0284 
0285             #--------------------
0286 
0287             if module.type_() == "HLTEgammaEtFilter":
0288                 # minimum Et requirement
0289                 self.__result.filters.append(self.makePSetForEtFilter(moduleName))
0290                 continue
0291 
0292             #--------------------
0293 
0294             if module.type_() == "HLTElectronOneOEMinusOneOPFilterRegional":
0295                 self.__result.filters.append(self.makePSetForOneOEMinusOneOPFilter(moduleName))
0296                 continue
0297 
0298             #--------------------
0299             if module.type_() == "HLTElectronPixelMatchFilter":
0300                 self.__result.filters.append(self.makePSetForPixelMatchFilter(moduleName))
0301                 continue
0302 
0303             #--------------------
0304             # generic filters: the module types
0305             # aren't enough, we must check on which
0306             # input collections they filter on
0307             #--------------------
0308 
0309             if module.type_() == "HLTEgammaGenericFilter":
0310 
0311                 pset = self.makePSetForEgammaGenericFilter(module, moduleName)
0312                 if pset != None:
0313                     self.__result.filters.append(pset)
0314                     continue
0315 
0316             #--------------------
0317 
0318             if module.type_() == "HLTElectronGenericFilter":
0319 
0320                 pset = self.makePSetForElectronGenericFilter(module, moduleName)
0321                 if pset != None:
0322                     self.__result.filters.append(pset)
0323                     continue
0324 
0325             #--------------------
0326 
0327 ##            print >> sys.stderr,msgPrefix,"WARNING: unknown module type", module.type_(), " with name " + moduleName + " in path " + pathName
0328                                          
0329     #----------------------------------------
0330     
0331     def makePSetForL1SeedFilter(self,moduleName):
0332         """ generates a PSet to analyze the behaviour of an L1 seed.
0333 
0334             moduleName is the name of the HLT module which filters
0335             on the L1 seed.
0336         """
0337 
0338         return cms.PSet(
0339             PlotBounds = cms.vdouble(0.0, 0.0),
0340             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0341             IsoCollections = cms.VInputTag(cms.InputTag("none")),
0342             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerL1NoIsoEG)
0343         ) 
0344 
0345     #----------------------------------------
0346 
0347     def makePSetForL1SeedToSuperClusterMatchFilter(self,moduleName):
0348         """ generates a PSet to analyze the behaviour of L1 to supercluster match filter.
0349 
0350             moduleName is the name of the HLT module which requires the match
0351             between supercluster and L1 seed.
0352         """
0353 
0354         return cms.PSet(
0355             PlotBounds = cms.vdouble(0.0, 0.0),
0356             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0357             IsoCollections = cms.VInputTag(cms.InputTag("none")),
0358             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
0359         ) 
0360 
0361     #----------------------------------------
0362 
0363     def makePSetForEtFilter(self, moduleName):
0364         """ generates a PSet for the Egamma DQM analyzer for the Et filter """
0365 
0366         return cms.PSet(
0367             PlotBounds = cms.vdouble(0.0, 0.0),
0368             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0369             IsoCollections = cms.VInputTag(cms.InputTag("none")),
0370             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
0371         )
0372 
0373     #----------------------------------------
0374 
0375     def makePSetForOneOEMinusOneOPFilter(self, moduleName):
0376 
0377         return cms.PSet(
0378             PlotBounds = cms.vdouble(0.0, 0.0),
0379             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0380             IsoCollections = cms.VInputTag(cms.InputTag("none")),
0381             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerElectron)
0382             )
0383 
0384     #----------------------------------------
0385 
0386     def makePSetForPixelMatchFilter(self, moduleName):
0387         return cms.PSet(
0388             PlotBounds = cms.vdouble(0.0, 0.0),
0389             HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0390             IsoCollections = cms.VInputTag(cms.InputTag("none")),
0391             theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
0392             )
0393 
0394     #----------------------------------------
0395 
0396     def makePSetForEgammaGenericFilter(self, module, moduleName):
0397 
0398         # example usages of HLTEgammaGenericFilter are:
0399         #   R9 shape filter                        hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolR9ShapeFilter 
0400         #   cluster shape filter                   hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolClusterShapeFilter 
0401         #   Ecal isolation filter                  hltL1NonIsoHLTNonIsoSingleElectronEt17TIghterEleIdIsolEcalIsolFilter
0402         #   H/E filter                             hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHEFilter
0403         #   HCAL isolation filter                  hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolHcalIsolFilter
0404 
0405         # the type of object to look for seems to be the
0406         # same for all uses of HLTEgammaGenericFilter
0407         theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
0408 
0409         # infer the type of filter by the type of the producer which
0410         # generates the collection used to cut on this
0411         inputCollectionLabel = module.isoTag.moduleLabel
0412 
0413         inputType = getattr(self.process, inputCollectionLabel).type_()
0414         # print >> sys.stderr, "inputType=",inputType,moduleName
0415 
0416         #--------------------
0417         # sanity check: non-isolated path should be produced by the
0418         # same type of module
0419         #
0420         # first check that the non-iso tag is non-empty
0421         assert(module.nonIsoTag.moduleLabel != "")
0422 
0423         assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
0424 
0425         #--------------------
0426 
0427 
0428         # the following cases seem to have identical PSets ?
0429 
0430         #--------------------
0431         # R9 shape
0432         #--------------------
0433 
0434         if inputType == 'EgammaHLTR9Producer':
0435             return cms.PSet(
0436                 PlotBounds = cms.vdouble(0.0, 0.0),
0437                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0438                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
0439                 theHLTOutputTypes = theHLTOutputTypes
0440                 )
0441 
0442         #--------------------
0443         # cluster shape
0444         #--------------------
0445         if inputType == 'EgammaHLTClusterShapeProducer':
0446             return cms.PSet(
0447                 PlotBounds = cms.vdouble(0.0, 0.0),
0448                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0449                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
0450                 theHLTOutputTypes = theHLTOutputTypes
0451                 )
0452 
0453         #--------------------
0454         # ecal isolation
0455         #--------------------
0456         if inputType == 'EgammaHLTEcalRecIsolationProducer':
0457             return cms.PSet(
0458                 PlotBounds = cms.vdouble(0.0, 0.0),
0459                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0460                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
0461                 theHLTOutputTypes = theHLTOutputTypes
0462                 )
0463 
0464         #--------------------
0465         # HCAL isolation and HE
0466         #--------------------
0467 
0468         if inputType == 'EgammaHLTHcalIsolationProducersRegional':
0469             return cms.PSet(
0470                 PlotBounds = cms.vdouble(0.0, 0.0),
0471                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0472                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
0473                 theHLTOutputTypes = theHLTOutputTypes
0474                 )
0475             
0476         
0477         raise Exception("can't determine what the HLTEgammaGenericFilter '" + moduleName + "' should do: uses a collection produced by a module of C++ type '" + inputType + "'")
0478 
0479     #----------------------------------------
0480 
0481     def makePSetForElectronGenericFilter(self, module, moduleName):
0482 
0483         # example usages of HLTElectronGenericFilter are:
0484 
0485         # deta filter      hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDetaFilter
0486         # dphi filter      hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolDphiFilter
0487         # track isolation  hltL1NonIsoHLTNonIsoSingleElectronEt17TighterEleIdIsolTrackIsolFilter
0488 
0489         # the type of object to look for seems to be the
0490         # same for all uses of HLTEgammaGenericFilter
0491         theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerElectron)
0492 
0493         # infer the type of filter by the type of the producer which
0494         # generates the collection used to cut on this
0495         inputCollectionLabel = module.isoTag.moduleLabel
0496 
0497         inputType = getattr(self.process, inputCollectionLabel).type_()
0498         # print >> sys.stderr, "inputType=",inputType,moduleName
0499 
0500         # sanity check: non-isolated path should be produced by the
0501         # same type of module
0502         assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
0503 
0504         # the following cases seem to have identical PSets ?
0505 
0506         #--------------------
0507         # deta and dphi filter
0508         #--------------------
0509 
0510         # note that whether deta or dphi is used is determined from
0511         # the product instance (not the module label)
0512         if inputType == 'EgammaHLTElectronDetaDphiProducer':
0513 
0514             return cms.PSet(
0515                 PlotBounds = cms.vdouble(0.0, 0.0),
0516                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0517                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
0518                 theHLTOutputTypes = theHLTOutputTypes
0519                 )
0520 
0521         #--------------------
0522         # track isolation
0523         #--------------------
0524 
0525         if inputType == 'EgammaHLTElectronTrackIsolationProducers':
0526 
0527             return cms.PSet(
0528                 PlotBounds = cms.vdouble(0.0, 0.0),
0529                 HLTCollectionLabels = cms.InputTag(moduleName,"",self.processName),
0530                 IsoCollections = cms.VInputTag(module.isoTag, module.nonIsoTag),
0531                 theHLTOutputTypes = theHLTOutputTypes
0532                 )
0533         raise Exception("can't determine what the HLTElectronGenericFilter '" + moduleName + "' should do: uses a collection produced by a module of C++ type '" + inputType + "'")
0534 
0535     #----------------------------------------
0536 
0537     def getResult(self):
0538         """ returns the composed analyzer module """
0539         return self.__result
0540 
0541     #----------------------------------------    
0542 
0543 #----------------------------------------------------------------------
0544 # main
0545 #----------------------------------------------------------------------
0546 if __name__ == "__main__":
0547 
0548     import FWCore.ParameterSet.Config as cms
0549     process = cms.Process("MYTEST")
0550     process.load("HLTrigger.Configuration.HLT_GRun_cff")
0551 
0552     moduleMaker = EgammaDQMModuleMaker(process, "HLT_Ele17_SW_TighterEleIdIsol_L1R_v3", 11, 1)
0553 
0554     # print "# ----------------------------------------------------------------------"
0555 
0556     print(moduleMaker.getResult().dumpPython())
0557 
0558 #----------------------------------------------------------------------
0559 
0560 def findEgammaPaths(process):
0561     """
0562     returns a dict:
0563 
0564      {
0565        "singleElectron": [ list of single electron path objects ],
0566        "doubleElectron": [ list of double electron path objects ],
0567        "singlePhoton":   [ list of single photon path objects ],
0568        "doublePhoton":   [ list of double photon path objects ],
0569      }
0570 
0571      Note that the elements in the lists are path objects, not path names.
0572 
0573      Note also that this is based on the name of the paths using some
0574      heuristics.
0575      """
0576 
0577     retval = { "singleElectron": [],
0578                "doubleElectron": [],
0579                "singlePhoton":   [],
0580                "doublePhoton":   [],
0581                }
0582     
0583     for path_name, path in process.paths.items():
0584 
0585         # print "XX",path_name.__class__,path.__class__
0586 
0587         if path_name.startswith("AlCa_"):
0588             continue
0589 
0590         if path_name.startswith("DQM_"):
0591             continue
0592 
0593         if not path_name.startswith("HLT_"):
0594             continue
0595 
0596         if path_name.startswith("HLT_Ele"):
0597             retval['singleElectron'].append(path)
0598             continue
0599         
0600         if path_name.startswith("HLT_Photon"):
0601             retval['singlePhoton'].append(path)
0602             continue
0603 
0604         if path_name.startswith("HLT_DoublePhoton"):
0605             retval['doublePhoton'].append(path)
0606             continue
0607 
0608         if path_name.startswith("HLT_DoubleEle"):
0609             retval['doubleElectron'].append(path)
0610             continue
0611 
0612     # end of loop over paths
0613     return retval
0614 
0615 #----------------------------------------------------------------------
0616 
0617 def getModuleNamesOfPath(path):
0618     """ returns the names of the modules found in the given path.
0619 
0620     Note that these are not guaranteed to be in any particular
0621     order.
0622     """
0623 
0624     # this function could actually call getModulesOfSequence(..)
0625     # and then produce a set with the unique names of
0626     # the modules
0627 
0628     import FWCore.ParameterSet.Modules
0629     class Visitor:
0630 
0631         #----------------------------------------
0632         def __init__(self):
0633             self.module_names_found = set()
0634 
0635         #----------------------------------------
0636         def enter(self,visitee):
0637 
0638             if isinstance(visitee, FWCore.ParameterSet.Modules._Module):
0639                 self.module_names_found.add(visitee.label_())
0640 
0641         #----------------------------------------
0642         def leave(self,visitee):
0643             pass
0644 
0645         #----------------------------------------
0646                 
0647     visitor = Visitor()
0648     path.visit(visitor)
0649 
0650     return visitor.module_names_found
0651 
0652 
0653 #----------------------------------------------------------------------
0654 def getCXXTypesOfPath(process, path):
0655     """ returns the names of (classes) of the C++ types of the modules
0656     found in the given path (in no particular order) """
0657 
0658     moduleNames = getModuleNamesOfPath(path)
0659 
0660     retval = set()
0661 
0662     for name in moduleNames:
0663 
0664         # skip those modules which are in the path
0665         # but not in the process object.
0666         # not understood why we need to do this
0667         # but seems to cause problems in practice...
0668         if not hasattr(process,name):
0669             continue
0670 
0671         module = getattr(process, name)
0672 
0673         retval.add(module.type_())
0674 
0675     return retval
0676 
0677 #----------------------------------------------------------------------
0678 
0679 def getModulesOfSequence(sequence):
0680     """ returns the modules found in a sequence.
0681 
0682     Note that a module can appear more than once.
0683     """
0684 
0685     import FWCore.ParameterSet.Modules
0686     class Visitor:
0687 
0688         #----------------------------------------
0689         def __init__(self):
0690             self.modules_found = []
0691 
0692         #----------------------------------------
0693         def enter(self,visitee):
0694 
0695             if isinstance(visitee, FWCore.ParameterSet.Modules._Module):
0696                 self.modules_found.append(visitee)
0697 
0698         #----------------------------------------
0699         def leave(self,visitee):
0700             pass
0701 
0702         #----------------------------------------
0703                 
0704     visitor = Visitor()
0705     sequence.visitNode(visitor)
0706 
0707     return visitor.modules_found
0708 
0709 
0710 #----------------------------------------------------------------------