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 
8 
9 #include <string>
10 #include <vector>
11 namespace {}
12 
13 // Athena initialize
16 {
17  ATH_MSG_VERBOSE("initialize() ...");
18 
20 
22  if (!m_SGKey_electrons.key().empty()) {
23  ATH_MSG_INFO("Using " << m_SGKey_electrons.key() << " for electrons");
24  }
25  ATH_CHECK(m_SGKey_electrons_decorations.initialize(!m_SGKey_electrons.key().empty()));
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
54 {
55 
56  if (!m_SGKey_photons.key().empty()) {
57  // Retrieve photon container
59  // setup vector of decorators
61  m_SGKey_photons_decorations[0], ctx);
63  m_SGKey_photons_decorations[1], ctx);
65  m_SGKey_photons_decorations[2], ctx);
67  m_SGKey_photons_decorations[3], ctx);
69  m_SGKey_photons_decorations[4], ctx);
71  m_SGKey_photons_decorations[5], ctx);
73  m_SGKey_photons_decorations[6], ctx);
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()) {
100  m_SGKey_egammaClusters, ctx);
101  egClContainer = egClContainerRH.ptr();
102  odecorationEl7.emplace(m_SGKey_electrons_decorations[7], ctx);
103  }
104 
105  // setup vector of decorators
107  m_SGKey_electrons_decorations[0], ctx);
109  m_SGKey_electrons_decorations[1], ctx);
111  m_SGKey_electrons_decorations[2], ctx);
113  m_SGKey_electrons_decorations[3], ctx);
115  m_SGKey_electrons_decorations[4], ctx);
117  m_SGKey_electrons_decorations[5], ctx);
119  m_SGKey_electrons_decorations[6], ctx);
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
151  SG::ReadHandle<xAOD::TauJetContainer> tauJetContainer(m_SGKey_taus, ctx);
152  // setup vector of decorators
154  m_SGKey_taus_decorations[0], ctx);
156  m_SGKey_taus_decorations[1], ctx);
158  m_SGKey_taus_decorations[2], ctx);
160  m_SGKey_taus_decorations[3], ctx);
162  m_SGKey_taus_decorations[4], ctx);
164  m_SGKey_taus_decorations[5], ctx);
166  m_SGKey_taus_decorations[6], ctx);
167 
168  const xAOD::TauJetContainer* importedTaus = tauJetContainer.ptr();
169  for (const auto* tau : *importedTaus) {
171  res.maxEcell_energy = -9999.;
172  for (size_t i = 0;i<tau->nClusters();++i) {
173  // get particle
174  const xAOD::IParticle* part = tau->cluster(i);
175  if ( not part ) {
176  ATH_MSG_WARNING("Tau particle link invalid");
177  continue;
178  }
179 
180  const xAOD::CaloCluster* cluster=dynamic_cast<const xAOD::CaloCluster*> (part);
181  if ( not cluster ) {
182  ATH_MSG_WARNING("Tau cluster link invalid");
183  continue;
184  }
185 
187  decorateObject(cluster, ctx);
188  if (resCand.maxEcell_energy > res.maxEcell_energy) {
189  res = resCand;
190  }
191  }
192 
193  decorationTau0(*tau) = res.maxEcell_time;
194  decorationTau1(*tau) = res.maxEcell_energy;
195  decorationTau2(*tau) = res.maxEcell_gain;
196  decorationTau3(*tau) = res.maxEcell_onlId;
197  decorationTau4(*tau) = res.maxEcell_x;
198  decorationTau5(*tau) = res.maxEcell_y;
199  decorationTau6(*tau) = res.maxEcell_z;
200  }
201  }
202 
203  if (!m_SGKey_jets.key().empty()) {
204  // Retrieve jet container
205  SG::ReadHandle<xAOD::JetContainer> jetContainer(m_SGKey_jets, ctx);
206  // setup vector of decorators
208  m_SGKey_jets_decorations[0], ctx);
210  m_SGKey_jets_decorations[1], ctx);
212  m_SGKey_jets_decorations[2], ctx);
214  m_SGKey_jets_decorations[3], ctx);
216  m_SGKey_jets_decorations[4], ctx);
218  m_SGKey_jets_decorations[5], ctx);
220  m_SGKey_jets_decorations[6], ctx);
221 
222  const xAOD::JetContainer* importedJets = jetContainer.ptr();
223  for (const auto* jet : *importedJets) {
224  if (jet->numConstituents() == 0) continue;
225 
227  res.maxEcell_energy = -9999.;
228  std::vector<const xAOD::CaloCluster*> clusterList;
229  clusterList.clear();
230 
231  xAOD::Type::ObjectType ctype = jet->rawConstituent( 0 )->type();
232 
234  // Particle Flow jets
235  for (size_t i=0;i<jet->numConstituents();++i) {
236  if(jet->rawConstituent(i)->type() != xAOD::Type::FlowElement) {
237  ATH_MSG_WARNING("Tried to call fillEperSamplingFE with a jet constituent that is not a FlowElement!");
238  continue;
239  }
240 
241  const xAOD::FlowElement* constit = static_cast<const xAOD::FlowElement*>(jet->rawConstituent(i));
242  if (constit) {
243  const SG::AuxElement::ConstAccessor< ElementLink<xAOD::IParticleContainer> > originalObject("originalObjectLink");
244  auto originalFE = dynamic_cast<const xAOD::FlowElement*>(*originalObject(*constit));
245  if(originalFE && !originalFE->isCharged()){
246  const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>(originalFE->otherObject(0));
247  if (cluster) {
248  clusterList.push_back(cluster);
249  }
250  }
251  }
252  }
253  } else if (ctype == xAOD::Type::CaloCluster) {
254  // Topo jets
255  for (size_t i=0;i<jet->numConstituents();++i) {
256  if(jet->rawConstituent(i)->type() != xAOD::Type::CaloCluster) {
257  ATH_MSG_WARNING("Tried to call fillEperSamplingCluster with a jet constituent that is not a cluster!");
258  continue;
259  }
260 
261  const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>(jet->rawConstituent(i));
262  if (cluster) {
263  clusterList.push_back(cluster);
264  }
265  }
266  } else {
267  // PFlow (old)
268  for (size_t i=0;i<jet->numConstituents();++i) {
269  if(jet->rawConstituent(i)->type() != xAOD::Type::ParticleFlow) {
270  continue;
271  }
272  const xAOD::PFO* iPFO = static_cast<const xAOD::PFO*>(jet->rawConstituent(i));
273  if ( iPFO ) {
274  for (unsigned int cidx=0;cidx<iPFO->nCaloCluster();++cidx) {
275  if ( iPFO->cluster(cidx) ) {
276  clusterList.push_back(iPFO->cluster(cidx));
277  }
278  }
279  }
280  }
281  }
282 
283  for (auto cluster : clusterList) {
285  decorateObject(cluster, ctx);
286  if (resCand.maxEcell_energy > res.maxEcell_energy) {
287  res = resCand;
288  }
289  }
290 
291  decorationJet0(*jet) = res.maxEcell_time;
292  decorationJet1(*jet) = res.maxEcell_energy;
293  decorationJet2(*jet) = res.maxEcell_gain;
294  decorationJet3(*jet) = res.maxEcell_onlId;
295  decorationJet4(*jet) = res.maxEcell_x;
296  decorationJet5(*jet) = res.maxEcell_y;
297  decorationJet6(*jet) = res.maxEcell_z;
298  }
299  }
300 
301  return StatusCode::SUCCESS;
302 }
303 
306  const xAOD::CaloCluster* cluster,
307  const EventContext& ctx) const
308 {
309 
311 
312  if (cluster) {
313  if (!cluster->getCellLinks()) {
314  ATH_MSG_DEBUG("CellLinks not found");
315  return result;
316  }
317 
318  SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{ m_cablingKey, ctx };
319  const LArOnOffIdMapping* cabling{ *cablingHdl };
320  if (!cabling) {
321  ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key());
322  return result;
323  }
324 
325  float emax = -9999.;
326 
327  const CaloCell* cell_maxE = nullptr;
328  for (const CaloCell* cell : *cluster) {
329  int sampling = cell->caloDDE()->getSampling();
330  if (sampling == CaloCell_ID::EMB2 || sampling == CaloCell_ID::EME2) {
331  if ((cell->provenance() & 0x2000)) {
332  if (cell->energy() > emax) {
333  emax = cell->energy();
334  cell_maxE = cell;
335  }
336  }
337  }
338  }
339 
340  if (cell_maxE) {
341  const CaloDetDescrElement* caloDDEl = cell_maxE->caloDDE();
342  result.maxEcell_time = cell_maxE->time();
343  result.maxEcell_energy = cell_maxE->energy();
344  result.maxEcell_gain = (int)cell_maxE->gain();
345  result.maxEcell_onlId =
346  (uint64_t)(cabling->createSignalChannelID(caloDDEl->identify()))
347  .get_compact();
348  result.maxEcell_x = caloDDEl->x();
349  result.maxEcell_y = caloDDEl->y();
350  result.maxEcell_z = caloDDEl->z();
351  }
352  }
353  return result;
354 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
DerivationFramework::MaxCellDecorator::initialize
virtual StatusCode initialize() override final
Definition: MaxCellDecorator.cxx:15
DerivationFramework::MaxCellDecorator::m_cablingKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Definition: MaxCellDecorator.h:49
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:40
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
DerivationFramework::MaxCellDecorator::m_SGKey_electrons_decorations
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_electrons_decorations
Definition: MaxCellDecorator.h:99
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:40
DerivationFramework::MaxCellDecorator::m_SGKey_egammaClusters
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...
Definition: MaxCellDecorator.h:69
DerivationFramework::MaxCellDecorator::m_SGKey_electrons
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_electrons
Definition: MaxCellDecorator.h:59
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
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::addBranches
virtual StatusCode addBranches(const EventContext &ctx) const override final
Definition: MaxCellDecorator.cxx:53
DerivationFramework::MaxCellDecorator::calculation
Definition: MaxCellDecorator.h:38
DerivationFramework::MaxCellDecorator::m_SGKey_taus
SG::ReadHandleKey< xAOD::TauJetContainer > m_SGKey_taus
Definition: MaxCellDecorator.h:77
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
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
DerivationFramework::MaxCellDecorator::m_SGKey_jets
SG::ReadHandleKey< xAOD::JetContainer > m_SGKey_jets
Definition: MaxCellDecorator.h:80
DerivationFramework::MaxCellDecorator::m_SGKey_taus_decorations
SG::WriteDecorHandleKeyArray< xAOD::TauJetContainer > m_SGKey_taus_decorations
Definition: MaxCellDecorator.h:108
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
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
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
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
DerivationFramework::MaxCellDecorator::m_SGKey_photons
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_photons
Definition: MaxCellDecorator.h:57
xAOD::CaloCluster_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: CaloCluster_v1.cxx:465
DerivationFramework::MaxCellDecorator::m_SGKey_jets_decorations
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_SGKey_jets_decorations
Definition: MaxCellDecorator.h:117
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
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
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.
DerivationFramework::MaxCellDecorator::m_SGKey_photons_decorations
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_photons_decorations
Definition: MaxCellDecorator.h:90
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
EventPicking.ctype
ctype
Definition: EventPicking.py:137
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:305
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.
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:27
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