ATLAS Offline Software
Loading...
Searching...
No Matches
ParticleJetTools::FatVertex Namespace Reference

Classes

struct  VertexType
struct  FatVertex

Enumerations

enum class  DetailedVertexType {
  PrimaryVertex , BHadronDecay , CHadronDecay , CHadronDecayFromBHadron ,
  TauDecay , TauDecayFromBHadron , StrangeDecay , StrangeFromBHadron ,
  StrangeFromCHadron , StrangeFromCFromBHadron , StrangeFromTau , StrangeFromTauFromBHadron ,
  PionDecay , MaterialInteraction , MaybeMaterialInteraction , StrangeOscillation ,
  OtherSecondaryVertex , PhotoelectricEmission , ComptonScattering , EPAnnihilation ,
  Bremsstrahlung , Conversion , Other , OtherNInparts ,
  OtherNoOutparts , OtherSingleOutpart
}
enum class  SimpleVertexType {
  PrimaryVertex , BHadronDecay , CHadronDecay , TauDecay ,
  StrangeDecay , PionDecay , MaterialInteraction , OtherSecondaryVertex ,
  Other
}

Functions

TLorentzVector sum_4vec (const std::vector< const xAOD::TruthParticle * > &parts)
float vertex_distance (const xAOD::TruthVertex *v1, const xAOD::TruthVertex *v2)
float vertex_distance_xy (const xAOD::TruthVertex *v1, const xAOD::TruthVertex *v2)
int num_valid_children (const xAOD::TruthParticle *part)
bool has_valid_child (const xAOD::TruthParticle *part)
std::vector< const xAOD::TruthParticle * > get_valid_children_by_pt (const xAOD::TruthParticle *part)
void generateFatVertex (const xAOD::TruthVertex *vertex, std::vector< const xAOD::TruthParticle * > &fat_inparts, std::vector< const xAOD::TruthParticle * > &fat_internal, std::vector< const xAOD::TruthParticle * > &fat_outparts, bool internal, const float truthVertexMergeDistance, const std::vector< const xAOD::TruthParticle * > &additional_in_parts)
 Generates a fat vertex by recursively searching children of the provided truth vertex and adding them to either the in parts, internal parts, or out parts.
std::vector< FatVertexgenerateFatVertices (const xAOD::TruthVertex *pv, const float truthVertexMergeDistance, const std::vector< const xAOD::TruthParticle * > &truth_particles)

Enumeration Type Documentation

◆ DetailedVertexType

Enumerator
PrimaryVertex 
BHadronDecay 
CHadronDecay 
CHadronDecayFromBHadron 
TauDecay 
TauDecayFromBHadron 
StrangeDecay 
StrangeFromBHadron 
StrangeFromCHadron 
StrangeFromCFromBHadron 
StrangeFromTau 
StrangeFromTauFromBHadron 
PionDecay 
MaterialInteraction 
MaybeMaterialInteraction 
StrangeOscillation 
OtherSecondaryVertex 
PhotoelectricEmission 
ComptonScattering 
EPAnnihilation 
Bremsstrahlung 
Conversion 
Other 
OtherNInparts 
OtherNoOutparts 
OtherSingleOutpart 

Definition at line 27 of file FatVertex.h.

27 {
50 Other,
54 };
@ PionDecay

◆ SimpleVertexType

Enumerator
PrimaryVertex 
BHadronDecay 
CHadronDecay 
TauDecay 
StrangeDecay 
PionDecay 
MaterialInteraction 
OtherSecondaryVertex 
Other 

Definition at line 55 of file FatVertex.h.

Function Documentation

◆ generateFatVertex()

void ParticleJetTools::FatVertex::generateFatVertex ( const xAOD::TruthVertex * vertex,
std::vector< const xAOD::TruthParticle * > & fat_inparts,
std::vector< const xAOD::TruthParticle * > & fat_internal,
std::vector< const xAOD::TruthParticle * > & fat_outparts,
bool internal,
const float truthVertexMergeDistance,
const std::vector< const xAOD::TruthParticle * > & additional_in_parts )

Generates a fat vertex by recursively searching children of the provided truth vertex and adding them to either the in parts, internal parts, or out parts.

Parameters
vertexThe truth vertex to search truth particles from
fat_inpartsThe vector of incoming particles to the fat vertex
fat_internalThe vector of internal particles to the fat vertex
fat_outpartsThe vector of outgoing particles to the fat vertex
internalWhether the current vertex is internal to the process
truthVertexMergeDistanceThe distance in mm to merge two vertices
additionalinput particles which come from the PV

Definition at line 77 of file FatVertex.cxx.

85 {
86 if ( !vertex ) return;
87 std::vector<const xAOD::TruthParticle*> out_particles = vertex->particles_out();
88 std::vector<const xAOD::TruthParticle*> in_particles = vertex->particles_in();
89
90 for(auto part : additional_in_parts){
91 if(part){
92 if (std::find(in_particles.begin(), in_particles.end(), part) == in_particles.end()){
93 in_particles.push_back(part);
94 }
95
96 if(part->hasDecayVtx() && part->decayVtx()){
97 for(auto child : part->decayVtx()->particles_out()){
98 if(child && std::find(out_particles.begin(), out_particles.end(), child) == out_particles.end()){
99 out_particles.push_back(child);
100 }
101 }
102 }
103 }
104 }
105 for ( auto part : in_particles ) {
106 if ( !part ) continue;
107 // Check that the current particle being checked is not already in the fat vertex
108 if ( std::find(fat_inparts.begin(), fat_inparts.end(), part) == fat_inparts.end()
109 && std::find(fat_internal.begin(), fat_internal.end(), part) == fat_internal.end()
110 && std::find(fat_outparts.begin(), fat_outparts.end(), part) == fat_outparts.end() ) {
111 // If 'internal' is false, we treat any 'internal' parts of a process as inputs
112 if ( internal ) fat_internal.push_back(part);
113 else fat_inparts.push_back(part);
114 }
115 }
116 for ( auto part : out_particles ) {
117 if ( !part ) continue;
118 if (
119 std::find(fat_inparts.begin(), fat_inparts.end(), part) != fat_inparts.end() ||
120 std::find(fat_internal.begin(), fat_internal.end(), part) != fat_internal.end() ||
121 std::find(fat_outparts.begin(), fat_outparts.end(), part) != fat_outparts.end()
122 ) continue;
123 // Simulation particles (status != 1,2) without a usable decay vertex:
124 // add as outparts (they're stable children of the current vertex).
125 // Sim particles WITH a decay vertex fall through to normal processing
126 // (merge distance check, single-child skip, outpart logic).
127 if (!(part->status() == 1 || part->status() == 2)){
128 if (!part->hasDecayVtx() || !part->decayVtx() || !has_valid_child(part)) {
129 fat_outparts.push_back(part);
130 continue;
131 }
132 }
133
134 // We have a particle which says it has a child, but its invalid -> end state particle,
135 // ->we add it to the outputs
136 if ( !has_valid_child(part) || !(part->hasDecayVtx() && part->decayVtx()) ) {
137 fat_outparts.push_back(part);
138 continue;
139 }
140
141 if(
142 !fat_inparts.empty() &&
143 part->hasDecayVtx() && part->decayVtx() &&
144 fat_inparts[0]->hasDecayVtx() && fat_inparts[0]->decayVtx() &&
145 vertex_distance(part->decayVtx(), fat_inparts[0]->decayVtx()) < truthVertexMergeDistance
146 ){
148 part->decayVtx(), fat_inparts, fat_internal, fat_outparts, true, truthVertexMergeDistance
149 );
150 continue;
151 }
152
153 // Check valid children sorted by pT
154 std::vector<const xAOD::TruthParticle*> valid_children = get_valid_children_by_pt(part);
155
156 // Single valid child with same pdgId = simple scattering (e- -> e-, pi -> pi)
157 // Not a reconstructable vertex — absorb as internal and continue
158 if ( valid_children.size() == 1 &&
159 valid_children[0]->pdgId() == part->pdgId() ) {
161 part->decayVtx(), fat_inparts, fat_internal, fat_outparts, true,
162 truthVertexMergeDistance
163 );
164 continue;
165 }
166
167 // Multiple children but highest-pT has same pdgId = brem/scattering + radiation
168 // (e- -> e- + gamma). The leading child is the same particle continuing —
169 // absorb as internal so the vertex is attributed to where it actually interacts
170 if ( valid_children.size() >= 2 &&
171 valid_children[0]->pdgId() == part->pdgId() ) {
173 part->decayVtx(), fat_inparts, fat_internal, fat_outparts, true,
174 truthVertexMergeDistance
175 );
176 continue;
177 }
178
179 // Strange hadron oscillation (K0 -> K0bar etc)
180 if ( valid_children.size() == 1 &&
181 part->isStrangeHadron() && valid_children[0]->isStrangeHadron() ) {
183 part->decayVtx(), fat_inparts, fat_internal, fat_outparts, true,
184 truthVertexMergeDistance
185 );
186 continue;
187 }
188 fat_outparts.push_back(part);
189 }
190 }
bool has_valid_child(const xAOD::TruthParticle *part)
Definition FatVertex.cxx:33
float vertex_distance(const xAOD::TruthVertex *v1, const xAOD::TruthVertex *v2)
Definition FatVertex.cxx:53
std::vector< const xAOD::TruthParticle * > get_valid_children_by_pt(const xAOD::TruthParticle *part)
Definition FatVertex.cxx:42
void generateFatVertex(const xAOD::TruthVertex *vertex, std::vector< const xAOD::TruthParticle * > &fat_inparts, std::vector< const xAOD::TruthParticle * > &fat_internal, std::vector< const xAOD::TruthParticle * > &fat_outparts, bool internal, const float truthVertexMergeDistance, const std::vector< const xAOD::TruthParticle * > &additional_in_parts=std::vector< const xAOD::TruthParticle * >())
Generates a fat vertex by recursively searching children of the provided truth vertex and adding them...
Definition FatVertex.cxx:77

◆ generateFatVertices()

std::vector< FatVertex > ParticleJetTools::FatVertex::generateFatVertices ( const xAOD::TruthVertex * pv,
const float truthVertexMergeDistance,
const std::vector< const xAOD::TruthParticle * > & truth_particles )

Definition at line 192 of file FatVertex.cxx.

196 {
197 std::vector<FatVertex> fat_vertices;
198 std::vector<const xAOD::TruthParticle*> searched;
199 std::vector<const xAOD::TruthParticle*> to_search;
200
201 to_search.push_back(pv->incomingParticle(0));
202
203 bool is_pv = true;
204 while ( !to_search.empty() ) {
205 const xAOD::TruthParticle* part = to_search.back();
206
207 to_search.pop_back();
208 searched.push_back(part);
209 if (!part || !part->hasDecayVtx() ) continue;
210 // If the particles first child is invalid, then all are, and we can skip it...
211 if(num_valid_children(part) == 0){
212 continue;
213 }
214 std::vector<const xAOD::TruthParticle*> inparts, internal, outparts;
216 part->decayVtx(), inparts, internal, outparts,
217 false, truthVertexMergeDistance,
218 is_pv ? truth_particles : std::vector<const xAOD::TruthParticle*>(0, nullptr)
219 );
220 // A vertex requires multiple outgoing particles. Accept if either:
221 // - multiple outparts survived thinning, OR
222 // - the inpart's nChildren >= 2 (truth record says real multi-body
223 // decay/interaction, even if some children were thinned)
224 bool is_real_vertex = outparts.size() > 1;
225 if (!is_real_vertex && !inparts.empty() && inparts[0] && inparts[0]->nChildren() >= 2) {
226 is_real_vertex = true;
227 }
228 if ( is_real_vertex ){
229 fat_vertices.push_back(FatVertex(inparts, internal, outparts, is_pv));
230 is_pv = false;
231 }
232
233 // Once a fat-vertex is completed, we ensure we don't search any of its particles
234 // again
235 for ( auto inp : inparts ) {
236 if ( std::find(searched.begin(), searched.end(), inp) == searched.end() ) {
237 searched.push_back(inp);
238 }
239 if(std::find(to_search.begin(), to_search.end(), inp) != to_search.end()){
240 to_search.erase(
241 std::remove(to_search.begin(), to_search.end(), inp),
242 to_search.end());
243 }
244 }
245 for ( auto intern : internal ) {
246 if ( std::find(searched.begin(), searched.end(), intern) == searched.end() ) {
247 searched.push_back(intern);
248 }
249 if(std::find(to_search.begin(), to_search.end(), intern) != to_search.end()){
250 to_search.erase(
251 std::remove(to_search.begin(), to_search.end(), intern),
252 to_search.end());
253 }
254 }
255 for ( auto outp : outparts ) {
256 if ( std::find(searched.begin(), searched.end(), outp) == searched.end()
257 && std::find(to_search.begin(), to_search.end(), outp) == to_search.end() ) {
258 to_search.push_back(outp);
259 }
260 }
261 }
262
263 // Iterate all fat vertices, and remove any with 0 out particles, as these are actually
264 // just stable particles
265 fat_vertices.erase(
267 fat_vertices.begin(),
268 fat_vertices.end(),
269 [](const FatVertex& fv) {
270 return fv.outparts.empty();
271 }
272 ),
273 fat_vertices.end()
274 );
275
276 return fat_vertices;
277 }
std::ostream * outp
send output to here ...
Definition hcg.cxx:76
int num_valid_children(const xAOD::TruthParticle *part)
Definition FatVertex.cxx:23
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
TruthParticle_v1 TruthParticle
Typedef to implementation.

◆ get_valid_children_by_pt()

std::vector< const xAOD::TruthParticle * > ParticleJetTools::FatVertex::get_valid_children_by_pt ( const xAOD::TruthParticle * part)

Definition at line 42 of file FatVertex.cxx.

42 {
43 std::vector<const xAOD::TruthParticle*> children;
44 if ( !part->hasDecayVtx() || !part->decayVtx() ) return children;
45 for ( auto child : part->decayVtx()->particles_out() ) {
46 if ( child ) children.push_back(child);
47 }
48 std::sort(children.begin(), children.end(),
49 [](const xAOD::TruthParticle* a, const xAOD::TruthParticle* b) { return a->pt() > b->pt(); });
50 return children;
51 }
static Double_t a
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ has_valid_child()

bool ParticleJetTools::FatVertex::has_valid_child ( const xAOD::TruthParticle * part)

Definition at line 33 of file FatVertex.cxx.

33 {
34 if ( part->nChildren() == 0 ) { return false; }
35 if ( !part->hasDecayVtx() || !part->decayVtx() ) { return false; }
36 for ( auto child : part->decayVtx()->particles_out() ) {
37 if ( child ) return true;
38 }
39 return false;
40 }

◆ num_valid_children()

int ParticleJetTools::FatVertex::num_valid_children ( const xAOD::TruthParticle * part)

Definition at line 23 of file FatVertex.cxx.

23 {
24 if ( part->nChildren() == 0 ) { return 0; }
25 if ( !part->hasDecayVtx() || !part->decayVtx() ) { return 0; }
26 int num_valid = 0;
27 for ( auto child : part->decayVtx()->particles_out() ) {
28 if ( child ) num_valid++;
29 }
30 return num_valid;
31 }

◆ sum_4vec()

TLorentzVector ParticleJetTools::FatVertex::sum_4vec ( const std::vector< const xAOD::TruthParticle * > & parts)

Definition at line 14 of file FatVertex.cxx.

14 {
15 TLorentzVector sum;
16 for ( auto part : parts ) {
17 if ( !part ) continue;
18 sum += part->p4();
19 }
20 return sum;
21 }

◆ vertex_distance()

float ParticleJetTools::FatVertex::vertex_distance ( const xAOD::TruthVertex * v1,
const xAOD::TruthVertex * v2 )

Definition at line 53 of file FatVertex.cxx.

53 {
54 if ( !v1 || !v2 ) return NAN;
55 return std::sqrt(
56 std::pow(v1->x() - v2->x(), 2) + std::pow(v1->y() - v2->y(), 2) +
57 std::pow(v1->z() - v2->z(), 2)
58 );
59 }
float z() const
Vertex longitudinal distance along the beam line form the origin.
float y() const
Vertex y displacement.
float x() const
Vertex x displacement.

◆ vertex_distance_xy()

float ParticleJetTools::FatVertex::vertex_distance_xy ( const xAOD::TruthVertex * v1,
const xAOD::TruthVertex * v2 )

Definition at line 61 of file FatVertex.cxx.

61 {
62 if ( !v1 || !v2 ) return NAN;
63 return std::sqrt(
64 std::pow(v1->x() - v2->x(), 2) + std::pow(v1->y() - v2->y(), 2)
65 );
66 }