ATLAS Offline Software
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 
6 // MaxCellDecorator.cxx, (c) ATLAS Detector software
8 
12 
13 #include <string>
14 #include <vector>
15 namespace {}
16 
17 // Constructor
19  const std::string& n,
20  const IInterface* p)
21  : base_class(t, n, p)
22 {
23 }
24 
25 // Destructor
27 
28 // Athena initialize and finalize
31 {
32  ATH_MSG_VERBOSE("initialize() ...");
33 
34  ATH_CHECK(m_cablingKey.initialize());
35 
36  if (!m_SGKey_electrons.key().empty()) {
37  const std::string key = m_SGKey_electrons.key();
38  ATH_MSG_INFO("Using " << key << " for electrons");
39  ATH_CHECK(m_SGKey_electrons.initialize());
40 
41  // setup vector of decorators
42  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_time");
43  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_energy");
44  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_gain");
45  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_onlId");
46  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_x");
47  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_y");
48  m_SGKey_electrons_decorations.emplace_back(key + ".maxEcell_z");
49 
50  if (!m_SGKey_egammaClusters.key().empty()) {
51  ATH_MSG_INFO("Using " << m_SGKey_egammaClusters.key() << " to try to match a cluster to the LRT egamma cluster");
52  ATH_CHECK(m_SGKey_egammaClusters.initialize());
53  m_SGKey_electrons_decorations.emplace_back(key + ".dR");
54  }
55 
56  ATH_CHECK(m_SGKey_electrons_decorations.initialize());
57  }
58 
59  if (!m_SGKey_photons.key().empty()) {
60  const std::string key = m_SGKey_photons.key();
61  ATH_MSG_INFO("Using " << key << " for photons");
62  ATH_CHECK(m_SGKey_photons.initialize());
63 
64  // setup vector of decorators
65  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_time");
66  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_energy");
67  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_gain");
68  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_onlId");
69  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_x");
70  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_y");
71  m_SGKey_photons_decorations.emplace_back(key + ".maxEcell_z");
72  ATH_CHECK(m_SGKey_photons_decorations.initialize());
73  }
74 
75  if (!m_SGKey_taus.key().empty()) {
76  const std::string key = m_SGKey_taus.key();
77  ATH_MSG_INFO("Using " << key << " for taus");
78  ATH_CHECK(m_SGKey_taus.initialize());
79 
80  // setup vector of decorators
81  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_time");
82  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_energy");
83  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_gain");
84  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_onlId");
85  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_x");
86  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_y");
87  m_SGKey_taus_decorations.emplace_back(key + ".maxEcell_z");
88  ATH_CHECK(m_SGKey_taus_decorations.initialize());
89  }
90 
91  if (!m_SGKey_jets.key().empty()) {
92  const std::string key = m_SGKey_jets.key();
93  ATH_MSG_INFO("Using " << key << " for jets");
94  ATH_CHECK(m_SGKey_jets.initialize());
95 
96  // setup vector of decorators
97  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_time");
98  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_energy");
99  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_gain");
100  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_onlId");
101  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_x");
102  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_y");
103  m_SGKey_jets_decorations.emplace_back(key + ".maxEcell_z");
104  ATH_CHECK(m_SGKey_jets_decorations.initialize());
105  }
106 
107  return StatusCode::SUCCESS;
108 }
109 
112 {
113  return StatusCode::SUCCESS;
114 }
115 
116 // The decoration itself
119 {
120 
121  if (!m_SGKey_photons.key().empty()) {
122  // Retrieve photon container
124  // setup vector of decorators
126  m_SGKey_photons_decorations[0], ctx);
128  m_SGKey_photons_decorations[1], ctx);
130  m_SGKey_photons_decorations[2], ctx);
132  m_SGKey_photons_decorations[3], ctx);
134  m_SGKey_photons_decorations[4], ctx);
136  m_SGKey_photons_decorations[5], ctx);
138  m_SGKey_photons_decorations[6], ctx);
139 
140  const xAOD::EgammaContainer* importedPhotons = photonContainer.ptr();
141  for (const auto* egamma : *importedPhotons) {
142  const xAOD::CaloCluster *cluster = egamma->caloCluster();
144  decorateObject(cluster, ctx);
145  decorationPh0(*egamma) = res.maxEcell_time;
146  decorationPh1(*egamma) = res.maxEcell_energy;
147  decorationPh2(*egamma) = res.maxEcell_gain;
148  decorationPh3(*egamma) = res.maxEcell_onlId;
149  decorationPh4(*egamma) = res.maxEcell_x;
150  decorationPh5(*egamma) = res.maxEcell_y;
151  decorationPh6(*egamma) = res.maxEcell_z;
152  }
153  }
154 
155  if (!m_SGKey_electrons.key().empty()) {
156  // Retrieve electron container
158  ctx);
159 
160  //
161  std::optional<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> odecorationEl7;
162  const xAOD::CaloClusterContainer* egClContainer(nullptr);
163  if (!m_SGKey_egammaClusters.key().empty()) {
165  m_SGKey_egammaClusters, ctx);
166  egClContainer = egClContainerRH.ptr();
167  odecorationEl7.emplace(m_SGKey_electrons_decorations[7], ctx);
168  }
169 
170  // setup vector of decorators
172  m_SGKey_electrons_decorations[0], ctx);
174  m_SGKey_electrons_decorations[1], ctx);
176  m_SGKey_electrons_decorations[2], ctx);
178  m_SGKey_electrons_decorations[3], ctx);
180  m_SGKey_electrons_decorations[4], ctx);
182  m_SGKey_electrons_decorations[5], ctx);
184  m_SGKey_electrons_decorations[6], ctx);
185 
186  const xAOD::EgammaContainer* importedElectrons = electronContainer.ptr();
187  for (const auto* egamma : *importedElectrons) {
188  const xAOD::CaloCluster *cluster = egamma->caloCluster();
189  if (!m_SGKey_egammaClusters.key().empty()) {
190  double dRMin = 9e9;
191  const xAOD::CaloCluster *matchedCluster(nullptr);
192  for (const auto *clus : *egClContainer) {
193  double dR = clus->p4().DeltaR(cluster->p4());
194  if (dR < dRMin && dR < m_dRLRTegClusegClusMax) {
195  dRMin = dR;
196  matchedCluster = clus;
197  }
198  }
199  cluster = matchedCluster;
200  odecorationEl7.value()(*egamma) = dRMin;
201  }
203  decorateObject(cluster, ctx);
204  decorationEl0(*egamma) = res.maxEcell_time;
205  decorationEl1(*egamma) = res.maxEcell_energy;
206  decorationEl2(*egamma) = res.maxEcell_gain;
207  decorationEl3(*egamma) = res.maxEcell_onlId;
208  decorationEl4(*egamma) = res.maxEcell_x;
209  decorationEl5(*egamma) = res.maxEcell_y;
210  decorationEl6(*egamma) = res.maxEcell_z;
211  }
212  }
213 
214  if (!m_SGKey_taus.key().empty()) {
215  // Retrieve tau container
216  SG::ReadHandle<xAOD::TauJetContainer> tauJetContainer(m_SGKey_taus, ctx);
217  // setup vector of decorators
219  m_SGKey_taus_decorations[0], ctx);
221  m_SGKey_taus_decorations[1], ctx);
223  m_SGKey_taus_decorations[2], ctx);
225  m_SGKey_taus_decorations[3], ctx);
227  m_SGKey_taus_decorations[4], ctx);
229  m_SGKey_taus_decorations[5], ctx);
231  m_SGKey_taus_decorations[6], ctx);
232 
233  const xAOD::TauJetContainer* importedTaus = tauJetContainer.ptr();
234  for (const auto* tau : *importedTaus) {
236  res.maxEcell_energy = -9999.;
237  for (size_t i = 0;i<tau->nClusters();++i) {
238  // get particle
239  const xAOD::IParticle* part = tau->cluster(i);
240  if ( not part ) {
241  ATH_MSG_WARNING("Tau particle link invalid");
242  continue;
243  }
244 
245  const xAOD::CaloCluster* cluster=dynamic_cast<const xAOD::CaloCluster*> (part);
246  if ( not cluster ) {
247  ATH_MSG_WARNING("Tau cluster link invalid");
248  continue;
249  }
250 
252  decorateObject(cluster, ctx);
253  if (resCand.maxEcell_energy > res.maxEcell_energy) {
254  res = resCand;
255  }
256  }
257 
258  decorationTau0(*tau) = res.maxEcell_time;
259  decorationTau1(*tau) = res.maxEcell_energy;
260  decorationTau2(*tau) = res.maxEcell_gain;
261  decorationTau3(*tau) = res.maxEcell_onlId;
262  decorationTau4(*tau) = res.maxEcell_x;
263  decorationTau5(*tau) = res.maxEcell_y;
264  decorationTau6(*tau) = res.maxEcell_z;
265  }
266  }
267 
268  if (!m_SGKey_jets.key().empty()) {
269  // Retrieve jet container
270  SG::ReadHandle<xAOD::JetContainer> jetContainer(m_SGKey_jets, ctx);
271  // setup vector of decorators
273  m_SGKey_jets_decorations[0], ctx);
275  m_SGKey_jets_decorations[1], ctx);
277  m_SGKey_jets_decorations[2], ctx);
279  m_SGKey_jets_decorations[3], ctx);
281  m_SGKey_jets_decorations[4], ctx);
283  m_SGKey_jets_decorations[5], ctx);
285  m_SGKey_jets_decorations[6], ctx);
286 
287  const xAOD::JetContainer* importedJets = jetContainer.ptr();
288  for (const auto* jet : *importedJets) {
289  if (jet->numConstituents() == 0) continue;
290 
292  res.maxEcell_energy = -9999.;
293  std::vector<const xAOD::CaloCluster*> clusterList;
294  clusterList.clear();
295 
296  xAOD::Type::ObjectType ctype = jet->rawConstituent( 0 )->type();
297 
298  if (ctype == xAOD::Type::FlowElement) {
299  // Particle Flow jets
300  for (size_t i=0;i<jet->numConstituents();++i) {
301  if(jet->rawConstituent(i)->type() != xAOD::Type::FlowElement) {
302  ATH_MSG_WARNING("Tried to call fillEperSamplingFE with a jet constituent that is not a FlowElement!");
303  continue;
304  }
305 
306  const xAOD::FlowElement* constit = static_cast<const xAOD::FlowElement*>(jet->rawConstituent(i));
307  if (constit) {
308  const SG::AuxElement::ConstAccessor< ElementLink<xAOD::IParticleContainer> > originalObject("originalObjectLink");
309  auto originalFE = dynamic_cast<const xAOD::FlowElement*>(*originalObject(*constit));
310  if(originalFE && !originalFE->isCharged()){
311  const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>(originalFE->otherObject(0));
312  if (cluster) {
313  clusterList.push_back(cluster);
314  }
315  }
316  }
317  }
318  } else if (ctype == xAOD::Type::CaloCluster) {
319  // Topo jets
320  for (size_t i=0;i<jet->numConstituents();++i) {
321  if(jet->rawConstituent(i)->type() != xAOD::Type::CaloCluster) {
322  ATH_MSG_WARNING("Tried to call fillEperSamplingCluster with a jet constituent that is not a cluster!");
323  continue;
324  }
325 
326  const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>(jet->rawConstituent(i));
327  if (cluster) {
328  clusterList.push_back(cluster);
329  }
330  }
331  } else {
332  // PFlow (old)
333  for (size_t i=0;i<jet->numConstituents();++i) {
334  if(jet->rawConstituent(i)->type() != xAOD::Type::ParticleFlow) {
335  continue;
336  }
337  const xAOD::PFO* iPFO = static_cast<const xAOD::PFO*>(jet->rawConstituent(i));
338  if ( iPFO ) {
339  for (unsigned int cidx=0;cidx<iPFO->nCaloCluster();++cidx) {
340  if ( iPFO->cluster(cidx) ) {
341  clusterList.push_back(iPFO->cluster(cidx));
342  }
343  }
344  }
345  }
346  }
347 
348  for (auto cluster : clusterList) {
350  decorateObject(cluster, ctx);
351  if (resCand.maxEcell_energy > res.maxEcell_energy) {
352  res = resCand;
353  }
354  }
355 
356  decorationJet0(*jet) = res.maxEcell_time;
357  decorationJet1(*jet) = res.maxEcell_energy;
358  decorationJet2(*jet) = res.maxEcell_gain;
359  decorationJet3(*jet) = res.maxEcell_onlId;
360  decorationJet4(*jet) = res.maxEcell_x;
361  decorationJet5(*jet) = res.maxEcell_y;
362  decorationJet6(*jet) = res.maxEcell_z;
363  }
364  }
365 
366  return StatusCode::SUCCESS;
367 }
368 
371  const xAOD::CaloCluster* cluster,
372  const EventContext& ctx) const
373 {
374 
376 
377  if (cluster) {
378  if (!cluster->getCellLinks()) {
379  ATH_MSG_DEBUG("CellLinks not found");
380  return result;
381  }
382 
383  SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{ m_cablingKey, ctx };
384  const LArOnOffIdMapping* cabling{ *cablingHdl };
385  if (!cabling) {
386  ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key());
387  return result;
388  }
389 
390  float emax = -9999.;
391 
392  const CaloCell* cell_maxE = nullptr;
393  for (const CaloCell* cell : *cluster) {
394  int sampling = cell->caloDDE()->getSampling();
395  if (sampling == CaloCell_ID::EMB2 || sampling == CaloCell_ID::EME2) {
396  if ((cell->provenance() & 0x2000)) {
397  if (cell->energy() > emax) {
398  emax = cell->energy();
399  cell_maxE = cell;
400  }
401  }
402  }
403  }
404 
405  if (cell_maxE) {
406  const CaloDetDescrElement* caloDDEl = cell_maxE->caloDDE();
407  result.maxEcell_time = cell_maxE->time();
408  result.maxEcell_energy = cell_maxE->energy();
409  result.maxEcell_gain = (int)cell_maxE->gain();
410  result.maxEcell_onlId =
411  (uint64_t)(cabling->createSignalChannelID(caloDDEl->identify()))
412  .get_compact();
413  result.maxEcell_x = caloDDEl->x();
414  result.maxEcell_y = caloDDEl->y();
415  result.maxEcell_z = caloDDEl->z();
416  }
417  }
418  return result;
419 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
DerivationFramework::MaxCellDecorator::initialize
StatusCode initialize()
Definition: MaxCellDecorator.cxx:30
DerivationFramework::MaxCellDecorator::addBranches
virtual StatusCode addBranches(const EventContext &ctx) const
Definition: MaxCellDecorator.cxx:118
electronContainer
xAOD::ElectronContainer * electronContainer
Definition: TrigGlobEffCorrValidation.cxx:187
get_generator_info.result
result
Definition: get_generator_info.py:21
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloDetDescrElement::y
float y() const
cell y
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:365
ObjectType
ObjectType
Definition: BaseObject.h:11
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
DerivationFramework::MaxCellDecorator::calculation::maxEcell_energy
float maxEcell_energy
Definition: MaxCellDecorator.h:46
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
DerivationFramework::MaxCellDecorator::~MaxCellDecorator
~MaxCellDecorator()
CaloCell::time
float time() const
get time (data member)
Definition: CaloCell.h:368
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
xAOD::CaloCluster
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloCluster.h:19
CaloCell_ID.h
egamma
Definition: egamma.h:58
CaloCell::energy
double energy() const
get energy (data member)
Definition: CaloCell.h:327
DerivationFramework::MaxCellDecorator::MaxCellDecorator
MaxCellDecorator(const std::string &t, const std::string &n, const IInterface *p)
Definition: MaxCellDecorator.cxx:18
DerivationFramework::MaxCellDecorator::calculation
Definition: MaxCellDecorator.h:44
CaloDetDescrElement::identify
Identifier identify() const override final
cell identifier
Definition: CaloDetDescrElement.cxx:63
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::PFO_v1::nCaloCluster
unsigned int nCaloCluster() const
Find out how many CaloCluster are linked.
Definition: PFO_v1.cxx:659
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:727
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
DerivationFramework::MaxCellDecorator::finalize
StatusCode finalize()
Definition: MaxCellDecorator.cxx:111
xAOD::FlowElement
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition: FlowElement.h:16
CaloCell::caloDDE
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition: CaloCell.h:321
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:11
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAODType::ParticleFlow
@ ParticleFlow
The object is a particle-flow object.
Definition: ObjectType.h:41
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:829
photonContainer
xAOD::PhotonContainer * photonContainer
Definition: TrigGlobEffCorrValidation.cxx:189
xAOD::CaloCluster_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: CaloCluster_v1.cxx:465
xAOD::PFO_v1
Class describing a particle flow object.
Definition: PFO_v1.h:35
CaloCell::gain
CaloGain::CaloGain gain() const
get gain (data member )
Definition: CaloCell.h:361
CaloDetDescrElement::x
float x() const
cell x
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:363
CaloClusterStoreHelper.h
SG::ReadHandle::ptr
const_pointer_type ptr()
Dereference the pointer.
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloDetDescrElement::z
float z() const
cell z
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:367
MaxCellDecorator.h
DerivationFramework::MaxCellDecorator::decorateObject
calculation decorateObject(const xAOD::CaloCluster *cluster, const EventContext &ctx) const
Definition: MaxCellDecorator.cxx:370
xAOD::PFO_v1::cluster
const CaloCluster * cluster(unsigned int index) const
Retrieve a const pointer to a CaloCluster.
Definition: PFO_v1.cxx:669
DataVector::emplace
iterator emplace(iterator position, value_type pElem)
Add a new element to the collection.
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25
LArOnOffIdMapping
Definition: LArOnOffIdMapping.h:20
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37