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_),
173 clusterIndex_(*grid_),
175 preciseEtaPhi_(
pset.existsAs<
bool>(
"usePreciseEtaPhi") ?
pset.getParameter<
bool>(
"usePreciseEtaPhi") :
false),
176 etaBounds_(
pset.getParameter<
std::
vector<double>>(
"etaBounds")),
177 phiBounds_(
pset.getParameter<
std::
vector<double>>(
"phiBounds")),
178 maxClustersEtaPhi_(
pset.getParameter<
std::
vector<unsigned
int>>(
"maxClustersEtaPhi")),
181 zsEt_(
pset.getParameter<double>(
"zsEt")),
182 seedEt_(
pset.getParameter<double>(
"seedEt")),
183 minClusterEt_(
pset.getParameter<double>(
"minClusterEt")),
184 minEtToGrow_(
pset.existsAs<double>(
"minEtToGrow") ?
pset.getParameter<double>(
"minEtToGrow") : -1),
185 energyWeightedPosition_(
pset.getParameter<
bool>(
"energyWeightedPosition")) {
197 if (
pset.existsAs<std::vector<int>>(
"neighborCells")) {
208 <<
"Size mismatch between eta/phi bounds and max clusters: " << (
etaBounds_.size() - 1) <<
" x " 212 throw cms::Exception(
"Configuration") <<
"etaBounds is not sorted\n";
215 throw cms::Exception(
"Configuration") <<
"phiBounds is not sorted\n";
226 clusterIndex_.fill(-1);
230 unsigned int i, ncells = grid_->size();
235 for (
i = 0;
i < ncells; ++
i) {
236 if (rawet_[
i] < zsEt_) {
246 for (
i = 0;
i < ncells; ++
i) {
247 if (rawet_[
i] > seedEt_) {
248 precluster_[
i].ptLocalMax = rawet_[
i];
251 for (
const auto &ineigh : neighborCells_) {
254 if (rawet_.neigh(
i, ineigh) > rawet_[
i])
255 precluster_[
i].ptLocalMax = 0;
261 for (
const auto &ineigh : neighborCells_) {
264 if (rawet_.neigh(
i, ineigh) >= rawet_[
i])
265 precluster_[
i].ptLocalMax = 0;
274 for (
i = 0;
i < ncells; ++
i) {
275 if (precluster_[
i].ptLocalMax == 0) {
276 switch (energyShareAlgo_) {
277 case EnergyShareAlgo::Fractions: {
279 for (
const auto &ineigh : neighborCells_) {
280 tot += precluster_.neigh(
i, ineigh).ptLocalMax;
282 precluster_[
i].ptOverNeighLocalMaxSum =
tot ? rawet_[
i] /
tot : 0;
285 precluster_[
i].ptOverNeighLocalMaxSum = rawet_[
i];
287 case EnergyShareAlgo::Greedy: {
289 for (
const auto &ineigh : neighborCells_) {
292 precluster_[
i].ptOverNeighLocalMaxSum =
maxet;
294 case EnergyShareAlgo::Crude: {
296 for (
const auto &ineigh : neighborCells_) {
297 number += (precluster_.neigh(
i, ineigh).ptLocalMax > 0);
299 precluster_[
i].ptOverNeighLocalMaxSum = (
number > 1 ? 0.5 : 1.0) * rawet_[
i];
305 clusterIndex_.fill(-1);
307 unclustered_ = rawet_;
310 for (
i = 0;
i < ncells; ++
i) {
311 if (precluster_[
i].ptLocalMax > 0) {
312 float myet = rawet_[
i];
318 for (
const auto &ineigh : neighborCells_) {
319 int ineighcell = grid_->neighbour(
i, ineigh);
320 if (ineighcell == -1)
323 switch (energyShareAlgo_) {
324 case EnergyShareAlgo::Fractions:
325 fracet = myet * precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
328 fracet = precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
330 case EnergyShareAlgo::Greedy:
331 fracet = (myet == precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum ? rawet_.neigh(
i, ineigh) : 0);
333 case EnergyShareAlgo::Crude:
334 fracet = precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
340 cluster.
constituents.emplace_back(ineighcell, fracet / rawet_.neigh(
i, ineigh));
341 if (energyWeightedPosition_) {
342 avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(
i));
343 avg_phi += fracet *
deltaPhi(grid_->phi(ineighcell), grid_->phi(
i));
346 if (
tot > minClusterEt_) {
349 for (
const auto &ineigh : neighborCells_) {
350 int ineighcell = grid_->neighbour(
i, ineigh);
351 if (ineighcell == -1)
353 unclustered_[ineighcell] = 0;
355 if (energyWeightedPosition_) {
356 cluster.
eta = grid_->eta(
i) + avg_eta /
tot;
357 cluster.
phi = grid_->phi(
i) + avg_phi /
tot;
361 cluster.
eta = grid_->eta(
i);
362 cluster.
phi = grid_->phi(
i);
364 clusterIndex_[
i] = clusters_.size();
365 clusters_.push_back(cluster);
369 if (minEtToGrow_ > 0)
374 int selneighs[4] = {1, 3, 4, 6};
375 std::vector<int> toreset;
376 for (
Cluster &cluster : clusters_) {
377 if (cluster.et > minEtToGrow_) {
378 int i = cluster.constituents.front().first;
379 for (
int side = 0; side < 4; ++side) {
380 int neigh = grid_->neighbour(
i, selneighs[side]);
383 for (
int in = 0;
in < 8; ++
in) {
384 int n2 = grid_->neighbour(neigh,
in);
387 cluster.et += unclustered_[n2];
388 if (unclustered_[n2]) {
389 cluster.constituents.emplace_back(n2, 1.0);
390 toreset.push_back(n2);
396 for (
int i : toreset)
402 auto ret = std::make_unique<l1t::PFClusterCollection>();
403 const EtGrid &
src = (unclusteredOnly ? unclustered_ : rawet_);
407 int totalClusters = 0;
408 for (
unsigned int i = 0, ncells = grid_->size();
i < ncells; ++
i) {
411 if ((unclusteredOnly ==
false) && (
ptMin == 0)) {
412 assert(cellKey_[
i] == totalClusters);
421 src[theIndex], grid_->eta(theIndex) + eta_shift[theIndex], grid_->
phi(theIndex) + phi_shift[theIndex]);
422 ret->back().setHwEta(grid_->ieta(theIndex));
423 ret->back().setHwPhi(grid_->iphi(theIndex));
429 auto ret = std::make_unique<l1t::PFClusterCollection>();
430 for (
const Cluster &cluster : clusters_) {
431 if (cluster.et >
ptMin) {
432 ret->emplace_back(cluster.et, cluster.eta, cluster.phi);
440 auto ret = std::make_unique<l1t::PFClusterCollection>();
441 for (
const Cluster &cluster : clusters_) {
442 if (cluster.et >
ptMin) {
443 ret->emplace_back(cluster.et, cluster.eta, cluster.phi);
444 for (
const auto &pair : cluster.constituents) {
446 ret->back().addConstituent(ref, pair.second);
459 clusterIndex_(*grid_),
461 etaBounds_(
pset.getParameter<
std::
vector<double>>(
"etaBounds")),
462 phiBounds_(
pset.getParameter<
std::
vector<double>>(
"phiBounds")),
463 maxClustersEtaPhi_(
pset.getParameter<
std::
vector<unsigned
int>>(
"maxClustersEtaPhi")),
464 hoeCut_(
pset.getParameter<double>(
"hoeCut")),
465 minPhotonEt_(
pset.getParameter<double>(
"minPhotonEt")),
466 minHadronRawEt_(
pset.getParameter<double>(
"minHadronRawEt")),
467 minHadronEt_(
pset.getParameter<double>(
"minHadronEt")),
468 noEmInHGC_(
pset.getParameter<
bool>(
"noEmInHGC")) {
470 throw cms::Exception(
"LogicError",
"Inconsistent grid between ecal and linker\n");
472 throw cms::Exception(
"LogicError",
"Inconsistent grid between hcal and linker\n");
475 <<
"Size mismatch between eta/phi bounds and max clusters: " << (
etaBounds_.size() - 1) <<
" x " 479 throw cms::Exception(
"Configuration") <<
"etaBounds is not sorted\n";
482 throw cms::Exception(
"Configuration") <<
"phiBounds is not sorted\n";
496 bool setRefs = (
ecal.isValid() &&
hcal.isValid());
497 auto ret = std::make_unique<l1t::PFClusterCollection>();
499 unsigned int index = 0;
502 if (cluster.et > 0) {
503 bool photon = (cluster.hcal_et < hoeCut_ * cluster.ecal_et);
504 if (
photon && noEmInHGC_) {
509 selector.fill(cluster.et, cluster.eta, cluster.phi,
index - 1);
517 if (cluster.
et > (
photon ? minPhotonEt_ : minHadronEt_)) {
518 ret->emplace_back(cluster.
et,
526 if (pair.first > 0) {
551 unsigned int i, ncells = grid_->size();
553 const EtGrid &hraw = hcal_.raw();
554 const IndexGrid &ecals = ecal_.indexGrid();
555 const IndexGrid &hcals = hcal_.indexGrid();
559 for (
i = 0;
i < ncells; ++
i) {
562 ecalToHCal_[
i].ptLocalMax = hcal_.cluster(
i).et;
565 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
566 tot += hcal_.cluster(grid_->neighbour(
i, ineigh)).
et;
568 ecalToHCal_[
i].ptOverNeighLocalMaxSum =
tot ? ecal_.cluster(
i).et /
tot : 0;
573 clusterIndex_.fill(-1);
577 for (
i = 0;
i < ncells; ++
i) {
582 if (ecalToHCal_[
i].ptLocalMax > 0) {
585 if (
ecal.et +
hcal.et > minHadronRawEt_) {
589 float wecal = cluster.
ecal_et / cluster.
et, whcal = 1.0 - wecal;
600 float myet =
hcal.et;
604 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
605 int ineighcell = grid_->neighbour(
i, ineigh);
606 if (ineighcell == -1)
608 float fracet = myet * ecalToHCal_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
612 avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(
i));
613 avg_phi += fracet *
deltaPhi(grid_->phi(ineighcell), grid_->phi(
i));
614 cluster.
constituents.emplace_back(-
i - 1, fracet / ecal_.cluster(ineighcell).et);
616 if (myet + etot > minHadronRawEt_) {
619 cluster.
et = myet + etot;
620 cluster.
eta =
hcal.eta + avg_eta / cluster.
et;
621 cluster.
phi =
hcal.phi + avg_phi / cluster.
et;
628 if (cluster.
et > 0) {
629 clusterIndex_[
i] = clusters_.size();
630 clusters_.push_back(cluster);
636 for (
i = 0;
i < ncells; ++
i) {
637 if (ecals[
i] >= 0 && ecalToHCal_[
i].ptLocalMax == 0 && ecalToHCal_[
i].ptOverNeighLocalMaxSum == 0) {
646 clusterIndex_[
i] = clusters_.size();
647 clusters_.push_back(cluster);
661 combClusterer_.clear();
665 combClusterer_.clear();
667 const EtGrid &hraw = hcal_.raw();
668 const EtGrid &eraw = ecal_.raw();
669 combClusterer_.raw() = eraw;
670 combClusterer_.raw() += hraw;
672 combClusterer_.run();
673 clusterIndex_ = combClusterer_.indexGrid();
674 const std::vector<Cluster> &clustersSrc = combClusterer_.clusters();
675 unsigned int nclust = clustersSrc.size();
677 for (
unsigned int ic = 0; ic <
nclust; ++ic) {
687 for (
const auto &pair :
src.constituents) {
688 if (eraw[pair.first]) {
689 dst.ecal_et += pair.second * eraw[pair.first];
690 dst.constituents.emplace_back(-pair.first - 1, pair.second);
692 if (hraw[pair.first]) {
693 dst.hcal_et += pair.second * hraw[pair.first];
694 dst.constituents.emplace_back(+pair.first + 1, pair.second);
709 combClusterer_.clear();
713 combClusterer_.clear();
715 const EtGrid &hraw = hcal_.raw();
716 const EtGrid &eraw = ecal_.raw();
719 combClusterer_.raw() = eraw;
720 combClusterer_.raw() += hraw;
722 combClusterer_.run();
723 clusterIndex_ = combClusterer_.indexGrid();
724 const std::vector<Cluster> &clustersSrc = combClusterer_.clusters();
725 unsigned int nclust = clustersSrc.size();
727 for (
unsigned int ic = 0; ic <
nclust; ++ic) {
738 for (
const auto &pair :
src.constituents) {
739 if (eraw[pair.first]) {
740 float ept = pair.second * eraw[pair.first];
742 dst.constituents.emplace_back(-pair.first - 1, pair.second);
744 eta_ecal = eeta[pair.first];
745 phi_ecal = ephi[pair.first];
749 if (hraw[pair.first]) {
750 dst.hcal_et += pair.second * hraw[pair.first];
751 dst.constituents.emplace_back(+pair.first + 1, pair.second);
754 dst.ecal_eta = eta_ecal;
755 dst.ecal_phi = phi_ecal;
768 if (!maxClustersEtaPhi_.empty()) {
769 unsigned int etai = etaBounds_.size();
770 for (
unsigned int ie = 0; ie < etaBounds_.size() - 1; ie++) {
771 if (
eta >= etaBounds_[ie] &&
eta < etaBounds_[ie + 1]) {
776 unsigned int phii = phiBounds_.size();
777 for (
unsigned int ip = 0; ip < phiBounds_.size() - 1; ip++) {
778 if (phi >= phiBounds_[ip] && phi < phiBounds_[ip + 1]) {
783 if (etai < etaBounds_.size() && phii < phiBounds_.size()) {
784 regionPtIndices_[etai * (phiBounds_.size() - 1) + phii].emplace_back(
pt,
index);
787 regionPtIndices_[0].emplace_back(
pt,
index);
792 std::vector<unsigned int>
indices;
793 for (
auto ®ionPtIndex : regionPtIndices_) {
794 std::sort(regionPtIndex.begin(), regionPtIndex.end(), std::greater<std::pair<float, unsigned int>>());
795 for (
const auto &
p : regionPtIndex) {
806 if (
algo ==
"simple") {
807 return std::make_unique<l1tpf_calo::SimpleCaloLinker>(
pset,
ecal,
hcal);
808 }
else if (
algo ==
"flat") {
809 return std::make_unique<l1tpf_calo::FlatCaloLinker>(
pset,
ecal,
hcal);
810 }
else if (
algo ==
"combined") {
811 return std::make_unique<l1tpf_calo::CombinedCaloLinker>(
pset,
ecal,
hcal);
813 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< double > etaBounds_
std::vector< float > eta_
virtual ~SimpleCaloLinkerBase()
std::vector< unsigned int > maxClustersEtaPhi_
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)
void fill(float pt, float eta, float phi, unsigned int index)
std::vector< unsigned int > maxClustersEtaPhi_
std::unique_ptr< SimpleCaloLinkerBase > makeCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
CombinedCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal)
~CombinedCaloLinker() override
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
std::vector< unsigned int > returnSorted()
std::vector< double > phiBounds_
float phi(float eta, float phi) const
void grow()
possibly grow clusters by adding unclustered energy on the sides
std::vector< double > phiBounds_
GridSelector(std::vector< double > etaBounds, std::vector< double > phiBounds, std::vector< unsigned int > maxClusters)
std::vector< double > etaBounds_
std::unique_ptr< l1t::PFClusterCollection > fetch(float ptMin=0.) const
~SimpleCaloLinker() override
~FlatCaloLinker() override
std::vector< std::array< int, 8 > > neighbours_
std::vector< int > neighborCells_
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_]