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 
71 };
72 
73 using EdgeParticleClustersProperty = property<edge_weight_t, EdgeProperty>;
74 using VertexMotherParticleProperty = property<vertex_name_t, VertexProperty>;
75 using DecayChain = adjacency_list<listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty>;
76 
77 namespace {
78  extern const std::string messageCategoryGraph_;
79 
80  template <typename Edge, typename Graph, typename Visitor>
81  void accumulateSimHits_edge(Edge &e, const Graph &g, Visitor *v) {
82  auto const edge_property = get(edge_weight, g, e);
83  v->total_simHits += edge_property.simHits;
84  IfLogDebug(DEBUG, messageCategoryGraph_)
85  << " Examining edges " << e << " --> particle " << edge_property.simTrack->type() << "("
86  << edge_property.simTrack->trackId() << ")"
87  << " with SimClusters: " << edge_property.simHits << " Accumulated SimClusters: " << v->total_simHits
88  << std::endl;
89  }
90  template <typename Vertex, typename Graph>
91  void print_vertex(Vertex &u, const Graph &g) {
92  auto const vertex_property = get(vertex_name, g, u);
93  IfLogDebug(DEBUG, messageCategoryGraph_) << " At " << u;
94  // The Mother of all vertices has **no** SimTrack associated.
95  if (vertex_property.simTrack)
96  IfLogDebug(DEBUG, messageCategoryGraph_) << " [" << vertex_property.simTrack->type() << "]"
97  << "(" << vertex_property.simTrack->trackId() << ")";
98  IfLogDebug(DEBUG, messageCategoryGraph_) << std::endl;
99  }
100 
101 // Graphviz output functions will only be generated in DEBUG mode
102 #if DEBUG
103  std::string graphviz_vertex(const VertexProperty &v) {
104  std::ostringstream oss;
105  oss << "{id: " << (v.simTrack ? v.simTrack->trackId() : 0) << ",\\ntype: " << (v.simTrack ? v.simTrack->type() : 0)
106  << ",\\nchits: " << v.cumulative_simHits << "}";
107  return oss.str();
108  }
109 
110  std::string graphviz_edge(const EdgeProperty &e) {
111  std::ostringstream oss;
112  oss << "[" << (e.simTrack ? e.simTrack->trackId() : 0) << "," << (e.simTrack ? e.simTrack->type() : 0) << ","
113  << e.simHits << "," << e.cumulative_simHits << "]";
114  return oss.str();
115  }
116 #endif
117 
118  class SimHitsAccumulator_dfs_visitor : public boost::default_dfs_visitor {
119  public:
120  int total_simHits = 0;
121  template <typename Edge, typename Graph>
122  void examine_edge(Edge e, const Graph &g) {
123  accumulateSimHits_edge(e, g, this);
124  }
125  template <typename Edge, typename Graph>
126  void finish_edge(Edge e, const Graph &g) {
127  auto const edge_property = get(edge_weight, g, e);
128  auto src = source(e, g);
129  auto trg = target(e, g);
130  auto cumulative = edge_property.simHits + get(vertex_name, g, trg).cumulative_simHits +
131  (get(vertex_name, g, src).simTrack ? get(vertex_name, g, src).cumulative_simHits
132  : 0); // when we hit the root vertex we have to stop
133  // adding back its contribution.
134  auto const src_vertex_property = get(vertex_name, g, src);
135  put(get(vertex_name, const_cast<Graph &>(g)), src, VertexProperty(src_vertex_property.simTrack, cumulative));
136  put(get(edge_weight, const_cast<Graph &>(g)),
137  e,
138  EdgeProperty(edge_property.simTrack, edge_property.simHits, cumulative));
139  IfLogDebug(DEBUG, messageCategoryGraph_)
140  << " Finished edge: " << e << " Track id: " << get(edge_weight, g, e).simTrack->trackId()
141  << " has accumulated " << cumulative << " hits" << std::endl;
142  IfLogDebug(DEBUG, messageCategoryGraph_) << " SrcVtx: " << src << "\t" << get(vertex_name, g, src).simTrack
143  << "\t" << get(vertex_name, g, src).cumulative_simHits << std::endl;
144  IfLogDebug(DEBUG, messageCategoryGraph_) << " TrgVtx: " << trg << "\t" << get(vertex_name, g, trg).simTrack
145  << "\t" << get(vertex_name, g, trg).cumulative_simHits << std::endl;
146  }
147  };
148 
149  using Selector = std::function<bool(EdgeProperty &)>;
150 } // namespace
151 
152 #endif
property< vertex_name_t, VertexProperty > VertexMotherParticleProperty
Definition: DecayGraph.h:74
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:69
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:75
int cumulative_simHits
Definition: DecayGraph.h:63
Functor that operates on <T>
Definition: Selector.h:22
VertexProperty(const SimTrack *t, int c)
Definition: DecayGraph.h:68
property< edge_weight_t, EdgeProperty > EdgeParticleClustersProperty
Definition: DecayGraph.h:73
#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:70