Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:28

0001 from __future__ import print_function
0002 from PhysicsTools.Heppy.physicsobjects.PhysicsObject import *
0003 from math import exp
0004 import re
0005 
0006 import ROOT
0007 
0008 class Photon(PhysicsObject ):
0009 
0010     def __init__(self, *args, **kwargs):
0011         '''Initializing rho to None. The user is responsible for setting it to the right value 
0012         to get the rho-corrected isolation.'''
0013         super(Photon, self).__init__(*args, **kwargs)
0014         self._physObjInit()
0015 
0016     def _physObjInit(self):
0017         self.rho = None
0018 
0019 
0020     def hOVERe(self):
0021         return self.physObj.hadTowOverEm() 
0022 
0023     def r9(self):
0024         return self.physObj.r9()
0025 
0026     def sigmaIetaIeta(self):
0027         return self.physObj.sigmaIetaIeta()
0028 
0029     def full5x5_r9(self):
0030         return self.physObj.full5x5_r9()
0031 
0032     def full5x5_sigmaIetaIeta(self):
0033         return self.physObj.full5x5_sigmaIetaIeta()
0034 
0035     def chargedHadronIso(self, corr=None):
0036         isoCharged = self.ftprAbsIsoCharged03 if hasattr(self,'ftprAbsIsoCharged03') else self.physObj.chargedHadronIso()
0037         if corr is None or corr == "": return isoCharged
0038         elif corr == "rhoArea": return max(isoCharged-self.rho*self.EffectiveArea03[0],0)
0039         else: raise RuntimeError("Photon isolation correction '%s' not yet implemented in Photon.py" % corr)
0040 
0041     def neutralHadronIso(self, corr=None):
0042         isoNHad = self.ftprAbsIsoNHad03 if hasattr(self,'ftprAbsIsoNHad03') else self.physObj.neutralHadronIso()
0043         if corr is None or corr == "": return isoNHad
0044         elif corr == "rhoArea": return max(isoNHad-self.rho*self.EffectiveArea03[1],0)
0045         else: raise RuntimeError("Photon isolation correction '%s' not yet implemented in Photon.py" % corr)
0046 
0047     def photonIso(self, corr=None):
0048         isoPho = self.ftprAbsIsoPho03 if hasattr(self,'ftprAbsIsoPho03') else self.physObj.photonIso()
0049         if corr is None or corr == "": return isoPho
0050         elif corr == "rhoArea": return max(isoPho-self.rho*self.EffectiveArea03[2],0)
0051         else: raise RuntimeError("Photon isolation correction '%s' not yet implemented in Photon.py" % corr)
0052 
0053     def photonIDCSA14(self, name, sidebands=False):
0054         keepThisPhoton = True
0055         sigmaThresh  = 999
0056         hovereThresh = 999
0057         if name == "PhotonCutBasedIDLoose_CSA14":
0058             if abs(self.physObj.eta())<1.479 :
0059                 sigmaThresh  = 0.010
0060                 hovereThresh = 0.0559
0061             else :
0062                 sigmaThresh  = 0.030
0063                 hovereThresh = 0.049
0064         elif name == "PhotonCutBasedIDLoose_PHYS14":
0065             if abs(self.physObj.eta())<1.479 :
0066                 sigmaThresh  = 0.0106
0067                 hovereThresh = 0.048
0068             else :
0069                 sigmaThresh  = 0.0266
0070                 hovereThresh = 0.069
0071         else :
0072           print("WARNING! Unkown photon ID! Will return true!") 
0073           return True
0074 
0075         if sidebands:
0076           if abs(self.physObj.eta())<1.479 :
0077             sigmaThresh = 0.015
0078           else :
0079             sigmaThresh = 0.035
0080 
0081         if self.full5x5_sigmaIetaIeta() > sigmaThresh  : keepThisPhoton = False
0082         if self.hOVERe()                > hovereThresh : keepThisPhoton = False
0083 
0084         return keepThisPhoton
0085 
0086     def CutBasedIDWP( self, name):
0087         # recommeneded PHYS14 working points from POG
0088         WPs = {
0089         # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#Pointers_for_PHYS14_selection_im
0090         "POG_PHYS14_25ns_Loose": {"conversionVeto": [True,True], "H/E":[0.028,0.093],"sigmaIEtaIEta":[0.0107,0.0272],
0091         "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]]},
0092         
0093         # https://twiki.cern.ch/twiki/bin/view/CMS/CutBasedPhotonIdentificationRun2?rev=11
0094         "POG_PHYS14_25ns_Loose_old": {"conversionVeto": [True,True], "H/E":[0.048,0.069],"sigmaIEtaIEta":[0.0106,0.0266],
0095         "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]]},
0096         
0097         "POG_PHYS14_25ns_Medium": {"conversionVeto": [True,True], "H/E":[0.012,0.023],"sigmaIEtaIEta":[0.0100,0.0267],
0098         "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]]},
0099         
0100         "POG_PHYS14_25ns_Tight": {"conversionVeto": [True,True], "H/E":[0.010,0.015],"sigmaIEtaIEta":[0.0100,0.0265],
0101         "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]]},
0102 
0103         # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#SPRING15_selections_bunch_crossing
0104         "POG_SPRING15_50ns_Loose": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0103,0.0277],
0105         "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]]},
0106 
0107         "POG_SPRING15_50ns_Medium": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0100,0.0267],
0108         "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]]},
0109 
0110         "POG_SPRING15_50ns_Tight": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0100,0.0267],
0111         "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]]},
0112 
0113         # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#SPRING15_selections_25_ns
0114         "POG_SPRING15_25ns_Loose": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0102,0.0274],
0115         "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]]},
0116 
0117         "POG_SPRING15_25ns_Medium": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0102,0.0268],
0118         "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]]},
0119 
0120         "POG_SPRING15_25ns_Tight": {"conversionVeto": [True,True], "H/E":[0.05,0.05],"sigmaIEtaIEta":[0.0100,0.0268],
0121         "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]]},
0122 
0123         # https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2#CSA14_selections_for_20_bx_25_sc
0124         "POG_CSA14_25ns_Loose": {"conversionVeto": [True,True], "H/E":[0.553,0.062],"sigmaIEtaIEta":[0.0099,0.0284],
0125         "chaHadIso":[2.49,1.04],"neuHadIso":[[15.43,0.007],[19.71,0.0129]],"phoIso":[[9.42,0.0033],[11.88,0.0108]]},
0126         
0127         "POG_CSA14_25ns_Medium": {"conversionVeto": [True,True], "H/E":[0.058,0.020],"sigmaIEtaIEta":[0.0099,0.0268],
0128         "chaHadIso":[1.91,0.82],"neuHadIso":[[4.66,0.007],[14.65,0.0129]],"phoIso":[[4.29,0.0033],[4.06,0.0108]]},
0129         
0130         "POG_CSA14_25ns_Tight": {"conversionVeto": [True,True], "H/E":[0.019,0.016],"sigmaIEtaIEta":[0.0099,0.0263],
0131         "chaHadIso":[1.61,0.69],"neuHadIso":[[3.98,0.007],[4.52,0.0129]],"phoIso":[[3.01,0.0033],[3.61,0.0108]]},
0132 
0133 
0134         }
0135         
0136         baseWP = re.split('_',name)
0137         if "looseSieie" in baseWP[-1]: 
0138             baseWP.pop()
0139             WPs["_".join(baseWP)]["sigmaIEtaIEta"] = [0.015,0.035]
0140 
0141         return WPs["_".join(baseWP)]
0142 
0143 
0144     def etaRegionID(self):
0145         #return 0 if the photon is in barrel and 1 if in endcap
0146         if abs(self.physObj.eta())<1.479 :
0147             idForBarrel = 0
0148         else:
0149             idForBarrel = 1
0150         return idForBarrel
0151 
0152     def calScaledIsoValueLin(self,offset,slope):
0153         return slope*self.pt()+offset
0154 
0155     def calScaledIsoValueQuadr(self,offset,term_1,term_2):
0156         return offset + term_1*self.pt() + term_2*pow(self.pt(),2)
0157 
0158     def calScaledIsoValueExp(self,offset,slope_exp,offset_exp):
0159         return offset + exp(slope_exp*self.pt()+offset_exp)
0160 
0161     def passPhotonID(self,name,conversionSafe_eleVeto=False):
0162         
0163         idForBarrel = self.etaRegionID()
0164         passPhotonID = True
0165 
0166         if self.CutBasedIDWP(name)["conversionVeto"][idForBarrel]:
0167             if (conversionSafe_eleVeto==False and self.physObj.hasPixelSeed()) or (conversionSafe_eleVeto==True and self.physObj.passElectronVeto()==False):
0168                 passPhotonID = False
0169 
0170         if self.CutBasedIDWP(name)["H/E"][idForBarrel] < self.hOVERe():
0171             passPhotonID = False
0172 
0173         if self.CutBasedIDWP(name)["sigmaIEtaIEta"][idForBarrel] < self.full5x5_sigmaIetaIeta():
0174             passPhotonID = False
0175 
0176         return passPhotonID
0177 
0178     def passPhotonIso(self,name,isocorr):
0179 
0180         idForBarrel = self.etaRegionID()
0181         passPhotonIso = True
0182 
0183         if self.CutBasedIDWP(name)["chaHadIso"][idForBarrel] < self.chargedHadronIso(isocorr):
0184             passPhotonIso = False
0185 
0186         if "POG_PHYS14_25ns" in name and idForBarrel == 0:
0187             if self.calScaledIsoValueExp(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
0188                 passPhotonIso = False
0189         elif "POG_SPRING15_50ns" in name:
0190              if self.calScaledIsoValueExp(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
0191                  passPhotonIso = False
0192         elif "POG_SPRING15_25ns" in name:
0193              if self.calScaledIsoValueQuadr(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
0194                  passPhotonIso = False
0195         else:
0196             if self.calScaledIsoValueLin(*self.CutBasedIDWP(name)["neuHadIso"][idForBarrel]) < self.neutralHadronIso(isocorr):
0197                 passPhotonIso = False
0198 
0199         if self.calScaledIsoValueLin(*self.CutBasedIDWP(name)["phoIso"][idForBarrel]) < self.photonIso(isocorr):
0200             passPhotonIso = False
0201         
0202         return passPhotonIso
0203 
0204     pass
0205 
0206 setattr(ROOT.pat.Photon, "recoPhotonIso", ROOT.reco.Photon.photonIso)
0207 setattr(ROOT.pat.Photon, "recoNeutralHadronIso", ROOT.reco.Photon.neutralHadronIso)
0208 setattr(ROOT.pat.Photon, "recoChargedHadronIso", ROOT.reco.Photon.chargedHadronIso)