ATLAS Offline Software
Loading...
Searching...
No Matches
EGammaClusterCoreCellRecovery.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Author: G. Unal (Guillaume.Unal@cern.ch)
6// Decorate egamma objects with the energies in L2 and L3 that are in cells
7// not included in the original supercluser due to the timing cut in topocluster
8// building. This is an AOD fix for data (and mc, but effect is small for mc)
9// produced with rel23 (and 24 ?)
10
12#include "CaloEvent/CaloCell.h"
13
14#include <TString.h>
15#include <string>
16namespace {}
17
18// Athena initialize
19StatusCode
21{
22 ATH_MSG_VERBOSE("initialize() ...");
23
24 // The main tool
26
27 if (m_SGKey_photons.key().empty() && m_SGKey_electrons.key().empty()) {
28 ATH_MSG_FATAL("No e-gamma collection provided for thinning. At least one "
29 "egamma collection (photons/electrons) must be provided!");
30 return StatusCode::FAILURE;
31 }
32
35 if (!m_SGKey_electrons.key().empty()) {
36 ATH_MSG_DEBUG("Using " << m_SGKey_electrons.key() << " for electrons");
37 if (msgLvl(MSG::DEBUG)) {
38 ATH_MSG_DEBUG("Decorations for " << m_SGKey_electrons.key());
39 for (const auto& s : m_SGKey_electrons_decorations)
40 { ATH_MSG_DEBUG(s.key()); }
41 }
42 }
43
44 // This tool needs the calo cells linked to the clusters...
45 ATH_CHECK(m_SGKey_CaloCells.initialize());
46
48 ATH_CHECK(m_SGKey_photons_decorations.initialize(!m_SGKey_photons.key().empty()));
49 if (!m_SGKey_photons.key().empty()) {
50 ATH_MSG_DEBUG("Using " << m_SGKey_photons.key() << " for photons");
51 if (msgLvl(MSG::DEBUG)) {
52 ATH_MSG_DEBUG("Decorations for " << m_SGKey_photons.key());
53 for (const auto& s : m_SGKey_photons_decorations)
54 { ATH_MSG_DEBUG(s.key()); }
55 }
56 }
57
58 return StatusCode::SUCCESS;
59}
60
61
62// The decoration itself
63StatusCode
65{
66
67 std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, char>> decon;
68 std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> decoE;
69 decon.reserve(2);
70 decoE.reserve(2);
71
72 // Photon decorations
73 if (!m_SGKey_photons.key().empty()) {
74
75 for (int i = 0; i < 2; i++) {
76 decon.emplace_back(m_SGKey_photons_decorations[i * 2], ctx);
77 decoE.emplace_back(m_SGKey_photons_decorations[i * 2 + 1], ctx);
78 }
79
80 // Retrieve photon container
82
83 // Decorate photons
84 for (const auto* photon : *photonContainer.ptr()) {
86 for (int i = 0; i < 2; i++) {
87 decon[i](*photon) = res.nCells[i];
88 decoE[i](*photon) = res.eCells[i];
89 }
90 }
91 }
92
93 // Electron decorations
94 if (!m_SGKey_electrons.key().empty()) {
95
96 decon.clear(); decon.reserve(2);
97 decoE.clear(); decoE.reserve(2);
98
99 for (int i = 0; i < 2; i++) {
100 decon.emplace_back(m_SGKey_electrons_decorations[i * 2], ctx);
101 decoE.emplace_back(m_SGKey_electrons_decorations[i * 2 + 1], ctx);
102 }
103
104 // Retrieve electron container
106 ctx);
107
108 // Decorate electrons
109 for (const auto* electron : *electronContainer.ptr()) {
111 for (int i = 0; i < 2; i++) {
112 decon[i](*electron) = res.nCells[i];
113 decoE[i](*electron) = res.eCells[i];
114 }
115 }
116 }
117
118 return StatusCode::SUCCESS;
119}
120
123 const xAOD::Egamma*& egamma) const
124{
126
127 ATH_MSG_DEBUG("Trying to recover cell for object of type " << egamma->type()
128 << " pT = " << egamma->pt()
129 << " eta = " << egamma->eta()
130 << " phi = " << egamma->phi());
131
132 const xAOD::CaloCluster *clus = egamma->caloCluster();
133 if (!clus) {
134 ATH_MSG_WARNING("No associated egamma cluster. Do nothing");
135 return info;
136 }
137
138 // Find max energy cell in layer 2
139 double etamax = -999., phimax = -999.;
140 if (findMaxECell(clus,etamax,phimax).isFailure()) {
141 ATH_MSG_WARNING("Problem in finding maximum energy cell in layer 2");
142 return info;
143 }
144
145 info.etamax = etamax;
146 info.phimax = phimax;
147 if (m_egammaCellRecoveryTool->execute(*clus,info).isFailure()) {
148 ATH_MSG_WARNING("Issue trying to recover cells");
149 }
150 return info;
151}
152
153StatusCode
155 const xAOD::CaloCluster *clus, double &etamax, double &phimax) const
156{
157 const CaloClusterCellLink* cellLinks = clus->getCellLinks();
158 if (!cellLinks) {
159 ATH_MSG_WARNING("No cell link for cluster. Do nothing");
160 return StatusCode::FAILURE;
161 }
162
163 // First check :
164 // if we run in MT, this would be nullptr without initializing a ReadHandleKey
165 const CaloCellContainer *caloCells = cellLinks->getCellContainer();
166 if (!caloCells) {
167 ATH_MSG_WARNING("No cells for cluster. Do nothing");
168 return StatusCode::FAILURE;
169 }
170
171 // Second check :
172 // one might have used a custom cell container for the linked cells
173 if (cellLinks->getCellContainerLink().dataID() != m_SGKey_CaloCells.key()) {
174 ATH_MSG_ERROR("Wrong key for the calo cells");
175 return StatusCode::FAILURE;
176 }
177
178 CaloClusterCellLink::const_iterator it_cell = cellLinks->begin(),
179 it_cell_e = cellLinks->end();
180
181 // find maximum cell energy in layer 2
182 double emax = 0.;
183 std::pair<const CaloCell*,double> maxcell{nullptr,0}; //just for debug
184 for(; it_cell != it_cell_e; ++it_cell) {
185 const CaloCell* cell = (*it_cell);
186 if (cell) {
187 if (!cell->caloDDE()) {
188 ATH_MSG_WARNING("Calo cell without detector element ?? eta = "
189 << cell->eta() << " phi = " << cell->phi());
190 continue;
191 }
192 int layer = cell->caloDDE()->getSampling();
193 if (layer == CaloSampling::EMB2 || layer == CaloSampling::EME2) {
194 double w = it_cell.weight();
195 double eCell = cell->energy();
196 if (m_UseWeightForMaxCell) eCell *= w;
197 if (eCell > emax) {
198 emax = eCell;
199 maxcell.first = cell;
200 maxcell.second = w;
201 }
202 }
203 }
204 }
205
206 if (emax > 0) {
207 etamax = maxcell.first->caloDDE()->eta_raw();
208 phimax = maxcell.first->caloDDE()->phi_raw();
209 if (msgLvl(MSG::DEBUG)) {
210 CaloSampling::CaloSample sam = maxcell.first->caloDDE()->getSampling();
211 double etaAmax = clus->etamax(sam);
212 double phiAmax = clus->phimax(sam);
213 double vemax = clus->energy_max(sam);
214 ATH_MSG_DEBUG("Cluster energy in sampling 2 = " << clus->energyBE(2)
215 << " maximum layer 2 energy cell, E = " << maxcell.first->energy()
216 << " check E = " << vemax
217 << " w = " << maxcell.second << "\n"
218 << " in calo frame, eta = " << etamax << " phi = " << phimax << "\n"
219 << " in ATLAS frame, eta = " << etaAmax << " phi = " << phiAmax);
220 }
221 } else {
222 ATH_MSG_WARNING("No layer 2 cell with positive energy ! Should never happen");
223 return StatusCode::FAILURE;
224 }
225 return StatusCode::SUCCESS;
226}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::pair< std::vector< unsigned int >, bool > res
xAOD::ElectronContainer * electronContainer
xAOD::PhotonContainer * photonContainer
Container class for CaloCell.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_photons_decorations
IegammaCellRecoveryTool::Info decorateObject(const xAOD::Egamma *&egamma) const
virtual StatusCode addBranches(const EventContext &ctx) const override final
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_electrons_decorations
ToolHandle< IegammaCellRecoveryTool > m_egammaCellRecoveryTool
Pointer to the egammaCellRecoveryTool.
StatusCode findMaxECell(const xAOD::CaloCluster *clus, double &etamax, double &phimax) const
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_photons
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_electrons
virtual double pt() const
transverse momentum
virtual double phi() const
phi in [-pi,pi[
virtual double eta() const
pseudo rapidity
elec/gamma data class.
Definition egamma.h:58
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
float energy_max(const CaloSample sampling) const
Retrieve maximum cell energy in given sampling.
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
float etamax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
float phimax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17