All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
lar_cluster3d::HoughSeedFinderAlg Class Reference

HoughSeedFinderAlg class. More...

#include <HoughSeedFinderAlg.h>

Inheritance diagram for lar_cluster3d::HoughSeedFinderAlg:
lar_cluster3d::SeedFinderAlgBase

Classes

class  AccumulatorBin
 
struct  SortBinIndexList
 
class  SortHoughClusterList
 

Public Member Functions

 HoughSeedFinderAlg (fhicl::ParameterSet const &pset)
 Constructor. More...
 
bool findTrackSeeds (reco::HitPairListPtr &hitPairListPtr, reco::PrincipalComponents &inputPCA, SeedHitPairListPairVec &seedHitPairVec) const override
 Given the list of hits this will search for candidate Seed objects and return them. More...
 
bool findTrackHits (reco::HitPairListPtr &hitPairListPtr, reco::PrincipalComponents &inputPCA, reco::HitPairListPtrList &hitPairListPtrList) const
 Given the list of hits this will return the sets of hits which belong on the same line. More...
 

Private Types

typedef std::pair< int, int > BinIndex
 
typedef std::map< BinIndex,
AccumulatorBin
RhoThetaAccumulatorBinMap
 
typedef std::list< BinIndexHoughCluster
 
typedef std::list< HoughClusterHoughClusterList
 

Private Member Functions

void findHitGaps (reco::HitPairListPtr &inputHitList, reco::HitPairListPtr &outputList) const
 Using Principal Components Axis, look for gaps in a list of 3D hits. More...
 
void HoughRegionQuery (BinIndex &curBin, RhoThetaAccumulatorBinMap &rhoThetaAccumulatorBinMap, HoughCluster &neighborPts, size_t threshold) const
 
void expandHoughCluster (BinIndex &curBin, HoughCluster &neighborPts, HoughCluster &houghCluster, RhoThetaAccumulatorBinMap &rhoThetaAccumulatorBinMap, size_t threshold) const
 
void findHoughClusters (const reco::HitPairListPtr &inputHits, reco::PrincipalComponents &pca, int &nLoops, RhoThetaAccumulatorBinMap &rhoThetaMap, HoughClusterList &clusterList) const
 
bool buildSeed (reco::HitPairListPtr &seed3DHits, SeedHitPairListPair &seedHitPair) const
 Given a list of candidate "seed" 3D hits, build the seed and get associated unique 2D hits. More...
 
void LineFit2DHits (std::set< const reco::ClusterHit2D * > &hitList, double XOrigin, TVector3 &Pos, TVector3 &Dir, double &ChiDOF) const
 

Private Attributes

size_t m_minimum3DHits
 
int m_thetaBins
 
int m_rhoBins
 
size_t m_hiThresholdMin
 
double m_hiThresholdFrac
 
double m_loThresholdFrac
 
size_t m_numSeed2DHits
 
double m_numAveDocas
 
int m_numSkippedHits
 
int m_maxLoopsPerCluster
 
double m_maximumGap
 
geo::Geometry const * m_geometry
 
PrincipalComponentsAlg m_pcaAlg
 
bool m_displayHist
 
std::vector< std::unique_ptr
< TCanvas > > 
m_Canvases
 Graphical trace canvases. More...
 
std::vector< TVirtualPad * > m_Pads
 View pads in current canvas. More...
 

Detailed Description

HoughSeedFinderAlg class.

Definition at line 34 of file HoughSeedFinderAlg.h.

Member Typedef Documentation

typedef std::pair<int, int> lar_cluster3d::HoughSeedFinderAlg::BinIndex
private

Definition at line 73 of file HoughSeedFinderAlg.h.

Definition at line 79 of file HoughSeedFinderAlg.h.

Definition at line 80 of file HoughSeedFinderAlg.h.

Definition at line 78 of file HoughSeedFinderAlg.h.

Constructor & Destructor Documentation

lar_cluster3d::HoughSeedFinderAlg::HoughSeedFinderAlg ( fhicl::ParameterSet const &  pset)

Constructor.

Parameters
pset

Definition at line 41 of file HoughSeedFinderAlg.cxx.

42  : m_minimum3DHits(5)
43  , m_thetaBins(360)
44  , m_rhoBins(75)
45  , m_hiThresholdMin(5)
46  , m_hiThresholdFrac(.05)
47  , m_loThresholdFrac(0.85)
48  , m_numSeed2DHits(80)
49  , m_numAveDocas(6.)
50  , m_numSkippedHits(10)
52  , m_maximumGap(5.)
53  , m_pcaAlg(pset.get<fhicl::ParameterSet>("PrincipalComponentsAlg"))
54  , m_displayHist(false)
55  {
56  m_minimum3DHits = pset.get<size_t>("Minimum3DHits", 5);
57  m_thetaBins = pset.get<int>("ThetaBins", 360);
58  m_rhoBins = pset.get<int>("HalfRhoBins", 75);
59  m_hiThresholdMin = pset.get<size_t>("HiThresholdMin", 5);
60  m_hiThresholdFrac = pset.get<double>("HiThresholdFrac", 0.05);
61  m_loThresholdFrac = pset.get<double>("LoThresholdFrac", 0.85);
62  m_numSeed2DHits = pset.get<size_t>("NumSeed2DHits", 80);
63  m_numAveDocas = pset.get<double>("NumAveDocas", 6.);
64  m_numSkippedHits = pset.get<int>("NumSkippedHits", 10);
65  m_maxLoopsPerCluster = pset.get<int>("MaxLoopsPerCluster", 3);
66  m_maximumGap = pset.get<double>("MaximumGap", 5.);
67  m_displayHist = pset.get<bool>("DisplayHoughHist", false);
68  m_geometry = art::ServiceHandle<geo::Geometry const>{}.get();
69  }

Member Function Documentation

bool lar_cluster3d::HoughSeedFinderAlg::buildSeed ( reco::HitPairListPtr seed3DHits,
SeedHitPairListPair seedHitPair 
) const
private

Given a list of candidate "seed" 3D hits, build the seed and get associated unique 2D hits.

Definition at line 583 of file HoughSeedFinderAlg.cxx.

585  {
586  if (seed3DHits.size() < m_minimum3DHits) return false;
587 
588  reco::PrincipalComponents seedFullPca;
589 
590  m_pcaAlg.PCAAnalysis_3D(seed3DHits, seedFullPca, true);
591 
592  if (!seedFullPca.getSvdOK()) return false;
593 
594  // Use the following to set the 3D doca and arclength for each hit
595  m_pcaAlg.PCAAnalysis_calc3DDocas(seed3DHits, seedFullPca);
596 
597  // Use this info to sort the hits along the principle axis
598  //seed3DHits.sort(SeedFinderAlgBase::Sort3DHitsByArcLen3D());
599  seed3DHits.sort(SeedFinderAlgBase::Sort3DHitsByAbsArcLen3D());
600 
601  // The idea here is to search for the first hit that lies "close" to the principle axis
602  // At that point we count out n hits to use as the seed
603  reco::HitPairListPtr seedHit3DList;
604  std::set<const reco::ClusterHit2D*> seedHitSet;
605  double aveDocaToAxis = seedFullPca.getAveHitDoca();
606  int gapCount(0);
607 
608  // Now loop through hits to search for a "continuous" block of at least m_numSeed2DHits
609  // We'll arrive at that number by collecting 2D hits in an stl set which will keep track of unique occurances
610  for (reco::HitPairListPtr::iterator peakBinItr = seed3DHits.begin();
611  peakBinItr != seed3DHits.end();
612  peakBinItr++) {
613  const reco::ClusterHit3D* hit3D = *peakBinItr;
614 
615  if (hit3D->getDocaToAxis() < m_numAveDocas * aveDocaToAxis) {
616  // Check if we need to reset because of gap count
617  if (gapCount > m_numSkippedHits) {
618  seedHit3DList.clear();
619  seedHitSet.clear();
620  }
621 
622  seedHit3DList.push_back(hit3D);
623 
624  for (const auto& hit : hit3D->getHits())
625  seedHitSet.insert(hit);
626 
627  gapCount = 0;
628  }
629  else
630  gapCount++;
631 
632  if (seedHitSet.size() > m_numSeed2DHits) break;
633  }
634 
635  // If not enough hits then we are done
636  if (seedHit3DList.size() < m_minimum3DHits) return false;
637 
639 
640  // Use only the "seed" 3D hits to get new PCA axes
641  m_pcaAlg.PCAAnalysis_3D(seedHit3DList, seedPca, true);
642 
643  if (!seedPca.getSvdOK()) return false;
644 
645  m_pcaAlg.PCAAnalysis_calc3DDocas(seedHit3DList, seedPca);
646  //seedHit3DList.sort(SeedFinderAlgBase::Sort3DHitsByAbsArcLen3D());
647  seedHit3DList.sort(SeedFinderAlgBase::Sort3DHitsByArcLen3D());
648 
649  // Now translate the seedCenter by the arc len to the first hit
650  double seedCenter[3] = {
651  seedPca.getAvePosition()[0], seedPca.getAvePosition()[1], seedPca.getAvePosition()[2]};
652  double seedDir[3] = {seedPca.getEigenVectors().row(2)[0],
653  seedPca.getEigenVectors().row(2)[1],
654  seedPca.getEigenVectors().row(2)[2]};
655 
656  double arcLen = seedHit3DList.front()->getArclenToPoca();
657  double seedStart[3] = {seedCenter[0] + arcLen * seedDir[0],
658  seedCenter[1] + arcLen * seedDir[1],
659  seedCenter[2] + arcLen * seedDir[2]};
660 
661  //seedStart[0] = seedHit3DList.front()->getX();
662  //seedStart[1] = seedHit3DList.front()->getY();
663  //seedStart[2] = seedHit3DList.front()->getZ();
664 
665  if (seedHitSet.size() >= 10) {
666  TVector3 newSeedPos;
667  TVector3 newSeedDir;
668  double chiDOF;
669 
670  LineFit2DHits(seedHitSet, seedStart[0], newSeedPos, newSeedDir, chiDOF);
671 
672  if (chiDOF > 0.) {
673  // check angles between new/old directions
674  double cosAng =
675  seedDir[0] * newSeedDir[0] + seedDir[1] * newSeedDir[1] + seedDir[2] * newSeedDir[2];
676 
677  if (cosAng < 0.) newSeedDir *= -1.;
678 
679  seedStart[0] = newSeedPos[0];
680  seedStart[1] = newSeedPos[1];
681  seedStart[2] = newSeedPos[2];
682  seedDir[0] = newSeedDir[0];
683  seedDir[1] = newSeedDir[1];
684  seedDir[2] = newSeedDir[2];
685  }
686  }
687 
688  // Keep track of this seed and the 3D hits that make it up
689  seedHitPair = SeedHitPairListPair(recob::Seed(seedStart, seedDir), seedHit3DList);
690 
691  // We are going to drop a few hits off the ends in the hope this facilitates finding more track like objects, provided there are enough hits
692  if (seed3DHits.size() > 100) {
693  // Need to reset the doca/arclen first
694  m_pcaAlg.PCAAnalysis_calc3DDocas(seed3DHits, seedFullPca);
695 
696  // Now resort the hits
697  seed3DHits.sort(SeedFinderAlgBase::Sort3DHitsByAbsArcLen3D());
698 
699  size_t numToKeep = seed3DHits.size() - 10;
700 
701  reco::HitPairListPtr::iterator endItr = seed3DHits.begin();
702 
703  std::advance(endItr, numToKeep);
704 
705  seed3DHits.erase(endItr, seed3DHits.end());
706  }
707 
708  return true;
709  }
void LineFit2DHits(std::set< const reco::ClusterHit2D * > &hitList, double XOrigin, TVector3 &Pos, TVector3 &Dir, double &ChiDOF) const
void PCAAnalysis_calc3DDocas(const reco::HitPairListPtr &hitPairVector, const reco::PrincipalComponents &pca) const
bool getSvdOK() const
Definition: Cluster3D.h:243
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
process_name hit
Definition: cheaterreco.fcl:51
float getDocaToAxis() const
Definition: Cluster3D.h:168
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:247
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:334
const float getAveHitDoca() const
Definition: Cluster3D.h:248
std::pair< recob::Seed, reco::HitPairListPtr > SeedHitPairListPair
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:170
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:246
void lar_cluster3d::HoughSeedFinderAlg::expandHoughCluster ( BinIndex curBin,
HoughCluster neighborPts,
HoughCluster houghCluster,
RhoThetaAccumulatorBinMap rhoThetaAccumulatorBinMap,
size_t  threshold 
) const
private

The workhorse routine for a DBScan like clustering routine to identify peak bins in Hough Space

Definition at line 253 of file HoughSeedFinderAlg.cxx.

258  {
259  /**
260  * @brief The workhorse routine for a DBScan like clustering routine to identify peak bins in Hough Space
261  */
262 
263  // Start by adding the input point to our Hough Cluster
264  houghCluster.push_back(curBin);
265 
266  for (auto& binIndex : neighborPts) {
267  AccumulatorBin& accBin = rhoThetaAccumulatorBinMap[binIndex];
268 
269  if (!accBin.isVisited()) {
270  accBin.setVisited();
271 
272  HoughCluster nextNeighborPts;
273 
274  HoughRegionQuery(binIndex, rhoThetaAccumulatorBinMap, nextNeighborPts, threshold);
275 
276  if (!nextNeighborPts.empty()) {
277  for (auto& neighborIdx : nextNeighborPts) {
278  neighborPts.push_back(neighborIdx);
279  }
280  }
281  }
282 
283  if (!accBin.isInCluster()) {
284  houghCluster.push_back(binIndex);
285  accBin.setInCluster();
286  }
287  }
288 
289  return;
290  }
void HoughRegionQuery(BinIndex &curBin, RhoThetaAccumulatorBinMap &rhoThetaAccumulatorBinMap, HoughCluster &neighborPts, size_t threshold) const
void lar_cluster3d::HoughSeedFinderAlg::findHitGaps ( reco::HitPairListPtr inputHitList,
reco::HitPairListPtr outputList 
) const
private

Using Principal Components Axis, look for gaps in a list of 3D hits.

Parameters
inputHitList- input list of 3D hits to check
pca- Principal Components Axis to use
hitListList- output list of hit lists which are gap free

Definition at line 332 of file HoughSeedFinderAlg.cxx.

334  {
335  // Intention is to try to find the largest "contiguous" block of hits in the input list
336  // In a nutshell, the idea is to order input hits according to the pca, then
337  // loop through the hits and store them in a new hit list. If a gap is detected then
338  // we terminate the previous list, create a new one and continue. After the loop over
339  // hits is complete then simply pick the biggest list.
340  // Step I is to run the pca and order the hits
342 
343  m_pcaAlg.PCAAnalysis_3D(inputHitList, pca, true);
344 
345  // It would seem that the analysis can fail!
346  if (!pca.getSvdOK()) {
347  outputList = inputHitList;
348  return;
349  }
350 
351  m_pcaAlg.PCAAnalysis_calc3DDocas(inputHitList, pca);
352 
353  inputHitList.sort(SeedFinderAlgBase::Sort3DHitsByArcLen3D());
354  outputList.clear();
355 
356  // Create containers to hold our hit lists
357  reco::HitPairListPtr continuousHitList;
358 
359  std::map<size_t, reco::HitPairListPtr> gapHitListMap;
360 
361  // Remember the distance arc length of the last hit
362  double arcLenLastHit = inputHitList.front()->getArclenToPoca();
363 
364  // Loop through the input hits
365  for (const auto& hit3D : inputHitList) {
366  // Hits in order, delta arclength should always be positive
367  double arcLen = hit3D->getArclenToPoca();
368  double deltaArcLen = arcLen - arcLenLastHit;
369 
370  if (deltaArcLen > m_maximumGap) {
371  gapHitListMap[continuousHitList.size()] = continuousHitList;
372  continuousHitList.clear();
373  }
374 
375  continuousHitList.emplace_back(hit3D);
376 
377  arcLenLastHit = arcLen;
378  }
379 
380  if (!continuousHitList.empty()) gapHitListMap[continuousHitList.size()] = continuousHitList;
381 
382  // Get the largest list of hits
383  std::map<size_t, reco::HitPairListPtr>::reverse_iterator longestListItr =
384  gapHitListMap.rbegin();
385 
386  if (longestListItr != gapHitListMap.rend()) {
387  size_t nContinuousHits = longestListItr->first;
388  reco::HitPairListPtr longestList = longestListItr->second;
389 
390  outputList.resize(nContinuousHits);
391  std::copy(longestList.begin(), longestList.end(), outputList.begin());
392  }
393 
394  return;
395  }
void PCAAnalysis_calc3DDocas(const reco::HitPairListPtr &hitPairVector, const reco::PrincipalComponents &pca) const
bool getSvdOK() const
Definition: Cluster3D.h:243
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:334
T copy(T const &v)
void lar_cluster3d::HoughSeedFinderAlg::findHoughClusters ( const reco::HitPairListPtr inputHits,
reco::PrincipalComponents pca,
int &  nLoops,
RhoThetaAccumulatorBinMap rhoThetaMap,
HoughClusterList clusterList 
) const
private

Definition at line 398 of file HoughSeedFinderAlg.cxx.

403  {
404  // The goal of this function is to do a basic Hough Transform on the input list of 3D hits.
405  // In order to transform this to a 2D problem, the 3D hits are projected to the plane of the two
406  // largest eigen values from the input principal components analysis axis.
407  // There are two basic steps to the job here:
408  // 1) Build and accumlate a rho-theta map
409  // 2) Go through that rho-theta map and find candidate Hough "clusters"
410  // Unfortunately, the following may not be suitable viewing for those who may be feint of heart
411  //
412  // Define some constants
413  static int histCount(0);
414  const double maxTheta(M_PI); // Obviously, 180 degrees
415  const double thetaBinSize(maxTheta / double(m_thetaBins)); // around 4 degrees (45 bins)
416  const double rhoBinSizeMin(m_geometry->WirePitch()); // Wire spacing gives a natural bin size?
417 
418  // Recover the parameters from the Principal Components Analysis that we need to project and accumulate
419  Eigen::Vector3f pcaCenter(
420  pca.getAvePosition()[0], pca.getAvePosition()[1], pca.getAvePosition()[2]);
421  Eigen::Vector3f planeVec0(pca.getEigenVectors().row(2));
422  Eigen::Vector3f planeVec1(pca.getEigenVectors().row(1));
423  Eigen::Vector3f pcaPlaneNrml(pca.getEigenVectors().row(0));
424  double eigenVal0 = 3. * sqrt(pca.getEigenValues()[2]);
425  double eigenVal1 = 3. * sqrt(pca.getEigenValues()[1]);
426  double maxRho = std::sqrt(eigenVal0 * eigenVal0 + eigenVal1 * eigenVal1) * 2. / 3.;
427  double rhoBinSize = maxRho / double(m_rhoBins);
428 
429  if (rhoBinSize < rhoBinSizeMin) rhoBinSize = rhoBinSizeMin;
430 
431  // **********************************************************************
432  // Part I: Accumulate values in the rho-theta map
433  // **********************************************************************
434 
435  size_t maxBinCount(0);
436  int nAccepted3DHits(0);
437 
438  // Commence looping over the input 3D hits and fill our accumulator bins
439  for (reco::HitPairListPtr::const_iterator hit3DItr = hitPairListPtr.begin();
440  hit3DItr != hitPairListPtr.end();
441  hit3DItr++) {
442  // Recover the hit
443  const reco::ClusterHit3D* hit3D(*hit3DItr);
444 
445  // Skip hits which are not skeleton points
446  if (!(hit3D->getStatusBits() & 0x10000000)) continue;
447 
448  nAccepted3DHits++;
449 
450  Eigen::Vector3f hit3DPosition(
451  hit3D->getPosition()[0], hit3D->getPosition()[1], hit3D->getPosition()[2]);
452  Eigen::Vector3f pcaToHitVec = hit3DPosition - pcaCenter;
453  Eigen::Vector3f pcaToHitPlaneVec(pcaToHitVec.dot(planeVec0), pcaToHitVec.dot(planeVec1), 0.);
454  double xPcaToHit = pcaToHitPlaneVec[0];
455  double yPcaToHit = pcaToHitPlaneVec[1];
456 
457  // Create an accumulator value
458  AccumulatorValues accValue(pcaToHitPlaneVec, hit3DItr);
459 
460  // Commence loop over theta to fill accumulator bins
461  // Note that with theta in the range 0-pi then we can have negative values for rho
462  for (int thetaIdx = 0; thetaIdx < m_thetaBins; thetaIdx++) {
463  // We need to convert our theta index to an angle
464  double theta = thetaBinSize * double(thetaIdx);
465 
466  // calculate rho for this angle
467  double rho = xPcaToHit * std::cos(theta) + yPcaToHit * std::sin(theta);
468 
469  // Get the rho index
470  int rhoIdx = std::round(rho / rhoBinSize);
471 
472  // Accumulate
473  BinIndex binIndex(rhoIdx, thetaIdx);
474 
475  rhoThetaAccumulatorBinMap[binIndex].addAccumulatorValue(accValue);
476 
477  if (rhoThetaAccumulatorBinMap[binIndex].getAccumulatorValues().size() > maxBinCount)
478  maxBinCount = rhoThetaAccumulatorBinMap[binIndex].getAccumulatorValues().size();
479  }
480  }
481 
482  // Accumulation done, if asked now display the hist
483  if (m_displayHist) {
484  std::ostringstream ostr;
485  ostr << "Hough Histogram " << histCount++;
486  m_Canvases.emplace_back(new TCanvas(ostr.str().c_str(), ostr.str().c_str(), 1000, 1000));
487 
488  std::ostringstream ostr2;
489  ostr2 << "Plane";
490 
491  m_Canvases.back()->GetFrame()->SetFillColor(46);
492  m_Canvases.back()->SetFillColor(19);
493  m_Canvases.back()->SetBorderMode(19);
494  m_Canvases.back()->cd(1);
495 
496  double zmin = 0.06;
497  double zmax = 0.94;
498  double xmin = 0.04;
499  double xmax = 0.95;
500  TPad* p = new TPad(ostr2.str().c_str(), ostr2.str().c_str(), zmin, xmin, zmax, xmax);
501  p->SetBit(kCanDelete); // Give away ownership.
502  p->Range(zmin, xmin, zmax, xmax);
503  p->SetFillStyle(4000); // Transparent.
504  p->Draw();
505  m_Pads.push_back(p);
506 
507  TH2D* houghHist = new TH2D("HoughHist",
508  "Hough Space",
509  2 * m_rhoBins,
510  -m_rhoBins + 0.5,
511  m_rhoBins + 0.5,
512  m_thetaBins,
513  0.,
514  m_thetaBins);
515 
516  for (const auto& rhoThetaMap : rhoThetaAccumulatorBinMap) {
517  houghHist->Fill(rhoThetaMap.first.first,
518  rhoThetaMap.first.second + 0.5,
519  rhoThetaMap.second.getAccumulatorValues().size());
520  }
521 
522  houghHist->SetBit(kCanDelete);
523  houghHist->Draw();
524  m_Canvases.back()->Update();
525  }
526 
527  // **********************************************************************
528  // Part II: Use DBScan (or a slight variation) to find clusters of bins
529  // **********************************************************************
530 
531  size_t thresholdLo = std::max(size_t(m_hiThresholdFrac * nAccepted3DHits), m_hiThresholdMin);
532  size_t thresholdHi = m_loThresholdFrac * maxBinCount;
533 
534  std::list<RhoThetaAccumulatorBinMap::iterator> binIndexList;
535 
536  for (RhoThetaAccumulatorBinMap::iterator mapItr = rhoThetaAccumulatorBinMap.begin();
537  mapItr != rhoThetaAccumulatorBinMap.end();
538  mapItr++)
539  binIndexList.push_back(mapItr);
540 
541  binIndexList.sort(SortBinIndexList());
542 
543  for (auto& mapItr : binIndexList) {
544  // If we have been here before we skip
545  //if (mapItr.second.isVisited()) continue;
546  if (mapItr->second.isInCluster()) continue;
547 
548  // Mark this bin as visited
549  // Actually, don't mark it since we are double thresholding and don't want it missed
550  //mapItr.second.setVisited();
551 
552  // Make sure over threshold
553  if (mapItr->second.getAccumulatorValues().size() < thresholdLo) {
554  mapItr->second.setNoise();
555  continue;
556  }
557 
558  // Set the low threshold to make sure we merge bins that might be either side of a boundary trajectory
559  thresholdHi = std::max(
560  size_t(m_loThresholdFrac * mapItr->second.getAccumulatorValues().size()), m_hiThresholdMin);
561 
562  // Recover our neighborhood
563  HoughCluster neighborhood;
564  BinIndex curBin(mapItr->first);
565 
566  HoughRegionQuery(curBin, rhoThetaAccumulatorBinMap, neighborhood, thresholdHi);
567 
568  houghClusters.push_back(HoughCluster());
569 
570  HoughCluster& houghCluster = houghClusters.back();
571 
573  curBin, neighborhood, houghCluster, rhoThetaAccumulatorBinMap, thresholdHi);
574  }
575 
576  // Sort the clusters using the SortHoughClusterList metric
577  if (!houghClusters.empty()) houghClusters.sort(SortHoughClusterList(rhoThetaAccumulatorBinMap));
578 
579  return;
580  }
std::vector< TVirtualPad * > m_Pads
View pads in current canvas.
pdgs p
Definition: selectors.fcl:22
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
void expandHoughCluster(BinIndex &curBin, HoughCluster &neighborPts, HoughCluster &houghCluster, RhoThetaAccumulatorBinMap &rhoThetaAccumulatorBinMap, size_t threshold) const
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:245
void HoughRegionQuery(BinIndex &curBin, RhoThetaAccumulatorBinMap &rhoThetaAccumulatorBinMap, HoughCluster &neighborPts, size_t threshold) const
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:247
std::vector< std::unique_ptr< TCanvas > > m_Canvases
Graphical trace canvases.
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:246
bool lar_cluster3d::HoughSeedFinderAlg::findTrackHits ( reco::HitPairListPtr hitPairListPtr,
reco::PrincipalComponents inputPCA,
reco::HitPairListPtrList hitPairListPtrList 
) const

Given the list of hits this will return the sets of hits which belong on the same line.

Definition at line 907 of file HoughSeedFinderAlg.cxx.

910  {
911  // The goal of this routine is run the Hough Transform on the input set of hits
912  // and then to return a list of lists of hits which are associated to a given line
913 
914  // Make sure we are using the right pca
915  reco::HitPairListPtr hitPairListPtr = inputHitPairListPtr;
916 
917  int nLoops(0);
918 
919  // Make a local copy of the input PCA
920  reco::PrincipalComponents pca = inputPCA;
921 
922  // We also require that there be some spread in the data, otherwise not worth running?
923  double eigenVal0 = 3. * sqrt(pca.getEigenValues()[2]);
924  double eigenVal1 = 3. * sqrt(pca.getEigenValues()[1]);
925 
926  if (eigenVal0 > 5. && eigenVal1 > 0.001) {
927  // **********************************************************************
928  // Part I: Build Hough space and find Hough clusters
929  // **********************************************************************
930  RhoThetaAccumulatorBinMap rhoThetaAccumulatorBinMap;
931  HoughClusterList houghClusters;
932 
933  findHoughClusters(hitPairListPtr, pca, nLoops, rhoThetaAccumulatorBinMap, houghClusters);
934 
935  // **********************************************************************
936  // Part II: Go through the clusters to find the peak bins
937  // **********************************************************************
938 
939  // We need to use a set so we can be sure to have unique hits
940  reco::HitPairListPtr clusterHitsList;
941  std::set<const reco::ClusterHit3D*> masterHitPtrList;
942  std::set<const reco::ClusterHit3D*> peakBinPtrList;
943 
944  size_t firstPeakCount(0);
945 
946  // Loop through the list of all clusters found above
947  for (auto& houghCluster : houghClusters) {
948  BinIndex peakBin = houghCluster.front();
949  size_t peakCount = 0;
950  size_t totalHits = 0;
951 
952  // Make a local (to this cluster) set of of hits
953  std::set<const reco::ClusterHit3D*> localHitPtrList;
954 
955  // Now loop through the bins that were attached to this cluster
956  for (auto& binIndex : houghCluster) {
957  // An even more local list so we can keep track of peak values
958  std::set<const reco::ClusterHit3D*> tempHitPtrList;
959 
960  // Recover the hits associated to this cluster
961  for (auto& hitItr : rhoThetaAccumulatorBinMap[binIndex].getAccumulatorValues()) {
962  reco::HitPairListPtr::const_iterator hit3DItr = hitItr.getHitIterator();
963 
964  tempHitPtrList.insert(*hit3DItr);
965  }
966 
967  // count hits before we remove any
968  totalHits += tempHitPtrList.size();
969 
970  // Trim out any hits already used by a bigger/better cluster
971  std::set<const reco::ClusterHit3D*> tempHit3DSet;
972 
973  std::set_difference(tempHitPtrList.begin(),
974  tempHitPtrList.end(),
975  masterHitPtrList.begin(),
976  masterHitPtrList.end(),
977  std::inserter(tempHit3DSet, tempHit3DSet.end()));
978 
979  tempHitPtrList = tempHit3DSet;
980 
981  size_t binCount = tempHitPtrList.size();
982 
983  if (peakCount < binCount) {
984  peakCount = binCount;
985  peakBin = binIndex;
986  peakBinPtrList = tempHitPtrList;
987  }
988 
989  // Add this to our local list
990  localHitPtrList.insert(tempHitPtrList.begin(), tempHitPtrList.end());
991  }
992 
993  if (localHitPtrList.size() < m_minimum3DHits) continue;
994 
995  if (!firstPeakCount) firstPeakCount = peakCount;
996 
997  // If the peak counts are significantly less than the first cluster's peak then skip
998  if (peakCount < firstPeakCount / 10) continue;
999 
1000  // **********************************************************************
1001  // Part III: Make a list of hits from the total number associated
1002  // **********************************************************************
1003 
1004  hitPairListPtrList.push_back(reco::HitPairListPtr());
1005 
1006  hitPairListPtrList.back().resize(localHitPtrList.size());
1007  std::copy(
1008  localHitPtrList.begin(), localHitPtrList.end(), hitPairListPtrList.back().begin());
1009 
1010  // We want to remove the hits which have been used from further contention
1011  masterHitPtrList.insert(localHitPtrList.begin(), localHitPtrList.end());
1012 
1013  if (hitPairListPtr.size() - masterHitPtrList.size() < m_minimum3DHits) break;
1014  } // end loop over hough clusters
1015  }
1016 
1017  return true;
1018  }
void findHoughClusters(const reco::HitPairListPtr &inputHits, reco::PrincipalComponents &pca, int &nLoops, RhoThetaAccumulatorBinMap &rhoThetaMap, HoughClusterList &clusterList) const
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:245
std::list< HoughCluster > HoughClusterList
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:334
std::map< BinIndex, AccumulatorBin > RhoThetaAccumulatorBinMap
T copy(T const &v)
bool lar_cluster3d::HoughSeedFinderAlg::findTrackSeeds ( reco::HitPairListPtr hitPairListPtr,
reco::PrincipalComponents inputPCA,
SeedHitPairListPairVec seedHitPairVec 
) const
overridevirtual

Given the list of hits this will search for candidate Seed objects and return them.

Implements lar_cluster3d::SeedFinderAlgBase.

Definition at line 712 of file HoughSeedFinderAlg.cxx.

715  {
716  // This will be a busy routine... the basic tasks are:
717  // 1) loop through hits and project to the plane defined by the two largest eigen values, accumulate in Hough space
718  // 2) "Cluster" the Hough space to associate hits which are common to a line
719  // 3) Process these clusters (still to be defined exactly)
720 
721  // Create an interim data structure which will allow us to sort our seeds by "best"
722  // before we return them in the seedHitPairVec
723  typedef std::map<size_t, SeedHitPairListPairVec> SizeToSeedToHitMap;
724 
725  SizeToSeedToHitMap seedHitPairMap;
726  SeedHitPairListPair seedHitPair;
727 
728  // Make sure we are using the right pca
729  reco::HitPairListPtr hitPairListPtr = inputHitPairListPtr;
730 
731  int nLoops(0);
732 
733  // Make a local copy of the input PCA
734  reco::PrincipalComponents pca = inputPCA;
735 
736  // We loop over hits in our list until there are no more
737  while (!hitPairListPtr.empty()) {
738  // We also require that there be some spread in the data, otherwise not worth running?
739  double eigenVal0 = 3. * sqrt(pca.getEigenValues()[2]);
740  double eigenVal1 = 3. * sqrt(pca.getEigenValues()[1]);
741 
742  if (eigenVal0 > 5. && eigenVal1 > 0.001) {
743  // **********************************************************************
744  // Part I: Build Hough space and find Hough clusters
745  // **********************************************************************
746  RhoThetaAccumulatorBinMap rhoThetaAccumulatorBinMap;
747  HoughClusterList houghClusters;
748 
749  findHoughClusters(hitPairListPtr, pca, nLoops, rhoThetaAccumulatorBinMap, houghClusters);
750 
751  // If no clusters then done
752  if (houghClusters.empty()) break;
753 
754  // **********************************************************************
755  // Part II: Go through the clusters to find the peak bins
756  // **********************************************************************
757 
758  // We need to use a set so we can be sure to have unique hits
759  reco::HitPairListPtr clusterHitsList;
760  std::set<const reco::ClusterHit3D*> masterHitPtrList;
761  std::set<const reco::ClusterHit3D*> peakBinPtrList;
762 
763  size_t firstPeakCount(0);
764 
765  // Loop through the list of all clusters found above
766  for (auto& houghCluster : houghClusters) {
767  BinIndex peakBin = houghCluster.front();
768  size_t peakCount = 0;
769  size_t totalHits = 0;
770 
771  // Make a local (to this cluster) set of of hits
772  std::set<const reco::ClusterHit3D*> localHitPtrList;
773 
774  // Now loop through the bins that were attached to this cluster
775  for (auto& binIndex : houghCluster) {
776  // An even more local list so we can keep track of peak values
777  std::set<const reco::ClusterHit3D*> tempHitPtrList;
778 
779  // Recover the hits associated to this cluster
780  for (auto& hitItr : rhoThetaAccumulatorBinMap[binIndex].getAccumulatorValues()) {
781  reco::HitPairListPtr::const_iterator hit3DItr = hitItr.getHitIterator();
782 
783  tempHitPtrList.insert(*hit3DItr);
784  }
785 
786  // count hits before we remove any
787  totalHits += tempHitPtrList.size();
788 
789  // Trim out any hits already used by a bigger/better cluster
790  std::set<const reco::ClusterHit3D*> tempHit3DSet;
791 
792  std::set_difference(tempHitPtrList.begin(),
793  tempHitPtrList.end(),
794  masterHitPtrList.begin(),
795  masterHitPtrList.end(),
796  std::inserter(tempHit3DSet, tempHit3DSet.end()));
797 
798  tempHitPtrList = tempHit3DSet;
799 
800  size_t binCount = tempHitPtrList.size();
801 
802  if (peakCount < binCount) {
803  peakCount = binCount;
804  peakBin = binIndex;
805  peakBinPtrList = tempHitPtrList;
806  }
807 
808  // Add this to our local list
809  localHitPtrList.insert(tempHitPtrList.begin(), tempHitPtrList.end());
810  }
811 
812  if (localHitPtrList.size() < m_minimum3DHits) continue;
813 
814  if (!firstPeakCount) firstPeakCount = peakCount;
815 
816  // If the peak counts are significantly less than the first cluster's peak then skip
817  if (peakCount < firstPeakCount / 10) continue;
818 
819  // **********************************************************************
820  // Part III: Make a Seed from the peak bin hits
821  // **********************************************************************
822 
823  reco::HitPairListPtr allPeakBinHits;
824 
825  for (const auto& hit3D : localHitPtrList)
826  allPeakBinHits.push_back(hit3D);
827 
828  reco::HitPairListPtr peakBinHits;
829 
830  // Find longest "continuous" set of hits and use these for the seed
831  findHitGaps(allPeakBinHits, peakBinHits);
832 
833  if (peakBinHits.size() < m_minimum3DHits) continue;
834 
835  // We now build the actual seed.
836  if (buildSeed(peakBinHits, seedHitPair)) {
837  // Keep track of this in our map (which will do ordering for us)
838  seedHitPairMap[peakBinHits.size()].push_back(seedHitPair);
839 
840  // For visual testing in event display, mark all the hits in the first seed so we can see them
841  if (seedHitPairMap.size() == 1) {
842  for (const auto& hit3D : peakBinHits)
843  hit3D->setStatusBit(0x40000000);
844  }
845 
846  // for(const auto& hit3D : seedHitPair.second) hit3D->setStatusBit(0x40000000);
847  }
848 
849  // Our peakBinHits collection will most likely be a subset of the localHitPtrList collection
850  // We want to remove only the "pure" hits which are those in the peakBinHits collection
851  // So, sort them and then add to our master list
852  peakBinHits.sort();
853 
854  masterHitPtrList.insert(peakBinHits.begin(), peakBinHits.end());
855 
856  if (hitPairListPtr.size() - masterHitPtrList.size() < m_minimum3DHits) break;
857  } // end loop over hough clusters
858 
859  // If the masterHitPtrList is empty then nothing happened and we're done
860  if (masterHitPtrList.empty()) break;
861 
862  // **********************************************************************
863  // Part IV: Remove remaining peak bin hits from HitPairPtrList
864  // **********************************************************************
865 
866  hitPairListPtr.sort();
867 
868  reco::HitPairListPtr::iterator newListEnd = std::set_difference(hitPairListPtr.begin(),
869  hitPairListPtr.end(),
870  masterHitPtrList.begin(),
871  masterHitPtrList.end(),
872  hitPairListPtr.begin());
873 
874  hitPairListPtr.erase(newListEnd, hitPairListPtr.end());
875 
876  if (hitPairListPtr.size() < m_minimum3DHits) break;
877 
878  if (nLoops++ > m_maxLoopsPerCluster) break;
879 
880  // ********************************************************
881  }
882  else
883  break; // eigen values not in range
884 
885  // At this point run the PCA on the remaining hits
886  m_pcaAlg.PCAAnalysis_3D(hitPairListPtr, pca, true);
887 
888  if (!pca.getSvdOK()) break;
889  }
890 
891  // The final task before returning is to transfer the stored seeds into the output seed vector
892  // What we want to do is make sure the first seeds are the "best" seeds which is defined as the
893  // seeds which were associated to the most hits by the Hough Transform. Our seed map will have
894  // the reverse of this ordering so we simply iterate through it "backwards"
895  for (SizeToSeedToHitMap::reverse_iterator seedMapItr = seedHitPairMap.rbegin();
896  seedMapItr != seedHitPairMap.rend();
897  seedMapItr++) {
898  for (const auto& seedHitPair : seedMapItr->second) {
899  seedHitPairVec.emplace_back(seedHitPair);
900  }
901  }
902 
903  return true;
904  }
void findHitGaps(reco::HitPairListPtr &inputHitList, reco::HitPairListPtr &outputList) const
Using Principal Components Axis, look for gaps in a list of 3D hits.
bool getSvdOK() const
Definition: Cluster3D.h:243
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
void findHoughClusters(const reco::HitPairListPtr &inputHits, reco::PrincipalComponents &pca, int &nLoops, RhoThetaAccumulatorBinMap &rhoThetaMap, HoughClusterList &clusterList) const
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:245
std::list< HoughCluster > HoughClusterList
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:334
bool buildSeed(reco::HitPairListPtr &seed3DHits, SeedHitPairListPair &seedHitPair) const
Given a list of candidate &quot;seed&quot; 3D hits, build the seed and get associated unique 2D hits...
std::map< BinIndex, AccumulatorBin > RhoThetaAccumulatorBinMap
std::pair< recob::Seed, reco::HitPairListPtr > SeedHitPairListPair
void lar_cluster3d::HoughSeedFinderAlg::HoughRegionQuery ( BinIndex curBin,
RhoThetaAccumulatorBinMap rhoThetaAccumulatorBinMap,
HoughCluster neighborPts,
size_t  threshold 
) const
private

Does a query of nearest neighbors to look for matching bins

Definition at line 216 of file HoughSeedFinderAlg.cxx.

220  {
221  /**
222  * @brief Does a query of nearest neighbors to look for matching bins
223  */
224 
225  // We simply loop over the nearest indices and see if we have any friends over threshold
226  for (int rhoIdx = curBin.first - 1; rhoIdx <= curBin.first + 1; rhoIdx++) {
227  for (int jdx = curBin.second - 1; jdx <= curBin.second + 1; jdx++) {
228  // Skip the self reference
229  if (rhoIdx == curBin.first && jdx == curBin.second) continue;
230 
231  // Theta bin needs to handle the wrap.
232  int thetaIdx(jdx);
233 
234  if (thetaIdx < 0)
235  thetaIdx = m_thetaBins - 1;
236  else if (thetaIdx > m_thetaBins - 1)
237  thetaIdx = 0;
238 
239  BinIndex binIndex(rhoIdx, thetaIdx);
240  RhoThetaAccumulatorBinMap::iterator mapItr = rhoThetaAccumulatorBinMap.find(binIndex);
241 
242  if (mapItr != rhoThetaAccumulatorBinMap.end()) {
243  if (mapItr->second.getAccumulatorValues().size() >= threshold)
244  neighborPts.push_back(binIndex);
245  }
246  }
247  }
248 
249  return;
250  }
void lar_cluster3d::HoughSeedFinderAlg::LineFit2DHits ( std::set< const reco::ClusterHit2D * > &  hitList,
double  XOrigin,
TVector3 &  Pos,
TVector3 &  Dir,
double &  ChiDOF 
) const
private

Definition at line 1022 of file HoughSeedFinderAlg.cxx.

1027  {
1028  // The following is lifted from Bruce Baller to try to get better
1029  // initial parameters for a candidate Seed. It is slightly reworked
1030  // which is why it is included here instead of used as is.
1031  //
1032  // Linear fit using X as the independent variable. Hits to be fitted
1033  // are passed in the hits vector in a pair form (X, WireID). The
1034  // fitted track position at XOrigin is returned in the Pos vector.
1035  // The direction cosines are returned in the Dir vector.
1036  //
1037  // SVD fit adapted from $ROOTSYS/tutorials/matrix/solveLinear.C
1038  // Fit equation is w = A(X)v, where w is a vector of hit wires, A is
1039  // a matrix to calculate a track projected to a point at X, and v is
1040  // a vector (Yo, Zo, dY/dX, dZ/dX).
1041  //
1042  // Note: The covariance matrix should also be returned
1043  // B. Baller August 2014
1044 
1045  // assume failure
1046  ChiDOF = -1;
1047 
1048  if (hit2DSet.size() < 4) return;
1049 
1050  const unsigned int nvars = 4;
1051  unsigned int npts = hit2DSet.size();
1052 
1053  TMatrixD A(npts, nvars);
1054  // vector holding the Wire number
1055  TVectorD w(npts);
1056  unsigned short ninpl[3] = {0};
1057  unsigned short nok = 0;
1058  unsigned short iht(0), cstat, tpc, ipl;
1059  double x, cw, sw, off;
1060 
1061  // Loop over unique 2D hits from the input list of 3D hits
1062  for (const auto& hit : hit2DSet) {
1063  geo::WireID wireID = hit->WireID();
1064 
1065  cstat = wireID.Cryostat;
1066  tpc = wireID.TPC;
1067  ipl = wireID.Plane;
1068 
1069  // get the wire plane offset
1070  off = m_geometry->WireCoordinate(0, 0, ipl, tpc, cstat);
1071 
1072  // get the "cosine-like" component
1073  cw = m_geometry->WireCoordinate(1, 0, ipl, tpc, cstat) - off;
1074 
1075  // the "sine-like" component
1076  sw = m_geometry->WireCoordinate(0, 1, ipl, tpc, cstat) - off;
1077 
1078  x = hit->getXPosition() - XOrigin;
1079 
1080  A[iht][0] = cw;
1081  A[iht][1] = sw;
1082  A[iht][2] = cw * x;
1083  A[iht][3] = sw * x;
1084  w[iht] = wireID.Wire - off;
1085 
1086  ++ninpl[ipl];
1087 
1088  // need at least two points in a plane
1089  if (ninpl[ipl] == 2) ++nok;
1090 
1091  iht++;
1092  }
1093 
1094  // need at least 2 planes with at least two points
1095  if (nok < 2) return;
1096 
1097  TDecompSVD svd(A);
1098  bool ok;
1099  TVectorD tVec = svd.Solve(w, ok);
1100 
1101  ChiDOF = 0;
1102 
1103  // not enough points to calculate Chisq
1104  if (npts <= 4) return;
1105 
1106  double ypr, zpr, diff;
1107 
1108  for (const auto& hit : hit2DSet) {
1109  geo::WireID wireID = hit->WireID();
1110 
1111  cstat = wireID.Cryostat;
1112  tpc = wireID.TPC;
1113  ipl = wireID.Plane;
1114  off = m_geometry->WireCoordinate(0, 0, ipl, tpc, cstat);
1115  cw = m_geometry->WireCoordinate(1, 0, ipl, tpc, cstat) - off;
1116  sw = m_geometry->WireCoordinate(0, 1, ipl, tpc, cstat) - off;
1117  x = hit->getXPosition() - XOrigin;
1118  ypr = tVec[0] + tVec[2] * x;
1119  zpr = tVec[1] + tVec[3] * x;
1120  diff = ypr * cw + zpr * sw - (wireID.Wire - off);
1121  ChiDOF += diff * diff;
1122  }
1123 
1124  float werr2 = m_geometry->WirePitch() * m_geometry->WirePitch();
1125  ChiDOF /= werr2;
1126  ChiDOF /= (float)(npts - 4);
1127 
1128  double norm = sqrt(1 + tVec[2] * tVec[2] + tVec[3] * tVec[3]);
1129  Dir[0] = 1 / norm;
1130  Dir[1] = tVec[2] / norm;
1131  Dir[2] = tVec[3] / norm;
1132 
1133  Pos[0] = XOrigin;
1134  Pos[1] = tVec[0];
1135  Pos[2] = tVec[1];
1136 
1137  } // TrkLineFit()
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
process_name opflash particleana ie x
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
process_name hit
Definition: cheaterreco.fcl:51
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
auto norm(Vector const &v)
Return norm of the specified vector.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
float A
Definition: dedx.py:137

Member Data Documentation

std::vector<std::unique_ptr<TCanvas> > lar_cluster3d::HoughSeedFinderAlg::m_Canvases
mutableprivate

Graphical trace canvases.

Definition at line 126 of file HoughSeedFinderAlg.h.

bool lar_cluster3d::HoughSeedFinderAlg::m_displayHist
private

Definition at line 125 of file HoughSeedFinderAlg.h.

geo::Geometry const* lar_cluster3d::HoughSeedFinderAlg::m_geometry
private

Definition at line 122 of file HoughSeedFinderAlg.h.

double lar_cluster3d::HoughSeedFinderAlg::m_hiThresholdFrac
private

Definition at line 114 of file HoughSeedFinderAlg.h.

size_t lar_cluster3d::HoughSeedFinderAlg::m_hiThresholdMin
private

Definition at line 113 of file HoughSeedFinderAlg.h.

double lar_cluster3d::HoughSeedFinderAlg::m_loThresholdFrac
private

Definition at line 115 of file HoughSeedFinderAlg.h.

double lar_cluster3d::HoughSeedFinderAlg::m_maximumGap
private

Definition at line 120 of file HoughSeedFinderAlg.h.

int lar_cluster3d::HoughSeedFinderAlg::m_maxLoopsPerCluster
private

Definition at line 119 of file HoughSeedFinderAlg.h.

size_t lar_cluster3d::HoughSeedFinderAlg::m_minimum3DHits
private

Definition at line 110 of file HoughSeedFinderAlg.h.

double lar_cluster3d::HoughSeedFinderAlg::m_numAveDocas
private

Definition at line 117 of file HoughSeedFinderAlg.h.

size_t lar_cluster3d::HoughSeedFinderAlg::m_numSeed2DHits
private

Definition at line 116 of file HoughSeedFinderAlg.h.

int lar_cluster3d::HoughSeedFinderAlg::m_numSkippedHits
private

Definition at line 118 of file HoughSeedFinderAlg.h.

std::vector<TVirtualPad*> lar_cluster3d::HoughSeedFinderAlg::m_Pads
mutableprivate

View pads in current canvas.

Definition at line 127 of file HoughSeedFinderAlg.h.

PrincipalComponentsAlg lar_cluster3d::HoughSeedFinderAlg::m_pcaAlg
private

Definition at line 123 of file HoughSeedFinderAlg.h.

int lar_cluster3d::HoughSeedFinderAlg::m_rhoBins
private

Definition at line 112 of file HoughSeedFinderAlg.h.

int lar_cluster3d::HoughSeedFinderAlg::m_thetaBins
private

Definition at line 111 of file HoughSeedFinderAlg.h.


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