CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
custom_jme_cff.py
Go to the documentation of this file.
1 import FWCore.ParameterSet.Config as cms
2 
4 
5 from CommonTools.PileupAlgos.Puppi_cff import puppi
6 
7 from RecoJets.JetProducers.PileupJetID_cfi import pileupJetIdCalculator, pileupJetId
8 from RecoJets.JetProducers.PileupJetID_cfi import _chsalgos_81x, _chsalgos_94x, _chsalgos_102x
9 
10 from PhysicsTools.NanoAOD.common_cff import Var, P4Vars
11 from PhysicsTools.NanoAOD.jets_cff import jetTable, jetCorrFactorsNano, updatedJets, finalJets, qgtagger, hfJetShowerShapeforNanoAOD
12 from PhysicsTools.NanoAOD.jets_cff import genJetTable, genJetFlavourAssociation, genJetFlavourTable
13 
14 from PhysicsTools.PatAlgos.tools.jetCollectionTools import GenJetAdder, RecoJetAdder
15 from PhysicsTools.PatAlgos.tools.jetTools import supportedJetAlgos
16 from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection
17 
18 import copy
19 
20 bTagCSVV2 = ['pfCombinedInclusiveSecondaryVertexV2BJetTags']
21 bTagDeepCSV = ['pfDeepCSVJetTags:probb','pfDeepCSVJetTags:probbb','pfDeepCSVJetTags:probc']
22 bTagDeepJet = [
23  'pfDeepFlavourJetTags:probb','pfDeepFlavourJetTags:probbb','pfDeepFlavourJetTags:problepb',
24  'pfDeepFlavourJetTags:probc','pfDeepFlavourJetTags:probuds','pfDeepFlavourJetTags:probg'
25 ]
26 from RecoBTag.ONNXRuntime.pfParticleNetAK4_cff import _pfParticleNetAK4JetTagsAll
27 bTagDiscriminatorsForAK4 = bTagCSVV2+bTagDeepCSV+bTagDeepJet+_pfParticleNetAK4JetTagsAll
28 
29 from RecoBTag.ONNXRuntime.pfDeepBoostedJet_cff import _pfDeepBoostedJetTagsAll
30 from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetJetTagsAll
31 
32 btagHbb = ['pfBoostedDoubleSecondaryVertexAK8BJetTags']
33 btagDDX = [
34  'pfDeepDoubleBvLJetTags:probHbb',
35  'pfDeepDoubleCvLJetTags:probHcc',
36  'pfDeepDoubleCvBJetTags:probHcc',
37  'pfMassIndependentDeepDoubleBvLJetTags:probHbb',
38  'pfMassIndependentDeepDoubleCvLJetTags:probHcc',
39  'pfMassIndependentDeepDoubleCvBJetTags:probHcc'
40 ]
41 btagDDXV2 = [
42  'pfMassIndependentDeepDoubleBvLV2JetTags:probHbb',
43  'pfMassIndependentDeepDoubleCvLV2JetTags:probHcc',
44  'pfMassIndependentDeepDoubleCvBV2JetTags:probHcc'
45 ]
46 
47 #
48 # By default, these collections are saved in NanoAODs:
49 # - ak4gen (GenJet in NanoAOD), slimmedGenJets in MiniAOD
50 # - ak8gen (GenJetAK8 in NanoAOD), slimmedGenJetsAK8 in MiniAOD
51 # Below is a list of genjets that we can save in NanoAOD. Set
52 # "enabled" to true if you want to store the jet collection
53 config_genjets = [
54  {
55  "jet" : "ak6gen",
56  "enabled" : False,
57  },
58 ]
59 config_genjets = list(filter(lambda k: k['enabled'], config_genjets))
60 #
61 # GenJets info in NanoAOD
62 #
63 nanoInfo_genjets = {
64  "ak6gen" : {
65  "name" : "GenJetAK6",
66  "doc" : "AK6 Gen jets (made with visible genparticles) with pt > 3 GeV", # default genjets pt cut after clustering is 3 GeV
67  },
68 }
69 #
70 # By default, these collections are saved in the main NanoAODs:
71 # - ak4pfchs (Jet in NanoAOD), slimmedJets in MiniAOD
72 # - ak8pfpuppi (FatJet in NanoAOD), slimmedJetsAK8 in MiniAOD
73 # Below is a list of recojets that we can save in NanoAOD. Set
74 # "enabled" to true if you want to store the recojet collection.
75 #
76 config_recojets = [
77  {
78  "jet" : "ak4calo",
79  "enabled" : True,
80  "inputCollection" : "slimmedCaloJets", #Exist in MiniAOD
81  "genJetsCollection": "AK4GenJetsNoNu",
82  },
83  {
84  "jet" : "ak4pf",
85  "enabled" : False,
86  "inputCollection" : "",
87  "genJetsCollection": "AK4GenJetsNoNu",
88  "minPtFastjet" : 0.,
89  },
90  {
91  "jet" : "ak4pfpuppi",
92  "enabled" : True,
93  "inputCollection" : "",
94  "genJetsCollection": "AK4GenJetsNoNu",
95  "bTagDiscriminators": bTagDiscriminatorsForAK4,
96  "minPtFastjet" : 0.,
97  },
98  {
99  "jet" : "ak8pf",
100  "enabled" : False,
101  "inputCollection" : "",
102  "genJetsCollection": "AK8GenJetsNoNu",
103  "minPtFastjet" : 0.,
104  },
105 ]
106 config_recojets = list(filter(lambda k: k['enabled'], config_recojets))
107 #
108 # RecoJets info in NanoAOD
109 #
110 nanoInfo_recojets = {
111  "ak4calo" : {
112  "name": "JetCalo",
113  "doc" : "AK4 Calo jets with JECs applied",
114  },
115  "ak4pf" : {
116  "name" : "JetPF",
117  "doc" : "AK4 PF jets",
118  "ptcut" : "",
119  },
120  "ak4pfpuppi" : {
121  "name" : "JetPuppi",
122  "doc" : "AK4 PF Puppi",
123  "ptcut" : "",
124  "doQGL" : True,
125  "doPUIDVar": True,
126  "doBTag": True,
127  },
128  "ak8pf" : {
129  "name" : "FatJetPF",
130  "doc" : "AK8 PF jets",
131  "ptcut" : "",
132  },
133 }
134 
135 GENJETVARS = cms.PSet(P4Vars,
136  nConstituents = jetTable.variables.nConstituents,
137 )
138 PFJETVARS = cms.PSet(P4Vars,
139  rawFactor = Var("1.-jecFactor('Uncorrected')",float,doc="1 - Factor to get back to raw pT",precision=6),
140  area = jetTable.variables.area,
141  chHEF = jetTable.variables.chHEF,
142  neHEF = jetTable.variables.neHEF,
143  chEmEF = jetTable.variables.chEmEF,
144  neEmEF = jetTable.variables.neEmEF,
145  muEF = jetTable.variables.muEF,
146  hfHEF = Var("HFHadronEnergyFraction()",float,doc = "hadronic energy fraction in HF",precision = 6),
147  hfEmEF = Var("HFEMEnergyFraction()",float,doc = "electromagnetic energy fraction in HF",precision = 6),
148  nMuons = jetTable.variables.nMuons,
149  nElectrons = jetTable.variables.nElectrons,
150  nConstituents = jetTable.variables.nConstituents,
151  nConstChHads = Var("chargedHadronMultiplicity()",int,doc="number of charged hadrons in the jet"),
152  nConstNeuHads = Var("neutralHadronMultiplicity()",int,doc="number of neutral hadrons in the jet"),
153  nConstHFHads = Var("HFHadronMultiplicity()", int,doc="number of HF hadrons in the jet"),
154  nConstHFEMs = Var("HFEMMultiplicity()",int,doc="number of HF EMs in the jet"),
155  nConstMuons = Var("muonMultiplicity()",int,doc="number of muons in the jet"),
156  nConstElecs = Var("electronMultiplicity()",int,doc="number of electrons in the jet"),
157  nConstPhotons = Var("photonMultiplicity()",int,doc="number of photons in the jet"),
158 )
159 PUIDVARS = cms.PSet(
160  puId_dR2Mean = Var("?(pt>10)?userFloat('puId_dR2Mean'):-1",float,doc="pT^2-weighted average square distance of jet constituents from the jet axis (PileUp ID BDT input variable)", precision= 6),
161  puId_majW = Var("?(pt>10)?userFloat('puId_majW'):-1",float,doc="major axis of jet ellipsoid in eta-phi plane (PileUp ID BDT input variable)", precision= 6),
162  puId_minW = Var("?(pt>10)?userFloat('puId_minW'):-1",float,doc="minor axis of jet ellipsoid in eta-phi plane (PileUp ID BDT input variable)", precision= 6),
163  puId_frac01 = Var("?(pt>10)?userFloat('puId_frac01'):-1",float,doc="fraction of constituents' pT contained within dR <0.1 (PileUp ID BDT input variable)", precision= 6),
164  puId_frac02 = Var("?(pt>10)?userFloat('puId_frac02'):-1",float,doc="fraction of constituents' pT contained within 0.1< dR <0.2 (PileUp ID BDT input variable)", precision= 6),
165  puId_frac03 = Var("?(pt>10)?userFloat('puId_frac03'):-1",float,doc="fraction of constituents' pT contained within 0.2< dR <0.3 (PileUp ID BDT input variable)", precision= 6),
166  puId_frac04 = Var("?(pt>10)?userFloat('puId_frac04'):-1",float,doc="fraction of constituents' pT contained within 0.3< dR <0.4 (PileUp ID BDT input variable)", precision= 6),
167  puId_ptD = Var("?(pt>10)?userFloat('puId_ptD'):-1",float,doc="pT-weighted average pT of constituents (PileUp ID BDT input variable)", precision= 6),
168  puId_beta = Var("?(pt>10)?userFloat('puId_beta'):-1",float,doc="fraction of pT of charged constituents associated to PV (PileUp ID BDT input variable)", precision= 6),
169  puId_pull = Var("?(pt>10)?userFloat('puId_pull'):-1",float,doc="magnitude of pull vector (PileUp ID BDT input variable)", precision= 6),
170  puId_jetR = Var("?(pt>10)?userFloat('puId_jetR'):-1",float,doc="fraction of jet pT carried by the leading constituent (PileUp ID BDT input variable)", precision= 6),
171  puId_jetRchg = Var("?(pt>10)?userFloat('puId_jetRchg'):-1",float,doc="fraction of jet pT carried by the leading charged constituent (PileUp ID BDT input variable)", precision= 6),
172  puId_nCharged = Var("?(pt>10)?userInt('puId_nCharged'):-1",int,doc="number of charged constituents (PileUp ID BDT input variable)"),
173 )
174 QGLVARS = cms.PSet(
175  qgl_axis2 = Var("?(pt>10)?userFloat('qgl_axis2'):-1",float,doc="ellipse minor jet axis (Quark vs Gluon likelihood input variable)", precision= 6),
176  qgl_ptD = Var("?(pt>10)?userFloat('qgl_ptD'):-1",float,doc="pT-weighted average pT of constituents (Quark vs Gluon likelihood input variable)", precision= 6),
177  qgl_mult = Var("?(pt>10)?userInt('qgl_mult'):-1", int,doc="PF candidates multiplicity (Quark vs Gluon likelihood input variable)"),
178 )
179 BTAGVARS = cms.PSet(
180  btagDeepB = Var("?(pt>15)&&((bDiscriminator('pfDeepCSVJetTags:probb')+bDiscriminator('pfDeepCSVJetTags:probbb'))>=0)?bDiscriminator('pfDeepCSVJetTags:probb')+bDiscriminator('pfDeepCSVJetTags:probbb'):-1",float,doc="DeepCSV b+bb tag discriminator",precision=10),
181  btagCSVV2 = Var("?pt>15?bDiscriminator('pfCombinedInclusiveSecondaryVertexV2BJetTags'):-1",float,doc=" pfCombinedInclusiveSecondaryVertexV2 b-tag discriminator (aka CSVV2)",precision=10),
182  btagDeepCvL = Var("?(pt>15)&&(bDiscriminator('pfDeepCSVJetTags:probc')>=0)?bDiscriminator('pfDeepCSVJetTags:probc')/(bDiscriminator('pfDeepCSVJetTags:probc')+bDiscriminator('pfDeepCSVJetTags:probudsg')):-1", float,doc="DeepCSV c vs udsg discriminator",precision=10),
183  btagDeepCvB = Var("?(pt>15)&&bDiscriminator('pfDeepCSVJetTags:probc')>=0?bDiscriminator('pfDeepCSVJetTags:probc')/(bDiscriminator('pfDeepCSVJetTags:probc')+bDiscriminator('pfDeepCSVJetTags:probb')+bDiscriminator('pfDeepCSVJetTags:probbb')):-1",float,doc="DeepCSV c vs b+bb discriminator",precision=10),
184 )
185 DEEPJETVARS = cms.PSet(
186  btagDeepFlavB = Var("?pt>15?bDiscriminator('pfDeepFlavourJetTags:probb')+bDiscriminator('pfDeepFlavourJetTags:probbb')+bDiscriminator('pfDeepFlavourJetTags:problepb'):-1",float,doc="DeepJet b+bb+lepb tag discriminator",precision=10),
187  btagDeepFlavC = Var("?pt>15?bDiscriminator('pfDeepFlavourJetTags:probc'):-1",float,doc="DeepFlavour charm tag raw score",precision=10),
188  btagDeepFlavG = Var("?pt>15?bDiscriminator('pfDeepFlavourJetTags:probg'):-1",float,doc="DeepFlavour gluon tag raw score",precision=10),
189  btagDeepFlavUDS = Var("?pt>15?bDiscriminator('pfDeepFlavourJetTags:probuds'):-1",float,doc="DeepFlavour uds tag raw score",precision=10),
190  btagDeepFlavCvL = Var("?(pt>15)&&(bDiscriminator('pfDeepFlavourJetTags:probc')+bDiscriminator('pfDeepFlavourJetTags:probuds')+bDiscriminator('pfDeepFlavourJetTags:probg'))>0?bDiscriminator('pfDeepFlavourJetTags:probc')/(bDiscriminator('pfDeepFlavourJetTags:probc')+bDiscriminator('pfDeepFlavourJetTags:probuds')+bDiscriminator('pfDeepFlavourJetTags:probg')):-1",float,doc="DeepJet c vs uds+g discriminator",precision=10),
191  btagDeepFlavCvB = Var("?(pt>15)&&(bDiscriminator('pfDeepFlavourJetTags:probc')+bDiscriminator('pfDeepFlavourJetTags:probb')+bDiscriminator('pfDeepFlavourJetTags:probbb')+bDiscriminator('pfDeepFlavourJetTags:problepb'))>0?bDiscriminator('pfDeepFlavourJetTags:probc')/(bDiscriminator('pfDeepFlavourJetTags:probc')+bDiscriminator('pfDeepFlavourJetTags:probb')+bDiscriminator('pfDeepFlavourJetTags:probbb')+bDiscriminator('pfDeepFlavourJetTags:problepb')):-1",float,doc="DeepJet c vs b+bb+lepb discriminator",precision=10),
192  btagDeepFlavQG = Var("?(pt>15)&&(bDiscriminator('pfDeepFlavourJetTags:probg')+bDiscriminator('pfDeepFlavourJetTags:probuds'))>0?bDiscriminator('pfDeepFlavourJetTags:probg')/(bDiscriminator('pfDeepFlavourJetTags:probg')+bDiscriminator('pfDeepFlavourJetTags:probuds')):-1",float,doc="DeepJet g vs uds discriminator",precision=10),
193 )
194 PARTICLENETAK4VARS = cms.PSet(
195  particleNetAK4_B = Var("?pt>15?bDiscriminator('pfParticleNetAK4DiscriminatorsJetTags:BvsAll'):-1",float,doc="ParticleNetAK4 tagger b vs all (udsg, c) discriminator",precision=10),
196  particleNetAK4_CvsL = Var("?pt>15?bDiscriminator('pfParticleNetAK4DiscriminatorsJetTags:CvsL'):-1",float,doc="ParticleNetAK4 tagger c vs udsg discriminator",precision=10),
197  particleNetAK4_CvsB = Var("?pt>15?bDiscriminator('pfParticleNetAK4DiscriminatorsJetTags:CvsB'):-1",float,doc="ParticleNetAK4 tagger c vs b discriminator",precision=10),
198  particleNetAK4_QvsG = Var("?pt>15?bDiscriminator('pfParticleNetAK4DiscriminatorsJetTags:QvsG'):-1",float,doc="ParticleNetAK4 tagger uds vs g discriminator",precision=10),
199  particleNetAK4_puIdDisc = Var("?pt>15?1-bDiscriminator('pfParticleNetAK4JetTags:probpu'):-1",float,doc="ParticleNetAK4 tagger pileup jet discriminator",precision=10),
200 )
201 
202 CALOJETVARS = cms.PSet(P4Vars,
203  area = jetTable.variables.area,
204  rawFactor = jetTable.variables.rawFactor,
205  emf = Var("emEnergyFraction()", float, doc = "electromagnetic energy fraction", precision = 10),
206 )
207 
208 
209 #******************************************
210 #
211 #
212 # Reco Jets related functions
213 #
214 #
215 #******************************************
216 def AddJetID(proc, jetName="", jetSrc="", jetTableName="", jetSequenceName=""):
217  """
218  Setup modules to calculate PF jet ID
219  """
220 
221  isPUPPIJet = True if "Puppi" in jetName else False
222 
223  looseJetId = "looseJetId{}".format(jetName)
224  setattr(proc, looseJetId, proc.looseJetId.clone(
225  src = jetSrc,
226  filterParams = proc.looseJetId.filterParams.clone(
227  version = "WINTER16"
228  ),
229  )
230  )
231 
232  tightJetId = "tightJetId{}".format(jetName)
233  setattr(proc, tightJetId, proc.tightJetId.clone(
234  src = jetSrc,
235  filterParams = proc.tightJetId.filterParams.clone(
236  version = "RUN2UL{}".format("PUPPI" if isPUPPIJet else "CHS")
237  ),
238  )
239  )
240 
241  tightJetIdLepVeto = "tightJetIdLepVeto{}".format(jetName)
242  setattr(proc, tightJetIdLepVeto, proc.tightJetIdLepVeto.clone(
243  src = jetSrc,
244  filterParams = proc.tightJetIdLepVeto.filterParams.clone(
245  version = "RUN2UL{}".format("PUPPI" if isPUPPIJet else "CHS")
246  ),
247  )
248  )
249 
250  for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
251  modifier.toModify(getattr(proc, tightJetId).filterParams, version = "WINTER16" )
252  modifier.toModify(getattr(proc, tightJetIdLepVeto).filterParams, version = "WINTER16" )
253  for modifier in run2_nanoAOD_94XMiniAODv1, run2_nanoAOD_94XMiniAODv2:
254  modifier.toModify(getattr(proc, tightJetId).filterParams, version = "WINTER17{}".format("PUPPI" if isPUPPIJet else ""))
255  modifier.toModify(getattr(proc, tightJetIdLepVeto).filterParams, version = "WINTER17{}".format("PUPPI" if isPUPPIJet else ""))
256  run2_nanoAOD_102Xv1.toModify(getattr(proc, tightJetId).filterParams, version = "SUMMER18{}".format("PUPPI" if isPUPPIJet else "") )
257  run2_nanoAOD_102Xv1.toModify(getattr(proc, tightJetIdLepVeto).filterParams, version = "SUMMER18{}".format("PUPPI" if isPUPPIJet else "") )
258 
259  #
260  # Save variables as userInts in each jet
261  #
262  patJetWithUserData = "{}WithUserData".format(jetSrc)
263  getattr(proc, patJetWithUserData).userInts.tightId = cms.InputTag(tightJetId)
264  getattr(proc, patJetWithUserData).userInts.tightIdLepVeto = cms.InputTag(tightJetIdLepVeto)
265  for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
266  modifier.toModify(getattr(proc, patJetWithUserData).userInts, looseId = cms.InputTag(looseJetId))
267 
268  #
269  # Specfiy variables in the jetTable to save in NanoAOD
270  #
271  getattr(proc, jetTableName).variables.jetId = Var("userInt('tightId')*2+4*userInt('tightIdLepVeto')",int,doc="Jet ID flags bit1 is loose (always false in 2017 since it does not exist), bit2 is tight, bit3 is tightLepVeto")
272  for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
273  modifier.toModify(getattr(proc, jetTableName).variables, jetId = Var("userInt('tightIdLepVeto')*4+userInt('tightId')*2+userInt('looseId')",int, doc="Jet ID flags bit1 is loose, bit2 is tight, bit3 is tightLepVeto"))
274 
275 
276  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, jetSrc))+1, getattr(proc, tightJetId))
277  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, tightJetId))+1, getattr(proc, tightJetIdLepVeto))
278 
279  setattr(proc,"_"+jetSequenceName+"_2016", getattr(proc,jetSequenceName).copy())
280  getattr(proc,"_"+jetSequenceName+"_2016").insert(getattr(proc, "_"+jetSequenceName+"_2016").index(getattr(proc, tightJetId)), getattr(proc, looseJetId))
281  for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
282  modifier.toReplaceWith(getattr(proc,jetSequenceName), getattr(proc, "_"+jetSequenceName+"_2016"))
283 
284  return proc
285 
286 def AddPileUpJetIDVars(proc, jetName="", jetSrc="", jetTableName="", jetSequenceName=""):
287  """
288  Setup modules to calculate pileup jet ID input variables for PF jet
289  """
290 
291  #
292  # Calculate pileup jet ID variables
293  #
294  puJetIdVarsCalculator = "puJetIdCalculator{}".format(jetName)
295  setattr(proc, puJetIdVarsCalculator, pileupJetIdCalculator.clone(
296  jets = jetSrc,
297  vertexes = "offlineSlimmedPrimaryVertices",
298  inputIsCorrected = True,
299  applyJec = False,
300  usePuppi = True if "Puppi" in jetName else False
301  )
302  )
303  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, jetSrc))+1, getattr(proc, puJetIdVarsCalculator))
304 
305  #
306  # Get the variables
307  #
308  puJetIDVar = "puJetIDVar{}".format(jetName)
309  setattr(proc, puJetIDVar, cms.EDProducer("PileupJetIDVarProducer",
310  srcJet = cms.InputTag(jetSrc),
311  srcPileupJetId = cms.InputTag(puJetIdVarsCalculator)
312  )
313  )
314  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, puJetIdVarsCalculator))+1, getattr(proc, puJetIDVar))
315 
316  #
317  # Save variables as userFloats and userInts for each jet
318  #
319  patJetWithUserData = "{}WithUserData".format(jetSrc)
320  getattr(proc,patJetWithUserData).userFloats.puId_dR2Mean = cms.InputTag("{}:dR2Mean".format(puJetIDVar))
321  getattr(proc,patJetWithUserData).userFloats.puId_majW = cms.InputTag("{}:majW".format(puJetIDVar))
322  getattr(proc,patJetWithUserData).userFloats.puId_minW = cms.InputTag("{}:minW".format(puJetIDVar))
323  getattr(proc,patJetWithUserData).userFloats.puId_frac01 = cms.InputTag("{}:frac01".format(puJetIDVar))
324  getattr(proc,patJetWithUserData).userFloats.puId_frac02 = cms.InputTag("{}:frac02".format(puJetIDVar))
325  getattr(proc,patJetWithUserData).userFloats.puId_frac03 = cms.InputTag("{}:frac03".format(puJetIDVar))
326  getattr(proc,patJetWithUserData).userFloats.puId_frac04 = cms.InputTag("{}:frac04".format(puJetIDVar))
327  getattr(proc,patJetWithUserData).userFloats.puId_ptD = cms.InputTag("{}:ptD".format(puJetIDVar))
328  getattr(proc,patJetWithUserData).userFloats.puId_beta = cms.InputTag("{}:beta".format(puJetIDVar))
329  getattr(proc,patJetWithUserData).userFloats.puId_pull = cms.InputTag("{}:pull".format(puJetIDVar))
330  getattr(proc,patJetWithUserData).userFloats.puId_jetR = cms.InputTag("{}:jetR".format(puJetIDVar))
331  getattr(proc,patJetWithUserData).userFloats.puId_jetRchg = cms.InputTag("{}:jetRchg".format(puJetIDVar))
332  getattr(proc,patJetWithUserData).userInts.puId_nCharged = cms.InputTag("{}:nCharged".format(puJetIDVar))
333 
334  #
335  # Specfiy variables in the jet table to save in NanoAOD
336  #
337  getattr(proc,jetTableName).variables.puId_dR2Mean = PUIDVARS.puId_dR2Mean
338  getattr(proc,jetTableName).variables.puId_majW = PUIDVARS.puId_majW
339  getattr(proc,jetTableName).variables.puId_minW = PUIDVARS.puId_minW
340  getattr(proc,jetTableName).variables.puId_frac01 = PUIDVARS.puId_frac01
341  getattr(proc,jetTableName).variables.puId_frac02 = PUIDVARS.puId_frac02
342  getattr(proc,jetTableName).variables.puId_frac03 = PUIDVARS.puId_frac03
343  getattr(proc,jetTableName).variables.puId_frac04 = PUIDVARS.puId_frac04
344  getattr(proc,jetTableName).variables.puId_ptD = PUIDVARS.puId_ptD
345  getattr(proc,jetTableName).variables.puId_beta = PUIDVARS.puId_beta
346  getattr(proc,jetTableName).variables.puId_pull = PUIDVARS.puId_pull
347  getattr(proc,jetTableName).variables.puId_jetR = PUIDVARS.puId_jetR
348  getattr(proc,jetTableName).variables.puId_jetRchg = PUIDVARS.puId_jetRchg
349  getattr(proc,jetTableName).variables.puId_nCharged = PUIDVARS.puId_nCharged
350 
351  return proc
352 
353 def AddQGLTaggerVars(proc, jetName="", jetSrc="", jetTableName="", jetSequenceName="", calculateQGLVars=False):
354  """
355  Schedule the QGTagger module to calculate input variables to the QG likelihood
356  """
357 
358  QGLTagger="qgtagger{}".format(jetName)
359  patJetWithUserData="{}WithUserData".format(jetSrc)
360 
361  if calculateQGLVars:
362  setattr(proc, QGLTagger, qgtagger.clone(
363  srcJets = jetSrc
364  )
365  )
366 
367  #
368  # Save variables as userFloats and userInts for each jet
369  #
370  getattr(proc,patJetWithUserData).userFloats.qgl_axis2 = cms.InputTag(QGLTagger+":axis2")
371  getattr(proc,patJetWithUserData).userFloats.qgl_ptD = cms.InputTag(QGLTagger+":ptD")
372  getattr(proc,patJetWithUserData).userInts.qgl_mult = cms.InputTag(QGLTagger+":mult")
373 
374  #
375  # Specfiy variables in the jet table to save in NanoAOD
376  #
377  getattr(proc,jetTableName).variables.qgl_axis2 = QGLVARS.qgl_axis2
378  getattr(proc,jetTableName).variables.qgl_ptD = QGLVARS.qgl_ptD
379  getattr(proc,jetTableName).variables.qgl_mult = QGLVARS.qgl_mult
380 
381  if calculateQGLVars:
382  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, jetSrc))+1, getattr(proc, QGLTagger))
383 
384  return proc
385 
386 def AddBTaggingScores(proc, jetTableName=""):
387  """
388  Store b-tagging scores from various algortihm
389  """
390 
391  getattr(proc, jetTableName).variables.btagDeepB = BTAGVARS.btagDeepB
392  getattr(proc, jetTableName).variables.btagCSVV2 = BTAGVARS.btagCSVV2
393  getattr(proc, jetTableName).variables.btagDeepCvL = BTAGVARS.btagDeepCvL
394  getattr(proc, jetTableName).variables.btagDeepCvB = BTAGVARS.btagDeepCvB
395  getattr(proc, jetTableName).variables.btagDeepFlavB = DEEPJETVARS.btagDeepFlavB
396  getattr(proc, jetTableName).variables.btagDeepFlavCvL = DEEPJETVARS.btagDeepFlavCvL
397  getattr(proc, jetTableName).variables.btagDeepFlavCvB = DEEPJETVARS.btagDeepFlavCvB
398 
399  return proc
400 
401 def AddDeepJetGluonLQuarkScores(proc, jetTableName=""):
402  """
403  Store DeepJet raw score in jetTable for gluon and light quark
404  """
405 
406  getattr(proc, jetTableName).variables.btagDeepFlavG = DEEPJETVARS.btagDeepFlavG
407  getattr(proc, jetTableName).variables.btagDeepFlavUDS = DEEPJETVARS.btagDeepFlavUDS
408  getattr(proc, jetTableName).variables.btagDeepFlavQG = DEEPJETVARS.btagDeepFlavQG
409 
410  return proc
411 
412 def AddParticleNetAK4Scores(proc, jetTableName=""):
413  """
414  Store ParticleNetAK4 scores in jetTable
415  """
416 
417  getattr(proc, jetTableName).variables.particleNetAK4_B = PARTICLENETAK4VARS.particleNetAK4_B
418  getattr(proc, jetTableName).variables.particleNetAK4_CvsL = PARTICLENETAK4VARS.particleNetAK4_CvsL
419  getattr(proc, jetTableName).variables.particleNetAK4_CvsB = PARTICLENETAK4VARS.particleNetAK4_CvsB
420  getattr(proc, jetTableName).variables.particleNetAK4_QvsG = PARTICLENETAK4VARS.particleNetAK4_QvsG
421  getattr(proc, jetTableName).variables.particleNetAK4_puIdDisc = PARTICLENETAK4VARS.particleNetAK4_puIdDisc
422 
423  return proc
424 
425 def AddNewPatJets(proc, recoJetInfo, runOnMC):
426  """
427  Add patJet into custom nanoAOD
428  """
429 
430  jetName = recoJetInfo.jetUpper
431  payload = recoJetInfo.jetCorrPayload
432  doPF = recoJetInfo.doPF
433  doCalo = recoJetInfo.doCalo
434  patJetFinalColl = recoJetInfo.patJetFinalCollection
435 
436  nanoInfoForJet = nanoInfo_recojets[recoJetInfo.jet]
437  jetTablePrefix = nanoInfoForJet["name"]
438  jetTableDoc = nanoInfoForJet["doc"]
439  ptcut = nanoInfoForJet["ptcut"] if "ptcut" in nanoInfoForJet else ""
440  doPUIDVar = nanoInfoForJet["doPUIDVar"] if "doPUIDVar" in nanoInfoForJet else False
441  doQGL = nanoInfoForJet["doQGL"] if "doQGL" in nanoInfoForJet else False
442  doBTag = nanoInfoForJet["doBTag"] if "doBTag" in nanoInfoForJet else False
443 
444  SavePatJets(proc,
445  jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc, doPF, doCalo,
446  ptcut=ptcut, doPUIDVar=doPUIDVar, doQGL=doQGL, doBTag=doBTag, runOnMC=runOnMC
447  )
448 
449  return proc
450 
451 def SavePatJets(proc, jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc,
452  doPF, doCalo, ptcut="", doPUIDVar=False, doQGL=False, doBTag=False, runOnMC=False):
453  """
454  Schedule modules for a given patJet collection and save its variables into custom NanoAOD
455  """
456 
457  #
458  # Setup jet correction factors
459  #
460  jetCorrFactors = "jetCorrFactorsNano{}".format(jetName)
461  setattr(proc, jetCorrFactors, jetCorrFactorsNano.clone(
462  src = patJetFinalColl,
463  payload = payload,
464  )
465  )
466 
467  #
468  # Update jets
469  #
470  srcJets = "updatedJets{}".format(jetName)
471  setattr(proc, srcJets, updatedJets.clone(
472  jetSource = patJetFinalColl,
473  jetCorrFactorsSource = [jetCorrFactors],
474  )
475  )
476 
477  #
478  # Setup UserDataEmbedder
479  #
480  srcJetsWithUserData = "updatedJets{}WithUserData".format(jetName)
481  setattr(proc, srcJetsWithUserData, cms.EDProducer("PATJetUserDataEmbedder",
482  src = cms.InputTag(srcJets),
483  userFloats = cms.PSet(),
484  userInts = cms.PSet(),
485  )
486  )
487 
488  #
489  # Filter jets with pt cut
490  #
491  finalJetsCutDefault = "(pt >= 8)"
492  if runOnMC:
493  finalJetsCutDefault = "(pt >= 8) || ((pt < 8) && (genJetFwdRef().backRef().isNonnull()))"
494 
495  finalJetsForTable = "finalJets{}".format(jetName)
496  setattr(proc, finalJetsForTable, finalJets.clone(
497  src = srcJetsWithUserData,
498  cut = ptcut if ptcut != "" else finalJetsCutDefault
499  )
500  )
501 
502  #
503  # Save jets in table
504  #
505  tableContent = PFJETVARS
506  if doCalo:
507  tableContent = CALOJETVARS
508 
509  jetTableCutDefault = "" #Don't apply any cuts for the table.
510 
511  jetTableDocDefault = jetTableDoc + " with JECs applied. Jets with pt > 8 GeV are stored."
512  if runOnMC:
513  jetTableDocDefault += "For jets with pt < 8 GeV, only those matched to gen jets are stored."
514 
515  jetTable = "jet{}Table".format(jetName)
516  setattr(proc,jetTable, cms.EDProducer("SimpleCandidateFlatTableProducer",
517  src = cms.InputTag(finalJetsForTable),
518  cut = cms.string(jetTableCutDefault),
519  name = cms.string(jetTablePrefix),
520  doc = cms.string(jetTableDocDefault),
521  singleton = cms.bool(False), # the number of entries is variable
522  extension = cms.bool(False), # this is the main table for the jets
523  variables = cms.PSet(tableContent)
524  )
525  )
526  getattr(proc,jetTable).variables.pt.precision=10
527 
528  #
529  # Save MC-only jet variables in table
530  #
531  jetMCTable = "jet{}MCTable".format(jetName)
532  setattr(proc, jetMCTable, cms.EDProducer("SimpleCandidateFlatTableProducer",
533  src = cms.InputTag(finalJetsForTable),
534  cut = getattr(proc,jetTable).cut,
535  name = cms.string(jetTablePrefix),
536  singleton = cms.bool(False),
537  extension = cms.bool(True), # this is an extension table
538  variables = cms.PSet(
539  partonFlavour = Var("partonFlavour()", int, doc="flavour from parton matching"),
540  hadronFlavour = Var("hadronFlavour()", int, doc="flavour from hadron ghost clustering"),
541  genJetIdx = Var("?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1", int, doc="index of matched gen jet"),
542  )
543  )
544  )
545 
546  #
547  # Define the jet modules sequence first
548  #
549  jetSequenceName = "jet{}Sequence".format(jetName)
550  setattr(proc, jetSequenceName, cms.Sequence(
551  getattr(proc,jetCorrFactors)+
552  getattr(proc,srcJets)+
553  getattr(proc,srcJetsWithUserData)+
554  getattr(proc,finalJetsForTable)
555  )
556  )
557 
558  #
559  # Define the jet table sequences
560  #
561  jetTableSequenceName = "jet{}TablesSequence".format(jetName)
562  setattr(proc, jetTableSequenceName, cms.Sequence(getattr(proc,jetTable)))
563 
564  jetTableSequenceMCName = "jet{}MCTablesSequence".format(jetName)
565  setattr(proc, jetTableSequenceMCName, cms.Sequence(getattr(proc,jetMCTable)))
566 
567  if runOnMC:
568  proc.nanoSequenceMC += getattr(proc,jetSequenceName)
569  proc.nanoSequenceMC += getattr(proc,jetTableSequenceName)
570  proc.nanoSequenceMC += getattr(proc,jetTableSequenceMCName)
571  else:
572  proc.nanoSequence += getattr(proc,jetSequenceName)
573  proc.nanoSequence += getattr(proc,jetTableSequenceName)
574 
575  #
576  # Schedule plugins to calculate Jet ID, PileUp Jet ID input variables, and Quark-Gluon Likehood input variables.
577  #
578  if doPF:
579  proc = AddJetID(proc, jetName=jetName, jetSrc=srcJets, jetTableName=jetTable, jetSequenceName=jetSequenceName)
580  if doPUIDVar:
581  proc = AddPileUpJetIDVars(proc, jetName=jetName, jetSrc=srcJets, jetTableName=jetTable, jetSequenceName=jetSequenceName)
582  if doQGL:
583  proc = AddQGLTaggerVars(proc,jetName=jetName, jetSrc=srcJets, jetTableName=jetTable, jetSequenceName=jetSequenceName, calculateQGLVars=True)
584 
585  #
586  # Save b-tagging algorithm scores. Should only be done for jet collection with b-tagging
587  # calculated when reclustered or collection saved with b-tagging info in MiniAOD
588  #
589  if doBTag:
590  AddBTaggingScores(proc,jetTableName=jetTable)
591  AddDeepJetGluonLQuarkScores(proc,jetTableName=jetTable)
592  AddParticleNetAK4Scores(proc,jetTableName=jetTable)
593 
594  return proc
595 
596 def ReclusterAK4CHSJets(proc, recoJA, runOnMC):
597  """
598  Recluster AK4 CHS jets and replace slimmedJets
599  that is used as default to save AK4 CHS jets
600  in NanoAODs.
601  """
602  print("custom_jme_cff::ReclusterAK4CHSJets: Recluster AK4 PF CHS jets")
603 
604  #
605  # Recluster AK4 CHS jets
606  #
607  cfg = {
608  "jet" : "ak4pfchs",
609  "inputCollection" : "",
610  "genJetsCollection": "AK4GenJetsNoNu",
611  "bTagDiscriminators": bTagDiscriminatorsForAK4,
612  "minPtFastjet" : 0.,
613  }
614  recoJetInfo = recoJA.addRecoJetCollection(proc, **cfg)
615 
616  jetName = recoJetInfo.jetUpper
617  patJetFinalColl = recoJetInfo.patJetFinalCollection
618 
619  #
620  # Change the input jet source for jetCorrFactorsNano
621  # and updatedJets
622  #
623  proc.jetCorrFactorsNano.src=patJetFinalColl
624  proc.updatedJets.jetSource=patJetFinalColl
625 
626  #
627  # Change pt cut
628  #
629  finalJetsCut = ""
630  if runOnMC:
631  finalJetsCut = "(pt >= 8) || ((pt < 8) && (genJetFwdRef().backRef().isNonnull()))"
632  else:
633  finalJetsCut = "(pt >= 8)"
634 
635  proc.finalJets.cut = finalJetsCut
636  #
637  # Add a minimum pt cut for corrT1METJets.
638  #
639  proc.corrT1METJetTable.cut = "pt>=8 && pt<15 && abs(eta)<9.9"
640 
641  #
642  # Jet table cut
643  #
644  jetTableCut = "" # must not have any cut at the jetTable for AK4 CHS as it has been cross-cleaned
645  proc.jetTable.cut = jetTableCut
646  proc.jetMCTable.cut = jetTableCut
647 
648  #
649  # Jet table documentation
650  #
651  jetTableDoc = "AK4 PF CHS jets with JECs applied. Jets with pt > 8 GeV are stored."
652  if runOnMC:
653  jetTableDoc += "For jets with pt < 8 GeV, only those matched to AK4 Gen jets are stored."
654  proc.jetTable.doc = jetTableDoc
655 
656  #
657  # Add variables
658  #
659  proc.jetTable.variables.hfHEF = PFJETVARS.hfHEF
660  proc.jetTable.variables.hfEmEF = PFJETVARS.hfEmEF
661  proc.jetTable.variables.nConstChHads = PFJETVARS.nConstChHads
662  proc.jetTable.variables.nConstNeuHads = PFJETVARS.nConstNeuHads
663  proc.jetTable.variables.nConstHFHads = PFJETVARS.nConstHFHads
664  proc.jetTable.variables.nConstHFEMs = PFJETVARS.nConstHFEMs
665  proc.jetTable.variables.nConstMuons = PFJETVARS.nConstMuons
666  proc.jetTable.variables.nConstElecs = PFJETVARS.nConstElecs
667  proc.jetTable.variables.nConstPhotons = PFJETVARS.nConstPhotons
668 
669  #
670  # Setup pileup jet ID with 80X training.
671  #
672  pileupJetId80X = "pileupJetId80X"
673  setattr(proc, pileupJetId80X, pileupJetId.clone(
674  jets = "updatedJets",
675  algos = cms.VPSet(_chsalgos_81x),
676  inputIsCorrected = True,
677  applyJec = False,
678  vertexes = "offlineSlimmedPrimaryVertices"
679  )
680  )
681  proc.jetSequence.insert(proc.jetSequence.index(proc.pileupJetId94X), getattr(proc, pileupJetId80X))
682 
683  proc.updatedJetsWithUserData.userInts.puId80XfullId = cms.InputTag('pileupJetId80X:fullId')
684  proc.updatedJetsWithUserData.userFloats.puId80XDisc = cms.InputTag("pileupJetId80X:fullDiscriminant")
685 
686  run2_nanoAOD_94X2016.toModify(proc.jetTable.variables, puIdDisc = Var("userFloat('puId80XDisc')",float,doc="Pilup ID discriminant with 80X (2016) training",precision=10))
687 
688  for modifier in run2_nanoAOD_94X2016, run2_nanoAOD_94XMiniAODv1, run2_nanoAOD_94XMiniAODv2, run2_nanoAOD_102Xv1:
689  modifier.toModify(proc.jetTable.variables, puId = Var("userInt('puId80XfullId')", int, doc="Pileup ID flags with 80X (2016) training"))
690 
691  #
692  # Add charged energy fraction from other primary vertices
693  #
694  proc.updatedJetsWithUserData.userFloats.chFPV1EF = cms.InputTag("jercVars:chargedFromPV1EnergyFraction")
695  proc.updatedJetsWithUserData.userFloats.chFPV2EF = cms.InputTag("jercVars:chargedFromPV2EnergyFraction")
696  proc.updatedJetsWithUserData.userFloats.chFPV3EF = cms.InputTag("jercVars:chargedFromPV3EnergyFraction")
697  proc.jetTable.variables.chFPV1EF = Var("userFloat('chFPV1EF')", float, doc="charged fromPV==1 Energy Fraction (component of the total charged Energy Fraction).", precision= 6)
698  proc.jetTable.variables.chFPV2EF = Var("userFloat('chFPV2EF')", float, doc="charged fromPV==2 Energy Fraction (component of the total charged Energy Fraction).", precision= 6)
699  proc.jetTable.variables.chFPV3EF = Var("userFloat('chFPV3EF')", float, doc="charged fromPV==3 Energy Fraction (component of the total charged Energy Fraction).", precision= 6)
700 
701  #
702  # Add variables for pileup jet ID studies.
703  #
704  proc = AddPileUpJetIDVars(proc,
705  jetName = "",
706  jetSrc = "updatedJets",
707  jetTableName = "jetTable",
708  jetSequenceName = "jetSequence"
709  )
710  #
711  # Add variables for quark guon likelihood tagger studies.
712  # Save variables as userFloats and userInts in each jet
713  #
714  proc.updatedJetsWithUserData.userFloats.qgl_axis2 = cms.InputTag("qgtagger:axis2")
715  proc.updatedJetsWithUserData.userFloats.qgl_ptD = cms.InputTag("qgtagger:ptD")
716  proc.updatedJetsWithUserData.userInts.qgl_mult = cms.InputTag("qgtagger:mult")
717  #
718  # Save quark gluon likelihood input variables variables
719  #
720  proc.jetTable.variables.qgl_axis2 = QGLVARS.qgl_axis2
721  proc.jetTable.variables.qgl_ptD = QGLVARS.qgl_ptD
722  proc.jetTable.variables.qgl_mult = QGLVARS.qgl_mult
723  #
724  # Save standard b-tagging and c-tagging variables
725  #
726  proc.jetTable.variables.btagDeepB = BTAGVARS.btagDeepB
727  proc.jetTable.variables.btagCSVV2 = BTAGVARS.btagCSVV2
728  proc.jetTable.variables.btagDeepCvL = BTAGVARS.btagDeepCvL
729  proc.jetTable.variables.btagDeepCvB = BTAGVARS.btagDeepCvB
730  #
731  # Save DeepJet b-tagging and c-tagging variables
732  #
733  proc.jetTable.variables.btagDeepFlavB = DEEPJETVARS.btagDeepFlavB
734  proc.jetTable.variables.btagDeepFlavCvL = DEEPJETVARS.btagDeepFlavCvL
735  proc.jetTable.variables.btagDeepFlavCvB = DEEPJETVARS.btagDeepFlavCvB
736  #
737  # Save DeepJet raw score for gluon and light quarks
738  #
739  proc.jetTable.variables.btagDeepFlavG = DEEPJETVARS.btagDeepFlavG
740  proc.jetTable.variables.btagDeepFlavUDS = DEEPJETVARS.btagDeepFlavUDS
741  proc.jetTable.variables.btagDeepFlavQG = DEEPJETVARS.btagDeepFlavQG
742  #
743  # Add ParticleNetAK4 scores
744  #
745  proc.jetTable.variables.particleNetAK4_B = PARTICLENETAK4VARS.particleNetAK4_B
746  proc.jetTable.variables.particleNetAK4_CvsL = PARTICLENETAK4VARS.particleNetAK4_CvsL
747  proc.jetTable.variables.particleNetAK4_CvsB = PARTICLENETAK4VARS.particleNetAK4_CvsB
748  proc.jetTable.variables.particleNetAK4_QvsG = PARTICLENETAK4VARS.particleNetAK4_QvsG
749  proc.jetTable.variables.particleNetAK4_puIdDisc = PARTICLENETAK4VARS.particleNetAK4_puIdDisc
750 
751  #Adding hf shower shape producer to the jet sequence. By default this producer is not automatically rerun at the NANOAOD step
752  #The following lines make sure it is.
753  hfJetShowerShapeforCustomNanoAOD = "hfJetShowerShapeforCustomNanoAOD"
754  setattr(proc, hfJetShowerShapeforCustomNanoAOD, hfJetShowerShapeforNanoAOD.clone(jets="updatedJets",vertices="offlineSlimmedPrimaryVertices") )
755  proc.jetSequence.insert(proc.jetSequence.index(proc.updatedJetsWithUserData), getattr(proc, hfJetShowerShapeforCustomNanoAOD))
756  proc.updatedJetsWithUserData.userFloats.hfsigmaEtaEta = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:sigmaEtaEta')
757  proc.updatedJetsWithUserData.userFloats.hfsigmaPhiPhi = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:sigmaPhiPhi')
758  proc.updatedJetsWithUserData.userInts.hfcentralEtaStripSize = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:centralEtaStripSize')
759  proc.updatedJetsWithUserData.userInts.hfadjacentEtaStripsSize = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:adjacentEtaStripsSize')
760  proc.jetTable.variables.hfsigmaEtaEta = Var("userFloat('hfsigmaEtaEta')",float,doc="sigmaEtaEta for HF jets (noise discriminating variable)",precision=10)
761  proc.jetTable.variables.hfsigmaPhiPhi = Var("userFloat('hfsigmaPhiPhi')",float,doc="sigmaPhiPhi for HF jets (noise discriminating variable)",precision=10)
762  proc.jetTable.variables.hfcentralEtaStripSize = Var("userInt('hfcentralEtaStripSize')", int, doc="eta size of the central tower strip in HF (noise discriminating variable) ")
763  proc.jetTable.variables.hfadjacentEtaStripsSize = Var("userInt('hfadjacentEtaStripsSize')", int, doc="eta size of the strips next to the central tower strip in HF (noise discriminating variable) ")
764 
765  return proc
766 
767 def AddNewAK8PuppiJetsForJEC(proc, recoJA, runOnMC):
768  """
769  Store a separate AK8 Puppi jet collection for JEC studies.
770  Only minimal info are stored
771  """
772  print("custom_jme_cff::AddNewAK8PuppiJetsForJEC: Make a new AK8 PF Puppi jet collection for JEC studies")
773 
774  #
775  # Recluster AK8 Puppi jets
776  #
777  cfg = {
778  "jet" : "ak8pfpuppi",
779  "inputCollection" : "",
780  "genJetsCollection": "AK8GenJetsNoNu",
781  "minPtFastjet" : 0., # Remove any pt threshold at the jet clustering stage.
782  }
783  recoJetInfo = recoJA.addRecoJetCollection(proc, **cfg)
784 
785  jetName = recoJetInfo.jetUpper
786  payload = recoJetInfo.jetCorrPayload
787 
788  patJetFinalColl = recoJetInfo.patJetFinalCollection
789  jetTablePrefix = "FatJetForJEC"
790  jetTableDoc = "AK8 PF Puppi jets with JECs applied. Reclustered for JEC studies so only minimal info stored."
791  ptcut = ""# No need to specify ptcut. Use default in SavePatJets function
792 
793  SavePatJets(proc,
794  jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc, doPF=True,
795  doCalo=False, ptcut=ptcut, doPUIDVar=False, doQGL=False, doBTag=False, runOnMC=runOnMC
796  )
797 
798  return proc
799 
800 def AddNewAK8CHSJets(proc, recoJA, runOnMC):
801  """
802  Store an AK8 CHS jet collection for JEC studies.
803  """
804  print("custom_jme_cff::AddNewAK8CHSJets: Make a new AK8 PF CHS jet collection for JEC studies")
805 
806  #
807  # Recluster AK8 CHS jets
808  #
809  cfg = {
810  "jet" : "ak8pfchs",
811  "inputCollection" : "",
812  "genJetsCollection": "AK8GenJetsNoNu",
813  "minPtFastjet" : 0., # Remove any pt threshold at the jet clustering stage.
814  }
815  recoJetInfo = recoJA.addRecoJetCollection(proc, **cfg)
816 
817  jetName = recoJetInfo.jetUpper
818  payload = recoJetInfo.jetCorrPayload
819 
820  patJetFinalColl = recoJetInfo.patJetFinalCollection
821  jetTablePrefix = "FatJetCHS"
822  jetTableDoc = "AK8 PF CHS jets with JECs applied. Reclustered for JEC studies so only minimal info stored."
823  ptcut = ""# No need to specify ptcut. Use default in SavePatJets function
824 
825  SavePatJets(proc,
826  jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc, doPF=True,
827  doCalo=False, ptcut=ptcut, doPUIDVar=False, doQGL=False, doBTag=False, runOnMC=runOnMC
828  )
829 
830  return proc
831 
833  """
834  Add more variables for AK8 PFPUPPI jets
835  """
836 
837  #
838  # These variables are not stored for AK8PFPUPPI (slimmedJetsAK8)
839  # in MiniAOD if their pt < 170 GeV. Hence the conditional fill.
840  #
841  proc.fatJetTable.variables.chHEF = Var("?isPFJet()?chargedHadronEnergyFraction():-1", float, doc="charged Hadron Energy Fraction", precision = 6)
842  proc.fatJetTable.variables.neHEF = Var("?isPFJet()?neutralHadronEnergyFraction():-1", float, doc="neutral Hadron Energy Fraction", precision = 6)
843  proc.fatJetTable.variables.chEmEF = Var("?isPFJet()?chargedEmEnergyFraction():-1", float, doc="charged Electromagnetic Energy Fraction", precision = 6)
844  proc.fatJetTable.variables.neEmEF = Var("?isPFJet()?neutralEmEnergyFraction():-1", float, doc="neutral Electromagnetic Energy Fraction", precision = 6)
845  proc.fatJetTable.variables.muEF = Var("?isPFJet()?muonEnergyFraction():-1", float, doc="muon Energy Fraction", precision = 6)
846  proc.fatJetTable.variables.hfHEF = Var("?isPFJet()?HFHadronEnergyFraction():-1", float, doc="energy fraction in forward hadronic calorimeter", precision = 6)
847  proc.fatJetTable.variables.hfEmEF = Var("?isPFJet()?HFEMEnergyFraction():-1", float, doc="energy fraction in forward EM calorimeter", precision = 6)
848  proc.fatJetTable.variables.nConstChHads = Var("?isPFJet()?chargedHadronMultiplicity():-1",int, doc="number of charged hadrons in the jet")
849  proc.fatJetTable.variables.nConstNeuHads = Var("?isPFJet()?neutralHadronMultiplicity():-1",int, doc="number of neutral hadrons in the jet")
850  proc.fatJetTable.variables.nConstHFHads = Var("?isPFJet()?HFHadronMultiplicity():-1", int, doc="number of HF Hadrons in the jet")
851  proc.fatJetTable.variables.nConstHFEMs = Var("?isPFJet()?HFEMMultiplicity():-1", int, doc="number of HF EMs in the jet")
852  proc.fatJetTable.variables.nConstMuons = Var("?isPFJet()?muonMultiplicity():-1", int, doc="number of muons in the jet")
853  proc.fatJetTable.variables.nConstElecs = Var("?isPFJet()?electronMultiplicity():-1", int, doc="number of electrons in the jet")
854  proc.fatJetTable.variables.nConstPhotons = Var("?isPFJet()?photonMultiplicity():-1", int, doc="number of photons in the jet")
855 
856  return proc
857 #******************************************
858 #
859 #
860 # Gen Jets related functions
861 #
862 #
863 #******************************************
864 def AddNewGenJets(proc, genJetInfo):
865  """
866  Add genJet into custom nanoAOD
867  """
868 
869  genJetName = genJetInfo.jetUpper
870  genJetAlgo = genJetInfo.jetAlgo
871  genJetSize = genJetInfo.jetSize
872  genJetSizeNr = genJetInfo.jetSizeNr
873  genJetFinalColl = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
874  genJetTablePrefix = nanoInfo_genjets[genJetInfo.jet]["name"]
875  genJetTableDoc = nanoInfo_genjets[genJetInfo.jet]["doc"]
876 
877  SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False)
878 
879  return proc
880 
881 def SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False):
882  """
883  Schedule modules for a given genJet collection and save its variables into custom NanoAOD
884  """
885 
886  genJetTableThisJet = "jet{}Table".format(genJetName)
887  setattr(proc, genJetTableThisJet, genJetTable.clone(
888  src = genJetFinalColl,
889  cut = "", # No cut specified here. Save all gen jets after clustering
890  name = genJetTablePrefix,
891  doc = genJetTableDoc,
892  variables = GENJETVARS
893  )
894  )
895 
896  genJetFlavourAssociationThisJet = "genJet{}FlavourAssociation".format(genJetName)
897  setattr(proc, genJetFlavourAssociationThisJet, genJetFlavourAssociation.clone(
898  jets = getattr(proc,genJetTableThisJet).src,
899  jetAlgorithm = supportedJetAlgos[genJetAlgo],
900  rParam = genJetSizeNr,
901  )
902  )
903 
904  genJetFlavourTableThisJet = "genJet{}FlavourTable".format(genJetName)
905  setattr(proc, genJetFlavourTableThisJet, genJetFlavourTable.clone(
906  name = getattr(proc,genJetTableThisJet).name,
907  src = getattr(proc,genJetTableThisJet).src,
908  cut = getattr(proc,genJetTableThisJet).cut,
909  jetFlavourInfos = genJetFlavourAssociationThisJet,
910  )
911  )
912 
913  genJetSequenceName = "genJet{}Sequence".format(genJetName)
914  setattr(proc, genJetSequenceName, cms.Sequence(
915  getattr(proc,genJetTableThisJet)+
916  getattr(proc,genJetFlavourAssociationThisJet)+
917  getattr(proc,genJetFlavourTableThisJet)
918  )
919  )
920  proc.nanoSequenceMC.insert(proc.nanoSequenceMC.index(proc.jetMC)+1, getattr(proc,genJetSequenceName))
921 
922  return proc
923 
924 def ReclusterAK4GenJets(proc, genJA):
925  """
926  Recluster AK4 Gen jets and replace
927  slimmedGenJets that is used as default
928  to save AK4 Gen jets in NanoAODs.
929  """
930  print("custom_jme_cff::ReclusterAK4GenJets: Recluster AK4 Gen jets")
931 
932  #
933  # Recluster AK4 Gen jet
934  #
935  cfg = {
936  "jet" : "ak4gen",
937  }
938  genJetInfo = genJA.addGenJetCollection(proc, **cfg)
939 
940  genJetName = genJetInfo.jetUpper
941  genJetAlgo = genJetInfo.jetAlgo
942  genJetSize = genJetInfo.jetSize
943  genJetSizeNr = genJetInfo.jetSizeNr
944  selectedGenJets = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
945 
946  #
947  # Change jet source to the newly clustered jet collection. Set very low pt cut for jets
948  # to be stored in the GenJet Table
949  #
950  proc.genJetTable.src = selectedGenJets
951  proc.genJetTable.cut = "" # No cut specified here. Save all gen jets after clustering
952  proc.genJetTable.doc = "AK4 Gen jets (made with visible genparticles) with pt > 3 GeV" # default pt cut after clustering is 3 GeV
953 
954  genJetFlavourAssociationThisJet = "genJet{}FlavourAssociation".format(genJetName)
955  setattr(proc, genJetFlavourAssociationThisJet, genJetFlavourAssociation.clone(
956  jets = proc.genJetTable.src,
957  jetAlgorithm = supportedJetAlgos[genJetAlgo],
958  rParam = genJetSizeNr,
959  )
960  )
961  proc.jetMC.insert(proc.jetMC.index(proc.genJetFlavourTable), getattr(proc, genJetFlavourAssociationThisJet))
962  return proc
963 
964 def AddNewAK8GenJetsForJEC(proc, genJA):
965  """
966  Make a separate AK8 Gen jet collection for JEC studies.
967  """
968  print("custom_jme_cff::AddNewAK8GenJetsForJEC: Add new AK8 Gen jets for JEC studies")
969 
970  #
971  # Recluster AK8 Gen jet
972  #
973  cfg = {
974  "jet" : "ak8gen",
975  }
976  genJetInfo = genJA.addGenJetCollection(proc, **cfg)
977 
978  genJetName = genJetInfo.jetUpper
979  genJetAlgo = genJetInfo.jetAlgo
980  genJetSize = genJetInfo.jetSize
981  genJetSizeNr = genJetInfo.jetSizeNr
982  genJetFinalColl = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
983  genJetTablePrefix = "GenJetAK8ForJEC"
984  genJetTableDoc = "AK8 Gen jets (made with visible genparticles) with pt > 3 GeV. Reclustered for JEC studies."
985 
986  SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False)
987 
988  return proc
989 
991  proc.genJetTable.variables.nConstituents = GENJETVARS.nConstituents
992  return proc
993 
995  proc.genJetAK8Table.variables.nConstituents = GENJETVARS.nConstituents
996  return proc
997 
998 #===========================================================================
999 #
1000 # Misc. functions
1001 #
1002 #===========================================================================
1004  """
1005  Remove default pt cuts for all jets set in jets_cff.py
1006  """
1007 
1008  proc.finalJets.cut = "" # 15 -> 10
1009  proc.finalJetsAK8.cut = "" # 170 -> 170
1010  proc.genJetTable.cut = "" # 10 -> 8
1011  proc.genJetFlavourTable.cut = "" # 10 -> 8
1012  proc.genJetAK8Table.cut = "" # 100 -> 80
1013  proc.genJetAK8FlavourTable.cut = "" # 100 -> 80
1014 
1015  return proc
1016 
1017 #===========================================================================
1018 #
1019 # CUSTOMIZATION function
1020 #
1021 #===========================================================================
1022 def PrepJMECustomNanoAOD(process,runOnMC):
1023 
1024  ############################################################################
1025  # Remove all default jet pt cuts from jets_cff.py
1026  ############################################################################
1027  process = RemoveAllJetPtCuts(process)
1028 
1029  ###########################################################################
1030  #
1031  # Gen-level jets related functions. Only for MC.
1032  #
1033  ###########################################################################
1034  genJA = GenJetAdder()
1035  if runOnMC:
1036  ############################################################################
1037  # Save additional variables for AK8 GEN jets
1038  ############################################################################
1039  process = AddVariablesForAK8GenJets(process)
1040  ############################################################################
1041  # Recluster AK8 GEN jets
1042  ############################################################################
1043  process = AddNewAK8GenJetsForJEC(process, genJA)
1044  ###########################################################################
1045  # Recluster AK4 GEN jets
1046  ###########################################################################
1047  process = ReclusterAK4GenJets(process, genJA)
1048  process = AddVariablesForAK4GenJets(process)
1049  ###########################################################################
1050  # Add additional GEN jets to NanoAOD
1051  ###########################################################################
1052  for jetConfig in config_genjets:
1053  cfg = { k : v for k, v in jetConfig.items() if k != "enabled"}
1054  genJetInfo = genJA.addGenJetCollection(process, **cfg)
1055  AddNewGenJets(process, genJetInfo)
1056 
1057  ###########################################################################
1058  #
1059  # Reco-level jets related functions. For both MC and data.
1060  #
1061  ###########################################################################
1062  recoJA = RecoJetAdder(runOnMC=runOnMC)
1063  ###########################################################################
1064  # Save additional variables for AK8Puppi jets
1065  ###########################################################################
1066  process = AddVariablesForAK8PuppiJets(process)
1067  ###########################################################################
1068  # Build a separate AK8Puppi jet collection for JEC studies
1069  ###########################################################################
1070  process = AddNewAK8PuppiJetsForJEC(process, recoJA, runOnMC)
1071  ###########################################################################
1072  # Build a AK8CHS jet collection for JEC studies
1073  ###########################################################################
1074  process = AddNewAK8CHSJets(process, recoJA, runOnMC)
1075  ###########################################################################
1076  # Recluster AK4 CHS jets and replace "slimmedJets"
1077  ###########################################################################
1078  process = ReclusterAK4CHSJets(process, recoJA, runOnMC)
1079  ###########################################################################
1080  # Add additional Reco jets to NanoAOD
1081  ###########################################################################
1082  for jetConfig in config_recojets:
1083  cfg = { k : v for k, v in jetConfig.items() if k != "enabled"}
1084  recoJetInfo = recoJA.addRecoJetCollection(process, **cfg)
1085  AddNewPatJets(process, recoJetInfo, runOnMC)
1086 
1087  ###########################################################################
1088  # Save Maximum of Pt Hat Max
1089  ###########################################################################
1090  if runOnMC:
1091  process.puTable.savePtHatMax = True
1092 
1093  ###########################################################################
1094  # Save all Parton-Shower weights
1095  ###########################################################################
1096  if runOnMC:
1097  process.genWeightsTable.keepAllPSWeights = True
1098 
1099  return process
1100 
1102  PrepJMECustomNanoAOD(process,runOnMC=True)
1103  return process
1104 
1106  PrepJMECustomNanoAOD(process,runOnMC=False)
1107  return process
def AddDeepJetGluonLQuarkScores
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
def AddNewAK8PuppiJetsForJEC
def AddVariablesForAK4GenJets
def AddVariablesForAK8GenJets
def AddVariablesForAK8PuppiJets