ATLAS Offline Software
Loading...
Searching...
No Matches
egammaSuperClusterBuilderBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
10
12
21#include "xAODTracking/Vertex.h"
22
25
26#include <cmath>
27#include <optional>
28#include <utility>
29
31
32/*
33 * Gaudi Algorithm implementation
34 */
36 const std::string& name,
37 ISvcLocator* pSvcLocator)
38 : AthReentrantAlgorithm(name, pSvcLocator)
39{
40}
41
42StatusCode
44{
47 ATH_CHECK(m_caloDetDescrMgrKey.initialize());
50
55 // The +- to account for the different L3 eta granularity
57 // the + is to account for different L0/L1 phi granularity
59
64
65 if (m_addCellsWindowEtaCellsBarrel % 2 == 0 ||
67 ATH_MSG_FATAL("For adding cells relative to the hottest cell to be "
68 "symmetric in eta, the AddCells "
69 "window size needs to be odd");
70
71 return StatusCode::FAILURE;
72 }
74 ATH_CHECK(m_MVACalibSvc.retrieve());
75
76 if (!m_egammaCheckEnergyDepositTool.empty()) {
78 } else {
80 }
81 if (!m_egammaCellRecoveryTool.empty()) {
83 } else {
85 }
86
87 ATH_MSG_INFO("e/gamma super clusters"
88 << '\n'
89 << "--> Eta Window size for L0/L1/L2 cells : "
90 << " Barrel +- " << m_addCellsWindowEtaBarrel << " ,EndCap +- "
92 << "--> Eta Window size for L3 cells : "
93 << " Barrel +- "
95 << " ,EndCap +- "
97 << " -> Phi window is fully dynamic for L2/L3" << '\n'
98 << " -> L0/L1 cells in phi will be collected in a Window : "
99 << "(L2 neg extend - " << m_extraL0L1PhiSize << " , "
100 << "L2 pos extend + " << m_extraL0L1PhiSize << ")");
101
102 return StatusCode::SUCCESS;
103}
104
105StatusCode
106egammaSuperClusterBuilderBase::execute(const EventContext& ctx) const
107{
109 ctx);
110 // check is only used for serial running; remove when MT scheduler used
111 ATH_CHECK(egammaRecs.isValid());
112
113 // Have to register cluster container in order to properly get cluster
114 // links.
115 SG::WriteHandle<xAOD::CaloClusterContainer> outputClusterContainer(
117
119
120 // Create the new Electron Super Cluster based EgammaRecContainer
123 ATH_CHECK(newEgammaRecs.record(std::make_unique<EgammaRecContainer>()));
124
125 size_t inputSize = egammaRecs->size();
126 outputClusterContainer->reserve(inputSize);
127 newEgammaRecs->reserve(inputSize);
128
129 std::optional<SG::WriteHandle<xAOD::CaloClusterContainer>> precorrClustersH;
130 if (!m_precorrClustersKey.empty()) {
131 precorrClustersH.emplace(m_precorrClustersKey, ctx);
133 precorrClustersH->ptr()->reserve(inputSize);
134 }
135
136 // The calo Det Descr manager
137 SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle{
139 };
140 ATH_CHECK(caloDetDescrMgrHandle.isValid());
141 const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
142
143 // If no input return
144 if (egammaRecs->empty()) {
145 return StatusCode::SUCCESS;
146 }
147
148 // Figure the cellCont we need to point to
149 const DataLink<CaloCellContainer>& cellCont =
150 (*egammaRecs)[0]->caloCluster()->getCellLinks()->getCellContainerLink();
151
152 // Loop over input egammaRec objects, build superclusters.
153 size_t numInput = egammaRecs->size();
154 std::vector<bool> isUsed(numInput, false);
155 std::vector<bool> isUsedRevert(numInput, false);
156
157 for (std::size_t i = 0; i < egammaRecs->size(); ++i) {
158 if (isUsed[i]) {
159 continue;
160 }
161 const auto* egRec = (*egammaRecs)[i];
162 // check for good seed cluster
163 const xAOD::CaloCluster* clus = egRec->caloCluster();
164 if (!seedClusterSelection(clus)) {
165 continue;
166 }
167
168 if (!egammaRecPassesSelection(egRec)) {
169 continue;
170 }
171
172 // save status in case we fail to create supercluster
173 isUsedRevert = isUsed;
174 // Mark seed as used,
175 isUsed[i] = true;
176
177 // Start accumulating the clusters from the seed
178 std::vector<const xAOD::CaloCluster*> accumulatedClusters;
179 accumulatedClusters.push_back(clus);
180
181 // Now we find all the secondary cluster for this seed
182 // and we accumulate them
183 const std::vector<std::size_t> secondaryIndices =
184 searchForSecondaryClusters(i, egammaRecs.cptr(), isUsed);
185 for (const auto& secClusIndex : secondaryIndices) {
186 const auto* const secRec = (*egammaRecs)[secClusIndex];
187 accumulatedClusters.push_back(secRec->caloCluster());
188 }
189 ATH_MSG_DEBUG("Total clusters " << accumulatedClusters.size());
190
191 // Create the new cluster
192 std::unique_ptr<xAOD::CaloCluster> newCluster =
194 accumulatedClusters,
195 cellCont,
196 *calodetdescrmgr,
197 getEgammaRecType(egRec),
198 precorrClustersH ? precorrClustersH->ptr() : nullptr);
199
200 // If we failed to create a cluster revert isUsed for the cluster
201 if (newCluster) {
202 outputClusterContainer->push_back(std::move(newCluster));
203 }
204 else {
205 isUsed.swap(isUsedRevert);
206 continue;
207 }
208
209 // Add the cluster links to the super cluster
211 *outputClusterContainer, outputClusterContainer->size() - 1, ctx);
212 std::vector<ElementLink<xAOD::CaloClusterContainer>> elClusters{
213 clusterLink
214 };
215
216 // Make egammaRec object, and push it back into output container.
217 auto newEgRec = std::make_unique<egammaRec>(*egRec);
218 newEgRec->setCaloClusters(elClusters);
219 newEgammaRecs->push_back(std::move(newEgRec));
220 } // End loop on egammaRecs
221
222 ATH_CHECK(redoMatching(ctx, newEgammaRecs));
223
224 return StatusCode::SUCCESS;
225}
226
227bool
229 return true;
230}
231
232StatusCode
234 [[maybe_unused]] const EventContext &ctx,
235 [[maybe_unused]] SG::WriteHandle<EgammaRecContainer> &newEgammaRecs
236) const {
237 return StatusCode::SUCCESS;
238}
239
240bool
242 const xAOD::CaloCluster* ref,
243 const xAOD::CaloCluster* clus) const
244{
245 auto inRange = [](float eta1, float phi1,
246 float eta2, float phi2,
247 float etaWindow, float phiWindow) {
248
249 const float dEta = std::abs(eta1 - eta2);
250 const float dPhi = std::abs(P4Helpers::deltaPhi(phi1, phi2));
251
252 return dEta < etaWindow && dPhi < phiWindow;
253 };
254
255 // First the case where the seed is both endcap and barrel, i.e. in the crack
256 // Check around both measurements of the seed
257 if (ref->hasSampling(CaloSampling::EMB2) &&
258 ref->hasSampling(CaloSampling::EME2)) {
259 const bool inRangeBarrel = inRange(ref->eta(),
260 ref->phi(),
261 clus->eta(),
262 clus->phi(),
265
266 const bool inRangeEndcap = inRange(ref->eta(),
267 ref->phi(),
268 clus->eta(),
269 clus->phi(),
272
273 const bool inRangeBarrelL2 = inRange(ref->etaSample(CaloSampling::EMB2),
274 ref->phiSample(CaloSampling::EMB2),
275 clus->eta(),
276 clus->phi(),
279
280 const bool inRangeEndcapL2 = inRange(ref->etaSample(CaloSampling::EME2),
281 ref->phiSample(CaloSampling::EME2),
282 clus->eta(),
283 clus->phi(),
286
287 // Matches any in case of split
288 return inRangeBarrel || inRangeEndcap || inRangeBarrelL2 || inRangeEndcapL2;
289 }
290
292 return inRange(ref->eta(),
293 ref->phi(),
294 clus->eta(),
295 clus->phi(),
298 }
299
300 return inRange(ref->eta(),
301 ref->phi(),
302 clus->eta(),
303 clus->phi(),
306}
307
308std::unique_ptr<xAOD::CaloCluster>
310 const EventContext& ctx,
311 const std::vector<const xAOD::CaloCluster*>& clusters,
312 const DataLink<CaloCellContainer>& cellCont,
313 const CaloDetDescrManager& mgr,
315 xAOD::CaloClusterContainer* precorrClusters) const
316{
317 if (clusters.empty()) {
318 ATH_MSG_ERROR("Missing the seed cluster! Should not happen.");
319 return nullptr;
320 }
321
322 // create a new empty cluster
323 // collection will own it if
324 auto newCluster = CaloClusterStoreHelper::makeCluster(cellCont);
325
326 if (!newCluster) {
327 ATH_MSG_ERROR("CaloClusterStoreHelper::makeCluster failed.");
328 return nullptr;
329 }
330 //
331 newCluster->setClusterSize(xAOD::CaloCluster::SuperCluster);
332 // Let's try to find the eta and phi of the hottest cell in L2.
333 // This will be used as the center for restricting the cluster size.
334 CookieCutterHelpers::CentralPosition cp0(clusters, mgr);
335
336 // Set the eta0/phi0 based on the references, but in raw coordinates
337 if (cp0.emaxB >= cp0.emaxEC) {
338 newCluster->setEta0(cp0.etaB);
339 newCluster->setPhi0(cp0.phiB);
340 } else {
341 newCluster->setEta0(cp0.etaEC);
342 newCluster->setPhi0(cp0.phiEC);
343 }
344
345 // Actually fill the cluster here
346 if (fillClusterConstrained(*newCluster, clusters, cp0).isFailure()) {
347 return nullptr;
348 }
349 // Apply SW-style summation of TileGap3 cells (if necessary).
350 float eta0 = std::abs(newCluster->eta0());
351 // In Run2, we did not impose restriction to include TG3 cells at this level.
352 // It should have been [1.37,1.63]. It has no impact on performance as TG3 was
353 // only used in energy calibration BDT in [1.4,1.6].
354 // In Run three we restrict to [1.37,1.75]
355 if (!m_useExtendedTG3 ||
356 (eta0 > s_ClEtaMinForTG3cell && eta0 < s_ClEtaMaxForTG3cell)) {
357 if (addTileGap3CellsinWindow(*newCluster, mgr).isFailure()) {
358 ATH_MSG_ERROR("Problem with the input cluster when running "
359 "AddTileGap3CellsinWindow?");
360
361 return nullptr;
362 }
363 }
365 CaloClusterKineHelper::calculateKine(newCluster.get(), true, true);
366
367 // If adding all EM cells we are somehow below the seed threshold then remove
368 if (newCluster->et() < m_EtThresholdCut) {
369 return nullptr;
370 }
371
372 // Check to see if cluster pases basic requirements. If not, kill it.
373 if (!m_egammaCheckEnergyDepositTool.empty() &&
374 !m_egammaCheckEnergyDepositTool->checkFractioninSamplingCluster(
375 newCluster.get())) {
376 return nullptr;
377 }
378
379 // Apply correction calibration
380 if (calibrateCluster(ctx, newCluster.get(), mgr, egType, precorrClusters)
381 .isFailure()) {
382 ATH_MSG_WARNING("There was problem calibrating the object");
383 return nullptr;
384 }
385
386 // Avoid negative energy clusters
387 if (newCluster->et() < 0) {
388 return nullptr;
389 }
390
392 // EDM vector to constituent clusters
393 std::vector<ElementLink<xAOD::CaloClusterContainer>> constituentLinks;
394 const std::string linkStr{"constituentClusterLinks"};
395 for (const xAOD::CaloCluster* cluster : clusters) {
397 cluster->getSisterClusterLink();
398
399 // Set the element Link to the constitents
400 if (sisterCluster) {
401 constituentLinks.push_back(sisterCluster);
402 } else {
403 ATH_MSG_WARNING("No sister Link available");
404 }
405 }
406 // Set the link from the super cluster to the constituents (accumulated)
407 // clusters used.
408 static const SG::AuxElement::Accessor<
409 std::vector<ElementLink<xAOD::CaloClusterContainer>>>
410 caloClusterLinks(linkStr);
411 caloClusterLinks(*newCluster) = constituentLinks;
412 }
413 // return the new cluster
414 return newCluster;
415}
416
417bool
419 const xAOD::CaloCluster* clus) const
420{
421 // The seed should have 2nd sampling
422 if (!clus->hasSampling(CaloSampling::EMB2) &&
423 !clus->hasSampling(CaloSampling::EME2)) {
424 return false;
425 }
426 const double eta2 = std::abs(clus->etaBE(2));
427 if (eta2 > 10) {
428 return false;
429 }
430 // Accordeon Energy samplings 1 to 3
431 const double EMAccEnergy =
432 clus->energyBE(1) + clus->energyBE(2) + clus->energyBE(3);
433 const double EMAccEt = EMAccEnergy / cosh(eta2);
434 // Require minimum energy for supercluster seeding.
435 return EMAccEt >= m_EtThresholdCut;
436}
437
438StatusCode
440 xAOD::CaloCluster& tofill,
441 const std::vector<const xAOD::CaloCluster*>& clusters,
443{
444 const float addCellsWindowEtaBarrel = m_addCellsWindowEtaBarrel;
445 const float addCellsWindowEtaEndcap = m_addCellsWindowEtaEndcap;
446 const float addCellsWindowL3EtaBarrel =
448 const float addCellsWindowL3EtaEndcap =
450
451 // Loop for L2/L3
452 for (const xAOD::CaloCluster* tocheck : clusters) {
453 xAOD::CaloCluster::const_cell_iterator cell_itr = tocheck->begin();
454 xAOD::CaloCluster::const_cell_iterator cell_end = tocheck->end();
455 // Loop over cells
456 for (; cell_itr != cell_end; ++cell_itr) {
457 // sanity check on the cell
458 const CaloCell* cell = *cell_itr;
459 if (!cell) {
460 continue;
461 }
462 const CaloDetDescrElement* dde = cell->caloDDE();
463 if (!dde) {
464 continue;
465 }
466 // we want only LAREM
467 if (!(dde->getSubCalo() == CaloCell_ID::LAREM)) {
468 continue;
469 }
470 // we want L2 or L3 cells
471 const auto sampling = dde->getSampling();
472 const bool isL2Cell =
473 (CaloCell_ID::EMB2 == sampling || CaloCell_ID::EME2 == sampling);
474 const bool isL3Cell =
475 (CaloCell_ID::EMB3 == sampling || CaloCell_ID::EME3 == sampling);
476
477 if ((!isL2Cell) && (!isL3Cell)) {
478 continue;
479 }
480 // Also exclude the inner wheel Endcap
481 if (dde->is_lar_em_endcap_inner()) {
482 continue;
483 }
484
485 bool inEtaRange = false;
486 // Check if is inside the eta range wrt to the hottest
487 // cell(s) for the cluster we construct
488 if (cp0.emaxB > 0) { // barrel
489 if (isL2Cell &&
490 (std::abs(cp0.etaB - dde->eta_raw()) < addCellsWindowEtaBarrel)) {
491 inEtaRange = true;
492 }
493 if (isL3Cell &&
494 (std::abs(cp0.etaB - dde->eta_raw()) < addCellsWindowL3EtaBarrel)) {
495 inEtaRange = true;
496 }
497 }
498 if (cp0.emaxEC > 0) { // endcap
499 if (isL2Cell &&
500 (std::abs(cp0.etaEC - dde->eta_raw()) < addCellsWindowEtaEndcap)) {
501 inEtaRange = true;
502 }
503 if (isL3Cell && (std::abs(cp0.etaEC - dde->eta_raw()) <
504 addCellsWindowL3EtaEndcap)) {
505 inEtaRange = true;
506 }
507 }
508 if (!inEtaRange) {
509 continue;
510 }
511 tofill.addCell(cell_itr.index(), cell_itr.weight());
512 } // Loop over cells for L2/L3
513 } // Loop over clusters for L2/L3
514
515 // We should have a size here
516 if (tofill.size() == 0) {
517 return StatusCode::FAILURE;
518 }
519 // Now calculate the cluster size in 2nd layer
520 // use that for constraining the L0/L1 cells we add
521 const CookieCutterHelpers::PhiSize phiSize(cp0, tofill);
522 const float phiPlusB = cp0.phiB + phiSize.plusB + m_extraL0L1PhiSize;
523 const float phiMinusB = cp0.phiB - phiSize.minusB - m_extraL0L1PhiSize;
524 const float phiPlusEC = cp0.phiEC + phiSize.plusEC + m_extraL0L1PhiSize;
525 const float phiMinusEC = cp0.phiEC - phiSize.minusEC - m_extraL0L1PhiSize;
526
527 // Loop for L0/L1
528 for (const xAOD::CaloCluster* tocheck : clusters) {
529 xAOD::CaloCluster::const_cell_iterator cell_itr = tocheck->begin();
530 xAOD::CaloCluster::const_cell_iterator cell_end = tocheck->end();
531 // Loop over cells
532 for (; cell_itr != cell_end; ++cell_itr) {
533 // sanity check on the cell
534 const CaloCell* cell = *cell_itr;
535 if (!cell) {
536 continue;
537 }
538 const CaloDetDescrElement* dde = cell->caloDDE();
539 if (!dde) {
540 continue;
541 }
542
543 // only deal with L1 or PS
544 const auto sampling = dde->getSampling();
545 const bool isL0L1Cell =
546 (CaloCell_ID::EMB1 == sampling || CaloCell_ID::EME1 == sampling ||
547 CaloCell_ID::PreSamplerB == sampling ||
548 CaloCell_ID::PreSamplerE == sampling);
549 if (!isL0L1Cell) {
550 continue;
551 }
552
553 bool inEtaRange = false;
554 // Check if is inside the eta range wrt to the hottest
555 // cell(s) for the cluster we construct
556 if (cp0.emaxB > 0) { // barrel
557 if (std::abs(cp0.etaB - dde->eta_raw()) < addCellsWindowEtaBarrel) {
558 inEtaRange = true;
559 }
560 }
561 if (cp0.emaxEC > 0) { // endcap
562 if (std::abs(cp0.etaEC - dde->eta_raw()) < addCellsWindowEtaEndcap) {
563 inEtaRange = true;
564 }
565 }
566 if (!inEtaRange) {
567 continue;
568 }
569
570 // Add L0/L1 when we are in the narrow range
571 bool inPhiRange = false;
572 if (cp0.emaxB > 0) { // barrel
573 const double cell_phi = proxim(dde->phi_raw(), cp0.phiB);
574 if (cell_phi > phiMinusB && cell_phi < phiPlusB) {
575 inPhiRange = true;
576 }
577 }
578 if (cp0.emaxEC > 0) { // endcap
579 const double cell_phi = proxim(dde->phi_raw(), cp0.phiEC);
580 if (cell_phi > phiMinusEC && cell_phi < phiPlusEC) {
581 inPhiRange = true;
582 }
583 }
584 if (!inPhiRange) {
585 continue;
586 }
587
588 tofill.addCell(cell_itr.index(), cell_itr.weight());
589 } // Cell Loop for L0/L1
590 } // Cluster loop for L0/L1
591
592 if (!m_egammaCellRecoveryTool.empty()) {
594 if (cp0.emaxB > cp0.emaxEC) {
595 info.etamax = cp0.etaB;
596 info.phimax = cp0.phiB;
597 } else {
598 info.etamax = cp0.etaEC;
599 info.phimax = cp0.phiEC;
600 }
601 if (m_egammaCellRecoveryTool->execute(tofill,info).isFailure()) {
602 ATH_MSG_WARNING("Issue trying to recover cells");
603 }
604
605 // And finally add the recovered cells
606 const CaloCellContainer* inputcells =
607 tofill.getCellLinks()->getCellContainer();
608 for (const auto *c : info.addedCells) {
609 int index = inputcells->findIndex(c->caloDDE()->calo_hash());
610 tofill.addCell(index, 1.);
611 }
612 }
613
614 return StatusCode::SUCCESS;
615}
616
617StatusCode
619 xAOD::CaloCluster& tofill,
620 const CaloDetDescrManager& mgr) const
621{
622
623 double searchWindowEta = m_useExtendedTG3 ? 0.35 : 0.2;
624 constexpr double searchWindowPhi = 2 * M_PI / 64.0 + M_PI / 64; // ~ 0.15 rad
625 std::vector<const CaloCell*> cells;
626 cells.reserve(16);
627 const CaloCellContainer* inputcells =
628 tofill.getCellLinks()->getCellContainer();
629
630 if (!inputcells) {
631 ATH_MSG_ERROR("No cell container in addRemainingCellsToCluster?");
632 return StatusCode::FAILURE;
633 }
634
635 CaloCellList myList(&mgr, inputcells);
636
637 const std::vector<CaloSampling::CaloSample> samples = {
638 CaloSampling::TileGap3
639 };
640
641 for (auto samp : samples) {
642 // quite slow
643 myList.select(
644 tofill.eta0(), tofill.phi0(), searchWindowEta, searchWindowPhi, samp);
645 cells.insert(cells.end(), myList.begin(), myList.end());
646 }
647
648 for (const auto* cell : cells) {
649 if (!cell) {
650 continue;
651 }
652 const CaloDetDescrElement* dde = cell->caloDDE();
653 if (!dde) {
654 continue;
655 }
656
657 float maxEta = s_TG3Run2E4cellEtaMax;
658 float minEta = s_TG3Run2E4cellEtaMin;
659 if (m_useExtendedTG3) {
660 minEta = s_TG3Run3E3cellEtaMin;
661 // if |eta2| < 1.56, keep only E3, else keep E3+E4.
662 // |eta2| uses as the eta of the highest energy cell in layer 2 as proxy
663 if (std::abs(tofill.eta0()) > 1.56) {
664 maxEta = s_TG3Run3E4cellEtaMax;
665 }
666 }
667 float cellaEtaRaw = std::abs(dde->eta_raw());
668 if (cellaEtaRaw >= minEta && cellaEtaRaw <= maxEta) {
669 int index = inputcells->findIndex(dde->calo_hash());
670 tofill.addCell(index, 1.);
671 }
672 }
673 return StatusCode::SUCCESS;
674}
675
676StatusCode
678 const EventContext& ctx,
679 xAOD::CaloCluster* newCluster,
680 const CaloDetDescrManager& mgr,
682 xAOD::CaloClusterContainer* precorrClusters) const
683{
684
686 // Save the state before the corrections
687 newCluster->setAltE(newCluster->e());
688 newCluster->setAltEta(newCluster->eta());
689 newCluster->setAltPhi(newCluster->phi());
690 // first do the corrections
691 if (precorrClusters) {
692 precorrClusters->push_back(std::make_unique<xAOD::CaloCluster>());
693 *precorrClusters->back() = *newCluster;
694 }
696 ctx, newCluster, egType, xAOD::EgammaHelpers::isBarrel(newCluster)));
697 double aeta = std::abs(newCluster->eta());
698 if (aeta > 10) {
699 ATH_MSG_DEBUG("Too large eta after S-shape corrections. "
700 "SuperCluster rejected");
701 return StatusCode::FAILURE;
702 }
703 newCluster->setRawE(newCluster->e());
704 newCluster->setRawEta(newCluster->eta());
705 newCluster->setRawPhi(newCluster->phi());
706 //
708 ATH_CHECK(m_MVACalibSvc->execute(*newCluster, egType));
709
710 return StatusCode::SUCCESS;
711}
712
const std::regex ref(r_ef)
#define M_PI
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Calculate total energy, position, etc. for a given layer of a cluster.
bool inRange(const double *boundaries, const double value, const double tolerance=0.02)
An algorithm that can be simultaneously executed in multiple threads.
Container class for CaloCell.
int findIndex(const IdentifierHash theHash) const
Return index of the cell with a given hash.
list_iterator end() const
void select(double eta, double phi, double deta, double dphi)
list_iterator begin() const
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
static std::unique_ptr< xAOD::CaloCluster > makeCluster(const CaloCellContainer *cellCont)
Creates a valid CaloCluster with a private Aux-Store and CellLink container.
static StatusCode AddContainerWriteHandle(SG::WriteHandle< xAOD::CaloClusterContainer > &clusColl)
Creates a new xAOD::CaloClusterContainer in the given WriteHandle + CaloClusterAuxContainer and recor...
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
bool is_lar_em_endcap_inner() const
cell belongs to the inner wheel of EM end cap
This class provides the client interface for accessing the detector description information common to...
const T * back() const
Access the last element in the collection as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Represent an egamma object for internal egamma usage during reconstruction.
Definition egammaRec.h:31
Gaudi::Property< int > m_addCellsWindowEtaCellsEndcap
Size of windows et eta in which cells of topoclusters are edded for the endcap (units of 2nd layer ce...
egammaSuperClusterBuilderBase(const std::string &name, ISvcLocator *pSvcLocator)
Protected constructor since this class should not be instantiated by itself.
SG::WriteHandleKey< EgammaRecContainer > m_outputEgammaRecContainerKey
Key for output egammaRec container.
SG::ReadHandleKey< EgammaRecContainer > m_inputEgammaRecContainerKey
Key for input egammaRec container.
Gaudi::Property< int > m_extraL3EtaSizeCells
"When adding L3 cells, how much wider in eta than the L2
Gaudi::Property< float > m_EtThresholdCut
Seed selection requirements.
StatusCode fillClusterConstrained(xAOD::CaloCluster &tofill, const std::vector< const xAOD::CaloCluster * > &clusters, const CookieCutterHelpers::CentralPosition &cp0) const
Fill super cluster constraining its size in eta,phi around the overall hottest cell and the its L2 si...
virtual StatusCode redoMatching(const EventContext &ctx, SG::WriteHandle< EgammaRecContainer > &newEgammaRecs) const
Gaudi::Property< int > m_searchWindowEtaCellsBarrel
Size of topocluster search window in eta for the barrel.
bool matchesInWindow(const xAOD::CaloCluster *ref, const xAOD::CaloCluster *clus) const
Is clus in window center around ref?
std::unique_ptr< xAOD::CaloCluster > createNewCluster(const EventContext &ctx, const std::vector< const xAOD::CaloCluster * > &clusters, const DataLink< CaloCellContainer > &cellCont, const CaloDetDescrManager &mgr, xAOD::EgammaParameters::EgammaType egType, xAOD::CaloClusterContainer *precorrClusters) const
Add new supercluster ,created out of the input clusters, to the newClusters collections.
Gaudi::Property< bool > m_linkToConstituents
Decorate the supercluster with links to the component topoclusters.
StatusCode calibrateCluster(const EventContext &ctx, xAOD::CaloCluster *newCluster, const CaloDetDescrManager &mgr, const xAOD::EgammaParameters::EgammaType egType, xAOD::CaloClusterContainer *precorrClusters) const
function to calibrate the new clusters energy
ToolHandle< IegammaCheckEnergyDepositTool > m_egammaCheckEnergyDepositTool
Pointer to the egammaCheckEnergyDepositTool.
ToolHandle< IegammaCellRecoveryTool > m_egammaCellRecoveryTool
Pointer to the egammaCellRecoveryTool.
Gaudi::Property< bool > m_useExtendedTG3
Use extended TG3 definition (only after Run 2).
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_precorrClustersKey
Optional key for pre-correction clusters.
virtual StatusCode execute(const EventContext &ctx) const override
should be called by the derived class in the execute phase
virtual bool egammaRecPassesSelection(const egammaRec *egRec) const
StatusCode addTileGap3CellsinWindow(xAOD::CaloCluster &tofill, const CaloDetDescrManager &mgr) const
add all tile Gap 3 cells in a window.
Gaudi::Property< int > m_searchWindowPhiCellsEndcap
Size of topocluster search window in phi for the end-cap.
virtual xAOD::EgammaParameters::EgammaType getEgammaRecType(const egammaRec *egRec) const =0
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloDetDescrMgrKey
ToolHandle< IegammaSwTool > m_clusterCorrectionTool
Tool to handle cluster corrections.
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_outputSuperClusterCollectionName
Key for output clusters.
Gaudi::Property< int > m_extraL0L1PhiSizeCells
"When adding L0 (PS) and L1 cells, how much wider than the L2 size of the cluster is the acceptance i...
Gaudi::Property< int > m_searchWindowEtaCellsEndcap
Size of topocluster search window in eta for the end-cap.
ServiceHandle< IegammaMVASvc > m_MVACalibSvc
Handle to the MVA calibration service.
virtual std::vector< std::size_t > searchForSecondaryClusters(std::size_t egammaInd, const EgammaRecContainer *egammaRecs, std::vector< bool > &isUsed) const =0
Gaudi::Property< int > m_addCellsWindowEtaCellsBarrel
Size of windows et eta in which cells of topoclusters are added for the barrel (units of 2nd layer ce...
Gaudi::Property< int > m_searchWindowPhiCellsBarrel
Size of topocluster search window in phi for the barrel.
virtual StatusCode initialize() override
should be called by the derived class in the initialize phase
bool seedClusterSelection(const xAOD::CaloCluster *clus) const
check if we pass the basic criteria for a seed cluster
void setRawEta(flt_t)
Set for signal state UNCALIBRATED.
void setAltPhi(flt_t)
Set for signal state ALTCALIBRATED.
void setRawPhi(flt_t)
Set for signal state UNCALIBRATED.
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version).
void setRawE(flt_t)
Set Energy for signal state UNCALIBRATED.
virtual double eta() const
The pseudorapidity ( ) of the particle.
void setAltEta(flt_t)
Set for signal state ALTCALIBRATED.
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
virtual double e() const
The total energy of the particle.
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version).
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
virtual double phi() const
The azimuthal angle ( ) of the particle.
void setAltE(flt_t)
Set Energy for signal state ALTCALIBRATED.
flt_t eta0() const
Returns raw of cluster seed.
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
bool addCell(const unsigned index, const double weight)
Method to add a cell to the cluster (Beware: Kinematics not updated!).
flt_t phi0() const
Returns raw of cluster seed.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition P4Helpers.h:34
void fillPositionsInCalo(xAOD::CaloCluster *cluster, const CaloDetDescrManager &mgr)
Function to decorate the calo cluster with position variables.
void refineEta1Position(xAOD::CaloCluster *cluster, const CaloDetDescrManager &mgr)
function to refine position in eta1
Definition index.py:1
bool isBarrel(const xAOD::Egamma *eg)
return true if the cluster is in the barrel
int summaryValueInt(const xAOD::TrackParticle &tp, const xAOD::SummaryType &info, int deflt=-999)
return the summary value for a TrackParticle or default value (-999) (to be used mostly in python whe...
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
double proxim(double b, double a)
Definition proxim.h:17
Find the reference position (eta, phi) relative to which cells are restricted.
Find the size of the cluster in phi using L2 cells.