Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
lar_cluster3d::Cluster3D Class Reference

Definition of the Cluster3D class. More...

Inheritance diagram for lar_cluster3d::Cluster3D:
art::EDProducer art::detail::Producer art::detail::LegacyModule art::Modifier art::ModuleBase art::ProductRegistryHelper

Classes

class  ArtOutputHandler
 

Public Member Functions

 Cluster3D (fhicl::ParameterSet const &pset)
 
- Public Member Functions inherited from art::EDProducer
 EDProducer (fhicl::ParameterSet const &pset)
 
template<typename Config >
 EDProducer (Table< Config > const &config)
 
std::string workerType () const
 
- Public Member Functions inherited from art::detail::Producer
virtual ~Producer () noexcept
 
 Producer (fhicl::ParameterSet const &)
 
 Producer (Producer const &)=delete
 
 Producer (Producer &&)=delete
 
Produceroperator= (Producer const &)=delete
 
Produceroperator= (Producer &&)=delete
 
void doBeginJob (SharedResources const &resources)
 
void doEndJob ()
 
void doRespondToOpenInputFile (FileBlock const &fb)
 
void doRespondToCloseInputFile (FileBlock const &fb)
 
void doRespondToOpenOutputFiles (FileBlock const &fb)
 
void doRespondToCloseOutputFiles (FileBlock const &fb)
 
bool doBeginRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doEndRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doBeginSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEndSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEvent (EventPrincipal &ep, ModuleContext const &mc, std::atomic< std::size_t > &counts_run, std::atomic< std::size_t > &counts_passed, std::atomic< std::size_t > &counts_failed)
 
- Public Member Functions inherited from art::Modifier
 ~Modifier () noexcept
 
 Modifier ()
 
 Modifier (Modifier const &)=delete
 
 Modifier (Modifier &&)=delete
 
Modifieroperator= (Modifier const &)=delete
 
Modifieroperator= (Modifier &&)=delete
 
- Public Member Functions inherited from art::ModuleBase
virtual ~ModuleBase () noexcept
 
 ModuleBase ()
 
ModuleDescription const & moduleDescription () const
 
void setModuleDescription (ModuleDescription const &)
 
std::array< std::vector< ProductInfo >, NumBranchTypes > const & getConsumables () const
 
void sortConsumables (std::string const &current_process_name)
 
template<typename T , BranchType BT>
ViewToken< T > consumesView (InputTag const &tag)
 
template<typename T , BranchType BT>
ViewToken< T > mayConsumeView (InputTag const &tag)
 

Private Types

using IdxToPCAMap = std::map< size_t, const reco::PrincipalComponents * >
 Special routine to handle creating and saving space points & edges PCA points. More...
 

Private Member Functions

void beginJob () override
 
void produce (art::Event &evt) override
 
void PrepareEvent (const art::Event &evt)
 Event Preparation. More...
 
void InitializeMonitoring ()
 Initialize the internal monitoring. More...
 
void findTrackSeeds (art::Event &evt, reco::ClusterParameters &cluster, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, std::vector< recob::Seed > &seedVec, art::Assns< recob::Seed, recob::Hit > &seedHitAssns) const
 An interface to the seed finding algorithm. More...
 
void splitClustersWithMST (reco::ClusterParameters &clusterParameters, reco::ClusterParametersList &clusterParametersList) const
 Attempt to split clusters by using a minimum spanning tree. More...
 
void splitClustersWithHough (reco::ClusterParameters &clusterParameters, reco::ClusterParametersList &clusterParametersList) const
 Attempt to split clusters using the output of the Hough Filter. More...
 
void MakeAndSaveSpacePoints (ArtOutputHandler &output, std::vector< recob::SpacePoint > &spacePointVec, art::Assns< recob::Hit, recob::SpacePoint > &spHitAssns, reco::HitPairListPtr &clusHitPairVector, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, const std::string &path="") const
 Special routine to handle creating and saving space points. More...
 
void MakeAndSaveKinkPoints (ArtOutputHandler &output, reco::ConvexHullKinkTupleList &clusHitPairVector) const
 Special routine to handle creating and saving space points. More...
 
void MakeAndSaveVertexPoints (ArtOutputHandler &, dcel2d::VertexList &, dcel2d::HalfEdgeList &) const
 Special routine to handle creating and saving space points & edges associated to voronoi diagrams. More...
 
void MakeAndSavePCAPoints (ArtOutputHandler &, const reco::PrincipalComponents &, IdxToPCAMap &) const
 
size_t FindAndStoreDaughters (util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::ClusterParameters &clusterParameters, size_t pfParticleParent, IdxToPCAMap &idxToPCAMap, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, Hit3DToSPPtrMap &best3DToSPPtrMap) const
 This will produce art output for daughters noting that it needs to be done recursively. More...
 
void ProduceArtClusters (util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::HitPairList &hitPairList, reco::ClusterParametersList &clusterParametersList, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap) const
 Top level output routine, allows checking cluster status. More...
 
size_t ConvertToArtOutput (util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::ClusterParameters &clusterParameters, size_t pfParticleParent, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, Hit3DToSPPtrMap &best3DToSPPtrMap) const
 Produces the art output from all the work done in this producer module. More...
 
bool aParallelHitsCluster (const reco::PrincipalComponents &pca) const
 There are several places we will want to know if a candidate cluster is a "parallel hits" type of cluster so encapsulate that here. More...
 
size_t countUltimateDaughters (reco::ClusterParameters &clusterParameters) const
 Count number of end of line daughters. More...
 

Private Attributes

bool m_onlyMakSpacePoints
 If true we don't do the full cluster 3D processing. More...
 
bool m_enableMonitoring
 Turn on monitoring of this algorithm. More...
 
float m_parallelHitsCosAng
 Cut for PCA 3rd axis angle to X axis. More...
 
float m_parallelHitsTransWid
 Cut on transverse width of cluster (PCA 2nd eigenvalue) More...
 
TTree * m_pRecoTree
 
int m_run
 
int m_event
 
int m_hits
 Keeps track of the number of hits seen. More...
 
int m_hits3D
 Keeps track of the number of 3D hits made. More...
 
float m_totalTime
 Keeps track of total execution time. More...
 
float m_artHitsTime
 Keeps track of time to recover hits. More...
 
float m_makeHitsTime
 Keeps track of time to build 3D hits. More...
 
float m_buildNeighborhoodTime
 Keeps track of time to build epsilon neighborhood. More...
 
float m_dbscanTime
 Keeps track of time to run DBScan. More...
 
float m_clusterMergeTime
 Keeps track of the time to merge clusters. More...
 
float m_pathFindingTime
 Keeps track of the path finding time. More...
 
float m_finishTime
 Keeps track of time to run output module. More...
 
std::string m_pathInstance
 Special instance for path points. More...
 
std::string m_vertexInstance
 Special instance name for vertex points. More...
 
std::string m_extremeInstance
 Instance name for the extreme points. More...
 
std::unique_ptr< lar_cluster3d::IHit3DBuilderm_hit3DBuilderAlg
 Builds the 3D hits to operate on. More...
 
std::unique_ptr< lar_cluster3d::IClusterAlgm_clusterAlg
 Algorithm to do 3D space point clustering. More...
 
std::unique_ptr< lar_cluster3d::IClusterModAlgm_clusterMergeAlg
 Algorithm to do cluster merging. More...
 
std::unique_ptr< lar_cluster3d::IClusterModAlgm_clusterPathAlg
 Algorithm to do cluster path finding. More...
 
std::unique_ptr< lar_cluster3d::IClusterParametersBuilderm_clusterBuilder
 Common cluster builder tool. More...
 
PrincipalComponentsAlg m_pcaAlg
 Principal Components algorithm. More...
 
SkeletonAlg m_skeletonAlg
 Skeleton point finder. More...
 
HoughSeedFinderAlg m_seedFinderAlg
 Seed finder. More...
 
PCASeedFinderAlg m_pcaSeedFinderAlg
 Use PCA axis to find seeds. More...
 
ParallelHitsSeedFinderAlg m_parallelHitsAlg
 Deal with parallel hits clusters. More...
 

Additional Inherited Members

- Public Types inherited from art::EDProducer
using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
- Public Types inherited from art::detail::Producer
template<typename UserConfig , typename KeysToIgnore = void>
using Table = Modifier::Table< UserConfig, KeysToIgnore >
 
- Public Types inherited from art::Modifier
template<typename UserConfig , typename UserKeysToIgnore = void>
using Table = ProducerTable< UserConfig, detail::ModuleConfig, UserKeysToIgnore >
 
- Static Public Member Functions inherited from art::EDProducer
static void commitEvent (EventPrincipal &ep, Event &e)
 
- Protected Member Functions inherited from art::ModuleBase
ConsumesCollectorconsumesCollector ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 

Detailed Description

Definition of the Cluster3D class.

Definition at line 107 of file Cluster3D_module.cc.

Member Typedef Documentation

using lar_cluster3d::Cluster3D::IdxToPCAMap = std::map<size_t, const reco::PrincipalComponents*>
private

Special routine to handle creating and saving space points & edges PCA points.

Parameters
outputthe object containting the art output
clusterParamsListList of clusters to get PCA's from

Definition at line 407 of file Cluster3D_module.cc.

Constructor & Destructor Documentation

lar_cluster3d::Cluster3D::Cluster3D ( fhicl::ParameterSet const &  pset)
explicit

Definition at line 535 of file Cluster3D_module.cc.

536  : EDProducer{pset}
537  , m_pcaAlg(pset.get<fhicl::ParameterSet>("PrincipalComponentsAlg"))
538  , m_skeletonAlg(pset.get<fhicl::ParameterSet>("SkeletonAlg"))
539  , m_seedFinderAlg(pset.get<fhicl::ParameterSet>("SeedFinderAlg"))
540  , m_pcaSeedFinderAlg(pset.get<fhicl::ParameterSet>("PCASeedFinderAlg"))
541  , m_parallelHitsAlg(pset.get<fhicl::ParameterSet>("ParallelHitsAlg"))
542  {
543  m_onlyMakSpacePoints = pset.get<bool>("MakeSpacePointsOnly", false);
544  m_enableMonitoring = pset.get<bool>("EnableMonitoring", false);
545  m_parallelHitsCosAng = pset.get<float>("ParallelHitsCosAng", 0.999);
546  m_parallelHitsTransWid = pset.get<float>("ParallelHitsTransWid", 25.0);
547  m_pathInstance = pset.get<std::string>("PathPointsName", "Path");
548  m_vertexInstance = pset.get<std::string>("VertexPointsName", "Vertex");
549  m_extremeInstance = pset.get<std::string>("ExtremePointsName", "Extreme");
550 
551  m_hit3DBuilderAlg = art::make_tool<lar_cluster3d::IHit3DBuilder>(
552  pset.get<fhicl::ParameterSet>("Hit3DBuilderAlg"));
553  m_clusterAlg =
554  art::make_tool<lar_cluster3d::IClusterAlg>(pset.get<fhicl::ParameterSet>("ClusterAlg"));
555  m_clusterMergeAlg = art::make_tool<lar_cluster3d::IClusterModAlg>(
556  pset.get<fhicl::ParameterSet>("ClusterMergeAlg"));
557  m_clusterPathAlg = art::make_tool<lar_cluster3d::IClusterModAlg>(
558  pset.get<fhicl::ParameterSet>("ClusterPathAlg"));
559  m_clusterBuilder = art::make_tool<lar_cluster3d::IClusterParametersBuilder>(
560  pset.get<fhicl::ParameterSet>("ClusterParamsBuilder"));
561 
562  // Handle special case of Space Point building outputting a new hit collection
564 
565  produces<std::vector<recob::PCAxis>>();
566  produces<std::vector<recob::PFParticle>>();
567  produces<std::vector<recob::Cluster>>();
568  produces<std::vector<recob::Seed>>();
569  produces<std::vector<recob::Edge>>();
570 
571  produces<art::Assns<recob::PFParticle, recob::PCAxis>>();
572  produces<art::Assns<recob::PFParticle, recob::Cluster>>();
573  produces<art::Assns<recob::PFParticle, recob::Seed>>();
574  produces<art::Assns<recob::Edge, recob::PFParticle>>();
575  produces<art::Assns<recob::Seed, recob::Hit>>();
576  produces<art::Assns<recob::Cluster, recob::Hit>>();
577 
578  produces<std::vector<recob::SpacePoint>>();
579  produces<art::Assns<recob::SpacePoint, recob::PFParticle>>();
580  produces<art::Assns<recob::Hit, recob::SpacePoint>>();
581  produces<art::Assns<recob::SpacePoint, recob::Edge>>();
582 
583  produces<std::vector<recob::SpacePoint>>(m_pathInstance);
584  produces<std::vector<recob::Edge>>(m_pathInstance);
585  produces<art::Assns<recob::SpacePoint, recob::PFParticle>>(m_pathInstance);
586  produces<art::Assns<recob::Edge, recob::PFParticle>>(m_pathInstance);
587  produces<art::Assns<recob::Hit, recob::SpacePoint>>(m_pathInstance);
588  produces<art::Assns<recob::SpacePoint, recob::Edge>>(m_pathInstance);
589 
590  produces<std::vector<recob::Edge>>(m_vertexInstance);
591  produces<std::vector<recob::SpacePoint>>(m_vertexInstance);
592 
593  produces<std::vector<recob::SpacePoint>>(m_extremeInstance);
594  }
std::unique_ptr< lar_cluster3d::IClusterModAlg > m_clusterPathAlg
Algorithm to do cluster path finding.
std::string m_vertexInstance
Special instance name for vertex points.
std::string string
Definition: nybbler.cc:12
float m_parallelHitsTransWid
Cut on transverse width of cluster (PCA 2nd eigenvalue)
float m_parallelHitsCosAng
Cut for PCA 3rd axis angle to X axis.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
SkeletonAlg m_skeletonAlg
Skeleton point finder.
bool m_onlyMakSpacePoints
If true we don&#39;t do the full cluster 3D processing.
HoughSeedFinderAlg m_seedFinderAlg
Seed finder.
std::unique_ptr< lar_cluster3d::IClusterAlg > m_clusterAlg
Algorithm to do 3D space point clustering.
std::string m_extremeInstance
Instance name for the extreme points.
PCASeedFinderAlg m_pcaSeedFinderAlg
Use PCA axis to find seeds.
ParallelHitsSeedFinderAlg m_parallelHitsAlg
Deal with parallel hits clusters.
ProducesCollector & producesCollector() noexcept
std::unique_ptr< lar_cluster3d::IClusterParametersBuilder > m_clusterBuilder
Common cluster builder tool.
std::unique_ptr< lar_cluster3d::IClusterModAlg > m_clusterMergeAlg
Algorithm to do cluster merging.
std::unique_ptr< lar_cluster3d::IHit3DBuilder > m_hit3DBuilderAlg
Builds the 3D hits to operate on.
PrincipalComponentsAlg m_pcaAlg
Principal Components algorithm.
std::string m_pathInstance
Special instance for path points.
bool m_enableMonitoring
Turn on monitoring of this algorithm.

Member Function Documentation

bool lar_cluster3d::Cluster3D::aParallelHitsCluster ( const reco::PrincipalComponents pca) const
inlineprivate

There are several places we will want to know if a candidate cluster is a "parallel hits" type of cluster so encapsulate that here.

Parameters
pcaThe Principal Components Analysis parameters for the cluster

Definition at line 467 of file Cluster3D_module.cc.

468  {
469  return fabs(pca.getEigenVectors().row(2)(0)) > m_parallelHitsCosAng &&
470  3. * sqrt(pca.getEigenValues()(1)) > m_parallelHitsTransWid;
471  }
float m_parallelHitsTransWid
Cut on transverse width of cluster (PCA 2nd eigenvalue)
float m_parallelHitsCosAng
Cut for PCA 3rd axis angle to X axis.
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:246
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:247
void lar_cluster3d::Cluster3D::beginJob ( )
overrideprivatevirtual

beginJob will be tasked with initializing monitoring, in necessary, but also to init the geometry and detector services (and this probably needs to go in a "beginEvent" method?)

Reimplemented from art::EDProducer.

Definition at line 599 of file Cluster3D_module.cc.

600  {
601  /**
602  * @brief beginJob will be tasked with initializing monitoring, in necessary, but also to init the
603  * geometry and detector services (and this probably needs to go in a "beginEvent" method?)
604  */
606  }
void InitializeMonitoring()
Initialize the internal monitoring.
bool m_enableMonitoring
Turn on monitoring of this algorithm.
size_t lar_cluster3d::Cluster3D::ConvertToArtOutput ( util::GeometryUtilities const &  gser,
ArtOutputHandler output,
reco::ClusterParameters clusterParameters,
size_t  pfParticleParent,
IHit3DBuilder::RecobHitToPtrMap hitToPtrMap,
Hit3DToSPPtrMap hit3DToSPPtrMap,
Hit3DToSPPtrMap best3DToSPPtrMap 
) const
private

Produces the art output from all the work done in this producer module.

Parameters
outputthe object containting the art output
clusterParametersCluster info to output (in internal format)
pfParticleParentThe parent ID reference for the output PFParticle
hitToPtrMapThis maps our Cluster2D hits back to art Ptr's to reco Hits

Definition at line 1444 of file Cluster3D_module.cc.

1451  {
1452  // prepare the algorithm to compute the cluster characteristics;
1453  // we use the "standard" one here, except that we override selected items
1454  // (so, thanks to metaprogramming, we finally have wrappers of wrappers);
1455  // configuration would happen here, but we are using the default
1456  // configuration for that algorithm
1457  using OverriddenClusterParamsAlg_t =
1459 
1461 
1462  // It should be straightforward at this point to transfer information from our vector of clusters
1463  // to the larsoft objects... of course we still have some work to do first, in particular to
1464  // find the candidate seeds and their seed hits
1465 
1466  // We keep track of 2 PCA axes, the first is the "full" PCA run over all the 3D hits in the
1467  // candidate cluster. The second will be that derived from just using the "skeleton" hits.
1468  // Make a copy of the full PCA to keep that, then get a reference for the skeleton PCA
1469  reco::PrincipalComponents& fullPCA = clusterParameters.getFullPCA();
1470  reco::PrincipalComponents& skeletonPCA = clusterParameters.getSkeletonPCA();
1471 
1472  size_t clusterStart = output.artClusterVector->size();
1473 
1474  // Start loop over views to build out the hit lists and the 2D cluster objects
1475  for (const auto& clusParametersPair : clusterParameters.getClusterParams()) {
1476  const reco::RecobClusterParameters& clusParams = clusParametersPair.second;
1477 
1478  // Protect against a missing view
1479  if (clusParams.m_view == geo::kUnknown) continue;
1480 
1481  // Get a vector of hit pointers to seed the cluster algorithm
1482  std::vector<const recob::Hit*> recobHitVec(clusParams.m_hitVector.size());
1483 
1484  std::transform(clusParams.m_hitVector.begin(),
1485  clusParams.m_hitVector.end(),
1486  recobHitVec.begin(),
1487  [](const auto& hit2D) { return hit2D->getHit(); });
1488 
1489  // Get the tdc/wire slope... from the unit vector...
1490  double startWire(clusParams.m_startWire);
1491  double endWire(clusParams.m_endWire);
1492  double startTime(clusParams.m_startTime);
1493  double endTime(clusParams.m_endTime);
1494 
1495  // feed the algorithm with all the cluster hits
1496  ClusterParamAlgo.ImportHits(gser, recobHitVec);
1497 
1498  // create the recob::Cluster directly in the vector
1499  cluster::ClusterCreator artCluster(gser,
1500  ClusterParamAlgo, // algo
1501  startWire, // start_wire
1502  0., // sigma_start_wire
1503  startTime, // start_tick
1504  clusParams.m_sigmaStartTime, // sigma_start_tick
1505  endWire, // end_wire
1506  0., // sigma_end_wire,
1507  endTime, // end_tick
1508  clusParams.m_sigmaEndTime, // sigma_end_tick
1509  output.artClusterVector->size(), // ID
1510  clusParams.m_view, // view
1511  clusParams.m_plane, // plane
1512  recob::Cluster::Sentry // sentry
1513  );
1514 
1515  output.artClusterVector->emplace_back(artCluster.move());
1516 
1517  // We love looping. In this case, our list of hits is comprised of "ClusterHits" and we need to get a RecobHitVector instead...
1518  RecobHitVector recobHits;
1519 
1520  for (const auto& hit2D : clusParams.m_hitVector) {
1521  if (hit2D == nullptr || hit2D->getHit() == nullptr) continue;
1522 
1523  art::Ptr<recob::Hit> hitPtr = hitToPtrMap[hit2D->getHit()];
1524  recobHits.push_back(hitPtr);
1525  }
1526 
1527  output.makeClusterHitAssns(recobHits);
1528  }
1529 
1530  // Last, let's try to get seeds for tracking..
1531  // Keep track of how many we have so far
1532  size_t numSeedsStart = output.artSeedVector->size();
1533 
1534  // Empty daughter vector for now
1535  std::vector<size_t> nullVector;
1536  size_t pfParticleIdx(output.artPFParticleVector->size());
1537 
1538  recob::PFParticle pfParticle(13, pfParticleIdx, pfParticleParent, nullVector);
1539  output.artPFParticleVector->push_back(pfParticle);
1540 
1541  // Assume that if we are a daughter particle then there is a set of "best" 3D points and the convex hull will have been calculated from them
1542  // If there is no best list then assume the convex hull is from all of the points...
1543  std::string instance("");
1544  reco::HitPairListPtr* hit3DListPtr = &clusterParameters.getHitPairListPtr();
1545  Hit3DToSPPtrMap* hit3DToPtrMap = &hit3DToSPPtrMap;
1546 
1547  auto spVector = output.artSpacePointVector.get();
1548  auto edgeVector = output.artEdgeVector.get();
1549  auto pfPartEdgeAssns = output.artPFPartEdgeAssociations.get();
1550  auto spEdgeAssns = output.artEdgeSPAssociations.get();
1551  auto spHitAssns = output.artSPHitAssociations.get();
1552  auto pfPartSPAssns = output.artPFPartSPAssociations.get();
1553 
1554  // Make associations to all space points for this cluster
1555  int spacePointStart = spVector->size();
1556 
1558  output, *spVector, *spHitAssns, *hit3DListPtr, hitToPtrMap, *hit3DToPtrMap);
1559 
1560  // And make sure to have associations to the PFParticle
1561  output.makePFPartSpacePointAssns(*spVector, *pfPartSPAssns, spacePointStart);
1562 
1563  // If they exist, make space points for the Path points
1564  if (!clusterParameters.getBestHitPairListPtr().empty()) {
1566  hit3DListPtr = &clusterParameters.getBestHitPairListPtr();
1567  hit3DToPtrMap = &best3DToSPPtrMap;
1568 
1569  spVector = output.artPathPointVector.get();
1570  edgeVector = output.artPathEdgeVector.get();
1571  pfPartEdgeAssns = output.artPFPartPathEdgeAssociations.get();
1572  spEdgeAssns = output.artEdgePPAssociations.get();
1573  spHitAssns = output.artPPHitAssociations.get();
1574  pfPartSPAssns = output.artPFPartPPAssociations.get();
1575 
1576  spacePointStart = spVector->size();
1577 
1579  output, *spVector, *spHitAssns, *hit3DListPtr, hitToPtrMap, *hit3DToPtrMap, instance);
1580 
1581  // And make sure to have associations to the PFParticle
1582  output.makePFPartSpacePointAssns(*spVector, *pfPartSPAssns, spacePointStart, instance);
1583  }
1584 
1585  // Now handle the edges according to whether associated with regular or "best" space points
1586  if (!clusterParameters.getBestEdgeList().empty()) {
1587  size_t edgeStart = edgeVector->size();
1588 
1589  for (const auto& edge : clusterParameters.getBestEdgeList()) {
1590  RecobSpacePointVector spacePointVec;
1591 
1592  try {
1593  spacePointVec.push_back(hit3DToPtrMap->at(std::get<0>(edge)));
1594  spacePointVec.push_back(hit3DToPtrMap->at(std::get<1>(edge)));
1595  }
1596  catch (...) {
1597  std::cout << "Caught exception in looking up space point ptr... " << std::get<0>(edge)
1598  << ", " << std::get<1>(edge) << std::endl;
1599  continue;
1600  }
1601 
1602  edgeVector->emplace_back(
1603  std::get<2>(edge), spacePointVec[0].key(), spacePointVec[1].key(), edgeVector->size());
1604 
1605  output.makeEdgeSpacePointAssns(*edgeVector, spacePointVec, *spEdgeAssns, instance);
1606  }
1607 
1608  output.makePFPartEdgeAssns(*edgeVector, *pfPartEdgeAssns, edgeStart, instance);
1609  }
1610 
1611  // Look at making the PCAxis and associations - for both the skeleton (the first) and the full
1612  // First need some float to double conversion containers
1613  recob::PCAxis::EigenVectors eigenVecs;
1614  double eigenVals[] = {0., 0., 0.};
1615  double avePosition[] = {0., 0., 0.};
1616 
1617  eigenVecs.resize(3);
1618 
1619  for (size_t outerIdx = 0; outerIdx < 3; outerIdx++) {
1620  avePosition[outerIdx] = skeletonPCA.getAvePosition()[outerIdx];
1621  eigenVals[outerIdx] = skeletonPCA.getEigenValues()[outerIdx];
1622 
1623  eigenVecs[outerIdx].resize(3);
1624 
1625  for (size_t innerIdx = 0; innerIdx < 3; innerIdx++)
1626  eigenVecs[outerIdx][innerIdx] = skeletonPCA.getEigenVectors().row(outerIdx)(innerIdx);
1627  }
1628 
1629  recob::PCAxis skelPcAxis(skeletonPCA.getSvdOK(),
1630  skeletonPCA.getNumHitsUsed(),
1631  eigenVals,
1632  eigenVecs,
1633  avePosition,
1634  skeletonPCA.getAveHitDoca(),
1635  output.artPCAxisVector->size());
1636 
1637  output.artPCAxisVector->push_back(skelPcAxis);
1638 
1639  for (size_t outerIdx = 0; outerIdx < 3; outerIdx++) {
1640  avePosition[outerIdx] = fullPCA.getAvePosition()[outerIdx];
1641  eigenVals[outerIdx] = fullPCA.getEigenValues()[outerIdx];
1642 
1643  for (size_t innerIdx = 0; innerIdx < 3; innerIdx++)
1644  eigenVecs[outerIdx][innerIdx] = fullPCA.getEigenVectors().row(outerIdx)(innerIdx);
1645  }
1646 
1647  recob::PCAxis fullPcAxis(fullPCA.getSvdOK(),
1648  fullPCA.getNumHitsUsed(),
1649  eigenVals, //fullPCA.getEigenValues(),
1650  eigenVecs, //fullPCA.getEigenVectors(),
1651  avePosition, //fullPCA.getAvePosition(),
1652  fullPCA.getAveHitDoca(),
1653  output.artPCAxisVector->size());
1654 
1655  output.artPCAxisVector->push_back(fullPcAxis);
1656 
1657  // Create associations to the PFParticle
1658  output.makePFPartPCAAssns();
1659  output.makePFPartSeedAssns(numSeedsStart);
1660  output.makePFPartClusterAssns(clusterStart);
1661 
1662  return pfParticleIdx;
1663  }
reco::HitPairListPtr & getBestHitPairListPtr()
Definition: Cluster3D.h:480
bool getSvdOK() const
Definition: Cluster3D.h:244
art::PtrVector< recob::SpacePoint > RecobSpacePointVector
Class managing the creation of a new recob::Cluster object.
std::string string
Definition: nybbler.cc:12
Unknown view.
Definition: geo_types.h:136
reco::PrincipalComponents & getSkeletonPCA()
Definition: Cluster3D.h:478
const std::string instance
reco::EdgeList & getBestEdgeList()
Definition: Cluster3D.h:481
int getNumHitsUsed() const
Definition: Cluster3D.h:245
A utility class used in construction of 3D clusters.
Definition: Cluster3D.h:300
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:476
art::PtrVector< recob::Hit > RecobHitVector
reco::PlaneToClusterParamsMap & getClusterParams()
Definition: Cluster3D.h:474
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
void ImportHits(util::GeometryUtilities const &gser, Iter begin, Iter end)
Calls SetHits() with the hits in the sequence.
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:246
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:477
def key(type, name=None)
Definition: graph.py:13
Wrapper for ClusterParamsAlgBase objects to accept diverse input.
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:248
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:335
void MakeAndSaveSpacePoints(ArtOutputHandler &output, std::vector< recob::SpacePoint > &spacePointVec, art::Assns< recob::Hit, recob::SpacePoint > &spHitAssns, reco::HitPairListPtr &clusHitPairVector, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, const std::string &path="") const
Special routine to handle creating and saving space points.
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
const float getAveHitDoca() const
Definition: Cluster3D.h:249
ClusterHit2DVec m_hitVector
Definition: Cluster3D.h:327
Algorithm collection class computing cluster parameters.
std::unordered_map< const reco::ClusterHit3D *, art::Ptr< recob::SpacePoint >> Hit3DToSPPtrMap
std::vector< std::vector< double > > EigenVectors
Definition: PCAxis.h:29
std::string m_pathInstance
Special instance for path points.
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:247
QTextStream & endl(QTextStream &s)
size_t lar_cluster3d::Cluster3D::countUltimateDaughters ( reco::ClusterParameters clusterParameters) const
private

Count number of end of line daughters.

Parameters
clusterParamsinput cluster parameters to look at

Definition at line 1391 of file Cluster3D_module.cc.

1392  {
1393  size_t localCount(0);
1394 
1395  if (!clusterParameters.daughterList().empty()) {
1396  for (auto& clusterParams : clusterParameters.daughterList())
1397  localCount += countUltimateDaughters(clusterParams);
1398  }
1399  else
1400  localCount++;
1401 
1402  return localCount;
1403  }
ClusterParametersList & daughterList()
Definition: Cluster3D.h:450
size_t countUltimateDaughters(reco::ClusterParameters &clusterParameters) const
Count number of end of line daughters.
size_t lar_cluster3d::Cluster3D::FindAndStoreDaughters ( util::GeometryUtilities const &  gser,
ArtOutputHandler output,
reco::ClusterParameters clusterParameters,
size_t  pfParticleParent,
IdxToPCAMap idxToPCAMap,
IHit3DBuilder::RecobHitToPtrMap hitToPtrMap,
Hit3DToSPPtrMap hit3DToSPPtrMap,
Hit3DToSPPtrMap best3DToSPPtrMap 
) const
private

This will produce art output for daughters noting that it needs to be done recursively.

Parameters
outputthe object containting the art output
clusterParametersCluster info to output (in internal format)
pfParticleParentThe parent ID reference for the output PFParticle
daughterListList of PFParticle indices for stored daughters
hitToPtrMapThis maps our Cluster2D hits back to art Ptr's to reco Hits

Definition at line 1406 of file Cluster3D_module.cc.

1414  {
1415  // This is a recursive routine, we keep calling ourself as long as the daughter list is non empty
1416  if (!clusterParameters.daughterList().empty()) {
1417  for (auto& clusterParams : clusterParameters.daughterList())
1418  FindAndStoreDaughters(gser,
1419  output,
1420  clusterParams,
1421  pfParticleParent,
1422  idxToPCAMap,
1423  hitToPtrMap,
1424  hit3DToSPPtrMap,
1425  best3DToSPPtrMap);
1426  }
1427  // Otherwise we want to store the information
1428  else {
1429  size_t daughterIdx = ConvertToArtOutput(gser,
1430  output,
1431  clusterParameters,
1432  pfParticleParent,
1433  hitToPtrMap,
1434  hit3DToSPPtrMap,
1435  best3DToSPPtrMap);
1436 
1437  idxToPCAMap[daughterIdx] = &clusterParameters.getFullPCA();
1438  }
1439 
1440  return idxToPCAMap.size();
1441  }
ClusterParametersList & daughterList()
Definition: Cluster3D.h:450
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:477
size_t FindAndStoreDaughters(util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::ClusterParameters &clusterParameters, size_t pfParticleParent, IdxToPCAMap &idxToPCAMap, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, Hit3DToSPPtrMap &best3DToSPPtrMap) const
This will produce art output for daughters noting that it needs to be done recursively.
size_t ConvertToArtOutput(util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::ClusterParameters &clusterParameters, size_t pfParticleParent, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, Hit3DToSPPtrMap &best3DToSPPtrMap) const
Produces the art output from all the work done in this producer module.
void lar_cluster3d::Cluster3D::findTrackSeeds ( art::Event evt,
reco::ClusterParameters cluster,
IHit3DBuilder::RecobHitToPtrMap hitToPtrMap,
std::vector< recob::Seed > &  seedVec,
art::Assns< recob::Seed, recob::Hit > &  seedHitAssns 
) const
private

An interface to the seed finding algorithm.

Parameters
evtthe ART event
clusterstructure of information representing a single cluster
hitToPtrMapThis maps our Cluster2D hits back to art Ptr's to reco Hits
seedVecthe output vector of candidate seeds
seedHitAssnsthe associations between the seeds and the 2D hits making them

This method provides an interface to various algorithms for finding candiate recob::Seed objects and, as well, their candidate related seed hits

Definition at line 741 of file Cluster3D_module.cc.

746  {
747  /**
748  * @brief This method provides an interface to various algorithms for finding candiate
749  * recob::Seed objects and, as well, their candidate related seed hits
750  */
751 
752  // Make sure we are using the right pca
753  reco::PrincipalComponents& fullPCA = cluster.getFullPCA();
754  reco::PrincipalComponents& skeletonPCA = cluster.getSkeletonPCA();
755  reco::HitPairListPtr& hitPairListPtr = cluster.getHitPairListPtr();
756  reco::HitPairListPtr skeletonListPtr;
757 
758  // We want to work with the "skeleton" hits so first step is to call the algorithm to
759  // recover only these hits from the entire input collection
760  m_skeletonAlg.GetSkeletonHits(hitPairListPtr, skeletonListPtr);
761 
762  // Skeleton hits are nice but we can do better if we then make a pass through to "average"
763  // the skeleton hits position in the Y-Z plane
764  m_skeletonAlg.AverageSkeletonPositions(skeletonListPtr);
765 
766  SeedHitPairListPairVec seedHitPairVec;
767 
768  // Some combination of the elements below will be used to determine which seed finding algorithm
769  // to pursue below
770  float eigenVal0 = 3. * sqrt(skeletonPCA.getEigenValues()[0]);
771  float eigenVal1 = 3. * sqrt(skeletonPCA.getEigenValues()[1]);
772  float eigenVal2 = 3. * sqrt(skeletonPCA.getEigenValues()[2]);
773  float transRMS = std::hypot(eigenVal0, eigenVal1);
774 
775  bool foundGoodSeed(false);
776 
777  // Choose a method for finding the seeds based on the PCA that was run...
778  // Currently we have an ad hoc if-else block which I hope will be improved soon!
779  if (aParallelHitsCluster(fullPCA)) {
780  // In this case we have a track moving relatively parallel to the wire plane with lots of
781  // ambiguous 3D hits. Your best bet here is to use the "parallel hits" algorithm to get the
782  // best axis and seeds
783  // This algorithm does not fail (foundGoodSeed will always return true)
784  foundGoodSeed = m_parallelHitsAlg.findTrackSeeds(hitPairListPtr, skeletonPCA, seedHitPairVec);
785  }
786  else if (eigenVal2 > 40. && transRMS < 5.) {
787  // If the input cluster is relatively "straight" then chances are it is a single straight track,
788  // probably a CR muon, and we can simply use the PCA to determine the seed
789  // This algorithm will check both "ends" of the input hits and if the angles become inconsistent
790  // then it will "fail"
791  foundGoodSeed =
792  m_pcaSeedFinderAlg.findTrackSeeds(skeletonListPtr, skeletonPCA, seedHitPairVec);
793  }
794 
795  // In the event the above two methods failed then we hit it with the real seed finder
796  if (!foundGoodSeed) {
797  // If here then we have a complicated 3D cluster and we'll use the hough transform algorithm to
798  // return a list of candidate seeds and seed hits
799  m_seedFinderAlg.findTrackSeeds(skeletonListPtr, skeletonPCA, seedHitPairVec);
800  }
801 
802  // Go through the returned lists and build out the art friendly seeds and hits
803  for (const auto& seedHitPair : seedHitPairVec) {
804  seedVec.push_back(seedHitPair.first);
805 
806  // We use a set here because our 3D hits can share 2D hits
807  // The set will make sure we get unique combinations of 2D hits
808  std::set<art::Ptr<recob::Hit>> seedHitSet;
809  for (const auto& hit3D : seedHitPair.second) {
810  for (const auto& hit2D : hit3D->getHits()) {
811  if (!hit2D) continue;
812 
813  const recob::Hit* recobHit = hit2D->getHit();
814  seedHitSet.insert(hitToPtrMap[recobHit]);
815  }
816  }
817 
818  RecobHitVector seedHitVec;
819  for (const auto& hit2D : seedHitSet)
820  seedHitVec.push_back(hit2D);
821 
822  util::CreateAssn(evt, seedVec, seedHitVec, seedHitAssns);
823  }
824  }
bool aParallelHitsCluster(const reco::PrincipalComponents &pca) const
There are several places we will want to know if a candidate cluster is a "parallel hits" type of clu...
reco::PrincipalComponents & getSkeletonPCA()
Definition: Cluster3D.h:478
SkeletonAlg m_skeletonAlg
Skeleton point finder.
virtual bool findTrackSeeds(reco::HitPairListPtr &hitPairListPtr, reco::PrincipalComponents &inputPCA, SeedHitPairListPairVec &seedHitMap) const
Given the list of hits this will search for candidate Seed objects and return them.
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:476
art::PtrVector< recob::Hit > RecobHitVector
HoughSeedFinderAlg m_seedFinderAlg
Seed finder.
void GetSkeletonHits(const reco::HitPairListPtr &inputHitList, reco::HitPairListPtr &skeletonHitList) const
Return the skeleton hits from the input list.
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Definition: hypot.h:60
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:246
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:477
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
PCASeedFinderAlg m_pcaSeedFinderAlg
Use PCA axis to find seeds.
void AverageSkeletonPositions(reco::HitPairListPtr &skeletonHitList) const
Modifies the position of input skeleton hits by averaging along the "best" wire direction.
ParallelHitsSeedFinderAlg m_parallelHitsAlg
Deal with parallel hits clusters.
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:335
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
virtual bool findTrackSeeds(reco::HitPairListPtr &hitPairListPtr, reco::PrincipalComponents &inputPCA, SeedHitPairListPairVec &seedHitPairVec) const
Given the list of hits this will search for candidate Seed objects and return them.
std::vector< SeedHitPairListPair > SeedHitPairListPairVec
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
virtual bool findTrackSeeds(reco::HitPairListPtr &hitPairListPtr, reco::PrincipalComponents &inputPCA, SeedHitPairListPairVec &seedHitMap) const
Given the list of hits this will search for candidate Seed objects and return them.
void lar_cluster3d::Cluster3D::InitializeMonitoring ( )
private

Initialize the internal monitoring.

Definition at line 700 of file Cluster3D_module.cc.

701  {
703  m_pRecoTree = tfs->make<TTree>("monitoring", "LAr Reco");
704  m_pRecoTree->Branch("run", &m_run, "run/I");
705  m_pRecoTree->Branch("event", &m_event, "event/I");
706  m_pRecoTree->Branch("hits", &m_hits, "hits/I");
707  m_pRecoTree->Branch("hits3D", &m_hits3D, "hits3D/I");
708  m_pRecoTree->Branch("totalTime", &m_totalTime, "time/F");
709  m_pRecoTree->Branch("artHitsTime", &m_artHitsTime, "time/F");
710  m_pRecoTree->Branch("makeHitsTime", &m_makeHitsTime, "time/F");
711  m_pRecoTree->Branch("buildneigborhoodTime", &m_buildNeighborhoodTime, "time/F");
712  m_pRecoTree->Branch("dbscanTime", &m_dbscanTime, "time/F");
713  m_pRecoTree->Branch("clusterMergeTime", &m_clusterMergeTime, "time/F");
714  m_pRecoTree->Branch("pathfindingtime", &m_pathFindingTime, "time/F");
715  m_pRecoTree->Branch("finishTime", &m_finishTime, "time/F");
716 
717  m_clusterPathAlg->initializeHistograms(*tfs.get());
718  }
float m_buildNeighborhoodTime
Keeps track of time to build epsilon neighborhood.
std::unique_ptr< lar_cluster3d::IClusterModAlg > m_clusterPathAlg
Algorithm to do cluster path finding.
T * get() const
Definition: ServiceHandle.h:63
int m_hits3D
Keeps track of the number of 3D hits made.
float m_makeHitsTime
Keeps track of time to build 3D hits.
float m_dbscanTime
Keeps track of time to run DBScan.
float m_finishTime
Keeps track of time to run output module.
float m_clusterMergeTime
Keeps track of the time to merge clusters.
int m_hits
Keeps track of the number of hits seen.
float m_pathFindingTime
Keeps track of the path finding time.
float m_artHitsTime
Keeps track of time to recover hits.
float m_totalTime
Keeps track of total execution time.
void lar_cluster3d::Cluster3D::MakeAndSaveKinkPoints ( ArtOutputHandler output,
reco::ConvexHullKinkTupleList clusHitPairVector 
) const
private

Special routine to handle creating and saving space points.

Parameters
outputthe object containting the art output
clusHitPairVectorList of 3D hits to output as "extreme" space points

Definition at line 1724 of file Cluster3D_module.cc.

1726  {
1727  // Right now error matrix is uniform...
1728  double spError[] = {1., 0., 1., 0., 0., 1.};
1729 
1730  // Copy these hits to the vector to be stored with the event
1731  for (auto& kinkTuple : kinkTupleVec) {
1732  const reco::ClusterHit3D* hit = std::get<2>(std::get<0>(kinkTuple));
1733 
1734  double chisq = hit->getHitChiSquare(); // secret handshake...
1735 
1736  // Create and store the space point
1737  double spacePointPos[] = {
1738  hit->getPosition()[0], hit->getPosition()[1], hit->getPosition()[2]};
1739 
1740  spError[1] = hit->getTotalCharge();
1741  spError[3] = hit->getChargeAsymmetry();
1742 
1743  output.artExtremePointVector->push_back(
1744  recob::SpacePoint(spacePointPos, spError, chisq, output.artExtremePointVector->size()));
1745  }
1746 
1747  return;
1748  }
Detector simulation of raw signals on wires.
void lar_cluster3d::Cluster3D::MakeAndSavePCAPoints ( ArtOutputHandler output,
const reco::PrincipalComponents fullPCA,
IdxToPCAMap idxToPCAMap 
) const
private

Definition at line 1817 of file Cluster3D_module.cc.

1820  {
1821  // We actually do two things here:
1822  // 1) Create space points from the centroids of the PCA for each cluster
1823  // 2) Create the edges that link the space points together
1824 
1825  // The first task is to put the list of PCA's into some semblance of order... they may be
1826  // preordered by likely they are piecewise ordered so fix that here
1827 
1828  // We'll need the current PCA axis to determine doca and arclen
1829  Eigen::Vector3f avePosition(
1830  fullPCA.getAvePosition()[0], fullPCA.getAvePosition()[1], fullPCA.getAvePosition()[2]);
1831  Eigen::Vector3f axisDirVec(fullPCA.getEigenVectors().row(2));
1832 
1833  using DocaToPCAPair = std::pair<float, const reco::PrincipalComponents*>;
1834  using DocaToPCAVec = std::vector<DocaToPCAPair>;
1835 
1836  DocaToPCAVec docaToPCAVec;
1837 
1838  // Outer loop over views
1839  for (const auto& idxToPCA : idxToPCAMap) {
1840  const reco::PrincipalComponents* pca = idxToPCA.second;
1841 
1842  // Now we need to calculate the doca and poca...
1843  // Start by getting this hits position
1844  Eigen::Vector3f pcaPos(
1845  pca->getAvePosition()[0], pca->getAvePosition()[1], pca->getAvePosition()[2]);
1846 
1847  // Form a TVector from this to the cluster average position
1848  Eigen::Vector3f pcaToAveVec = pcaPos - avePosition;
1849 
1850  // With this we can get the arclength to the doca point
1851  float arclenToPoca = pcaToAveVec.dot(axisDirVec);
1852 
1853  docaToPCAVec.emplace_back(arclenToPoca, pca);
1854  }
1855 
1856  std::sort(docaToPCAVec.begin(), docaToPCAVec.end(), [](const auto& left, const auto& right) {
1857  return left.first < right.first;
1858  });
1859 
1860  // Set up the space point creation
1861  // Right now error matrix is uniform...
1862  double spError[] = {1., 0., 1., 0., 0., 1.};
1863  double chisq = 1.;
1864 
1865  const reco::PrincipalComponents* lastPCA(nullptr);
1866 
1867  // Set up to loop through the clusters
1868  for (const auto& docaToPCAPair : docaToPCAVec) {
1869  // Recover the PCA for this cluster
1870  const reco::PrincipalComponents* curPCA = docaToPCAPair.second;
1871 
1872  if (lastPCA) {
1873  double lastPointPos[] = {
1874  lastPCA->getAvePosition()[0], lastPCA->getAvePosition()[1], lastPCA->getAvePosition()[2]};
1875  size_t lastPointBin = output.artVertexPointVector->size();
1876  double curPointPos[] = {
1877  curPCA->getAvePosition()[0], curPCA->getAvePosition()[1], curPCA->getAvePosition()[2]};
1878  size_t curPointBin = lastPointBin + 1;
1879 
1880  output.artVertexPointVector->emplace_back(lastPointPos, spError, chisq, lastPointBin);
1881  output.artVertexPointVector->emplace_back(curPointPos, spError, chisq, curPointBin);
1882 
1883  Eigen::Vector3f distVec(curPointPos[0] - lastPointPos[0],
1884  curPointPos[1] - lastPointPos[1],
1885  curPointPos[2] - lastPointPos[2]);
1886 
1887  output.artVertexEdgeVector->emplace_back(
1888  distVec.norm(), lastPointBin, curPointBin, output.artEdgeVector->size());
1889  }
1890 
1891  lastPCA = curPCA;
1892  }
1893  }
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:248
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:247
void lar_cluster3d::Cluster3D::MakeAndSaveSpacePoints ( ArtOutputHandler output,
std::vector< recob::SpacePoint > &  spacePointVec,
art::Assns< recob::Hit, recob::SpacePoint > &  spHitAssns,
reco::HitPairListPtr clusHitPairVector,
IHit3DBuilder::RecobHitToPtrMap hitToPtrMap,
Hit3DToSPPtrMap hit3DToSPPtrMap,
const std::string path = "" 
) const
private

Special routine to handle creating and saving space points.

Parameters
outputthe object containting the art output
clusterParametersCluster info to output (in internal format)
pfParticleParentThe parent ID reference for the output PFParticle
hitToPtrMapThis maps our Cluster2D hits back to art Ptr's to reco Hits

Definition at line 1666 of file Cluster3D_module.cc.

1673  {
1674  // Reserve space...
1675  spacePointVec.reserve(spacePointVec.size() + clusHitPairVector.size());
1676 
1677  // Right now error matrix is uniform...
1678  double spError[] = {1., 0., 1., 0., 0., 1.};
1679 
1680  // Copy these hits to the vector to be stored with the event
1681  for (auto& hitPair : clusHitPairVector) {
1682  // Skip those space points that have already been created
1683  if (hit3DToSPPtrMap.find(hitPair) != hit3DToSPPtrMap.end()) continue;
1684 
1685  // Don't make space point if this hit was "rejected"
1686  if (hitPair->bitsAreSet(reco::ClusterHit3D::REJECTEDHIT)) continue;
1687 
1688  double chisq = hitPair->getHitChiSquare(); // secret handshake...
1689 
1690  // Mark this hit pair as in use
1691  hitPair->setStatusBit(reco::ClusterHit3D::MADESPACEPOINT);
1692 
1693  // Create and store the space point
1694  size_t spacePointID = spacePointVec.size();
1695  double spacePointPos[] = {
1696  hitPair->getPosition()[0], hitPair->getPosition()[1], hitPair->getPosition()[2]};
1697 
1698  spError[1] = hitPair->getTotalCharge();
1699  spError[3] = hitPair->getChargeAsymmetry();
1700 
1701  spacePointVec.emplace_back(spacePointPos, spError, chisq, spacePointID);
1702 
1703  // Update mapping
1704  hit3DToSPPtrMap[hitPair] = output.makeSpacePointPtr(spacePointID, instance);
1705 
1706  // space point hits associations
1707  RecobHitVector recobHits;
1708 
1709  for (const auto& hit : hitPair->getHits()) {
1710  if (!hit) continue;
1711 
1712  art::Ptr<recob::Hit> hitPtr = hitToPtrMap[hit->getHit()];
1713  recobHits.push_back(hitPtr);
1714  }
1715 
1716  if (!recobHits.empty())
1717  output.makeSpacePointHitAssns(spacePointVec, recobHits, spHitAssns, instance);
1718  }
1719 
1720  return;
1721  }
const std::string instance
Hit has been rejected for any reason.
Definition: Cluster3D.h:99
art::PtrVector< recob::Hit > RecobHitVector
Detector simulation of raw signals on wires.
Hit has been made into Space Point.
Definition: Cluster3D.h:103
void lar_cluster3d::Cluster3D::MakeAndSaveVertexPoints ( ArtOutputHandler output,
dcel2d::VertexList vertexList,
dcel2d::HalfEdgeList halfEdgeList 
) const
private

Special routine to handle creating and saving space points & edges associated to voronoi diagrams.

Parameters
outputthe object containting the art output
vertexListlist of vertices in the diagram
HalfEdgeListlist of half edges in the diagram

Definition at line 1751 of file Cluster3D_module.cc.

1754  {
1755  // We actually do two things here:
1756  // 1) Create space points to represent the vertex locations of the voronoi diagram
1757  // 2) Create the edges that link the space points together
1758 
1759  // Set up the space point creation
1760  // Right now error matrix is uniform...
1761  double spError[] = {1., 0., 1., 0., 0., 1.};
1762  double chisq = 1.;
1763 
1764  // Keep track of the vertex to space point association
1765  std::map<const dcel2d::Vertex*, size_t> vertexToSpacePointMap;
1766 
1767  // Copy these hits to the vector to be stored with the event
1768  for (auto& vertex : vertexList) {
1769  const dcel2d::Coords& coords = vertex.getCoords();
1770 
1771  // Create and store the space point
1772  double spacePointPos[] = {coords[0], coords[1], coords[2]};
1773 
1774  vertexToSpacePointMap[&vertex] = output.artVertexPointVector->size();
1775 
1776  output.artVertexPointVector->emplace_back(
1777  spacePointPos, spError, chisq, output.artVertexPointVector->size());
1778  }
1779 
1780  // Try to avoid double counting
1781  std::set<const dcel2d::HalfEdge*> halfEdgeSet;
1782 
1783  // Build the edges now
1784  for (const auto& halfEdge : halfEdgeList) {
1785  // Recover twin
1786  const dcel2d::HalfEdge* twin = halfEdge.getTwinHalfEdge();
1787 
1788  // It can happen that we have no twin... and also check that we've not been here before
1789  if (twin && halfEdgeSet.find(twin) == halfEdgeSet.end()) {
1790  // Recover the vertices
1791  const dcel2d::Vertex* fromVertex = twin->getTargetVertex();
1792  const dcel2d::Vertex* toVertex = halfEdge.getTargetVertex();
1793 
1794  // It can happen for the open edges that there is no target vertex
1795  if (!toVertex || !fromVertex) continue;
1796 
1797  if (vertexToSpacePointMap.find(fromVertex) == vertexToSpacePointMap.end() ||
1798  vertexToSpacePointMap.find(toVertex) == vertexToSpacePointMap.end())
1799  continue;
1800 
1801  // Need the distance between vertices
1802  Eigen::Vector3f distVec = toVertex->getCoords() - fromVertex->getCoords();
1803 
1804  output.artVertexEdgeVector->emplace_back(distVec.norm(),
1805  vertexToSpacePointMap[fromVertex],
1806  vertexToSpacePointMap[toVertex],
1807  output.artEdgeVector->size());
1808 
1809  halfEdgeSet.insert(&halfEdge);
1810  }
1811  }
1812 
1813  return;
1814  }
HalfEdge * getTwinHalfEdge() const
Definition: DCEL.h:163
Vertex * getTargetVertex() const
Definition: DCEL.h:161
Eigen::Vector3f Coords
Definition: DCEL.h:46
const Coords & getCoords() const
Definition: DCEL.h:69
vertex reconstruction
void lar_cluster3d::Cluster3D::PrepareEvent ( const art::Event evt)
private

Event Preparation.

Parameters
evtthe ART event

Definition at line 723 of file Cluster3D_module.cc.

724  {
725  m_run = evt.run();
726  m_event = evt.id().event();
727  m_hits = 0;
728  m_hits3D = 0;
729  m_totalTime = 0.f;
730  m_artHitsTime = 0.f;
731  m_makeHitsTime = 0.f;
733  m_dbscanTime = 0.f;
734  m_pathFindingTime = 0.f;
735  m_finishTime = 0.f;
736  }
float m_buildNeighborhoodTime
Keeps track of time to build epsilon neighborhood.
int m_hits3D
Keeps track of the number of 3D hits made.
float m_makeHitsTime
Keeps track of time to build 3D hits.
float m_dbscanTime
Keeps track of time to run DBScan.
float m_finishTime
Keeps track of time to run output module.
RunNumber_t run() const
Definition: DataViewImpl.cc:71
int m_hits
Keeps track of the number of hits seen.
float m_pathFindingTime
Keeps track of the path finding time.
EventNumber_t event() const
Definition: EventID.h:116
float m_artHitsTime
Keeps track of time to recover hits.
EventID id() const
Definition: Event.cc:34
float m_totalTime
Keeps track of total execution time.
void lar_cluster3d::Cluster3D::produce ( art::Event evt)
overrideprivatevirtual

Implements art::EDProducer.

Definition at line 611 of file Cluster3D_module.cc.

612  {
613  mf::LogInfo("Cluster3D") << " *** Cluster3D::produce(...) [Run=" << evt.run()
614  << ", Event=" << evt.id().event() << "] Starting Now! *** "
615  << std::endl;
616 
617  // Set up for monitoring the timing... at some point this should be removed in favor of
618  // external profilers
619  cet::cpu_timer theClockTotal;
620  cet::cpu_timer theClockFinish;
621 
622  if (m_enableMonitoring) theClockTotal.start();
623 
624  // This really only does anything if we are monitoring since it clears our tree variables
625  this->PrepareEvent(evt);
626 
627  // Get instances of the primary data structures needed
628  reco::ClusterParametersList clusterParametersList;
629  IHit3DBuilder::RecobHitToPtrMap clusterHitToArtPtrMap;
630  std::unique_ptr<reco::HitPairList> hitPairList(
631  new reco::HitPairList); // Potentially lots of hits, use heap instead of stack
632 
633  // Call the algorithm that builds 3D hits and stores the hit collection
634  m_hit3DBuilderAlg->Hit3DBuilder(evt, *hitPairList, clusterHitToArtPtrMap);
635 
636  // Only do the rest if we are not in the mode of only building space points (requested by ML folks)
637  if (!m_onlyMakSpacePoints) {
638  // Call the main workhorse algorithm for building the local version of candidate 3D clusters
639  m_clusterAlg->Cluster3DHits(*hitPairList, clusterParametersList);
640 
641  // Try merging clusters
642  m_clusterMergeAlg->ModifyClusters(clusterParametersList);
643 
644  // Run the path finding
645  m_clusterPathAlg->ModifyClusters(clusterParametersList);
646  }
647 
648  if (m_enableMonitoring) theClockFinish.start();
649 
650  // Get the art ouput object
651  ArtOutputHandler output(evt, m_pathInstance, m_vertexInstance, m_extremeInstance);
652 
653  // Call the module that does the end processing (of which there is quite a bit of work!)
654  // This goes here to insure that something is always written to the data store
655  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
656  auto const detProp =
658  util::GeometryUtilities const gser{*lar::providerFrom<geo::Geometry>(), clockData, detProp};
659  ProduceArtClusters(gser, output, *hitPairList, clusterParametersList, clusterHitToArtPtrMap);
660 
661  // Output to art
662  output.outputObjects();
663 
664  // If monitoring then deal with the fallout
665  if (m_enableMonitoring) {
666  theClockFinish.stop();
667  theClockTotal.stop();
668 
669  m_run = evt.run();
670  m_event = evt.id().event();
671  m_totalTime = theClockTotal.accumulated_real_time();
675  m_dbscanTime = m_clusterAlg->getTimeToExecute(IClusterAlg::RUNDBSCAN) +
676  m_clusterAlg->getTimeToExecute(IClusterAlg::BUILDCLUSTERINFO);
677  m_clusterMergeTime = m_clusterMergeAlg->getTimeToExecute();
678  m_pathFindingTime = m_clusterPathAlg->getTimeToExecute();
679  m_finishTime = theClockFinish.accumulated_real_time();
680  m_hits = static_cast<int>(clusterHitToArtPtrMap.size());
681  m_hits3D = static_cast<int>(hitPairList->size());
682  m_pRecoTree->Fill();
683 
684  mf::LogDebug("Cluster3D") << "*** Cluster3D total time: " << m_totalTime
685  << ", art: " << m_artHitsTime << ", make: " << m_makeHitsTime
686  << ", build: " << m_buildNeighborhoodTime
687  << ", clustering: " << m_dbscanTime
688  << ", merge: " << m_clusterMergeTime
689  << ", path: " << m_pathFindingTime << ", finish: " << m_finishTime
690  << std::endl;
691  }
692 
693  // Will we ever get here? ;-)
694  return;
695  }
float m_buildNeighborhoodTime
Keeps track of time to build epsilon neighborhood.
std::list< reco::ClusterHit3D > HitPairList
Definition: Cluster3D.h:339
std::unique_ptr< lar_cluster3d::IClusterModAlg > m_clusterPathAlg
Algorithm to do cluster path finding.
std::string m_vertexInstance
Special instance name for vertex points.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
int m_hits3D
Keeps track of the number of 3D hits made.
void ProduceArtClusters(util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::HitPairList &hitPairList, reco::ClusterParametersList &clusterParametersList, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap) const
Top level output routine, allows checking cluster status.
bool m_onlyMakSpacePoints
If true we don&#39;t do the full cluster 3D processing.
std::unique_ptr< lar_cluster3d::IClusterAlg > m_clusterAlg
Algorithm to do 3D space point clustering.
float m_makeHitsTime
Keeps track of time to build 3D hits.
float m_dbscanTime
Keeps track of time to run DBScan.
std::string m_extremeInstance
Instance name for the extreme points.
float m_finishTime
Keeps track of time to run output module.
float m_clusterMergeTime
Keeps track of the time to merge clusters.
RunNumber_t run() const
Definition: DataViewImpl.cc:71
int m_hits
Keeps track of the number of hits seen.
float m_pathFindingTime
Keeps track of the path finding time.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
std::unique_ptr< lar_cluster3d::IClusterModAlg > m_clusterMergeAlg
Algorithm to do cluster merging.
std::unique_ptr< lar_cluster3d::IHit3DBuilder > m_hit3DBuilderAlg
Builds the 3D hits to operate on.
EventNumber_t event() const
Definition: EventID.h:116
float m_artHitsTime
Keeps track of time to recover hits.
double accumulated_real_time() const
Definition: cpu_timer.cc:66
void start()
Definition: cpu_timer.cc:83
std::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
Definition: IHit3DBuilder.h:56
void PrepareEvent(const art::Event &evt)
Event Preparation.
EventID id() const
Definition: Event.cc:34
std::string m_pathInstance
Special instance for path points.
float m_totalTime
Keeps track of total execution time.
std::list< ClusterParameters > ClusterParametersList
Definition: Cluster3D.h:404
QTextStream & endl(QTextStream &s)
bool m_enableMonitoring
Turn on monitoring of this algorithm.
void lar_cluster3d::Cluster3D::ProduceArtClusters ( util::GeometryUtilities const &  gser,
ArtOutputHandler output,
reco::HitPairList hitPairList,
reco::ClusterParametersList clusterParametersList,
IHit3DBuilder::RecobHitToPtrMap hitToPtrMap 
) const
private

Top level output routine, allows checking cluster status.

Parameters
hitPairListList of all 3D Hits in internal Cluster3D format
clusterParametersListData structure containing the cluster information to output
hitToPtrMapThis maps our Cluster2D hits back to art Ptr's to reco Hits

The workhorse to take the candidate 3D clusters and produce all of the necessary art output

Definition at line 1173 of file Cluster3D_module.cc.

1178  {
1179  /**
1180  * @brief The workhorse to take the candidate 3D clusters and produce all of the necessary art output
1181  */
1182 
1183  mf::LogDebug("Cluster3D") << " *** Cluster3D::ProduceArtClusters() *** " << std::endl;
1184 
1185  // Make sure there is something to do here!
1186  if (!clusterParametersList.empty()) {
1187  // This is the loop over candidate 3D clusters
1188  // Note that it might be that the list of candidate clusters is modified by splitting
1189  // So we use the following construct to make sure we get all of them
1190  for (auto& clusterParameters : clusterParametersList) {
1191  // It should be straightforward at this point to transfer information from our vector of clusters
1192  // to the larsoft objects... of course we still have some work to do first, in particular to
1193  // find the candidate seeds and their seed hits
1194 
1195  // The chances of getting here and this condition not being true are probably zero... but check anyway
1196  if (!clusterParameters.getFullPCA().getSvdOK()) {
1197  mf::LogDebug("Cluster3D")
1198  << "--> no feature extraction done on this cluster!!" << std::endl;
1199  continue;
1200  }
1201 
1202  // Keep track of hit 3D to SP for when we do edges
1203  Hit3DToSPPtrMap hit3DToSPPtrMap;
1204  Hit3DToSPPtrMap best3DToSPPtrMap;
1205 
1206  // Do a special output of voronoi vertices here...
1207  dcel2d::VertexList& vertexList = clusterParameters.getVertexList();
1208  dcel2d::HalfEdgeList& halfEdgeList = clusterParameters.getHalfEdgeList();
1209 
1210  MakeAndSaveVertexPoints(output, vertexList, halfEdgeList);
1211 
1212  // Special case handling... if no daughters then call standard conversion routine to make sure space points
1213  // created, etc.
1214  if (clusterParameters.daughterList().empty()) {
1215  ConvertToArtOutput(gser,
1216  output,
1217  clusterParameters,
1219  hitToPtrMap,
1220  hit3DToSPPtrMap,
1221  best3DToSPPtrMap);
1222 
1223  // Get the extreme points
1225  clusterParameters.getConvexHull().getConvexHullKinkPoints());
1226  }
1227  // Otherwise, the cluster has daughters so we handle specially
1228  else {
1229  // Set up to keep track of parent/daughters
1230  IdxToPCAMap idxToPCAMap;
1231  size_t numTotalDaughters = countUltimateDaughters(clusterParameters);
1232  size_t pfParticleIdx(output.artPFParticleVector->size() + numTotalDaughters);
1233 
1234  FindAndStoreDaughters(gser,
1235  output,
1236  clusterParameters,
1237  pfParticleIdx,
1238  idxToPCAMap,
1239  hitToPtrMap,
1240  hit3DToSPPtrMap,
1241  best3DToSPPtrMap);
1242 
1243  // Need to make a daughter vec from our map
1244  std::vector<size_t> daughterVec;
1245 
1246  for (auto& idxToPCA : idxToPCAMap)
1247  daughterVec.emplace_back(idxToPCA.first);
1248 
1249  // Now create/handle the parent PFParticle
1250  recob::PFParticle pfParticle(
1251  13, pfParticleIdx, recob::PFParticle::kPFParticlePrimary, daughterVec);
1252  output.artPFParticleVector->push_back(pfParticle);
1253 
1254  recob::PCAxis::EigenVectors eigenVecs;
1255  double eigenVals[] = {0., 0., 0.};
1256  double avePosition[] = {0., 0., 0.};
1257 
1258  eigenVecs.resize(3);
1259 
1260  reco::PrincipalComponents& skeletonPCA = clusterParameters.getSkeletonPCA();
1261 
1262  for (size_t outerIdx = 0; outerIdx < 3; outerIdx++) {
1263  avePosition[outerIdx] = skeletonPCA.getAvePosition()[outerIdx];
1264  eigenVals[outerIdx] = skeletonPCA.getEigenValues()[outerIdx];
1265 
1266  eigenVecs[outerIdx].resize(3);
1267 
1268  // Be careful here... eigen stores in column major order buy default
1269  for (size_t innerIdx = 0; innerIdx < 3; innerIdx++)
1270  eigenVecs[outerIdx][innerIdx] = skeletonPCA.getEigenVectors().row(outerIdx)[innerIdx];
1271  }
1272 
1273  recob::PCAxis skelPcAxis(skeletonPCA.getSvdOK(),
1274  skeletonPCA.getNumHitsUsed(),
1275  eigenVals,
1276  eigenVecs,
1277  avePosition,
1278  skeletonPCA.getAveHitDoca(),
1279  output.artPCAxisVector->size());
1280 
1281  output.artPCAxisVector->push_back(skelPcAxis);
1282 
1283  reco::PrincipalComponents& fullPCA = clusterParameters.getFullPCA();
1284 
1285  for (size_t outerIdx = 0; outerIdx < 3; outerIdx++) {
1286  avePosition[outerIdx] = fullPCA.getAvePosition()[outerIdx];
1287  eigenVals[outerIdx] = fullPCA.getEigenValues()[outerIdx];
1288 
1289  for (size_t innerIdx = 0; innerIdx < 3; innerIdx++)
1290  eigenVecs[outerIdx][innerIdx] = fullPCA.getEigenVectors().row(outerIdx)(innerIdx);
1291  }
1292 
1293  recob::PCAxis fullPcAxis(fullPCA.getSvdOK(),
1294  fullPCA.getNumHitsUsed(),
1295  eigenVals,
1296  eigenVecs,
1297  avePosition,
1298  fullPCA.getAveHitDoca(),
1299  output.artPCAxisVector->size());
1300 
1301  output.artPCAxisVector->push_back(fullPcAxis);
1302 
1303  // Create associations to the PFParticle
1304  output.makePFPartPCAAssns();
1305 
1306  // Make associations to all space points for this cluster
1308  *output.artSpacePointVector.get(),
1309  *output.artSPHitAssociations.get(),
1310  clusterParameters.getHitPairListPtr(),
1311  hitToPtrMap,
1312  hit3DToSPPtrMap);
1313 
1314  // Get the extreme points
1316  clusterParameters.getConvexHull().getConvexHullKinkPoints());
1317 
1318  // Build the edges now
1319  size_t edgeStart(output.artEdgeVector->size());
1320 
1321  for (const auto& edge : clusterParameters.getConvexHull().getConvexHullEdgeList()) {
1322  RecobSpacePointVector spacePointVec;
1323 
1324  try {
1325  spacePointVec.push_back(hit3DToSPPtrMap.at(std::get<0>(edge)));
1326  spacePointVec.push_back(hit3DToSPPtrMap.at(std::get<1>(edge)));
1327  }
1328  catch (...) {
1329  std::cout << "Caught exception in looking up space point ptr... " << std::get<0>(edge)
1330  << ", " << std::get<1>(edge) << std::endl;
1331  continue;
1332  }
1333 
1334  output.artEdgeVector->emplace_back(std::get<2>(edge),
1335  spacePointVec[0].key(),
1336  spacePointVec[1].key(),
1337  output.artEdgeVector->size());
1338 
1339  output.makeEdgeSpacePointAssns(
1340  *output.artEdgeVector.get(), spacePointVec, *output.artEdgeSPAssociations.get());
1341  }
1342 
1343  output.makePFPartEdgeAssns(
1344  *output.artEdgeVector.get(), *output.artPFPartEdgeAssociations.get(), edgeStart);
1345  }
1346  }
1347  }
1348 
1349  // Right now error matrix is uniform...
1350  int nFreePoints(0);
1351 
1352  // Run through the HitPairVector and add any unused hit pairs to the list
1353  for (auto& hitPair : hitPairVector) {
1354  if (hitPair.bitsAreSet(reco::ClusterHit3D::MADESPACEPOINT)) continue;
1355 
1356  double spacePointPos[] = {
1357  hitPair.getPosition()[0], hitPair.getPosition()[1], hitPair.getPosition()[2]};
1358  double spacePointErr[] = {1., 0., 0., 1., 0., 1.};
1359  double chisq = hitPair.getHitChiSquare();
1360 
1361  RecobHitVector recobHits;
1362 
1363  for (const auto hit : hitPair.getHits()) {
1364  if (!hit) {
1365  chisq = -1000.;
1366  continue;
1367  }
1368 
1369  art::Ptr<recob::Hit> hitPtr = hitToPtrMap[hit->getHit()];
1370  recobHits.push_back(hitPtr);
1371  }
1372 
1373  nFreePoints++;
1374 
1375  spacePointErr[1] = hitPair.getTotalCharge();
1376  spacePointErr[3] = hitPair.getChargeAsymmetry();
1377 
1378  output.artSpacePointVector->push_back(
1379  recob::SpacePoint(spacePointPos, spacePointErr, chisq, output.artSpacePointVector->size()));
1380 
1381  if (!recobHits.empty())
1382  output.makeSpacePointHitAssns(
1383  *output.artSpacePointVector.get(), recobHits, *output.artSPHitAssociations.get());
1384  }
1385 
1386  std::cout << "++++>>>> total num hits: " << hitPairVector.size()
1387  << ", num free: " << nFreePoints << std::endl;
1388  }
bool getSvdOK() const
Definition: Cluster3D.h:244
art::PtrVector< recob::SpacePoint > RecobSpacePointVector
static constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
Definition: PFParticle.h:61
std::list< HalfEdge > HalfEdgeList
Definition: DCEL.h:184
int getNumHitsUsed() const
Definition: Cluster3D.h:245
art::PtrVector< recob::Hit > RecobHitVector
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:246
size_t countUltimateDaughters(reco::ClusterParameters &clusterParameters) const
Count number of end of line daughters.
def key(type, name=None)
Definition: graph.py:13
const Eigen::Vector3f & getAvePosition() const
Definition: Cluster3D.h:248
size_t FindAndStoreDaughters(util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::ClusterParameters &clusterParameters, size_t pfParticleParent, IdxToPCAMap &idxToPCAMap, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, Hit3DToSPPtrMap &best3DToSPPtrMap) const
This will produce art output for daughters noting that it needs to be done recursively.
Detector simulation of raw signals on wires.
void MakeAndSaveSpacePoints(ArtOutputHandler &output, std::vector< recob::SpacePoint > &spacePointVec, art::Assns< recob::Hit, recob::SpacePoint > &spHitAssns, reco::HitPairListPtr &clusHitPairVector, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, const std::string &path="") const
Special routine to handle creating and saving space points.
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
const float getAveHitDoca() const
Definition: Cluster3D.h:249
Hit has been made into Space Point.
Definition: Cluster3D.h:103
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void MakeAndSaveVertexPoints(ArtOutputHandler &, dcel2d::VertexList &, dcel2d::HalfEdgeList &) const
Special routine to handle creating and saving space points & edges associated to voronoi diagrams...
size_t ConvertToArtOutput(util::GeometryUtilities const &gser, ArtOutputHandler &output, reco::ClusterParameters &clusterParameters, size_t pfParticleParent, IHit3DBuilder::RecobHitToPtrMap &hitToPtrMap, Hit3DToSPPtrMap &hit3DToSPPtrMap, Hit3DToSPPtrMap &best3DToSPPtrMap) const
Produces the art output from all the work done in this producer module.
std::unordered_map< const reco::ClusterHit3D *, art::Ptr< recob::SpacePoint >> Hit3DToSPPtrMap
void MakeAndSaveKinkPoints(ArtOutputHandler &output, reco::ConvexHullKinkTupleList &clusHitPairVector) const
Special routine to handle creating and saving space points.
std::vector< std::vector< double > > EigenVectors
Definition: PCAxis.h:29
std::list< Vertex > VertexList
Definition: DCEL.h:182
const EigenVectors & getEigenVectors() const
Definition: Cluster3D.h:247
QTextStream & endl(QTextStream &s)
std::map< size_t, const reco::PrincipalComponents * > IdxToPCAMap
Special routine to handle creating and saving space points & edges PCA points.
void lar_cluster3d::Cluster3D::splitClustersWithHough ( reco::ClusterParameters clusterParameters,
reco::ClusterParametersList clusterParametersList 
) const
private

Attempt to split clusters using the output of the Hough Filter.

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

Definition at line 1029 of file Cluster3D_module.cc.

1031  {
1032  // @brief A method for splitted "crossed tracks" clusters into separate clusters
1033  //
1034  // If this routine is called then we believe we have a cluster which needs splitting.
1035  // The specific topology we are looking for is two long straight tracks which cross at some
1036  // point in close proximity so their hits were joined into a single 3D cluster. The method
1037  // to split this topology is to let the hough transform algorithm find the two leading candidates
1038  // and then to see if we use those to build two clusters instead of one.
1039 
1040  // Recover the hits we'll work on.
1041  // Note that we use on the skeleton hits so will need to recover them
1042  reco::HitPairListPtr& hitPairListPtr = clusterParameters.getHitPairListPtr();
1043  reco::HitPairListPtr skeletonListPtr;
1044 
1045  // We want to work with the "skeleton" hits so first step is to call the algorithm to
1046  // recover only these hits from the entire input collection
1047  m_skeletonAlg.GetSkeletonHits(hitPairListPtr, skeletonListPtr);
1048 
1049  // Skeleton hits are nice but we can do better if we then make a pass through to "average"
1050  // the skeleton hits position in the Y-Z plane
1051  m_skeletonAlg.AverageSkeletonPositions(skeletonListPtr);
1052 
1053  // Define the container for our lists of hits
1054  reco::HitPairListPtrList hitPairListPtrList;
1055 
1056  // Now feed this to the Hough Transform to find candidate straight lines
1058  skeletonListPtr, clusterParameters.getSkeletonPCA(), hitPairListPtrList);
1059 
1060  // We need at least two lists or else there is nothing to do
1061  if (hitPairListPtrList.size() < 2) return;
1062 
1063  // The game plan will be the following:
1064  // 1) Take the first list of hits and run the PCA on this to get an axis
1065  // - Then calculate the 3d doca for ALL hits in the cluster to this axis
1066  // - Move all hits within "3 sigam" of the axis to a new list
1067  // 2) run the PCA on the second list of hits to get that axis
1068  // - Then calculate the 3d doca for all hits in our first list
1069  // - Copy hits in the first list which are within 3 sigma of the new axis
1070  // back into our original cluster - these are shared hits
1071  reco::HitPairListPtrList::iterator hitPairListIter = hitPairListPtrList.begin();
1072  reco::HitPairListPtr& firstHitList = *hitPairListIter++;
1073  reco::PrincipalComponents firstHitListPCA;
1074 
1075  m_pcaAlg.PCAAnalysis_3D(firstHitList, firstHitListPCA);
1076 
1077  // Make sure we have a successful calculation.
1078  if (firstHitListPCA.getSvdOK()) {
1079  // The fill routines below will expect to see unused 2D hits so we need to clear the
1080  // status bits... and I am not sure of a better way...
1081  for (const auto& hit3D : hitPairListPtr) {
1082  for (const auto& hit2D : hit3D->getHits())
1083  if (hit2D) hit2D->clearStatusBits(0x1);
1084  }
1085 
1086  // Calculate the 3D doca's for the hits which were used to make this PCA
1087  m_pcaAlg.PCAAnalysis_calc3DDocas(firstHitList, firstHitListPCA);
1088 
1089  // Divine from the ether some maximum allowed range for transfering hits
1090  float allowedHitRange = 6. * firstHitListPCA.getAveHitDoca();
1091 
1092  // Now go through and calculate the 3D doca's for ALL the hits in the original cluster
1093  m_pcaAlg.PCAAnalysis_calc3DDocas(hitPairListPtr, firstHitListPCA);
1094 
1095  // Let's make a new cluster to hold the hits
1096  clusterParametersList.push_back(reco::ClusterParameters());
1097 
1098  // Can we get a reference to what we just created?
1099  reco::ClusterParameters& newClusterParams = clusterParametersList.back();
1100 
1101  reco::HitPairListPtr& newClusterHitList = newClusterParams.getHitPairListPtr();
1102 
1103  newClusterHitList.resize(hitPairListPtr.size());
1104 
1105  // Do the actual copy of the hits we want
1106  reco::HitPairListPtr::iterator newListEnd = std::copy_if(hitPairListPtr.begin(),
1107  hitPairListPtr.end(),
1108  newClusterHitList.begin(),
1109  CopyIfInRange(allowedHitRange));
1110 
1111  // Shrink to fit
1112  newClusterHitList.resize(std::distance(newClusterHitList.begin(), newListEnd));
1113 
1114  // And now remove these hits from the original cluster
1115  hitPairListPtr.remove_if(CopyIfInRange(allowedHitRange));
1116 
1117  // Get an empty hit to cluster map...
1118  reco::Hit2DToClusterMap hit2DToClusterMap;
1119 
1120  // Now "fill" the cluster parameters but turn off the hit rejection
1121  m_clusterBuilder->FillClusterParams(newClusterParams, hit2DToClusterMap, 0., 1.);
1122 
1123  // Set the skeleton pca to the value calculated above on input
1124  clusterParameters.getSkeletonPCA() = firstHitListPCA;
1125 
1126  // We are done with splitting out one track. Because the two tracks cross in
1127  // close proximity, this is the one case where we might consider sharing 3D hits
1128  // So let's make a little detour here to try to copy some of those hits back into
1129  // the main hit list
1130  reco::HitPairListPtr& secondHitList = *hitPairListIter;
1131  reco::PrincipalComponents secondHitListPCA;
1132 
1133  m_pcaAlg.PCAAnalysis_3D(secondHitList, secondHitListPCA);
1134 
1135  // Make sure we have a successful calculation.
1136  if (secondHitListPCA.getSvdOK()) {
1137  // Calculate the 3D doca's for the hits which were used to make this PCA
1138  m_pcaAlg.PCAAnalysis_calc3DDocas(secondHitList, secondHitListPCA);
1139 
1140  // Since this is the "other" cluster, we'll be a bit more generous in adding back hits
1141  float newAllowedHitRange = 6. * secondHitListPCA.getAveHitDoca();
1142 
1143  // Go through and calculate the 3D doca's for the hits in our new candidate cluster
1144  m_pcaAlg.PCAAnalysis_calc3DDocas(newClusterHitList, secondHitListPCA);
1145 
1146  // Create a temporary list to fill with the hits we might want to save
1147  reco::HitPairListPtr tempHitList(newClusterHitList.size());
1148 
1149  // Do the actual copy of the hits we want...
1150  reco::HitPairListPtr::iterator tempListEnd =
1151  std::copy_if(newClusterHitList.begin(),
1152  newClusterHitList.end(),
1153  tempHitList.begin(),
1154  CopyIfInRange(newAllowedHitRange));
1155 
1156  hitPairListPtr.insert(hitPairListPtr.end(), tempHitList.begin(), tempListEnd);
1157  }
1158 
1159  // Of course, now we need to modify the original cluster parameters
1160  reco::ClusterParameters originalParams(hitPairListPtr);
1161 
1162  // Now "fill" the cluster parameters but turn off the hit rejection
1163  m_clusterBuilder->FillClusterParams(originalParams, hit2DToClusterMap, 0., 1.);
1164 
1165  // Overwrite original cluster parameters with our new values
1166  clusterParameters.getClusterParams() = originalParams.getClusterParams();
1167  clusterParameters.getFullPCA() = originalParams.getFullPCA();
1168  clusterParameters.getSkeletonPCA() = secondHitListPCA;
1169  }
1170  }
intermediate_table::iterator iterator
void PCAAnalysis_calc3DDocas(const reco::HitPairListPtr &hitPairVector, const reco::PrincipalComponents &pca) const
bool getSvdOK() const
Definition: Cluster3D.h:244
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
reco::PrincipalComponents & getSkeletonPCA()
Definition: Cluster3D.h:478
SkeletonAlg m_skeletonAlg
Skeleton point finder.
std::list< HitPairListPtr > HitPairListPtrList
Definition: Cluster3D.h:337
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:476
reco::PlaneToClusterParamsMap & getClusterParams()
Definition: Cluster3D.h:474
HoughSeedFinderAlg m_seedFinderAlg
Seed finder.
void GetSkeletonHits(const reco::HitPairListPtr &inputHitList, reco::HitPairListPtr &skeletonHitList) const
Return the skeleton hits from the input list.
reco::PrincipalComponents & getFullPCA()
Definition: Cluster3D.h:477
void AverageSkeletonPositions(reco::HitPairListPtr &skeletonHitList) const
Modifies the position of input skeleton hits by averaging along the "best" wire direction.
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:335
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
virtual 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...
std::unique_ptr< lar_cluster3d::IClusterParametersBuilder > m_clusterBuilder
Common cluster builder tool.
const float getAveHitDoca() const
Definition: Cluster3D.h:249
PrincipalComponentsAlg m_pcaAlg
Principal Components algorithm.
std::unordered_map< const reco::ClusterHit2D *, ClusterToHitPairSetMap > Hit2DToClusterMap
Definition: Cluster3D.h:511
void lar_cluster3d::Cluster3D::splitClustersWithMST ( reco::ClusterParameters clusterParameters,
reco::ClusterParametersList clusterParametersList 
) const
private

Attempt to split clusters by using a minimum spanning tree.

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

Definition at line 836 of file Cluster3D_module.cc.

838  {
839  // This is being left in place for future development. Essentially, it was an attempt to implement
840  // a Minimum Spanning Tree as a way to split a particular cluster topology, one where two straight
841  // tracks cross closely enought to appear as one cluster. As of Feb 2, 2015 I think the idea is still
842  // worth merit so am leaving this module in place for now.
843  //
844  // If this routine is called then we believe we have a cluster which needs splitting.
845  // The way we will do this is to use a Minimum Spanning Tree algorithm to associate all
846  // hits together by their distance apart. In theory, we should be able to split the cluster
847  // by finding the largest distance and splitting at that point.
848  //
849  // Typedef some data structures that we will use.
850  // Start with the adjacency map
851  typedef std::pair<float, const reco::ClusterHit3D*> DistanceHit3DPair;
852  typedef std::list<DistanceHit3DPair> DistanceHit3DPairList;
853  typedef std::map<const reco::ClusterHit3D*, DistanceHit3DPairList> Hit3DToDistanceMap;
854 
855  // Now typedef the lists we'll keep
856  typedef std::list<const reco::ClusterHit3D*> Hit3DList;
857  typedef std::pair<Hit3DList::iterator, Hit3DList::iterator> Hit3DEdgePair;
858  typedef std::pair<float, Hit3DEdgePair> DistanceEdgePair;
859  typedef std::list<DistanceEdgePair> DistanceEdgePairList;
860 
861  struct DistanceEdgePairOrder {
862  bool
863  operator()(const DistanceEdgePair& left, const DistanceEdgePair& right) const
864  {
865  return left.first > right.first;
866  }
867  };
868 
869  // Recover the hits we'll work on.
870  // Note that we use on the skeleton hits so will need to recover them
871  reco::HitPairListPtr& hitPairListPtr = clusterParameters.getHitPairListPtr();
872  reco::HitPairListPtr skeletonListPtr;
873 
874  // We want to work with the "skeleton" hits so first step is to call the algorithm to
875  // recover only these hits from the entire input collection
876  m_skeletonAlg.GetSkeletonHits(hitPairListPtr, skeletonListPtr);
877 
878  // Skeleton hits are nice but we can do better if we then make a pass through to "average"
879  // the skeleton hits position in the Y-Z plane
880  m_skeletonAlg.AverageSkeletonPositions(skeletonListPtr);
881 
882  // First task is to define and build the adjacency map
883  Hit3DToDistanceMap hit3DToDistanceMap;
884 
885  for (reco::HitPairListPtr::const_iterator hit3DOuterItr = skeletonListPtr.begin();
886  hit3DOuterItr != skeletonListPtr.end();) {
887  const reco::ClusterHit3D* hit3DOuter = *hit3DOuterItr++;
888  DistanceHit3DPairList& outerHitList = hit3DToDistanceMap[hit3DOuter];
889  TVector3 outerPos(
890  hit3DOuter->getPosition()[0], hit3DOuter->getPosition()[1], hit3DOuter->getPosition()[2]);
891 
892  for (reco::HitPairListPtr::const_iterator hit3DInnerItr = hit3DOuterItr;
893  hit3DInnerItr != skeletonListPtr.end();
894  hit3DInnerItr++) {
895  const reco::ClusterHit3D* hit3DInner = *hit3DInnerItr;
896  TVector3 innerPos(
897  hit3DInner->getPosition()[0], hit3DInner->getPosition()[1], hit3DInner->getPosition()[2]);
898  TVector3 deltaPos = innerPos - outerPos;
899  float hitDistance(float(deltaPos.Mag()));
900 
901  if (hitDistance > 20.) continue;
902 
903  hit3DToDistanceMap[hit3DInner].emplace_back(hitDistance, hit3DOuter);
904  outerHitList.emplace_back(hitDistance, hit3DInner);
905  }
906 
907  // Make sure our membership bit is clear
909  }
910 
911  // Make pass through again to order each of the lists
912  for (auto& mapPair : hit3DToDistanceMap) {
913  mapPair.second.sort(Hit3DDistanceOrder());
914  }
915 
916  // Get the containers for the MST to operate on/with
917  Hit3DList hit3DList;
918  DistanceEdgePairList distanceEdgePairList;
919 
920  // Initialize with first element
921  hit3DList.emplace_back(skeletonListPtr.front());
922  distanceEdgePairList.emplace_back(
923  DistanceEdgePair(0., Hit3DEdgePair(hit3DList.begin(), hit3DList.begin())));
924 
925  skeletonListPtr.front()->setStatusBit(reco::ClusterHit3D::SELECTEDBYMST);
926 
927  float largestDistance(0.);
928  float averageDistance(0.);
929 
930  // Now run the MST
931  // Basically, we loop until the MST list is the same size as the input list
932  while (hit3DList.size() < skeletonListPtr.size()) {
933  Hit3DList::iterator bestHit3DIter = hit3DList.begin();
934  float bestDist = 10000000.;
935 
936  // Loop through all hits currently in the list and look for closest hit not in the list
937  for (Hit3DList::iterator hit3DIter = hit3DList.begin(); hit3DIter != hit3DList.end();
938  hit3DIter++) {
939  const reco::ClusterHit3D* hit3D = *hit3DIter;
940 
941  // For the given 3D hit, find the closest to it that is not already in the list
942  DistanceHit3DPairList& nearestList = hit3DToDistanceMap[hit3D];
943 
944  while (!nearestList.empty()) {
945  const reco::ClusterHit3D* hit3DToCheck = nearestList.front().second;
946 
947  if (!hit3DToCheck->bitsAreSet(reco::ClusterHit3D::SELECTEDBYMST)) {
948  if (nearestList.front().first < bestDist) {
949  bestHit3DIter = hit3DIter;
950  bestDist = nearestList.front().first;
951  }
952  break;
953  }
954 
955  nearestList.pop_front();
956  }
957  }
958 
959  if (bestDist > largestDistance) largestDistance = bestDist;
960 
961  averageDistance += bestDist;
962 
963  // Now we add the best hit not in the list to our list, keep track of the distance
964  // to the object it was closest to
965  const reco::ClusterHit3D* bestHit3D = *bestHit3DIter; // "best" hit already in the list
966  const reco::ClusterHit3D* nextHit3D =
967  hit3DToDistanceMap[bestHit3D].front().second; // "next" hit we are adding to the list
968 
969  Hit3DList::iterator nextHit3DIter = hit3DList.insert(hit3DList.end(), nextHit3D);
970 
971  distanceEdgePairList.emplace_back(bestDist, Hit3DEdgePair(bestHit3DIter, nextHit3DIter));
972 
974  }
975 
976  averageDistance /= float(hit3DList.size());
977 
978  float thirdDist = 2. * sqrt(clusterParameters.getSkeletonPCA().getEigenValues()[2]);
979 
980  // Ok, find the largest distance in the iterator map
981  distanceEdgePairList.sort(DistanceEdgePairOrder());
982 
983  DistanceEdgePairList::iterator largestDistIter = distanceEdgePairList.begin();
984 
985  for (DistanceEdgePairList::iterator edgeIter = distanceEdgePairList.begin();
986  edgeIter != distanceEdgePairList.end();
987  edgeIter++) {
988  if (edgeIter->first < thirdDist) break;
989 
990  largestDistIter = edgeIter;
991  }
992 
993  reco::HitPairListPtr::iterator breakIter = largestDistIter->second.second;
994  reco::HitPairListPtr bestList;
995 
996  bestList.resize(std::distance(hit3DList.begin(), breakIter));
997 
998  std::copy(hit3DList.begin(), breakIter, bestList.begin());
999 
1000  // Remove from the grand hit list and see what happens...
1001  // The pieces below are incomplete and were really for testing only.
1002  hitPairListPtr.sort();
1003  bestList.sort();
1004 
1005  reco::HitPairListPtr::iterator newListEnd = std::set_difference(hitPairListPtr.begin(),
1006  hitPairListPtr.end(),
1007  bestList.begin(),
1008  bestList.end(),
1009  hitPairListPtr.begin());
1010 
1011  hitPairListPtr.erase(newListEnd, hitPairListPtr.end());
1012  }
intermediate_table::iterator iterator
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:158
reco::PrincipalComponents & getSkeletonPCA()
Definition: Cluster3D.h:478
void clearStatusBits(unsigned bits) const
Definition: Cluster3D.h:181
SkeletonAlg m_skeletonAlg
Skeleton point finder.
intermediate_table::const_iterator const_iterator
reco::HitPairListPtr & getHitPairListPtr()
Definition: Cluster3D.h:476
void GetSkeletonHits(const reco::HitPairListPtr &inputHitList, reco::HitPairListPtr &skeletonHitList) const
Return the skeleton hits from the input list.
Hit has been used in Cluster Splitting MST.
Definition: Cluster3D.h:112
const EigenValues & getEigenValues() const
Definition: Cluster3D.h:246
void AverageSkeletonPositions(reco::HitPairListPtr &skeletonHitList) const
Modifies the position of input skeleton hits by averaging along the "best" wire direction.
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:335
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
bool bitsAreSet(const unsigned int &bitsToCheck) const
Definition: Cluster3D.h:177
T copy(T const &v)
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:180

Member Data Documentation

float lar_cluster3d::Cluster3D::m_artHitsTime
private

Keeps track of time to recover hits.

Definition at line 497 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_buildNeighborhoodTime
private

Keeps track of time to build epsilon neighborhood.

Definition at line 499 of file Cluster3D_module.cc.

std::unique_ptr<lar_cluster3d::IClusterAlg> lar_cluster3d::Cluster3D::m_clusterAlg
private

Algorithm to do 3D space point clustering.

Definition at line 512 of file Cluster3D_module.cc.

std::unique_ptr<lar_cluster3d::IClusterParametersBuilder> lar_cluster3d::Cluster3D::m_clusterBuilder
private

Common cluster builder tool.

Definition at line 518 of file Cluster3D_module.cc.

std::unique_ptr<lar_cluster3d::IClusterModAlg> lar_cluster3d::Cluster3D::m_clusterMergeAlg
private

Algorithm to do cluster merging.

Definition at line 514 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_clusterMergeTime
private

Keeps track of the time to merge clusters.

Definition at line 501 of file Cluster3D_module.cc.

std::unique_ptr<lar_cluster3d::IClusterModAlg> lar_cluster3d::Cluster3D::m_clusterPathAlg
private

Algorithm to do cluster path finding.

Definition at line 516 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_dbscanTime
private

Keeps track of time to run DBScan.

Definition at line 500 of file Cluster3D_module.cc.

bool lar_cluster3d::Cluster3D::m_enableMonitoring
private

Turn on monitoring of this algorithm.

Definition at line 484 of file Cluster3D_module.cc.

int lar_cluster3d::Cluster3D::m_event
private

Definition at line 493 of file Cluster3D_module.cc.

std::string lar_cluster3d::Cluster3D::m_extremeInstance
private

Instance name for the extreme points.

Definition at line 506 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_finishTime
private

Keeps track of time to run output module.

Definition at line 503 of file Cluster3D_module.cc.

std::unique_ptr<lar_cluster3d::IHit3DBuilder> lar_cluster3d::Cluster3D::m_hit3DBuilderAlg
private

Builds the 3D hits to operate on.

Definition at line 510 of file Cluster3D_module.cc.

int lar_cluster3d::Cluster3D::m_hits
private

Keeps track of the number of hits seen.

Definition at line 494 of file Cluster3D_module.cc.

int lar_cluster3d::Cluster3D::m_hits3D
private

Keeps track of the number of 3D hits made.

Definition at line 495 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_makeHitsTime
private

Keeps track of time to build 3D hits.

Definition at line 498 of file Cluster3D_module.cc.

bool lar_cluster3d::Cluster3D::m_onlyMakSpacePoints
private

If true we don't do the full cluster 3D processing.

Algorithm parameters

Definition at line 483 of file Cluster3D_module.cc.

ParallelHitsSeedFinderAlg lar_cluster3d::Cluster3D::m_parallelHitsAlg
private

Deal with parallel hits clusters.

Definition at line 523 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_parallelHitsCosAng
private

Cut for PCA 3rd axis angle to X axis.

Definition at line 485 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_parallelHitsTransWid
private

Cut on transverse width of cluster (PCA 2nd eigenvalue)

Definition at line 486 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_pathFindingTime
private

Keeps track of the path finding time.

Definition at line 502 of file Cluster3D_module.cc.

std::string lar_cluster3d::Cluster3D::m_pathInstance
private

Special instance for path points.

Definition at line 504 of file Cluster3D_module.cc.

PrincipalComponentsAlg lar_cluster3d::Cluster3D::m_pcaAlg
private

Principal Components algorithm.

Definition at line 519 of file Cluster3D_module.cc.

PCASeedFinderAlg lar_cluster3d::Cluster3D::m_pcaSeedFinderAlg
private

Use PCA axis to find seeds.

Definition at line 522 of file Cluster3D_module.cc.

TTree* lar_cluster3d::Cluster3D::m_pRecoTree
private

Tree variables for output

Definition at line 491 of file Cluster3D_module.cc.

int lar_cluster3d::Cluster3D::m_run
private

Definition at line 492 of file Cluster3D_module.cc.

HoughSeedFinderAlg lar_cluster3d::Cluster3D::m_seedFinderAlg
private

Seed finder.

Definition at line 521 of file Cluster3D_module.cc.

SkeletonAlg lar_cluster3d::Cluster3D::m_skeletonAlg
private

Skeleton point finder.

Definition at line 520 of file Cluster3D_module.cc.

float lar_cluster3d::Cluster3D::m_totalTime
private

Keeps track of total execution time.

Definition at line 496 of file Cluster3D_module.cc.

std::string lar_cluster3d::Cluster3D::m_vertexInstance
private

Special instance name for vertex points.

Definition at line 505 of file Cluster3D_module.cc.


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