ATLAS Offline Software
Loading...
Searching...
No Matches
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
12
14
15FlowEnergyDecorator::FlowEnergyDecorator(const std::string& name, ISvcLocator* loc)
16 : AthReentrantAlgorithm(name, 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
40StatusCode 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}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
An algorithm that can be simultaneously executed in multiple threads.
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eFracEMKey
virtual StatusCode execute(const EventContext &) const override
SG::ReadDecorHandleKeyArray< xAOD::FlowElementContainer > m_emReadDecorKeys
SG::ReadHandleKey< xAOD::FlowElementContainer > m_PFlowContainerKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eHADKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eEMKey
virtual StatusCode initialize() override
SG::ReadHandleKey< xAOD::FlowElementContainer > m_FlowContainerKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_eFracHADKey
FlowEnergyDecorator(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadDecorHandleKeyArray< xAOD::FlowElementContainer > m_hadReadDecorKeys
SG::WriteDecorHandleKeyArray< xAOD::FlowElementContainer > m_hadWriteDecorKeys
SG::WriteDecorHandleKeyArray< xAOD::FlowElementContainer > m_emWriteDecorKeys
Property holding a SG store/key/clid/attr name from which a ReadDecorHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Handle class for adding a decoration to an object.
test if a value is close enough to zero to be an unreliable denominator.
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16