ATLAS Offline Software
MuonDecayTruthTrajectoryBuilder.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 // Niels van Eldik 2010
6 
8 
9 #include <stack>
10 
12 #include "AtlasHepMC/GenParticle.h"
13 #include "AtlasHepMC/GenVertex.h"
17 
18 namespace Muon {
19 
20  //================================================================
22  const IInterface* parent) :
24  // ,m_isDecayIntoTwoMuons(false)
25  {
26  declareInterface<Trk::ITruthTrajectoryBuilder>(this);
27  }
28  //================================================================
30  result->clear();
31  if (input) {
33  auto current = input;
34  ATH_MSG_DEBUG(" New TruthTrajectory: input: " << input << " PDG id " << input->pdg_id());
35 
36  // Extend trajectory outwards. The last particle should go at [0]
37  // in the TruthTrajectory, so we need to use a tmp storage while
38  // traversing the structure.
39  std::stack<HepMC::ConstGenParticlePtr> tmp;
40  while ((next = getDaughter(current))) { tmp.push(current = next); }
41 
42  // copy the outer half to result
43  while (!tmp.empty()) {
44  ATH_MSG_DEBUG(" Adding daughter: " << current); // FIXME "current" is not changed in this loop - it might make sense to print tmp.top() instead here?
45  result->emplace_back(tmp.top(),tmp.top()->parent_event()->event_number(),HepMcParticleLink::IS_EVENTNUM);
46  tmp.pop();
47  }
48 
49  // The input particle itself
50  result->emplace_back(input,input->parent_event()->event_number(),HepMcParticleLink::IS_EVENTNUM);
51 
52  // Now continue towards the interaction point
53  while ((next = getMother(current))) {
54  ATH_MSG_DEBUG(" Adding mother: " << current); // FIXME "current" here refers to the child particle rather than the mother? Consider moving this after "current = next"
55  current = next;
56  result->emplace_back(current,current->parent_event()->event_number(),HepMcParticleLink::IS_EVENTNUM);
57  }
58 
59  ATH_MSG_DEBUG(" Final TruthTrajectory: ");
60  std::vector<HepMcParticleLink>::const_iterator pit = result->begin();
61  std::vector<HepMcParticleLink>::const_iterator pit_end = result->end();
62  for (; pit != pit_end; ++pit) {
63  const HepMC::GenParticle& par = *pit->cptr();
64  if (msgLvl(MSG::DEBUG)) {
65  msg(MSG::DEBUG) << " PDG ID " << par.pdg_id()
66  << " pt: " << par.momentum().perp();
67  if (par.production_vertex())
68  msg(MSG::DEBUG) << " vertices prod: r " << par.production_vertex()->position().perp() << " z "
69  << par.production_vertex()->position().z();
70  if (par.end_vertex())
71  msg(MSG::DEBUG) << " end: r " << par.end_vertex()->position().perp() << " z " << par.end_vertex()->position().z();
72  msg(MSG::DEBUG) << endmsg;
73  }
74  }
75  }
76  }
77 
78  //================================================================
80  const HepMC::ConstGenVertexPtr& vtx) const {
81  HepMC::ConstGenParticlePtr mother{nullptr};
82  HepMC::ConstGenParticlePtr daughter{nullptr};
83  int particles_in_size = vtx ? vtx->particles_in_size() : 0;
84  int particles_out_size = vtx ? vtx->particles_out_size() : 0;
85  if (vtx && msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << " new vertex: nparticles in " << particles_in_size << endmsg;
86  // only truth vertices with 1 incoming particle
87  if (vtx && (particles_in_size == 1)) {
88 #ifdef HEPMC3
89  mother = vtx->particles_in().front();
90 #else
91  mother = *vtx->particles_in_const_begin();
92 #endif
93 
94  if (mother && msgLvl(MSG::DEBUG))
95  msg(MSG::DEBUG) << " new mother: " << mother->pdg_id() << " status " << mother->status() << " particles out "
96  << particles_out_size << endmsg;
97  // Allow status code 1 and 2. E.g. a pion that produced a long track can decay outside of InDet and have status==2.
98  if (mother && MC::isPhysical(mother)) {
99  unsigned int nDecayMuons = 0;
100  HepMC::ConstGenParticlePtr passed_cuts{nullptr};
101  for (const auto& candidate : *vtx) {
102  if (msgLvl(MSG::DEBUG)) {
103  msg(MSG::DEBUG) << " PDG ID " << candidate->pdg_id() << " particle: " << candidate
104  << " pt: " << candidate->momentum().perp();
105  if (candidate->production_vertex())
106  msg(MSG::DEBUG) << " vertices prod: r " << candidate->production_vertex()->position().perp() << " z "
107  << candidate->production_vertex()->position().z();
108  if (candidate->end_vertex())
109  msg(MSG::DEBUG) << " end: r " << candidate->end_vertex()->position().perp() << " z "
110  << candidate->end_vertex()->position().z();
111  msg(MSG::DEBUG) << endmsg;
112  }
113 
114  if (candidate->pdg_id() == mother->pdg_id()) {
115  if (passed_cuts && MC::isElectron(mother)) { // second negative electron is a special case
116  if (candidate->momentum().e() > passed_cuts->momentum().e()) { passed_cuts = candidate; }
117  } else {
118  passed_cuts = candidate;
119  }
120  } else if (MC::isMuon(candidate)) {
121  ATH_MSG_DEBUG(" selecting Decay into muon ");
122  ++nDecayMuons;
123  passed_cuts = candidate;
124  } else { // temp addition for debugging
125  msg(MSG::DEBUG) << " Neither muon nor identical pdgId " << endmsg;
126  passed_cuts = candidate;
127  }
128  }
129 
130  if (nDecayMuons > 0) {
131  daughter = passed_cuts;
132  if (nDecayMuons == 2) {
133  ATH_MSG_DEBUG(" decay into two muons ");
134  // m_isDecayIntoTwoMuons = true;
135  }
136  }
137  }
138  }
139 
140  return std::make_pair(mother, daughter);
141  }
142 
143  //================================================================
145  if(mother) {
146  MotherDaughter res = truthTrajectoryCuts(mother->end_vertex());
147  if(res.first == mother) return res.second;
148  }
149  return {nullptr};
150  }
151 
152  //================================================================
154  return daughter ? truthTrajectoryCuts(daughter->production_vertex()).first : HepMC::ConstGenParticlePtr{nullptr};
155  }
156 
157  //================================================================
158 
159 } // namespace Muon
fillPileUpNoiseLumi.current
current
Definition: fillPileUpNoiseLumi.py:52
get_generator_info.result
result
Definition: get_generator_info.py:21
GenVertex.h
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Muon
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Definition: TrackSystemController.h:45
GenParticle.h
Muon::MuonDecayTruthTrajectoryBuilder::MotherDaughter
std::pair< HepMC::ConstGenParticlePtr, HepMC::ConstGenParticlePtr > MotherDaughter
Return type for the next method.
Definition: MuonDecayTruthTrajectoryBuilder.h:37
MC::isPhysical
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
Definition: HepMCHelpers.h:51
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
Muon::MuonDecayTruthTrajectoryBuilder::MuonDecayTruthTrajectoryBuilder
MuonDecayTruthTrajectoryBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Definition: MuonDecayTruthTrajectoryBuilder.cxx:21
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
Muon::MuonDecayTruthTrajectoryBuilder::getDaughter
HepMC::ConstGenParticlePtr getDaughter(const HepMC::ConstGenParticlePtr &particle) const override
Returns an umambiguous daughter of the truth particle on a TruthTrajectory, or 0.
Definition: MuonDecayTruthTrajectoryBuilder.cxx:144
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:12
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
test_pyathena.parent
parent
Definition: test_pyathena.py:15
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
MuonDecayTruthTrajectoryBuilder.h
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
TruthTrajectory
Definition: TruthTrajectory.h:26
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
Muon::MuonDecayTruthTrajectoryBuilder::truthTrajectoryCuts
MotherDaughter truthTrajectoryCuts(const HepMC::ConstGenVertexPtr &vtx) const
Decides if the vertex connects two particles on the same TruthTrajectory.
Definition: MuonDecayTruthTrajectoryBuilder.cxx:79
DataVector.h
An STL vector of pointers that by default owns its pointed-to elements.
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TruthTrajectory.h
HepMC::ConstGenVertexPtr
const HepMC::GenVertex * ConstGenVertexPtr
Definition: GenVertex.h:60
AthAlgTool
Definition: AthAlgTool.h:26
Muon::MuonDecayTruthTrajectoryBuilder::getMother
HepMC::ConstGenParticlePtr getMother(const HepMC::ConstGenParticlePtr &particle) const override
Returns an umambiguous mother of the truth particle on a TruthTrajectory, or 0.
Definition: MuonDecayTruthTrajectoryBuilder.cxx:153
Muon::MuonDecayTruthTrajectoryBuilder::buildTruthTrajectory
void buildTruthTrajectory(TruthTrajectory *result, const HepMC::ConstGenParticlePtr &input) const override
Build a TruthTrajectory this particle belongs to.
Definition: MuonDecayTruthTrajectoryBuilder.cxx:29
HepMCHelpers.h
GenParticle
@ GenParticle
Definition: TruthClasses.h:30
isMuon
bool isMuon(const T &p)
Definition: AtlasPID.h:170