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
00021 unsigned int mask = TestWP(workingPoint, ele, conversions, beamspot, vtxs, iso_ch, iso_em, iso_nh, rho);
00022
00023
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
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
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
00069 float eta = ele.superCluster()->eta();
00070 float eopin = ele.eSuperClusterOverP();
00071 float fbrem = ele.fbrem();
00072
00073
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
00095
00096
00097 bool isEB = ele.isEB() ? true : false;
00098 float pt = ele.pt();
00099 float eta = ele.superCluster()->eta();
00100
00101
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
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
00121 bool vtxFitConversion = ConversionTools::hasMatchedConversion(ele, conversions, beamspot.position());
00122 float mHits = ele.gsfTrack()->trackerExpectedHitsInner().numberOfHits();
00123
00124
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
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
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
00302 unsigned int idx = isEB ? 0 : 1;
00303
00304
00305 float AEff = ElectronEffectiveArea::GetElectronEffectiveArea(ElectronEffectiveArea::kEleGammaAndNeutralHadronIso03, eta, ElectronEffectiveArea::kEleEAData2011);
00306
00307
00308 double rhoPrime = std::max(rho, 0.0);
00309 double iso_n = std::max(iso_nh + iso_em - rhoPrime * AEff, 0.0);
00310
00311
00312 double iso = (iso_n + iso_ch) / pt;
00313
00314
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
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