CMS 3D CMS Logo

Photon.py
Go to the documentation of this file.
1 from __future__ import print_function
3 from math import exp
4 import re
5 
6 import ROOT
7 
9 
10  def __init__(self, *args, **kwargs):
11  '''Initializing rho to None. The user is responsible for setting it to the right value
12  to get the rho-corrected isolation.'''
13  super(Photon, self).__init__(*args, **kwargs)
14  self._physObjInit()
15 
16  def _physObjInit(self):
17  self.rho = None
18 
19 
20  def hOVERe(self):
21  return self.physObj.hadTowOverEm()
22 
23  def r9(self):
24  return self.physObj.r9()
25 
26  def sigmaIetaIeta(self):
27  return self.physObj.sigmaIetaIeta()
28 
29  def full5x5_r9(self):
30  return self.physObj.full5x5_r9()
31 
33  return self.physObj.full5x5_sigmaIetaIeta()
34 
35  def chargedHadronIso(self, corr=None):
36  isoCharged = self.ftprAbsIsoCharged03 if hasattr(self,'ftprAbsIsoCharged03') else self.physObj.chargedHadronIso()
37  if corr is None or corr == "": return isoCharged
38  elif corr == "rhoArea": return max(isoCharged-self.rho*self.EffectiveArea03[0],0)
39  else: raise RuntimeError("Photon isolation correction '%s' not yet implemented in Photon.py" % corr)
40 
41  def neutralHadronIso(self, corr=None):
42  isoNHad = self.ftprAbsIsoNHad03 if hasattr(self,'ftprAbsIsoNHad03') else self.physObj.neutralHadronIso()
43  if corr is None or corr == "": return isoNHad
44  elif corr == "rhoArea": return max(isoNHad-self.rho*self.EffectiveArea03[1],0)
45  else: raise RuntimeError("Photon isolation correction '%s' not yet implemented in Photon.py" % corr)
46 
47  def photonIso(self, corr=None):
48  isoPho = self.ftprAbsIsoPho03 if hasattr(self,'ftprAbsIsoPho03') else self.physObj.photonIso()
49  if corr is None or corr == "": return isoPho
50  elif corr == "rhoArea": return max(isoPho-self.rho*self.EffectiveArea03[2],0)
51  else: raise RuntimeError("Photon isolation correction '%s' not yet implemented in Photon.py" % corr)
52 
53  def photonIDCSA14(self, name, sidebands=False):
54  keepThisPhoton = True
55  sigmaThresh = 999
56  hovereThresh = 999
57  if name == "PhotonCutBasedIDLoose_CSA14":
58  if abs(self.physObj.eta())<1.479 :
59  sigmaThresh = 0.010
60  hovereThresh = 0.0559
61  else :
62  sigmaThresh = 0.030
63  hovereThresh = 0.049
64  elif name == "PhotonCutBasedIDLoose_PHYS14":
65  if abs(self.physObj.eta())<1.479 :
66  sigmaThresh = 0.0106
67  hovereThresh = 0.048
68  else :
69  sigmaThresh = 0.0266
70  hovereThresh = 0.069
71  else :
72  print("WARNING! Unkown photon ID! Will return true!")
73  return True
74 
75  if sidebands:
76  if abs(self.physObj.eta())<1.479 :
77  sigmaThresh = 0.015
78  else :
79  sigmaThresh = 0.035
80 
81  if self.full5x5_sigmaIetaIeta() > sigmaThresh : keepThisPhoton = False
82  if self.hOVERe() > hovereThresh : keepThisPhoton = False
83 
84  return keepThisPhoton
85 
86  def CutBasedIDWP( self, name):
87  # recommeneded PHYS14 working points from POG
88  WPs = {
89  # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#Pointers_for_PHYS14_selection_im
90  "POG_PHYS14_25ns_Loose": {"conversionVeto": [True,True], "H/E":[0.028,0.093],"sigmaIEtaIEta":[0.0107,0.0272],
91  "chaHadIso":[2.67,1.79],"neuHadIso":[[7.23,0.0028,0.5408],[8.89,0.01725]],"phoIso":[[2.11,0.0014],[3.09,0.0091]]},
92 
93  # https://twiki.cern.ch/twiki/bin/view/CMS/CutBasedPhotonIdentificationRun2?rev=11
94  "POG_PHYS14_25ns_Loose_old": {"conversionVeto": [True,True], "H/E":[0.048,0.069],"sigmaIEtaIEta":[0.0106,0.0266],
95  "chaHadIso":[2.56,3.12],"neuHadIso":[[3.74,0.0025,0.],[17.11,0.0118,0.]],"phoIso":[[2.68,0.001],[2.70,0.0059]]},
96 
97  "POG_PHYS14_25ns_Medium": {"conversionVeto": [True,True], "H/E":[0.012,0.023],"sigmaIEtaIEta":[0.0100,0.0267],
98  "chaHadIso":[1.79,1.09],"neuHadIso":[[0.16,0.0028,0.5408],[4.31,0.0172]],"phoIso":[[1.90,0.0014],[1.90,0.0091]]},
99 
100  "POG_PHYS14_25ns_Tight": {"conversionVeto": [True,True], "H/E":[0.010,0.015],"sigmaIEtaIEta":[0.0100,0.0265],
101  "chaHadIso":[1.66,1.04],"neuHadIso":[[0.14,0.0028,0.5408],[3.89,0.0172]],"phoIso":[[1.40,0.0014],[1.40,0.0091]]},
102 
103  # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#SPRING15_selections_bunch_crossing
104  "POG_SPRING15_50ns_Loose": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0103,0.0277],
105  "chaHadIso":[2.44,1.84],"neuHadIso":[[2.57,0.0044,0.5809],[4.00, 0.0040,0.9402]],"phoIso":[[1.92,0.0043],[2.15,0.0041]]},
106 
107  "POG_SPRING15_50ns_Medium": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0100,0.0267],
108  "chaHadIso":[1.31,1.25],"neuHadIso":[[0.60,0.0044,0.5809],[1.65, 0.0040,0.9402]],"phoIso":[[1.33,0.0043],[1.02,0.0041]]},
109 
110  "POG_SPRING15_50ns_Tight": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0100,0.0267],
111  "chaHadIso":[0.91,0.65],"neuHadIso":[[0.33,0.0044,0.5809],[0.93, 0.0040,0.9402]],"phoIso":[[0.61,0.0043],[0.54,0.0041]]},
112 
113  # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#SPRING15_selections_25_ns
114  "POG_SPRING15_25ns_Loose": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0102,0.0274],
115  "chaHadIso":[3.32,1.97],"neuHadIso":[[1.92,0.0014,0.000019],[11.86, 0.00139,0.000025]],"phoIso":[[0.81,0.0053],[0.83,0.0034]]},
116 
117  "POG_SPRING15_25ns_Medium": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0102,0.0268],
118  "chaHadIso":[1.37,1.10],"neuHadIso":[[1.06,0.0014,0.000019],[2.69, 0.00139,0.000025]],"phoIso":[[0.28,0.0053],[0.39,0.0034]]},
119 
120  "POG_SPRING15_25ns_Tight": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0100,0.0268],
121  "chaHadIso":[0.76,0.56],"neuHadIso":[[0.97,0.0014,0.000019],[2.09, 0.00139,0.000025]],"phoIso":[[0.08,0.0053],[0.16,0.0034]]},
122 
123  # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#CSA14_selections_for_20_bx_25_sc
124  "POG_CSA14_25ns_Loose": {"conversionVeto": [True,True], "H/E":[0.553,0.062],"sigmaIEtaIEta":[0.0099,0.0284],
125  "chaHadIso":[2.49,1.04],"neuHadIso":[[15.43,0.007],[19.71,0.0129]],"phoIso":[[9.42,0.0033],[11.88,0.0108]]},
126 
127  "POG_CSA14_25ns_Medium": {"conversionVeto": [True,True], "H/E":[0.058,0.020],"sigmaIEtaIEta":[0.0099,0.0268],
128  "chaHadIso":[1.91,0.82],"neuHadIso":[[4.66,0.007],[14.65,0.0129]],"phoIso":[[4.29,0.0033],[4.06,0.0108]]},
129 
130  "POG_CSA14_25ns_Tight": {"conversionVeto": [True,True], "H/E":[0.019,0.016],"sigmaIEtaIEta":[0.0099,0.0263],
131  "chaHadIso":[1.61,0.69],"neuHadIso":[[3.98,0.007],[4.52,0.0129]],"phoIso":[[3.01,0.0033],[3.61,0.0108]]},
132 
133 
134  }
135 
136  baseWP = re.split('_',name)
137  if "looseSieie" in baseWP[-1]:
138  baseWP.pop()
139  WPs["_".join(baseWP)]["sigmaIEtaIEta"] = [0.015,0.035]
140 
141  return WPs["_".join(baseWP)]
142 
143 
144  def etaRegionID(self):
145  #return 0 if the photon is in barrel and 1 if in endcap
146  if abs(self.physObj.eta())<1.479 :
147  idForBarrel = 0
148  else:
149  idForBarrel = 1
150  return idForBarrel
151 
152  def calScaledIsoValueLin(self,offset,slope):
153  return slope*self.pt()+offset
154 
155  def calScaledIsoValueQuadr(self,offset,term_1,term_2):
156  return offset + term_1*self.pt() + term_2*pow(self.pt(),2)
157 
158  def calScaledIsoValueExp(self,offset,slope_exp,offset_exp):
159  return offset + exp(slope_exp*self.pt()+offset_exp)
160 
161  def passPhotonID(self,name,conversionSafe_eleVeto=False):
162 
163  idForBarrel = self.etaRegionID()
164  passPhotonID = True
165 
166  if self.CutBasedIDWP(name)["conversionVeto"][idForBarrel]:
167  if (conversionSafe_eleVeto==False and self.physObj.hasPixelSeed()) or (conversionSafe_eleVeto==True and self.physObj.passElectronVeto()==False):
168  passPhotonID = False
169 
170  if self.CutBasedIDWP(name)["H/E"][idForBarrel] < self.hOVERe():
171  passPhotonID = False
172 
173  if self.CutBasedIDWP(name)["sigmaIEtaIEta"][idForBarrel] < self.full5x5_sigmaIetaIeta():
174  passPhotonID = False
175 
176  return passPhotonID
177 
178  def passPhotonIso(self,name,isocorr):
179 
180  idForBarrel = self.etaRegionID()
181  passPhotonIso = True
182 
183  if self.CutBasedIDWP(name)["chaHadIso"][idForBarrel] < self.chargedHadronIso(isocorr):
184  passPhotonIso = False
185 
186  if "POG_PHYS14_25ns" in name and idForBarrel == 0:
187  if self.calScaledIsoValueExp(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
188  passPhotonIso = False
189  elif "POG_SPRING15_50ns" in name:
190  if self.calScaledIsoValueExp(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
191  passPhotonIso = False
192  elif "POG_SPRING15_25ns" in name:
193  if self.calScaledIsoValueQuadr(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
194  passPhotonIso = False
195  else:
196  if self.calScaledIsoValueLin(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
197  passPhotonIso = False
198 
199  if self.calScaledIsoValueLin(*self.CutBasedIDWP(name)["phoIso"][idForBarrel]) < self.photonIso(isocorr):
200  passPhotonIso = False
201 
202  return passPhotonIso
203 
204  pass
205 
206 setattr(ROOT.pat.Photon, "recoPhotonIso", ROOT.reco.Photon.photonIso)
207 setattr(ROOT.pat.Photon, "recoNeutralHadronIso", ROOT.reco.Photon.neutralHadronIso)
208 setattr(ROOT.pat.Photon, "recoChargedHadronIso", ROOT.reco.Photon.chargedHadronIso)
def photonIDCSA14(self, name, sidebands=False)
Definition: Photon.py:53
def _physObjInit(self)
Definition: Photon.py:16
def full5x5_sigmaIetaIeta(self)
Definition: Photon.py:32
def passPhotonID(self, name, conversionSafe_eleVeto=False)
Definition: Photon.py:161
def photonIso(self, corr=None)
Definition: Photon.py:47
def full5x5_r9(self)
Definition: Photon.py:29
def neutralHadronIso(self, corr=None)
Definition: Photon.py:41
def CutBasedIDWP(self, name)
Definition: Photon.py:86
def chargedHadronIso(self, corr=None)
Definition: Photon.py:35
def calScaledIsoValueExp(self, offset, slope_exp, offset_exp)
Definition: Photon.py:158
def sigmaIetaIeta(self)
Definition: Photon.py:26
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 passPhotonIso(self, name, isocorr)
Definition: Photon.py:178
def r9(self)
Definition: Photon.py:23
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
def calScaledIsoValueQuadr(self, offset, term_1, term_2)
Definition: Photon.py:155
def __init__(self, args, kwargs)
Definition: Photon.py:10
def hOVERe(self)
Definition: Photon.py:20
def calScaledIsoValueLin(self, offset, slope)
Definition: Photon.py:152
def etaRegionID(self)
Definition: Photon.py:144
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29