59 {
60
61 std::map<int, Hit> hits_by_id;
62 for (auto &hit : hits) hits_by_id[hit.id] = hit;
63
64 if (debug) {
65 cout << "--------\nBuild2dClustersLayer Input Hits" << endl;
66 for (auto &hitpair : hits_by_id) hitpair.second.Print();
67 }
68
69
70 std::vector<Cluster> clusters;
71 for (auto &hitpair : hits_by_id) {
72 auto &hit = hitpair.second;
73 bool isLocalMax = true;
74 for (auto n : g->neighbors[hit.id]) {
75
76 if (hits_by_id.count(n) && hits_by_id[n].e > hit.e) isLocalMax = false;
77 }
78
79
80 if (isLocalMax && (hit.e > seed_thresh)) {
81 hit.used = true;
83 c.hits.push_back(hit);
84 c.e = hit.e;
85 c.x = hit.x;
86 c.y = hit.y;
87 c.z = hit.z;
88 c.seed = hit.id;
89 c.module = g->id_map[hit.id].second;
90 c.layer = hit.layer;
91 clusters.push_back(c);
92 }
93 }
94
95 if (debug) {
96 cout << "--------\nAfter seed-finding" << endl;
97 for (auto &hitpair : hits_by_id) hitpair.second.Print();
98 for (auto &c : clusters) c.Print();
99 }
100
101
102 int i_neighbor = 0;
103 while (i_neighbor < n_neighbors) {
104
105 std::map<int, std::vector<int> > assoc_clus2hitIDs;
106 for (int iclus = 0; iclus < clusters.size(); iclus++) {
107 auto &clus = clusters[iclus];
108 std::vector<int> neighbors;
109 for (const auto &hit : clus.hits) {
110 for (auto n : g->neighbors[hit.id]) {
111 if (hits_by_id.count(n) && !hits_by_id[n].used &&
112 hits_by_id[n].e > neighb_thresh) {
113 neighbors.push_back(n);
114 }
115 }
116 }
117 assoc_clus2hitIDs[iclus] = neighbors;
118 }
119
120
121 std::map<int, std::vector<int> > assoc_hitID2clusters;
122 for (auto clus2hitID : assoc_clus2hitIDs) {
123 auto iclus = clus2hitID.first;
124 auto &hitIDs = clus2hitID.second;
125 for (const auto &hitID : hitIDs) {
126 if (assoc_hitID2clusters.count(hitID))
127 assoc_hitID2clusters[hitID].push_back(iclus);
128 else
129 assoc_hitID2clusters[hitID] = {iclus};
130 }
131 }
132
133
134
135 for (auto hitID2clusters : assoc_hitID2clusters) {
136 auto hitID = hitID2clusters.first;
137 auto iclusters = hitID2clusters.second;
138 if (iclusters.size() == 1) {
139
140 auto &hit = hits_by_id[hitID];
141 auto iclus = iclusters[0];
142 hit.used = true;
143 clusters[iclus].hits.push_back(hit);
144 clusters[iclus].e += hit.e;
145 } else {
146 auto &hit = hits_by_id[hitID];
147 hit.used = true;
148 float esum = 0;
149 for (auto iclus : iclusters) {
150 esum += clusters[iclus].e;
151 }
152 for (auto iclus : iclusters) {
154 if (split_energy) newHit.e = hit.e * clusters[iclus].e / esum;
155 clusters[iclus].hits.push_back(newHit);
156 clusters[iclus].e += newHit.e;
157 }
158 }
159 }
160
161
162 for (auto &c : clusters) {
163 c.e = 0;
164 c.x = 0;
165 c.y = 0;
166 c.z = 0;
167 c.xx = 0;
168 c.yy = 0;
169 c.zz = 0;
170 float sumw = 0;
171 for (auto hit : c.hits) {
172
173 c.e += hit.e;
174
175 float w = std::max(0., log(hit.e / MIN_TP_ENERGY));
176 c.x += hit.x * w;
177 c.y += hit.y * w;
178 c.z += hit.z * w;
179 c.xx += hit.x * hit.x * w;
180 c.yy += hit.y * hit.y * w;
181 c.zz += hit.z * hit.z * w;
182 sumw += w;
183 }
184 c.x /= sumw;
185 c.y /= sumw;
186 c.z /= sumw;
187 c.xx /= sumw;
188 c.yy /= sumw;
189 c.zz /= sumw;
190 c.xx = sqrt(c.xx - c.x * c.x);
191 c.yy = sqrt(c.yy - c.y * c.y);
192 c.zz = sqrt(c.zz - c.z * c.z);
193 }
194
195 i_neighbor++;
196
197 if (debug) {
198 cout << "--------\nAfter " << i_neighbor << " neighbors" << endl;
199 for (auto &hitpair : hits_by_id) hitpair.second.Print();
200 for (auto &c : clusters) c.Print();
201 }
202 }
203
204 return clusters;
205}