LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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 pma::Track3D &trk, const img::DataProviderAlg &adcImage, float thr) const
 
double validate_on_adc_test (const pma::Track3D &trk, const img::DataProviderAlg &adcImage, const std::vector< art::Ptr< recob::Hit > > &hits, TH1F *histoPassing, TH1F *histoRejected) const
 
double validate (const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit > > &hits) const
 
double validate (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 (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 std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
 wire planes; number of segments used to create the track depends on the number of hits. More...
 
pma::Track3DbuildMultiTPCTrack (const std::vector< art::Ptr< recob::Hit > > &hits) const
 as far as hits origin from at least two wire planes. More...
 
pma::Track3DbuildShowerSeg (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. More...
 
pma::Track3DbuildSegment (const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
 
pma::Track3DbuildSegment (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 std::vector< art::Ptr< recob::Hit > > &hits, const TVector3 &point) const
 
void FilterOutSmallParts (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 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 (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). More...
 
void guideEndpoints (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 (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 (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 (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 (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 (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 fOptimizationEps
 
double fFineTuningEps
 
double fTrkValidationDist2D
 
double fHitTestingDist2D
 
double fMinTwoViewFraction
 
geo::GeometryCore const * fGeom
 
detinfo::DetectorProperties const * fDetProp
 

Detailed Description

Definition at line 52 of file ProjectionMatchingAlg.h.

Constructor & Destructor Documentation

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

Definition at line 17 of file ProjectionMatchingAlg.cxx.

References fDetProp, fFineTuningEps, fHitTestingDist2D, pma::ProjectionMatchingAlg::Config::FineTuningEps, fMinTwoViewFraction, fOptimizationEps, fTrkValidationDist2D, pma::ProjectionMatchingAlg::Config::HitTestingDist2D, pma::ProjectionMatchingAlg::Config::HitWeightU, pma::ProjectionMatchingAlg::Config::HitWeightV, pma::ProjectionMatchingAlg::Config::HitWeightZ, geo::kU, geo::kV, geo::kZ, pma::ProjectionMatchingAlg::Config::MinTwoViewFraction, pma::ProjectionMatchingAlg::Config::NodeMargin3D, pma::ProjectionMatchingAlg::Config::OptimizationEps, pma::Node3D::SetMargin(), pma::Element3D::SetOptFactor(), and pma::ProjectionMatchingAlg::Config::TrkValidationDist2D.

17  :
19  fDetProp(lar::providerFrom<detinfo::DetectorPropertiesService>())
20 {
21  fOptimizationEps = config.OptimizationEps();
22  fFineTuningEps = config.FineTuningEps();
23 
24  fTrkValidationDist2D = config.TrkValidationDist2D();
25  fHitTestingDist2D = config.HitTestingDist2D();
26 
27  fMinTwoViewFraction = config.MinTwoViewFraction();
28 
29  pma::Node3D::SetMargin(config.NodeMargin3D());
30 
31  pma::Element3D::SetOptFactor(geo::kU, config.HitWeightU());
32  pma::Element3D::SetOptFactor(geo::kV, config.HitWeightV());
33  pma::Element3D::SetOptFactor(geo::kZ, config.HitWeightZ());
34 
35  fDetProp = lar::providerFrom<detinfo::DetectorPropertiesService>();
36 }
detinfo::DetectorProperties const * fDetProp
static void SetOptFactor(unsigned int view, float value)
Definition: PmaElement3D.h:104
geo::GeometryCore const * fGeom
Planes which measure V.
Definition: geo_types.h:77
Planes which measure Z direction.
Definition: geo_types.h:79
static void SetMargin(double m)
Set allowed node position margin around TPC.
Definition: PmaNode3D.h:105
Planes which measure U.
Definition: geo_types.h:76
pma::ProjectionMatchingAlg::ProjectionMatchingAlg ( const fhicl::ParameterSet pset)
inline

Member Function Documentation

bool pma::ProjectionMatchingAlg::addEndpointRef ( 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 996 of file ProjectionMatchingAlg.cxx.

References pma::Track3D::AddRefPoint(), chkEndpointHits(), fGeom, hits(), geo::GeometryCore::IntersectionPoint(), pma::Track3D::size(), x, y, and z.

Referenced by autoFlip(), and guideEndpoints().

1000 {
1001  double x = 0.0, y = 0.0, z = 0.0;
1002  std::vector< std::pair<int, unsigned int> > wire_view;
1003  for (unsigned int i = 0; i < 3; i++)
1004  if (wires[i].first >= 0)
1005  {
1006  const auto hiter = hits.find(i);
1007  if (hiter != hits.end())
1008  {
1009  if (chkEndpointHits(wires[i].first, wires[i].second, xPos[i], i, tpc, cryo, trk, hiter->second))
1010  {
1011  x += xPos[i];
1012  wire_view.push_back(std::pair<int, unsigned int>(wires[i].first, i));
1013  }
1014  }
1015  }
1016  if (wire_view.size() > 1)
1017  {
1018  x /= wire_view.size();
1020  wire_view[0].first, wire_view[1].first,
1021  wire_view[0].second, wire_view[1].second,
1022  cryo, tpc, y, z);
1023  trk.AddRefPoint(x, y, z);
1024  mf::LogVerbatim("ProjectionMatchingAlg") << "trk tpc:" << tpc << " size:" << trk.size()
1025  << " add ref.point (" << x << "; " << y << "; " << z << ")";
1026  return true;
1027  }
1028  else
1029  {
1030  mf::LogVerbatim("ProjectionMatchingAlg") << "trk tpc:" << tpc << " size:" << trk.size()
1031  << " wire-plane-parallel track, but need two clean views of endpoint";
1032  return false;
1033  }
1034 }
Float_t x
Definition: compare.C:6
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
geo::GeometryCore const * fGeom
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:279
void AddRefPoint(const TVector3 &p)
Definition: PmaTrack3D.h:189
bool chkEndpointHits(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 IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
size_t size() const
Definition: PmaTrack3D.h:76
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 1265 of file ProjectionMatchingAlg.cxx.

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

Referenced by isContained(), and mergeTracks().

1266 {
1267  unsigned int k = 0;
1268  double distFF = pma::Dist2(first.front()->Point3D(), second.front()->Point3D());
1269  double dist = distFF;
1270 
1271  double distFB = pma::Dist2(first.front()->Point3D(), second.back()->Point3D());
1272  if (distFB < dist) { k = 1; dist = distFB; }
1273 
1274  double distBF = pma::Dist2(first.back()->Point3D(), second.front()->Point3D());
1275  if (distBF < dist) { k = 2; dist = distBF; }
1276 
1277  double distBB = pma::Dist2(first.back()->Point3D(), second.back()->Point3D());
1278  if (distBB < dist) { k = 3; dist = distBB; }
1279 
1280  switch (k) // flip to get dst end before src start, do not merge if track's order reversed
1281  {
1282  case 0: first.Flip(); break;
1283  case 1: mf::LogError("PMAlgTrackMaker") << "Tracks in reversed order."; return false;
1284  case 2: break;
1285  case 3: second.Flip(); break;
1286  default: throw cet::exception("pma::ProjectionMatchingAlg") << "alignTracks: should never happen." << std::endl;
1287  }
1288  return true;
1289 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
bool Flip(std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:499
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
pma::Hit3D *& back()
Definition: PmaTrack3D.h:74
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
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 235 of file ProjectionMatchingAlg.h.

References addEndpointRef(), pma::Track3D::AutoFlip(), chkEndpointHits(), dir, GetCloseHits(), getSegCount(), Has(), hits(), geo::kZ, n, selectInitialHits(), ShortenSeg(), TestTrk(), and lar::dump::vector().

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

as far as hits origin from at least two wire planes.

Build a track from sets of hits, multiple TPCs are OK (like taken from PFParticles),

Definition at line 481 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(), and isContained().

483 {
484  std::map< unsigned int, std::vector< art::Ptr<recob::Hit> > > hits_by_tpc;
485  for (auto const & h : hits)
486  {
487  hits_by_tpc[h->WireID().TPC].push_back(h);
488  }
489 
490  std::vector< pma::Track3D* > tracks;
491  for(auto const & hsel : hits_by_tpc)
492  {
493  //pma::Track3D* trk = buildTrack(hsel.second);
494  pma::Track3D* trk = buildSegment(hsel.second);
495  if (trk) tracks.push_back(trk);
496  }
497 
498  bool need_reopt = false;
499  while (tracks.size() > 1)
500  {
501  need_reopt = true;
502 
503  pma::Track3D* first = tracks.front();
504  pma::Track3D* best = 0;
505  double d, dmin = 1.0e12;
506  size_t t_best = 0, cfg = 0;
507  for (size_t t = 1; t < tracks.size(); ++t)
508  {
509  pma::Track3D* second = tracks[t];
510 
511  d = pma::Dist2(first->front()->Point3D(), second->front()->Point3D());
512  if (d < dmin) { dmin = d; best = second; t_best = t; cfg = 0; }
513 
514  d = pma::Dist2(first->front()->Point3D(), second->back()->Point3D());
515  if (d < dmin) { dmin = d; best = second; t_best = t; cfg = 1; }
516 
517  d = pma::Dist2(first->back()->Point3D(), second->front()->Point3D());
518  if (d < dmin) { dmin = d; best = second; t_best = t; cfg = 2; }
519 
520  d = pma::Dist2(first->back()->Point3D(), second->back()->Point3D());
521  if (d < dmin) { dmin = d; best = second; t_best = t; cfg = 3; }
522  }
523  if (best)
524  {
525  switch (cfg)
526  {
527  default:
528  case 0:
529  case 1:
530  mergeTracks(*best, *first, false);
531  tracks[0] = best; delete first; break;
532 
533  case 2:
534  case 3:
535  mergeTracks(*first, *best, false);
536  delete best; break;
537  }
538  tracks.erase(tracks.begin() + t_best);
539  }
540  else break; // should not happen
541  }
542 
543  pma::Track3D* trk = 0;
544  if (!tracks.empty())
545  {
546  trk = tracks.front();
547  if (need_reopt)
548  {
549  double g = trk->Optimize(0, fOptimizationEps);
550  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt after merging initial tpc segments: done, g = " << g;
551  }
552 
553  int nSegments = getSegCount(trk->size()) - trk->Segments().size() + 1;
554  if (nSegments > 0) // need to add segments
555  {
556  double g = 0.0;
557  size_t nNodes = (size_t)( nSegments - 1 ); // n nodes to add
558  if (nNodes)
559  {
560  mf::LogVerbatim("ProjectionMatchingAlg") << " optimize trk (add " << nSegments << " seg)";
561 
562  g = trk->Optimize(nNodes, fOptimizationEps, false, true, 25, 10); // build nodes
563  mf::LogVerbatim("ProjectionMatchingAlg") << " nodes done, g = " << g;
564  trk->SelectAllHits();
565  }
566  g = trk->Optimize(0, fFineTuningEps); // final tuning
567  mf::LogVerbatim("ProjectionMatchingAlg") << " tune done, g = " << g;
568  }
569  trk->SortHits();
570  }
571  return trk;
572 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
pma::Hit3D *& back()
Definition: PmaTrack3D.h:74
Float_t d
Definition: plot.C:237
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
static size_t getSegCount(size_t trk_size)
void SortHits(void)
size_t size() const
Definition: PmaTrack3D.h:76
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
bool SelectAllHits(void)
void mergeTracks(pma::Track3D &dst, pma::Track3D &src, bool reopt) const
pma::Track3D * pma::ProjectionMatchingAlg::buildSegment ( const std::vector< art::Ptr< recob::Hit > > &  hits_1,
const std::vector< art::Ptr< recob::Hit > > &  hits_2 = std::vector< art::Ptr<recob::Hit> >() 
) const

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 854 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(), isContained(), ems::EMShower3D::Make3DSeg(), shower::EMShowerAlg::MakeShower(), ems::EMShower3D::Reoptimize(), and ems::EMShower3D::Validate().

857 {
858  pma::Track3D* trk = new pma::Track3D();
859  trk->SetEndSegWeight(0.001F);
860  trk->AddHits(hits_1);
861  trk->AddHits(hits_2);
862 
863  if (trk->HasTwoViews() &&
864  (trk->TPCs().size() == 1)) // now only in single tpc
865  {
866  if (!trk->Initialize(0.001F))
867  {
868  mf::LogWarning("ProjectionMatchingAlg") << "initialization failed, delete segment";
869  delete trk;
870  return 0;
871  }
872  trk->Optimize(0, fFineTuningEps);
873 
874  trk->SortHits();
875  return trk;
876  }
877  else
878  {
879  mf::LogWarning("ProjectionMatchingAlg") << "need at least two views in single tpc";
880  delete trk;
881  return 0;
882  }
883 }
std::vector< unsigned int > TPCs(void) const
Definition: PmaTrack3D.cxx:437
void SetEndSegWeight(float value)
Definition: PmaTrack3D.h:271
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
bool HasTwoViews(size_t nmin=1) const
Definition: PmaTrack3D.cxx:428
bool Initialize(float initEndSegW=0.05F)
Definition: PmaTrack3D.cxx:84
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SortHits(void)
void AddHits(const std::vector< art::Ptr< recob::Hit > > &hits)
Definition: PmaTrack3D.cxx:393
pma::Track3D * pma::ProjectionMatchingAlg::buildSegment ( 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 886 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().

890 {
891  pma::Track3D* trk = buildSegment(hits_1, hits_2);
892 
893  if (trk)
894  {
895  double dfront = pma::Dist2(trk->front()->Point3D(), point);
896  double dback = pma::Dist2(trk->back()->Point3D(), point);
897  if (dfront > dback) trk->Flip();
898 
899  trk->Nodes().front()->SetPoint3D(point);
900  trk->Nodes().front()->SetFrozen(true);
901  trk->Optimize(0, fFineTuningEps);
902 
903  trk->SortHits();
904  }
905  return trk;
906 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
bool Flip(std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:499
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
pma::Hit3D *& back()
Definition: PmaTrack3D.h:74
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
void SortHits(void)
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
pma::Track3D * pma::ProjectionMatchingAlg::buildSegment ( 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 909 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().

912 {
913  pma::Track3D* trk = buildSegment(hits);
914 
915  if (trk)
916  {
917  double dfront = pma::Dist2(trk->front()->Point3D(), point);
918  double dback = pma::Dist2(trk->back()->Point3D(), point);
919  if (dfront > dback) trk->Flip();
920 
921  trk->Nodes().front()->SetPoint3D(point);
922  trk->Nodes().front()->SetFrozen(true);
923  trk->Optimize(0, fFineTuningEps);
924 
925  trk->SortHits();
926  }
927  return trk;
928 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
bool Flip(std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:499
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
pma::Hit3D *& back()
Definition: PmaTrack3D.h:74
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
void SortHits(void)
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
pma::Track3D * pma::ProjectionMatchingAlg::buildShowerSeg ( const std::vector< art::Ptr< recob::Hit > > &  hits,
const pma::Vector3D vtx 
) const

Build a shower segment from sets of hits and attached to the provided vertex.

Definition at line 576 of file ProjectionMatchingAlg.cxx.

References buildSegment(), geo::GeometryCore::Cryostat(), fGeom, FilterOutSmallParts(), geo::GeometryCore::FindCryostatAtPosition(), geo::GeometryCore::FindTPCAtPosition(), pma::GetProjectionToPlane(), geo::TPCGeo::HasPlane(), geo::GeometryCore::HasTPC(), hits(), ShortenSeg(), pma::Track3D::size(), geo::CryostatGeo::TPC(), and geo::TPCID::TPC.

Referenced by pma::PMAlgFitter::buildShowers(), and isContained().

579 {
580  double vtxarray[3] {vtx.X(), vtx.Y(), vtx.Z()};
581 
582  if (!fGeom->HasTPC(fGeom->FindTPCAtPosition(vtxarray))) return 0;
583 
584  TVector3 vtxv3(vtx.X(), vtx.Y(), vtx.Z());
585 
586  const size_t tpc = fGeom->FindTPCAtPosition(vtxarray).TPC;
587  const size_t cryo = fGeom->FindCryostatAtPosition(vtxarray);
588  const geo::TPCGeo& tpcgeom = fGeom->Cryostat(cryo).TPC(tpc);
589 
590  // use only hits from tpc where the vtx is
591  std::vector<art::Ptr<recob::Hit> > hitstpc;
592  for (size_t h = 0; h < hits.size(); ++h)
593  if (hits[h]->WireID().TPC == tpc)
594  hitstpc.push_back(hits[h]);
595 
596  if (!hitstpc.size()) return 0;
597 
598  std::vector<art::Ptr<recob::Hit> > hitstrk;
599  size_t view = 0; size_t countviews = 0;
600  while (view < 3)
601  {
602  mf::LogVerbatim("ProjectionMatchinAlg") << "collecting hits from view: " << view;
603  if (!tpcgeom.HasPlane(view)) {++view; continue;}
604 
605  // select hits only for a single view
606  std::vector<art::Ptr<recob::Hit> > hitsview;
607  for (size_t h = 0; h < hitstpc.size(); ++h)
608  if (hitstpc[h]->WireID().Plane == view)
609  hitsview.push_back(hitstpc[h]);
610  if (!hitsview.size()) {++view; continue;}
611 
612  // filter our small groups of hits, far from main shower
613  std::vector<art::Ptr<recob::Hit> > hitsfilter;
614  TVector2 proj_pr = pma::GetProjectionToPlane(vtxv3, view, tpc, cryo);
615 
616  mf::LogVerbatim("ProjectionMatchinAlg") << "start filter out: ";
617  FilterOutSmallParts(2.0, hitsview, hitsfilter, proj_pr);
618  mf::LogVerbatim("ProjectionMatchingAlg") << "after filter out";
619 
620  for (size_t h = 0; h < hitsfilter.size(); ++h)
621  hitstrk.push_back(hitsfilter[h]);
622 
623  if (hitsfilter.size() >= 5) countviews++;
624 
625  ++view;
626  }
627 
628  if (!hitstrk.size() || (countviews < 2))
629  {
630  mf::LogWarning("ProjectionMatchinAlg") << "too few hits, segment not built";
631  return 0;
632  }
633 
634  // hits are prepared, finally segment is built
635 
636  pma::Track3D* trk = new pma::Track3D();
637  trk = buildSegment(hitstrk, vtxv3);
638 
639  // make shorter segment to estimate direction more precise
640  ShortenSeg(*trk, tpcgeom);
641 
642  if (trk->size() < 10)
643  {
644  mf::LogWarning("ProjectionMatchingAlg") << "too short segment, delete segment";
645  delete trk;
646  return 0;
647  }
648 
649  return trk;
650 }
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:155
geo::GeometryCore const * fGeom
Geometry information for a single TPC.
Definition: TPCGeo.h:37
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
void ShortenSeg(pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
bool HasTPC(geo::TPCID const &tpcid) const
Returns whether we have the specified TPC.
void FilterOutSmallParts(double r2d, const std::vector< art::Ptr< recob::Hit > > &hits_in, std::vector< art::Ptr< recob::Hit > > &hits_out, const TVector2 &vtx2d) const
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:280
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
size_t size() const
Definition: PmaTrack3D.h:76
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 std::vector< art::Ptr< recob::Hit > > &  hits_1,
const std::vector< art::Ptr< recob::Hit > > &  hits_2 = std::vector< art::Ptr<recob::Hit> >() 
) const

wire planes; number of segments used to create the track depends on the number of hits.

Build a track from two sets of hits from single TPC, hits should origin from at least two

Definition at line 424 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 isContained(), and pma::PMAlgTracker::matchCluster().

427 {
428  pma::Track3D* trk = new pma::Track3D(); // track candidate
429  trk->AddHits(hits_1);
430  trk->AddHits(hits_2);
431 
432  mf::LogVerbatim("ProjectionMatchingAlg") << "track size: " << trk->size();
433  std::vector< unsigned int > tpcs = trk->TPCs();
434  for (size_t t = 0; t < tpcs.size(); ++t)
435  {
436  mf::LogVerbatim("ProjectionMatchingAlg") << " tpc:" << tpcs[t];
437  }
438  mf::LogVerbatim("ProjectionMatchingAlg")
439  << " #coll:" << trk->NHits(geo::kZ)
440  << " #ind2:" << trk->NHits(geo::kV)
441  << " #ind1:" << trk->NHits(geo::kU);
442 
443  size_t nSegments = getSegCount(trk->size());
444  size_t nNodes = (size_t)( nSegments - 1 ); // n nodes to add
445 
446  mf::LogVerbatim("ProjectionMatchingAlg") << " initialize trk";
447  if (!trk->Initialize())
448  {
449  mf::LogWarning("ProjectionMatchingAlg") << " initialization failed, delete trk";
450  delete trk;
451  return 0;
452  }
453 
454  double f = twoViewFraction(*trk);
455  if (f > fMinTwoViewFraction)
456  {
457  double g = 0.0;
458  mf::LogVerbatim("ProjectionMatchingAlg") << " optimize trk (" << nSegments << " seg)";
459  if (nNodes)
460  {
461  g = trk->Optimize(nNodes, fOptimizationEps, false, true, 25, 10); // build nodes
462  mf::LogVerbatim("ProjectionMatchingAlg") << " nodes done, g = " << g;
463  trk->SelectAllHits();
464  }
465  g = trk->Optimize(0, fFineTuningEps); // final tuning
466  mf::LogVerbatim("ProjectionMatchingAlg") << " tune done, g = " << g;
467 
468  trk->SortHits();
469  // trk->ShiftEndsToHits(); // not sure if useful already here
470  return trk;
471  }
472  else
473  {
474  mf::LogVerbatim("ProjectionMatchingAlg") << " clusters do not match, f = " << f;
475  delete trk;
476  return 0;
477  }
478 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< unsigned int > TPCs(void) const
Definition: PmaTrack3D.cxx:437
Planes which measure V.
Definition: geo_types.h:77
Planes which measure Z direction.
Definition: geo_types.h:79
TFile f
Definition: plotHisto.C:6
Planes which measure U.
Definition: geo_types.h:76
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:406
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
static size_t getSegCount(size_t trk_size)
bool Initialize(float initEndSegW=0.05F)
Definition: PmaTrack3D.cxx:84
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SortHits(void)
size_t size() const
Definition: PmaTrack3D.h:76
double twoViewFraction(pma::Track3D &trk) const
bool SelectAllHits(void)
void AddHits(const std::vector< art::Ptr< recob::Hit > > &hits)
Definition: PmaTrack3D.cxx:393
bool pma::ProjectionMatchingAlg::chkEndpointHits ( 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 963 of file ProjectionMatchingAlg.cxx.

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

Referenced by addEndpointRef(), and autoFlip().

968 {
969  size_t nCloseHits = 0;
970  int forwWires = 3, backWires = -1;
971  double xMargin = 0.4;
972  for (auto h : hits)
973  if ((view == (int)h->WireID().Plane) &&
974  (tpc == h->WireID().TPC) &&
975  (cryo == h->WireID().Cryostat))
976  {
977  bool found = false;
978  for (size_t ht = 0; ht < trk.size(); ht++)
979  if (trk[ht]->Hit2DPtr().key() == h.key())
980  {
981  found = true; break;
982  }
983  if (found) continue;
984 
985  int dw = wdir * (h->WireID().Wire - wire);
986  if ((dw <= forwWires) && (dw >= backWires))
987  {
988  double x = fDetProp->ConvertTicksToX(h->PeakTime(), view, tpc, cryo);
989  if (fabs(x - drift_x) < xMargin) nCloseHits++;
990  }
991  }
992  if (nCloseHits > 1) return false;
993  else return true;
994 }
Float_t x
Definition: compare.C:6
detinfo::DetectorProperties const * fDetProp
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
size_t size() const
Definition: PmaTrack3D.h:76
pma::Track3D * pma::ProjectionMatchingAlg::extendTrack ( const pma::Track3D trk,
const std::vector< art::Ptr< recob::Hit > > &  hits,
bool  add_nodes 
) const

Add more hits to an existing track, reoptimize, optionally add more nodes.

Definition at line 931 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(), isContained(), and pma::PMAlgTracker::reassignHits_1().

935 {
936  pma::Track3D* copy = new pma::Track3D(trk);
937  copy->AddHits(hits);
938 
939  mf::LogVerbatim("ProjectionMatchingAlg") << "ext. track size: " << copy->size()
940  << " #coll:" << copy->NHits(geo::kZ)
941  << " #ind2:" << copy->NHits(geo::kV)
942  << " #ind1:" << copy->NHits(geo::kU);
943 
944  if (add_nodes)
945  {
946  size_t nSegments = getSegCount(copy->size());
947  int nNodes = nSegments - copy->Nodes().size() + 1; // n nodes to add
948  if (nNodes < 0) nNodes = 0;
949 
950  if (nNodes)
951  {
952  mf::LogVerbatim("ProjectionMatchingAlg") << " add " << nNodes << " nodes";
953  copy->Optimize(nNodes, fOptimizationEps);
954  }
955  }
956  double g = copy->Optimize(0, fFineTuningEps);
957  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt done, g = " << g;
958 
959  return copy;
960 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Planes which measure V.
Definition: geo_types.h:77
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
Planes which measure Z direction.
Definition: geo_types.h:79
Planes which measure U.
Definition: geo_types.h:76
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:406
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
static size_t getSegCount(size_t trk_size)
size_t size() const
Definition: PmaTrack3D.h:76
void AddHits(const std::vector< art::Ptr< recob::Hit > > &hits)
Definition: PmaTrack3D.cxx:393
void pma::ProjectionMatchingAlg::FilterOutSmallParts ( 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 654 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), GetCloseHits(), and pma::WireDriftToCm().

Referenced by buildShowerSeg(), and isContained().

659 {
660  size_t min_size = hits_in.size() / 5;
661  if (min_size < 3) min_size = 3;
662 
663  std::vector<size_t> used;
664  std::vector< std::vector< art::Ptr<recob::Hit> > > sub_groups;
665  std::vector< art::Ptr<recob::Hit> > close_hits;
666 
667  float mindist2 = 99999.99; size_t id_sub_groups_save = 0; size_t id = 0;
668  while (GetCloseHits(r2d, hits_in, used, close_hits))
669  {
670 
671  sub_groups.emplace_back(close_hits);
672 
673  for (size_t h = 0; h < close_hits.size(); ++h)
674  {
675  TVector2 hi_cm = pma::WireDriftToCm(close_hits[h]->WireID().Wire,
676  close_hits[h]->PeakTime(),
677  close_hits[h]->WireID().Plane,
678  close_hits[h]->WireID().TPC,
679  close_hits[h]->WireID().Cryostat);
680 
681  float dist2 = pma::Dist2(hi_cm, vtx2d);
682  if (dist2 < mindist2)
683  {
684  id_sub_groups_save = id;
685  mindist2 = dist2;
686  }
687  }
688 
689  id++;
690  }
691 
692  for (size_t i = 0; i < sub_groups.size(); ++i)
693  {
694  if (i == id_sub_groups_save)
695  {
696  for (auto h : sub_groups[i]) hits_out.push_back(h);
697  }
698  }
699 
700  for (size_t i = 0; i < sub_groups.size(); ++i)
701  {
702  if ((i != id_sub_groups_save) && (hits_out.size() < 10) && (sub_groups[i].size() > min_size))
703  for (auto h : sub_groups[i]) hits_out.push_back(h);
704  }
705 }
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
bool GetCloseHits(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
TVector2 WireDriftToCm(unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:296
recob::tracking::Plane Plane
Definition: TrackState.h:17
bool pma::ProjectionMatchingAlg::GetCloseHits ( 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 709 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), fDetProp, fGeom, detinfo::DetectorProperties::GetXTicksCoefficient(), Has(), recob::Hit::PeakTime(), geo::TPCGeo::Plane(), geo::GeometryCore::TPC(), geo::WireID::Wire, recob::Hit::WireID(), and geo::PlaneGeo::WirePitch().

Referenced by autoFlip(), and FilterOutSmallParts().

714 {
715  hits_out.clear();
716 
717  const double gapMargin = 5.0; // can be changed to f(id_tpc1, id_tpc2)
718  size_t idx = 0;
719 
720  while ((idx < hits_in.size()) && Has(used, idx)) idx++;
721 
722  if (idx < hits_in.size())
723  {
724  hits_out.push_back(hits_in[idx]);
725  used.push_back(idx);
726 
727  unsigned int tpc = hits_in[idx]->WireID().TPC;
728  unsigned int cryo = hits_in[idx]->WireID().Cryostat;
729  unsigned int view = hits_in[idx]->WireID().Plane;
730  double wirePitch = fGeom->TPC(tpc, cryo).Plane(view).WirePitch();
731  double driftPitch = fDetProp->GetXTicksCoefficient(tpc, cryo);
732 
733  double r2d2 = r2d*r2d;
734  double gapMargin2 = sqrt(2 * gapMargin*gapMargin);
735  gapMargin2 = (gapMargin2 + r2d)*(gapMargin2 + r2d);
736 
737  bool collect = true;
738  while (collect)
739  {
740  collect = false;
741  for (size_t i = 0; i < hits_in.size(); i++)
742  if (!Has(used, i))
743  {
744  art::Ptr<recob::Hit> const & hi = hits_in[i];
745  TVector2 hi_cm(wirePitch * hi->WireID().Wire, driftPitch * hi->PeakTime());
746 
747  bool accept = false;
748 
749  for (auto const & ho : hits_out)
750  {
751 
752  TVector2 ho_cm(wirePitch * ho->WireID().Wire, driftPitch * ho->PeakTime());
753  double d2 = pma::Dist2(hi_cm, ho_cm);
754 
755  if (d2 < r2d2) { accept = true; break; }
756  }
757  if (accept)
758  {
759  collect = true;
760  hits_out.push_back(hi);
761  used.push_back(i);
762  }
763  }
764  }
765  return true;
766  }
767  else return false;
768 }
detinfo::DetectorProperties const * fDetProp
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
geo::GeometryCore const * fGeom
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
virtual double GetXTicksCoefficient(int t, int c) const =0
bool Has(const std::vector< size_t > &v, size_t idx) const
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
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:299
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:367
size_t pma::ProjectionMatchingAlg::getSegCount ( size_t  trk_size)
staticprivate

Definition at line 415 of file ProjectionMatchingAlg.cxx.

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

416 {
417  int nSegments = (int)( 0.8 * trk_size / sqrt(trk_size) );
418 
419  if (nSegments > 1) return (size_t)nSegments;
420  else return 1;
421 }
void pma::ProjectionMatchingAlg::guideEndpoints ( pma::Track3D trk,
const std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > &  hits 
) const

Add 3D reference points to clean endpoints of a track (both need to be in the same TPC).

Definition at line 1036 of file ProjectionMatchingAlg.cxx.

References addEndpointRef(), pma::Track3D::BackCryo(), pma::Track3D::BackTPC(), detinfo::DetectorProperties::ConvertTicksToX(), fDetProp, fFineTuningEps, fGeom, pma::Track3D::FrontCryo(), pma::Track3D::FrontTPC(), pma::Segment3D::GetDirection3D(), geo::TPCGeo::HasPlane(), hits(), pma::Element3D::Length(), pma::Track3D::NextHit(), pma::Track3D::Optimize(), pma::Track3D::PrevHit(), pma::Track3D::Segments(), pma::Track3D::size(), and geo::GeometryCore::TPC().

Referenced by pma::PMAlgTrackingBase::guideEndpoints(), and isContained().

1038 {
1039  unsigned int tpc = trk.FrontTPC(), cryo = trk.FrontCryo();
1040  if ((tpc != trk.BackTPC()) || (cryo != trk.BackCryo()))
1041  {
1042  mf::LogWarning("ProjectionMatchingAlg") << "Please, apply before TPC stitching.";
1043  return;
1044  }
1045 
1046  const double maxCosXZ = 0.992546; // 7 deg
1047 
1048  pma::Segment3D* segFront = trk.Segments().front();
1049  if (trk.Segments().size() > 2)
1050  {
1051  pma::Segment3D* segFront1 = trk.Segments()[1];
1052  if ((segFront->Length() < 0.8) && (segFront1->Length() > 5.0))
1053  segFront = segFront1;
1054  }
1055  pma::Vector3D dirFront = segFront->GetDirection3D();
1056  pma::Vector3D dirFrontXZ(dirFront.X(), 0., dirFront.Z());
1057  dirFrontXZ *= 1.0 / dirFrontXZ.R();
1058 
1059  pma::Segment3D* segBack = trk.Segments().back();
1060  if (trk.Segments().size() > 2)
1061  {
1062  pma::Segment3D* segBack1 = trk.Segments()[trk.Segments().size() - 2];
1063  if ((segBack->Length() < 0.8) && (segBack1->Length() > 5.0))
1064  segBack = segBack1;
1065  }
1066  pma::Vector3D dirBack = segBack->GetDirection3D();
1067  pma::Vector3D dirBackXZ(dirBack.X(), 0., dirBack.Z());
1068  dirBackXZ *= 1.0 / dirBackXZ.R();
1069 
1070  if ((fabs(dirFrontXZ.Z()) < maxCosXZ) && (fabs(dirBackXZ.Z()) < maxCosXZ))
1071  {
1072  return; // front & back are not parallel to wire planes => exit
1073  }
1074 
1075  unsigned int nPlanesFront = 0, nPlanesBack = 0;
1076  std::pair<int, int> wiresFront[3], wiresBack[3]; // wire index; index direction
1077  double xFront[3], xBack[3];
1078 
1079  for (unsigned int i = 0; i < 3; i++)
1080  {
1081  bool frontPresent = false, backPresent = false;
1082  if (fGeom->TPC(tpc, cryo).HasPlane(i))
1083  {
1084  int idxFront0 = trk.NextHit(-1, i);
1085  int idxBack0 = trk.PrevHit(trk.size(), i);
1086  if ((idxFront0 >= 0) && (idxFront0 < (int)trk.size()) &&
1087  (idxBack0 >= 0) && (idxBack0 < (int)trk.size()))
1088  {
1089  int idxFront1 = trk.NextHit(idxFront0, i);
1090  int idxBack1 = trk.PrevHit(idxBack0, i);
1091  if ((idxFront1 >= 0) && (idxFront1 < (int)trk.size()) &&
1092  (idxBack1 >= 0) && (idxBack1 < (int)trk.size()))
1093  {
1094  int wFront0 = trk[idxFront0]->Wire();
1095  int wBack0 = trk[idxBack0]->Wire();
1096 
1097  int wFront1 = trk[idxFront1]->Wire();
1098  int wBack1 = trk[idxBack1]->Wire();
1099 
1100  wiresFront[i].first = wFront0;
1101  wiresFront[i].second = wFront0 - wFront1;
1102  xFront[i] = fDetProp->ConvertTicksToX(trk[idxFront0]->PeakTime(), i, tpc, cryo);
1103 
1104  wiresBack[i].first = wBack0;
1105  wiresBack[i].second = wBack0 - wBack1;
1106  xBack[i] = fDetProp->ConvertTicksToX(trk[idxBack0]->PeakTime(), i, tpc, cryo);
1107 
1108  if (wiresFront[i].second)
1109  {
1110  if (wiresFront[i].second > 0) wiresFront[i].second = 1;
1111  else wiresFront[i].second = -1;
1112 
1113  frontPresent = true;
1114  nPlanesFront++;
1115  }
1116 
1117  if (wiresBack[i].second)
1118  {
1119  if (wiresBack[i].second > 0) wiresBack[i].second = 1;
1120  else wiresBack[i].second = -1;
1121 
1122  backPresent = true;
1123  nPlanesBack++;
1124  }
1125  }
1126  }
1127  }
1128  if (!frontPresent) { wiresFront[i].first = -1; }
1129  if (!backPresent) { wiresBack[i].first = -1; }
1130  }
1131 
1132  bool refAdded = false;
1133  if ((nPlanesFront > 1) && (fabs(dirFrontXZ.Z()) >= maxCosXZ))
1134  {
1135  refAdded |= addEndpointRef(trk, hits, wiresFront, xFront, tpc, cryo);
1136  }
1137 
1138  if ((nPlanesBack > 1) && (fabs(dirBackXZ.Z()) >= maxCosXZ))
1139  {
1140  refAdded |= addEndpointRef(trk, hits, wiresBack, xBack, tpc, cryo);
1141  }
1142  if (refAdded)
1143  {
1144  mf::LogVerbatim("ProjectionMatchingAlg") << "guide wire-plane-parallel track endpoints";
1145  double g = trk.Optimize(0, 0.1 * fFineTuningEps);
1146  mf::LogVerbatim("ProjectionMatchingAlg") << " done, g = " << g;
1147  }
1148 }
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:155
detinfo::DetectorProperties const * fDetProp
unsigned int FrontTPC(void) const
Definition: PmaTrack3D.h:104
unsigned int BackTPC(void) const
Definition: PmaTrack3D.h:107
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:877
bool addEndpointRef(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
geo::GeometryCore const * fGeom
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
unsigned int BackCryo(void) const
Definition: PmaTrack3D.h:108
double Optimize(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 FrontCryo(void) const
Definition: PmaTrack3D.h:105
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
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:861
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
size_t size() const
Definition: PmaTrack3D.h:76
double Length(void) const
Definition: PmaElement3D.h:49
void pma::ProjectionMatchingAlg::guideEndpoints ( 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 1151 of file ProjectionMatchingAlg.cxx.

References addEndpointRef(), pma::Track3D::BackCryo(), pma::Track3D::BackTPC(), detinfo::DetectorProperties::ConvertTicksToX(), fDetProp, fFineTuningEps, fGeom, pma::Track3D::FrontCryo(), pma::Track3D::FrontTPC(), pma::Segment3D::GetDirection3D(), geo::TPCGeo::HasPlane(), hits(), pma::Track3D::kBegin, pma::Element3D::Length(), pma::Track3D::NextHit(), pma::Track3D::Optimize(), art::productstatus::present(), pma::Track3D::PrevHit(), pma::Track3D::Segments(), pma::Track3D::size(), and geo::GeometryCore::TPC().

1154 {
1155  const double maxCosXZ = 0.992546; // 7 deg
1156 
1157  unsigned int tpc, cryo;
1158  pma::Segment3D* seg0 = 0;
1159  pma::Segment3D* seg1 = 0;
1160 
1161  if (endpoint == pma::Track3D::kBegin)
1162  {
1163  tpc = trk.FrontTPC(), cryo = trk.FrontCryo();
1164  seg0 = trk.Segments().front();
1165  if (trk.Segments().size() > 2)
1166  {
1167  seg1 = trk.Segments()[1];
1168  }
1169  }
1170  else
1171  {
1172  tpc = trk.BackTPC(), cryo = trk.BackCryo();
1173  seg0 = trk.Segments().back();
1174  if (trk.Segments().size() > 2)
1175  {
1176  seg1 = trk.Segments()[trk.Segments().size() - 2];
1177  }
1178  }
1179  if (seg1 && (seg0->Length() < 0.8) && (seg1->Length() > 5.0))
1180  {
1181  seg0 = seg1;
1182  }
1183  pma::Vector3D dir0 = seg0->GetDirection3D();
1184  pma::Vector3D dir0XZ(dir0.X(), 0., dir0.Z());
1185  dir0XZ *= 1.0 / dir0XZ.R();
1186 
1187  if (fabs(dir0XZ.Z()) < maxCosXZ) { return; } // not parallel to wire planes => exit
1188 
1189  unsigned int nPlanes = 0;
1190  std::pair<int, int> wires[3]; // wire index; index direction
1191  double x0[3];
1192 
1193  for (unsigned int i = 0; i < 3; i++)
1194  {
1195  bool present = false;
1196  if (fGeom->TPC(tpc, cryo).HasPlane(i))
1197  {
1198  int idx0 = -1, idx1 = -1;
1199  if (endpoint == pma::Track3D::kBegin)
1200  {
1201  idx0 = trk.NextHit(-1, i);
1202  }
1203  else
1204  {
1205  idx0 = trk.PrevHit(trk.size(), i);
1206  }
1207 
1208  if ((idx0 >= 0) && (idx0 < (int)trk.size()) &&
1209  (trk[idx0]->TPC() == tpc) && (trk[idx0]->Cryo() == cryo))
1210  {
1211  if (endpoint == pma::Track3D::kBegin)
1212  {
1213  idx1 = trk.NextHit(idx0, i);
1214  }
1215  else
1216  {
1217  idx1 = trk.PrevHit(idx0, i);
1218  }
1219 
1220  if ((idx1 >= 0) && (idx1 < (int)trk.size()) &&
1221  (trk[idx1]->TPC() == tpc) && (trk[idx1]->Cryo() == cryo))
1222  {
1223  int w0 = trk[idx0]->Wire();
1224  int w1 = trk[idx1]->Wire();
1225 
1226  wires[i].first = w0;
1227  wires[i].second = w0 - w1;
1228  x0[i] = fDetProp->ConvertTicksToX(trk[idx0]->PeakTime(), i, tpc, cryo);
1229 
1230  if (wires[i].second)
1231  {
1232  if (wires[i].second > 0) wires[i].second = 1;
1233  else wires[i].second = -1;
1234 
1235  present = true;
1236  nPlanes++;
1237  }
1238  }
1239  }
1240  }
1241  if (!present) { wires[i].first = -1; }
1242  }
1243 
1244  if ((nPlanes > 1) && (fabs(dir0XZ.Z()) >= maxCosXZ) &&
1245  addEndpointRef(trk, hits, wires, x0, tpc, cryo))
1246  {
1247  mf::LogVerbatim("ProjectionMatchingAlg") << "guide wire-plane-parallel track endpoint";
1248  double g = trk.Optimize(0, 0.1 * fFineTuningEps);
1249  mf::LogVerbatim("ProjectionMatchingAlg") << " done, g = " << g;
1250  }
1251 }
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:155
detinfo::DetectorProperties const * fDetProp
unsigned int FrontTPC(void) const
Definition: PmaTrack3D.h:104
unsigned int BackTPC(void) const
Definition: PmaTrack3D.h:107
int PrevHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:877
bool addEndpointRef(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
geo::GeometryCore const * fGeom
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
unsigned int BackCryo(void) const
Definition: PmaTrack3D.h:108
double Optimize(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 FrontCryo(void) const
Definition: PmaTrack3D.h:105
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
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:861
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
size_t size() const
Definition: PmaTrack3D.h:76
ProductStatus present()
Definition: ProductStatus.h:16
double Length(void) const
Definition: PmaElement3D.h:49
bool pma::ProjectionMatchingAlg::Has ( const std::vector< size_t > &  v,
size_t  idx 
) const
private

Definition at line 834 of file ProjectionMatchingAlg.cxx.

Referenced by autoFlip(), and GetCloseHits().

835 {
836  for (auto c : v) if (c == idx) return true;
837  return false;
838 }
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 153 of file ProjectionMatchingAlg.h.

References alignTracks(), pma::Track3D::back(), buildMultiTPCTrack(), buildSegment(), buildShowerSeg(), buildTrack(), extendTrack(), FilterOutSmallParts(), pma::Track3D::FirstElement(), pma::Track3D::front(), guideEndpoints(), hits(), pma::Track3D::LastElement(), mergeTracks(), pma::Hit3D::Point3D(), RemoveNotEnabledHits(), pma::Node3D::SameTPC(), trimTrackToVolume(), and lar::dump::vector().

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

154  {
155  return (trk.FirstElement()->SameTPC(trk.front()->Point3D(), margin) &&
156  trk.LastElement()->SameTPC(trk.back()->Point3D(), margin));
157  }
pma::Node3D * LastElement(void) const
Definition: PmaTrack3D.h:234
pma::Hit3D *& back()
Definition: PmaTrack3D.h:74
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:83
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
pma::Node3D * FirstElement(void) const
Definition: PmaTrack3D.h:233
void pma::ProjectionMatchingAlg::mergeTracks ( 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 1291 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(), isContained(), and pma::PMAlgTracker::mergeCoLinear().

1292 {
1293  if (!alignTracks(dst, src)) return;
1294 
1295  unsigned int tpc = src.FrontTPC();
1296  unsigned int cryo = src.FrontCryo();
1297  double lmean = dst.Length() / (dst.Nodes().size() - 1);
1298  if ((pma::Dist2(
1299  dst.Nodes().back()->Point3D(),
1300  src.Nodes().front()->Point3D()) > 0.5 * lmean) ||
1301  (tpc != dst.BackTPC()) || (cryo != dst.BackCryo()))
1302  {
1303  dst.AddNode(src.Nodes().front()->Point3D(), tpc, cryo);
1304  if (src.Nodes().front()->IsFrozen())
1305  dst.Nodes().back()->SetFrozen(true);
1306  }
1307  for (size_t n = 1; n < src.Nodes().size(); n++)
1308  {
1309  pma::Node3D* node = src.Nodes()[n];
1310 
1311  dst.AddNode(src.Nodes()[n]->Point3D(),
1312  node->TPC(), node->Cryo());
1313 
1314  if (node->IsFrozen())
1315  dst.Nodes().back()->SetFrozen(true);
1316  }
1317  for (size_t h = 0; h < src.size(); h++)
1318  {
1319  dst.push_back(src[h]->Hit2DPtr());
1320  }
1321  if (reopt)
1322  {
1323  double g = dst.Optimize(0, fFineTuningEps);
1324  mf::LogVerbatim("ProjectionMatchingAlg") << " reopt after merging done, g = " << g;
1325  }
1326  else
1327  {
1328  dst.MakeProjection();
1329  }
1330 
1331  dst.SortHits();
1332  dst.ShiftEndsToHits();
1333 
1334  dst.MakeProjection();
1335  dst.SortHits();
1336 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
unsigned int FrontTPC(void) const
Definition: PmaTrack3D.h:104
unsigned int BackTPC(void) const
Definition: PmaTrack3D.h:107
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:31
bool ShiftEndsToHits(void)
void AddNode(pma::Node3D *node)
bool alignTracks(pma::Track3D &first, pma::Track3D &second) const
unsigned int BackCryo(void) const
Definition: PmaTrack3D.h:108
double Optimize(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 FrontCryo(void) const
Definition: PmaTrack3D.h:105
void push_back(pma::Hit3D *hit)
Definition: PmaTrack3D.h:66
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
Definition: PmaElement3D.h:33
double Length(size_t step=1) const
Definition: PmaTrack3D.h:81
bool IsFrozen(void) const
Check if the vertex 3D position is fixed.
Definition: PmaElement3D.h:96
void MakeProjection(void)
Char_t n[5]
void SortHits(void)
size_t size() const
Definition: PmaTrack3D.h:76
void pma::ProjectionMatchingAlg::RemoveNotEnabledHits ( pma::Track3D trk) const

Definition at line 842 of file ProjectionMatchingAlg.cxx.

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

Referenced by isContained(), and ShortenSeg().

843 {
844  size_t h = 0;
845  while (h < trk.size())
846  {
847  if (trk[h]->IsEnabled()) ++h;
848  else (trk.release_at(h));
849  }
850 }
pma::Hit3D * release_at(size_t index)
Definition: PmaTrack3D.cxx:340
size_t size() const
Definition: PmaTrack3D.h:76
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 1339 of file ProjectionMatchingAlg.cxx.

References 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 autoFlip(), ems::EMShower3D::ConvertFrom(), and ems::EMShower3D::ConvertFrom2().

1340 {
1341  for (size_t i = 0; i < trk.size(); i++)
1342  {
1343  pma::Hit3D* hit = trk[i];
1344  if (hit->View2D() == view)
1345  {
1346  if ((hit->GetDistToProj() > 0.5) || // more than 0.5cm away away from the segment
1347  (hit->GetSegFraction() < -1.0)) // projects before segment start (to check!!!)
1348  hit->TagOutlier(true);
1349  else hit->TagOutlier(false);
1350  }
1351  }
1352 
1353  unsigned int nhits = 0;
1354  double last_x, dx = 0.0, last_q, dq = 0.0, dqdx = 0.0;
1355  int ih = trk.NextHit(-1, view);
1356 
1357  pma::Hit3D* hit = trk[ih];
1358  pma::Hit3D* lastHit = hit;
1359 
1360  if ((ih >= 0) && (ih < (int)trk.size()))
1361  {
1362  hit->TagOutlier(true);
1363 
1364  ih = trk.NextHit(ih, view);
1365  while ((dx < 2.5) && (ih >= 0) && (ih < (int)trk.size()))
1366  {
1367  hit = trk[ih];
1368 
1369  if (util::absDiff(hit->Wire(), lastHit->Wire()) > 2)
1370  break; // break on gap in wire direction
1371 
1372  last_x = trk.HitDxByView(ih, view);
1373  last_q = hit->SummedADC();
1374  if (dx + last_x < 3.0)
1375  {
1376  dq += last_q;
1377  dx += last_x;
1378  nhits++;
1379  }
1380  else break;
1381 
1382  lastHit = hit;
1383  ih = trk.NextHit(ih, view);
1384  }
1385  while ((ih >= 0) && (ih < (int)trk.size()))
1386  {
1387  hit = trk[ih];
1388  hit->TagOutlier(true);
1389  ih = trk.NextHit(ih, view);
1390  }
1391  }
1392  else { mf::LogError("ProjectionMatchingAlg") << "Initial part selection failed."; }
1393 
1394  if (!nhits) { mf::LogError("ProjectionMatchingAlg") << "Initial part too short to select useful hits."; }
1395 
1396  if (dx > 0.0) dqdx = dq / dx;
1397 
1398  if (nused) (*nused) = nhits;
1399 
1400  //std::cout << "nhits=" << nhits << ", dq=" << dq << ", dx=" << dx << std::endl;
1401  return dqdx;
1402 }
double GetDistToProj(void) const
Definition: PmaHit3D.h:69
unsigned int View2D(void) const
Definition: PmaHit3D.h:58
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned int Wire(void) const
Definition: PmaHit3D.h:59
float GetSegFraction() const
Definition: PmaHit3D.h:72
float SummedADC(void) const
Definition: PmaHit3D.h:62
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
virtual void TagOutlier(bool state)
Definition: PmaHit3D.h:86
int NextHit(int index, unsigned int view=geo::kZ, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:861
double HitDxByView(size_t index, unsigned int view) const
Definition: PmaTrack3D.cxx:952
size_t size() const
Definition: PmaTrack3D.h:76
void pma::ProjectionMatchingAlg::ShortenSeg ( pma::Track3D trk,
const geo::TPCGeo tpcgeom 
) const
private

Definition at line 772 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 autoFlip(), and buildShowerSeg().

773 {
774  double mse = trk.GetMse();
775  mf::LogWarning("ProjectionMatchingAlg") << "initial value of mse: " << mse;
776  while ((mse > 0.5) && TestTrk(trk, tpcgeom))
777  {
778  mse = trk.GetMse();
779  for (size_t h = 0; h < trk.size(); ++h)
780  if (std::sqrt(pma::Dist2(trk[h]->Point3D(), trk.front()->Point3D()))
781  > 0.8*trk.Length()) trk[h]->SetEnabled(false);
782 
784 
785  // trk.Optimize(0.0001, false); // BUG: first argument missing; tentatively:
786  trk.Optimize(0, 0.0001, false);
787  trk.SortHits();
788 
789  mf::LogWarning("ProjectionMatchingAlg") << " mse: " << mse;
790  if (mse == trk.GetMse()) break;
791  else mse = trk.GetMse();
792  }
793 
795 }
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:19
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
double Length(size_t step=1) const
Definition: PmaTrack3D.h:81
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SortHits(void)
size_t size() const
Definition: PmaTrack3D.h:76
void RemoveNotEnabledHits(pma::Track3D &trk) const
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
bool TestTrk(pma::Track3D &trk, const geo::TPCGeo &tpcgeom) const
unsigned int pma::ProjectionMatchingAlg::testHits ( 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 146 of file ProjectionMatchingAlg.h.

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

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

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

Definition at line 799 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), pma::Track3D::front(), geo::TPCGeo::HasPlane(), pma::Track3D::NEnabledHits(), pma::Hit3D::Point3D(), pma::Track3D::size(), and fhicl::has_insertion_operator_impl::test().

Referenced by autoFlip(), and ShortenSeg().

800 {
801  bool test = false;
802 
803  if (tpcgeom.HasPlane(0) && tpcgeom.HasPlane(1))
804  {
805  if ((trk.NEnabledHits(0) > 5) && (trk.NEnabledHits(1) > 5))
806  test = true;
807  }
808  else if (tpcgeom.HasPlane(0) && tpcgeom.HasPlane(2))
809  {
810  if ((trk.NEnabledHits(0) > 5) && (trk.NEnabledHits(2) > 5))
811  test = true;
812  }
813  else if (tpcgeom.HasPlane(1) && tpcgeom.HasPlane(2))
814  {
815  if ((trk.NEnabledHits(1) > 5) && (trk.NEnabledHits(2) > 5))
816  test = true;
817  }
818 
819  double length = 0.0;
820  for (size_t h = 0; h < trk.size(); ++h)
821  {
822  if (!trk[h]->IsEnabled()) break;
823  length = std::sqrt(pma::Dist2(trk.front()->Point3D(), trk[h]->Point3D()));
824  }
825 
826  mf::LogWarning("ProjectionMatchingAlg") << "length of segment: " << length;
827  if (length < 3.0) test = false; // cm
828 
829  return test;
830 }
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
Definition: TPCGeo.h:155
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
unsigned int NEnabledHits(unsigned int view=geo::kUnknown) const
Definition: PmaTrack3D.cxx:416
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
size_t size() const
Definition: PmaTrack3D.h:76
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
std::vector< pma::Hit3D * > pma::ProjectionMatchingAlg::trimTrackToVolume ( pma::Track3D trk,
TVector3  p0,
TVector3  p1 
) const

Definition at line 1254 of file ProjectionMatchingAlg.cxx.

Referenced by isContained().

1256 {
1257  std::vector< pma::Hit3D* > trimmedHits;
1258 
1259 
1260 
1261  return trimmedHits;
1262 }
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 396 of file ProjectionMatchingAlg.cxx.

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

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

397 {
398  trk.SelectHits();
399  trk.DisableSingleViewEnds();
400 
401  size_t idx = 0;
402  while ((idx < trk.size() - 1) && !trk[idx]->IsEnabled()) idx++;
403  double l0 = trk.Length(0, idx + 1);
404 
405  idx = trk.size() - 1;
406  while ((idx > 1) && !trk[idx]->IsEnabled()) idx--;
407  double l1 = trk.Length(idx - 1, trk.size() - 1);
408 
409  trk.SelectHits();
410 
411  return 1.0 - (l0 + l1) / trk.Length();
412 }
bool SelectHits(float fraction=1.0F)
unsigned int DisableSingleViewEnds(void)
double Length(size_t step=1) const
Definition: PmaTrack3D.h:81
size_t size() const
Definition: PmaTrack3D.h:76
double pma::ProjectionMatchingAlg::validate ( 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 231 of file ProjectionMatchingAlg.cxx.

References detinfo::DetectorProperties::ConvertTicksToX(), pma::Track3D::Cryos(), pma::Dist2(), pma::Track3D::Dist2(), f, fDetProp, fGeom, pma::Track3D::front(), fTrkValidationDist2D, pma::GetSegmentProjVector(), geo::GeometryCore::HasWire(), hits(), geo::TPCGeo::Plane(), geo::GeometryCore::PlaneWireToChannel(), pma::Hit3D::Point3D(), pma::Node3D::SameTPC(), pma::Track3D::Segments(), pma::Element3D::TPC(), geo::GeometryCore::TPC(), pma::Track3D::TPCs(), geo::GeometryCore::WireCoordinate(), pma::Track3D::WireDriftRange(), and geo::PlaneGeo::WirePitch().

Referenced by ProjectionMatchingAlg(), ems::EMShower3D::Validate(), and pma::PMAlgTracker::validate().

233 {
234  if (hits.empty()) { return 0; }
235 
236  double max_d = fTrkValidationDist2D;
237  double d2, max_d2 = max_d * max_d;
238  unsigned int nAll = 0, nPassed = 0;
239  unsigned int testPlane = hits.front()->WireID().Plane;
240 
241  std::vector< unsigned int > trkTPCs = trk.TPCs();
242  std::vector< unsigned int > trkCryos = trk.Cryos();
243  std::map< std::pair< unsigned int, unsigned int >, std::pair< TVector2, TVector2 > > ranges;
244  std::map< std::pair< unsigned int, unsigned int >, double > wirePitch;
245  for (auto c : trkCryos)
246  for (auto t : trkTPCs)
247  {
248  ranges[std::pair< unsigned int, unsigned int >(t, c)] = trk.WireDriftRange(testPlane, t, c);
249  wirePitch[std::pair< unsigned int, unsigned int >(t, c)] = fGeom->TPC(t, c).Plane(testPlane).WirePitch();
250  }
251 
252  unsigned int tpc, cryo;
253  std::map< std::pair< unsigned int, unsigned int >, std::vector< pma::Vector2D > > all_close_points;
254 
255  for (const auto h : hits)
256  if (h->WireID().Plane == testPlane)
257  {
258  tpc = h->WireID().TPC;
259  cryo = h->WireID().Cryostat;
260  std::pair< unsigned int, unsigned int > tpc_cryo(tpc, cryo);
261  std::pair< TVector2, TVector2 > rect = ranges[tpc_cryo];
262 
263  if ((h->WireID().Wire > rect.first.X() - 10) && // chceck only hits in the rectangle around
264  (h->WireID().Wire < rect.second.X() + 10) && // the track projection, it is faster than
265  (h->PeakTime() > rect.first.Y() - 100) && // calculation of trk.Dist2(p2d, testPlane)
266  (h->PeakTime() < rect.second.Y() + 100))
267  {
268  TVector2 p2d(wirePitch[tpc_cryo] * h->WireID().Wire, fDetProp->ConvertTicksToX(h->PeakTime(), testPlane, tpc, cryo));
269 
270  d2 = trk.Dist2(p2d, testPlane, tpc, cryo);
271 
272  if (d2 < max_d2) all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y());
273  }
274  }
275 
276  auto const & channelStatus = art::ServiceHandle< lariov::ChannelStatusService >()->GetProvider();
277 
278  double step = 0.3;
279  // then check how points-close-to-the-track-projection are distributed along the
280  // track, namely: are there track sections crossing empty spaces, except dead wires?
281  pma::Vector3D p(trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
282  for (auto const * seg : trk.Segments())
283  {
284  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
285  {
286  p = seg->End(); continue;
287  }
288  pma::Vector3D p0 = seg->Start();
289  pma::Vector3D p1 = seg->End();
290 
291  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
292 
293  tpc = seg->TPC(); cryo = seg->Cryo();
294 
295  pma::Vector3D dc = step * seg->GetDirection3D();
296 
297  auto const & points = all_close_points[std::pair< unsigned int, unsigned int >(tpc, cryo)];
298 
299  double f = pma::GetSegmentProjVector(p, p0, p1);
300 
301  double wirepitch = fGeom->TPC(tpc, cryo).Plane(testPlane).WirePitch();
302  while ((f < 1.0) && node->SameTPC(p))
303  {
304  pma::Vector2D p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
305  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
306  if (fGeom->HasWire(wireID))
307  {
309  if (channelStatus.IsGood(ch))
310  {
311  if (points.size())
312  {
313  p2d.SetX(wirepitch * p2d.X());
314  for (const auto & h : points)
315  {
316  d2 = pma::Dist2(p2d, h);
317  if (d2 < max_d2) { nPassed++; break; }
318  }
319  }
320  nAll++;
321  }
322  //else mf::LogVerbatim("ProjectionMatchingAlg")
323  // << "crossing BAD CHANNEL (wire #" << (int)p2d.X() << ")" << std::endl;
324  }
325 
326  p += dc; f = pma::GetSegmentProjVector(p, p0, p1);
327  }
328  p = seg->End();
329  }
330 
331  if (nAll > 0)
332  {
333  double v = nPassed / (double)nAll;
334  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
335  return v;
336  }
337  else return 1.0;
338 }
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
std::vector< unsigned int > TPCs(void) const
Definition: PmaTrack3D.cxx:437
detinfo::DetectorProperties const * fDetProp
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:19
geo::GeometryCore const * fGeom
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:31
TFile f
Definition: plotHisto.C:6
std::pair< TVector2, TVector2 > WireDriftRange(unsigned int view, unsigned int tpc, unsigned int cryo) const
Definition: PmaTrack3D.cxx:469
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:28
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:83
std::vector< unsigned int > Cryos(void) const
Definition: PmaTrack3D.cxx:453
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
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:100
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:299
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:367
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.
double pma::ProjectionMatchingAlg::validate ( 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).

Definition at line 341 of file ProjectionMatchingAlg.cxx.

References pma::Dist2(), f, fGeom, fTrkValidationDist2D, pma::GetSegmentProjVector(), geo::GeometryCore::HasWire(), hits(), geo::TPCGeo::Plane(), geo::GeometryCore::PlaneWireToChannel(), geo::GeometryCore::TPC(), geo::GeometryCore::WireCoordinate(), pma::WireDriftToCm(), and geo::PlaneGeo::WirePitch().

345 {
346  double step = 0.3;
347  double max_d = fTrkValidationDist2D;
348  double d2, max_d2 = max_d * max_d;
349  unsigned int nAll = 0, nPassed = 0;
350 
351  TVector3 p(p0);
352  TVector3 dc(p1); dc -= p;
353  dc *= step / dc.Mag();
354 
355  auto const & channelStatus = art::ServiceHandle< lariov::ChannelStatusService >()->GetProvider();
356 
357  double f = pma::GetSegmentProjVector(p, p0, p1);
358  double wirepitch = fGeom->TPC(tpc, cryo).Plane(testPlane).WirePitch();
359  while (f < 1.0)
360  {
361  TVector2 p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
362  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
363  if (fGeom->HasWire(wireID))
364  {
366  if (channelStatus.IsGood(ch))
367  {
368  p2d.Set(wirepitch * p2d.X(), p2d.Y());
369  for (const auto & h : hits)
370  if ((h->WireID().Plane == testPlane) &&
371  (h->WireID().TPC == tpc) &&
372  (h->WireID().Cryostat == cryo))
373  {
374  d2 = pma::Dist2(p2d, pma::WireDriftToCm(h->WireID().Wire, h->PeakTime(), testPlane, tpc, cryo));
375  if (d2 < max_d2) { nPassed++; break; }
376  }
377  nAll++;
378  }
379  //else mf::LogVerbatim("ProjectionMatchingAlg")
380  // << "crossing BAD CHANNEL (wire #" << (int)p2d.X() << ")" << std::endl;
381  }
382 
383  p += dc; f = pma::GetSegmentProjVector(p, p0, p1);
384  }
385 
386  if (nAll > 3) // validate actually only if 2D projection in testPlane has some minimum length
387  {
388  double v = nPassed / (double)nAll;
389  mf::LogVerbatim("ProjectionMatchingAlg") << " segment fraction ok: " << v;
390  return v;
391  }
392  else return 1.0;
393 }
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
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
geo::GeometryCore const * fGeom
TFile f
Definition: plotHisto.C:6
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:100
TVector2 WireDriftToCm(unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:296
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:299
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:367
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.
double pma::ProjectionMatchingAlg::validate_on_adc ( 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 39 of file ProjectionMatchingAlg.cxx.

References detinfo::DetectorProperties::ConvertXToTicks(), pma::Track3D::Cryos(), f, fDetProp, fGeom, pma::Track3D::front(), pma::GetSegmentProjVector(), geo::GeometryCore::HasWire(), img::DataProviderAlg::Plane(), geo::GeometryCore::PlaneWireToChannel(), pma::Hit3D::Point3D(), img::DataProviderAlg::poolMax(), pma::Node3D::SameTPC(), pma::Track3D::Segments(), pma::Element3D::TPC(), pma::Track3D::TPCs(), and geo::GeometryCore::WireCoordinate().

Referenced by ProjectionMatchingAlg(), and pma::PMAlgTracker::validate().

41 {
42  unsigned int nAll = 0, nPassed = 0;
43  unsigned int testPlane = adcImage.Plane();
44 
45  std::vector< unsigned int > trkTPCs = trk.TPCs();
46  std::vector< unsigned int > trkCryos = trk.Cryos();
47 
48  unsigned int tpc, cryo;
49 
50  auto const & channelStatus = art::ServiceHandle< lariov::ChannelStatusService >()->GetProvider();
51 
52  double step = 0.3;
53  // check how pixels with a high signal are distributed along the track
54  // namely: are there track sections crossing empty spaces, except dead wires?
55  pma::Vector3D p(trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
56  for (auto const * seg : trk.Segments())
57  {
58  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
59  {
60  p = seg->End(); continue;
61  }
62  pma::Vector3D p0 = seg->Start();
63  pma::Vector3D p1 = seg->End();
64 
65  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
66 
67  tpc = seg->TPC(); cryo = seg->Cryo();
68 
69  pma::Vector3D dc = step * seg->GetDirection3D();
70 
71  double f = pma::GetSegmentProjVector(p, p0, p1);
72  while ((f < 1.0) && node->SameTPC(p))
73  {
74  pma::Vector2D p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
75  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
76 
77  int widx = (int)p2d.X();
78  int didx = (int)fDetProp->ConvertXToTicks(p2d.Y(), testPlane, tpc, cryo);
79 
80  if (fGeom->HasWire(wireID))
81  {
83  if (channelStatus.IsGood(ch))
84  {
85  float max_adc = adcImage.poolMax(widx, didx, 2); // +/- 2 wires, can be parameterized
86  if (max_adc > thr) nPassed++;
87 
88  nAll++;
89  }
90  //else mf::LogVerbatim("ProjectionMatchingAlg")
91  // << "crossing BAD CHANNEL (wire #" << (int)p2d.X() << ")" << std::endl;
92  }
93 
94  p += dc; f = pma::GetSegmentProjVector(p, p0, p1);
95  }
96 
97  p = seg->End(); // need to have it at the end due to the p in the first iter set to the hit position, not segment start
98  }
99 
100  if (nAll > 0)
101  {
102  double v = nPassed / (double)nAll;
103  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
104  return v;
105  }
106  else return 1.0;
107 }
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
std::vector< unsigned int > TPCs(void) const
Definition: PmaTrack3D.cxx:437
detinfo::DetectorProperties const * fDetProp
geo::GeometryCore const * fGeom
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:31
TFile f
Definition: plotHisto.C:6
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:28
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:83
unsigned int Plane(void) const
std::vector< unsigned int > Cryos(void) const
Definition: PmaTrack3D.cxx:453
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
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:100
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
float poolMax(int wire, int drift, size_t r=0) const
Pool max value in a patch around the wire/drift pixel.
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.
double pma::ProjectionMatchingAlg::validate_on_adc_test ( const pma::Track3D trk,
const img::DataProviderAlg adcImage,
const std::vector< art::Ptr< recob::Hit > > &  hits,
TH1F *  histoPassing,
TH1F *  histoRejected 
) const

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

References detinfo::DetectorProperties::ConvertTicksToX(), detinfo::DetectorProperties::ConvertXToTicks(), pma::Track3D::Cryos(), pma::Dist2(), pma::Track3D::Dist2(), f, fDetProp, fGeom, pma::Track3D::front(), fTrkValidationDist2D, pma::GetSegmentProjVector(), geo::GeometryCore::HasWire(), hits(), img::DataProviderAlg::Plane(), geo::TPCGeo::Plane(), geo::GeometryCore::PlaneWireToChannel(), pma::Hit3D::Point3D(), img::DataProviderAlg::poolMax(), pma::Node3D::SameTPC(), pma::Track3D::Segments(), pma::Element3D::TPC(), geo::GeometryCore::TPC(), pma::Track3D::TPCs(), geo::GeometryCore::WireCoordinate(), pma::Track3D::WireDriftRange(), and geo::PlaneGeo::WirePitch().

Referenced by ProjectionMatchingAlg(), and pma::PMAlgTracker::validate().

114 {
115  double max_d = fTrkValidationDist2D;
116  double d2, max_d2 = max_d * max_d;
117  unsigned int nAll = 0, nPassed = 0;
118  unsigned int testPlane = adcImage.Plane();
119 
120  std::vector< unsigned int > trkTPCs = trk.TPCs();
121  std::vector< unsigned int > trkCryos = trk.Cryos();
122  std::map< std::pair< unsigned int, unsigned int >, std::pair< TVector2, TVector2 > > ranges;
123  std::map< std::pair< unsigned int, unsigned int >, double > wirePitch;
124  for (auto c : trkCryos)
125  for (auto t : trkTPCs)
126  {
127  ranges[std::pair< unsigned int, unsigned int >(t, c)] = trk.WireDriftRange(testPlane, t, c);
128  wirePitch[std::pair< unsigned int, unsigned int >(t, c)] = fGeom->TPC(t, c).Plane(testPlane).WirePitch();
129  }
130 
131  unsigned int tpc, cryo;
132  std::map< std::pair< unsigned int, unsigned int >, std::vector< pma::Vector2D > > all_close_points;
133 
134  for (const auto h : hits)
135  if (h->WireID().Plane == testPlane)
136  {
137  tpc = h->WireID().TPC;
138  cryo = h->WireID().Cryostat;
139  std::pair< unsigned int, unsigned int > tpc_cryo(tpc, cryo);
140  std::pair< TVector2, TVector2 > rect = ranges[tpc_cryo];
141 
142  if ((h->WireID().Wire > rect.first.X() - 10) && // chceck only hits in the rectangle around
143  (h->WireID().Wire < rect.second.X() + 10) && // the track projection, it is faster than
144  (h->PeakTime() > rect.first.Y() - 100) && // calculation of trk.Dist2(p2d, testPlane)
145  (h->PeakTime() < rect.second.Y() + 100))
146  {
147  TVector2 p2d(wirePitch[tpc_cryo] * h->WireID().Wire, fDetProp->ConvertTicksToX(h->PeakTime(), testPlane, tpc, cryo));
148 
149  d2 = trk.Dist2(p2d, testPlane, tpc, cryo);
150 
151  if (d2 < max_d2) { all_close_points[tpc_cryo].emplace_back(p2d.X(), p2d.Y()); }
152  }
153  }
154 
155  auto const & channelStatus = art::ServiceHandle< lariov::ChannelStatusService >()->GetProvider();
156 
157  double step = 0.3;
158  // then check how points-close-to-the-track-projection are distributed along the
159  // track, namely: are there track sections crossing empty spaces, except dead wires?
160  pma::Vector3D p(trk.front()->Point3D().X(), trk.front()->Point3D().Y(), trk.front()->Point3D().Z());
161  for (auto const * seg : trk.Segments())
162  {
163  if (seg->TPC() < 0) // skip segments between tpc's, look only at those contained in tpc
164  {
165  p = seg->End(); continue;
166  }
167  pma::Vector3D p0 = seg->Start();
168  pma::Vector3D p1 = seg->End();
169 
170  pma::Node3D* node = static_cast<pma::Node3D*>(seg->Prev());
171 
172  tpc = seg->TPC(); cryo = seg->Cryo();
173 
174  pma::Vector3D dc = step * seg->GetDirection3D();
175 
176  auto const & points = all_close_points[std::pair< unsigned int, unsigned int >(tpc, cryo)];
177 
178  double f = pma::GetSegmentProjVector(p, p0, p1);
179 
180  double wirepitch = fGeom->TPC(tpc, cryo).Plane(testPlane).WirePitch();
181  while ((f < 1.0) && node->SameTPC(p))
182  {
183  pma::Vector2D p2d(fGeom->WireCoordinate(p.Y(), p.Z(), testPlane, tpc, cryo), p.X());
184  geo::WireID wireID(cryo, tpc, testPlane, (int)p2d.X());
185 
186  int widx = (int)p2d.X();
187  int didx = (int)fDetProp->ConvertXToTicks(p2d.Y(), testPlane, tpc, cryo);
188 
189  if (fGeom->HasWire(wireID))
190  {
192  if (channelStatus.IsGood(ch))
193  {
194  bool is_close = false;
195  float max_adc = adcImage.poolMax(widx, didx, 2);
196 
197  if (points.size())
198  {
199  p2d.SetX(wirepitch * p2d.X());
200  for (const auto & h : points)
201  {
202  d2 = pma::Dist2(p2d, h);
203  if (d2 < max_d2) { is_close = true; nPassed++; break; }
204  }
205  }
206  nAll++;
207 
208  // now fill the calibration histograms
209  if (is_close) { if (histoPassing) histoPassing->Fill(max_adc); }
210  else { if (histoRejected) histoRejected->Fill(max_adc); }
211  }
212  //else mf::LogVerbatim("ProjectionMatchingAlg")
213  // << "crossing BAD CHANNEL (wire #" << (int)p2d.X() << ")" << std::endl;
214  }
215 
216  p += dc; f = pma::GetSegmentProjVector(p, p0, p1);
217  }
218  p = seg->End();
219  }
220 
221  if (nAll > 0)
222  {
223  double v = nPassed / (double)nAll;
224  mf::LogVerbatim("ProjectionMatchingAlg") << " trk fraction ok: " << v;
225  return v;
226  }
227  else return 1.0;
228 }
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
std::vector< unsigned int > TPCs(void) const
Definition: PmaTrack3D.cxx:437
detinfo::DetectorProperties const * fDetProp
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:19
geo::GeometryCore const * fGeom
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:31
TFile f
Definition: plotHisto.C:6
std::pair< TVector2, TVector2 > WireDriftRange(unsigned int view, unsigned int tpc, unsigned int cryo) const
Definition: PmaTrack3D.cxx:469
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:28
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:83
unsigned int Plane(void) const
std::vector< unsigned int > Cryos(void) const
Definition: PmaTrack3D.cxx:453
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
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:100
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:299
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
float poolMax(int wire, int drift, size_t r=0) const
Pool max value in a patch around the wire/drift pixel.
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:367
bool HasWire(geo::WireID const &wireid) const
Returns whether we have the specified wire.

Member Data Documentation

detinfo::DetectorProperties const* pma::ProjectionMatchingAlg::fDetProp
private
double pma::ProjectionMatchingAlg::fFineTuningEps
private
geo::GeometryCore const* pma::ProjectionMatchingAlg::fGeom
private
double pma::ProjectionMatchingAlg::fHitTestingDist2D
private

Definition at line 282 of file ProjectionMatchingAlg.h.

Referenced by ProjectionMatchingAlg(), and testHits().

double pma::ProjectionMatchingAlg::fMinTwoViewFraction
private

Definition at line 284 of file ProjectionMatchingAlg.h.

Referenced by buildTrack(), and ProjectionMatchingAlg().

double pma::ProjectionMatchingAlg::fOptimizationEps
private
double pma::ProjectionMatchingAlg::fTrkValidationDist2D
private

Definition at line 281 of file ProjectionMatchingAlg.h.

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


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