23 std::vector<Point_t> positions; positions.reserve(src.
size());
24 std::vector<Vector_t> momenta; momenta.reserve(src.
size());
25 std::vector<recob::TrajectoryPointFlags> outFlags; outFlags.reserve(src.
size());
27 for (
size_t i = 0, h = 0; i < src.
size(); i++)
28 if (src[i]->IsEnabled())
30 auto const & point3d = src[i]->Point3D();
31 positions.emplace_back(point3d.X(), point3d.Y(), point3d.Z());
42 pdg, totChi2, ndof, covStart, covEnd, tidx);
49 fProjectionMatchingAlg(pmalgConfig),
50 fPMAlgVertexing(pmvtxConfig)
52 unsigned int cryo, tpc, view;
53 for (
auto const& h : allhitlist)
55 cryo = h->WireID().Cryostat;
56 tpc = h->WireID().TPC;
57 view = h->WireID().Plane;
59 fHitMap[cryo][tpc][view].push_back(h);
72 for (
auto const & t : tracks.
tracks())
74 auto &
trk = *(t.Track());
76 unsigned int tpc =
trk.FrontTPC(), cryo =
trk.FrontCryo();
77 if ((tpc ==
trk.BackTPC()) && (cryo ==
trk.BackCryo()))
95 const std::vector< recob::Cluster > & clusters,
96 const std::vector< recob::PFParticle > & pfparticles,
104 fTrackingOnlyPdg(pmalgFitterConfig.TrackingOnlyPdg()),
105 fTrackingSkipPdg(pmalgFitterConfig.TrackingSkipPdg()),
106 fRunVertexing(pmalgFitterConfig.RunVertexing())
108 mf::LogVerbatim(
"PMAlgFitter") <<
"Found " << allhitlist.size() <<
"hits in the event.";
109 mf::LogVerbatim(
"PMAlgFitter") <<
"Sort hits by clusters assigned to PFParticles...";
112 for (
size_t i = 0; i < pfparticles.size(); ++i)
116 auto cv = clusFromPfps.at(i);
117 for (
const auto & c : cv)
122 auto hv = hitsFromClusters.at(c.key());
123 fCluHits[c.key()].reserve(hv.size());
124 for (
auto const & h : hv)
fCluHits[c.key()].push_back(h);
128 if (vtxFromPfps.isValid() && vtxFromPfps.at(i).size())
131 vtxFromPfps.at(i).front()->XYZ(xyz);
137 <<
fCluHits.size() <<
" clusters from " 138 <<
fPfpClusters.size() <<
" pfparticles for 3D tracking.";
175 bool selectPdg =
true;
180 int pfPartIdx = pfpCluEntry.first;
187 mf::LogVerbatim(
"PMAlgFitter") <<
"Process clusters from PFP:" << pfPartIdx <<
", pdg:" << pdg;
189 std::vector< art::Ptr<recob::Hit> > allHits;
192 std::unordered_map<geo::View_t, size_t> clu_count;
193 for (
const auto & c : pfpCluEntry.second)
195 if (c->NHits() == 0) {
continue; }
197 candidate.
Clusters().push_back(c.key());
198 clu_count[c->View()]++;
200 allHits.reserve(allHits.size() +
fCluHits.at(c.key()).size());
201 for (
const auto & h :
fCluHits.at(c.key()))
203 allHits.push_back(h);
206 if (clu_count.size() > 1)
208 candidate.
SetKey(pfpCluEntry.first);
219 mf::LogError(
"PMAlgFitter") <<
"Trajectory fit lenght is nan.";
235 bool selectPdg =
true;
241 int pfPartIdx = pfpCluEntry.first;
244 if (pdg != 11)
continue;
248 mf::LogVerbatim(
"PMAlgFitter") <<
"Process clusters from PFP:" << pfPartIdx <<
", pdg:" << pdg;
250 std::vector< art::Ptr<recob::Hit> > allHits;
253 std::unordered_map<geo::View_t, size_t> clu_count;
254 for (
const auto & c : pfpCluEntry.second)
256 if (c->NHits() == 0) {
continue; }
258 candidate.
Clusters().push_back(c.key());
259 clu_count[c->View()]++;
261 allHits.reserve(allHits.size() +
fCluHits.at(c.key()).size());
262 for (
const auto & h :
fCluHits.at(c.key()))
263 allHits.push_back(h);
265 if (clu_count.size() > 1)
267 candidate.
SetKey(pfpCluEntry.first);
271 auto search =
fPfpVtx.find(pfPartIdx);
299 const std::vector< TH1F* > & hpassing,
const std::vector< TH1F* > & hrejected) :
305 fMinSeedSize1stPass(pmalgTrackerConfig.MinSeedSize1stPass()),
306 fMinSeedSize2ndPass(pmalgTrackerConfig.MinSeedSize2ndPass()),
307 fTrackLikeThreshold(pmalgTrackerConfig.TrackLikeThreshold()),
309 fMinTwoViewFraction(pmalgConfig.MinTwoViewFraction()),
311 fFlipToBeam(pmalgTrackerConfig.FlipToBeam()),
312 fFlipDownward(pmalgTrackerConfig.FlipDownward()),
313 fFlipToX(pmalgTrackerConfig.FlipToX()),
314 fAutoFlip_dQdx(pmalgTrackerConfig.AutoFlip_dQdx()),
316 fMergeWithinTPC(pmalgTrackerConfig.MergeWithinTPC()),
317 fMergeTransverseShift(pmalgTrackerConfig.MergeTransverseShift()),
318 fMergeAngle(pmalgTrackerConfig.MergeAngle()),
320 fCosmicTagger(pmtaggerConfig),
321 fTagCosmicTracks(fCosmicTagger.tagAny()),
323 fStitchBetweenTPCs(pmalgTrackerConfig.StitchBetweenTPCs()),
324 fStitchDistToWall(pmalgTrackerConfig.StitchDistToWall()),
325 fStitchTransverseShift(pmalgTrackerConfig.StitchTransverseShift()),
326 fStitchAngle(pmalgTrackerConfig.StitchAngle()),
328 fMatchT0inAPACrossing(pmalgTrackerConfig.MatchT0inAPACrossing()),
329 fMatchT0inCPACrossing(pmalgTrackerConfig.MatchT0inCPACrossing()),
330 fStitcher(pmstitchConfig),
334 fAdcInPassingPoints(hpassing), fAdcInRejectedPoints(hrejected),
336 fGeom(&*(
art::ServiceHandle<
geo::Geometry>())),
342 mf::LogVerbatim(
"PMAlgTracker") <<
"Using views in the following order:";
354 else {
throw cet::exception(
"pma::PMAlgTracker") <<
"validation name not supported" << std::endl; }
358 mf::LogWarning(
"PMAlgTracker") <<
"Not enough planes to perform validation, switch mode to hits.";
365 mf::LogVerbatim(
"PMAlgTracker") <<
"Validation ADC thresholds per plane:";
376 for (
size_t i = 0; i < hitsFromClusters.size(); ++i)
378 auto v = hitsFromClusters.at(i);
380 for (
auto const & h : v)
fCluHits.back().push_back(h);
388 const std::vector< float > & trackLike)
390 mf::LogVerbatim(
"PMAlgTracker") <<
"Filter track-like clusters using likelihood values...";
393 for (
size_t i = 0; i < hitsFromClusters.size(); ++i)
395 auto v = hitsFromClusters.at(i);
397 for (
auto const & h : v)
fCluHits.back().push_back(h);
410 for (
size_t i = 0; i < hitsFromClusters.size(); ++i)
412 auto v = hitsFromClusters.at(i);
414 for (
auto const & h : v)
417 for (
size_t j = 0; j < hitsFromEmParts.size(); ++j)
419 auto u = hitsFromEmParts.at(j);
420 for (
auto const & g : u)
422 if (g.key() == h.key()) { trkLike =
false;
break; }
426 if (trkLike)
fCluHits.back().push_back(h);
431 mf::LogVerbatim(
"PMAlgTracker") <<
"...done, " << n <<
" clusters for 3D tracking.";
440 mf::LogVerbatim(
"PMAlgTracker") <<
"first or last node too far out of its initial TPC";
464 default:
throw cet::exception(
"pma::PMAlgTracker") <<
"validation mode not supported" << std::endl;
break;
477 if ((
hits.size() > 1) || (dist2 > 1.0))
481 size_t best_u = 0, n_max = 0;
482 for (
size_t u = 0; u < tracks.
size(); u++)
487 if (n > n_max) { n_max =
n; best_u = u; best_trk = trk2; }
490 if (best_trk && (n_max >=
hits.size() / 3))
492 mf::LogVerbatim(
"PMAlgTrackMaker") <<
" Reassign(v1) " << n_max <<
" hits." << std::endl;
502 tracks[best_u].SetTrack(ext);
509 size_t minSizeCompl =
hits.size() / 8;
510 if (minSizeCompl < 3) minSizeCompl = 3;
513 unsigned int tpc =
hits.front()->WireID().TPC;
514 unsigned int cryo =
hits.front()->WireID().Cryostat;
520 mf::LogVerbatim(
"PMAlgTrackMaker") <<
" Add new track, cut hits from source track." << std::endl;
529 else if ((
hits.size() == 1) || (dist2 > 2.25))
531 mf::LogVerbatim(
"PMAlgTrackMaker") <<
" Cut single-view isolated hit." << std::endl;
543 while ((idx < trk.
size() - 1) && !(trk[idx]->IsEnabled()))
545 hits.push_back(trk[idx++]->Hit2DPtr());
551 if ((idx < trk.
size() - 1) &&
552 (trk[idx]->View2D() == trk[idx - 1]->View2D()))
558 hits.push_back(trk[idx++]->Hit2DPtr());
569 size_t idx = trk.
size() - 1;
570 while ((idx > 0) && !(trk[idx]->IsEnabled()))
572 hits.push_back(trk[idx--]->Hit2DPtr());
576 if (idx < trk.
size() - 1)
579 (trk[idx]->View2D() == trk[idx + 1]->View2D()))
585 hits.push_back(trk[idx--]->Hit2DPtr());
596 for (
size_t t = 0; t < tracks.
size(); t++)
599 if (trk.
size() < 6)
continue;
603 std::vector< art::Ptr<recob::Hit> >
hits;
625 if ((
hits.size() > 1) || (dist2 > 1.0))
630 for (
size_t u = 0; u < tracks.
size(); u++)
635 if (n > n_max) { n_max =
n; best_trk = trk2; }
638 if (best_trk && (n_max >= (
size_t)(0.8 *
hits.size())))
640 mf::LogVerbatim(
"PMAlgTrackMaker") <<
" Reassign(v2) " << n_max <<
" hits." << std::endl;
651 else if ((
hits.size() == 1) || (dist2 > 2.25))
653 mf::LogVerbatim(
"PMAlgTrackMaker") <<
" Cut single-view isolated hit." << std::endl;
672 for (
size_t t = 0; t < tracks.
size(); t++)
675 if (trk.
size() < 6)
continue;
679 std::vector< art::Ptr<recob::Hit> >
hits;
696 double& dist,
double& cos3d,
bool& reverseOrder,
697 double distThr,
double distThrMin,
702 double l1 = trk1->
Length();
703 double l2 = trk2->
Length();
705 if (l1 > l2) lmax = l1;
708 double d = lmax * distThr;
709 if (d < distThrMin) d = distThrMin;
716 if (distFB < dist) { k = 1; dist = distFB; }
719 if (distBF < dist) { k = 2; dist = distBF; }
722 if (distBB < dist) { k = 3; dist = distBB; }
732 case 0: trk1->
Flip();
break;
733 case 1: tmp = trk1; trk1 = trk2; trk2 =
tmp;
break;
735 case 3: trk2->
Flip();
break;
736 default:
mf::LogError(
"PMAlgTracker") <<
"Should never happen.";
738 if (k == 1) reverseOrder =
true;
739 else reverseOrder =
false;
741 size_t nodeEndIdx = trk1->
Nodes().size() - 1;
744 TVector3 trk2front0 = trk2->
Nodes()[0]->Point3D();
745 TVector3 trk2front1 = trk2->
Nodes()[1]->Point3D();
747 double distProj1 = sqrt(
pma::Dist2(endpoint1, proj1) );
750 TVector3 trk1back0 = trk1->
Nodes()[nodeEndIdx]->Point3D();
751 TVector3 trk1back1 = trk1->
Nodes()[nodeEndIdx - 1]->Point3D();
753 double distProj2 = sqrt(
pma::Dist2(endpoint2, proj2) );
758 cos3d = dir1.Dot(dir2);
760 if ((cos3d > cosThr) && (distProj1 < distProjThr) && (distProj2 < distProjThr))
764 const double maxCosXZ = 0.996195;
767 dir1_xz *= 1.0 / dir1_xz.R();
770 dir2_xz *= 1.0 / dir2_xz.R();
772 if ((fabs(dir1_xz.Z()) > maxCosXZ) && (fabs(dir2_xz.Z()) > maxCosXZ))
778 distProj1 = sqrt(
pma::Dist2(endpoint1, proj1) );
784 distProj2 = sqrt(
pma::Dist2(endpoint2, proj2) );
786 double cosThrXZ = cos(0.5 * acos(cosThr));
787 double distProjThrXZ = 0.5 * distProjThr;
788 double cosXZ = dir1_xz.Dot(dir2_xz);
789 if ((cosXZ > cosThrXZ) && (distProj1 < distProjThrXZ) && (distProj2 < distProjThrXZ))
799 double distThr = 0.25;
800 double distThrMin = 0.5;
803 double cosThr = cos(TMath::Pi() *
fMergeAngle / 180.0);
805 bool foundMerge =
false;
810 double d, dmin, c, cmax, l, lbest;
812 while (t < tracks.
size())
818 dmin = 1.0e12; cmax = 0; lbest = 0;
819 for (u = t + 1; u < tracks.
size(); u++)
821 trk2 = tracks[u].Track();
822 if (
areCoLinear(trk1, trk2, d, c, r, distThr, distThrMin, distProjThr, cosThr))
825 if (((c > cmax) && (d < dmin + 0.5 * lbest)) ||
826 ((d < dmin) && (l > 1.5 * lbest)))
840 << trk1->
size() <<
") with track (" << trk2->
size() <<
")";
844 tracks[t].SetTrack(trk2);
849 tracks[u].DeleteTrack();
865 for (
auto node :
trk.Track()->Nodes())
866 if (node->IsBranching()) node->SetFrozen(
true);
871 for (
auto node :
trk.Track()->Nodes())
872 node->SetFrozen(
false);
877 double distThr = 0.25;
878 double distThrMin = 2.5;
881 double cosThr = cos(TMath::Pi() *
fStitchAngle / 180.0);
884 double dfront1, dback1, dfront2, dback2;
888 for (
auto & tpc_entry1 : tracks)
890 unsigned int tpc1 = tpc_entry1.first;
894 while (t < tracks1.
size())
896 bool r, reverse =
false;
897 double l, lbest = 0,
d, dmin = 1.0e12, c, cmax = 0.0;
899 unsigned int best_tpc = 0;
903 dfront1 = trk1->
Nodes().front()->GetDistToWall();
904 dback1 = trk1->
Nodes().back()->GetDistToWall();
905 if ((dfront1 < wallDistThr) || (dback1 < wallDistThr))
907 for (
auto & tpc_entry2 : tracks)
909 unsigned int tpc2 = tpc_entry2.first;
910 if (tpc2 == tpc1)
continue;
914 for (
size_t u = 0; u < tracks2.
size(); u++)
917 dfront2 = trk2->
Nodes().front()->GetDistToWall();
918 dback2 = trk2->
Nodes().back()->GetDistToWall();
919 if ((dfront2 < wallDistThr) || (dback2 < wallDistThr))
921 if (
areCoLinear(trk1, trk2,
d, c, r, distThr, distThrMin, distProjThr, cosThr))
924 if (((c > cmax) && (
d < dmin + 0.5 * lbest)) || (0.75 * l < dmin))
926 cmax = c; dmin =
d; lbest = l;
941 << tpc1 <<
":" << tracks1.
size() <<
":" << trk1->
size() <<
") with track (" 942 << best_tpc <<
":" << tracks[best_tpc].size() <<
":" << best_trk2->
size() <<
")";
943 auto const* geom = lar::providerFrom<geo::Geometry>();
945 const geo::TPCGeo &tpc2 = geom->TPC(best_trk2->
Nodes().front()->TPC(),best_trk2->
Nodes().front()->Cryo());
954 tracks1[t].SetTrack(best_trk2);
964 tracks[best_tpc][best_idx].DeleteTrack();
966 tracks[best_tpc].erase_at(best_idx);
979 for (
auto const & t : tracks.
tracks())
982 if (n > max_hits) { max_hits =
n; }
1004 <<
"Reconstruct tracks within Cryo:" << tpc_iter->Cryostat
1005 <<
" / TPC:" << tpc_iter->TPC <<
".";
1009 mf::LogVerbatim(
"PMAlgTracker") <<
"Prepare validation ADC images...";
1011 for (
size_t p = 0; p < nplanes; ++p) { ok &=
fAdcImages[p].setWireDriftData(
fWires, p, tpc_iter->TPC, tpc_iter->Cryostat); }
1023 mf::LogVerbatim(
"PMAlgTracker") <<
"Found tracks: " << tracks[tpc_iter->TPC].size();
1024 if (tracks[tpc_iter->TPC].empty()) {
continue; }
1033 mf::LogVerbatim(
"PMAlgTracker") <<
"Merge co-linear tracks within TPC " << tpc_iter->TPC <<
".";
1043 mf::LogVerbatim(
"PMAlgTracker") <<
"Stitch co-linear tracks between TPCs.";
1047 for (
auto & tpc_entry : tracks)
1048 for (
auto &
trk : tpc_entry.second.tracks())
1051 else {
trk.DeleteTrack(); }
1062 mf::LogVerbatim(
"PMAlgTracker") <<
"Vertex finding / track-vertex reoptimization.";
1072 mf::LogVerbatim(
"PMAlgTracker") <<
"Find co-linear CPA-crossing tracks with any T0.";
1078 mf::LogVerbatim(
"PMAlgTracker") <<
"Find co-linear APA-crossing tracks with any T0.";
1084 mf::LogVerbatim(
"PMAlgTracker") <<
"Second pass cosmic tagging for stitched tracks";
1105 size_t minBuildSize,
unsigned int tpc,
unsigned int cryo)
1109 size_t minSizeCompl = minBuildSize / 8;
1110 if (minSizeCompl < 2) minSizeCompl = 2;
1112 int max_first_idx = 0;
1113 while (max_first_idx >= 0)
1117 if ((max_first_idx >= 0) && !
fCluHits[max_first_idx].empty())
1122 minSizeCompl, tpc, cryo, first_view);
1135 size_t minSizeCompl,
unsigned int tpc,
unsigned int cryo,
geo::View_t first_view)
1141 if (first_clu_idx >= 0)
1147 unsigned int nFirstHits = first_hits.size(), first_plane_idx = first_hits.front()->WireID().Plane;
1148 mf::LogVerbatim(
"PMAlgTracker") << std::endl <<
"--- start new candidate ---";
1149 mf::LogVerbatim(
"PMAlgTracker") <<
"use view *** " << first_view <<
" *** plane idx " << first_plane_idx <<
" *** size: " << nFirstHits;
1151 float x, xmax =
fDetProp->
ConvertTicksToX(first_hits.front()->PeakTime(), first_plane_idx, tpc, cryo), xmin = xmax;
1153 for (
size_t j = 1; j < first_hits.size(); ++j)
1156 if (x > xmax) { xmax =
x; }
1157 if (x < xmin) { xmin =
x; }
1164 bool try_build =
true;
1168 if (first_clu_idx >= 0) candidate.
Clusters().push_back((
size_t)first_clu_idx);
1171 int idx = -1, av_idx = -1;
1172 unsigned int nMaxHits = 0, nHits = 0;
1174 for (
auto av : fAvailableViews)
1176 if (av == first_view)
continue;
1178 av_idx =
maxCluster(first_clu_idx, candidates, xmin, xmax, minSizeCompl, av, tpc, cryo);
1182 if ((nHits > nMaxHits) && (nHits >= minSizeCompl))
1184 nMaxHits = nHits; idx = av_idx; bestView = av;
1190 for (
auto av : fAvailableViews)
1192 if ((av != first_view) && (av != bestView)) { testView = av;
break; }
1197 mf::LogVerbatim(
"PMAlgTracker") <<
"--> " << imatch++ <<
" match with:";
1198 mf::LogVerbatim(
"PMAlgTracker") <<
" cluster in view *** " << bestView <<
" *** size: " << nMaxHits;
1201 else {
mf::LogVerbatim(
"PMAlgTracker") <<
" validation plane *** " << testView <<
" ***"; }
1203 double m0 = 0.0, v0 = 0.0;
1204 double mseThr = 0.15, validThr = 0.7;
1206 candidate.
Clusters().push_back(idx);
1217 if (candidate.
Track() && (m0 < mseThr) && (v0 > validThr))
1219 mf::LogVerbatim(
"PMAlgTracker") <<
" good track candidate, MSE = " << m0 <<
", v = " << v0;
1226 double fraction = 0.5;
1238 candidate.
Clusters().push_back(idx);
1244 mf::LogVerbatim(
"PMAlgTracker") <<
"merge clusters from the validation plane";
1248 bool extended =
false;
1257 candidate.
Clusters().push_back(idx);
1268 mf::LogVerbatim(
"PMAlgTracker") <<
"track REJECTED, MSE = " << m0 <<
"; v = " << v0;
1279 if (!candidates.
empty())
1282 double f, max_f = 0., min_mse = 10., max_v = 0.;
1283 for (
size_t t = 0; t < candidates.
size(); t++)
1284 if (candidates[t].IsGood() &&
1285 (candidates[t].Track()->Nodes().
size() > 1) &&
1286 candidates[t].
Track()->HasTwoViews())
1290 if ((f > max_f) || ((f == max_f) &&
1291 ((candidates[t].Validation() > max_v) || (candidates[t].Mse() < min_mse))))
1294 min_mse = candidates[t].Mse();
1295 max_v = candidates[t].Validation();
1302 candidates[best_trk].Track()->ShiftEndsToHits();
1304 for (
auto c : candidates[best_trk].Clusters())
1307 result = candidates[best_trk];
1310 for (
size_t t = 0; t < candidates.
size(); t++)
1312 if (
int(t) != best_trk) candidates[t].DeleteTrack();
1322 unsigned int testView,
bool add_nodes)
1324 double m_max = 2.0 * candidate.
Mse();
1325 if (m_max < 0.05) m_max = 0.05;
1327 double v_min1 = 0.98 * candidate.
Validation();
1328 double v_min2 = 0.9 * candidate.
Validation();
1331 double m1 = copy->
GetMse();
1332 double v1 =
validate(*copy, testView);
1334 if (((m1 < candidate.
Mse()) && (v1 >= v_min2)) ||
1335 ((m1 < 0.5) && (m1 <= m_max) && (v1 >= v_min1)))
1338 <<
" track EXTENDED, MSE = " << m1 <<
", v = " << v1;
1350 <<
" track NOT extended, MSE = " << m1 <<
", v = " << v1;
1358 size_t minSize,
double fraction,
1359 unsigned int preferedView,
unsigned int testView,
1360 unsigned int tpc,
unsigned int cryo)
const 1362 double f, fmax = 0.0;
1363 unsigned int n,
max = 0;
1365 for (
size_t i = 0; i <
fCluHits.size(); ++i)
1369 unsigned int view =
fCluHits[i].front()->View();
1370 unsigned int nhits =
fCluHits[i].size();
1374 (view == testView) ||
1375 ((preferedView !=
geo::kUnknown)&&(view != preferedView)) ||
1380 f = n / (double)nhits;
1381 if ((f > fraction) && (n >
max))
1383 max =
n; fmax =
f; idx = i;
1387 if (idx >= 0)
mf::LogVerbatim(
"PMAlgTracker") <<
"max matching hits: " << max <<
" (" << fmax <<
")";
1388 else mf::LogVerbatim(
"PMAlgTracker") <<
"no clusters to extend the track";
1396 float xmin,
float xmax,
size_t min_clu_size,
1397 geo::View_t view,
unsigned int tpc,
unsigned int cryo)
const 1400 size_t s_max = 0,
s;
1401 double fraction = 0.0;
1404 size_t first_idx = 0;
1405 bool has_first =
false;
1406 if (first_idx_tag >= 0)
1408 first_idx = (size_t)first_idx_tag;
1412 for (
size_t i = 0; i <
fCluHits.size(); ++i)
1414 if ((
fCluHits[i].size() < min_clu_size) || (
fCluHits[i].front()->View() != view) ||
1418 bool pair_checked =
false;
1419 for (
auto const & c : candidates.
tracks())
1420 if (has_first &&
has(c.Clusters(), first_idx) &&
has(c.Clusters(), i))
1422 pair_checked =
true;
break;
1424 if (pair_checked)
continue;
1428 if ((v.front()->WireID().TPC == tpc) &&
1429 (v.front()->WireID().Cryostat == cryo))
1432 for (
size_t j = 0; j < v.size(); ++j)
1435 if ((x >= xmin) && (x <= xmax))
s++;
1440 s_max =
s; idx = i; fraction =
s / (double)v.size();
1444 if (fraction > 0.4)
return idx;
1450 geo::View_t view,
unsigned int tpc,
unsigned int cryo)
const 1453 size_t s_max = 0,
s;
1455 for (
size_t i = 0; i <
fCluHits.size(); ++i)
1464 if ((v.front()->WireID().TPC == tpc) &&
1465 (v.front()->WireID().Cryostat == cryo))
1468 if ((
s >= min_clu_size) && (
s > s_max))
1483 mf::LogVerbatim(
"PMAlgTracker") << std::endl <<
"----------- matched clusters: -----------";
1484 for (
size_t i = 0; i <
fCluHits.size(); ++i)
1489 <<
" tpc: " <<
fCluHits[i].front()->WireID().TPC
1490 <<
";\tview: " <<
fCluHits[i].front()->View()
1491 <<
";\tsize: " <<
fCluHits[i].size()
1503 mf::LogVerbatim(
"PMAlgTracker") <<
"--------- not matched clusters: ---------";
1504 size_t nsingles = 0;
1505 for (
size_t i = 0; i <
fCluHits.size(); ++i)
1509 if (
fCluHits[i].size() == 1) { nsingles++; }
1513 <<
" tpc: " <<
fCluHits[i].front()->WireID().TPC
1514 <<
";\tview: " <<
fCluHits[i].front()->View()
1515 <<
";\tsize: " <<
fCluHits[i].size()
1531 mf::LogVerbatim(
"PMAlgTracker") <<
"-----------------------------------------";
unsigned int testHits(const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit > > &hits, double eps=1.0) const
Count the number of hits that are closer than eps * fHitTestingDist2D to the track 2D projection...
double collectSingleViewFront(pma::Track3D &trk, std::vector< art::Ptr< recob::Hit > > &hits)
bool SelectHits(float fraction=1.0F)
pma::Track3D * buildShowerSeg(const std::vector< art::Ptr< recob::Hit > > &hits, const pma::Vector3D &vtx) const
Build a shower segment from sets of hits and attached to the provided vertex.
const std::vector< size_t > & Clusters(void) const
std::vector< std::vector< art::Ptr< recob::Hit > > > fCluHits
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
bool mergeCoLinear(pma::TrkCandidateColl &tracks)
pma::Node3D * LastElement(void) const
void tag(pma::TrkCandidateColl &tracks)
void CleanupTails(void)
Cut out tails with no hits assigned.
double GetMse(unsigned int view=geo::kUnknown) const
MSE of hits weighted with hit amplidudes and wire plane coefficients.
TPC_id_iterator begin_TPC_id() const
Returns an iterator pointing to the first TPC ID in the detector.
static constexpr Mask_t makeMask(Flags...flags)
Returns a bit mask with only the specified bit set.
PMAlgTracker(const std::vector< art::Ptr< recob::Hit > > &allhitlist, const std::vector< recob::Wire > &wires, const pma::ProjectionMatchingAlg::Config &pmalgConfig, const pma::PMAlgTracker::Config &pmalgTrackerConfig, const pma::PMAlgVertexing::Config &pmvtxConfig, const pma::PMAlgStitching::Config &pmstitchConfig, const pma::PMAlgCosmicTagger::Config &pmtaggerConfig, const std::vector< TH1F * > &hpassing, const std::vector< TH1F * > &hrejected)
void guideEndpoints(pma::Track3D &trk, const std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > &hits) const
Add 3D reference points to clean endpoints of a track (both need to be in the same TPC)...
void SetKey(int key)
Set key of an external object associated to this track candidate.
recob::Track convertFrom(const pma::Track3D &src, unsigned int tidx, int pdg=0)
geo::GeometryCore const * fGeom
double Dist2(const TVector2 &v1, const TVector2 &v2)
unsigned int FrontTPC(void) const
bool Flip(std::vector< pma::Track3D * > &allTracks)
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void flipTreesToCoordinate(size_t coordinate)
size_t fMinSeedSize2ndPass
void erase_at(size_t pos)
std::set< geo::View_t > const & Views() const
Returns a list of possible views in the detector.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
bool reassignHits_2(const std::vector< art::Ptr< recob::Hit > > &hits, pma::TrkCandidateColl &tracks, size_t trk_idx, double dist2)
void setParentDaughterConnections(void)
Geometry information for a single TPC.
std::vector< pma::Node3D * > const & Nodes(void) const
bool fMatchT0inAPACrossing
double fMinTwoViewFraction
bool reassignHits_1(const std::vector< art::Ptr< recob::Hit > > &hits, pma::TrkCandidateColl &tracks, size_t trk_idx, double dist2)
fhicl::Atom< std::string > Validation
bool fMatchT0inCPACrossing
const detinfo::DetectorProperties * fDetProp
std::vector< std::vector< art::Ptr< recob::Hit > > > fCluHits
std::vector< TrkCandidate > const & tracks(void) const
pma::PMAlgCosmicTagger fCosmicTagger
void SetValidation(double v)
void SetTrack(pma::Track3D *trk)
double GetDistToWall(void) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
bool areCoLinear(pma::Track3D *trk1, pma::Track3D *trk2, double &dist, double &cos3d, bool &reverseOrder, double distThr, double distThrMin, double distProjThr, double cosThr)
double fStitchTransverseShift
void listUsedClusters(void) const
std::vector< pma::Segment3D * > const & Segments(void) const
void RemoveHits(const std::vector< art::Ptr< recob::Hit > > &hits)
Remove hits; removes also hit->node/seg assignments.
recob::tracking::Vector_t Vector3D
std::map< int, pma::Vector3D > fPfpVtx
pma::Vector3D GetDirection3D(size_t index) const
Get trajectory direction at given hit index.
pma::Track3D * buildMultiTPCTrack(const std::vector< art::Ptr< recob::Hit > > &hits) const
as far as hits origin from at least two wire planes.
pma::TrkCandidate matchCluster(int first_clu_idx, const std::vector< art::Ptr< recob::Hit > > &first_hits, size_t minSizeCompl, unsigned int tpc, unsigned int cryo, geo::View_t first_view)
void freezeBranchingNodes(pma::TrkCandidateColl &tracks)
recob::tracking::Point_t Point_t
bool ShiftEndsToHits(void)
void StitchTracksCPA(pma::TrkCandidateColl &tracks)
std::vector< double > fAdcValidationThr
std::vector< int > fTrackingOnlyPdg
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
size_t matchTrack(const pma::TrkCandidateColl &tracks, const std::vector< art::Ptr< recob::Hit > > &hits) const
std::vector< float > fCluWeights
pma::PMAlgStitching fStitcher
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. See recob::tracking::Coord_t for more details on the ...
fhicl::Sequence< double > AdcValidationThr
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
bool isContained(const pma::Track3D &trk, float margin=0.0F) const
TVector2 GetProjectionToSegment(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
A trajectory in space reconstructed from hits.
double validate(pma::Track3D &trk, unsigned int testView)
float fTrackLikeThreshold
std::vector< int > fTrackingSkipPdg
bool reassignSingleViewEnds_2(pma::TrkCandidateColl &tracks)
pma::Track3D * buildTrack(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
wire planes; number of segments used to create the track depends on the number of hits...
const std::vector< recob::Wire > & fWires
bool has(const std::vector< size_t > &v, size_t idx) const
pma::ProjectionMatchingAlg fProjectionMatchingAlg
double fMergeTransverseShift
double collectSingleViewEnd(pma::Track3D &trk, std::vector< art::Ptr< recob::Hit > > &hits)
std::map< int, int > fPfpPdgCodes
General LArSoft Utilities.
bool extendTrack(pma::TrkCandidate &candidate, const std::vector< art::Ptr< recob::Hit > > &hits, unsigned int testView, bool add_nodes)
unsigned int FrontCryo(void) const
TPC_id_iterator end_TPC_id() const
Returns an iterator pointing after the last TPC ID in the detector.
bool has(const std::vector< int > &v, int i) const
unsigned int DisableSingleViewEnds(void)
std::vector< size_t > fInitialClusters
double validate_on_adc_test(const pma::Track3D &trk, const img::DataProviderAlg &adcImage, const std::vector< art::Ptr< recob::Hit > > &hits, TH1F *histoPassing, TH1F *histoRejected) const
bool reassignSingleViewEnds_1(pma::TrkCandidateColl &tracks)
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
TVector3 const & Point3D(void) const
double validate_on_adc(const pma::Track3D &trk, const img::DataProviderAlg &adcImage, float thr) const
fhicl::Table< img::DataProviderAlg::Config > AdcImageAlg
bool HasTwoViews(size_t nmin=1) const
recob::tracking::SMatrixSym55 SMatrixSym55
Implementation of the Projection Matching Algorithm.
double Validation(void) const
double Length(size_t step=1) const
std::vector< img::DataProviderAlg > fAdcImages
LArSoft-specific namespace.
void init(const art::FindManyP< recob::Hit > &hitsFromClusters)
short int DetectDriftDirection() const
Returns the expected drift direction based on geometry.
void StitchTracksAPA(pma::TrkCandidateColl &tracks)
PMAlgFitter(const std::vector< art::Ptr< recob::Hit > > &allhitlist, const std::vector< recob::Cluster > &clusters, const std::vector< recob::PFParticle > &pfparticles, const art::FindManyP< recob::Hit > &hitsFromClusters, const art::FindManyP< recob::Cluster > &clusFromPfps, const art::FindManyP< recob::Vertex > &vtxFromPfps, const pma::ProjectionMatchingAlg::Config &pmalgConfig, const pma::PMAlgFitter::Config &pmalgFitterConfig, const pma::PMAlgVertexing::Config &pmvtxConfig)
std::map< unsigned int, std::vector< size_t > > fTriedClusters
pma::Track3D * extendTrack(const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit > > &hits, bool add_nodes) const
Add more hits to an existing track, reoptimize, optionally add more nodes.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void guideEndpoints(pma::TrkCandidateColl &tracks)
std::map< size_t, pma::TrkCandidateColl > tpc_track_map
int maxCluster(int first_idx_tag, const pma::TrkCandidateColl &candidates, float xmin, float xmax, size_t min_clu_size, geo::View_t view, unsigned int tpc, unsigned int cryo) const
std::vector< geo::View_t > fAvailableViews
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
PMAlgTrackingBase(const std::vector< art::Ptr< recob::Hit > > &allhitlist, const pma::ProjectionMatchingAlg::Config &pmalgConfig, const pma::PMAlgVertexing::Config &pmvtxConfig)
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
const pma::TrkCandidateColl & result(void)
size_t fMinSeedSize1stPass
pma::TrkCandidateColl fResult
std::vector< size_t > fUsedClusters
EValidationMode fValidation
recob::tracking::Plane Plane
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. See recob::tracking::Coord_t for more detai...
Namespace collecting geometry-related classes utilities.
double twoViewFraction(pma::Track3D &trk) const
void releaseAllNodes(pma::TrkCandidateColl &tracks)
size_t run(pma::TrkCandidateColl &trk_input)
const std::vector< TH1F * > & fAdcInPassingPoints
recob::tracking::Vector_t Vector_t
double validate(const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit > > &hits) const
const std::vector< TH1F * > & fAdcInRejectedPoints
pma::Node3D * FirstElement(void) const
void push_back(const TrkCandidate &trk)
void fromMaxCluster_tpc(pma::TrkCandidateColl &result, size_t minBuildSize, unsigned int tpc, unsigned int cryo)
pma::PMAlgVertexing fPMAlgVertexing
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
cet::coded_exception< error, detail::translate > exception
void ApplyDriftShiftInTree(double dx, bool skipFirst=false)
Adjust track tree position in the drift direction (when T0 is being corrected).
pma::cryo_tpc_view_hitmap fHitMap
void mergeTracks(pma::Track3D &dst, pma::Track3D &src, bool reopt) const
pma::Track3D * Track(void) const
void AddHits(const std::vector< art::Ptr< recob::Hit > > &hits)
std::map< int, std::vector< art::Ptr< recob::Cluster > > > fPfpClusters