CMS 3D CMS Logo

JetAnalyzer.py
Go to the documentation of this file.
1 from __future__ import print_function
2 import math, os
3 from PhysicsTools.Heppy.analyzers.core.Analyzer import Analyzer
4 from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
5 from PhysicsTools.Heppy.physicsobjects.PhysicsObjects import Jet
6 from PhysicsTools.HeppyCore.utils.deltar import deltaR2, deltaPhi, matchObjectCollection, matchObjectCollection2, bestMatch,matchObjectCollection3
7 from PhysicsTools.Heppy.physicsutils.JetReCalibrator import JetReCalibrator
8 import PhysicsTools.HeppyCore.framework.config as cfg
9 
10 from PhysicsTools.Heppy.physicsutils.QGLikelihoodCalculator import QGLikelihoodCalculator
11 
12 import six
13 import copy
14 def cleanNearestJetOnly(jets,leptons,deltaR):
15  dr2 = deltaR**2
16  good = [ True for j in jets ]
17  for l in leptons:
18  ibest, d2m = -1, dr2
19  for i,j in enumerate(jets):
20  d2i = deltaR2(l.eta(),l.phi(), j.eta(),j.phi())
21  if d2i < d2m:
22  ibest, d2m = i, d2i
23  if ibest != -1: good[ibest] = False
24  return [ j for (i,j) in enumerate(jets) if good[i] == True ]
25 
26 def cleanJetsAndLeptons(jets,leptons,deltaR,arbitration):
27  dr2 = deltaR**2
28  goodjet = [ True for j in jets ]
29  goodlep = [ True for l in leptons ]
30  for il, l in enumerate(leptons):
31  ibest, d2m = -1, dr2
32  for i,j in enumerate(jets):
33  d2i = deltaR2(l.eta(),l.phi(), j.eta(),j.phi())
34  if d2i < dr2:
35  choice = arbitration(j,l)
36  if choice == j:
37  # if the two match, and we prefer the jet, then drop the lepton and be done
38  goodlep[il] = False
39  break
40  elif choice == (j,l) or choice == (l,j):
41  # asked to keep both, so we don't consider this match
42  continue
43  if d2i < d2m:
44  ibest, d2m = i, d2i
45  # this lepton has been killed by a jet, then we clean the jet that best matches it
46  if not goodlep[il]: continue
47  if ibest != -1: goodjet[ibest] = False
48  return ( [ j for (i ,j) in enumerate(jets) if goodjet[i ] == True ],
49  [ l for (il,l) in enumerate(leptons) if goodlep[il] == True ] )
50 
51 
52 
53 def shiftJERfactor(JERShift, aeta):
54  factor = 1.079 + JERShift*0.026
55  if aeta > 3.2: factor = 1.056 + JERShift * 0.191
56  elif aeta > 2.8: factor = 1.395 + JERShift * 0.063
57  elif aeta > 2.3: factor = 1.254 + JERShift * 0.062
58  elif aeta > 1.7: factor = 1.208 + JERShift * 0.046
59  elif aeta > 1.1: factor = 1.121 + JERShift * 0.029
60  elif aeta > 0.5: factor = 1.099 + JERShift * 0.028
61  return factor
62 
63 
64 
65 
66 
67 class JetAnalyzer( Analyzer ):
68  """Taken from RootTools.JetAnalyzer, simplified, modified, added corrections """
69  def __init__(self, cfg_ana, cfg_comp, looperName):
70  super(JetAnalyzer,self).__init__(cfg_ana, cfg_comp, looperName)
71  mcGT = cfg_ana.mcGT if hasattr(cfg_ana,'mcGT') else "PHYS14_25_V2"
72  dataGT = cfg_ana.dataGT if hasattr(cfg_ana,'dataGT') else "GR_70_V2_AN1"
73  self.shiftJEC = self.cfg_ana.shiftJEC if hasattr(self.cfg_ana, 'shiftJEC') else 0
74  self.recalibrateJets = self.cfg_ana.recalibrateJets
75  self.addJECShifts = self.cfg_ana.addJECShifts if hasattr(self.cfg_ana, 'addJECShifts') else 0
76  if self.recalibrateJets == "MC" : self.recalibrateJets = self.cfg_comp.isMC
77  elif self.recalibrateJets == "Data": self.recalibrateJets = not self.cfg_comp.isMC
78  elif self.recalibrateJets not in [True,False]: raise RuntimeError("recalibrateJets must be any of { True, False, 'MC', 'Data' }, while it is %r " % self.recalibrateJets)
79 
80  calculateSeparateCorrections = getattr(cfg_ana,"calculateSeparateCorrections", False);
81  calculateType1METCorrection = getattr(cfg_ana,"calculateType1METCorrection", False);
82  self.doJEC = self.recalibrateJets or (self.shiftJEC != 0) or self.addJECShifts or calculateSeparateCorrections or calculateType1METCorrection
83  if self.doJEC:
84  doResidual = getattr(cfg_ana, 'applyL2L3Residual', 'Data')
85  if doResidual == "MC": doResidual = self.cfg_comp.isMC
86  elif doResidual == "Data": doResidual = not self.cfg_comp.isMC
87  elif doResidual not in [True,False]: raise RuntimeError("If specified, applyL2L3Residual must be any of { True, False, 'MC', 'Data'(default)}")
88  GT = getattr(cfg_comp, 'jecGT', mcGT if self.cfg_comp.isMC else dataGT)
89  # Now take care of the optional arguments
90  kwargs = { 'calculateSeparateCorrections':calculateSeparateCorrections,
91  'calculateType1METCorrection' :calculateType1METCorrection, }
92  if kwargs['calculateType1METCorrection']: kwargs['type1METParams'] = cfg_ana.type1METParams
93  # instantiate the jet re-calibrator
94  self.jetReCalibrator = JetReCalibrator(GT, cfg_ana.recalibrationType, doResidual, cfg_ana.jecPath, **kwargs)
95  self.doPuId = getattr(self.cfg_ana, 'doPuId', True)
96  self.jetLepDR = getattr(self.cfg_ana, 'jetLepDR', 0.4)
97  self.jetLepArbitration = getattr(self.cfg_ana, 'jetLepArbitration', lambda jet,lepton: lepton)
98  self.lepPtMin = getattr(self.cfg_ana, 'minLepPt', -1)
99  self.lepSelCut = getattr(self.cfg_ana, 'lepSelCut', lambda lep : True)
100  self.jetGammaDR = getattr(self.cfg_ana, 'jetGammaDR', 0.4)
101  self.jetGammaLepDR = getattr(self.cfg_ana, 'jetGammaLepDR', 0.4)
102  self.cleanFromLepAndGammaSimultaneously = getattr(self.cfg_ana, 'cleanFromLepAndGammaSimultaneously', False)
104  if hasattr(self.cfg_ana, 'jetGammaLepDR'):
105  self.jetGammaLepDR = self.jetGammaLepDR
106  elif (self.jetGammaDR == self.jetLepDR):
107  self.jetGammaLepDR = self.jetGammaDR
108  else:
109  raise RuntimeError("DR for simultaneous cleaning of jets from leptons and photons is not defined, and dR(gamma, jet)!=dR(lep, jet)")
110  if(self.cfg_ana.doQG):
111  qgdefname="{CMSSW_BASE}/src/PhysicsTools/Heppy/data/pdfQG_AK4chs_13TeV_v2b.root"
112  self.qglcalc = QGLikelihoodCalculator(getattr(self.cfg_ana,"QGpath",qgdefname).format(CMSSW_BASE= os.environ['CMSSW_BASE']))
113  if not hasattr(self.cfg_ana ,"collectionPostFix"):self.cfg_ana.collectionPostFix=""
114 
115  def declareHandles(self):
116  super(JetAnalyzer, self).declareHandles()
117  self.handles['jets'] = AutoHandle( self.cfg_ana.jetCol, 'std::vector<pat::Jet>' )
118  self.handles['genJet'] = AutoHandle( self.cfg_ana.genJetCol, 'vector<reco::GenJet>' )
119  self.shiftJER = self.cfg_ana.shiftJER if hasattr(self.cfg_ana, 'shiftJER') else 0
120  self.addJERShifts = self.cfg_ana.addJERShifts if hasattr(self.cfg_ana, 'addJERShifts') else 0
121  self.handles['rho'] = AutoHandle( self.cfg_ana.rho, 'double' )
122 
123  def beginLoop(self, setup):
124  super(JetAnalyzer,self).beginLoop(setup)
125 
126  def process(self, event):
127  self.readCollections( event.input )
128  rho = float(self.handles['rho'].product()[0])
129  self.rho = rho
130 
131  ## Read jets, if necessary recalibrate and shift MET
132  if self.cfg_ana.copyJetsByValue:
133  import ROOT
134  #from ROOT.heppy import JetUtils
135  allJets = map(lambda j:Jet(ROOT.heppy.JetUtils.copyJet(j)), self.handles['jets'].product()) #copy-by-value is safe if JetAnalyzer is ran more than once
136  else:
137  allJets = map(Jet, self.handles['jets'].product())
138 
139  #set dummy MC flavour for all jets in case we want to ntuplize discarded jets later
140  for jet in allJets:
141  jet.mcFlavour = 0
142 
143  self.deltaMetFromJEC = [0.,0.]
144  self.type1METCorr = [0.,0.,0.]
145 # print "before. rho",self.rho,self.cfg_ana.collectionPostFix,'allJets len ',len(allJets),'pt', [j.pt() for j in allJets]
146  if self.doJEC:
147  if not self.recalibrateJets: # check point that things won't change
148  jetsBefore = [ (j.pt(),j.eta(),j.phi(),j.rawFactor()) for j in allJets ]
149  self.jetReCalibrator.correctAll(allJets, rho, delta=self.shiftJEC,
150  addCorr=True, addShifts=self.addJECShifts,
151  metShift=self.deltaMetFromJEC, type1METCorr=self.type1METCorr )
152  if not self.recalibrateJets:
153  jetsAfter = [ (j.pt(),j.eta(),j.phi(),j.rawFactor()) for j in allJets ]
154  if len(jetsBefore) != len(jetsAfter):
155  print("ERROR: I had to recompute jet corrections, and they rejected some of the jets:\nold = %s\n new = %s\n" % (jetsBefore,jetsAfter))
156  else:
157  for (told, tnew) in zip(jetsBefore,jetsAfter):
158  if (deltaR2(told[1],told[2],tnew[1],tnew[2])) > 0.0001:
159  print("ERROR: I had to recompute jet corrections, and one jet direction moved: old = %s, new = %s\n" % (told, tnew))
160  elif abs(told[0]-tnew[0])/(told[0]+tnew[0]) > 0.5e-3 or abs(told[3]-tnew[3]) > 0.5e-3:
161  print("ERROR: I had to recompute jet corrections, and one jet pt or corr changed: old = %s, new = %s\n" % (told, tnew))
162  self.allJetsUsedForMET = allJets
163 # print "after. rho",self.rho,self.cfg_ana.collectionPostFix,'allJets len ',len(allJets),'pt', [j.pt() for j in allJets]
164 
165  if self.cfg_comp.isMC:
166  self.genJets = [ x for x in self.handles['genJet'].product() ]
167  if self.cfg_ana.do_mc_match:
168  for igj, gj in enumerate(self.genJets):
169  gj.index = igj
170 # self.matchJets(event, allJets)
171  self.matchJets(event, [ j for j in allJets if j.pt()>self.cfg_ana.jetPt ]) # To match only jets above chosen threshold
172  if getattr(self.cfg_ana, 'smearJets', False):
173  self.smearJets(event, allJets)
174 
175 
176 
177 
178  ##Sort Jets by pT
179  allJets.sort(key = lambda j : j.pt(), reverse = True)
180 
181  leptons = []
182  if hasattr(event, 'selectedLeptons'):
183  leptons = [ l for l in event.selectedLeptons if l.pt() > self.lepPtMin and self.lepSelCut(l) ]
184  if self.cfg_ana.cleanJetsFromTaus and hasattr(event, 'selectedTaus'):
185  leptons = leptons[:] + event.selectedTaus
186  if self.cfg_ana.cleanJetsFromIsoTracks and hasattr(event, 'selectedIsoCleanTrack'):
187  leptons = leptons[:] + event.selectedIsoCleanTrack
188 
189  ## Apply jet selection
190  self.jets = []
191  self.jetsFailId = []
192  self.jetsAllNoID = []
193  self.jetsIdOnly = []
194  for jet in allJets:
195  #Check if lepton and jet have overlapping PF candidates
196  leps_with_overlaps = []
197  if getattr(self.cfg_ana, 'checkLeptonPFOverlap', True):
198  for i in range(jet.numberOfSourceCandidatePtrs()):
199  p1 = jet.sourceCandidatePtr(i) #Ptr<Candidate> p1
200  for lep in leptons:
201  for j in range(lep.numberOfSourceCandidatePtrs()):
202  p2 = lep.sourceCandidatePtr(j)
203  has_overlaps = p1.key() == p2.key() and p1.refCore().id().productIndex() == p2.refCore().id().productIndex() and p1.refCore().id().processIndex() == p2.refCore().id().processIndex()
204  if has_overlaps:
205  leps_with_overlaps += [lep]
206  if len(leps_with_overlaps)>0:
207  for lep in leps_with_overlaps:
208  lep.jetOverlap = jet
209  if self.testJetNoID( jet ):
210  self.jetsAllNoID.append(jet)
211  if(self.cfg_ana.doQG):
212  jet.qgl_calc = self.qglcalc.computeQGLikelihood
213  jet.qgl_rho = rho
214  if self.testJetID( jet ):
215  self.jets.append(jet)
216  self.jetsIdOnly.append(jet)
217  else:
218  self.jetsFailId.append(jet)
219  elif self.testJetID (jet ):
220  self.jetsIdOnly.append(jet)
221 
222  jetsEtaCut = [j for j in self.jets if abs(j.eta()) < self.cfg_ana.jetEta ]
223  self.cleanJetsAll, cleanLeptons = cleanJetsAndLeptons(jetsEtaCut, leptons, self.jetLepDR, self.jetLepArbitration)
224 
225  self.cleanJets = [j for j in self.cleanJetsAll if abs(j.eta()) < self.cfg_ana.jetEtaCentral ]
226  self.cleanJetsFwd = [j for j in self.cleanJetsAll if abs(j.eta()) >= self.cfg_ana.jetEtaCentral ]
227  self.discardedJets = [j for j in self.jets if j not in self.cleanJetsAll]
228  if hasattr(event, 'selectedLeptons') and self.cfg_ana.cleanSelectedLeptons:
229  event.discardedLeptons = [ l for l in leptons if l not in cleanLeptons ]
230  event.selectedLeptons = [ l for l in event.selectedLeptons if l not in event.discardedLeptons ]
231  for lep in leptons:
232  if hasattr(lep, "jetOverlap"):
233  if lep.jetOverlap in self.cleanJetsAll:
234  #print "overlap reco", lep.p4().pt(), lep.p4().eta(), lep.p4().phi(), lep.jetOverlap.p4().pt(), lep.jetOverlap.p4().eta(), lep.jetOverlap.p4().phi()
235  lep.jetOverlapIdx = self.cleanJetsAll.index(lep.jetOverlap)
236  elif lep.jetOverlap in self.discardedJets:
237  #print "overlap discarded", lep.p4().pt(), lep.p4().eta(), lep.p4().phi(), lep.jetOverlap.p4().pt(), lep.jetOverlap.p4().eta(), lep.jetOverlap.p4().phi()
238  lep.jetOverlapIdx = 1000 + self.discardedJets.index(lep.jetOverlap)
239 
240  ## First cleaning, then Jet Id
241  self.noIdCleanJetsAll, cleanLeptons = cleanJetsAndLeptons(self.jetsAllNoID, leptons, self.jetLepDR, self.jetLepArbitration)
242  self.noIdCleanJets = [j for j in self.noIdCleanJetsAll if abs(j.eta()) < self.cfg_ana.jetEtaCentral ]
243  self.noIdCleanJetsFwd = [j for j in self.noIdCleanJetsAll if abs(j.eta()) >= self.cfg_ana.jetEtaCentral ]
244  self.noIdDiscardedJets = [j for j in self.jetsAllNoID if j not in self.noIdCleanJetsAll]
245 
246  ## Clean Jets from photons (first cleaning, then Jet Id)
247  photons = []
248  if hasattr(event, 'selectedPhotons'):
249  if self.cfg_ana.cleanJetsFromFirstPhoton:
250  photons = event.selectedPhotons[:1]
251  else:
252  photons = [ g for g in event.selectedPhotons ]
253 
256 
258  self.gamma_cleanJetsAll = cleanNearestJetOnly(jetsEtaCut, photons+leptons, self.jetGammaLepDR)
259  self.gamma_noIdCleanJetsAll = cleanNearestJetOnly(self.jetsAllNoID, photons+leptons, self.jetGammaLepDR)
260  else:
263 
264  self.gamma_cleanJets = [j for j in self.gamma_cleanJetsAll if abs(j.eta()) < self.cfg_ana.jetEtaCentral ]
265  self.gamma_cleanJetsFwd = [j for j in self.gamma_cleanJetsAll if abs(j.eta()) >= self.cfg_ana.jetEtaCentral ]
266 
267  self.gamma_noIdCleanJets = [j for j in self.gamma_noIdCleanJetsAll if abs(j.eta()) < self.cfg_ana.jetEtaCentral ]
268  self.gamma_noIdCleanJetsFwd = [j for j in self.gamma_noIdCleanJetsAll if abs(j.eta()) >= self.cfg_ana.jetEtaCentral ]
269  ###
270 
271  if self.cfg_ana.alwaysCleanPhotons:
272  self.cleanJets = self.gamma_cleanJets
274  self.cleanJetsFwd = self.gamma_cleanJetsFwd
275  #
279 
280  ## Jet Id, after jet/lepton cleaning
282  for jet in self.noIdCleanJetsAll:
283  if not self.testJetID( jet ):
284  self.cleanJetsFailIdAll.append(jet)
285 
286  self.cleanJetsFailId = [j for j in self.cleanJetsFailIdAll if abs(j.eta()) < self.cfg_ana.jetEtaCentral ]
287 
288  ## Jet Id, after jet/photon cleaning
290  for jet in self.gamma_noIdCleanJetsAll:
291  if not self.testJetID( jet ):
292  self.gamma_cleanJetsFailIdAll.append(jet)
293 
294  self.gamma_cleanJetsFailId = [j for j in self.gamma_cleanJetsFailIdAll if abs(j.eta()) < self.cfg_ana.jetEtaCentral ]
295 
296  ## Associate jets to leptons
297  incleptons = event.inclusiveLeptons if hasattr(event, 'inclusiveLeptons') else event.selectedLeptons
298  jlpairs = matchObjectCollection(incleptons, allJets, self.jetLepDR**2)
299 
300  for jet in allJets:
301  jet.leptons = [l for l in jlpairs if jlpairs[l] == jet ]
302  for lep in incleptons:
303  jet = jlpairs[lep]
304  if jet is None:
305  setattr(lep,"jet"+self.cfg_ana.collectionPostFix,lep)
306  else:
307  setattr(lep,"jet"+self.cfg_ana.collectionPostFix,jet)
308  ## Associate jets to taus
309  taus = getattr(event,'selectedTaus',[])
310  jtaupairs = matchObjectCollection( taus, allJets, self.jetLepDR**2)
311 
312  for jet in allJets:
313  jet.taus = [l for l in jtaupairs if jtaupairs[l] == jet ]
314  for tau in taus:
315  setattr(tau,"jet"+self.cfg_ana.collectionPostFix,jtaupairs[tau])
316 
317  #MC stuff
318  if self.cfg_comp.isMC:
320  for j in self.cleanJetsAll:
321  if hasattr(j, 'deltaMetFromJetSmearing'):
322  self.deltaMetFromJetSmearing[0] += j.deltaMetFromJetSmearing[0]
323  self.deltaMetFromJetSmearing[1] += j.deltaMetFromJetSmearing[1]
324 
325  self.cleanGenJets = cleanNearestJetOnly(self.genJets, leptons, self.jetLepDR)
326 
327  if self.cfg_ana.cleanGenJetsFromPhoton:
328  self.cleanGenJets = cleanNearestJetOnly(self.cleanGenJets, photons, self.jetLepDR)
329 
330  if getattr(self.cfg_ana, 'attachNeutrinos', True) and hasattr(self.cfg_ana,"genNuSelection") :
331  jetNus=[x for x in event.genParticles if abs(x.pdgId()) in [12,14,16] and self.cfg_ana.genNuSelection(x) ]
332  pairs= matchObjectCollection (jetNus, self.genJets, 0.4**2)
333 
334  for (nu,genJet) in six.iteritems(pairs) :
335  if genJet is not None :
336  if not hasattr(genJet,"nu") :
337  genJet.nu=nu.p4()
338  else :
339  genJet.nu+=nu.p4()
340 
341 
342  if self.cfg_ana.do_mc_match:
343  self.jetFlavour(event)
344 
345  if hasattr(event,"jets"+self.cfg_ana.collectionPostFix): raise RuntimeError("Event already contains a jet collection with the following postfix: "+self.cfg_ana.collectionPostFix)
346  setattr(event,"rho" +self.cfg_ana.collectionPostFix, self.rho )
347  setattr(event,"deltaMetFromJEC" +self.cfg_ana.collectionPostFix, self.deltaMetFromJEC )
348  setattr(event,"type1METCorr" +self.cfg_ana.collectionPostFix, self.type1METCorr )
349  setattr(event,"allJetsUsedForMET" +self.cfg_ana.collectionPostFix, self.allJetsUsedForMET )
350  setattr(event,"jets" +self.cfg_ana.collectionPostFix, self.jets )
351  setattr(event,"jetsFailId" +self.cfg_ana.collectionPostFix, self.jetsFailId )
352  setattr(event,"jetsAllNoID" +self.cfg_ana.collectionPostFix, self.jetsAllNoID )
353  setattr(event,"jetsIdOnly" +self.cfg_ana.collectionPostFix, self.jetsIdOnly )
354  setattr(event,"cleanJetsAll" +self.cfg_ana.collectionPostFix, self.cleanJetsAll )
355  setattr(event,"cleanJets" +self.cfg_ana.collectionPostFix, self.cleanJets )
356  setattr(event,"cleanJetsFwd" +self.cfg_ana.collectionPostFix, self.cleanJetsFwd )
357  setattr(event,"cleanJetsFailIdAll" +self.cfg_ana.collectionPostFix, self.cleanJetsFailIdAll )
358  setattr(event,"cleanJetsFailId" +self.cfg_ana.collectionPostFix, self.cleanJetsFailId )
359  setattr(event,"discardedJets" +self.cfg_ana.collectionPostFix, self.discardedJets )
360  setattr(event,"gamma_cleanJetsAll" +self.cfg_ana.collectionPostFix, self.gamma_cleanJetsAll )
361  setattr(event,"gamma_cleanJets" +self.cfg_ana.collectionPostFix, self.gamma_cleanJets )
362  setattr(event,"gamma_cleanJetsFwd" +self.cfg_ana.collectionPostFix, self.gamma_cleanJetsFwd )
363  setattr(event,"gamma_cleanJetsFailIdAll" +self.cfg_ana.collectionPostFix, self.gamma_cleanJetsFailIdAll )
364  setattr(event,"gamma_cleanJetsFailId" +self.cfg_ana.collectionPostFix, self.gamma_cleanJetsFailId )
365 
366 
367  if self.cfg_comp.isMC:
368  setattr(event,"deltaMetFromJetSmearing"+self.cfg_ana.collectionPostFix, self.deltaMetFromJetSmearing)
369  setattr(event,"cleanGenJets" +self.cfg_ana.collectionPostFix, self.cleanGenJets )
370  setattr(event,"genJets" +self.cfg_ana.collectionPostFix, self.genJets )
371  if self.cfg_ana.do_mc_match:
372  setattr(event,"bqObjects" +self.cfg_ana.collectionPostFix, self.bqObjects )
373  setattr(event,"cqObjects" +self.cfg_ana.collectionPostFix, self.cqObjects )
374  setattr(event,"partons" +self.cfg_ana.collectionPostFix, self.partons )
375  setattr(event,"heaviestQCDFlavour" +self.cfg_ana.collectionPostFix, self.heaviestQCDFlavour )
376 
377 
378  return True
379 
380 
381 
382  def testJetID(self, jet):
383  jet.puJetIdPassed = jet.puJetId()
384  jet.pfJetIdPassed = jet.jetID('POG_PFID_Loose')
385  if self.cfg_ana.relaxJetId:
386  return True
387  else:
388  return jet.pfJetIdPassed and (jet.puJetIdPassed or not(self.doPuId))
389 
390  def testJetNoID( self, jet ):
391  # 2 is loose pile-up jet id
392  return jet.pt() > self.cfg_ana.jetPt and \
393  abs( jet.eta() ) < self.cfg_ana.jetEta;
394 
395  def jetFlavour(self,event):
396  def isFlavour(x,f):
397  id = abs(x.pdgId())
398  if id > 999: return (id/1000)%10 == f
399  if id > 99: return (id/100)%10 == f
400  return id % 100 == f
401 
402 
403 
404  self.bqObjects = [ p for p in event.genParticles if (p.status() == 2 and isFlavour(p,5)) ]
405  self.cqObjects = [ p for p in event.genParticles if (p.status() == 2 and isFlavour(p,4)) ]
406 
407  self.partons = [ p for p in event.genParticles if ((p.status() == 23 or p.status() == 3) and abs(p.pdgId())>0 and (abs(p.pdgId()) in [1,2,3,4,5,21]) ) ]
409  self.partons,
410  deltaRMax = 0.3)
411 
412  for jet in self.cleanJetsAll:
413  parton = match[jet]
414  jet.partonId = (parton.pdgId() if parton != None else 0)
415  jet.partonMotherId = (parton.mother(0).pdgId() if parton != None and parton.numberOfMothers()>0 else 0)
416 
417  for jet in self.jets:
418  (bmatch, dr) = bestMatch(jet, self.bqObjects)
419  if dr < 0.4:
420  jet.mcFlavour = 5
421  else:
422  (cmatch, dr) = bestMatch(jet, self.cqObjects)
423  if dr < 0.4:
424  jet.mcFlavour = 4
425  else:
426  jet.mcFlavour = 0
427 
428  self.heaviestQCDFlavour = 5 if len(self.bqObjects) else (4 if len(self.cqObjects) else 1);
429 
430  def matchJets(self, event, jets):
431  match = matchObjectCollection2(jets,
432  event.genbquarks + event.genwzquarks,
433  deltaRMax = 0.3)
434  for jet in jets:
435  gen = match[jet]
436  jet.mcParton = gen
437  jet.mcMatchId = (gen.sourceId if gen != None else 0)
438  jet.mcMatchFlav = (abs(gen.pdgId()) if gen != None else 0)
439 
440  match = matchObjectCollection2(jets,
441  self.genJets,
442  deltaRMax = 0.3)
443  for jet in jets:
444  jet.mcJet = match[jet]
445 
446 
447 
448  def smearJets(self, event, jets):
449  # https://twiki.cern.ch/twiki/bin/viewauth/CMS/TWikiTopRefSyst#Jet_energy_resolution
450  for jet in jets:
451  gen = jet.mcJet
452  if gen != None:
453  genpt, jetpt, aeta = gen.pt(), jet.pt(), abs(jet.eta())
454  # from https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution
455  #8 TeV tables
456  factor = shiftJERfactor(self.shiftJER, aeta)
457  ptscale = max(0.0, (jetpt + (factor-1)*(jetpt-genpt))/jetpt)
458  #print "get with pt %.1f (gen pt %.1f, ptscale = %.3f)" % (jetpt,genpt,ptscale)
459  jet.deltaMetFromJetSmearing = [ -(ptscale-1)*jet.rawFactor()*jet.px(), -(ptscale-1)*jet.rawFactor()*jet.py() ]
460  if ptscale != 0:
461  jet.setP4(jet.p4()*ptscale)
462  # leave the uncorrected unchanged for sync
463  jet.setRawFactor(jet.rawFactor()/ptscale)
464  #else: print "jet with pt %.1d, eta %.2f is unmatched" % (jet.pt(), jet.eta())
465  if (self.shiftJER==0) and (self.addJERShifts):
466  setattr(jet, "corrJER", ptscale )
467  factorJERUp= shiftJERfactor(1, aeta)
468  ptscaleJERUp = max(0.0, (jetpt + (factorJERUp-1)*(jetpt-genpt))/jetpt)
469  setattr(jet, "corrJERUp", ptscaleJERUp)
470  factorJERDown= shiftJERfactor(-1, aeta)
471  ptscaleJERDown = max(0.0, (jetpt + (factorJERDown-1)*(jetpt-genpt))/jetpt)
472  setattr(jet, "corrJERDown", ptscaleJERDown)
473 
474 
475 
476 
477 
478 setattr(JetAnalyzer,"defaultConfig", cfg.Analyzer(
479  class_object = JetAnalyzer,
480  jetCol = 'slimmedJets',
481  copyJetsByValue = False, #Whether or not to copy the input jets or to work with references (should be 'True' if JetAnalyzer is run more than once)
482  genJetCol = 'slimmedGenJets',
483  rho = ('fixedGridRhoFastjetAll','',''),
484  jetPt = 25.,
485  jetEta = 4.7,
486  jetEtaCentral = 2.4,
487  jetLepDR = 0.4,
488  jetLepArbitration = (lambda jet,lepton : lepton), # you can decide which to keep in case of overlaps; e.g. if the jet is b-tagged you might want to keep the jet
489  cleanSelectedLeptons = True, #Whether to clean 'selectedLeptons' after disambiguation. Treat with care (= 'False') if running Jetanalyzer more than once
490  minLepPt = 10,
491  lepSelCut = lambda lep : True,
492  relaxJetId = False,
493  doPuId = False, # Not commissioned in 7.0.X
494  doQG = False,
495  checkLeptonPFOverlap = True,
496  recalibrateJets = False,
497  applyL2L3Residual = 'Data', # if recalibrateJets, apply L2L3Residual to Data only
498  recalibrationType = "AK4PFchs",
499  shiftJEC = 0, # set to +1 or -1 to apply +/-1 sigma shift to the nominal jet energies
500  addJECShifts = False, # if true, add "corr", "corrJECUp", and "corrJECDown" for each jet (requires uncertainties to be available!)
501  smearJets = True,
502  shiftJER = 0, # set to +1 or -1 to get +/-1 sigma shifts
503  jecPath = "",
504  calculateSeparateCorrections = False,
505  calculateType1METCorrection = False,
506  type1METParams = { 'jetPtThreshold':15., 'skipEMfractionThreshold':0.9, 'skipMuons':True },
507  addJERShifts = 0, # add +/-1 sigma shifts to jets, intended to be used with shiftJER=0
508  cleanJetsFromFirstPhoton = False,
509  cleanJetsFromTaus = False,
510  cleanJetsFromIsoTracks = False,
511  alwaysCleanPhotons = False,
512  do_mc_match=True,
513  cleanGenJetsFromPhoton = False,
514  jetGammaDR=0.4,
515  cleanFromLepAndGammaSimultaneously = False,
516  jetGammaLepDR=0.4,
517  attachNeutrinos = True,
518  genNuSelection = lambda nu : True, #FIXME: add here check for ispromptfinalstate
519  collectionPostFix = ""
520  )
521 )
deltaMetFromJEC
Read jets, if necessary recalibrate and shift MET.
Definition: JetAnalyzer.py:143
gamma_cleanJetaAll
Clean Jets from photons (first cleaning, then Jet Id)
Definition: JetAnalyzer.py:254
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
cleanJetsFailIdAll
Jet Id, after jet/lepton cleaning.
Definition: JetAnalyzer.py:281
noIdCleanJets
First cleaning, then Jet Id.
Definition: JetAnalyzer.py:242
def matchObjectCollection
Definition: deltar.py:151
def matchJets(self, event, jets)
Definition: JetAnalyzer.py:430
deltaMetFromJetSmearing
Associate jets to leptons.
Definition: JetAnalyzer.py:319
Definition: Jet.py:1
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
def cleanNearestJetOnly(jets, leptons, deltaR)
Definition: JetAnalyzer.py:14
def bestMatch(object, matchCollection)
Definition: deltar.py:138
def cleanJetsAndLeptons(jets, leptons, deltaR, arbitration)
Definition: JetAnalyzer.py:26
def shiftJERfactor(JERShift, aeta)
Definition: JetAnalyzer.py:53
def __init__(self, cfg_ana, cfg_comp, looperName)
Definition: JetAnalyzer.py:69
def matchObjectCollection2(objects, matchCollection, deltaRMax=0.3)
Definition: deltar.py:166
gamma_cleanJetsFailIdAll
Jet Id, after jet/photon cleaning.
Definition: JetAnalyzer.py:289