ATLAS Offline Software
Loading...
Searching...
No Matches
PFUnifiedMatchingTool.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
23
24#include <sstream>
25
26using namespace eflowSubtract;
27
28PFUnifiedMatchingTool::PFUnifiedMatchingTool(const std::string &type, const std::string &name, const IInterface *parent) : base_class(type, name, parent),
32
34= default;
35
37{
38
39 ATH_CHECK(m_theEOverPTool.retrieve());
40
41 ATH_CHECK(m_theEOverPTool->fillBinnedParameters(m_binnedParameters.get()));
42
44 if (!m_trkpos)
45 {
46 ATH_MSG_ERROR("Failed to get TrackPositionProvider for cluster preselection!");
47 return StatusCode::FAILURE;
48 }
49
50 //Retrieve track-cluster matching tools
51 ATH_CHECK(m_theMatchingTool.retrieve());
53
54 return StatusCode::SUCCESS;
55
56}
57
59 const EventContext& ctx,
60 PFData &data
61) const
62{
63
64 if (!data.caloObjects) {
65 ATH_MSG_ERROR("PFData::caloObjects is null; caller must set it before invoking the matching tool");
66 return StatusCode::FAILURE;
67 }
68
69 ATH_MSG_DEBUG("Executing");
70
72 // reset tracks in data and refill only with those needed for split showers
73 data.tracks.clear();
75 }
76
78 // reset clusters in data and refill only with those needed for split showers
79 data.clusters.clear();
81 }
82
83 ATH_MSG_DEBUG("This event has " << data.tracks.size() << " tracks " << data.clusters.size() << " clusters ");
84
85 if (msgLvl(MSG::DEBUG)) printAllClusters(data.clusters);
86
87 unsigned int numMatches = matchAndCreateEflowCaloObj(ctx, data);
88
89 // store numMatches for later use in subtraction tool
90 if (m_recoverSplitShowers) data.nOrigCaloObj = numMatches;
91 else data.nMatches = numMatches;
92
93
94 return StatusCode::SUCCESS;
95}
96
97unsigned int PFUnifiedMatchingTool::matchAndCreateEflowCaloObj(const EventContext& ctx, PFData &data) const{
98
99 //Counts up how many tracks found at least 1 calorimeter cluster matched to it.
100 unsigned int nMatches(0);
101
102 /* Cache the original number of eflowCaloObjects, if there were any */
103 const unsigned int nCaloObj = data.caloObjects->size();
104
105 /* loop tracks in data.tracks and do matching */
106 for (auto *thisEfRecTrack : data.tracks)
107 {
109 if (!thisEfRecTrack->hasBin()) {
110 std::unique_ptr<eflowCaloObject> thisEflowCaloObject = std::make_unique<eflowCaloObject>();
111 thisEflowCaloObject->addTrack(thisEfRecTrack);
112 data.caloObjects->push_back(std::move(thisEflowCaloObject));
113 continue;
114 }
115
116 if (msgLvl(MSG::DEBUG))
117 {
118 const xAOD::TrackParticle *track = thisEfRecTrack->getTrack();
119 ATH_MSG_DEBUG("Matching track with e,pt, eta and phi " << track->e() << ", " << track->pt() << ", " << track->eta() << " and " << track->phi());
120 }
121
122 std::vector<eflowTrackClusterLink*> bestClusters;
123 std::vector<float> deltaRPrime;
124
130 std::vector<std::pair<eflowRecCluster *, float>> bestClusters_02 = m_theMatchingToolForPull_02->doMatches(thisEfRecTrack, data.clusters, -1);
131 for (auto &matchpair : bestClusters_02)
132 {
133 eflowRecCluster *theCluster = matchpair.first;
134 float distancesq = matchpair.second;
135 eflowTrackClusterLink *trackClusterLink = eflowTrackClusterLink::getInstance(thisEfRecTrack, theCluster, ctx);
136 if (distancesq < 0.15 * 0.15)
137 {
138 // Narrower cone is a subset of the selected clusters
139 // Distance returned is deltaR^2
140 static const std::string cone15Str{"cone_015"};
141 thisEfRecTrack->addAlternativeClusterMatch(trackClusterLink, cone15Str);
142 }
143 static const std::string cone2Str{"cone_02"};
144 thisEfRecTrack->addAlternativeClusterMatch(trackClusterLink, cone2Str);
145 }//loop over bestClusters_02
146
147 //This matching scheme is used to match the calorimeter cluster(s) to be used in the charged showers subtraction for this track.
148 std::vector<std::pair<eflowRecCluster *, float>> matchedClusters = m_theMatchingTool->doMatches(thisEfRecTrack, data.clusters,m_nClusterMatchesToUse);
149 for (auto thePair : matchedClusters) {
150 bestClusters.push_back(eflowTrackClusterLink::getInstance(thisEfRecTrack, thePair.first, ctx));
151 if (m_addCPData) deltaRPrime.push_back(std::sqrt(thePair.second));
152 }
153 }
154 else {
155 const std::vector<eflowTrackClusterLink*>* matchedClusters_02 = thisEfRecTrack->getAlternativeClusterMatches("cone_02");
156 if (!matchedClusters_02) continue;
157 else bestClusters = *matchedClusters_02;
158 }
159
160 if (bestClusters.empty()) continue;
161
162 if (msgLvl(MSG::DEBUG))
163 {
164 for (auto *thisClusterLink : bestClusters ) {
165 xAOD::CaloCluster* thisCluster = thisClusterLink->getCluster()->getCluster();
166 ATH_MSG_DEBUG("Matched this track to cluster with e,pt, eta and phi " << thisCluster->e() << ", " << thisCluster->pt() << ", " << thisCluster->eta() << " and " << thisCluster->phi());
167 }
168 }
169
170 nMatches++;
171
172 //loop over the matched calorimeter clusters and associate tracks and clusters to each other as needed.
173 unsigned int linkIndex = 0;
174 for (auto *trkClusLink : bestClusters){
175
176 eflowRecCluster *thisEFRecCluster = trkClusLink->getCluster();
177
179 // Look up whether this cluster is intended for recovery
180 if (std::find(data.clusters.begin(), data.clusters.end(), trkClusLink->getCluster()) == data.clusters.end()) {
181 linkIndex++;
182 continue;
183 }
184 }
185
186 eflowTrackClusterLink *trackClusterLink = eflowTrackClusterLink::getInstance(thisEfRecTrack, thisEFRecCluster, ctx);
187 thisEfRecTrack->addClusterMatch(trackClusterLink);
188 if (m_addCPData) {
189 thisEfRecTrack->addDeltaRPrime(deltaRPrime[linkIndex]);
190 }
191 thisEFRecCluster->addTrackMatch(trackClusterLink);
192 }
193 linkIndex++;
194 }
195
196 /* Create 3 types eflowCaloObjects: track-only, cluster-only, track-cluster-link */
197 std::vector<eflowRecCluster *> clusters(data.clusters.begin(), data.clusters.end());
198 if (m_recoverSplitShowers) std::sort(clusters.begin(), clusters.end(), eflowRecCluster::SortDescendingPt());
199 unsigned int nCaloObjects = eflowCaloObjectMaker::makeTrkCluCaloObjects(data.tracks, clusters, data.caloObjects);
200 ATH_MSG_DEBUG("Created " << nCaloObjects << " eflowCaloObjects.");
201 if (msgLvl(MSG::DEBUG)){
202 for (auto thisEFlowCaloObject : *(data.caloObjects)){
203 ATH_MSG_DEBUG("This eflowCaloObject has " << thisEFlowCaloObject->nTracks() << " tracks and " << thisEFlowCaloObject->nClusters() << " clusters ");
204 for (unsigned int count = 0; count < thisEFlowCaloObject->nTracks(); count++){
205 const xAOD::TrackParticle* thisTrack = thisEFlowCaloObject->efRecTrack(count)->getTrack();
206 ATH_MSG_DEBUG("Have track with e, pt, eta and phi of " << thisTrack->e() << ", " << thisTrack->pt() << ", " << thisTrack->eta() << " and " << thisTrack->phi());
207 }
208 for (unsigned int count = 0; count < thisEFlowCaloObject->nClusters(); count++){
209 const xAOD::CaloCluster* thisCluster = thisEFlowCaloObject->efRecCluster(count)->getCluster();
210 ATH_MSG_DEBUG("Have cluster with e, pt, eta and phi of " << thisCluster->e() << ", " << thisCluster->pt() << ", " << thisCluster->eta() << " and " << thisCluster->phi());
211 }
212 }
213 }
214
215 if (!m_recoverSplitShowers) return nMatches;
216 else return nCaloObj;
217}
218
219
221 std::stringstream result;
222 result << " track with E, eta and phi "<< track->e() << ", " << track->eta() << " and " << track->phi();
223 return result.str();
224}
225
227 std::stringstream result;
228 result << " cluster with E, eta and phi of " << cluster->e() << ", " << cluster->eta() << " and " << cluster->phi();
229 return result.str();
230}
231
232void PFUnifiedMatchingTool::printAllClusters(const std::vector<eflowRecCluster *>& recClusterVector) const {
233
234 for ( const auto *thisEFRecCluster : recClusterVector){
235 if (thisEFRecCluster->getTrackMatches().empty()) {
236 ATH_MSG_DEBUG("Isolated" << printCluster(thisEFRecCluster->getCluster()));
237 } else {
238 ATH_MSG_DEBUG("Matched" << printCluster(thisEFRecCluster->getCluster()));
239 std::vector<eflowTrackClusterLink*> theTrackLinks = thisEFRecCluster->getTrackMatches();
240 for ( auto *thisTrack : theTrackLinks){
241 ATH_MSG_DEBUG("Matched" << printTrack(thisTrack->getTrack()->getTrack()));
242 }
243 }
244 }
245}
246
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
Handle class for reading a decoration on an object.
static void fillClustersToRecover(PFData &data)
static std::unique_ptr< IPositionProvider > Get(const std::string &positionType)
static void fillTracksToRecover(PFData &data)
virtual StatusCode processPFlowData(const EventContext &ctx, PFData &thePFData) const override
static std::string printTrack(const xAOD::TrackParticle *track)
PFUnifiedMatchingTool(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< bool > m_recoverSplitShowers
Toggle whether we are recovering split showers or not.
Gaudi::Property< int > m_nClusterMatchesToUse
Number of clusters to match to each track if not doing recover split shower subtraction.
void printAllClusters(const std::vector< eflowRecCluster * > &recClusterVector) const
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
static std::string printCluster(const xAOD::CaloCluster *cluster)
virtual StatusCode initialize() override
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.
Gaudi::Property< bool > m_addCPData
Toggle whether to decorate eflowRecTrack with additional data for Combined Performance studies.
virtual unsigned int matchAndCreateEflowCaloObj(const EventContext &ctx, PFData &data) const
This matches ID tracks and CaloClusters, and then creates eflowCaloObjects.
static unsigned int makeTrkCluCaloObjects(eflowRecTrackContainer *eflowTrackContainer, eflowRecClusterContainer *eflowClusterContainer, eflowCaloObjectContainer *caloObjectContainer)
Inherits from eflowEEtaBinBase.
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:54
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
STL namespace.
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: