CMS 3D CMS Logo

IsoTrackAnalyzer.py
Go to the documentation of this file.
1 from __future__ import print_function
2 import operator
3 import itertools
4 import copy
5 import types
6 
7 from ROOT import TLorentzVector
8 
9 from PhysicsTools.Heppy.analyzers.core.Analyzer import Analyzer
10 from PhysicsTools.HeppyCore.framework.event import Event
11 from PhysicsTools.HeppyCore.statistics.counter import Counter, Counters
12 from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
13 from PhysicsTools.Heppy.physicsobjects.Lepton import Lepton
14 from PhysicsTools.Heppy.physicsobjects.Tau import Tau
15 from PhysicsTools.Heppy.physicsobjects.IsoTrack import IsoTrack
16 
17 from PhysicsTools.HeppyCore.utils.deltar import deltaR, deltaPhi, bestMatch , matchObjectCollection3
18 
19 import PhysicsTools.HeppyCore.framework.config as cfg
20 
21 from ROOT import heppy
22 
23 
24 
25 
26 def mtw(x1,x2):
27  import math
28  return math.sqrt(2*x1.pt()*x2.pt()*(1-math.cos(x1.phi()-x2.phi())))
29 
30 def makeNearestLeptons(leptons,track, event):
31 
32  minDeltaR = 99999
33 
34  nearestLepton = []
35  ibest=-1
36  for i,lepton in enumerate(leptons):
37  minDeltaRtemp=deltaR(lepton.eta(),lepton.phi(),track.eta(),track.phi())
38  if minDeltaRtemp < minDeltaR:
39  minDeltaR = minDeltaRtemp
40  ibest=i
41 
42  if len(leptons) > 0 and ibest!=-1:
43  nearestLepton.append(leptons[ibest])
44 
45  return nearestLepton
46 
48 
49  def __init__(self, cfg_ana, cfg_comp, looperName ):
50  super(IsoTrackAnalyzer,self).__init__(cfg_ana,cfg_comp,looperName)
52 
53  self.doIsoAnnulus = getattr(cfg_ana, 'doIsoAnnulus', False)
54 
55 
56  #----------------------------------------
57  # DECLARATION OF HANDLES OF LEPTONS STUFF
58  #----------------------------------------
59  def declareHandles(self):
60  super(IsoTrackAnalyzer, self).declareHandles()
61  self.handles['met'] = AutoHandle( 'slimmedMETs', 'std::vector<pat::MET>' )
62  self.handles['packedCandidates'] = AutoHandle( 'packedPFCandidates', 'std::vector<pat::PackedCandidate>')
63 
64  def beginLoop(self, setup):
65  super(IsoTrackAnalyzer,self).beginLoop(setup)
66  self.counters.addCounter('events')
67  count = self.counters.counter('events')
68  count.register('all events')
69  count.register('has >=1 selected Track')
70  count.register('has >=1 selected Iso Track')
71 
72  #------------------
73  # MAKE LIST
74  #------------------
75  def makeIsoTrack(self, event):
76 
77  event.selectedIsoTrack = []
78  event.selectedIsoCleanTrack = []
79  #event.preIsoTrack = []
80 
81  patcands = self.handles['packedCandidates'].product()
82 
83  charged = [ p for p in patcands if ( p.charge() != 0 and p.fromPV() > 1 ) ]
84 
85  self.IsoTrackIsolationComputer.setPackedCandidates(patcands, 1, 9999, 9999.)
86 
87 
88  alltrack = map( IsoTrack, charged )
89 
90 
91  for track in alltrack:
92 
93  if ( abs(track.dz()) > self.cfg_ana.dzMax ): continue
94  if ( (abs(track.pdgId())!=11) and (abs(track.pdgId())!=13) and (track.pt() < self.cfg_ana.ptMin) ): continue
95  if ( track.pt() < self.cfg_ana.ptMinEMU ): continue
96 
97  foundNonIsoTrack = False
98 
99 
100  if( (self.cfg_ana.doSecondVeto) and len(event.selectedLeptons)>0) :
101  if( deltaR(event.selectedLeptons[0].eta(), event.selectedLeptons[0].phi(), track.eta(), track.phi()) <0.01) : continue
102  if ( (abs(track.pdgId())!=11) and (abs(track.pdgId())!=13) and (track.charge()*event.selectedLeptons[0].charge()) ): continue
103 
104 
105 
106  track.associatedVertex = event.goodVertices[0] if len(event.goodVertices)>0 else event.vertices[0]
107 
108 
109 
110  isoSum = self.IsoTrackIsolationComputer.chargedAbsIso(track.physObj, self.cfg_ana.isoDR, 0., self.cfg_ana.ptPartMin)
111  if( abs(track.pdgId())==211 ): isoSum = isoSum - track.pt() #BM: this is an ugly hack and it is error prone. It needs to be fixed using the addVeto method properly
112 
113  if self.cfg_ana.doRelIsolation:
114  relIso = (isoSum)/track.pt()
115  if ( (abs(track.pdgId())!=11) and (abs(track.pdgId())!=13) and (relIso > self.cfg_ana.MaxIsoSum) ): continue
116  elif((relIso > self.cfg_ana.MaxIsoSumEMU)): continue
117  else:
118  if(isoSum > (self.cfg_ana.maxAbsIso)): continue
119 
120  if self.doIsoAnnulus:
121  self.attachIsoAnnulus04(track)
122 
123  track.absIso = isoSum
124 
125 
127 
128 # if (isoSum < minIsoSum ) :
129  if self.cfg_ana.doRelIsolation or (track.absIso < min(0.2*track.pt(), self.cfg_ana.maxAbsIso)):
130  event.selectedIsoTrack.append(track)
131 
132  if self.cfg_ana.doPrune:
133  myMet = self.handles['met'].product()[0]
134  mtwIsoTrack = mtw(track, myMet)
135  if mtwIsoTrack < 100:
136  if abs(track.pdgId()) == 11 or abs(track.pdgId()) == 13:
137  if track.pt()>5 and track.absIso/track.pt()<0.2:
138 
139  myLeptons = [ l for l in event.selectedLeptons if l.pt() > 10 ]
140  nearestSelectedLeptons = makeNearestLeptons(myLeptons,track, event)
141  if len(nearestSelectedLeptons) > 0:
142  for lep in nearestSelectedLeptons:
143  if deltaR(lep.eta(), lep.phi(), track.eta(), track.phi()) > 0.01:
144  event.selectedIsoCleanTrack.append(track)
145  else:
146  event.selectedIsoCleanTrack.append(track)
147 
148 
149 
150 
151 
152 
225 
226  event.selectedIsoTrack.sort(key = lambda l : l.pt(), reverse = True)
227  event.selectedIsoCleanTrack.sort(key = lambda l : l.pt(), reverse = True)
228 
229  self.counters.counter('events').inc('all events')
230  #if(len(event.preIsoTrack)): self.counters.counter('events').inc('has >=1 selected Track')
231  if(len(event.selectedIsoTrack)): self.counters.counter('events').inc('has >=1 selected Iso Track')
232 
233 
234  def attachIsoAnnulus04(self, mu):
235  mu.absIsoAnCharged = self.IsoTrackIsolationComputer.chargedAbsIso (mu.physObj, 0.4, self.cfg_ana.isoDR, 0.0,self.IsoTrackIsolationComputer.selfVetoNone)
236  mu.absIsoAnPho = self.IsoTrackIsolationComputer.photonAbsIsoRaw (mu.physObj, 0.4, self.cfg_ana.isoDR, 0.0,self.IsoTrackIsolationComputer.selfVetoNone)
237  mu.absIsoAnNHad = self.IsoTrackIsolationComputer.neutralHadAbsIsoRaw(mu.physObj, 0.4, self.cfg_ana.isoDR, 0.0,self.IsoTrackIsolationComputer.selfVetoNone)
238  mu.absIsoAnPU = self.IsoTrackIsolationComputer.puAbsIso (mu.physObj, 0.4, self.cfg_ana.isoDR, 0.0,self.IsoTrackIsolationComputer.selfVetoNone)
239  mu.absIsoAnNeutral = max(0.0, mu.absIsoAnPho + mu.absIsoAnNHad - 0.5*mu.absIsoAnPU)
240 
241  mu.absIsoAn04 = mu.absIsoAnCharged + mu.absIsoAnNeutral
242  mu.relIsoAn04 = mu.absIsoAn04/mu.pt()
243 
244 
245  def matchIsoTrack(self, event):
246  matchTau = matchObjectCollection3(event.selectedIsoTrack, event.gentaus + event.gentauleps + event.genleps, deltaRMax = 0.5)
247  for lep in event.selectedIsoTrack:
248  gen = matchTau[lep]
249  lep.mcMatchId = 1 if gen else 0
250 
251 
252  def printInfo(self, event):
253  print('event to Veto')
254  print('----------------')
255 
256  if len(event.selectedIsoTrack)>0:
257  print('lenght: ',len(event.selectedIsoTrack))
258  print('track candidate pt: ',event.selectedIsoTrack[0].pt())
259  print('track candidate eta: ',event.selectedIsoTrack[0].eta())
260  print('track candidate phi: ',event.selectedIsoTrack[0].phi())
261  print('track candidate mass: ',event.selectedIsoTrack[0].mass())
262  print('pdgId candidate : ',event.selectedIsoTrack[0].pdgId())
263  print('dz: ',event.selectedIsoTrack[0].dz())
264  print('iso: ',event.selectedIsoTrack[0].absIso)
265  print('matchId: ',event.selectedIsoTrack[0].mcMatchId)
266 
267 # for lepton in event.selectedLeptons:
268 # print 'good lepton type: ',lepton.pdgId()
269 # print 'pt: ',lepton.pt()
270 
271 # for tau in event.selectedTaus:
272 # print 'good lepton type: ',tau.pdgId()
273 # print 'pt: ',tau.pt()
274 
275  print('----------------')
276 
277 
278  def process(self, event):
279 
280  if self.cfg_ana.setOff:
281  return True
282 
283  self.readCollections( event.input )
284  self.makeIsoTrack(event)
285 
286  if len(event.selectedIsoTrack)==0 : return True
287 
288 
291 
292 
293 
294  if not self.cfg_comp.isMC:
295  return True
296 
297  if hasattr(event, 'gentaus') and hasattr(event, 'gentauleps') and hasattr(event, 'genleps') and self.cfg_ana.do_mc_match :
298  self.matchIsoTrack(event)
299 
300 
301 
302 
303 
304 # if (self.cfg_ana.doSecondVeto and (event.selectedIsoTrack[0].pdgId()!=11) and (event.selectedIsoTrack[0].pdgId()!=12) and event.isoIsoTrack < self.cfg_ana.MaxIsoSum ) :
305 
307 
308 # if ((self.cfg_ana.doSecondVeto and event.selectedIsoTrack[0].pdgId()==11 or event.selectedIsoTrack[0].pdgId()==12) and event.isoIsoTrack < self.cfg_ana.MaxIsoSumEMU ) :
309 
311 
312 
313  return True
314 
315 
316 setattr(IsoTrackAnalyzer,"defaultConfig",cfg.Analyzer(
317  class_object=IsoTrackAnalyzer,
318  setOff=True,
319 
320  candidates='packedPFCandidates',
321  candidatesTypes='std::vector<pat::PackedCandidate>',
322  ptMin = 5, # for pion
323  ptMinEMU = 5, # for EMU
324  dzMax = 0.1,
325 
326  isoDR = 0.3,
327  ptPartMin = 0,
328  dzPartMax = 0.1,
329  maxAbsIso = 8,
330 
331  doRelIsolation = False,
332  MaxIsoSum = 0.1,
333  MaxIsoSumEMU = 0.2,
334  doSecondVeto = False,
335 
336  doIsoAnnulus= False,
337 
338  doPrune = True,
339  do_mc_match = True, # note: it will in any case try it only on MC, not on data
340  )
341 )
def attachIsoAnnulus04(self, mu)
def makeNearestLeptons(leptons, track, event)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
def matchIsoTrack(self, event)
def __init__(self, cfg_ana, cfg_comp, looperName)
def matchObjectCollection3
Definition: deltar.py:41
def printInfo(self, event)