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