CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/EgammaAnalysis/ElectronTools/src/EGammaCutBasedEleId.cc

Go to the documentation of this file.
00001 #include "EgammaAnalysis/ElectronTools/interface/EGammaCutBasedEleId.h"
00002 #include "EgammaAnalysis/ElectronTools/interface/ElectronEffectiveArea.h"
00003 #include "RecoEgamma/EgammaTools/interface/ConversionTools.h"
00004 
00005 #include <algorithm>
00006 
00007 #ifndef STANDALONEID
00008 
00009 bool EgammaCutBasedEleId::PassWP(WorkingPoint workingPoint,
00010     const reco::GsfElectron &ele,
00011     const edm::Handle<reco::ConversionCollection> &conversions,
00012     const reco::BeamSpot &beamspot,
00013     const edm::Handle<reco::VertexCollection> &vtxs,
00014     const double &iso_ch,
00015     const double &iso_em,
00016     const double &iso_nh,
00017     const double &rho)
00018 {
00019 
00020     // get the mask
00021     unsigned int mask = TestWP(workingPoint, ele, conversions, beamspot, vtxs, iso_ch, iso_em, iso_nh, rho);
00022 
00023     // check if the desired WP passed
00024     if ((mask & PassAll) == PassAll) return true;
00025     return false;
00026 }
00027 
00028 bool EgammaCutBasedEleId::PassWP(WorkingPoint workingPoint,
00029     const reco::GsfElectronRef &ele,
00030     const edm::Handle<reco::ConversionCollection> &conversions,
00031     const reco::BeamSpot &beamspot,
00032     const edm::Handle<reco::VertexCollection> &vtxs,
00033     const double &iso_ch,
00034     const double &iso_em,
00035     const double &iso_nh,
00036     const double &rho)
00037 {
00038   return PassWP(workingPoint,*ele,conversions,beamspot,vtxs,iso_ch,iso_em,iso_nh,rho);
00039 }
00040 
00041 bool EgammaCutBasedEleId::PassTriggerCuts(TriggerWorkingPoint triggerWorkingPoint, const reco::GsfElectron &ele)
00042 {
00043 
00044     // get the variables
00045     bool isEB           = ele.isEB() ? true : false;
00046     float pt            = ele.pt();
00047     float dEtaIn        = ele.deltaEtaSuperClusterTrackAtVtx();
00048     float dPhiIn        = ele.deltaPhiSuperClusterTrackAtVtx();
00049     float sigmaIEtaIEta = ele.sigmaIetaIeta();
00050     float hoe           = ele.hadronicOverEm();
00051     float trackIso      = ele.dr03TkSumPt();
00052     float ecalIso       = ele.dr03EcalRecHitSumEt();
00053     float hcalIso       = ele.dr03HcalTowerSumEt();
00054 
00055     // test the trigger cuts
00056     return EgammaCutBasedEleId::PassTriggerCuts(triggerWorkingPoint, isEB, pt, dEtaIn, dPhiIn, sigmaIEtaIEta, hoe, trackIso, ecalIso, hcalIso);
00057 
00058 }
00059 
00060 bool EgammaCutBasedEleId::PassTriggerCuts(TriggerWorkingPoint triggerWorkingPoint, const reco::GsfElectronRef &ele) 
00061 {
00062   return EgammaCutBasedEleId::PassTriggerCuts(triggerWorkingPoint, *ele);
00063 }
00064 
00065 bool EgammaCutBasedEleId::PassEoverPCuts(const reco::GsfElectron &ele)
00066 {
00067 
00068     // get the variables
00069     float eta           = ele.superCluster()->eta();
00070     float eopin         = ele.eSuperClusterOverP();
00071     float fbrem         = ele.fbrem();    
00072 
00073     // test the eop/fbrem cuts
00074     return EgammaCutBasedEleId::PassEoverPCuts(eta, eopin, fbrem);
00075 
00076 }
00077 
00078 bool EgammaCutBasedEleId::PassEoverPCuts(const reco::GsfElectronRef &ele) {
00079   return PassEoverPCuts(*ele);
00080 }
00081 
00082 
00083 unsigned int EgammaCutBasedEleId::TestWP(WorkingPoint workingPoint,
00084     const reco::GsfElectron &ele,
00085     const edm::Handle<reco::ConversionCollection> &conversions,
00086     const reco::BeamSpot &beamspot,
00087     const edm::Handle<reco::VertexCollection> &vtxs,
00088     const double &iso_ch,
00089     const double &iso_em,
00090     const double &iso_nh,
00091     const double &rho)
00092 {
00093 
00094     // get the ID variables from the electron object
00095 
00096     // kinematic variables
00097     bool isEB           = ele.isEB() ? true : false;
00098     float pt            = ele.pt();
00099     float eta           = ele.superCluster()->eta();
00100 
00101     // id variables
00102     float dEtaIn        = ele.deltaEtaSuperClusterTrackAtVtx();
00103     float dPhiIn        = ele.deltaPhiSuperClusterTrackAtVtx();
00104     float sigmaIEtaIEta = ele.sigmaIetaIeta();
00105     float hoe           = ele.hadronicOverEm();
00106     float ooemoop       = (1.0/ele.ecalEnergy() - ele.eSuperClusterOverP()/ele.ecalEnergy());
00107 
00108     // impact parameter variables
00109     float d0vtx         = 0.0;
00110     float dzvtx         = 0.0;
00111     if (vtxs->size() > 0) {
00112         reco::VertexRef vtx(vtxs, 0);    
00113         d0vtx = ele.gsfTrack()->dxy(vtx->position());
00114         dzvtx = ele.gsfTrack()->dz(vtx->position());
00115     } else {
00116         d0vtx = ele.gsfTrack()->dxy();
00117         dzvtx = ele.gsfTrack()->dz();
00118     }
00119 
00120     // conversion rejection variables
00121     bool vtxFitConversion = ConversionTools::hasMatchedConversion(ele, conversions, beamspot.position());
00122     float mHits = ele.gsfTrack()->trackerExpectedHitsInner().numberOfHits(); 
00123 
00124     // get the mask value
00125     unsigned int mask = EgammaCutBasedEleId::TestWP(workingPoint, isEB, pt, eta, dEtaIn, dPhiIn,
00126         sigmaIEtaIEta, hoe, ooemoop, d0vtx, dzvtx, iso_ch, iso_em, iso_nh, vtxFitConversion, mHits, rho);
00127 
00128     // return the mask value
00129     return mask;
00130 
00131 }
00132 
00133 unsigned int EgammaCutBasedEleId::TestWP(WorkingPoint workingPoint,
00134                                          const reco::GsfElectronRef &ele,
00135                                          const edm::Handle<reco::ConversionCollection> &conversions,
00136                                          const reco::BeamSpot &beamspot,
00137                                          const edm::Handle<reco::VertexCollection> &vtxs,
00138                                          const double &iso_ch,
00139                                          const double &iso_em,
00140                                          const double &iso_nh,
00141                                          const double &rho) {
00142   return TestWP(workingPoint,*ele,conversions,beamspot,vtxs,iso_ch,iso_em,iso_nh,rho);
00143 }
00144 
00145 
00146 #endif
00147 
00148 bool EgammaCutBasedEleId::PassWP(WorkingPoint workingPoint, const bool isEB, const float pt, const float eta,
00149     const float dEtaIn, const float dPhiIn, const float sigmaIEtaIEta, const float hoe,
00150     const float ooemoop, const float d0vtx, const float dzvtx, const float iso_ch, const float iso_em, const float iso_nh, 
00151     const bool vtxFitConversion, const unsigned int mHits, const double rho)
00152 {
00153     unsigned int mask = EgammaCutBasedEleId::TestWP(workingPoint, isEB, pt, eta, dEtaIn, dPhiIn,
00154         sigmaIEtaIEta, hoe, ooemoop, d0vtx, dzvtx, iso_ch, iso_em, iso_nh, vtxFitConversion, mHits, rho);
00155 
00156     if ((mask & PassAll) == PassAll) return true;
00157     return false;
00158 }
00159 
00160 bool EgammaCutBasedEleId::PassTriggerCuts(const TriggerWorkingPoint triggerWorkingPoint, 
00161     const bool isEB, const float pt, 
00162     const float dEtaIn, const float dPhiIn, const float sigmaIEtaIEta, const float hoe,
00163     const float trackIso, const float ecalIso, const float hcalIso)
00164 {
00165 
00166    
00167     // choose cut if barrel or endcap
00168     unsigned int idx = isEB ? 0 : 1;
00169 
00170     if (triggerWorkingPoint == EgammaCutBasedEleId::TRIGGERTIGHT) {
00171         float cut_dEtaIn[2]         = {0.007, 0.009};
00172         float cut_dPhiIn[2]         = {0.15, 0.10};
00173         float cut_sigmaIEtaIEta[2]  = {0.01, 0.03};
00174         float cut_hoe[2]            = {0.12, 0.10};
00175         float cut_trackIso[2]       = {0.20, 0.20};
00176         float cut_ecalIso[2]        = {0.20, 0.20};
00177         float cut_hcalIso[2]        = {0.20, 0.20};
00178         if (fabs(dEtaIn) > cut_dEtaIn[idx])             return false;
00179         if (fabs(dPhiIn) > cut_dPhiIn[idx])             return false;
00180         if (sigmaIEtaIEta > cut_sigmaIEtaIEta[idx])     return false;
00181         if (hoe > cut_hoe[idx])                         return false;
00182         if (trackIso / pt > cut_trackIso[idx])          return false;
00183         if (ecalIso / pt > cut_ecalIso[idx])            return false;
00184         if (hcalIso / pt > cut_hcalIso[idx])            return false;
00185     }
00186     else if (triggerWorkingPoint == EgammaCutBasedEleId::TRIGGERWP70) {
00187         float cut_dEtaIn[2]         = {0.004, 0.005};
00188         float cut_dPhiIn[2]         = {0.03, 0.02};
00189         float cut_sigmaIEtaIEta[2]  = {0.01, 0.03};
00190         float cut_hoe[2]            = {0.025, 0.025};
00191         float cut_trackIso[2]       = {0.10, 0.10};
00192         float cut_ecalIso[2]        = {0.10, 0.05};
00193         float cut_hcalIso[2]        = {0.05, 0.05};
00194         if (fabs(dEtaIn) > cut_dEtaIn[idx])             return false;
00195         if (fabs(dPhiIn) > cut_dPhiIn[idx])             return false;
00196         if (sigmaIEtaIEta > cut_sigmaIEtaIEta[idx])     return false;
00197         if (hoe > cut_hoe[idx])                         return false;
00198         if (trackIso / pt > cut_trackIso[idx])          return false;
00199         if (ecalIso / pt > cut_ecalIso[idx])            return false;
00200         if (hcalIso / pt > cut_hcalIso[idx])            return false;
00201     }
00202     else {
00203         std::cout << "[EgammaCutBasedEleId::PassTriggerCuts] Undefined working point" << std::endl;
00204     }   
00205 
00206     return true; 
00207 }
00208 
00209 bool EgammaCutBasedEleId::PassEoverPCuts(const float eta, const float eopin, const float fbrem)
00210 {
00211     if (fbrem > 0.15)                           return true;
00212     else if (fabs(eta) < 1.0 && eopin > 0.95)   return true;
00213     return false;
00214 }
00215 
00216 unsigned int EgammaCutBasedEleId::TestWP(WorkingPoint workingPoint, const bool isEB, const float pt, const float eta,
00217     const float dEtaIn, const float dPhiIn, const float sigmaIEtaIEta, const float hoe, 
00218     const float ooemoop, const float d0vtx, const float dzvtx, const float iso_ch, const float iso_em, const float iso_nh, 
00219     const bool vtxFitConversion, const unsigned int mHits, const double rho)
00220 {
00221 
00222     unsigned int mask = 0;
00223     float cut_dEtaIn[2]         = {999.9, 999.9};
00224     float cut_dPhiIn[2]         = {999.9, 999.9};
00225     float cut_sigmaIEtaIEta[2]  = {999.9, 999.9};
00226     float cut_hoe[2]            = {999.9, 999.9};
00227     float cut_ooemoop[2]        = {999.9, 999.9};
00228     float cut_d0vtx[2]          = {999.9, 999.9};
00229     float cut_dzvtx[2]          = {999.9, 999.9};
00230     float cut_iso[2]            = {999.9, 999.9};
00231     bool cut_vtxFit[2]          = {false, false};
00232     unsigned int cut_mHits[2]   = {999, 999};
00233 
00234     if (workingPoint == EgammaCutBasedEleId::VETO) {
00235         cut_dEtaIn[0]        = 0.007; cut_dEtaIn[1]        = 0.010;
00236         cut_dPhiIn[0]        = 0.800; cut_dPhiIn[1]        = 0.700;
00237         cut_sigmaIEtaIEta[0] = 0.010; cut_sigmaIEtaIEta[1] = 0.030;
00238         cut_hoe[0]           = 0.150; cut_hoe[1]           = 999.9;
00239         cut_ooemoop[0]       = 999.9; cut_ooemoop[1]       = 999.9;
00240         cut_d0vtx[0]         = 0.040; cut_d0vtx[1]         = 0.040;
00241         cut_dzvtx[0]         = 0.200; cut_dzvtx[1]         = 0.200;
00242         cut_vtxFit[0]        = false; cut_vtxFit[1]        = false;
00243         cut_mHits[0]         = 999  ; cut_mHits[1]         = 999;
00244         cut_iso[0]           = 0.150; cut_iso[1]           = 0.150;
00245     } 
00246     else if (workingPoint == EgammaCutBasedEleId::LOOSE) {
00247         cut_dEtaIn[0]        = 0.007; cut_dEtaIn[1]        = 0.009;
00248         cut_dPhiIn[0]        = 0.150; cut_dPhiIn[1]        = 0.100;
00249         cut_sigmaIEtaIEta[0] = 0.010; cut_sigmaIEtaIEta[1] = 0.030;
00250         cut_hoe[0]           = 0.120; cut_hoe[1]           = 0.100;
00251         cut_ooemoop[0]       = 0.050; cut_ooemoop[1]       = 0.050;
00252         cut_d0vtx[0]         = 0.020; cut_d0vtx[1]         = 0.020;
00253         cut_dzvtx[0]         = 0.200; cut_dzvtx[1]         = 0.200;
00254         cut_vtxFit[0]        = true ; cut_vtxFit[1]        = true;
00255         cut_mHits[0]         = 1    ; cut_mHits[1]         = 1;
00256         if (pt >= 20.0) {
00257             cut_iso[0] = 0.150; cut_iso[1] = 0.150;
00258         }
00259         else {
00260             cut_iso[0] = 0.150; cut_iso[1] = 0.100;
00261         }
00262     } 
00263     else if (workingPoint == EgammaCutBasedEleId::MEDIUM) {
00264         cut_dEtaIn[0]        = 0.004; cut_dEtaIn[1]        = 0.007;
00265         cut_dPhiIn[0]        = 0.060; cut_dPhiIn[1]        = 0.030;
00266         cut_sigmaIEtaIEta[0] = 0.010; cut_sigmaIEtaIEta[1] = 0.030;
00267         cut_hoe[0]           = 0.120; cut_hoe[1]           = 0.100;
00268         cut_ooemoop[0]       = 0.050; cut_ooemoop[1]       = 0.050;
00269         cut_d0vtx[0]         = 0.020; cut_d0vtx[1]         = 0.020;
00270         cut_dzvtx[0]         = 0.100; cut_dzvtx[1]         = 0.100;
00271         cut_vtxFit[0]        = true ; cut_vtxFit[1]        = true;
00272         cut_mHits[0]         = 1    ; cut_mHits[1]         = 1;
00273         if (pt >= 20.0) {
00274             cut_iso[0] = 0.150; cut_iso[1] = 0.150;
00275         }
00276         else {
00277             cut_iso[0] = 0.150; cut_iso[1] = 0.100;
00278         }
00279     } 
00280     else if (workingPoint == EgammaCutBasedEleId::TIGHT) {
00281         cut_dEtaIn[0]        = 0.004; cut_dEtaIn[1]        = 0.005;
00282         cut_dPhiIn[0]        = 0.030; cut_dPhiIn[1]        = 0.020;
00283         cut_sigmaIEtaIEta[0] = 0.010; cut_sigmaIEtaIEta[1] = 0.030;
00284         cut_hoe[0]           = 0.120; cut_hoe[1]           = 0.100;
00285         cut_ooemoop[0]       = 0.050; cut_ooemoop[1]       = 0.050;
00286         cut_d0vtx[0]         = 0.020; cut_d0vtx[1]         = 0.020;
00287         cut_dzvtx[0]         = 0.100; cut_dzvtx[1]         = 0.100;
00288         cut_vtxFit[0]        = true ; cut_vtxFit[1]        = true;
00289         cut_mHits[0]         = 0    ; cut_mHits[1]         = 0;
00290         if (pt >= 20.0) {
00291             cut_iso[0] = 0.100; cut_iso[1] = 0.100;
00292         }
00293         else {
00294             cut_iso[0] = 0.100; cut_iso[1] = 0.070;
00295         }
00296     } 
00297     else {
00298         std::cout << "[EgammaCutBasedEleId::TestWP] Undefined working point" << std::endl;
00299     }
00300 
00301     // choose cut if barrel or endcap
00302     unsigned int idx = isEB ? 0 : 1;
00303 
00304     // effective area for isolation
00305     float AEff = ElectronEffectiveArea::GetElectronEffectiveArea(ElectronEffectiveArea::kEleGammaAndNeutralHadronIso03, eta, ElectronEffectiveArea::kEleEAData2011);
00306 
00307     // apply to neutrals
00308     double rhoPrime = std::max(rho, 0.0);
00309     double iso_n = std::max(iso_nh + iso_em - rhoPrime * AEff, 0.0);
00310 
00311     // compute final isolation
00312     double iso = (iso_n + iso_ch) / pt;
00313 
00314     // test cuts
00315     if (fabs(dEtaIn) < cut_dEtaIn[idx])             mask |= DETAIN;
00316     if (fabs(dPhiIn) < cut_dPhiIn[idx])             mask |= DPHIIN; 
00317     if (sigmaIEtaIEta < cut_sigmaIEtaIEta[idx])     mask |= SIGMAIETAIETA;
00318     if (hoe < cut_hoe[idx])                         mask |= HOE;
00319     if (fabs(ooemoop) < cut_ooemoop[idx])           mask |= OOEMOOP;
00320     if (fabs(d0vtx) < cut_d0vtx[idx])               mask |= D0VTX;
00321     if (fabs(dzvtx) < cut_dzvtx[idx])               mask |= DZVTX;
00322     if (!cut_vtxFit[idx] || !vtxFitConversion)      mask |= VTXFIT;
00323     if (mHits <= cut_mHits[idx])                    mask |= MHITS;
00324     if (iso < cut_iso[idx])                         mask |= ISO;
00325 
00326     // return the mask
00327     return mask;
00328 
00329 }
00330 
00331 void EgammaCutBasedEleId::PrintDebug(unsigned int mask)
00332 {
00333     printf("detain(%i), ",  bool(mask & DETAIN));
00334     printf("dphiin(%i), ",  bool(mask & DPHIIN));
00335     printf("sieie(%i), ",   bool(mask & SIGMAIETAIETA));
00336     printf("hoe(%i), ",     bool(mask & HOE));
00337     printf("ooemoop(%i), ", bool(mask & OOEMOOP));
00338     printf("d0vtx(%i), ",   bool(mask & D0VTX));
00339     printf("dzvtx(%i), ",   bool(mask & DZVTX));
00340     printf("iso(%i), ",     bool(mask & ISO));
00341     printf("vtxfit(%i), ",  bool(mask & VTXFIT));
00342     printf("mhits(%i)\n",   bool(mask & MHITS));
00343 }
00344