File indexing completed on 2021-02-14 13:30:24
0001 #ifndef L1Trigger_Phase2L1ParticleFlow_CALOCLUSTERER_H
0002 #define L1Trigger_Phase2L1ParticleFlow_CALOCLUSTERER_H
0003
0004
0005
0006
0007
0008 namespace edm {
0009 class ParameterSet;
0010 }
0011
0012
0013 #include <cstdint>
0014 #include <cmath>
0015 #include <vector>
0016 #include <array>
0017 #include <algorithm>
0018 #include "DataFormats/L1TParticleFlow/interface/PFCluster.h"
0019 #include "DataFormats/Common/interface/OrphanHandle.h"
0020
0021 namespace l1tpf_calo {
0022 class Grid {
0023 public:
0024 virtual ~Grid() {}
0025 unsigned int size() const { return ncells_; }
0026 virtual int find_cell(float eta, float phi) const = 0;
0027 int neighbour(int icell, unsigned int idx) const { return neighbours_[icell][idx]; }
0028 float eta(int icell) const { return eta_[icell]; }
0029 float phi(int icell) const { return phi_[icell]; }
0030 float etaWidth(int icell) const { return etaWidth_[icell]; }
0031 float phiWidth(int icell) const { return phiWidth_[icell]; }
0032 int ieta(int icell) const { return ieta_[icell]; }
0033 int iphi(int icell) const { return iphi_[icell]; }
0034
0035 protected:
0036 Grid(unsigned int size)
0037 : ncells_(size),
0038 eta_(size),
0039 etaWidth_(size),
0040 phi_(size),
0041 phiWidth_(size),
0042 ieta_(size),
0043 iphi_(size),
0044 neighbours_(size) {}
0045 unsigned int ncells_;
0046 std::vector<float> eta_, etaWidth_, phi_, phiWidth_;
0047 std::vector<int> ieta_, iphi_;
0048 std::vector<std::array<int, 8>> neighbours_;
0049 };
0050
0051 class Phase1GridBase : public Grid {
0052 public:
0053 Phase1GridBase(int nEta, int nPhi, int ietaCoarse, int ietaVeryCoarse, const float *towerEtas);
0054
0055 int find_cell(float eta, float phi) const override;
0056 int ifind_cell(int ieta, int iphi) const { return cell_map_[(ieta + nEta_) + 2 * nEta_ * (iphi - 1)]; }
0057
0058 protected:
0059 const int nEta_, nPhi_, ietaCoarse_, ietaVeryCoarse_;
0060 const float *towerEtas_;
0061 std::vector<int> cell_map_;
0062
0063 bool valid_ieta_iphi(int ieta, int iphi) const {
0064 if (ieta == 0 || iphi == 0)
0065 return false;
0066 if (std::abs(ieta) >= ietaVeryCoarse_ && (iphi % 4 != 1))
0067 return false;
0068 if (std::abs(ieta) >= ietaCoarse_ && (iphi % 2 != 1))
0069 return false;
0070 return true;
0071 }
0072
0073 int imove(int ieta, int iphi, int deta, int dphi);
0074 };
0075
0076 class Phase1Grid : public Phase1GridBase {
0077 public:
0078 Phase1Grid()
0079 : Phase1GridBase(phase1_nEta_, phase1_nPhi_, phase1_ietaCoarse_, phase1_ietaVeryCoarse_, phase1_towerEtas_) {}
0080
0081 protected:
0082 static const int phase1_nEta_ = 41, phase1_nPhi_ = 72, phase1_ietaCoarse_ = 29, phase1_ietaVeryCoarse_ = 40;
0083 static const float phase1_towerEtas_[phase1_nEta_];
0084 };
0085 class Phase2Grid : public Phase1GridBase {
0086 public:
0087 Phase2Grid()
0088 : Phase1GridBase(phase2_nEta_, phase2_nPhi_, phase2_ietaCoarse_, phase2_ietaVeryCoarse_, phase2_towerEtas_) {}
0089
0090 protected:
0091 static const int phase2_nEta_ = 48, phase2_nPhi_ = 72, phase2_ietaCoarse_ = 36, phase2_ietaVeryCoarse_ = 47;
0092 static const float phase2_towerEtas_[phase2_nEta_];
0093 };
0094
0095 template <typename T>
0096 class GridData {
0097 public:
0098 GridData() : grid_(nullptr), data_(), empty_() {}
0099 GridData(const Grid &grid) : grid_(&grid), data_(grid.size()), empty_() {}
0100
0101 T &operator()(float eta, float phi) { return data_[grid_->find_cell(eta, phi)]; }
0102 const T &operator()(float eta, float phi) const { return data_[grid_->find_cell(eta, phi)]; }
0103
0104 const Grid &grid() const { return *grid_; }
0105
0106 unsigned int size() const { return data_.size(); }
0107
0108 float eta(int icell) const { return grid().eta(icell); }
0109 float phi(int icell) const { return grid().phi(icell); }
0110 int ieta(int icell) const { return grid().ieta(icell); }
0111 int iphi(int icell) const { return grid().iphi(icell); }
0112
0113 T &operator[](int icell) { return data_[icell]; }
0114 const T &operator[](int icell) const { return data_[icell]; }
0115
0116 const T &neigh(int icell, unsigned int idx) const {
0117 int ineigh = grid_->neighbour(icell, idx);
0118 return (ineigh < 0 ? empty_ : data_[ineigh]);
0119 }
0120
0121 GridData<T> &operator=(const GridData<T> &other) {
0122 assert(grid_ == other.grid_);
0123 data_ = other.data_;
0124 return *this;
0125 }
0126 GridData<T> &operator+=(const GridData<T> &other) {
0127 assert(grid_ == other.grid_);
0128 for (unsigned int i = 0, n = data_.size(); i < n; ++i) {
0129 data_[i] += other.data_[i];
0130 }
0131 return *this;
0132 }
0133
0134
0135 void fill(const T &val) { std::fill(data_.begin(), data_.end(), val); }
0136 void zero() { fill(T()); }
0137
0138
0139 void clear() {
0140 for (T &t : data_)
0141 t.clear();
0142 }
0143
0144 private:
0145 const Grid *grid_;
0146 std::vector<T> data_;
0147 const T empty_;
0148 };
0149 typedef GridData<float> EtGrid;
0150 typedef GridData<int> IndexGrid;
0151
0152 struct PreCluster {
0153 PreCluster() : ptLocalMax(0), ptOverNeighLocalMaxSum(0) {}
0154 float ptLocalMax;
0155 float ptOverNeighLocalMaxSum;
0156 void clear() { ptLocalMax = ptOverNeighLocalMaxSum = 0; }
0157 };
0158 typedef GridData<PreCluster> PreClusterGrid;
0159
0160 struct Cluster {
0161 Cluster() : et(0), eta(0), phi(0) {}
0162 float et, eta, phi;
0163 std::vector<std::pair<int, float>> constituents;
0164 void clear() {
0165 et = eta = phi = 0;
0166 constituents.clear();
0167 }
0168 };
0169
0170 struct CombinedCluster : public Cluster {
0171 float ecal_et, hcal_et;
0172 void clear() {
0173 Cluster::clear();
0174 ecal_et = hcal_et = 0;
0175 }
0176 };
0177
0178 const Grid *getGrid(const std::string &type);
0179
0180 class SingleCaloClusterer {
0181 public:
0182 SingleCaloClusterer(const edm::ParameterSet &pset);
0183 ~SingleCaloClusterer();
0184 void clear();
0185 void add(const reco::Candidate &c) { add(c.pt(), c.eta(), c.phi()); }
0186 void add(float pt, float eta, float phi) { rawet_(eta, phi) += pt; }
0187 void run();
0188
0189
0190
0191 void grow();
0192
0193 const EtGrid &raw() const { return rawet_; }
0194 const IndexGrid &indexGrid() const { return clusterIndex_; }
0195 const std::vector<Cluster> &clusters() const { return clusters_; }
0196 const Cluster &cluster(int i) const {
0197 return (i == -1 || clusterIndex_[i] == -1) ? nullCluster_ : clusters_[clusterIndex_[i]];
0198 }
0199
0200
0201 EtGrid &raw() { return rawet_; }
0202
0203
0204 template <typename Corrector>
0205 void correct(const Corrector &corrector) {
0206 for (Cluster &c : clusters_) {
0207 c.et = corrector(c);
0208 }
0209 }
0210
0211 std::unique_ptr<l1t::PFClusterCollection> fetchCells(bool unclusteredOnly = false, float ptMin = 0.) const;
0212
0213 std::unique_ptr<l1t::PFClusterCollection> fetch(float ptMin = 0.) const;
0214 std::unique_ptr<l1t::PFClusterCollection> fetch(const edm::OrphanHandle<l1t::PFClusterCollection> &cells,
0215 float ptMin = 0.) const;
0216
0217 private:
0218 enum class EnergyShareAlgo {
0219 Fractions,
0220 None,
0221 Greedy,
0222 Crude
0223 };
0224 const Grid *grid_;
0225 EtGrid rawet_, unclustered_;
0226 PreClusterGrid precluster_;
0227 IndexGrid clusterIndex_, cellKey_;
0228 std::vector<Cluster> clusters_;
0229 const Cluster nullCluster_;
0230 float zsEt_, seedEt_, minClusterEt_, minEtToGrow_;
0231 EnergyShareAlgo energyShareAlgo_;
0232 bool energyWeightedPosition_;
0233 };
0234
0235 class SimpleCaloLinkerBase {
0236 public:
0237 SimpleCaloLinkerBase(const edm::ParameterSet &pset,
0238 const SingleCaloClusterer &ecal,
0239 const SingleCaloClusterer &hcal);
0240 virtual ~SimpleCaloLinkerBase();
0241 virtual void clear() { clearBase(); }
0242 virtual void run() = 0;
0243 void clearBase() {
0244 clusters_.clear();
0245 clusterIndex_.fill(-1);
0246 }
0247
0248
0249 template <typename Corrector>
0250 void correct(const Corrector &corrector) {
0251 for (CombinedCluster &c : clusters_) {
0252 c.et = corrector(c);
0253 }
0254 }
0255
0256 std::unique_ptr<l1t::PFClusterCollection> fetch() const;
0257 std::unique_ptr<l1t::PFClusterCollection> fetch(const edm::OrphanHandle<l1t::PFClusterCollection> &ecal,
0258 const edm::OrphanHandle<l1t::PFClusterCollection> &hcal) const;
0259
0260 protected:
0261 const Grid *grid_;
0262 const SingleCaloClusterer &ecal_, &hcal_;
0263 IndexGrid clusterIndex_;
0264 std::vector<CombinedCluster> clusters_;
0265 float hoeCut_, minPhotonEt_, minHadronRawEt_, minHadronEt_;
0266 bool noEmInHGC_;
0267 };
0268
0269 class SimpleCaloLinker : public SimpleCaloLinkerBase {
0270 public:
0271 SimpleCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal);
0272 ~SimpleCaloLinker() override;
0273 void clear() override;
0274 void run() override;
0275
0276 protected:
0277 PreClusterGrid ecalToHCal_;
0278 };
0279 class FlatCaloLinker : public SimpleCaloLinkerBase {
0280 public:
0281 FlatCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal);
0282 ~FlatCaloLinker() override;
0283 void clear() override;
0284 void run() override;
0285
0286 protected:
0287 SingleCaloClusterer combClusterer_;
0288 };
0289
0290
0291 std::unique_ptr<SimpleCaloLinkerBase> makeCaloLinker(const edm::ParameterSet &pset,
0292 const SingleCaloClusterer &ecal,
0293 const SingleCaloClusterer &hcal);
0294
0295 }
0296
0297 #endif