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) {
54 for (icell = 0; icell <
int(
ncells_); ++icell) {
57 for (
int deta = -1; deta <= +1; ++deta) {
58 for (
int dphi = -1; dphi <= +1; ++dphi) {
59 if (deta == 0 && dphi == 0)
88 int iphi = std::floor(phi * nPhi_ / (2 *
M_PI));
120 ie = (ie == -nEta_ ? 0 : (ie == +1 ? -1 : ie - 1));
123 ie = (ie == +nEta_ ? 0 : (ie == -1 ? +1 : ie + 1));
134 iph = (iph == 1 ? nPhi_ : iph - 1);
137 iph = (iph == nPhi_ ? 1 : iph + 1);
144 if (!valid_ieta_iphi(ie, iph))
146 int icell = ifind_cell(ie, iph);
156 if (
type ==
"phase1")
158 else if (
type ==
"phase2")
167 unclustered_(*grid_),
169 clusterIndex_(*grid_),
173 zsEt_(
pset.getParameter<double>(
"zsEt")),
174 seedEt_(
pset.getParameter<double>(
"seedEt")),
175 minClusterEt_(
pset.getParameter<double>(
"minClusterEt")),
176 minEtToGrow_(
pset.existsAs<double>(
"minEtToGrow") ?
pset.getParameter<double>(
"minEtToGrow") : -1),
177 energyWeightedPosition_(
pset.getParameter<
bool>(
"energyWeightedPosition")) {
196 clusterIndex_.fill(-1);
200 unsigned int i, ncells = grid_->size();
205 for (
i = 0;
i < ncells; ++
i) {
206 if (rawet_[
i] < zsEt_) {
216 for (
i = 0;
i < ncells; ++
i) {
217 if (rawet_[
i] > seedEt_) {
218 precluster_[
i].ptLocalMax = rawet_[
i];
221 for (
int ineigh = 0; ineigh <= 3; ++ineigh) {
222 if (rawet_.neigh(
i, ineigh) > rawet_[
i])
223 precluster_[
i].ptLocalMax = 0;
229 for (
int ineigh = 4; ineigh < 8; ++ineigh) {
230 if (rawet_.neigh(
i, ineigh) >= rawet_[
i])
231 precluster_[
i].ptLocalMax = 0;
240 for (
i = 0;
i < ncells; ++
i) {
241 if (precluster_[
i].ptLocalMax == 0) {
242 switch (energyShareAlgo_) {
243 case EnergyShareAlgo::Fractions: {
245 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
246 tot += precluster_.neigh(
i, ineigh).ptLocalMax;
248 precluster_[
i].ptOverNeighLocalMaxSum = tot ? rawet_[
i] / tot : 0;
251 precluster_[
i].ptOverNeighLocalMaxSum = rawet_[
i];
253 case EnergyShareAlgo::Greedy: {
255 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
258 precluster_[
i].ptOverNeighLocalMaxSum =
maxet;
260 case EnergyShareAlgo::Crude: {
262 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
263 number += (precluster_.neigh(
i, ineigh).ptLocalMax > 0);
265 precluster_[
i].ptOverNeighLocalMaxSum = (
number > 1 ? 0.5 : 1.0) * rawet_[
i];
271 clusterIndex_.fill(-1);
273 unclustered_ = rawet_;
276 for (
i = 0;
i < ncells; ++
i) {
277 if (precluster_[
i].ptLocalMax > 0) {
278 float myet = rawet_[
i];
284 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
285 int ineighcell = grid_->neighbour(
i, ineigh);
286 if (ineighcell == -1)
289 switch (energyShareAlgo_) {
290 case EnergyShareAlgo::Fractions:
291 fracet = myet * precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
294 fracet = precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
296 case EnergyShareAlgo::Greedy:
297 fracet = (myet == precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum ? rawet_.neigh(
i, ineigh) : 0);
299 case EnergyShareAlgo::Crude:
300 fracet = precluster_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
306 cluster.
constituents.emplace_back(ineighcell, fracet / rawet_.neigh(
i, ineigh));
307 if (energyWeightedPosition_) {
308 avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(
i));
309 avg_phi += fracet *
deltaPhi(grid_->phi(ineighcell), grid_->phi(
i));
312 if (tot > minClusterEt_) {
315 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
316 int ineighcell = grid_->neighbour(
i, ineigh);
317 if (ineighcell == -1)
319 unclustered_[ineighcell] = 0;
321 if (energyWeightedPosition_) {
322 cluster.
eta = grid_->eta(
i) + avg_eta / tot;
323 cluster.
phi = grid_->phi(
i) + avg_phi / tot;
327 cluster.
eta = grid_->eta(
i);
328 cluster.
phi = grid_->phi(
i);
330 clusterIndex_[
i] = clusters_.size();
331 clusters_.push_back(cluster);
335 if (minEtToGrow_ > 0)
340 int selneighs[4] = {1, 3, 4, 6};
341 std::vector<int> toreset;
342 for (
Cluster &cluster : clusters_) {
343 if (cluster.et > minEtToGrow_) {
344 int i = cluster.constituents.front().first;
345 for (
int side = 0; side < 4; ++side) {
346 int neigh = grid_->neighbour(
i, selneighs[side]);
349 for (
int in = 0;
in < 8; ++
in) {
350 int n2 = grid_->neighbour(neigh,
in);
353 cluster.et += unclustered_[n2];
354 if (unclustered_[n2]) {
355 cluster.constituents.emplace_back(n2, 1.0);
356 toreset.push_back(n2);
362 for (
int i : toreset)
368 auto ret = std::make_unique<l1t::PFClusterCollection>();
369 const EtGrid &
src = (unclusteredOnly ? unclustered_ : rawet_);
370 for (
unsigned int i = 0, ncells = grid_->size();
i < ncells; ++
i) {
373 if ((unclusteredOnly ==
false) && (
ptMin == 0)) {
376 ret->emplace_back(
src[
i], grid_->eta(
i), grid_->phi(
i));
377 ret->back().setHwEta(grid_->ieta(
i));
378 ret->back().setHwPhi(grid_->iphi(
i));
384 auto ret = std::make_unique<l1t::PFClusterCollection>();
385 for (
const Cluster &cluster : clusters_) {
386 if (cluster.et >
ptMin) {
387 ret->emplace_back(cluster.et, cluster.eta, cluster.phi);
395 auto ret = std::make_unique<l1t::PFClusterCollection>();
396 for (
const Cluster &cluster : clusters_) {
397 if (cluster.et >
ptMin) {
398 ret->emplace_back(cluster.et, cluster.eta, cluster.phi);
399 for (
const auto &pair : cluster.constituents) {
401 ret->back().addConstituent(ref, pair.second);
414 clusterIndex_(*grid_),
416 hoeCut_(
pset.getParameter<double>(
"hoeCut")),
417 minPhotonEt_(
pset.getParameter<double>(
"minPhotonEt")),
418 minHadronRawEt_(
pset.getParameter<double>(
"minHadronRawEt")),
419 minHadronEt_(
pset.getParameter<double>(
"minHadronEt")),
420 noEmInHGC_(
pset.getParameter<
bool>(
"noEmInHGC")) {
422 throw cms::Exception(
"LogicError",
"Inconsistent grid between ecal and linker\n");
424 throw cms::Exception(
"LogicError",
"Inconsistent grid between hcal and linker\n");
437 bool setRefs = (
ecal.isValid() &&
hcal.isValid());
438 auto ret = std::make_unique<l1t::PFClusterCollection>();
440 if (cluster.et > 0) {
441 bool photon = (cluster.hcal_et < hoeCut_ * cluster.ecal_et);
442 if (
photon && noEmInHGC_) {
447 if (cluster.et > (
photon ? minPhotonEt_ : minHadronEt_)) {
448 ret->emplace_back(cluster.et,
451 cluster.ecal_et > 0 ?
std::max(cluster.et - cluster.ecal_et, 0.f) / cluster.ecal_et : -1,
454 for (
const auto &pair : cluster.constituents) {
456 if (pair.first > 0) {
482 unsigned int i, ncells = grid_->size();
484 const EtGrid &hraw = hcal_.raw();
485 const IndexGrid &ecals = ecal_.indexGrid();
486 const IndexGrid &hcals = hcal_.indexGrid();
490 for (
i = 0;
i < ncells; ++
i) {
493 ecalToHCal_[
i].ptLocalMax = hcal_.cluster(
i).et;
496 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
497 tot += hcal_.cluster(grid_->neighbour(
i, ineigh)).
et;
499 ecalToHCal_[
i].ptOverNeighLocalMaxSum = tot ? ecal_.cluster(
i).et / tot : 0;
504 clusterIndex_.fill(-1);
508 for (
i = 0;
i < ncells; ++
i) {
513 if (ecalToHCal_[
i].ptLocalMax > 0) {
516 if (
ecal.et +
hcal.et > minHadronRawEt_) {
520 float wecal = cluster.
ecal_et / cluster.
et, whcal = 1.0 - wecal;
529 float myet =
hcal.et;
533 for (
int ineigh = 0; ineigh < 8; ++ineigh) {
534 int ineighcell = grid_->neighbour(
i, ineigh);
535 if (ineighcell == -1)
537 float fracet = myet * ecalToHCal_.neigh(
i, ineigh).ptOverNeighLocalMaxSum;
541 avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(
i));
542 avg_phi += fracet *
deltaPhi(grid_->phi(ineighcell), grid_->phi(
i));
543 cluster.
constituents.emplace_back(-
i - 1, fracet / ecal_.cluster(ineighcell).et);
545 if (myet + etot > minHadronRawEt_) {
548 cluster.
et = myet + etot;
549 cluster.
eta =
hcal.eta + avg_eta / cluster.
et;
550 cluster.
phi =
hcal.phi + avg_phi / cluster.
et;
555 if (cluster.
et > 0) {
556 clusterIndex_[
i] = clusters_.size();
557 clusters_.push_back(cluster);
563 for (
i = 0;
i < ncells; ++
i) {
564 if (ecals[
i] >= 0 && ecalToHCal_[
i].ptLocalMax == 0 && ecalToHCal_[
i].ptOverNeighLocalMaxSum == 0) {
573 clusterIndex_[
i] = clusters_.size();
574 clusters_.push_back(cluster);
588 combClusterer_.clear();
592 combClusterer_.clear();
594 const EtGrid &hraw = hcal_.raw();
595 const EtGrid &eraw = ecal_.raw();
596 combClusterer_.raw() = eraw;
597 combClusterer_.raw() += hraw;
599 combClusterer_.run();
600 clusterIndex_ = combClusterer_.indexGrid();
601 const std::vector<Cluster> &clustersSrc = combClusterer_.clusters();
602 unsigned int nclust = clustersSrc.size();
604 for (
unsigned int ic = 0; ic <
nclust; ++ic) {
612 for (
const auto &pair :
src.constituents) {
613 if (eraw[pair.first]) {
614 dst.ecal_et += pair.second * eraw[pair.first];
615 dst.constituents.emplace_back(-pair.first - 1, pair.second);
617 if (hraw[pair.first]) {
618 dst.hcal_et += pair.second * hraw[pair.first];
619 dst.constituents.emplace_back(+pair.first + 1, pair.second);
629 if (
algo ==
"simple") {
630 return std::make_unique<l1tpf_calo::SimpleCaloLinker>(
pset,
ecal,
hcal);
631 }
else if (
algo ==
"flat") {
632 return std::make_unique<l1tpf_calo::FlatCaloLinker>(
pset,
ecal,
hcal);
634 throw cms::Exception(
"Configuration") <<
"Unsupported linker algo '" <<
algo <<
"'\n";