LDMX Software
IdealClusterBuilder.h
1#ifndef IDEALCLUSTERBUILDER_H
2#define IDEALCLUSTERBUILDER_H
3
4#include <algorithm>
5#include <iostream>
6#include <map>
7#include <vector>
8
9using std::cout;
10using std::endl;
11
12namespace trigger {
13
15 public:
16 bool is_initialized_ = false;
17
18 // cell + module -> TP ID (get from geo service)
19 std::map<std::pair<int, int>, int> reverse_id_map_;
20 std::map<int, std::pair<int, int> > id_map_;
21
22 // TP ID to X,Y positions in mm
23 std::map<int, std::pair<float, float> > positions_;
24
25 // pairwise X,Y distances of all TPs
26 std::map<std::pair<int, int>, float> distances_;
27
28 // list of neighbors associated to each TP
29 std::map<int, std::vector<int> > neighbors_;
30
31 int getId(int cell_id, int module_id) {
32 return reverse_id_map_[std::make_pair(cell_id, module_id)];
33 }
34 float getDist(int id1, int id2) {
35 return distances_[std::make_pair(id1, id2)];
36 }
37
38 void addTp(int tid, int cell_id, int module_id, float x, float y);
39 void addNeighbor(int id1, int id2);
40 bool checkNeighbor(int id1, int id2);
41
42 void initialize();
43};
44
45/*
46 FWIW, Pictorally, the numbering for the center module is:
47 28 29 30 31 | 47 46 44 41
48 24 25 26 27 | 45 43 40 37
49 20 21 22 23 | 42 39 36 34
50 16 17 18 19 | 38 35 33 32
51 -----------
52 12 13 14 15
53 08 09 10 11
54 04 05 06 07
55 00 01 02 03
56*/
57
58class Hit {
59 public:
60 float x_ = 0;
61 float y_ = 0;
62 float z_ = 0;
63 float e_ = 0;
64 int idx_ = -1;
65 int cell_id_ = -1;
66 int module_id_ = -1;
67 int id_ = -1; // encodes x,y
68 int layer_ = 0; // z
69 int n_sub_hit_ = 0; // for towers
70 bool used_ = false;
71 void print() {
72 cout << "Hit (" << "e= " << e_ << ", id=" << id_ << ", layer= " << layer_
73 << ", x= " << x_ << ", y= " << y_ << ", z= " << z_
74 << ", nSub= " << n_sub_hit_ << ", used= " << used_ << ")" << endl;
75 }
76};
77
78class Cluster {
79 public:
80 std::vector<Hit> hits_;
81 std::vector<Cluster> clusters2d_; // for 3d
82 // calculate and store properties...
83 float x_ = 0;
84 float y_ = 0;
85 float z_ = 0;
86 // xyz RMS
87 float xx_ = 0;
88 float yy_ = 0;
89 float zz_ = 0;
90 float e_ = 0;
91 int seed_ = -1; // id(xy)
92 int module_ = -1; // uses seed
93 int layer_ = -1;
94
95 // 3d specific
96 bool is_2d_ = true;
97 bool used_ = false;
98 int first_layer_ = -1;
99 int last_layer_ = -1;
100 int depth_ = 0;
101 float dxdz_ = 0;
102 float dxdze_ = 0;
103 float dydz_ = 0;
104 float dydze_ = 0;
105
106 void print(ClusterGeometry* g = 0) {
107 // ClusterGeometry* g;
108 if (g == 0) {
109 cout << "Cluster (" << "e= " << e_ << ", seed id=" << seed_
110 << ", x= " << x_ << ", y= " << y_ << ", z= " << z_
111 << ", nHit= " << hits_.size() << ")" << endl;
112 } else {
113 auto idpair = g->id_map_[seed_];
114 cout << "Cluster (" << "e= " << e_ << ", seed id=" << seed_
115 << ", cell id=" << idpair.first << ", module id=" << idpair.second
116 << ", layer=" << layer_ << ", x= " << x_ << ", y= " << y_
117 << ", z= " << z_ << ", nHit= " << hits_.size() << ")" << endl;
118 }
119 }
120 void print3d() {
121 cout << "Cluster (" << "e= " << e_ << ", seed id=" << seed_ << ", x= " << x_
122 << ", y= " << y_ << ", z= " << z_
123 << ", n2dClus= " << clusters2d_.size()
124 << ", first_layer=" << first_layer_ << ", depth=" << depth_ << ")"
125 << endl;
126 }
127 void printHits() {
128 print();
129 for (auto& h : hits_) {
130 cout << " ";
131 h.print();
132 }
133 }
134};
135
137 public:
138 virtual ~IdealClusterBuilder() = default;
139 std::vector<Hit> all_hits_{};
140 std::vector<Cluster> all_clusters_{};
141 ClusterGeometry* g_;
142
143 float seed_thresh_ = 0; // e.g. 100
144 float neighb_thresh_ = 0; // e.g. 100
145 int n_neighbors_ = 1;
146 bool split_energy_ = true;
147 // bool use_towers = true;
148 bool use_towers_ = false;
149 const int LAYER_MAX = 35;
150 const int LAYER_SHOWERMAX = 7;
151 const int LAYER_SEEDMIN = 3;
152 const int LAYER_SEEDMAX = 15;
153 const float MIN_TP_ENERGY = 0.5; // in MeV
154 const int DEPTH_GOOD = 5;
155 /* int order3d[LAYER_MAX]={ */
156 /* 7,8,6,9,5,10,4,11,3,12,2,13,1,14,0,15,16,17,18,19 */
157 /* }; */
158 bool debug_ = false;
159
160 void addHit(Hit h) {
161 if (h.layer_ >= LAYER_MAX) return;
162 auto p = std::make_pair(h.cell_id_, h.module_id_);
163 h.id_ = g_->reverse_id_map_[p];
164 all_hits_.push_back(h);
165 }
166 std::vector<Cluster> getClusters() { return all_clusters_; }
167 void setClusterGeo(ClusterGeometry* g) { g_ = g; }
168
169 virtual void buildClusters();
170 std::vector<Cluster> build2dClustersLayer(std::vector<Hit> hits);
171 void build2dClusters();
172 void build3dClusters();
173 void fit(Cluster& c3);
174
175 /* void BuildClusters(); */
176 /* void Cluster2dHits(); */
177};
178
179template <class T>
180void eSort(std::vector<T>& v) {
181 std::sort(v.begin(), v.end(),
182 [](const auto& lhs, const auto& rhs) { return lhs.e_ > rhs.e_; });
183}
184
185} // namespace trigger
186
187#endif // IDEALCLUSTERBUILDER_H