00001 #ifndef EgammaTowerIsolation_h
00002 #define EgammaTowerIsolation_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include<vector>
00016
00017
00018
00019 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00020 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
00021 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00022 #include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
00023
00024
00025 #include <cmath>
00026 #include <algorithm>
00027 #include <cstdint>
00028
00029 #include "DataFormats/Math/interface/deltaR.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038 template<unsigned int NC>
00039 class EgammaTowerIsolationNew {
00040 public:
00041
00042 struct Sum {
00043 Sum(): he{0},h2{0},heBC{0},h2BC{0}
00044 {}
00045 float he[NC];
00046 float h2[NC];
00047 float heBC[NC];
00048 float h2BC[NC];
00049 };
00050
00051
00052 constexpr static unsigned int NCuts = NC;
00053
00054
00055
00056 EgammaTowerIsolationNew () : nt(0){}
00057 EgammaTowerIsolationNew (float extRadius[NC],
00058 float intRadius[NC],
00059 CaloTowerCollection const & towers) ;
00060
00061
00062 ~EgammaTowerIsolationNew() { delete[] mem;}
00063
00064 void compute(bool et, Sum&sum, reco::Candidate const & cand, CaloTowerDetId const * first, CaloTowerDetId const * last) const {
00065 reco::SuperCluster const & sc = *cand.get<reco::SuperClusterRef>().get();
00066 return compute(et,sum,sc,first,last);
00067 }
00068 void compute(bool et, Sum &sum, reco::SuperCluster const & sc, CaloTowerDetId const * first, CaloTowerDetId const * last) const;
00069
00070 void setRadius(float const extRadius[NC],float const intRadius[NC]) {
00071 for (std::size_t i=0; i!=NCuts; ++i) {
00072 extRadius2_[i]=extRadius[i]*extRadius[i];
00073 intRadius2_[i]=intRadius[i]*intRadius[i];
00074 }
00075 maxEta = *std::max_element(extRadius,extRadius+NC);
00076 }
00077
00078 public:
00079
00080 float extRadius2_[NCuts] ;
00081 float intRadius2_[NCuts] ;
00082
00083 float maxEta;
00084
00085 const uint32_t nt;
00086 float * eta;
00087 float * phi;
00088 float * he;
00089 float * h2;
00090 float * st;
00091 uint32_t * id;
00092 uint32_t * mem=nullptr;
00093 void initSoa() {
00094 mem = new uint32_t[nt*6];
00095 eta = (float*)(mem); phi = eta+nt; he = phi+nt; h2 = he+nt; st = h2+nt;
00096 id = (uint32_t*)(st) + nt;
00097 }
00098
00099
00100 };
00101
00102 namespace etiStat {
00103
00104 struct Count {
00105 uint32_t create=0;
00106 uint32_t comp=0;
00107 uint32_t span=0;
00108 static Count count;
00109 ~Count();
00110 };
00111
00112 }
00113
00114
00115 template<unsigned int NC>
00116 inline
00117 EgammaTowerIsolationNew<NC>::EgammaTowerIsolationNew(float extRadius[NC],
00118 float intRadius[NC],
00119 CaloTowerCollection const & towers) :
00120 maxEta(*std::max_element(extRadius,extRadius+NC)),
00121 nt(towers.size()) {
00122 if (nt==0) return;
00123 initSoa();
00124
00125 etiStat::Count::count.create++;
00126
00127
00128 for (std::size_t i=0; i!=NCuts; ++i) {
00129 extRadius2_[i]=extRadius[i]*extRadius[i];
00130 intRadius2_[i]=intRadius[i]*intRadius[i];
00131 }
00132
00133
00134 uint32_t index[nt];
00135 float e[nt];
00136 for (std::size_t k=0; k!=nt; ++k) {
00137 e[k]=towers[k].eta();
00138 index[k]=k;
00139 std::push_heap(index,index+k+1,[&e](uint32_t i, uint32_t j){ return e[i]<e[j];});
00140 }
00141 std::sort_heap(index,index+nt,[&e](uint32_t i, uint32_t j){ return e[i]<e[j];});
00142
00143
00144 for (std::size_t i=0;i!=nt; ++i) {
00145 auto j = index[i];
00146 eta[i]=towers[j].eta();
00147 phi[i]=towers[j].phi();
00148 id[i]=towers[j].id();
00149 st[i] = 1.f/std::cosh(eta[i]);
00150 he[i] = towers[j].hadEnergy();
00151 h2[i] = towers[j].hadEnergyHeOuterLayer();
00152 }
00153 }
00154
00155
00156 template<unsigned int NC>
00157 inline
00158 void
00159 EgammaTowerIsolationNew<NC>::compute(bool et, Sum &sum, reco::SuperCluster const & sc, CaloTowerDetId const * first, CaloTowerDetId const * last) const {
00160 if (nt==0) return;
00161
00162 etiStat::Count::count.comp++;
00163
00164 float candEta = sc.eta();
00165 float candPhi = sc.phi();
00166
00167
00168 auto lb = std::lower_bound(eta,eta+nt,candEta-maxEta);
00169 auto ub = std::upper_bound(lb,eta+nt,candEta+maxEta);
00170 uint32_t il = lb-eta;
00171 uint32_t iu = std::min(nt,uint32_t(ub-eta+1));
00172
00173 etiStat::Count::count.span += (iu-il);
00174
00175 bool ok[iu-il];
00176 for (std::size_t i=il;i!=iu; ++i)
00177 ok[i-il] = (std::find(first,last,id[i])==last);
00178
00179
00180
00181
00182 for (std::size_t i=il;i!=iu; ++i) {
00183 float dr2 = reco::deltaR2(candEta,candPhi,eta[i], phi[i]);
00184 float tt = et ? st[i] : 1.f;
00185 for (std::size_t j=0; j!=NCuts; ++j) {
00186 if (dr2<extRadius2_[j]) {
00187 if (dr2>=intRadius2_[j]) {
00188 sum.he[j] +=he[i]*tt;
00189 sum.h2[j] +=h2[i]*tt;
00190 }
00191 if(ok[i-il]) {
00192 sum.heBC[j] +=he[i]*tt;
00193 sum.h2BC[j] +=h2[i]*tt;
00194 }
00195 }
00196 }
00197 }
00198 }
00199
00200 class EgammaTowerIsolation {
00201 public:
00202
00203 enum HcalDepth{AllDepths=-1,Undefined=0,Depth1=1,Depth2=2};
00204
00205
00206 EgammaTowerIsolation (float extRadiusI,
00207 float intRadiusI,
00208 float etLow,
00209 signed int depth,
00210 const CaloTowerCollection* towers );
00211
00212 double getTowerEtSum (const reco::Candidate* cand, const std::vector<CaloTowerDetId> * detIdToExclude=0 ) const{
00213 reco::SuperCluster const & sc = *cand->get<reco::SuperClusterRef>().get();
00214 return getSum(true,sc,detIdToExclude);
00215 }
00216 double getTowerESum (const reco::Candidate* cand, const std::vector<CaloTowerDetId> * detIdToExclude=0) const{
00217 reco::SuperCluster const & sc = *cand->get<reco::SuperClusterRef>().get();
00218 return getSum(false,sc,detIdToExclude);
00219 }
00220 double getTowerEtSum (reco::SuperCluster const * sc, const std::vector<CaloTowerDetId> * detIdToExclude=0 ) const{
00221 return getSum(true,*sc,detIdToExclude);
00222 }
00223 double getTowerESum (reco::SuperCluster const * sc, const std::vector<CaloTowerDetId> * detIdToExclude=0) const{
00224 return getSum(false,*sc,detIdToExclude);
00225 }
00226 private:
00227 double getSum (bool et, reco::SuperCluster const & sc, const std::vector<CaloTowerDetId> * detIdToExclude) const;
00228
00229
00230 private:
00231 static EgammaTowerIsolationNew<1> * newAlgo;
00232 static const CaloTowerCollection* oldTowers;
00233 static uint32_t id15;
00234 signed int depth_;
00235 float extRadius;
00236 float intRadius;
00237 };
00238
00239
00240
00241 #endif