ATLAS Offline Software
Loading...
Searching...
No Matches
MuonSpectrometer/MuonValidation/MuonVertexValidation/src/Utils.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#include "Utils.h"
6
7
9
10double getCTau(const xAOD::TruthVertex *decVtx){
11 // compute the ctau for a given decay vertex via: ctau = |r|/gamma
12 return decVtx->v4().Vect().Mag() / decVtx->genvecV4().Gamma();
13}
14
15
16double getCalEnergyLogRatio(double EMF){
17 double logRatio{-99.};
18 double zero{0.};
19 double one{1.};
20
22 if(CxxUtils::fpcompare::greater_equal(EMF,one)) logRatio = -999.;
23 else logRatio = std::log10(double(1./EMF - 1.));
24 }
25 else {
26 logRatio = 999;
27 }
28
29 return logRatio;
30}
31
32
34 return (part1->pt()>part2->pt());
35}
36
37
38std::vector<const xAOD::TruthParticle*> getChildren(const xAOD::TruthParticle* mother){
39 // returns pointers to children of a given particle
40 if (!mother) return {};
41
42 std::vector<const xAOD::TruthParticle*> children{};
43 for (size_t i=0; i<mother->nChildren(); ++i) {
44 const xAOD::TruthParticle* child = mother->child(i);
45 // avoid infinite loop
46 if (!child || child == mother) continue;
47 children.push_back(child);
48 }
49
50 return children;
51}
52
53
54std::vector<const xAOD::TruthParticle*> getStableChildrenRecursive(const xAOD::TruthParticle* particle, bool findOnlyGenStable, std::unordered_set<const xAOD::TruthParticle*>& visited){
55 // Can either find all stable particles or only those that are generator stable only.
56
57 std::vector<const xAOD::TruthParticle*> stableChildren;
58 // Base case: if the particle is null or has already been visited, return empty vector
59 if (!particle || visited.count(particle)) return stableChildren;
60 visited.insert(particle);
61
62 // Return the particle if it is stable
63 bool particleIsStable = findOnlyGenStable ? particle->isGenStable() : particle->isStable();
64 if (particleIsStable) {
65 stableChildren.push_back(particle);
66 return stableChildren;
67 }
68
69 // Recursive case: get the children of the particle and traverse their decay chains
70 std::vector<const xAOD::TruthParticle*> children = getChildren(particle);
71 for (const xAOD::TruthParticle* child : children) {
72 if (!child) continue;
73 std::vector<const xAOD::TruthParticle*> grandChildren = getStableChildrenRecursive(child, findOnlyGenStable, visited);
74 for (const xAOD::TruthParticle* c : grandChildren) {
75 if (std::none_of(stableChildren.begin(), stableChildren.end(), [&](const auto& x) {return x==c;})) stableChildren.push_back(c);
76 }
77 }
78
79 return stableChildren;
80}
81
82
83std::vector<const xAOD::TruthParticle*> getStableChildren(const xAOD::TruthParticle* particle, bool findOnlyGenStable){
84 // Finds the stable decay products of a given particle. Can either find all stable particles or only those that are generator stable only.
85 // Interface to the recursive function that traverses the decay chain of the particle.
86 std::unordered_set<const xAOD::TruthParticle*> visited; // keeps track of visited particles to avoid infinite loops in decay chains
87 return getStableChildrenRecursive(particle, findOnlyGenStable, visited);
88}
89
90
91std::vector<const xAOD::TruthParticle*> getDecayProducts(const xAOD::TruthVertex* vtx){
92 // Returns the decay products of a given vertex. Use this instead of vtx->particles_out() to remove null pointers.
93 std::vector<const xAOD::TruthParticle*> decayProducts;
94 if (!vtx) return decayProducts;
95
96 for (size_t i = 0; i < vtx->nOutgoingParticles(); ++i) {
97 const xAOD::TruthParticle* tp = vtx->outgoingParticle(i);
98 if (!tp) continue;
99 decayProducts.push_back(tp);
100 }
101
102 return decayProducts;
103}
104
105
106
107std::vector<ActiveVertex> getActiveVertices(const xAOD::Jet* jet, const xAOD::TruthParticleContainer& truthParticles){
108 // Finds active vertices in the ancestry tree of the Truth particles close to the jet
109 // Production vertices passing the minimal activity requirements are stored as ActiveVertex objects
110
111 std::set<const xAOD::TruthVertex*> seenVertices; // vertices already seen in the ancestry tree
112 std::vector<ActiveVertex> actVertices; // holds all the active vertices associated with the jet
113 std::vector<const xAOD::TruthParticle*> children; // decay products of the current vertex
114 size_t nChildren{0};
115
116 for (const xAOD::TruthParticle* tp : truthParticles){
117 if (!tp || !tp->isStable() || jet->p4().DeltaR(tp->p4()) > 0.4) continue; // only final state particles close to the jet axis will pass
118 if (!HepMC::is_simulation_particle(tp)) continue; // only simulated particles will pass.
119
120 size_t decayDepth{0};
121 const xAOD::TruthParticle* current = tp;
122 while (current) {
123 if (decayDepth > 200) break; // safety break
124 // prevent loop from going too deep where the truth record contains information used for generator internal book keeping
125 // add check on HepMC::is_simulation_particle(current) to limit to GEANT4 layer of ancestry
126 if (!MC::isPhysical(current)) break;
127 const xAOD::TruthVertex* prodVtx = current->prodVtx();
128 if (!prodVtx || seenVertices.count(prodVtx)) break; // No more ancestry or already visited.
129 if (prodVtx->v4().Mag2() < 0) break; // minimal requirements on the vertex: physical spacetime interval
130 seenVertices.insert(prodVtx);
131 decayDepth++;
132
133 children = getDecayProducts(prodVtx);
134 nChildren = children.size();
135 // requirements for an active vertex
136 if (nChildren >= 2) {
137 TLorentzVector vtx4Vec;
138 float scalarPtSum{0.};
139 for (const xAOD::TruthParticle* child : children) {
140 vtx4Vec += child->p4();
141 scalarPtSum += child->p4().Pt();
142 }
143 actVertices.push_back({prodVtx, vtx4Vec.E(), vtx4Vec.M(), vtx4Vec.Pt(), scalarPtSum, nChildren, decayDepth});
144 }
145 current = prodVtx->incomingParticle(0); // move up one level in the ancestor tree
146 }
147 }
148
149 return actVertices;
150}
151
152
154 double trackIso_pT, double softTrackIso_R, double jetIso_pT, double jetIso_LogRatio){
155 // compute the isolation metrics of the MS vertex:
156 // - delta R to closest hard track
157 // - delta R to closest punch-through candidate jet
158 // - sum of soft track pT in a cone around the vertex
159
160 VtxIso iso{};
161 const Amg::Vector3D vtx_pos = vtx->position();
162
163 // isolation towards tracks
164 Amg::Vector3D softTrack_pTsum{Amg::Vector3D::Zero()};
165 double hardTrack_mindR{99.};
166 for(const xAOD::TrackParticle* Track : Tracks){
167 double dR = xAOD::P4Helpers::deltaR(vtx_pos.eta(), vtx_pos.phi(), Track->eta(), Track->phi());
168 // hard tracks
169 if(Track->pt() >= trackIso_pT && dR < hardTrack_mindR) hardTrack_mindR = dR;
170 // soft tracks
171 if(Track->pt() < trackIso_pT && dR < softTrackIso_R) softTrack_pTsum += Amg::Vector3D(Track->p4()[0], Track->p4()[1], Track->p4()[2]);
172 }
173
174 iso.track_mindR = hardTrack_mindR != 99. ? hardTrack_mindR : -1.;
175 iso.track_pTsum = softTrack_pTsum.mag() != 0. ? softTrack_pTsum.perp()/Gaudi::Units::GeV : -1.;
176
177 // isolation towards jets
178 double jet_mindR{99.};
179 for(const xAOD::Jet* Jet : Jets){
180 if(Jet->pt() < jetIso_pT) continue;
181 // if(!Jet->getAttribute<char>("passJVT")) continue;
182 double logratio = getCalEnergyLogRatio(Jet->getAttribute<float>("EMFrac"));
183 if(logratio >= jetIso_LogRatio) continue;
184
185 double dR = xAOD::P4Helpers::deltaR(vtx_pos.eta(), vtx_pos.phi(), Jet->eta(), Jet->phi());
186 if(dR < jet_mindR){
187 jet_mindR = dR;
188 }
189 }
190 iso.jet_mindR = jet_mindR != 99. ? jet_mindR : -1.;
191
192 return iso;
193}
194
195} // namespace MSVtxValidationAlgUtils
#define x
virtual double eta() const
pseudo rapidity
virtual double phi() const
phi in [-pi,pi[
virtual double pt() const
transverse momentum
const TruthParticle_v1 * child(size_t i) const
Retrieve the i-th mother (TruthParticle) of this TruthParticle.
size_t nChildren() const
Number of children of this particle.
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
FourVec_t v4() const
The full 4-vector of the vertex.
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
size_t nOutgoingParticles() const
Get the number of outgoing particles.
GenVecFourVec_t genvecV4() const
The full 4-vector of the particle : GenVector form.
const Amg::Vector3D & position() const
Returns the 3-pos.
void zero(TH2 *h)
zero the contents of a 2d histogram
Eigen::Matrix< double, 3, 1 > Vector3D
bool greater(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition fpcompare.h:140
bool greater_equal(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition fpcompare.h:192
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 Jets.py:1
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
std::vector< const xAOD::TruthParticle * > getDecayProducts(const xAOD::TruthVertex *vtx)
std::vector< const xAOD::TruthParticle * > getStableChildren(const xAOD::TruthParticle *particle, bool findOnlyGenStable)
std::vector< const xAOD::TruthParticle * > getChildren(const xAOD::TruthParticle *mother)
std::vector< const xAOD::TruthParticle * > getStableChildrenRecursive(const xAOD::TruthParticle *particle, bool findOnlyGenStable, std::unordered_set< const xAOD::TruthParticle * > &visited)
VtxIso getIso(const xAOD::Vertex *vtx, const xAOD::TrackParticleContainer &Tracks, const xAOD::JetContainer &Jets, double trackIso_pT, double softTrackIso_R, double jetIso_pT, double jetIso_LogRatio)
std::vector< ActiveVertex > getActiveVertices(const xAOD::Jet *jet, const xAOD::TruthParticleContainer &truthParticles)
bool comparePt(const xAOD::TruthParticle *part1, const xAOD::TruthParticle *part2)
Definition part1.py:1
Definition part2.py:1
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Jet_v1 Jet
Definition of the current "jet version".
TruthVertex_v1 TruthVertex
Typedef to implementation.
Definition TruthVertex.h:15
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.