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