Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-26 02:34:21

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