CMS 3D CMS Logo

DecayGraph.h
Go to the documentation of this file.
1 #ifndef SimGeneral_MixingModule_DecayGraph_h
2 #define SimGeneral_MixingModule_DecayGraph_h
3 
6 
7 #if DEBUG
8 // boost optional (used by boost graph) results in some false positives with
9 // // -Wmaybe-uninitialized
10 #pragma GCC diagnostic push
11 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
12 #endif
13 
14 // BOOST GRAPH LIBRARY
15 #include <boost/graph/adjacency_list.hpp>
16 #include <boost/graph/breadth_first_search.hpp>
17 #include <boost/graph/depth_first_search.hpp>
18 #include <boost/graph/graphviz.hpp>
19 
20 using boost::add_edge;
21 using boost::adjacency_list;
22 using boost::directedS;
23 using boost::edge;
24 using boost::edge_weight;
25 using boost::edge_weight_t;
26 using boost::listS;
27 using boost::property;
28 using boost::vecS;
29 using boost::vertex;
30 using boost::vertex_name;
31 using boost::vertex_name_t;
32 
33 /* GRAPH DEFINITIONS
34 
35  The graphs represent the full decay chain.
36 
37  The parent-child relationship is the natural one, following "time".
38 
39  Each edge has a property (edge_weight_t) that holds a const pointer to the
40  SimTrack that connects the 2 vertices of the edge, the number of simHits
41  associated to that simTrack and the cumulative number of simHits of itself
42  and of all its children. Only simHits within the selected detectors are
43  taken into account. The cumulative property is filled during the dfs
44  exploration of the graph: if not explored the number is 0.
45 
46  Each vertex has a property (vertex_name_t) that holds a const pointer to the
47  SimTrack that originated that vertex and the cumulative number of simHits of
48  all its outgoing edges. The cumulative property is filled during the dfs
49  exploration of the graph: if not explored the number is 0.
50 
51  Stable particles are recovered/added in a second iterations and are linked
52  to ghost vertices with an offset starting from the highest generated vertex.
53 
54  Multiple decays of a single particle that retains its original trackId are
55  merged into one unique vertex (the first encountered) in order to avoid
56  multiple counting of its associated simHits (if any).
57 
58 */
59 struct EdgeProperty {
62  int simHits;
64 };
65 
73 };
74 
75 using EdgeParticleClustersProperty = property<edge_weight_t, EdgeProperty>;
76 using VertexMotherParticleProperty = property<vertex_name_t, VertexProperty>;
77 using DecayChain = adjacency_list<listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty>;
78 
79 namespace {
80  extern const std::string messageCategoryGraph_;
81 
82  template <typename Edge, typename Graph, typename Visitor>
83  void accumulateSimHits_edge(Edge &e, const Graph &g, Visitor *v) {
84  auto const edge_property = get(edge_weight, g, e);
85  v->total_simHits += edge_property.simHits;
86  IfLogDebug(DEBUG, messageCategoryGraph_)
87  << " Examining edges " << e << " --> particle " << edge_property.simTrack->type() << "("
88  << edge_property.simTrack->trackId() << ")"
89  << " with SimClusters: " << edge_property.simHits << " Accumulated SimClusters: " << v->total_simHits
90  << std::endl;
91  }
92  template <typename Vertex, typename Graph>
93  void print_vertex(Vertex &u, const Graph &g) {
94  auto const vertex_property = get(vertex_name, g, u);
95  IfLogDebug(DEBUG, messageCategoryGraph_) << " At " << u;
96  // The Mother of all vertices has **no** SimTrack associated.
97  if (vertex_property.simTrack)
98  IfLogDebug(DEBUG, messageCategoryGraph_) << " [" << vertex_property.simTrack->type() << "]"
99  << "(" << vertex_property.simTrack->trackId() << ")";
100  IfLogDebug(DEBUG, messageCategoryGraph_) << std::endl;
101  }
102 
103 // Graphviz output functions will only be generated in DEBUG mode
104 #if DEBUG
105  std::string graphviz_vertex(const VertexProperty &v) {
106  std::ostringstream oss;
107  oss << "{id: " << (v.simTrack ? v.simTrack->trackId() : 0) << ",\\ntype: " << (v.simTrack ? v.simTrack->type() : 0)
108  << ",\\nchits: " << v.cumulative_simHits << "}";
109  return oss.str();
110  }
111 
112  std::string graphviz_edge(const EdgeProperty &e) {
113  std::ostringstream oss;
114  oss << "[" << (e.simTrack ? e.simTrack->trackId() : 0) << "," << (e.simTrack ? e.simTrack->type() : 0) << ","
115  << e.simHits << "," << e.cumulative_simHits << "]";
116  return oss.str();
117  }
118 #endif
119 
120  class SimHitsAccumulator_dfs_visitor : public boost::default_dfs_visitor {
121  public:
122  int total_simHits = 0;
123  template <typename Edge, typename Graph>
124  void examine_edge(Edge e, const Graph &g) {
125  accumulateSimHits_edge(e, g, this);
126  }
127  template <typename Edge, typename Graph>
128  void finish_edge(Edge e, const Graph &g) {
129  auto const edge_property = get(edge_weight, g, e);
130  auto src = source(e, g);
131  auto trg = target(e, g);
132  auto cumulative = edge_property.simHits + get(vertex_name, g, trg).cumulative_simHits +
133  (get(vertex_name, g, src).simTrack ? get(vertex_name, g, src).cumulative_simHits
134  : 0); // when we hit the root vertex we have to stop
135  // adding back its contribution.
136  auto const src_vertex_property = get(vertex_name, g, src);
137  put(get(vertex_name, const_cast<Graph &>(g)), src, VertexProperty(src_vertex_property.simTrack, cumulative));
138  put(get(edge_weight, const_cast<Graph &>(g)),
139  e,
140  EdgeProperty(edge_property.simTrack, edge_property.simHits, cumulative));
141  IfLogDebug(DEBUG, messageCategoryGraph_)
142  << " Finished edge: " << e << " Track id: " << get(edge_weight, g, e).simTrack->trackId()
143  << " has accumulated " << cumulative << " hits" << std::endl;
144  IfLogDebug(DEBUG, messageCategoryGraph_) << " SrcVtx: " << src << "\t" << get(vertex_name, g, src).simTrack
145  << "\t" << get(vertex_name, g, src).cumulative_simHits << std::endl;
146  IfLogDebug(DEBUG, messageCategoryGraph_) << " TrgVtx: " << trg << "\t" << get(vertex_name, g, trg).simTrack
147  << "\t" << get(vertex_name, g, trg).cumulative_simHits << std::endl;
148  }
149  };
150 
151  using Selector = std::function<bool(EdgeProperty &)>;
152 } // namespace
153 
154 #endif
property< vertex_name_t, VertexProperty > VertexMotherParticleProperty
Definition: DecayGraph.h:76
EdgeProperty(const SimTrack *t, int h, int c)
Definition: DecayGraph.h:60
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
const SimTrack * simTrack
Definition: DecayGraph.h:71
void put(edm::Event &evt, double value, const char *instanceName)
const SimTrack * simTrack
Definition: DecayGraph.h:61
#define IfLogDebug(cond, cat)
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
Definition: DecayGraph.h:77
int cumulative_simHits
Definition: DecayGraph.h:63
Functor that operates on <T>
Definition: Selector.h:22
VertexProperty(const VertexProperty &other)
Definition: DecayGraph.h:69
VertexProperty(const SimTrack *t, int c)
Definition: DecayGraph.h:68
property< edge_weight_t, EdgeProperty > EdgeParticleClustersProperty
Definition: DecayGraph.h:75
#define DEBUG
Definition: DMRChecker.cc:120
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
static std::string const source
Definition: EdmProvDump.cc:49
int cumulative_simHits
Definition: DecayGraph.h:72