ATLAS Offline Software
Loading...
Searching...
No Matches
CaloCellDecorator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
10
14
15// Calo includes
20
21#include <cstdint>
22#include <string>
23#include <sys/types.h>
24#include <vector>
25
26
27// Destructor
29
30// Athena initialize
31StatusCode
33{
34 ATH_MSG_VERBOSE("initialize() ...");
35
36 // Cabling and calo initialize
37 ATH_CHECK(m_cablingKey.initialize());
38 ATH_CHECK(m_SGKey_CaloCells.initialize());
39 ATH_CHECK(m_caloDetDescrMgrKey.initialize());
40
41 // Setup for photons
43 if (!m_SGKey_photons.key().empty()) {
44 ATH_MSG_INFO("Decorating photons with calo cells using " << m_SGKey_photons.key() << " container");
45 }
46 ATH_CHECK(m_SGKey_photons_decorations.initialize(!m_SGKey_photons.key().empty()));
47
48 // Setup for electrons
50 if (!m_SGKey_electrons.key().empty()) {
51 ATH_MSG_INFO("Decorating electrons with calo cells using " << m_SGKey_electrons.key() << " container");
52 }
54
55 // Initialize tools
58
59 return StatusCode::SUCCESS;
60
61}
62
63StatusCode
65{
66
67 if (!m_SGKey_photons.key().empty()) {
68 // Decorate photons
73 ctx
74 )
75 );
76
77 }
78
79 if (!m_SGKey_electrons.key().empty()) {
80 // Decorate electrons
85 ctx
86 )
87 );
88
89 }
90
91 return StatusCode::SUCCESS;
92}
93
94StatusCode
98 const EventContext& ctx) const
99{
100
101 // Retrieve containers
104
105 // Calo detector description manager
107 ATH_CHECK(caloDetDescrMgrHandle.isValid());
108
109 // Setup decorators
111 decoration0(decorKeys[0], ctx);
113 decoration1(decorKeys[1], ctx);
115 decoration2(decorKeys[2], ctx);
117 decoration3(decorKeys[3], ctx);
119 decoration4(decorKeys[4], ctx);
121 decoration5(decorKeys[5], ctx);
123 decoration6(decorKeys[6], ctx);
125 decoration7(decorKeys[7], ctx);
127 decoration8(decorKeys[8], ctx);
129 decoration9(decorKeys[9], ctx);
131 decoration10(decorKeys[10], ctx);
133 decoration11(decorKeys[11], ctx);
134
135 // Loop through egamma objects and decorate
136 const xAOD::EgammaContainer* importedEgamma = egammaContainer.ptr();
137 const CaloCellContainer* caloCells = caloCellContainer.ptr();
138 const CaloDetDescrManager* cmgr = *caloDetDescrMgrHandle;
139
140 for (const auto* egamma : *importedEgamma) {
141 const xAOD::CaloCluster *cluster = egamma->caloCluster();
143 getDecorations(cluster, caloCells, cmgr, ctx);
144
145 // Decorate
146 decoration0(*egamma) = res.cells_E;
147 decoration1(*egamma) = res.cells_time;
148 decoration2(*egamma) = res.cells_eta;
149 decoration3(*egamma) = res.cells_phi;
150 decoration4(*egamma) = res.cells_x;
151 decoration5(*egamma) = res.cells_y;
152 decoration6(*egamma) = res.cells_z;
153 decoration7(*egamma) = res.cells_gain;
154 decoration8(*egamma) = res.cells_layer;
155 decoration9(*egamma) = res.cells_quality;
156 decoration10(*egamma) = res.cells_onlId;
157 decoration11(*egamma) = res.cells_clusterOriginInfo;
158 }
159
160 return StatusCode::SUCCESS;
161
162};
163
166 const xAOD::CaloCluster* cluster,
167 const CaloCellContainer* caloCells,
168 const CaloDetDescrManager* cmgr,
169 const EventContext& ctx) const
170{
171
173
174 if (cluster) {
175 if (!cluster->getCellLinks()) {
176 ATH_MSG_WARNING("CellLinks not found");
177 return decorations;
178 }
179
180 const LArOnOffIdMapping* cabling{nullptr};
181 if (!SG::get(cabling, m_cablingKey, ctx).isSuccess()){
182 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key());
183 throw std::runtime_error("Cabling retrieval failed");
184 }
185
186 std::unordered_map<const CaloCell*, CaloCellDecorator::CellClusterInfo> info;
187
188 // Lambda function to keep track of cells already added to the decorations
189 // and to update origin info depending on whether they were in the supercluster,
190 // recovered by timing cut recovery, or in the 7x11 cluster.
191 auto registerCell = [&](const CaloCell* cell, uint8_t originMask) {
192 int layer = layerFromSampling(cell->caloDDE()->getSampling());
193 if (layer < 0) return; // Ignore non-LAr cells
194
195 auto [it, inserted] = info.emplace(cell, CellClusterInfo{});
196 CellClusterInfo& ci = it->second;
197
198 // Update origin mask
199 ci.mask |= originMask;
200
201 if (inserted) {
202 ci.index = decorations.cells_E.size();
203
204 uint64_t onlId = (uint64_t)(cabling->createSignalChannelID(cell->caloDDE()->identify())).get_compact();
205 decorations.cells_E.push_back(cell->e());
206 decorations.cells_time.push_back(cell->time());
207 decorations.cells_eta.push_back(cell->eta());
208 decorations.cells_phi.push_back(cell->phi());
209 decorations.cells_x.push_back(cell->x());
210 decorations.cells_y.push_back(cell->y());
211 decorations.cells_z.push_back(cell->z());
212 decorations.cells_gain.push_back((int)cell->gain());
213 decorations.cells_layer.push_back(layer);
214 decorations.cells_quality.push_back(cell->quality());
215 decorations.cells_clusterOriginInfo.push_back(ci.mask);
216 decorations.cells_onlId.push_back(onlId);
217 }
218 else {
219 // Update origin info if cell already exists
220 decorations.cells_clusterOriginInfo[ci.index] = ci.mask;
221 }
222
223 };
224
225 double emax = 0.;
226 const CaloCell* maxcell = nullptr;
227
228 // Loop through supercluster cells
229 for (const CaloCell* cell : *cluster) {
230 // Find maximum energy cell in L2 from those in the supercluster
231 int layer = layerFromSampling(cell->caloDDE()->getSampling());
232 if (layer == 2) {
233 if (cell->e() > emax) {
234 emax = cell->e();
235 maxcell = cell;
236 }
237 }
238 registerCell(cell, 0x01); // Supercluster cell
239 }
240
241 IegammaCellRecoveryTool::Info timeCutRecoveryInfo{};
242 if (maxcell->e() > 0.) {
243 timeCutRecoveryInfo.etamax = maxcell->caloDDE()->eta_raw();
244 timeCutRecoveryInfo.phimax = maxcell->caloDDE()->phi_raw();
245 if (m_egammaCellRecoveryTool->execute(*cluster, timeCutRecoveryInfo).isFailure()) {
246 ATH_MSG_WARNING("egammaCellRecoveryTool execution failed");
247 }
248 } else {
249 ATH_MSG_WARNING("Max cell in L2 has zero energy, should never happen! Skipping timing cut recovery");
250 }
251
252 // Loop through timing cut recovered cells
253 for (const CaloCell* cell : timeCutRecoveryInfo.addedCells) {
254 registerCell(cell, 0x02); // Timing cut recovered cell
255 }
256
258 if (m_egammaLargeClusterCellRecoveryTool->execute(cluster, cmgr, caloCells, largeClusterInfo).isFailure()) {
259 ATH_MSG_WARNING("egammaLargeClusterCellRecoveryTool execution failed");
260 }
261
262 // Loop through 7x11 cluster cells
263 for (const CaloCell* cell : largeClusterInfo.cells711) {
264 registerCell(cell, 0x04); // 7x11 cluster cell
265 }
266 }
267
268 return decorations;
269};
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Adds cell-level features as decorations to e/gamma objects. The cells included are those in the objec...
Calculate total energy, position, etc. for a given layer of a cluster.
std::pair< std::vector< unsigned int >, bool > res
Handle class for reading from StoreGate.
Container class for CaloCell.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition CaloCell.h:333
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
This class provides the client interface for accessing the detector description information common to...
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_photons
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_photons_decorations
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_electrons_decorations
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_electrons
ToolHandle< IegammaLargeClusterCellRecoveryTool > m_egammaLargeClusterCellRecoveryTool
Pointer to egammaLargeClusterCellRecoveryTool.
ToolHandle< IegammaCellRecoveryTool > m_egammaCellRecoveryTool
Pointer to the egammaCellRecoveryTool.
StatusCode decorateCells(const SG::ReadHandleKey< xAOD::EgammaContainer > &contKey, const SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > &decorKeys, const EventContext &ctx) const
Decorates e/gamma objects with vector cell features E, t, eta, phi, layer, x, y, z,...
CellDecorationData getDecorations(const xAOD::CaloCluster *cluster, const CaloCellContainer *caloCells, const CaloDetDescrManager *cmgr, const EventContext &ctx) const
Loops through cells and adds to decoration struct.
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloDetDescrMgrKey
virtual StatusCode addBranches(const EventContext &ctx) const override final
int layerFromSampling(int s) const
Inline to get calorimeter sampling.
virtual StatusCode initialize() override final
SG::ReadHandleKey< CaloCellContainer > m_SGKey_CaloCells
std::vector< const CaloCell * > addedCells
Property holding a SG store/key/clid from which a ReadHandle is made.
const_pointer_type ptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
This is a data object, containing a collection of egamma Objects.
elec/gamma data class.
Definition egamma.h:58
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Athena::TPCnvVers::Old Athena::TPCnvVers::Old Athena::TPCnvVers::Old Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Current egammaContainer
DecorHandleKeyArray< WriteDecorHandle< T, S >, WriteDecorHandleKey< T >, Gaudi::DataHandle::Writer > WriteDecorHandleKeyArray
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
EgammaContainer_v1 EgammaContainer
Definition of the current "egamma container version".
Struct to keep track of where cell came from e.g.