Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
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 TVector3 &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
 

Detailed Description

Definition at line 53 of file ProjectionMatchingAlg.h.

Constructor & Destructor Documentation

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

Definition at line 29 of file ProjectionMatchingAlg.cxx.

35  , fGeom{lar::providerFrom<geo::Geometry>()}
36 {
38 
42 }
static void SetOptFactor(unsigned int view, float value)
Definition: PmaElement3D.h:107
geo::GeometryCore const * fGeom
Planes which measure V.
Definition: geo_types.h:130
Planes which measure Z direction.
Definition: geo_types.h:132
static void SetMargin(double m)
Set allowed node position margin around TPC.
Definition: PmaNode3D.h:151
Planes which measure U.
Definition: geo_types.h:129
static Config * config
Definition: config.cpp:1054
pma::ProjectionMatchingAlg::ProjectionMatchingAlg ( const fhicl::ParameterSet pset)
inline

Definition at line 93 of file ProjectionMatchingAlg.h.

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 1041 of file ProjectionMatchingAlg.cxx.

1049 {
1050  double x = 0.0, y = 0.0, z = 0.0;
1051  std::vector<std::pair<int, unsigned int>> wire_view;
1052  for (unsigned int i = 0; i < 3; i++)
1053  if (wires[i].first >= 0) {
1054  const auto hiter = hits.find(i);
1055  if (hiter != hits.end()) {
1056  if (chkEndpointHits_(detProp,
1057  wires[i].first,
1058  wires[i].second,
1059  xPos[i],
1060  i,
1061  tpc,
1062  cryo,
1063  trk,
1064  hiter->second)) {
1065  x += xPos[i];
1066  wire_view.emplace_back(wires[i].first, i);
1067  }
1068  }
1069  }
1070  if (wire_view.size() > 1) {
1071  x /= wire_view.size();
1072  fGeom->IntersectionPoint(wire_view[0].first,
1073  wire_view[1].first,
1074  wire_view[0].second,
1075  wire_view[1].second,
1076  cryo,
1077  tpc,
1078  y,
1079  z);
1080  trk.AddRefPoint(x, y, z);
1081  mf::LogVerbatim("ProjectionMatchingAlg")
1082  << "trk tpc:" << tpc << " size:" << trk.size() << " add ref.point (" << x << "; " << y << "; "
1083  << z << ")";
1084  return true;
1085  }
1086  else {
1087  mf::LogVerbatim("ProjectionMatchingAlg")
1088  << "trk tpc:" << tpc << " size:" << trk.size()
1089  << " wire-plane-parallel track, but need two clean views of endpoint";
1090  return false;
1091  }
1092 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
geo::GeometryCore const * fGeom
void AddRefPoint(const TVector3 &p)
Definition: PmaTrack3D.h:262
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of 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
list x
Definition: train.py:276
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
size_t size() const
Definition: PmaTrack3D.h:108
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 1292 of file ProjectionMatchingAlg.cxx.

1293 {
1294  unsigned int k = 0;
1295  double const distFF = pma::Dist2(first.front()->Point3D(), second.front()->Point3D());
1296  double dist = distFF;
1297 
1298  double const distFB = pma::Dist2(first.front()->Point3D(), second.back()->Point3D());
1299  if (distFB < dist) {
1300  k = 1;
1301  dist = distFB;
1302  }
1303 
1304  double const distBF = pma::Dist2(first.back()->Point3D(), second.front()->Point3D());
1305  if (distBF < dist) {
1306  k = 2;
1307  dist = distBF;
1308  }
1309 
1310  double distBB = pma::Dist2(first.back()->Point3D(), second.back()->Point3D());
1311  if (distBB < dist) {
1312  k = 3;
1313  dist = distBB;
1314  }
1315 
1316  switch (k) // flip to get dst end before src start, do not merge if track's order reversed
1317  {
1318  case 0:
1319  first.Flip(); // detProp);
1320  break;
1321  case 1: mf::LogError("PMAlgTrackMaker") << "Tracks in reversed order."; return false;
1322  case 2: break;
1323  case 3:
1324  second.Flip(); // detProp);
1325  break;
1326  default:
1327  throw cet::exception("pma::ProjectionMatchingAlg")
1328  << "alignTracks: should never happen." << std::endl;
1329  }
1330  return true;
1331 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:103
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:533
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
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 258 of file ProjectionMatchingAlg.h.

262  {
263  trk.AutoFlip(dir, thr, n);
264  };
void AutoFlip(pma::Track3D::EDirection dir, double thr=0.0, unsigned int n=0)
Definition: PmaTrack3D.cxx:672
G4double thr[100]
Definition: G4S2Light.cc:59
string dir
std::void_t< T > n
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 504 of file ProjectionMatchingAlg.cxx.

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

902 {
903  pma::Track3D* trk = new pma::Track3D();
904  trk->SetEndSegWeight(0.001F);
905  trk->AddHits(detProp, hits_1);
906  trk->AddHits(detProp, hits_2);
907 
908  if (trk->HasTwoViews() && (trk->TPCs().size() == 1)) // now only in single tpc
909  {
910  if (!trk->Initialize(detProp, 0.001F)) {
911  mf::LogWarning("ProjectionMatchingAlg") << "initialization failed, delete segment";
912  delete trk;
913  return 0;
914  }
915  trk->Optimize(detProp, 0, fFineTuningEps);
916 
917  trk->SortHits();
918  return trk;
919  }
920  else {
921  mf::LogWarning("ProjectionMatchingAlg") << "need at least two views in single tpc";
922  delete trk;
923  return 0;
924  }
925 }
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
Definition: PmaTrack3D.cxx:403
bool Initialize(detinfo::DetectorPropertiesData const &detProp, float initEndSegW=0.05F)
Definition: PmaTrack3D.cxx:77
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:452
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:398
bool HasTwoViews(size_t nmin=1) const
Definition: PmaTrack3D.cxx:442
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 TVector3 &  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 929 of file ProjectionMatchingAlg.cxx.

933 {
934  pma::Track3D* trk = buildSegment(detProp, hits_1, hits_2);
935 
936  if (trk) {
937  double dfront = pma::Dist2(trk->front()->Point3D(), point);
938  double dback = pma::Dist2(trk->back()->Point3D(), point);
939  if (dfront > dback) trk->Flip();
940 
941  trk->Nodes().front()->SetPoint3D(point);
942  trk->Nodes().front()->SetFrozen(true);
943  trk->Optimize(detProp, 0, fFineTuningEps);
944 
945  trk->SortHits();
946  }
947  return trk;
948 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
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:103
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:335
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:533
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 952 of file ProjectionMatchingAlg.cxx.

955 {
956  pma::Track3D* trk = buildSegment(detProp, hits);
957 
958  if (trk) {
959  double dfront = pma::Dist2(trk->front()->Point3D(), point);
960  double dback = pma::Dist2(trk->back()->Point3D(), point);
961  if (dfront > dback) trk->Flip(); // detProp);
962 
963  trk->Nodes().front()->SetPoint3D(point);
964  trk->Nodes().front()->SetFrozen(true);
965  trk->Optimize(detProp, 0, fFineTuningEps);
966 
967  trk->SortHits();
968  }
969  return trk;
970 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
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:103
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:335
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:533
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 616 of file ProjectionMatchingAlg.cxx.

619 {
620  double vtxarray[3]{vtx.X(), vtx.Y(), vtx.Z()};
621 
622  if (!fGeom->HasTPC(fGeom->FindTPCAtPosition(vtxarray))) return 0;
623 
624  TVector3 vtxv3(vtx.X(), vtx.Y(), vtx.Z());
625 
626  const size_t tpc = fGeom->FindTPCAtPosition(vtxarray).TPC;
627  const size_t cryo = fGeom->FindCryostatAtPosition(vtxarray);
628  const geo::TPCGeo& tpcgeom = fGeom->Cryostat(cryo).TPC(tpc);
629 
630  // use only hits from tpc where the vtx is
631  std::vector<art::Ptr<recob::Hit>> hitstpc;
632  for (size_t h = 0; h < hits.size(); ++h)
633  if (hits[h]->WireID().TPC == tpc) hitstpc.push_back(hits[h]);
634 
635  if (!hitstpc.size()) return 0;
636 
637  std::vector<art::Ptr<recob::Hit>> hitstrk;
638  size_t view = 0;
639  size_t countviews = 0;
640  while (view < 3) {
641  mf::LogVerbatim("ProjectionMatchinAlg") << "collecting hits from view: " << view;
642  if (!tpcgeom.HasPlane(view)) {
643  ++view;
644  continue;
645  }
646 
647  // select hits only for a single view
648  std::vector<art::Ptr<recob::Hit>> hitsview;
649  for (size_t h = 0; h < hitstpc.size(); ++h)
650  if (hitstpc[h]->WireID().Plane == view) hitsview.push_back(hitstpc[h]);
651  if (!hitsview.size()) {
652  ++view;
653  continue;
654  }
655 
656  // filter our small groups of hits, far from main shower
657  std::vector<art::Ptr<recob::Hit>> hitsfilter;
658  TVector2 proj_pr = pma::GetProjectionToPlane(vtxv3, view, tpc, cryo);
659 
660  mf::LogVerbatim("ProjectionMatchinAlg") << "start filter out: ";
661  FilterOutSmallParts(detProp, 2.0, hitsview, hitsfilter, proj_pr);
662  mf::LogVerbatim("ProjectionMatchingAlg") << "after filter out";
663 
664  for (size_t h = 0; h < hitsfilter.size(); ++h)
665  hitstrk.push_back(hitsfilter[h]);
666 
667  if (hitsfilter.size() >= 5) countviews++;
668 
669  ++view;
670  }
671 
672  if (!hitstrk.size() || (countviews < 2)) {
673  mf::LogWarning("ProjectionMatchinAlg") << "too few hits, segment not built";
674  return 0;
675  }
676 
677  // hits are prepared, finally segment is built
678 
679  pma::Track3D* trk = new pma::Track3D();
680  trk = buildSegment(detProp, hitstrk, vtxv3);
681 
682  // make shorter segment to estimate direction more precise
683  ShortenSeg_(detProp, *trk, tpcgeom);
684 
685  if (trk->size() < 10) {
686  mf::LogWarning("ProjectionMatchingAlg") << "too short segment, delete segment";
687  delete trk;
688  return 0;
689  }
690 
691  return trk;
692 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
Definition: TPCGeo.h:175
geo::GeometryCore const * fGeom
Geometry information for a single TPC.
Definition: TPCGeo.h:38
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) 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
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
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
bool HasTPC(geo::TPCID const &tpcid) const
Returns whether we have the specified TPC.
void ShortenSeg_(const detinfo::DetectorPropertiesData &detProp, pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
Definition: CryostatGeo.cxx:93
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:270
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
size_t size() const
Definition: PmaTrack3D.h:108
geo::CryostatID::CryostatID_t FindCryostatAtPosition(geo::Point_t const &worldLoc) const
Returns the index of the cryostat at specified location.
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 451 of file ProjectionMatchingAlg.cxx.

454 {
455  pma::Track3D* trk = new pma::Track3D(); // track candidate
456  trk->AddHits(detProp, hits_1);
457  trk->AddHits(detProp, hits_2);
458 
459  mf::LogVerbatim("ProjectionMatchingAlg") << "track size: " << trk->size();
460  std::vector<unsigned int> tpcs = trk->TPCs();
461  for (size_t t = 0; t < tpcs.size(); ++t) {
462  mf::LogVerbatim("ProjectionMatchingAlg") << " tpc:" << tpcs[t];
463  }
464  mf::LogVerbatim("ProjectionMatchingAlg")
465  << " #coll:" << trk->NHits(geo::kZ) << " #ind2:" << trk->NHits(geo::kV)
466  << " #ind1:" << trk->NHits(geo::kU);
467 
468  size_t nSegments = getSegCount_(trk->size());
469  size_t nNodes = (size_t)(nSegments - 1); // n nodes to add
470 
471  mf::LogVerbatim("ProjectionMatchingAlg") << " initialize trk";
472  if (!trk->Initialize(detProp)) {
473  mf::LogWarning("ProjectionMatchingAlg") << " initialization failed, delete trk";
474  delete trk;
475  return 0;
476  }
477 
478  double f = twoViewFraction(*trk);
479  if (f > fMinTwoViewFraction) {
480  double g = 0.0;
481  mf::LogVerbatim("ProjectionMatchingAlg") << " optimize trk (" << nSegments << " seg)";
482  if (nNodes) {
483  g = trk->Optimize(detProp, nNodes, fOptimizationEps, false, true, 25,
484  10); // build nodes
485  mf::LogVerbatim("ProjectionMatchingAlg") << " nodes done, g = " << g;
486  trk->SelectAllHits();
487  }
488  g = trk->Optimize(detProp, 0, fFineTuningEps); // final tuning
489  mf::LogVerbatim("ProjectionMatchingAlg") << " tune done, g = " << g;
490 
491  trk->SortHits();
492  // trk->ShiftEndsToHits(); // not sure if useful already here
493  return trk;
494  }
495  else {
496  mf::LogVerbatim("ProjectionMatchingAlg") << " clusters do not match, f = " << f;
497  delete trk;
498  return 0;
499  }
500 }
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
Definition: PmaTrack3D.cxx:403
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
static constexpr double g
Definition: Units.h:144
bool SelectAllHits()
Planes which measure V.
Definition: geo_types.h:130
bool Initialize(detinfo::DetectorPropertiesData const &detProp, float initEndSegW=0.05F)
Definition: PmaTrack3D.cxx:77
Planes which measure Z direction.
Definition: geo_types.h:132
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:452
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:129
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:422
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:108
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 1004 of file ProjectionMatchingAlg.cxx.

1013 {
1014  size_t nCloseHits = 0;
1015  int forwWires = 3, backWires = -1;
1016  double xMargin = 0.4;
1017  for (auto h : hits)
1018  if ((view == (int)h->WireID().Plane) && (tpc == h->WireID().TPC) &&
1019  (cryo == h->WireID().Cryostat)) {
1020  bool found = false;
1021  for (size_t ht = 0; ht < trk.size(); ht++)
1022  if (trk[ht]->Hit2DPtr().key() == h.key()) {
1023  found = true;
1024  break;
1025  }
1026  if (found) continue;
1027 
1028  int dw = wdir * (h->WireID().Wire - wire);
1029  if ((dw <= forwWires) && (dw >= backWires)) {
1030  double x = detProp.ConvertTicksToX(h->PeakTime(), view, tpc, cryo);
1031  if (fabs(x - drift_x) < xMargin) nCloseHits++;
1032  }
1033  }
1034  if (nCloseHits > 1)
1035  return false;
1036  else
1037  return true;
1038 }
double ConvertTicksToX(double ticks, int p, int t, int c) const
list x
Definition: train.py:276
size_t size() const
Definition: PmaTrack3D.h:108
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 974 of file ProjectionMatchingAlg.cxx.

978 {
979  pma::Track3D* copy = new pma::Track3D(trk);
980  copy->AddHits(detProp, hits);
981 
982  mf::LogVerbatim("ProjectionMatchingAlg")
983  << "ext. track size: " << copy->size() << " #coll:" << copy->NHits(geo::kZ)
984  << " #ind2:" << copy->NHits(geo::kV) << " #ind1:" << copy->NHits(geo::kU);
985 
986  if (add_nodes) {
987  size_t nSegments = getSegCount_(copy->size());
988  int nNodes = nSegments - copy->Nodes().size() + 1; // n nodes to add
989  if (nNodes < 0) nNodes = 0;
990 
991  if (nNodes) {
992  mf::LogVerbatim("ProjectionMatchingAlg") << " add " << nNodes << " nodes";
993  copy->Optimize(detProp, nNodes, fOptimizationEps);
994  }
995  }
996  double g = copy->Optimize(detProp, 0, fFineTuningEps);
997  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt done, g = " << g;
998 
999  return copy;
1000 }
void AddHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits)
Definition: PmaTrack3D.cxx:403
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
static constexpr double g
Definition: Units.h:144
Planes which measure V.
Definition: geo_types.h:130
Planes which measure Z direction.
Definition: geo_types.h:132
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:129
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:422
T copy(T const &v)
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:335
size_t size() const
Definition: PmaTrack3D.h:108
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 697 of file ProjectionMatchingAlg.cxx.

702 {
703  size_t min_size = hits_in.size() / 5;
704  if (min_size < 3) min_size = 3;
705 
706  std::vector<size_t> used;
707  std::vector<std::vector<art::Ptr<recob::Hit>>> sub_groups;
708  std::vector<art::Ptr<recob::Hit>> close_hits;
709 
710  float mindist2 = 99999.99;
711  size_t id_sub_groups_save = 0;
712  size_t id = 0;
713  while (GetCloseHits_(detProp, r2d, hits_in, used, close_hits)) {
714 
715  sub_groups.emplace_back(close_hits);
716 
717  for (size_t h = 0; h < close_hits.size(); ++h) {
718  TVector2 hi_cm = pma::WireDriftToCm(detProp,
719  close_hits[h]->WireID().Wire,
720  close_hits[h]->PeakTime(),
721  close_hits[h]->WireID().Plane,
722  close_hits[h]->WireID().TPC,
723  close_hits[h]->WireID().Cryostat);
724 
725  float dist2 = pma::Dist2(hi_cm, vtx2d);
726  if (dist2 < mindist2) {
727  id_sub_groups_save = id;
728  mindist2 = dist2;
729  }
730  }
731 
732  id++;
733  }
734 
735  for (size_t i = 0; i < sub_groups.size(); ++i) {
736  if (i == id_sub_groups_save) {
737  for (auto h : sub_groups[i])
738  hits_out.push_back(h);
739  }
740  }
741 
742  for (size_t i = 0; i < sub_groups.size(); ++i) {
743  if ((i != id_sub_groups_save) && (hits_out.size() < 10) && (sub_groups[i].size() > min_size))
744  for (auto h : sub_groups[i])
745  hits_out.push_back(h);
746  }
747 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
TVector2 WireDriftToCm(detinfo::DetectorPropertiesData const &detProp, unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:294
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:92
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 752 of file ProjectionMatchingAlg.cxx.

757 {
758  hits_out.clear();
759 
760  const double gapMargin = 5.0; // can be changed to f(id_tpc1, id_tpc2)
761  size_t idx = 0;
762 
763  while ((idx < hits_in.size()) && Has_(used, idx))
764  idx++;
765 
766  if (idx < hits_in.size()) {
767  hits_out.push_back(hits_in[idx]);
768  used.push_back(idx);
769 
770  unsigned int tpc = hits_in[idx]->WireID().TPC;
771  unsigned int cryo = hits_in[idx]->WireID().Cryostat;
772  unsigned int view = hits_in[idx]->WireID().Plane;
773  double wirePitch = fGeom->TPC(tpc, cryo).Plane(view).WirePitch();
774  double driftPitch = detProp.GetXTicksCoefficient(tpc, cryo);
775 
776  double r2d2 = r2d * r2d;
777  double gapMargin2 = sqrt(2 * gapMargin * gapMargin);
778  gapMargin2 = (gapMargin2 + r2d) * (gapMargin2 + r2d);
779 
780  bool collect = true;
781  while (collect) {
782  collect = false;
783  for (size_t i = 0; i < hits_in.size(); i++)
784  if (!Has_(used, i)) {
785  art::Ptr<recob::Hit> const& hi = hits_in[i];
786  TVector2 hi_cm(wirePitch * hi->WireID().Wire, driftPitch * hi->PeakTime());
787 
788  bool accept = false;
789 
790  for (auto const& ho : hits_out) {
791 
792  TVector2 ho_cm(wirePitch * ho->WireID().Wire, driftPitch * ho->PeakTime());
793  double d2 = pma::Dist2(hi_cm, ho_cm);
794 
795  if (d2 < r2d2) {
796  accept = true;
797  break;
798  }
799  }
800  if (accept) {
801  collect = true;
802  hits_out.push_back(hi);
803  used.push_back(i);
804  }
805  }
806  }
807  return true;
808  }
809  else
810  return false;
811 }
bool Has_(const std::vector< size_t > &v, size_t idx) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
double GetXTicksCoefficient(int t, int c) const
geo::GeometryCore const * fGeom
geo::WireID WireID() const
Definition: Hit.h:233
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:411
size_t pma::ProjectionMatchingAlg::getSegCount_ ( size_t  trk_size)
staticprivate

Definition at line 443 of file ProjectionMatchingAlg.cxx.

444 {
445  int const nSegments = 0.8 * trk_size / sqrt(trk_size);
446  return std::max(size_t{1}, static_cast<size_t>(nSegments));
447 }
static int max(int a, int b)
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 1095 of file ProjectionMatchingAlg.cxx.

1099 {
1100  unsigned int tpc = trk.FrontTPC(), cryo = trk.FrontCryo();
1101  if ((tpc != trk.BackTPC()) || (cryo != trk.BackCryo())) {
1102  mf::LogWarning("ProjectionMatchingAlg") << "Please, apply before TPC stitching.";
1103  return;
1104  }
1105 
1106  const double maxCosXZ = 0.992546; // 7 deg
1107 
1108  pma::Segment3D* segFront = trk.Segments().front();
1109  if (trk.Segments().size() > 2) {
1110  pma::Segment3D* segFront1 = trk.Segments()[1];
1111  if ((segFront->Length() < 0.8) && (segFront1->Length() > 5.0)) segFront = segFront1;
1112  }
1113  pma::Vector3D dirFront = segFront->GetDirection3D();
1114  pma::Vector3D dirFrontXZ(dirFront.X(), 0., dirFront.Z());
1115  dirFrontXZ *= 1.0 / dirFrontXZ.R();
1116 
1117  pma::Segment3D* segBack = trk.Segments().back();
1118  if (trk.Segments().size() > 2) {
1119  pma::Segment3D* segBack1 = trk.Segments()[trk.Segments().size() - 2];
1120  if ((segBack->Length() < 0.8) && (segBack1->Length() > 5.0)) segBack = segBack1;
1121  }
1122  pma::Vector3D dirBack = segBack->GetDirection3D();
1123  pma::Vector3D dirBackXZ(dirBack.X(), 0., dirBack.Z());
1124  dirBackXZ *= 1.0 / dirBackXZ.R();
1125 
1126  if ((fabs(dirFrontXZ.Z()) < maxCosXZ) && (fabs(dirBackXZ.Z()) < maxCosXZ)) {
1127  return; // front & back are not parallel to wire planes => exit
1128  }
1129 
1130  unsigned int nPlanesFront = 0, nPlanesBack = 0;
1131  std::pair<int, int> wiresFront[3], wiresBack[3]; // wire index; index direction
1132  double xFront[3], xBack[3];
1133 
1134  for (unsigned int i = 0; i < 3; i++) {
1135  bool frontPresent = false, backPresent = false;
1136  if (fGeom->TPC(tpc, cryo).HasPlane(i)) {
1137  int idxFront0 = trk.NextHit(-1, i);
1138  int idxBack0 = trk.PrevHit(trk.size(), i);
1139  if ((idxFront0 >= 0) && (idxFront0 < (int)trk.size()) && (idxBack0 >= 0) &&
1140  (idxBack0 < (int)trk.size())) {
1141  int idxFront1 = trk.NextHit(idxFront0, i);
1142  int idxBack1 = trk.PrevHit(idxBack0, i);
1143  if ((idxFront1 >= 0) && (idxFront1 < (int)trk.size()) && (idxBack1 >= 0) &&
1144  (idxBack1 < (int)trk.size())) {
1145  int wFront0 = trk[idxFront0]->Wire();
1146  int wBack0 = trk[idxBack0]->Wire();
1147 
1148  int wFront1 = trk[idxFront1]->Wire();
1149  int wBack1 = trk[idxBack1]->Wire();
1150 
1151  wiresFront[i].first = wFront0;
1152  wiresFront[i].second = wFront0 - wFront1;
1153  xFront[i] = detProp.ConvertTicksToX(trk[idxFront0]->PeakTime(), i, tpc, cryo);
1154 
1155  wiresBack[i].first = wBack0;
1156  wiresBack[i].second = wBack0 - wBack1;
1157  xBack[i] = detProp.ConvertTicksToX(trk[idxBack0]->PeakTime(), i, tpc, cryo);
1158 
1159  if (wiresFront[i].second) {
1160  if (wiresFront[i].second > 0)
1161  wiresFront[i].second = 1;
1162  else
1163  wiresFront[i].second = -1;
1164 
1165  frontPresent = true;
1166  nPlanesFront++;
1167  }
1168 
1169  if (wiresBack[i].second) {
1170  if (wiresBack[i].second > 0)
1171  wiresBack[i].second = 1;
1172  else
1173  wiresBack[i].second = -1;
1174 
1175  backPresent = true;
1176  nPlanesBack++;
1177  }
1178  }
1179  }
1180  }
1181  if (!frontPresent) { wiresFront[i].first = -1; }
1182  if (!backPresent) { wiresBack[i].first = -1; }
1183  }
1184 
1185  bool refAdded = false;
1186  if ((nPlanesFront > 1) && (fabs(dirFrontXZ.Z()) >= maxCosXZ)) {
1187  refAdded |= addEndpointRef_(detProp, trk, hits, wiresFront, xFront, tpc, cryo);
1188  }
1189 
1190  if ((nPlanesBack > 1) && (fabs(dirBackXZ.Z()) >= maxCosXZ)) {
1191  refAdded |= addEndpointRef_(detProp, trk, hits, wiresBack, xBack, tpc, cryo);
1192  }
1193  if (refAdded) {
1194  mf::LogVerbatim("ProjectionMatchingAlg") << "guide wire-plane-parallel track endpoints";
1195  double g = trk.Optimize(detProp, 0, 0.1 * fFineTuningEps);
1196  mf::LogVerbatim("ProjectionMatchingAlg") << " done, g = " << g;
1197  }
1198 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
Definition: TPCGeo.h:175
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
static constexpr double g
Definition: Units.h:144
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:927
geo::GeometryCore const * fGeom
unsigned int BackTPC() const
Definition: PmaTrack3D.h:156
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:31
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:161
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:326
unsigned int FrontTPC() const
Definition: PmaTrack3D.h:145
unsigned int FrontCryo() const
Definition: PmaTrack3D.h:150
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of this segment.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:909
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
size_t size() const
Definition: PmaTrack3D.h:108
double Length(void) const
Definition: PmaElement3D.h:52
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 1202 of file ProjectionMatchingAlg.cxx.

1207 {
1208  const double maxCosXZ = 0.992546; // 7 deg
1209 
1210  unsigned int tpc, cryo;
1211  pma::Segment3D* seg0 = 0;
1212  pma::Segment3D* seg1 = 0;
1213 
1214  if (endpoint == pma::Track3D::kBegin) {
1215  tpc = trk.FrontTPC(), cryo = trk.FrontCryo();
1216  seg0 = trk.Segments().front();
1217  if (trk.Segments().size() > 2) { seg1 = trk.Segments()[1]; }
1218  }
1219  else {
1220  tpc = trk.BackTPC(), cryo = trk.BackCryo();
1221  seg0 = trk.Segments().back();
1222  if (trk.Segments().size() > 2) { seg1 = trk.Segments()[trk.Segments().size() - 2]; }
1223  }
1224  if (seg1 && (seg0->Length() < 0.8) && (seg1->Length() > 5.0)) { seg0 = seg1; }
1225  pma::Vector3D dir0 = seg0->GetDirection3D();
1226  pma::Vector3D dir0XZ(dir0.X(), 0., dir0.Z());
1227  dir0XZ *= 1.0 / dir0XZ.R();
1228 
1229  if (fabs(dir0XZ.Z()) < maxCosXZ) { return; } // not parallel to wire planes => exit
1230 
1231  unsigned int nPlanes = 0;
1232  std::pair<int, int> wires[3]; // wire index; index direction
1233  double x0[3];
1234 
1235  for (unsigned int i = 0; i < 3; i++) {
1236  bool present = false;
1237  if (fGeom->TPC(tpc, cryo).HasPlane(i)) {
1238  int idx0 = -1, idx1 = -1;
1239  if (endpoint == pma::Track3D::kBegin) { idx0 = trk.NextHit(-1, i); }
1240  else {
1241  idx0 = trk.PrevHit(trk.size(), i);
1242  }
1243 
1244  if ((idx0 >= 0) && (idx0 < (int)trk.size()) && (trk[idx0]->TPC() == tpc) &&
1245  (trk[idx0]->Cryo() == cryo)) {
1246  if (endpoint == pma::Track3D::kBegin) { idx1 = trk.NextHit(idx0, i); }
1247  else {
1248  idx1 = trk.PrevHit(idx0, i);
1249  }
1250 
1251  if ((idx1 >= 0) && (idx1 < (int)trk.size()) && (trk[idx1]->TPC() == tpc) &&
1252  (trk[idx1]->Cryo() == cryo)) {
1253  int w0 = trk[idx0]->Wire();
1254  int w1 = trk[idx1]->Wire();
1255 
1256  wires[i].first = w0;
1257  wires[i].second = w0 - w1;
1258  x0[i] = detProp.ConvertTicksToX(trk[idx0]->PeakTime(), i, tpc, cryo);
1259 
1260  if (wires[i].second) {
1261  if (wires[i].second > 0)
1262  wires[i].second = 1;
1263  else
1264  wires[i].second = -1;
1265 
1266  present = true;
1267  nPlanes++;
1268  }
1269  }
1270  }
1271  }
1272  if (!present) { wires[i].first = -1; }
1273  }
1274 
1275  if ((nPlanes > 1) && (fabs(dir0XZ.Z()) >= maxCosXZ) &&
1276  addEndpointRef_(detProp, trk, hits, wires, x0, tpc, cryo)) {
1277  mf::LogVerbatim("ProjectionMatchingAlg") << "guide wire-plane-parallel track endpoint";
1278  double g = trk.Optimize(detProp, 0, 0.1 * fFineTuningEps);
1279  mf::LogVerbatim("ProjectionMatchingAlg") << " done, g = " << g;
1280  }
1281 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
Definition: TPCGeo.h:175
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
static constexpr double g
Definition: Units.h:144
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:927
geo::GeometryCore const * fGeom
unsigned int BackTPC() const
Definition: PmaTrack3D.h:156
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:31
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:161
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:326
unsigned int FrontTPC() const
Definition: PmaTrack3D.h:145
unsigned int FrontCryo() const
Definition: PmaTrack3D.h:150
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of this segment.
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:909
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
size_t size() const
Definition: PmaTrack3D.h:108
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10
double Length(void) const
Definition: PmaElement3D.h:52
bool pma::ProjectionMatchingAlg::Has_ ( const std::vector< size_t > &  v,
size_t  idx 
) const
private

Definition at line 875 of file ProjectionMatchingAlg.cxx.

876 {
877  for (auto c : v)
878  if (c == idx) return true;
879  return false;
880 }
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 160 of file ProjectionMatchingAlg.h.

161  {
162  return (trk.FirstElement()->SameTPC(trk.front()->Point3D(), margin) &&
163  trk.LastElement()->SameTPC(trk.back()->Point3D(), margin));
164  }
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
pma::Node3D * FirstElement() const
Definition: PmaTrack3D.h:340
pma::Node3D * LastElement() const
Definition: PmaTrack3D.h:345
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:102
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:103
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 1334 of file ProjectionMatchingAlg.cxx.

1338 {
1339  if (!alignTracks(dst, src)) return;
1340 
1341  unsigned int tpc = src.FrontTPC();
1342  unsigned int cryo = src.FrontCryo();
1343  double lmean = dst.Length() / (dst.Nodes().size() - 1);
1344  if ((pma::Dist2(dst.Nodes().back()->Point3D(), src.Nodes().front()->Point3D()) > 0.5 * lmean) ||
1345  (tpc != dst.BackTPC()) || (cryo != dst.BackCryo())) {
1346  dst.AddNode(detProp, src.Nodes().front()->Point3D(), tpc, cryo);
1347  if (src.Nodes().front()->IsFrozen()) dst.Nodes().back()->SetFrozen(true);
1348  }
1349  for (size_t n = 1; n < src.Nodes().size(); n++) {
1350  pma::Node3D* node = src.Nodes()[n];
1351 
1352  dst.AddNode(detProp, src.Nodes()[n]->Point3D(), node->TPC(), node->Cryo());
1353 
1354  if (node->IsFrozen()) dst.Nodes().back()->SetFrozen(true);
1355  }
1356  for (size_t h = 0; h < src.size(); h++) {
1357  dst.push_back(detProp, src[h]->Hit2DPtr());
1358  }
1359  if (reopt) {
1360  double g = dst.Optimize(detProp, 0, fFineTuningEps);
1361  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt after merging done, g = " << g;
1362  }
1363  else {
1364  dst.MakeProjection();
1365  }
1366 
1367  dst.SortHits();
1368  dst.ShiftEndsToHits();
1369 
1370  dst.MakeProjection();
1371  dst.SortHits();
1372 }
void MakeProjection()
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
static constexpr double g
Definition: Units.h:144
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
unsigned int BackTPC() const
Definition: PmaTrack3D.h:156
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:34
unsigned int BackCryo() const
Definition: PmaTrack3D.h:161
void AddNode(pma::Node3D *node)
bool alignTracks(pma::Track3D &first, pma::Track3D &second) const
std::void_t< T > n
unsigned int FrontTPC() const
Definition: PmaTrack3D.h:145
unsigned int FrontCryo() const
Definition: PmaTrack3D.h:150
void push_back(pma::Hit3D *hit)
Definition: PmaTrack3D.h:87
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
Definition: PmaElement3D.h:36
double Length(size_t step=1) const
Definition: PmaTrack3D.h:117
bool IsFrozen(void) const
Check if the vertex 3D position is fixed.
Definition: PmaElement3D.h:99
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:335
size_t size() const
Definition: PmaTrack3D.h:108
bool ShiftEndsToHits()
void pma::ProjectionMatchingAlg::RemoveNotEnabledHits ( pma::Track3D trk) const

Definition at line 885 of file ProjectionMatchingAlg.cxx.

886 {
887  size_t h = 0;
888  while (h < trk.size()) {
889  if (trk[h]->IsEnabled())
890  ++h;
891  else
892  (trk.release_at(h));
893  }
894 }
pma::Hit3D * release_at(size_t index)
Definition: PmaTrack3D.cxx:343
size_t size() const
Definition: PmaTrack3D.h:108
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 1376 of file ProjectionMatchingAlg.cxx.

1379 {
1380  for (size_t i = 0; i < trk.size(); i++) {
1381  pma::Hit3D* hit = trk[i];
1382  if (hit->View2D() == view) {
1383  if ((hit->GetDistToProj() > 0.5) || // more than 0.5cm away away from the segment
1384  (hit->GetSegFraction() < -1.0)) // projects before segment start (to check!!!)
1385  hit->TagOutlier(true);
1386  else
1387  hit->TagOutlier(false);
1388  }
1389  }
1390 
1391  unsigned int nhits = 0;
1392  double last_x, dx = 0.0, last_q, dq = 0.0, dqdx = 0.0;
1393  int ih = trk.NextHit(-1, view);
1394 
1395  pma::Hit3D* hit = trk[ih];
1396  pma::Hit3D* lastHit = hit;
1397 
1398  if ((ih >= 0) && (ih < (int)trk.size())) {
1399  hit->TagOutlier(true);
1400 
1401  ih = trk.NextHit(ih, view);
1402  while ((dx < 2.5) && (ih >= 0) && (ih < (int)trk.size())) {
1403  hit = trk[ih];
1404 
1405  if (util::absDiff(hit->Wire(), lastHit->Wire()) > 2) break; // break on gap in wire direction
1406 
1407  last_x = trk.HitDxByView(ih, view);
1408  last_q = hit->SummedADC();
1409  if (dx + last_x < 3.0) {
1410  dq += last_q;
1411  dx += last_x;
1412  nhits++;
1413  }
1414  else
1415  break;
1416 
1417  lastHit = hit;
1418  ih = trk.NextHit(ih, view);
1419  }
1420  while ((ih >= 0) && (ih < (int)trk.size())) {
1421  hit = trk[ih];
1422  hit->TagOutlier(true);
1423  ih = trk.NextHit(ih, view);
1424  }
1425  }
1426  else {
1427  mf::LogError("ProjectionMatchingAlg") << "Initial part selection failed.";
1428  }
1429 
1430  if (!nhits) {
1431  mf::LogError("ProjectionMatchingAlg") << "Initial part too short to select useful hits.";
1432  }
1433 
1434  if (dx > 0.0) dqdx = dq / dx;
1435 
1436  if (nused) (*nused) = nhits;
1437 
1438  return dqdx;
1439 }
void TagOutlier(bool state) noexcept
Definition: PmaHit3D.h:177
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned int Wire() const noexcept
Definition: PmaHit3D.h:98
float SummedADC() const noexcept
Definition: PmaHit3D.h:109
float GetSegFraction() const noexcept
Definition: PmaHit3D.h:143
Detector simulation of raw signals on wires.
constexpr auto absDiff(A const &a, B const &b)
Returns the absolute value of the difference between two values.
Definition: NumericUtils.h:43
unsigned int View2D() const noexcept
Definition: PmaHit3D.h:93
double GetDistToProj() const
Definition: PmaHit3D.h:136
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:909
double HitDxByView(size_t index, unsigned int view) const
size_t size() const
Definition: PmaTrack3D.h:108
void pma::ProjectionMatchingAlg::ShortenSeg_ ( const detinfo::DetectorPropertiesData detProp,
pma::Track3D trk,
const geo::TPCGeo tpcgeom 
) const
private

Definition at line 816 of file ProjectionMatchingAlg.cxx.

819 {
820  double mse = trk.GetMse();
821  mf::LogWarning("ProjectionMatchingAlg") << "initial value of mse: " << mse;
822  while ((mse > 0.5) && TestTrk_(trk, tpcgeom)) {
823  mse = trk.GetMse();
824  for (size_t h = 0; h < trk.size(); ++h)
825  if (std::sqrt(pma::Dist2(trk[h]->Point3D(), trk.front()->Point3D())) > 0.8 * trk.Length())
826  trk[h]->SetEnabled(false);
827 
829 
830  // trk.Optimize(0.0001, false); // BUG: first argument missing; tentatively:
831  trk.Optimize(detProp, 0, 0.0001, false);
832  trk.SortHits();
833 
834  mf::LogWarning("ProjectionMatchingAlg") << " mse: " << mse;
835  if (mse == trk.GetMse()) break;
836 
837  mse = trk.GetMse();
838  }
839 
841 }
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:37
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
::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:55
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:117
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:108
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 149 of file ProjectionMatchingAlg.h.

153  {
154  return trk.TestHits(detProp, hits, eps * fHitTestingDist2D);
155  }
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:858
bool pma::ProjectionMatchingAlg::TestTrk_ ( pma::Track3D trk,
const geo::TPCGeo tpcgeom 
) const
private

Definition at line 846 of file ProjectionMatchingAlg.cxx.

847 {
848  bool test = false;
849 
850  if (tpcgeom.HasPlane(0) && tpcgeom.HasPlane(1)) {
851  if ((trk.NEnabledHits(0) > 5) && (trk.NEnabledHits(1) > 5)) test = true;
852  }
853  else if (tpcgeom.HasPlane(0) && tpcgeom.HasPlane(2)) {
854  if ((trk.NEnabledHits(0) > 5) && (trk.NEnabledHits(2) > 5)) test = true;
855  }
856  else if (tpcgeom.HasPlane(1) && tpcgeom.HasPlane(2)) {
857  if ((trk.NEnabledHits(1) > 5) && (trk.NEnabledHits(2) > 5)) test = true;
858  }
859 
860  double length = 0.0;
861  for (size_t h = 0; h < trk.size(); ++h) {
862  if (!trk[h]->IsEnabled()) break;
863  length = std::sqrt(pma::Dist2(trk.front()->Point3D(), trk[h]->Point3D()));
864  }
865 
866  mf::LogWarning("ProjectionMatchingAlg") << "length of segment: " << length;
867  if (length < 3.0) test = false; // cm
868 
869  return test;
870 }
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
Definition: TPCGeo.h:175
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
unsigned int NEnabledHits(unsigned int view=geo::kUnknown) const
Definition: PmaTrack3D.cxx:432
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:108
std::vector< pma::Hit3D * > pma::ProjectionMatchingAlg::trimTrackToVolume ( pma::Track3D trk,
TVector3  p0,
TVector3  p1 
) const

Definition at line 1285 of file ProjectionMatchingAlg.cxx.

1286 {
1287  return {};
1288 }
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 421 of file ProjectionMatchingAlg.cxx.

422 {
423  trk.SelectHits();
424  trk.DisableSingleViewEnds();
425 
426  size_t idx = 0;
427  while ((idx < trk.size() - 1) && !trk[idx]->IsEnabled())
428  idx++;
429  double l0 = trk.Length(0, idx + 1);
430 
431  idx = trk.size() - 1;
432  while ((idx > 1) && !trk[idx]->IsEnabled())
433  idx--;
434  double l1 = trk.Length(idx - 1, trk.size() - 1);
435 
436  trk.SelectHits();
437 
438  return 1.0 - (l0 + l1) / trk.Length();
439 }
bool SelectHits(float fraction=1.0F)
unsigned int DisableSingleViewEnds()
double Length(size_t step=1) const
Definition: PmaTrack3D.h:117
size_t size() const
Definition: PmaTrack3D.h:108
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 254 of file ProjectionMatchingAlg.cxx.

258 {
259  if (hits.empty()) { return 0; }
260 
261  double max_d = fTrkValidationDist2D;
262  double d2, max_d2 = max_d * max_d;
263  unsigned int nAll = 0, nPassed = 0;
264  unsigned int testPlane = hits.front()->WireID().Plane;
265 
266  std::vector<unsigned int> trkTPCs = trk.TPCs();
267  std::vector<unsigned int> trkCryos = trk.Cryos();
268  std::map<std::pair<unsigned int, unsigned int>, std::pair<TVector2, TVector2>> ranges;
269  std::map<std::pair<unsigned int, unsigned int>, double> wirePitch;
270  for (auto const& [t, c] : views::cartesian_product(trkTPCs, trkCryos)) {
271  ranges[{t, c}] = trk.WireDriftRange(detProp, testPlane, t, c);
272  wirePitch[{t, c}] = fGeom->TPC(t, c).Plane(testPlane).WirePitch();
273  }
274 
275  unsigned int tpc, cryo;
276  std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
277 
278  for (auto const& h :
279  hits | views::transform(to_element) | views::filter(hits_on_plane{testPlane})) {
280  tpc = h.WireID().TPC;
281  cryo = h.WireID().Cryostat;
282  std::pair<unsigned int, unsigned int> tpc_cryo(tpc, cryo);
283  std::pair<TVector2, TVector2> rect = ranges[tpc_cryo];
284 
285  if ((h.WireID().Wire > rect.first.X() - 10) && // chceck only hits in the rectangle around
286  (h.WireID().Wire < rect.second.X() + 10) && // the track projection, it is faster than
287  (h.PeakTime() > rect.first.Y() - 100) && // calculation of trk.Dist2(p2d, testPlane)
288  (h.PeakTime() < rect.second.Y() + 100)) {
289  TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
290  detProp.ConvertTicksToX(h.PeakTime(), testPlane, tpc, cryo));
291 
292  d2 = trk.Dist2(p2d, testPlane, tpc, cryo);
293 
294  if (d2 < max_d2) all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y());
295  }
296  }
297 
298  // then check how points-close-to-the-track-projection are distributed along
299  // the track, namely: are there track sections crossing empty spaces, except
300  // dead wires?
302  trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
303  for (auto const* seg : trk.Segments()) {
304  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
305  {
306  p = seg->End();
307  continue;
308  }
309  pma::Vector3D p0 = seg->Start();
310  pma::Vector3D p1 = seg->End();
311 
312  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
313 
314  tpc = seg->TPC();
315  cryo = seg->Cryo();
316 
317  pma::Vector3D dc = step * seg->GetDirection3D();
318 
319  auto const& points = all_close_points[{tpc, cryo}];
320 
321  double f = pma::GetSegmentProjVector(p, p0, p1);
322 
323  double wirepitch = fGeom->TPC(tpc, cryo).Plane(testPlane).WirePitch();
324  while ((f < 1.0) && node->SameTPC(p)) {
325  pma::Vector2D p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
326  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
327  if (fGeom->HasWire(wireID)) {
329  if (channelStatus.IsGood(ch)) {
330  if (points.size()) {
331  p2d.SetX(wirepitch * p2d.X());
332  for (const auto& h : points) {
333  d2 = pma::Dist2(p2d, h);
334  if (d2 < max_d2) {
335  nPassed++;
336  break;
337  }
338  }
339  }
340  nAll++;
341  }
342  //else mf::LogVerbatim("ProjectionMatchingAlg")
343  // << "crossing BAD CHANNEL (wire #" << (int)p2d.X() << ")" << std::endl;
344  }
345 
346  p += dc;
347  f = pma::GetSegmentProjVector(p, p0, p1);
348  }
349  p = seg->End();
350  }
351 
352  if (nAll > 0) {
353  double v = nPassed / (double)nAll;
354  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
355  return v;
356  }
357 
358  return 1.0;
359 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
constexpr to_element_t to_element
Definition: ToElement.h:24
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:37
geo::GeometryCore const * fGeom
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:452
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:31
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:34
std::vector< unsigned int > Cryos() const
Definition: PmaTrack3D.cxx:471
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:326
p
Definition: test.py:223
virtual bool IsGood(raw::ChannelID_t channel) const
Returns whether the specified channel is physical and good.
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:102
double ConvertTicksToX(double ticks, int p, int t, int c) const
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:117
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:30
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
static unsigned filter(unsigned char *out, const unsigned char *in, unsigned w, unsigned h, const LodePNG_InfoColor *info)
Definition: lodepng.cpp:3576
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
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:411
std::pair< TVector2, TVector2 > WireDriftRange(detinfo::DetectorPropertiesData const &detProp, unsigned int view, unsigned int tpc, unsigned int cryo) const
Definition: PmaTrack3D.cxx:490
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.
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 46 of file ProjectionMatchingAlg.cxx.

51 {
52  unsigned int nAll = 0, nPassed = 0;
53  unsigned int testPlane = adcImage.Plane();
54 
55  std::vector<unsigned int> trkTPCs = trk.TPCs();
56  std::vector<unsigned int> trkCryos = trk.Cryos();
57 
58  // check how pixels with a high signal are distributed along the track
59  // namely: are there track sections crossing empty spaces, except dead wires?
61  trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
62  for (auto const* seg : trk.Segments()) {
63  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
64  {
65  p = seg->End();
66  continue;
67  }
68  pma::Vector3D p0 = seg->Start();
69  pma::Vector3D p1 = seg->End();
70 
71  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
72 
73  unsigned tpc = seg->TPC();
74  unsigned cryo = seg->Cryo();
75 
76  pma::Vector3D dc = step * seg->GetDirection3D();
77 
78  double f = pma::GetSegmentProjVector(p, p0, p1);
79  while ((f < 1.0) && node->SameTPC(p)) {
80  pma::Vector2D p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
81  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
82 
83  int widx = (int)p2d.X();
84  int didx = (int)detProp.ConvertXToTicks(p2d.Y(), testPlane, tpc, cryo);
85 
86  if (fGeom->HasWire(wireID)) {
88  if (channelStatus.IsGood(ch)) {
89  float max_adc = adcImage.poolMax(widx, didx, 2); // +/- 2 wires, can be parameterized
90  if (max_adc > thr) nPassed++;
91 
92  nAll++;
93  }
94  }
95 
96  p += dc;
97  f = pma::GetSegmentProjVector(p, p0, p1);
98  }
99 
100  p = seg->End(); // need to have it at the end due to the p in the first iter
101  // set to the hit position, not segment start
102  }
103 
104  if (nAll > 0) {
105  double v = nPassed / (double)nAll;
106  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
107  return v;
108  }
109 
110  return 1.0;
111 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
G4double thr[100]
Definition: G4S2Light.cc:59
geo::GeometryCore const * fGeom
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:452
unsigned int Plane() const
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:31
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:34
std::vector< unsigned int > Cryos() const
Definition: PmaTrack3D.cxx:471
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:326
p
Definition: test.py:223
double ConvertXToTicks(double X, int p, int t, int c) const
virtual bool IsGood(raw::ChannelID_t channel) const
Returns whether the specified channel is physical and good.
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:102
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:117
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:30
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.
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.
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.

134 {
135  double max_d = fTrkValidationDist2D;
136  double d2, max_d2 = max_d * max_d;
137  unsigned int nAll = 0, nPassed = 0;
138  unsigned int testPlane = adcImage.Plane();
139 
140  std::vector<unsigned int> trkTPCs = trk.TPCs();
141  std::vector<unsigned int> trkCryos = trk.Cryos();
142  std::map<std::pair<unsigned int, unsigned int>, std::pair<TVector2, TVector2>> ranges;
143  std::map<std::pair<unsigned int, unsigned int>, double> wirePitch;
144  for (auto const& [t, c] : views::cartesian_product(trkTPCs, trkCryos)) {
145  ranges[{t, c}] = trk.WireDriftRange(detProp, testPlane, t, c);
146  wirePitch[{t, c}] = fGeom->TPC(t, c).Plane(testPlane).WirePitch();
147  }
148 
149  unsigned int tpc, cryo;
150  std::map<std::pair<unsigned int, unsigned int>, std::vector<pma::Vector2D>> all_close_points;
151 
152  for (auto const& h :
153  hits | views::transform(to_element) | views::filter(hits_on_plane{testPlane})) {
154  tpc = h.WireID().TPC;
155  cryo = h.WireID().Cryostat;
156  std::pair<unsigned int, unsigned int> tpc_cryo(tpc, cryo);
157  std::pair<TVector2, TVector2> rect = ranges[tpc_cryo];
158 
159  if ((h.WireID().Wire > rect.first.X() - 10) && // check only hits in the rectangle around
160  (h.WireID().Wire < rect.second.X() + 10) && // the track projection, it is faster than
161  (h.PeakTime() > rect.first.Y() - 100) && // calculation of trk.Dist2(p2d, testPlane)
162  (h.PeakTime() < rect.second.Y() + 100)) {
163  TVector2 p2d(wirePitch[tpc_cryo] * h.WireID().Wire,
164  detProp.ConvertTicksToX(h.PeakTime(), testPlane, tpc, cryo));
165 
166  d2 = trk.Dist2(p2d, testPlane, tpc, cryo);
167 
168  if (d2 < max_d2) { all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y()); }
169  }
170  }
171 
172  // then check how points-close-to-the-track-projection are distributed along
173  // the track, namely: are there track sections crossing empty spaces, except
174  // dead wires?
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  double wirepitch = fGeom->TPC(tpc, cryo).Plane(testPlane).WirePitch();
198  while ((f < 1.0) && node->SameTPC(p)) {
199  pma::Vector2D p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
200  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
201 
202  int widx = (int)p2d.X();
203  int didx = (int)detProp.ConvertXToTicks(p2d.Y(), testPlane, tpc, cryo);
204 
205  if (fGeom->HasWire(wireID)) {
207  if (channelStatus.IsGood(ch)) {
208  bool is_close = false;
209  float max_adc = adcImage.poolMax(widx, didx, 2);
210 
211  if (points.size()) {
212  p2d.SetX(wirepitch * p2d.X());
213  for (const auto& h : points) {
214  d2 = pma::Dist2(p2d, h);
215  if (d2 < 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  //else mf::LogVerbatim("ProjectionMatchingAlg")
233  // << "crossing BAD CHANNEL (wire #" << (int)p2d.X() << ")" << std::endl;
234  }
235 
236  p += dc;
237  f = pma::GetSegmentProjVector(p, p0, p1);
238  }
239  p = seg->End();
240  }
241 
242  if (nAll > 0) {
243  double v = nPassed / (double)nAll;
244  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
245  return v;
246  }
247 
248  return 1.0;
249 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
constexpr to_element_t to_element
Definition: ToElement.h:24
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:37
geo::GeometryCore const * fGeom
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
std::vector< unsigned int > TPCs() const
Definition: PmaTrack3D.cxx:452
unsigned int Plane() const
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:31
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:34
std::vector< unsigned int > Cryos() const
Definition: PmaTrack3D.cxx:471
std::vector< pma::Segment3D * > const & Segments() const noexcept
Definition: PmaTrack3D.h:326
p
Definition: test.py:223
double ConvertXToTicks(double X, int p, int t, int c) const
virtual bool IsGood(raw::ChannelID_t channel) const
Returns whether the specified channel is physical and good.
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:102
double ConvertTicksToX(double ticks, int p, int t, int c) const
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:117
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:30
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
static unsigned filter(unsigned char *out, const unsigned char *in, unsigned w, unsigned h, const LodePNG_InfoColor *info)
Definition: lodepng.cpp:3576
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
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:411
std::pair< TVector2, TVector2 > WireDriftRange(detinfo::DetectorPropertiesData const &detProp, unsigned int view, unsigned int tpc, unsigned int cryo) const
Definition: PmaTrack3D.cxx:490
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.

Member Data Documentation

double const pma::ProjectionMatchingAlg::fFineTuningEps
private

Definition at line 317 of file ProjectionMatchingAlg.h.

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

Definition at line 329 of file ProjectionMatchingAlg.h.

double const pma::ProjectionMatchingAlg::fHitTestingDist2D
private

Definition at line 322 of file ProjectionMatchingAlg.h.

double const pma::ProjectionMatchingAlg::fMinTwoViewFraction
private

Definition at line 325 of file ProjectionMatchingAlg.h.

double const pma::ProjectionMatchingAlg::fOptimizationEps
private

Definition at line 313 of file ProjectionMatchingAlg.h.

double const pma::ProjectionMatchingAlg::fTrkValidationDist2D
private

Definition at line 320 of file ProjectionMatchingAlg.h.


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