LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
BoundedRegionClusterMergingAlgorithm.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 BoundedRegionClusterMergingAlgorithm::BoundedRegionClusterMergingAlgorithm() :
21  m_xRegionMin(-100.f),
22  m_xRegionMax(0.f),
23  m_zRegionMin(235.f),
24  m_zRegionMax(400.f),
25  m_maxDistance(10.f),
26  m_minClusterHits(2)
27 {
28 }
29 
31 {
32  const ClusterList *pClusterList{nullptr};
33 
34  if (m_inputClusterListName.empty())
35  {
36  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
37  }
38  else
39  {
40  PANDORA_RETURN_RESULT_IF_AND_IF(
41  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_inputClusterListName, pClusterList));
42  }
43 
44  if (!pClusterList || pClusterList->empty())
45  {
46  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
47  std::cout << "BoundedRegionClusterMergingAlgorithm: unable to find cluster list " << m_inputClusterListName << std::endl;
48 
49  return STATUS_CODE_SUCCESS;
50  }
51 
52  while (true)
53  {
54  ClusterVector clusterVector;
55  ClusterMergeMap clusterMergeMap;
56  this->GetListOfBoundedRegionClusters(pClusterList, clusterVector);
57  if (clusterVector.size() < 2)
58  break;
59 
60  this->PopulateClusterMergeMap(clusterVector, clusterMergeMap);
61  if (clusterMergeMap.empty())
62  break;
63 
64  this->MergeClusters(clusterVector, clusterMergeMap);
65  }
66 
67  return STATUS_CODE_SUCCESS;
68 }
69 
70 //------------------------------------------------------------------------------------------------------------------------------------------
71 
73  const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
74 {
75  for (const Cluster *const pCluster : *pClusterList)
76  {
77  if (!pCluster->IsAvailable())
78  continue;
79 
80  if (pCluster->GetNCaloHits() < m_minClusterHits)
81  continue;
82 
83  CartesianVector minimumPos(0.f, 0.f, 0.f), maximumPos(0.f, 0.f, 0.f);
84  LArClusterHelper::GetClusterBoundingBox(pCluster, minimumPos, maximumPos);
85  (void)maximumPos; // To get rid of an unused variable warning
86 
87  if (minimumPos.GetX() > m_xRegionMin && minimumPos.GetX() < m_xRegionMax && minimumPos.GetZ() > m_zRegionMin && minimumPos.GetZ() < m_zRegionMax)
88  clusterVector.emplace_back(pCluster);
89  }
90 
91  if (!clusterVector.empty())
92  std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
93 }
94 
95 //------------------------------------------------------------------------------------------------------------------------------------------
96 
98 {
99  ClusterVector usedClusters;
100 
101  for (unsigned int i = 0; i < clusterVector.size() - 1; ++i)
102  {
103  const Cluster *const pCluster1{clusterVector.at(i)};
104 
105  for (unsigned int j = i + 1; j < clusterVector.size(); ++j)
106  {
107  const Cluster *const pCluster2{clusterVector.at(j)};
108  if (!pCluster2->IsAvailable())
109  continue;
110 
111  if (std::find(usedClusters.begin(), usedClusters.end(), pCluster2) != usedClusters.end())
112  continue;
113 
114  if (this->AreClustersAssociated(pCluster1, pCluster2))
115  {
116  clusterMergeMap[pCluster1].emplace_back(pCluster2);
117  usedClusters.emplace_back(pCluster2);
118  }
119  }
120  }
121 }
122 
123 //------------------------------------------------------------------------------------------------------------------------------------------
124 
125 bool BoundedRegionClusterMergingAlgorithm::AreClustersAssociated(const Cluster *const pCluster1, const Cluster *const pCluster2) const
126 {
127  const float distance{LArClusterHelper::GetClosestDistance(pCluster1, pCluster2)};
128  return distance < m_maxDistance;
129 }
130 
131 //------------------------------------------------------------------------------------------------------------------------------------------
132 
133 void BoundedRegionClusterMergingAlgorithm::GetListOfCleanClusters(const ClusterList *const /*pClusterList*/, pandora::ClusterVector & /*clusterVector*/) const
134 {
135 }
136 
137 //------------------------------------------------------------------------------------------------------------------------------------------
138 
139 StatusCode BoundedRegionClusterMergingAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
140 {
141  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinimumX", m_xRegionMin));
142  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaximumX", m_xRegionMax));
143  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinimumZ", m_zRegionMin));
144  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaximumZ", m_zRegionMax));
145 
146  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxDistance", m_maxDistance));
147 
148  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterHits", m_minClusterHits));
149  return ClusterMergingAlgorithm::ReadSettings(xmlHandle);
150 }
151 
152 } // namespace lar_content
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position, then pulse-height.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
std::string m_inputClusterListName
The name of the input cluster list. If not specified, will access current list.
void GetListOfBoundedRegionClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with all clusters starting in the defined region.
void PopulateClusterMergeMap(const pandora::ClusterVector &clusterVector, ClusterMergeMap &clusterMergeMap) const
Form associations between pointing clusters.
TFile f
Definition: plotHisto.C:6
static void GetClusterBoundingBox(const pandora::Cluster *const pCluster, pandora::CartesianVector &minimumCoordinate, pandora::CartesianVector &maximumCoordinate)
Get minimum and maximum X, Y and Z positions of the calo hits in a cluster.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the cluster helper class.
float m_maxDistance
Maximum distance below which clusters can be associated.
float m_xRegionMin
Minimum x value of the bounded region box.
float m_zRegionMax
Maximum z value (wire dimension) of the bounded region box.
float m_xRegionMax
Maximum x value of the bounded region box.
unsigned int m_minClusterHits
Threshold on the size of clusters to be considered for merging.
void MergeClusters(pandora::ClusterVector &clusterVector, ClusterMergeMap &clusterMergeMap) const
Merge associated clusters.
void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with subset of cluster list, containing clusters judged to be clean...
float m_zRegionMin
Minimum z value (wire dimension) of the bounded region box.
bool AreClustersAssociated(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2) const
Compare two clusters and decide if they should be associated with each other.
Header file for the bounded region cluster merging algorithm class.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
virtual 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.