GGS(GenericGEANT4Simulation)Software  2.7.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 #include <algorithm>
15 #include <unordered_map>
16 #include <vector>
17 
18 #ifndef _INTERACTIONTREE_
19 #define _INTERACTIONTREE_
20 
21 template <class T> class TreeNode {
22 public:
23  TreeNode();
24  TreeNode(int ID);
25  ~TreeNode();
26 
27  int trackID;
28  std::vector<TreeNode *> children;
29  std::vector<T> hits;
30 };
31 
32 template <class T> class InteractionTree {
33 public:
35  ~InteractionTree();
36 
37  TreeNode<T> *GetRootNode() { return hashMap[1]; }
38  void AddHit(int trackID, T hit);
39  void AddNode(int trackID, int parentID);
40  void SortHits(bool (*f)(T, T));
41  // void Init();
42  void Clear() { hashMap.clear(); };
43  void Dump();
44 
45  // TreeNode* node;
46  std::unordered_map<int, TreeNode<T> *> hashMap;
47 
48 private:
49  typedef typename std::unordered_map<int, TreeNode<T> *>::iterator UOMIterator;
50 };
51 
52 template <class T> TreeNode<T>::TreeNode() {}
53 
54 template <class T> TreeNode<T>::TreeNode(int ID) : trackID(ID) {}
55 
56 template <class T> TreeNode<T>::~TreeNode() {
57  children.clear();
58  std::vector<T>().swap(hits); // we don't want to call the destructor of T
59 }
60 
61 template <class T> InteractionTree<T>::InteractionTree() {}
62 
63 template <class T> InteractionTree<T>::~InteractionTree() { Clear(); }
64 
65 template <class T> void InteractionTree<T>::AddHit(int trackID, T hit) {
66 
67  if (hashMap.find(trackID) == hashMap.end())
68  AddNode(trackID, hit->parentID);
69 
70  hashMap[trackID]->hits.push_back(hit);
71 }
72 
73 template <class T> void InteractionTree<T>::AddNode(int trackID, int parentID) {
74 
75  std::pair<UOMIterator, bool> mapResult;
76 
77  if (hashMap.find(parentID) == hashMap.end()) {
78  TreeNode<T> *parentnode = new TreeNode<T>(parentID);
79  mapResult = hashMap.insert(std::make_pair(parentID, parentnode)); // let's create an empty parent...
80  }
81 
82  TreeNode<T> *childnode = new TreeNode<T>(trackID);
83  hashMap[parentID]->children.push_back(childnode);
84  hashMap.insert(std::make_pair(trackID, childnode));
85 }
86 
87 template <class T> void InteractionTree<T>::SortHits(bool (*order)(T, T)) {
88 
89  for (std::pair<int, TreeNode<T> *> element : hashMap) {
90  std::sort(element.second->hits.begin(), element.second->hits.end(), order);
91  }
92 }
93 
94 template <class T> void InteractionTree<T>::Dump() {
95 
96  for (std::pair<int, TreeNode<T> *> element : hashMap) {
97  std::cout << "trackID " << element.first << " has " << element.second->children.size() << " children" << std::endl;
98  for (int ic = 0; ic < element.second->children.size(); ic++) {
99  std::cout << " - " << element.second->children[ic]->trackID << std::endl;
100  for (int ihit = 0; ihit < element.second->children[ic]->hits.size(); ihit++) {
101  std::cout << " --- " << element.second->children[ic]->hits[ihit]->particlePdg << " "
102  << element.second->children[ic]->hits[ihit]->time << " "
103  << element.second->children[ic]->hits[ihit]->eDep << " ";
104  std::cout << "(" << element.second->children[ic]->hits[ihit]->entrancePoint[0] << ", ";
105  std::cout << element.second->children[ic]->hits[ihit]->entrancePoint[1] << ", ";
106  std::cout << element.second->children[ic]->hits[ihit]->entrancePoint[2] << ") -> ";
107  std::cout << "(" << element.second->children[ic]->hits[ihit]->exitPoint[0] << ", ";
108  std::cout << element.second->children[ic]->hits[ihit]->exitPoint[1] << ", ";
109  std::cout << element.second->children[ic]->hits[ihit]->exitPoint[2] << ")";
110  std::cout << std::endl;
111  }
112  }
113  }
114 }
115 
116 #endif