1 from __future__
import print_function
8 from ROOT
import TLorentzVector
11 from PhysicsTools.Heppy.analyzers.core.Analyzer
import Analyzer
12 from PhysicsTools.HeppyCore.framework.event
import Event
13 from PhysicsTools.HeppyCore.statistics.counter
import Counter, Counters
14 from PhysicsTools.Heppy.analyzers.core.AutoHandle
import AutoHandle
15 from PhysicsTools.Heppy.physicsobjects.Photon
import Photon
16 from PhysicsTools.Heppy.physicsutils.PhotonCalibrator
import Run2PhotonCalibrator
20 import PhysicsTools.HeppyCore.framework.config
as cfg
26 def __init__(self, cfg_ana, cfg_comp, looperName ):
27 super(PhotonAnalyzer,self).
__init__(cfg_ana,cfg_comp,looperName)
28 self.
etaCentral = self.cfg_ana.etaCentral
if hasattr(self.cfg_ana,
'etaCentral')
else 9999
35 if self.cfg_ana.doPhotonScaleCorrections:
36 conf = cfg_ana.doPhotonScaleCorrections
40 conf[
'isSync']
if 'isSync' in conf
else False,
45 self.handles[
'rhoPhoton'] = AutoHandle( self.cfg_ana.rhoPhoton,
'double')
51 self.handles[
'photons'] = AutoHandle( self.cfg_ana.photons,
'std::vector<pat::Photon>')
52 self.mchandles[
'packedGen'] = AutoHandle(
'packedGenParticles',
'std::vector<pat::PackedGenParticle>' )
53 self.mchandles[
'prunedGen'] = AutoHandle(
'prunedGenParticles',
'std::vector<reco::GenParticle>' )
55 self.handles[
'packedCandidates'] = AutoHandle(
'packedPFCandidates',
'std::vector<pat::PackedCandidate>')
56 self.handles[
'jets'] = AutoHandle(
"slimmedJets",
'std::vector<pat::Jet>' )
60 super(PhotonAnalyzer,self).
beginLoop(setup)
61 self.counters.addCounter(
'events')
62 count = self.counters.
counter(
'events')
63 count.register(
'all events')
64 count.register(
'has >=1 gamma at preselection')
65 count.register(
'has >=1 selected gamma')
68 event.allphotons =
map( Photon, self.handles[
'photons'].product() )
69 event.allphotons.sort(key =
lambda l : l.pt(), reverse =
True)
71 event.selectedPhotons = []
72 event.selectedPhotonsCentral = []
76 self.
IsolationComputer.setPackedCandidates(self.handles[
'packedCandidates'].product(), -1, 0.1, 0.2)
79 if self.cfg_ana.doPhotonScaleCorrections:
80 for gamma
in event.allphotons:
84 for gamma
in event.allphotons:
85 if gamma.pt() < self.cfg_ana.ptMin:
continue 86 if abs(gamma.eta()) > self.cfg_ana.etaMax:
continue 89 gamma.rho =
float(self.handles[
'rhoPhoton'].product()[0])
91 if abs(gamma.eta()) < 1.0: gamma.EffectiveArea03 = [ 0.0234, 0.0053, 0.078 ]
92 elif abs(gamma.eta()) < 1.479: gamma.EffectiveArea03 = [ 0.0189, 0.0103, 0.0629 ]
93 elif abs(gamma.eta()) < 2.0: gamma.EffectiveArea03 = [ 0.0171, 0.0057, 0.0264 ]
94 elif abs(gamma.eta()) < 2.2: gamma.EffectiveArea03 = [ 0.0129, 0.0070, 0.0462 ]
95 elif abs(gamma.eta()) < 2.3: gamma.EffectiveArea03 = [ 0.0110, 0.0152, 0.0740 ]
96 elif abs(gamma.eta()) < 2.4: gamma.EffectiveArea03 = [ 0.0074, 0.0232, 0.0924 ]
97 else: gamma.EffectiveArea03 = [ 0.0035, 0.1709, 0.1484 ]
102 gamma.relIso = (
max(gamma.chargedHadronIso()-gamma.rho*gamma.EffectiveArea03[0],0) +
max(gamma.neutralHadronIso()-gamma.rho*gamma.EffectiveArea03[1],0) +
max(gamma.photonIso() - gamma.rho*gamma.EffectiveArea03[2],0))/gamma.pt()
105 """Create an integer equal to 1-2-3 for (loose,medium,tight)""" 108 if gamma.photonID(X%
"Loose"):
112 if gamma.photonID(X%
"Tight"):
116 gamma.idCutBased = idWP(gamma,
"PhotonCutBasedID%s")
119 keepThisPhoton =
True 121 if self.cfg_ana.gammaID==
"PhotonCutBasedIDLoose_CSA14" or self.cfg_ana.gammaID==
"PhotonCutBasedIDLoose_PHYS14" :
122 gamma.idCutBased = gamma.photonIDCSA14(self.cfg_ana.gammaID)
124 keepThisPhoton = gamma.photonIDCSA14(self.cfg_ana.gammaID,
True)
126 if gamma.hasPixelSeed():
127 keepThisPhoton =
False 129 elif "NoIso" in self.cfg_ana.gammaID:
130 idName = re.split(
'_NoIso',self.cfg_ana.gammaID)
131 keepThisPhoton = gamma.passPhotonID(idName[0],self.cfg_ana.conversionSafe_eleVeto)
132 basenameID = re.split(
'_looseSieie',idName[0])
133 gamma.idCutBased = gamma.passPhotonID(basenameID[0],self.cfg_ana.conversionSafe_eleVeto)
139 keepThisPhoton = gamma.passPhotonID(self.cfg_ana.gammaID,self.cfg_ana.conversionSafe_eleVeto)
and gamma.passPhotonIso(self.cfg_ana.gammaID,self.cfg_ana.gamma_isoCorr)
142 event.selectedPhotons.append(gamma)
145 event.selectedPhotonsCentral.append(gamma)
147 event.selectedPhotons.sort(key =
lambda l : l.pt(), reverse =
True)
148 event.selectedPhotonsCentral.sort(key =
lambda l : l.pt(), reverse =
True)
150 self.counters.
counter(
'events').inc(
'all events')
151 if foundPhoton: self.counters.
counter(
'events').inc(
'has >=1 gamma at preselection')
152 if len(event.selectedPhotons): self.counters.
counter(
'events').inc(
'has >=1 selected gamma')
155 event.genPhotons = [ x
for x
in event.genParticles
if x.status() == 1
and abs(x.pdgId()) == 22 ]
156 event.genPhotonsWithMom = [ x
for x
in event.genPhotons
if x.numberOfMothers()>0 ]
157 event.genPhotonsWithoutMom = [ x
for x
in event.genPhotons
if x.numberOfMothers()==0 ]
158 event.genPhotonsMatched = [ x
for x
in event.genPhotonsWithMom
if abs(x.mother(0).
pdgId())<23
or x.mother(0).
pdgId()==2212 ]
161 packedGenParts = [ p
for p
in self.mchandles[
'packedGen'].product()
if abs(p.eta()) < 3.1 ]
162 partons = [ p
for p
in self.mchandles[
'prunedGen'].product()
if (p.status()==23
or p.status()==22)
and abs(p.pdgId())<22 ]
163 for gamma
in event.allphotons:
166 if gen
and gen.pt()>=0.5*gamma.pt()
and gen.pt()<=2.*gamma.pt():
170 for part
in packedGenParts:
171 if abs(part.pdgId())==12:
continue 172 if abs(part.pdgId())==14:
continue 173 if abs(part.pdgId())==16:
continue 174 if abs(part.pdgId())==18:
continue 175 deltar =
deltaR(gen.eta(), gen.phi(), part.eta(), part.phi())
182 if sumPt03<0. : sumPt03=0.
183 if sumPt04<0. : sumPt04=0.
184 gamma.genIso03 = sumPt03
185 gamma.genIso04 = sumPt04
189 deltar =
deltaR(gen.eta(), gen.phi(), p.eta(), p.phi())
190 if deltar < deltaRmin:
192 gamma.drMinParton = deltaRmin
194 genNoMom = matchNoMom[gamma]
199 for part
in packedGenParts:
200 if abs(part.pdgId())==12:
continue 201 if abs(part.pdgId())==14:
continue 202 if abs(part.pdgId())==16:
continue 203 if abs(part.pdgId())==18:
continue 204 deltar =
deltaR(genNoMom.eta(), genNoMom.phi(), part.eta(), part.phi())
209 sumPt03 -= genNoMom.pt()
210 sumPt04 -= genNoMom.pt()
211 if sumPt03<0. : sumPt03=0.
212 if sumPt04<0. : sumPt04=0.
213 gamma.genIso03 = sumPt03
214 gamma.genIso04 = sumPt04
218 deltar =
deltaR(genNoMom.eta(), genNoMom.phi(), p.eta(), p.phi())
219 if deltar < deltaRmin:
221 gamma.drMinParton = deltaRmin
226 gamma.drMinParton = -1.
234 for part
in particles:
235 if deltaR(eta, phi, part.eta(), part.phi()) < deltar:
246 if self.
checkMatch( eta, phi, jets, 2.*deltarmax ):
249 if self.
checkMatch( eta, phi, photons, 2.*deltarmax ):
252 if self.
checkMatch( eta, phi, event.selectedLeptons, deltarmax ):
258 if deltaR(eta, phi, part.eta(), part.phi()) > deltarmax :
continue 271 patcands = self.handles[
'packedCandidates'].product()
272 jets = self.handles[
'jets'].product()
274 charged = [ p
for p
in patcands
if ( p.charge() != 0
and abs(p.pdgId())>20
and abs(p.dz())<=0.1
and p.fromPV()>1
and p.trackHighPurity() ) ]
275 photons10 = [ p
for p
in patcands
if ( p.pdgId() == 22
and p.pt()>10. ) ]
276 jets20 = [ j
for j
in jets
if j.pt() > 20
and abs(j.eta())<2.5 ]
278 for gamma
in event.allphotons:
280 etaPhot = gamma.eta()
281 phiPhot = gamma.eta()
283 phiRC = phiPhot + 0.5*pi
288 gamma.chHadIsoRC03 = self.
computeRandomCone( event, etaPhot, phiRC, 0.3, charged, jets20, photons10 )
289 gamma.chHadIsoRC04 = self.
computeRandomCone( event, etaPhot, phiRC, 0.4, charged, jets20, photons10 )
293 phiRC = phiPhot - 0.5*pi
297 if gamma.chHadIsoRC03<0. : gamma.chHadIsoRC03 = self.
computeRandomCone( event, etaPhot, phiRC, 0.3, charged, jets20, photons10 )
298 if gamma.chHadIsoRC04<0. : gamma.chHadIsoRC04 = self.
computeRandomCone( event, etaPhot, phiRC, 0.4, charged, jets20, photons10 )
303 gamma.ftprAbsIsoCharged03 = self.
IsolationComputer.chargedAbsIso(gamma.physObj, 0.3, 0, 0.0);
304 gamma.ftprAbsIsoPho03 = self.
IsolationComputer.photonAbsIsoRaw( gamma.physObj, 0.3, 0, 0.0);
305 gamma.ftprAbsIsoNHad03 = self.
IsolationComputer.neutralHadAbsIsoRaw( gamma.physObj, 0.3, 0, 0.0);
306 gamma.ftprAbsIso03 = gamma.ftprAbsIsoCharged03 + gamma.ftprAbsIsoPho03 + gamma.ftprAbsIsoNHad03
307 if self.cfg_ana.gamma_isoCorr ==
"rhoArea":
308 gamma.ftprAbsIso03 = (
max(gamma.ftprAbsIsoCharged03-gamma.rho*gamma.EffectiveArea03[0],0) +
max(gamma.ftprAbsIsoPho03-gamma.rho*gamma.EffectiveArea03[1],0) +
max(gamma.ftprAbsIsoNHad03 - gamma.rho*gamma.EffectiveArea03[2],0))
309 elif self.cfg_ana.gamma_isoCorr !=
'raw':
310 raise RuntimeError(
"Unsupported gamma_isoCorr name '" +
str(self.cfg_ana.gamma_isoCorr) +
"'! For now only 'rhoArea', 'raw' are supported.")
311 gamma.ftprRelIso03 = gamma.ftprAbsIso03/gamma.pt()
314 print(
'----------------')
315 if len(event.selectedPhotons)>0:
316 print(
'lenght: ',len(event.selectedPhotons))
317 print(
'gamma candidate pt: ',event.selectedPhotons[0].
pt())
318 print(
'gamma candidate eta: ',event.selectedPhotons[0].
eta())
319 print(
'gamma candidate phi: ',event.selectedPhotons[0].phi())
320 print(
'gamma candidate mass: ',event.selectedPhotons[0].
mass())
321 print(
'gamma candidate HoE: ',event.selectedPhotons[0].hOVERe())
322 print(
'gamma candidate r9: ',event.selectedPhotons[0].full5x5_r9())
326 print(
'gamma candidate gamma iso: ',event.selectedPhotons[0].
photonIso())
327 print(
'gamma idCutBased',event.selectedPhotons[0].idCutBased)
331 self.readCollections( event.input )
335 if self.cfg_ana.do_randomCone:
338 if not self.cfg_comp.isMC:
341 if self.cfg_ana.do_mc_match
and hasattr(event,
'genParticles'):
348 setattr(PhotonAnalyzer,
"defaultConfig",cfg.Analyzer(
349 class_object=PhotonAnalyzer,
350 photons=
'slimmedPhotons',
354 doPhotonScaleCorrections=
False,
355 gammaID =
"PhotonCutBasedIDLoose_CSA14",
356 rhoPhoton =
'fixedGridRhoFastjetAll',
357 gamma_isoCorr =
'rhoArea',
359 doFootprintRemovedIsolation =
False,
360 packedCandidates =
'packedPFCandidates',
361 footprintRemovedIsolationPUCorr =
'rhoArea',
362 conversionSafe_eleVeto =
False,
364 do_randomCone =
False,
def matchPhotons(self, event)
def attachFootprintRemovedIsolation(self, gamma)
doFootprintRemovedIsolation
def printInfo(self, event)
def randomCone(self, event)
def makePhotons(self, event)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Abs< T >::type abs(const T &t)
def __init__(self, cfg_ana, cfg_comp, looperName)
def computeRandomCone(self, event, eta, phi, deltarmax, charged, jets, photons)
def checkMatch(self, eta, phi, particles, deltar)
footprintRemovedIsolationPUCorr
def beginLoop(self, setup)
def matchObjectCollection3