ATLAS Offline Software
Loading...
Searching...
No Matches
TrackCaloClusterTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
5
7
10
11
12#include "CxxUtils/sincos.h"
13
16
17
18namespace {
19 // helper functions needed only in this file are defined in this anonymous namespace
20
21 using FourMom_t = xAOD::IParticle::FourMom_t; // this is actually
22
23 // update the given eta and phi coordinates by shifting the origin to the position of vertex
24 void computeVertexCorr(double& eta, double& phi, const Amg::Vector3D& vertex, double radius) {
25
26 if (radius<1.) return;
27
28 if (std::fabs(eta)>10. || std::fabs(phi)>10.) return;
29
31 double iradius = 1 / radius;
32 eta += (-vertex[2]/std::cosh(eta) + sc.apply (vertex[1], vertex[0])*std::tanh(eta)) * iradius;
33 phi += sc.apply (vertex[0], -vertex[1]) * iradius;
34 }
35
36
37
38 template<typename T>
39 void setParameters(xAOD::FlowElement* fe, float pt, float eta, float phi, float m,
42 const std::vector<ElementLink<T> >& neutralLinks){
43 std::vector<ElementLink<xAOD::IParticleContainer> > ipLinks(neutralLinks.size());
44 for(size_t i=0;i<neutralLinks.size();i++) ipLinks[i] = neutralLinks[i];
45 setParameters(fe,pt,eta,phi, m, stype,trackLink, ipLinks);
46 }
47
48 template<>
49 void setParameters<xAOD::IParticleContainer>(xAOD::FlowElement* fe, float pt, float eta, float phi, float m,
52 const std::vector<ElementLink<xAOD::IParticleContainer> >& neutralLinks){
53 fe->setP4(pt,eta,phi,m);
54 fe->setSignalType(stype);
55 fe->setChargedObjectLinks( {trackLink} );
56 fe->setOtherObjectLinks( neutralLinks);
57 }
58
59
61 template<typename DTYPE, typename CTYPE>
63 static const std::string ts = typeid(DTYPE).name();
64 if(wh.empty() ) return SG::AuxElement::ConstAccessor<DTYPE>( typeid(DTYPE).name() );
65 const auto split = wh.key().rfind ('.');
66 if (split == std::string::npos)
67 throw std::runtime_error ("decor key does not contain a .: " + wh.key());
68 return SG::AuxElement::ConstAccessor<DTYPE>( wh.key().substr (split + 1) );
69 }
70
71
72
73}
74
75
76//*******************************************************************************
77
78TrackCaloClusterBaseTool::TrackCaloClusterBaseTool(const std::string& t, const std::string& n, const IInterface* p )
79 : AthAlgTool(t,n,p)
80{
81 declareInterface<ITrackCaloClusterTool>(this);
82}
84
85
88
89 ATH_CHECK(m_assoClustersKey.initialize());
90
92 return StatusCode::SUCCESS;
93}
94
95
96
97
98
99
100
101//*******************************************************************************
102
103TCCCombinedTool::TCCCombinedTool(const std::string& t, const std::string& n, const IInterface* p )
104 : TrackCaloClusterBaseTool(t,n,p) { }
105
106
107StatusCode TCCCombinedTool::fillTCC(xAOD::FlowElementContainer* tccContainer, const TrackCaloClusterInfo & tccInfo ) const {
108
109 if(tccInfo.pv0==nullptr){
110 ATH_MSG_ERROR ("No PV0 available ! ");
111 return StatusCode::FAILURE;
112 }
113
114 // declare Decorator in case we want to save out corrected positions
115 static const SG::AuxElement::Decorator<int> dec_isCorrected("Corrected");
116 static const SG::AuxElement::Decorator<float> dec_calEntryEta("CaloEntryPosEtaCorr") ;
117 static const SG::AuxElement::Decorator<float> dec_calEntryPhi("CaloEntryPosPhiCorr") ;
118 static const SG::AuxElement::Decorator<float> dec_detEta("DetectorEta") ;
119
120 // it is not possible to prepare a blank ReadDecorHandle (which we need if !m_caloEntryParsDecor.empty()), so instead or re-instantiating a ReadDecorHandle on each
121 // track in the loop below, we just instantiate a ConstAccessor
123 auto caloEntryParams = asConstAccessor<const Trk::TrackParameters*>(m_caloEntryParsDecor);
124
125
126 for ( const xAOD::TrackParticle* trk : *tccInfo.allTracks ) {
127
128 if (! m_trackVertexAssoTool->isCompatible(*trk, *tccInfo.pv0) ) continue ;
129
130 const auto & clusterLinks = clusterLinksH(*trk);
131 if( clusterLinks.empty() ) continue;
132
133 FourMom_t tcc_4p(0.,0.,0.,0.); // will be the TCC 4-vector
134
135 // Loop over associated clusters to sum the 4-vectors x weigths
136 for( const ElementLink<xAOD::CaloClusterContainer> & clLink : clusterLinks){
137 const xAOD::CaloCluster* cluster = *clLink;
138
139 double cluster_pt = m_useEnergy ? cluster->e() : cluster->pt();
140 double totalcluster_pt = m_useEnergy ? tccInfo.trackTotalClusterPt.at(trk).E() : tccInfo.trackTotalClusterPt.at(trk).Pt();
141
142 tcc_4p += cluster->p4()*(( trk->pt() * cluster_pt / totalcluster_pt) / ((tccInfo.clusterToTracksWeightMap.at(cluster)).Pt()));
143
144 ATH_MSG_VERBOSE ("cluster->pt() " << cluster_pt << " cluster->eta() " << cluster->eta() << " cluster->phi() "
145 << cluster->phi() << " track pt " << trk->pt() << " (tccInfo.clusterToTracksWeightMap.at(cluster)).Pt() " << (tccInfo.clusterToTracksWeightMap.at(cluster)).Pt());
146 } // for caloClusterLinks
147
148
149 // get angular position from tracks
150 double eta = trk->eta();
151 double phi = trk->phi();
152
154 // retrieve the caloExtensionContainer to get the track direction at the calo entrance
155
156 const Trk::TrackParameters* pars = caloEntryParams(*trk);
157 eta = pars->position().eta();
158 phi = pars->position().phi();
159
160 computeVertexCorr(eta, phi, tccInfo.pv0->position(), pars->position().perp());
162 dec_isCorrected(*trk) = 1;
163 dec_calEntryEta(*trk) = eta;
164 dec_calEntryPhi(*trk) = phi;
165 }
166 }
167
168 // Build the final TCC
170 tccContainer->push_back(tcc);
172 ElementLink<xAOD::TrackParticleContainer>(*tccInfo.allTracks, trk->index() ),clusterLinks);
173
174 ATH_MSG_VERBOSE ("Created TCC with pt " << tcc->pt() << " eta " << tcc->eta() << " phi " << tcc->phi() << " mass " << tcc->m() << " signalType= " << tcc->signalType());
175
176 if(m_saveDetectorEta) {
177 const Trk::TrackParameters* pars = caloEntryParams(*trk);
178 double det_eta = pars->position().eta();
179 dec_detEta(*tcc) = det_eta;
180 }
181 } // for assoc clusters
182
183
184 return StatusCode::SUCCESS;
185}
186
187
188
189
190
191
192
193//*******************************************************************************
194
195TCCChargedTool::TCCChargedTool(const std::string& t, const std::string& n, const IInterface* p )
196 : TrackCaloClusterBaseTool(t,n,p) { }
197
198
199
200StatusCode TCCChargedTool::fillTCC(xAOD::FlowElementContainer* tccContainer, const TrackCaloClusterInfo & tccInfo ) const {
201
202
203 // it is not possible to prepare a blank ReadDecorHandle (which we need if !m_caloEntryParsDecor.empty()), so instead or re-instantiating a ReadDecorHandle on each
204 // track in the loop below, we just instantiate a ConstAccessor
205 auto caloEntryParams = asConstAccessor<const Trk::TrackParameters*>(m_caloEntryParsDecor);
206
208
209 // declare Decorator in case we want to save out corrected positions
210 static const SG::AuxElement::Decorator<float> dec_detEta("DetectorEta") ;
211
212 unsigned int i = 0;
213 // Loop over ALL tracks at the source of TCC
214 for ( const xAOD::TrackParticle* track : *tccInfo.allTracks ) {
215 if( ! clusterLinksH(*track).empty() ) continue; // because if not empty, it is matched to a cluster
216 // considre ONLY tracks NOT matched to a cluster :
217 if(tccInfo.trackTotalClusterPt.find(track)==tccInfo.trackTotalClusterPt.end()){
218 bool isMatched = m_trackVertexAssoTool->isCompatible(*track, *tccInfo.pv0 );
219 if (!isMatched) continue;
220
222 tccContainer->push_back(tcc);
224 setParameters(tcc, track->pt(),track->eta(),track->phi(),track->m(),xAOD::FlowElement::SignalType::Charged,trkLink,std::vector<ElementLink<xAOD::CaloClusterContainer>>());
225 ATH_MSG_VERBOSE ("Created TCC with pt " << tcc->pt() << " eta " << tcc->eta() << " phi " << tcc->phi() << " mass " << tcc->m() << " taste " << tcc->signalType());
226
228 // retrieve the caloExtensionContainer to get the track direction at the calo entrance
229 double det_eta = track->eta();
230 const Trk::TrackParameters* pars = caloEntryParams(*track);
231 if(pars) det_eta = pars->position().eta();
232 dec_detEta(*tcc) = det_eta;
233 }
234 }
235 i++;
236 }
237 return StatusCode::SUCCESS;
238}
239
240
241
242
243
244//*******************************************************************************
245
246TCCNeutralTool::TCCNeutralTool(const std::string& t, const std::string& n, const IInterface* p )
247 : TrackCaloClusterBaseTool(t,n,p) {}
248
251 if (!m_clusterFilterTool.empty()){
252 ATH_CHECK(m_clusterFilterTool.retrieve());
253 m_applyFilter=true;
254 } else m_applyFilter=false;
255 return StatusCode::SUCCESS;
256}
257
258
259
260StatusCode TCCNeutralTool::fillTCC(xAOD::FlowElementContainer* tccContainer, const TrackCaloClusterInfo & tccInfo ) const {
261
262 unsigned int i = 0;
263 // declare Decorator in case we want to save out corrected positions
264 static const SG::AuxElement::Decorator<float> dec_detEta("DetectorEta") ;
265
266 // Loop over ALL clusters
267 for ( const xAOD::CaloCluster* cluster : *tccInfo.allClusters ) {
268 // consider only clusters NOT matched to a track :
269 if(tccInfo.clusterToTracksWeightMap.find(cluster)==tccInfo.clusterToTracksWeightMap.end()){
270 if (m_applyFilter and m_clusterFilterTool->rejectCluster(*cluster)) continue;
271
272 // create a neutral TCC
274 tccContainer->push_back(tcc);
276 const std::vector< ElementLink<xAOD::CaloClusterContainer> > ClusterLink {clusterLink};
277 setParameters(tcc, cluster->pt(),cluster->eta(),cluster->phi(),cluster->m(),xAOD::FlowElement::SignalType::Neutral,ElementLink<xAOD::TrackParticleContainer>(),ClusterLink);
278 ATH_MSG_VERBOSE ("Created TCC with pt " << tcc->pt() << " eta " << tcc->eta() << " phi " << tcc->phi() << " mass " << tcc->m() << " taste " << tcc->signalType());
279
280 static const SG::AuxElement::Accessor< float > acc_det_eta ( "DetectorEta" );
281 if(m_saveDetectorEta && acc_det_eta.isAvailable(*cluster)) {
282 dec_detEta(*tcc) = dec_detEta(*cluster);
283 }
284 }
285 i++;
286 } // for all clusters
287 return StatusCode::SUCCESS;
288}
289
290
291
292
293
294
295
296
297
298
299//*******************************************************************************
300
301
302
303namespace TCCHelpers{
307 struct UFOBuilder : public CombinedUFOLoop {
308
312
313 std::vector<ElementLink< xAOD::FlowElementContainer > > m_pfoLinks;
314 FourMom_t m_tcc_4p = {0.,0.,0.,0.};
315
316 virtual void processPFO(const xAOD::TrackParticle* trk, const xAOD::FlowElement* pfo) {
318 const xAOD::FlowElementContainer *tmp_pfoContainer = dynamic_cast< const xAOD::FlowElementContainer* >(pfo->container());
319 ElementLink< xAOD::FlowElementContainer > pfoLink(tmp_pfoContainer,pfo->index());
320 m_pfoLinks.push_back(pfoLink);
321 double pfo_pt = m_useEnergy ? pfo->e() : pfo->pt();
322 const FourMom_t & totalP = m_tccInfo->trackTotalClusterPt.at(trk);
323 double totalpfo_pt = m_useEnergy ? totalP.E() : totalP.Pt();
324 m_tcc_4p += pfo->p4()*(( trk->pt() * pfo_pt / totalpfo_pt) / ((m_tccInfo->clusterToTracksWeightMap.at(pfo)).Pt()));
325 }
326
327 virtual void processTrk(const xAOD::TrackParticle* trk ) {
328 // build the actual combined UFO
329 if(m_tcc_4p.Pt() <=0) return;
330
332 m_tccContainer->push_back(tcc);
335
336 // reset accumulators for next track :
337 m_pfoLinks.clear();
338 m_tcc_4p = {0.,0.,0.,0.};
339 }
340 };
341}
342
343
344
345UFOTool::UFOTool(const std::string& t, const std::string& n, const IInterface* p )
346 : TrackCaloClusterBaseTool(t,n,p) {}
347
349 //override parent class because of additional requirements on the PFOHandles etc
351
352 ATH_CHECK(m_assoClustersKey.initialize());
353
355 ATH_CHECK(m_inputPFOHandle.initialize(!m_inputPFOHandle.empty()));
356 return StatusCode::SUCCESS;
357}
358
359StatusCode UFOTool::fillTCC(xAOD::FlowElementContainer* tccContainer, const TrackCaloClusterInfo & tccInfo ) const {
360
362 const EventContext& ctx=Gaudi::Hive::currentContext();
363
365
366 // We use a dedicated helper to build the combined UFO. Initialize it :
368 ufoB.m_orig_pfoK = m_orig_pfo;
373
374 ufoB.m_pfoContainer = pfos.ptr();
375 ufoB.m_tccInfo = &tccInfo;
376 ufoB.m_tccContainer = tccContainer;
378
379 // create a combined UFO for each track matched to some PFO
381 ufoB.combinedUFOLoop(&tccInfo, pfos.cptr());
382
383 // Create a UFO for all neutral and charged PFO which are not matched to any tracks
384 for ( const xAOD::FlowElement* pfo : *pfos ) {
385 if(pfo->pt() <= 0) continue;
386 if(tccInfo.clusterToTracksWeightMap.find(pfo)!=tccInfo.clusterToTracksWeightMap.end())
387 {
388 // If the pfo is part of clusterToTracksWeightMap, this means it will be included as part of a combined UFO
389 continue;
390 }
391
392 if(pfo->isCharged()) {
393 // this decoration is set by JetRecTools/Root/ChargedHadronSubtractionTool.cxx !
394 const static SG::AuxElement::Accessor<char> PVMatchedAcc("matchedToPV");
395 if(!PVMatchedAcc(*pfo)) continue;
396 }
397
398 const xAOD::FlowElementContainer *tmp_pfoContainer = dynamic_cast< const xAOD::FlowElementContainer* >(pfo->container());
399 ElementLink< xAOD::FlowElementContainer > pfoLink(tmp_pfoContainer,pfo->index());
400 const std::vector< ElementLink<xAOD::FlowElementContainer> > PFOLink {pfoLink};
402 tccContainer->push_back(tcc);
403
404 if(pfo->isCharged()) {
405 //retrieve the track from the charged PFO
406 const xAOD::IParticle* pfo_chargedobj=pfo->chargedObjects().at(0);
407 const xAOD::TrackParticle* pfo_track=dynamic_cast<const xAOD::TrackParticle*>(pfo_chargedobj);
408
409 setParameters(tcc, pfo->pt(), pfo->eta(), pfo->phi(), pfo->m(), xAOD::FlowElement::SignalType::Charged, ElementLink<xAOD::TrackParticleContainer>(*tccInfo.allTracks, pfo_track->index()), PFOLink);
410 }else{
411 setParameters(tcc, pfo->pt(),pfo->eta(),pfo->phi(),pfo->m(),xAOD::FlowElement::SignalType::Neutral,ElementLink<xAOD::TrackParticleContainer>(),PFOLink);
412 }
413 } // PFO
414
415 return StatusCode::SUCCESS;
416}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
Base class for elements of a container that can have aux data.
static Double_t sc
Some common helper functions used by decoration handles.
Handle class for reading a decoration on an object.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
const SG::AuxVectorData * container() const
Return the container holding this element.
size_t index() const
Return the index of this element within its container.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Property holding a SG store/key/clid/attr name from which a ReadDecorHandle is made.
Handle class for reading a decoration on an object.
const_pointer_type ptr()
Dereference the pointer.
const_pointer_type cptr()
Dereference the pointer.
TCCChargedTool(const std::string &, const std::string &, const IInterface *)
virtual StatusCode fillTCC(xAOD::FlowElementContainer *container, const TrackCaloClusterInfo &tccInfo) const override
Gaudi::Property< bool > m_storeCorrectedPosition
virtual StatusCode fillTCC(xAOD::FlowElementContainer *container, const TrackCaloClusterInfo &tccInfo) const override
Gaudi::Property< bool > m_doOriginCorrection
TCCCombinedTool(const std::string &, const std::string &, const IInterface *)
virtual StatusCode initialize() override
ToolHandle< IClusterFilterTool > m_clusterFilterTool
optionnal tool to filter cluster we don't want to consider as TCC
virtual StatusCode fillTCC(xAOD::FlowElementContainer *container, const TrackCaloClusterInfo &tccInfo) const override
TCCNeutralTool(const std::string &, const std::string &, const IInterface *)
Gaudi::Property< bool > m_saveDetectorEta
flag to add dectetor eta decoration onto the produced TrackCaloClusters
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_caloEntryParsDecor
TrackCaloClusterBaseTool(const std::string &, const std::string &, const IInterface *)
virtual ~TrackCaloClusterBaseTool()
ToolHandle< CP::ITrackVertexAssociationTool > m_trackVertexAssoTool
The tool used to make sure a track is associated to PV0.
Gaudi::Property< bool > m_useEnergy
use cluster energy or pt?
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_assoClustersKey
virtual StatusCode initialize() override
Gaudi::Property< std::string > m_orig_pfo
virtual StatusCode fillTCC(xAOD::FlowElementContainer *container, const TrackCaloClusterInfo &tccInfo) const override
Gaudi::Property< float > m_clusterEcut
cluster with E below this cut won't be considered in the TCC alg. WARNING cut must be configured as i...
UFOTool(const std::string &, const std::string &, const IInterface *)
SG::ReadHandleKey< xAOD::FlowElementContainer > m_inputPFOHandle
virtual StatusCode initialize() override
virtual double pt() const
The transverse momentum ( ) of the particle (negative for negative-energy clusters)
virtual double m() const
The invariant mass of the particle.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double e() const
The total energy of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
virtual double pt() const override
void setP4(float pt, float eta, float phi, float m)
virtual double m() const override
The invariant mass of the particle.
virtual double phi() const override
The azimuthal angle ( ) of the particle.
virtual double eta() const override
The pseudorapidity ( ) of the particle.
signal_t signalType() const
void setChargedObjectLinks(const std::vector< ElementLink< IParticleContainer > > &elV)
void setSignalType(signal_t t)
SignalType
Enum to encode the nature of the object this FlowElement represents.
void setOtherObjectLinks(const std::vector< ElementLink< IParticleContainer > > &elV)
virtual double e() const override
The total energy of the particle.
virtual FourMom_t p4() const override
The full 4-momentum of the particle.
Class providing the definition of the 4-vector interface.
TLorentzVector FourMom_t
Definition of the 4-momentum type.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
const Amg::Vector3D & position() const
Returns the 3-pos.
void setParameters(T *h, TGraphAsymmErrors *tg)
Definition computils.h:436
int ts
Definition globals.cxx:24
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
Eigen::Matrix< double, 3, 1 > Vector3D
TLorentzVector FourMom_t
std::string decorKeyFromKey(const std::string &key, const std::string &deflt)
Extract the decoration part of key.
\bried Internal helper class for TCC & UFO building.
ParametersBase< TrackParametersDim, Charged > TrackParameters
str wh
Definition parseDir.py:45
FlowElementContainer_v1 FlowElementContainer
Definition of the current "pfo container version".
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
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Helper to simultaneously calculate sin and cos of the same angle.
Helper to simultaneously calculate sin and cos of the same angle.
Definition sincos.h:39
Implements a loop over tracks and pflow object to build UFOs.
Definition TCCHelpers.h:34
const SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > * m_linkdecorkey
Definition TCCHelpers.h:49
const CP::ITrackVertexAssociationTool * m_trackVertexAssoTool
Definition TCCHelpers.h:46
virtual void combinedUFOLoop(const TrackCaloClusterInfo *tccInfo, const xAOD::FlowElementContainer *pfos)
Definition TCCHelpers.h:54
Implement a concrete CombinedUFOLoop dedicated to building UFO see TCCHelpers.h in TrackCaloClusterRe...
virtual void processTrk(const xAOD::TrackParticle *trk)
std::vector< ElementLink< xAOD::FlowElementContainer > > m_pfoLinks
xAOD::FlowElementContainer * m_tccContainer
const TrackCaloClusterInfo * m_tccInfo
const xAOD::FlowElementContainer * m_pfoContainer
virtual void processPFO(const xAOD::TrackParticle *trk, const xAOD::FlowElement *pfo)
Holds all the necessary information to build TrackCaloCluster objects.
std::map< const xAOD::TrackParticle *, FourMom_t > trackTotalClusterPt
std::map< const xAOD::IParticle *, FourMom_t > clusterToTracksWeightMap
const xAOD::Vertex * pv0
const xAOD::TrackParticleContainer * allTracks
const xAOD::CaloClusterContainer * allClusters