CMS 3D CMS Logo

custom_jme_cff.py
Go to the documentation of this file.
1 import FWCore.ParameterSet.Config as cms
2 
3 from Configuration.Eras.Modifier_run2_jme_2016_cff import run2_jme_2016
4 from Configuration.Eras.Modifier_run2_jme_2017_cff import run2_jme_2017
5 
6 from CommonTools.PileupAlgos.Puppi_cff import puppi
7 
8 from RecoJets.JetProducers.PileupJetID_cfi import pileupJetIdCalculator, pileupJetId
9 from RecoJets.JetProducers.PileupJetID_cfi import _chsalgos_81x, _chsalgos_94x, _chsalgos_102x
10 
11 from PhysicsTools.NanoAOD.common_cff import Var, P4Vars
12 from PhysicsTools.NanoAOD.jets_cff import jetTable, jetCorrFactorsNano, updatedJets, finalJets, qgtagger
13 from PhysicsTools.NanoAOD.jets_cff import genJetTable, genJetFlavourAssociation, genJetFlavourTable
14 
15 from PhysicsTools.PatAlgos.tools.jetCollectionTools import GenJetAdder, RecoJetAdder
16 from PhysicsTools.PatAlgos.tools.jetTools import supportedJetAlgos
17 from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection
18 
19 import copy
20 
21 bTagCSVV2 = ['pfDeepCSVJetTags:probb','pfDeepCSVJetTags:probbb','pfDeepCSVJetTags:probc']
22 bTagCMVAV2 = ['pfCombinedMVAV2BJetTags']
23 bTagDeepCSV = ['pfCombinedInclusiveSecondaryVertexV2BJetTags']
24 bTagDeepJet = [
25  'pfDeepFlavourJetTags:probb','pfDeepFlavourJetTags:probbb','pfDeepFlavourJetTags:problepb',
26  'pfDeepFlavourJetTags:probc','pfDeepFlavourJetTags:probuds','pfDeepFlavourJetTags:probg'
27 ]
28 bTagDiscriminatorsForAK4 = bTagCSVV2+bTagCMVAV2+bTagDeepCSV+bTagDeepJet
29 
30 #
31 # By default, these collections are saved in NanoAODs:
32 # - ak4gen (GenJet in NanoAOD), slimmedGenJets in MiniAOD
33 # - ak8gen (GenJetAK8 in NanoAOD), slimmedGenJetsAK8 in MiniAOD
34 # Below is a list of genjets that we can save in NanoAOD. Set
35 # "enabled" to true if you want to store the jet collection
36 config_genjets = [
37  {
38  "jet" : "ak8gen",
39  "enabled" : False,
40  },
41 ]
42 config_genjets = list(filter(lambda k: k['enabled'], config_genjets))
43 #
44 # GenJets info in NanoAOD
45 #
46 nanoInfo_genjets = {
47  "ak8gen" : {
48  "name" : "GenJetAK8",
49  "doc" : "AK8 Gen jets",
50  },
51 }
52 #
53 # By default, these collections are saved in the main NanoAODs:
54 # - ak4pfchs (Jet in NanoAOD), slimmedJets in MiniAOD
55 # - ak8pfpuppi (FatJet in NanoAOD), slimmedJetsAK8 in MiniAOD
56 # Below is a list of recojets that we can save in NanoAOD. Set
57 # "enabled" to true if you want to store the recojet collection.
58 #
59 config_recojets = [
60  {
61  "jet" : "ak4calo",
62  "enabled" : True,
63  "inputCollection" : "slimmedCaloJets", #Exist in MiniAOD
64  "genJetsCollection": "AK4GenJetsNoNu",
65  },
66  {
67  "jet" : "ak4pf",
68  "enabled" : True,
69  "inputCollection" : "",
70  "genJetsCollection": "AK4GenJetsNoNu",
71  },
72  {
73  "jet" : "ak4pfpuppi",
74  "enabled" : True,
75  "inputCollection" : "",
76  "genJetsCollection": "AK4GenJetsNoNu",
77  "bTagDiscriminators": bTagDiscriminatorsForAK4
78  },
79  {
80  "jet" : "ak8pf",
81  "enabled" : True,
82  "inputCollection" : "",
83  "genJetsCollection": "slimmedGenJetsAK8",
84  },
85  {
86  "jet" : "ak8pfchs",
87  "enabled" : True,
88  "inputCollection" : "",
89  "genJetsCollection": "slimmedGenJetsAK8",
90  },
91 ]
92 config_recojets = list(filter(lambda k: k['enabled'], config_recojets))
93 #
94 # RecoJets info in NanoAOD
95 #
96 nanoInfo_recojets = {
97  "ak4pfpuppi" : {
98  "name" : "JetPuppi",
99  "doc" : "AK4 PF Puppi jets with JECs applied, after basic selection (pt > 2)",
100  "ptcut" : "pt > 2",
101  "doQGL" : True,
102  "doPUIDVar": True,
103  "doBTag": True,
104  },
105  "ak4pf" : {
106  "name" : "JetPF",
107  "doc" : "AK4 PF jets with JECs applied, after basic selection (pt > 2)",
108  "ptcut" : "pt > 2",
109  },
110  "ak4calo" : {
111  "name": "JetCalo",
112  "doc" : "AK4 Calo jets with JECs applied",
113  },
114  "ak8pfchs" : {
115  "name" : "FatJetCHS",
116  "doc" : "AK8 PF CHS jets with JECs applied, after basic selection (pt > 100)",
117  "ptcut" : "pt > 100"
118  },
119  "ak8pf" : {
120  "name" : "FatJetPF",
121  "doc" : "AK8 PF jets with JECs applied, after basic selection (pt > 100)",
122  "ptcut" : "pt > 100",
123  },
124 }
125 
126 
127 
128 GENJETVARS = cms.PSet(P4Vars,
129  nConstituents = jetTable.variables.nConstituents,
130 )
131 PFJETVARS = cms.PSet(P4Vars,
132  rawFactor = jetTable.variables.rawFactor,
133  area = jetTable.variables.area,
134  chHEF = jetTable.variables.chHEF,
135  neHEF = jetTable.variables.neHEF,
136  chEmEF = jetTable.variables.chEmEF,
137  neEmEF = jetTable.variables.neEmEF,
138  muEF = jetTable.variables.muEF,
139  hfHEF = Var("HFHadronEnergyFraction()",float,doc = "hadronic energy fraction in HF",precision = 6),
140  hfEmEF = Var("HFEMEnergyFraction()",float,doc = "electromagnetic energy fraction in HF",precision = 6),
141  nMuons = jetTable.variables.nMuons,
142  nElectrons = jetTable.variables.nElectrons,
143  nConstituents = jetTable.variables.nConstituents,
144  nConstChHads = Var("chargedHadronMultiplicity()",int,doc="number of charged hadrons in the jet"),
145  nConstNeuHads = Var("neutralHadronMultiplicity()",int,doc="number of neutral hadrons in the jet"),
146  nConstHFHads = Var("HFHadronMultiplicity()", int,doc="number of HF hadrons in the jet"),
147  nConstHFEMs = Var("HFEMMultiplicity()",int,doc="number of HF EMs in the jet"),
148  nConstMuons = Var("muonMultiplicity()",int,doc="number of muons in the jet"),
149  nConstElecs = Var("electronMultiplicity()",int,doc="number of electrons in the jet"),
150  nConstPhotons = Var("photonMultiplicity()",int,doc="number of photons in the jet"),
151 )
152 PUIDVARS = cms.PSet(
153  puId_dR2Mean = Var("userFloat('puId_dR2Mean')",float,doc="pT^2-weighted average square distance of jet constituents from the jet axis (PileUp ID BDT input variable)", precision= 6),
154  puId_majW = Var("userFloat('puId_majW')",float,doc="major axis of jet ellipsoid in eta-phi plane (PileUp ID BDT input variable)", precision= 6) ,
155  puId_minW = Var("userFloat('puId_minW')",float,doc="minor axis of jet ellipsoid in eta-phi plane (PileUp ID BDT input variable)", precision= 6) ,
156  puId_frac01 = Var("userFloat('puId_frac01')",float,doc="fraction of constituents' pT contained within dR <0.1 (PileUp ID BDT input variable)", precision= 6) ,
157  puId_frac02 = Var("userFloat('puId_frac02')",float,doc="fraction of constituents' pT contained within 0.1< dR <0.2 (PileUp ID BDT input variable)", precision= 6) ,
158  puId_frac03 = Var("userFloat('puId_frac03')",float,doc="fraction of constituents' pT contained within 0.2< dR <0.3 (PileUp ID BDT input variable)", precision= 6) ,
159  puId_frac04 = Var("userFloat('puId_frac04')",float,doc="fraction of constituents' pT contained within 0.3< dR <0.4 (PileUp ID BDT input variable)", precision= 6) ,
160  puId_ptD = Var("userFloat('puId_ptD')",float,doc="pT-weighted average pT of constituents (PileUp ID BDT input variable)", precision= 6) ,
161  puId_beta = Var("userFloat('puId_beta')",float,doc="fraction of pT of charged constituents associated to PV (PileUp ID BDT input variable)", precision= 6) ,
162  puId_pull = Var("userFloat('puId_pull')",float,doc="magnitude of pull vector (PileUp ID BDT input variable)", precision= 6) ,
163  puId_jetR = Var("userFloat('puId_jetR')",float,doc="fraction of jet pT carried by the leading constituent (PileUp ID BDT input variable)", precision= 6) ,
164  puId_jetRchg = Var("userFloat('puId_jetRchg')",float,doc="fraction of jet pT carried by the leading charged constituent (PileUp ID BDT input variable)", precision= 6) ,
165  puId_nCharged = Var("userInt('puId_nCharged')",int,doc="number of charged constituents (PileUp ID BDT input variable)"),
166 )
167 QGLVARS = cms.PSet(
168  qgl_axis2 = Var("userFloat('qgl_axis2')",float,doc="ellipse minor jet axis (Quark vs Gluon likelihood input variable)", precision= 6),
169  qgl_ptD = Var("userFloat('qgl_ptD')",float,doc="pT-weighted average pT of constituents (Quark vs Gluon likelihood input variable)", precision= 6),
170  qgl_mult = Var("userInt('qgl_mult')", int,doc="PF candidates multiplicity (Quark vs Gluon likelihood input variable)"),
171 )
172 BTAGVARS = cms.PSet(
173  btagCMVA = jetTable.variables.btagCMVA,
174  btagDeepB = jetTable.variables.btagDeepB,
175  btagCSVV2 = jetTable.variables.btagCSVV2,
176  btagDeepC = jetTable.variables.btagDeepC,
177 )
178 DEEPJETVARS = cms.PSet(
179  btagDeepFlavB = jetTable.variables.btagDeepFlavB,
180  btagDeepFlavC = jetTable.variables.btagDeepFlavC,
181  btagDeepFlavG = Var("bDiscriminator('pfDeepFlavourJetTags:probg')",float,doc="DeepFlavour gluon tag raw score",precision=10),
182  btagDeepFlavUDS = Var("bDiscriminator('pfDeepFlavourJetTags:probuds')",float,doc="DeepFlavour uds tag raw score",precision=10)
183 )
184 CALOJETVARS = cms.PSet(P4Vars,
185  area = jetTable.variables.area,
186  rawFactor = jetTable.variables.rawFactor,
187  emf = Var("emEnergyFraction()", float, doc = "electromagnetic energy fraction", precision = 10),
188 )
189 
190 
191 #******************************************
192 #
193 #
194 # Reco Jets related functions
195 #
196 #
197 #******************************************
198 def AddJetID(proc, jetName="", jetSrc="", jetTableName="", jetSequenceName=""):
199  """
200  Setup modules to calculate PF jet ID
201  """
202 
203  isPUPPIJet = True if "Puppi" in jetName else False
204 
205  looseJetId = "looseJetId{}".format(jetName)
206  setattr(proc, looseJetId, proc.looseJetId.clone(
207  src = jetSrc,
208  filterParams=proc.looseJetId.filterParams.clone(
209  version ="WINTER16"
210  ),
211  )
212  )
213 
214  tightJetId = "tightJetId{}".format(jetName)
215  setattr(proc, tightJetId, proc.tightJetId.clone(
216  src = jetSrc,
217  filterParams=proc.tightJetId.filterParams.clone(
218  version = "SUMMER18{}".format("PUPPI" if isPUPPIJet else "")
219  ),
220  )
221  )
222 
223  tightJetIdLepVeto = "tightJetIdLepVeto{}".format(jetName)
224  setattr(proc, tightJetIdLepVeto, proc.tightJetIdLepVeto.clone(
225  src = jetSrc,
226  filterParams=proc.tightJetIdLepVeto.filterParams.clone(
227  version = "SUMMER18{}".format("PUPPI" if isPUPPIJet else "")
228  ),
229  )
230  )
231  run2_jme_2016.toModify(getattr(proc, tightJetId) .filterParams, version = "WINTER16" )
232  run2_jme_2016.toModify(getattr(proc, tightJetIdLepVeto) .filterParams, version = "WINTER16" )
233  run2_jme_2017.toModify(getattr(proc, tightJetId) .filterParams, version = "WINTER17{}".format("PUPPI" if isPUPPIJet else ""))
234  run2_jme_2017.toModify(getattr(proc, tightJetIdLepVeto) .filterParams, version = "WINTER17{}".format("PUPPI" if isPUPPIJet else ""))
235 
236  #
237  # Save variables as userInts in each jet
238  #
239  patJetWithUserData = "{}WithUserData".format(jetSrc)
240  getattr(proc, patJetWithUserData).userInts.tightId = cms.InputTag(tightJetId)
241  getattr(proc, patJetWithUserData).userInts.tightIdLepVeto = cms.InputTag(tightJetIdLepVeto)
242  run2_jme_2016.toModify(getattr(proc, patJetWithUserData).userInts, looseId = cms.InputTag(looseJetId))
243 
244  #
245  # Specfiy variables in the jetTable to save in NanoAOD
246  #
247  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")
248  run2_jme_2016.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"))
249 
250  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, jetSrc))+1, getattr(proc, tightJetId))
251  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, tightJetId))+1, getattr(proc, tightJetIdLepVeto))
252 
253  setattr(proc,"_"+jetSequenceName+"_2016", getattr(proc,jetSequenceName).copy())
254  getattr(proc,"_"+jetSequenceName+"_2016").insert(getattr(proc, "_"+jetSequenceName+"_2016").index(getattr(proc, tightJetId)), getattr(proc, looseJetId))
255  run2_jme_2016.toReplaceWith(getattr(proc,jetSequenceName), getattr(proc, "_"+jetSequenceName+"_2016"))
256 
257  return proc
258 
259 def AddPileUpJetIDVars(proc, jetName="", jetSrc="", jetTableName="", jetSequenceName=""):
260  """
261  Setup modules to calculate pileup jet ID input variables for PF jet
262  """
263 
264  #
265  # Calculate pileup jet ID variables
266  #
267  puJetIdVarsCalculator = "puJetIdCalculator{}".format(jetName)
268  setattr(proc, puJetIdVarsCalculator, pileupJetIdCalculator.clone(
269  jets = jetSrc,
270  vertexes = "offlineSlimmedPrimaryVertices",
271  inputIsCorrected = True,
272  applyJec = False,
273  usePuppi = True if "Puppi" in jetName else False
274  )
275  )
276  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, jetSrc))+1, getattr(proc, puJetIdVarsCalculator))
277 
278  #
279  # Get the variables
280  #
281  puJetIDVar = "puJetIDVar{}".format(jetName)
282  setattr(proc, puJetIDVar, cms.EDProducer("PileupJetIDVarProducer",
283  srcJet = cms.InputTag(jetSrc),
284  srcPileupJetId = cms.InputTag(puJetIdVarsCalculator)
285  )
286  )
287  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, puJetIdVarsCalculator))+1, getattr(proc, puJetIDVar))
288 
289  #
290  # Save variables as userFloats and userInts for each jet
291  #
292  patJetWithUserData = "{}WithUserData".format(jetSrc)
293  getattr(proc,patJetWithUserData).userFloats.puId_dR2Mean = cms.InputTag("{}:dR2Mean".format(puJetIDVar))
294  getattr(proc,patJetWithUserData).userFloats.puId_majW = cms.InputTag("{}:majW".format(puJetIDVar))
295  getattr(proc,patJetWithUserData).userFloats.puId_minW = cms.InputTag("{}:minW".format(puJetIDVar))
296  getattr(proc,patJetWithUserData).userFloats.puId_frac01 = cms.InputTag("{}:frac01".format(puJetIDVar))
297  getattr(proc,patJetWithUserData).userFloats.puId_frac02 = cms.InputTag("{}:frac02".format(puJetIDVar))
298  getattr(proc,patJetWithUserData).userFloats.puId_frac03 = cms.InputTag("{}:frac03".format(puJetIDVar))
299  getattr(proc,patJetWithUserData).userFloats.puId_frac04 = cms.InputTag("{}:frac04".format(puJetIDVar))
300  getattr(proc,patJetWithUserData).userFloats.puId_ptD = cms.InputTag("{}:ptD".format(puJetIDVar))
301  getattr(proc,patJetWithUserData).userFloats.puId_beta = cms.InputTag("{}:beta".format(puJetIDVar))
302  getattr(proc,patJetWithUserData).userFloats.puId_pull = cms.InputTag("{}:pull".format(puJetIDVar))
303  getattr(proc,patJetWithUserData).userFloats.puId_jetR = cms.InputTag("{}:jetR".format(puJetIDVar))
304  getattr(proc,patJetWithUserData).userFloats.puId_jetRchg = cms.InputTag("{}:jetRchg".format(puJetIDVar))
305  getattr(proc,patJetWithUserData).userInts.puId_nCharged = cms.InputTag("{}:nCharged".format(puJetIDVar))
306 
307  #
308  # Specfiy variables in the jet table to save in NanoAOD
309  #
310  getattr(proc,jetTableName).variables.puId_dR2Mean = PUIDVARS.puId_dR2Mean
311  getattr(proc,jetTableName).variables.puId_majW = PUIDVARS.puId_majW
312  getattr(proc,jetTableName).variables.puId_minW = PUIDVARS.puId_minW
313  getattr(proc,jetTableName).variables.puId_frac01 = PUIDVARS.puId_frac01
314  getattr(proc,jetTableName).variables.puId_frac02 = PUIDVARS.puId_frac02
315  getattr(proc,jetTableName).variables.puId_frac03 = PUIDVARS.puId_frac03
316  getattr(proc,jetTableName).variables.puId_frac04 = PUIDVARS.puId_frac04
317  getattr(proc,jetTableName).variables.puId_ptD = PUIDVARS.puId_ptD
318  getattr(proc,jetTableName).variables.puId_beta = PUIDVARS.puId_beta
319  getattr(proc,jetTableName).variables.puId_pull = PUIDVARS.puId_pull
320  getattr(proc,jetTableName).variables.puId_jetR = PUIDVARS.puId_jetR
321  getattr(proc,jetTableName).variables.puId_jetRchg = PUIDVARS.puId_jetRchg
322  getattr(proc,jetTableName).variables.puId_nCharged = PUIDVARS.puId_nCharged
323 
324  return proc
325 
326 def AddQGLTaggerVars(proc, jetName="", jetSrc="", jetTableName="", jetSequenceName="", calculateQGLVars=False):
327  """
328  Schedule the QGTagger module to calculate input variables to the QG likelihood
329  """
330 
331  QGLTagger="qgtagger{}".format(jetName)
332  patJetWithUserData="{}WithUserData".format(jetSrc)
333 
334  if calculateQGLVars:
335  setattr(proc, QGLTagger, qgtagger.clone(
336  srcJets=jetSrc
337  )
338  )
339 
340  #
341  # Save variables as userFloats and userInts for each jet
342  #
343  getattr(proc,patJetWithUserData).userFloats.qgl_axis2 = cms.InputTag(QGLTagger+":axis2")
344  getattr(proc,patJetWithUserData).userFloats.qgl_ptD = cms.InputTag(QGLTagger+":ptD")
345  getattr(proc,patJetWithUserData).userInts.qgl_mult = cms.InputTag(QGLTagger+":mult")
346 
347  #
348  # Specfiy variables in the jet table to save in NanoAOD
349  #
350  getattr(proc,jetTableName).variables.qgl_axis2 = QGLVARS.qgl_axis2
351  getattr(proc,jetTableName).variables.qgl_ptD = QGLVARS.qgl_ptD
352  getattr(proc,jetTableName).variables.qgl_mult = QGLVARS.qgl_mult
353 
354  if calculateQGLVars:
355  getattr(proc,jetSequenceName).insert(getattr(proc,jetSequenceName).index(getattr(proc, jetSrc))+1, getattr(proc, QGLTagger))
356 
357  return proc
358 
359 def AddBTaggingScores(proc, jetTableName=""):
360  """
361  Store b-tagging scores from various algortihm
362  """
363 
364  getattr(proc, jetTableName).variables.btagCMVA = jetTable.variables.btagCMVA
365  getattr(proc, jetTableName).variables.btagDeepB = jetTable.variables.btagDeepB
366  getattr(proc, jetTableName).variables.btagCSVV2 = jetTable.variables.btagCSVV2
367  getattr(proc, jetTableName).variables.btagDeepC = jetTable.variables.btagDeepC
368  getattr(proc, jetTableName).variables.btagDeepFlavB = jetTable.variables.btagDeepFlavB
369  getattr(proc, jetTableName).variables.btagDeepFlavC = jetTable.variables.btagDeepFlavC
370 
371  return proc
372 
373 def AddDeepJetGluonLQuarkScores(proc, jetTableName=""):
374  """
375  Store DeepJet raw score in jetTable for gluon and light quark
376  """
377 
378  getattr(proc, jetTableName).variables.btagDeepFlavG = DEEPJETVARS.btagDeepFlavG
379  getattr(proc, jetTableName).variables.btagDeepFlavUDS = DEEPJETVARS.btagDeepFlavUDS
380 
381  return proc
382 
383 def AddNewPatJets(proc, recoJetInfo, runOnMC):
384  """
385  Add patJet into custom nanoAOD
386  """
387 
388  jetName = recoJetInfo.jetUpper
389  payload = recoJetInfo.jetCorrPayload
390  doPF = recoJetInfo.doPF
391  doCalo = recoJetInfo.doCalo
392 
393  if recoJetInfo.inputCollection != "":
394  patJetFinalColl = recoJetInfo.inputCollection
395  else:
396  patJetFinalColl = "selectedUpdatedPatJets{}Final".format(jetName)
397 
398  if doCalo:
399  patJetFinalColl = "selectedPatJets{}".format(jetName)
400 
401  nanoInfoForJet = nanoInfo_recojets[recoJetInfo.jet]
402  jetTablePrefix = nanoInfoForJet["name"]
403  jetTableDoc = nanoInfoForJet["doc"]
404  ptcut = nanoInfoForJet["ptcut"] if "ptcut" in nanoInfoForJet else ""
405  doPUIDVar = nanoInfoForJet["doPUIDVar"] if "doPUIDVar" in nanoInfoForJet else False
406  doQGL = nanoInfoForJet["doQGL"] if "doQGL" in nanoInfoForJet else False
407  doBTag = nanoInfoForJet["doBTag"] if "doBTag" in nanoInfoForJet else False
408 
409  SavePatJets(proc,
410  jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc, doPF, doCalo,
411  ptcut=ptcut, doPUIDVar=doPUIDVar, doQGL=doQGL, doBTag=doBTag, runOnMC=runOnMC
412  )
413 
414  return proc
415 
416 def SavePatJets(proc, jetName, payload, patJetFinalColl, jetTablePrefix, jetTableDoc,
417  doPF, doCalo, ptcut="", doPUIDVar=False, doQGL=False, doBTag=False, runOnMC=False):
418  """
419  Schedule modules for a given patJet collection and save its variables into custom NanoAOD
420  """
421 
422  #
423  # Setup jet correction factors
424  #
425  jetCorrFactors = "jetCorrFactorsNano{}".format(jetName)
426  setattr(proc, jetCorrFactors, jetCorrFactorsNano.clone(
427  src = patJetFinalColl,
428  payload = payload,
429  )
430  )
431 
432  #
433  # Update jets
434  #
435  srcJets = "updatedJets{}".format(jetName)
436  setattr(proc, srcJets, updatedJets.clone(
437  jetSource = patJetFinalColl,
438  jetCorrFactorsSource=[jetCorrFactors],
439  )
440  )
441 
442  #
443  # Setup UserDataEmbedder
444  #
445  srcJetsWithUserData = "updatedJets{}WithUserData".format(jetName)
446  setattr(proc, srcJetsWithUserData, cms.EDProducer("PATJetUserDataEmbedder",
447  src = cms.InputTag(srcJets),
448  userFloats = cms.PSet(),
449  userInts = cms.PSet(),
450  )
451  )
452 
453  #
454  # Filter jets with pt cut
455  #
456  finalJetsForTable = "finalJets{}".format(jetName)
457  setattr(proc, finalJetsForTable, finalJets.clone(
458  src = srcJetsWithUserData,
459  cut = ptcut
460  )
461  )
462 
463  #
464  # Save jets in table
465  #
466  tableContent = PFJETVARS
467  if doCalo:
468  tableContent = CALOJETVARS
469 
470  jetTable = "jet{}Table".format(jetName)
471  setattr(proc,jetTable, cms.EDProducer("SimpleCandidateFlatTableProducer",
472  src = cms.InputTag(finalJetsForTable),
473  cut = cms.string(""), # Don't specify cuts here
474  name = cms.string(jetTablePrefix),
475  doc = cms.string(jetTableDoc),
476  singleton = cms.bool(False), # the number of entries is variable
477  extension = cms.bool(False), # this is the main table for the jets
478  variables = cms.PSet(tableContent)
479  )
480  )
481  getattr(proc,jetTable).variables.pt.precision=10
482 
483  #
484  # Save MC-only jet variables in table
485  #
486  jetMCTable = "jet{}MCTable".format(jetName)
487  setattr(proc, jetMCTable, cms.EDProducer("SimpleCandidateFlatTableProducer",
488  src = cms.InputTag(finalJetsForTable),
489  cut = getattr(proc,jetTable).cut,
490  name = cms.string(jetTablePrefix),
491  singleton = cms.bool(False),
492  extension = cms.bool(True), # this is an extension table
493  variables = cms.PSet(
494  partonFlavour = Var("partonFlavour()", int, doc="flavour from parton matching"),
495  hadronFlavour = Var("hadronFlavour()", int, doc="flavour from hadron ghost clustering"),
496  genJetIdx = Var("?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1", int, doc="index of matched gen jet"),
497  )
498  )
499  )
500 
501  #
502  # Define the jet modules sequence first
503  #
504  jetSequenceName = "jet{}Sequence".format(jetName)
505  setattr(proc, jetSequenceName, cms.Sequence(
506  getattr(proc,jetCorrFactors)+
507  getattr(proc,srcJets)+
508  getattr(proc,srcJetsWithUserData)+
509  getattr(proc,finalJetsForTable)
510  )
511  )
512 
513  #
514  # Define the jet table sequences
515  #
516  jetTableSequenceName = "jet{}TablesSequence".format(jetName)
517  setattr(proc, jetTableSequenceName, cms.Sequence(getattr(proc,jetTable)))
518 
519  jetTableSequenceMCName = "jet{}MCTablesSequence".format(jetName)
520  setattr(proc, jetTableSequenceMCName, cms.Sequence(getattr(proc,jetMCTable)))
521 
522  if runOnMC:
523  proc.nanoSequenceMC += getattr(proc,jetSequenceName)
524  proc.nanoSequenceMC += getattr(proc,jetTableSequenceName)
525  proc.nanoSequenceMC += getattr(proc,jetTableSequenceMCName)
526  else:
527  proc.nanoSequence += getattr(proc,jetSequenceName)
528  proc.nanoSequence += getattr(proc,jetTableSequenceName)
529 
530  #
531  # Schedule plugins to calculate Jet ID, PileUp Jet ID input variables, and Quark-Gluon Likehood input variables.
532  #
533  if doPF:
534  proc = AddJetID(proc, jetName=jetName, jetSrc=srcJets, jetTableName=jetTable, jetSequenceName=jetSequenceName)
535  if doPUIDVar:
536  proc = AddPileUpJetIDVars(proc, jetName=jetName, jetSrc=srcJets, jetTableName=jetTable, jetSequenceName=jetSequenceName)
537  if doQGL:
538  proc = AddQGLTaggerVars(proc,jetName=jetName, jetSrc=srcJets, jetTableName=jetTable, jetSequenceName=jetSequenceName, calculateQGLVars=True)
539 
540  #
541  # Save b-tagging algorithm scores. Should only be done for jet collection with b-tagging
542  # calculated when reclustered or collection saved with b-tagging info in MiniAOD
543  #
544  if doBTag:
545  AddBTaggingScores(proc,jetTableName=jetTable)
546  AddDeepJetGluonLQuarkScores(proc,jetTableName=jetTable)
547 
548  return proc
549 
550 def ReclusterAK4CHSJets(proc, recoJA, runOnMC):
551  """
552  Recluster AK4 CHS jets and replace slimmedJets
553  that is used as default to save AK4 CHS jets
554  in NanoAODs.
555  """
556  print("custom_jme_cff::ReclusterAK4CHSJets: Recluster AK4 PF CHS jets")
557 
558  #
559  # Recluster AK4 CHS jets
560  #
561  cfg = {
562  "jet" : "ak4pfchs",
563  "inputCollection" : "",
564  "genJetsCollection": "AK4GenJetsNoNu",
565  "bTagDiscriminators": bTagDiscriminatorsForAK4
566  }
567  recoJetInfo = recoJA.addRecoJetCollection(proc, **cfg)
568 
569  jetName = recoJetInfo.jetUpper
570  patJetFinalColl = "selectedUpdatedPatJets{}Final".format(jetName)
571 
572  #
573  # Change the input jet source for jetCorrFactorsNano
574  # and updatedJets
575  #
576  proc.jetCorrFactorsNano.src=patJetFinalColl
577  proc.updatedJets.jetSource=patJetFinalColl
578 
579  #
580  # Change pt cut
581  #
582  proc.finalJets.cut = "pt > 2"
583  proc.simpleCleanerTable.jetSel = "pt > 10" # Change this from 15 -> 10
584 
585  #
586  # Add variables
587  #
588  proc.jetTable.variables.hfHEF = PFJETVARS.hfHEF
589  proc.jetTable.variables.hfEmEF = PFJETVARS.hfEmEF
590  proc.jetTable.variables.nConstChHads = PFJETVARS.nConstChHads
591  proc.jetTable.variables.nConstNeuHads = PFJETVARS.nConstNeuHads
592  proc.jetTable.variables.nConstHFHads = PFJETVARS.nConstHFHads
593  proc.jetTable.variables.nConstHFEMs = PFJETVARS.nConstHFEMs
594  proc.jetTable.variables.nConstMuons = PFJETVARS.nConstMuons
595  proc.jetTable.variables.nConstElecs = PFJETVARS.nConstElecs
596  proc.jetTable.variables.nConstPhotons = PFJETVARS.nConstPhotons
597 
598  proc.jetTable.doc = cms.string("AK4 PF CHS Jets with JECs applied, after basic selection (pt > 2)")
599 
600  #
601  # Setup pileup jet ID with 80X training.
602  #
603  pileupJetId80X = "pileupJetId80X"
604  setattr(proc, pileupJetId80X, pileupJetId.clone(
605  jets="updatedJets",
606  algos=cms.VPSet(_chsalgos_81x),
607  inputIsCorrected=True,
608  applyJec=False,
609  vertexes="offlineSlimmedPrimaryVertices"
610  )
611  )
612  proc.jetSequence.insert(proc.jetSequence.index(proc.pileupJetId94X), getattr(proc, pileupJetId80X))
613 
614  proc.updatedJetsWithUserData.userInts.puId80XfullId = cms.InputTag('pileupJetId80X:fullId')
615  run2_jme_2016.toModify(proc.updatedJetsWithUserData.userFloats, puId80XDisc = cms.InputTag("pileupJetId80X:fullDiscriminant"))
616 
617  proc.jetTable.variables.puId = Var("userInt('puId80XfullId')", int, doc="Pilup ID flags with 80X (2016) training")
618  run2_jme_2016.toModify(proc.jetTable.variables, puIdDisc = Var("userFloat('puId80XDisc')",float,doc="Pilup ID discriminant with 80X (2016) training",precision=10))
619 
620  #
621  # Add variables for pileup jet ID studies.
622  #
623  proc = AddPileUpJetIDVars(proc,
624  jetName="",
625  jetSrc="updatedJets",
626  jetTableName="jetTable",
627  jetSequenceName="jetSequence"
628  )
629  #
630  # Add variables for quark guon likelihood tagger studies.
631  # Save variables as userFloats and userInts in each jet
632  #
633  proc.updatedJetsWithUserData.userFloats.qgl_axis2 = cms.InputTag("qgtagger:axis2")
634  proc.updatedJetsWithUserData.userFloats.qgl_ptD = cms.InputTag("qgtagger:ptD")
635  proc.updatedJetsWithUserData.userInts.qgl_mult = cms.InputTag("qgtagger:mult")
636  #
637  # Specfiy variables in the jetTable to save in NanoAOD
638  #
639  proc.jetTable.variables.qgl_axis2 = QGLVARS.qgl_axis2
640  proc.jetTable.variables.qgl_ptD = QGLVARS.qgl_ptD
641  proc.jetTable.variables.qgl_mult = QGLVARS.qgl_mult
642  #
643  # Save DeepJet raw score for gluon and light quarks
644  #
645  proc.jetTable.variables.btagDeepFlavG = DEEPJETVARS.btagDeepFlavG
646  proc.jetTable.variables.btagDeepFlavUDS = DEEPJETVARS.btagDeepFlavUDS
647 
648  return proc
649 
651  """
652  Add more variables for AK8 PFPUPPI jets
653  """
654 
655  #
656  # These variables are not stored for AK8PFCHS (slimmedJetsAK8)
657  # in MiniAOD if their pt < 170 GeV. Hence the conditional fill.
658  #
659  proc.fatJetTable.variables.chHEF = Var("?isPFJet()?chargedHadronEnergyFraction():-1", float, doc="charged Hadron Energy Fraction", precision = 6)
660  proc.fatJetTable.variables.neHEF = Var("?isPFJet()?neutralHadronEnergyFraction():-1", float, doc="neutral Hadron Energy Fraction", precision = 6)
661  proc.fatJetTable.variables.chEmEF = Var("?isPFJet()?chargedEmEnergyFraction():-1", float, doc="charged Electromagnetic Energy Fraction", precision = 6)
662  proc.fatJetTable.variables.neEmEF = Var("?isPFJet()?neutralEmEnergyFraction():-1", float, doc="neutral Electromagnetic Energy Fraction", precision = 6)
663  proc.fatJetTable.variables.muEF = Var("?isPFJet()?muonEnergyFraction():-1", float, doc="muon Energy Fraction", precision = 6)
664  proc.fatJetTable.variables.hfHEF = Var("?isPFJet()?HFHadronEnergyFraction():-1", float, doc="energy fraction in forward hadronic calorimeter", precision = 6)
665  proc.fatJetTable.variables.hfEmEF = Var("?isPFJet()?HFEMEnergyFraction():-1", float, doc="energy fraction in forward EM calorimeter", precision = 6)
666  proc.fatJetTable.variables.nConstChHads = Var("?isPFJet()?chargedHadronMultiplicity():-1",int, doc="number of charged hadrons in the jet")
667  proc.fatJetTable.variables.nConstNeuHads = Var("?isPFJet()?neutralHadronMultiplicity():-1",int, doc="number of neutral hadrons in the jet")
668  proc.fatJetTable.variables.nConstHFHads = Var("?isPFJet()?HFHadronMultiplicity():-1", int, doc="number of HF Hadrons in the jet")
669  proc.fatJetTable.variables.nConstHFEMs = Var("?isPFJet()?HFEMMultiplicity():-1", int, doc="number of HF EMs in the jet")
670  proc.fatJetTable.variables.nConstMuons = Var("?isPFJet()?muonMultiplicity():-1", int, doc="number of muons in the jet")
671  proc.fatJetTable.variables.nConstElecs = Var("?isPFJet()?electronMultiplicity():-1", int, doc="number of electrons in the jet")
672  proc.fatJetTable.variables.nConstPhotons = Var("?isPFJet()?photonMultiplicity():-1", int, doc="number of photons in the jet")
673 
674  return proc
675 #******************************************
676 #
677 #
678 # Gen Jets related functions
679 #
680 #
681 #******************************************
682 def AddNewGenJets(proc, genJetInfo):
683  """
684  Add genJet into custom nanoAOD
685  """
686 
687  genJetName = genJetInfo.jetUpper
688  genJetAlgo = genJetInfo.jetAlgo
689  genJetSize = genJetInfo.jetSize
690  genJetSizeNr = genJetInfo.jetSizeNr
691  genJetFinalColl = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
692  genJetTablePrefix = nanoInfo_genjets[genJetInfo.jet]["name"]
693  genJetTableDoc = nanoInfo_genjets[genJetInfo.jet]["doc"]
694 
695  SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False)
696 
697  return proc
698 
699 def SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False):
700  """
701  Schedule modules for a given genJet collection and save its variables into custom NanoAOD
702  """
703 
704  genJetTableThisJet = "jet{}Table".format(genJetName)
705  setattr(proc, genJetTableThisJet, genJetTable.clone(
706  src = genJetFinalColl,
707  cut = "pt > 1",
708  name = genJetTablePrefix,
709  doc = genJetTableDoc,
710  variables = GENJETVARS
711  )
712  )
713 
714  genJetFlavourAssociationThisJet = "genJet{}FlavourAssociation".format(genJetName)
715  setattr(proc, genJetFlavourAssociationThisJet, genJetFlavourAssociation.clone(
716  jets = getattr(proc,genJetTableThisJet).src,
717  jetAlgorithm = supportedJetAlgos[genJetAlgo],
718  rParam = genJetSizeNr,
719  )
720  )
721 
722  genJetFlavourTableThisJet = "genJet{}FlavourTable".format(genJetName)
723  setattr(proc, genJetFlavourTableThisJet, genJetFlavourTable.clone(
724  name = getattr(proc,genJetTableThisJet).name,
725  src = getattr(proc,genJetTableThisJet).src,
726  cut = getattr(proc,genJetTableThisJet).cut,
727  jetFlavourInfos = genJetFlavourAssociationThisJet,
728  )
729  )
730 
731  genJetSequenceName = "genJet{}Sequence".format(genJetName)
732  setattr(proc, genJetSequenceName, cms.Sequence(
733  getattr(proc,genJetTableThisJet)+
734  getattr(proc,genJetFlavourAssociationThisJet)+
735  getattr(proc,genJetFlavourTableThisJet)
736  )
737  )
738  proc.nanoSequenceMC.insert(proc.nanoSequenceMC.index(proc.jetMC)+1, getattr(proc,genJetSequenceName))
739 
740  return proc
741 
742 def ReclusterAK4GenJets(proc, genJA):
743  """
744  Recluster AK4 Gen jets and replace
745  slimmedGenJets that is used as default
746  to save AK4 Gen jets in NanoAODs.
747  """
748  print("custom_jme_cff::ReclusterAK4GenJets: Recluster AK4 Gen jets")
749 
750  #
751  # Recluster AK4 Gen jet
752  #
753  cfg = {
754  "jet" : "ak4gen",
755  }
756  genJetInfo = genJA.addGenJetCollection(proc, **cfg)
757 
758  genJetName = genJetInfo.jetUpper
759  genJetAlgo = genJetInfo.jetAlgo
760  genJetSize = genJetInfo.jetSize
761  genJetSizeNr = genJetInfo.jetSizeNr
762  selectedPatGenJets = "{}{}{}".format(genJetAlgo.upper(), genJetSize, "GenJetsNoNu")
763 
764  #
765  # Change jet source to the newly clustered jet collection. Set very low pt cut for jets
766  # to be stored in the GenJet Table
767  #
768  proc.genJetTable.src = selectedPatGenJets
769  proc.genJetTable.cut = "pt > 1"
770  proc.genJetTable.doc ="AK4 Gen jets (made with visible genparticles)"
771 
772  genJetFlavourAssociationThisJet = "genJet{}FlavourAssociation".format(genJetName)
773  setattr(proc, genJetFlavourAssociationThisJet, genJetFlavourAssociation.clone(
774  jets = proc.genJetTable.src,
775  jetAlgorithm = supportedJetAlgos[genJetAlgo],
776  rParam = genJetSizeNr,
777  )
778  )
779  proc.jetMC.insert(proc.jetMC.index(proc.genJetFlavourTable), getattr(proc, genJetFlavourAssociationThisJet))
780  return proc
781 
783  proc.genJetTable.variables.nConstituents = GENJETVARS.nConstituents
784  return proc
785 
787  proc.genJetAK8Table.variables.nConstituents = GENJETVARS.nConstituents
788  return proc
789 
790 #===========================================================================
791 #
792 # Misc. functions
793 #
794 #===========================================================================
796  """
797  Remove default pt cuts for all jets set in jets_cff.py
798  """
799 
800  proc.finalJets.cut = "" # 15 -> 10
801  proc.finalJetsAK8.cut = "" # 170 -> 170
802  proc.genJetTable.cut = "" # 10 -> 8
803  proc.genJetFlavourTable.cut = "" # 10 -> 8
804  proc.genJetAK8Table.cut = "" # 100 -> 80
805  proc.genJetAK8FlavourTable.cut = "" # 100 -> 80
806 
807  return proc
808 
809 #===========================================================================
810 #
811 # CUSTOMIZATION function
812 #
813 #===========================================================================
814 def PrepJMECustomNanoAOD(process,runOnMC):
815 
816  ############################################################################
817  # Remove all default jet pt cuts from jets_cff.py
818  ############################################################################
819  process = RemoveAllJetPtCuts(process)
820 
821  ###########################################################################
822  #
823  # Gen-level jets related functions. Only for MC.
824  #
825  ###########################################################################
826  genJA = GenJetAdder()
827  if runOnMC:
828  ############################################################################
829  # Save additional variables for AK8 GEN jets
830  ############################################################################
831  process = AddVariablesForAK8GenJets(process)
832  ###########################################################################
833  # Recluster AK4 GEN jets
834  ###########################################################################
835  process = ReclusterAK4GenJets(process, genJA)
836  process = AddVariablesForAK4GenJets(process)
837  ###########################################################################
838  # Add additional GEN jets to NanoAOD
839  ###########################################################################
840  for jetConfig in config_genjets:
841  cfg = { k : v for k, v in jetConfig.items() if k != "enabled"}
842  genJetInfo = genJA.addGenJetCollection(process, **cfg)
843  AddNewGenJets(process, genJetInfo)
844 
845  ###########################################################################
846  #
847  # Reco-level jets related functions. For both MC and data.
848  #
849  ###########################################################################
850  recoJA = RecoJetAdder(runOnMC=runOnMC)
851  ###########################################################################
852  # Save additional variables for AK8Puppi jets
853  ###########################################################################
854  process = AddVariablesForAK8PuppiJets(process)
855  ###########################################################################
856  # Recluster AK4 CHS jets and replace "slimmedJets"
857  ###########################################################################
858  process = ReclusterAK4CHSJets(process, recoJA, runOnMC)
859  ###########################################################################
860  # Add additional Reco jets to NanoAOD
861  ###########################################################################
862  for jetConfig in config_recojets:
863  cfg = { k : v for k, v in jetConfig.items() if k != "enabled"}
864  recoJetInfo = recoJA.addRecoJetCollection(process, **cfg)
865  AddNewPatJets(process, recoJetInfo, runOnMC)
866 
867  return process
868 
870  PrepJMECustomNanoAOD(process,runOnMC=True)
871  return process
872 
874  PrepJMECustomNanoAOD(process,runOnMC=False)
875  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 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 AddNewGenJets(proc, genJetInfo)
def SaveGenJets(proc, genJetName, genJetAlgo, genJetSizeNr, genJetFinalColl, genJetTablePrefix, genJetTableDoc, runOnMC=False)
def AddVariablesForAK4GenJets(proc)
def AddVariablesForAK8PuppiJets(proc)
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