GGS(GenericGEANT4Simulation)Software  2.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
InteractionTree.h
1 /*
2  * InteractionTree.h
3  *
4  * Created on: 16 Mar 2017
5  * Author: Valerio Formato
6  */
7 
8 /*
9  * A simple templated class to map particle interaction in a tree structure
10  * with linked nodes. Particle/position hits can be stored per-track and sorted
11  * by an arbitrary function.
12  */
13 
14 
15 #include <algorithm>
16 #include <vector>
17 #include <unordered_map>
18 
19 #ifndef _INTERACTIONTREE_
20 #define _INTERACTIONTREE_
21 
22 
23 template <class T> class TreeNode {
24 public:
25 
26  TreeNode();
27  TreeNode(int ID);
28  ~TreeNode();
29 
30  int trackID;
31  std::vector<TreeNode*> children;
32  std::vector<T> hits;
33 };
34 
35 
36 template <class T> class InteractionTree {
37 public:
38 
40  ~InteractionTree();
41 
42  TreeNode<T>* GetRootNode(){ return hashMap[1]; }
43  void AddHit(int trackID, T hit);
44  void AddNode(int trackID, int parentID);
45  void SortHits( bool (*f)(T, T) );
46  // void Init();
47  void Clear(){ hashMap.clear(); };
48  void Dump();
49 
50  // TreeNode* node;
51  std::unordered_map<int, TreeNode<T>*> hashMap;
52 
53 private:
54  typedef typename std::unordered_map<int, TreeNode<T>*>::iterator UOMIterator;
55 
56 };
57 
58 
59 template <class T> TreeNode<T>::TreeNode(){
60 }
61 
62 template <class T> TreeNode<T>::TreeNode(int ID) : trackID(ID){
63 }
64 
65 template <class T> TreeNode<T>::~TreeNode(){
66  children.clear();
67  std::vector<T>().swap(hits); //we don't want to call the destructor of T
68 }
69 
70 
71 
72 
73 template <class T> InteractionTree<T>::InteractionTree(){
74 }
75 
76 template <class T> InteractionTree<T>::~InteractionTree(){
77  Clear();
78 }
79 
80 
81 template <class T> void InteractionTree<T>::AddHit(int trackID, T hit){
82 
83  if( hashMap.find(trackID) == hashMap.end() ) AddNode(trackID, hit->parentID);
84 
85  hashMap[trackID]->hits.push_back(hit);
86 }
87 
88 template <class T> void InteractionTree<T>::AddNode(int trackID, int parentID){
89 
90  std::pair<UOMIterator, bool> mapResult;
91 
92  if( hashMap.find(parentID) == hashMap.end() ){
93  TreeNode<T>* parentnode = new TreeNode<T>(parentID);
94  mapResult = hashMap.insert( std::make_pair(parentID, parentnode) ); //let's create an empty parent...
95  }
96 
97  TreeNode<T>* childnode = new TreeNode<T>(trackID);
98  hashMap[parentID]->children.push_back(childnode);
99  hashMap.insert( std::make_pair(trackID, childnode) );
100 
101 }
102 
103 template <class T> void InteractionTree<T>::SortHits( bool (*order)(T, T) ){
104 
105  for( std::pair<int, TreeNode<T>*> element : hashMap ){
106  std::sort( element.second->hits.begin(), element.second->hits.end(), order );
107  }
108 
109 }
110 
111 
112 template <class T> void InteractionTree<T>::Dump(){
113 
114  for( std::pair<int, TreeNode<T>*> element : hashMap ){
115  std::cout << "trackID " << element.first << " has " << element.second->children.size() << " children" << std::endl;
116  for(int ic=0; ic<element.second->children.size(); ic++){
117  std::cout << " - " << element.second->children[ic]->trackID << std::endl;
118  for(int ihit=0; ihit<element.second->children[ic]->hits.size(); ihit++){
119  std::cout << " --- " << element.second->children[ic]->hits[ihit]->particlePdg << " " << element.second->children[ic]->hits[ihit]->time << " " << element.second->children[ic]->hits[ihit]->eDep << " ";
120  std::cout << "(" << element.second->children[ic]->hits[ihit]->entrancePoint[0] << ", ";
121  std::cout << element.second->children[ic]->hits[ihit]->entrancePoint[1] << ", ";
122  std::cout << element.second->children[ic]->hits[ihit]->entrancePoint[2] << ") -> ";
123  std::cout << "(" << element.second->children[ic]->hits[ihit]->exitPoint[0] << ", ";
124  std::cout << element.second->children[ic]->hits[ihit]->exitPoint[1] << ", ";
125  std::cout << element.second->children[ic]->hits[ihit]->exitPoint[2] << ")";
126  std::cout << std::endl;
127  }
128  }
129  }
130 
131 }
132 
133 
134 #endif