13 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 14 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 22 #include "range/v3/view.hpp" 29 constexpr
double step{0.3};
38 ,
fGeom{lar::providerFrom<geo::Geometry>()}
51 const lariov::ChannelStatusProvider& channelStatus,
54 float const thr)
const 56 unsigned int nAll = 0, nPassed = 0;
57 unsigned int testPlane = adcImage.
Plane();
59 std::vector<unsigned int> trkTPCs = trk.
TPCs();
60 std::vector<unsigned int> trkCryos = trk.
Cryos();
66 for (
auto const* seg : trk.
Segments()) {
77 unsigned tpc = seg->
TPC();
78 unsigned cryo = seg->Cryo();
83 while ((f < 1.0) && node->
SameTPC(p)) {
88 int widx = (int)p2d.X();
93 if (channelStatus.IsGood(ch)) {
94 float max_adc = adcImage.
poolMax(widx, didx, 2);
95 if (max_adc > thr) nPassed++;
110 double v = nPassed / (double)nAll;
119 struct hits_on_plane {
121 unsigned int const plane_;
129 const lariov::ChannelStatusProvider& channelStatus,
134 TH1F* histoRejected)
const 137 double const max_d2 = max_d * max_d;
138 unsigned int nAll = 0, nPassed = 0;
139 unsigned int testPlane = adcImage.
Plane();
141 std::vector<unsigned int> trkTPCs = trk.
TPCs();
142 std::vector<unsigned int> trkCryos = trk.
Cryos();
143 std::map<std::pair<unsigned int, unsigned int>, std::pair<TVector2, TVector2>>
ranges;
144 std::map<std::pair<unsigned int, unsigned int>,
double> wirePitch;
145 for (
auto const& [t, c] : views::cartesian_product(trkTPCs, trkCryos)) {
150 unsigned int tpc, cryo;
151 std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
154 hits | views::transform(
to_element) | views::filter(hits_on_plane{testPlane})) {
155 tpc = h.WireID().TPC;
156 cryo = h.WireID().Cryostat;
157 std::pair<unsigned int, unsigned int> tpc_cryo(tpc, cryo);
158 std::pair<TVector2, TVector2> rect = ranges[tpc_cryo];
160 if ((h.WireID().Wire > rect.first.X() - 10) &&
161 (h.WireID().Wire < rect.second.X() + 10) &&
162 (h.PeakTime() > rect.first.Y() - 100) &&
163 (h.PeakTime() < rect.second.Y() + 100)) {
164 TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
167 double const d2 = trk.
Dist2(p2d, testPlane, tpc, cryo);
169 if (d2 < max_d2) { all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y()); }
177 for (
auto const* seg : trk.
Segments()) {
193 auto const& points = all_close_points[{tpc, cryo}];
199 while ((f < 1.0) && node->
SameTPC(p)) {
201 geo::WireID const wireID{planeID,
static_cast<unsigned int>(p2d.X())};
203 int widx = (int)p2d.X();
208 if (channelStatus.IsGood(ch)) {
209 bool is_close =
false;
210 float max_adc = adcImage.
poolMax(widx, didx, 2);
213 p2d.SetX(wirepitch * p2d.X());
214 for (
const auto& h : points) {
226 if (histoPassing) histoPassing->Fill(max_adc);
229 if (histoRejected) histoRejected->Fill(max_adc);
241 double v = nPassed / (double)nAll;
252 const lariov::ChannelStatusProvider& channelStatus,
256 if (
hits.empty()) {
return 0; }
259 double const max_d2 = max_d * max_d;
260 unsigned int nAll = 0, nPassed = 0;
261 unsigned int testPlane =
hits.front()->WireID().Plane;
263 std::vector<unsigned int> trkTPCs = trk.
TPCs();
264 std::vector<unsigned int> trkCryos = trk.
Cryos();
265 std::map<std::pair<unsigned int, unsigned int>, std::pair<TVector2, TVector2>>
ranges;
266 std::map<std::pair<unsigned int, unsigned int>,
double> wirePitch;
267 for (
auto const& [t, c] : views::cartesian_product(trkTPCs, trkCryos)) {
272 unsigned int tpc, cryo;
273 std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
276 hits | views::transform(
to_element) | views::filter(hits_on_plane{testPlane})) {
277 tpc = h.WireID().TPC;
278 cryo = h.WireID().Cryostat;
279 std::pair<unsigned int, unsigned int> tpc_cryo(tpc, cryo);
280 std::pair<TVector2, TVector2> rect = ranges[tpc_cryo];
282 if ((h.WireID().Wire > rect.first.X() - 10) &&
283 (h.WireID().Wire < rect.second.X() + 10) &&
284 (h.PeakTime() > rect.first.Y() - 100) &&
285 (h.PeakTime() < rect.second.Y() + 100)) {
286 TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
289 double const d2 = trk.
Dist2(p2d, testPlane, tpc, cryo);
291 if (d2 < max_d2) all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y());
299 for (
auto const* seg : trk.
Segments()) {
315 auto const& points = all_close_points[{tpc, cryo}];
321 double const wirepitch = plane.
WirePitch();
322 while ((f < 1.0) && node->
SameTPC(p)) {
324 geo::WireID const wireID{planeID,
static_cast<unsigned int>(p2d.X())};
327 if (channelStatus.IsGood(ch)) {
329 p2d.SetX(wirepitch * p2d.X());
330 for (
const auto& h : points) {
348 double v = nPassed / (double)nAll;
358 const lariov::ChannelStatusProvider& channelStatus,
362 unsigned int testPlane,
364 unsigned int cryo)
const 367 double d2, max_d2 = max_d * max_d;
368 unsigned int nAll = 0, nPassed = 0;
373 dc *= step / dc.Mag();
383 if (channelStatus.IsGood(ch)) {
384 p2d.Set(wirepitch * p2d.X(), p2d.Y());
385 for (
const auto& h :
hits)
386 if ((h->WireID().Plane == testPlane) && (h->WireID().TPC == tpc) &&
387 (h->WireID().Cryostat == cryo)) {
406 double v = nPassed / (double)nAll;
407 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" segment fraction ok: " << v;
421 while ((idx < trk.
size() - 1) && !trk[idx]->IsEnabled())
423 double l0 = trk.
Length(0, idx + 1);
425 idx = trk.
size() - 1;
426 while ((idx > 1) && !trk[idx]->IsEnabled())
428 double l1 = trk.
Length(idx - 1, trk.
size() - 1);
432 return 1.0 - (l0 + l1) / trk.
Length();
438 int const nSegments = 0.8 * trk_size / sqrt(trk_size);
439 return std::max(
size_t{1},
static_cast<size_t>(nSegments));
453 std::vector<unsigned int> tpcs = trk->
TPCs();
454 for (
size_t t = 0; t < tpcs.size(); ++t) {
462 size_t nNodes = (size_t)(nSegments - 1);
466 mf::LogWarning(
"ProjectionMatchingAlg") <<
" initialization failed, delete trk";
474 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" optimize trk (" << nSegments <<
" seg)";
488 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" clusters do not match, f = " <<
f;
499 std::map<unsigned int, std::vector<art::Ptr<recob::Hit>>> hits_by_tpc;
500 for (
auto const& h :
hits) {
501 hits_by_tpc[h->WireID().TPC].push_back(h);
504 std::vector<pma::Track3D*> tracks;
505 for (
auto const& hsel : hits_by_tpc) {
507 if (trk) tracks.push_back(trk);
510 bool need_reopt =
false;
511 while (tracks.size() > 1) {
516 double d, dmin = 1.0e12;
517 size_t t_best = 0, cfg = 0;
518 for (
size_t t = 1; t < tracks.size(); ++t) {
569 tracks.erase(tracks.begin() + t_best);
576 if (!tracks.empty()) {
577 trk = tracks.front();
581 <<
" reopt after merging initial tpc segments: done, g = " << g;
588 size_t nNodes = (size_t)(nSegments - 1);
590 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" optimize trk (add " << nSegments <<
" seg)";
616 TVector3 vtxv3(vtx.X(), vtx.Y(), vtx.Z());
623 std::vector<art::Ptr<recob::Hit>> hitstpc;
624 for (
size_t h = 0; h <
hits.size(); ++h)
627 if (!hitstpc.size())
return 0;
629 std::vector<art::Ptr<recob::Hit>> hitstrk;
631 size_t countviews = 0;
633 mf::LogVerbatim(
"ProjectionMatchinAlg") <<
"collecting hits from view: " << view;
640 std::vector<art::Ptr<recob::Hit>> hitsview;
641 for (
size_t h = 0; h < hitstpc.size(); ++h)
642 if (hitstpc[h]->
WireID().Plane == view) hitsview.push_back(hitstpc[h]);
643 if (!hitsview.size()) {
649 std::vector<art::Ptr<recob::Hit>> hitsfilter;
656 for (
size_t h = 0; h < hitsfilter.size(); ++h)
657 hitstrk.push_back(hitsfilter[h]);
659 if (hitsfilter.size() >= 5) countviews++;
664 if (!hitstrk.size() || (countviews < 2)) {
665 mf::LogWarning(
"ProjectionMatchinAlg") <<
"too few hits, segment not built";
677 if (trk->
size() < 10) {
678 mf::LogWarning(
"ProjectionMatchingAlg") <<
"too short segment, delete segment";
693 const TVector2& vtx2d)
const 695 size_t min_size = hits_in.size() / 5;
696 if (min_size < 3) min_size = 3;
698 std::vector<size_t> used;
699 std::vector<std::vector<art::Ptr<recob::Hit>>> sub_groups;
700 std::vector<art::Ptr<recob::Hit>> close_hits;
702 float mindist2 = 99999.99;
703 size_t id_sub_groups_save = 0;
705 while (
GetCloseHits_(detProp, r2d, hits_in, used, close_hits)) {
707 sub_groups.emplace_back(close_hits);
709 for (
size_t h = 0; h < close_hits.size(); ++h) {
711 close_hits[h]->
WireID().Wire,
712 close_hits[h]->PeakTime(),
714 close_hits[h]->
WireID().TPC,
715 close_hits[h]->
WireID().Cryostat);
718 if (dist2 < mindist2) {
719 id_sub_groups_save = id;
727 for (
size_t i = 0; i < sub_groups.size(); ++i) {
728 if (i == id_sub_groups_save) {
729 for (
auto h : sub_groups[i])
730 hits_out.push_back(h);
734 for (
size_t i = 0; i < sub_groups.size(); ++i) {
735 if ((i != id_sub_groups_save) && (hits_out.size() < 10) && (sub_groups[i].
size() > min_size))
736 for (
auto h : sub_groups[i])
737 hits_out.push_back(h);
746 std::vector<size_t>& used,
751 const double gapMargin = 5.0;
754 while ((idx < hits_in.size()) &&
Has_(used, idx))
757 if (idx < hits_in.size()) {
758 hits_out.push_back(hits_in[idx]);
761 unsigned int tpc = hits_in[idx]->WireID().TPC;
762 unsigned int cryo = hits_in[idx]->WireID().Cryostat;
763 unsigned int view = hits_in[idx]->WireID().Plane;
767 double r2d2 = r2d * r2d;
768 double gapMargin2 = sqrt(2 * gapMargin * gapMargin);
769 gapMargin2 = (gapMargin2 + r2d) * (gapMargin2 + r2d);
774 for (
size_t i = 0; i < hits_in.size(); i++)
775 if (!
Has_(used, i)) {
781 for (
auto const& ho : hits_out) {
783 TVector2 ho_cm(wirePitch * ho->WireID().Wire, driftPitch * ho->PeakTime());
793 hits_out.push_back(hi);
810 double mse = trk.
GetMse();
811 mf::LogWarning(
"ProjectionMatchingAlg") <<
"initial value of mse: " << mse;
812 while ((mse > 0.5) &&
TestTrk_(trk, tpcgeom)) {
814 for (
size_t h = 0; h < trk.
size(); ++h)
816 trk[h]->SetEnabled(
false);
820 trk.
Optimize(detProp, 0, 0.0001,
false);
824 if (mse == trk.
GetMse())
break;
838 auto has_plane = [
this, &
id = tpcgeom.
ID()](
unsigned int plane) {
842 if (has_plane(0) && has_plane(1)) {
845 else if (has_plane(0) && has_plane(2)) {
848 else if (has_plane(1) && has_plane(2)) {
853 for (
size_t h = 0; h < trk.
size(); ++h) {
854 if (!trk[h]->IsEnabled())
break;
858 mf::LogWarning(
"ProjectionMatchingAlg") <<
"length of segment: " << length;
859 if (length < 3.0) test =
false;
869 if (c == idx)
return true;
878 while (h < trk.
size()) {
879 if (trk[h]->IsEnabled())
901 mf::LogWarning(
"ProjectionMatchingAlg") <<
"initialization failed, delete segment";
911 mf::LogWarning(
"ProjectionMatchingAlg") <<
"need at least two views in single tpc";
929 if (dfront > dback) trk->
Flip();
931 trk->
Nodes().front()->SetPoint3D({point.X(), point.Y(), point.Z()});
932 trk->
Nodes().front()->SetFrozen(
true);
944 const TVector3& point)
const 951 if (dfront > dback) trk->
Flip();
953 trk->
Nodes().front()->SetPoint3D(point);
954 trk->
Nodes().front()->SetFrozen(
true);
967 bool add_nodes)
const 978 int nNodes = nSegments - copy->
Nodes().size() + 1;
979 if (nNodes < 0) nNodes = 0;
982 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" add " << nNodes <<
" nodes";
1004 size_t nCloseHits = 0;
1005 int forwWires = 3, backWires = -1;
1006 double xMargin = 0.4;
1008 if ((view == (
int)h->WireID().Plane) && (tpc == h->WireID().TPC) &&
1009 (cryo == h->WireID().Cryostat)) {
1011 for (
size_t ht = 0; ht < trk.
size(); ht++)
1012 if (trk[ht]->Hit2DPtr().key() == h.key()) {
1016 if (found)
continue;
1018 int dw = wdir * (h->WireID().Wire - wire);
1019 if ((dw <= forwWires) && (dw >= backWires)) {
1021 if (fabs(x - drift_x) < xMargin) nCloseHits++;
1034 std::pair<int, int>
const* wires,
1037 unsigned int cryo)
const 1040 std::vector<std::pair<int, unsigned int>> wire_view;
1041 for (
unsigned int i = 0; i < 3; i++)
1042 if (wires[i].first >= 0) {
1043 const auto hiter =
hits.find(i);
1044 if (hiter !=
hits.end()) {
1055 wire_view.emplace_back(wires[i].first, i);
1059 if (wire_view.size() > 1) {
1060 x /= wire_view.size();
1061 auto const [wire0, plane0] = wire_view[0];
1062 auto const [wire1, plane1] = wire_view[1];
1070 <<
"trk tpc:" << tpc <<
" size:" << trk.
size() <<
" add ref.point (" << x <<
"; " <<
y <<
"; " 1076 <<
"trk tpc:" << tpc <<
" size:" << trk.
size()
1077 <<
" wire-plane-parallel track, but need two clean views of endpoint";
1088 mf::LogWarning(
"ProjectionMatchingAlg") <<
"Please, apply before TPC stitching.";
1092 const double maxCosXZ = 0.992546;
1097 if ((segFront->
Length() < 0.8) && (segFront1->
Length() > 5.0)) segFront = segFront1;
1101 dirFrontXZ *= 1.0 / dirFrontXZ.R();
1106 if ((segBack->
Length() < 0.8) && (segBack1->
Length() > 5.0)) segBack = segBack1;
1110 dirBackXZ *= 1.0 / dirBackXZ.R();
1112 if ((fabs(dirFrontXZ.Z()) < maxCosXZ) && (fabs(dirBackXZ.Z()) < maxCosXZ)) {
1116 unsigned int nPlanesFront = 0, nPlanesBack = 0;
1117 std::pair<int, int> wiresFront[3], wiresBack[3];
1118 double xFront[3], xBack[3];
1120 for (
unsigned int i = 0; i < 3; i++) {
1121 bool frontPresent =
false, backPresent =
false;
1123 int idxFront0 = trk.
NextHit(-1, i);
1125 if ((idxFront0 >= 0) && (idxFront0 < (int)trk.
size()) && (idxBack0 >= 0) &&
1126 (idxBack0 < (int)trk.
size())) {
1127 int idxFront1 = trk.
NextHit(idxFront0, i);
1128 int idxBack1 = trk.
PrevHit(idxBack0, i);
1129 if ((idxFront1 >= 0) && (idxFront1 < (
int)trk.
size()) && (idxBack1 >= 0) &&
1130 (idxBack1 < (int)trk.
size())) {
1131 int wFront0 = trk[idxFront0]->Wire();
1132 int wBack0 = trk[idxBack0]->Wire();
1134 int wFront1 = trk[idxFront1]->Wire();
1135 int wBack1 = trk[idxBack1]->Wire();
1137 wiresFront[i].first = wFront0;
1138 wiresFront[i].second = wFront0 - wFront1;
1139 xFront[i] = detProp.
ConvertTicksToX(trk[idxFront0]->PeakTime(), i, tpc, cryo);
1141 wiresBack[i].first = wBack0;
1142 wiresBack[i].second = wBack0 - wBack1;
1143 xBack[i] = detProp.
ConvertTicksToX(trk[idxBack0]->PeakTime(), i, tpc, cryo);
1145 if (wiresFront[i].
second) {
1146 if (wiresFront[i].second > 0)
1147 wiresFront[i].second = 1;
1149 wiresFront[i].second = -1;
1151 frontPresent =
true;
1155 if (wiresBack[i].second) {
1156 if (wiresBack[i].second > 0)
1157 wiresBack[i].second = 1;
1159 wiresBack[i].second = -1;
1167 if (!frontPresent) { wiresFront[i].first = -1; }
1168 if (!backPresent) { wiresBack[i].first = -1; }
1171 bool refAdded =
false;
1172 if ((nPlanesFront > 1) && (fabs(dirFrontXZ.Z()) >= maxCosXZ)) {
1176 if ((nPlanesBack > 1) && (fabs(dirBackXZ.Z()) >= maxCosXZ)) {
1180 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
"guide wire-plane-parallel track endpoints";
1193 const double maxCosXZ = 0.992546;
1195 unsigned int tpc, cryo;
1209 if (seg1 && (seg0->
Length() < 0.8) && (seg1->
Length() > 5.0)) { seg0 = seg1; }
1212 dir0XZ *= 1.0 / dir0XZ.R();
1214 if (fabs(dir0XZ.Z()) < maxCosXZ) {
return; }
1216 unsigned int nPlanes = 0;
1217 std::pair<int, int> wires[3];
1220 for (
unsigned int i = 0; i < 3; i++) {
1223 int idx0 = -1, idx1 = -1;
1229 if ((idx0 >= 0) && (idx0 < (int)trk.
size()) && (trk[idx0]->TPC() == tpc) &&
1230 (trk[idx0]->Cryo() == cryo)) {
1236 if ((idx1 >= 0) && (idx1 < (
int)trk.
size()) && (trk[idx1]->TPC() == tpc) &&
1237 (trk[idx1]->Cryo() == cryo)) {
1238 int w0 = trk[idx0]->Wire();
1239 int w1 = trk[idx1]->Wire();
1241 wires[i].first = w0;
1242 wires[i].second = w0 - w1;
1246 if (wires[i].second > 0)
1247 wires[i].second = 1;
1249 wires[i].second = -1;
1257 if (!present) { wires[i].first = -1; }
1260 if ((nPlanes > 1) && (fabs(dir0XZ.Z()) >= maxCosXZ) &&
1262 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
"guide wire-plane-parallel track endpoint";
1281 double dist = distFF;
1284 if (distFB < dist) {
1290 if (distBF < dist) {
1296 if (distBB < dist) {
1303 case 0: first.
Flip();
break;
1304 case 1:
mf::LogError(
"PMAlgTrackMaker") <<
"Tracks in reversed order.";
return false;
1306 case 3: second.
Flip();
break;
1309 <<
"alignTracks: should never happen." << std::endl;
1317 bool const reopt)
const 1323 double lmean = dst.
Length() / (dst.
Nodes().size() - 1);
1324 if ((
pma::Dist2(dst.
Nodes().back()->Point3D(), src.
Nodes().front()->Point3D()) > 0.5 * lmean) ||
1326 dst.
AddNode(detProp, src.
Nodes().front()->Point3D(), tpc, cryo);
1327 if (src.
Nodes().front()->IsFrozen()) dst.
Nodes().back()->SetFrozen(
true);
1329 for (
size_t n = 1;
n < src.
Nodes().size();
n++) {
1336 for (
size_t h = 0; h < src.
size(); h++) {
1337 dst.
push_back(detProp, src[h]->Hit2DPtr());
1341 mf::LogVerbatim(
"ProjectionMatchingAlg") <<
" reopt after merging done, g = " << g;
1357 unsigned int* nused)
const 1359 for (
size_t i = 0; i < trk.
size(); i++) {
1361 if (hit->
View2D() == view) {
1370 unsigned int nhits = 0;
1371 double last_x, dx = 0.0, last_q, dq = 0.0, dqdx = 0.0;
1372 int ih = trk.
NextHit(-1, view);
1377 if ((ih >= 0) && (ih < (
int)trk.
size())) {
1381 while ((dx < 2.5) && (ih >= 0) && (ih < (
int)trk.
size())) {
1389 if (dx + last_x < 3.0) {
1400 while ((ih >= 0) && (ih < (
int)trk.
size())) {
1407 mf::LogError(
"ProjectionMatchingAlg") <<
"Initial part selection failed.";
1411 mf::LogError(
"ProjectionMatchingAlg") <<
"Initial part too short to select useful hits.";
1414 if (dx > 0.0) dqdx = dq / dx;
1416 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 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
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)
double const fMinTwoViewFraction
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
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
bool HasWire(WireID const &wireid) const
Returns whether we have the specified wire.
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).
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)
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
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
bool HasPlane(PlaneID const &planeid) const
Returns whether we have the specified plane.
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
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.
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
virtual raw::ChannelID_t PlaneWireToChannel(WireID const &wireID) const =0
Returns the channel ID a wire is connected to.
float SummedADC() const noexcept
double const fHitTestingDist2D
double const fOptimizationEps
Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
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.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two 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.
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
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.
geo::WireReadoutGeom const * fWireReadoutGeom
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
static constexpr WireIDIntersection invalid()
std::vector< pma::Node3D * > const & Nodes() const noexcept
2D representation of charge deposited in the TDC/wire plane
fhicl::Atom< double > OptimizationEps
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
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.
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
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
TPCID const & ID() const
Returns the identifier of this TPC.
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