ATLAS Offline Software
Loading...
Searching...
No Matches
JetCaloCalculations.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
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 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()) ;
75 return t;
76 }
77
78 virtual double energyHEC(JetConstitIterator & it ) const override {
79 float m=0.;
80 const xAOD::PFO* pfo = static_cast<const xAOD::PFO*>(it->rawConstituent()) ;
82 return m;
83 }
84
85 };
86
92 virtual ~FlowElementExtractor()= default;
93 virtual bool valid(JetConstitIterator & it ) const override {
94 const xAOD::FlowElement* fe = dynamic_cast<const xAOD::FlowElement*>(it->rawConstituent());
95 if (fe != nullptr) return (!fe->isCharged());
96 return false;
97 }
98
99 virtual double moment(JetConstitIterator & it , xAOD::CaloCluster::MomentType momentType) const override {
100 float m=0.;
101 const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(it->rawConstituent());
102 FEHelpers::getClusterMoment(*fe, momentType, m);
103 return m;
104 }
105
106 virtual double time(JetConstitIterator & it) const override {
107 const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(it->rawConstituent());
108 const static SG::AuxElement::ConstAccessor<float> accTiming("TIMING");
109
110 float timing = -1;
111
112 if(accTiming.isAvailable(*fe)){
113 timing = accTiming(*fe);
114 }
115 else{
116 if(fe->otherObjects().size() == 1 && fe->otherObject(0)){
117 const auto* neutralObject = (fe->otherObject(0));
118 const xAOD::CaloCluster* cluster = nullptr;
119
120 if(neutralObject->type() == xAOD::Type::CaloCluster){
121 cluster = dynamic_cast<const xAOD::CaloCluster*> (neutralObject);
122 }
123 //If we have a PFO (in case of fe being a UFO), we need to get the associated cluster first
124 else {
125 const xAOD::FlowElement* pfo = dynamic_cast<const xAOD::FlowElement*>(neutralObject);
126 if(!pfo->otherObjects().empty() && pfo->otherObject(0) && pfo->otherObject(0)->type() == xAOD::Type::CaloCluster){
127 cluster = dynamic_cast<const xAOD::CaloCluster*> (pfo->otherObject(0));
128 }
129 }
130
131 if(cluster){
132 timing = cluster->time();
133 }
134 }
135 }
136 return timing;
137 }
138
139 virtual double energyHEC(JetConstitIterator & it ) const override {
140 const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(it->rawConstituent());
141
142 // Add up the four individual HEC layers
143 const static SG::AuxElement::ConstAccessor<float> accHEC0("LAYERENERGY_HEC0");
144 const static SG::AuxElement::ConstAccessor<float> accHEC1("LAYERENERGY_HEC1");
145 const static SG::AuxElement::ConstAccessor<float> accHEC2("LAYERENERGY_HEC2");
146 const static SG::AuxElement::ConstAccessor<float> accHEC3("LAYERENERGY_HEC3");
147
148 float sum_HEC = 0.0;
149
150 // The variables are available for PFOs but not UFOs
151 if(accHEC0.isAvailable(*fe) && accHEC1.isAvailable(*fe) && accHEC2.isAvailable(*fe) && accHEC3.isAvailable(*fe)){
152 sum_HEC = accHEC0(*fe) + accHEC1(*fe) + accHEC2(*fe) + accHEC3(*fe);
153 }
154 else{
155 for (size_t n = 0; n < fe->otherObjects().size(); ++n) {
156 if(! fe->otherObject(n)) continue;
157 const auto* neutralObject = (fe->otherObject(n));
158
159 const xAOD::CaloCluster* cluster = nullptr;
160
161 //If we have a cluster, we can directly access the calorimeter information
162 if(neutralObject->type() == xAOD::Type::CaloCluster){
163 cluster = dynamic_cast<const xAOD::CaloCluster*> (neutralObject);
164 }
165 //If we have a PFO (in case of fe being a UFO), we need to get the associated cluster first
166 else {
167 const xAOD::FlowElement* pfo = dynamic_cast<const xAOD::FlowElement*>(neutralObject);
168 if(!pfo->otherObjects().empty() && pfo->otherObject(0) && pfo->otherObject(0)->type() == xAOD::Type::CaloCluster){
169 cluster = dynamic_cast<const xAOD::CaloCluster*> (pfo->otherObject(0));
170 }
171 }
172 if(cluster){
173 sum_HEC += cluster->eSample( CaloSampling::HEC0 ) + cluster->eSample( CaloSampling::HEC1 ) + cluster->eSample( CaloSampling::HEC2 ) + cluster->eSample( CaloSampling::HEC3 );
174 }
175 }
176 }
177 return sum_HEC;
178 }
179
180 };
181
182
186 static const CaloConstitExtractor nullEx;
187 static const CaloClusterExtractor clusteEx;
188 static const PFOExtractor pfoEx;
189 static const FlowElementExtractor feEx;
190
191 if(jet->numConstituents() == 0 ) return &nullEx;
192
193 // WARNING not entirely safe : assume all constits are of same type
194
195 switch(jet->rawConstituent(0)->type() ) {
197 return &clusteEx;
199 return &pfoEx;
201 return &feEx;
202 default:
203 break;
204 }
205 return &nullEx;
206 }
207
208}
209
210
211
212// Implementation of JetCaloCalculator framwework
213namespace jet {
214
216 m_name(xAOD::JetAttributeAccessor::name(id)),
217 m_id(id)
218 {
219 // std::cout<< " JetCaloCalculatorBase" << " id "<< id <<std::endl;
220 }
221
223
224 if (! setupJet( jet ) ) return 0;
225 size_t nConstit = jet->numConstituents();
226 if( nConstit == 0) return true;
227
228 // retrieve the cluster moment extractor for this jet.
230
231
232 xAOD::JetConstituentVector constits = jet->getConstituents();
233 // Use the constituent iterator
234 // IMPORTANT : use UncalibratedJetConstituent.
235 // By default the calculators will just use the kinematic from the iterator they are
236 // given. This allows to choose what scale we give them.
237 // Here we use UncalibratedJetConstituent as default, because most (or all) calo quantity to be calculated
238 // are based on EM scale cluster moments.
239 xAOD::JetConstituentVector::iterator it = constits.begin(constitscale );
240 xAOD::JetConstituentVector::iterator itE = constits.end(constitscale);
241
242 for(; it != itE; ++it)
243 {
244 if( m_constitExtractor->valid(it) )
245 processConstituent(it); // (no support for weight now)
246 }
247
248 return jetCalculation();
249
250 }
251
252
253
254 // ********************************************************
255 // JetCaloCalculations methods
256 // ********************************************************
260
261 // ********************************************************
263 for(size_t i=0;i < m_calculators.size();i++) m_calculators[i]->setupEvent();
264 return true;
265 }
266
267
268 // ********************************************************
269 std::vector<double> JetCaloCalculations::process(const xAOD::Jet* jet) const {
270 size_t nConstit = jet->numConstituents();
271 std::vector<double> results;
272 results.reserve(m_calculators.size());
273
274 if( nConstit == 0) {
275 results.resize(m_calculators.size(),0);
276 return results;
277 }
278
279 // Clone calculators : we are in a const method, we can't call the
280 // non const setupJet() and processConstituent() methods of our calculators.
281 std::vector<JetCaloCalculator*> clonedCalc;
282 clonedCalc.reserve(m_calculators.size());
283 for( const JetCaloCalculator *calc : m_calculators) clonedCalc.push_back( calc->clone() );
284
285 // prepare each calculator
286 for(JetCaloCalculator* calc: clonedCalc) {
287 calc->setupJet(jet);
288 }
289
290 // retrieve the cluster moment extractor for this jet.
292 // assign the extractor to the calculators :
293 for( JetCaloCalculator* calc : clonedCalc) calc->setExtractor(extractor);
294
295 xAOD::JetConstituentVector constits = jet->getConstituents();
296 // Use the constituent iterator at UNCALIBRATED scale
299
300 // loop over constituents
301 for(; it != itE; ++it)
302 {
303 //std::cout << " processing constit ---- "<< (*it)->pt() << " v= "<< extractor->valid(it) << std::endl;
304
305 if( ! extractor->valid(it) ) continue; // this can happen for charged pflow objects
306 // loop over calculators for this constituent.
307 for(JetCaloCalculator* calc : clonedCalc) {
308 calc->processConstituent(it);
309 }
310 } // constituents loop
311
312 // copy results & clear the cloned calc
313 for(JetCaloCalculator* calc: clonedCalc) {
314 results.push_back( calc->jetCalculation() );
315 delete calc;
316 }
317
318 return results;
319 }
320
321
322 // std::vector<double> JetCaloCalculations::calculations(){
323
324 // std::vector<double> v(m_calculators.size());
325 // for(size_t i=0;i < m_calculators.size();i++) {
326 // v[i] = m_calculators[i]->jetCalculation() ;
327 // }
328 // return v;
329 // }
330
332 if(m_owncalculators) for(size_t i=0;i < m_calculators.size();i++) delete m_calculators[i];
333 m_calculators.clear();
334 }
335}
Defines enum to access jet attribute and associated particles/objects.
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
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