30 std::vector< tss::Cluster2D >
result;
31 while (inp.
size() > 1)
37 std::vector< TVector2 > centers;
38 centers.emplace_back(hFirst->
Point2D());
40 while (centers.size())
42 run(inp, result, centers);
55 std::vector< tss::Cluster2D > &
result,
56 std::vector< TVector2 > & centers)
const 58 if (!centers.size())
return;
60 TVector2
center(centers.front());
61 centers.erase(centers.begin());
66 const double dmax2 = 0.5 * 0.5;
76 size_t seedIdx = 0, hitIdx,
h;
77 double d2, min_d2 = seeds.front().dist2(
center, hitIdx);
78 for (
size_t i = 1; i < seeds.size(); i++)
80 d2 = seeds[i].dist2(
center, h);
81 if (d2 < min_d2) { min_d2 = d2; seedIdx = i; hitIdx =
h; }
87 result.emplace_back(segment);
88 if (segment.
size() > 1)
91 if (hEnd) centers.emplace_back(hEnd->
Point2D());
95 seeds.erase(seeds.begin() + seedIdx);
101 result.back().push_back(hFirst);
110 TVector2 segDir = end -
center;
112 double dc, min_dc = 1.0e9;
116 for (
auto h : inp.
hits())
121 TVector2 hDir =
h->Point2D() -
center;
123 if ((hDir * segDir >= 0.0) || (dc < 0.1))
128 min_dc = dc; firstIdx = candidates.
size() - 1;
133 if (candidates.
size() > 1)
136 candidates.
hits()[firstIdx] = candidates.
hits()[0];
137 candidates.
hits()[0] = hFirst;
142 if (candidates.
size())
147 mf::LogError(
"Segmentation2D") <<
"Hit not found in the input cluster.";
151 while ((i < candidates.
size()) &&
157 mf::LogError(
"Segmentation2D") <<
"Hit not found in the input cluster.";
172 for (
size_t h = 0;
h < inp.
size();
h++)
175 if ((d2 >= d2_min) && (d2 <= d2_max))
186 for (
size_t i = 0; i < group.size(); i++)
188 bool denseStart =
false, denseEnd =
false;
189 TVector2 start0(group[i].start()->Point2D()), end0(group[i].
end()->Point2D());
191 for (
size_t j = 0; j < group.size(); j++)
193 if (i == j)
continue;
195 TVector2 start1(group[j].start()->Point2D()), end1(group[j].
end()->Point2D());
197 if (!group[j].isDenseStart())
202 group[j].tagDenseStart(
true);
207 group[j].tagDenseStart(
true);
212 if (!group[j].isDenseEnd())
216 group[j].tagDenseEnd(
true);
221 group[j].tagDenseEnd(
true);
227 if (denseStart) group[i].tagDenseStart(
true);
228 if (denseEnd) group[i].tagDenseEnd(
true);
244 std::vector< size_t > toMergeS, toMergeE;
245 int idxMaxS = -1, idxMaxE = -1;
247 for (
size_t i = 0; i < group.size(); i++)
250 if (group[i].isEM())
continue;
252 if (group[i].isDenseStart())
256 std::vector< size_t > toMerge;
257 TVector2 start0(group[i].start()->Point2D());
258 for (
size_t j = 0; j < group.size(); j++)
260 if (group[j].isEM())
continue;
264 if ((group[j].
size() > 1) &&
265 (group[j].length2() < rad2)) ns++;
270 if (
pma::Dist2(start0, group[j].start()->Point2D()) < rad2)
272 ns++; toMerge.push_back(j); tagged =
true;
274 if ((group[j].
size() > 1) && (
pma::Dist2(start0, group[j].
end()->Point2D()) < rad2))
276 ns++;
if (!tagged) toMerge.push_back(j);
280 if (ns > maxS) { maxS =
ns; idxMaxS = i; toMergeS = toMerge; }
283 if ((group[i].
size() > 1) && group[i].isDenseEnd())
286 std::vector< size_t > toMerge;
287 TVector2 end0(group[i].
end()->Point2D());
288 for (
size_t j = 0; j < group.size(); j++)
290 if (group[j].isEM())
continue;
294 if ((group[j].
size() > 1) &&
295 (group[j].length2() < rad2)) ne++;
300 if (
pma::Dist2(end0, group[j].start()->Point2D()) < rad2)
302 ne++; toMerge.push_back(j); tagged =
true;
304 if ((group[j].
size() > 1) && (
pma::Dist2(end0, group[j].
end()->Point2D()) < rad2))
306 ne++;
if (!tagged) toMerge.push_back(j);
310 if (ne > maxE) { maxE = ne; idxMaxE = i; toMergeE = toMerge; }
315 std::vector< size_t > toMergeIdxs = toMergeS;
316 if (idxMaxE > idx) { idx = idxMaxE; toMergeIdxs = toMergeE; }
319 toMergeIdxs.push_back(idx);
322 if (idx > -1) group[idx].tagEM(
true);
332 if (idxs.size() < 2)
return 0;
334 for (
const auto i : idxs)
336 if (i < group.size()) group[i].setTag(
true);
339 mf::LogError(
"Segmentation2D") <<
"Merging index out of group range.";
344 size_t k = idxs.front(), i = idxs.front() + 1;
345 while (i < group.size())
347 if (group[i].isTagged())
349 group[
k].merge(group[i]);
350 group.erase(group.begin() + i);
354 group[
k].setTag(
false);
361 const std::vector< tss::Cluster2D > & inp,
362 std::vector< const tss::Hit2D* > & trackHits,
363 std::vector< const tss::Hit2D* > & emHits)
const 369 for (
const auto &
cx : inp)
371 if (!
cx.size())
continue;
375 for (
auto h :
cx.hits()) emHits.push_back(
h);
379 for (
auto h :
cx.hits()) trackHits.push_back(
h);
388 std::vector< const tss::Hit2D* > & trackHits,
389 std::vector< const tss::Hit2D* > & emHits)
const 396 for (
const auto hx : inp.
hits())
399 for (
const auto hy : inp.
hits())
401 if (
hx->Hit2DPtr() ==
hy->Hit2DPtr())
continue;
408 emHits.push_back(
hx);
412 trackHits.push_back(
hx);
419 const std::vector< tss::Cluster2D > & inp,
420 std::vector< const tss::Hit2D* > & trackHits,
421 std::vector< const tss::Hit2D* > & emHits)
const 428 for (
const auto &
cx : inp)
430 if (!
cx.size())
continue;
432 for (
const auto hx :
cx.hits())
435 for (
const auto &
cy : inp)
437 if (!
cy.size())
continue;
439 for (
const auto hy :
cy.hits())
441 if (
hx->Hit2DPtr() ==
hy->Hit2DPtr())
continue;
449 emHits.push_back(
hx);
453 trackHits.push_back(
hx);
464 bool clover =
false;
bool clunder =
false;
465 bool clleft =
false;
bool clright =
false;
467 if (cl2.
isEM())
return false;
471 TVector2 point((cl2.
max()).
X(), (cl2.
min()).
Y());
472 float width = (cl2.
max()).
X() - (cl2.
min()).
X();
473 float height = (cl2.
max()).
Y() - (cl2.
min()).
Y();
475 for (
unsigned int h = 0;
h < cl1.
size();
h++)
477 float wire = cl1[
h].Point2D().X();
float drift = cl1[
h].Point2D().Y();
479 if ( (wire <= (point.X() + shift)) && (wire >= (point.X() - width - shift)) )
481 if (drift < point.Y())
485 else if (drift > (point.Y() + height))
490 if (wire > point.X())
494 else if (wire < (point.X() - width))
501 if (clover && clunder && clleft && clright)
return true;
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
TVector2 const & Point2D() const
int mergeClusters(std::vector< tss::Cluster2D > &group, const std::vector< size_t > &idxs) 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)
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
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
std::vector< TrajPoint > seeds
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
void splitHits(const std::vector< tss::Cluster2D > &inp, std::vector< const tss::Hit2D * > &trackHits, std::vector< const tss::Hit2D * > &emHits) const