ATLAS Offline Software
InDetTrackTruthOriginTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
12 
13 #include <math.h>
14 
15 namespace InDet {
16 
17  InDetTrackTruthOriginTool::InDetTrackTruthOriginTool(const std::string& name) :
18  asg::AsgTool(name)
19  {
20 
21 #ifndef XAOD_STANDALONE
22  declareInterface<IInDetTrackTruthOriginTool>(this);
23 #endif
24 
25  declareProperty("matchingProbabilityCut", m_matchingProbabilityCut = 0.5);
26 
27  declareProperty("truthParticleLinkName", m_truthParticleLinkName = "truthParticleLink");
28  declareProperty("truthMatchProbabilityAuxName", m_truthMatchProbabilityAuxName = "truthMatchProbability");
29  declareProperty("isFullPileUpTruth", m_isFullPileupTruth = false);
30 
31  }
32 
33  InDetTrackTruthOriginTool::~InDetTrackTruthOriginTool() = default;
34 
36  if(m_isFullPileupTruth) ATH_MSG_INFO("InDetTrackTruthOriginTool configured for full pile-up truth sample");
37  return StatusCode::SUCCESS;
38  }
39 
41 
42  // if the track doesnt't have a valid truth link, skip to the next track
43  // in practice, all tracks seem to have a truth link, but we need to also
44  // check whether it's valid
46  static const SG::ConstAccessor<TruthLink>
47  truthParticleLinkAcc ("truthParticleLink");
48  if ( !truthParticleLinkAcc.isAvailable(*track) ) {
49  return nullptr;
50  }
51 
52  // retrieve the link and check its validity
53  const TruthLink &link = truthParticleLinkAcc(*track);
54 
55  // a missing or invalid link implies truth particle has been dropped from
56  // the truth record at some stage - probably it was from pilup which by
57  // default we don't store truth information for
58  if(!link or !link.isValid()) {
59  return nullptr;
60  }
61 
62  // seems safe to access and return the linked truth particle
63  return *link;
64  }
65 
67 
68  int origin = 0;
69 
70  // is it fragmentation? yes until proven otherwise
71  bool isFragmentation = true;
72 
73  // from B decay chain?
74  if(isFrom(truth, 5)) {
75  origin = origin | (0x1 << InDet::TrkOrigin::BHadronDecay);
76  isFragmentation = false;
77  }
78 
79  // from D decay chain?
80  if(isFrom(truth, 4)) {
81  origin = origin | (0x1 << InDet::TrkOrigin::DHadronDecay);
82  isFragmentation = false;
83  }
84 
85  // from tau decay chain?
86  if(isFrom(truth, 15)) {
87  origin = origin | (0x1 << InDet::TrkOrigin::TauDecay);
88  isFragmentation = false;
89  }
90 
91  // Secondary?
92  if (HepMC::is_simulation_particle(truth)) {
93 
94  // unknown origin (e.g. parent not in the record)
95  if(truth->nParents() != 1) {
96  origin = origin | (0x1 << InDet::TrkOrigin::OtherOrigin);
97  }
98 
99  else {
100  const xAOD::TruthParticle *parent = truth->parent(0);
101 
102  if(parent == nullptr) {
103  origin = origin | (0x1 << InDet::TrkOrigin::OtherOrigin);
104  }
105 
106  // sub-categorize secondaries which have one valid parent
107  else {
108 
109  int pdgId = truth->pdgId();
110  int parentId = parent->pdgId();
111 
112  // photon conversion
113  if(parent->isPhoton() && truth->isElectron()) {
114  origin = origin | (0x1 << InDet::TrkOrigin::GammaConversion);
115  }
116 
117  // Strange Mesons
118  else if(parent->isStrangeMeson() && parent->nChildren() == 2) {
119  origin = origin | (0x1 << InDet::TrkOrigin::StrangeMesonDecay);
120  // specifically Kshort
121  if (abs(pdgId) == 211 && parentId == 310) {
122  origin = origin | (0x1 << InDet::TrkOrigin::KshortDecay);
123  }
124  }
125 
126  // Strange Baryons
127  else if(parent->isStrangeBaryon() && parent->nChildren() == 2) {
128  origin = origin | (0x1 << InDet::TrkOrigin::StrangeBaryonDecay);
129  // specifically Lambdas
130  if ((abs(pdgId) == 211 || abs(pdgId) == 2212) && abs(parentId) == 3122) {
131  origin = origin | (0x1 << InDet::TrkOrigin::LambdaDecay);
132  }
133  }
134 
135  // other long living particle decays
136  else if(parent->isHadron() && parent->nChildren() == 2) {
137  origin = origin | (0x1 << InDet::TrkOrigin::OtherDecay);
138  }
139 
140  // hadronic interactions
141  else if(parent->nChildren() > 2) {
142  origin = origin | (0x1 << InDet::TrkOrigin::HadronicInteraction);
143  }
144 
145  // other secondaries
146  else {
147  origin = origin | (0x1 << InDet::TrkOrigin::OtherSecondary);
148  }
149  }
150  }
151 
152  isFragmentation = false;
153  }
154 
155  // uncategorized: call it fragmentation
156  if(isFragmentation) {
157  origin = origin | (0x1 << InDet::TrkOrigin::Fragmentation);
158  }
159 
160  return origin;
161  }
162 
164 
165  // get truth particle
166  const xAOD::TruthParticle* truth = getTruth( track );
167 
168  // get track TMP
170  float truthProb = tmpAcc( *track );
171 
172  int origin = 0;
173 
174  // truth link is broken: call it from pileup (not true for < 100 MeV and some specialised samples!)
175  if (!truth){
176  origin = origin | (0x1 << InDet::TrkOrigin::Pileup);
177  }
178 
179  // For full pile-up truth samples, check explicitly if truth record is present among hard-scatter collection to assign Pileup origin
180  else if(m_isFullPileupTruth){
181  const xAOD::TruthEventContainer* truthEventContainer(nullptr);
182  if(evtStore()->retrieve(truthEventContainer, "TruthEvents").isFailure()){
183  ATH_MSG_ERROR("InDetTrackTruthOriginTool configured for full pile-up truth but could not retrieve TruthEvents container");
184  }
185  const xAOD::TruthEvent* event = truthEventContainer ? truthEventContainer->at(0) : nullptr;
186 
187  if(event){
188  const auto& links = event->truthParticleLinks();
189 
190  bool isFromHSProdVtx = false;
191  for (const auto& link : links){
192  if(link.isValid() && truth == *link){
193  isFromHSProdVtx = true;
194  break;
195  }
196  }
197 
198  if(!isFromHSProdVtx) origin = origin | (0x1 << InDet::TrkOrigin::Pileup);
199  }
200  }
201 
202  // low TruthMatchProbability: call it fake (also includes poorly reconstructed tracks)
203  if(truthProb < m_matchingProbabilityCut) {
204  origin = origin | (0x1 << InDet::TrkOrigin::Fake);
205  }
206 
207  // truth link is present: find truth origin
208  if (truth) {
209  origin = origin | getTruthOrigin(truth);
210  }
211 
212  return origin;
213  }
214 
215  bool InDetTrackTruthOriginTool::isFrom(const xAOD::TruthParticle* truth, int flav) const {
216  return isFromRec( truth, flav, 0 );
217  }
218 
219  bool InDetTrackTruthOriginTool::isFromRec(const xAOD::TruthParticle* truth, int flav, int depth) const {
220 
221  if ( truth == nullptr ) return false;
222 
223  if ( depth > 30 ) return false;
224 
225  if( flav != 5 && flav != 4 && flav != 15 ) return false;
226 
227  if( flav == 5 && truth->isBottomHadron() ) return true;
228 
229  if( flav == 4 && truth->isCharmHadron() ) return true;
230 
231  if( flav == 15 && abs(truth->pdgId()) == 15 ) return true;
232 
233 
234  for(unsigned int p=0; p<truth->nParents(); p++) {
235  const xAOD::TruthParticle* parent = truth->parent(p);
236  if(parent == truth ) continue ; // avoid infinite recursion
237  if( isFromRec(parent, flav, depth+1) ) return true;
238  }
239 
240  return false;
241  }
242 
243 }
InDet::TrkOrigin::StrangeMesonDecay
@ StrangeMesonDecay
Definition: InDetTrackTruthOriginDefs.h:23
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::TruthParticle_v1::parent
const TruthParticle_v1 * parent(size_t i=0) const
Retrieve the i-th mother (TruthParticle) of this TruthParticle.
Definition: TruthParticle_v1.cxx:131
egammaParameters::depth
@ depth
pointing depth of the shower as calculated in egammaqgcld
Definition: egammaParamDefs.h:276
InDet::InDetTrackTruthOriginTool::m_truthMatchProbabilityAuxName
std::string m_truthMatchProbabilityAuxName
Definition: InDetTrackTruthOriginTool.h:57
xAOD::TruthParticle_v1::isElectron
bool isElectron() const
Whether the particle is an electron (or positron)
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
InDet::TrkOrigin::Pileup
@ Pileup
Definition: InDetTrackTruthOriginDefs.h:20
xAOD::TruthParticle_v1::isCharmHadron
bool isCharmHadron() const
Determine if the PID is that of a c-hadron.
InDet::InDetTrackTruthOriginTool::initialize
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: InDetTrackTruthOriginTool.cxx:35
InDet::InDetTrackTruthOriginTool::isFromRec
virtual bool isFromRec(const xAOD::TruthParticle *truth, int flav, int depth=0) const
recursion-safe(r) version of isFrom
Definition: InDetTrackTruthOriginTool.cxx:219
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
TruthParticleContainer.h
InDet::TrkOrigin::Fake
@ Fake
Definition: InDetTrackTruthOriginDefs.h:18
InDet::InDetTrackTruthOriginTool::m_matchingProbabilityCut
float m_matchingProbabilityCut
Definition: InDetTrackTruthOriginTool.h:54
TruthLink
ElementLink< xAOD::TruthParticleContainer > TruthLink
Definition: TruthRelatedMuonPlotOrganizer.cxx:12
InDet::TrkOrigin::TauDecay
@ TauDecay
Definition: InDetTrackTruthOriginDefs.h:26
asg
Definition: DataHandleTestTool.h:28
InDet::TrkOrigin::KshortDecay
@ KshortDecay
Definition: InDetTrackTruthOriginDefs.h:22
InDet::TrkOrigin::DHadronDecay
@ DHadronDecay
Definition: InDetTrackTruthOriginDefs.h:33
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
InDet::TrkOrigin::OtherOrigin
@ OtherOrigin
Definition: InDetTrackTruthOriginDefs.h:37
InDet::InDetTrackTruthOriginTool::getTrackOrigin
virtual int getTrackOrigin(const xAOD::TrackParticle *track) const override
Computes the track origin.
Definition: InDetTrackTruthOriginTool.cxx:163
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
xAOD::TruthParticle_v1::nParents
size_t nParents() const
Number of parents of this particle.
Definition: TruthParticle_v1.cxx:122
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
HepMC::is_simulation_particle
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
Definition: MagicNumbers.h:355
InDet::InDetTrackTruthOriginTool::m_isFullPileupTruth
bool m_isFullPileupTruth
Definition: InDetTrackTruthOriginTool.h:59
InDet::TrkOrigin::BHadronDecay
@ BHadronDecay
Definition: InDetTrackTruthOriginDefs.h:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
DMTest::links
links
Definition: CLinks_v1.cxx:22
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
InDet::TrkOrigin::StrangeBaryonDecay
@ StrangeBaryonDecay
Definition: InDetTrackTruthOriginDefs.h:25
test_pyathena.parent
parent
Definition: test_pyathena.py:15
xAOD::TruthEvent_v1
Class describing a signal truth event in the MC record.
Definition: TruthEvent_v1.h:35
InDet::TrkOrigin::GammaConversion
@ GammaConversion
Definition: InDetTrackTruthOriginDefs.h:27
InDet::InDetTrackTruthOriginTool::isFrom
virtual bool isFrom(const xAOD::TruthParticle *truth, int flav) const override
Check if a truth particle is from the specified origin (from B or D hadron, or tau)
Definition: InDetTrackTruthOriginTool.cxx:215
InDet::TrkOrigin::LambdaDecay
@ LambdaDecay
Definition: InDetTrackTruthOriginDefs.h:24
InDet::TrkOrigin::OtherDecay
@ OtherDecay
Definition: InDetTrackTruthOriginDefs.h:28
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
xAOD::TruthParticle_v1::isBottomHadron
bool isBottomHadron() const
Determine if the PID is that of a b-hadron.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
MagicNumbers.h
InDetTrackTruthOriginTool.h
InDet::TrkOrigin::Fragmentation
@ Fragmentation
Definition: InDetTrackTruthOriginDefs.h:35
InDetTrackTruthOriginDefs.h
InDet::TrkOrigin::isFragmentation
bool isFragmentation(int origin)
not from B, D, or any secondary
Definition: InDetTrackTruthOriginDefs.h:143
InDet::InDetTrackTruthOriginTool::getTruth
virtual const xAOD::TruthParticle * getTruth(const xAOD::TrackParticle *track) const override
Safely access a track's linked truth particle, if available.
Definition: InDetTrackTruthOriginTool.cxx:40
InDet::TrkOrigin::OtherSecondary
@ OtherSecondary
Definition: InDetTrackTruthOriginDefs.h:30
xAOD::parentId
@ parentId
Definition: TrackingPrimitives.h:516
InDet::TrkOrigin::HadronicInteraction
@ HadronicInteraction
Definition: InDetTrackTruthOriginDefs.h:29
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
TruthEventContainer.h
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
InDet::InDetTrackTruthOriginTool::getTruthOrigin
virtual int getTruthOrigin(const xAOD::TruthParticle *truth) const override
Computes the truth particle origin.
Definition: InDetTrackTruthOriginTool.cxx:66