ATLAS Offline Software
Loading...
Searching...
No Matches
TauPi0ClusterScaler.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
8
9#include <vector>
10#include <map>
11
12
14 TauRecToolBase(name) {
15}
16
17
19 const EventContext& /*ctx*/,
20 xAOD::PFOContainer& neutralPFOContainer,
21 xAOD::PFOContainer& chargedPFOContainer) const {
22
23 // Clear vector of cell-based charged PFO Links, which are required when running xAOD
24 tau.clearProtoChargedPFOLinks();
25
26 // Only run on 1-5 prong taus
27 if (tau.nTracks() == 0 or tau.nTracks() >5) {
28 return StatusCode::SUCCESS;
29 }
30
31 ATH_MSG_DEBUG("Process a new tau candidate, addreess " << &tau
32 << ", e: " << tau.pt()
33 << ", eta: " << tau.eta()
34 << ", pt: " << tau.pt());
35
36 // Create new proto charged PFOs
37 createChargedPFOs(tau, chargedPFOContainer);
38
39 // Associate hadronic PFOs to charged PFOs using extrapolated positions in HCal
40 associateHadronicToChargedPFOs(tau, chargedPFOContainer);
41
42 // Associate charged PFOs to neutral PFOs using extrapolated positions in ECal
43 associateChargedToNeutralPFOs(tau, neutralPFOContainer);
44
45 // Estimate charged PFO EM energy and subtract from neutral PFOs
46 subtractChargedEnergyFromNeutralPFOs(tau, neutralPFOContainer);
47
48 for (xAOD::PFO* pfo : neutralPFOContainer) {
49 ATH_MSG_DEBUG("Final Neutral PFO, address " << pfo
50 << ", e: " << pfo->pt()
51 << ", eta: " << pfo->eta()
52 << ", pt: " << pfo->pt());
53 }
54
55 return StatusCode::SUCCESS;
56}
57
58
59
61 std::vector<ElementLink<xAOD::IParticleContainer>> emptyLinks;
62
63 for (xAOD::PFO* pfo : pfoContainer) {
64 pfo->setAssociatedParticleLinks(type, emptyLinks);
65 }
66}
67
68
69
71 for (const auto& tauTrackLink : tau.tauTrackLinks(xAOD::TauJetParameters::classifiedCharged)) {
72 if (not tauTrackLink.isValid()) {
73 ATH_MSG_WARNING("Invalid tauTrackLink");
74 continue;
75 }
76 const xAOD::TauTrack* tauTrack = (*tauTrackLink);
77
78 // Create charged PFO
79 xAOD::PFO* chargedPFO = new xAOD::PFO();
80 chargedPFOContainer.push_back(chargedPFO);
81
82 // Set properties
83 chargedPFO->setCharge(tauTrack->track()->charge());
84 chargedPFO->setP4(tauTrack->p4());
85
86 // Link to track
87 if (not chargedPFO->setTrackLink(tauTrack->trackLinks().at(0))) {
88 ATH_MSG_WARNING("Could not add Track to PFO");
89 }
90
91 // FIXME: Better to change xAOD::PFODetails::CaloCluster, it is confusing
92 if (not chargedPFO->setAssociatedParticleLink(xAOD::PFODetails::CaloCluster, tauTrackLink)) {
93 ATH_MSG_WARNING("Could not add TauTrack to PFO");
94 }
95
96 tau.addProtoChargedPFOLink(ElementLink<xAOD::PFOContainer>(chargedPFO, chargedPFOContainer));
97 }
98}
99
100
101
103 float position = -10.0;
104
105 // Obtain the associated TauTrack
106 std::vector<const xAOD::IParticle*> tauTrackParticles;
107 // FIXME: The type here is confusing
108 chargedPFO.associatedParticles(xAOD::PFODetails::CaloCluster, tauTrackParticles);
109 if (tauTrackParticles.empty()) {
110 ATH_MSG_WARNING("ChargedPFO has no associated TauTrack, will set -10.0 to " << detail);
111 return -10.0;
112 }
113
114 const xAOD::TauTrack* tauTrack = dynamic_cast<const xAOD::TauTrack*>(tauTrackParticles.at(0));
115 if (not tauTrack) {
116 ATH_MSG_WARNING("Failed to retrieve TauTrack from ChargedPFO, will set -10.0 to " << detail);
117 return -10.0;
118 }
119
120 if( not tauTrack->detail(detail, position)) {
121 ATH_MSG_WARNING("Failed to retrieve extrapolated chargedPFO position, will set -10.0 to " << detail);
122 return -10.0;
123 }
124
125 return position;
126}
127
128
129
131 std::map< xAOD::PFO*,std::vector< ElementLink< xAOD::IParticleContainer > > > linkMap;
132
133 // For each hadronic PFO, associate it to the closest charged PFO. It assumes that one hadronic PFO comes from at
134 // most one charged PFO.
135 for (const auto& hadPFOLink : tau.hadronicPFOLinks()) {
136 if (not hadPFOLink.isValid()) {
137 ATH_MSG_WARNING("Invalid hadPFOLink");
138 continue;
139 }
140 ATH_MSG_DEBUG("hadPFO " << hadPFOLink.index() << ", eta: " << (*hadPFOLink)->eta() << ", phi: " << (*hadPFOLink)->phi() );
141
142 // Assign hadPFO to closest extrapolated chargedPFO track within dR < 0.4
143 xAOD::PFO* chargedPFOMatch = nullptr;
144 float dRmin = 0.4;
145
146 for(size_t i=0; i<tau.nProtoChargedPFOs(); i++) {
147 xAOD::PFO* chargedPFO = chargedPFOContainer.at( tau.protoChargedPFO(i)->index() );
148
151
152 float dR = xAOD::P4Helpers::deltaR((**hadPFOLink), etaCalo, phiCalo, false);
153 if (dR < dRmin){
154 dRmin = dR;
155 chargedPFOMatch = chargedPFO;
156 }
157 }
158
159 if( not chargedPFOMatch ){
160 ATH_MSG_DEBUG("Unassigned Hadronic PFO");
161 continue;
162 }
163
164 // create link to had PFO (add to chargedPFO later)
165 ElementLink< xAOD::IParticleContainer > newHadLink( hadPFOLink.dataID(), hadPFOLink.index() );
166 if (not newHadLink.isValid()){
167 ATH_MSG_WARNING("Created an invalid element link to xAOD::PFO");
168 continue;
169 }
170
171 if( not linkMap.count(chargedPFOMatch) ) {
172 linkMap[chargedPFOMatch] = std::vector< ElementLink< xAOD::IParticleContainer > >();
173 }
174
175 linkMap[chargedPFOMatch].push_back(newHadLink);
176 }
177
178 // finally set hadronic PFO links (note: we use existing TauShot enum)
179 for (auto [k,v] : linkMap) {
180 if(not k->setAssociatedParticleLinks(xAOD::PFODetails::TauShot, v))
181 ATH_MSG_WARNING("Couldn't add hadronic PFO links to charged PFO!");
182 }
183}
184
185
186
188 std::map< xAOD::PFO*,std::vector< ElementLink< xAOD::IParticleContainer > > > linkMap;
189 for (const auto& chargedPFOLink : tau.protoChargedPFOLinks()) {
190 if (not chargedPFOLink.isValid()) {
191 ATH_MSG_WARNING("Invalid protoChargedPFOLink");
192 continue;
193 }
194 const xAOD::PFO* chargedPFO = (*chargedPFOLink);
195
198
199 // Assign extrapolated chargedPFO to closest neutralPFO within dR<0.04
200 xAOD::PFO* neutralPFOMatch = nullptr;
201
202 float dRmin = m_maxDeltaRNeutralCharged;
203 for(size_t i=0; i<tau.nProtoNeutralPFOs(); i++) {
204 xAOD::PFO* neutralPFO = neutralPFOContainer.at( tau.protoNeutralPFO(i)->index() );
205
206 // FIXME: cluster p4 is not corrected to the tau axis
207 float dR = xAOD::P4Helpers::deltaR((*neutralPFO->cluster(0)), etaCalo, phiCalo, false);
208 if (dR < dRmin){
209 dRmin = dR;
210 neutralPFOMatch = neutralPFO;
211 }
212 }
213
214 if (not neutralPFOMatch){
215 ATH_MSG_DEBUG("Unassigned Charged PFO");
216 continue;
217 }
218
219 // create link to charged PFO
220 ElementLink<xAOD::IParticleContainer> newChargedLink( chargedPFOLink.dataID(), chargedPFOLink.index() );
221 if (not newChargedLink.isValid()){
222 ATH_MSG_WARNING("Created an invalid element link to xAOD::PFO");
223 continue;
224 }
225
226 if( not linkMap.count(neutralPFOMatch) ) {
227 linkMap[neutralPFOMatch] = std::vector< ElementLink< xAOD::IParticleContainer > >();
228 }
229
230 linkMap[neutralPFOMatch].push_back(newChargedLink);
231 }
232
233 // Finally set charged PFO links,
234 for (auto [k,v] : linkMap) {
235 if(not k->setAssociatedParticleLinks(xAOD::PFODetails::Track,v)) {
236 ATH_MSG_WARNING("Couldn't add charged PFO links to neutral PFO!");
237 }
238 }
239}
240
241
242
244
245 for(size_t i=0; i<tau.nProtoNeutralPFOs(); i++) {
246 xAOD::PFO* neutralPFO = neutralPFOContainer.at( tau.protoNeutralPFO(i)->index() );
247
248 // Get associated charged PFOs
249 std::vector<const xAOD::IParticle*> chargedPFOs;
250 neutralPFO->associatedParticles(xAOD::PFODetails::Track, chargedPFOs);
251 if (chargedPFOs.empty()) {
252 ATH_MSG_DEBUG("No associated charged to subtract");
253 continue;
254 }
255 ATH_MSG_DEBUG("Associated charged PFOs: " << chargedPFOs.size() );
256
257 // estimate charged EM energy and subtract
258 float neutralEnergy = neutralPFO->e();
259 for (const xAOD::IParticle* chargedParticle : chargedPFOs) {
260 const xAOD::PFO* chargedPFO = dynamic_cast<const xAOD::PFO*>(chargedParticle);
261 if( not chargedPFO ){
262 ATH_MSG_WARNING("Failed to downcast IParticle ptr: " << chargedParticle << ", to ChargedPFO! " );
263 continue;
264 }
265 float chargedEMEnergy = chargedPFO->e();
266
267 std::vector<const xAOD::IParticle*> hadPFOs;
269 for (const auto *hadPFO : hadPFOs) {
270 chargedEMEnergy -= hadPFO->e();
271 }
272
273 if( chargedEMEnergy < 0.0 ) chargedEMEnergy = 0.0;
274 neutralEnergy -= chargedEMEnergy;
275 ATH_MSG_DEBUG("Subtracting charged energy: " << chargedEMEnergy );
276 }
277 float neutralPt = neutralEnergy / std::cosh(neutralPFO->eta());
278 if (neutralPt <= m_minNeutralPFOPt) neutralPt = m_minNeutralPFOPt;
279
280 ATH_MSG_DEBUG("Neutral PFO pt, original: " << neutralPFO->pt() << " subtracted: " << neutralPt);
281 neutralPFO->setP4(neutralPt , neutralPFO->eta(), neutralPFO->phi(), neutralPFO->m());
282 }
283}
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
const T * at(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
void createChargedPFOs(xAOD::TauJet &pTau, xAOD::PFOContainer &pChargedPFOContainer) const
create charged PFOs
void clearAssociatedParticleLinks(xAOD::PFOContainer &pfoContainer, xAOD::PFODetails::PFOParticleType type) const
Clear accosicated partcle links for the pfo container.
float getExtrapolatedPosition(const xAOD::PFO &chargedPFO, xAOD::TauJetParameters::TrackDetail detail) const
Get extrapolated position to the CAL.
void associateChargedToNeutralPFOs(const xAOD::TauJet &pTau, xAOD::PFOContainer &pNeutralPFOContainer) const
associate charged PFOs to neutral PFOs
Gaudi::Property< float > m_minNeutralPFOPt
TauPi0ClusterScaler(const std::string &name)
virtual StatusCode executeTool(xAOD::TauJet &pTau, const EventContext &ctx, xAOD::PFOContainer &pNeutralPFOContainer, xAOD::PFOContainer &pChargedPFOContainer) const override
void associateHadronicToChargedPFOs(const xAOD::TauJet &pTau, xAOD::PFOContainer &pChargedPFOContainer) const
associate hadronic PFOs to charged PFOs
Gaudi::Property< double > m_maxDeltaRNeutralCharged
void subtractChargedEnergyFromNeutralPFOs(const xAOD::TauJet &tau, xAOD::PFOContainer &pNeutralPFOContainer) const
associate charged PFOs to neutral PFOs
TauRecToolBase(const std::string &name)
Class providing the definition of the 4-vector interface.
bool setTrackLink(const ElementLink< xAOD::TrackParticleContainer > &theTrack)
Set a track constituent - does NOT append to existing container.
Definition PFO_v1.cxx:543
bool associatedParticles(PFODetails::PFOParticleType ParticleType, std::vector< const IParticle * > &theParticles) const
get a vector of PFO constituent particle types via enum
Definition PFO_v1.cxx:610
void setP4(const FourMom_t &vec)
set the 4-vec
Definition PFO_v1.cxx:107
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition PFO_v1.cxx:60
bool setAssociatedParticleLink(PFODetails::PFOParticleType ParticleType, const ElementLink< IParticleContainer > &theParticle)
Set an IParticle constituent via enum - does NOT append to existing container.
Definition PFO_v1.cxx:561
virtual double m() const
The invariant mass of the particle.
Definition PFO_v1.cxx:74
void setCharge(float charge)
set charge of PFO
virtual double e() const
The total energy of the particle.
Definition PFO_v1.cxx:81
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition PFO_v1.cxx:67
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition PFO_v1.cxx:52
const CaloCluster * cluster(unsigned int index) const
Retrieve a const pointer to a CaloCluster.
Definition PFO_v1.cxx:669
bool detail(TauJetParameters::TrackDetail detail, float &value) const
virtual FourMom_t p4() const
The full 4-momentum of the particle.
const TrackParticleLinks_t & trackLinks() const
const TrackParticle * track() const
float charge() const
Returns the charge.
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
PFOParticleType
This enum is used to label the associated particles to the PFO object.
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
PFOContainer_v1 PFOContainer
Definition of the current "pfo container version".
TauTrack_v1 TauTrack
Definition of the current version.
Definition TauTrack.h:16
TauJet_v3 TauJet
Definition of the current "tau version".
Definition TauJet.h:17