ATLAS Offline Software
FlowEnergyDecorator.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 #include "FlowEnergyDecorator.h"
7 #include "StoreGate/ReadHandle.h"
11 #include "CxxUtils/close_to_zero.h"
12 
14 
15 FlowEnergyDecorator::FlowEnergyDecorator(const std::string& name, ISvcLocator* loc)
17 {}
18 
20  ATH_MSG_INFO("Initializing " << name() << "... ");
21 
22  ATH_CHECK(m_FlowContainerKey.initialize());
23  ATH_CHECK(m_PFlowContainerKey.initialize());
24 
25  // Initialize the decorations keys for total EM and HAD energies and fractions
26  ATH_CHECK(m_eEMKey.initialize());
27  ATH_CHECK(m_eHADKey.initialize());
28  ATH_CHECK(m_eFracEMKey.initialize());
29  ATH_CHECK(m_eFracHADKey.initialize());
30 
31  // Initialize the layer energy accessors and decorators keys for both EM and HAD layers
32  ATH_CHECK(m_emReadDecorKeys.initialize());
33  ATH_CHECK(m_emWriteDecorKeys.initialize());
34  ATH_CHECK(m_hadReadDecorKeys.initialize());
35  ATH_CHECK(m_hadWriteDecorKeys.initialize());
36 
37  return StatusCode::SUCCESS;
38 }
39 
40 StatusCode FlowEnergyDecorator::execute(const EventContext& ctx) const {
41  ATH_MSG_DEBUG("Executing " << name() << "... ");
42 
43 
45  if ( !pflowCont.isValid() ) {
46  ATH_MSG_ERROR("Failed to retrieve " << m_PFlowContainerKey.key() << " !");
47  return StatusCode::FAILURE;
48  }
49 
51  if ( !ufoCont.isValid() ) {
52  ATH_MSG_ERROR("Failed to retrieve " << m_FlowContainerKey.key() << " !");
53  return StatusCode::FAILURE;
54  }
55 
56  // Declare the WriteDecorHandles for the total EM and HAD energies and fractions (no accessors needed here)
61 
62  // Declare the ReadDecorHandles and WriteDecorHandles for each EM layer energy accessor and decorator
63  std::vector< SG::ReadDecorHandle<xAOD::FlowElementContainer, float> > layerAccessors_em;
64  layerAccessors_em.reserve(m_emReadDecorKeys.size());
66  layerAccessors_em.emplace_back(key, ctx);
67  }
68  std::vector< SG::WriteDecorHandle<xAOD::FlowElementContainer, float> > layerDecors_em;
69  layerDecors_em.reserve(m_emWriteDecorKeys.size());
71  layerDecors_em.emplace_back(key, ctx);
72  }
73 
74  // Declare the ReadDecorHandles and WriteDecorHandles for each HAD layer energy accessor and decorator
75  std::vector< SG::ReadDecorHandle<xAOD::FlowElementContainer, float> > layerAccessors_had;
76  layerAccessors_had.reserve(m_hadReadDecorKeys.size());
78  layerAccessors_had.emplace_back(key, ctx);
79  }
80  std::vector< SG::WriteDecorHandle<xAOD::FlowElementContainer, float> > layerDecors_had;
81  layerDecors_em.reserve(m_hadWriteDecorKeys.size());
83  layerDecors_had.emplace_back(key, ctx);
84  }
85 
86  // loop over all UFOs from UFOCSSK
87  for ( const xAOD::FlowElement* flow : *ufoCont ) {
88  float eEM = 0.;
89  float eHAD = 0.;
90 
91  // loop over all EM layers in the calorimeter
92  for (size_t iem = 0; iem < m_emReadDecorKeys.size(); ++iem) {
93 
94  // declare references to the accessor and decorator for a given HAD layer
95  const auto& layerAccessor = layerAccessors_em.at(iem);
96  auto& layerDecor = layerDecors_em.at(iem);
97 
98  float e = 0.;
99 
100  // get the links to the pflow constituents of the UFO
101  const std::vector<ElementLink<xAOD::IParticleContainer>>& pflowLinks = flow->otherObjectLinks();
102  // loop over all available pflows of a given UFO
103  for ( auto& el : pflowLinks ) {
104  if ( !el.isValid() ) {throw std::runtime_error("Invalid ElementLink found.");};
105  const xAOD::FlowElement* c = dynamic_cast<const xAOD::FlowElement*>(*el);
106  if (not c) continue;
107  if (c->charge() != 0) continue; // if the constituent is a track, continue
108  e += layerAccessor(*c); // else the constituent is a cluster, so add the energy of every cluster for a given layer for the considered UFO
109  }
110  layerDecor(*flow) = e; // decorate the UFO with the energy associated to a given EM layer (once the energies from every cluster in this layer have been summed up)
111  eEM += e;
112  }
113 
114  // loop over all HAD layers in the calorimeter
115  for (size_t ihad = 0; ihad < m_hadReadDecorKeys.size(); ++ihad) {
116 
117  // declare references to the accessor and decorator for a given HAD layer
118  const auto& layerAccessor = layerAccessors_had.at(ihad);
119  auto& layerDecor = layerDecors_had.at(ihad);
120 
121  float e = 0.;
122 
123  // get the links to the pflow constituents of the UFO
124  const std::vector<ElementLink<xAOD::IParticleContainer>>& pflowLinks = flow->otherObjectLinks();
125 
126  // loop over all available pflows of a given UFO
127  for ( auto& el : pflowLinks ) {
128  if ( !el.isValid() ) {throw std::runtime_error("Invalid ElementLink found.");};
129  const xAOD::FlowElement* c = static_cast<const xAOD::FlowElement*>(*el);
130  if (c->charge() != 0) continue;
131  e += layerAccessor(*c);
132  }
133  layerDecor(*flow) = e; // decorate the UFO with the energy associated to a given HAD layer (once the energies from every cluster in this layer have been summed up)
134  eHAD += e;
135  }
136 
137  // decorate the UFO with the total electromagnetic or hadronic energy once the loop over the layers is over for a given UFO
138  eEMDecorHandle(*flow) = eEM;
139  eHADDecorHandle(*flow) = eHAD;
140 
141  // decorate the UFO with the electromagnetic or hadronic energy fractions once the loop over the layers is over for a given UFO
142  const float eTOT = eEM + eHAD;
143  const bool eTotZero = close_to_zero(eTOT);
144  eFracEMDecorHandle(*flow) = (!eTotZero) ? (eEM / eTOT) : 0.;
145  eFracHADDecorHandle(*flow) = (!eTotZero) ? (eHAD / eTOT) : 0.;
146  }
147 
148  return StatusCode::SUCCESS;
149 }
SG::WriteDecorHandleKey
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Definition: StoreGate/StoreGate/WriteDecorHandleKey.h:89
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
FlowElementContainer.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
FlowEnergyDecorator::m_eFracEMKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eFracEMKey
Definition: FlowEnergyDecorator.h:66
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
FlowEnergyDecorator::FlowEnergyDecorator
FlowEnergyDecorator(const std::string &name, ISvcLocator *pSvcLocator)
Definition: FlowEnergyDecorator.cxx:15
FlowEnergyDecorator::m_emWriteDecorKeys
SG::WriteDecorHandleKeyArray< xAOD::FlowElementContainer > m_emWriteDecorKeys
Definition: FlowEnergyDecorator.h:78
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
FlowEnergyDecorator::m_hadWriteDecorKeys
SG::WriteDecorHandleKeyArray< xAOD::FlowElementContainer > m_hadWriteDecorKeys
Definition: FlowEnergyDecorator.h:86
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
FlowElement.h
HepMC::flow
int flow(const T &a, int i)
Definition: Flow.h:51
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
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
WriteDecorHandle.h
Handle class for adding a decoration to an object.
FlowEnergyDecorator::m_eFracHADKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eFracHADKey
Definition: FlowEnergyDecorator.h:70
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FlowEnergyDecorator::execute
virtual StatusCode execute(const EventContext &) const override
Definition: FlowEnergyDecorator.cxx:40
python.getProblemFolderFromLogs.el
dictionary el
Definition: getProblemFolderFromLogs.py:54
FlowEnergyDecorator::m_eEMKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eEMKey
Definition: FlowEnergyDecorator.h:58
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
FlowEnergyDecorator::m_hadReadDecorKeys
SG::ReadDecorHandleKeyArray< xAOD::FlowElementContainer > m_hadReadDecorKeys
Definition: FlowEnergyDecorator.h:82
FlowEnergyDecorator::initialize
virtual StatusCode initialize() override
Definition: FlowEnergyDecorator.cxx:19
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
close_to_zero.h
test if a value is close enough to zero to be an unreliable denominator.
FlowEnergyDecorator.h
CxxUtils::close_to_zero
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())
Definition: close_to_zero.h:48
FlowEnergyDecorator::m_eHADKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eHADKey
Definition: FlowEnergyDecorator.h:62
FlowEnergyDecorator::m_PFlowContainerKey
SG::ReadHandleKey< xAOD::FlowElementContainer > m_PFlowContainerKey
Definition: FlowEnergyDecorator.h:38
ReadDecorHandle.h
Handle class for reading a decoration on an object.
ReadHandle.h
Handle class for reading from StoreGate.
SG::ReadDecorHandleKey
Property holding a SG store/key/clid/attr name from which a ReadDecorHandle is made.
Definition: StoreGate/StoreGate/ReadDecorHandleKey.h:85
FlowEnergyDecorator::m_emReadDecorKeys
SG::ReadDecorHandleKeyArray< xAOD::FlowElementContainer > m_emReadDecorKeys
Definition: FlowEnergyDecorator.h:74
python.compressB64.c
def c
Definition: compressB64.py:93
FlowEnergyDecorator::m_FlowContainerKey
SG::ReadHandleKey< xAOD::FlowElementContainer > m_FlowContainerKey
Definition: FlowEnergyDecorator.h:33
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37