LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
lar_cluster3d::VoronoiPathFinder Class Referenceabstract
Inheritance diagram for lar_cluster3d::VoronoiPathFinder:
lar_cluster3d::IClusterModAlg

Public Member Functions

 VoronoiPathFinder (const fhicl::ParameterSet &)
 Constructor. More...
 
 ~VoronoiPathFinder ()
 Destructor. More...
 
void configure (fhicl::ParameterSet const &pset) override
 
void initializeHistograms (art::TFileDirectory &) override
 Interface for initializing histograms if they are desired Note that the idea is to put hisgtograms in a subfolder. More...
 
void ModifyClusters (reco::ClusterParametersList &) const override
 Scan an input collection of clusters and modify those according to the specific implementing algorithm. More...
 
float getTimeToExecute () const override
 If monitoring, recover the time to execute a particular function. More...
 
virtual void configure (const fhicl::ParameterSet &)=0
 Interface for configuring the particular algorithm tool. More...
 

Private Types

using Point = std::tuple< float, float, const reco::ClusterHit3D * >
 
using PointList = std::list< Point >
 
using MinMaxPoints = std::pair< Point, Point >
 
using MinMaxPointPair = std::pair< MinMaxPoints, MinMaxPoints >
 

Private Member Functions

reco::ClusterParametersList::iterator breakIntoTinyBits (reco::ClusterParameters &cluster, reco::PrincipalComponents &lastPCA, reco::ClusterParametersList::iterator positionItr, reco::ClusterParametersList &outputClusterList, int level=0) const
 Use PCA to try to find path in cluster. More...
 
reco::ClusterParametersList::iterator subDivideCluster (reco::ClusterParameters &cluster, reco::ClusterParametersList::iterator positionItr, reco::ClusterParametersList &outputClusterList, int level=0) const
 Use PCA to try to find path in cluster. More...
 
bool makeCandidateCluster (Eigen::Vector3f &, reco::ClusterParameters &, reco::HitPairListPtr::iterator, reco::HitPairListPtr::iterator, int) const
 
float closestApproach (const Eigen::Vector3f &, const Eigen::Vector3f &, const Eigen::Vector3f &, const Eigen::Vector3f &, Eigen::Vector3f &, Eigen::Vector3f &) const
 
void buildConvexHull (reco::ClusterParameters &clusterParameters, int level=0) const
 
void buildVoronoiDiagram (reco::ClusterParameters &clusterParameters) const
 

Private Attributes

bool fEnableMonitoring
 FHICL parameters. More...
 
size_t fMinTinyClusterSize
 Minimum size for a "tiny" cluster. More...
 
float fTimeToProcess
 
bool fFillHistograms
 Histogram definitions. More...
 
TH1F * fTopNum3DHits
 
TH1F * fTopNumEdges
 
TH1F * fTopEigen21Ratio
 
TH1F * fTopEigen20Ratio
 
TH1F * fTopEigen10Ratio
 
TH1F * fTopPrimaryLength
 
TH1F * fSubNum3DHits
 
TH1F * fSubNumEdges
 
TH1F * fSubEigen21Ratio
 
TH1F * fSubEigen20Ratio
 
TH1F * fSubEigen10Ratio
 
TH1F * fSubPrimaryLength
 
TH1F * fSubCosToPrevPCA
 
TH1F * fSubCosExtToPCA
 
TH1F * fSubMaxDefect
 
TH1F * fSubUsedDefect
 
std::unique_ptr< lar_cluster3d::IClusterAlgfClusterAlg
 Tools. More...
 
PrincipalComponentsAlg fPCAAlg
 

Detailed Description

Definition at line 40 of file VoronoiPathFinder_tool.cc.

Member Typedef Documentation

Definition at line 118 of file VoronoiPathFinder_tool.cc.

using lar_cluster3d::VoronoiPathFinder::Point = std::tuple<float, float, const reco::ClusterHit3D*>
private

Definition at line 116 of file VoronoiPathFinder_tool.cc.

Definition at line 117 of file VoronoiPathFinder_tool.cc.

Constructor & Destructor Documentation

lar_cluster3d::VoronoiPathFinder::VoronoiPathFinder ( const fhicl::ParameterSet )
explicit

Constructor.

Parameters
pset

Definition at line 162 of file VoronoiPathFinder_tool.cc.

References configure().

163  : fPCAAlg(pset.get<fhicl::ParameterSet>("PrincipalComponentsAlg"))
164  {
165  this->configure(pset);
166  }
void configure(fhicl::ParameterSet const &pset) override
lar_cluster3d::VoronoiPathFinder::~VoronoiPathFinder ( )

Destructor.

Definition at line 170 of file VoronoiPathFinder_tool.cc.

170 {}

Member Function Documentation

reco::ClusterParametersList::iterator lar_cluster3d::VoronoiPathFinder::breakIntoTinyBits ( reco::ClusterParameters cluster,
reco::PrincipalComponents lastPCA,
reco::ClusterParametersList::iterator  positionItr,
reco::ClusterParametersList outputClusterList,
int  level = 0 
) const
private

Use PCA to try to find path in cluster.

Parameters
clusterParametersThe given cluster parameters object to try to split
clusterParametersListThe list of clusters

Definition at line 330 of file VoronoiPathFinder_tool.cc.

References util::abs(), buildConvexHull(), fFillHistograms, reco::PrincipalComponents::flipAxis(), fMinTinyClusterSize, fPCAAlg, fSubCosToPrevPCA, fSubEigen10Ratio, fSubEigen20Ratio, fSubEigen21Ratio, fSubNum3DHits, fSubNumEdges, fSubPrimaryLength, reco::ClusterParameters::getBestEdgeList(), reco::ClusterParameters::getConvexHull(), reco::ConvexHull::getConvexHullExtremePoints(), reco::PrincipalComponents::getEigenValues(), reco::PrincipalComponents::getEigenVectors(), reco::ClusterParameters::getFullPCA(), reco::ClusterParameters::getHitPairListPtr(), reco::ClusterHit3D::getPosition(), reco::ClusterParameters::getSkeletonPCA(), reco::PrincipalComponents::getSvdOK(), art::detail::indent(), art::left(), lar_cluster3d::PrincipalComponentsAlg::PCAAnalysis_3D(), lar_cluster3d::PrincipalComponentsAlg::PCAAnalysis_calc3DDocas(), art::right(), reco::ClusterParameters::UpdateParameters(), and reco::ClusterHit2D::USED.

Referenced by getTimeToExecute().

336  {
337  // This needs to be a recursive routine...
338  // Idea is to take the input cluster and order 3D hits by arclength along PCA primary axis
339  // If the cluster is above the minimum number of hits then we divide into two and call ourself
340  // with the two halves. This means we form a new cluster with hits and PCA and then call ourself
341  // If the cluster is below the minimum then we can't break any more, simply add this cluster to
342  // the new output list.
343 
344  // set an indention string
345  std::string pluses(level / 2, '+');
346  std::string indent(level / 2, ' ');
347 
348  indent += pluses;
349 
350  reco::ClusterParametersList::iterator inputPositionItr = positionItr;
351 
352  // To make best use of this we'll also want the PCA for this cluster... so...
353  // Recover the prime ingredients
354  reco::PrincipalComponents& fullPCA = clusterToBreak.getFullPCA();
355  std::vector<double> eigenValVec = {3. * std::sqrt(fullPCA.getEigenValues()[0]),
356  3. * std::sqrt(fullPCA.getEigenValues()[1]),
357  3. * std::sqrt(fullPCA.getEigenValues()[2])};
358  Eigen::Vector3f fullPrimaryVec(fullPCA.getEigenVectors().row(2));
359  Eigen::Vector3f lastPrimaryVec(lastPCA.getEigenVectors().row(2));
360 
361  double cosNewToLast = std::abs(fullPrimaryVec.dot(lastPrimaryVec));
362  double eigen2To1Ratio = eigenValVec[2] / eigenValVec[1];
363  double eigen1To0Ratio = eigenValVec[1] / eigenValVec[2];
364  double eigen2To0Ratio = eigenValVec[0] / eigenValVec[2];
365  double eigen2And1Ave = 0.5 * (eigenValVec[1] + eigenValVec[0]);
366  double eigenAveTo0Ratio = eigen2And1Ave / eigenValVec[2];
367 
368  bool storeCurrentCluster(true);
369  int minimumClusterSize(fMinTinyClusterSize);
370 
371  std::cout << indent << ">>> breakIntoTinyBits with "
372  << clusterToBreak.getHitPairListPtr().size() << " input hits, "
373  << clusterToBreak.getBestEdgeList().size() << " edges, rat21: " << eigen2To1Ratio
374  << ", rat20: " << eigen2To0Ratio << ", rat10: " << eigen1To0Ratio
375  << ", ave0: " << eigenAveTo0Ratio << std::endl;
376  std::cout << indent << " --> eigen 0/1/2: " << eigenValVec[0] << "/" << eigenValVec[1] << "/"
377  << eigenValVec[2] << ", cos: " << cosNewToLast << std::endl;
378 
379  // Create a rough cut intended to tell us when we've reached the land of diminishing returns
380  if (clusterToBreak.getBestEdgeList().size() > 5 && cosNewToLast > 0.25 &&
381  eigen2To1Ratio < 0.9 && eigen2To0Ratio > 0.001 &&
382  clusterToBreak.getHitPairListPtr().size() > size_t(2 * minimumClusterSize)) {
383  // We want to find the convex hull vertices that lie furthest from the line to/from the extreme points
384  // To find these we:
385  // 1) recover the extreme points
386  // 2) form the vector between them
387  // 3) loop through the vertices and keep track of distance to this vector
388  // 4) Sort the resulting list by furthest points and select the one we want
389  reco::ProjectedPointList::const_iterator extremePointListItr =
390  clusterToBreak.getConvexHull().getConvexHullExtremePoints().begin();
391 
392  const reco::ClusterHit3D* firstEdgeHit = std::get<2>(*extremePointListItr++);
393  const reco::ClusterHit3D* secondEdgeHit = std::get<2>(*extremePointListItr);
394  Eigen::Vector3f edgeVec(secondEdgeHit->getPosition()[0] - firstEdgeHit->getPosition()[0],
395  secondEdgeHit->getPosition()[1] - firstEdgeHit->getPosition()[1],
396  secondEdgeHit->getPosition()[2] - firstEdgeHit->getPosition()[2]);
397  double edgeLen = edgeVec.norm();
398 
399  // normalize it
400  edgeVec.normalize();
401 
402  // Recover the list of 3D hits associated to this cluster
403  reco::HitPairListPtr& clusHitPairVector = clusterToBreak.getHitPairListPtr();
404 
405  // Calculate the doca to the PCA primary axis for each 3D hit
406  // Importantly, this also gives us the arclength along that axis to the hit
407  fPCAAlg.PCAAnalysis_calc3DDocas(clusHitPairVector, fullPCA);
408 
409  // Sort the hits along the PCA
410  clusHitPairVector.sort([](const auto& left, const auto& right) {
411  return left->getArclenToPoca() < right->getArclenToPoca();
412  });
413 
414  // Set up container to keep track of edges
415  using DistEdgeTuple = std::tuple<float, const reco::EdgeTuple*>;
416  using DistEdgeTupleVec = std::vector<DistEdgeTuple>;
417 
418  DistEdgeTupleVec distEdgeTupleVec;
419 
420  // Now loop through all the edges and search for the furthers point
421  for (const auto& edge : clusterToBreak.getBestEdgeList()) {
422  const reco::ClusterHit3D* nextEdgeHit = std::get<0>(edge); // recover the first point
423 
424  // Create vector to this point from the longest edge
425  Eigen::Vector3f hitToEdgeVec(nextEdgeHit->getPosition()[0] - firstEdgeHit->getPosition()[0],
426  nextEdgeHit->getPosition()[1] - firstEdgeHit->getPosition()[1],
427  nextEdgeHit->getPosition()[2] -
428  firstEdgeHit->getPosition()[2]);
429 
430  // Get projection
431  float hitProjection = hitToEdgeVec.dot(edgeVec);
432 
433  // Require that the point is really "opposite" the longest edge
434  if (hitProjection > 0. && hitProjection < edgeLen) {
435  Eigen::Vector3f distToHitVec = hitToEdgeVec - hitProjection * edgeVec;
436  float distToHit = distToHitVec.norm();
437 
438  distEdgeTupleVec.emplace_back(distToHit, &edge);
439  }
440  }
441 
442  std::sort(
443  distEdgeTupleVec.begin(), distEdgeTupleVec.end(), [](const auto& left, const auto& right) {
444  return std::get<0>(left) > std::get<0>(right);
445  });
446 
447  for (const auto& distEdgeTuple : distEdgeTupleVec) {
448  const reco::EdgeTuple& edgeTuple = *std::get<1>(distEdgeTuple);
449  const reco::ClusterHit3D* edgeHit = std::get<0>(edgeTuple);
450 
451  // Now find the hit identified above as furthest away
453  std::find(clusHitPairVector.begin(), clusHitPairVector.end(), edgeHit);
454 
455  // Make sure enough hits either side, otherwise we just keep the current cluster
456  if (vertexItr == clusHitPairVector.end() ||
457  std::distance(clusHitPairVector.begin(), vertexItr) < minimumClusterSize ||
458  std::distance(vertexItr, clusHitPairVector.end()) < minimumClusterSize)
459  continue;
460 
461  // Now we create a list of pairs of iterators to the start and end of each subcluster
462  using Hit3DItrPair =
463  std::pair<reco::HitPairListPtr::iterator, reco::HitPairListPtr::iterator>;
464  using VertexPairList = std::list<Hit3DItrPair>;
465 
466  VertexPairList vertexPairList;
467 
468  vertexPairList.emplace_back(Hit3DItrPair(clusHitPairVector.begin(), vertexItr));
469  vertexPairList.emplace_back(Hit3DItrPair(vertexItr, clusHitPairVector.end()));
470 
471  storeCurrentCluster = false;
472 
473  // Ok, now loop through our pairs
474  for (auto& hit3DItrPair : vertexPairList) {
475  reco::ClusterParameters clusterParams;
476  reco::HitPairListPtr& hitPairListPtr = clusterParams.getHitPairListPtr();
477 
478  std::cout << indent << "+> -- building new cluster, size: "
479  << std::distance(hit3DItrPair.first, hit3DItrPair.second) << std::endl;
480 
481  // size the container...
482  hitPairListPtr.resize(std::distance(hit3DItrPair.first, hit3DItrPair.second));
483 
484  // and copy the hits into the container
485  std::copy(hit3DItrPair.first, hit3DItrPair.second, hitPairListPtr.begin());
486 
487  // First stage of feature extraction runs here
488  fPCAAlg.PCAAnalysis_3D(hitPairListPtr, clusterParams.getFullPCA());
489 
490  // Recover the new fullPCA
491  reco::PrincipalComponents& newFullPCA = clusterParams.getFullPCA();
492 
493  // Must have a valid pca
494  if (newFullPCA.getSvdOK()) {
495  std::cout << indent << "+> -- >> cluster has a valid Full PCA" << std::endl;
496 
497  // If the PCA's are opposite the flip the axes
498  if (fullPrimaryVec.dot(newFullPCA.getEigenVectors().row(2)) < 0.) {
499  for (size_t vecIdx = 0; vecIdx < 3; vecIdx++)
500  newFullPCA.flipAxis(vecIdx);
501  }
502 
503  // Set the skeleton PCA to make sure it has some value
504  clusterParams.getSkeletonPCA() = clusterParams.getFullPCA();
505 
506  // Be sure to compute the oonvex hull surrounding the now broken cluster
507  buildConvexHull(clusterParams, level + 2);
508 
509  positionItr =
510  breakIntoTinyBits(clusterParams, fullPCA, positionItr, outputClusterList, level + 4);
511  }
512  }
513 
514  // If successful in breaking the cluster then we are done, otherwise try to loop
515  // again taking the next furthest hit
516  break;
517  }
518  }
519 
520  // First question, are we done breaking?
521  if (storeCurrentCluster) {
522  // I think this is where we fill out the rest of the parameters?
523  // Start by adding the 2D hits...
524  // See if we can avoid duplicates by temporarily transferring to a set
525  std::set<const reco::ClusterHit2D*> hitSet;
526 
527  // Loop through 3D hits to get a set of unique 2D hits
528  for (const auto& hit3D : clusterToBreak.getHitPairListPtr()) {
529  for (const auto& hit2D : hit3D->getHits()) {
530  if (hit2D) hitSet.insert(hit2D);
531  }
532  }
533 
534  // Now add these to the new cluster
535  for (const auto& hit2D : hitSet) {
536  hit2D->setStatusBit(reco::ClusterHit2D::USED);
537  clusterToBreak.UpdateParameters(hit2D);
538  }
539 
540  std::cout << indent << "*********>>> storing new subcluster of size "
541  << clusterToBreak.getHitPairListPtr().size() << std::endl;
542 
543  positionItr = outputClusterList.insert(positionItr, clusterToBreak);
544 
545  // Are we filling histograms
546  if (fFillHistograms) {
547  int num3DHits = clusterToBreak.getHitPairListPtr().size();
548  int numEdges = clusterToBreak.getBestEdgeList().size();
549  Eigen::Vector3f newPrimaryVec(fullPCA.getEigenVectors().row(2));
550  Eigen::Vector3f lastPrimaryVec(lastPCA.getEigenVectors().row(2));
551  float cosToLast = newPrimaryVec.dot(lastPrimaryVec);
552 
553  fSubNum3DHits->Fill(std::min(num3DHits, 199), 1.);
554  fSubNumEdges->Fill(std::min(numEdges, 199), 1.);
555  fSubEigen21Ratio->Fill(eigen2To1Ratio, 1.);
556  fSubEigen20Ratio->Fill(eigen2To0Ratio, 1.);
557  fSubEigen10Ratio->Fill(eigen1To0Ratio, 1.);
558  fSubCosToPrevPCA->Fill(cosToLast, 1.);
559  fSubPrimaryLength->Fill(std::min(eigenValVec[2], 199.), 1.);
560  }
561 
562  // The above points to the element, want the next element
563  positionItr++;
564  }
565  else if (inputPositionItr != positionItr) {
566  std::cout << indent << "***** DID NOT STORE A CLUSTER *****" << std::endl;
567  }
568 
569  return positionItr;
570  }
intermediate_table::iterator iterator
void PCAAnalysis_calc3DDocas(const reco::HitPairListPtr &hitPairVector, const reco::PrincipalComponents &pca) const
bool getSvdOK() const
Definition: Cluster3D.h:240
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
void flipAxis(size_t axis)
Definition: Cluster3D.cxx:232
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:155
reco::PrincipalComponents & getSkeletonPCA()
Definition: Cluster3D.h:465
constexpr auto abs(T v)
Returns the absolute value of the argument.
intermediate_table::const_iterator const_iterator
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:463
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:242
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:464
std::tuple< const reco::ClusterHit3D *, const reco::ClusterHit3D *, double > EdgeTuple
Definition: Cluster3D.h:336
std::string indent(std::size_t const i)
void buildConvexHull(reco::ClusterParameters &clusterParameters, int level=0) const
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:326
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
reco::ClusterParametersList::iterator breakIntoTinyBits(reco::ClusterParameters &cluster, reco::PrincipalComponents &lastPCA, reco::ClusterParametersList::iterator positionItr, reco::ClusterParametersList &outputClusterList, int level=0) const
Use PCA to try to find path in cluster.
size_t fMinTinyClusterSize
Minimum size for a "tiny" cluster.
bool fFillHistograms
Histogram definitions.
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:243
void lar_cluster3d::VoronoiPathFinder::buildConvexHull ( reco::ClusterParameters clusterParameters,
int  level = 0 
) const
private

Definition at line 881 of file VoronoiPathFinder_tool.cc.

References util::abs(), reco::PrincipalComponents::getAvePosition(), lar_cluster3d::ConvexHull::getConvexHull(), reco::ClusterParameters::getConvexHull(), lar_cluster3d::ConvexHull::getConvexHullArea(), reco::ConvexHull::getConvexHullEdgeList(), reco::ConvexHull::getConvexHullEdgeMap(), reco::ConvexHull::getConvexHullExtremePoints(), reco::PrincipalComponents::getEigenVectors(), reco::ClusterParameters::getFullPCA(), reco::ClusterParameters::getHitPairListPtr(), reco::ClusterHit3D::getPosition(), reco::ConvexHull::getProjectedPointList(), art::detail::indent(), art::left(), and art::right().

Referenced by breakIntoTinyBits(), makeCandidateCluster(), and ModifyClusters().

883  {
884  // set an indention string
885  std::string minuses(level / 2, '-');
886  std::string indent(level / 2, ' ');
887 
888  indent += minuses;
889 
890  // The plan is to build the enclosing 2D polygon around the points in the PCA plane of most spread for this cluster
891  // To do so we need to start by building a list of 2D projections onto the plane of most spread...
892  reco::PrincipalComponents& pca = clusterParameters.getFullPCA();
893 
894  // Recover the parameters from the Principal Components Analysis that we need to project and accumulate
895  Eigen::Vector3f pcaCenter(
896  pca.getAvePosition()[0], pca.getAvePosition()[1], pca.getAvePosition()[2]);
897 
898  //dcel2d::PointList pointList;
899  using Point = std::tuple<float, float, const reco::ClusterHit3D*>;
900  using PointList = std::list<Point>;
901 
902  reco::ConvexHull& convexHull = clusterParameters.getConvexHull();
903  PointList pointList = convexHull.getProjectedPointList();
904 
905  // Loop through hits and do projection to plane
906  for (const auto& hit3D : clusterParameters.getHitPairListPtr()) {
907  Eigen::Vector3f pcaToHitVec(hit3D->getPosition()[0] - pcaCenter(0),
908  hit3D->getPosition()[1] - pcaCenter(1),
909  hit3D->getPosition()[2] - pcaCenter(2));
910  Eigen::Vector3f pcaToHit = pca.getEigenVectors() * pcaToHitVec;
911 
912  pointList.emplace_back(dcel2d::Point(pcaToHit(0), pcaToHit(1), hit3D));
913  }
914 
915  // Sort the point vec by increasing x, then increase y
916  pointList.sort([](const auto& left, const auto& right) {
917  return (std::abs(std::get<0>(left) - std::get<0>(right)) >
918  std::numeric_limits<float>::epsilon()) ?
919  std::get<0>(left) < std::get<0>(right) :
920  std::get<1>(left) < std::get<1>(right);
921  });
922 
923  // containers for finding the "best" hull...
924  std::vector<ConvexHull> convexHullVec;
925  std::vector<PointList> rejectedListVec;
926  bool increaseDepth(pointList.size() > 5);
927  float lastArea(std::numeric_limits<float>::max());
928 
929  while (increaseDepth) {
930  // Get another convexHull container
931  convexHullVec.push_back(ConvexHull(pointList));
932  rejectedListVec.push_back(PointList());
933 
934  const ConvexHull& convexHull = convexHullVec.back();
935  PointList& rejectedList = rejectedListVec.back();
936  const PointList& convexHullPoints = convexHull.getConvexHull();
937 
938  increaseDepth = false;
939 
940  if (convexHull.getConvexHullArea() > 0.) {
941  std::cout << indent << "-> built convex hull, 3D hits: " << pointList.size() << " with "
942  << convexHullPoints.size() << " vertices"
943  << ", area: " << convexHull.getConvexHullArea() << std::endl;
944  std::cout << indent << "-> -Points:";
945  for (const auto& point : convexHullPoints)
946  std::cout << " (" << std::get<0>(point) << "," << std::get<1>(point) << ")";
947  std::cout << std::endl;
948 
949  if (convexHullVec.size() < 2 || convexHull.getConvexHullArea() < 0.8 * lastArea) {
950  for (auto& point : convexHullPoints) {
951  pointList.remove(point);
952  rejectedList.emplace_back(point);
953  }
954  lastArea = convexHull.getConvexHullArea();
955  // increaseDepth = true;
956  }
957  }
958  }
959 
960  // do we have a valid convexHull?
961  while (!convexHullVec.empty() && convexHullVec.back().getConvexHullArea() < 0.5) {
962  convexHullVec.pop_back();
963  rejectedListVec.pop_back();
964  }
965 
966  // If we found the convex hull then build edges around the region
967  if (!convexHullVec.empty()) {
968  size_t nRejectedTotal(0);
969  reco::HitPairListPtr hitPairListPtr = clusterParameters.getHitPairListPtr();
970 
971  for (const auto& rejectedList : rejectedListVec) {
972  nRejectedTotal += rejectedList.size();
973 
974  for (const auto& rejectedPoint : rejectedList) {
975  std::cout << indent << "-> -- Point is "
976  << convexHullVec.back().findNearestDistance(rejectedPoint)
977  << " from nearest edge" << std::endl;
978 
979  if (convexHullVec.back().findNearestDistance(rejectedPoint) > 0.5)
980  hitPairListPtr.remove(std::get<2>(rejectedPoint));
981  }
982  }
983 
984  std::cout << indent << "-> Removed " << nRejectedTotal << " leaving " << pointList.size()
985  << "/" << hitPairListPtr.size() << " points" << std::endl;
986 
987  // Now add "edges" to the cluster to describe the convex hull (for the display)
988  reco::Hit3DToEdgeMap& edgeMap = convexHull.getConvexHullEdgeMap();
989  reco::EdgeList& bestEdgeList = convexHull.getConvexHullEdgeList();
990 
991  Point lastPoint = convexHullVec.back().getConvexHull().front();
992 
993  for (auto& curPoint : convexHullVec.back().getConvexHull()) {
994  if (curPoint == lastPoint) continue;
995 
996  const reco::ClusterHit3D* lastPoint3D = std::get<2>(lastPoint);
997  const reco::ClusterHit3D* curPoint3D = std::get<2>(curPoint);
998 
999  float distBetweenPoints = (curPoint3D->getPosition()[0] - lastPoint3D->getPosition()[0]) *
1000  (curPoint3D->getPosition()[0] - lastPoint3D->getPosition()[0]) +
1001  (curPoint3D->getPosition()[1] - lastPoint3D->getPosition()[1]) *
1002  (curPoint3D->getPosition()[1] - lastPoint3D->getPosition()[1]) +
1003  (curPoint3D->getPosition()[2] - lastPoint3D->getPosition()[2]) *
1004  (curPoint3D->getPosition()[2] - lastPoint3D->getPosition()[2]);
1005 
1006  distBetweenPoints = std::sqrt(distBetweenPoints);
1007 
1008  reco::EdgeTuple edge(lastPoint3D, curPoint3D, distBetweenPoints);
1009 
1010  edgeMap[lastPoint3D].push_back(edge);
1011  edgeMap[curPoint3D].push_back(edge);
1012  bestEdgeList.emplace_back(edge);
1013 
1014  lastPoint = curPoint;
1015  }
1016 
1017  // Store the "extreme" points
1018  const ConvexHull::PointList& extremePoints = convexHullVec.back().getExtremePoints();
1019  reco::ProjectedPointList& extremePointList = convexHull.getConvexHullExtremePoints();
1020 
1021  for (const auto& point : extremePoints)
1022  extremePointList.push_back(point);
1023  }
1024 
1025  return;
1026  }
std::tuple< float, float, const reco::ClusterHit3D * > Point
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:155
std::list< ProjectedPoint > ProjectedPointList
Definition: Cluster3D.h:346
std::list< Point > PointList
The list of the projected points.
Definition: ConvexHull.h:33
constexpr auto abs(T v)
Returns the absolute value of the argument.
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:463
std::list< EdgeTuple > EdgeList
Definition: Cluster3D.h:337
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:464
std::tuple< const reco::ClusterHit3D *, const reco::ClusterHit3D *, double > EdgeTuple
Definition: Cluster3D.h:336
Define a container for working with the convex hull.
Definition: Cluster3D.h:354
std::string indent(std::size_t const i)
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:244
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:326
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
reco::ConvexHull & getConvexHull()
Definition: Cluster3D.h:469
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:42
std::unordered_map< const reco::ClusterHit3D *, reco::EdgeList > Hit3DToEdgeMap
Definition: Cluster3D.h:339
reco::ProjectedPointList & getProjectedPointList()
Definition: Cluster3D.h:370
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:243
void lar_cluster3d::VoronoiPathFinder::buildVoronoiDiagram ( reco::ClusterParameters clusterParameters) const
private

Definition at line 1028 of file VoronoiPathFinder_tool.cc.

References util::abs(), voronoi2d::VoronoiDiagram::buildVoronoiDiagram(), reco::PrincipalComponents::getAvePosition(), reco::ClusterParameters::getBestEdgeList(), reco::PrincipalComponents::getEigenVectors(), reco::ClusterParameters::getFaceList(), reco::ClusterParameters::getFullPCA(), reco::ClusterParameters::getHalfEdgeList(), reco::ClusterParameters::getHit3DToEdgeMap(), reco::ClusterParameters::getHitPairListPtr(), reco::ClusterHit3D::getPosition(), reco::ClusterParameters::getVertexList(), art::left(), and art::right().

Referenced by ModifyClusters().

1029  {
1030  // The plan is to build the enclosing 2D polygon around the points in the PCA plane of most spread for this cluster
1031  // To do so we need to start by building a list of 2D projections onto the plane of most spread...
1032  reco::PrincipalComponents& pca = clusterParameters.getFullPCA();
1033 
1034  // Recover the parameters from the Principal Components Analysis that we need to project and accumulate
1035  Eigen::Vector3f pcaCenter(
1036  pca.getAvePosition()[0], pca.getAvePosition()[1], pca.getAvePosition()[2]);
1037 
1038  dcel2d::PointList pointList;
1039 
1040  // Loop through hits and do projection to plane
1041  for (const auto& hit3D : clusterParameters.getHitPairListPtr()) {
1042  Eigen::Vector3f pcaToHitVec(hit3D->getPosition()[0] - pcaCenter(0),
1043  hit3D->getPosition()[1] - pcaCenter(1),
1044  hit3D->getPosition()[2] - pcaCenter(2));
1045  Eigen::Vector3f pcaToHit = pca.getEigenVectors() * pcaToHitVec;
1046 
1047  pointList.emplace_back(dcel2d::Point(pcaToHit(1), pcaToHit(2), hit3D));
1048  }
1049 
1050  // Sort the point vec by increasing x, then increase y
1051  pointList.sort([](const auto& left, const auto& right) {
1052  return (std::abs(std::get<0>(left) - std::get<0>(right)) >
1053  std::numeric_limits<float>::epsilon()) ?
1054  std::get<0>(left) < std::get<0>(right) :
1055  std::get<1>(left) < std::get<1>(right);
1056  });
1057 
1058  std::cout << " ==> Build V diagram, sorted point list contains " << pointList.size() << " hits"
1059  << std::endl;
1060 
1061  // Set up the voronoi diagram builder
1062  voronoi2d::VoronoiDiagram voronoiDiagram(clusterParameters.getHalfEdgeList(),
1063  clusterParameters.getVertexList(),
1064  clusterParameters.getFaceList());
1065 
1066  // And make the diagram
1067  voronoiDiagram.buildVoronoiDiagram(pointList);
1068 
1069  // Recover the voronoi diagram vertex list and the container to store them in
1070  dcel2d::VertexList& vertexList = clusterParameters.getVertexList();
1071 
1072  // Now get the inverse of the rotation matrix so we can get the vertex positions,
1073  // which lie in the plane of the two largest PCA axes, in the standard coordinate system
1074  Eigen::Matrix3f rotationMatrixInv = pca.getEigenVectors().inverse();
1075 
1076  // Translate and fill
1077  for (auto& vertex : vertexList) {
1078  Eigen::Vector3f coords = rotationMatrixInv * vertex.getCoords();
1079 
1080  coords += pcaCenter;
1081 
1082  vertex.setCoords(coords);
1083  }
1084 
1085  // Now do the Convex Hull
1086  // Now add "edges" to the cluster to describe the convex hull (for the display)
1087  reco::Hit3DToEdgeMap& edgeMap = clusterParameters.getHit3DToEdgeMap();
1088  reco::EdgeList& bestEdgeList = clusterParameters.getBestEdgeList();
1089 
1090  // const dcel2d::PointList& edgePoints = voronoiDiagram.getConvexHull();
1091  // PointList localList;
1092  //
1093  // for(const auto& edgePoint : edgePoints) localList.emplace_back(std::get<0>(edgePoint),std::get<1>(edgePoint),std::get<2>(edgePoint));
1094  //
1095  // // Sort the point vec by increasing x, then increase y
1096  // localList.sort([](const auto& left, const auto& right){return (std::abs(std::get<0>(left) - std::get<0>(right)) > std::numeric_limits<float>::epsilon()) ? std::get<0>(left) < std::get<0>(right) : std::get<1>(left) < std::get<1>(right);});
1097  //
1098  // // Why do I need to do this?
1099  // ConvexHull convexHull(localList);
1100  //
1101  // Point lastPoint = convexHull.getConvexHull().front();
1102  dcel2d::Point lastPoint = voronoiDiagram.getConvexHull().front();
1103 
1104  // std::cout << "@@@@>> Build convex hull, voronoi handed " << edgePoints.size() << " points, convexHull cut to " << convexHull.getConvexHull().size() << std::endl;
1105 
1106  // for(auto& curPoint : convexHull.getConvexHull())
1107  for (auto& curPoint : voronoiDiagram.getConvexHull()) {
1108  if (curPoint == lastPoint) continue;
1109 
1110  const reco::ClusterHit3D* lastPoint3D = std::get<2>(lastPoint);
1111  const reco::ClusterHit3D* curPoint3D = std::get<2>(curPoint);
1112 
1113  float distBetweenPoints = (curPoint3D->getPosition()[0] - lastPoint3D->getPosition()[0]) *
1114  (curPoint3D->getPosition()[0] - lastPoint3D->getPosition()[0]) +
1115  (curPoint3D->getPosition()[1] - lastPoint3D->getPosition()[1]) *
1116  (curPoint3D->getPosition()[1] - lastPoint3D->getPosition()[1]) +
1117  (curPoint3D->getPosition()[2] - lastPoint3D->getPosition()[2]) *
1118  (curPoint3D->getPosition()[2] - lastPoint3D->getPosition()[2]);
1119 
1120  distBetweenPoints = std::sqrt(distBetweenPoints);
1121 
1122  reco::EdgeTuple edge(lastPoint3D, curPoint3D, distBetweenPoints);
1123 
1124  edgeMap[lastPoint3D].push_back(edge);
1125  edgeMap[curPoint3D].push_back(edge);
1126  bestEdgeList.emplace_back(edge);
1127 
1128  lastPoint = curPoint;
1129  }
1130 
1131  std::cout << "****> vertexList containted " << vertexList.size() << " vertices for "
1132  << clusterParameters.getHitPairListPtr().size() << " hits" << std::endl;
1133 
1134  return;
1135  }
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:155
constexpr auto abs(T v)
Returns the absolute value of the argument.
reco::EdgeList & getBestEdgeList()
Definition: Cluster3D.h:468
reco::Hit3DToEdgeMap & getHit3DToEdgeMap()
Definition: Cluster3D.h:466
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:463
std::list< EdgeTuple > EdgeList
Definition: Cluster3D.h:337
VoronoiDiagram class definiton.
Definition: Voronoi.h:30
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:464
std::tuple< const reco::ClusterHit3D *, const reco::ClusterHit3D *, double > EdgeTuple
Definition: Cluster3D.h:336
void buildVoronoiDiagram(const dcel2d::PointList &)
Given an input set of 2D points construct a 2D voronoi diagram.
Definition: Voronoi.cxx:135
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:244
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
dcel2d::FaceList & getFaceList()
Definition: Cluster3D.h:470
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:42
std::list< Point > PointList
Definition: DCEL.h:43
std::unordered_map< const reco::ClusterHit3D *, reco::EdgeList > Hit3DToEdgeMap
Definition: Cluster3D.h:339
dcel2d::HalfEdgeList & getHalfEdgeList()
Definition: Cluster3D.h:472
std::list< Vertex > VertexList
Definition: DCEL.h:169
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:243
dcel2d::VertexList & getVertexList()
Definition: Cluster3D.h:471
vertex reconstruction
float lar_cluster3d::VoronoiPathFinder::closestApproach ( const Eigen::Vector3f &  P0,
const Eigen::Vector3f &  u0,
const Eigen::Vector3f &  P1,
const Eigen::Vector3f &  u1,
Eigen::Vector3f &  poca0,
Eigen::Vector3f &  poca1 
) const
private

Definition at line 1137 of file VoronoiPathFinder_tool.cc.

References d, DEFINE_ART_CLASS_TOOL, den, and e.

Referenced by getTimeToExecute().

1143  {
1144  // Technique is to compute the arclength to each point of closest approach
1145  Eigen::Vector3f w0 = P0 - P1;
1146  float a(1.);
1147  float b(u0.dot(u1));
1148  float c(1.);
1149  float d(u0.dot(w0));
1150  float e(u1.dot(w0));
1151  float den(a * c - b * b);
1152 
1153  float arcLen0 = (b * e - c * d) / den;
1154  float arcLen1 = (a * e - b * d) / den;
1155 
1156  poca0 = P0 + arcLen0 * u0;
1157  poca1 = P1 + arcLen1 * u1;
1158 
1159  return (poca0 - poca1).norm();
1160  }
Float_t den
Definition: plot.C:35
Float_t d
Definition: plot.C:235
Float_t e
Definition: plot.C:35
virtual void lar_cluster3d::IClusterModAlg::configure ( const fhicl::ParameterSet )
pure virtualinherited

Interface for configuring the particular algorithm tool.

Parameters
ParameterSetThe input set of parameters for configuration
void lar_cluster3d::VoronoiPathFinder::configure ( fhicl::ParameterSet const &  pset)
override

Definition at line 174 of file VoronoiPathFinder_tool.cc.

References fClusterAlg, fEnableMonitoring, fMinTinyClusterSize, fTimeToProcess, and fhicl::ParameterSet::get().

Referenced by VoronoiPathFinder().

175  {
176  fEnableMonitoring = pset.get<bool>("EnableMonitoring", true);
177  fMinTinyClusterSize = pset.get<size_t>("MinTinyClusterSize", 40);
178  fClusterAlg =
179  art::make_tool<lar_cluster3d::IClusterAlg>(pset.get<fhicl::ParameterSet>("ClusterAlg"));
180 
181  fTimeToProcess = 0.;
182 
183  return;
184  }
std::unique_ptr< lar_cluster3d::IClusterAlg > fClusterAlg
Tools.
size_t fMinTinyClusterSize
Minimum size for a "tiny" cluster.
float lar_cluster3d::VoronoiPathFinder::getTimeToExecute ( ) const
inlineoverridevirtual

If monitoring, recover the time to execute a particular function.

Implements lar_cluster3d::IClusterModAlg.

Definition at line 75 of file VoronoiPathFinder_tool.cc.

References breakIntoTinyBits(), closestApproach(), fTimeToProcess, makeCandidateCluster(), and subDivideCluster().

void lar_cluster3d::VoronoiPathFinder::initializeHistograms ( art::TFileDirectory &  histDir)
overridevirtual

Interface for initializing histograms if they are desired Note that the idea is to put hisgtograms in a subfolder.

Parameters
TFileDirectory- the folder to store the hists in

Implements lar_cluster3d::IClusterModAlg.

Definition at line 186 of file VoronoiPathFinder_tool.cc.

References dir, fFillHistograms, fSubCosExtToPCA, fSubCosToPrevPCA, fSubEigen10Ratio, fSubEigen20Ratio, fSubEigen21Ratio, fSubMaxDefect, fSubNum3DHits, fSubNumEdges, fSubPrimaryLength, fSubUsedDefect, fTopEigen10Ratio, fTopEigen20Ratio, fTopEigen21Ratio, fTopNum3DHits, fTopNumEdges, and fTopPrimaryLength.

187  {
188  // It is assumed that the input TFileDirectory has been set up to group histograms into a common
189  // folder at the calling routine's level. Here we create one more level of indirection to keep
190  // histograms made by this tool separate.
191  fFillHistograms = true;
192 
193  std::string dirName = "VoronoiPath";
194 
195  art::TFileDirectory dir = histDir.mkdir(dirName.c_str());
196 
197  // Divide into two sets of hists... those for the overall cluster and
198  // those for the subclusters
199  fTopNum3DHits = dir.make<TH1F>("TopNum3DHits", "Number 3D Hits", 200, 0., 200.);
200  fTopNumEdges = dir.make<TH1F>("TopNumEdges", "Number Edges", 200, 0., 200.);
201  fTopEigen21Ratio = dir.make<TH1F>("TopEigen21Rat", "Eigen 2/1 Ratio", 100, 0., 1.);
202  fTopEigen20Ratio = dir.make<TH1F>("TopEigen20Rat", "Eigen 2/0 Ratio", 100, 0., 1.);
203  fTopEigen10Ratio = dir.make<TH1F>("TopEigen10Rat", "Eigen 1/0 Ratio", 100, 0., 1.);
204  fTopPrimaryLength = dir.make<TH1F>("TopPrimaryLen", "Primary Length", 200, 0., 200.);
205 
206  fSubNum3DHits = dir.make<TH1F>("SubNum3DHits", "Number 3D Hits", 200, 0., 200.);
207  fSubNumEdges = dir.make<TH1F>("SubNumEdges", "Number Edges", 200, 0., 200.);
208  fSubEigen21Ratio = dir.make<TH1F>("SubEigen21Rat", "Eigen 2/1 Ratio", 100, 0., 1.);
209  fSubEigen20Ratio = dir.make<TH1F>("SubEigen20Rat", "Eigen 2/0 Ratio", 100, 0., 1.);
210  fSubEigen10Ratio = dir.make<TH1F>("SubEigen10Rat", "Eigen 1/0 Ratio", 100, 0., 1.);
211  fSubPrimaryLength = dir.make<TH1F>("SubPrimaryLen", "Primary Length", 200, 0., 200.);
212  fSubCosToPrevPCA = dir.make<TH1F>("SubCosToPrev", "Cos(theta)", 101, 0., 1.01);
213  fSubCosExtToPCA = dir.make<TH1F>("SubCosExtPCA", "Cos(theta)", 102, -1.01, 1.01);
214  fSubMaxDefect = dir.make<TH1F>("SubMaxDefect", "Max Defect", 100, 0., 50.);
215  fSubUsedDefect = dir.make<TH1F>("SubUsedDefect", "Used Defect", 100, 0., 50.);
216 
217  return;
218  }
TDirectory * dir
Definition: macro.C:5
bool fFillHistograms
Histogram definitions.
bool lar_cluster3d::VoronoiPathFinder::makeCandidateCluster ( Eigen::Vector3f &  primaryPCA,
reco::ClusterParameters candCluster,
reco::HitPairListPtr::iterator  firstHitItr,
reco::HitPairListPtr::iterator  lastHitItr,
int  level 
) const
private

Definition at line 803 of file VoronoiPathFinder_tool.cc.

References util::abs(), buildConvexHull(), reco::PrincipalComponents::flipAxis(), fPCAAlg, reco::ClusterParameters::getBestEdgeList(), reco::PrincipalComponents::getEigenValues(), reco::PrincipalComponents::getEigenVectors(), reco::ClusterParameters::getFullPCA(), reco::ClusterParameters::getHitPairListPtr(), reco::ClusterParameters::getSkeletonPCA(), reco::PrincipalComponents::getSvdOK(), art::detail::indent(), and lar_cluster3d::PrincipalComponentsAlg::PCAAnalysis_3D().

Referenced by getTimeToExecute(), and subDivideCluster().

808  {
809  std::string indent(level / 2, ' ');
810 
811  reco::HitPairListPtr& hitPairListPtr = candCluster.getHitPairListPtr();
812 
813  std::cout << indent
814  << "+> -- building new cluster, size: " << std::distance(firstHitItr, lastHitItr)
815  << std::endl;
816 
817  // size the container...
818  hitPairListPtr.resize(std::distance(firstHitItr, lastHitItr));
819 
820  // and copy the hits into the container
821  std::copy(firstHitItr, lastHitItr, hitPairListPtr.begin());
822 
823  // First stage of feature extraction runs here
824  fPCAAlg.PCAAnalysis_3D(hitPairListPtr, candCluster.getFullPCA());
825 
826  // Recover the new fullPCA
827  reco::PrincipalComponents& newFullPCA = candCluster.getFullPCA();
828 
829  // Will we want to store this cluster?
830  bool keepThisCluster(false);
831 
832  // Must have a valid pca
833  if (newFullPCA.getSvdOK()) {
834  std::cout << indent << "+> -- >> cluster has a valid Full PCA" << std::endl;
835 
836  // Need to check if the PCA direction has been reversed
837  Eigen::Vector3f newPrimaryVec(newFullPCA.getEigenVectors().row(2));
838 
839  // If the PCA's are opposite the flip the axes
840  if (primaryPCA.dot(newPrimaryVec) < 0.) {
841  for (size_t vecIdx = 0; vecIdx < 3; vecIdx++)
842  newFullPCA.flipAxis(vecIdx);
843 
844  newPrimaryVec = Eigen::Vector3f(newFullPCA.getEigenVectors().row(2));
845  }
846 
847  // Set the skeleton PCA to make sure it has some value
848  candCluster.getSkeletonPCA() = candCluster.getFullPCA();
849 
850  // Be sure to compute the oonvex hull surrounding the now broken cluster
851  buildConvexHull(candCluster, level + 2);
852 
853  std::vector<double> eigenValVec = {3. * std::sqrt(newFullPCA.getEigenValues()[0]),
854  3. * std::sqrt(newFullPCA.getEigenValues()[1]),
855  3. * std::sqrt(newFullPCA.getEigenValues()[2])};
856  double cosNewToLast = std::abs(primaryPCA.dot(newPrimaryVec));
857  double eigen2To1Ratio = eigenValVec[2] / eigenValVec[1];
858  double eigen1To0Ratio = eigenValVec[1] / eigenValVec[2];
859  double eigen2To0Ratio = eigenValVec[0] / eigenValVec[2];
860  double eigen2And1Ave = 0.5 * (eigenValVec[1] + eigenValVec[0]);
861  double eigenAveTo0Ratio = eigen2And1Ave / eigenValVec[2];
862 
863  std::cout << indent << ">>> subDivideClusters with " << candCluster.getHitPairListPtr().size()
864  << " input hits, " << candCluster.getBestEdgeList().size()
865  << " edges, rat21: " << eigen2To1Ratio << ", rat20: " << eigen2To0Ratio
866  << ", rat10: " << eigen1To0Ratio << ", ave0: " << eigenAveTo0Ratio << std::endl;
867  std::cout << indent << " --> eigen 0/1/2: " << eigenValVec[0] << "/" << eigenValVec[1]
868  << "/" << eigenValVec[2] << ", cos: " << cosNewToLast << std::endl;
869 
870  // Create a rough cut intended to tell us when we've reached the land of diminishing returns
871  // if (candCluster.getBestEdgeList().size() > 4 && cosNewToLast > 0.25 && eigen2To1Ratio < 0.9 && eigen2To0Ratio > 0.001)
872  if (candCluster.getBestEdgeList().size() > 4 && cosNewToLast > 0.25 &&
873  eigen2To1Ratio > 0.01 && eigen2To1Ratio < 0.99 && eigen1To0Ratio < 0.5) {
874  keepThisCluster = true;
875  }
876  }
877 
878  return keepThisCluster;
879  }
bool getSvdOK() const
Definition: Cluster3D.h:240
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
void flipAxis(size_t axis)
Definition: Cluster3D.cxx:232
reco::PrincipalComponents & getSkeletonPCA()
Definition: Cluster3D.h:465
constexpr auto abs(T v)
Returns the absolute value of the argument.
reco::EdgeList & getBestEdgeList()
Definition: Cluster3D.h:468
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:463
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:242
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:464
std::string indent(std::size_t const i)
void buildConvexHull(reco::ClusterParameters &clusterParameters, int level=0) const
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:326
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:243
void lar_cluster3d::VoronoiPathFinder::ModifyClusters ( reco::ClusterParametersList clusterParametersList) const
overridevirtual

Scan an input collection of clusters and modify those according to the specific implementing algorithm.

Parameters
clusterParametersListA list of cluster objects (parameters from associated hits)

Top level interface for algorithm to consider pairs of clusters from the input list and determine if they are consistent with each other and, therefore, should be merged. This is done by looking at the PCA for each cluster and looking at the projection of the primary axis along the vector connecting their centers.

Implements lar_cluster3d::IClusterModAlg.

Definition at line 220 of file VoronoiPathFinder_tool.cc.

References buildConvexHull(), buildVoronoiDiagram(), reco::ClusterParameters::daughterList(), fEnableMonitoring, fFillHistograms, fMinTinyClusterSize, fTimeToProcess, fTopEigen10Ratio, fTopEigen20Ratio, fTopEigen21Ratio, fTopNum3DHits, fTopNumEdges, fTopPrimaryLength, reco::PrincipalComponents::getEigenValues(), reco::ClusterParameters::getHitPairListPtr(), and subDivideCluster().

221  {
229  // Initial clustering is done, now trim the list and get output parameters
230  cet::cpu_timer theClockBuildClusters;
231 
232  // Start clocks if requested
233  if (fEnableMonitoring) theClockBuildClusters.start();
234 
235  int countClusters(0);
236 
237  // This is the loop over candidate 3D clusters
238  // Note that it might be that the list of candidate clusters is modified by splitting
239  // So we use the following construct to make sure we get all of them
240  reco::ClusterParametersList::iterator clusterParametersListItr = clusterParametersList.begin();
241 
242  while (clusterParametersListItr != clusterParametersList.end()) {
243  // Dereference to get the cluster paramters
244  reco::ClusterParameters& clusterParameters = *clusterParametersListItr;
245 
246  std::cout << "**> Looking at Cluster " << countClusters++
247  << ", # hits: " << clusterParameters.getHitPairListPtr().size() << std::endl;
248 
249  // It turns out that computing the convex hull surrounding the points in the 2D projection onto the
250  // plane of largest spread in the PCA is a good way to break up the cluster... and we do it here since
251  // we (currently) want this to be part of the standard output
252  buildVoronoiDiagram(clusterParameters);
253 
254  // Make sure our cluster has enough hits...
255  if (clusterParameters.getHitPairListPtr().size() > fMinTinyClusterSize) {
256  // Get an interim cluster list
257  reco::ClusterParametersList reclusteredParameters;
258 
259  // Call the main workhorse algorithm for building the local version of candidate 3D clusters
260  //******** Remind me why we need to call this at this point when the same hits will be used? ********
261  //fClusterAlg->Cluster3DHits(clusterParameters.getHitPairListPtr(), reclusteredParameters);
262  reclusteredParameters.push_back(clusterParameters);
263 
264  std::cout << ">>>>>>>>>>> Reclustered to " << reclusteredParameters.size()
265  << " Clusters <<<<<<<<<<<<<<<" << std::endl;
266 
267  // Only process non-empty results
268  if (!reclusteredParameters.empty()) {
269  // Loop over the reclustered set
270  for (auto& cluster : reclusteredParameters) {
271  std::cout << "****> Calling breakIntoTinyBits with "
272  << cluster.getHitPairListPtr().size() << " hits" << std::endl;
273 
274  // It turns out that computing the convex hull surrounding the points in the 2D projection onto the
275  // plane of largest spread in the PCA is a good way to break up the cluster... and we do it here since
276  // we (currently) want this to be part of the standard output
278 
279  // Break our cluster into smaller elements...
280  subDivideCluster(cluster, cluster.daughterList().end(), cluster.daughterList(), 4);
281 
282  std::cout << "****> Broke Cluster with " << cluster.getHitPairListPtr().size()
283  << " into " << cluster.daughterList().size() << " sub clusters";
284  for (auto& clus : cluster.daughterList())
285  std::cout << ", " << clus.getHitPairListPtr().size();
286  std::cout << std::endl;
287 
288  // Add the daughters to the cluster
289  clusterParameters.daughterList().insert(clusterParameters.daughterList().end(),
290  cluster);
291 
292  // If filling histograms we do the main cluster here
293  if (fFillHistograms) {
294  reco::PrincipalComponents& fullPCA = cluster.getFullPCA();
295  std::vector<double> eigenValVec = {3. * std::sqrt(fullPCA.getEigenValues()[0]),
296  3. * std::sqrt(fullPCA.getEigenValues()[1]),
297  3. * std::sqrt(fullPCA.getEigenValues()[2])};
298  double eigen2To1Ratio = eigenValVec[0] / eigenValVec[1];
299  double eigen1To0Ratio = eigenValVec[1] / eigenValVec[2];
300  double eigen2To0Ratio = eigenValVec[0] / eigenValVec[2];
301  int num3DHits = cluster.getHitPairListPtr().size();
302  int numEdges = cluster.getBestEdgeList().size();
303 
304  fTopNum3DHits->Fill(std::min(num3DHits, 199), 1.);
305  fTopNumEdges->Fill(std::min(numEdges, 199), 1.);
306  fTopEigen21Ratio->Fill(eigen2To1Ratio, 1.);
307  fTopEigen20Ratio->Fill(eigen2To0Ratio, 1.);
308  fTopEigen10Ratio->Fill(eigen1To0Ratio, 1.);
309  fTopPrimaryLength->Fill(std::min(eigenValVec[0], 199.), 1.);
310  }
311  }
312  }
313  }
314 
315  // Go to next cluster parameters object
316  clusterParametersListItr++;
317  }
318 
319  if (fEnableMonitoring) {
320  theClockBuildClusters.stop();
321 
322  fTimeToProcess = theClockBuildClusters.accumulated_real_time();
323  }
324 
325  mf::LogDebug("Cluster3D") << ">>>>> Cluster Path finding done" << std::endl;
326 
327  return;
328  }
intermediate_table::iterator iterator
void buildVoronoiDiagram(reco::ClusterParameters &clusterParameters) const
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:463
Cluster finding and building.
ClusterParametersList & daughterList()
Definition: Cluster3D.h:438
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:242
void buildConvexHull(reco::ClusterParameters &clusterParameters, int level=0) const
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
size_t fMinTinyClusterSize
Minimum size for a "tiny" cluster.
reco::ClusterParametersList::iterator subDivideCluster(reco::ClusterParameters &cluster, reco::ClusterParametersList::iterator positionItr, reco::ClusterParametersList &outputClusterList, int level=0) const
Use PCA to try to find path in cluster.
bool fFillHistograms
Histogram definitions.
std::list< ClusterParameters > ClusterParametersList
Definition: Cluster3D.h:393
reco::ClusterParametersList::iterator lar_cluster3d::VoronoiPathFinder::subDivideCluster ( reco::ClusterParameters cluster,
reco::ClusterParametersList::iterator  positionItr,
reco::ClusterParametersList outputClusterList,
int  level = 0 
) const
private

Use PCA to try to find path in cluster.

Parameters
clusterParametersThe given cluster parameters object to try to split
clusterParametersListThe list of clusters

Definition at line 572 of file VoronoiPathFinder_tool.cc.

References fFillHistograms, fMinTinyClusterSize, fPCAAlg, fSubCosExtToPCA, fSubCosToPrevPCA, fSubEigen10Ratio, fSubEigen20Ratio, fSubEigen21Ratio, fSubMaxDefect, fSubNum3DHits, fSubNumEdges, fSubPrimaryLength, fSubUsedDefect, reco::ClusterParameters::getBestEdgeList(), reco::ClusterParameters::getConvexHull(), reco::ConvexHull::getConvexHullExtremePoints(), reco::PrincipalComponents::getEigenValues(), reco::PrincipalComponents::getEigenVectors(), reco::ClusterParameters::getFullPCA(), reco::ClusterParameters::getHitPairListPtr(), reco::ClusterHit3D::getPosition(), art::detail::indent(), art::left(), makeCandidateCluster(), lar_cluster3d::PrincipalComponentsAlg::PCAAnalysis_calc3DDocas(), art::right(), and reco::ClusterHit2D::USED.

Referenced by getTimeToExecute(), and ModifyClusters().

577  {
578  // This is a recursive routine to divide an input cluster, according to the maximum defect point of
579  // the convex hull until we reach the point of no further improvement.
580  // The assumption is that the input cluster is fully formed already, this routine then simply
581  // divides, if successful division into two pieces it then stores the results
582 
583  // No point in doing anything if we don't have enough space points
584  if (clusterToBreak.getHitPairListPtr().size() > size_t(2 * fMinTinyClusterSize)) {
585  // set an indention string
586  std::string pluses(level / 2, '+');
587  std::string indent(level / 2, ' ');
588 
589  indent += pluses;
590 
591  // To make best use of this we'll also want the PCA for this cluster... so...
592  // Recover the prime ingredients
593  reco::PrincipalComponents& fullPCA = clusterToBreak.getFullPCA();
594  std::vector<double> eigenValVec = {3. * std::sqrt(fullPCA.getEigenValues()[0]),
595  3. * std::sqrt(fullPCA.getEigenValues()[1]),
596  3. * std::sqrt(fullPCA.getEigenValues()[2])};
597  Eigen::Vector3f fullPrimaryVec(fullPCA.getEigenVectors().row(2));
598 
599  // We want to find the convex hull vertices that lie furthest from the line to/from the extreme points
600  // To find these we:
601  // 1) recover the extreme points
602  // 2) form the vector between them
603  // 3) loop through the vertices and keep track of distance to this vector
604  // 4) Sort the resulting list by furthest points and select the one we want
605  reco::ProjectedPointList::const_iterator extremePointListItr =
606  clusterToBreak.getConvexHull().getConvexHullExtremePoints().begin();
607 
608  const reco::ClusterHit3D* firstEdgeHit = std::get<2>(*extremePointListItr++);
609  const reco::ClusterHit3D* secondEdgeHit = std::get<2>(*extremePointListItr);
610  Eigen::Vector3f edgeVec(secondEdgeHit->getPosition()[0] - firstEdgeHit->getPosition()[0],
611  secondEdgeHit->getPosition()[1] - firstEdgeHit->getPosition()[1],
612  secondEdgeHit->getPosition()[2] - firstEdgeHit->getPosition()[2]);
613  double edgeLen = edgeVec.norm();
614 
615  // normalize it
616  edgeVec.normalize();
617 
618  // Recover the list of 3D hits associated to this cluster
619  reco::HitPairListPtr& clusHitPairVector = clusterToBreak.getHitPairListPtr();
620 
621  // Calculate the doca to the PCA primary axis for each 3D hit
622  // Importantly, this also gives us the arclength along that axis to the hit
623  fPCAAlg.PCAAnalysis_calc3DDocas(clusHitPairVector, fullPCA);
624 
625  // Sort the hits along the PCA
626  clusHitPairVector.sort([](const auto& left, const auto& right) {
627  return left->getArclenToPoca() < right->getArclenToPoca();
628  });
629 
630  // Set up container to keep track of edges
631  using DistEdgeTuple = std::tuple<float, const reco::EdgeTuple*>;
632  using DistEdgeTupleVec = std::vector<DistEdgeTuple>;
633 
634  DistEdgeTupleVec distEdgeTupleVec;
635 
636  // Now loop through all the edges and search for the furthers point
637  for (const auto& edge : clusterToBreak.getBestEdgeList()) {
638  const reco::ClusterHit3D* nextEdgeHit = std::get<0>(edge); // recover the first point
639 
640  // Create vector to this point from the longest edge
641  Eigen::Vector3f hitToEdgeVec(nextEdgeHit->getPosition()[0] - firstEdgeHit->getPosition()[0],
642  nextEdgeHit->getPosition()[1] - firstEdgeHit->getPosition()[1],
643  nextEdgeHit->getPosition()[2] -
644  firstEdgeHit->getPosition()[2]);
645 
646  // Get projection
647  float hitProjection = hitToEdgeVec.dot(edgeVec);
648 
649  // Require that the point is really "opposite" the longest edge
650  if (hitProjection > 0. && hitProjection < edgeLen) {
651  Eigen::Vector3f distToHitVec = hitToEdgeVec - hitProjection * edgeVec;
652  float distToHit = distToHitVec.norm();
653 
654  distEdgeTupleVec.emplace_back(distToHit, &edge);
655  }
656  }
657 
658  std::sort(
659  distEdgeTupleVec.begin(), distEdgeTupleVec.end(), [](const auto& left, const auto& right) {
660  return std::get<0>(left) > std::get<0>(right);
661  });
662 
663  // Get a temporary container to hol
664  reco::ClusterParametersList tempClusterParametersList;
665  float usedDefectDist(0.);
666 
667  for (const auto& distEdgeTuple : distEdgeTupleVec) {
668  const reco::EdgeTuple& edgeTuple = *std::get<1>(distEdgeTuple);
669  const reco::ClusterHit3D* edgeHit = std::get<0>(edgeTuple);
670 
671  usedDefectDist = std::get<0>(distEdgeTuple);
672 
673  // Now find the hit identified above as furthest away
675  std::find(clusHitPairVector.begin(), clusHitPairVector.end(), edgeHit);
676 
677  // Make sure enough hits either side, otherwise we just keep the current cluster
678  if (vertexItr == clusHitPairVector.end() ||
679  std::distance(clusHitPairVector.begin(), vertexItr) < int(fMinTinyClusterSize) ||
680  std::distance(vertexItr, clusHitPairVector.end()) < int(fMinTinyClusterSize))
681  continue;
682 
683  tempClusterParametersList.push_back(reco::ClusterParameters());
684 
685  reco::ClusterParameters& clusterParams1 = tempClusterParametersList.back();
686 
688  fullPrimaryVec, clusterParams1, clusHitPairVector.begin(), vertexItr, level)) {
689  tempClusterParametersList.push_back(reco::ClusterParameters());
690 
691  reco::ClusterParameters& clusterParams2 = tempClusterParametersList.back();
692 
694  fullPrimaryVec, clusterParams2, vertexItr, clusHitPairVector.end(), level))
695  break;
696  }
697 
698  // If here then we could not make two valid clusters and so we try again
699  tempClusterParametersList.clear();
700  }
701 
702  // Fallback in the event of still large clusters but not defect points
703  if (tempClusterParametersList.empty()) {
704  std::cout << indent << "===> no cluster cands, edgeLen: " << edgeLen
705  << ", # hits: " << clusHitPairVector.size()
706  << ", max defect: " << std::get<0>(distEdgeTupleVec.front()) << std::endl;
707 
708  usedDefectDist = 0.;
709 
710  if (edgeLen > 20.) {
711  reco::HitPairListPtr::iterator vertexItr = clusHitPairVector.begin();
712 
713  std::advance(vertexItr, clusHitPairVector.size() / 2);
714 
715  tempClusterParametersList.push_back(reco::ClusterParameters());
716 
717  reco::ClusterParameters& clusterParams1 = tempClusterParametersList.back();
718 
720  fullPrimaryVec, clusterParams1, clusHitPairVector.begin(), vertexItr, level)) {
721  tempClusterParametersList.push_back(reco::ClusterParameters());
722 
723  reco::ClusterParameters& clusterParams2 = tempClusterParametersList.back();
724 
726  fullPrimaryVec, clusterParams2, vertexItr, clusHitPairVector.end(), level))
727  tempClusterParametersList.clear();
728  }
729  }
730  }
731 
732  // Can only end with no candidate clusters or two so don't
733  for (auto& clusterParams : tempClusterParametersList) {
734  size_t curOutputClusterListSize = outputClusterList.size();
735 
736  positionItr = subDivideCluster(clusterParams, positionItr, outputClusterList, level + 4);
737 
738  std::cout << indent << "Output cluster list prev: " << curOutputClusterListSize
739  << ", now: " << outputClusterList.size() << std::endl;
740 
741  // If the cluster we sent in was successfully broken then the position iterator will be shifted
742  // This means we don't want to restore the current cluster here
743  if (curOutputClusterListSize < outputClusterList.size()) continue;
744 
745  // I think this is where we fill out the rest of the parameters?
746  // Start by adding the 2D hits...
747  // See if we can avoid duplicates by temporarily transferring to a set
748  std::set<const reco::ClusterHit2D*> hitSet;
749 
750  // Loop through 3D hits to get a set of unique 2D hits
751  for (const auto& hit3D : clusterParams.getHitPairListPtr()) {
752  for (const auto& hit2D : hit3D->getHits()) {
753  if (hit2D) hitSet.insert(hit2D);
754  }
755  }
756 
757  // Now add these to the new cluster
758  for (const auto& hit2D : hitSet) {
759  hit2D->setStatusBit(reco::ClusterHit2D::USED);
760  clusterParams.UpdateParameters(hit2D);
761  }
762 
763  std::cout << indent << "*********>>> storing new subcluster of size "
764  << clusterParams.getHitPairListPtr().size() << std::endl;
765 
766  positionItr = outputClusterList.insert(positionItr, clusterParams);
767 
768  // Are we filling histograms
769  if (fFillHistograms) {
770  // Recover the new fullPCA
771  reco::PrincipalComponents& newFullPCA = clusterParams.getFullPCA();
772 
773  Eigen::Vector3f newPrimaryVec(fullPCA.getEigenVectors().row(2));
774  Eigen::Vector3f lastPrimaryVec(newFullPCA.getEigenVectors().row(2));
775 
776  int num3DHits = clusterParams.getHitPairListPtr().size();
777  int numEdges = clusterParams.getBestEdgeList().size();
778  float cosToLast = newPrimaryVec.dot(lastPrimaryVec);
779  double eigen2To1Ratio = eigenValVec[0] / eigenValVec[1];
780  double eigen1To0Ratio = eigenValVec[1] / eigenValVec[2];
781  double eigen2To0Ratio = eigenValVec[2] / eigenValVec[2];
782 
783  fSubNum3DHits->Fill(std::min(num3DHits, 199), 1.);
784  fSubNumEdges->Fill(std::min(numEdges, 199), 1.);
785  fSubEigen21Ratio->Fill(eigen2To1Ratio, 1.);
786  fSubEigen20Ratio->Fill(eigen2To0Ratio, 1.);
787  fSubEigen10Ratio->Fill(eigen1To0Ratio, 1.);
788  fSubCosToPrevPCA->Fill(cosToLast, 1.);
789  fSubPrimaryLength->Fill(std::min(eigenValVec[2], 199.), 1.);
790  fSubCosExtToPCA->Fill(fullPrimaryVec.dot(edgeVec), 1.);
791  fSubMaxDefect->Fill(std::get<0>(distEdgeTupleVec.front()), 1.);
792  fSubUsedDefect->Fill(usedDefectDist, 1.);
793  }
794 
795  // The above points to the element, want the next element
796  positionItr++;
797  }
798  }
799 
800  return positionItr;
801  }
intermediate_table::iterator iterator
void PCAAnalysis_calc3DDocas(const reco::HitPairListPtr &hitPairVector, const reco::PrincipalComponents &pca) const
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:155
intermediate_table::const_iterator const_iterator
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:242
std::tuple< const reco::ClusterHit3D *, const reco::ClusterHit3D *, double > EdgeTuple
Definition: Cluster3D.h:336
std::string indent(std::size_t const i)
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:326
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
bool makeCandidateCluster(Eigen::Vector3f &, reco::ClusterParameters &, reco::HitPairListPtr::iterator, reco::HitPairListPtr::iterator, int) const
size_t fMinTinyClusterSize
Minimum size for a "tiny" cluster.
reco::ClusterParametersList::iterator subDivideCluster(reco::ClusterParameters &cluster, reco::ClusterParametersList::iterator positionItr, reco::ClusterParametersList &outputClusterList, int level=0) const
Use PCA to try to find path in cluster.
bool fFillHistograms
Histogram definitions.
std::list< ClusterParameters > ClusterParametersList
Definition: Cluster3D.h:393
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:243

Member Data Documentation

std::unique_ptr<lar_cluster3d::IClusterAlg> lar_cluster3d::VoronoiPathFinder::fClusterAlg
private

Tools.

Algorithm to do 3D space point clustering

Definition at line 158 of file VoronoiPathFinder_tool.cc.

Referenced by configure().

bool lar_cluster3d::VoronoiPathFinder::fEnableMonitoring
private

FHICL parameters.

Definition at line 127 of file VoronoiPathFinder_tool.cc.

Referenced by configure(), and ModifyClusters().

bool lar_cluster3d::VoronoiPathFinder::fFillHistograms
private

Histogram definitions.

Definition at line 134 of file VoronoiPathFinder_tool.cc.

Referenced by breakIntoTinyBits(), initializeHistograms(), ModifyClusters(), and subDivideCluster().

size_t lar_cluster3d::VoronoiPathFinder::fMinTinyClusterSize
private

Minimum size for a "tiny" cluster.

Definition at line 128 of file VoronoiPathFinder_tool.cc.

Referenced by breakIntoTinyBits(), configure(), ModifyClusters(), and subDivideCluster().

PrincipalComponentsAlg lar_cluster3d::VoronoiPathFinder::fPCAAlg
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubCosExtToPCA
private

Definition at line 150 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and subDivideCluster().

TH1F* lar_cluster3d::VoronoiPathFinder::fSubCosToPrevPCA
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubEigen10Ratio
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubEigen20Ratio
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubEigen21Ratio
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubMaxDefect
private

Definition at line 151 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and subDivideCluster().

TH1F* lar_cluster3d::VoronoiPathFinder::fSubNum3DHits
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubNumEdges
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubPrimaryLength
private
TH1F* lar_cluster3d::VoronoiPathFinder::fSubUsedDefect
private

Definition at line 152 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and subDivideCluster().

float lar_cluster3d::VoronoiPathFinder::fTimeToProcess
mutableprivate

Definition at line 129 of file VoronoiPathFinder_tool.cc.

Referenced by configure(), getTimeToExecute(), and ModifyClusters().

TH1F* lar_cluster3d::VoronoiPathFinder::fTopEigen10Ratio
private

Definition at line 140 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and ModifyClusters().

TH1F* lar_cluster3d::VoronoiPathFinder::fTopEigen20Ratio
private

Definition at line 139 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and ModifyClusters().

TH1F* lar_cluster3d::VoronoiPathFinder::fTopEigen21Ratio
private

Definition at line 138 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and ModifyClusters().

TH1F* lar_cluster3d::VoronoiPathFinder::fTopNum3DHits
private

Definition at line 136 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and ModifyClusters().

TH1F* lar_cluster3d::VoronoiPathFinder::fTopNumEdges
private

Definition at line 137 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and ModifyClusters().

TH1F* lar_cluster3d::VoronoiPathFinder::fTopPrimaryLength
private

Definition at line 141 of file VoronoiPathFinder_tool.cc.

Referenced by initializeHistograms(), and ModifyClusters().


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