From 71616fac722de8cb89b538468bb5dd724ad434a4 Mon Sep 17 00:00:00 2001 From: Nurfikri Norjoharuddeen Date: Wed, 11 Sep 2019 16:03:30 +0200 Subject: [PATCH] Moved jetCollectionTools. Decoupled nanoAOD-based tasks from jetCollectionTools.py and store in custom_jme_cff.py --- PhysicsTools/NanoAOD/python/custom_jme_cff.py | 360 ++++++++++++++++-- .../python/{ => tools}/jetCollectionTools.py | 295 +++++--------- 2 files changed, 426 insertions(+), 229 deletions(-) rename PhysicsTools/PatAlgos/python/{ => tools}/jetCollectionTools.py (65%) diff --git a/PhysicsTools/NanoAOD/python/custom_jme_cff.py b/PhysicsTools/NanoAOD/python/custom_jme_cff.py index 4e289dd57a17b..a4d4a478f55b6 100644 --- a/PhysicsTools/NanoAOD/python/custom_jme_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_jme_cff.py @@ -6,52 +6,343 @@ from PhysicsTools.NanoAOD.common_cff import Var, P4Vars from PhysicsTools.NanoAOD.jets_cff import jetTable -from PhysicsTools.PatAlgos.jetCollectionTools import JETVARS, GenJetAdder, RecoJetAdder +from PhysicsTools.PatAlgos.tools.jetCollectionTools import GenJetAdder, RecoJetAdder + +import copy # # By default, these collections are saved in NanoAODs: # - ak4gen (GenJet in NanoAOD) # - ak8gen (GenJetAK8 in NanoAOD) -# -# Below is a list of genjets that we can save in NanoAOD. Switch enabled to be -# true if you want to store the jets +# Below is a list of genjets that we can save in NanoAOD. Set +# "enabled" to true if you want to store the jet collection config_genjets = [ - { "jet" : "ak6gen", "enabled" : False, "name" : "GenJetAK6", "doc" : "AK6 jets" }, - { "jet" : "ak10gen", "enabled" : False, "name" : "GenJetAK10", "doc" : "AK10 jets" }, + { + "jet" : "ak5gen", + "enabled" : False, + }, + { + "jet" : "ak6gen", + "enabled" : False, + }, + { + "jet" : "ak7gen", + "enabled" : False, + }, + { + "jet" : "ak9gen", + "enabled" : False, + }, + { + "jet" : "ak10gen", + "enabled" : False, + }, ] config_genjets = list(filter(lambda k: k['enabled'], config_genjets)) # +# GenJets info in NanoAOD +# +nanoInfo_genjets = { + "ak5gen" : { + "name" : "GenJetAK5", + "doc" : "AK5 jets", + }, + "ak6gen" : { + "name" : "GenJetAK6", + "doc" : "AK6 jets", + }, + "ak7gen" : { + "name" : "GenJetAK7", + "doc" : "AK9 jets", + }, + "ak9gen" : { + "name" : "GenJetAK9", + "doc" : "AK9 jets", + }, + "ak10gen" : { + "name" : "GenJetAK10", + "doc" : "AK10 jets", + }, +} # # By default, these collections are saved in NanoAODs: # - ak4pfchs (Jet in NanoAOD) # - ak8pfpuppi (FatJet in NanoAOD) # By default, the ak4pfchs (Jet) and ak8pfpuppi (FatJet) collections # are saved in NanoAODs. -# Below is a list of recojets that we can save in NanoAOD. Switch enabled to be -# true if you want to store the jets +# Below is a list of recojets that we can save in NanoAOD. Set "enabled" +# to true if you want to store the recojet collection. +# config_recojets = [ - { "jet" : "ak4pfpuppi", "enabled" : True, "name" : "JetPUPPI", "doc" : "AK4PFPUPPI jets", "inputCollection" : "slimmedJetsPuppi", "genJetsCollection": "slimmedGenJets" }, #Available in MiniAOD - { "jet" : "ak4calo", "enabled" : True, "name" : "JetCalo", "doc" : "AK4Calo jets", "inputCollection" : "slimmedCaloJets" , "genJetsCollection": "slimmedGenJets" }, #Available in MiniAOD - { "jet" : "ak4pf", "enabled" : True, "name" : "JetPF", "doc" : "AK4PF jets", "inputCollection" : "", "genJetsCollection": "slimmedGenJets" }, - { "jet" : "ak8pf", "enabled" : True, "name" : "FatJetPF", "doc" : "AK8PF jets", "inputCollection" : "", "genJetsCollection": "slimmedGenJetsAK8" }, - { "jet" : "ak8pfchs", "enabled" : True, "name" : "FatJetCHS", "doc" : "AK8PFCHS jets", "inputCollection" : "", "genJetsCollection": "slimmedGenJetsAK8" }, - { "jet" : "ak6pf", "enabled" : False, "name" : "JetAK6PF", "doc" : "AK6PF jets", "inputCollection" : "", "genJetsCollection": "AK6GenJetsNoNu" }, - { "jet" : "ak10pf", "enabled" : False, "name" : "FatJetAK10PF", "doc" : "AK10PF jets", "inputCollection" : "", "genJetsCollection": "AK10GenJetsNoNu" }, + { + "jet" : "ak4pfpuppi", + "enabled" : True, + "inputCollection" : "slimmedJetsPuppi", #Exist in MiniAOD + "genJetsCollection": "slimmedGenJets", + }, + { + "jet" : "ak4calo", + "enabled" : True, + "inputCollection" : "slimmedCaloJets", #Exist in MiniAOD + "genJetsCollection": "slimmedGenJets", + }, + { + "jet" : "ak4pf", + "enabled" : True, + "inputCollection" : "", + "genJetsCollection": "slimmedGenJets", + }, + { + "jet" : "ak8pf", + "enabled" : True, + "inputCollection" : "", + "genJetsCollection": "slimmedGenJetsAK8", + }, + { + "jet" : "ak8pfchs", + "enabled" : True, + "inputCollection" : "", + "genJetsCollection": "slimmedGenJetsAK8", + }, + { + "jet" : "ak6pf", + "enabled" : False, + "inputCollection" : "", + "genJetsCollection": "AK6GenJetsNoNu", + }, + { + "jet" : "ak10pf", + "enabled" : False, + "inputCollection" : "", + "genJetsCollection": "AK10GenJetsNoNu", + }, ] config_recojets = list(filter(lambda k: k['enabled'], config_recojets)) +# +# RecoJets info in NanoAOD +# +nanoInfo_recojets = { + "ak4pfpuppi" : { + "name" : "JetPUPPI", + "doc" : "AK4PFPUPPI jets", + }, + "ak4calo" : { + "name": "JetCalo", + "doc" : "AK4Calo jets", + }, + "ak4pf" : { + "name": "JetPF", + "doc" : "AK4PF jets", + }, + "ak8pf" : { + "name": "FatJetPF", + "doc" : "AK8PF jets", + }, + "ak8pfchs" : { + "name" : "FatJetCHS", + "doc" : "AK8PFCHS jets", + }, + "ak6pf" : { + "name": "JetAK6PF", + "doc" : "AK6PF jets", + }, + "ak10pf" : { + "name" : "FatJetAK10PF", + "doc" : "AK10PF jets", + }, +} + +# +# The reco jet names already exists +# in NanoAOD. +# +recojetNameInNano = [ "Jet", "FatJet" ] +# +# The gen jet names already exists +# in NanoAOD. +# +genjetNameInNano = [ "GenJet", "GenJetAK8" ] + +JETVARS = cms.PSet(P4Vars, + HFHEF = Var("HFHadronEnergyFraction()", float, doc = "energy fraction in forward hadronic calorimeter", precision = 6), + HFEMEF = Var("HFEMEnergyFraction()", float, doc = "energy fraction in forward EM calorimeter", precision = 6), + area = jetTable.variables.area, + chHEF = jetTable.variables.chHEF, + neHEF = jetTable.variables.neHEF, + chEmEF = jetTable.variables.chEmEF, + neEmEF = jetTable.variables.neEmEF, + muEF = jetTable.variables.muEF, + rawFactor = jetTable.variables.rawFactor, + jetId = jetTable.variables.jetId, + jercCHPUF = jetTable.variables.jercCHPUF, + jercCHF = jetTable.variables.jercCHF, +) for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016: modifier.toModify(JETVARS, jetId = Var("userInt('tightId')*2+userInt('looseId')", int, doc = "Jet ID flags bit1 is loose, bit2 is tight") ) +#============================================ +# +# TableGenJetAdder +# +#============================================ +class TableGenJetAdder(object): + """ + Tool to store gen jet variables in NanoAOD for customized + gen jet collections. + """ + def __init__(self): + self.main = [] + + def getSequence(self, proc): + """ + Tool to add + """ + tasks = self.main + + resultSequence = cms.Sequence() + for idx, task in enumerate(tasks): + if idx == 0: + resultSequence = cms.Sequence(getattr(proc, task)) + else: + resultSequence.insert(idx, getattr(proc, task)) + return resultSequence + + def addTable(self, proc, genJetInfo): + currentTasks = [] + + print("custom_jme_cff::TableGenJetAdder::addTable: Adding Table for GenJet Collection: {}".format(genJetInfo.jet)) + + name = nanoInfo_genjets[genJetInfo.jet]["name"] + doc = nanoInfo_genjets[genJetInfo.jet]["doc"] + + if name in genjetNameInNano: + raise RuntimeError('GenJet collection name (%s) taken in NanoAOD for %s' %(name, genJetInfo.jet)) + + # + # GenJet Table + # + table = "{}Table".format(genJetInfo.jetTagName) + genJetsCollection = "{}{}{}".format(genJetInfo.jetAlgo.upper(), genJetInfo.jetSize, 'GenJetsNoNu') + setattr(proc, table, cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag(genJetsCollection), + cut = cms.string(""), + name = cms.string(name), + doc = cms.string('{} (generator level)'.format(doc)), + singleton = cms.bool(False), + extension = cms.bool(False), + variables = cms.PSet(P4Vars, + area = jetTable.variables.area, + ), + ) + ) + currentTasks.append(table) + + # + # GenJet Flavour Table + # + genFlavour = "{}Flavour".format(genJetInfo.jetTagName) + genFlavourTable = "{}Table".format(genFlavour) + if genFlavourTable in self.main: + raise ValueError("Step '%s' already implemented" % genFlavourTable) + setattr(proc, genFlavourTable, cms.EDProducer("GenJetFlavourTableProducer", + name = cms.string(name), + src = cms.InputTag(genJetsCollection), + cut = cms.string(""), + deltaR = cms.double(0.1), + jetFlavourInfos = cms.InputTag(genFlavour), + ) + ) + currentTasks.append(genFlavourTable) + self.main.extend(currentTasks) + +#============================================ +# +# TableRecoJetAdder +# +#============================================ +class TableRecoJetAdder(object): + """ + Tool to store reco jet variables in NanoAOD for customized + reco jet collections. + """ + def __init__(self): + self.main = [] + + def getSequence(self, proc): + tasks = self.main + + resultSequence = cms.Sequence() + for idx, task in enumerate(tasks): + if idx == 0: + resultSequence = cms.Sequence(getattr(proc, task)) + else: + resultSequence.insert(idx, getattr(proc, task)) + return resultSequence + + def addTable(self, proc, recoJetInfo): + + currentTasks = [] + + print("custom_jme_cff::TableRecoJetAdder::addTable: Adding Table for Reco Jet Collection: {}".format(recoJetInfo.jet)) + + name = nanoInfo_recojets[recoJetInfo.jet]["name"] + doc = nanoInfo_recojets[recoJetInfo.jet]["doc"] + + if name in recojetNameInNano: + raise RuntimeError('RecoJet collection name (%s) taken in NanoAOD for %s' %(name, recoJetInfo.jet)) + + table = "{}Table".format(recoJetInfo.jetTagName) + if recoJetInfo.skipUserData: + if recoJetInfo.doCalo: + tableContents = cms.PSet( + P4Vars, + area = jetTable.variables.area, + rawFactor = jetTable.variables.rawFactor, + emf = Var("emEnergyFraction()", float, doc = "electromagnetic energy fraction", precision = 10), + ) + else: + tableContents = cms.PSet( + P4Vars, + area = jetTable.variables.area, + rawFactor = jetTable.variables.rawFactor, + ) + else: + tableContents = JETVARS.clone() + + updatedJets = "updatedJets{}".format(recoJetInfo.jetTagName) + setattr(proc, table, cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag(updatedJets), + cut = cms.string(""), + name = cms.string(name), + doc = cms.string(doc), + singleton = cms.bool(False), + extension = cms.bool(False), + variables = tableContents, + ) + ) + currentTasks.append(table) + + tightJetIdLepVeto = "tightJetIdLepVeto{}".format(recoJetInfo.jetTagName) + if not recoJetInfo.skipUserData: + altTasks = copy.deepcopy(currentTasks) + for idx, task in enumerate(altTasks): + if task == tightJetIdLepVeto: + altTasks[idx] = looseJetId + for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016: + modifier.toReplaceWith(currentTasks, altTasks) + self.main.extend(currentTasks) + + def PrepJMECustomNanoAOD(process): # # Additional variables to AK4GenJets # process.genJetTable.variables.area = JETVARS.area # - # additional variables to AK8GenJets + # Additional variables to AK8GenJets # process.genJetAK8Table.variables.area = JETVARS.area # @@ -76,8 +367,8 @@ def PrepJMECustomNanoAOD(process): # # process.jercVarsFatJet = process.jercVars.clone( - srcJet = cms.InputTag("updatedJetsAK8"), - maxDR = cms.double(0.8), + srcJet = "updatedJetsAK8", + maxDR = 0.8, ) process.jetSequence.insert(process.jetSequence.index(process.updatedJetsAK8WithUserData), process.jercVarsFatJet) @@ -89,28 +380,43 @@ def PrepJMECustomNanoAOD(process): ) process.fatJetTable.variables.jercCHPUF = JETVARS.jercCHPUF process.fatJetTable.variables.jercCHF = JETVARS.jercCHF - # # Remove any pT cuts. # - process.finalJets.cut = cms.string("") # 15 -> 10 - process.finalJetsAK8.cut = cms.string("") # 170 -> 170 - process.genJetTable.cut = cms.string("") # 10 -> 8 - process.genJetFlavourTable.cut = cms.string("") # 10 -> 8 - process.genJetAK8Table.cut = cms.string("") # 100 -> 80 - process.genJetAK8FlavourTable.cut = cms.string("") # 100 -> 80 + process.finalJets.cut = "" # 15 -> 10 + process.finalJetsAK8.cut = "" # 170 -> 170 + process.genJetTable.cut = "" # 10 -> 8 + process.genJetFlavourTable.cut = "" # 10 -> 8 + process.genJetAK8Table.cut = "" # 100 -> 80 + process.genJetAK8FlavourTable.cut = "" # 100 -> 80 ###################################################################################################################### + # + # Add GenJets to NanoAOD + # genJA = GenJetAdder() + tableGenJA = TableGenJetAdder() + for jetConfig in config_genjets: cfg = { k : v for k, v in jetConfig.items() if k != "enabled" } - genJA.addGenJetCollection(process, **cfg) + genJetInfo = genJA.addGenJetCollection(process, **cfg) + tableGenJA.addTable(process, genJetInfo) + process.nanoSequenceMC += genJA.getSequence(process) + process.nanoSequenceMC += tableGenJA.getSequence(process) + # + # Add RecoJets to NanoAOD + # recoJA = RecoJetAdder() + tableRecoJA = TableRecoJetAdder() + for jetConfig in config_recojets: cfg = { k : v for k, v in jetConfig.items() if k != "enabled" } - recoJA.addRecoJetCollection(process, **cfg) + recoJetInfo = recoJA.addRecoJetCollection(process, **cfg) + tableRecoJA.addTable(process, recoJetInfo) + process.nanoSequenceMC += recoJA.getSequence(process) + process.nanoSequenceMC += tableRecoJA.getSequence(process) diff --git a/PhysicsTools/PatAlgos/python/jetCollectionTools.py b/PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py similarity index 65% rename from PhysicsTools/PatAlgos/python/jetCollectionTools.py rename to PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py index ac427d97bd99d..97f0bf92eebe3 100644 --- a/PhysicsTools/PatAlgos/python/jetCollectionTools.py +++ b/PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py @@ -1,50 +1,40 @@ import FWCore.ParameterSet.Config as cms +from FWCore.GuiBrowsers.ConfigToolBase import * + from Configuration.Eras.Modifier_run2_miniAOD_80XLegacy_cff import run2_miniAOD_80XLegacy from Configuration.Eras.Modifier_run2_nanoAOD_94X2016_cff import run2_nanoAOD_94X2016 from RecoJets.JetProducers.PFJetParameters_cfi import PFJetParameters from RecoJets.JetProducers.GenJetParameters_cfi import GenJetParameters from RecoJets.JetProducers.AnomalousCellParameters_cfi import AnomalousCellParameters +from RecoJets.JetProducers.ak4GenJets_cfi import ak4GenJets from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection, supportedJetAlgos from PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cfi import updatedPatJets from PhysicsTools.PatAlgos.recoLayer0.jetCorrFactors_cfi import patJetCorrFactors +from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetFlavourAssociation + from CommonTools.PileupAlgos.Puppi_cff import puppi from CommonTools.PileupAlgos.softKiller_cfi import softKiller -from PhysicsTools.NanoAOD.common_cff import Var, P4Vars -from PhysicsTools.NanoAOD.jets_cff import jetTable - -import copy import re - -JETVARS = cms.PSet(P4Vars, - HFHEF = Var("HFHadronEnergyFraction()", float, doc = "energy fraction in forward hadronic calorimeter", precision = 6), - HFEMEF = Var("HFEMEnergyFraction()", float, doc = "energy fraction in forward EM calorimeter", precision = 6), - area = jetTable.variables.area, - chHEF = jetTable.variables.chHEF, - neHEF = jetTable.variables.neHEF, - chEmEF = jetTable.variables.chEmEF, - neEmEF = jetTable.variables.neEmEF, - muEF = jetTable.variables.muEF, - rawFactor = jetTable.variables.rawFactor, - jetId = jetTable.variables.jetId, - jercCHPUF = jetTable.variables.jercCHPUF, - jercCHF = jetTable.variables.jercCHF, -) - - #============================================ # -# JetInfo +# GenJetInfo # #============================================ class GenJetInfo(object): + """ + Class to hold information of a genjet collection + """ def __init__(self, jet, inputCollection): self.jet = jet + self.jetLower = jet.lower() + self.jetUpper = jet.upper() + self.jetTagName = self.jetUpper self.inputCollection = inputCollection algoKey = 'algo' sizeKey = 'size' @@ -56,7 +46,6 @@ def __init__(self, jet, inputCollection): size = sizeKey, ) ) - jetMatch = jetRegex.match(jet.lower()) if not jetMatch: raise RuntimeError('Invalid jet collection: %s' % jet) @@ -70,6 +59,9 @@ def __init__(self, jet, inputCollection): # #============================================ class GenJetAdder(object): + """ + Tool to schedule modules for building a genjet collection with input MiniAODs + """ def __init__(self): self.prerequisites = [] self.main = [] @@ -89,14 +81,13 @@ def getSequence(self, proc): def addGenJetCollection(self, proc, jet, - name, - doc, inputCollection = "", genName = "", minPt = 5., ): - print("custom_jme_cff::GenJetAdder::addGenJetCollection: Adding Gen Jet Collection: {}".format(jet)) + print("jetCollectionTools::GenJetAdder::addGenJetCollection: Adding Gen Jet Collection: {}".format(jet)) currentTasks = [] + # # Decide which jet collection we're dealing with # @@ -105,24 +96,16 @@ def addGenJetCollection(self, tagName = jetUpper genJetInfo = GenJetInfo(jet,inputCollection) - # - # Skip AK4GenJets and AK8GenJets. - # They're already available in the default NanoAOD - # - if genJetInfo.jetSize == "4" and genJetInfo.jetAlgo == "ak": - pass - elif genJetInfo.jetSize == "8" and genJetInfo.jetAlgo == "ak": - pass #======================================================= # - # If jet collection in MiniAOD is not - # specified, build the jet collection. + # If gen jet collection in MiniAOD is not + # specified, build the genjet collection. # #======================================================== if not inputCollection: - print("custom_jme_cff::GenJetAdder::addGenJetCollection: inputCollection in NanoAOD not specified. Building genjet collection now") + print("jetCollectionTools::GenJetAdder::addGenJetCollection: inputCollection not specified. Building genjet collection now") # - # Setup Gen Particles + # Setup GenParticles # packedGenPartNoNu = "packedGenParticlesForJetsNoNu" if packedGenPartNoNu not in self.prerequisites: @@ -136,86 +119,43 @@ def addGenJetCollection(self, # Create the GenJet collection # genJetsCollection = "{}{}{}".format(genJetInfo.jetAlgo.upper(), genJetInfo.jetSize, 'GenJetsNoNu') - setattr(proc, genJetsCollection, - cms.EDProducer("FastjetJetProducer", - GenJetParameters.clone( - src = packedGenPartNoNu, - doAreaFastjet = cms.bool(True), - ), - AnomalousCellParameters, - jetAlgorithm = cms.string(supportedJetAlgos[genJetInfo.jetAlgo]), - rParam = cms.double(genJetInfo.jetSizeNr), + setattr(proc, genJetsCollection, ak4GenJets.clone( + src = packedGenPartNoNu, + jetAlgorithm = cms.string(supportedJetAlgos[genJetInfo.jetAlgo]), + rParam = cms.double(genJetInfo.jetSizeNr), ) ) self.prerequisites.append(genJetsCollection) - - ############################ - # - # Tables - # - ############################ - genTable = "{}Table".format(tagName) - if genTable in self.main: - raise ValueError("Step '%s' already implemented" % genTable) - - setattr(proc, genTable, cms.EDProducer("SimpleCandidateFlatTableProducer", - src = cms.InputTag(genJetsCollection), - cut = cms.string(""), - name = cms.string(name), - doc = cms.string('{} (generator level)'.format(doc)), - singleton = cms.bool(False), - extension = cms.bool(False), - variables = cms.PSet(P4Vars, - area = jetTable.variables.area, - ), - ) - ) - currentTasks.append(genTable) # # GenJet Flavour Labelling # - genFlavour = "{}Flavour".format(tagName) - if genFlavour in self.main: - raise ValueError("Step '%s' already implemented" % genFlavour) - setattr(proc, genFlavour, cms.EDProducer("JetFlavourClustering", - jets = cms.InputTag(genJetsCollection), - bHadrons = cms.InputTag("patJetPartons", "bHadrons"), - cHadrons = cms.InputTag("patJetPartons", "cHadrons"), - partons = cms.InputTag("patJetPartons", "physicsPartons"), - leptons = cms.InputTag("patJetPartons", "leptons"), - jetAlgorithm = cms.string(supportedJetAlgos[genJetInfo.jetAlgo]), - rParam = cms.double(genJetInfo.jetSizeNr), - ghostRescaling = cms.double(1e-18), - hadronFlavourHasPriority = cms.bool(False), - ) - ) - currentTasks.append(genFlavour) - # - # GenJet Flavour Table - # - genFlavourTable = "{}FlavourTable".format(tagName) - if genFlavourTable in self.main: - raise ValueError("Step '%s' already implemented" % genFlavourTable) - setattr(proc, genFlavourTable, cms.EDProducer("GenJetFlavourTableProducer", - name = cms.string(name), - src = cms.InputTag(genJetsCollection), - cut = cms.string(""), - deltaR = cms.double(0.1), - jetFlavourInfos = cms.InputTag(genFlavour), + genFlavour = "{}Flavour".format(genJetInfo.jetTagName) + setattr(proc, genFlavour, patJetFlavourAssociation.clone( + jets = cms.InputTag(genJetsCollection), + jetAlgorithm = cms.string(supportedJetAlgos[genJetInfo.jetAlgo]), + rParam = cms.double(genJetInfo.jetSizeNr), ) ) - currentTasks.append(genFlavourTable) + currentTasks.append(genFlavour) self.main.extend(currentTasks) + return genJetInfo + #============================================ # # RecoJetInfo # #============================================ class RecoJetInfo(object): + """ + Class to hold information of a recojet collection + """ def __init__(self, jet, inputCollection): self.jet = jet + self.jetLower = jet.lower() + self.jetUpper = jet.upper() + self.jetTagName = self.jetUpper self.inputCollection = inputCollection algoKey = 'algo' sizeKey = 'size' @@ -261,23 +201,13 @@ def __init__(self, jet, inputCollection): # #============================================ class RecoJetAdder(object): - def __init__(self): + """ + Tool to schedule modules for building a recojet collection with input MiniAODs + """ + def __init__(self): self.prerequisites = [] self.main = [] - self.bTagDiscriminators = [ - 'pfTrackCountingHighEffBJetTags', - 'pfTrackCountingHighPurBJetTags', - 'pfJetProbabilityBJetTags', - 'pfJetBProbabilityBJetTags', - 'pfSimpleSecondaryVertexHighEffBJetTags', - 'pfSimpleSecondaryVertexHighPurBJetTags', - 'pfCombinedSecondaryVertexV2BJetTags', - 'pfCombinedInclusiveSecondaryVertexV2BJetTags', - 'pfCombinedMVAV2BJetTags', - 'pfDeepCSVJetTags:probb', - 'pfDeepCSVJetTags:probbb', - 'pfBoostedDoubleSecondaryVertexAK8BJetTags', - ] + self.bTagDiscriminators = ["None"] # No b-tagging by default self.JETCorrLevels = [ "L1FastJet", "L2Relative", "L3Absolute" ] self.pfLabel = "packedPFCandidates" self.pvLabel = "offlineSlimmedPrimaryVertices" @@ -298,27 +228,18 @@ def getSequence(self, proc): return resultSequence def addRecoJetCollection(self, - proc, - jet, - name, - doc, - inputCollection = "", - genJetsCollection = "", - minPt = 5., - bTagDiscriminators = None, - JETCorrLevels = None, + proc, + jet, + inputCollection = "", + genJetsCollection = "", + minPt = 5., + bTagDiscriminators = None, + JETCorrLevels = None, ): - print("custom_jme_cff::RecoJetAdder::addRecoJetCollection: Adding Reco Jet Collection: {}".format(jet)) + print("jetCollectionTools::RecoJetAdder::addRecoJetCollection: Adding Reco Jet Collection: {}".format(jet)) currentTasks = [] - # - # Check if name already exists in NanoAOD. - # Hard-coded at the moment. - # - if name in [ "Jet", "FatJet" ]: - raise RuntimeError("Name already taken: %s" % name) - if inputCollection and inputCollection not in [ "slimmedJets", "slimmedJetsAK8", "slimmedJetsPuppi", "slimmedCaloJets", ]: @@ -333,10 +254,10 @@ def addRecoJetCollection(self, # # Decide which jet collection we're dealing with # - jetLower = jet.lower() - jetUpper = jet.upper() - tagName = jetUpper recoJetInfo = RecoJetInfo(jet, inputCollection) + jetLower = recoJetInfo.jetLower + jetUpper = recoJetInfo.jetUpper + tagName = recoJetInfo.jetTagName if inputCollection == "slimmedJets": assert(jetLower == "ak4pfchs") @@ -349,12 +270,12 @@ def addRecoJetCollection(self, #======================================================= # - # If jet collection in MiniAOD is not + # If jet collection in MiniAOD is not # specified, build the jet collection. # #======================================================== if not inputCollection or recoJetInfo.doCalo: - print("custom_jme_cff::RecoJetAdder::addRecoJetCollection: inputCollection in NanoAOD not specified. Building recojet collection now") + print("jetCollectionTools::RecoJetAdder::addRecoJetCollection: inputCollection not specified. Building recojet collection now") #======================================================= # @@ -396,8 +317,8 @@ def addRecoJetCollection(self, elif recoJetInfo.jetPUMethod == "puppi": setattr(proc, pfCand, puppi.clone( - candName = cms.InputTag(self.pfLabel), - vertexName = cms.InputTag(self.pvLabel), + candName = self.pfLabel, + vertexName = self.pvLabel, ) ) self.prerequisites.append(pfCand) @@ -407,13 +328,14 @@ def addRecoJetCollection(self, elif recoJetInfo.jetPUMethod == "sk": setattr(proc, pfCand, softKiller.clone( - PFCandidates = cms.InputTag(self.pfLabel), - rParam = cms.double(recoJetInfo.jetSizeNr), + PFCandidates = self.pfLabel, + rParam = recoJetInfo.jetSizeNr, ) ) self.prerequisites.append(pfCand) else: raise RuntimeError("Currently unsupported PU method: '%s'" % recoJetInfo.jetPUMethod) + #============================================ # # Create the recojet collection @@ -428,9 +350,9 @@ def addRecoJetCollection(self, setattr(proc, jetCollection, cms.EDProducer("FastjetJetProducer", PFJetParameters.clone( - src = cms.InputTag(pfCand), - doAreaFastjet = cms.bool(True), - jetPtMin = cms.double(minPt), + src = pfCand, + doAreaFastjet = True, + jetPtMin = minPt, ), AnomalousCellParameters, jetAlgorithm = cms.string(supportedJetAlgos[recoJetInfo.jetAlgo]), @@ -485,9 +407,9 @@ def addRecoJetCollection(self, genJetCollection = cms.InputTag(genJetsCollection), genParticles = cms.InputTag(self.gpLabel), ) - + getJetMCFlavour = not recoJetInfo.doCalo and recoJetInfo.jetPUMethod != "cs" - + setattr(getattr(proc, "patJets{}".format(tagName)), "getJetMCFlavour", cms.bool(getJetMCFlavour)) setattr(getattr(proc, "patJetCorrFactors{}".format(tagName)), "payload", cms.string(recoJetInfo.jetCorrPayload)) selJet = "selectedPatJets{}".format(tagName) @@ -495,30 +417,40 @@ def addRecoJetCollection(self, selJet = inputCollection if not recoJetInfo.skipUserData: + # + # # jercVar = "jercVars{}".format(tagName) if jercVar in self.main: raise ValueError("Step '%s' already implemented" % jercVar) - setattr(proc, jercVar, proc.jercVars.clone(srcJet = cms.InputTag(selJet))) + setattr(proc, jercVar, proc.jercVars.clone(srcJet = selJet)) currentTasks.append(jercVar) # + # + # looseJetId = "looseJetId{}".format(tagName) if looseJetId in self.main: raise ValueError("Step '%s' already implemented" % looseJetId) - setattr(proc, looseJetId, proc.looseJetId.clone(src = cms.InputTag(selJet))) + setattr(proc, looseJetId, proc.looseJetId.clone(src = selJet)) + # + # # tightJetId = "tightJetId{}".format(tagName) if tightJetId in self.main: raise ValueError("Step '%s' already implemented" % tightJetId) - setattr(proc, tightJetId, proc.tightJetId.clone(src = cms.InputTag(selJet))) + setattr(proc, tightJetId, proc.tightJetId.clone(src = selJet)) currentTasks.append(tightJetId) # + # + # tightJetIdLepVeto = "tightJetIdLepVeto{}".format(tagName) if tightJetIdLepVeto in self.main: raise ValueError("Step '%s' already implemented" % tightJetIdLepVeto) - setattr(proc, tightJetIdLepVeto, proc.tightJetIdLepVeto.clone(src = cms.InputTag(selJet))) + setattr(proc, tightJetIdLepVeto, proc.tightJetIdLepVeto.clone(src = selJet)) currentTasks.append(tightJetIdLepVeto) # + # + # selectedPatJetsWithUserData = "{}WithUserData".format(selJet) if selectedPatJetsWithUserData in self.main: raise ValueError("Step '%s' already implemented" % selectedPatJetsWithUserData) @@ -544,17 +476,20 @@ def addRecoJetCollection(self, currentTasks.append(selectedPatJetsWithUserData) else: selectedPatJetsWithUserData = "selectedPatJets{}".format(tagName) - - # Not sure why we can't re-use patJetCorrFactors* created by addJetCollection() (even cloning doesn't work) - # Let's just create our own + + # + # Not sure why we can't re-use patJetCorrFactors* created by addJetCollection() + # (even cloning doesn't work) Let's just create our own + # jetCorrFactors = "jetCorrFactors{}".format(tagName) if jetCorrFactors in self.main: raise ValueError("Step '%s' already implemented" % jetCorrFactors) + setattr(proc, jetCorrFactors, patJetCorrFactors.clone( src = selectedPatJetsWithUserData, - levels = cms.vstring(JETCorrLevels), - primaryVertices = cms.InputTag(self.pvLabel), - payload = cms.string(recoJetInfo.jetCorrPayload), + levels = JETCorrLevels, + primaryVertices = self.pvLabel, + payload = recoJetInfo.jetCorrPayload, rho = "fixedGridRhoFastjetAll{}".format("Calo" if recoJetInfo.doCalo else ""), ) ) @@ -570,52 +505,8 @@ def addRecoJetCollection(self, jetCorrFactorsSource = cms.VInputTag(cms.InputTag(jetCorrFactors)), ) ) - currentTasks.append(updatedJets) - - ############################ - # - # Tables - # - ############################ - table = "{}Table".format(tagName) - if table in self.main: - raise ValueError("Step '%s' already implemented" % table) - - if recoJetInfo.skipUserData: - if recoJetInfo.doCalo: - tableContents = cms.PSet( - P4Vars, - area = jetTable.variables.area, - rawFactor = jetTable.variables.rawFactor, - emf = Var("emEnergyFraction()", float, doc = "electromagnetic energy fraction", precision = 10), - ) - else: - tableContents = cms.PSet( - P4Vars, - area = jetTable.variables.area, - rawFactor = jetTable.variables.rawFactor, - ) - else: - tableContents = JETVARS.clone() - - setattr(proc, table, cms.EDProducer("SimpleCandidateFlatTableProducer", - src = cms.InputTag(updatedJets), - cut = cms.string(""), - name = cms.string(name), - doc = cms.string(doc), - singleton = cms.bool(False), - extension = cms.bool(False), - variables = tableContents, - ) - ) - currentTasks.append(table) - - if not recoJetInfo.skipUserData: - altTasks = copy.deepcopy(currentTasks) - for idx, task in enumerate(altTasks): - if task == tightJetIdLepVeto: - altTasks[idx] = looseJetId - for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016: - modifier.toReplaceWith(currentTasks, altTasks) + currentTasks.append(updatedJets) self.main.extend(currentTasks) + + return recoJetInfo