00001
00002 import FWCore.ParameterSet.Config as cms
00003 import sys, os
00004
00005
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
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
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
00066 procName = getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
00067
00068
00069
00070
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
00083 if process != None:
00084 setattr(process, genPartModuleName, genPartModule)
00085
00086 genPartModule.setLabel(genPartModuleName)
00087
00088
00089
00090
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
00106 selectorModule.setLabel(selectorModuleName)
00107
00108
00109
00110
00111
00112 return cms.Sequence(
00113
00114 genPartModule
00115
00116 *
00117
00118
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
00154 self.processName = "HLT"
00155
00156
00157
00158
00159
00160 if cutCollection == None:
00161 cutCollection = "fiducial" + getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
00162
00163
00164
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(),
00172 PtMax = cms.untracked.double(100.0),
00173 pdgGen = cms.int32(pdgGen),
00174 cutcollection = cms.InputTag(cutCollection),
00175
00176
00177 cutnum = cms.int32(requiredNumberOfGeneratedObjects),
00178
00179
00180
00181 )
00182
00183
00184
00185
00186
00187
00188
00189
00190 moduleNames = str(self.path).split('+')
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 import FWCore.ParameterSet.Modules
00220
00221 for moduleName in moduleNames:
00222
00223
00224
00225
00226
00227
00228
00229
00230 if not hasattr(self.process, moduleName):
00231 continue
00232
00233
00234
00235
00236
00237
00238
00239
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
00253 if module.type_() in ('HLTTriggerTypeFilter',
00254 'HLTPrescaler',
00255 'HLTBool'):
00256 continue
00257
00258
00259
00260
00261 if module.type_() == 'HLTLevel1GTSeed':
00262
00263 self.__result.filters.append(self.makePSetForL1SeedFilter(moduleName))
00264 continue
00265
00266
00267 if module.type_() == 'HLTEgammaL1MatchFilterRegional':
00268
00269 self.__result.filters.append(self.makePSetForL1SeedToSuperClusterMatchFilter(moduleName))
00270 continue
00271
00272
00273
00274 if module.type_() == "HLTEgammaEtFilter":
00275
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
00292
00293
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
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
00386
00387
00388
00389
00390
00391
00392
00393
00394 theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerCluster)
00395
00396
00397
00398 inputCollectionLabel = module.isoTag.moduleLabel
00399
00400 inputType = getattr(self.process, inputCollectionLabel).type_()
00401
00402
00403
00404
00405
00406
00407
00408 assert(module.nonIsoTag.moduleLabel != "")
00409
00410 assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
00411
00412
00413
00414
00415
00416
00417
00418
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
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
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
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
00471
00472
00473
00474
00475
00476
00477
00478 theHLTOutputTypes = cms.int32(TriggerTypeDefs_cfi.TriggerElectron)
00479
00480
00481
00482 inputCollectionLabel = module.isoTag.moduleLabel
00483
00484 inputType = getattr(self.process, inputCollectionLabel).type_()
00485
00486
00487
00488
00489 assert(inputType == getattr(self.process, module.nonIsoTag.moduleLabel).type_())
00490
00491
00492
00493
00494
00495
00496
00497
00498
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
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
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
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
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
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
00612
00613
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
00652
00653
00654
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