CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoEgamma/EgammaIsolationAlgos/interface/EgammaTowerIsolation.h

Go to the documentation of this file.
00001 #ifndef EgammaTowerIsolation_h
00002 #define EgammaTowerIsolation_h
00003 
00004 //*****************************************************************************
00005 // File:      EgammaTowerIsolation.h
00006 // ----------------------------------------------------------------------------
00007 // OrigAuth:  Matthias Mozer
00008 // Institute: IIHE-VUB
00009 //  Adding feature to exclude towers used by H/E
00010 //
00011 //  11/11/12 Hack by VI to make it 100 times faster
00012 //=============================================================================
00013 //*****************************************************************************
00014 
00015 #include<vector>
00016 
00017 
00018 //CMSSW includes
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   for each set of cuts it will compute Et for all, depth1 and depth2 twice:
00035   one between inner and outer and once inside outer vetoid the tower to excude
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   // number of cuts
00052   constexpr static unsigned int NCuts = NC;
00053 
00054   //constructors
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   //SOA
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   // sort in eta  (kd-tree anoverkill,does not vectorize...)
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]); // std::sin(towers[j].theta());   //;
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   // should be restricted in eta....
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   //constructors
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