ATLAS Offline Software
Loading...
Searching...
No Matches
Loops.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef XAOD_ANALYSIS
6#ifndef TRUTHUTILS_LOOPS_H
7#define TRUTHUTILS_LOOPS_H
8#include <algorithm>
9#include <vector>
10#include <memory>
11
12namespace MC {
13template <class Evt, class Prt, class Vtx>
14class Loops {
15public:
16
18 Loops() {}
19
21 Loops(const Evt* evt) {
22 findLoops(evt,true);
23 }
24
26 bool isLoop(const Prt& p) const {
27 return std::find(m_loop_particles.begin(), m_loop_particles.end(), p) != m_loop_particles.end();
28 }
29
31 bool isLoop(const Vtx& v) const {
32 return std::find(m_loop_vertices.begin(), m_loop_vertices.end(), v) != m_loop_vertices.end();
33 }
34
36 const std::vector<Prt>& loop_particles() const {
37 return m_loop_particles;
38 }
39
41 const std::vector<Vtx>& loop_vertices() const {
42 return m_loop_vertices;
43 }
44
47 int findLoops(const Evt* evt, bool force) {
48 // If the event is empty, return -1 (an error code, basically)
49 if (!evt) return -1;
50 // If we have already indexed the event and are not forced to do it again, return
51 if (evt == m_evt && !force) return 0;
52
53 // Update the local event pointer. This is now the most recent event that has been indexed.
54 m_evt = evt;
55 // Clear the lists of particles and vertices. These will now refer to this event.
56 m_loop_particles.clear();
57 m_loop_vertices.clear();
58
59 // Create a map, keeping track of whether particles are in loops.
60 // 0 for "unknown", 1 for "in a loop", -1 for "not in a loop"
61 std::map<Prt, int> incycle;
62
63 // Easiest case to deal with: if a particle has no production or end vertex, it is not in a loop
64 for (const auto & p: *m_evt){
65 if (!p->end_vertex()||!p->production_vertex()){
66 incycle[p] = -1;
67 } else {
68 incycle[p] = 0;
69 }
70 }
71
72 // Now begin interating through particles to try to find loops
73 size_t minincycle = m_evt->particles_size();
74 for (;;) {
75 // Number of particles still unknown in the current iteration
76 size_t unknown = 0;
77 for (const auto & p: *m_evt) {
78
79 // If the particle was already identified as in/not in a loop, skip it
80 if (incycle[p] != 0) continue;
81 // Otherwise it is unknown on this iteration
82 unknown++;
83
84 // Start from the end vertex of the particle
85 auto ev = p->end_vertex();
86 if (ev) {
87 // If the end vertex of a particle exclusively has particles not in loops
88 // then this particle cannot be in a loop either
89 bool goodo = true;
90 for (auto& po: *ev) goodo = goodo && (incycle[po] == -1);
91 if (goodo) incycle[p] = -1;
92 }
93
94 // Now start from the production vertex of the particle
95 auto pv = p->production_vertex();
96 if (pv) {
97 // If the production vertex of a particle exclusively has particles not
98 // in loops, then this particle cannot be in a loop either
99 bool goodi = true;
100#ifdef HEPMC3
101 for (auto& pi: ev->particles_in()) goodi = goodi && (incycle[pi] == -1);
102#else
103 for (auto ip = ev->particles_in_const_begin();
104 ip != ev->particles_in_const_end();
105 ++ip)
106 {
107 goodi = goodi && (incycle[*ip] == -1);
108 }
109#endif
110 if (goodi) incycle[p] = -1;
111 }
112 }
113 // If the number of unknown particles has not changed, we are done iterating
114 if (minincycle == unknown) break;
115 // If the number of unknown particles has changed, update at iterate again
116 minincycle = std::min(minincycle, unknown);
117 } // Outer loop - iterate until all particles have been dealt with
118
119 // Any remaining particles that have not been identified are a part of a loop
120 // Add them to our list of looping particles
121 for (const auto & p: *m_evt){
122 if (incycle[p] == 0) incycle[p] = 1;
123 if (incycle[p] == 1) m_loop_particles.push_back(p);
124 }
125
126 // Now loop over all vertices.
127#ifdef HEPMC3
128 for (auto & v: m_evt->vertices()) {
129#else
130 for (auto iv = m_evt->vertices_begin(); iv != m_evt->vertices_end(); ++iv) {
131 auto v = *iv;
132#endif
133 bool push = false;
134 // First check incoming particles.
135 // If any incoming are in loops, consider this vertex to be in a loop.
136#ifdef HEPMC3
137 for ( auto& pin: v->particles_in()){
138 if (incycle[pin] == 1) {
139#else
140 for ( auto ipin = v->particles_in_const_begin();
141 ipin != v->particles_in_const_end();
142 ++ipin){
143 if (incycle[*ipin] == 1) {
144#endif
145 push = true;
146 break;
147 }
148 } // End of loop over incoming particles
149 // In case we have not yet identified the vertex as being in a loop
150 // then check the outgoing particles from the vertex.
151 // If any outgoing are in loops, consider this vertex to be in a loop.
152 if(!push) {
153 for ( const auto& pou: *v) {
154 if (incycle[pou] == 1) {
155 push = true;
156 break;
157 }
158 }
159 }
160 // Update the records if this vertex is in a loop.
161 if (push) m_loop_vertices.push_back(v);
162 } // End of loop over vertices
163
164 // All finished. Return success.
165 return 0;
166 } // End of the findLoops function
167
168private:
169
171 const Evt* m_evt = nullptr;
172
174 std::vector<Prt> m_loop_particles;
175
177 std::vector<Vtx> m_loop_vertices;
178};
179}
180#endif
181#endif
#define pi
bool isLoop(const Prt &p) const
Is this particle in a loop?
Definition Loops.h:26
const Evt * m_evt
Local pointer to the event passed in the constructor or most recent call to findLoops.
Definition Loops.h:171
Loops(const Evt *evt)
Constructor passing the event; immediately index the event that is passed.
Definition Loops.h:21
Loops()
Default constructor.
Definition Loops.h:18
bool isLoop(const Vtx &v) const
Is this vertex in a loop?
Definition Loops.h:31
const std::vector< Vtx > & loop_vertices() const
Accessor: return the full list of vertices in loops.
Definition Loops.h:41
std::vector< Vtx > m_loop_vertices
List of all vertices in m_evt that are in loops.
Definition Loops.h:177
int findLoops(const Evt *evt, bool force)
Function that does the work to identify loops Pass the event of interest.
Definition Loops.h:47
const std::vector< Prt > & loop_particles() const
Accessor: return the full list of particles in loops.
Definition Loops.h:36
std::vector< Prt > m_loop_particles
List of all particles in m_evt that are in loops.
Definition Loops.h:174
int ev
Definition globals.cxx:25
A namespace for all vertexing packages and related stuff.