LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ConnectedRemnantsTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 ConnectedRemnantsTool::ConnectedRemnantsTool() :
21  m_maxClusterSeparation(10.f)
22 {
23 }
24 
25 //------------------------------------------------------------------------------------------------------------------------------------------
26 
27 bool ConnectedRemnantsTool::Run(ThreeViewRemnantsAlgorithm *const pAlgorithm, TensorType &overlapTensor)
28 {
29  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
30  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
31 
32  ProtoParticleVector protoParticleVector;
33  ClusterMergeMap clusterMergeMap;
34  this->FindConnectedShowers(overlapTensor, protoParticleVector, clusterMergeMap);
35 
36  const bool particlesMade(pAlgorithm->CreateThreeDParticles(protoParticleVector));
37  const bool mergesMade(pAlgorithm->MakeClusterMerges(clusterMergeMap));
38 
39  return (particlesMade || mergesMade);
40 }
41 
42 //------------------------------------------------------------------------------------------------------------------------------------------
43 
45  const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector, ClusterMergeMap &clusterMergeMap) const
46 {
47  ClusterSet usedClusters;
48  ClusterVector sortedKeyClusters;
49  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
50 
51  for (const Cluster *const pKeyCluster : sortedKeyClusters)
52  {
53  if (!pKeyCluster->IsAvailable())
54  continue;
55 
56  TensorType::ElementList connectedElements;
57  overlapTensor.GetConnectedElements(pKeyCluster, true, connectedElements);
58 
59  ClusterVector clusterVectorU, clusterVectorV, clusterVectorW;
60  this->GetClusters(connectedElements, usedClusters, clusterVectorU, clusterVectorV, clusterVectorW);
61 
62  if (clusterVectorU.empty() || clusterVectorV.empty() || clusterVectorW.empty())
63  continue;
64 
65  usedClusters.insert(clusterVectorU.begin(), clusterVectorU.end());
66  usedClusters.insert(clusterVectorV.begin(), clusterVectorV.end());
67  usedClusters.insert(clusterVectorW.begin(), clusterVectorW.end());
68 
69  if (!(this->IsConnected(clusterVectorU) && this->IsConnected(clusterVectorV) && this->IsConnected(clusterVectorW)))
70  continue;
71 
72  const Cluster *const pClusterU = clusterVectorU.front();
73  const Cluster *const pClusterV = clusterVectorV.front();
74  const Cluster *const pClusterW = clusterVectorW.front();
75 
76  ProtoParticle protoParticle;
77  protoParticle.m_clusterList.push_back(pClusterU);
78  protoParticle.m_clusterList.push_back(pClusterV);
79  protoParticle.m_clusterList.push_back(pClusterW);
80  protoParticleVector.push_back(protoParticle);
81 
82  this->FillMergeMap(pClusterU, clusterVectorU, clusterMergeMap);
83  this->FillMergeMap(pClusterV, clusterVectorV, clusterMergeMap);
84  this->FillMergeMap(pClusterW, clusterVectorW, clusterMergeMap);
85  }
86 }
87 
88 //------------------------------------------------------------------------------------------------------------------------------------------
89 
90 void ConnectedRemnantsTool::GetClusters(const TensorType::ElementList &elementList, const ClusterSet &usedClusters,
91  ClusterVector &clusterVectorU, ClusterVector &clusterVectorV, ClusterVector &clusterVectorW) const
92 {
93  for (const TensorType::Element &element : elementList)
94  {
95  if (usedClusters.count(element.GetClusterU()) || usedClusters.count(element.GetClusterV()) || usedClusters.count(element.GetClusterW()))
96  continue;
97 
98  clusterVectorU.push_back(element.GetClusterU());
99  clusterVectorV.push_back(element.GetClusterV());
100  clusterVectorW.push_back(element.GetClusterW());
101  }
102 }
103 
104 //------------------------------------------------------------------------------------------------------------------------------------------
105 
106 void ConnectedRemnantsTool::FillMergeMap(const Cluster *const pFirstCluster, const ClusterVector &clusterVector, ClusterMergeMap &clusterMergeMap) const
107 {
108  if (clusterVector.empty())
109  throw StatusCodeException(STATUS_CODE_FAILURE);
110 
111  for (const Cluster *const pSecondCluster : clusterVector)
112  {
113  if (pFirstCluster == pSecondCluster)
114  continue;
115 
116  ClusterList &clusterList(clusterMergeMap[pFirstCluster]);
117 
118  if (clusterList.end() == std::find(clusterList.begin(), clusterList.end(), pSecondCluster))
119  clusterList.push_back(pSecondCluster);
120  }
121 }
122 
123 //------------------------------------------------------------------------------------------------------------------------------------------
124 
125 bool ConnectedRemnantsTool::IsConnected(const ClusterVector &clusterVector) const
126 {
127  for (const Cluster *const pCluster1 : clusterVector)
128  {
129  for (const Cluster *const pCluster2 : clusterVector)
130  {
131  if (pCluster1 == pCluster2)
132  continue;
133 
135  return false;
136  }
137  }
138 
139  return true;
140 }
141 
142 //------------------------------------------------------------------------------------------------------------------------------------------
143 
144 StatusCode ConnectedRemnantsTool::ReadSettings(const TiXmlHandle xmlHandle)
145 {
146  PANDORA_RETURN_RESULT_IF_AND_IF(
147  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxClusterSeparation", m_maxClusterSeparation));
148 
149  return STATUS_CODE_SUCCESS;
150 }
151 
152 } // namespace lar_content
std::vector< ProtoParticle > ProtoParticleVector
void FindConnectedShowers(const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector, ClusterMergeMap &clusterMergeMap) const
Identify candidate particles.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
TFile f
Definition: plotHisto.C:6
void FillMergeMap(const pandora::Cluster *const pCluster, const pandora::ClusterVector &clusterVector, ClusterMergeMap &clusterMergeMap) const
Fill map of clusters to be merged.
std::vector< Element > ElementList
Header file for the cluster helper class.
pandora::ClusterList m_clusterList
List of 2D clusters in a 3D proto particle.
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
void GetClusters(const TensorType::ElementList &connectedElements, const pandora::ClusterSet &usedClusters, pandora::ClusterVector &clusterVectorU, pandora::ClusterVector &clusterVectorV, pandora::ClusterVector &clusterVectorW) const
Separate connected clusters into cluster lists by view.
bool IsConnected(const pandora::ClusterVector &clusterVector) const
Check whether all clusters in a list are spatially connected.
bool Run(ThreeViewRemnantsAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
Header file for the connected remnants tool class.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.