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 nSubHit = 0; // for towers
74 bool used = false;
75 void Print() {
76 cout << "Hit ("
77 << "e= " << e << ", id=" << id << ", layer= " << layer << ", x= " << x
78 << ", y= " << y << ", z= " << z << ", nSub= " << nSubHit
79 << ", used= " << used << ")" << endl;
80 }
81};
82
83class Cluster {
84 public:
85 std::vector<Hit> hits;
86 std::vector<Cluster> clusters2d; // for 3d
87 // calculate and store properties...
88 float x = 0;
89 float y = 0;
90 float z = 0;
91 // xyz RMS
92 float xx = 0;
93 float yy = 0;
94 float zz = 0;
95 float e = 0;
96 int seed = -1; // id(xy)
97 int module = -1; // uses seed
98 int layer = -1;
99
100 // 3d specific
101 bool is2D = true;
102 bool used = false;
103 int first_layer = -1;
104 int last_layer = -1;
105 int depth = 0;
106 float dxdz = 0;
107 float dxdze = 0;
108 float dydz = 0;
109 float dydze = 0;
110
111 void Print(ClusterGeometry* g = 0) {
112 // ClusterGeometry* g;
113 if (g == 0) {
114 cout << "Cluster ("
115 << "e= " << e << ", seed id=" << seed << ", x= " << x << ", y= " << y
116 << ", z= " << z << ", nHit= " << hits.size() << ")" << endl;
117 } else {
118 auto idpair = g->id_map[seed];
119 cout << "Cluster ("
120 << "e= " << e << ", seed id=" << seed << ", cell id=" << idpair.first
121 << ", module id=" << idpair.second << ", layer=" << layer
122 << ", x= " << x << ", y= " << y << ", z= " << z
123 << ", nHit= " << hits.size() << ")" << endl;
124 }
125 }
126 void Print3d() {
127 cout << "Cluster ("
128 << "e= " << e << ", seed id=" << seed << ", x= " << x << ", y= " << y
129 << ", z= " << z << ", n2dClus= " << clusters2d.size()
130 << ", first_layer=" << first_layer << ", depth=" << depth << ")"
131 << endl;
132 }
133 void PrintHits() {
134 Print();
135 for (auto& h : hits) {
136 cout << " ";
137 h.Print();
138 }
139 }
140};
141
143 public:
144 virtual ~IdealClusterBuilder() = default;
145 std::vector<Hit> all_hits{};
146 std::vector<Cluster> all_clusters{};
148
149 float seed_thresh = 0; // e.g. 100
150 float neighb_thresh = 0; // e.g. 100
151 int n_neighbors = 1;
152 bool split_energy = true;
153 // bool use_towers = true;
154 bool use_towers = false;
155 const int LAYER_MAX = 35;
156 const int LAYER_SHOWERMAX = 7;
157 const int LAYER_SEEDMIN = 3;
158 const int LAYER_SEEDMAX = 15;
159 const float MIN_TP_ENERGY = 0.5; // in MeV
160 int DEPTH_GOOD = 5;
161 /* int order3d[LAYER_MAX]={ */
162 /* 7,8,6,9,5,10,4,11,3,12,2,13,1,14,0,15,16,17,18,19 */
163 /* }; */
164 bool debug = false;
165
166 void AddHit(Hit h) {
167 if (h.layer >= LAYER_MAX) return;
168 auto p = std::make_pair(h.cell_id, h.module_id);
169 h.id = g->reverse_id_map[p];
170 all_hits.push_back(h);
171 }
172 std::vector<Cluster> GetClusters() { return all_clusters; }
173 void SetClusterGeo(ClusterGeometry* _g) { g = _g; }
174
175 virtual void BuildClusters();
176 std::vector<Cluster> Build2dClustersLayer(std::vector<Hit> hits);
177 void Build2dClusters();
178 void Build3dClusters();
179 void Fit(Cluster& c3);
180
181 /* void BuildClusters(); */
182 /* void Cluster2dHits(); */
183};
184
185template <class T>
186void ESort(std::vector<T>& v) {
187 std::sort(v.begin(), v.end(),
188 [](const auto& lhs, const auto& rhs) { return lhs.e > rhs.e; });
189}
190
191} // namespace trigger
192
193#endif // IDEALCLUSTERBUILDER_H