ATLAS Offline Software
Loading...
Searching...
No Matches
JetCaloCalculations.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6
9
10#include "xAODPFlow/PFO.h"
12
18
19namespace CaloConstitHelpers {
20
22
23
29 virtual ~CaloClusterExtractor()= default;
30 virtual bool valid(JetConstitIterator & it ) const override {
31 return (dynamic_cast<const xAOD::CaloCluster*>(it->rawConstituent())!=nullptr);
32 }
33
34 virtual double moment(JetConstitIterator & it, xAOD::CaloCluster::MomentType momentType) const override {
35 double m = 0;
36 static_cast<const xAOD::CaloCluster*>(it->rawConstituent())->retrieveMoment(momentType,m) ;
37 return m;
38 }
39
40 virtual double time(JetConstitIterator & it) const override {
41 return static_cast<const xAOD::CaloCluster*>(it->rawConstituent())->time();
42 }
43
44 virtual double energyHEC(JetConstitIterator & it) const override {
45 const xAOD::CaloCluster* cl = static_cast<const xAOD::CaloCluster*>(it->rawConstituent());
46 return cl->eSample( CaloSampling::HEC0) + cl->eSample( CaloSampling::HEC1) +
47 cl->eSample( CaloSampling::HEC2) + cl->eSample( CaloSampling::HEC3);
48 }
49
50 };
51
57 virtual ~PFOExtractor()= default;
58 virtual bool valid(JetConstitIterator & it ) const override {
59 const xAOD::PFO* pfo = dynamic_cast<const xAOD::PFO*>(it->rawConstituent());
60 if (pfo!=nullptr) return (!pfo->isCharged());
61 return false;
62 }
63
64 virtual double moment(JetConstitIterator & it , xAOD::CaloCluster::MomentType momentType) const override {
65 float m=0.;
66 const xAOD::PFO* pfo = static_cast<const xAOD::PFO*>(it->rawConstituent()) ;
67 bool ok [[maybe_unused]] = pfo->getClusterMoment(m, momentType );
68 return m;
69 }
70
71 virtual double time(JetConstitIterator & it) const override {
72 float t=0.;
73 const xAOD::PFO* pfo = static_cast<const xAOD::PFO*>(it->rawConstituent()) ;
74 bool ok[[maybe_unused]] = pfo->attribute( xAOD::PFODetails::eflowRec_TIMING, t);
75
76 return t;
77 }
78
79 virtual double energyHEC(JetConstitIterator & it ) const override {
80 float m=0.;
81 const xAOD::PFO* pfo = static_cast<const xAOD::PFO*>(it->rawConstituent()) ;
82 bool ok[[maybe_unused]] = pfo->attribute( xAOD::PFODetails::eflowRec_LAYERENERGY_HEC, m);
83 return m;
84 }
85
86 };
87
93 virtual ~FlowElementExtractor()= default;
94 virtual bool valid(JetConstitIterator & it ) const override {
95 const xAOD::FlowElement* fe = dynamic_cast<const xAOD::FlowElement*>(it->rawConstituent());
96 if (fe != nullptr) return (!fe->isCharged());
97 return false;
98 }
99
100 virtual double moment(JetConstitIterator & it , xAOD::CaloCluster::MomentType momentType) const override {
101 float m=0.;
102 const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(it->rawConstituent());
103 FEHelpers::getClusterMoment(*fe, momentType, m);
104 return m;
105 }
106
107 virtual double time(JetConstitIterator & it) const override {
108 const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(it->rawConstituent());
109 const static SG::AuxElement::ConstAccessor<float> accTiming("TIMING");
110
111 float timing = -1;
112
113 if(accTiming.isAvailable(*fe)){
114 timing = accTiming(*fe);
115 }
116 else{
117 if(fe->otherObjects().size() == 1 && fe->otherObject(0)){
118 const auto* neutralObject = (fe->otherObject(0));
119 const xAOD::CaloCluster* cluster = nullptr;
120
121 if(neutralObject->type() == xAOD::Type::CaloCluster){
122 cluster = dynamic_cast<const xAOD::CaloCluster*> (neutralObject);
123 }
124 //If we have a PFO (in case of fe being a UFO), we need to get the associated cluster first
125 else {
126 const xAOD::FlowElement* pfo = static_cast<const xAOD::FlowElement*>(neutralObject);
127 if(!pfo->otherObjects().empty() && pfo->otherObject(0) && pfo->otherObject(0)->type() == xAOD::Type::CaloCluster){
128 cluster = dynamic_cast<const xAOD::CaloCluster*> (pfo->otherObject(0));
129 }
130 }
131
132 if(cluster){
133 timing = cluster->time();
134 }
135 }
136 }
137 return timing;
138 }
139
140 virtual double energyHEC(JetConstitIterator & it ) const override {
141 const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(it->rawConstituent());
142
143 // Add up the four individual HEC layers
144 const static SG::AuxElement::ConstAccessor<float> accHEC0("LAYERENERGY_HEC0");
145 const static SG::AuxElement::ConstAccessor<float> accHEC1("LAYERENERGY_HEC1");
146 const static SG::AuxElement::ConstAccessor<float> accHEC2("LAYERENERGY_HEC2");
147 const static SG::AuxElement::ConstAccessor<float> accHEC3("LAYERENERGY_HEC3");
148
149 float sum_HEC = 0.0;
150
151 // The variables are available for PFOs but not UFOs
152 if(accHEC0.isAvailable(*fe) && accHEC1.isAvailable(*fe) && accHEC2.isAvailable(*fe) && accHEC3.isAvailable(*fe)){
153 sum_HEC = accHEC0(*fe) + accHEC1(*fe) + accHEC2(*fe) + accHEC3(*fe);
154 }
155 else{
156 for (size_t n = 0; n < fe->otherObjects().size(); ++n) {
157 if(! fe->otherObject(n)) continue;
158 const auto* neutralObject = (fe->otherObject(n));
159
160 const xAOD::CaloCluster* cluster = nullptr;
161
162 //If we have a cluster, we can directly access the calorimeter information
163 if(neutralObject->type() == xAOD::Type::CaloCluster){
164 cluster = dynamic_cast<const xAOD::CaloCluster*> (neutralObject);
165 }
166 //If we have a PFO (in case of fe being a UFO), we need to get the associated cluster first
167 else {
168 const xAOD::FlowElement* pfo = static_cast<const xAOD::FlowElement*>(neutralObject);
169 if(!pfo->otherObjects().empty() && pfo->otherObject(0) && pfo->otherObject(0)->type() == xAOD::Type::CaloCluster){
170 cluster = dynamic_cast<const xAOD::CaloCluster*> (pfo->otherObject(0));
171 }
172 }
173 if(cluster){
174 sum_HEC += cluster->eSample( CaloSampling::HEC0 ) + cluster->eSample( CaloSampling::HEC1 ) + cluster->eSample( CaloSampling::HEC2 ) + cluster->eSample( CaloSampling::HEC3 );
175 }
176 }
177 }
178 return sum_HEC;
179 }
180
181 };
182
183
187 static const CaloConstitExtractor nullEx;
188 static const CaloClusterExtractor clusteEx;
189 static const PFOExtractor pfoEx;
190 static const FlowElementExtractor feEx;
191
192 if(jet->numConstituents() == 0 ) return &nullEx;
193
194 // WARNING not entirely safe : assume all constits are of same type
195
196 switch(jet->rawConstituent(0)->type() ) {
198 return &clusteEx;
200 return &pfoEx;
202 return &feEx;
203 default:
204 break;
205 }
206 return &nullEx;
207 }
208
209}
210
211
212
213// Implementation of JetCaloCalculator framwework
214namespace jet {
215
217 m_name(xAOD::JetAttributeAccessor::name(id)),
218 m_id(id)
219 {
220 // std::cout<< " JetCaloCalculatorBase" << " id "<< id <<std::endl;
221 }
222
224
225 if (! setupJet( jet ) ) return 0;
226 size_t nConstit = jet->numConstituents();
227 if( nConstit == 0) return true;
228
229 // retrieve the cluster moment extractor for this jet.
231
232
233 xAOD::JetConstituentVector constits = jet->getConstituents();
234 // Use the constituent iterator
235 // IMPORTANT : use UncalibratedJetConstituent.
236 // By default the calculators will just use the kinematic from the iterator they are
237 // given. This allows to choose what scale we give them.
238 // Here we use UncalibratedJetConstituent as default, because most (or all) calo quantity to be calculated
239 // are based on EM scale cluster moments.
240 xAOD::JetConstituentVector::iterator it = constits.begin(constitscale );
241 xAOD::JetConstituentVector::iterator itE = constits.end(constitscale);
242
243 for(; it != itE; ++it)
244 {
245 if( m_constitExtractor->valid(it) )
246 processConstituent(it); // (no support for weight now)
247 }
248
249 return jetCalculation();
250
251 }
252
253
254
255 // ********************************************************
256 // JetCaloCalculations methods
257 // ********************************************************
261
262 // ********************************************************
264 for(size_t i=0;i < m_calculators.size();i++) m_calculators[i]->setupEvent();
265 return true;
266 }
267
268
269 // ********************************************************
270 std::vector<double> JetCaloCalculations::process(const xAOD::Jet* jet) const {
271 size_t nConstit = jet->numConstituents();
272 std::vector<double> results;
273 results.reserve(m_calculators.size());
274
275 if( nConstit == 0) {
276 results.resize(m_calculators.size(),0);
277 return results;
278 }
279
280 // Clone calculators : we are in a const method, we can't call the
281 // non const setupJet() and processConstituent() methods of our calculators.
282 std::vector<JetCaloCalculator*> clonedCalc;
283 clonedCalc.reserve(m_calculators.size());
284 for( const JetCaloCalculator *calc : m_calculators) clonedCalc.push_back( calc->clone() );
285
286 // prepare each calculator
287 for(JetCaloCalculator* calc: clonedCalc) {
288 calc->setupJet(jet);
289 }
290
291 // retrieve the cluster moment extractor for this jet.
293 // assign the extractor to the calculators :
294 for( JetCaloCalculator* calc : clonedCalc) calc->setExtractor(extractor);
295
296 xAOD::JetConstituentVector constits = jet->getConstituents();
297 // Use the constituent iterator at UNCALIBRATED scale
300
301 // loop over constituents
302 for(; it != itE; ++it)
303 {
304 //std::cout << " processing constit ---- "<< (*it)->pt() << " v= "<< extractor->valid(it) << std::endl;
305
306 if( ! extractor->valid(it) ) continue; // this can happen for charged pflow objects
307 // loop over calculators for this constituent.
308 for(JetCaloCalculator* calc : clonedCalc) {
309 calc->processConstituent(it);
310 }
311 } // constituents loop
312
313 // copy results & clear the cloned calc
314 for(JetCaloCalculator* calc: clonedCalc) {
315 results.push_back( calc->jetCalculation() );
316 delete calc;
317 }
318
319 return results;
320 }
321
322
323 // std::vector<double> JetCaloCalculations::calculations(){
324
325 // std::vector<double> v(m_calculators.size());
326 // for(size_t i=0;i < m_calculators.size();i++) {
327 // v[i] = m_calculators[i]->jetCalculation() ;
328 // }
329 // return v;
330 // }
331
333 if(m_owncalculators) for(size_t i=0;i < m_calculators.size();i++) delete m_calculators[i];
334 m_calculators.clear();
335 }
336}
Defines enum to access jet attribute and associated particles/objects.
size_t size() const
Number of registered mappings.
std::vector< JetCaloCalculator * > m_calculators
virtual std::vector< double > process(const xAOD::Jet *jet) const
Perform all tasks correspondings to the associated JetCaloCalculators on Jet jet.
void addCalculator(JetCaloCalculator *c)
Base class to support cpu-efficient calculation on calorimeter jets either at CaloCell or constituent...
virtual double jetCalculation() const
return the result of the calculation
virtual bool setupJet(const xAOD::Jet *)=0
virtual bool processConstituent(xAOD::JetConstituentVector::iterator &)
Perform 1 calculation step using 1 constituent.
virtual std::string name() const
virtual double operator()(const xAOD::Jet *jet, xAOD::JetConstitScale s=xAOD::UncalibratedJetConstituent)
convenience function to perform the full calculation on a given jet
const CaloConstitHelpers::CaloConstitExtractor * m_constitExtractor
xAOD::JetAttribute::AttributeID m_id
flt_t time() const
Access cluster time.
float eSample(const CaloSample sampling) const
MomentType
Enums to identify different moments.
std::vector< const xAOD::IParticle * > otherObjects() const
const xAOD::IParticle * otherObject(std::size_t i) const
virtual Type::ObjectType type() const =0
The type of the object as a simple enumeration.
A vector of jet constituents at the scale used during jet finding.
iterator begin() const
iterator on the first constituent
iterator end() const
iterator after the last constituent
bool attribute(PFODetails::PFOAttributes AttributeType, T &anAttribute) const
get a PFO Variable via enum
bool getClusterMoment(float &theMoment, xAOD::CaloCluster::MomentType momentType) const
Accessor for cluster moments.
Definition PFO_v1.cxx:402
bool isCharged() const
is a charged PFO
Definition PFO_v1.cxx:251
const CaloConstitExtractor * extractorForJet(const xAOD::Jet *jet)
returns a pointer to a CaloConstitExtractor for a given jet.
xAOD::JetConstituentVector::iterator JetConstitIterator
bool getClusterMoment(const xAOD::FlowElement &fe, xAOD::CaloCluster::MomentType momentType, float &value)
Definition FEHelpers.cxx:51
@ 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
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Jet_v1 Jet
Definition of the current "jet version".
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
JetConstitScale
Definition JetTypes.h:20
@ UncalibratedJetConstituent
Definition JetTypes.h:21
virtual double time(JetConstitIterator &it) const override
virtual double energyHEC(JetConstitIterator &it) const override
virtual bool valid(JetConstitIterator &it) const override
virtual double moment(JetConstitIterator &it, xAOD::CaloCluster::MomentType momentType) const override
Interface to retrieve calo informations from a jet constituent.
virtual bool valid(xAOD::JetConstituentVector::iterator &) const
virtual bool valid(JetConstitIterator &it) const override
virtual double energyHEC(JetConstitIterator &it) const override
virtual double moment(JetConstitIterator &it, xAOD::CaloCluster::MomentType momentType) const override
virtual double time(JetConstitIterator &it) const override
virtual double energyHEC(JetConstitIterator &it) const override
virtual double moment(JetConstitIterator &it, xAOD::CaloCluster::MomentType momentType) const override
virtual bool valid(JetConstitIterator &it) const override
virtual double time(JetConstitIterator &it) const override