149 std::vector<KLMHit2d*>& poolHits)
153 constexpr double kMADFactor = 3.0;
154 constexpr int kMaxOutlierIterations = 5;
155 constexpr double kMinInlierFraction = 0.3;
160 const std::vector<KLMHit2d*> before = clusterHits;
161 const std::size_t minInliers = std::max<std::size_t>(
162 2,
static_cast<std::size_t
>(std::ceil(kMinInlierFraction * before.size())));
164 std::vector<KLMHit2d*> inliers = before;
165 for (
int iter = 0; iter < kMaxOutlierIterations; iter++) {
166 const ROOT::Math::XYZVector ref =
167 referenceDirection(inliers, iter == 0);
168 const double threshold =
170 std::vector<KLMHit2d*> next;
171 next.reserve(before.size());
173 if (ROOT::Math::VectorUtil::Angle(h->getPosition(), ref) <= threshold)
176 if (next.size() < minInliers)
178 if (next.size() == inliers.size()) {
179 std::vector<KLMHit2d*> a = next, b = inliers;
180 std::sort(a.begin(), a.end());
181 std::sort(b.begin(), b.end());
183 inliers = std::move(next);
187 inliers = std::move(next);
190 if (inliers.size() < minInliers)
192 if (inliers.size() == before.size())
197 std::unordered_set<KLMHit2d*> inlierSet(inliers.begin(), inliers.end());
198 std::vector<KLMHit2d*> outliers;
199 outliers.reserve(before.size() - inliers.size());
201 if (inlierSet.find(h) == inlierSet.end())
202 outliers.push_back(h);
204 clusterHits.swap(inliers);
205 poolHits.insert(poolHits.end(), outliers.begin(), outliers.end());
206 sort(poolHits.begin(), poolHits.end(), compareDistance);
212 int i, nLayers, innermostLayer, nHits;
215 int* layerHitsBKLM, *layerHitsEKLM;
218 std::vector<KLMHit2d*> klmHit2ds, klmClusterHits;
219 std::vector<KLMHit2d*>::iterator it, it0, it2;
221 layerHitsBKLM =
new int[nLayersBKLM];
222 layerHitsEKLM =
new int[nLayersEKLM];
225 for (i = 0; i < nHits; i++) {
231 sort(klmHit2ds.begin(), klmHit2ds.end(), compareDistance);
233 while (klmHit2ds.size() > 0) {
234 klmClusterHits.clear();
235 it = klmHit2ds.begin();
236 klmClusterHits.push_back(*it);
237 it = klmHit2ds.erase(it);
238 while (it != klmHit2ds.end()) {
239 it2 = klmClusterHits.begin();
242 while (it2 != klmClusterHits.end()) {
243 if (ROOT::Math::VectorUtil::Angle(
244 (*it)->getPosition(), (*it2)->getPosition()) <
246 klmClusterHits.push_back(*it);
247 it = klmHit2ds.erase(it);
254 if (ROOT::Math::VectorUtil::Angle(
255 (*it)->getPosition(), (*it2)->getPosition()) <
257 klmClusterHits.push_back(*it);
258 it = klmHit2ds.erase(it);
268 ROOT::Math::XYZVector clusterPosition{0, 0, 0};
269 for (i = 0; i < nLayersBKLM; i++)
270 layerHitsBKLM[i] = 0;
271 for (i = 0; i < nLayersEKLM; i++)
272 layerHitsEKLM[i] = 0;
275 for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
276 if (minTime < 0 || (*it)->getTime() < minTime)
277 minTime = (*it)->getTime();
279 layerHitsBKLM[(*it)->getLayer() - 1]++;
281 layerHitsEKLM[(*it)->getLayer() - 1]++;
283 it0 = klmClusterHits.begin();
286 for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
287 clusterPosition = clusterPosition + (*it)->getPosition();
295 selSubdet[0] = (*it0)->getSubdetector();
296 selLayer[0] = (*it0)->getLayer();
299 for (i = 0; i < nLayersBKLM && selCount < 2; i++) {
300 if (layerHitsBKLM[i] > 0) {
302 selLayer[selCount] = i + 1;
306 for (i = 0; i < nLayersEKLM && selCount < 2; i++) {
307 if (layerHitsEKLM[i] > 0) {
309 selLayer[selCount] = i + 1;
314 selSubdet[0] = (*it0)->getSubdetector();
315 selLayer[0] = (*it0)->getLayer();
319 bool foundPair =
false;
320 for (i = 0; i < nLayersBKLM - 1; i++) {
321 if (layerHitsBKLM[i] > 0 && layerHitsBKLM[i + 1] > 0) {
332 for (i = 0; i < nLayersEKLM - 1; i++) {
333 if (layerHitsEKLM[i] > 0 && layerHitsEKLM[i + 1] > 0) {
345 selSubdet[0] = (*it0)->getSubdetector();
346 selLayer[0] = (*it0)->getLayer();
350 for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
351 int sd = (*it)->getSubdetector();
352 int ly = (*it)->getLayer();
354 for (i = 0; i < selCount; i++) {
355 if (sd == selSubdet[i] && ly == selLayer[i]) {
361 clusterPosition = clusterPosition + (*it)->getPosition();
366 B2FATAL(
"KLMClustersReconstructor: no hits for vertex position.");
368 clusterPosition = clusterPosition * (1.0 / nHits);
372 for (i = 0; i < nLayersBKLM; i++) {
373 if (layerHitsBKLM[i] > 0) {
375 if (innermostLayer < 0)
376 innermostLayer = i + 1;
379 for (i = 0; i < nLayersEKLM; i++) {
380 if (layerHitsEKLM[i] > 0) {
382 if (innermostLayer < 0)
383 innermostLayer = i + 1;
392 p = klmClusterHits.size() * 0.215;
402 clusterPosition.X(), clusterPosition.Y(), clusterPosition.Z(), minTime, nLayers,
404 for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it)
409 for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
410 auto bklmhit1ds = (*it)->getRelationsTo<
BKLMHit1d>();
411 for (
const auto& bklmhit1d : bklmhit1ds) {
412 auto klmdigits = bklmhit1d.getRelationsTo<
KLMDigit>();
413 nDigits += klmdigits.size();
416 nDigits += klmdigits.size();
421 delete[] layerHitsBKLM;
422 delete[] layerHitsEKLM;