9 #include <mdst/dataobjects/MCParticleGraph.h>
11 #include <framework/datastore/StoreArray.h>
12 #include <framework/logging/Logger.h>
14 #include <boost/graph/graph_traits.hpp>
15 #include <boost/graph/adjacency_list.hpp>
16 #include <boost/graph/depth_first_search.hpp>
24 using namespace boost;
36 template <
class Edge,
class Graph>
void back_edge(Edge, Graph&) {
throw MCParticleGraph::CyclicReferenceError(); }
61 m_index(0), m_particles(particles), m_plist(plist), m_setVertex(setVertex), m_setTime(setTime) {}
74 template <
class Graph>
void sort(Graph& g)
78 m_seen.resize(num_vertices(g),
false);
85 find_daughters(0, g, dummy);
89 while (!m_vqueue.empty()) {
90 unsigned int cur = m_vqueue.front();
92 finish_vertex(cur, g);
107 p.setFirstDaughter(0);
108 p.setLastDaughter(0);
110 find_daughters(v, g, p);
113 if (out_degree(v, g) == 0 && m_setTime) {
114 p.setDecayTime(numeric_limits<double>::infinity());
118 new (m_plist->AddrAt(p.getIndex() - 1))
MCParticle(m_plist, p);
132 int& d1 = mother.m_firstDaughter;
133 int& d2 = mother.m_lastDaughter;
135 typename graph_traits<Graph>::out_edge_iterator j, j_end;
136 for (tie(j, j_end) = out_edges(v, g); j != j_end; ++j) {
138 Vertex nv = target(*j, g);
141 if (daughter.m_ignore) {
144 if (!m_seen[nv]) daughter.setIndex(mother.getIndex());
145 find_daughters(nv, g, mother);
149 daughter.setIndex(++m_index);
155 d1 = daughter.getIndex();
157 }
else if ((d2 + 1) == daughter.getIndex()) {
159 }
else if ((d1 - 1) == daughter.getIndex()) {
163 throw MCParticleGraph::NonContinousDaughtersError();
166 setVertexTime(mother, daughter);
167 daughter.m_mother = mother.getIndex();
183 m.setValidVertex(m.hasValidVertex() && d.hasValidVertex());
184 if (m.hasValidVertex() && d.getProductionTime() >= m.getDecayTime()) {
186 m.setDecayVertex(d.getProductionVertex());
189 m.setDecayTime(d.getProductionTime());
209 void MCParticleGraph::generateList(
const string& name,
int options)
215 typedef adjacency_list<vecS, vecS, directedS> Graph;
216 int num_particles(0);
219 for (
unsigned int i = 0; i < m_particles.size(); ++i) {
220 if (!m_particles[i]->m_ignore) ++num_particles;
221 if (m_particles[i]->m_primary) m_decays.insert(
DecayLine(0, i + 1));
223 Graph g(m_decays.begin(), m_decays.end(), m_particles.size() + 1);
226 if (options & c_checkCyclic) {
228 depth_first_search(g, visitor(vis));
232 if (options & c_clearParticles) MCParticles.
getPtr()->Clear();
239 void MCParticleGraph::loadList(
const string& name)
243 B2ERROR(
"MCParticle Collection is not valid, cannot load into Graph");
247 unsigned numParticles = MCParticles.
getEntries();
248 unsigned particleOffset = size();
254 for (
unsigned i = 0; i < numParticles; ++i) {
256 const MCParticle& oldParticle = *MCParticles[i];
258 newParticle = oldParticle;
261 if (oldMother !=
nullptr) {
262 unsigned motherIndex = oldMother->
getArrayIndex() + particleOffset;
263 if (motherIndex >= size())
264 B2FATAL(
"MCParticle collection \"" << name <<
"\" not sorted correctly: mother index larger than daughter. Cannot load into Graph");
Class to represent Particle data in graph.
void comesFrom(GraphParticle &mother)
Tells the graph that this particle is a decay product of mother.
Class to go over all the particles in the Graph an sort them in a sensible way.
void setVertexTime(MCParticleGraph::GraphParticle &m, const MCParticleGraph::GraphParticle &d)
Set the vertex and time information of the mother particle.
ParticleSorter(MemoryPool< MCParticleGraph::GraphParticle > &particles, TClonesArray *plist, bool setVertex, bool setTime)
ParticleSorter constructor.
MemoryPool< MCParticleGraph::GraphParticle > & m_particles
Reference to the list of particles which should be sorted.
void find_daughters(Vertex v, Graph &g, MCParticleGraph::GraphParticle &mother)
Find the daughters of the given vertex.
void finish_vertex(Vertex v, Graph &g)
Go through the daughters of the vertex.
bool m_setTime
True if the production time information should be saved.
std::queue< unsigned int > m_vqueue
The list of the vertices that will be visited.
vector< bool > m_seen
Vector of the particles that were already seen while sorting the graph.
void setStartIndex(int index)
Set the starting index for the particle graph.
int m_index
The latest index given to a particle.
bool m_setVertex
True if the vertex information should be saved.
TClonesArray * m_plist
The final array of sorted particles which is stored in the DataStore.
void sort(Graph &g)
Sort the particles and generate MCParticle list.
std::pair< unsigned int, unsigned int > DecayLine
Type representing a decay in the graph.
A Class to store the Monte Carlo particle information.
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Class to provide a constant access time memory pool for one kind of objects.
int getEntries() const
Get the number of objects in the array.
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
MCParticle * getMother() const
Returns a pointer to the mother particle.
Abstract base class for different kinds of events.
Simple struct to check boost graph for cyclic references.
void back_edge(Edge, Graph &)
This method is invoked on back edges in the graph.