File indexing completed on 2024-04-06 12:24:54
0001 #ifndef EgammaTowerIsolation_h
0002 #define EgammaTowerIsolation_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <vector>
0016
0017
0018 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
0019 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
0020 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0021 #include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
0022
0023 #include <cmath>
0024 #include <algorithm>
0025 #include <cstdint>
0026 #include <atomic>
0027
0028 #include "DataFormats/Math/interface/deltaR.h"
0029
0030
0031
0032
0033
0034
0035 template <unsigned int NC>
0036 class EgammaTowerIsolationNew {
0037 public:
0038 struct Sum {
0039 Sum() : he{0}, h2{0}, heBC{0}, h2BC{0} {}
0040 float he[NC];
0041 float h2[NC];
0042 float heBC[NC];
0043 float h2BC[NC];
0044 };
0045
0046
0047 constexpr static unsigned int NCuts = NC;
0048
0049
0050
0051 EgammaTowerIsolationNew() : nt(0) {}
0052 EgammaTowerIsolationNew(float extRadius[NC], float intRadius[NC], CaloTowerCollection const& towers);
0053
0054 ~EgammaTowerIsolationNew() { delete[] mem; }
0055
0056 template <typename I>
0057 void compute(bool et, Sum& sum, reco::Candidate const& cand, I first, I last) const {
0058 reco::SuperCluster const* sc = cand.get<reco::SuperClusterRef>().get();
0059 if (sc) {
0060 compute(et, sum, *sc, first, last);
0061 }
0062 }
0063 template <typename I>
0064 void compute(bool et, Sum& sum, reco::SuperCluster const& sc, I first, I last) const;
0065
0066 void setRadius(float const extRadius[NC], float const intRadius[NC]) {
0067 for (std::size_t i = 0; i != NCuts; ++i) {
0068 extRadius2_[i] = extRadius[i] * extRadius[i];
0069 intRadius2_[i] = intRadius[i] * intRadius[i];
0070 }
0071 maxEta = *std::max_element(extRadius, extRadius + NC);
0072 }
0073
0074 public:
0075 float extRadius2_[NCuts];
0076 float intRadius2_[NCuts];
0077
0078 float maxEta;
0079
0080 const uint32_t nt;
0081 float* eta;
0082 float* phi;
0083 float* he;
0084 float* h2;
0085 float* st;
0086 uint32_t* id;
0087 uint32_t* mem = nullptr;
0088 void initSoa() {
0089 mem = new uint32_t[nt * 6];
0090 eta = (float*)(mem);
0091 phi = eta + nt;
0092 he = phi + nt;
0093 h2 = he + nt;
0094 st = h2 + nt;
0095 id = (uint32_t*)(st) + nt;
0096 }
0097 };
0098
0099
0100 #ifdef ETISTATDEBUG
0101 namespace etiStat {
0102
0103 struct Count {
0104 std::atomic<uint32_t> create = 0;
0105 std::atomic<uint32_t> comp = 0;
0106 std::atomic<uint32_t> span = 0;
0107 static Count count;
0108 ~Count();
0109 };
0110
0111 }
0112 #endif
0113
0114 template <unsigned int NC>
0115 inline EgammaTowerIsolationNew<NC>::EgammaTowerIsolationNew(float extRadius[NC],
0116 float intRadius[NC],
0117 CaloTowerCollection const& towers)
0118 : maxEta(*std::max_element(extRadius, extRadius + NC)), nt(towers.size()) {
0119 if (nt == 0)
0120 return;
0121 initSoa();
0122
0123 #ifdef ETISTATDEBUG
0124 etiStat::Count::count.create++;
0125 #endif
0126
0127 for (std::size_t i = 0; i != NCuts; ++i) {
0128 extRadius2_[i] = extRadius[i] * extRadius[i];
0129 intRadius2_[i] = intRadius[i] * intRadius[i];
0130 }
0131
0132
0133 uint32_t index[nt];
0134 #ifdef __clang__
0135 std::vector<float> e(nt);
0136 #else
0137 float e[nt];
0138 #endif
0139 for (std::size_t k = 0; k != nt; ++k) {
0140 e[k] = towers[k].eta();
0141 index[k] = k;
0142 std::push_heap(index, index + k + 1, [&e](uint32_t i, uint32_t j) { return e[i] < e[j]; });
0143 }
0144 std::sort_heap(index, index + nt, [&e](uint32_t i, uint32_t j) { return e[i] < e[j]; });
0145
0146 for (std::size_t i = 0; i != nt; ++i) {
0147 auto j = index[i];
0148 eta[i] = towers[j].eta();
0149 phi[i] = towers[j].phi();
0150 id[i] = towers[j].id();
0151 st[i] = 1.f / std::cosh(eta[i]);
0152 he[i] = towers[j].hadEnergy();
0153 h2[i] = towers[j].hadEnergyHeOuterLayer();
0154 }
0155 }
0156
0157 template <unsigned int NC>
0158 template <typename I>
0159 inline void EgammaTowerIsolationNew<NC>::compute(
0160 bool et, Sum& sum, reco::SuperCluster const& sc, I first, I last) const {
0161 if (nt == 0)
0162 return;
0163
0164 #ifdef ETISTATDEBUG
0165 etiStat::Count::count.comp++;
0166 #endif
0167
0168 float candEta = sc.eta();
0169 float candPhi = sc.phi();
0170
0171 auto lb = std::lower_bound(eta, eta + nt, candEta - maxEta);
0172 auto ub = std::upper_bound(lb, eta + nt, candEta + maxEta);
0173 uint32_t il = lb - eta;
0174 uint32_t iu = std::min(nt, uint32_t(ub - eta + 1));
0175
0176 #ifdef ETISTATDEBUG
0177 etiStat::Count::count.span += (iu - il);
0178 #endif
0179
0180
0181 for (std::size_t i = il; i != iu; ++i) {
0182 float dr2 = reco::deltaR2(candEta, candPhi, eta[i], phi[i]);
0183 float tt = et ? st[i] : 1.f;
0184 for (std::size_t j = 0; j != NCuts; ++j) {
0185 if (dr2 < extRadius2_[j]) {
0186 if (dr2 >= intRadius2_[j]) {
0187 sum.he[j] += he[i] * tt;
0188 sum.h2[j] += h2[i] * tt;
0189 }
0190 if (std::find(first, last, id[i]) == last) {
0191 sum.heBC[j] += he[i] * tt;
0192 sum.h2BC[j] += h2[i] * tt;
0193 }
0194 }
0195 }
0196 }
0197 }
0198
0199 class EgammaTowerIsolation {
0200 public:
0201 enum HcalDepth { AllDepths = -1, Undefined = 0, Depth1 = 1, Depth2 = 2 };
0202
0203
0204 EgammaTowerIsolation(
0205 float extRadiusI, float intRadiusI, float etLow, signed int depth, const CaloTowerCollection* towers);
0206
0207 double getTowerEtSum(const reco::Candidate* cand, const std::vector<CaloTowerDetId>* detIdToExclude = nullptr) const {
0208 reco::SuperCluster const& sc = *cand->get<reco::SuperClusterRef>().get();
0209 return getSum(true, sc, detIdToExclude);
0210 }
0211 double getTowerESum(const reco::Candidate* cand, const std::vector<CaloTowerDetId>* detIdToExclude = nullptr) const {
0212 reco::SuperCluster const& sc = *cand->get<reco::SuperClusterRef>().get();
0213 return getSum(false, sc, detIdToExclude);
0214 }
0215 double getTowerEtSum(reco::SuperCluster const* sc,
0216 const std::vector<CaloTowerDetId>* detIdToExclude = nullptr) const {
0217 return getSum(true, *sc, detIdToExclude);
0218 }
0219 double getTowerESum(reco::SuperCluster const* sc, const std::vector<CaloTowerDetId>* detIdToExclude = nullptr) const {
0220 return getSum(false, *sc, detIdToExclude);
0221 }
0222
0223 private:
0224 double getSum(bool et, reco::SuperCluster const& sc, const std::vector<CaloTowerDetId>* detIdToExclude) const;
0225
0226 private:
0227 signed int depth_;
0228 float extRadius;
0229 float intRadius;
0230 };
0231
0232 #endif