ATLAS Offline Software
Loading...
Searching...
No Matches
MaxCellDecorator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include <string>
10#include <vector>
11namespace {}
12
13// Athena initialize
16{
17 ATH_MSG_VERBOSE("initialize() ...");
18
19 ATH_CHECK(m_cablingKey.initialize());
20
22 if (!m_SGKey_electrons.key().empty()) {
23 ATH_MSG_INFO("Using " << m_SGKey_electrons.key() << " for electrons");
24 }
26
28
30 if (!m_SGKey_photons.key().empty()) {
31 ATH_MSG_INFO("Using " << m_SGKey_photons.key() << " for photons");
32 }
33 ATH_CHECK(m_SGKey_photons_decorations.initialize(!m_SGKey_photons.key().empty()));
34
36 if (!m_SGKey_taus.key().empty()) {
37 ATH_MSG_INFO("Using " << m_SGKey_taus.key() << " for taus");
38 }
39 ATH_CHECK(m_SGKey_taus_decorations.initialize(!m_SGKey_taus.key().empty()));
40
42 if (!m_SGKey_jets.key().empty()) {
43 ATH_MSG_INFO("Using " << m_SGKey_jets.key() << " for jets");
44 }
45 ATH_CHECK(m_SGKey_jets_decorations.initialize(!m_SGKey_jets.key().empty()));
46
47 return StatusCode::SUCCESS;
48}
49
50
51// The decoration itself
52StatusCode
54{
55
56 if (!m_SGKey_photons.key().empty()) {
57 // Retrieve photon container
59 // setup vector of decorators
74
75 const xAOD::EgammaContainer* importedPhotons = photonContainer.ptr();
76 for (const auto* egamma : *importedPhotons) {
77 const xAOD::CaloCluster *cluster = egamma->caloCluster();
79 decorateObject(cluster, ctx);
80 decorationPh0(*egamma) = res.maxEcell_time;
81 decorationPh1(*egamma) = res.maxEcell_energy;
82 decorationPh2(*egamma) = res.maxEcell_gain;
83 decorationPh3(*egamma) = res.maxEcell_onlId;
84 decorationPh4(*egamma) = res.maxEcell_x;
85 decorationPh5(*egamma) = res.maxEcell_y;
86 decorationPh6(*egamma) = res.maxEcell_z;
87 }
88 }
89
90 if (!m_SGKey_electrons.key().empty()) {
91 // Retrieve electron container
93 ctx);
94
95 //
96 std::optional<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> odecorationEl7;
97 const xAOD::CaloClusterContainer* egClContainer{};
98 if (!m_SGKey_egammaClusters.key().empty()) {
101 egClContainer = egClContainerRH.ptr();
102 odecorationEl7.emplace(m_SGKey_electrons_decorations[7], ctx);
103 }
104
105 // setup vector of decorators
120
121 const xAOD::EgammaContainer* importedElectrons = electronContainer.ptr();
122 for (const auto* egamma : *importedElectrons) {
123 const xAOD::CaloCluster *cluster = egamma->caloCluster();
124 if (!m_SGKey_egammaClusters.key().empty()) {
125 double dRMin = 9e9;
126 const xAOD::CaloCluster *matchedCluster(nullptr);
127 for (const auto *clus : *egClContainer) {
128 double dR = clus->p4().DeltaR(cluster->p4());
129 if (dR < dRMin && dR < m_dRLRTegClusegClusMax) {
130 dRMin = dR;
131 matchedCluster = clus;
132 }
133 }
134 cluster = matchedCluster;
135 odecorationEl7.value()(*egamma) = dRMin;
136 }
138 decorateObject(cluster, ctx);
139 decorationEl0(*egamma) = res.maxEcell_time;
140 decorationEl1(*egamma) = res.maxEcell_energy;
141 decorationEl2(*egamma) = res.maxEcell_gain;
142 decorationEl3(*egamma) = res.maxEcell_onlId;
143 decorationEl4(*egamma) = res.maxEcell_x;
144 decorationEl5(*egamma) = res.maxEcell_y;
145 decorationEl6(*egamma) = res.maxEcell_z;
146 }
147 }
148
149 if (!m_SGKey_taus.key().empty()) {
150 // Retrieve tau container
152 // setup vector of decorators
167
168 const xAOD::TauJetContainer* importedTaus = tauJetContainer.ptr();
169 for (const auto* tau : *importedTaus) {
171 res.maxEcell_energy = -9999.;
172 for (const auto& link : tau->clusterLinks()) {
173 if ( !link.isValid() ) {
174 ATH_MSG_WARNING("Tau particle link invalid");
175 continue;
176 }
177 const xAOD::IParticle* part = *link;
178 if ( not part ) {
179 ATH_MSG_WARNING("Tau particle link invalid");
180 continue;
181 }
182
183 const xAOD::CaloCluster* cluster=dynamic_cast<const xAOD::CaloCluster*> (part);
184 if ( not cluster ) {
185 ATH_MSG_WARNING("Tau cluster link invalid");
186 continue;
187 }
188
190 decorateObject(cluster, ctx);
191 if (resCand.maxEcell_energy > res.maxEcell_energy) {
192 res = resCand;
193 }
194 }
195
196 decorationTau0(*tau) = res.maxEcell_time;
197 decorationTau1(*tau) = res.maxEcell_energy;
198 decorationTau2(*tau) = res.maxEcell_gain;
199 decorationTau3(*tau) = res.maxEcell_onlId;
200 decorationTau4(*tau) = res.maxEcell_x;
201 decorationTau5(*tau) = res.maxEcell_y;
202 decorationTau6(*tau) = res.maxEcell_z;
203 }
204 }
205
206 if (!m_SGKey_jets.key().empty()) {
207 // Retrieve jet container
209 // setup vector of decorators
224
225 const xAOD::JetContainer* importedJets = jetContainer.ptr();
226 for (const auto* jet : *importedJets) {
227 if (jet->numConstituents() == 0) continue;
228
230 res.maxEcell_energy = -9999.;
231 std::vector<const xAOD::CaloCluster*> clusterList;
232 clusterList.clear();
233
234 xAOD::Type::ObjectType ctype = jet->rawConstituent( 0 )->type();
235
236 if (ctype == xAOD::Type::FlowElement) {
237 // Particle Flow jets.
238 const static SG::AuxElement::ConstAccessor< ElementLink<xAOD::IParticleContainer> >
239 originalObjectAcc("originalObjectLink");
240
241 for (size_t i=0;i<jet->numConstituents();++i) {
242 if(jet->rawConstituent(i)->type() != xAOD::Type::FlowElement) {
243 ATH_MSG_WARNING("Tried to call fillEperSamplingFE with a jet constituent that is not a FlowElement!");
244 continue;
245 }
246
247 const xAOD::FlowElement* constit = static_cast<const xAOD::FlowElement*>(jet->rawConstituent(i));
248 if (!constit) continue;
249
250 if ( !originalObjectAcc.isAvailable(*constit) ) {
251 ATH_MSG_WARNING("FlowElement constituent has no originalObjectLink decoration");
252 continue;
253 }
254 const ElementLink<xAOD::IParticleContainer>& origLink = originalObjectAcc(*constit);
255 if ( !origLink.isValid() ) {
256 ATH_MSG_WARNING("FlowElement constituent originalObjectLink is invalid");
257 continue;
258 }
259
260 auto originalFE = dynamic_cast<const xAOD::FlowElement*>(*origLink);
261 if(originalFE && !originalFE->isCharged()){
262 const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>(originalFE->otherObject(0));
263 if (cluster) {
264 clusterList.push_back(cluster);
265 }
266 }
267 }
268 } else if (ctype == xAOD::Type::CaloCluster) {
269 // Topo jets
270 for (size_t i=0;i<jet->numConstituents();++i) {
271 if(jet->rawConstituent(i)->type() != xAOD::Type::CaloCluster) {
272 ATH_MSG_WARNING("Tried to call fillEperSamplingCluster with a jet constituent that is not a cluster!");
273 continue;
274 }
275
276 const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>(jet->rawConstituent(i));
277 if (cluster) {
278 clusterList.push_back(cluster);
279 }
280 }
281 } else {
282 // PFlow (old)
283 for (size_t i=0;i<jet->numConstituents();++i) {
284 if(jet->rawConstituent(i)->type() != xAOD::Type::ParticleFlow) {
285 continue;
286 }
287 const xAOD::PFO* iPFO = static_cast<const xAOD::PFO*>(jet->rawConstituent(i));
288 if ( iPFO ) {
289 for (unsigned int cidx=0;cidx<iPFO->nCaloCluster();++cidx) {
290 if ( iPFO->cluster(cidx) ) {
291 clusterList.push_back(iPFO->cluster(cidx));
292 }
293 }
294 }
295 }
296 }
297
298 for (auto cluster : clusterList) {
300 decorateObject(cluster, ctx);
301 if (resCand.maxEcell_energy > res.maxEcell_energy) {
302 res = resCand;
303 }
304 }
305
306 decorationJet0(*jet) = res.maxEcell_time;
307 decorationJet1(*jet) = res.maxEcell_energy;
308 decorationJet2(*jet) = res.maxEcell_gain;
309 decorationJet3(*jet) = res.maxEcell_onlId;
310 decorationJet4(*jet) = res.maxEcell_x;
311 decorationJet5(*jet) = res.maxEcell_y;
312 decorationJet6(*jet) = res.maxEcell_z;
313 }
314 }
315
316 return StatusCode::SUCCESS;
317}
318
321 const xAOD::CaloCluster* cluster,
322 const EventContext& ctx) const
323{
324
326
327 if (cluster) {
328 if (!cluster->getCellLinks()) {
329 ATH_MSG_DEBUG("CellLinks not found");
330 return result;
331 }
332
334 const LArOnOffIdMapping* cabling{ *cablingHdl };
335 if (!cabling) {
336 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key());
337 return result;
338 }
339
340 float emax = -9999.;
341
342 const CaloCell* cell_maxE = nullptr;
343 for (const CaloCell* cell : *cluster) {
344 int sampling = cell->caloDDE()->getSampling();
345 if (sampling == CaloCell_ID::EMB2 || sampling == CaloCell_ID::EME2) {
346 if ((cell->provenance() & 0x2000)) {
347 if (cell->energy() > emax) {
348 emax = cell->energy();
349 cell_maxE = cell;
350 }
351 }
352 }
353 }
354
355 if (cell_maxE) {
356 const CaloDetDescrElement* caloDDEl = cell_maxE->caloDDE();
357 result.maxEcell_time = cell_maxE->time();
358 result.maxEcell_energy = cell_maxE->energy();
359 result.maxEcell_gain = (int)cell_maxE->gain();
360 result.maxEcell_onlId =
361 (uint64_t)(cabling->createSignalChannelID(caloDDEl->identify()))
362 .get_compact();
363 result.maxEcell_x = caloDDEl->x();
364 result.maxEcell_y = caloDDEl->y();
365 result.maxEcell_z = caloDDEl->z();
366 }
367 }
368 return result;
369}
#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)
#define ATH_MSG_DEBUG(x)
std::pair< std::vector< unsigned int >, bool > res
xAOD::ElectronContainer * electronContainer
xAOD::PhotonContainer * photonContainer
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
double energy() const
get energy (data member)
Definition CaloCell.h:327
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
CaloGain::CaloGain gain() const
get gain (data member )
Definition CaloCell.h:361
This class groups all DetDescr information related to a CaloCell.
Identifier identify() const override final
cell identifier
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_SGKey_jets_decorations
SG::ReadHandleKey< xAOD::TauJetContainer > m_SGKey_taus
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_photons
SG::WriteDecorHandleKeyArray< xAOD::TauJetContainer > m_SGKey_taus_decorations
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_electrons_decorations
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_SGKey_egammaClusters
This should be only for using run 2 reprocessing, which misses the cell link from LRT electron cluste...
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_electrons
calculation decorateObject(const xAOD::CaloCluster *cluster, const EventContext &ctx) const
Gaudi::Property< double > m_dRLRTegClusegClusMax
matching cone size
virtual StatusCode initialize() override final
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_photons_decorations
SG::ReadHandleKey< xAOD::JetContainer > m_SGKey_jets
virtual StatusCode addBranches(const EventContext &ctx) const override final
const_pointer_type ptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
elec/gamma data class.
Definition egamma.h:58
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version).
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Class providing the definition of the 4-vector interface.
unsigned int nCaloCluster() const
Find out how many CaloCluster are linked.
Definition PFO_v1.cxx:659
const CaloCluster * cluster(unsigned int index) const
Retrieve a const pointer to a CaloCluster.
Definition PFO_v1.cxx:669
::StatusCode StatusCode
StatusCode definition for legacy code.
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ ParticleFlow
The object is a particle-flow object.
Definition ObjectType.h:41
@ FlowElement
The object is a track-calo-cluster.
Definition ObjectType.h:52
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
EgammaContainer_v1 EgammaContainer
Definition of the current "egamma container version".
TauJetContainer_v3 TauJetContainer
Definition of the current "taujet container version".