CMS 3D CMS Logo

jetCollectionTools.py
Go to the documentation of this file.
1 import FWCore.ParameterSet.Config as cms
2 
4 
5 from CommonTools.ParticleFlow.pfCHS_cff import pfCHS
6 
7 from CommonTools.PileupAlgos.Puppi_cff import puppi
8 from CommonTools.PileupAlgos.softKiller_cfi import softKiller
9 
10 from RecoJets.JetProducers.PFJetParameters_cfi import PFJetParameters
11 from RecoJets.JetProducers.GenJetParameters_cfi import GenJetParameters
12 from RecoJets.JetProducers.GenJetParameters_cfi import GenJetParameters
13 from RecoJets.JetProducers.AnomalousCellParameters_cfi import AnomalousCellParameters
14 
15 from RecoJets.JetProducers.ak4GenJets_cfi import ak4GenJets
16 from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets, ak4PFJetsCHS, ak4PFJetsPuppi, ak4PFJetsSK, ak4PFJetsCS
17 from RecoJets.JetProducers.ak4CaloJets_cfi import ak4CaloJets
18 
20 from PhysicsTools.PatAlgos.recoLayer0.jetCorrFactors_cfi import patJetCorrFactors
21 from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetFlavourAssociation
22 
23 from PhysicsTools.PatAlgos.tools.jetTools import supportedJetAlgos, addJetCollection, updateJetCollection
24 from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask, addToProcessAndTask
25 
26 import re
27 
28 #============================================
29 #
30 # GenJetInfo
31 #
32 #============================================
34  """
35  Class to hold information of a genjet collection
36  """
37  def __init__(self, jet, inputCollection):
38  self.jet = jet
39  self.jetLower = jet.lower()
40  self.jetUpper = jet.upper()
41  self.jetTagName = self.jetUpper
42  self.inputCollection = inputCollection
43  algoKey = 'algo'
44  sizeKey = 'size'
45  recoKey = 'reco'
46  jetRegex = re.compile(
47  r'(?P<{algo}>({algoList}))(?P<{size}>[0-9]+)gen'.format(
48  algo = algoKey,
49  algoList = '|'.join(supportedJetAlgos.keys()),
50  size = sizeKey,
51  )
52  )
53  jetMatch = jetRegex.match(jet.lower())
54  if not jetMatch:
55  raise RuntimeError('Invalid jet collection: %s' % jet)
56  self.jetAlgo = jetMatch.group(algoKey)
57  self.jetSize = jetMatch.group(sizeKey)
58  self.jetSizeNr = float(self.jetSize) / 10.
59 
60 #============================================
61 #
62 # GenJetAdder
63 #
64 #============================================
66  """
67  Tool to schedule modules for building a genjet collection with input MiniAODs
68  """
69  def __init__(self):
70  self.prerequisites = []
71  self.main = []
72  self.gpLabel = "prunedGenParticles"
73 
74  def addProcessAndTask(self, proc, label, module):
75  task = getPatAlgosToolsTask(proc)
76  addToProcessAndTask(label, module, proc, task)
77 
78  def addGenJetCollection(self,
79  proc,
80  jet,
81  inputCollection = "",
82  minPtFastjet = None,
83  ):
84  print("jetCollectionTools::GenJetAdder::addGenJetCollection: Adding Gen Jet Collection: {}".format(jet))
85 
86  #
87  # Decide which genJet collection we are dealing with
88  #
89  genJetInfo = GenJetInfo(jet,inputCollection)
90  jetLower = genJetInfo.jetLower
91  jetUpper = genJetInfo.jetUpper
92 
93  #=======================================================
94  #
95  # If genJet collection in MiniAOD is not
96  # specified, build the genjet collection.
97  #
98  #========================================================
99  if not inputCollection:
100  print("jetCollectionTools::GenJetAdder::addGenJetCollection: inputCollection not specified. Building genjet collection now")
101  #
102  # Setup GenParticles
103  #
104  packedGenPartNoNu = "packedGenParticlesForJetsNoNu"
105  if packedGenPartNoNu not in self.prerequisites:
106  self.addProcessAndTask(proc, packedGenPartNoNu, cms.EDFilter("CandPtrSelector",
107  src = cms.InputTag("packedGenParticles"),
108  cut = cms.string("abs(pdgId) != 12 && abs(pdgId) != 14 && abs(pdgId) != 16"),
109  )
110  )
111  self.prerequisites.append(packedGenPartNoNu)
112  #
113  # Create the GenJet collection
114  #
115  genJetsCollection = "{}{}{}".format(genJetInfo.jetAlgo.upper(), genJetInfo.jetSize, 'GenJetsNoNu')
116  self.addProcessAndTask(proc, genJetsCollection, ak4GenJets.clone(
117  src = packedGenPartNoNu,
118  jetAlgorithm = cms.string(supportedJetAlgos[genJetInfo.jetAlgo]),
119  rParam = cms.double(genJetInfo.jetSizeNr),
120  )
121  )
122  #
123  # Set minimum pt threshold of gen jets to be saved after fastjet clustering
124  #
125  if minPtFastjet != None:
126  getattr(proc, genJetsCollection).jetPtMin = minPtFastjet
127  self.prerequisites.append(genJetsCollection)
128 
129  return genJetInfo
130 #============================================
131 #
132 # RecoJetInfo
133 #
134 #============================================
136  """
137  Class to hold information of a recojet collection
138  """
139  def __init__(self, jet, inputCollection):
140  self.jet = jet
141  self.jetLower = jet.lower()
142  self.jetUpper = jet.upper()
143  self.jetTagName = self.jetUpper
144  self.inputCollection = inputCollection
145  algoKey = 'algo'
146  sizeKey = 'size'
147  recoKey = 'reco'
148  puMethodKey = 'puMethod'
149  jetRegex = re.compile(
150  r'(?P<{algo}>({algoList}))(?P<{size}>[0-9]+)(?P<{reco}>(pf|calo))(?P<{puMethod}>(chs|puppi|sk|cs|))'.format(
151  algo = algoKey,
152  algoList = '|'.join(supportedJetAlgos.keys()),
153  size = sizeKey,
154  reco = recoKey,
155  puMethod = puMethodKey,
156  )
157  )
158  jetMatch = jetRegex.match(jet.lower())
159  if not jetMatch:
160  raise RuntimeError('Invalid jet collection: %s' % jet)
161 
162  self.jetAlgo = jetMatch.group(algoKey)
163  self.jetSize = jetMatch.group(sizeKey)
164  self.jetReco = jetMatch.group(recoKey)
165  self.jetPUMethod = jetMatch.group(puMethodKey)
166 
167  self.jetSizeNr = float(self.jetSize) / 10.
168 
169  self.doCalo = self.jetReco == "calo"
170  self.doPF = self.jetReco == "pf"
171 
172  self.doCS = self.jetPUMethod == "cs"
173  self.skipUserData = self.doCalo or (self.jetPUMethod in [ "puppi", "sk" ] and inputCollection == "")
174 
175  self.jetCorrPayload = "{}{}{}".format(
176  self.jetAlgo.upper(), self.jetSize, "Calo" if self.doCalo else self.jetReco.upper()
177  )
178 
179  if self.jetPUMethod == "puppi":
180  self.jetCorrPayload += "Puppi"
181  elif self.jetPUMethod in [ "cs", "sk" ]:
182  self.jetCorrPayload += "chs"
183  else:
184  self.jetCorrPayload += self.jetPUMethod.lower()
185 
187 
188 #============================================
189 #
190 # RecoJetAdder
191 #
192 #============================================
194  """
195  Tool to schedule modules for building a patJet collection from MiniAODs
196  """
197  def __init__(self,runOnMC=True):
198  self.prerequisites = []
199  self.main = []
200  self.pfLabel = "packedPFCandidates"
201  self.pvLabel = "offlineSlimmedPrimaryVertices"
202  self.svLabel = "slimmedSecondaryVertices"
203  self.muLabel = "slimmedMuons"
204  self.elLabel = "slimmedElectrons"
205  self.gpLabel = "prunedGenParticles"
206  self.runOnMC = runOnMC
207  self.patJetsInMiniAOD = ["slimmedJets", "slimmedJetsAK8", "slimmedJetsPuppi", "slimmedCaloJets"]
208 
209  def addProcessAndTask(self, proc, label, module):
210  task = getPatAlgosToolsTask(proc)
211  addToProcessAndTask(label, module, proc, task)
212 
213  def addRecoJetCollection(self,
214  proc,
215  jet,
216  inputCollection = "",
217  minPtFastjet = None,
218  genJetsCollection = "",
219  bTagDiscriminators = ["None"],
220  JETCorrLevels = ["L1FastJet", "L2Relative", "L3Absolute", "L2L3Residual"],
221  ):
222  print("jetCollectionTools::RecoJetAdder::addRecoJetCollection: Adding Reco Jet Collection: {}".format(jet))
223 
224  currentTasks = []
225 
226  if inputCollection and inputCollection not in self.patJetsInMiniAOD:
227  raise RuntimeError("Invalid input collection: %s" % inputCollection)
228 
229  #=======================================================
230  #
231  # Figure out which jet collection we're dealing with
232  #
233  #=======================================================
234  recoJetInfo = RecoJetInfo(jet, inputCollection)
235  jetLower = recoJetInfo.jetLower
236  jetUpper = recoJetInfo.jetUpper
237  tagName = recoJetInfo.jetTagName
238 
239  if inputCollection == "slimmedJets":
240  assert(jetLower == "ak4pfchs")
241  elif inputCollection == "slimmedJetsAK8":
242  assert(jetLower == "ak8pfpuppi")
243  elif inputCollection == "slimmedJetsPuppi":
244  assert(jetLower == "ak4pfpuppi")
245  elif inputCollection == "slimmedCaloJets":
246  assert(jetLower == "ak4calo")
247 
248  #=======================================================
249  #
250  # If the patJet collection in MiniAOD is not specified,
251  # we have to build the patJet collection from scratch.
252  #
253  #========================================================
254  if not inputCollection or recoJetInfo.doCalo:
255  print("jetCollectionTools::RecoJetAdder::addRecoJetCollection: inputCollection not specified. Building recojet collection now")
256 
257  #=======================================================
258  #
259  # Prepare the inputs to jet clustering
260  #
261  #========================================================
262  #
263  # Specify PF candidates
264  #
265  pfCand = self.pfLabel
266  #
267  # Setup PU method for PF candidates
268  #
269  if recoJetInfo.jetPUMethod not in [ "", "cs" ]:
270  pfCand += recoJetInfo.jetPUMethod
271 
272 
273  #
274  # Setup modules to perform PU mitigation for
275  # PF candidates
276  #
277  if pfCand not in self.prerequisites:
278  #
279  # Skip if no PU Method or CS specified
280  #
281  if recoJetInfo.jetPUMethod in [ "", "cs" ]:
282  pass
283  #
284  # CHS
285  #
286  elif recoJetInfo.jetPUMethod == "chs":
287  self.addProcessAndTask(proc, pfCand, pfCHS.clone(
288  src = self.pfLabel
289  )
290  )
291  self.prerequisites.append(pfCand)
292  #
293  # PUPPI
294  #
295  elif recoJetInfo.jetPUMethod == "puppi":
296  self.addProcessAndTask(proc, pfCand, puppi.clone(
297  candName = self.pfLabel,
298  vertexName = self.pvLabel,
299  clonePackedCands = True,
300  useExistingWeights = True,
301  )
302  )
303  self.prerequisites.append(pfCand)
304  #
305  # Softkiller
306  #
307  elif recoJetInfo.jetPUMethod == "sk":
308  self.addProcessAndTask(proc, pfCand, softKiller.clone(
309  PFCandidates = self.pfLabel,
310  rParam = recoJetInfo.jetSizeNr,
311  )
312  )
313  self.prerequisites.append(pfCand)
314  else:
315  raise RuntimeError("Currently unsupported PU method: '%s'" % recoJetInfo.jetPUMethod)
316 
317  #============================================
318  #
319  # Create the recojet collection
320  #
321  #============================================
322  if not recoJetInfo.doCalo:
323  jetCollection = '{}Collection'.format(jetUpper)
324 
325  if jetCollection in self.main:
326  raise ValueError("Step '%s' already implemented" % jetCollection)
327  #
328  # Cluster new jet
329  #
330  if recoJetInfo.jetPUMethod == "chs":
331  self.addProcessAndTask(proc, jetCollection, ak4PFJetsCHS.clone(
332  src = pfCand,
333  )
334  )
335  elif recoJetInfo.jetPUMethod == "puppi":
336  self.addProcessAndTask(proc, jetCollection, ak4PFJetsPuppi.clone(
337  src = self.pfLabel,
338  srcWeights = pfCand
339  )
340  )
341  elif recoJetInfo.jetPUMethod == "sk":
342  self.addProcessAndTask(proc, pfCand, ak4PFJetsSK.clone(
343  src = pfCand,
344  )
345  )
346  elif recoJetInfo.jetPUMethod == "cs":
347  self.addProcessAndTask(proc, jetCollection, ak4PFJetsCS.clone(
348  src = pfCand,
349  )
350  )
351  else:
352  self.addProcessAndTask(proc, jetCollection, ak4PFJets.clone(
353  src = pfCand,
354  )
355  )
356  getattr(proc, jetCollection).jetAlgorithm = supportedJetAlgos[recoJetInfo.jetAlgo]
357  getattr(proc, jetCollection).rParam = recoJetInfo.jetSizeNr
358  #
359  # Set minimum pt threshold of reco jets to be saved after fastjet clustering
360  #
361  if minPtFastjet != None:
362  getattr(proc, jetCollection).jetPtMin = minPtFastjet
363  currentTasks.append(jetCollection)
364  else:
365  jetCollection = inputCollection
366 
367 
368  #=============================================
369  #
370  # Make patJet collection
371  #
372  #=============================================
373  #
374  # Jet correction
375  #
376  if recoJetInfo.jetPUMethod == "puppi":
377  jetCorrLabel = "Puppi"
378  elif recoJetInfo.jetPUMethod in [ "cs", "sk" ]:
379  jetCorrLabel = "chs"
380  else:
381  jetCorrLabel = recoJetInfo.jetPUMethod
382 
383  jetCorrections = (
384  "{}{}{}{}".format(
385  recoJetInfo.jetAlgo.upper(),
386  recoJetInfo.jetSize,
387  "Calo" if recoJetInfo.doCalo else recoJetInfo.jetReco.upper(),
388  jetCorrLabel
389  ),
390  JETCorrLevels,
391  "None",
392  )
393 
394  postfix = "Recluster" if inputCollection == "" else ""
395  addJetCollection(
396  proc,
397  labelName = jetUpper,
398  postfix = postfix,
399  jetSource = cms.InputTag(jetCollection),
400  algo = recoJetInfo.jetAlgo,
401  rParam = recoJetInfo.jetSizeNr,
402  pvSource = cms.InputTag(self.pvLabel),
403  pfCandidates = cms.InputTag(self.pfLabel),
404  svSource = cms.InputTag(self.svLabel),
405  muSource = cms.InputTag(self.muLabel),
406  elSource = cms.InputTag(self.elLabel),
407  genJetCollection = cms.InputTag(genJetsCollection),
408  genParticles = cms.InputTag(self.gpLabel),
409  jetCorrections = jetCorrections,
410  )
411 
412  #
413  # Need to set this explicitly for PUPPI jets
414  #
415  if recoJetInfo.jetPUMethod == "puppi":
416  getattr(proc, "patJetFlavourAssociation{}{}".format(jetUpper,postfix)).weights = cms.InputTag(pfCand)
417 
418  getJetMCFlavour = not recoJetInfo.doCalo and recoJetInfo.jetPUMethod != "cs"
419  if not self.runOnMC: #Remove modules for Gen-level object matching
420  delattr(proc, 'patJetGenJetMatch{}{}'.format(jetUpper,postfix))
421  delattr(proc, 'patJetPartonMatch{}{}'.format(jetUpper,postfix))
422  getJetMCFlavour = False
423  setattr(getattr(proc, "patJets{}{}".format(jetUpper,postfix)), "getJetMCFlavour", cms.bool(getJetMCFlavour))
424 
425  selectedPatJets = "selectedPatJets{}{}".format(jetUpper,postfix)
426  #=============================================
427  #
428  # Update the patJet collection.
429  # This is where we setup
430  # - JEC
431  # - b-tagging discriminators
432  #
433  #=============================================
434  updateJetCollection(
435  proc,
436  labelName = jetUpper,
437  postfix = "Final",
438  jetSource = cms.InputTag(selectedPatJets),
439  jetCorrections = jetCorrections,
440  btagDiscriminators = bTagDiscriminators,
441  )
442 
443  recoJetInfo.patJetFinalCollection = "selectedUpdatedPatJets{}{}".format(jetUpper,"Final")
444  else:
445  recoJetInfo.patJetFinalCollection = inputCollection
446 
447  self.main.extend(currentTasks)
448 
449  return recoJetInfo
def __init__(self, runOnMC=True)
def addGenJetCollection(self, proc, jet, inputCollection="", minPtFastjet=None)
def addToProcessAndTask(label, module, process, task)
Definition: helpers.py:28
def addProcessAndTask(self, proc, label, module)
assert(be >=bs)
User floats producers, selectors ##########################.
def __init__(self, jet, inputCollection)
def __init__(self, jet, inputCollection)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
def addRecoJetCollection(self, proc, jet, inputCollection="", minPtFastjet=None, genJetsCollection="", bTagDiscriminators=["None"], JETCorrLevels=["L1FastJet", L2Relative, L3Absolute, L2L3Residual)
def addProcessAndTask(self, proc, label, module)
def getPatAlgosToolsTask(process)
Definition: helpers.py:13