25 #include "range/v3/algorithm.hpp" 26 #include "range/v3/view.hpp" 31 : fMaxHitsPerSeg(src.fMaxHitsPerSeg)
32 , fPenaltyFactor(src.fPenaltyFactor)
33 , fMaxSegStopFactor(src.fMaxSegStopFactor)
34 , fSegStopValue(src.fSegStopValue)
35 , fMinSegStop(src.fMinSegStop)
36 , fMaxSegStop(src.fMaxSegStop)
37 , fSegStopFactor(src.fSegStopFactor)
38 , fPenaltyValue(src.fPenaltyValue)
39 , fEndSegWeight(src.fEndSegWeight)
40 , fHitsRadius(src.fHitsRadius)
42 , fT0Flag(src.fT0Flag)
53 for (
auto const* node : src.
fNodes)
65 for (
size_t i = 0; i <
fHits.size(); i++)
70 for (
size_t i = 0; i <
fSegments.size(); i++)
72 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.";
115 for (
size_t i = 0; i <
fNodes.size(); i++)
132 TVector3 v3d_1(0., 0., 0.), v3d_2(0., 0., 0.);
134 assert(!
fHits.empty());
139 float minX = detProp.
ConvertTicksToX(hit0_a->PeakTime(), hit0_a->View2D(), tpc, cryo);
156 float minDiff0 = 5000, minDiff1 = 5000;
157 for (
auto hit : fHits) {
159 double diff = fabs(x - minX);
160 if ((diff < minDiff0) && (
hit->View2D() != hit0_a->View2D())) {
164 diff = fabs(x - maxX);
165 if ((diff < minDiff1) && (
hit->View2D() != hit1_a->
View2D())) {
171 if (hit0_a && hit0_b && hit1_a && hit1_b) {
172 double x = 0.5 * (detProp.
ConvertTicksToX(hit0_a->PeakTime(), hit0_a->View2D(), tpc, cryo) +
176 hit0_a->Wire(), hit0_b->
Wire(), hit0_a->View2D(), hit0_b->
View2D(), cryo, tpc,
y,
z);
177 v3d_1.SetXYZ(x, y, z);
183 v3d_2.SetXYZ(x, y, z);
186 AddNode(detProp, v3d_1, tpc, cryo);
187 AddNode(detProp, v3d_2, tpc, cryo);
191 Optimize(detProp, 0, 0.01F,
false,
true, 100);
217 TVector3
mean(0., 0., 0.),
stdev(0., 0., 0.),
p(0., 0., 0.);
221 p.SetXYZ(p.X() * p.X(), p.Y() * p.Y(), p.Z() * p.Z());
227 p.SetXYZ(p.X() * p.X(), p.Y() * p.Y(), p.Z() * p.Z());
243 stdev.SetXYZ(sx, sy, sz);
245 double scale = 2.0 *
stdev.Mag();
246 double iscale = 1.0 / scale;
248 size_t max_index = 0;
249 double norm2, max_norm2 = 0.0;
250 std::vector<TVector3>
data;
256 if (norm2 > max_norm2) {
263 double y = 0.0, kappa = 1.0, prev_kappa, kchg = 1.0;
264 TVector3
w(data[max_index]);
266 while (kchg > 0.0001)
267 for (
size_t i = 0; i < data.size(); i++) {
269 w += (y / kappa) * (data[i] - y * w);
273 kchg = fabs((kappa - prev_kappa) / prev_kappa);
277 TVector3 v1(w), v2(w);
292 Optimize(detProp, 0, 0.01F,
false,
true, 100);
303 const auto& tpcGeo = geom->
TPC(tpc, cryo);
305 double minX = tpcGeo.
MinX(), maxX = tpcGeo.MaxX();
306 double minY = tpcGeo.MinY(), maxY = tpcGeo.MaxY();
307 double minZ = tpcGeo.MinZ(), maxZ = tpcGeo.MaxZ();
309 TVector3 v3d_1(0.5 * (minX + maxX), 0.5 * (minY + maxY), 0.5 * (minZ + maxZ));
310 TVector3 v3d_2(v3d_1);
312 TVector3 shift(5.0, 5.0, 5.0);
317 AddNode(detProp, v3d_1, tpc, cryo);
318 AddNode(detProp, v3d_2, tpc, cryo);
329 for (
size_t i = 0; i <
fNodes.size(); ++i)
330 if (
fNodes[i] == n)
return (
int)i;
337 for (
size_t i = 0; i <
size(); i++)
338 if (
fHits[i] == hit)
return (
int)i;
354 for (
auto const& trk_hit :
fHits) {
355 if (trk_hit->fHit == hit)
return false;
366 for (
size_t i = 0; i <
size(); i++) {
367 if (hit ==
fHits[i]->fHit) {
383 if (
s->HasHit(h))
return s->GetDirection3D();
386 if (
n->HasHit(h))
return n->GetDirection3D();
392 <<
"GetDirection3D(): had to update hit assignment to segment/node.";
394 return pe->GetDirection3D();
397 throw cet::exception(
"pma::Track3D") <<
"GetDirection3D(): direction of a not assigned hit " 407 for (
auto const&
hit : hits)
415 for (
auto const&
hit : hits) {
426 if (
hit->View2D() == view) n++;
444 unsigned int nviews = 0;
451 std::vector<unsigned int>
454 std::vector<unsigned int> tpc_idxs;
456 unsigned int tpc =
hit->TPC();
459 for (
unsigned int const tpc_idx : tpc_idxs)
460 if (tpc_idx == tpc) {
465 if (!found) tpc_idxs.push_back(tpc);
470 std::vector<unsigned int>
473 std::vector<unsigned int> cryo_idxs;
475 unsigned int cryo =
hit->Cryo();
478 for (
size_t j = 0; j < cryo_idxs.size(); j++)
479 if (cryo_idxs[j] == cryo) {
484 if (!found) cryo_idxs.push_back(cryo);
489 std::pair<TVector2, TVector2>
493 unsigned int cryo)
const 495 std::pair<TVector2, TVector2> range(TVector2(0., 0.), TVector2(0., 0.));
507 if (n1 ==
fNodes.size()) n1--;
509 TVector2 p0 =
fNodes[n0]->Projection2D(view);
512 TVector2 p1 =
fNodes[n1]->Projection2D(view);
515 if (p0.X() > p1.X()) {
517 p0.Set(p1.X(), p0.Y());
520 if (p0.Y() > p1.Y()) {
522 p0.Set(p0.X(), p1.Y());
534 std::vector<pma::Track3D*>& allTracks)
536 if (
fNodes.size() < 2) {
return true; }
538 std::vector<pma::Track3D*> toSort;
551 allTracks.push_back(u);
552 if (u->
Flip(detProp, allTracks)) {
554 toSort.push_back(
this);
558 <<
"Flip(): Could not flip after split (but new track is preserved!!).";
572 if (t->
Flip(detProp, allTracks))
575 toSort.push_back(
this);
585 toSort.push_back(
this);
588 for (
size_t t = 0;
t < toSort.size();
t++) {
590 for (
size_t u = 0; u <
t; u++)
591 if (toSort[u] == toSort[t]) {
596 toSort[
t]->MakeProjection();
597 toSort[
t]->SortHits();
606 for (
size_t i = 0; i <
fNodes.size() - 1; i++)
607 if (
fNodes[i]->NextCount() > 1) {
608 for (
size_t j = 0; j <
fNodes[i]->NextCount(); j++) {
614 if (
fNodes.back()->NextCount())
615 for (
size_t j = 0; j <
fNodes.back()->NextCount(); j++) {
617 toSort.push_back(s->
Parent());
620 if (
fNodes.front()->Prev()) {
622 toSort.push_back(s->
Parent());
627 toSort.push_back(
this);
634 std::vector<pma::Track3D*> toSort;
636 toSort.push_back(
this);
638 for (
size_t t = 0;
t < toSort.size();
t++) {
640 for (
size_t u = 0; u <
t; u++)
641 if (toSort[u] == toSort[t]) {
646 toSort[
t]->MakeProjection();
647 toSort[
t]->SortHits();
655 if (!
fNodes.size()) {
return false; }
674 unsigned int nViews = 3;
676 for (
unsigned int i = 0; i < nViews; i++) {
679 unsigned int bestView = 2;
680 if (dedxInViews[0].
size() > 2 * dedxInViews[2].
size()) bestView = 0;
681 if (dedxInViews[1].
size() > 2 * dedxInViews[2].
size()) bestView = 1;
683 std::vector<std::vector<double>> dedx;
684 for (
size_t i = 0; i <
size(); i++) {
685 auto it = dedxInViews[bestView].find(i);
686 if (it != dedxInViews[bestView].
end()) { dedx.push_back(it->second); }
688 if (!dedx.empty()) dedx.pop_back();
690 float dEdxStart = 0.0F, dEdxStop = 0.0F;
691 float dEStart = 0.0F, dxStart = 0.0F;
692 float dEStop = 0.0F, dxStop = 0.0F;
693 if (dedx.size() > 4) {
696 if (dedx.size() > 30)
698 else if (dedx.size() > 20)
700 else if (dedx.size() > 10)
706 size_t k = (dedx.size() - 2) >> 1;
709 for (
size_t i = 1, j = 0; j <
n; i++, j++) {
710 dEStart += dedx[i][5];
711 dxStart += dedx[i][6];
713 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
715 for (
size_t i = dedx.size() - 2, j = 0; j <
n; i--, j++) {
716 dEStop += dedx[i][5];
717 dxStop += dedx[i][6];
719 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
721 else if (dedx.size() == 4) {
722 dEStart = dedx[0][5] + dedx[1][5];
723 dxStart = dedx[0][6] + dedx[1][6];
724 dEStop = dedx[2][5] + dedx[3][5];
725 dxStop = dedx[2][6] + dedx[3][6];
726 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
727 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
729 else if (dedx.size() > 1) {
730 if (dedx.front()[2] > 0.0F) dEdxStart = dedx.front()[5] / dedx.front()[6];
731 if (dedx.back()[2] > 0.0F) dEdxStop = dedx.back()[5] / dedx.back()[6];
738 <<
"Auto-flip fired (1), thr: " << (1.0 +
thr) <<
", value: " << dEdxStart / dEdxStop;
743 <<
"Auto-flip fired (2), thr: " << (1.0 +
thr) <<
", value: " << dEdxStop / dEdxStart;
750 std::vector<pma::Track3D*>& allTracks,
755 unsigned int nViews = 3;
757 for (
unsigned int i = 0; i < nViews; i++) {
760 unsigned int bestView = 2;
761 if (dedxInViews[0].
size() > 2 * dedxInViews[2].
size()) bestView = 0;
762 if (dedxInViews[1].
size() > 2 * dedxInViews[2].
size()) bestView = 1;
764 std::vector<std::vector<double>> dedx;
765 for (
size_t i = 0; i <
size(); i++) {
766 auto it = dedxInViews[bestView].find(i);
767 if (it != dedxInViews[bestView].
end()) { dedx.push_back(it->second); }
769 if (!dedx.empty()) dedx.pop_back();
771 float dEdxStart = 0.0F, dEdxStop = 0.0F;
772 float dEStart = 0.0F, dxStart = 0.0F;
773 float dEStop = 0.0F, dxStop = 0.0F;
774 if (dedx.size() > 4) {
777 if (dedx.size() > 30)
779 else if (dedx.size() > 20)
781 else if (dedx.size() > 10)
787 size_t k = (dedx.size() - 2) >> 1;
790 for (
size_t i = 1, j = 0; j <
n; i++, j++) {
791 dEStart += dedx[i][5];
792 dxStart += dedx[i][6];
794 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
796 for (
size_t i = dedx.size() - 2, j = 0; j <
n; i--, j++) {
797 dEStop += dedx[i][5];
798 dxStop += dedx[i][6];
800 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
802 else if (dedx.size() == 4) {
803 dEStart = dedx[0][5] + dedx[1][5];
804 dxStart = dedx[0][6] + dedx[1][6];
805 dEStop = dedx[2][5] + dedx[3][5];
806 dxStop = dedx[2][6] + dedx[3][6];
807 if (dxStart > 0.0F) dEdxStart = dEStart / dxStart;
808 if (dxStop > 0.0F) dEdxStop = dEStop / dxStop;
810 else if (dedx.size() > 1) {
811 if (dedx.front()[2] > 0.0F) dEdxStart = dedx.front()[5] / dedx.front()[6];
812 if (dedx.back()[2] > 0.0F) dEdxStop = dedx.back()[5] / dedx.back()[6];
820 <<
"Auto-flip fired (1), thr: " << (1.0 +
thr) <<
", value: " << dEdxStart / dEdxStop;
821 done =
Flip(detProp, allTracks);
825 <<
"Auto-flip fired (2), thr: " << (1.0 +
thr) <<
", value: " << dEdxStop / dEdxStart;
826 done =
Flip(detProp, allTracks);
834 bool normalized)
const 837 mf::LogWarning(
"pma::Track3D") <<
"TestHitsMse(): Empty cluster.";
842 for (
auto const&
h : hits) {
843 unsigned int cryo =
h->WireID().Cryostat;
844 unsigned int tpc =
h->WireID().TPC;
845 unsigned int view =
h->WireID().Plane;
846 unsigned int wire =
h->WireID().Wire;
847 float drift =
h->PeakTime();
852 return mse / hits.size();
868 double tst, d2 = dist *
dist;
869 unsigned int nhits = 0;
870 for (
auto const&
h : hits)
879 auto const nHits =
size();
880 if (nHits < 2)
return 0.0;
887 if (start >= nHits - 1)
return 0.0;
888 if (stop >= nHits) stop = nHits - 1;
894 size_t i = start +
step;
912 if (index < -1) index = -1;
913 while (++index < (
int)
size())
916 if (hit->
View2D() == view) {
934 if (hit->
View2D() == view) {
948 bool secondDir)
const 953 if (hit->
View2D() != view) {
954 mf::LogWarning(
"pma::Track3D") <<
"Function used with the hit not matching specified view.";
958 bool hitFound =
false;
962 while (!hitFound && (++i < (
int)
size())) {
966 if (nexthit->
View2D() == view)
984 while (!hitFound && (--i >= 0)) {
988 if (nexthit->
View2D() == view)
1005 default:
mf::LogError(
"pma::Track3D") <<
"Direction undefined.";
break;
1013 if (index <
size()) {
1018 mf::LogError(
"pma::Track3D") <<
"Hit index out of range.";
1029 while (k < nCount) {
1031 if (seg && (seg->
Parent() ==
this))
return seg;
1042 if (seg->Parent() ==
this)
return seg;
1051 bool inclDisabled)
const 1055 if (!
size())
return 0.0;
1061 double rv, dr, dR, dq, dEq, qSkipped = 0.0;
1063 size_t j =
NextHit(-1, view, inclDisabled),
s = skip;
1064 if (j >=
size())
return 0.0F;
1076 j =
NextHit(j, view, inclDisabled);
1079 size_t jmax =
PrevHit(
size(), view, inclDisabled);
1081 std::vector<size_t> indexes;
1082 TVector3 p0(0., 0., 0.), p1(0., 0., 0.);
1083 TVector2 c0(0., 0.),
c1(0., 0.);
1087 indexes.push_back(j);
1106 while (((m < step) || (dR < 0.1) || (dr == 0.0)) && (j <= jmax)) {
1108 if (j > jmax)
break;
1111 if (!inclDisabled && !hit->
IsEnabled()) {
1117 indexes.push_back(j);
1138 double range =
Length(0, j);
1140 std::vector<double> trk_section;
1141 trk_section.push_back(c0.X());
1142 trk_section.push_back(c0.Y());
1143 trk_section.push_back(p0.X());
1144 trk_section.push_back(p0.Y());
1145 trk_section.push_back(p0.Z());
1146 trk_section.push_back(dEq);
1147 trk_section.push_back(dR);
1148 trk_section.push_back(range);
1150 for (
auto const idx : indexes)
1151 dedx[idx] = trk_section;
1153 j =
NextHit(j, view, inclDisabled);
1162 unsigned int view)
const 1164 std::vector<float> drifts;
1165 for (
size_t i = 0; i <
fNodes.size() - 1; i++) {
1167 if ((tpc !=
fNodes[i + 1]->
TPC()) || (cryo !=
fNodes[i + 1]->Cryo()))
continue;
1170 fNodes[i]->Projection2D(view).
X(),
1171 fNodes[i]->Projection2D(view).
Y(),
1176 fNodes[i + 1]->Projection2D(view).
X(),
1177 fNodes[i + 1]->Projection2D(view).
Y(),
1182 if ((p0.X() - wire) * (p1.X() - wire) <= 0.0) {
1183 double frac_w = (wire - p0.X()) / (p1.X() - p0.X());
1184 double d = p0.Y() + frac_w * (p1.Y() - p0.Y());
1185 drifts.push_back((
float)d);
1195 int dPrev, dw,
w, wx, wPrev, i =
NextHit(-1, view);
1200 std::vector<pma::Hit3D*> missHits;
1202 while (i < (
int)
size()) {
1206 if (hit->
View2D() == view) {
1209 wPrev = hitPrev->
Wire();
1211 if (
abs(w - wPrev) > 1) {
1220 unsigned int iWire = wx;
1222 if (drifts.size()) {
1223 peakTime = drifts[0];
1224 for (
size_t d = 1;
d < drifts.size();
d++)
1225 if (fabs(drifts[
d] - dPrev) < fabs(peakTime - dPrev)) peakTime = drifts[
d];
1228 mf::LogVerbatim(
"pma::Track3D") <<
"Track does not intersect with the wire " << wx;
1232 new pma::Hit3D(detProp, iWire, view, hit->
TPC(), hit->
Cryo(), peakTime, 1.0, 1.0);
1233 missHits.push_back(hmiss);
1244 while ((i < (
int)
size()) && (hit->
TPC() !=
fHits[i]->TPC())) {
1251 if (missHits.size()) {
1252 for (
size_t hi = 0; hi < missHits.size(); hi++) {
1260 return missHits.size();
1285 if (!maxSeg)
return false;
1287 unsigned int nHitsByView[3];
1288 unsigned int nHits, maxHits = 0;
1289 unsigned int vIndex = 0, segHits, maxSegHits = 0;
1290 float segLength, maxLength = maxSeg->
Length();
1291 for (
unsigned int i = si + 1; i <
fNodes.size(); i++) {
1298 segHits = nHitsByView[0] + nHitsByView[1] + nHitsByView[2];
1301 if ((nHitsByView[0] == 0) && ((nHitsByView[1] < 4) || (nHitsByView[2] < 4)))
continue;
1302 if ((nHitsByView[1] == 0) && ((nHitsByView[0] < 4) || (nHitsByView[2] < 4)))
continue;
1303 if ((nHitsByView[2] == 0) && ((nHitsByView[0] < 4) || (nHitsByView[1] < 4)))
continue;
1308 if (nHits > maxHits) {
1310 maxLength = seg->
Length();
1311 maxSegHits = segHits;
1315 else if (nHits == maxHits) {
1316 segLength = seg->
Length();
1317 if (segLength > maxLength) {
1318 maxLength = segLength;
1319 maxSegHits = segHits;
1326 if (maxSegHits > 1) {
1333 unsigned int maxViewIdx = 2, midViewIdx = 2;
1334 if ((nHitsByView[2] >= nHitsByView[1]) && (nHitsByView[1] >= nHitsByView[0])) {
1338 else if ((nHitsByView[1] >= nHitsByView[2]) && (nHitsByView[2] >= nHitsByView[0])) {
1342 else if ((nHitsByView[0] >= nHitsByView[2]) && (nHitsByView[2] >= nHitsByView[1])) {
1346 else if ((nHitsByView[2] >= nHitsByView[0]) && (nHitsByView[0] >= nHitsByView[1])) {
1350 else if ((nHitsByView[0] >= nHitsByView[1]) && (nHitsByView[1] >= nHitsByView[2])) {
1354 else if ((nHitsByView[1] >= nHitsByView[0]) && (nHitsByView[0] >= nHitsByView[2])) {
1358 if (nHitsByView[midViewIdx] < 2) midViewIdx = maxViewIdx;
1360 if (nHitsByView[midViewIdx] < 2) {
1365 unsigned int mHits[3] = {0, 0, 0};
1366 unsigned int halfIndex = (nHitsByView[midViewIdx] >> 1) - 1;
1367 unsigned int n = 0, i = 0, i0 = 0, i1 = 0;
1368 while (i < maxSeg->
NHits() - 1) {
1371 if (maxSeg->
Hit(i).
View2D() == midViewIdx) {
1372 if (n == halfIndex)
break;
1381 while ((i < maxSeg->
NHits()) &&
1387 if (!nHitsByView[0]) {
1388 if (nHitsByView[1] && (mHits[1] < 2)) {
1392 if (nHitsByView[2] && (mHits[2] < 2)) {
1401 unsigned int tpc = maxSeg->
Hit(i0).
TPC();
1402 unsigned int cryo = maxSeg->
Hit(i0).
Cryo();
1409 fNodes[vIndex]->GetDriftShift());
1426 TVector3
const& p3d,
1432 new pma::Node3D(detProp, p3d, tpc, cryo,
false,
fNodes[at_idx]->GetDriftShift());
1457 bool try_start_at_idx)
1459 if (!idx || (idx + 1 >=
fNodes.size()))
return 0;
1467 for (
size_t i = 0; i < idx; ++i) {
1475 while (k < n->NextCount()) {
1494 while (h <
size()) {
1496 unsigned int view = h3d->
View2D(), tpc = h3d->
TPC(), cryo = h3d->
Cryo();
1497 double dist2D_old =
Dist2(h3d->
Point2D(), view, tpc, cryo);
1498 double dist2D_new = t0->
Dist2(h3d->
Point2D(), view, tpc, cryo);
1500 if ((dist2D_new < dist2D_old) && t0->
HasTPC(tpc))
1510 if (try_start_at_idx && t0->
CanFlip()) {
1511 mf::LogVerbatim(
"pma::Track3D") <<
" attach new t0 and this trk to a common start node";
1516 mf::LogVerbatim(
"pma::Track3D") <<
" attach this trk to the new t0 end node";
1530 for (
size_t i = 0; i < idx; ++i) {
1548 if (vtx == vStart)
return true;
1551 if (vStart->
Prev()) {
1553 if (rootPrev->
IsAttachedTo(rootThis)) {
return false; }
1557 if (rootNext->
IsAttachedTo(rootThis)) {
return false; }
1569 if (!noFlip &&
CanFlip() && (vStart->
TPC() == fNodes.back()->TPC()) &&
1572 (fNodes.back()->NextCount() == 0)) {
1573 mf::LogError(
"pma::Track3D") <<
"Flip, endpoint closer to vStart.";
1577 if (vStart->
TPC() == vtx->
TPC())
1586 if (
fNodes.front()->Prev())
return false;
1610 if (vStart->
Prev()) {
1623 mf::LogError(
"pma::Track3D") <<
"Flips in vtx and vStart not possible, cannot attach.";
1647 throw cet::exception(
"pma::Track3D") <<
"Something is still using disconnected vertex.";
1659 if (vtx == vStart)
return true;
1662 if (vStart->
Prev()) {
1664 if (rootPrev->
IsAttachedTo(rootThis)) {
return false; }
1668 if (rootNext->
IsAttachedTo(rootThis)) {
return false; }
1680 if (vStart->
TPC() == vtx->
TPC())
1689 if (vStart->
Prev())
return false;
1693 fNodes.push_back(vStart);
1695 size_t idx =
fNodes.size() - 1;
1706 if (vStart->
Prev()) {
1710 mf::LogError(
"pma::Track3D") <<
"Cannot attach back to inner node of other track.";
1717 mf::LogError(
"pma::Track3D") <<
"Flip not possible, cannot attach.";
1736 <<
"Something is still using disconnected vertex." <<
std::endl;
1747 if (src->
fNodes.front()->Prev()) {
1749 <<
"Cant extend with a track being a daughter of another track." <<
std::endl;
1753 for (
size_t i = 0; i < src->
fNodes.size(); ++i) {
1756 size_t idx =
fNodes.size() - 1;
1761 while (src->
size()) {
1784 if (!trk) trk =
this;
1787 throw cet::exception(
"pma::Track3D") <<
"Broken track, no nodes.";
1795 for (
auto trk : branches)
1796 if (
trk ==
this) {
throw cet::exception(
"pma::Track3D") <<
"Track tree has loop."; }
1798 branches.push_back(
this);
1801 if (skipFirst) i0 = 1;
1803 for (
size_t i = i0; i <
fNodes.size(); ++i)
1804 for (
size_t n = 0;
n <
fNodes[i]->NextCount();
n++) {
1815 if (trk ==
this)
return true;
1817 std::vector<pma::Track3D const*> branchesThis, branchesTrk;
1822 for (
auto bThis : branchesThis)
1823 for (
auto bTrk : branchesTrk)
1824 if (bThis == bTrk)
return true;
1832 if (point == p)
return true;
1839 double sumMse = 0.0;
1840 unsigned int nEnabledHits = 0;
1842 sumMse +=
n->SumDist2(view);
1843 nEnabledHits +=
n->NEnabledHits(view);
1846 sumMse +=
s->SumDist2(view);
1847 nEnabledHits +=
s->NEnabledHits(view);
1851 return sumMse / nEnabledHits;
1861 for (
size_t i = 0; i <
fNodes.size(); i++) {
1864 return sum /
fNodes.size();
1877 mf::LogError(
"pma::Track3D") <<
"Track not initialized.";
1886 if (g0 == 0.0)
return g0;
1891 n->SetVertexToBranching(setAllNodes);
1897 if (selSegHits || selVtxHits)
SelectRndHits(selSegHits, selVtxHits);
1899 bool stepDone =
true;
1900 unsigned int stepIter = 0;
1903 unsigned int iter = 0;
1904 while ((gstep > eps) && (iter < 1000)) {
1905 if ((fNodes.size() < 4) || (iter % 10 == 0))
1915 for (
auto n : fNodes)
1925 gstep = fabs(g0 - g1) / g0;
1930 if (fNodes.size() > 2) {
1933 }
while (!stepDone && (stepIter < 5));
1943 case 0: stop =
true;
break;
1949 if (!
AddNode(detProp)) stop =
true;
1968 if (
AddNode(detProp)) nNodes--;
1971 else if (nNodes > 4) {
1982 if (
AddNode(detProp)) nNodes--;
1985 if (
AddNode(detProp)) { nNodes--; }
2004 constexpr
size_t maxTreeDepth = 100;
2011 if (++depth > maxTreeDepth) {
mf::LogError(
"pma::Track3D") <<
"Tree depth above allowed max."; }
2019 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2054 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2078 dist = sqrt(
Dist2(p3d_cm));
2085 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2087 if (seg != segThis) {
2127 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2129 if (seg != segThis) {
2168 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2188 if ((nearestTrk !=
this) && (dmin < 0.5 * d0)) {
2190 mf::LogVerbatim(
"pma::Track3D") <<
"*** hit moved to another track ***";
2195 if (!
size()) {
mf::LogError(
"pma::Track3D") <<
"ALL hits moved to other tracks."; }
2210 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2236 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2263 for (
size_t i = 0; i < vtx->
NextCount(); i++) {
2281 mf::LogError(
"pma::Track3D") <<
"TuneFullTree failed.";
2287 mf::LogError(
"pma::Track3D") <<
"Infinifte value of g.";
2294 if (g0 == 0.0)
return g0;
2297 unsigned int stepIter = 0;
2300 unsigned int iter = 0;
2301 while ((gstep > eps) && (iter < 60)) {
2312 if (g0 == 0.0F)
break;
2314 gstep = fabs(g0 - g1) / g0;
2320 }
while (stepIter < 5);
2325 if (g0 >= 0) {
mf::LogVerbatim(
"pma::Track3D") <<
" done, g = " << g0; }
2327 mf::LogError(
"pma::Track3D") <<
"TuneFullTree failed.";
2348 for (
size_t i = 0; i < node->
NextCount(); i++) {
2354 node =
static_cast<pma::Node3D*
>(segThis->Next());
2360 h->fPoint3D[0] += dx;
2369 double newdx =
fNodes.front()->GetDriftShift();
2380 auto const* geom = lar::providerFrom<geo::Geometry>();
2385 double correctedSign = 0;
2386 if (tpcGeo.DetectDriftDirection() > 0) {
2387 if (dx > 0) { correctedSign = 1.0; }
2389 correctedSign = -1.0;
2393 if (dx > 0) { correctedSign = -1.0; }
2395 correctedSign = 1.0;
2402 dxInTicks = dxInTicks * correctedSign;
2408 mf::LogDebug(
"pma::Track3D") << dx <<
", " << dxInTicks <<
", " << correctedSign <<
", " <<
fT0 2409 <<
", " << tpcGeo.DetectDriftDirection()
2420 for (
size_t i = 0; i <
fSegments.size(); i++)
2431 for (
size_t i = 1; i <
fNodes.size(); i++) {
2439 unsigned int nhits = 0;
2440 while (!nhits && (
fNodes.size() > 2) && !
fNodes.front()->IsBranching()) {
2442 nhits = vtx->
NHits();
2445 nhits += seg->
NHits();
2459 while (!nhits && (
fNodes.size() > 2) && !
fNodes.back()->IsBranching()) {
2461 nhits = vtx->
NHits();
2464 nhits += seg->
NHits();
2484 if (!(
fNodes.front()->Prev())) {
2488 if (vtx ==
fNodes.front())
2491 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner node.";
2499 double l0 = seg->
Length();
2501 if ((seg->
Length() < 0.2 * l0) && (
fNodes.size() > 2)) {
2505 <<
"ShiftEndsToHits(): Short start segment, node removed.";
2514 mf::LogWarning(
"pma::Track3D") <<
"Branching node, not removed.";
2520 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner segment.";
2527 if (!(
fNodes.back()->NextCount())) {
2531 if (vtx ==
fNodes.back())
2534 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner node.";
2542 double l0 = seg->
Length();
2544 if ((seg->
Length() < 0.2 * l0) && (
fNodes.size() > 2)) {
2545 size_t idx =
fNodes.size() - 2;
2549 <<
"ShiftEndsToHits(): Short end segment, node removed.";
2558 mf::LogWarning(
"pma::Track3D") <<
"Branching node, not removed.";
2564 mf::LogWarning(
"pma::Track3D") <<
"First hit is projected to inner segment.";
2578 unsigned int cryo)
const 2580 double dist, min_dist = 1.0e12;
2582 int t = (
int)tpc,
c = (
int)cryo;
2583 auto n0 =
fNodes.front();
2584 if ((n0->TPC() ==
t) && (n0->Cryo() ==
c)) {
2585 dist = n0->GetDistance2To(p2d, view);
2586 if (dist < min_dist) min_dist =
dist;
2589 if ((n1->TPC() ==
t) && (n1->Cryo() ==
c)) {
2590 dist = n1->GetDistance2To(p2d, view);
2591 if (dist < min_dist) min_dist =
dist;
2595 if ((
s->TPC() ==
t) && (
s->Cryo() ==
c)) {
2596 dist =
s->GetDistance2To(p2d, view);
2597 if (dist < min_dist) min_dist =
dist;
2606 auto to_distance2 = [&p3d](
auto seg) {
return seg->GetDistance2To(p3d); };
2607 return min(
fSegments | views::transform(to_distance2));
2615 bool skipBackVtx)
const 2617 if (
fSegments.front()->TPC() < 0) skipFrontVtx =
false;
2618 if (
fSegments.back()->TPC() < 0) skipBackVtx =
false;
2620 if (skipFrontVtx && skipBackVtx && (
fSegments.size() == 1))
2623 size_t v0 = 0, v1 =
fNodes.size();
2624 if (skipFrontVtx) v0 = 1;
2625 if (skipBackVtx) --v1;
2629 for (
size_t i = v0; i < v1; i++)
2631 double dist =
fNodes[i]->GetDistance2To(p2d, view);
2632 if (dist < min_dist) {
2638 if (segment->TPC() == tpc) {
2639 if (segment->TPC() < 0)
continue;
2641 double const dist = segment->GetDistance2To(p2d, view);
2642 if (dist < min_dist) {
2656 for (
size_t i = 1; i <
fNodes.size(); i++) {
2657 dist =
fNodes[i]->GetDistance2To(p3d);
2658 if (dist < min_dist) {
2663 for (
size_t i = 0; i <
fSegments.size(); i++) {
2664 dist =
fSegments[i]->GetDistance2To(p3d);
2665 if (dist < min_dist) {
2677 double& dist2)
const 2687 double d2, min_d2 = 1.0e100;
2690 for (
size_t i = 0; i <
fSegments.size(); i++) {
2693 d2 =
fSegments[i]->GetDistance2To(p2d, view);
2700 p3d = seg->GetUnconstrainedProj3D(p2d, view);
2713 std::vector<pma::Hit3D*> hits_tmp;
2714 hits_tmp.reserve(
size());
2720 for (
size_t i = 0; i < vtx->
NHits(); i++) {
2722 if (h3d->
fParent ==
this) hits_tmp.push_back(h3d);
2727 for (
size_t i = 0; i < seg->
NHits(); i++) {
2729 if (h3d->
fParent ==
this) hits_tmp.push_back(h3d);
2739 if (
size() == hits_tmp.size()) {
2740 for (
size_t i = 0; i <
size(); i++) {
2741 fHits[i] = hits_tmp[i];
2745 mf::LogError(
"pma::Track3D") <<
"Hit sorting problem.";
2753 unsigned int nDisabled = 0;
2755 std::array<int, 4> hasHits{{}};
2760 bool rebuild =
false, stop =
false;
2770 for (
size_t i = 0; i < vtx->
NHits(); i++) {
2772 if ((hitIndex >= 0) && (hitIndex + 1 < (
int)
size()))
2773 nextHit =
fHits[hitIndex + 1];
2779 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2787 for (
size_t i = 0; i < seg->
NHits(); i++) {
2789 if ((hitIndex >= 0) && (hitIndex + 1 < (
int)
size()))
2790 nextHit =
fHits[hitIndex + 1];
2796 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2805 if (
fNodes.size() < 3)
break;
2807 nViews = hasHits[1] + hasHits[2] + hasHits[3];
2808 if (hasHits[0] || (nViews > 1))
2810 else if (!
fNodes.front()->IsBranching()) {
2830 for (
int i = vtx->
NHits() - 1; i >= 0; i--) {
2832 if ((hitIndex >= 0) && (hitIndex - 1 >= 0))
2833 nextHit =
fHits[hitIndex - 1];
2839 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2847 for (
int i = seg->
NHits() - 1; i >= 0; i--) {
2849 if ((hitIndex >= 0) && (hitIndex - 1 >= 0))
2850 nextHit =
fHits[hitIndex - 1];
2856 nViews = hasHits[0] + hasHits[1] + hasHits[2] + hasHits[3];
2865 if (
fNodes.size() < 3)
break;
2867 nViews = hasHits[1] + hasHits[2] + hasHits[3];
2868 if (hasHits[0] || (nViews > 1))
2870 else if (!
fNodes.back()->IsBranching()) {
2890 if (fraction < 0.0F) fraction = 0.0F;
2891 if (fraction > 1.0F) fraction = 1.0F;
2894 size_t nHitsColl = (size_t)(fraction *
NHits(
geo::kZ));
2895 size_t nHitsInd2 = (size_t)(fraction *
NHits(
geo::kV));
2896 size_t nHitsInd1 = (size_t)(fraction *
NHits(
geo::kU));
2897 size_t coll = 0, ind2 = 0, ind1 = 0;
2899 bool b, changed =
false;
2902 if (fraction < 1.0F) {
2903 h->SetEnabled(
false);
2904 switch (
h->View2D()) {
2906 if (coll++ < nHitsColl)
h->SetEnabled(
true);
2909 if (ind2++ < nHitsInd2)
h->SetEnabled(
true);
2912 if (ind1++ < nHitsInd1)
h->SetEnabled(
true);
2917 h->SetEnabled(
true);
2919 changed |= (b !=
h->IsEnabled());
2922 if (fraction < 1.0F) {
2932 bool changed =
false;
2934 changed |=
n->SelectRndHits(vtxmax);
2936 changed |=
s->SelectRndHits(segmax);
2943 bool changed =
false;
2945 changed |= !(
h->IsEnabled());
2946 h->SetEnabled(
true);
2955 n->ClearAssigned(
this);
2957 s->ClearAssigned(
this);
2961 bool skipFrontVtx =
false, skipBackVtx =
false;
2964 if (!(fNodes.front()->IsFrozen()) && !(fNodes.front()->Prev()) &&
2965 (fNodes.front()->NextCount() == 1)) {
2966 skipFrontVtx =
true;
2968 if (!(fNodes.front()->IsFrozen()) && (fNodes.back()->NextCount() == 0)) { skipBackVtx =
true; }
2982 for (
auto n : fNodes)
2983 n->UpdateHitParams();
2984 for (
auto s : fSegments)
2985 s->UpdateHitParams();
2991 std::vector<std::pair<pma::Hit3D*, pma::Element3D*>> assignments;
2992 assignments.reserve(
fHits.size());
2994 for (
auto hi :
fHits) {
2998 for (
size_t j = 0; j <
s->NHits(); ++j)
2999 if (hi ==
s->Hits()[j])
3002 double min_d2 =
s->GetDistance2To(hi->Point2D(), hi->View2D());
3003 int const tpc = hi->TPC();
3006 if (nnext->
TPC() == tpc) {
3007 double const d2 = nnext->
GetDistance2To(hi->Point2D(), hi->View2D());
3014 if (snext && (snext->
TPC() == tpc)) {
3015 double const d2 = snext->
GetDistance2To(hi->Point2D(), hi->View2D());
3022 if (nnext->
TPC() == tpc) {
3023 double const d2 = nnext->
GetDistance2To(hi->Point2D(), hi->View2D());
3033 if (nprev->
TPC() == tpc) {
3034 double const d2 = nprev->
GetDistance2To(hi->Point2D(), hi->View2D());
3041 if (sprev && (sprev->
TPC() == tpc)) {
3042 double const d2 = sprev->
GetDistance2To(hi->Point2D(), hi->View2D());
3049 if (nprev->
TPC() == tpc) {
3050 double const d2 = nprev->
GetDistance2To(hi->Point2D(), hi->View2D());
3067 for (
size_t j = 0; j <
n->NHits(); ++j)
3068 if (hi ==
n->Hits()[j])
3071 double d2, min_d2 =
n->GetDistance2To(hi->Point2D(), hi->View2D());
3072 int tpc = hi->TPC();
3075 if (snext && (snext->
TPC() == tpc)) {
3083 if (nnext->
TPC() == tpc) {
3091 if (snext && (snext->
TPC() == tpc)) {
3102 if (sprev && (sprev->
TPC() == tpc)) {
3110 if (nprev->
TPC() == tpc) {
3118 if (sprev && (sprev->
TPC() == tpc)) {
3135 assignments.emplace_back(hi, pe);
3137 mf::LogWarning(
"pma::Track3D") <<
"Hit was not assigned to any element.";
3140 for (
auto const&
a : assignments)
3141 a.second->AddHit(
a.first);
3144 n->UpdateHitParams();
3146 s->UpdateHitParams();
3153 n->UpdateProjection();
3155 s->UpdateProjection();
3162 unsigned int count = 0;
3165 sum +=
n->SumDist2();
3166 count +=
n->NEnabledHits();
3170 sum +=
s->SumDist2();
3171 count +=
s->NEnabledHits();
3174 if (count) {
return sum /
count; }
3176 mf::LogError(
"pma::Track3D") <<
"0 enabled hits in AverageDist2 calculation.";
3191 float nCubeRoot =
pow((
double)n, 1.0 / 3.0);
3193 if (avgDist2Root > 0) {
3211 if (v0 == v1)
return false;
3225 fNodes[v1]->RemoveNext(nextSeg);
3233 fNodes[v0]->AddNext(midSeg);
3235 if (nextSeg)
fNodes[v1]->AddNext(nextSeg);
3250 unsigned int v1, v2;
3253 if (
fSegments.front()->IsFrozen())
return false;
3254 if (
fNodes.front()->NextCount() > 1)
return false;
3259 if (
fSegments.back()->IsFrozen())
return false;
3260 if (
fNodes.back()->NextCount() > 1)
return false;
3264 default:
return false;
3286 std::vector<pma::Hit3D*> hitsColl, hitsInd1, hitsInd2;
3288 switch (
hit->View2D()) {
3289 case geo::kZ: hitsColl.push_back(
hit);
break;
3290 case geo::kV: hitsInd2.push_back(
hit);
break;
3291 case geo::kU: hitsInd1.push_back(
hit);
break;
bool SelectHits(float fraction=1.0F)
void ApplyDriftShift(double dx)
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
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)
double GetMse(unsigned int view=geo::kUnknown) const
MSE of hits weighted with hit amplidudes and wire plane coefficients.
void SortHitsInTree(bool skipFirst=false)
bool AttachTo(pma::Node3D *vStart, bool noFlip=false)
double GetHitsRadius2D(const std::vector< pma::Hit3D * > &hits, bool exact=false)
static constexpr double g
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)
geo::WireID WireID() const
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.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
unsigned int Cryo() const noexcept
double MinX() const
Returns the world x coordinate of the start of the box.
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)
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)
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.
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)
art framework interface to geometry description
constexpr double TickPeriod() const noexcept
A single tick period in microseconds.
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
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)
static int max(int a, int b)
PlaneID_t Plane
Index of the plane within its TPC.
unsigned int DisableSingleViewEnds()
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
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.
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
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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)
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
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)
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
pma::Track3D * GetNearestTrkInTree(const TVector3 &p3d_cm, double &dist, bool skipFirst=false)
virtual bool AddNext(pma::SortedObjectBase *nextElement)
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
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
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
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
QTextStream & endl(QTextStream &s)
std::vector< pma::Hit3D * > fHits