26 #include "range/v3/algorithm.hpp" 27 #include "range/v3/view.hpp" 32 : fMaxHitsPerSeg(src.fMaxHitsPerSeg)
33 , fPenaltyFactor(src.fPenaltyFactor)
34 , fMaxSegStopFactor(src.fMaxSegStopFactor)
35 , fSegStopValue(src.fSegStopValue)
36 , fMinSegStop(src.fMinSegStop)
37 , fMaxSegStop(src.fMaxSegStop)
38 , fSegStopFactor(src.fSegStopFactor)
39 , fPenaltyValue(src.fPenaltyValue)
40 , fEndSegWeight(src.fEndSegWeight)
41 , fHitsRadius(src.fHitsRadius)
43 , fT0Flag(src.fT0Flag)
54 for (
auto const* node : src.
fNodes)
66 for (
size_t i = 0; i <
fHits.size(); i++)
71 for (
size_t i = 0; i <
fSegments.size(); i++)
73 for (
size_t i = 0; i <
fNodes.size(); i++)
80 mf::LogError(
"pma::Track3D") <<
"Need min. 2 hits per view, at least two views.";
85 if (cryos.size() > 1) {
86 mf::LogError(
"pma::Track3D") <<
"Only one cryostat for now, please.";
89 int cryo = cryos.front();
92 if (tpcs.size() > 1) {
97 int tpc = tpcs.front();
100 mf::LogVerbatim(
"pma::Track3D") <<
"Track initialized with 3D reference points.";
102 mf::LogVerbatim(
"pma::Track3D") <<
"Track initialized with hit positions.";
105 mf::LogVerbatim(
"pma::Track3D") <<
"Track initialized in the module center.";
114 for (
size_t i = 0; i <
fNodes.size(); i++)
131 TVector3 v3d_1(0., 0., 0.), v3d_2(0., 0., 0.);
133 assert(!
fHits.empty());
138 geo::PlaneID const hit0_a_planeid{tpcid, hit0_a->View2D()};
141 float minX = detProp.
ConvertTicksToX(hit0_a->PeakTime(), hit0_a_planeid);
158 float minDiff0 = 5000, minDiff1 = 5000;
159 for (
auto hit : fHits) {
161 double diff = fabs(x - minX);
162 if ((diff < minDiff0) && (
hit->View2D() != hit0_a->View2D())) {
166 diff = fabs(x - maxX);
167 if ((diff < minDiff1) && (
hit->View2D() != hit1_a->
View2D())) {
173 if (hit0_a && hit0_b && hit1_a && hit1_b) {
176 double x = 0.5 * (detProp.
ConvertTicksToX(hit0_a->PeakTime(), hit0_a_planeid) +
183 v3d_1.SetXYZ(x, y, z);
191 v3d_2.SetXYZ(x, y, z);
194 AddNode(detProp, v3d_1, tpc, cryo);
195 AddNode(detProp, v3d_2, tpc, cryo);
199 Optimize(detProp, 0, 0.01F,
false,
true, 100);
226 TVector3
mean(0., 0., 0.), stdev(0., 0., 0.), p(0., 0., 0.);
230 p.SetXYZ(p.X() * p.X(), p.Y() * p.Y(), p.Z() * p.Z());
236 p.SetXYZ(p.X() * p.X(), p.Y() * p.Y(), p.Z() * p.Z());
239 double sx = stdev.X(), sy = stdev.Y(), sz = stdev.Z();
252 stdev.SetXYZ(sx, sy, sz);
254 double scale = 2.0 * stdev.Mag();
255 double iscale = 1.0 /
scale;
257 size_t max_index = 0;
258 double norm2, max_norm2 = 0.0;
259 std::vector<TVector3> data;
265 if (norm2 > max_norm2) {
272 double y = 0.0, kappa = 1.0, prev_kappa, kchg = 1.0;
273 TVector3
w(data[max_index]);
275 while (kchg > 0.0001)
276 for (
size_t i = 0; i < data.size(); i++) {
278 w += (y / kappa) * (data[i] - y * w);
282 kchg = fabs((kappa - prev_kappa) / prev_kappa);
286 TVector3 v1(w), v2(w);
301 Optimize(detProp, 0, 0.01F,
false,
true, 100);
313 double minX = tpcGeo.
MinX(), maxX = tpcGeo.MaxX();
314 double minY = tpcGeo.MinY(),
maxY = tpcGeo.MaxY();
315 double minZ = tpcGeo.MinZ(), maxZ = tpcGeo.MaxZ();
317 TVector3 v3d_1(0.5 * (minX + maxX), 0.5 * (minY +
maxY), 0.5 * (minZ + maxZ));
318 TVector3 v3d_2(v3d_1);
320 TVector3 shift(5.0, 5.0, 5.0);
325 AddNode(detProp, v3d_1, tpc, cryo);
326 AddNode(detProp, v3d_2, tpc, cryo);
336 for (
size_t i = 0; i <
fNodes.size(); ++i)
337 if (
fNodes[i] == n)
return (
int)i;
343 for (
size_t i = 0; i <
size(); i++)
344 if (
fHits[i] == hit)
return (
int)i;
358 for (
auto const& trk_hit :
fHits) {
359 if (trk_hit->fHit == hit)
return false;
369 for (
size_t i = 0; i <
size(); i++) {
370 if (hit ==
fHits[i]->fHit) {
385 if (s->HasHit(h))
return s->GetDirection3D();
388 if (
n->HasHit(h))
return n->GetDirection3D();
394 <<
"GetDirection3D(): had to update hit assignment to segment/node.";
396 return pe->GetDirection3D();
399 throw cet::exception(
"pma::Track3D") <<
"GetDirection3D(): direction of a not assigned hit " 400 << index <<
" (size: " <<
fHits.size() <<
")" << std::endl;
425 if (
hit->View2D() == view) n++;
441 unsigned int nviews = 0;
450 std::vector<unsigned int> tpc_idxs;
452 unsigned int tpc =
hit->TPC();
455 for (
unsigned int const tpc_idx : tpc_idxs)
456 if (tpc_idx == tpc) {
461 if (!found) tpc_idxs.push_back(tpc);
468 std::vector<unsigned int> cryo_idxs;
470 unsigned int cryo =
hit->Cryo();
473 for (
size_t j = 0; j < cryo_idxs.size(); j++)
474 if (cryo_idxs[j] == cryo) {
479 if (!found) cryo_idxs.push_back(cryo);
488 unsigned int cryo)
const 490 std::pair<TVector2, TVector2> range(TVector2(0., 0.), TVector2(0., 0.));
493 while ((n0 <
fNodes.size()) && (
fNodes[n0]->TPC() != (int)tpc))
498 while ((n1 <
fNodes.size()) && (
fNodes[n1]->TPC() == (int)tpc))
502 if (n1 ==
fNodes.size()) n1--;
504 TVector2 p0 =
fNodes[n0]->Projection2D(view);
507 TVector2 p1 =
fNodes[n1]->Projection2D(view);
510 if (p0.X() > p1.X()) {
512 p0.Set(p1.X(), p0.Y());
515 if (p0.Y() > p1.Y()) {
517 p0.Set(p0.X(), p1.Y());
528 std::vector<pma::Track3D*>& allTracks)
530 if (
fNodes.size() < 2) {
return true; }
532 std::vector<pma::Track3D*> toSort;
545 allTracks.push_back(u);
546 if (u->
Flip(detProp, allTracks)) {
548 toSort.push_back(
this);
552 <<
"Flip(): Could not flip after split (but new track is preserved!!).";
561 throw cet::exception(
"pma::Track3D") <<
"Node not found." << std::endl;
566 if (t->
Flip(detProp, allTracks))
569 toSort.push_back(
this);
579 toSort.push_back(
this);
582 for (
size_t t = 0; t < toSort.size(); t++) {
584 for (
size_t u = 0; u < t; u++)
585 if (toSort[u] == toSort[t]) {
590 toSort[t]->MakeProjection();
591 toSort[t]->SortHits();
599 for (
size_t i = 0; i <
fNodes.size() - 1; i++)
600 if (
fNodes[i]->NextCount() > 1) {
601 for (
size_t j = 0; j <
fNodes[i]->NextCount(); j++) {
607 if (
fNodes.back()->NextCount())
608 for (
size_t j = 0; j <
fNodes.back()->NextCount(); j++) {
610 toSort.push_back(s->
Parent());
613 if (
fNodes.front()->Prev()) {
615 toSort.push_back(s->
Parent());
620 toSort.push_back(
this);
626 std::vector<pma::Track3D*> toSort;
628 toSort.push_back(
this);
630 for (
size_t t = 0; t < toSort.size(); t++) {
632 for (
size_t u = 0; u < t; u++)
633 if (toSort[u] == toSort[t]) {
638 toSort[t]->MakeProjection();
639 toSort[t]->SortHits();
646 if (!
fNodes.size()) {
return false; }
664 unsigned int nViews = 3;
666 for (
unsigned int i = 0; i < nViews; i++) {
669 unsigned int bestView = 2;
670 if (dedxInViews[0].
size() > 2 * dedxInViews[2].
size()) bestView = 0;
671 if (dedxInViews[1].
size() > 2 * dedxInViews[2].
size()) bestView = 1;
673 std::vector<std::vector<double>> dedx;
674 for (
size_t i = 0; i <
size(); i++) {
675 auto it = dedxInViews[bestView].find(i);
676 if (it != dedxInViews[bestView].
end()) { dedx.push_back(it->second); }
678 if (!dedx.empty()) dedx.pop_back();
680 float dEdxStart = 0.0F, dEdxStop = 0.0F;
681 float dEStart = 0.0F, dxStart = 0.0F;
682 float dEStop = 0.0F, dxStop = 0.0F;
683 if (dedx.size() > 4) {
686 if (dedx.size() > 30)
688 else if (dedx.size() > 20)
690 else if (dedx.size() > 10)
696 size_t k = (dedx.size() - 2) >> 1;
699 for (
size_t i = 1, j = 0; j <
n; i++, j++) {
700 dEStart += dedx[i][5];
701 dxStart += dedx[i][6];
703 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
705 for (
size_t i = dedx.size() - 2, j = 0; j <
n; i--, j++) {
706 dEStop += dedx[i][5];
707 dxStop += dedx[i][6];
709 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
711 else if (dedx.size() == 4) {
712 dEStart = dedx[0][5] + dedx[1][5];
713 dxStart = dedx[0][6] + dedx[1][6];
714 dEStop = dedx[2][5] + dedx[3][5];
715 dxStop = dedx[2][6] + dedx[3][6];
716 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
717 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
719 else if (dedx.size() > 1) {
720 if (dedx.front()[2] > 0.0F) dEdxStart = dedx.front()[5] / dedx.front()[6];
721 if (dedx.back()[2] > 0.0F) dEdxStop = dedx.back()[5] / dedx.back()[6];
728 <<
"Auto-flip fired (1), thr: " << (1.0 + thr) <<
", value: " << dEdxStart / dEdxStop;
733 <<
"Auto-flip fired (2), thr: " << (1.0 + thr) <<
", value: " << dEdxStop / dEdxStart;
739 std::vector<pma::Track3D*>& allTracks,
744 unsigned int nViews = 3;
746 for (
unsigned int i = 0; i < nViews; i++) {
749 unsigned int bestView = 2;
750 if (dedxInViews[0].
size() > 2 * dedxInViews[2].
size()) bestView = 0;
751 if (dedxInViews[1].
size() > 2 * dedxInViews[2].
size()) bestView = 1;
753 std::vector<std::vector<double>> dedx;
754 for (
size_t i = 0; i <
size(); i++) {
755 auto it = dedxInViews[bestView].find(i);
756 if (it != dedxInViews[bestView].
end()) { dedx.push_back(it->second); }
758 if (!dedx.empty()) dedx.pop_back();
760 float dEdxStart = 0.0F, dEdxStop = 0.0F;
761 float dEStart = 0.0F, dxStart = 0.0F;
762 float dEStop = 0.0F, dxStop = 0.0F;
763 if (dedx.size() > 4) {
766 if (dedx.size() > 30)
768 else if (dedx.size() > 20)
770 else if (dedx.size() > 10)
776 size_t k = (dedx.size() - 2) >> 1;
779 for (
size_t i = 1, j = 0; j <
n; i++, j++) {
780 dEStart += dedx[i][5];
781 dxStart += dedx[i][6];
783 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
785 for (
size_t i = dedx.size() - 2, j = 0; j <
n; i--, j++) {
786 dEStop += dedx[i][5];
787 dxStop += dedx[i][6];
789 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
791 else if (dedx.size() == 4) {
792 dEStart = dedx[0][5] + dedx[1][5];
793 dxStart = dedx[0][6] + dedx[1][6];
794 dEStop = dedx[2][5] + dedx[3][5];
795 dxStop = dedx[2][6] + dedx[3][6];
796 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
797 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
799 else if (dedx.size() > 1) {
800 if (dedx.front()[2] > 0.0F) dEdxStart = dedx.front()[5] / dedx.front()[6];
801 if (dedx.back()[2] > 0.0F) dEdxStop = dedx.back()[5] / dedx.back()[6];
809 <<
"Auto-flip fired (1), thr: " << (1.0 + thr) <<
", value: " << dEdxStart / dEdxStop;
810 done =
Flip(detProp, allTracks);
814 <<
"Auto-flip fired (2), thr: " << (1.0 + thr) <<
", value: " << dEdxStop / dEdxStart;
815 done =
Flip(detProp, allTracks);
822 bool normalized)
const 825 mf::LogWarning(
"pma::Track3D") <<
"TestHitsMse(): Empty cluster.";
830 for (
auto const& h :
hits) {
831 unsigned int cryo = h->WireID().Cryostat;
832 unsigned int tpc = h->WireID().TPC;
833 unsigned int view = h->WireID().Plane;
834 unsigned int wire = h->WireID().Wire;
835 float drift = h->PeakTime();
840 return mse / hits.size();
855 double tst, d2 = dist *
dist;
856 unsigned int nhits = 0;
857 for (
auto const& h :
hits)
865 auto const nHits =
size();
866 if (nHits < 2)
return 0.0;
873 if (start >= nHits - 1)
return 0.0;
874 if (stop >= nHits) stop = nHits - 1;
880 size_t i = start + step;
897 if (index < -1) index = -1;
898 while (++index < (
int)
size())
901 if (hit->
View2D() == view) {
914 if (index > (
int)
size()) index = (int)
size();
918 if (hit->
View2D() == view) {
931 bool secondDir)
const 936 if (hit->
View2D() != view) {
937 mf::LogWarning(
"pma::Track3D") <<
"Function used with the hit not matching specified view.";
941 bool hitFound =
false;
945 while (!hitFound && (++i < (
int)
size())) {
949 if (nexthit->
View2D() == view)
967 while (!hitFound && (--i >= 0)) {
971 if (nexthit->
View2D() == view)
988 default:
mf::LogError(
"pma::Track3D") <<
"Direction undefined.";
break;
995 if (index <
size()) {
1000 mf::LogError(
"pma::Track3D") <<
"Hit index out of range.";
1010 while (k < nCount) {
1012 if (seg && (seg->
Parent() ==
this))
return seg;
1022 if (seg->Parent() ==
this)
return seg;
1030 bool inclDisabled)
const 1034 if (!
size())
return 0.0;
1040 double rv, dr, dR, dq, dEq, qSkipped = 0.0;
1042 size_t j =
NextHit(-1, view, inclDisabled), s = skip;
1043 if (j >=
size())
return 0.0F;
1055 j =
NextHit(j, view, inclDisabled);
1058 size_t jmax =
PrevHit(
size(), view, inclDisabled);
1060 std::vector<size_t> indexes;
1061 TVector3 p0(0., 0., 0.), p1(0., 0., 0.);
1062 TVector2 c0(0., 0.),
c1(0., 0.);
1066 indexes.push_back(j);
1085 while (((m < step) || (dR < 0.1) || (dr == 0.0)) && (j <= jmax)) {
1087 if (j > jmax)
break;
1090 if (!inclDisabled && !hit->
IsEnabled()) {
1096 indexes.push_back(j);
1117 double range =
Length(0, j);
1119 std::vector<double> trk_section;
1120 trk_section.push_back(c0.X());
1121 trk_section.push_back(c0.Y());
1122 trk_section.push_back(p0.X());
1123 trk_section.push_back(p0.Y());
1124 trk_section.push_back(p0.Z());
1125 trk_section.push_back(dEq);
1126 trk_section.push_back(dR);
1127 trk_section.push_back(range);
1129 for (
auto const idx : indexes)
1130 dedx[idx] = trk_section;
1132 j =
NextHit(j, view, inclDisabled);
1141 unsigned int view)
const 1143 std::vector<float> drifts;
1144 for (
size_t i = 0; i <
fNodes.size() - 1; i++) {
1146 if ((tpc !=
fNodes[i + 1]->TPC()) || (cryo !=
fNodes[i + 1]->Cryo()))
continue;
1149 fNodes[i]->Projection2D(view).
X(),
1150 fNodes[i]->Projection2D(view).
Y(),
1155 fNodes[i + 1]->Projection2D(view).
X(),
1156 fNodes[i + 1]->Projection2D(view).
Y(),
1161 if ((p0.X() - wire) * (p1.X() - wire) <= 0.0) {
1162 double frac_w = (wire - p0.X()) / (p1.X() - p0.X());
1163 double d = p0.Y() + frac_w * (p1.Y() - p0.Y());
1164 drifts.push_back((
float)d);
1173 int dPrev, dw,
w, wx, wPrev, i =
NextHit(-1, view);
1178 std::vector<pma::Hit3D*> missHits;
1180 while (i < (
int)
size()) {
1184 if (hit->
View2D() == view) {
1187 wPrev = hitPrev->
Wire();
1189 if (
abs(w - wPrev) > 1) {
1198 unsigned int iWire = wx;
1200 if (drifts.size()) {
1201 peakTime = drifts[0];
1202 for (
size_t d = 1;
d < drifts.size();
d++)
1203 if (fabs(drifts[
d] - dPrev) < fabs(peakTime - dPrev)) peakTime = drifts[
d];
1206 mf::LogVerbatim(
"pma::Track3D") <<
"Track does not intersect with the wire " << wx;
1210 new pma::Hit3D(detProp, iWire, view, hit->
TPC(), hit->
Cryo(), peakTime, 1.0, 1.0);
1211 missHits.push_back(hmiss);
1222 while ((i < (
int)
size()) && (hit->
TPC() !=
fHits[i]->TPC())) {
1229 if (missHits.size()) {
1230 for (
size_t hi = 0; hi < missHits.size(); hi++) {
1238 return missHits.size();
1261 if (!maxSeg)
return false;
1263 unsigned int nHitsByView[3];
1264 unsigned int nHits, maxHits = 0;
1265 unsigned int vIndex = 0, segHits, maxSegHits = 0;
1266 float segLength, maxLength = maxSeg->
Length();
1267 for (
unsigned int i = si + 1; i <
fNodes.size(); i++) {
1274 segHits = nHitsByView[0] + nHitsByView[1] + nHitsByView[2];
1277 if ((nHitsByView[0] == 0) && ((nHitsByView[1] < 4) || (nHitsByView[2] < 4)))
continue;
1278 if ((nHitsByView[1] == 0) && ((nHitsByView[0] < 4) || (nHitsByView[2] < 4)))
continue;
1279 if ((nHitsByView[2] == 0) && ((nHitsByView[0] < 4) || (nHitsByView[1] < 4)))
continue;
1284 if (nHits > maxHits) {
1286 maxLength = seg->
Length();
1287 maxSegHits = segHits;
1291 else if (nHits == maxHits) {
1292 segLength = seg->
Length();
1293 if (segLength > maxLength) {
1294 maxLength = segLength;
1295 maxSegHits = segHits;
1302 if (maxSegHits > 1) {
1309 unsigned int maxViewIdx = 2, midViewIdx = 2;
1310 if ((nHitsByView[2] >= nHitsByView[1]) && (nHitsByView[1] >= nHitsByView[0])) {
1314 else if ((nHitsByView[1] >= nHitsByView[2]) && (nHitsByView[2] >= nHitsByView[0])) {
1318 else if ((nHitsByView[0] >= nHitsByView[2]) && (nHitsByView[2] >= nHitsByView[1])) {
1322 else if ((nHitsByView[2] >= nHitsByView[0]) && (nHitsByView[0] >= nHitsByView[1])) {
1326 else if ((nHitsByView[0] >= nHitsByView[1]) && (nHitsByView[1] >= nHitsByView[2])) {
1330 else if ((nHitsByView[1] >= nHitsByView[0]) && (nHitsByView[0] >= nHitsByView[2])) {
1334 if (nHitsByView[midViewIdx] < 2) midViewIdx = maxViewIdx;
1336 if (nHitsByView[midViewIdx] < 2) {
1341 unsigned int mHits[3] = {0, 0, 0};
1342 unsigned int halfIndex = (nHitsByView[midViewIdx] >> 1) - 1;
1343 unsigned int n = 0, i = 0, i0 = 0, i1 = 0;
1344 while (i < maxSeg->
NHits() - 1) {
1347 if (maxSeg->
Hit(i).
View2D() == midViewIdx) {
1348 if (n == halfIndex)
break;
1357 while ((i < maxSeg->
NHits()) &&
1363 if (!nHitsByView[0]) {
1364 if (nHitsByView[1] && (mHits[1] < 2)) {
1368 if (nHitsByView[2] && (mHits[2] < 2)) {
1377 unsigned int tpc = maxSeg->
Hit(i0).
TPC();
1378 unsigned int cryo = maxSeg->
Hit(i0).
Cryo();
1385 fNodes[vIndex]->GetDriftShift());
1401 TVector3
const& p3d,
1407 new pma::Node3D(detProp, p3d, tpc, cryo,
false,
fNodes[at_idx]->GetDriftShift());
1430 bool try_start_at_idx)
1432 if (!idx || (idx + 1 >=
fNodes.size()))
return 0;
1440 for (
size_t i = 0; i < idx; ++i) {
1448 while (k < n->NextCount()) {
1467 while (h <
size()) {
1469 unsigned int view = h3d->
View2D(), tpc = h3d->
TPC(), cryo = h3d->
Cryo();
1470 double dist2D_old =
Dist2(h3d->
Point2D(), view, tpc, cryo);
1471 double dist2D_new = t0->
Dist2(h3d->
Point2D(), view, tpc, cryo);
1473 if ((dist2D_new < dist2D_old) && t0->
HasTPC(tpc))
1483 if (try_start_at_idx && t0->
CanFlip()) {
1484 mf::LogVerbatim(
"pma::Track3D") <<
" attach new t0 and this trk to a common start node";
1489 mf::LogVerbatim(
"pma::Track3D") <<
" attach this trk to the new t0 end node";
1503 for (
size_t i = 0; i < idx; ++i) {
1520 if (vtx == vStart)
return true;
1523 if (vStart->
Prev()) {
1525 if (rootPrev->
IsAttachedTo(rootThis)) {
return false; }
1529 if (rootNext->
IsAttachedTo(rootThis)) {
return false; }
1541 if (!noFlip &&
CanFlip() && (vStart->
TPC() == fNodes.back()->TPC()) &&
1544 (fNodes.back()->NextCount() == 0)) {
1545 mf::LogError(
"pma::Track3D") <<
"Flip, endpoint closer to vStart.";
1549 if (vStart->
TPC() == vtx->
TPC())
1557 if (
fNodes.front()->Prev())
return false;
1580 if (vStart->
Prev()) {
1593 mf::LogError(
"pma::Track3D") <<
"Flips in vtx and vStart not possible, cannot attach.";
1617 throw cet::exception(
"pma::Track3D") <<
"Something is still using disconnected vertex.";
1628 if (vtx == vStart)
return true;
1631 if (vStart->
Prev()) {
1633 if (rootPrev->
IsAttachedTo(rootThis)) {
return false; }
1637 if (rootNext->
IsAttachedTo(rootThis)) {
return false; }
1649 if (vStart->
TPC() == vtx->
TPC())
1657 if (vStart->
Prev())
return false;
1661 fNodes.push_back(vStart);
1663 size_t idx =
fNodes.size() - 1;
1673 if (vStart->
Prev()) {
1677 mf::LogError(
"pma::Track3D") <<
"Cannot attach back to inner node of other track.";
1684 mf::LogError(
"pma::Track3D") <<
"Flip not possible, cannot attach.";
1703 <<
"Something is still using disconnected vertex." << std::endl;
1713 if (src->
fNodes.front()->Prev()) {
1715 <<
"Cant extend with a track being a daughter of another track." << std::endl;
1719 for (
size_t i = 0; i < src->
fNodes.size(); ++i) {
1722 size_t idx =
fNodes.size() - 1;
1727 while (src->
size()) {
1749 if (!trk) trk =
this;
1752 throw cet::exception(
"pma::Track3D") <<
"Broken track, no nodes.";
1759 for (
auto trk : branches)
1760 if (
trk ==
this) {
throw cet::exception(
"pma::Track3D") <<
"Track tree has loop."; }
1762 branches.push_back(
this);
1765 if (skipFirst) i0 = 1;
1767 for (
size_t i = i0; i <
fNodes.size(); ++i)
1768 for (
size_t n = 0;
n <
fNodes[i]->NextCount();
n++) {
1778 if (trk ==
this)
return true;
1780 std::vector<pma::Track3D const*> branchesThis, branchesTrk;
1785 for (
auto bThis : branchesThis)
1786 for (
auto bTrk : branchesTrk)
1787 if (bThis == bTrk)
return true;
1794 if (point == p)
return true;
1800 double sumMse = 0.0;
1801 unsigned int nEnabledHits = 0;
1803 sumMse +=
n->SumDist2(view);
1804 nEnabledHits +=
n->NEnabledHits(view);
1807 sumMse += s->SumDist2(view);
1808 nEnabledHits += s->NEnabledHits(view);
1812 return sumMse / nEnabledHits;
1821 for (
size_t i = 0; i <
fNodes.size(); i++) {
1824 return sum /
fNodes.size();
1836 mf::LogError(
"pma::Track3D") <<
"Track not initialized.";
1845 if (g0 == 0.0)
return g0;
1850 n->SetVertexToBranching(setAllNodes);
1856 if (selSegHits || selVtxHits)
SelectRndHits(selSegHits, selVtxHits);
1858 bool stepDone =
true;
1859 unsigned int stepIter = 0;
1862 unsigned int iter = 0;
1863 while ((gstep > eps) && (iter < 1000)) {
1864 if ((fNodes.size() < 4) || (iter % 10 == 0))
1874 for (
auto n : fNodes)
1884 gstep = fabs(g0 - g1) / g0;
1889 if (fNodes.size() > 2) {
1892 }
while (!stepDone && (stepIter < 5));
1902 case 0: stop =
true;
break;
1908 if (!
AddNode(detProp)) stop =
true;
1927 if (
AddNode(detProp)) nNodes--;
1930 else if (nNodes > 4) {
1941 if (
AddNode(detProp)) nNodes--;
1944 if (
AddNode(detProp)) { nNodes--; }
1962 constexpr
size_t maxTreeDepth = 100;
1969 if (++depth > maxTreeDepth) {
mf::LogError(
"pma::Track3D") <<
"Tree depth above allowed max."; }
1977 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2011 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2036 dist = sqrt(
Dist2(p3d_cm));
2043 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2045 if (seg != segThis) {
2084 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2086 if (seg != segThis) {
2124 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2144 if ((nearestTrk !=
this) && (dmin < 0.5 * d0)) {
2146 mf::LogVerbatim(
"pma::Track3D") <<
"*** hit moved to another track ***";
2151 if (!
size()) {
mf::LogError(
"pma::Track3D") <<
"ALL hits moved to other tracks."; }
2165 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2190 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2216 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2233 mf::LogError(
"pma::Track3D") <<
"TuneFullTree failed.";
2239 mf::LogError(
"pma::Track3D") <<
"Infinifte value of g.";
2246 if (g0 == 0.0)
return g0;
2249 unsigned int stepIter = 0;
2252 unsigned int iter = 0;
2253 while ((gstep > eps) && (iter < 60)) {
2264 if (g0 == 0.0F)
break;
2266 gstep = fabs(g0 - g1) / g0;
2272 }
while (stepIter < 5);
2277 if (g0 >= 0) {
mf::LogVerbatim(
"pma::Track3D") <<
" done, g = " << g0; }
2279 mf::LogError(
"pma::Track3D") <<
"TuneFullTree failed.";
2299 for (
size_t i = 0; i < node->
NextCount(); i++) {
2305 node =
static_cast<pma::Node3D*
>(segThis->Next());
2310 for (
auto h :
fHits) {
2320 double newdx =
fNodes.front()->GetDriftShift();
2330 auto const* geom = lar::providerFrom<geo::Geometry>();
2335 double correctedSign = 0;
2336 if (tpcGeo.DetectDriftDirection() > 0) {
2337 if (dx > 0) { correctedSign = 1.0; }
2339 correctedSign = -1.0;
2343 if (dx > 0) { correctedSign = -1.0; }
2345 correctedSign = 1.0;
2352 dxInTicks = dxInTicks * correctedSign;
2358 mf::LogDebug(
"pma::Track3D") << dx <<
", " << dxInTicks <<
", " << correctedSign <<
", " <<
fT0 2359 <<
", " << tpcGeo.DetectDriftDirection()
2369 for (
size_t i = 0; i <
fSegments.size(); i++)
2379 for (
size_t i = 1; i <
fNodes.size(); i++) {
2386 unsigned int nhits = 0;
2387 while (!nhits && (
fNodes.size() > 2) && !
fNodes.front()->IsBranching()) {
2389 nhits = vtx->
NHits();
2392 nhits += seg->
NHits();
2406 while (!nhits && (
fNodes.size() > 2) && !
fNodes.back()->IsBranching()) {
2408 nhits = vtx->
NHits();
2411 nhits += seg->
NHits();
2430 if (!(
fNodes.front()->Prev())) {
2434 if (vtx ==
fNodes.front())
2437 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner node.";
2445 double l0 = seg->
Length();
2447 if ((seg->
Length() < 0.2 * l0) && (
fNodes.size() > 2)) {
2451 <<
"ShiftEndsToHits(): Short start segment, node removed.";
2460 mf::LogWarning(
"pma::Track3D") <<
"Branching node, not removed.";
2466 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner segment.";
2473 if (!(
fNodes.back()->NextCount())) {
2477 if (vtx ==
fNodes.back())
2480 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner node.";
2488 double l0 = seg->
Length();
2490 if ((seg->
Length() < 0.2 * l0) && (
fNodes.size() > 2)) {
2491 size_t idx =
fNodes.size() - 2;
2495 <<
"ShiftEndsToHits(): Short end segment, node removed.";
2504 mf::LogWarning(
"pma::Track3D") <<
"Branching node, not removed.";
2510 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner segment.";
2523 unsigned int cryo)
const 2525 double dist, min_dist = 1.0e12;
2527 int t = (int)tpc, c = (
int)cryo;
2528 auto n0 =
fNodes.front();
2529 if ((n0->TPC() == t) && (n0->Cryo() == c)) {
2530 dist = n0->GetDistance2To(p2d, view);
2531 if (dist < min_dist) min_dist =
dist;
2534 if ((n1->TPC() == t) && (n1->Cryo() == c)) {
2535 dist = n1->GetDistance2To(p2d, view);
2536 if (dist < min_dist) min_dist =
dist;
2540 if ((s->TPC() == t) && (s->Cryo() == c)) {
2541 dist = s->GetDistance2To(p2d, view);
2542 if (dist < min_dist) min_dist =
dist;
2550 auto to_distance2 = [&p3d](
auto seg) {
return seg->GetDistance2To(p3d); };
2551 return min(
fSegments | views::transform(to_distance2));
2558 bool skipBackVtx)
const 2560 if (
fSegments.front()->TPC() < 0) skipFrontVtx =
false;
2561 if (
fSegments.back()->TPC() < 0) skipBackVtx =
false;
2563 if (skipFrontVtx && skipBackVtx && (
fSegments.size() == 1))
2566 size_t v0 = 0, v1 =
fNodes.size();
2567 if (skipFrontVtx) v0 = 1;
2568 if (skipBackVtx) --v1;
2571 auto min_dist = std::numeric_limits<double>::max();
2572 for (
size_t i = v0; i < v1; i++)
2573 if (
fNodes[i]->TPC() == tpc) {
2574 double dist =
fNodes[i]->GetDistance2To(p2d, view);
2575 if (dist < min_dist) {
2581 if (segment->TPC() == tpc) {
2582 if (segment->TPC() < 0)
continue;
2584 double const dist = segment->GetDistance2To(p2d, view);
2585 if (dist < min_dist) {
2590 if (!pe_min)
throw cet::exception(
"pma::Track3D") <<
"Nearest element not found." << std::endl;
2598 for (
size_t i = 1; i <
fNodes.size(); i++) {
2599 dist =
fNodes[i]->GetDistance2To(p3d);
2600 if (dist < min_dist) {
2605 for (
size_t i = 0; i <
fSegments.size(); i++) {
2606 dist =
fSegments[i]->GetDistance2To(p3d);
2607 if (dist < min_dist) {
2618 double& dist2)
const 2628 double d2, min_d2 = 1.0e100;
2631 for (
size_t i = 0; i <
fSegments.size(); i++) {
2632 if (
fSegments[i]->TPC() != tpc)
continue;
2634 d2 =
fSegments[i]->GetDistance2To(p2d, view);
2641 p3d = seg->GetUnconstrainedProj3D(p2d, view);
2653 std::vector<pma::Hit3D*> hits_tmp;
2654 hits_tmp.reserve(
size());
2660 for (
size_t i = 0; i < vtx->
NHits(); i++) {
2662 if (h3d->
fParent ==
this) hits_tmp.push_back(h3d);
2667 for (
size_t i = 0; i < seg->
NHits(); i++) {
2669 if (h3d->
fParent ==
this) hits_tmp.push_back(h3d);
2679 if (
size() == hits_tmp.size()) {
2680 for (
size_t i = 0; i <
size(); i++) {
2681 fHits[i] = hits_tmp[i];
2685 mf::LogError(
"pma::Track3D") <<
"Hit sorting problem.";
2692 unsigned int nDisabled = 0;
2694 std::array<int, 4> hasHits{{}};
2699 bool rebuild =
false, stop =
false;
2709 for (
size_t i = 0; i < vtx->
NHits(); i++) {
2711 if ((hitIndex >= 0) && (hitIndex + 1 < (
int)
size()))
2712 nextHit =
fHits[hitIndex + 1];
2718 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2726 for (
size_t i = 0; i < seg->
NHits(); i++) {
2728 if ((hitIndex >= 0) && (hitIndex + 1 < (
int)
size()))
2729 nextHit =
fHits[hitIndex + 1];
2735 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2744 if (
fNodes.size() < 3)
break;
2746 nViews = hasHits[1] + hasHits[2] + hasHits[3];
2747 if (hasHits[0] || (nViews > 1))
2749 else if (!
fNodes.front()->IsBranching()) {
2769 for (
int i = vtx->
NHits() - 1; i >= 0; i--) {
2771 if ((hitIndex >= 0) && (hitIndex - 1 >= 0))
2772 nextHit =
fHits[hitIndex - 1];
2778 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2786 for (
int i = seg->
NHits() - 1; i >= 0; i--) {
2788 if ((hitIndex >= 0) && (hitIndex - 1 >= 0))
2789 nextHit =
fHits[hitIndex - 1];
2795 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2804 if (
fNodes.size() < 3)
break;
2806 nViews = hasHits[1] + hasHits[2] + hasHits[3];
2807 if (hasHits[0] || (nViews > 1))
2809 else if (!
fNodes.back()->IsBranching()) {
2828 if (fraction < 0.0F) fraction = 0.0F;
2829 if (fraction > 1.0F) fraction = 1.0F;
2832 size_t nHitsColl = (size_t)(fraction *
NHits(
geo::kZ));
2833 size_t nHitsInd2 = (size_t)(fraction *
NHits(
geo::kV));
2834 size_t nHitsInd1 = (size_t)(fraction *
NHits(
geo::kU));
2835 size_t coll = 0, ind2 = 0, ind1 = 0;
2837 bool b, changed =
false;
2838 for (
auto h :
fHits) {
2840 if (fraction < 1.0F) {
2841 h->SetEnabled(
false);
2842 switch (h->View2D()) {
2844 if (coll++ < nHitsColl) h->SetEnabled(
true);
2847 if (ind2++ < nHitsInd2) h->SetEnabled(
true);
2850 if (ind1++ < nHitsInd1) h->SetEnabled(
true);
2855 h->SetEnabled(
true);
2857 changed |= (b != h->IsEnabled());
2860 if (fraction < 1.0F) {
2869 bool changed =
false;
2871 changed |=
n->SelectRndHits(vtxmax);
2873 changed |= s->SelectRndHits(segmax);
2879 bool changed =
false;
2880 for (
auto h :
fHits) {
2881 changed |= !(h->IsEnabled());
2882 h->SetEnabled(
true);
2890 n->ClearAssigned(
this);
2892 s->ClearAssigned(
this);
2896 bool skipFrontVtx =
false, skipBackVtx =
false;
2899 if (!(fNodes.front()->IsFrozen()) && !(fNodes.front()->Prev()) &&
2900 (fNodes.front()->NextCount() == 1)) {
2901 skipFrontVtx =
true;
2903 if (!(fNodes.front()->IsFrozen()) && (fNodes.back()->NextCount() == 0)) { skipBackVtx =
true; }
2905 for (
auto h :
fHits)
2907 pe =
GetNearestElement(h->Point2D(), h->View2D(), h->TPC(), skipFrontVtx, skipBackVtx);
2917 for (
auto n : fNodes)
2918 n->UpdateHitParams();
2919 for (
auto s : fSegments)
2920 s->UpdateHitParams();
2925 std::vector<std::pair<pma::Hit3D*, pma::Element3D*>> assignments;
2926 assignments.reserve(
fHits.size());
2928 for (
auto hi :
fHits) {
2932 for (
size_t j = 0; j < s->NHits(); ++j)
2933 if (hi == s->Hits()[j])
2937 int const tpc = hi->TPC();
2940 if (nnext->
TPC() == tpc) {
2941 double const d2 = nnext->
GetDistance2To(hi->Point2D(), hi->View2D());
2948 if (snext && (snext->
TPC() == tpc)) {
2949 double const d2 = snext->
GetDistance2To(hi->Point2D(), hi->View2D());
2956 if (nnext->
TPC() == tpc) {
2957 double const d2 = nnext->
GetDistance2To(hi->Point2D(), hi->View2D());
2967 if (nprev->
TPC() == tpc) {
2968 double const d2 = nprev->
GetDistance2To(hi->Point2D(), hi->View2D());
2975 if (sprev && (sprev->
TPC() == tpc)) {
2976 double const d2 = sprev->
GetDistance2To(hi->Point2D(), hi->View2D());
2983 if (nprev->
TPC() == tpc) {
2984 double const d2 = nprev->
GetDistance2To(hi->Point2D(), hi->View2D());
3001 for (
size_t j = 0; j <
n->NHits(); ++j)
3002 if (hi ==
n->Hits()[j])
3005 double d2, min_d2 =
n->GetDistance2To(hi->Point2D(), hi->View2D());
3006 int tpc = hi->TPC();
3009 if (snext && (snext->
TPC() == tpc)) {
3017 if (nnext->
TPC() == tpc) {
3025 if (snext && (snext->
TPC() == tpc)) {
3036 if (sprev && (sprev->
TPC() == tpc)) {
3044 if (nprev->
TPC() == tpc) {
3052 if (sprev && (sprev->
TPC() == tpc)) {
3069 assignments.emplace_back(hi, pe);
3071 mf::LogWarning(
"pma::Track3D") <<
"Hit was not assigned to any element.";
3074 for (
auto const& a : assignments)
3075 a.second->AddHit(a.first);
3078 n->UpdateHitParams();
3080 s->UpdateHitParams();
3086 n->UpdateProjection();
3088 s->UpdateProjection();
3094 unsigned int count = 0;
3097 sum +=
n->SumDist2();
3098 count +=
n->NEnabledHits();
3102 sum += s->SumDist2();
3103 count += s->NEnabledHits();
3106 if (count) {
return sum / count; }
3108 mf::LogError(
"pma::Track3D") <<
"0 enabled hits in AverageDist2 calculation.";
3122 float nCubeRoot = pow((
double)n, 1.0 / 3.0);
3124 if (avgDist2Root > 0) {
3141 if (v0 == v1)
return false;
3155 fNodes[v1]->RemoveNext(nextSeg);
3163 fNodes[v0]->AddNext(midSeg);
3165 if (nextSeg)
fNodes[v1]->AddNext(nextSeg);
3179 unsigned int v1, v2;
3182 if (
fSegments.front()->IsFrozen())
return false;
3183 if (
fNodes.front()->NextCount() > 1)
return false;
3188 if (
fSegments.back()->IsFrozen())
return false;
3189 if (
fNodes.back()->NextCount() > 1)
return false;
3193 default:
return false;
3195 if (
fNodes[v1]->TPC() !=
fNodes[v2]->TPC())
return false;
3214 std::vector<pma::Hit3D*> hitsColl, hitsInd1, hitsInd2;
3216 switch (
hit->View2D()) {
3217 case geo::kZ: hitsColl.push_back(
hit);
break;
3218 case geo::kV: hitsInd2.push_back(
hit);
break;
3219 case geo::kU: hitsInd1.push_back(
hit);
break;
bool SelectHits(float fraction=1.0F)
void ApplyDriftShift(double dx)
code to link reconstructed objects back to the MC truth information
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
void MakeFastProjection()
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
TVector3 const & Point3D() const
void AutoFlip(pma::Track3D::EDirection dir, double thr=0.0, unsigned int n=0)
bool HasTPC(int tpc) const
virtual bool AddNext(pma::SortedObjectBase *nextElement)
Utilities related to art service access.
double GetMse(unsigned int view=geo::kUnknown) const
MSE of hits weighted with hit amplidudes and wire plane coefficients.
void RemoveHitAt(size_t index)
void SortHitsInTree(bool skipFirst=false)
bool AttachTo(pma::Node3D *vStart, bool noFlip=false)
double GetHitsRadius2D(const std::vector< pma::Hit3D * > &hits, bool exact=false)
double Dist2(const TVector2 &p2d, unsigned int view, unsigned int tpc, unsigned int cryo) const
Implementation of the Projection Matching Algorithm.
TVector2 const & Point2D() const noexcept
bool IsAttachedTo(pma::Track3D const *trk) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
double GetXTicksCoefficient(int t, int c) const
void ApplyDriftShiftInTree(const detinfo::DetectorClocksData &clockData, detinfo::DetectorPropertiesData const &detProp, double dx, bool skipFirst=false)
void ClearAssigned(pma::Track3D *trk=0) override
void AddPoint(TVector3 *p)
virtual int RemoveNext(pma::SortedObjectBase *nextElement)
pma::Hit3D const * front() const
bool IsEnabled() const noexcept
Implementation of the Projection Matching Algorithm.
unsigned int TestHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, double dist=0.4) const
Count close 2D hits.
unsigned int Cryo() const noexcept
double MinX() const
Returns the world x coordinate of the start of the box.
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
void ReassignHitsInTree(pma::Track3D *plRoot=nullptr)
int index_of(const pma::Hit3D *hit) const
double GetDistance2To(const TVector3 &p3d) const override
Distance [cm] from the 3D point to the point 3D.
bool AttachBackToSameTPC(pma::Node3D *vStart)
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
bool GetBranches(std::vector< pma::Track3D const * > &branches, bool skipFirst=false) const
virtual unsigned int NextCount(void) const
bool AttachToOtherTPC(pma::Node3D *vStart)
bool CheckEndSegment(pma::Track3D::ETrackEnd endCode)
constexpr auto abs(T v)
Returns the absolute value of the argument.
bool InitFromHits(detinfo::DetectorPropertiesData const &detProp, int tpc, int cryo, float initEndSegW=0.05F)
double GetObjFunction(float penaltyFactor=1.0F) const
Objective function optimized in track reconstruction.
double TriggerOffsetTPC() const
TVector3 const & Point3D() const
CryostatID_t Cryostat
Index of cryostat.
bool Initialize(detinfo::DetectorPropertiesData const &detProp, float initEndSegW=0.05F)
void Optimize(float penaltyValue, float endSegWeight)
Planes which measure Z direction.
TVector2 WireDriftToCm(detinfo::DetectorPropertiesData const &detProp, unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
std::vector< unsigned int > TPCs() const
WireID_t Wire
Index of the wire within its plane.
geo::WireID const & WireID() const
Initial tdc tick for hit.
virtual pma::SortedObjectBase * Next(unsigned int=0) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< pma::Segment3D * > fSegments
bool AttachBackToOtherTPC(pma::Node3D *vStart)
unsigned int Wire() const noexcept
recob::tracking::Vector_t Vector3D
double TuneFullTree(double eps=0.001, double gmax=50.0)
pma::Vector3D GetDirection3D(size_t index) const
Get trajectory direction at given hit index.
double Optimize(const detinfo::DetectorPropertiesData &detProp, int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
double TuneSinglePass(bool skipFirst=false)
constexpr double TickPeriod() const noexcept
A single tick period in microseconds.
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
unsigned int NEnabledHits(unsigned int view=geo::kUnknown) const
int TPC(void) const
TPC index or -1 if out of any TPC.
std::vector< unsigned int > Cryos() const
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
pma::Track3D * Split(detinfo::DetectorPropertiesData const &detProp, size_t idx, bool try_start_at_idx=true)
double TestHitsMse(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, bool normalized=true) const
MSE of 2D hits.
bool UpdateParamsInTree(bool skipFirst, size_t &depth)
bool CanFlip() const
Check if the track can be flipped without breaking any other track.
size_t NPoints(void) const
unsigned int fSegStopValue
void ExtendWith(pma::Track3D *src)
Extend the track with everything from src, delete the src;.
void AddNode(pma::Node3D *node)
pma::Hit3D * release_at(size_t index)
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
unsigned int NHits(unsigned int view) const
pma::Node3D * FirstElement() const
pma::Node3D * LastElement() const
float PeakTime() const noexcept
virtual int RemoveNext(pma::SortedObjectBase *nextElement)
bool GetUnconstrainedProj3D(detinfo::DetectorPropertiesData const &detProp, art::Ptr< recob::Hit > hit, TVector3 &p3d, double &dist2) const
double GetDriftShift() const
bool HasRefPoint(TVector3 *p) const
bool InitFromRefPoints(detinfo::DetectorPropertiesData const &detProp, int tpc, int cryo)
std::vector< float > DriftsOfWireIntersection(detinfo::DetectorPropertiesData const &detProp, unsigned int wire, unsigned int view) const
void SetT0FromDx(const detinfo::DetectorClocksData &clockData, detinfo::DetectorPropertiesData const &detProp, double dx)
Function to convert dx into dT0.
ElecClock const & TPCClock() const noexcept
Borrow a const TPC clock with time set to Trigger time [us].
float SummedADC() const noexcept
pma::Hit3D & Hit(size_t index)
void SetEnabled(bool state) noexcept
void RemoveHits(const std::vector< art::Ptr< recob::Hit >> &hits)
Remove hits; removes also hit->node/seg assignments.
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
double GetObjFnInTree(bool skipFirst=false)
void InternalFlip(std::vector< pma::Track3D * > &toSort)
bool erase(const art::Ptr< recob::Hit > &hit)
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
unsigned int DisableSingleViewEnds()
bool AttachToSameTPC(pma::Node3D *vStart)
void InsertNode(detinfo::DetectorPropertiesData const &detProp, TVector3 const &p3d, size_t at_idx, unsigned int tpc, unsigned int cryo)
double TriggerTime() const
Trigger electronics clock time in [us].
std::vector< pma::Node3D * > fNodes
Detector simulation of raw signals on wires.
bool SelectRndHits(size_t segmax, size_t vtxmax)
size_t CompleteMissingWires(detinfo::DetectorPropertiesData const &detProp, unsigned int view)
double ConvertTicksToX(double ticks, int p, int t, int c) const
void InitFromMiddle(detinfo::DetectorPropertiesData const &detProp, int tpc, int cryo)
void push_back(pma::Hit3D *hit)
double AverageDist2() const
unsigned int View2D() const noexcept
bool HasTwoViews(size_t nmin=1) const
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
void CleanupTails()
Cut out tails with no hits assigned.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Implementation of the Projection Matching Algorithm.
float PeakTime() const
Time of the signal peak, in tick units.
void MakeProjectionInTree(bool skipFirst=false)
std::map< size_t, std::vector< double > > dedx_map
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
double Length(size_t step=1) const
bool IsFrozen(void) const
Check if the vertex 3D position is fixed.
double GetRawdEdxSequence(std::map< size_t, std::vector< double >> &dedx, unsigned int view=geo::kZ, unsigned int skip=0, bool inclDisabled=false) const
Contains all timing reference information for the detector.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
std::vector< TVector3 * > fAssignedPoints
pma::Segment3D * PrevSegment(pma::Node3D *vtx) const
bool RemoveNode(size_t idx)
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
double GetDistToProj() const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
virtual double GetDistance2To(const TVector3 &p3d) const =0
Distance [cm] from the 3D point to the object 3D.
pma::Hit3D const * back() const
TVector2 CmToWireDrift(detinfo::DetectorPropertiesData const &detProp, float xw, float yd, unsigned int plane, unsigned int tpc, unsigned int cryo)
double HitDxByView(size_t index, unsigned int view) const
double GetDistance2To(const TVector3 &p3d) const override
Distance [cm] from the 3D segment to the point 3D.
void AddHit(pma::Hit3D *h)
bool SwapVertices(size_t v0, size_t v1)
virtual void Disconnect(void)
pma::Track3D * GetNearestTrkInTree(const TVector3 &p3d_cm, double &dist, bool skipFirst=false)
virtual bool AddNext(pma::SortedObjectBase *nextElement)
bool IntersectionPoint(WireID const &wid1, WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
virtual pma::SortedObjectBase * Prev(void) const
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
TPCID_t TPC
Index of the TPC within its cryostat.
unsigned int TPC() const noexcept
pma::Track3D * Parent(void) const
bool AttachBackTo(pma::Node3D *vStart)
void SetProjection(pma::Hit3D &h) const override
Set hit 3D position and its 2D projection to the vertex.
pma::Element3D * GetNearestElement(const TVector2 &p2d, unsigned int view, int tpc=-1, bool skipFrontVtx=false, bool skipBackVtx=false) const
pma::Segment3D * NextSegment(pma::Node3D *vtx) const
double Length(void) const
art framework interface to geometry description
size_t NEnabledHits(unsigned int view=geo::kUnknown) const
cet::coded_exception< error, detail::translate > exception
std::pair< TVector2, TVector2 > WireDriftRange(detinfo::DetectorPropertiesData const &detProp, unsigned int view, unsigned int tpc, unsigned int cryo) const
std::vector< pma::Hit3D * > fHits