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),
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)
90 int iphi = std::floor(phi * nPhi_ / (2 *
M_PI));
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);
158 if (
type ==
"phase1")
160 else if (
type ==
"phase2")
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")) {
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) {
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");
439 bool setRefs = (
ecal.isValid() &&
hcal.isValid());
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;
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();
606 for (
unsigned int ic = 0; ic <
nclust; ++ic) {
614 for (
const auto &pair :
src.constituents) {
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)
std::vector< float > eta_
virtual ~SimpleCaloLinkerBase()
constexpr T reduceRange(T x)
ret
prodAgent to be discontinued
SimpleCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
SingleCaloClusterer(const edm::ParameterSet &pset)
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)
bool valid_ieta_iphi(int ieta, int iphi) const
std::unique_ptr< l1t::PFClusterCollection > fetch() const
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_
Abs< T >::type abs(const T &t)
std::unique_ptr< l1t::PFClusterCollection > fetchCells(bool unclusteredOnly=false, 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
std::unique_ptr< l1t::PFClusterCollection > fetch(float ptMin=0.) const
~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_]
static const float phase2_towerEtas_[phase2_nEta_]