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_miniAOD_80XLegacy_cff import run2_miniAOD_80XLegacy
4 from Configuration.Eras.Modifier_run2_nanoAOD_94X2016_cff import run2_nanoAOD_94X2016
5 
6 from PhysicsTools.NanoAOD.common_cff import Var, P4Vars
7 from PhysicsTools.NanoAOD.jets_cff import jetTable
8 
9 from PhysicsTools.PatAlgos.tools.jetCollectionTools import GenJetAdder, RecoJetAdder
10 
11 import copy
12 
13 #
14 # By default, these collections are saved in NanoAODs:
15 # - ak4gen (GenJet in NanoAOD)
16 # - ak8gen (GenJetAK8 in NanoAOD)
17 # Below is a list of genjets that we can save in NanoAOD. Set
18 # "enabled" to true if you want to store the jet collection
19 config_genjets = [
20  {
21  "jet" : "ak5gen",
22  "enabled" : False,
23  },
24  {
25  "jet" : "ak6gen",
26  "enabled" : False,
27  },
28  {
29  "jet" : "ak7gen",
30  "enabled" : False,
31  },
32  {
33  "jet" : "ak9gen",
34  "enabled" : False,
35  },
36  {
37  "jet" : "ak10gen",
38  "enabled" : False,
39  },
40 ]
41 config_genjets = list(filter(lambda k: k['enabled'], config_genjets))
42 #
43 # GenJets info in NanoAOD
44 #
45 nanoInfo_genjets = {
46  "ak5gen" : {
47  "name" : "GenJetAK5",
48  "doc" : "AK5 jets",
49  },
50  "ak6gen" : {
51  "name" : "GenJetAK6",
52  "doc" : "AK6 jets",
53  },
54  "ak7gen" : {
55  "name" : "GenJetAK7",
56  "doc" : "AK9 jets",
57  },
58  "ak9gen" : {
59  "name" : "GenJetAK9",
60  "doc" : "AK9 jets",
61  },
62  "ak10gen" : {
63  "name" : "GenJetAK10",
64  "doc" : "AK10 jets",
65  },
66 }
67 #
68 # By default, these collections are saved in NanoAODs:
69 # - ak4pfchs (Jet in NanoAOD)
70 # - ak8pfpuppi (FatJet in NanoAOD)
71 # By default, the ak4pfchs (Jet) and ak8pfpuppi (FatJet) collections
72 # are saved in NanoAODs.
73 # Below is a list of recojets that we can save in NanoAOD. Set "enabled"
74 # to true if you want to store the recojet collection.
75 #
76 config_recojets = [
77  {
78  "jet" : "ak4pfpuppi",
79  "enabled" : True,
80  "inputCollection" : "slimmedJetsPuppi", #Exist in MiniAOD
81  "genJetsCollection": "slimmedGenJets",
82  },
83  {
84  "jet" : "ak4calo",
85  "enabled" : True,
86  "inputCollection" : "slimmedCaloJets", #Exist in MiniAOD
87  "genJetsCollection": "slimmedGenJets",
88  },
89  {
90  "jet" : "ak4pf",
91  "enabled" : True,
92  "inputCollection" : "",
93  "genJetsCollection": "slimmedGenJets",
94  },
95  {
96  "jet" : "ak8pf",
97  "enabled" : True,
98  "inputCollection" : "",
99  "genJetsCollection": "slimmedGenJetsAK8",
100  },
101  {
102  "jet" : "ak8pfchs",
103  "enabled" : True,
104  "inputCollection" : "",
105  "genJetsCollection": "slimmedGenJetsAK8",
106  },
107  {
108  "jet" : "ak6pf",
109  "enabled" : False,
110  "inputCollection" : "",
111  "genJetsCollection": "AK6GenJetsNoNu",
112  },
113  {
114  "jet" : "ak10pf",
115  "enabled" : False,
116  "inputCollection" : "",
117  "genJetsCollection": "AK10GenJetsNoNu",
118  },
119 ]
120 config_recojets = list(filter(lambda k: k['enabled'], config_recojets))
121 #
122 # RecoJets info in NanoAOD
123 #
124 nanoInfo_recojets = {
125  "ak4pfpuppi" : {
126  "name" : "JetPUPPI",
127  "doc" : "AK4PFPUPPI jets",
128  },
129  "ak4calo" : {
130  "name": "JetCalo",
131  "doc" : "AK4Calo jets",
132  },
133  "ak4pf" : {
134  "name": "JetPF",
135  "doc" : "AK4PF jets",
136  },
137  "ak8pf" : {
138  "name": "FatJetPF",
139  "doc" : "AK8PF jets",
140  },
141  "ak8pfchs" : {
142  "name" : "FatJetCHS",
143  "doc" : "AK8PFCHS jets",
144  },
145  "ak6pf" : {
146  "name": "JetAK6PF",
147  "doc" : "AK6PF jets",
148  },
149  "ak10pf" : {
150  "name" : "FatJetAK10PF",
151  "doc" : "AK10PF jets",
152  },
153 }
154 
155 #
156 # The reco jet names already exists
157 # in NanoAOD.
158 #
159 recojetNameInNano = [ "Jet", "FatJet" ]
160 #
161 # The gen jet names already exists
162 # in NanoAOD.
163 #
164 genjetNameInNano = [ "GenJet", "GenJetAK8" ]
165 
166 JETVARS = cms.PSet(P4Vars,
167  HFHEF = Var("HFHadronEnergyFraction()", float, doc = "energy fraction in forward hadronic calorimeter", precision = 6),
168  HFEMEF = Var("HFEMEnergyFraction()", float, doc = "energy fraction in forward EM calorimeter", precision = 6),
169  area = jetTable.variables.area,
170  chHEF = jetTable.variables.chHEF,
171  neHEF = jetTable.variables.neHEF,
172  chEmEF = jetTable.variables.chEmEF,
173  neEmEF = jetTable.variables.neEmEF,
174  muEF = jetTable.variables.muEF,
175  rawFactor = jetTable.variables.rawFactor,
176  jetId = jetTable.variables.jetId,
177  jercCHPUF = jetTable.variables.jercCHPUF,
178  jercCHF = jetTable.variables.jercCHF,
179 )
180 
181 for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
182  modifier.toModify(JETVARS,
183  jetId = Var("userInt('tightId')*2+userInt('looseId')", int, doc = "Jet ID flags bit1 is loose, bit2 is tight")
184  )
185 
186 #============================================
187 #
188 # TableGenJetAdder
189 #
190 #============================================
192  """
193  Tool to store gen jet variables in NanoAOD for customized
194  gen jet collections.
195  """
196  def __init__(self):
197  self.main = []
198 
199  def getSequence(self, proc):
200  """
201  Tool to add
202  """
203  tasks = self.main
204 
205  resultSequence = cms.Sequence()
206  for idx, task in enumerate(tasks):
207  if idx == 0:
208  resultSequence = cms.Sequence(getattr(proc, task))
209  else:
210  resultSequence.insert(idx, getattr(proc, task))
211  return resultSequence
212 
213  def addTable(self, proc, genJetInfo):
214  currentTasks = []
215 
216  print("custom_jme_cff::TableGenJetAdder::addTable: Adding Table for GenJet Collection: {}".format(genJetInfo.jet))
217 
218  name = nanoInfo_genjets[genJetInfo.jet]["name"]
219  doc = nanoInfo_genjets[genJetInfo.jet]["doc"]
220 
221  if name in genjetNameInNano:
222  raise RuntimeError('GenJet collection name (%s) taken in NanoAOD for %s' %(name, genJetInfo.jet))
223 
224  #
225  # GenJet Table
226  #
227  table = "{}Table".format(genJetInfo.jetTagName)
228  genJetsCollection = "{}{}{}".format(genJetInfo.jetAlgo.upper(), genJetInfo.jetSize, 'GenJetsNoNu')
229  setattr(proc, table, cms.EDProducer("SimpleCandidateFlatTableProducer",
230  src = cms.InputTag(genJetsCollection),
231  cut = cms.string(""),
232  name = cms.string(name),
233  doc = cms.string('{} (generator level)'.format(doc)),
234  singleton = cms.bool(False),
235  extension = cms.bool(False),
236  variables = cms.PSet(P4Vars,
237  area = jetTable.variables.area,
238  ),
239  )
240  )
241  currentTasks.append(table)
242 
243  #
244  # GenJet Flavour Table
245  #
246  genFlavour = "{}Flavour".format(genJetInfo.jetTagName)
247  genFlavourTable = "{}Table".format(genFlavour)
248  if genFlavourTable in self.main:
249  raise ValueError("Step '%s' already implemented" % genFlavourTable)
250  setattr(proc, genFlavourTable, cms.EDProducer("GenJetFlavourTableProducer",
251  name = cms.string(name),
252  src = cms.InputTag(genJetsCollection),
253  cut = cms.string(""),
254  deltaR = cms.double(0.1),
255  jetFlavourInfos = cms.InputTag(genFlavour),
256  )
257  )
258  currentTasks.append(genFlavourTable)
259  self.main.extend(currentTasks)
260 
261 #============================================
262 #
263 # TableRecoJetAdder
264 #
265 #============================================
267  """
268  Tool to store reco jet variables in NanoAOD for customized
269  reco jet collections.
270  """
271  def __init__(self):
272  self.main = []
273 
274  def getSequence(self, proc):
275  tasks = self.main
276 
277  resultSequence = cms.Sequence()
278  for idx, task in enumerate(tasks):
279  if idx == 0:
280  resultSequence = cms.Sequence(getattr(proc, task))
281  else:
282  resultSequence.insert(idx, getattr(proc, task))
283  return resultSequence
284 
285  def addTable(self, proc, recoJetInfo):
286 
287  currentTasks = []
288 
289  print("custom_jme_cff::TableRecoJetAdder::addTable: Adding Table for Reco Jet Collection: {}".format(recoJetInfo.jet))
290 
291  name = nanoInfo_recojets[recoJetInfo.jet]["name"]
292  doc = nanoInfo_recojets[recoJetInfo.jet]["doc"]
293 
294  if name in recojetNameInNano:
295  raise RuntimeError('RecoJet collection name (%s) taken in NanoAOD for %s' %(name, recoJetInfo.jet))
296 
297  table = "{}Table".format(recoJetInfo.jetTagName)
298  if recoJetInfo.skipUserData:
299  if recoJetInfo.doCalo:
300  tableContents = cms.PSet(
301  P4Vars,
302  area = jetTable.variables.area,
303  rawFactor = jetTable.variables.rawFactor,
304  emf = Var("emEnergyFraction()", float, doc = "electromagnetic energy fraction", precision = 10),
305  )
306  else:
307  tableContents = cms.PSet(
308  P4Vars,
309  area = jetTable.variables.area,
310  rawFactor = jetTable.variables.rawFactor,
311  )
312  else:
313  tableContents = JETVARS.clone()
314 
315  updatedJets = "updatedJets{}".format(recoJetInfo.jetTagName)
316  setattr(proc, table, cms.EDProducer("SimpleCandidateFlatTableProducer",
317  src = cms.InputTag(updatedJets),
318  cut = cms.string(""),
319  name = cms.string(name),
320  doc = cms.string(doc),
321  singleton = cms.bool(False),
322  extension = cms.bool(False),
323  variables = tableContents,
324  )
325  )
326  currentTasks.append(table)
327 
328  tightJetIdLepVeto = "tightJetIdLepVeto{}".format(recoJetInfo.jetTagName)
329  if not recoJetInfo.skipUserData:
330  altTasks = copy.deepcopy(currentTasks)
331  for idx, task in enumerate(altTasks):
332  if task == tightJetIdLepVeto:
333  altTasks[idx] = looseJetId
334  for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
335  modifier.toReplaceWith(currentTasks, altTasks)
336  self.main.extend(currentTasks)
337 
338 
339 def PrepJMECustomNanoAOD(process):
340  #
341  # Additional variables to AK4GenJets
342  #
343  process.genJetTable.variables.area = JETVARS.area
344  #
345  # Additional variables to AK8GenJets
346  #
347  process.genJetAK8Table.variables.area = JETVARS.area
348  #
349  # Additional variables for AK4PFCHS
350  #
351  process.jetTable.variables.HFHEF = JETVARS.HFHEF
352  process.jetTable.variables.HFEMEF = JETVARS.HFEMEF
353  #
354  # Additional variables to AK8PFPUPPI
355  #
356  # These variables are not stored for AK8PFCHS (slimmedJetsAK8)
357  # in MiniAOD if their pt < 170 GeV. Hence the conditional fill.
358  #
359  process.fatJetTable.variables.chHEF = Var("?isPFJet()?chargedHadronEnergyFraction():-1", float, doc="charged Hadron Energy Fraction", precision = 6)
360  process.fatJetTable.variables.neHEF = Var("?isPFJet()?neutralHadronEnergyFraction():-1", float, doc="neutral Hadron Energy Fraction", precision = 6)
361  process.fatJetTable.variables.chEmEF = Var("?isPFJet()?chargedEmEnergyFraction():-1", float, doc="charged Electromagnetic Energy Fraction", precision = 6)
362  process.fatJetTable.variables.neEmEF = Var("?isPFJet()?neutralEmEnergyFraction():-1", float, doc="neutral Electromagnetic Energy Fraction", precision = 6)
363  process.fatJetTable.variables.muEF = Var("?isPFJet()?muonEnergyFraction():-1", float, doc="muon Energy Fraction", precision = 6)
364  process.fatJetTable.variables.HFHEF = Var("?isPFJet()?HFHadronEnergyFraction():-1", float, doc="energy fraction in forward hadronic calorimeter", precision = 6)
365  process.fatJetTable.variables.HFEMEF = Var("?isPFJet()?HFEMEnergyFraction():-1", float, doc="energy fraction in forward EM calorimeter", precision = 6)
366  #
367  #
368  #
369  process.jercVarsFatJet = process.jercVars.clone(
370  srcJet = "updatedJetsAK8",
371  maxDR = 0.8,
372  )
373  process.jetSequence.insert(process.jetSequence.index(process.updatedJetsAK8WithUserData), process.jercVarsFatJet)
374 
375  process.updatedJetsAK8WithUserData.userFloats.jercCHPUF = cms.InputTag(
376  "%s:chargedHadronPUEnergyFraction" % process.jercVarsFatJet.label()
377  )
378  process.updatedJetsAK8WithUserData.userFloats.jercCHF = cms.InputTag(
379  "%s:chargedHadronCHSEnergyFraction" % process.jercVarsFatJet.label()
380  )
381  process.fatJetTable.variables.jercCHPUF = JETVARS.jercCHPUF
382  process.fatJetTable.variables.jercCHF = JETVARS.jercCHF
383  #
384  # Remove any pT cuts.
385  #
386  process.finalJets.cut = "" # 15 -> 10
387  process.finalJetsAK8.cut = "" # 170 -> 170
388  process.genJetTable.cut = "" # 10 -> 8
389  process.genJetFlavourTable.cut = "" # 10 -> 8
390  process.genJetAK8Table.cut = "" # 100 -> 80
391  process.genJetAK8FlavourTable.cut = "" # 100 -> 80
392 
393  ######################################################################################################################
394 
395  #
396  # Add GenJets to NanoAOD
397  #
398  genJA = GenJetAdder()
399  tableGenJA = TableGenJetAdder()
400 
401  for jetConfig in config_genjets:
402  cfg = { k : v for k, v in jetConfig.items() if k != "enabled" }
403  genJetInfo = genJA.addGenJetCollection(process, **cfg)
404  tableGenJA.addTable(process, genJetInfo)
405 
406  process.nanoSequenceMC += genJA.getSequence(process)
407  process.nanoSequenceMC += tableGenJA.getSequence(process)
408 
409  #
410  # Add RecoJets to NanoAOD
411  #
412  recoJA = RecoJetAdder()
413  tableRecoJA = TableRecoJetAdder()
414 
415  for jetConfig in config_recojets:
416  cfg = { k : v for k, v in jetConfig.items() if k != "enabled" }
417  recoJetInfo = recoJA.addRecoJetCollection(process, **cfg)
418  tableRecoJA.addTable(process, recoJetInfo)
419 
420  process.nanoSequenceMC += recoJA.getSequence(process)
421  process.nanoSequenceMC += tableRecoJA.getSequence(process)
422 
def addTable(self, proc, recoJetInfo)
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 addTable(self, proc, genJetInfo)
def PrepJMECustomNanoAOD(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