12 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 13 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 21 #include "range/v3/view.hpp" 28 constexpr
double step{0.3};
37 ,
fGeom{lar::providerFrom<geo::Geometry>()}
49 const lariov::ChannelStatusProvider& channelStatus,
52 float const thr)
const 54 unsigned int nAll = 0, nPassed = 0;
55 unsigned int testPlane = adcImage.
Plane();
57 std::vector<unsigned int> trkTPCs = trk.
TPCs();
58 std::vector<unsigned int> trkCryos = trk.
Cryos();
64 for (
auto const* seg : trk.
Segments()) {
75 unsigned tpc = seg->
TPC();
76 unsigned cryo = seg->Cryo();
81 while ((f < 1.0) && node->
SameTPC(p)) {
84 geo::WireID wireID(cryo, tpc, testPlane, (
int)p2d.X());
86 int widx = (int)p2d.X();
91 if (channelStatus.IsGood(ch)) {
92 float max_adc = adcImage.
poolMax(widx, didx, 2);
93 if (max_adc > thr) nPassed++;
108 double v = nPassed / (double)nAll;
117 struct hits_on_plane {
119 unsigned int const plane_;
127 const lariov::ChannelStatusProvider& channelStatus,
132 TH1F* histoRejected)
const 135 double const max_d2 = max_d * max_d;
136 unsigned int nAll = 0, nPassed = 0;
137 unsigned int testPlane = adcImage.
Plane();
139 std::vector<unsigned int> trkTPCs = trk.
TPCs();
140 std::vector<unsigned int> trkCryos = trk.
Cryos();
141 std::map<std::pair<unsigned int, unsigned int>, std::pair<TVector2, TVector2>>
ranges;
142 std::map<std::pair<unsigned int, unsigned int>,
double> wirePitch;
143 for (
auto const& [t, c] : views::cartesian_product(trkTPCs, trkCryos)) {
148 unsigned int tpc, cryo;
149 std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
152 hits | views::transform(
to_element) | views::filter(hits_on_plane{testPlane})) {
153 tpc = h.WireID().TPC;
154 cryo = h.WireID().Cryostat;
155 std::pair<unsigned int, unsigned int> tpc_cryo(tpc, cryo);
156 std::pair<TVector2, TVector2> rect = ranges[tpc_cryo];
158 if ((h.WireID().Wire > rect.first.X() - 10) &&
159 (h.WireID().Wire < rect.second.X() + 10) &&
160 (h.PeakTime() > rect.first.Y() - 100) &&
161 (h.PeakTime() < rect.second.Y() + 100)) {
162 TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
165 double const d2 = trk.
Dist2(p2d, testPlane, tpc, cryo);
167 if (d2 < max_d2) { all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y()); }
176 for (
auto const* seg : trk.
Segments()) {
192 auto const& points = all_close_points[{tpc, cryo}];
197 while ((f < 1.0) && node->
SameTPC(p)) {
200 geo::WireID const wireID{planeID,
static_cast<unsigned int>(p2d.X())};
202 int widx = (int)p2d.X();
207 if (channelStatus.IsGood(ch)) {
208 bool is_close =
false;
209 float max_adc = adcImage.
poolMax(widx, didx, 2);
212 p2d.SetX(wirepitch * p2d.X());
213 for (
const auto& h : points) {
225 if (histoPassing) histoPassing->Fill(max_adc);
228 if (histoRejected) histoRejected->Fill(max_adc);
242 double v = nPassed / (double)nAll;
253 const lariov::ChannelStatusProvider& channelStatus,
257 if (
hits.empty()) {
return 0; }
260 double const max_d2 = max_d * max_d;
261 unsigned int nAll = 0, nPassed = 0;
262 unsigned int testPlane =
hits.front()->WireID().Plane;
264 std::vector<unsigned int> trkTPCs = trk.
TPCs();
265 std::vector<unsigned int> trkCryos = trk.
Cryos();
266 std::map<std::pair<unsigned int, unsigned int>, std::pair<TVector2, TVector2>>
ranges;
267 std::map<std::pair<unsigned int, unsigned int>,
double> wirePitch;
268 for (
auto const& [t, c] : views::cartesian_product(trkTPCs, trkCryos)) {
273 unsigned int tpc, cryo;
274 std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
277 hits | views::transform(
to_element) | views::filter(hits_on_plane{testPlane})) {
278 tpc = h.WireID().TPC;
279 cryo = h.WireID().Cryostat;
280 std::pair<unsigned int, unsigned int> tpc_cryo(tpc, cryo);
281 std::pair<TVector2, TVector2> rect = ranges[tpc_cryo];
283 if ((h.WireID().Wire > rect.first.X() - 10) &&
284 (h.WireID().Wire < rect.second.X() + 10) &&
285 (h.PeakTime() > rect.first.Y() - 100) &&
286 (h.PeakTime() < rect.second.Y() + 100)) {
287 TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
290 double const d2 = trk.
Dist2(p2d, testPlane, tpc, cryo);
292 if (d2 < max_d2) all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y());
301 for (
auto const* seg : trk.
Segments()) {
317 auto const& points = all_close_points[{tpc, cryo}];
323 while ((f < 1.0) && node->
SameTPC(p)) {
325 geo::WireID const wireID{planeID,
static_cast<unsigned int>(p2d.X())};
328 if (channelStatus.IsGood(ch)) {
330 p2d.SetX(wirepitch * p2d.X());
331 for (
const auto& h : points) {
351 double v = nPassed / (double)nAll;
361 const lariov::ChannelStatusProvider& channelStatus,
365 unsigned int testPlane,
367 unsigned int cryo)
const 370 double d2, max_d2 = max_d * max_d;
371 unsigned int nAll = 0, nPassed = 0;
376 dc *= step / dc.Mag();
383 geo::WireID wireID(cryo, tpc, testPlane, (
int)p2d.X());
386 if (channelStatus.IsGood(ch)) {
387 p2d.Set(wirepitch * p2d.X(), p2d.Y());
388 for (
const auto& h :
hits)
389 if ((h->WireID().Plane == testPlane) && (h->WireID().TPC == tpc) &&
390 (h->WireID().Cryostat == cryo)) {
409 double v = nPassed / (double)nAll;
410 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" segment fraction ok: " << v;
424 while ((idx < trk.
size() - 1) && !trk[idx]->IsEnabled())
426 double l0 = trk.
Length(0, idx + 1);
428 idx = trk.
size() - 1;
429 while ((idx > 1) && !trk[idx]->IsEnabled())
431 double l1 = trk.
Length(idx - 1, trk.
size() - 1);
435 return 1.0 - (l0 + l1) / trk.
Length();
441 int const nSegments = 0.8 * trk_size / sqrt(trk_size);
442 return std::max(
size_t{1},
static_cast<size_t>(nSegments));
456 std::vector<unsigned int> tpcs = trk->
TPCs();
457 for (
size_t t = 0; t < tpcs.size(); ++t) {
465 size_t nNodes = (size_t)(nSegments - 1);
469 mf::LogWarning(
"ProjectionMatchingAlg") <<
" initialization failed, delete trk";
477 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" optimize trk (" << nSegments <<
" seg)";
492 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" clusters do not match, f = " <<
f;
503 std::map<unsigned int, std::vector<art::Ptr<recob::Hit>>> hits_by_tpc;
504 for (
auto const& h :
hits) {
505 hits_by_tpc[h->WireID().TPC].push_back(h);
508 std::vector<pma::Track3D*> tracks;
509 for (
auto const& hsel : hits_by_tpc) {
511 if (trk) tracks.push_back(trk);
514 bool need_reopt =
false;
515 while (tracks.size() > 1) {
520 double d, dmin = 1.0e12;
521 size_t t_best = 0, cfg = 0;
522 for (
size_t t = 1; t < tracks.size(); ++t) {
573 tracks.erase(tracks.begin() + t_best);
580 if (!tracks.empty()) {
581 trk = tracks.front();
585 <<
" reopt after merging initial tpc segments: done, g = " << g;
592 size_t nNodes = (size_t)(nSegments - 1);
594 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" optimize trk (add " << nSegments <<
" seg)";
620 TVector3 vtxv3(vtx.X(), vtx.Y(), vtx.Z());
627 std::vector<art::Ptr<recob::Hit>> hitstpc;
628 for (
size_t h = 0; h <
hits.size(); ++h)
631 if (!hitstpc.size())
return 0;
633 std::vector<art::Ptr<recob::Hit>> hitstrk;
635 size_t countviews = 0;
637 mf::LogVerbatim(
"ProjectionMatchinAlg") <<
"collecting hits from view: " << view;
644 std::vector<art::Ptr<recob::Hit>> hitsview;
645 for (
size_t h = 0; h < hitstpc.size(); ++h)
646 if (hitstpc[h]->
WireID().Plane == view) hitsview.push_back(hitstpc[h]);
647 if (!hitsview.size()) {
653 std::vector<art::Ptr<recob::Hit>> hitsfilter;
660 for (
size_t h = 0; h < hitsfilter.size(); ++h)
661 hitstrk.push_back(hitsfilter[h]);
663 if (hitsfilter.size() >= 5) countviews++;
668 if (!hitstrk.size() || (countviews < 2)) {
669 mf::LogWarning(
"ProjectionMatchinAlg") <<
"too few hits, segment not built";
681 if (trk->
size() < 10) {
682 mf::LogWarning(
"ProjectionMatchingAlg") <<
"too short segment, delete segment";
697 const TVector2& vtx2d)
const 699 size_t min_size = hits_in.size() / 5;
700 if (min_size < 3) min_size = 3;
702 std::vector<size_t> used;
703 std::vector<std::vector<art::Ptr<recob::Hit>>> sub_groups;
704 std::vector<art::Ptr<recob::Hit>> close_hits;
706 float mindist2 = 99999.99;
707 size_t id_sub_groups_save = 0;
709 while (
GetCloseHits_(detProp, r2d, hits_in, used, close_hits)) {
711 sub_groups.emplace_back(close_hits);
713 for (
size_t h = 0; h < close_hits.size(); ++h) {
715 close_hits[h]->
WireID().Wire,
716 close_hits[h]->PeakTime(),
718 close_hits[h]->
WireID().TPC,
719 close_hits[h]->
WireID().Cryostat);
722 if (dist2 < mindist2) {
723 id_sub_groups_save = id;
731 for (
size_t i = 0; i < sub_groups.size(); ++i) {
732 if (i == id_sub_groups_save) {
733 for (
auto h : sub_groups[i])
734 hits_out.push_back(h);
738 for (
size_t i = 0; i < sub_groups.size(); ++i) {
739 if ((i != id_sub_groups_save) && (hits_out.size() < 10) && (sub_groups[i].
size() > min_size))
740 for (
auto h : sub_groups[i])
741 hits_out.push_back(h);
750 std::vector<size_t>& used,
755 const double gapMargin = 5.0;
758 while ((idx < hits_in.size()) &&
Has_(used, idx))
761 if (idx < hits_in.size()) {
762 hits_out.push_back(hits_in[idx]);
765 unsigned int tpc = hits_in[idx]->WireID().TPC;
766 unsigned int cryo = hits_in[idx]->WireID().Cryostat;
767 unsigned int view = hits_in[idx]->WireID().Plane;
771 double r2d2 = r2d * r2d;
772 double gapMargin2 = sqrt(2 * gapMargin * gapMargin);
773 gapMargin2 = (gapMargin2 + r2d) * (gapMargin2 + r2d);
778 for (
size_t i = 0; i < hits_in.size(); i++)
779 if (!
Has_(used, i)) {
785 for (
auto const& ho : hits_out) {
787 TVector2 ho_cm(wirePitch * ho->WireID().Wire, driftPitch * ho->PeakTime());
797 hits_out.push_back(hi);
814 double mse = trk.
GetMse();
815 mf::LogWarning(
"ProjectionMatchingAlg") <<
"initial value of mse: " << mse;
816 while ((mse > 0.5) &&
TestTrk_(trk, tpcgeom)) {
818 for (
size_t h = 0; h < trk.
size(); ++h)
820 trk[h]->SetEnabled(
false);
825 trk.
Optimize(detProp, 0, 0.0001,
false);
829 if (mse == trk.
GetMse())
break;
854 for (
size_t h = 0; h < trk.
size(); ++h) {
855 if (!trk[h]->IsEnabled())
break;
859 mf::LogWarning(
"ProjectionMatchingAlg") <<
"length of segment: " << length;
860 if (length < 3.0) test =
false;
870 if (c == idx)
return true;
879 while (h < trk.
size()) {
880 if (trk[h]->IsEnabled())
902 mf::LogWarning(
"ProjectionMatchingAlg") <<
"initialization failed, delete segment";
912 mf::LogWarning(
"ProjectionMatchingAlg") <<
"need at least two views in single tpc";
930 if (dfront > dback) trk->
Flip();
932 trk->
Nodes().front()->SetPoint3D({point.X(), point.Y(), point.Z()});
933 trk->
Nodes().front()->SetFrozen(
true);
945 const TVector3& point)
const 952 if (dfront > dback) trk->
Flip();
954 trk->
Nodes().front()->SetPoint3D(point);
955 trk->
Nodes().front()->SetFrozen(
true);
968 bool add_nodes)
const 979 int nNodes = nSegments - copy->
Nodes().size() + 1;
980 if (nNodes < 0) nNodes = 0;
983 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" add " << nNodes <<
" nodes";
1005 size_t nCloseHits = 0;
1006 int forwWires = 3, backWires = -1;
1007 double xMargin = 0.4;
1009 if ((view == (
int)h->WireID().Plane) && (tpc == h->WireID().TPC) &&
1010 (cryo == h->WireID().Cryostat)) {
1012 for (
size_t ht = 0; ht < trk.
size(); ht++)
1013 if (trk[ht]->Hit2DPtr().key() == h.key()) {
1017 if (found)
continue;
1019 int dw = wdir * (h->WireID().Wire - wire);
1020 if ((dw <= forwWires) && (dw >= backWires)) {
1022 if (fabs(x - drift_x) < xMargin) nCloseHits++;
1035 std::pair<int, int>
const* wires,
1038 unsigned int cryo)
const 1040 double x = 0.0,
y = 0.0,
z = 0.0;
1041 std::vector<std::pair<int, unsigned int>> wire_view;
1042 for (
unsigned int i = 0; i < 3; i++)
1043 if (wires[i].first >= 0) {
1044 const auto hiter =
hits.find(i);
1045 if (hiter !=
hits.end()) {
1056 wire_view.emplace_back(wires[i].first, i);
1060 if (wire_view.size() > 1) {
1061 x /= wire_view.size();
1062 auto const [wire0, plane0] = wire_view[0];
1063 auto const [wire1, plane1] = wire_view[1];
1068 <<
"trk tpc:" << tpc <<
" size:" << trk.
size() <<
" add ref.point (" << x <<
"; " <<
y <<
"; " 1074 <<
"trk tpc:" << tpc <<
" size:" << trk.
size()
1075 <<
" wire-plane-parallel track, but need two clean views of endpoint";
1086 mf::LogWarning(
"ProjectionMatchingAlg") <<
"Please, apply before TPC stitching.";
1090 const double maxCosXZ = 0.992546;
1095 if ((segFront->
Length() < 0.8) && (segFront1->
Length() > 5.0)) segFront = segFront1;
1099 dirFrontXZ *= 1.0 / dirFrontXZ.R();
1104 if ((segBack->
Length() < 0.8) && (segBack1->
Length() > 5.0)) segBack = segBack1;
1108 dirBackXZ *= 1.0 / dirBackXZ.R();
1110 if ((fabs(dirFrontXZ.Z()) < maxCosXZ) && (fabs(dirBackXZ.Z()) < maxCosXZ)) {
1114 unsigned int nPlanesFront = 0, nPlanesBack = 0;
1115 std::pair<int, int> wiresFront[3], wiresBack[3];
1116 double xFront[3], xBack[3];
1118 for (
unsigned int i = 0; i < 3; i++) {
1119 bool frontPresent =
false, backPresent =
false;
1121 int idxFront0 = trk.
NextHit(-1, i);
1123 if ((idxFront0 >= 0) && (idxFront0 < (int)trk.
size()) && (idxBack0 >= 0) &&
1124 (idxBack0 < (int)trk.
size())) {
1125 int idxFront1 = trk.
NextHit(idxFront0, i);
1126 int idxBack1 = trk.
PrevHit(idxBack0, i);
1127 if ((idxFront1 >= 0) && (idxFront1 < (
int)trk.
size()) && (idxBack1 >= 0) &&
1128 (idxBack1 < (int)trk.
size())) {
1129 int wFront0 = trk[idxFront0]->Wire();
1130 int wBack0 = trk[idxBack0]->Wire();
1132 int wFront1 = trk[idxFront1]->Wire();
1133 int wBack1 = trk[idxBack1]->Wire();
1135 wiresFront[i].first = wFront0;
1136 wiresFront[i].second = wFront0 - wFront1;
1137 xFront[i] = detProp.
ConvertTicksToX(trk[idxFront0]->PeakTime(), i, tpc, cryo);
1139 wiresBack[i].first = wBack0;
1140 wiresBack[i].second = wBack0 - wBack1;
1141 xBack[i] = detProp.
ConvertTicksToX(trk[idxBack0]->PeakTime(), i, tpc, cryo);
1143 if (wiresFront[i].
second) {
1144 if (wiresFront[i].second > 0)
1145 wiresFront[i].second = 1;
1147 wiresFront[i].second = -1;
1149 frontPresent =
true;
1153 if (wiresBack[i].second) {
1154 if (wiresBack[i].second > 0)
1155 wiresBack[i].second = 1;
1157 wiresBack[i].second = -1;
1165 if (!frontPresent) { wiresFront[i].first = -1; }
1166 if (!backPresent) { wiresBack[i].first = -1; }
1169 bool refAdded =
false;
1170 if ((nPlanesFront > 1) && (fabs(dirFrontXZ.Z()) >= maxCosXZ)) {
1174 if ((nPlanesBack > 1) && (fabs(dirBackXZ.Z()) >= maxCosXZ)) {
1178 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
"guide wire-plane-parallel track endpoints";
1191 const double maxCosXZ = 0.992546;
1193 unsigned int tpc, cryo;
1207 if (seg1 && (seg0->
Length() < 0.8) && (seg1->
Length() > 5.0)) { seg0 = seg1; }
1210 dir0XZ *= 1.0 / dir0XZ.R();
1212 if (fabs(dir0XZ.Z()) < maxCosXZ) {
return; }
1214 unsigned int nPlanes = 0;
1215 std::pair<int, int> wires[3];
1218 for (
unsigned int i = 0; i < 3; i++) {
1221 int idx0 = -1, idx1 = -1;
1227 if ((idx0 >= 0) && (idx0 < (int)trk.
size()) && (trk[idx0]->TPC() == tpc) &&
1228 (trk[idx0]->Cryo() == cryo)) {
1234 if ((idx1 >= 0) && (idx1 < (
int)trk.
size()) && (trk[idx1]->TPC() == tpc) &&
1235 (trk[idx1]->Cryo() == cryo)) {
1236 int w0 = trk[idx0]->Wire();
1237 int w1 = trk[idx1]->Wire();
1239 wires[i].first = w0;
1240 wires[i].second = w0 - w1;
1244 if (wires[i].second > 0)
1245 wires[i].second = 1;
1247 wires[i].second = -1;
1255 if (!present) { wires[i].first = -1; }
1258 if ((nPlanes > 1) && (fabs(dir0XZ.Z()) >= maxCosXZ) &&
1260 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
"guide wire-plane-parallel track endpoint";
1279 double dist = distFF;
1282 if (distFB < dist) {
1288 if (distBF < dist) {
1294 if (distBB < dist) {
1304 case 1:
mf::LogError(
"PMAlgTrackMaker") <<
"Tracks in reversed order.";
return false;
1311 <<
"alignTracks: should never happen." << std::endl;
1319 bool const reopt)
const 1325 double lmean = dst.
Length() / (dst.
Nodes().size() - 1);
1326 if ((
pma::Dist2(dst.
Nodes().back()->Point3D(), src.
Nodes().front()->Point3D()) > 0.5 * lmean) ||
1328 dst.
AddNode(detProp, src.
Nodes().front()->Point3D(), tpc, cryo);
1329 if (src.
Nodes().front()->IsFrozen()) dst.
Nodes().back()->SetFrozen(
true);
1331 for (
size_t n = 1;
n < src.
Nodes().size();
n++) {
1338 for (
size_t h = 0; h < src.
size(); h++) {
1339 dst.
push_back(detProp, src[h]->Hit2DPtr());
1343 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" reopt after merging done, g = " << g;
1359 unsigned int* nused)
const 1361 for (
size_t i = 0; i < trk.
size(); i++) {
1363 if (hit->
View2D() == view) {
1372 unsigned int nhits = 0;
1373 double last_x, dx = 0.0, last_q, dq = 0.0, dqdx = 0.0;
1374 int ih = trk.
NextHit(-1, view);
1379 if ((ih >= 0) && (ih < (
int)trk.
size())) {
1383 while ((dx < 2.5) && (ih >= 0) && (ih < (
int)trk.
size())) {
1391 if (dx + last_x < 3.0) {
1402 while ((ih >= 0) && (ih < (
int)trk.
size())) {
1409 mf::LogError(
"ProjectionMatchingAlg") <<
"Initial part selection failed.";
1413 mf::LogError(
"ProjectionMatchingAlg") <<
"Initial part too short to select useful hits.";
1416 if (dx > 0.0) dqdx = dq / dx;
1418 if (nused) (*nused) = nhits;
bool SelectHits(float fraction=1.0F)
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
pma::Track3D * buildTrack(const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &hits_1, const std::vector< art::Ptr< recob::Hit >> &hits_2={}) const
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 addEndpointRef_(const detinfo::DetectorPropertiesData &detProp, pma::Track3D &trk, const std::map< unsigned int, std::vector< art::Ptr< recob::Hit >>> &hits, std::pair< int, int > const *wires, double const *xPos, unsigned int tpc, unsigned int cryo) const
Length_t WireCoordinate(Point_t const &pos, PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
Functions to help with numbers.
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.
constexpr to_element_t to_element
bool Has_(const std::vector< size_t > &v, size_t idx) const
double Dist2(const TVector2 &p2d, unsigned int view, unsigned int tpc, unsigned int cryo) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
bool HasWire(WireID const &wireid) const
Returns whether we have the specified wire.
double const fMinTwoViewFraction
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
double GetXTicksCoefficient(int t, int c) const
pma::Track3D * extendTrack(const detinfo::DetectorPropertiesData &clockData, 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.
static void SetOptFactor(unsigned int view, float value)
geo::GeometryCore const * fGeom
pma::Hit3D const * front() const
Implementation of the Projection Matching Algorithm.
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
::geo::Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
TVector3 const & Point3D() const
CryostatID_t Cryostat
Index of cryostat.
bool Initialize(detinfo::DetectorPropertiesData const &detProp, float initEndSegW=0.05F)
Planes which measure Z direction.
void TagOutlier(bool state) noexcept
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.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
static void SetMargin(double m)
Set allowed node position margin around TPC.
static size_t getSegCount_(size_t trk_size)
unsigned int Plane() const
unsigned int Wire() const noexcept
unsigned int BackTPC() const
recob::tracking::Vector_t Vector3D
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 const fFineTuningEps
void AddRefPoint(const TVector3 &p)
bool GetCloseHits_(const detinfo::DetectorPropertiesData &detProp, double r2d, const std::vector< art::Ptr< recob::Hit >> &hits_in, std::vector< size_t > &used, std::vector< art::Ptr< recob::Hit >> &hits_out) const
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
unsigned int BackCryo() const
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
double selectInitialHits(pma::Track3D &trk, unsigned int view=geo::kZ, unsigned int *nused=0) const
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
void AddNode(pma::Node3D *node)
pma::Hit3D * release_at(size_t index)
unsigned int NHits(unsigned int view) const
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
bool alignTracks(pma::Track3D &first, pma::Track3D &second) const
double const fTrkValidationDist2D
void SetEndSegWeight(float value) noexcept
std::vector< pma::Segment3D * > const & Segments() const noexcept
double validate_on_adc_test(const detinfo::DetectorPropertiesData &detProp, const lariov::ChannelStatusProvider &channelStatus, const pma::Track3D &trk, const img::DataProviderAlg &adcImage, const std::vector< art::Ptr< recob::Hit >> &hits, TH1F *histoPassing, TH1F *histoRejected) const
void FilterOutSmallParts(const detinfo::DetectorPropertiesData &detProp, double r2d, const std::vector< art::Ptr< recob::Hit >> &hits_in, std::vector< art::Ptr< recob::Hit >> &hits_out, const TVector2 &vtx2d) const
double ConvertXToTicks(double X, int p, int t, int c) const
float SummedADC() const noexcept
double const fHitTestingDist2D
double const fOptimizationEps
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
unsigned int FrontTPC() const
unsigned int FrontCryo() const
pma::Track3D * buildSegment(const detinfo::DetectorPropertiesData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits_1, const std::vector< art::Ptr< recob::Hit >> &hits_2={}) const
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
unsigned int DisableSingleViewEnds()
float GetSegFraction() const noexcept
Detector simulation of raw signals on wires.
double ConvertTicksToX(double ticks, int p, int t, int c) const
void push_back(pma::Hit3D *hit)
unsigned int View2D() const noexcept
CryostatID PositionToCryostatID(Point_t const &point) const
Returns the ID of the cryostat at specified location.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
bool HasTwoViews(size_t nmin=1) const
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
double Length(size_t step=1) const
bool IsFrozen(void) const
Check if the vertex 3D position is fixed.
double validate(const detinfo::DetectorPropertiesData &detProp, const lariov::ChannelStatusProvider &channelStatus, const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit >> &hits) const
void ShortenSeg_(const detinfo::DetectorPropertiesData &detProp, pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
bool chkEndpointHits_(const detinfo::DetectorPropertiesData &detProp, int wire, int wdir, double drift_x, int view, unsigned int tpc, unsigned int cryo, const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit >> &hits) const
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
pma::Track3D * buildShowerSeg(const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, const pma::Vector3D &vtx) const
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
void mergeTracks(const detinfo::DetectorPropertiesData &detProp, pma::Track3D &dst, pma::Track3D &src, bool reopt) const
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of this segment.
constexpr auto absDiff(A const &a, B const &b)
Returns the absolute value of the difference between two values.
double GetDistToProj() const
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
ProjectionMatchingAlg(const Config &config)
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
void guideEndpoints(const detinfo::DetectorPropertiesData &clockData, pma::Track3D &trk, const std::map< unsigned int, std::vector< art::Ptr< recob::Hit >>> &hits) const
pma::Hit3D const * back() const
std::vector< pma::Hit3D * > trimTrackToVolume(pma::Track3D &trk, TVector3 p0, TVector3 p1) const
double validate_on_adc(const detinfo::DetectorPropertiesData &detProp, const lariov::ChannelStatusProvider &channelStatus, const pma::Track3D &trk, const img::DataProviderAlg &adcImage, float thr) const
double HitDxByView(size_t index, unsigned int view) const
std::vector< pma::Node3D * > const & Nodes() const noexcept
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
2D representation of charge deposited in the TDC/wire plane
fhicl::Atom< double > OptimizationEps
bool IntersectionPoint(WireID const &wid1, WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
float poolMax(int wire, int drift, size_t r=0) const
Pool max value in a patch around the wire/drift pixel.
TPCID_t TPC
Index of the TPC within its cryostat.
second_as<> second
Type of time stored in seconds, in double precision.
recob::tracking::Plane Plane
void RemoveNotEnabledHits(pma::Track3D &trk) const
double twoViewFraction(pma::Track3D &trk) const
bool HasTPC(TPCID const &tpcid) const
Returns whether we have the specified TPC.
constexpr ProductStatus present() noexcept
double Length(void) const
bool TestTrk_(pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
std::pair< TVector2, TVector2 > WireDriftRange(detinfo::DetectorPropertiesData const &detProp, unsigned int view, unsigned int tpc, unsigned int cryo) const
pma::Track3D * buildMultiTPCTrack(const detinfo::DetectorPropertiesData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits) const