ATLAS Offline Software
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 
9 using namespace TauAnalysisTools;
10 
11 //=================================PUBLIC-PART==================================
12 //______________________________________________________________________________
13 TauTruthMatchingTool::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 
30  {
31  ATH_MSG_FATAL("Failed initializing BuildTruthTaus");
32  return StatusCode::FAILURE;
33  }
34  return StatusCode::SUCCESS;
35 }
36 
37 //______________________________________________________________________________
38 std::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 //______________________________________________________________________________
50 {
51  return getTruth (xTau, m_truthTausEvent);
52 }
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)
70  if ( !(*m_bIsTruthMatchedAvailable.ptr()) && (*m_bIsTruthParticleLinkAvailable.ptr())) {
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 //______________________________________________________________________________
98 std::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 //______________________________________________________________________________
111 TLorentzVector TauTruthMatchingTool::getTruthTauP4Vis(const xAOD::TauJet& xTau)
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 //______________________________________________________________________________
125 TLorentzVector TauTruthMatchingTool::getTruthTauP4Vis(const xAOD::TruthParticle& xTruthTau) const
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 //______________________________________________________________________________
140 TLorentzVector TauTruthMatchingTool::getTruthTauP4Invis(const xAOD::TauJet& xTau)
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 //______________________________________________________________________________
154 TLorentzVector TauTruthMatchingTool::getTruthTauP4Invis(const xAOD::TruthParticle& xTruthTau) const
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 
174 {
176 }
177 
178 //______________________________________________________________________________
179 int 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 //______________________________________________________________________________
197 int 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 //______________________________________________________________________________
220 xAOD::TauJetParameters::DecayMode TauTruthMatchingTool::getDecayMode(const xAOD::TauJet& xTau)
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 //______________________________________________________________________________
238 xAOD::TauJetParameters::DecayMode TauTruthMatchingTool::getDecayMode(const xAOD::TruthParticle& xTruthTau) const
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 //______________________________________________________________________________
275 StatusCode TauTruthMatchingTool::findTruthTau(const xAOD::TauJet& xTau,
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 
290  if (*m_bIsTruthMatchedAvailable.ptr() || *m_bIsTruthParticleLinkAvailable.ptr()) {
291  return StatusCode::SUCCESS;
292  }
293 
294  // only search for truth taus once
295 
296  // need to be reviewed
297 
298  if (m_bTruthTauAvailable)
299  return checkTruthMatch(xTau, *truthTausEvent.m_xTruthTauContainerConst, truthTausEvent);
300  else
301  return checkTruthMatch(xTau, *truthTausEvent.m_xTruthTauContainer, truthTausEvent);
302 }
303 
304 //______________________________________________________________________________
305 StatusCode 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  {
421  decTruthParticleLink(xTau) = lTruthParticleLink;
422  }
423 
424  return StatusCode::SUCCESS;
425 }
426 
427 
436 TauTruthMatchingTool::lockDecorations (const xAOD::TauJetContainer& taus) const
437 {
438  xAOD::TauJetContainer& taus_nc ATLAS_THREAD_SAFE = const_cast<xAOD::TauJetContainer&> (taus);
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 
xAOD::TauJetParameters::Mode_1p0n
@ Mode_1p0n
Definition: TauDefs.h:386
TauAnalysisTools
Definition: TruthCollectionMakerTau.h:16
TauAnalysisTools::TruthElectron
@ TruthElectron
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:102
TauTruthMatchingTool.h
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
xAOD::TauJetParameters::Mode_1p1n
@ Mode_1p1n
Definition: TauDefs.h:387
TauAnalysisTools::getTruth
const xAOD::TruthParticle * getTruth(const xAOD::TauJet &xTau)
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:194
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TauAnalysisTools::IBuildTruthTaus::ITruthTausEvent
Declare the interface that the class provides.
Definition: IBuildTruthTaus.h:37
TauAnalysisTools::TruthHadronicTau
@ TruthHadronicTau
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:99
initialize
void initialize()
Definition: run_EoverP.cxx:894
xAOD::char
char
Definition: TrigDecision_v1.cxx:38
TauAnalysisTools::getNTauDecayParticles
int getNTauDecayParticles(const xAOD::TruthParticle &xTruthTau, int iPdgId, bool bCompareAbsoluteValues)
Count truth matched decay particles of a particular PDGID.
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:256
SG::ConstAccessor< char >
SG::Decorator::auxid
SG::auxid_t auxid() const
Return the aux id for this variable.
TauAnalysisTools::TruthLeptonicTau
@ TruthLeptonicTau
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:100
xAOD::TauJetParameters::Mode_1pXn
@ Mode_1pXn
Definition: TauDefs.h:388
xAOD::TauJetParameters::DecayMode
DecayMode
Definition: TauDefs.h:385
TauAnalysisTools::BuildTruthTaus
Definition: BuildTruthTaus.h:39
SG::Decorator< char >
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::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
xAOD::TauJet_v3
Class describing a tau jet.
Definition: TauJet_v3.h:41
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
xAOD::TauJetParameters::Mode_3p0n
@ Mode_3p0n
Definition: TauDefs.h:389
TauAnalysisTools::TruthMuon
@ TruthMuon
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:101
TauAnalysisTools::TruthMatchedParticleType
TruthMatchedParticleType
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:97
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::TauJet_v3::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: TauJet_v3.cxx:96
TauAnalysisTools::getTruthParticleType
TruthMatchedParticleType getTruthParticleType(const xAOD::TauJet &xTau)
return TauJet match type
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:493
xAOD::TauJetParameters::Mode_3pXn
@ Mode_3pXn
Definition: TauDefs.h:390
xAOD::TruthParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TruthParticle_v1.cxx:161
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::TauJetParameters::Mode_Error
@ Mode_Error
Definition: TauDefs.h:393
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
xAOD::TauJetParameters::Mode_NotSet
@ Mode_NotSet
Definition: TauDefs.h:392
xAOD::Jet_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition: Jet_v1.cxx:44
HelperFunctions.h
xAOD::TauJetParameters::Mode_Other
@ Mode_Other
Definition: TauDefs.h:391