ATLAS Offline Software
TauTruthMatchingTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Local include(s)
8 
9 // Core include(s):
10 #include "AthLinks/ElementLink.h"
14 
15 // EDM include(s):
16 #include "xAODTau/TauxAODHelpers.h"
17 
18 using namespace TauAnalysisTools;
19 
20 //=================================PUBLIC-PART==================================
21 //______________________________________________________________________________
22 TauTruthMatchingTool::TauTruthMatchingTool( const std::string& name )
24  , m_accPtVis("pt_vis")
25  , m_accEtaVis("eta_vis")
26  , m_accPhiVis("phi_vis")
27  , m_accMVis("m_vis")
28 {
29  declareProperty( "MaxDeltaR", m_dMaxDeltaR = 0.2);
30 }
31 
32 //______________________________________________________________________________
34 {
35  ATH_MSG_INFO( "Initializing TauTruthMatchingTool" );
36 
37  // configure BuildTruthTaus in truth matching mode, not truth tau building mode
38  TauTruthMatchingTool::BuildTruthTaus::setTruthMatchingMode();
39 
41  {
42  ATH_MSG_FATAL("Failed initializing BuildTruthTaus");
43  return StatusCode::FAILURE;
44  }
45  return StatusCode::SUCCESS;
46 }
47 
48 //______________________________________________________________________________
49 std::unique_ptr<TauTruthMatchingTool::ITruthTausEvent> TauTruthMatchingTool::getEvent() const
50 {
51  auto truthTausEvent = std::make_unique<TruthTausEvent>();
52  if (retrieveTruthTaus(*truthTausEvent).isFailure()) {
53  truthTausEvent.reset();
54  }
55  return truthTausEvent;
56 }
57 
58 //______________________________________________________________________________
60 {
61  return getTruth (xTau, m_truthTausEvent);
62 }
63 
64 
66  ITruthTausEvent& itruthTausEvent) const
67 {
68  TruthTausEvent& truthTausEvent = dynamic_cast<TruthTausEvent&> (itruthTausEvent);
69 
70  if (retrieveTruthTaus(truthTausEvent).isFailure())
71  return nullptr;
72 
73  if (findTruthTau(xTau, truthTausEvent).isFailure())
74  ATH_MSG_WARNING("There was a failure in finding the matched truth tau");
75 
76  static const SG::ConstAccessor<char> accIsTruthMatched("IsTruthMatched");
77  static const SG::ConstAccessor< ElementLink< xAOD::TruthParticleContainer > > accTruthParticleLink("truthParticleLink");
78 
79  // derivations may drop IsTruthMatched, redecorate using truthParticleLink (this assumes links to truth leptons are preserved, i.e. TruthTaus, TruthElectron, TruthMuon)
80  if ( !(*m_bIsTruthMatchedAvailable.ptr()) && (*m_bIsTruthParticleLinkAvailable.ptr())) {
81  ATH_MSG_DEBUG("TauJetContainer has truthParticleLink available while IsTruthMatched not available. Re-evaluate IsTruthMatched");
82  static const SG::Decorator<char> decIsTruthMatched("IsTruthMatched");
83  if (accTruthParticleLink(xTau)) {
84  decIsTruthMatched(xTau) = (char)true;
85  } else {
86  decIsTruthMatched(xTau) = (char)false;
87  }
88  }
89 
90  // if matched to a truth particle return its pointer, else return a null pointer
91  if ((bool)accIsTruthMatched(xTau))
92  {
93  if (accTruthParticleLink(xTau).isValid())
94  {
95  return *accTruthParticleLink(xTau);
96  }
97  else
98  {
99  ATH_MSG_WARNING("ElementLink to TruthParticle is not valid.");
100  return nullptr;
101  }
102  }
103 
104  return nullptr;
105 }
106 
107 //______________________________________________________________________________
108 std::vector<const xAOD::TruthParticle*> TauTruthMatchingTool::getTruth(const std::vector<const xAOD::TauJet*>& vTaus)
109 {
110  std::vector<const xAOD::TruthParticle*> vTruths;
111  for (auto xTau : vTaus)
112  vTruths.push_back(getTruth(*xTau));
113  return vTruths;
114 }
115 
117 // Wrapper functions //
119 
120 //______________________________________________________________________________
121 TLorentzVector TauTruthMatchingTool::getTruthTauP4Vis(const xAOD::TauJet& xTau)
122 {
123  const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
124  TLorentzVector vTLV;
125  if (xTruthTau == nullptr)
126  {
127  ATH_MSG_INFO("no truth particle was found, returning TLorentzVector with all values equal to 0");
128  return vTLV;
129  }
130 
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::getTruthTauP4Vis(const xAOD::TruthParticle& xTruthTau) const
141 {
142  TLorentzVector vTLV;
143  static const SG::ConstAccessor<double> acc ("pt_vis");
144  if (!acc.isAvailable(xTruthTau))
145  return vTLV;
146  vTLV.SetPtEtaPhiM(
147  m_accPtVis(xTruthTau),
148  m_accEtaVis(xTruthTau),
149  m_accPhiVis(xTruthTau),
150  m_accMVis(xTruthTau));
151  return vTLV;
152 }
153 
154 //______________________________________________________________________________
155 TLorentzVector TauTruthMatchingTool::getTruthTauP4Invis(const xAOD::TauJet& xTau)
156 {
157  const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
158  TLorentzVector vTLV;
159  if (xTruthTau == nullptr)
160  {
161  ATH_MSG_INFO("no truth particle was found, returning TLorentzVector with all values equal to 0");
162  return vTLV;
163  }
164 
165  static const SG::ConstAccessor<double> accPtInvis("pt_invis");
166  static const SG::ConstAccessor<double> accEtaInvis("eta_invis");
167  static const SG::ConstAccessor<double> accPhiInvis("phi_invis");
168  static const SG::ConstAccessor<double> accMInvis("m_invis");
169  vTLV.SetPtEtaPhiM(
170  accPtInvis(*xTruthTau),
171  accEtaInvis(*xTruthTau),
172  accPhiInvis(*xTruthTau),
173  accMInvis(*xTruthTau));
174  return vTLV;
175 }
176 
177 //______________________________________________________________________________
178 TLorentzVector TauTruthMatchingTool::getTruthTauP4Invis(const xAOD::TruthParticle& xTruthTau) const
179 {
180  TLorentzVector vTLV;
181 
182  static const SG::ConstAccessor<double> accPtInvis("pt_invis");
183  static const SG::ConstAccessor<double> accEtaInvis("eta_invis");
184  static const SG::ConstAccessor<double> accPhiInvis("phi_invis");
185  static const SG::ConstAccessor<double> accMInvis("m_invis");
186 
187  if (!accPtInvis.isAvailable(xTruthTau))
188  return vTLV;
189  vTLV.SetPtEtaPhiM(
190  accPtInvis(xTruthTau),
191  accEtaInvis(xTruthTau),
192  accPhiInvis(xTruthTau),
193  accMInvis(xTruthTau));
194  return vTLV;
195 }
196 
198 {
200 }
201 
202 //______________________________________________________________________________
203 int TauTruthMatchingTool::getNTauDecayParticles(const xAOD::TauJet& xTau, int iPdgId, bool bCompareAbsoluteValues)
204 {
205  const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
206  if (xTruthTau == nullptr)
207  {
208  ATH_MSG_DEBUG("no truth particle was found, return 0");
209  return 0;
210  }
211  static const SG::ConstAccessor<std::vector<int> > accDecayModeVector("DecayModeVector");
212  if (!accDecayModeVector.isAvailable(*xTruthTau))
213  {
214  ATH_MSG_INFO("found truth particle is not a truth tau, return 0");
215  return 0;
216  }
217  return getNTauDecayParticles(*xTruthTau,iPdgId, bCompareAbsoluteValues);
218 }
219 
220 //______________________________________________________________________________
221 int TauTruthMatchingTool::getNTauDecayParticles(const xAOD::TruthParticle& xTruthTau, int iPdgId, bool bCompareAbsoluteValues) const
222 {
223  int iNum = 0;
224  static const SG::ConstAccessor<std::vector<int> > accDecayModeVector("DecayModeVector");
225  if (!accDecayModeVector.isAvailable(xTruthTau))
226  {
227  ATH_MSG_WARNING("passed truth particle is not a truth tau, return 0");
228  return 0;
229  }
230 
231  for(auto iPdgId2 : accDecayModeVector(xTruthTau))
232  if (!bCompareAbsoluteValues)
233  {
234  if (iPdgId2 == iPdgId) iNum++;
235  }
236  else
237  {
238  if (std::abs(iPdgId2) == std::abs(iPdgId)) iNum++;
239  }
240  return iNum;
241 }
242 
243 //______________________________________________________________________________
244 xAOD::TauJetParameters::DecayMode TauTruthMatchingTool::getDecayMode(const xAOD::TauJet& xTau)
245 {
246  const xAOD::TruthParticle* xTruthTau = getTruth(xTau);
247  if (xTruthTau == nullptr)
248  {
249  ATH_MSG_DEBUG("no truth particle was found, return Mode_Error");
251  }
252  static const SG::ConstAccessor<size_t> accNumCharged("numCharged");
253  if (!accNumCharged.isAvailable(*xTruthTau))
254  {
255  ATH_MSG_INFO("found truth particle is not a truth tau, return Mode_Error");
257  }
258  return getDecayMode(*xTruthTau);
259 }
260 
261 //______________________________________________________________________________
262 xAOD::TauJetParameters::DecayMode TauTruthMatchingTool::getDecayMode(const xAOD::TruthParticle& xTruthTau) const
263 {
264  static const SG::ConstAccessor<size_t> accNumCharged("numCharged");
265  if (!accNumCharged.isAvailable(xTruthTau))
266  {
267  ATH_MSG_WARNING("passed truth particle is not a truth tau, return Mode_Error");
269  }
270 
271  int iCharged = getNTauDecayParticles(xTruthTau,MC::PIPLUS, true) + getNTauDecayParticles(xTruthTau,MC::KPLUS, true);
272  int iNeutral = getNTauDecayParticles(xTruthTau,MC::PI0, true);
273  if (iCharged == 1)
274  {
275  if (iNeutral == 0) return xAOD::TauJetParameters::DecayMode::Mode_1p0n;
276  if (iNeutral == 1) return xAOD::TauJetParameters::DecayMode::Mode_1p1n;
277  if (iNeutral >= 2) return xAOD::TauJetParameters::DecayMode::Mode_1pXn;
278  }
279  else if (iCharged == 3)
280  {
281  if (iNeutral == 0) return xAOD::TauJetParameters::DecayMode::Mode_3p0n;
282  if (iNeutral >= 1) return xAOD::TauJetParameters::DecayMode::Mode_3pXn;
283  }
284 
285  if (iCharged == 2 or iCharged == 4 or iCharged == 5)
287  if (iCharged == 0 or iCharged >=6)
289 
290  // if you got here, something should have gone wrong
292 }
293 
295 // Private Part //
297 
298 //______________________________________________________________________________
299 StatusCode TauTruthMatchingTool::findTruthTau(const xAOD::TauJet& xTau,
300  TruthTausEvent& truthTausEvent) const
301 {
302  // check if decorations were already added to the first passed tau
303  if (!m_bIsTruthMatchedAvailable.isValid()) {
304  static const SG::ConstAccessor<char> accIsTruthMatched("IsTruthMatched");
305  m_bIsTruthMatchedAvailable.set (accIsTruthMatched.isAvailable(xTau));
306  }
307  // check if decorations were already added to the first passed tau
308  if (!m_bIsTruthParticleLinkAvailable.isValid()) {
310  accTruthParticleLink("truthParticleLink");
311  m_bIsTruthParticleLinkAvailable.set (accTruthParticleLink.isAvailable(xTau));
312  }
313 
314  if (*m_bIsTruthMatchedAvailable.ptr() || *m_bIsTruthParticleLinkAvailable.ptr()) {
315  return StatusCode::SUCCESS;
316  }
317 
318  // only search for truth taus once
319 
320  // need to be reviewed
321 
322  if (m_bTruthTauAvailable)
323  return checkTruthMatch(xTau, *truthTausEvent.m_xTruthTauContainerConst, truthTausEvent);
324  else
325  return checkTruthMatch(xTau, *truthTausEvent.m_xTruthTauContainer, truthTausEvent);
326 }
327 
328 //______________________________________________________________________________
329 StatusCode TauTruthMatchingTool::checkTruthMatch (const xAOD::TauJet& xTau, const xAOD::TruthParticleContainer& xTruthTauContainer, const TruthTausEvent& truthTausEvent) const
330 {
331  const xAOD::TruthParticle* xTruthMatch = nullptr;
332  const xAOD::Jet* xTruthJetMatch = nullptr;
333  TruthMatchedParticleType eTruthMatchedParticleType = Unknown;
334  static const SG::Decorator<char> decIsTruthMatched("IsTruthMatched");
335  static const SG::Decorator< ElementLink< xAOD::JetContainer > > decTruthJetLink("truthJetLink");
336 
337  for (auto xTruthTauIt : xTruthTauContainer)
338  {
339  TLorentzVector vTruthVisTLV;
340  vTruthVisTLV.SetPtEtaPhiM(m_accPtVis(*xTruthTauIt),
341  m_accEtaVis(*xTruthTauIt),
342  m_accPhiVis(*xTruthTauIt),
343  m_accMVis(*xTruthTauIt));
344  if (xTau.p4().DeltaR(vTruthVisTLV) <= m_dMaxDeltaR)
345  {
346  static const SG::ConstAccessor<char> accIsHadronicTau("IsHadronicTau");
347  if ((bool)accIsHadronicTau(*xTruthTauIt))
348  eTruthMatchedParticleType = TruthHadronicTau;
349  else
350  eTruthMatchedParticleType = TruthLeptonicTau;
351 
352  xTruthMatch = xTruthTauIt;
353  break;
354  }
355  }
356 
357  double dPtMax = 0.;
358  if (!xTruthMatch and truthTausEvent.m_xTruthMuonContainerConst)
359  {
360  dPtMax = 0.;
361  for (auto xTruthMuonIt : *truthTausEvent.m_xTruthMuonContainerConst)
362  {
363  if (xTau.p4().DeltaR(xTruthMuonIt->p4()) <= m_dMaxDeltaR)
364  {
365  if (xTruthMuonIt->pt()<dPtMax)
366  continue;
367  eTruthMatchedParticleType = TruthMuon;
368  xTruthMatch = xTruthMuonIt;
369  dPtMax = xTruthMuonIt->pt();
370  }
371  }
372  }
373 
374  if (!xTruthMatch and truthTausEvent.m_xTruthElectronContainerConst)
375  {
376  dPtMax = 0.;
377  for (auto xTruthElectronIt : *truthTausEvent.m_xTruthElectronContainerConst)
378  {
379  if (xTau.p4().DeltaR(xTruthElectronIt->p4()) <= m_dMaxDeltaR)
380  {
381  if (xTruthElectronIt->pt()<dPtMax)
382  continue;
383  eTruthMatchedParticleType = TruthElectron;
384  xTruthMatch = xTruthElectronIt;
385  dPtMax = xTruthElectronIt->pt();
386  }
387  }
388  }
389 
390  if (truthTausEvent.m_xTruthJetContainerConst)
391  {
392  dPtMax = 0.;
393  for (auto xTruthJetIt : *truthTausEvent.m_xTruthJetContainerConst)
394  {
395  if (xTau.p4().DeltaR(xTruthJetIt->p4()) <= m_dMaxDeltaR)
396  {
397  if (xTruthJetIt->pt()<dPtMax)
398  continue;
399  xTruthJetMatch = xTruthJetIt;
400  dPtMax = xTruthJetIt->pt();
401  }
402  }
403  }
404 
405  if (xTruthMatch)
406  decIsTruthMatched(xTau) = (char)true;
407  else
408  decIsTruthMatched(xTau) = (char)false;
409 
410  if (xTruthJetMatch)
411  {
412  ElementLink < xAOD::JetContainer > lTruthParticleLink(xTruthJetMatch, *truthTausEvent.m_xTruthJetContainerConst);
413  decTruthJetLink(xTau) = lTruthParticleLink;
414  }
415  else
416  {
417  ElementLink < xAOD::JetContainer > lTruthParticleLink;
418  decTruthJetLink(xTau) = lTruthParticleLink;
419  }
420 
421  // create link to the original TruthParticle
422  static const SG::Decorator< ElementLink< xAOD::TruthParticleContainer > > decTruthParticleLink("truthParticleLink");
423 
424  if (xTruthMatch)
425  {
426  if (eTruthMatchedParticleType == TruthHadronicTau or eTruthMatchedParticleType == TruthLeptonicTau)
427  {
428  ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, xTruthTauContainer);
429  decTruthParticleLink(xTau) = lTruthParticleLink;
430  }
431  else if (eTruthMatchedParticleType == TruthMuon)
432  {
433  ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, *truthTausEvent.m_xTruthMuonContainerConst);
434  decTruthParticleLink(xTau) = lTruthParticleLink;
435  }
436  else if (eTruthMatchedParticleType == TruthElectron)
437  {
438  ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthMatch, *truthTausEvent.m_xTruthElectronContainerConst);
439  decTruthParticleLink(xTau) = lTruthParticleLink;
440  }
441  }
442  else
443  {
445  decTruthParticleLink(xTau) = lTruthParticleLink;
446  }
447 
448  return StatusCode::SUCCESS;
449 }
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:100
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:35
TauAnalysisTools::TruthHadronicTau
@ TruthHadronicTau
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:97
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
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 >
TauAnalysisTools::TruthLeptonicTau
@ TruthLeptonicTau
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:98
xAOD::TauJetParameters::Mode_1pXn
@ Mode_1pXn
Definition: TauDefs.h:388
xAOD::TauJetParameters::DecayMode
DecayMode
Definition: TauDefs.h:385
TauAnalysisTools::BuildTruthTaus
Definition: BuildTruthTaus.h:34
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
TauxAODHelpers.h
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
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:581
xAOD::TauJetParameters::Mode_3p0n
@ Mode_3p0n
Definition: TauDefs.h:389
TauAnalysisTools::TruthMuon
@ TruthMuon
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:99
TauAnalysisTools::TruthMatchedParticleType
TruthMatchedParticleType
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:95
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
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:97
TauAnalysisTools::getTruthParticleType
TruthMatchedParticleType getTruthParticleType(const xAOD::TauJet &xTau)
return TauJet match type
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:572
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:166
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
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
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
Decorator.h
Helper class to provide type-safe access to aux data.
HelperFunctions.h
HepMCHelpers.h
xAOD::TauJetParameters::Mode_Other
@ Mode_Other
Definition: TauDefs.h:391