LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
pma::ProjectionMatchingAlg Class Reference

#include "ProjectionMatchingAlg.h"

Classes

struct  Config
 

Public Member Functions

 ProjectionMatchingAlg (const Config &config)
 
 ProjectionMatchingAlg (const fhicl::ParameterSet &pset)
 
double validate_on_adc (const detinfo::DetectorPropertiesData &detProp, const lariov::ChannelStatusProvider &channelStatus, const pma::Track3D &trk, const img::DataProviderAlg &adcImage, float thr) const
 
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
 
double validate (const detinfo::DetectorPropertiesData &detProp, const lariov::ChannelStatusProvider &channelStatus, const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit >> &hits) const
 
double validate (const detinfo::DetectorPropertiesData &detProp, const lariov::ChannelStatusProvider &channelStatus, const TVector3 &p0, const TVector3 &p1, const std::vector< art::Ptr< recob::Hit >> &hits, unsigned int testView, unsigned int tpc, unsigned int cryo) const
 
double twoViewFraction (pma::Track3D &trk) const
 
unsigned int testHits (detinfo::DetectorPropertiesData const &detProp, 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. More...
 
bool isContained (const pma::Track3D &trk, float margin=0.0F) const
 
pma::Track3DbuildTrack (const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &hits_1, const std::vector< art::Ptr< recob::Hit >> &hits_2={}) const
 
pma::Track3DbuildMultiTPCTrack (const detinfo::DetectorPropertiesData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits) const
 
pma::Track3DbuildShowerSeg (const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, const pma::Vector3D &vtx) const
 
pma::Track3DbuildSegment (const detinfo::DetectorPropertiesData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits_1, const std::vector< art::Ptr< recob::Hit >> &hits_2={}) const
 
pma::Track3DbuildSegment (const detinfo::DetectorPropertiesData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits_1, const std::vector< art::Ptr< recob::Hit >> &hits_2, const geo::Point_t &point) const
 
pma::Track3DbuildSegment (const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, const TVector3 &point) 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
 
void RemoveNotEnabledHits (pma::Track3D &trk) const
 
pma::Track3DextendTrack (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. More...
 
void guideEndpoints (const detinfo::DetectorPropertiesData &clockData, pma::Track3D &trk, const std::map< unsigned int, std::vector< art::Ptr< recob::Hit >>> &hits) const
 
void guideEndpoints (const detinfo::DetectorPropertiesData &clockData, pma::Track3D &trk, pma::Track3D::ETrackEnd endpoint, const std::map< unsigned int, std::vector< art::Ptr< recob::Hit >>> &hits) const
 Add 3D reference points to clean endpoint of a track. More...
 
std::vector< pma::Hit3D * > trimTrackToVolume (pma::Track3D &trk, TVector3 p0, TVector3 p1) const
 
bool alignTracks (pma::Track3D &first, pma::Track3D &second) const
 
void mergeTracks (const detinfo::DetectorPropertiesData &detProp, pma::Track3D &dst, pma::Track3D &src, bool reopt) const
 
void autoFlip (pma::Track3D &trk, pma::Track3D::EDirection dir=Track3D::kForward, double thr=0.0, unsigned int n=0) const
 
double selectInitialHits (pma::Track3D &trk, unsigned int view=geo::kZ, unsigned int *nused=0) const
 

Private Member Functions

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
 
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
 
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
 
bool Has_ (const std::vector< size_t > &v, size_t idx) const
 
void ShortenSeg_ (const detinfo::DetectorPropertiesData &detProp, pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
 
bool TestTrk_ (pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
 

Static Private Member Functions

static size_t getSegCount_ (size_t trk_size)
 

Private Attributes

double const fOptimizationEps
 
double const fFineTuningEps
 
double const fTrkValidationDist2D
 
double const fHitTestingDist2D
 
double const fMinTwoViewFraction
 
geo::GeometryCore const * fGeom
 
geo::WireReadoutGeom const * fWireReadoutGeom
 

Detailed Description

Definition at line 57 of file ProjectionMatchingAlg.h.

Constructor & Destructor Documentation

pma::ProjectionMatchingAlg::ProjectionMatchingAlg ( const Config config)

Definition at line 32 of file ProjectionMatchingAlg.cxx.

References fFineTuningEps, fGeom, fHitTestingDist2D, fMinTwoViewFraction, fTrkValidationDist2D, fWireReadoutGeom, Get, geo::kU, geo::kV, geo::kZ, pma::ProjectionMatchingAlg::Config::OptimizationEps, pma::Node3D::SetMargin(), and pma::Element3D::SetOptFactor().

33  : fOptimizationEps{config.OptimizationEps()}
34  , fFineTuningEps{config.FineTuningEps()}
35  , fTrkValidationDist2D{config.TrkValidationDist2D()}
36  , fHitTestingDist2D{config.HitTestingDist2D()}
37  , fMinTwoViewFraction{config.MinTwoViewFraction()}
38  , fGeom{lar::providerFrom<geo::Geometry>()}
40 {
41  pma::Node3D::SetMargin(config.NodeMargin3D());
42 
43  pma::Element3D::SetOptFactor(geo::kU, config.HitWeightU());
44  pma::Element3D::SetOptFactor(geo::kV, config.HitWeightV());
45  pma::Element3D::SetOptFactor(geo::kZ, config.HitWeightZ());
46 }
static void SetOptFactor(unsigned int view, float value)
Definition: PmaElement3D.h:113
geo::GeometryCore const * fGeom
Planes which measure V.
Definition: geo_types.h:132
Planes which measure Z direction.
Definition: geo_types.h:134
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
static void SetMargin(double m)
Set allowed node position margin around TPC.
Definition: PmaNode3D.h:121
Planes which measure U.
Definition: geo_types.h:131
geo::WireReadoutGeom const * fWireReadoutGeom
pma::ProjectionMatchingAlg::ProjectionMatchingAlg ( const fhicl::ParameterSet pset)
inline

Definition at line 97 of file ProjectionMatchingAlg.h.

References hits(), and lar::dump::vector().

99  {}
ProjectionMatchingAlg(const Config &config)

Member Function Documentation

bool pma::ProjectionMatchingAlg::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
private

Definition at line 1030 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::AddRefPoint(), chkEndpointHits_(), fWireReadoutGeom, hits(), geo::WireIDIntersection::invalid(), pma::Track3D::size(), geo::WireReadoutGeom::WireIDsIntersect(), x, y, and z.

Referenced by guideEndpoints().

1038 {
1039  double x = 0.0;
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()) {
1045  if (chkEndpointHits_(detProp,
1046  wires[i].first,
1047  wires[i].second,
1048  xPos[i],
1049  i,
1050  tpc,
1051  cryo,
1052  trk,
1053  hiter->second)) {
1054  x += xPos[i];
1055  wire_view.emplace_back(wires[i].first, i);
1056  }
1057  }
1058  }
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];
1063  auto const [y, z, _] = fWireReadoutGeom
1064  ->WireIDsIntersect(geo::WireID(cryo, tpc, plane0, wire0),
1065  geo::WireID(cryo, tpc, plane1, wire1))
1066  .value_or(geo::WireIDIntersection::invalid());
1067 
1068  trk.AddRefPoint(x, y, z);
1069  mf::LogVerbatim("ProjectionMatchingAlg")
1070  << "trk tpc:" << tpc << " size:" << trk.size() << " add ref.point (" << x << "; " << y << "; "
1071  << z << ")";
1072  return true;
1073  }
1074 
1075  mf::LogVerbatim("ProjectionMatchingAlg")
1076  << "trk tpc:" << tpc << " size:" << trk.size()
1077  << " wire-plane-parallel track, but need two clean views of endpoint";
1078  return false;
1079 }
Float_t x
Definition: compare.C:6
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
void AddRefPoint(const TVector3 &p)
Definition: PmaTrack3D.h:218
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two wires.
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
geo::WireReadoutGeom const * fWireReadoutGeom
static constexpr WireIDIntersection invalid()
Definition: geo_types.h:594
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
size_t size() const
Definition: PmaTrack3D.h:89
bool pma::ProjectionMatchingAlg::alignTracks ( pma::Track3D first,
pma::Track3D second 
) const

Flip tracks to get second as a continuation of first; returns false if not possible (tracks in reversed order).

Definition at line 1277 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::back(), larg4::dist(), pma::Dist2(), pma::Track3D::Flip(), pma::Track3D::front(), and pma::Hit3D::Point3D().

Referenced by mergeTracks().

1278 {
1279  unsigned int k = 0;
1280  double const distFF = pma::Dist2(first.front()->Point3D(), second.front()->Point3D());
1281  double dist = distFF;
1282 
1283  double const distFB = pma::Dist2(first.front()->Point3D(), second.back()->Point3D());
1284  if (distFB < dist) {
1285  k = 1;
1286  dist = distFB;
1287  }
1288 
1289  double const distBF = pma::Dist2(first.back()->Point3D(), second.front()->Point3D());
1290  if (distBF < dist) {
1291  k = 2;
1292  dist = distBF;
1293  }
1294 
1295  double distBB = pma::Dist2(first.back()->Point3D(), second.back()->Point3D());
1296  if (distBB < dist) {
1297  k = 3;
1298  dist = distBB;
1299  }
1300 
1301  switch (k) // flip to get dst end before src start, do not merge if track's order reversed
1302  {
1303  case 0: first.Flip(); break;
1304  case 1: mf::LogError("PMAlgTrackMaker") << "Tracks in reversed order."; return false;
1305  case 2: break;
1306  case 3: second.Flip(); break;
1307  default:
1308  throw cet::exception("pma::ProjectionMatchingAlg")
1309  << "alignTracks: should never happen." << std::endl;
1310  }
1311  return true;
1312 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double dist(const TReal *x, const TReal *y, const unsigned int dimension)
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:88
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:527
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void pma::ProjectionMatchingAlg::autoFlip ( pma::Track3D trk,
pma::Track3D::EDirection  dir = Track3D::kForward,
double  thr = 0.0,
unsigned int  n = 0 
) const
inline

Try to correct track direction of the stopping particle: dir: kForward - particle stop is at the end of the track; kBackward - particle stop is at the beginning of the track; dQ/dx difference has to be above thr to actually flip the track; compares dQ/dx of n hits at each end of the track (default is based on the track length).

Definition at line 259 of file ProjectionMatchingAlg.h.

References pma::Track3D::AutoFlip(), dir, hits(), geo::kZ, n, and lar::dump::vector().

263  {
264  trk.AutoFlip(dir, thr, n);
265  };
void AutoFlip(pma::Track3D::EDirection dir, double thr=0.0, unsigned int n=0)
Definition: PmaTrack3D.cxx:662
TDirectory * dir
Definition: macro.C:5
Char_t n[5]
pma::Track3D * pma::ProjectionMatchingAlg::buildMultiTPCTrack ( const detinfo::DetectorPropertiesData clockData,
const std::vector< art::Ptr< recob::Hit >> &  hits 
) const

Build a track from sets of hits, multiple TPCs are OK (like taken from PFParticles), as far as hits origin from at least two wire planes.

Definition at line 495 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::back(), buildSegment(), d, pma::Dist2(), fFineTuningEps, fOptimizationEps, pma::Track3D::front(), getSegCount_(), hits(), mergeTracks(), pma::Track3D::Optimize(), pma::Hit3D::Point3D(), pma::Track3D::Segments(), pma::Track3D::SelectAllHits(), pma::Track3D::size(), and pma::Track3D::SortHits().

Referenced by pma::PMAlgFitter::buildTracks().

498 {
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);
502  }
503 
504  std::vector<pma::Track3D*> tracks;
505  for (auto const& hsel : hits_by_tpc) {
506  pma::Track3D* trk = buildSegment(detProp, hsel.second);
507  if (trk) tracks.push_back(trk);
508  }
509 
510  bool need_reopt = false;
511  while (tracks.size() > 1) {
512  need_reopt = true;
513 
514  pma::Track3D* first = tracks.front();
515  pma::Track3D* best = 0;
516  double d, dmin = 1.0e12;
517  size_t t_best = 0, cfg = 0;
518  for (size_t t = 1; t < tracks.size(); ++t) {
519  pma::Track3D* second = tracks[t];
520 
521  d = pma::Dist2(first->front()->Point3D(), second->front()->Point3D());
522  if (d < dmin) {
523  dmin = d;
524  best = second;
525  t_best = t;
526  cfg = 0;
527  }
528 
529  d = pma::Dist2(first->front()->Point3D(), second->back()->Point3D());
530  if (d < dmin) {
531  dmin = d;
532  best = second;
533  t_best = t;
534  cfg = 1;
535  }
536 
537  d = pma::Dist2(first->back()->Point3D(), second->front()->Point3D());
538  if (d < dmin) {
539  dmin = d;
540  best = second;
541  t_best = t;
542  cfg = 2;
543  }
544 
545  d = pma::Dist2(first->back()->Point3D(), second->back()->Point3D());
546  if (d < dmin) {
547  dmin = d;
548  best = second;
549  t_best = t;
550  cfg = 3;
551  }
552  }
553  if (best) {
554  switch (cfg) {
555  default:
556  case 0:
557  case 1:
558  mergeTracks(detProp, *best, *first, false);
559  tracks[0] = best;
560  delete first;
561  break;
562 
563  case 2:
564  case 3:
565  mergeTracks(detProp, *first, *best, false);
566  delete best;
567  break;
568  }
569  tracks.erase(tracks.begin() + t_best);
570  }
571  else
572  break; // should not happen
573  }
574 
575  pma::Track3D* trk = 0;
576  if (!tracks.empty()) {
577  trk = tracks.front();
578  if (need_reopt) {
579  double g = trk->Optimize(detProp, 0, fOptimizationEps);
580  mf::LogVerbatim("ProjectionMatchingAlg")
581  << " reopt after merging initial tpc segments: done, g = " << g;
582  }
583 
584  int nSegments = getSegCount_(trk->size()) - trk->Segments().size() + 1;
585  if (nSegments > 0) // need to add segments
586  {
587  double g = 0.0;
588  size_t nNodes = (size_t)(nSegments - 1); // n nodes to add
589  if (nNodes) {
590  mf::LogVerbatim("ProjectionMatchingAlg") << " optimize trk (add " << nSegments << " seg)";
591 
592  g = trk->Optimize(detProp, nNodes, fOptimizationEps, false, true, 25,
593  10); // build nodes
594  mf::LogVerbatim("ProjectionMatchingAlg") << " nodes done, g = " << g;
595  trk->SelectAllHits();
596  }
597  g = trk->Optimize(detProp, 0, fFineTuningEps); // final tuning
598  mf::LogVerbatim("ProjectionMatchingAlg") << " tune done, g = " << g;
599  }
600  trk->SortHits();
601  }
602  return trk;
603 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool SelectAllHits()
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
static size_t getSegCount_(size_t trk_size)
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.
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:269
Float_t d
Definition: plot.C:235
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
void mergeTracks(const detinfo::DetectorPropertiesData &detProp, pma::Track3D &dst, pma::Track3D &src, bool reopt) const
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:88
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
size_t size() const
Definition: PmaTrack3D.h:89
pma::Track3D * pma::ProjectionMatchingAlg::buildSegment ( const detinfo::DetectorPropertiesData clockData,
const std::vector< art::Ptr< recob::Hit >> &  hits_1,
const std::vector< art::Ptr< recob::Hit >> &  hits_2 = {} 
) const

Build a straight segment from two sets of hits (they should origin from two wire planes); method is intendet for short tracks or shower initial parts, where only a few hits per plane are available and there is no chance to see a curvature or any other features.

Definition at line 888 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::AddHits(), fFineTuningEps, pma::Track3D::HasTwoViews(), pma::Track3D::Initialize(), pma::Track3D::Optimize(), pma::Track3D::SetEndSegWeight(), pma::Track3D::SortHits(), and pma::Track3D::TPCs().

Referenced by buildMultiTPCTrack(), buildSegment(), buildShowerSeg(), shower::EMShowerAlg::ConstructTrack(), ems::EMShower3D::Make3DSeg(), shower::EMShowerAlg::MakeShower(), ems::EMShower3D::Reoptimize(), and ems::EMShower3D::Validate().

892 {
893  pma::Track3D* trk = new pma::Track3D();
894  trk->SetEndSegWeight(0.001F);
895  trk->AddHits(detProp, hits_1);
896  trk->AddHits(detProp, hits_2);
897 
898  if (trk->HasTwoViews() && (trk->TPCs().size() == 1)) // now only in single tpc
899  {
900  if (!trk->Initialize(detProp, 0.001F)) {
901  mf::LogWarning("ProjectionMatchingAlg") << "initialization failed, delete segment";
902  delete trk;
903  return 0;
904  }
905  trk->Optimize(detProp, 0, fFineTuningEps);
906 
907  trk->SortHits();
908  return trk;
909  }
910  else {
911  mf::LogWarning("ProjectionMatchingAlg") << "need at least two views in single tpc";
912  delete trk;
913  return 0;
914  }
915 }
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
Definition: PmaTrack3D.cxx:404
bool Initialize(detinfo::DetectorPropertiesData const &detProp, float initEndSegW=0.05F)
Definition: PmaTrack3D.cxx:78
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:448
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.
void SetEndSegWeight(float value) noexcept
Definition: PmaTrack3D.h:320
bool HasTwoViews(size_t nmin=1) const
Definition: PmaTrack3D.cxx:439
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
pma::Track3D * pma::ProjectionMatchingAlg::buildSegment ( const detinfo::DetectorPropertiesData clockData,
const std::vector< art::Ptr< recob::Hit >> &  hits_1,
const std::vector< art::Ptr< recob::Hit >> &  hits_2,
const geo::Point_t point 
) const

Build a straight segment from two sets of hits (they should origin from two wire planes), starting from a given point (like vertex known from another algorithm); method is intendet for short tracks or shower initial parts, where only a few hits per plane are available and there is no chance to see a curvature or any other features.

Definition at line 918 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::back(), buildSegment(), pma::Dist2(), fFineTuningEps, pma::Track3D::Flip(), pma::Track3D::front(), pma::Track3D::Nodes(), pma::Track3D::Optimize(), pma::Hit3D::Point3D(), and pma::Track3D::SortHits().

923 {
924  pma::Track3D* trk = buildSegment(detProp, hits_1, hits_2);
925 
926  if (trk) {
927  double dfront = pma::Dist2(trk->front()->Point3D(), point);
928  double dback = pma::Dist2(trk->back()->Point3D(), point);
929  if (dfront > dback) trk->Flip();
930 
931  trk->Nodes().front()->SetPoint3D({point.X(), point.Y(), point.Z()});
932  trk->Nodes().front()->SetFrozen(true);
933  trk->Optimize(detProp, 0, fFineTuningEps);
934 
935  trk->SortHits();
936  }
937  return trk;
938 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
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.
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
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:88
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:274
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:527
pma::Track3D * pma::ProjectionMatchingAlg::buildSegment ( const detinfo::DetectorPropertiesData detProp,
const std::vector< art::Ptr< recob::Hit >> &  hits,
const TVector3 &  point 
) const

Build a straight segment from set of hits (they should origin from two wire planes at least), starting from a given point.

Definition at line 941 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::back(), buildSegment(), pma::Dist2(), fFineTuningEps, pma::Track3D::Flip(), pma::Track3D::front(), hits(), pma::Track3D::Nodes(), pma::Track3D::Optimize(), pma::Hit3D::Point3D(), and pma::Track3D::SortHits().

945 {
946  pma::Track3D* trk = buildSegment(detProp, hits);
947 
948  if (trk) {
949  double dfront = pma::Dist2(trk->front()->Point3D(), point);
950  double dback = pma::Dist2(trk->back()->Point3D(), point);
951  if (dfront > dback) trk->Flip();
952 
953  trk->Nodes().front()->SetPoint3D(point);
954  trk->Nodes().front()->SetFrozen(true);
955  trk->Optimize(detProp, 0, fFineTuningEps);
956 
957  trk->SortHits();
958  }
959  return trk;
960 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
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.
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
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:88
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:274
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:527
pma::Track3D * pma::ProjectionMatchingAlg::buildShowerSeg ( const detinfo::DetectorPropertiesData detProp,
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.

Definition at line 607 of file ProjectionMatchingAlg.cxx.

References buildSegment(), geo::CryostatID::Cryostat, fGeom, FilterOutSmallParts(), geo::GeometryCore::FindTPCAtPosition(), fWireReadoutGeom, pma::GetProjectionToPlane(), geo::WireReadoutGeom::HasPlane(), geo::GeometryCore::HasTPC(), hits(), geo::TPCGeo::ID(), geo::GeometryCore::PositionToCryostatID(), ShortenSeg_(), pma::Track3D::size(), geo::TPCID::TPC, and geo::GeometryCore::TPC().

Referenced by pma::PMAlgFitter::buildShowers().

611 {
612  geo::Point_t const vtxpoint{vtx.X(), vtx.Y(), vtx.Z()};
613 
614  if (!fGeom->HasTPC(fGeom->FindTPCAtPosition(vtxpoint))) return 0;
615 
616  TVector3 vtxv3(vtx.X(), vtx.Y(), vtx.Z());
617 
618  const size_t tpc = fGeom->FindTPCAtPosition(vtxpoint).TPC;
619  const size_t cryo = fGeom->PositionToCryostatID(vtxpoint).Cryostat;
620  const geo::TPCGeo& tpcgeom = fGeom->TPC(geo::TPCID(cryo, tpc));
621 
622  // use only hits from tpc where the vtx is
623  std::vector<art::Ptr<recob::Hit>> hitstpc;
624  for (size_t h = 0; h < hits.size(); ++h)
625  if (hits[h]->WireID().TPC == tpc) hitstpc.push_back(hits[h]);
626 
627  if (!hitstpc.size()) return 0;
628 
629  std::vector<art::Ptr<recob::Hit>> hitstrk;
630  size_t view = 0;
631  size_t countviews = 0;
632  while (view < 3) {
633  mf::LogVerbatim("ProjectionMatchinAlg") << "collecting hits from view: " << view;
634  if (!fWireReadoutGeom->HasPlane(geo::PlaneID(tpcgeom.ID(), view))) {
635  ++view;
636  continue;
637  }
638 
639  // select hits only for a single 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()) {
644  ++view;
645  continue;
646  }
647 
648  // filter our small groups of hits, far from main shower
649  std::vector<art::Ptr<recob::Hit>> hitsfilter;
650  TVector2 proj_pr = pma::GetProjectionToPlane(vtxv3, view, tpc, cryo);
651 
652  mf::LogVerbatim("ProjectionMatchinAlg") << "start filter out: ";
653  FilterOutSmallParts(detProp, 2.0, hitsview, hitsfilter, proj_pr);
654  mf::LogVerbatim("ProjectionMatchingAlg") << "after filter out";
655 
656  for (size_t h = 0; h < hitsfilter.size(); ++h)
657  hitstrk.push_back(hitsfilter[h]);
658 
659  if (hitsfilter.size() >= 5) countviews++;
660 
661  ++view;
662  }
663 
664  if (!hitstrk.size() || (countviews < 2)) {
665  mf::LogWarning("ProjectionMatchinAlg") << "too few hits, segment not built";
666  return 0;
667  }
668 
669  // hits are prepared, finally segment is built
670 
671  pma::Track3D* trk = new pma::Track3D();
672  trk = buildSegment(detProp, hitstrk, vtxv3);
673 
674  // make shorter segment to estimate direction more precise
675  ShortenSeg_(detProp, *trk, tpcgeom);
676 
677  if (trk->size() < 10) {
678  mf::LogWarning("ProjectionMatchingAlg") << "too short segment, delete segment";
679  delete trk;
680  return 0;
681  }
682 
683  return trk;
684 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
geo::GeometryCore const * fGeom
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
Geometry information for a single TPC.
Definition: TPCGeo.h:33
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
bool HasPlane(PlaneID const &planeid) const
Returns whether we have the specified plane.
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
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
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.
Definition: geo_types.h:306
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.
Definition: geo_vectors.h:180
void ShortenSeg_(const detinfo::DetectorPropertiesData &detProp, pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
geo::WireReadoutGeom const * fWireReadoutGeom
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:263
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:315
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:448
size_t size() const
Definition: PmaTrack3D.h:89
TPCID const & ID() const
Returns the identifier of this TPC.
Definition: TPCGeo.h:147
bool HasTPC(TPCID const &tpcid) const
Returns whether we have the specified TPC.
Definition: GeometryCore.h:429
pma::Track3D * pma::ProjectionMatchingAlg::buildTrack ( const detinfo::DetectorPropertiesData detProp,
const std::vector< art::Ptr< recob::Hit >> &  hits_1,
const std::vector< art::Ptr< recob::Hit >> &  hits_2 = {} 
) const

Build a track from two sets of hits from single TPC, hits should origin from at least two wire planes; number of segments used to create the track depends on the number of hits.

Definition at line 443 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::AddHits(), f, fFineTuningEps, fMinTwoViewFraction, fOptimizationEps, getSegCount_(), pma::Track3D::Initialize(), geo::kU, geo::kV, geo::kZ, pma::Track3D::NHits(), pma::Track3D::Optimize(), pma::Track3D::SelectAllHits(), pma::Track3D::size(), pma::Track3D::SortHits(), pma::Track3D::TPCs(), and twoViewFraction().

Referenced by pma::PMAlgTracker::matchCluster().

447 {
448  pma::Track3D* trk = new pma::Track3D(); // track candidate
449  trk->AddHits(detProp, hits_1);
450  trk->AddHits(detProp, hits_2);
451 
452  mf::LogVerbatim("ProjectionMatchingAlg") << "track size: " << trk->size();
453  std::vector<unsigned int> tpcs = trk->TPCs();
454  for (size_t t = 0; t < tpcs.size(); ++t) {
455  mf::LogVerbatim("ProjectionMatchingAlg") << " tpc:" << tpcs[t];
456  }
457  mf::LogVerbatim("ProjectionMatchingAlg")
458  << " #coll:" << trk->NHits(geo::kZ) << " #ind2:" << trk->NHits(geo::kV)
459  << " #ind1:" << trk->NHits(geo::kU);
460 
461  size_t nSegments = getSegCount_(trk->size());
462  size_t nNodes = (size_t)(nSegments - 1); // n nodes to add
463 
464  mf::LogVerbatim("ProjectionMatchingAlg") << " initialize trk";
465  if (!trk->Initialize(detProp)) {
466  mf::LogWarning("ProjectionMatchingAlg") << " initialization failed, delete trk";
467  delete trk;
468  return 0;
469  }
470 
471  double f = twoViewFraction(*trk);
472  if (f > fMinTwoViewFraction) {
473  double g = 0.0;
474  mf::LogVerbatim("ProjectionMatchingAlg") << " optimize trk (" << nSegments << " seg)";
475  if (nNodes) {
476  g = trk->Optimize(detProp, nNodes, fOptimizationEps, false, true, 25,
477  10); // build nodes
478  mf::LogVerbatim("ProjectionMatchingAlg") << " nodes done, g = " << g;
479  trk->SelectAllHits();
480  }
481  g = trk->Optimize(detProp, 0, fFineTuningEps); // final tuning
482  mf::LogVerbatim("ProjectionMatchingAlg") << " tune done, g = " << g;
483 
484  trk->SortHits();
485  return trk;
486  }
487  else {
488  mf::LogVerbatim("ProjectionMatchingAlg") << " clusters do not match, f = " << f;
489  delete trk;
490  return 0;
491  }
492 }
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
Definition: PmaTrack3D.cxx:404
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool SelectAllHits()
Planes which measure V.
Definition: geo_types.h:132
bool Initialize(detinfo::DetectorPropertiesData const &detProp, float initEndSegW=0.05F)
Definition: PmaTrack3D.cxx:78
Planes which measure Z direction.
Definition: geo_types.h:134
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:448
static size_t getSegCount_(size_t trk_size)
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.
TFile f
Definition: plotHisto.C:6
Planes which measure U.
Definition: geo_types.h:131
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:421
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:89
double twoViewFraction(pma::Track3D &trk) const
bool pma::ProjectionMatchingAlg::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
private

Definition at line 993 of file ProjectionMatchingAlg.cxx.

References detinfo::DetectorPropertiesData::ConvertTicksToX(), hits(), pma::Track3D::size(), and x.

Referenced by addEndpointRef_().

1003 {
1004  size_t nCloseHits = 0;
1005  int forwWires = 3, backWires = -1;
1006  double xMargin = 0.4;
1007  for (auto h : hits)
1008  if ((view == (int)h->WireID().Plane) && (tpc == h->WireID().TPC) &&
1009  (cryo == h->WireID().Cryostat)) {
1010  bool found = false;
1011  for (size_t ht = 0; ht < trk.size(); ht++)
1012  if (trk[ht]->Hit2DPtr().key() == h.key()) {
1013  found = true;
1014  break;
1015  }
1016  if (found) continue;
1017 
1018  int dw = wdir * (h->WireID().Wire - wire);
1019  if ((dw <= forwWires) && (dw >= backWires)) {
1020  double x = detProp.ConvertTicksToX(h->PeakTime(), view, tpc, cryo);
1021  if (fabs(x - drift_x) < xMargin) nCloseHits++;
1022  }
1023  }
1024  if (nCloseHits > 1)
1025  return false;
1026  else
1027  return true;
1028 }
Float_t x
Definition: compare.C:6
double ConvertTicksToX(double ticks, int p, int t, int c) const
size_t size() const
Definition: PmaTrack3D.h:89
pma::Track3D * pma::ProjectionMatchingAlg::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.

Definition at line 963 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::AddHits(), fFineTuningEps, fOptimizationEps, getSegCount_(), hits(), geo::kU, geo::kV, geo::kZ, pma::Track3D::NHits(), pma::Track3D::Nodes(), pma::Track3D::Optimize(), and pma::Track3D::size().

Referenced by pma::PMAlgTracker::extendTrack(), and pma::PMAlgTracker::reassignHits_1().

968 {
969  pma::Track3D* copy = new pma::Track3D(trk);
970  copy->AddHits(detProp, hits);
971 
972  mf::LogVerbatim("ProjectionMatchingAlg")
973  << "ext. track size: " << copy->size() << " #coll:" << copy->NHits(geo::kZ)
974  << " #ind2:" << copy->NHits(geo::kV) << " #ind1:" << copy->NHits(geo::kU);
975 
976  if (add_nodes) {
977  size_t nSegments = getSegCount_(copy->size());
978  int nNodes = nSegments - copy->Nodes().size() + 1; // n nodes to add
979  if (nNodes < 0) nNodes = 0;
980 
981  if (nNodes) {
982  mf::LogVerbatim("ProjectionMatchingAlg") << " add " << nNodes << " nodes";
983  copy->Optimize(detProp, nNodes, fOptimizationEps);
984  }
985  }
986  double g = copy->Optimize(detProp, 0, fFineTuningEps);
987  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt done, g = " << g;
988 
989  return copy;
990 }
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
Definition: PmaTrack3D.cxx:404
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Planes which measure V.
Definition: geo_types.h:132
Planes which measure Z direction.
Definition: geo_types.h:134
static size_t getSegCount_(size_t trk_size)
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.
Planes which measure U.
Definition: geo_types.h:131
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:421
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:274
size_t size() const
Definition: PmaTrack3D.h:89
void pma::ProjectionMatchingAlg::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

Get rid of small groups of hits around cascades; used to calculate cascade starting direction using the compact core cluster.

Definition at line 688 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), GetCloseHits_(), util::size(), and pma::WireDriftToCm().

Referenced by buildShowerSeg().

694 {
695  size_t min_size = hits_in.size() / 5;
696  if (min_size < 3) min_size = 3;
697 
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;
701 
702  float mindist2 = 99999.99;
703  size_t id_sub_groups_save = 0;
704  size_t id = 0;
705  while (GetCloseHits_(detProp, r2d, hits_in, used, close_hits)) {
706 
707  sub_groups.emplace_back(close_hits);
708 
709  for (size_t h = 0; h < close_hits.size(); ++h) {
710  TVector2 hi_cm = pma::WireDriftToCm(detProp,
711  close_hits[h]->WireID().Wire,
712  close_hits[h]->PeakTime(),
713  close_hits[h]->WireID().Plane,
714  close_hits[h]->WireID().TPC,
715  close_hits[h]->WireID().Cryostat);
716 
717  float dist2 = pma::Dist2(hi_cm, vtx2d);
718  if (dist2 < mindist2) {
719  id_sub_groups_save = id;
720  mindist2 = dist2;
721  }
722  }
723 
724  id++;
725  }
726 
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);
731  }
732  }
733 
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);
738  }
739 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
TVector2 WireDriftToCm(detinfo::DetectorPropertiesData const &detProp, unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:286
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
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
recob::tracking::Plane Plane
Definition: TrackState.h:17
bool pma::ProjectionMatchingAlg::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
private

Definition at line 743 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), fWireReadoutGeom, detinfo::DetectorPropertiesData::GetXTicksCoefficient(), Has_(), recob::Hit::PeakTime(), geo::WireReadoutGeom::Plane(), geo::WireID::Wire, recob::Hit::WireID(), and geo::PlaneGeo::WirePitch().

Referenced by FilterOutSmallParts().

748 {
749  hits_out.clear();
750 
751  const double gapMargin = 5.0; // can be changed to f(id_tpc1, id_tpc2)
752  size_t idx = 0;
753 
754  while ((idx < hits_in.size()) && Has_(used, idx))
755  idx++;
756 
757  if (idx < hits_in.size()) {
758  hits_out.push_back(hits_in[idx]);
759  used.push_back(idx);
760 
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;
764  double wirePitch = fWireReadoutGeom->Plane(geo::PlaneID(cryo, tpc, view)).WirePitch();
765  double driftPitch = detProp.GetXTicksCoefficient(tpc, cryo);
766 
767  double r2d2 = r2d * r2d;
768  double gapMargin2 = sqrt(2 * gapMargin * gapMargin);
769  gapMargin2 = (gapMargin2 + r2d) * (gapMargin2 + r2d);
770 
771  bool collect = true;
772  while (collect) {
773  collect = false;
774  for (size_t i = 0; i < hits_in.size(); i++)
775  if (!Has_(used, i)) {
776  art::Ptr<recob::Hit> const& hi = hits_in[i];
777  TVector2 hi_cm(wirePitch * hi->WireID().Wire, driftPitch * hi->PeakTime());
778 
779  bool accept = false;
780 
781  for (auto const& ho : hits_out) {
782 
783  TVector2 ho_cm(wirePitch * ho->WireID().Wire, driftPitch * ho->PeakTime());
784  double d2 = pma::Dist2(hi_cm, ho_cm);
785 
786  if (d2 < r2d2) {
787  accept = true;
788  break;
789  }
790  }
791  if (accept) {
792  collect = true;
793  hits_out.push_back(hi);
794  used.push_back(i);
795  }
796  }
797  }
798  return true;
799  }
800  else
801  return false;
802 }
bool Has_(const std::vector< size_t > &v, size_t idx) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
double GetXTicksCoefficient(int t, int c) const
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:290
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:226
geo::WireReadoutGeom const * fWireReadoutGeom
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:312
size_t pma::ProjectionMatchingAlg::getSegCount_ ( size_t  trk_size)
staticprivate

Definition at line 436 of file ProjectionMatchingAlg.cxx.

Referenced by buildMultiTPCTrack(), buildTrack(), and extendTrack().

437 {
438  int const nSegments = 0.8 * trk_size / sqrt(trk_size);
439  return std::max(size_t{1}, static_cast<size_t>(nSegments));
440 }
void pma::ProjectionMatchingAlg::guideEndpoints ( const detinfo::DetectorPropertiesData clockData,
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).

Definition at line 1081 of file ProjectionMatchingAlg.cxx.

References addEndpointRef_(), pma::Track3D::BackCryo(), pma::Track3D::BackTPC(), detinfo::DetectorPropertiesData::ConvertTicksToX(), fFineTuningEps, pma::Track3D::FrontCryo(), pma::Track3D::FrontTPC(), fWireReadoutGeom, pma::Segment3D::GetDirection3D(), geo::WireReadoutGeom::HasPlane(), hits(), pma::Element3D::Length(), pma::Track3D::NextHit(), pma::Track3D::Optimize(), pma::Track3D::PrevHit(), pma::Track3D::Segments(), and pma::Track3D::size().

Referenced by pma::PMAlgTrackingBase::guideEndpoints().

1085 {
1086  unsigned int tpc = trk.FrontTPC(), cryo = trk.FrontCryo();
1087  if ((tpc != trk.BackTPC()) || (cryo != trk.BackCryo())) {
1088  mf::LogWarning("ProjectionMatchingAlg") << "Please, apply before TPC stitching.";
1089  return;
1090  }
1091 
1092  const double maxCosXZ = 0.992546; // 7 deg
1093 
1094  pma::Segment3D* segFront = trk.Segments().front();
1095  if (trk.Segments().size() > 2) {
1096  pma::Segment3D* segFront1 = trk.Segments()[1];
1097  if ((segFront->Length() < 0.8) && (segFront1->Length() > 5.0)) segFront = segFront1;
1098  }
1099  pma::Vector3D dirFront = segFront->GetDirection3D();
1100  pma::Vector3D dirFrontXZ(dirFront.X(), 0., dirFront.Z());
1101  dirFrontXZ *= 1.0 / dirFrontXZ.R();
1102 
1103  pma::Segment3D* segBack = trk.Segments().back();
1104  if (trk.Segments().size() > 2) {
1105  pma::Segment3D* segBack1 = trk.Segments()[trk.Segments().size() - 2];
1106  if ((segBack->Length() < 0.8) && (segBack1->Length() > 5.0)) segBack = segBack1;
1107  }
1108  pma::Vector3D dirBack = segBack->GetDirection3D();
1109  pma::Vector3D dirBackXZ(dirBack.X(), 0., dirBack.Z());
1110  dirBackXZ *= 1.0 / dirBackXZ.R();
1111 
1112  if ((fabs(dirFrontXZ.Z()) < maxCosXZ) && (fabs(dirBackXZ.Z()) < maxCosXZ)) {
1113  return; // front & back are not parallel to wire planes => exit
1114  }
1115 
1116  unsigned int nPlanesFront = 0, nPlanesBack = 0;
1117  std::pair<int, int> wiresFront[3], wiresBack[3]; // wire index; index direction
1118  double xFront[3], xBack[3];
1119 
1120  for (unsigned int i = 0; i < 3; i++) {
1121  bool frontPresent = false, backPresent = false;
1122  if (fWireReadoutGeom->HasPlane(geo::PlaneID(cryo, tpc, i))) {
1123  int idxFront0 = trk.NextHit(-1, i);
1124  int idxBack0 = trk.PrevHit(trk.size(), 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();
1133 
1134  int wFront1 = trk[idxFront1]->Wire();
1135  int wBack1 = trk[idxBack1]->Wire();
1136 
1137  wiresFront[i].first = wFront0;
1138  wiresFront[i].second = wFront0 - wFront1;
1139  xFront[i] = detProp.ConvertTicksToX(trk[idxFront0]->PeakTime(), i, tpc, cryo);
1140 
1141  wiresBack[i].first = wBack0;
1142  wiresBack[i].second = wBack0 - wBack1;
1143  xBack[i] = detProp.ConvertTicksToX(trk[idxBack0]->PeakTime(), i, tpc, cryo);
1144 
1145  if (wiresFront[i].second) {
1146  if (wiresFront[i].second > 0)
1147  wiresFront[i].second = 1;
1148  else
1149  wiresFront[i].second = -1;
1150 
1151  frontPresent = true;
1152  nPlanesFront++;
1153  }
1154 
1155  if (wiresBack[i].second) {
1156  if (wiresBack[i].second > 0)
1157  wiresBack[i].second = 1;
1158  else
1159  wiresBack[i].second = -1;
1160 
1161  backPresent = true;
1162  nPlanesBack++;
1163  }
1164  }
1165  }
1166  }
1167  if (!frontPresent) { wiresFront[i].first = -1; }
1168  if (!backPresent) { wiresBack[i].first = -1; }
1169  }
1170 
1171  bool refAdded = false;
1172  if ((nPlanesFront > 1) && (fabs(dirFrontXZ.Z()) >= maxCosXZ)) {
1173  refAdded |= addEndpointRef_(detProp, trk, hits, wiresFront, xFront, tpc, cryo);
1174  }
1175 
1176  if ((nPlanesBack > 1) && (fabs(dirBackXZ.Z()) >= maxCosXZ)) {
1177  refAdded |= addEndpointRef_(detProp, trk, hits, wiresBack, xBack, tpc, cryo);
1178  }
1179  if (refAdded) {
1180  mf::LogVerbatim("ProjectionMatchingAlg") << "guide wire-plane-parallel track endpoints";
1181  double g = trk.Optimize(detProp, 0, 0.1 * fFineTuningEps);
1182  mf::LogVerbatim("ProjectionMatchingAlg") << " done, g = " << g;
1183  }
1184 }
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
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:911
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
unsigned int BackTPC() const
Definition: PmaTrack3D.h:121
bool HasPlane(PlaneID const &planeid) const
Returns whether we have the specified plane.
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:34
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.
unsigned int BackCryo() const
Definition: PmaTrack3D.h:122
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:269
unsigned int FrontTPC() const
Definition: PmaTrack3D.h:118
unsigned int FrontCryo() const
Definition: PmaTrack3D.h:119
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of this segment.
geo::WireReadoutGeom const * fWireReadoutGeom
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:894
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
size_t size() const
Definition: PmaTrack3D.h:89
double Length(void) const
Definition: PmaElement3D.h:53
void pma::ProjectionMatchingAlg::guideEndpoints ( const detinfo::DetectorPropertiesData clockData,
pma::Track3D trk,
pma::Track3D::ETrackEnd  endpoint,
const std::map< unsigned int, std::vector< art::Ptr< recob::Hit >>> &  hits 
) const

Add 3D reference points to clean endpoint of a track.

Definition at line 1187 of file ProjectionMatchingAlg.cxx.

References addEndpointRef_(), pma::Track3D::BackCryo(), pma::Track3D::BackTPC(), detinfo::DetectorPropertiesData::ConvertTicksToX(), fFineTuningEps, pma::Track3D::FrontCryo(), pma::Track3D::FrontTPC(), fWireReadoutGeom, pma::Segment3D::GetDirection3D(), geo::WireReadoutGeom::HasPlane(), hits(), pma::Track3D::kBegin, pma::Element3D::Length(), pma::Track3D::NextHit(), pma::Track3D::Optimize(), art::productstatus::present(), pma::Track3D::PrevHit(), pma::Track3D::Segments(), and pma::Track3D::size().

1192 {
1193  const double maxCosXZ = 0.992546; // 7 deg
1194 
1195  unsigned int tpc, cryo;
1196  pma::Segment3D* seg0 = 0;
1197  pma::Segment3D* seg1 = 0;
1198 
1199  if (endpoint == pma::Track3D::kBegin) {
1200  tpc = trk.FrontTPC(), cryo = trk.FrontCryo();
1201  seg0 = trk.Segments().front();
1202  if (trk.Segments().size() > 2) { seg1 = trk.Segments()[1]; }
1203  }
1204  else {
1205  tpc = trk.BackTPC(), cryo = trk.BackCryo();
1206  seg0 = trk.Segments().back();
1207  if (trk.Segments().size() > 2) { seg1 = trk.Segments()[trk.Segments().size() - 2]; }
1208  }
1209  if (seg1 && (seg0->Length() < 0.8) && (seg1->Length() > 5.0)) { seg0 = seg1; }
1210  pma::Vector3D dir0 = seg0->GetDirection3D();
1211  pma::Vector3D dir0XZ(dir0.X(), 0., dir0.Z());
1212  dir0XZ *= 1.0 / dir0XZ.R();
1213 
1214  if (fabs(dir0XZ.Z()) < maxCosXZ) { return; } // not parallel to wire planes => exit
1215 
1216  unsigned int nPlanes = 0;
1217  std::pair<int, int> wires[3]; // wire index; index direction
1218  double x0[3];
1219 
1220  for (unsigned int i = 0; i < 3; i++) {
1221  bool present = false;
1222  if (fWireReadoutGeom->HasPlane(geo::PlaneID(cryo, tpc, i))) {
1223  int idx0 = -1, idx1 = -1;
1224  if (endpoint == pma::Track3D::kBegin) { idx0 = trk.NextHit(-1, i); }
1225  else {
1226  idx0 = trk.PrevHit(trk.size(), i);
1227  }
1228 
1229  if ((idx0 >= 0) && (idx0 < (int)trk.size()) && (trk[idx0]->TPC() == tpc) &&
1230  (trk[idx0]->Cryo() == cryo)) {
1231  if (endpoint == pma::Track3D::kBegin) { idx1 = trk.NextHit(idx0, i); }
1232  else {
1233  idx1 = trk.PrevHit(idx0, i);
1234  }
1235 
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();
1240 
1241  wires[i].first = w0;
1242  wires[i].second = w0 - w1;
1243  x0[i] = detProp.ConvertTicksToX(trk[idx0]->PeakTime(), i, tpc, cryo);
1244 
1245  if (wires[i].second) {
1246  if (wires[i].second > 0)
1247  wires[i].second = 1;
1248  else
1249  wires[i].second = -1;
1250 
1251  present = true;
1252  nPlanes++;
1253  }
1254  }
1255  }
1256  }
1257  if (!present) { wires[i].first = -1; }
1258  }
1259 
1260  if ((nPlanes > 1) && (fabs(dir0XZ.Z()) >= maxCosXZ) &&
1261  addEndpointRef_(detProp, trk, hits, wires, x0, tpc, cryo)) {
1262  mf::LogVerbatim("ProjectionMatchingAlg") << "guide wire-plane-parallel track endpoint";
1263  double g = trk.Optimize(detProp, 0, 0.1 * fFineTuningEps);
1264  mf::LogVerbatim("ProjectionMatchingAlg") << " done, g = " << g;
1265  }
1266 }
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
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:911
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
unsigned int BackTPC() const
Definition: PmaTrack3D.h:121
bool HasPlane(PlaneID const &planeid) const
Returns whether we have the specified plane.
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:34
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.
unsigned int BackCryo() const
Definition: PmaTrack3D.h:122
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:269
unsigned int FrontTPC() const
Definition: PmaTrack3D.h:118
unsigned int FrontCryo() const
Definition: PmaTrack3D.h:119
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of this segment.
geo::WireReadoutGeom const * fWireReadoutGeom
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:894
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
size_t size() const
Definition: PmaTrack3D.h:89
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10
double Length(void) const
Definition: PmaElement3D.h:53
bool pma::ProjectionMatchingAlg::Has_ ( const std::vector< size_t > &  v,
size_t  idx 
) const
private

Definition at line 866 of file ProjectionMatchingAlg.cxx.

Referenced by GetCloseHits_().

867 {
868  for (auto c : v)
869  if (c == idx) return true;
870  return false;
871 }
bool pma::ProjectionMatchingAlg::isContained ( const pma::Track3D trk,
float  margin = 0.0F 
) const
inline

Test if hits at the track endpoinds do not stick out of TPC which they belong to. Here one can implement some configurable margin if needed for real data imeprfections.

Definition at line 162 of file ProjectionMatchingAlg.h.

References pma::Track3D::back(), pma::Track3D::FirstElement(), pma::Track3D::front(), hits(), pma::Track3D::LastElement(), pma::Hit3D::Point3D(), pma::Node3D::SameTPC(), and lar::dump::vector().

Referenced by pma::PMAlgTracker::matchCluster(), and pma::PMAlgTracker::reassignHits_1().

163  {
164  return (trk.FirstElement()->SameTPC(trk.front()->Point3D(), margin) &&
165  trk.LastElement()->SameTPC(trk.back()->Point3D(), margin));
166  }
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
pma::Node3D * FirstElement() const
Definition: PmaTrack3D.h:275
pma::Node3D * LastElement() const
Definition: PmaTrack3D.h:276
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:103
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:88
void pma::ProjectionMatchingAlg::mergeTracks ( const detinfo::DetectorPropertiesData detProp,
pma::Track3D dst,
pma::Track3D src,
bool  reopt 
) const

Add src to dst as it was its continuation; nodes of src are added to dst after its own nodes, hits of src are added to hits of dst, then dst is reoptimized.

Definition at line 1314 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::AddNode(), alignTracks(), pma::Track3D::BackCryo(), pma::Track3D::BackTPC(), pma::Element3D::Cryo(), pma::Dist2(), fFineTuningEps, pma::Track3D::FrontCryo(), pma::Track3D::FrontTPC(), pma::Element3D::IsFrozen(), pma::Track3D::Length(), pma::Track3D::MakeProjection(), n, pma::Track3D::Nodes(), pma::Track3D::Optimize(), pma::Track3D::push_back(), pma::Track3D::ShiftEndsToHits(), pma::Track3D::size(), pma::Track3D::SortHits(), and pma::Element3D::TPC().

Referenced by buildMultiTPCTrack(), and pma::PMAlgTracker::mergeCoLinear().

1318 {
1319  if (!alignTracks(dst, src)) return;
1320 
1321  unsigned int tpc = src.FrontTPC();
1322  unsigned int cryo = src.FrontCryo();
1323  double lmean = dst.Length() / (dst.Nodes().size() - 1);
1324  if ((pma::Dist2(dst.Nodes().back()->Point3D(), src.Nodes().front()->Point3D()) > 0.5 * lmean) ||
1325  (tpc != dst.BackTPC()) || (cryo != dst.BackCryo())) {
1326  dst.AddNode(detProp, src.Nodes().front()->Point3D(), tpc, cryo);
1327  if (src.Nodes().front()->IsFrozen()) dst.Nodes().back()->SetFrozen(true);
1328  }
1329  for (size_t n = 1; n < src.Nodes().size(); n++) {
1330  pma::Node3D* node = src.Nodes()[n];
1331 
1332  dst.AddNode(detProp, src.Nodes()[n]->Point3D(), node->TPC(), node->Cryo());
1333 
1334  if (node->IsFrozen()) dst.Nodes().back()->SetFrozen(true);
1335  }
1336  for (size_t h = 0; h < src.size(); h++) {
1337  dst.push_back(detProp, src[h]->Hit2DPtr());
1338  }
1339  if (reopt) {
1340  double g = dst.Optimize(detProp, 0, fFineTuningEps);
1341  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt after merging done, g = " << g;
1342  }
1343  else {
1344  dst.MakeProjection();
1345  }
1346 
1347  dst.SortHits();
1348  dst.ShiftEndsToHits();
1349 
1350  dst.MakeProjection();
1351  dst.SortHits();
1352 }
void MakeProjection()
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
unsigned int BackTPC() const
Definition: PmaTrack3D.h:121
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.
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:35
unsigned int BackCryo() const
Definition: PmaTrack3D.h:122
void AddNode(pma::Node3D *node)
bool alignTracks(pma::Track3D &first, pma::Track3D &second) const
unsigned int FrontTPC() const
Definition: PmaTrack3D.h:118
unsigned int FrontCryo() const
Definition: PmaTrack3D.h:119
void push_back(pma::Hit3D *hit)
Definition: PmaTrack3D.h:77
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
Definition: PmaElement3D.h:37
double Length(size_t step=1) const
Definition: PmaTrack3D.h:94
bool IsFrozen(void) const
Check if the vertex 3D position is fixed.
Definition: PmaElement3D.h:105
Char_t n[5]
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:274
size_t size() const
Definition: PmaTrack3D.h:89
bool ShiftEndsToHits()
void pma::ProjectionMatchingAlg::RemoveNotEnabledHits ( pma::Track3D trk) const

Definition at line 875 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::release_at(), and pma::Track3D::size().

Referenced by ShortenSeg_().

876 {
877  size_t h = 0;
878  while (h < trk.size()) {
879  if (trk[h]->IsEnabled())
880  ++h;
881  else
882  (trk.release_at(h));
883  }
884 }
pma::Hit3D * release_at(size_t index)
Definition: PmaTrack3D.cxx:348
size_t size() const
Definition: PmaTrack3D.h:89
double pma::ProjectionMatchingAlg::selectInitialHits ( pma::Track3D trk,
unsigned int  view = geo::kZ,
unsigned int *  nused = 0 
) const

Intendet to calculate dQ/dx in the initial part of EM cascade; collection view is used by default, but it works also with other projections.

Definition at line 1355 of file ProjectionMatchingAlg.cxx.

References lar::util::absDiff(), pma::Hit3D::GetDistToProj(), pma::Hit3D::GetSegFraction(), pma::Track3D::HitDxByView(), pma::Track3D::NextHit(), pma::Track3D::size(), pma::Hit3D::SummedADC(), pma::Hit3D::TagOutlier(), pma::Hit3D::View2D(), and pma::Hit3D::Wire().

Referenced by ems::EMShower3D::ConvertFrom(), and ems::EMShower3D::ConvertFrom2().

1358 {
1359  for (size_t i = 0; i < trk.size(); i++) {
1360  pma::Hit3D* hit = trk[i];
1361  if (hit->View2D() == view) {
1362  if ((hit->GetDistToProj() > 0.5) || // more than 0.5cm away away from the segment
1363  (hit->GetSegFraction() < -1.0)) // projects before segment start (to check!!!)
1364  hit->TagOutlier(true);
1365  else
1366  hit->TagOutlier(false);
1367  }
1368  }
1369 
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);
1373 
1374  pma::Hit3D* hit = trk[ih];
1375  pma::Hit3D* lastHit = hit;
1376 
1377  if ((ih >= 0) && (ih < (int)trk.size())) {
1378  hit->TagOutlier(true);
1379 
1380  ih = trk.NextHit(ih, view);
1381  while ((dx < 2.5) && (ih >= 0) && (ih < (int)trk.size())) {
1382  hit = trk[ih];
1383 
1384  if (lar::util::absDiff(hit->Wire(), lastHit->Wire()) > 2)
1385  break; // break on gap in wire direction
1386 
1387  last_x = trk.HitDxByView(ih, view);
1388  last_q = hit->SummedADC();
1389  if (dx + last_x < 3.0) {
1390  dq += last_q;
1391  dx += last_x;
1392  nhits++;
1393  }
1394  else
1395  break;
1396 
1397  lastHit = hit;
1398  ih = trk.NextHit(ih, view);
1399  }
1400  while ((ih >= 0) && (ih < (int)trk.size())) {
1401  hit = trk[ih];
1402  hit->TagOutlier(true);
1403  ih = trk.NextHit(ih, view);
1404  }
1405  }
1406  else {
1407  mf::LogError("ProjectionMatchingAlg") << "Initial part selection failed.";
1408  }
1409 
1410  if (!nhits) {
1411  mf::LogError("ProjectionMatchingAlg") << "Initial part too short to select useful hits.";
1412  }
1413 
1414  if (dx > 0.0) dqdx = dq / dx;
1415 
1416  if (nused) (*nused) = nhits;
1417 
1418  return dqdx;
1419 }
void TagOutlier(bool state) noexcept
Definition: PmaHit3D.h:90
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned int Wire() const noexcept
Definition: PmaHit3D.h:61
float SummedADC() const noexcept
Definition: PmaHit3D.h:64
float GetSegFraction() const noexcept
Definition: PmaHit3D.h:74
Detector simulation of raw signals on wires.
unsigned int View2D() const noexcept
Definition: PmaHit3D.h:60
constexpr auto absDiff(A const &a, B const &b)
Returns the absolute value of the difference between two values.
Definition: NumericUtils.h:69
double GetDistToProj() const
Definition: PmaHit3D.h:71
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:894
double HitDxByView(size_t index, unsigned int view) const
Definition: PmaTrack3D.cxx:993
size_t size() const
Definition: PmaTrack3D.h:89
void pma::ProjectionMatchingAlg::ShortenSeg_ ( const detinfo::DetectorPropertiesData detProp,
pma::Track3D trk,
const geo::TPCGeo tpcgeom 
) const
private

Definition at line 806 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), pma::Track3D::front(), pma::Track3D::GetMse(), pma::Track3D::Length(), pma::Track3D::Optimize(), pma::Hit3D::Point3D(), RemoveNotEnabledHits(), pma::Track3D::size(), pma::Track3D::SortHits(), and TestTrk_().

Referenced by buildShowerSeg().

809 {
810  double mse = trk.GetMse();
811  mf::LogWarning("ProjectionMatchingAlg") << "initial value of mse: " << mse;
812  while ((mse > 0.5) && TestTrk_(trk, tpcgeom)) {
813  mse = trk.GetMse();
814  for (size_t h = 0; h < trk.size(); ++h)
815  if (std::sqrt(pma::Dist2(trk[h]->Point3D(), trk.front()->Point3D())) > 0.8 * trk.Length())
816  trk[h]->SetEnabled(false);
817 
819 
820  trk.Optimize(detProp, 0, 0.0001, false);
821  trk.SortHits();
822 
823  mf::LogWarning("ProjectionMatchingAlg") << " mse: " << mse;
824  if (mse == trk.GetMse()) break;
825 
826  mse = trk.GetMse();
827  }
828 
830 }
double GetMse(unsigned int view=geo::kUnknown) const
MSE of hits weighted with hit amplidudes and wire plane coefficients.
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
::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
Definition: PmaHit3D.h:50
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 Length(size_t step=1) const
Definition: PmaTrack3D.h:94
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:89
void RemoveNotEnabledHits(pma::Track3D &trk) const
bool TestTrk_(pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
unsigned int pma::ProjectionMatchingAlg::testHits ( detinfo::DetectorPropertiesData const &  detProp,
const pma::Track3D trk,
const std::vector< art::Ptr< recob::Hit >> &  hits,
double  eps = 1.0 
) const
inline

Count the number of hits that are closer than eps * fHitTestingDist2D to the track 2D projection.

Definition at line 152 of file ProjectionMatchingAlg.h.

References hits(), and pma::Track3D::TestHits().

Referenced by pma::PMAlgTracker::matchCluster(), pma::PMAlgTracker::matchTrack(), and pma::PMAlgTracker::reassignHits_1().

156  {
157  return trk.TestHits(detProp, hits, eps * fHitTestingDist2D);
158  }
unsigned int TestHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, double dist=0.4) const
Count close 2D hits.
Definition: PmaTrack3D.cxx:845
bool pma::ProjectionMatchingAlg::TestTrk_ ( pma::Track3D trk,
const geo::TPCGeo tpcgeom 
) const
private

Definition at line 834 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), pma::Track3D::front(), fWireReadoutGeom, geo::WireReadoutGeom::HasPlane(), geo::TPCGeo::ID(), pma::Track3D::NEnabledHits(), pma::Hit3D::Point3D(), and pma::Track3D::size().

Referenced by ShortenSeg_().

835 {
836  bool test = false;
837 
838  auto has_plane = [this, &id = tpcgeom.ID()](unsigned int plane) {
839  return fWireReadoutGeom->HasPlane(geo::PlaneID{id, plane});
840  };
841 
842  if (has_plane(0) && has_plane(1)) {
843  if ((trk.NEnabledHits(0) > 5) && (trk.NEnabledHits(1) > 5)) test = true;
844  }
845  else if (has_plane(0) && has_plane(2)) {
846  if ((trk.NEnabledHits(0) > 5) && (trk.NEnabledHits(2) > 5)) test = true;
847  }
848  else if (has_plane(1) && has_plane(2)) {
849  if ((trk.NEnabledHits(1) > 5) && (trk.NEnabledHits(2) > 5)) test = true;
850  }
851 
852  double length = 0.0;
853  for (size_t h = 0; h < trk.size(); ++h) {
854  if (!trk[h]->IsEnabled()) break;
855  length = std::sqrt(pma::Dist2(trk.front()->Point3D(), trk[h]->Point3D()));
856  }
857 
858  mf::LogWarning("ProjectionMatchingAlg") << "length of segment: " << length;
859  if (length < 3.0) test = false; // cm
860 
861  return test;
862 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
bool HasPlane(PlaneID const &planeid) const
Returns whether we have the specified plane.
unsigned int NEnabledHits(unsigned int view=geo::kUnknown) const
Definition: PmaTrack3D.cxx:430
geo::WireReadoutGeom const * fWireReadoutGeom
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:89
TPCID const & ID() const
Returns the identifier of this TPC.
Definition: TPCGeo.h:147
std::vector< pma::Hit3D * > pma::ProjectionMatchingAlg::trimTrackToVolume ( pma::Track3D trk,
TVector3  p0,
TVector3  p1 
) const

Definition at line 1269 of file ProjectionMatchingAlg.cxx.

1272 {
1273  return {};
1274 }
double pma::ProjectionMatchingAlg::twoViewFraction ( pma::Track3D trk) const

Calculate the fraction of trajectory seen by two 2D projections at least; even a prfect track starts/stops with the hit from one 2D view, then hits from other views come, which results with the fraction value high, but always < 1.0; wrong cluster matchings or incomplete tracks give significantly lower values.

Definition at line 415 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::DisableSingleViewEnds(), pma::Track3D::Length(), pma::Track3D::SelectHits(), and pma::Track3D::size().

Referenced by buildTrack(), and pma::PMAlgTracker::matchCluster().

416 {
417  trk.SelectHits();
418  trk.DisableSingleViewEnds();
419 
420  size_t idx = 0;
421  while ((idx < trk.size() - 1) && !trk[idx]->IsEnabled())
422  idx++;
423  double l0 = trk.Length(0, idx + 1);
424 
425  idx = trk.size() - 1;
426  while ((idx > 1) && !trk[idx]->IsEnabled())
427  idx--;
428  double l1 = trk.Length(idx - 1, trk.size() - 1);
429 
430  trk.SelectHits();
431 
432  return 1.0 - (l0 + l1) / trk.Length();
433 }
bool SelectHits(float fraction=1.0F)
unsigned int DisableSingleViewEnds()
double Length(size_t step=1) const
Definition: PmaTrack3D.h:94
size_t size() const
Definition: PmaTrack3D.h:89
double pma::ProjectionMatchingAlg::validate ( const detinfo::DetectorPropertiesData detProp,
const lariov::ChannelStatusProvider &  channelStatus,
const pma::Track3D trk,
const std::vector< art::Ptr< recob::Hit >> &  hits 
) const

Calculate the fraction of the track that is closer than fTrkValidationDist2D to any hit from hits in their plane (a plane that was not used to build the track). Hits should be preselected, so all belong to the same plane.

Definition at line 251 of file ProjectionMatchingAlg.cxx.

References detinfo::DetectorPropertiesData::ConvertTicksToX(), pma::Track3D::Cryos(), pma::Dist2(), pma::Track3D::Dist2(), f, pma::Track3D::front(), fTrkValidationDist2D, fWireReadoutGeom, pma::GetSegmentProjVector(), geo::WireReadoutGeom::HasWire(), hits(), geo::WireReadoutGeom::Plane(), geo::WireReadoutGeom::PlaneWireToChannel(), pma::Hit3D::Point3D(), pma::Node3D::SameTPC(), pma::Track3D::Segments(), lar::to_element, geo::vect::toPoint(), pma::Element3D::TPC(), pma::Track3D::TPCs(), lar::dump::vector(), geo::PlaneGeo::WireCoordinate(), pma::Track3D::WireDriftRange(), pma::WireDriftToCm(), and geo::PlaneGeo::WirePitch().

Referenced by pma::PMAlgTracker::validate().

255 {
256  if (hits.empty()) { return 0; }
257 
258  double max_d = fTrkValidationDist2D;
259  double const max_d2 = max_d * max_d;
260  unsigned int nAll = 0, nPassed = 0;
261  unsigned int testPlane = hits.front()->WireID().Plane;
262 
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)) {
268  ranges[{t, c}] = trk.WireDriftRange(detProp, testPlane, t, c);
269  wirePitch[{t, c}] = fWireReadoutGeom->Plane(geo::PlaneID(c, t, testPlane)).WirePitch();
270  }
271 
272  unsigned int tpc, cryo;
273  std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
274 
275  for (auto const& h :
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];
281 
282  if ((h.WireID().Wire > rect.first.X() - 10) && // check only hits in the rectangle around
283  (h.WireID().Wire < rect.second.X() + 10) && // the track projection, it is faster than
284  (h.PeakTime() > rect.first.Y() - 100) && // calculation of trk.Dist2(p2d, testPlane)
285  (h.PeakTime() < rect.second.Y() + 100)) {
286  TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
287  detProp.ConvertTicksToX(h.PeakTime(), testPlane, tpc, cryo));
288 
289  double const d2 = trk.Dist2(p2d, testPlane, tpc, cryo);
290 
291  if (d2 < max_d2) all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y());
292  }
293  }
294 
295  // then check how points-close-to-the-track-projection are distributed along the track,
296  // namely: are there track sections crossing empty spaces, except dead wires?
297  pma::Vector3D p(
298  trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
299  for (auto const* seg : trk.Segments()) {
300  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
301  {
302  p = seg->End();
303  continue;
304  }
305  pma::Vector3D p0 = seg->Start();
306  pma::Vector3D p1 = seg->End();
307 
308  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
309 
310  tpc = seg->TPC();
311  cryo = seg->Cryo();
312 
313  pma::Vector3D dc = step * seg->GetDirection3D();
314 
315  auto const& points = all_close_points[{tpc, cryo}];
316 
317  double f = pma::GetSegmentProjVector(p, p0, p1);
318 
319  geo::PlaneID const planeID{cryo, tpc, testPlane};
320  auto const& plane = fWireReadoutGeom->Plane(planeID);
321  double const wirepitch = plane.WirePitch();
322  while ((f < 1.0) && node->SameTPC(p)) {
323  pma::Vector2D p2d(plane.WireCoordinate(toPoint(p)), p.X());
324  geo::WireID const wireID{planeID, static_cast<unsigned int>(p2d.X())};
325  if (fWireReadoutGeom->HasWire(wireID)) {
327  if (channelStatus.IsGood(ch)) {
328  if (points.size()) {
329  p2d.SetX(wirepitch * p2d.X());
330  for (const auto& h : points) {
331  if (pma::Dist2(p2d, h) < max_d2) {
332  nPassed++;
333  break;
334  }
335  }
336  }
337  nAll++;
338  }
339  }
340 
341  p += dc;
342  f = pma::GetSegmentProjVector(p, p0, p1);
343  }
344  p = seg->End();
345  }
346 
347  if (nAll > 0) {
348  double v = nPassed / (double)nAll;
349  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
350  return v;
351  }
352 
353  return 1.0;
354 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
constexpr to_element_t to_element
Definition: ToElement.h:25
double Dist2(const TVector2 &p2d, unsigned int view, unsigned int tpc, unsigned int cryo) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
bool HasWire(WireID const &wireid) const
Returns whether we have the specified wire.
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:448
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:34
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:35
std::vector< unsigned int > Cryos() const
Definition: PmaTrack3D.cxx:466
TFile f
Definition: plotHisto.C:6
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:269
virtual raw::ChannelID_t PlaneWireToChannel(WireID const &wireID) const =0
Returns the channel ID a wire is connected to.
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.
Definition: PmaNode3D.cxx:103
double ConvertTicksToX(double ticks, int p, int t, int c) const
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:112
geo::WireReadoutGeom const * fWireReadoutGeom
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:33
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.
Definition: RawTypes.h:28
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:312
std::pair< TVector2, TVector2 > WireDriftRange(detinfo::DetectorPropertiesData const &detProp, unsigned int view, unsigned int tpc, unsigned int cryo) const
Definition: PmaTrack3D.cxx:484
double pma::ProjectionMatchingAlg::validate ( const detinfo::DetectorPropertiesData detProp,
const lariov::ChannelStatusProvider &  channelStatus,
const TVector3 &  p0,
const TVector3 &  p1,
const std::vector< art::Ptr< recob::Hit >> &  hits,
unsigned int  testView,
unsigned int  tpc,
unsigned int  cryo 
) const

Calculate the fraction of the 3D segment that is closer than fTrkValidationDist2D to any hit from hits in the testPlane of TPC/Cryo. Hits from the testPlane are preselected by this function among all provided (so a bit slower than fn above).

double pma::ProjectionMatchingAlg::validate_on_adc ( const detinfo::DetectorPropertiesData detProp,
const lariov::ChannelStatusProvider &  channelStatus,
const pma::Track3D trk,
const img::DataProviderAlg adcImage,
float  thr 
) const

Calculate the fraction of the track that is close to non-empty pixel (above thr value) in the ADC image of the testView (a view that was not used to build the track).

Definition at line 49 of file ProjectionMatchingAlg.cxx.

References detinfo::DetectorPropertiesData::ConvertXToTicks(), pma::Track3D::Cryos(), f, pma::Track3D::front(), fWireReadoutGeom, pma::GetSegmentProjVector(), geo::WireReadoutGeom::HasWire(), geo::WireReadoutGeom::Plane(), img::DataProviderAlg::Plane(), geo::PlaneID::Plane, geo::WireReadoutGeom::PlaneWireToChannel(), pma::Hit3D::Point3D(), img::DataProviderAlg::poolMax(), pma::Node3D::SameTPC(), pma::Track3D::Segments(), geo::vect::toPoint(), pma::Element3D::TPC(), pma::Track3D::TPCs(), geo::PlaneGeo::WireCoordinate(), and recob::Hit::WireID().

Referenced by pma::PMAlgTracker::validate().

55 {
56  unsigned int nAll = 0, nPassed = 0;
57  unsigned int testPlane = adcImage.Plane();
58 
59  std::vector<unsigned int> trkTPCs = trk.TPCs();
60  std::vector<unsigned int> trkCryos = trk.Cryos();
61 
62  // check how pixels with a high signal are distributed along the track namely: are there
63  // track sections crossing empty spaces, except dead wires?
64  pma::Vector3D p(
65  trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
66  for (auto const* seg : trk.Segments()) {
67  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
68  {
69  p = seg->End();
70  continue;
71  }
72  pma::Vector3D p0 = seg->Start();
73  pma::Vector3D p1 = seg->End();
74 
75  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
76 
77  unsigned tpc = seg->TPC();
78  unsigned cryo = seg->Cryo();
79 
80  pma::Vector3D dc = step * seg->GetDirection3D();
81 
82  double f = pma::GetSegmentProjVector(p, p0, p1);
83  while ((f < 1.0) && node->SameTPC(p)) {
84  geo::PlaneID const planeID{cryo, tpc, testPlane};
85  pma::Vector2D const p2d(fWireReadoutGeom->Plane(planeID).WireCoordinate(toPoint(p)), p.X());
86  geo::WireID const wireID(planeID, (int)p2d.X());
87 
88  int widx = (int)p2d.X();
89  int didx = (int)detProp.ConvertXToTicks(p2d.Y(), testPlane, tpc, cryo);
90 
91  if (fWireReadoutGeom->HasWire(wireID)) {
93  if (channelStatus.IsGood(ch)) {
94  float max_adc = adcImage.poolMax(widx, didx, 2); // +/- 2 wires, can be parameterized
95  if (max_adc > thr) nPassed++;
96 
97  nAll++;
98  }
99  }
100 
101  p += dc;
102  f = pma::GetSegmentProjVector(p, p0, p1);
103  }
104 
105  p = seg->End(); // need to have it at the end due to the p in the first iter set to
106  // the hit position, not segment start
107  }
108 
109  if (nAll > 0) {
110  double v = nPassed / (double)nAll;
111  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
112  return v;
113  }
114 
115  return 1.0;
116 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
Definition: PlaneGeo.h:704
bool HasWire(WireID const &wireid) const
Returns whether we have the specified wire.
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:448
unsigned int Plane() const
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:34
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:35
std::vector< unsigned int > Cryos() const
Definition: PmaTrack3D.cxx:466
TFile f
Definition: plotHisto.C:6
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:269
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.
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.
Definition: PmaNode3D.cxx:103
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:112
geo::WireReadoutGeom const * fWireReadoutGeom
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:33
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.
Definition: RawTypes.h:28
float poolMax(int wire, int drift, size_t r=0) const
Pool max value in a patch around the wire/drift pixel.
double pma::ProjectionMatchingAlg::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

Calculate the fraction of the track that is closer than fTrkValidationDist2D to any hit from hits in the testView (a view that was not used to build the track). Creates also histograms of values in pixels for the passing and rejected points on the track, so the threshold value for the ADC-based calibration can be estimated.

Definition at line 127 of file ProjectionMatchingAlg.cxx.

References detinfo::DetectorPropertiesData::ConvertTicksToX(), detinfo::DetectorPropertiesData::ConvertXToTicks(), pma::Track3D::Cryos(), pma::Dist2(), pma::Track3D::Dist2(), f, pma::Track3D::front(), fTrkValidationDist2D, fWireReadoutGeom, pma::GetSegmentProjVector(), geo::WireReadoutGeom::HasWire(), hits(), geo::WireReadoutGeom::Plane(), img::DataProviderAlg::Plane(), geo::WireReadoutGeom::PlaneWireToChannel(), pma::Hit3D::Point3D(), img::DataProviderAlg::poolMax(), pma::Node3D::SameTPC(), pma::Track3D::Segments(), lar::to_element, geo::vect::toPoint(), pma::Element3D::TPC(), pma::Track3D::TPCs(), geo::PlaneGeo::WireCoordinate(), pma::Track3D::WireDriftRange(), and geo::PlaneGeo::WirePitch().

Referenced by pma::PMAlgTracker::validate().

135 {
136  double max_d = fTrkValidationDist2D;
137  double const max_d2 = max_d * max_d;
138  unsigned int nAll = 0, nPassed = 0;
139  unsigned int testPlane = adcImage.Plane();
140 
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)) {
146  ranges[{t, c}] = trk.WireDriftRange(detProp, testPlane, t, c);
147  wirePitch[{t, c}] = fWireReadoutGeom->Plane(geo::PlaneID(c, t, testPlane)).WirePitch();
148  }
149 
150  unsigned int tpc, cryo;
151  std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
152 
153  for (auto const& h :
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];
159 
160  if ((h.WireID().Wire > rect.first.X() - 10) && // check only hits in the rectangle around
161  (h.WireID().Wire < rect.second.X() + 10) && // the track projection, it is faster than
162  (h.PeakTime() > rect.first.Y() - 100) && // calculation of trk.Dist2(p2d, testPlane)
163  (h.PeakTime() < rect.second.Y() + 100)) {
164  TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
165  detProp.ConvertTicksToX(h.PeakTime(), testPlane, tpc, cryo));
166 
167  double const d2 = trk.Dist2(p2d, testPlane, tpc, cryo);
168 
169  if (d2 < max_d2) { all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y()); }
170  }
171  }
172 
173  // then check how points-close-to-the-track-projection are distributed along the track,
174  // namely: are there track sections crossing empty spaces, except dead wires?
175  pma::Vector3D p(
176  trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
177  for (auto const* seg : trk.Segments()) {
178  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
179  {
180  p = seg->End();
181  continue;
182  }
183  pma::Vector3D p0 = seg->Start();
184  pma::Vector3D p1 = seg->End();
185 
186  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
187 
188  tpc = seg->TPC();
189  cryo = seg->Cryo();
190 
191  pma::Vector3D dc = step * seg->GetDirection3D();
192 
193  auto const& points = all_close_points[{tpc, cryo}];
194 
195  double f = pma::GetSegmentProjVector(p, p0, p1);
196 
197  geo::PlaneID const planeID{cryo, tpc, testPlane};
198  double wirepitch = fWireReadoutGeom->Plane(planeID).WirePitch();
199  while ((f < 1.0) && node->SameTPC(p)) {
200  pma::Vector2D p2d(fWireReadoutGeom->Plane(planeID).WireCoordinate(toPoint(p)), p.X());
201  geo::WireID const wireID{planeID, static_cast<unsigned int>(p2d.X())};
202 
203  int widx = (int)p2d.X();
204  int didx = (int)detProp.ConvertXToTicks(p2d.Y(), planeID);
205 
206  if (fWireReadoutGeom->HasWire(wireID)) {
208  if (channelStatus.IsGood(ch)) {
209  bool is_close = false;
210  float max_adc = adcImage.poolMax(widx, didx, 2);
211 
212  if (points.size()) {
213  p2d.SetX(wirepitch * p2d.X());
214  for (const auto& h : points) {
215  if (pma::Dist2(p2d, h) < max_d2) {
216  is_close = true;
217  nPassed++;
218  break;
219  }
220  }
221  }
222  nAll++;
223 
224  // now fill the calibration histograms
225  if (is_close) {
226  if (histoPassing) histoPassing->Fill(max_adc);
227  }
228  else {
229  if (histoRejected) histoRejected->Fill(max_adc);
230  }
231  }
232  }
233 
234  p += dc;
235  f = pma::GetSegmentProjVector(p, p0, p1);
236  }
237  p = seg->End();
238  }
239 
240  if (nAll > 0) {
241  double v = nPassed / (double)nAll;
242  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
243  return v;
244  }
245 
246  return 1.0;
247 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
constexpr to_element_t to_element
Definition: ToElement.h:25
double Dist2(const TVector2 &p2d, unsigned int view, unsigned int tpc, unsigned int cryo) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
Definition: PlaneGeo.h:704
bool HasWire(WireID const &wireid) const
Returns whether we have the specified wire.
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:87
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
TVector3 const & Point3D() const
Definition: PmaHit3D.h:50
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:448
unsigned int Plane() const
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:34
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:35
std::vector< unsigned int > Cryos() const
Definition: PmaTrack3D.cxx:466
TFile f
Definition: plotHisto.C:6
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:269
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.
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.
Definition: PmaNode3D.cxx:103
double ConvertTicksToX(double ticks, int p, int t, int c) const
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:112
geo::WireReadoutGeom const * fWireReadoutGeom
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:33
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.
Definition: RawTypes.h:28
float poolMax(int wire, int drift, size_t r=0) const
Pool max value in a patch around the wire/drift pixel.
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:312
std::pair< TVector2, TVector2 > WireDriftRange(detinfo::DetectorPropertiesData const &detProp, unsigned int view, unsigned int tpc, unsigned int cryo) const
Definition: PmaTrack3D.cxx:484

Member Data Documentation

double const pma::ProjectionMatchingAlg::fFineTuningEps
private
geo::GeometryCore const* pma::ProjectionMatchingAlg::fGeom
private

Definition at line 330 of file ProjectionMatchingAlg.h.

Referenced by buildShowerSeg(), and ProjectionMatchingAlg().

double const pma::ProjectionMatchingAlg::fHitTestingDist2D
private

Definition at line 323 of file ProjectionMatchingAlg.h.

Referenced by ProjectionMatchingAlg().

double const pma::ProjectionMatchingAlg::fMinTwoViewFraction
private

Definition at line 326 of file ProjectionMatchingAlg.h.

Referenced by buildTrack(), and ProjectionMatchingAlg().

double const pma::ProjectionMatchingAlg::fOptimizationEps
private

Definition at line 314 of file ProjectionMatchingAlg.h.

Referenced by buildMultiTPCTrack(), buildTrack(), and extendTrack().

double const pma::ProjectionMatchingAlg::fTrkValidationDist2D
private

Definition at line 321 of file ProjectionMatchingAlg.h.

Referenced by ProjectionMatchingAlg(), validate(), and validate_on_adc_test().

geo::WireReadoutGeom const* pma::ProjectionMatchingAlg::fWireReadoutGeom
private

The documentation for this class was generated from the following files: