11 0, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131,
12 1.218, 1.305, 1.392, 1.479, 1.566, 1.653, 1.740, 1.830, 1.930, 2.043, 2.172, 2.322, 2.5, 2.650,
13 2.853, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
15 0, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131, 1.218, 1.305,
16 1.392, 1.479, 1.564, 1.648, 1.732, 1.817, 1.901, 1.986, 2.071, 2.155, 2.240, 2.324, 2.409, 2.493, 2.577, 2.662,
17 2.747, 2.831, 2.915, 3.0, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
20 int nEta,
int nPhi,
int ietaCoarse,
int ietaVeryCoarse,
const float *towerEtas)
21 :
Grid(2 * ((ietaCoarse - 1) * nPhi + (ietaVeryCoarse - ietaCoarse) * (nPhi / 2) +
22 (nEta - ietaVeryCoarse + 1) * (nPhi / 4))),
25 ietaCoarse_(ietaCoarse),
26 ietaVeryCoarse_(ietaVeryCoarse),
27 towerEtas_(towerEtas),
28 cell_map_(2 * nEta * nPhi, -1) {
32 for (
int iph = 1; iph <=
nPhi_; ++iph) {
39 eta_[icell] = (ie > 0 ? 0.5 : -0.5) * (etaLo + etaHi);
56 for (icell = 0; icell < int(
ncells_); ++icell) {
59 for (
int deta = -1; deta <= +1; ++deta) {
60 for (
int dphi = -1; dphi <= +1; ++dphi) {
61 if (deta == 0 && dphi == 0)
82 assert(ieta > 0 && ieta < nEta_);
90 int iphi = std::floor(phi * nPhi_ / (2 *
M_PI));
94 if (
std::abs(ieta) >= ietaVeryCoarse_)
96 else if (
std::abs(ieta) >= ietaCoarse_)
104 assert(valid_ieta_iphi(ieta, iphi));
105 int icell = ifind_cell(ieta, iphi);
119 int ie = ieta, iph = iphi;
122 ie = (ie == -nEta_ ? 0 : (ie == +1 ? -1 : ie - 1));
125 ie = (ie == +nEta_ ? 0 : (ie == -1 ? +1 : ie + 1));
136 iph = (iph == 1 ? nPhi_ : iph - 1);
139 iph = (iph == nPhi_ ? 1 : iph + 1);
146 if (!valid_ieta_iphi(ie, iph))
148 int icell = ifind_cell(ie, iph);
149 assert(!(ie == ieta && iph == iphi));
151 assert(icell != ifind_cell(ieta, iphi));
158 if (type ==
"phase1")
160 else if (type ==
"phase2")
163 throw cms::Exception(
"Configuration") <<
"Unsupported grid type '" << type <<
"'\n";
169 unclustered_(*grid_),
171 clusterIndex_(*grid_),
175 zsEt_(pset.getParameter<double>(
"zsEt")),
176 seedEt_(pset.getParameter<double>(
"seedEt")),
177 minClusterEt_(pset.getParameter<double>(
"minClusterEt")),
178 minEtToGrow_(pset.existsAs<double>(
"minEtToGrow") ? pset.getParameter<double>(
"minEtToGrow") : -1),
179 energyWeightedPosition_(pset.getParameter<bool>(
"energyWeightedPosition")) {
181 if (energyShareAlgo ==
"fractions")
183 else if (energyShareAlgo ==
"none")
185 else if (energyShareAlgo ==
"greedy")
187 else if (energyShareAlgo ==
"crude")
190 throw cms::Exception(
"Configuration") <<
"Unsupported energyShareAlgo '" << energyShareAlgo <<
"'\n";
198 clusterIndex_.fill(-1);
202 unsigned int i, ncells = grid_->size();
207 for (i = 0; i < ncells; ++
i) {
208 if (rawet_[i] < zsEt_) {
218 for (i = 0; i < ncells; ++
i) {
219 if (rawet_[i] > seedEt_) {
220 precluster_[
i].ptLocalMax = rawet_[
i];
223 for (
int ineigh = 0; ineigh <= 3; ++ineigh) {
224 if (rawet_.neigh(i, ineigh) > rawet_[
i])
225 precluster_[i].ptLocalMax = 0;
231 for (
int ineigh = 4; ineigh < 8; ++ineigh) {
232 if (rawet_.neigh(i, ineigh) >= rawet_[
i])
233 precluster_[i].ptLocalMax = 0;
242 for (i = 0; i < ncells; ++
i) {
243 if (precluster_[i].ptLocalMax == 0) {
244 switch (energyShareAlgo_) {
245 case EnergyShareAlgo::Fractions: {
247 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
248 tot += precluster_.neigh(i, ineigh).ptLocalMax;
250 precluster_[
i].ptOverNeighLocalMaxSum = tot ? rawet_[
i] / tot : 0;
253 precluster_[
i].ptOverNeighLocalMaxSum = rawet_[
i];
255 case EnergyShareAlgo::Greedy: {
257 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
258 maxet =
std::max(maxet, precluster_.neigh(i, ineigh).ptLocalMax);
260 precluster_[
i].ptOverNeighLocalMaxSum = maxet;
262 case EnergyShareAlgo::Crude: {
264 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
265 number += (precluster_.neigh(i, ineigh).ptLocalMax > 0);
267 precluster_[
i].ptOverNeighLocalMaxSum = (number > 1 ? 0.5 : 1.0) * rawet_[
i];
273 clusterIndex_.fill(-1);
275 unclustered_ = rawet_;
278 for (i = 0; i < ncells; ++
i) {
279 if (precluster_[i].ptLocalMax > 0) {
280 float myet = rawet_[
i];
286 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
287 int ineighcell = grid_->neighbour(i, ineigh);
288 if (ineighcell == -1)
291 switch (energyShareAlgo_) {
292 case EnergyShareAlgo::Fractions:
293 fracet = myet * precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum;
296 fracet = precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum;
298 case EnergyShareAlgo::Greedy:
299 fracet = (myet == precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum ? rawet_.neigh(i, ineigh) : 0);
301 case EnergyShareAlgo::Crude:
302 fracet = precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum;
308 cluster.
constituents.emplace_back(ineighcell, fracet / rawet_.neigh(i, ineigh));
309 if (energyWeightedPosition_) {
310 avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(i));
311 avg_phi += fracet *
deltaPhi(grid_->phi(ineighcell), grid_->phi(i));
314 if (tot > minClusterEt_) {
317 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
318 int ineighcell = grid_->neighbour(i, ineigh);
319 if (ineighcell == -1)
321 unclustered_[ineighcell] = 0;
323 if (energyWeightedPosition_) {
324 cluster.
eta = grid_->eta(i) + avg_eta / tot;
325 cluster.
phi = grid_->phi(i) + avg_phi / tot;
329 cluster.
eta = grid_->eta(i);
330 cluster.
phi = grid_->phi(i);
332 clusterIndex_[
i] = clusters_.size();
333 clusters_.push_back(cluster);
337 if (minEtToGrow_ > 0)
342 int selneighs[4] = {1, 3, 4, 6};
343 std::vector<int> toreset;
344 for (
Cluster &cluster : clusters_) {
345 if (cluster.et > minEtToGrow_) {
346 int i = cluster.constituents.front().first;
347 for (
int side = 0; side < 4; ++side) {
348 int neigh = grid_->neighbour(i, selneighs[side]);
351 for (
int in = 0;
in < 8; ++
in) {
352 int n2 = grid_->neighbour(neigh,
in);
355 cluster.et += unclustered_[n2];
356 if (unclustered_[n2]) {
357 cluster.constituents.emplace_back(n2, 1.0);
358 toreset.push_back(n2);
364 for (
int i : toreset)
370 auto ret = std::make_unique<l1t::PFClusterCollection>();
371 const EtGrid &
src = (unclusteredOnly ? unclustered_ : rawet_);
372 for (
unsigned int i = 0, ncells = grid_->size();
i < ncells; ++
i) {
375 if ((unclusteredOnly ==
false) && (ptMin == 0)) {
378 ret->emplace_back(src[
i], grid_->eta(i), grid_->phi(i));
379 ret->back().setHwEta(grid_->ieta(i));
380 ret->back().setHwPhi(grid_->iphi(i));
386 auto ret = std::make_unique<l1t::PFClusterCollection>();
387 for (
const Cluster &cluster : clusters_) {
388 if (cluster.et > ptMin) {
389 ret->emplace_back(cluster.et, cluster.eta, cluster.phi);
397 auto ret = std::make_unique<l1t::PFClusterCollection>();
398 for (
const Cluster &cluster : clusters_) {
399 if (cluster.et > ptMin) {
400 ret->emplace_back(cluster.et, cluster.eta, cluster.phi);
401 for (
const auto &pair : cluster.constituents) {
403 ret->back().addConstituent(ref, pair.second);
416 clusterIndex_(*grid_),
418 hoeCut_(pset.getParameter<double>(
"hoeCut")),
419 minPhotonEt_(pset.getParameter<double>(
"minPhotonEt")),
420 minHadronRawEt_(pset.getParameter<double>(
"minHadronRawEt")),
421 minHadronEt_(pset.getParameter<double>(
"minHadronEt")),
422 noEmInHGC_(pset.getParameter<bool>(
"noEmInHGC")) {
424 throw cms::Exception(
"LogicError",
"Inconsistent grid between ecal and linker\n");
426 throw cms::Exception(
"LogicError",
"Inconsistent grid between hcal and linker\n");
433 return fetch(ecal, hcal);
440 auto ret = std::make_unique<l1t::PFClusterCollection>();
442 if (cluster.et > 0) {
443 bool photon = (cluster.hcal_et < hoeCut_ * cluster.ecal_et);
444 if (photon && noEmInHGC_) {
449 if (cluster.et > (photon ? minPhotonEt_ : minHadronEt_)) {
450 ret->emplace_back(cluster.et,
453 cluster.ecal_et > 0 ?
std::max(cluster.et - cluster.ecal_et, 0.f) / cluster.ecal_et : -1,
456 for (
const auto &pair : cluster.constituents) {
458 if (pair.first > 0) {
484 unsigned int i, ncells = grid_->size();
486 const EtGrid &hraw = hcal_.raw();
487 const IndexGrid &ecals = ecal_.indexGrid();
488 const IndexGrid &hcals = hcal_.indexGrid();
492 for (i = 0; i < ncells; ++
i) {
495 ecalToHCal_[
i].ptLocalMax = hcal_.cluster(i).et;
498 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
499 tot += hcal_.cluster(grid_->neighbour(i, ineigh)).et;
501 ecalToHCal_[
i].ptOverNeighLocalMaxSum = tot ? ecal_.cluster(i).et / tot : 0;
506 clusterIndex_.fill(-1);
510 for (i = 0; i < ncells; ++
i) {
515 if (ecalToHCal_[i].ptLocalMax > 0) {
518 if (ecal.
et + hcal.
et > minHadronRawEt_) {
522 float wecal = cluster.
ecal_et / cluster.
et, whcal = 1.0 - wecal;
523 cluster.
eta = ecal.
eta * wecal + hcal.
eta * whcal;
524 cluster.
phi = ecal.
phi * wecal + hcal.
phi * whcal;
531 float myet = hcal.
et;
535 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
536 int ineighcell = grid_->neighbour(i, ineigh);
537 if (ineighcell == -1)
539 float fracet = myet * ecalToHCal_.neigh(i, ineigh).ptOverNeighLocalMaxSum;
543 avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(i));
544 avg_phi += fracet *
deltaPhi(grid_->phi(ineighcell), grid_->phi(i));
545 cluster.
constituents.emplace_back(-i - 1, fracet / ecal_.cluster(ineighcell).et);
547 if (myet + etot > minHadronRawEt_) {
550 cluster.
et = myet + etot;
551 cluster.
eta = hcal.
eta + avg_eta / cluster.
et;
552 cluster.
phi = hcal.
phi + avg_phi / cluster.
et;
557 if (cluster.
et > 0) {
558 clusterIndex_[
i] = clusters_.size();
559 clusters_.push_back(cluster);
565 for (i = 0; i < ncells; ++
i) {
566 if (ecals[i] >= 0 && ecalToHCal_[i].ptLocalMax == 0 && ecalToHCal_[i].ptOverNeighLocalMaxSum == 0) {
575 clusterIndex_[
i] = clusters_.size();
576 clusters_.push_back(cluster);
590 combClusterer_.clear();
594 combClusterer_.clear();
596 const EtGrid &hraw = hcal_.raw();
597 const EtGrid &eraw = ecal_.raw();
598 combClusterer_.raw() = eraw;
599 combClusterer_.raw() += hraw;
601 combClusterer_.run();
602 clusterIndex_ = combClusterer_.indexGrid();
603 const std::vector<Cluster> &clustersSrc = combClusterer_.clusters();
604 unsigned int nclust = clustersSrc.size();
605 clusters_.resize(nclust);
606 for (
unsigned int ic = 0; ic <
nclust; ++ic) {
615 if (eraw[pair.first]) {
616 dst.
ecal_et += pair.second * eraw[pair.first];
617 dst.
constituents.emplace_back(-pair.first - 1, pair.second);
619 if (hraw[pair.first]) {
620 dst.
hcal_et += pair.second * hraw[pair.first];
621 dst.
constituents.emplace_back(+pair.first + 1, pair.second);
631 if (algo ==
"simple") {
632 return std::make_unique<l1tpf_calo::SimpleCaloLinker>(
pset,
ecal,
hcal);
633 }
else if (algo ==
"flat") {
634 return std::make_unique<l1tpf_calo::FlatCaloLinker>(
pset,
ecal,
hcal);
636 throw cms::Exception(
"Configuration") <<
"Unsupported linker algo '" << algo <<
"'\n";
Phase1GridBase(int nEta, int nPhi, int ietaCoarse, int ietaVeryCoarse, const float *towerEtas)
int imove(int ieta, int iphi, int deta, int dphi)
tuple ret
prodAgent to be discontinued
std::vector< float > eta_
virtual ~SimpleCaloLinkerBase()
constexpr T reduceRange(T x)
std::unique_ptr< l1t::PFClusterCollection > fetchCells(bool unclusteredOnly=false, float ptMin=0.) const
SimpleCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
SingleCaloClusterer(const edm::ParameterSet &pset)
const EtGrid & raw() const
std::unique_ptr< SimpleCaloLinkerBase > makeCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
std::vector< float > etaWidth_
FlatCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
SimpleCaloLinkerBase(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
const Grid * getGrid(const std::string &type)
int find_cell(float eta, float phi) const override
std::vector< int > cell_map_
const int ietaVeryCoarse_
std::vector< float > phiWidth_
static const int phase1_nEta_
tuple key
prepare the HTCondor submission files and eventually submit them
Abs< T >::type abs(const T &t)
std::unique_ptr< l1t::PFClusterCollection > fetch(float ptMin=0.) const
static const int phase2_nEta_
std::vector< float > phi_
std::vector< std::pair< int, float > > constituents
void grow()
possibly grow clusters by adding unclustered energy on the sides
caConstants::TupleMultiplicity const CAHitNtupletGeneratorKernelsGPU::HitToTuple const cms::cuda::AtomicPairCounter GPUCACell const *__restrict__ cells
void fill(std::map< std::string, TH1 * > &h, const std::string &s, double x)
const Grid & grid() const
T getParameter(std::string const &) const
__host__ __device__ constexpr RandomIt lower_bound(RandomIt first, RandomIt last, const T &value, Compare comp={})
~SimpleCaloLinker() override
~FlatCaloLinker() override
std::vector< std::array< int, 8 > > neighbours_
EnergyShareAlgo energyShareAlgo_
std::pair< std::string, std::shared_ptr< void > > fetch(const cond::Hash &payloadId, Session &session)
static const float phase1_towerEtas_[phase1_nEta_]
bool valid_ieta_iphi(int ieta, int iphi) const
static const float phase2_towerEtas_[phase2_nEta_]
std::unique_ptr< l1t::PFClusterCollection > fetch() const