1 from PhysicsTools.Heppy.analyzers.core.Analyzer
import Analyzer
2 from PhysicsTools.Heppy.analyzers.core.AutoHandle
import AutoHandle
3 from PhysicsTools.Heppy.physicsobjects.Electron
import Electron
4 from PhysicsTools.Heppy.physicsobjects.Muon
import Muon
8 from PhysicsTools.Heppy.physicsutils.RochesterCorrections
import rochcor
9 from PhysicsTools.Heppy.physicsutils.MuScleFitCorrector
import MuScleFitCorr
10 from PhysicsTools.Heppy.physicsutils.ElectronCalibrator
import EmbeddedElectronCalibrator
17 from ROOT
import heppy
23 def __init__(self, cfg_ana, cfg_comp, looperName ):
24 super(LeptonAnalyzer,self).
__init__(cfg_ana,cfg_comp,looperName)
25 if self.cfg_ana.doMuScleFitCorrections
and self.cfg_ana.doMuScleFitCorrections !=
"none":
26 if self.cfg_ana.doMuScleFitCorrections
not in [
"none",
"prompt",
"prompt-sync",
"rereco",
"rereco-sync" ]:
27 raise RuntimeError,
'doMuScleFitCorrections must be one of "none", "prompt", "prompt-sync", "rereco", "rereco-sync"'
28 rereco = (
"prompt" not in self.cfg_ana.doMuScleFitCorrections)
29 sync = (
"sync" in self.cfg_ana.doMuScleFitCorrections)
30 self.
muscleCorr = MuScleFitCorr(cfg_comp.isMC, rereco, sync)
31 if hasattr(self.cfg_ana,
"doRochesterCorrections")
and self.cfg_ana.doRochesterCorrections:
32 raise RuntimeError,
"You can't run both Rochester and MuScleFit corrections!"
34 self.cfg_ana.doMuScleFitCorrections =
False
36 self.electronEnergyCalibrator = EmbeddedElectronCalibrator()
39 self.
eleEffectiveArea = getattr(cfg_ana,
'ele_effectiveAreas',
"Phys14_25ns_v1")
40 self.
muEffectiveArea = getattr(cfg_ana,
'mu_effectiveAreas',
"Phys14_25ns_v1")
50 self.handles[
'muons'] = AutoHandle(self.cfg_ana.muons,
"std::vector<pat::Muon>")
51 self.handles[
'electrons'] = AutoHandle(self.cfg_ana.electrons,
"std::vector<pat::Electron>")
54 self.handles[
'rhoMu'] = AutoHandle( self.cfg_ana.rhoMuon,
'double')
56 self.handles[
'rhoEle'] = AutoHandle( self.cfg_ana.rhoElectron,
'double')
59 super(LeptonAnalyzer,self).
beginLoop(setup)
60 self.counters.addCounter(
'events')
61 count = self.counters.counter(
'events')
62 count.register(
'all events')
71 event.inclusiveLeptons = []
74 event.selectedLeptons = []
75 event.selectedMuons = []
76 event.selectedElectrons = []
77 event.otherLeptons = []
84 if (mu.track().isNonnull()
and mu.muonID(self.cfg_ana.inclusive_muon_id)
and
85 mu.pt()>self.cfg_ana.inclusive_muon_pt
and abs(mu.eta())<self.cfg_ana.inclusive_muon_eta
and
86 abs(mu.dxy())<self.cfg_ana.inclusive_muon_dxy
and abs(mu.dz())<self.cfg_ana.inclusive_muon_dz):
87 event.inclusiveLeptons.append(mu)
89 if (mu.muonID(self.cfg_ana.loose_muon_id)
and
90 mu.pt() > self.cfg_ana.loose_muon_pt
and abs(mu.eta()) < self.cfg_ana.loose_muon_eta
and
91 abs(mu.dxy()) < self.cfg_ana.loose_muon_dxy
and abs(mu.dz()) < self.cfg_ana.loose_muon_dz
and
92 mu.relIso03 < self.cfg_ana.loose_muon_relIso
and
93 mu.absIso03 < (self.cfg_ana.loose_muon_absIso
if hasattr(self.cfg_ana,
'loose_muon_absIso')
else 9e99)):
95 event.selectedLeptons.append(mu)
96 event.selectedMuons.append(mu)
98 mu.looseIdSusy =
False
99 event.otherLeptons.append(mu)
104 looseMuons = event.selectedLeptons[:]
105 for ele
in allelectrons:
108 if ( ele.electronID(self.cfg_ana.inclusive_electron_id)
and
109 ele.pt()>self.cfg_ana.inclusive_electron_pt
and abs(ele.eta())<self.cfg_ana.inclusive_electron_eta
and
110 abs(ele.dxy())<self.cfg_ana.inclusive_electron_dxy
and abs(ele.dz())<self.cfg_ana.inclusive_electron_dz
and
111 ele.lostInner()<=self.cfg_ana.inclusive_electron_lostHits ):
112 event.inclusiveLeptons.append(ele)
114 if (ele.electronID(self.cfg_ana.loose_electron_id)
and
115 ele.pt()>self.cfg_ana.loose_electron_pt
and abs(ele.eta())<self.cfg_ana.loose_electron_eta
and
116 abs(ele.dxy()) < self.cfg_ana.loose_electron_dxy
and abs(ele.dz())<self.cfg_ana.loose_electron_dz
and
117 ele.relIso03 <= self.cfg_ana.loose_electron_relIso
and
118 ele.absIso03 < (self.cfg_ana.loose_electron_absIso
if hasattr(self.cfg_ana,
'loose_electron_absIso')
else 9e99)
and
119 ele.lostInner() <= self.cfg_ana.loose_electron_lostHits
and
120 (
True if (hasattr(self.cfg_ana,
'notCleaningElectrons')
and self.cfg_ana.notCleaningElectrons)
else (
bestMatch(ele, looseMuons)[1] > (self.cfg_ana.min_dr_electron_muon**2)) )):
121 event.selectedLeptons.append(ele)
122 event.selectedElectrons.append(ele)
123 ele.looseIdSusy =
True
125 event.otherLeptons.append(ele)
126 ele.looseIdSusy =
False
128 event.otherLeptons.sort(key =
lambda l : l.pt(), reverse =
True)
129 event.selectedLeptons.sort(key =
lambda l : l.pt(), reverse =
True)
130 event.selectedMuons.sort(key =
lambda l : l.pt(), reverse =
True)
131 event.selectedElectrons.sort(key =
lambda l : l.pt(), reverse =
True)
132 event.inclusiveLeptons.sort(key =
lambda l : l.pt(), reverse =
True)
134 for lepton
in event.selectedLeptons:
135 if hasattr(self,
'efficiency'):
136 self.efficiency.attachToObject(lepton)
140 make a list of all muons, and apply basic corrections to them
143 allmuons =
map( Muon, self.handles[
'muons'].product() )
146 if self.cfg_ana.doMuScleFitCorrections:
148 self.muscleCorr.correct(mu, event.run)
149 elif self.cfg_ana.doRochesterCorrections:
151 corp4 = rochcor.corrected_p4(mu, event.run)
155 if self.cfg_ana.doSegmentBasedMuonCleaning:
156 isgood = cmgMuonCleanerBySegments.clean( self.handles[
'muons'].product() )
158 for i,mu
in enumerate(allmuons):
159 if isgood[i]: newmu.append(mu)
164 mu.rho = float(self.handles[
'rhoMu'].product()[0])
166 if aeta < 1.0 : mu.EffectiveArea03 = 0.382;
167 elif aeta < 1.47 : mu.EffectiveArea03 = 0.317;
168 elif aeta < 2.0 : mu.EffectiveArea03 = 0.242;
169 elif aeta < 2.2 : mu.EffectiveArea03 = 0.326;
170 elif aeta < 2.3 : mu.EffectiveArea03 = 0.462;
171 else : mu.EffectiveArea03 = 0.372;
172 if aeta < 1.0 : mu.EffectiveArea04 = 0.674;
173 elif aeta < 1.47 : mu.EffectiveArea04 = 0.565;
174 elif aeta < 2.0 : mu.EffectiveArea04 = 0.442;
175 elif aeta < 2.2 : mu.EffectiveArea04 = 0.515;
176 elif aeta < 2.3 : mu.EffectiveArea04 = 0.821;
177 else : mu.EffectiveArea04 = 0.660;
180 if aeta < 0.800: mu.EffectiveArea03 = 0.0913
181 elif aeta < 1.300: mu.EffectiveArea03 = 0.0765
182 elif aeta < 2.000: mu.EffectiveArea03 = 0.0546
183 elif aeta < 2.200: mu.EffectiveArea03 = 0.0728
184 else: mu.EffectiveArea03 = 0.1177
185 if aeta < 0.800: mu.EffectiveArea04 = 0.1564
186 elif aeta < 1.300: mu.EffectiveArea04 = 0.1325
187 elif aeta < 2.000: mu.EffectiveArea04 = 0.0913
188 elif aeta < 2.200: mu.EffectiveArea04 = 0.1212
189 else: mu.EffectiveArea04 = 0.2085
190 else:
raise RuntimeError,
"Unsupported value for mu_effectiveAreas: can only use Data2012 (rho: ?) and Phys14_v1 (rho: fixedGridRhoFastjetAll)"
193 mu.associatedVertex = event.goodVertices[0]
197 if self.cfg_ana.mu_isoCorr==
"rhoArea" :
198 mu.absIso03 = (mu.pfIsolationR03().sumChargedHadronPt +
max( mu.pfIsolationR03().sumNeutralHadronEt + mu.pfIsolationR03().sumPhotonEt - mu.rho * mu.EffectiveArea03,0.0))
199 mu.absIso04 = (mu.pfIsolationR04().sumChargedHadronPt +
max( mu.pfIsolationR04().sumNeutralHadronEt + mu.pfIsolationR04().sumPhotonEt - mu.rho * mu.EffectiveArea04,0.0))
200 elif self.cfg_ana.mu_isoCorr==
"deltaBeta" :
201 mu.absIso03 = (mu.pfIsolationR03().sumChargedHadronPt +
max( mu.pfIsolationR03().sumNeutralHadronEt + mu.pfIsolationR03().sumPhotonEt - mu.pfIsolationR03().sumPUPt/2,0.0))
202 mu.absIso04 = (mu.pfIsolationR04().sumChargedHadronPt +
max( mu.pfIsolationR04().sumNeutralHadronEt + mu.pfIsolationR04().sumPhotonEt - mu.pfIsolationR04().sumPUPt/2,0.0))
204 raise RuntimeError,
"Unsupported mu_isoCorr name '" + str(self.cfg_ana.mu_isoCorr) +
"'! For now only 'rhoArea' and 'deltaBeta' are supported."
205 mu.relIso03 = mu.absIso03/mu.pt()
206 mu.relIso04 = mu.absIso04/mu.pt()
212 make a list of all electrons, and apply basic corrections to them
214 allelectrons =
map( Electron, self.handles[
'electrons'].product() )
218 for e
in allelectrons:
220 for e2
in allelenodup:
221 if abs(e.pt()-e2.pt()) < 1e-6
and abs(e.eta()-e2.eta()) < 1e-6
and abs(e.phi()-e2.phi()) < 1e-6
and e.charge() == e2.charge():
224 if not dup: allelenodup.append(e)
225 allelectrons = allelenodup
228 for ele
in allelectrons:
229 ele.rho = float(self.handles[
'rhoEle'].product()[0])
232 SCEta =
abs(ele.superCluster().
eta())
233 if SCEta < 1.0 : ele.EffectiveArea03 = 0.13
234 elif SCEta < 1.479: ele.EffectiveArea03 = 0.14
235 elif SCEta < 2.0 : ele.EffectiveArea03 = 0.07
236 elif SCEta < 2.2 : ele.EffectiveArea03 = 0.09
237 elif SCEta < 2.3 : ele.EffectiveArea03 = 0.11
238 elif SCEta < 2.4 : ele.EffectiveArea03 = 0.11
239 else : ele.EffectiveArea03 = 0.14
240 if SCEta < 1.0 : ele.EffectiveArea04 = 0.208;
241 elif SCEta < 1.479: ele.EffectiveArea04 = 0.209;
242 elif SCEta < 2.0 : ele.EffectiveArea04 = 0.115;
243 elif SCEta < 2.2 : ele.EffectiveArea04 = 0.143;
244 elif SCEta < 2.3 : ele.EffectiveArea04 = 0.183;
245 elif SCEta < 2.4 : ele.EffectiveArea04 = 0.194;
246 else : ele.EffectiveArea04 = 0.261;
248 aeta =
abs(ele.eta())
249 if aeta < 0.800: ele.EffectiveArea03 = 0.1013
250 elif aeta < 1.300: ele.EffectiveArea03 = 0.0988
251 elif aeta < 2.000: ele.EffectiveArea03 = 0.0572
252 elif aeta < 2.200: ele.EffectiveArea03 = 0.0842
253 else: ele.EffectiveArea03 = 0.1530
254 if aeta < 0.800: ele.EffectiveArea04 = 0.1830
255 elif aeta < 1.300: ele.EffectiveArea04 = 0.1734
256 elif aeta < 2.000: ele.EffectiveArea04 = 0.1077
257 elif aeta < 2.200: ele.EffectiveArea04 = 0.1565
258 else: ele.EffectiveArea04 = 0.2680
259 else:
raise RuntimeError,
"Unsupported value for ele_effectiveAreas: can only use Data2012 (rho: ?) and Phys14_v1 (rho: fixedGridRhoFastjetAll)"
262 if self.cfg_ana.doElectronScaleCorrections:
263 for ele
in allelectrons:
264 self.electronEnergyCalibrator.correct(ele, event.run)
267 for ele
in allelectrons:
268 ele.associatedVertex = event.goodVertices[0]
271 for ele
in allelectrons:
272 if self.cfg_ana.ele_isoCorr==
"rhoArea" :
273 ele.absIso03 = (ele.chargedHadronIsoR(0.3) +
max(ele.neutralHadronIsoR(0.3)+ele.photonIsoR(0.3)-ele.rho*ele.EffectiveArea03,0))
274 ele.absIso04 = (ele.chargedHadronIsoR(0.4) +
max(ele.neutralHadronIsoR(0.4)+ele.photonIsoR(0.4)-ele.rho*ele.EffectiveArea04,0))
275 elif self.cfg_ana.ele_isoCorr==
"deltaBeta" :
276 ele.absIso03 = (ele.chargedHadronIsoR(0.3) +
max( ele.neutralHadronIsoR(0.3)+ele.photonIsoR(0.3) - ele.puChargedHadronIsoR(0.3)/2, 0.0))
277 ele.absIso04 = (ele.chargedHadronIsoR(0.4) +
max( ele.neutralHadronIsoR(0.4)+ele.photonIsoR(0.4) - ele.puChargedHadronIsoR(0.4)/2, 0.0))
279 raise RuntimeError,
"Unsupported ele_isoCorr name '" + str(self.cfg_ana.ele_isoCorr) +
"'! For now only 'rhoArea' and 'deltaBeta' are supported."
280 ele.relIso03 = ele.absIso03/ele.pt()
281 ele.relIso04 = ele.absIso04/ele.pt()
284 for ele
in allelectrons:
285 if self.cfg_ana.ele_tightId==
"MVA" :
286 ele.tightIdResult = ele.electronID(
"POG_MVA_ID_Trig_full5x5")
287 elif self.cfg_ana.ele_tightId==
"Cuts_2012" :
288 ele.tightIdResult = -1 + 1*ele.electronID(
"POG_Cuts_ID_2012_Veto_full5x5") + 1*ele.electronID(
"POG_Cuts_ID_2012_Loose_full5x5") + 1*ele.electronID(
"POG_Cuts_ID_2012_Medium_full5x5") + 1*ele.electronID(
"POG_Cuts_ID_2012_Tight_full5x5")
290 raise RuntimeError,
"Unsupported ele_tightId name '" + str(self.cfg_ana.ele_tightId) +
"'! For now only 'MVA' and 'Cuts_2012' are supported."
296 def plausible(rec,gen):
297 if abs(rec.pdgId()) == 11
and abs(gen.pdgId()) != 11:
return False
298 if abs(rec.pdgId()) == 13
and abs(gen.pdgId()) != 13:
return False
299 dr =
deltaR(rec.eta(),rec.phi(),gen.eta(),gen.phi())
300 if dr < 0.3:
return True
301 if rec.pt() < 10
and abs(rec.pdgId()) == 13
and gen.pdgId() != rec.pdgId():
return False
302 if dr < 0.7:
return True
303 if min(rec.pt(),gen.pt())/
max(rec.pt(),gen.pt()) < 0.3:
return False
306 leps = event.inclusiveLeptons
if self.cfg_ana.match_inclusiveLeptons
else event.selectedLeptons
308 event.genleps + event.gentauleps,
309 deltaRMax = 1.2, filter = plausible)
312 lep.mcMatchId = (gen.sourceId
if gen !=
None else 0)
313 lep.mcMatchTau = (gen
in event.gentauleps
if gen
else -99)
316 for i
in xrange( particle.numberOfMothers() ):
317 mom = particle.mother(i)
318 momid =
abs(mom.pdgId())
319 if momid / 1000 == bid
or momid / 100 == bid
or momid == bid:
321 elif mom.status() == 2
and self.
isFromB(mom, done=done):
326 event.anyLeptons = [ x
for x
in event.genParticles
if x.status() == 1
and abs(x.pdgId())
in [11,13] ]
327 leps = event.inclusiveLeptons
if hasattr(event,
'inclusiveLeptons')
else event.selectedLeptons
331 lep.mcMatchAny_gp = gen
333 if self.
isFromB(gen): lep.mcMatchAny = 5
334 elif self.
isFromB(gen,bid=4): lep.mcMatchAny = 4
335 else: lep.mcMatchAny = 1
339 if gen !=
None and hasattr(lep,
'mcMatchId')
and lep.mcMatchId == 0:
341 elif not hasattr(lep,
'mcMatchId'):
343 if not hasattr(lep,
'mcMatchTau'): lep.mcMatchTau = 0
346 self.readCollections( event.input )
347 self.counters.counter(
'events').inc(
'all events')
352 if self.cfg_comp.isMC
and self.cfg_ana.do_mc_match:
359 setattr(LeptonAnalyzer,
"defaultConfig",cfg.Analyzer(
361 class_object=LeptonAnalyzer,
363 muons=
'slimmedMuons',
364 electrons=
'slimmedElectrons',
365 rhoMuon=
'fixedGridRhoFastjetAll',
366 rhoElectron =
'fixedGridRhoFastjetAll',
369 doMuScleFitCorrections=
False,
370 doRochesterCorrections=
False,
371 doElectronScaleCorrections=
False,
372 doSegmentBasedMuonCleaning=
False,
374 inclusive_muon_id =
"POG_ID_Loose",
375 inclusive_muon_pt = 3,
376 inclusive_muon_eta = 2.4,
377 inclusive_muon_dxy = 0.5,
378 inclusive_muon_dz = 1.0,
380 loose_muon_id =
"POG_ID_Loose",
382 loose_muon_eta = 2.4,
383 loose_muon_dxy = 0.05,
385 loose_muon_relIso = 0.4,
387 inclusive_electron_id =
"",
388 inclusive_electron_pt = 5,
389 inclusive_electron_eta = 2.5,
390 inclusive_electron_dxy = 0.5,
391 inclusive_electron_dz = 1.0,
392 inclusive_electron_lostHits = 1.0,
394 loose_electron_id =
"",
395 loose_electron_pt = 7,
396 loose_electron_eta = 2.4,
397 loose_electron_dxy = 0.05,
398 loose_electron_dz = 0.2,
399 loose_electron_relIso = 0.4,
400 loose_electron_lostHits = 1.0,
402 mu_isoCorr =
"rhoArea" ,
403 mu_effectiveAreas =
"Phys14_25ns_v1",
405 ele_isoCorr =
"rhoArea" ,
406 el_effectiveAreas =
"Phys14_25ns_v1" ,
407 ele_tightId =
"Cuts_2012" ,
409 min_dr_electron_muon = 0.02,
412 match_inclusiveLeptons =
False,
Abs< T >::type abs(const T &t)
double deltaR(double eta1, double eta2, double phi1, double phi2)
eleEffectiveArea
Duplicate removal for fast sim (to be checked if still necessary in latest greatest 5...
def matchObjectCollection3