29 std::vector< tss::Cluster2D > result;
30 while (inp.
size() > 1)
36 std::vector< TVector2 > centers;
37 centers.emplace_back(hFirst->
Point2D());
39 while (centers.size())
41 run(inp, result, centers);
54 std::vector< tss::Cluster2D > & result,
55 std::vector< TVector2 > & centers)
const 57 if (!centers.size())
return;
59 TVector2 center(centers.front());
60 centers.erase(centers.begin());
65 const double dmax2 = 0.5 * 0.5;
75 size_t seedIdx = 0, hitIdx, h;
76 double d2, min_d2 = seeds.front().dist2(center, hitIdx);
77 for (
size_t i = 1; i < seeds.size(); i++)
79 d2 = seeds[i].dist2(center, h);
80 if (d2 < min_d2) { min_d2 = d2; seedIdx = i; hitIdx = h; }
86 result.emplace_back(segment);
87 if (segment.
size() > 1)
90 if (hEnd) centers.emplace_back(hEnd->
Point2D());
94 seeds.erase(seeds.begin() + seedIdx);
100 result.back().push_back(hFirst);
109 TVector2 segDir = end - center;
111 double dc, min_dc = 1.0e9;
115 for (
auto h : inp.
hits())
120 TVector2 hDir = h->Point2D() - center;
122 if ((hDir * segDir >= 0.0) || (dc < 0.1))
127 min_dc = dc; firstIdx = candidates.
size() - 1;
132 if (candidates.
size() > 1)
135 candidates.
hits()[firstIdx] = candidates.
hits()[0];
136 candidates.
hits()[0] = hFirst;
141 if (candidates.
size())
146 mf::LogError(
"Segmentation2D") <<
"Hit not found in the input cluster.";
150 while ((i < candidates.
size()) &&
156 mf::LogError(
"Segmentation2D") <<
"Hit not found in the input cluster.";
171 for (
size_t h = 0; h < inp.
size(); h++)
173 double d2 =
pma::Dist2(center, inp[h].Point2D());
174 if ((d2 >= d2_min) && (d2 <= d2_max))
185 for (
size_t i = 0; i < group.size(); i++)
187 bool denseStart =
false, denseEnd =
false;
188 TVector2 start0(group[i].start()->Point2D()), end0(group[i].
end()->Point2D());
190 for (
size_t j = 0; j < group.size(); j++)
192 if (i == j)
continue;
194 TVector2 start1(group[j].start()->Point2D()), end1(group[j].
end()->Point2D());
196 if (!group[j].isDenseStart())
201 group[j].tagDenseStart(
true);
206 group[j].tagDenseStart(
true);
211 if (!group[j].isDenseEnd())
215 group[j].tagDenseEnd(
true);
220 group[j].tagDenseEnd(
true);
226 if (denseStart) group[i].tagDenseStart(
true);
227 if (denseEnd) group[i].tagDenseEnd(
true);
243 std::vector< size_t > toMergeS, toMergeE;
244 int idxMaxS = -1, idxMaxE = -1;
246 for (
size_t i = 0; i < group.size(); i++)
249 if (group[i].isEM())
continue;
251 if (group[i].isDenseStart())
255 std::vector< size_t > toMerge;
256 TVector2 start0(group[i].start()->Point2D());
257 for (
size_t j = 0; j < group.size(); j++)
259 if (group[j].isEM())
continue;
263 if ((group[j].size() > 1) &&
264 (group[j].length2() < rad2)) ns++;
269 if (
pma::Dist2(start0, group[j].start()->Point2D()) < rad2)
271 ns++; toMerge.push_back(j); tagged =
true;
273 if ((group[j].size() > 1) && (
pma::Dist2(start0, group[j].
end()->Point2D()) < rad2))
275 ns++;
if (!tagged) toMerge.push_back(j);
279 if (ns > maxS) { maxS = ns; idxMaxS = i; toMergeS = toMerge; }
282 if ((group[i].size() > 1) && group[i].isDenseEnd())
285 std::vector< size_t > toMerge;
286 TVector2 end0(group[i].
end()->Point2D());
287 for (
size_t j = 0; j < group.size(); j++)
289 if (group[j].isEM())
continue;
293 if ((group[j].size() > 1) &&
294 (group[j].length2() < rad2)) ne++;
299 if (
pma::Dist2(end0, group[j].start()->Point2D()) < rad2)
301 ne++; toMerge.push_back(j); tagged =
true;
303 if ((group[j].size() > 1) && (
pma::Dist2(end0, group[j].
end()->Point2D()) < rad2))
305 ne++;
if (!tagged) toMerge.push_back(j);
309 if (ne > maxE) { maxE = ne; idxMaxE = i; toMergeE = toMerge; }
314 std::vector< size_t > toMergeIdxs = toMergeS;
315 if (idxMaxE > idx) { idx = idxMaxE; toMergeIdxs = toMergeE; }
318 toMergeIdxs.push_back(idx);
321 if (idx > -1) group[idx].tagEM(
true);
331 if (idxs.size() < 2)
return 0;
333 for (
const auto i : idxs)
335 if (i < group.size()) group[i].setTag(
true);
338 mf::LogError(
"Segmentation2D") <<
"Merging index out of group range.";
343 size_t k = idxs.front(), i = idxs.front() + 1;
344 while (i < group.size())
346 if (group[i].isTagged())
348 group[k].merge(group[i]);
349 group.erase(group.begin() + i);
353 group[k].setTag(
false);
360 const std::vector< tss::Cluster2D > & inp,
361 std::vector< const tss::Hit2D* > & trackHits,
362 std::vector< const tss::Hit2D* > & emHits)
const 368 for (
const auto & cx : inp)
370 if (!cx.size())
continue;
374 for (
auto h : cx.hits()) emHits.push_back(h);
378 for (
auto h : cx.hits()) trackHits.push_back(h);
387 std::vector< const tss::Hit2D* > & trackHits,
388 std::vector< const tss::Hit2D* > & emHits)
const 395 for (
const auto hx : inp.
hits())
398 for (
const auto hy : inp.
hits())
400 if (hx->Hit2DPtr() == hy->Hit2DPtr())
continue;
402 if (
pma::Dist2(hx->Point2D(), hy->Point2D()) < rad2) n++;
407 emHits.push_back(hx);
411 trackHits.push_back(hx);
418 const std::vector< tss::Cluster2D > & inp,
419 std::vector< const tss::Hit2D* > & trackHits,
420 std::vector< const tss::Hit2D* > & emHits)
const 427 for (
const auto & cx : inp)
429 if (!cx.size())
continue;
431 for (
const auto hx : cx.hits())
434 for (
const auto & cy : inp)
436 if (!cy.size())
continue;
438 for (
const auto hy : cy.hits())
440 if (hx->Hit2DPtr() == hy->Hit2DPtr())
continue;
442 if (
pma::Dist2(hx->Point2D(), hy->Point2D()) < rad2) n++;
448 emHits.push_back(hx);
452 trackHits.push_back(hx);
463 bool clover =
false;
bool clunder =
false;
464 bool clleft =
false;
bool clright =
false;
466 if (cl2.
isEM())
return false;
470 TVector2 point((cl2.
max()).
X(), (cl2.
min()).
Y());
471 float width = (cl2.
max()).
X() - (cl2.
min()).
X();
472 float height = (cl2.
max()).
Y() - (cl2.
min()).
Y();
474 for (
unsigned int h = 0; h < cl1.
size(); h++)
476 float wire = cl1[h].Point2D().X();
float drift = cl1[h].Point2D().Y();
478 if ( (wire <= (point.X() + shift)) && (wire >= (point.X() - width - shift)) )
480 if (drift < point.Y())
484 else if (drift > (point.Y() + height))
489 if (wire > point.X())
493 else if (wire < (point.X() - width))
500 if (clover && clunder && clleft && clright)
return true;
int mergeClusters(std::vector< tss::Cluster2D > &group, const std::vector< size_t > &idxs) const
TVector2 const & Point2D(void) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
const tss::Hit2D * start(void) const
void mergeDenseParts(std::vector< tss::Cluster2D > &group) const
void push_back(const tss::Hit2D *hit)
void splitHitsNaive(const tss::Cluster2D &inp, std::vector< const tss::Hit2D * > &trackHits, std::vector< const tss::Hit2D * > &emHits) const
Split into linear clusters.
const Hit2D * outermost(size_t &idx) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
const Hit2D * closest(const TVector2 &p2d, size_t &idx) const
tss::Cluster2D selectRing(const tss::Cluster2D &inp, TVector2 center) const
void reconfigure(const fhicl::ParameterSet &p)
const std::vector< const tss::Hit2D * > & hits(void) const
TVector2 GetProjectionToSegment(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
bool Cl2InsideCl1(tss::Cluster2D &cl1, tss::Cluster2D &cl2) const
T get(std::string const &key) const
std::vector< tss::Cluster2D > run(const std::vector< tss::Hit2D > &inp) const
const tss::Hit2D * end(void) const
std::vector< tss::Cluster2D > run(tss::Cluster2D &inp) const
tss::Cluster2D buildSegment(tss::Cluster2D &inp, TVector2 center, TVector2 end) const
bool hitsTouching(const tss::Hit2D &h1, const tss::Hit2D &h2) const
Implementation of the Projection Matching Algorithm.
void tagDenseEnds(std::vector< tss::Cluster2D > &group) const
bool release(const tss::Hit2D *hit)
const TVector2 max(void) const
const TVector2 min(void) const
tss::SimpleClustering fSimpleClustering
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void splitHits(const std::vector< tss::Cluster2D > &inp, std::vector< const tss::Hit2D * > &trackHits, std::vector< const tss::Hit2D * > &emHits) const