Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ClusterGrowingAlgorithm.cc
Go to the documentation of this file.
1
10
12
14
15using namespace pandora;
16
17namespace lar_content
18{
19
21{
22}
23
24//------------------------------------------------------------------------------------------------------------------------------------------
25
27{
28 const ClusterList *pClusterList = NULL;
29
30 if (m_inputClusterListName.empty())
31 {
32 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
33 }
34 else
35 {
37 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_inputClusterListName, pClusterList));
38 }
39
40 if (!pClusterList || pClusterList->empty())
41 {
43 std::cout << "ClusterGrowingAlgorithm: unable to find cluster list " << m_inputClusterListName << std::endl;
44
45 return STATUS_CODE_SUCCESS;
46 }
47
48 ClusterVector inputClusters, seedClusters;
49 this->GetListOfCleanClusters(pClusterList, inputClusters);
50 this->GetListOfSeedClusters(inputClusters, seedClusters);
51
52 while (true)
53 {
54 ClusterVector currentClusters, nonSeedClusters;
55 this->GetListOfCleanClusters(pClusterList, currentClusters);
56 this->GetListOfNonSeedClusters(currentClusters, seedClusters, nonSeedClusters);
57
58 ClusterMergeMap clusterMergeMap;
59 this->PopulateClusterMergeMap(seedClusters, nonSeedClusters, clusterMergeMap);
60
61 if (clusterMergeMap.empty())
62 break;
63
64 this->MergeClusters(clusterMergeMap);
65 }
66
67 return STATUS_CODE_SUCCESS;
68}
69
70//------------------------------------------------------------------------------------------------------------------------------------------
71
73 const ClusterVector &inputClusters, const ClusterVector &seedClusters, ClusterVector &nonSeedClusters) const
74{
75 for (ClusterVector::const_iterator iter = inputClusters.begin(), iterEnd = inputClusters.end(); iter != iterEnd; ++iter)
76 {
77 const Cluster *const pCluster = *iter;
78
79 if (seedClusters.end() != std::find(seedClusters.begin(), seedClusters.end(), pCluster))
80 continue;
81
82 nonSeedClusters.push_back(pCluster);
83 }
84
85 std::sort(nonSeedClusters.begin(), nonSeedClusters.end(), LArClusterHelper::SortByNHits);
86}
87
88//------------------------------------------------------------------------------------------------------------------------------------------
89
91 const ClusterVector &seedClusters, const ClusterVector &nonSeedClusters, ClusterMergeMap &clusterMergeMap) const
92{
93 for (ClusterVector::const_iterator nIter = nonSeedClusters.begin(), nIterEnd = nonSeedClusters.end(); nIter != nIterEnd; ++nIter)
94 {
95 const Cluster *const pNonSeedCluster = *nIter;
96
97 const Cluster *pBestSeedCluster(NULL);
98 float bestDistance(m_maxClusterSeparation);
99
100 for (ClusterVector::const_iterator sIter = seedClusters.begin(), sIterEnd = seedClusters.end(); sIter != sIterEnd; ++sIter)
101 {
102 const Cluster *const pThisSeedCluster = *sIter;
103 const float thisDistance(LArClusterHelper::GetClosestDistance(pNonSeedCluster, pThisSeedCluster));
104
105 if (thisDistance < bestDistance)
106 {
107 pBestSeedCluster = pThisSeedCluster;
108 bestDistance = thisDistance;
109 }
110 }
111
112 if (pBestSeedCluster)
113 clusterMergeMap[pBestSeedCluster].push_back(pNonSeedCluster);
114 }
115}
116
117//------------------------------------------------------------------------------------------------------------------------------------------
118
120{
121 ClusterList parentClusterList;
122 for (const auto &mapEntry : clusterMergeMap)
123 parentClusterList.push_back(mapEntry.first);
124 parentClusterList.sort(LArClusterHelper::SortByNHits);
125
126 for (const Cluster *const pParentCluster : parentClusterList)
127 {
128 const ClusterList &clusterList(clusterMergeMap.at(pParentCluster));
129
130 if (clusterList.empty())
131 throw StatusCodeException(STATUS_CODE_FAILURE);
132
133 for (const Cluster *const pAssociatedCluster : clusterList)
134 {
135 if (m_inputClusterListName.empty())
136 {
137 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pParentCluster, pAssociatedCluster));
138 }
139 else
140 {
141 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
143 }
144 }
145 }
146}
147
148//------------------------------------------------------------------------------------------------------------------------------------------
149
151{
153 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "InputClusterListName", m_inputClusterListName));
154
156 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxClusterSeparation", m_maxClusterSeparation));
157
158 return STATUS_CODE_SUCCESS;
159}
160
161} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the cluster growing algorithm class.
Header file for the cluster helper class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
static pandora::StatusCode GetCurrentList(const pandora::Algorithm &algorithm, const T *&pT)
Get the current list.
static pandora::StatusCode MergeAndDeleteClusters(const pandora::Algorithm &algorithm, const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete)
Merge two clusters in the current list, enlarging one cluster and deleting the second.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
std::string m_inputClusterListName
The name of the input cluster list. If not specified, will access current list.
virtual void GetListOfSeedClusters(const pandora::ClusterVector &cleanClusters, pandora::ClusterVector &seedClusters) const =0
Select seed clusters for growing.
void PopulateClusterMergeMap(const pandora::ClusterVector &seedClusters, const pandora::ClusterVector &nonSeedClusters, ClusterMergeMap &clusterMergeMap) const
Identify a set of cluster merges.
void MergeClusters(const ClusterMergeMap &clusterMergeMap) const
Merge clusters.
virtual void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &cleanClusters) const =0
Populate cluster vector with the subset of clusters judged to be clean.
virtual pandora::StatusCode Run()
Run the algorithm.
void GetListOfNonSeedClusters(const pandora::ClusterVector &inputClusters, const pandora::ClusterVector &seedClusters, pandora::ClusterVector &nonSeedClusters) const
Get List of non-seed clusters.
float m_maxClusterSeparation
Maximum distance at which clusters can be joined.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
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,...
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
Cluster class.
Definition Cluster.h:31
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
StatusCodeException class.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
StatusCode
The StatusCode enum.