ATLAS Offline Software
Loading...
Searching...
No Matches
TauTruthMatchingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Local include(s)
8
9using namespace TauAnalysisTools;
10
11//=================================PUBLIC-PART==================================
12//______________________________________________________________________________
13TauTruthMatchingTool::TauTruthMatchingTool( const std::string& name )
15 , m_accPtVis("pt_vis")
16 , m_accEtaVis("eta_vis")
17 , m_accPhiVis("phi_vis")
18 , m_accMVis("m_vis")
19{}
20
21//______________________________________________________________________________
23{
24 ATH_MSG_INFO( "Initializing TauTruthMatchingTool" );
25
26 // configure BuildTruthTaus in truth matching mode, not truth tau building mode
27 TauTruthMatchingTool::BuildTruthTaus::setTruthMatchingMode();
28
29 if (TauTruthMatchingTool::BuildTruthTaus::initialize().isFailure())
30 {
31 ATH_MSG_FATAL("Failed initializing BuildTruthTaus");
32 return StatusCode::FAILURE;
33 }
34 return StatusCode::SUCCESS;
35}
36
37//______________________________________________________________________________
38std::unique_ptr<TauTruthMatchingTool::ITruthTausEvent> TauTruthMatchingTool::getEvent() const
39{
40 const EventContext& ctx = Gaudi::Hive::currentContext();
41 auto truthTausEvent = std::make_unique<TruthTausEvent>();
42 if (retrieveTruthTaus(*truthTausEvent, ctx).isFailure()) {
43 truthTausEvent.reset();
44 }
45 return truthTausEvent;
46}
47
48//______________________________________________________________________________
53
54
56 ITruthTausEvent& itruthTausEvent) const
57{
58 TruthTausEvent& truthTausEvent = dynamic_cast<TruthTausEvent&> (itruthTausEvent);
59 const EventContext& ctx = Gaudi::Hive::currentContext();
60 if (retrieveTruthTaus(truthTausEvent, ctx).isFailure())
61 return nullptr;
62
63 if (findTruthTau(xTau, truthTausEvent).isFailure())
64 ATH_MSG_WARNING("There was a failure in finding the matched truth tau");
65
66 static const SG::ConstAccessor<char> accIsTruthMatched("IsTruthMatched");
67 static const SG::ConstAccessor< ElementLink< xAOD::TruthParticleContainer > > accTruthParticleLink("truthParticleLink");
68
69 // derivations may drop IsTruthMatched, redecorate using truthParticleLink (this assumes links to truth leptons are preserved, i.e. TruthTaus, TruthElectron, TruthMuon)
71 ATH_MSG_DEBUG("TauJetContainer has truthParticleLink available while IsTruthMatched not available. Re-evaluate IsTruthMatched");
72 static const SG::Decorator<char> decIsTruthMatched("IsTruthMatched");
73 if (accTruthParticleLink(xTau)) {
74 decIsTruthMatched(xTau) = (char)true;
75 } else {
76 decIsTruthMatched(xTau) = (char)false;
77 }
78 }
79
80 // if matched to a truth particle return its pointer, else return a null pointer
81 if (static_cast<bool>(accIsTruthMatched(xTau)))
82 {
83 if (accTruthParticleLink(xTau).isValid())
84 {
85 return *accTruthParticleLink(xTau);
86 }
87 else
88 {
89 ATH_MSG_WARNING("ElementLink to TruthParticle is not valid.");
90 return nullptr;
91 }
92 }
93
94 return nullptr;
95}
96
97//______________________________________________________________________________
98std::vector<const xAOD::TruthParticle*> TauTruthMatchingTool::getTruth(const std::vector<const xAOD::TauJet*>& vTaus)
99{
100 std::vector<const xAOD::TruthParticle*> vTruths;
101 for (auto xTau : vTaus)
102 vTruths.push_back(getTruth(*xTau));
103 return vTruths;
104}
105
107// Wrapper functions //
109
110//______________________________________________________________________________
112{
113 const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
114 TLorentzVector vTLV;
115 if (xTruthTau == nullptr)
116 {
117 ATH_MSG_INFO("no truth particle was found, returning TLorentzVector with all values equal to 0");
118 } else {
119 vTLV = getTruthTauP4Vis(*xTruthTau);
120 }
121 return vTLV;
122}
123
124//______________________________________________________________________________
126{
127 TLorentzVector vTLV;
128 static const SG::ConstAccessor<double> acc ("pt_vis");
129 if (!acc.isAvailable(xTruthTau))
130 return vTLV;
131 vTLV.SetPtEtaPhiM(
132 m_accPtVis(xTruthTau),
133 m_accEtaVis(xTruthTau),
134 m_accPhiVis(xTruthTau),
135 m_accMVis(xTruthTau));
136 return vTLV;
137}
138
139//______________________________________________________________________________
141{
142 const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
143 TLorentzVector vTLV;
144 if (xTruthTau == nullptr)
145 {
146 ATH_MSG_INFO("no truth particle was found, returning TLorentzVector with all values equal to 0");
147 } else {
148 vTLV = getTruthTauP4Invis(*xTruthTau);
149 }
150 return vTLV;
151}
152
153//______________________________________________________________________________
155{
156 TLorentzVector vTLV;
157
158 static const SG::ConstAccessor<double> accPtInvis("pt_invis");
159 static const SG::ConstAccessor<double> accEtaInvis("eta_invis");
160 static const SG::ConstAccessor<double> accPhiInvis("phi_invis");
161 static const SG::ConstAccessor<double> accMInvis("m_invis");
162
163 if (!accPtInvis.isAvailable(xTruthTau))
164 return vTLV;
165 vTLV.SetPtEtaPhiM(
166 accPtInvis(xTruthTau),
167 accEtaInvis(xTruthTau),
168 accPhiInvis(xTruthTau),
169 accMInvis(xTruthTau));
170 return vTLV;
171}
172
177
178//______________________________________________________________________________
179int TauTruthMatchingTool::getNTauDecayParticles(const xAOD::TauJet& xTau, int iPdgId, bool bCompareAbsoluteValues)
180{
181 const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
182 if (xTruthTau == nullptr)
183 {
184 ATH_MSG_DEBUG("no truth particle was found, return 0");
185 return 0;
186 }
187 static const SG::ConstAccessor<std::vector<int> > accDecayModeVector("DecayModeVector");
188 if (!accDecayModeVector.isAvailable(*xTruthTau))
189 {
190 ATH_MSG_INFO("found truth particle is not a truth tau, return 0");
191 return 0;
192 }
193 return getNTauDecayParticles(*xTruthTau,iPdgId, bCompareAbsoluteValues);
194}
195
196//______________________________________________________________________________
197int TauTruthMatchingTool::getNTauDecayParticles(const xAOD::TruthParticle& xTruthTau, int iPdgId, bool bCompareAbsoluteValues) const
198{
199 int iNum = 0;
200 static const SG::ConstAccessor<std::vector<int> > accDecayModeVector("DecayModeVector");
201 if (!accDecayModeVector.isAvailable(xTruthTau))
202 {
203 ATH_MSG_WARNING("passed truth particle is not a truth tau, return 0");
204 return 0;
205 }
206
207 for(auto iPdgId2 : accDecayModeVector(xTruthTau))
208 if (!bCompareAbsoluteValues)
209 {
210 if (iPdgId2 == iPdgId) iNum++;
211 }
212 else
213 {
214 if (std::abs(iPdgId2) == std::abs(iPdgId)) iNum++;
215 }
216 return iNum;
217}
218
219//______________________________________________________________________________
221{
222 const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
223 if (xTruthTau == nullptr)
224 {
225 ATH_MSG_DEBUG("no truth particle was found, return Mode_Error");
227 }
228 static const SG::ConstAccessor<size_t> accNumCharged("numCharged");
229 if (!accNumCharged.isAvailable(*xTruthTau))
230 {
231 ATH_MSG_INFO("found truth particle is not a truth tau, return Mode_Error");
233 }
234 return getDecayMode(*xTruthTau);
235}
236
237//______________________________________________________________________________
239{
240 static const SG::ConstAccessor<size_t> accNumCharged("numCharged");
241 if (!accNumCharged.isAvailable(xTruthTau))
242 {
243 ATH_MSG_WARNING("passed truth particle is not a truth tau, return Mode_Error");
245 }
246
247 int iCharged = getNTauDecayParticles(xTruthTau,MC::PIPLUS, true) + getNTauDecayParticles(xTruthTau,MC::KPLUS, true);
248 int iNeutral = getNTauDecayParticles(xTruthTau,MC::PI0, true);
249 if (iCharged == 1)
250 {
251 if (iNeutral == 0) return xAOD::TauJetParameters::DecayMode::Mode_1p0n;
252 if (iNeutral == 1) return xAOD::TauJetParameters::DecayMode::Mode_1p1n;
253 if (iNeutral >= 2) return xAOD::TauJetParameters::DecayMode::Mode_1pXn;
254 }
255 else if (iCharged == 3)
256 {
257 if (iNeutral == 0) return xAOD::TauJetParameters::DecayMode::Mode_3p0n;
258 if (iNeutral >= 1) return xAOD::TauJetParameters::DecayMode::Mode_3pXn;
259 }
260
261 if (iCharged == 2 or iCharged == 4 or iCharged == 5)
263 if (iCharged == 0 or iCharged >=6)
265
266 // if you got here, something should have gone wrong
268}
269
271// Private Part //
273
274//______________________________________________________________________________
276 TruthTausEvent& truthTausEvent) const
277{
278 // check if decorations were already added to the first passed tau
279 if (!m_bIsTruthMatchedAvailable.isValid()) {
280 static const SG::ConstAccessor<char> accIsTruthMatched("IsTruthMatched");
281 m_bIsTruthMatchedAvailable.set (accIsTruthMatched.isAvailable(xTau));
282 }
283 // check if decorations were already added to the first passed tau
284 if (!m_bIsTruthParticleLinkAvailable.isValid()) {
286 accTruthParticleLink("truthParticleLink");
287 m_bIsTruthParticleLinkAvailable.set (accTruthParticleLink.isAvailable(xTau));
288 }
289
291 return StatusCode::SUCCESS;
292 }
293
294 // only search for truth taus once
295
296 // need to be reviewed
297
299 return checkTruthMatch(xTau, *truthTausEvent.m_xTruthTauContainerConst, truthTausEvent);
300 else
301 return checkTruthMatch(xTau, *truthTausEvent.m_xTruthTauContainer, truthTausEvent);
302}
303
304//______________________________________________________________________________
305StatusCode TauTruthMatchingTool::checkTruthMatch (const xAOD::TauJet& xTau, const xAOD::TruthParticleContainer& xTruthTauContainer, const TruthTausEvent& truthTausEvent) const
306{
307 const xAOD::TruthParticle* xTruthMatch = nullptr;
308 const xAOD::Jet* xTruthJetMatch = nullptr;
309 TruthMatchedParticleType eTruthMatchedParticleType = Unknown;
310 static const SG::Decorator<char> decIsTruthMatched("IsTruthMatched");
311 static const SG::Decorator< ElementLink< xAOD::JetContainer > > decTruthJetLink("truthJetLink");
312
313 for (auto xTruthTauIt : xTruthTauContainer)
314 {
315 TLorentzVector vTruthVisTLV;
316 vTruthVisTLV.SetPtEtaPhiM(m_accPtVis(*xTruthTauIt),
317 m_accEtaVis(*xTruthTauIt),
318 m_accPhiVis(*xTruthTauIt),
319 m_accMVis(*xTruthTauIt));
320 if (xTau.p4().DeltaR(vTruthVisTLV) <= m_dMaxDeltaR)
321 {
322 static const SG::ConstAccessor<char> accIsHadronicTau("IsHadronicTau");
323 if (static_cast<bool>(accIsHadronicTau(*xTruthTauIt)))
324 eTruthMatchedParticleType = TruthHadronicTau;
325 else
326 eTruthMatchedParticleType = TruthLeptonicTau;
327
328 xTruthMatch = xTruthTauIt;
329 break;
330 }
331 }
332
333 double dPtMax = 0.;
334 if (!xTruthMatch and truthTausEvent.m_xTruthMuonContainerConst)
335 {
336 dPtMax = 0.;
337 for (auto xTruthMuonIt : *truthTausEvent.m_xTruthMuonContainerConst)
338 {
339 if (xTau.p4().DeltaR(xTruthMuonIt->p4()) <= m_dMaxDeltaR)
340 {
341 if (xTruthMuonIt->pt()<dPtMax)
342 continue;
343 eTruthMatchedParticleType = TruthMuon;
344 xTruthMatch = xTruthMuonIt;
345 dPtMax = xTruthMuonIt->pt();
346 }
347 }
348 }
349
350 if (!xTruthMatch and truthTausEvent.m_xTruthElectronContainerConst)
351 {
352 dPtMax = 0.;
353 for (auto xTruthElectronIt : *truthTausEvent.m_xTruthElectronContainerConst)
354 {
355 if (xTau.p4().DeltaR(xTruthElectronIt->p4()) <= m_dMaxDeltaR)
356 {
357 if (xTruthElectronIt->pt()<dPtMax)
358 continue;
359 eTruthMatchedParticleType = TruthElectron;
360 xTruthMatch = xTruthElectronIt;
361 dPtMax = xTruthElectronIt->pt();
362 }
363 }
364 }
365
366 if (truthTausEvent.m_xTruthJetContainerConst)
367 {
368 dPtMax = 0.;
369 for (auto xTruthJetIt : *truthTausEvent.m_xTruthJetContainerConst)
370 {
371 if (xTau.p4().DeltaR(xTruthJetIt->p4()) <= m_dMaxDeltaR)
372 {
373 if (xTruthJetIt->pt()<dPtMax)
374 continue;
375 xTruthJetMatch = xTruthJetIt;
376 dPtMax = xTruthJetIt->pt();
377 }
378 }
379 }
380
381 if (xTruthMatch)
382 decIsTruthMatched(xTau) = (char)true;
383 else
384 decIsTruthMatched(xTau) = (char)false;
385
386 if (xTruthJetMatch)
387 {
388 ElementLink < xAOD::JetContainer > lTruthParticleLink(xTruthJetMatch, *truthTausEvent.m_xTruthJetContainerConst);
389 decTruthJetLink(xTau) = lTruthParticleLink;
390 }
391 else
392 {
393 ElementLink < xAOD::JetContainer > lTruthParticleLink;
394 decTruthJetLink(xTau) = lTruthParticleLink;
395 }
396
397 // create link to the original TruthParticle
398 static const SG::Decorator< ElementLink< xAOD::TruthParticleContainer > > decTruthParticleLink("truthParticleLink");
399
400 if (xTruthMatch)
401 {
402 if (eTruthMatchedParticleType == TruthHadronicTau or eTruthMatchedParticleType == TruthLeptonicTau)
403 {
404 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, xTruthTauContainer);
405 decTruthParticleLink(xTau) = lTruthParticleLink;
406 }
407 else if (eTruthMatchedParticleType == TruthMuon)
408 {
409 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, *truthTausEvent.m_xTruthMuonContainerConst);
410 decTruthParticleLink(xTau) = lTruthParticleLink;
411 }
412 else if (eTruthMatchedParticleType == TruthElectron)
413 {
414 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, *truthTausEvent.m_xTruthElectronContainerConst);
415 decTruthParticleLink(xTau) = lTruthParticleLink;
416 }
417 }
418 else
419 {
420 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink;
421 decTruthParticleLink(xTau) = lTruthParticleLink;
422 }
423
424 return StatusCode::SUCCESS;
425}
426
427
435StatusCode
437{
439 static const SG::Decorator<char> decIsTruthMatched("IsTruthMatched");
440 static const SG::Decorator< ElementLink< xAOD::JetContainer > > decTruthJetLink("truthJetLink");
441 static const SG::Decorator< ElementLink< xAOD::TruthParticleContainer > > decTruthParticleLink("truthParticleLink");
442 taus_nc.lockDecoration (decIsTruthMatched.auxid());
443 taus_nc.lockDecoration (decTruthJetLink.auxid());
444 taus_nc.lockDecoration (decTruthParticleLink.auxid());
445 return StatusCode::SUCCESS;
446}
447
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
static Double_t taus
#define ATLAS_THREAD_SAFE
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
SG::auxid_t auxid() const
Return the aux id for this variable.
virtual StatusCode retrieveTruthTaus() override
Declare the interface that the class provides.
virtual StatusCode lockDecorations(const xAOD::TauJetContainer &taus) const override final
Decorations produced by an algorithm need to be locked; otherwise, they will be ignored by deep copie...
virtual TLorentzVector getTruthTauP4Vis(const xAOD::TauJet &xTau) override final
StatusCode findTruthTau(const xAOD::TauJet &xTau, TruthTausEvent &truthTausEvent) const
CxxUtils::CachedValue< bool > m_bIsTruthParticleLinkAvailable
virtual std::unique_ptr< ITruthTausEvent > getEvent() const override final
virtual TauAnalysisTools::TruthMatchedParticleType getTruthParticleType(const xAOD::TauJet &xTau) override final
virtual StatusCode initialize() override final
virtual xAOD::TauJetParameters::DecayMode getDecayMode(const xAOD::TauJet &xTau) override final
virtual int getNTauDecayParticles(const xAOD::TauJet &xTau, int iPdgId, bool bCompareAbsoluteValues=false) override final
virtual TLorentzVector getTruthTauP4Invis(const xAOD::TauJet &xTau) override final
virtual const xAOD::TruthParticle * getTruth(const xAOD::TauJet &xTau) override final
CxxUtils::CachedValue< bool > m_bIsTruthMatchedAvailable
StatusCode checkTruthMatch(const xAOD::TauJet &xTau, const xAOD::TruthParticleContainer &xTauContainer, const TruthTausEvent &truthTausEvent) const
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition Jet_v1.cxx:44
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition TauJet_v3.cxx:96
virtual double pt() const override final
The transverse momentum ( ) of the particle.
static const int PI0
static const int KPLUS
static const int PIPLUS
TruthMatchedParticleType getTruthParticleType(const xAOD::TauJet &xTau)
return TauJet match type
Jet_v1 Jet
Definition of the current "jet version".
TauJet_v3 TauJet
Definition of the current "tau version".
TruthParticle_v1 TruthParticle
Typedef to implementation.
TauJetContainer_v3 TauJetContainer
Definition of the current "taujet container version".
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.