56 {
57
58 std::map<int, Hit> hits_by_id;
59 for (auto &hit : hits) hits_by_id[hit.id_] = hit;
60
61 if (debug_) {
62 cout << "--------\nBuild2dClustersLayer Input Hits" << endl;
63 for (auto &hitpair : hits_by_id) hitpair.second.print();
64 }
65
66
67 std::vector<Cluster> clusters;
68 for (auto &hitpair : hits_by_id) {
69 auto &hit = hitpair.second;
70 bool is_local_max = true;
71 for (auto n : g_->neighbors_[hit.id_]) {
72 if (hits_by_id.count(n) && hits_by_id[n].e_ > hit.e_)
73 is_local_max = false;
74 }
75 if (is_local_max && (hit.e_ > seed_thresh_)) {
76 hit.used_ = true;
78 c.hits_.push_back(hit);
79 c.e_ = hit.e_;
80 c.x_ = hit.x_;
81 c.y_ = hit.y_;
82 c.z_ = hit.z_;
83 c.seed_ = hit.id_;
84 c.module_ = g_->id_map_[hit.id_].second;
85 c.layer_ = hit.layer_;
86 clusters.push_back(c);
87 }
88 }
89
90 if (debug_) {
91 cout << "--------\nAfter seed-finding" << endl;
92 for (auto &hitpair : hits_by_id) hitpair.second.print();
93 for (auto &c : clusters) c.print();
94 }
95
96
97 int i_neighbor = 0;
98 while (i_neighbor < n_neighbors_) {
99
100 std::map<int, std::vector<int> > assoc_clus2hit_i_ds;
101 for (int iclus = 0; iclus < clusters.size(); iclus++) {
102 auto &clus = clusters[iclus];
103 std::vector<int> neighbors;
104 for (const auto &hit : clus.hits_) {
105 for (auto n : g_->neighbors_[hit.id_]) {
106 if (hits_by_id.count(n) && !hits_by_id[n].used_ &&
107 hits_by_id[n].e_ > neighb_thresh_) {
108 neighbors.push_back(n);
109 }
110 }
111 }
112 assoc_clus2hit_i_ds[iclus] = neighbors;
113 }
114
115
116 std::map<int, std::vector<int> > assoc_hit_i_d2clusters;
117 for (auto clus2hit_id : assoc_clus2hit_i_ds) {
118 auto iclus = clus2hit_id.first;
119 auto &hit_i_ds = clus2hit_id.second;
120 for (const auto &hit_id : hit_i_ds) {
121 if (assoc_hit_i_d2clusters.count(hit_id))
122 assoc_hit_i_d2clusters[hit_id].push_back(iclus);
123 else
124 assoc_hit_i_d2clusters[hit_id] = {iclus};
125 }
126 }
127
128
129
130 for (auto hit_i_d2clusters : assoc_hit_i_d2clusters) {
131 auto hit_id = hit_i_d2clusters.first;
132 auto iclusters = hit_i_d2clusters.second;
133 if (iclusters.size() == 1) {
134
135 auto &hit = hits_by_id[hit_id];
136 auto iclus = iclusters[0];
137 hit.used_ = true;
138 clusters[iclus].hits_.push_back(hit);
139 clusters[iclus].e_ += hit.e_;
140 } else {
141 auto &hit = hits_by_id[hit_id];
142 hit.used_ = true;
143 float esum = 0;
144 for (auto iclus : iclusters) {
145 esum += clusters[iclus].e_;
146 }
147 for (auto iclus : iclusters) {
149 if (split_energy_) new_hit.e_ = hit.e_ * clusters[iclus].e_ / esum;
150 clusters[iclus].hits_.push_back(new_hit);
151 clusters[iclus].e_ += new_hit.e_;
152 }
153 }
154 }
155
156
157 for (auto &c : clusters) {
158 c.e_ = 0;
159 c.x_ = 0;
160 c.y_ = 0;
161 c.z_ = 0;
162 c.xx_ = 0;
163 c.yy_ = 0;
164 c.zz_ = 0;
165 float sumw = 0;
166 for (auto hit : c.hits_) {
167
168 c.e_ += hit.e_;
169
170 float w = std::max(0., log(hit.e_ / MIN_TP_ENERGY));
171 c.x_ += hit.x_ * w;
172 c.y_ += hit.y_ * w;
173 c.z_ += hit.z_ * w;
174 c.xx_ += hit.x_ * hit.x_ * w;
175 c.yy_ += hit.y_ * hit.y_ * w;
176 c.zz_ += hit.z_ * hit.z_ * w;
177 sumw += w;
178 }
179 c.x_ /= sumw;
180 c.y_ /= sumw;
181 c.z_ /= sumw;
182 c.xx_ /= sumw;
183 c.yy_ /= sumw;
184 c.zz_ /= sumw;
185 c.xx_ = sqrt(c.xx_ - c.x_ * c.x_);
186 c.yy_ = sqrt(c.yy_ - c.y_ * c.y_);
187 c.zz_ = sqrt(c.zz_ - c.z_ * c.z_);
188 }
189
190 i_neighbor++;
191
192 if (debug_) {
193 cout << "--------\nAfter " << i_neighbor << " neighbors" << endl;
194 for (auto &hitpair : hits_by_id) hitpair.second.print();
195 for (auto &c : clusters) c.print();
196 }
197 }
198
199 return clusters;
200}