File indexing completed on 2024-04-06 12:18:50
0001
0002 from __future__ import print_function
0003 import FWCore.ParameterSet.Config as cms
0004 import sys, os, re
0005
0006
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
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
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
0067 procName = getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
0068
0069
0070
0071
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
0084 if process != None:
0085 setattr(process, genPartModuleName, genPartModule)
0086
0087 genPartModule.setLabel(genPartModuleName)
0088
0089
0090
0091
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
0107 selectorModule.setLabel(selectorModuleName)
0108
0109
0110
0111
0112
0113 return cms.Sequence(
0114
0115 genPartModule
0116
0117 *
0118
0119
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
0155 self.processName = "HLT"
0156
0157
0158
0159
0160
0161 if cutCollection == None:
0162 cutCollection = "fiducial" + getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
0163
0164
0165
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
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(),
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
0190 cutnum = cms.int32(requiredNumberOfGeneratedObjects),
0191
0192
0193
0194 )
0195
0196
0197
0198
0199
0200
0201
0202
0203 moduleNames = str(self.path).split('+')
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 import FWCore.ParameterSet.Modules
0233
0234 for moduleName in moduleNames:
0235
0236
0237
0238
0239
0240
0241
0242
0243 if not hasattr(self.process, moduleName):
0244 continue
0245
0246
0247
0248
0249
0250
0251
0252
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
0266 if module.type_() in ('HLTTriggerTypeFilter',
0267 'HLTPrescaler',
0268 'HLTBool'):
0269 continue
0270
0271
0272
0273
0274 if module.type_() == 'HLTLevel1GTSeed':
0275
0276 self.__result.filters.append(self.makePSetForL1SeedFilter(moduleName))
0277 continue
0278
0279
0280 if module.type_() == 'HLTEgammaL1MatchFilterRegional':
0281
0282 self.__result.filters.append(self.makePSetForL1SeedToSuperClusterMatchFilter(moduleName))
0283 continue
0284
0285
0286
0287 if module.type_() == "HLTEgammaEtFilter":
0288
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
0305
0306
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
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
0399
0400
0401
0402
0403
0404
0405
0406
0407 theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
0408
0409
0410
0411 inputCollectionLabel = module.isoTag.moduleLabel
0412
0413 inputType = getattr(self.process, inputCollectionLabel).type_()
0414
0415
0416
0417
0418
0419
0420
0421 assert(module.nonIsoTag.moduleLabel != "")
0422
0423 assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
0424
0425
0426
0427
0428
0429
0430
0431
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
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
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
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
0484
0485
0486
0487
0488
0489
0490
0491 theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerElectron)
0492
0493
0494
0495 inputCollectionLabel = module.isoTag.moduleLabel
0496
0497 inputType = getattr(self.process, inputCollectionLabel).type_()
0498
0499
0500
0501
0502 assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
0503
0504
0505
0506
0507
0508
0509
0510
0511
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
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
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
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
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
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
0625
0626
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
0665
0666
0667
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