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 */
67 const SG::AuxElement::Accessor<TruthLink> truthLinkAccessor("truthParticleLink");
68 for (auto *thisEfRecTrack : data.tracks)
69 {
71 if (!thisEfRecTrack->hasBin()) {
72 std::unique_ptr<eflowCaloObject> thisEflowCaloObject = std::make_unique<eflowCaloObject>();
73 thisEflowCaloObject->addTrack(thisEfRecTrack);
74 data.caloObjects->push_back(std::move(thisEflowCaloObject));
75 continue;
76 }
77
78 if (msgLvl(MSG::DEBUG))
79 {
80 const xAOD::TrackParticle *track = thisEfRecTrack->getTrack();
81 ATH_MSG_DEBUG("Matching track with e,pt, eta and phi " << track->e() << ", " << track->pt() << ", " << track->eta() << " and " << track->phi());
82 }
83
84 std::vector<eflowTrackClusterLink*> bestClusters;
85 std::vector<float> deltaRPrime;
86
87
88 const xAOD::TruthParticle* trackMatchedTruthParticle = nullptr;
89
90
91
92 TruthLink truthLink = truthLinkAccessor(*(thisEfRecTrack->getTrack()));
93 //if not valid don't print a WARNING because this is an expected condition as discussed here:
94 //https://indico.cern.ch/event/795039/contributions/3391771/attachments/1857138/3050771/TruthTrackFTAGWS.pdf
95 if (truthLink.isValid()) trackMatchedTruthParticle = *truthLink;
96
97 if (trackMatchedTruthParticle){
98 double uniqueID = HepMC::uniqueID(trackMatchedTruthParticle);
99
101 if (!caloClusterReadDecorHandleNLeadingTruthParticles.isValid()){
102 ATH_MSG_WARNING("Failed to retrieve CaloCluster decoration with key " << caloClusterReadDecorHandleNLeadingTruthParticles.key());
103 }
104
105 for (auto * thisCluster : data.clusters){
106 //accessor for decoration
107 //split key into substring to get the name of the decoration
108
109 std::string decorHandleName = m_caloClusterReadDecorHandleKeyNLeadingTruthParticles.key();
110 std::string::size_type pos = decorHandleName.find(".");
111 std::string decorName = decorHandleName.substr(pos+1);
112
113 SG::AuxElement::Accessor< std::vector< std::pair<unsigned int, double> > > accessor(decorName);
114
115 std::vector<std::pair<unsigned int, double > > uniqueIDTruthPairs = accessor(*(thisCluster->getCluster()));
116
117 for (auto &uniqueIDTruthPair : uniqueIDTruthPairs){
118 if (uniqueIDTruthPair.first == uniqueID){
119 eflowTrackClusterLink* thisLink = eflowTrackClusterLink::getInstance(thisEfRecTrack, thisCluster, ctx);
120 bestClusters.push_back(thisLink);
121 break;
122 }
123 }//loop over calocluster truth pair decorations
124 }//loop over caloclusters
125
126 }//if have truth particle matched to track
127 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");
128
129
130
131 if (bestClusters.empty()) continue;
132
133 if (msgLvl(MSG::DEBUG))
134 {
135 for (auto *thisClusterLink : bestClusters ) {
136 xAOD::CaloCluster* thisCluster = thisClusterLink->getCluster()->getCluster();
137 ATH_MSG_DEBUG("Matched this track to cluster with e,pt, eta and phi " << thisCluster->e() << ", " << thisCluster->pt() << ", " << thisCluster->eta() << " and " << thisCluster->phi());
138 }
139 }
140
141 nMatches++;
142
143 //loop over the matched calorimeter clusters and associate tracks and clusters to each other as needed.
144 for (auto *trkClusLink : bestClusters){
145
146 eflowRecCluster *thisEFRecCluster = trkClusLink->getCluster();
147
149 // Look up whether this cluster is intended for recovery
150 if (std::find(data.clusters.begin(), data.clusters.end(), trkClusLink->getCluster()) == data.clusters.end()) {
151 continue;
152 }
153 }
154
155 eflowTrackClusterLink *trackClusterLink = eflowTrackClusterLink::getInstance(thisEfRecTrack, thisEFRecCluster, ctx);
156 thisEfRecTrack->addClusterMatch(trackClusterLink);
157
158 thisEFRecCluster->addTrackMatch(trackClusterLink);
159 }
160 }
161
162 /* Create 3 types eflowCaloObjects: track-only, cluster-only, track-cluster-link */
163 std::vector<eflowRecCluster *> clusters(data.clusters.begin(), data.clusters.end());
164 if (m_recoverSplitShowers) std::sort(clusters.begin(), clusters.end(), eflowRecCluster::SortDescendingPt());
165 unsigned int nCaloObjects = eflowCaloObjectMaker::makeTrkCluCaloObjects(data.tracks, clusters, data.caloObjects);
166 ATH_MSG_DEBUG("Created " << nCaloObjects << " eflowCaloObjects.");
167 if (msgLvl(MSG::DEBUG)){
168 for (auto thisEFlowCaloObject : *(data.caloObjects)){
169 ATH_MSG_DEBUG("This eflowCaloObject has " << thisEFlowCaloObject->nTracks() << " tracks and " << thisEFlowCaloObject->nClusters() << " clusters ");
170 for (unsigned int count = 0; count < thisEFlowCaloObject->nTracks(); count++){
171 const xAOD::TrackParticle* thisTrack = thisEFlowCaloObject->efRecTrack(count)->getTrack();
172 ATH_MSG_DEBUG("Have track with e, pt, eta and phi of " << thisTrack->e() << ", " << thisTrack->pt() << ", " << thisTrack->eta() << " and " << thisTrack->phi());
173 }
174 for (unsigned int count = 0; count < thisEFlowCaloObject->nClusters(); count++){
175 const xAOD::CaloCluster* thisCluster = thisEFlowCaloObject->efRecCluster(count)->getCluster();
176 ATH_MSG_DEBUG("Have cluster with e, pt, eta and phi of " << thisCluster->e() << ", " << thisCluster->pt() << ", " << thisCluster->eta() << " and " << thisCluster->phi());
177 }
178 }
179 }
180
181 if (!m_recoverSplitShowers) return nMatches;
182 else return nCaloObj;
183}
#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.