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