LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
ClusterMergingAlgorithm.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 StatusCode ClusterMergingAlgorithm::Run()
21 {
22  const ClusterList *pClusterList = NULL;
23 
24  if (m_inputClusterListName.empty())
25  {
26  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
27  }
28  else
29  {
30  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_inputClusterListName, pClusterList));
31  }
32 
33  if (!pClusterList || pClusterList->empty())
34  {
35  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
36  std::cout << "ClusterMergingAlgorithm: unable to find cluster list " << m_inputClusterListName << std::endl;
37 
38  return STATUS_CODE_SUCCESS;
39  }
40 
41  while (true)
42  {
43  ClusterVector unsortedVector, clusterVector;
44  this->GetListOfCleanClusters(pClusterList, unsortedVector);
45  this->GetSortedListOfCleanClusters(unsortedVector, clusterVector);
46 
47  ClusterMergeMap clusterMergeMap;
48  this->PopulateClusterMergeMap(clusterVector, clusterMergeMap);
49 
50  if (clusterMergeMap.empty())
51  break;
52 
53  this->MergeClusters(clusterVector, clusterMergeMap);
54  }
55 
56  return STATUS_CODE_SUCCESS;
57 }
58 
59 //------------------------------------------------------------------------------------------------------------------------------------------
60 
61 void ClusterMergingAlgorithm::MergeClusters(ClusterVector &clusterVector, ClusterMergeMap &clusterMergeMap) const
62 {
63  ClusterSet clusterVetoList;
64 
65  for (const Cluster *const pSeedCluster : clusterVector)
66  {
67  ClusterList mergeList;
68  this->CollectAssociatedClusters(pSeedCluster, pSeedCluster, clusterMergeMap, clusterVetoList, mergeList);
69  mergeList.sort(LArClusterHelper::SortByNHits);
70 
71  for (const Cluster *const pAssociatedCluster : mergeList)
72  {
73  if (clusterVetoList.count(pAssociatedCluster))
74  throw StatusCodeException(STATUS_CODE_FAILURE);
75 
76  if (!pAssociatedCluster->IsAvailable())
77  throw StatusCodeException(STATUS_CODE_FAILURE);
78 
79  (void) clusterVetoList.insert(pAssociatedCluster);
80 
81  if (m_inputClusterListName.empty())
82  {
83  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pSeedCluster, pAssociatedCluster));
84  }
85  else
86  {
87  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pSeedCluster, pAssociatedCluster,
88  m_inputClusterListName, m_inputClusterListName));
89  }
90  }
91  }
92 }
93 
94 //------------------------------------------------------------------------------------------------------------------------------------------
95 
96 void ClusterMergingAlgorithm::CollectAssociatedClusters(const Cluster *const pSeedCluster, const ClusterMergeMap &clusterMergeMap, ClusterList& associatedClusterList) const
97 {
98  ClusterSet clusterVetoList;
99  this->CollectAssociatedClusters(pSeedCluster, pSeedCluster, clusterMergeMap, clusterVetoList, associatedClusterList);
100 }
101 
102 //------------------------------------------------------------------------------------------------------------------------------------------
103 
104 void ClusterMergingAlgorithm::CollectAssociatedClusters(const Cluster *const pSeedCluster, const Cluster *const pCurrentCluster, const ClusterMergeMap &clusterMergeMap,
105  const ClusterSet &clusterVetoList, ClusterList &associatedClusterList) const
106 {
107  if (clusterVetoList.count(pCurrentCluster))
108  return;
109 
110  ClusterMergeMap::const_iterator iter1 = clusterMergeMap.find(pCurrentCluster);
111 
112  if (iter1 == clusterMergeMap.end())
113  return;
114 
115  ClusterVector associatedClusters(iter1->second.begin(), iter1->second.end());
116  std::sort(associatedClusters.begin(), associatedClusters.end(), LArClusterHelper::SortByNHits);
117 
118  for (const Cluster *const pAssociatedCluster : associatedClusters)
119  {
120  if (pAssociatedCluster == pSeedCluster)
121  continue;
122 
123  if (associatedClusterList.end() != std::find(associatedClusterList.begin(), associatedClusterList.end(), pAssociatedCluster))
124  continue;
125 
126  associatedClusterList.push_back(pAssociatedCluster);
127  this->CollectAssociatedClusters(pSeedCluster, pAssociatedCluster, clusterMergeMap, clusterVetoList, associatedClusterList);
128  }
129 }
130 
131 //------------------------------------------------------------------------------------------------------------------------------------------
132 
133 void ClusterMergingAlgorithm::GetSortedListOfCleanClusters(const ClusterVector &inputClusters, ClusterVector &outputClusters) const
134 {
135  ClusterVector pfoClusters, availableClusters;
136 
137  for (ClusterVector::const_iterator iter = inputClusters.begin(), iterEnd = inputClusters.end(); iter != iterEnd; ++iter)
138  {
139  const Cluster *const pCluster = *iter;
140 
141  if (!pCluster->IsAvailable())
142  {
143  pfoClusters.push_back(pCluster);
144  }
145  else
146  {
147  availableClusters.push_back(pCluster);
148  }
149  }
150 
151  std::sort(pfoClusters.begin(), pfoClusters.end(), LArClusterHelper::SortByNHits);
152  std::sort(availableClusters.begin(), availableClusters.end(), LArClusterHelper::SortByNHits);
153 
154  outputClusters.insert(outputClusters.end(), pfoClusters.begin(), pfoClusters.end());
155  outputClusters.insert(outputClusters.end(), availableClusters.begin(), availableClusters.end());
156 }
157 
158 //------------------------------------------------------------------------------------------------------------------------------------------
159 
160 StatusCode ClusterMergingAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
161 {
162  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
163  "InputClusterListName", m_inputClusterListName));
164 
165  return STATUS_CODE_SUCCESS;
166 }
167 
168 } // namespace lar_content
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
Header file for the cluster merging algorithm class.