CMS 3D CMS Logo

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