ATLAS Offline Software
Loading...
Searching...
No Matches
PFUnifiedMatchingTruthTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "PFData.h"
7
8#include "eflowCaloObject.h"
12#include "eflowRecTrack.h"
15#include "PFClusterFiller.h"
16#include "PFTrackFiller.h"
17
22
23using namespace eflowSubtract;
24
25
27= default;
28
30{
31
32 ATH_CHECK(m_theEOverPTool.retrieve());
33
34 ATH_CHECK(m_theEOverPTool->fillBinnedParameters(m_binnedParameters.get()));
35
37 if (!m_trkpos)
38 {
39 ATH_MSG_ERROR("Failed to get TrackPositionProvider for cluster preselection!");
40 return StatusCode::FAILURE;
41 }
42
43 //Retrieve track-cluster matching tools
44 ATH_CHECK(m_theMatchingTool.retrieve());
47
48
51 }
52
53 return StatusCode::SUCCESS;
54
55}
56
57unsigned int PFUnifiedMatchingTruthTool::matchAndCreateEflowCaloObj(const EventContext& ctx, PFData &data) const{
58
59 //Counts up how many tracks found at least 1 calorimeter cluster matched to it.
60 unsigned int nMatches(0);
61
62 /* Cache the original number of eflowCaloObjects, if there were any */
63 const unsigned int nCaloObj = data.caloObjects->size();
64
65 /* loop tracks in data.tracks and do matching */
66 for (auto *thisEfRecTrack : data.tracks)
67 {
69 if (!thisEfRecTrack->hasBin()) {
70 std::unique_ptr<eflowCaloObject> thisEflowCaloObject = std::make_unique<eflowCaloObject>();
71 thisEflowCaloObject->addTrack(thisEfRecTrack);
72 data.caloObjects->push_back(std::move(thisEflowCaloObject));
73 continue;
74 }
75
76 if (msgLvl(MSG::DEBUG))
77 {
78 const xAOD::TrackParticle *track = thisEfRecTrack->getTrack();
79 ATH_MSG_DEBUG("Matching track with e,pt, eta and phi " << track->e() << ", " << track->pt() << ", " << track->eta() << " and " << track->phi());
80 }
81
82 std::vector<eflowTrackClusterLink*> bestClusters;
83 std::vector<float> deltaRPrime;
84
85
86 const xAOD::TruthParticle* trackMatchedTruthParticle = nullptr;
88
89 const static SG::AuxElement::Accessor<TruthLink> truthLinkAccessor("truthParticleLink");
90
91 TruthLink truthLink = truthLinkAccessor(*(thisEfRecTrack->getTrack()));
92 //if not valid don't print a WARNING because this is an expected condition as discussed here:
93 //https://indico.cern.ch/event/795039/contributions/3391771/attachments/1857138/3050771/TruthTrackFTAGWS.pdf
94 if (truthLink.isValid()) trackMatchedTruthParticle = *truthLink;
95
96 if (trackMatchedTruthParticle){
97 double uniqueID = HepMC::uniqueID(trackMatchedTruthParticle);
98
100 if (!caloClusterReadDecorHandleNLeadingTruthParticles.isValid()){
101 ATH_MSG_WARNING("Failed to retrieve CaloCluster decoration with key " << caloClusterReadDecorHandleNLeadingTruthParticles.key());
102 }
103
104 for (auto * thisCluster : data.clusters){
105 //accessor for decoration
106 //split key into substring to get the name of the decoration
107
108 std::string decorHandleName = m_caloClusterReadDecorHandleKeyNLeadingTruthParticles.key();
109 std::string::size_type pos = decorHandleName.find(".");
110 std::string decorName = decorHandleName.substr(pos+1);
111
112 SG::AuxElement::Accessor< std::vector< std::pair<unsigned int, double> > > accessor(decorName);
113
114 std::vector<std::pair<unsigned int, double > > uniqueIDTruthPairs = accessor(*(thisCluster->getCluster()));
115
116 for (auto &uniqueIDTruthPair : uniqueIDTruthPairs){
117 if (uniqueIDTruthPair.first == uniqueID){
118 eflowTrackClusterLink* thisLink = eflowTrackClusterLink::getInstance(thisEfRecTrack, thisCluster, ctx);
119 bestClusters.push_back(thisLink);
120 break;
121 }
122 }//loop over calocluster truth pair decorations
123 }//loop over caloclusters
124
125 }//if have truth particle matched to track
126 else ATH_MSG_VERBOSE("Track with pt, eta and phi " << thisEfRecTrack->getTrack()->pt() << ", " << thisEfRecTrack->getTrack()->eta() << " and " << thisEfRecTrack->getTrack()->phi() << " does not have a valid truth pointer");
127
128
129
130 if (bestClusters.empty()) continue;
131
132 if (msgLvl(MSG::DEBUG))
133 {
134 for (auto *thisClusterLink : bestClusters ) {
135 xAOD::CaloCluster* thisCluster = thisClusterLink->getCluster()->getCluster();
136 ATH_MSG_DEBUG("Matched this track to cluster with e,pt, eta and phi " << thisCluster->e() << ", " << thisCluster->pt() << ", " << thisCluster->eta() << " and " << thisCluster->phi());
137 }
138 }
139
140 nMatches++;
141
142 //loop over the matched calorimeter clusters and associate tracks and clusters to each other as needed.
143 for (auto *trkClusLink : bestClusters){
144
145 eflowRecCluster *thisEFRecCluster = trkClusLink->getCluster();
146
148 // Look up whether this cluster is intended for recovery
149 if (std::find(data.clusters.begin(), data.clusters.end(), trkClusLink->getCluster()) == data.clusters.end()) {
150 continue;
151 }
152 }
153
154 eflowTrackClusterLink *trackClusterLink = eflowTrackClusterLink::getInstance(thisEfRecTrack, thisEFRecCluster, ctx);
155 thisEfRecTrack->addClusterMatch(trackClusterLink);
156
157 thisEFRecCluster->addTrackMatch(trackClusterLink);
158 }
159 }
160
161 /* Create 3 types eflowCaloObjects: track-only, cluster-only, track-cluster-link */
162 std::vector<eflowRecCluster *> clusters(data.clusters.begin(), data.clusters.end());
163 if (m_recoverSplitShowers) std::sort(clusters.begin(), clusters.end(), eflowRecCluster::SortDescendingPt());
164 unsigned int nCaloObjects = eflowCaloObjectMaker::makeTrkCluCaloObjects(data.tracks, clusters, data.caloObjects);
165 ATH_MSG_DEBUG("Created " << nCaloObjects << " eflowCaloObjects.");
166 if (msgLvl(MSG::DEBUG)){
167 for (auto thisEFlowCaloObject : *(data.caloObjects)){
168 ATH_MSG_DEBUG("This eflowCaloObject has " << thisEFlowCaloObject->nTracks() << " tracks and " << thisEFlowCaloObject->nClusters() << " clusters ");
169 for (unsigned int count = 0; count < thisEFlowCaloObject->nTracks(); count++){
170 const xAOD::TrackParticle* thisTrack = thisEFlowCaloObject->efRecTrack(count)->getTrack();
171 ATH_MSG_DEBUG("Have track with e, pt, eta and phi of " << thisTrack->e() << ", " << thisTrack->pt() << ", " << thisTrack->eta() << " and " << thisTrack->phi());
172 }
173 for (unsigned int count = 0; count < thisEFlowCaloObject->nClusters(); count++){
174 const xAOD::CaloCluster* thisCluster = thisEFlowCaloObject->efRecCluster(count)->getCluster();
175 ATH_MSG_DEBUG("Have cluster with e, pt, eta and phi of " << thisCluster->e() << ", " << thisCluster->pt() << ", " << thisCluster->eta() << " and " << thisCluster->phi());
176 }
177 }
178 }
179
180 if (!m_recoverSplitShowers) return nMatches;
181 else return nCaloObj;
182}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading a decoration on an object.
ElementLink< xAOD::TruthParticleContainer > TruthLink
static std::unique_ptr< IPositionProvider > Get(const std::string &positionType)
ToolHandle< PFTrackClusterMatchingTool > m_theMatchingToolForPull_015
Gaudi::Property< bool > m_recoverSplitShowers
Toggle whether we are recovering split showers or not.
ToolHandle< IEFlowCellEOverPTool > m_theEOverPTool
Tool for getting e/p values and hadronic shower cell ordering principle parameters.
ToolHandle< PFTrackClusterMatchingTool > m_theMatchingToolForPull_02
std::unique_ptr< eflowEEtaBinnedParameters > m_binnedParameters
std::unique_ptr< PFMatch::TrackEtaPhiInFixedLayersProvider > m_trkpos
Track position provider to be used to preselect clusters.
ToolHandle< PFTrackClusterMatchingTool > m_theMatchingTool
Default track-cluster matching tool.
virtual StatusCode initialize() override
SG::ReadDecorHandleKey< xAOD::CaloClusterContainer > m_caloClusterReadDecorHandleKeyNLeadingTruthParticles
Read handle key to decorate CaloCluster with threeN leading truth particle uniqueID and energy.
unsigned int matchAndCreateEflowCaloObj(const EventContext &ctx, PFData &data) const override
This matches ID tracks and CaloClusters, and then creates eflowCaloObjects.
Handle class for reading a decoration on an object.
static unsigned int makeTrkCluCaloObjects(eflowRecTrackContainer *eflowTrackContainer, eflowRecClusterContainer *eflowClusterContainer, eflowCaloObjectContainer *caloObjectContainer)
This class extends the information about a xAOD::CaloCluster.
void addTrackMatch(eflowTrackClusterLink *trackMatch)
xAOD::CaloCluster * getCluster()
virtual double pt() const
The transverse momentum ( ) of the particle (negative for negative-energy clusters).
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 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.
virtual double e() const override final
The total energy of the particle.
static std::string release
Definition computils.h:50
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
int uniqueID(const T &p)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthParticle_v1 TruthParticle
Typedef to implementation.