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