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  run2_jme_2016.toModify(proc.updatedJetsWithUserData.userFloats, puId80XDisc = cms.InputTag("pileupJetId80X:fullDiscriminant"))
686 
687  proc.jetTable.variables.puId = Var("userInt('puId80XfullId')", int, doc="Pilup ID flags with 80X (2016) training")
688  run2_jme_2016.toModify(proc.jetTable.variables, puIdDisc = Var("userFloat('puId80XDisc')",float,doc="Pilup ID discriminant with 80X (2016) training",precision=10))
689 
690  #
691  # Add variables for pileup jet ID studies.
692  #
693  proc = AddPileUpJetIDVars(proc,
694  jetName = "",
695  jetSrc = "updatedJets",
696  jetTableName = "jetTable",
697  jetSequenceName = "jetSequence"
698  )
699  #
700  # Add variables for quark guon likelihood tagger studies.
701  # Save variables as userFloats and userInts in each jet
702  #
703  proc.updatedJetsWithUserData.userFloats.qgl_axis2 = cms.InputTag("qgtagger:axis2")
704  proc.updatedJetsWithUserData.userFloats.qgl_ptD = cms.InputTag("qgtagger:ptD")
705  proc.updatedJetsWithUserData.userInts.qgl_mult = cms.InputTag("qgtagger:mult")
706  #
707  # Save quark gluon likelihood input variables variables
708  #
709  proc.jetTable.variables.qgl_axis2 = QGLVARS.qgl_axis2
710  proc.jetTable.variables.qgl_ptD = QGLVARS.qgl_ptD
711  proc.jetTable.variables.qgl_mult = QGLVARS.qgl_mult
712  #
713  # Save standard b-tagging and c-tagging variables
714  #
715  proc.jetTable.variables.btagDeepB = BTAGVARS.btagDeepB
716  proc.jetTable.variables.btagCSVV2 = BTAGVARS.btagCSVV2
717  proc.jetTable.variables.btagDeepCvL = BTAGVARS.btagDeepCvL
718  proc.jetTable.variables.btagDeepCvB = BTAGVARS.btagDeepCvB
719  #
720  # Save DeepJet b-tagging and c-tagging variables
721  #
722  proc.jetTable.variables.btagDeepFlavB = DEEPJETVARS.btagDeepFlavB
723  proc.jetTable.variables.btagDeepFlavCvL = DEEPJETVARS.btagDeepFlavCvL
724  proc.jetTable.variables.btagDeepFlavCvB = DEEPJETVARS.btagDeepFlavCvB
725  #
726  # Save DeepJet raw score for gluon and light quarks
727  #
728  proc.jetTable.variables.btagDeepFlavG = DEEPJETVARS.btagDeepFlavG
729  proc.jetTable.variables.btagDeepFlavUDS = DEEPJETVARS.btagDeepFlavUDS
730  proc.jetTable.variables.btagDeepFlavQG = DEEPJETVARS.btagDeepFlavQG
731  #
732  # Add ParticleNetAK4 scores
733  #
734  proc.jetTable.variables.particleNetAK4_B = PARTICLENETAK4VARS.particleNetAK4_B
735  proc.jetTable.variables.particleNetAK4_CvsL = PARTICLENETAK4VARS.particleNetAK4_CvsL
736  proc.jetTable.variables.particleNetAK4_CvsB = PARTICLENETAK4VARS.particleNetAK4_CvsB
737  proc.jetTable.variables.particleNetAK4_QvsG = PARTICLENETAK4VARS.particleNetAK4_QvsG
738  proc.jetTable.variables.particleNetAK4_puIdDisc = PARTICLENETAK4VARS.particleNetAK4_puIdDisc
739 
740  #Adding hf shower shape producer to the jet sequence. By default this producer is not automatically rerun at the NANOAOD step
741  #The following lines make sure it is.
742  hfJetShowerShapeforCustomNanoAOD = "hfJetShowerShapeforCustomNanoAOD"
743  setattr(proc, hfJetShowerShapeforCustomNanoAOD, hfJetShowerShapeforNanoAOD.clone(jets="updatedJets",vertices="offlineSlimmedPrimaryVertices") )
744  proc.jetSequence.insert(proc.jetSequence.index(proc.updatedJetsWithUserData), getattr(proc, hfJetShowerShapeforCustomNanoAOD))
745  proc.updatedJetsWithUserData.userFloats.hfsigmaEtaEta = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:sigmaEtaEta')
746  proc.updatedJetsWithUserData.userFloats.hfsigmaPhiPhi = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:sigmaPhiPhi')
747  proc.updatedJetsWithUserData.userInts.hfcentralEtaStripSize = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:centralEtaStripSize')
748  proc.updatedJetsWithUserData.userInts.hfadjacentEtaStripsSize = cms.InputTag('hfJetShowerShapeforCustomNanoAOD:adjacentEtaStripsSize')
749  proc.jetTable.variables.hfsigmaEtaEta = Var("userFloat('hfsigmaEtaEta')",float,doc="sigmaEtaEta for HF jets (noise discriminating variable)",precision=10)
750  proc.jetTable.variables.hfsigmaPhiPhi = Var("userFloat('hfsigmaPhiPhi')",float,doc="sigmaPhiPhi for HF jets (noise discriminating variable)",precision=10)
751  proc.jetTable.variables.hfcentralEtaStripSize = Var("userInt('hfcentralEtaStripSize')", int, doc="eta size of the central tower strip in HF (noise discriminating variable) ")
752  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) ")
753 
754  return proc
755 
756 def AddNewAK8PuppiJetsForJEC(proc, recoJA, runOnMC):
757  """
758  Store a separate AK8 Puppi jet collection for JEC studies.
759  Only minimal info are stored
760  """
761  print("custom_jme_cff::AddNewAK8PuppiJetsForJEC: Make a new AK8 PF Puppi jet collection for JEC studies")
762 
763  #
764  # Recluster AK8 Puppi jets
765  #
766  cfg = {
767  "jet" : "ak8pfpuppi",
768  "inputCollection" : "",
769  "genJetsCollection": "AK8GenJetsNoNu",
770  "minPtFastjet" : 0., # Remove any pt threshold at the jet clustering stage.
771  }
772  recoJetInfo = recoJA.addRecoJetCollection(proc, **cfg)
773 
774  jetName = recoJetInfo.jetUpper
775  payload = recoJetInfo.jetCorrPayload
776 
777  patJetFinalColl = recoJetInfo.patJetFinalCollection
778  jetTablePrefix = "FatJetForJEC"
779  jetTableDoc = "AK8 PF Puppi jets with JECs applied. Reclustered for JEC studies so only minimal info stored."
780  ptcut = ""# No need to specify ptcut. Use default in SavePatJets function
781 
782  SavePatJets(proc,
783  jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc, doPF=True,
784  doCalo=False, ptcut=ptcut, doPUIDVar=False, doQGL=False, doBTag=False, runOnMC=runOnMC
785  )
786 
787  return proc
788 
789 def AddNewAK8CHSJets(proc, recoJA, runOnMC):
790  """
791  Store an AK8 CHS jet collection for JEC studies.
792  """
793  print("custom_jme_cff::AddNewAK8CHSJets: Make a new AK8 PF CHS jet collection for JEC studies")
794 
795  #
796  # Recluster AK8 CHS jets
797  #
798  cfg = {
799  "jet" : "ak8pfchs",
800  "inputCollection" : "",
801  "genJetsCollection": "AK8GenJetsNoNu",
802  "minPtFastjet" : 0., # Remove any pt threshold at the jet clustering stage.
803  }
804  recoJetInfo = recoJA.addRecoJetCollection(proc, **cfg)
805 
806  jetName = recoJetInfo.jetUpper
807  payload = recoJetInfo.jetCorrPayload
808 
809  patJetFinalColl = recoJetInfo.patJetFinalCollection
810  jetTablePrefix = "FatJetCHS"
811  jetTableDoc = "AK8 PF CHS jets with JECs applied. Reclustered for JEC studies so only minimal info stored."
812  ptcut = ""# No need to specify ptcut. Use default in SavePatJets function
813 
814  SavePatJets(proc,
815  jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc, doPF=True,
816  doCalo=False, ptcut=ptcut, doPUIDVar=False, doQGL=False, doBTag=False, runOnMC=runOnMC
817  )
818 
819  return proc
820 
822  """
823  Add more variables for AK8 PFPUPPI jets
824  """
825 
826  #
827  # These variables are not stored for AK8PFPUPPI (slimmedJetsAK8)
828  # in MiniAOD if their pt < 170 GeV. Hence the conditional fill.
829  #
830  proc.fatJetTable.variables.chHEF = Var("?isPFJet()?chargedHadronEnergyFraction():-1", float, doc="charged Hadron Energy Fraction", precision = 6)
831  proc.fatJetTable.variables.neHEF = Var("?isPFJet()?neutralHadronEnergyFraction():-1", float, doc="neutral Hadron Energy Fraction", precision = 6)
832  proc.fatJetTable.variables.chEmEF = Var("?isPFJet()?chargedEmEnergyFraction():-1", float, doc="charged Electromagnetic Energy Fraction", precision = 6)
833  proc.fatJetTable.variables.neEmEF = Var("?isPFJet()?neutralEmEnergyFraction():-1", float, doc="neutral Electromagnetic Energy Fraction", precision = 6)
834  proc.fatJetTable.variables.muEF = Var("?isPFJet()?muonEnergyFraction():-1", float, doc="muon Energy Fraction", precision = 6)
835  proc.fatJetTable.variables.hfHEF = Var("?isPFJet()?HFHadronEnergyFraction():-1", float, doc="energy fraction in forward hadronic calorimeter", precision = 6)
836  proc.fatJetTable.variables.hfEmEF = Var("?isPFJet()?HFEMEnergyFraction():-1", float, doc="energy fraction in forward EM calorimeter", precision = 6)
837  proc.fatJetTable.variables.nConstChHads = Var("?isPFJet()?chargedHadronMultiplicity():-1",int, doc="number of charged hadrons in the jet")
838  proc.fatJetTable.variables.nConstNeuHads = Var("?isPFJet()?neutralHadronMultiplicity():-1",int, doc="number of neutral hadrons in the jet")
839  proc.fatJetTable.variables.nConstHFHads = Var("?isPFJet()?HFHadronMultiplicity():-1", int, doc="number of HF Hadrons in the jet")
840  proc.fatJetTable.variables.nConstHFEMs = Var("?isPFJet()?HFEMMultiplicity():-1", int, doc="number of HF EMs in the jet")
841  proc.fatJetTable.variables.nConstMuons = Var("?isPFJet()?muonMultiplicity():-1", int, doc="number of muons in the jet")
842  proc.fatJetTable.variables.nConstElecs = Var("?isPFJet()?electronMultiplicity():-1", int, doc="number of electrons in the jet")
843  proc.fatJetTable.variables.nConstPhotons = Var("?isPFJet()?photonMultiplicity():-1", int, doc="number of photons in the jet")
844 
845  return proc
846 #******************************************
847 #
848 #
849 # Gen Jets related functions
850 #
851 #
852 #******************************************
853 def AddNewGenJets(proc, genJetInfo):
854  """
855  Add genJet into custom nanoAOD
856  """
857 
858  genJetName = genJetInfo.jetUpper
859  genJetAlgo = genJetInfo.jetAlgo
860  genJetSize = genJetInfo.jetSize
861  genJetSizeNr = genJetInfo.jetSizeNr
862  genJetFinalColl = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
863  genJetTablePrefix = nanoInfo_genjets[genJetInfo.jet]["name"]
864  genJetTableDoc = nanoInfo_genjets[genJetInfo.jet]["doc"]
865 
866  SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False)
867 
868  return proc
869 
870 def SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False):
871  """
872  Schedule modules for a given genJet collection and save its variables into custom NanoAOD
873  """
874 
875  genJetTableThisJet = "jet{}Table".format(genJetName)
876  setattr(proc, genJetTableThisJet, genJetTable.clone(
877  src = genJetFinalColl,
878  cut = "", # No cut specified here. Save all gen jets after clustering
879  name = genJetTablePrefix,
880  doc = genJetTableDoc,
881  variables = GENJETVARS
882  )
883  )
884 
885  genJetFlavourAssociationThisJet = "genJet{}FlavourAssociation".format(genJetName)
886  setattr(proc, genJetFlavourAssociationThisJet, genJetFlavourAssociation.clone(
887  jets = getattr(proc,genJetTableThisJet).src,
888  jetAlgorithm = supportedJetAlgos[genJetAlgo],
889  rParam = genJetSizeNr,
890  )
891  )
892 
893  genJetFlavourTableThisJet = "genJet{}FlavourTable".format(genJetName)
894  setattr(proc, genJetFlavourTableThisJet, genJetFlavourTable.clone(
895  name = getattr(proc,genJetTableThisJet).name,
896  src = getattr(proc,genJetTableThisJet).src,
897  cut = getattr(proc,genJetTableThisJet).cut,
898  jetFlavourInfos = genJetFlavourAssociationThisJet,
899  )
900  )
901 
902  genJetSequenceName = "genJet{}Sequence".format(genJetName)
903  setattr(proc, genJetSequenceName, cms.Sequence(
904  getattr(proc,genJetTableThisJet)+
905  getattr(proc,genJetFlavourAssociationThisJet)+
906  getattr(proc,genJetFlavourTableThisJet)
907  )
908  )
909  proc.nanoSequenceMC.insert(proc.nanoSequenceMC.index(proc.jetMC)+1, getattr(proc,genJetSequenceName))
910 
911  return proc
912 
913 def ReclusterAK4GenJets(proc, genJA):
914  """
915  Recluster AK4 Gen jets and replace
916  slimmedGenJets that is used as default
917  to save AK4 Gen jets in NanoAODs.
918  """
919  print("custom_jme_cff::ReclusterAK4GenJets: Recluster AK4 Gen jets")
920 
921  #
922  # Recluster AK4 Gen jet
923  #
924  cfg = {
925  "jet" : "ak4gen",
926  }
927  genJetInfo = genJA.addGenJetCollection(proc, **cfg)
928 
929  genJetName = genJetInfo.jetUpper
930  genJetAlgo = genJetInfo.jetAlgo
931  genJetSize = genJetInfo.jetSize
932  genJetSizeNr = genJetInfo.jetSizeNr
933  selectedGenJets = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
934 
935  #
936  # Change jet source to the newly clustered jet collection. Set very low pt cut for jets
937  # to be stored in the GenJet Table
938  #
939  proc.genJetTable.src = selectedGenJets
940  proc.genJetTable.cut = "" # No cut specified here. Save all gen jets after clustering
941  proc.genJetTable.doc = "AK4 Gen jets (made with visible genparticles) with pt > 3 GeV" # default pt cut after clustering is 3 GeV
942 
943  genJetFlavourAssociationThisJet = "genJet{}FlavourAssociation".format(genJetName)
944  setattr(proc, genJetFlavourAssociationThisJet, genJetFlavourAssociation.clone(
945  jets = proc.genJetTable.src,
946  jetAlgorithm = supportedJetAlgos[genJetAlgo],
947  rParam = genJetSizeNr,
948  )
949  )
950  proc.jetMC.insert(proc.jetMC.index(proc.genJetFlavourTable), getattr(proc, genJetFlavourAssociationThisJet))
951  return proc
952 
953 def AddNewAK8GenJetsForJEC(proc, genJA):
954  """
955  Make a separate AK8 Gen jet collection for JEC studies.
956  """
957  print("custom_jme_cff::AddNewAK8GenJetsForJEC: Add new AK8 Gen jets for JEC studies")
958 
959  #
960  # Recluster AK8 Gen jet
961  #
962  cfg = {
963  "jet" : "ak8gen",
964  }
965  genJetInfo = genJA.addGenJetCollection(proc, **cfg)
966 
967  genJetName = genJetInfo.jetUpper
968  genJetAlgo = genJetInfo.jetAlgo
969  genJetSize = genJetInfo.jetSize
970  genJetSizeNr = genJetInfo.jetSizeNr
971  genJetFinalColl = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
972  genJetTablePrefix = "GenJetAK8ForJEC"
973  genJetTableDoc = "AK8 Gen jets (made with visible genparticles) with pt > 3 GeV. Reclustered for JEC studies."
974 
975  SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False)
976 
977  return proc
978 
980  proc.genJetTable.variables.nConstituents = GENJETVARS.nConstituents
981  return proc
982 
984  proc.genJetAK8Table.variables.nConstituents = GENJETVARS.nConstituents
985  return proc
986 
987 #===========================================================================
988 #
989 # Misc. functions
990 #
991 #===========================================================================
993  """
994  Remove default pt cuts for all jets set in jets_cff.py
995  """
996 
997  proc.finalJets.cut = "" # 15 -> 10
998  proc.finalJetsAK8.cut = "" # 170 -> 170
999  proc.genJetTable.cut = "" # 10 -> 8
1000  proc.genJetFlavourTable.cut = "" # 10 -> 8
1001  proc.genJetAK8Table.cut = "" # 100 -> 80
1002  proc.genJetAK8FlavourTable.cut = "" # 100 -> 80
1003 
1004  return proc
1005 
1006 #===========================================================================
1007 #
1008 # CUSTOMIZATION function
1009 #
1010 #===========================================================================
1011 def PrepJMECustomNanoAOD(process,runOnMC):
1012 
1013  ############################################################################
1014  # Remove all default jet pt cuts from jets_cff.py
1015  ############################################################################
1016  process = RemoveAllJetPtCuts(process)
1017 
1018  ###########################################################################
1019  #
1020  # Gen-level jets related functions. Only for MC.
1021  #
1022  ###########################################################################
1023  genJA = GenJetAdder()
1024  if runOnMC:
1025  ############################################################################
1026  # Save additional variables for AK8 GEN jets
1027  ############################################################################
1028  process = AddVariablesForAK8GenJets(process)
1029  ############################################################################
1030  # Recluster AK8 GEN jets
1031  ############################################################################
1032  process = AddNewAK8GenJetsForJEC(process, genJA)
1033  ###########################################################################
1034  # Recluster AK4 GEN jets
1035  ###########################################################################
1036  process = ReclusterAK4GenJets(process, genJA)
1037  process = AddVariablesForAK4GenJets(process)
1038  ###########################################################################
1039  # Add additional GEN jets to NanoAOD
1040  ###########################################################################
1041  for jetConfig in config_genjets:
1042  cfg = { k : v for k, v in jetConfig.items() if k != "enabled"}
1043  genJetInfo = genJA.addGenJetCollection(process, **cfg)
1044  AddNewGenJets(process, genJetInfo)
1045 
1046  ###########################################################################
1047  #
1048  # Reco-level jets related functions. For both MC and data.
1049  #
1050  ###########################################################################
1051  recoJA = RecoJetAdder(runOnMC=runOnMC)
1052  ###########################################################################
1053  # Save additional variables for AK8Puppi jets
1054  ###########################################################################
1055  process = AddVariablesForAK8PuppiJets(process)
1056  ###########################################################################
1057  # Build a separate AK8Puppi jet collection for JEC studies
1058  ###########################################################################
1059  process = AddNewAK8PuppiJetsForJEC(process, recoJA, runOnMC)
1060  ###########################################################################
1061  # Build a AK8CHS jet collection for JEC studies
1062  ###########################################################################
1063  process = AddNewAK8CHSJets(process, recoJA, runOnMC)
1064  ###########################################################################
1065  # Recluster AK4 CHS jets and replace "slimmedJets"
1066  ###########################################################################
1067  process = ReclusterAK4CHSJets(process, recoJA, runOnMC)
1068  ###########################################################################
1069  # Add additional Reco jets to NanoAOD
1070  ###########################################################################
1071  for jetConfig in config_recojets:
1072  cfg = { k : v for k, v in jetConfig.items() if k != "enabled"}
1073  recoJetInfo = recoJA.addRecoJetCollection(process, **cfg)
1074  AddNewPatJets(process, recoJetInfo, runOnMC)
1075 
1076  ###########################################################################
1077  # Save Maximum of Pt Hat Max
1078  ###########################################################################
1079  if runOnMC:
1080  process.puTable.savePtHatMax = True
1081 
1082  ###########################################################################
1083  # Save all Parton-Shower weights
1084  ###########################################################################
1085  if runOnMC:
1086  process.genWeightsTable.keepAllPSWeights = True
1087 
1088  return process
1089 
1091  PrepJMECustomNanoAOD(process,runOnMC=True)
1092  return process
1093 
1095  PrepJMECustomNanoAOD(process,runOnMC=False)
1096  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