LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
lar_content::ClusterAssociationAlgorithm Class Referenceabstract

ClusterAssociationAlgorithm class. More...

#include "ClusterAssociationAlgorithm.h"

Inheritance diagram for lar_content::ClusterAssociationAlgorithm:
lar_content::CrossGapsAssociationAlgorithm lar_content::HitWidthClusterMergingAlgorithm lar_content::LongitudinalAssociationAlgorithm lar_content::TransverseAssociationAlgorithm

Classes

class  ClusterAssociation
 ClusterAssociation class. More...
 

Public Member Functions

 ClusterAssociationAlgorithm ()
 Default constructor. More...
 

Protected Types

typedef std::unordered_map< const pandora::Cluster *, ClusterAssociationClusterAssociationMap
 

Protected Member Functions

virtual pandora::StatusCode Run ()
 
virtual pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
virtual void GetListOfCleanClusters (const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const =0
 Populate cluster vector with subset of cluster list, containing clusters judged to be clean. More...
 
virtual void PopulateClusterAssociationMap (const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const =0
 Populate the cluster association map. More...
 
virtual bool IsExtremalCluster (const bool isForward, const pandora::Cluster *const pCurrentCluster, const pandora::Cluster *const pTestCluster) const =0
 Determine which of two clusters is extremal. More...
 

Private Member Functions

void UnambiguousPropagation (const pandora::Cluster *const pCluster, const bool isForward, ClusterAssociationMap &clusterAssociationMap) const
 Unambiguous propagation. More...
 
void AmbiguousPropagation (const pandora::Cluster *const pCluster, const bool isForward, ClusterAssociationMap &clusterAssociationMap) const
 Ambiguous propagation. More...
 
void UpdateForUnambiguousMerge (const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete, const bool isForwardMerge, ClusterAssociationMap &clusterAssociationMap) const
 Update cluster association map to reflect an unambiguous cluster merge. More...
 
void UpdateForAmbiguousMerge (const pandora::Cluster *const pCluster, ClusterAssociationMap &clusterAssociationMap) const
 Update cluster association map to reflect an ambiguous cluster merge. More...
 
void NavigateAlongAssociations (const ClusterAssociationMap &clusterAssociationMap, const pandora::Cluster *const pCluster, const bool isForward, const pandora::Cluster *&pExtremalCluster, pandora::ClusterSet &clusterSet) const
 Navigate along cluster associations, from specified cluster, in specified direction. More...
 

Private Attributes

bool m_mergeMade
 
bool m_resolveAmbiguousAssociations
 Whether to resolve ambiguous associations. More...
 

Detailed Description

Member Typedef Documentation

typedef std::unordered_map<const pandora::Cluster *, ClusterAssociation> lar_content::ClusterAssociationAlgorithm::ClusterAssociationMap
protected

Definition at line 43 of file ClusterAssociationAlgorithm.h.

Constructor & Destructor Documentation

lar_content::ClusterAssociationAlgorithm::ClusterAssociationAlgorithm ( )

Default constructor.

Definition at line 20 of file ClusterAssociationAlgorithm.cc.

20  :
21  m_mergeMade(false),
23 {
24 }
bool m_resolveAmbiguousAssociations
Whether to resolve ambiguous associations.

Member Function Documentation

void lar_content::ClusterAssociationAlgorithm::AmbiguousPropagation ( const pandora::Cluster *const  pCluster,
const bool  isForward,
ClusterAssociationMap clusterAssociationMap 
) const
private

Ambiguous propagation.

Parameters
pClusteraddress of the cluster to propagate
isForwardwhether propagation direction is forward
clusterAssociationMapthe cluster association map

Definition at line 123 of file ClusterAssociationAlgorithm.cc.

References m_mergeMade, NavigateAlongAssociations(), lar_content::LArClusterHelper::SortByNHits(), and UpdateForAmbiguousMerge().

Referenced by Run().

124 {
125  ClusterAssociationMap::iterator cIter = clusterAssociationMap.find(pCluster);
126 
127  if (clusterAssociationMap.end() == cIter)
128  throw StatusCodeException(STATUS_CODE_FAILURE);
129 
130  const Cluster *pExtremalCluster = pCluster;
131 
132  ClusterSet firstClusterSet;
133  this->NavigateAlongAssociations(clusterAssociationMap, pCluster, isForward, pExtremalCluster, firstClusterSet);
134 
135  ClusterSet secondClusterSet;
136  this->NavigateAlongAssociations(clusterAssociationMap, pExtremalCluster, !isForward, pExtremalCluster, secondClusterSet);
137 
138  ClusterVector daughterClusterVector;
139 
140  if (pCluster == pExtremalCluster)
141  {
142  for (const Cluster *const pFirstCluster : firstClusterSet)
143  {
144  if ((pCluster != pFirstCluster) && (secondClusterSet.count(pFirstCluster)) &&
145  (daughterClusterVector.end() == std::find(daughterClusterVector.begin(), daughterClusterVector.end(), pFirstCluster)))
146  {
147  daughterClusterVector.push_back(pFirstCluster);
148  }
149  }
150  }
151 
152  std::sort(daughterClusterVector.begin(), daughterClusterVector.end(), LArClusterHelper::SortByNHits);
153 
154  for (ClusterVector::iterator dIter = daughterClusterVector.begin(), dIterEnd = daughterClusterVector.end(); dIter != dIterEnd; ++dIter)
155  {
156  this->UpdateForAmbiguousMerge(*dIter, clusterAssociationMap);
157 
158  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pCluster, *dIter));
159  m_mergeMade = true;
160  *dIter = NULL;
161  }
162 
163  this->UpdateForAmbiguousMerge(pCluster, clusterAssociationMap);
164 }
intermediate_table::iterator iterator
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.
void NavigateAlongAssociations(const ClusterAssociationMap &clusterAssociationMap, const pandora::Cluster *const pCluster, const bool isForward, const pandora::Cluster *&pExtremalCluster, pandora::ClusterSet &clusterSet) const
Navigate along cluster associations, from specified cluster, in specified direction.
void UpdateForAmbiguousMerge(const pandora::Cluster *const pCluster, ClusterAssociationMap &clusterAssociationMap) const
Update cluster association map to reflect an ambiguous cluster merge.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
virtual void lar_content::ClusterAssociationAlgorithm::GetListOfCleanClusters ( const pandora::ClusterList *const  pClusterList,
pandora::ClusterVector &  clusterVector 
) const
protectedpure virtual

Populate cluster vector with subset of cluster list, containing clusters judged to be clean.

Parameters
pClusterListaddress of the cluster list
clusterVectorto receive the populated cluster vector

Implemented in lar_content::TransverseAssociationAlgorithm, lar_content::LongitudinalAssociationAlgorithm, lar_content::CrossGapsAssociationAlgorithm, and lar_content::HitWidthClusterMergingAlgorithm.

Referenced by Run().

virtual bool lar_content::ClusterAssociationAlgorithm::IsExtremalCluster ( const bool  isForward,
const pandora::Cluster *const  pCurrentCluster,
const pandora::Cluster *const  pTestCluster 
) const
protectedpure virtual

Determine which of two clusters is extremal.

Parameters
isForwardwhether propagation direction is forward
pCurrentClustercurrent extremal cluster
pTestClusterpotential extremal cluster
Returns
boolean

Implemented in lar_content::TransverseAssociationAlgorithm, lar_content::LongitudinalAssociationAlgorithm, lar_content::CrossGapsAssociationAlgorithm, and lar_content::HitWidthClusterMergingAlgorithm.

Referenced by NavigateAlongAssociations().

void lar_content::ClusterAssociationAlgorithm::NavigateAlongAssociations ( const ClusterAssociationMap clusterAssociationMap,
const pandora::Cluster *const  pCluster,
const bool  isForward,
const pandora::Cluster *&  pExtremalCluster,
pandora::ClusterSet &  clusterSet 
) const
private

Navigate along cluster associations, from specified cluster, in specified direction.

Parameters
clusterAssociationMapthe cluster association map
pClusteraddress of cluster with which to begin search
isForwardwhether propagation direction is forward
pExtremalClusterto receive the extremal cluster
clusterSetto receive set of clusters traversed

Definition at line 233 of file ClusterAssociationAlgorithm.cc.

References IsExtremalCluster().

Referenced by AmbiguousPropagation().

235 {
236  ClusterAssociationMap::const_iterator iterAssociation = clusterAssociationMap.find(pCluster);
237 
238  if (clusterAssociationMap.end() == iterAssociation)
239  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
240 
241  (void)clusterSet.insert(pCluster);
242 
243  if ((pCluster != pExtremalCluster) && this->IsExtremalCluster(isForward, pExtremalCluster, pCluster))
244  pExtremalCluster = pCluster;
245 
246  const ClusterSet &associatedClusterSet(isForward ? iterAssociation->second.m_forwardAssociations : iterAssociation->second.m_backwardAssociations);
247 
248  for (ClusterSet::const_iterator iter = associatedClusterSet.begin(), iterEnd = associatedClusterSet.end(); iter != iterEnd; ++iter)
249  {
250  this->NavigateAlongAssociations(clusterAssociationMap, *iter, isForward, pExtremalCluster, clusterSet);
251  }
252 }
intermediate_table::const_iterator const_iterator
void NavigateAlongAssociations(const ClusterAssociationMap &clusterAssociationMap, const pandora::Cluster *const pCluster, const bool isForward, const pandora::Cluster *&pExtremalCluster, pandora::ClusterSet &clusterSet) const
Navigate along cluster associations, from specified cluster, in specified direction.
virtual bool IsExtremalCluster(const bool isForward, const pandora::Cluster *const pCurrentCluster, const pandora::Cluster *const pTestCluster) const =0
Determine which of two clusters is extremal.
virtual void lar_content::ClusterAssociationAlgorithm::PopulateClusterAssociationMap ( const pandora::ClusterVector &  clusterVector,
ClusterAssociationMap clusterAssociationMap 
) const
protectedpure virtual

Populate the cluster association map.

Parameters
clusterVectorthe cluster vector
clusterAssociationMapto receive the populated cluster association map

Implemented in lar_content::TransverseAssociationAlgorithm, lar_content::LongitudinalAssociationAlgorithm, lar_content::CrossGapsAssociationAlgorithm, and lar_content::HitWidthClusterMergingAlgorithm.

Referenced by Run().

StatusCode lar_content::ClusterAssociationAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
protectedvirtual
StatusCode lar_content::ClusterAssociationAlgorithm::Run ( )
protectedvirtual

Definition at line 28 of file ClusterAssociationAlgorithm.cc.

References AmbiguousPropagation(), GetListOfCleanClusters(), m_mergeMade, m_resolveAmbiguousAssociations, PopulateClusterAssociationMap(), and UnambiguousPropagation().

29 {
30  const ClusterList *pClusterList = NULL;
31  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
32 
33  ClusterVector clusterVector;
34  this->GetListOfCleanClusters(pClusterList, clusterVector);
35 
36  ClusterAssociationMap clusterAssociationMap;
37  this->PopulateClusterAssociationMap(clusterVector, clusterAssociationMap);
38 
39  m_mergeMade = true;
40 
41  while (m_mergeMade)
42  {
43  // Unambiguous propagation
44  while (m_mergeMade)
45  {
46  m_mergeMade = false;
47 
48  for (const Cluster *const pCluster : clusterVector)
49  {
50  // ATTN The clusterVector may end up with dangling pointers; only protected by this check against managed cluster list
51  if (pClusterList->end() == std::find(pClusterList->begin(), pClusterList->end(), pCluster))
52  continue;
53 
54  this->UnambiguousPropagation(pCluster, true, clusterAssociationMap);
55  this->UnambiguousPropagation(pCluster, false, clusterAssociationMap);
56  }
57  }
58 
60  continue;
61 
62  // Propagation with ambiguities
63  for (const Cluster *const pCluster : clusterVector)
64  {
65  // ATTN The clusterVector may end up with dangling pointers; only protected by this check against up-to-date association list
66  ClusterAssociationMap::const_iterator mapIterFwd = clusterAssociationMap.find(pCluster);
67 
68  if (clusterAssociationMap.end() == mapIterFwd)
69  continue;
70 
71  if (mapIterFwd->second.m_backwardAssociations.empty() && !mapIterFwd->second.m_forwardAssociations.empty())
72  this->AmbiguousPropagation(pCluster, true, clusterAssociationMap);
73 
74  ClusterAssociationMap::const_iterator mapIterBwd = clusterAssociationMap.find(pCluster);
75 
76  if (clusterAssociationMap.end() == mapIterBwd)
77  continue;
78 
79  if (mapIterBwd->second.m_forwardAssociations.empty() && !mapIterBwd->second.m_backwardAssociations.empty())
80  this->AmbiguousPropagation(pCluster, false, clusterAssociationMap);
81  }
82  }
83 
84  return STATUS_CODE_SUCCESS;
85 }
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
intermediate_table::const_iterator const_iterator
bool m_resolveAmbiguousAssociations
Whether to resolve ambiguous associations.
void AmbiguousPropagation(const pandora::Cluster *const pCluster, const bool isForward, ClusterAssociationMap &clusterAssociationMap) const
Ambiguous propagation.
virtual void PopulateClusterAssociationMap(const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const =0
Populate the cluster association map.
void UnambiguousPropagation(const pandora::Cluster *const pCluster, const bool isForward, ClusterAssociationMap &clusterAssociationMap) const
Unambiguous propagation.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
virtual void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const =0
Populate cluster vector with subset of cluster list, containing clusters judged to be clean...
void lar_content::ClusterAssociationAlgorithm::UnambiguousPropagation ( const pandora::Cluster *const  pCluster,
const bool  isForward,
ClusterAssociationMap clusterAssociationMap 
) const
private

Unambiguous propagation.

Parameters
pClusteraddress of the cluster to propagate
isForwardwhether propagation direction is forward
clusterAssociationMapthe cluster association map

Definition at line 89 of file ClusterAssociationAlgorithm.cc.

References m_mergeMade, and UpdateForUnambiguousMerge().

Referenced by Run().

90 {
91  const Cluster *const pClusterToEnlarge = pCluster;
92  ClusterAssociationMap::iterator iterEnlarge = clusterAssociationMap.find(pClusterToEnlarge);
93 
94  if (clusterAssociationMap.end() == iterEnlarge)
95  return;
96 
97  ClusterSet &clusterSetEnlarge(isForward ? iterEnlarge->second.m_forwardAssociations : iterEnlarge->second.m_backwardAssociations);
98 
99  if (clusterSetEnlarge.size() != 1)
100  return;
101 
102  const Cluster *const pClusterToDelete = *(clusterSetEnlarge.begin());
103  ClusterAssociationMap::iterator iterDelete = clusterAssociationMap.find(pClusterToDelete);
104 
105  if (clusterAssociationMap.end() == iterDelete)
106  return;
107 
108  ClusterSet &clusterSetDelete(isForward ? iterDelete->second.m_backwardAssociations : iterDelete->second.m_forwardAssociations);
109 
110  if (clusterSetDelete.size() != 1)
111  return;
112 
113  this->UpdateForUnambiguousMerge(pClusterToEnlarge, pClusterToDelete, isForward, clusterAssociationMap);
114 
115  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pClusterToEnlarge, pClusterToDelete));
116  m_mergeMade = true;
117 
118  this->UnambiguousPropagation(pClusterToEnlarge, isForward, clusterAssociationMap);
119 }
intermediate_table::iterator iterator
void UnambiguousPropagation(const pandora::Cluster *const pCluster, const bool isForward, ClusterAssociationMap &clusterAssociationMap) const
Unambiguous propagation.
void UpdateForUnambiguousMerge(const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete, const bool isForwardMerge, ClusterAssociationMap &clusterAssociationMap) const
Update cluster association map to reflect an unambiguous cluster merge.
void lar_content::ClusterAssociationAlgorithm::UpdateForAmbiguousMerge ( const pandora::Cluster *const  pCluster,
ClusterAssociationMap clusterAssociationMap 
) const
private

Update cluster association map to reflect an ambiguous cluster merge.

Parameters
pClusteraddress of the cluster to be cleared
clusterAssociationMapthe cluster association map

Definition at line 206 of file ClusterAssociationAlgorithm.cc.

Referenced by AmbiguousPropagation().

207 {
208  ClusterAssociationMap::iterator cIter = clusterAssociationMap.find(pCluster);
209 
210  if (clusterAssociationMap.end() == cIter)
211  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
212 
213  for (ClusterAssociationMap::iterator mIter = clusterAssociationMap.begin(), mIterEnd = clusterAssociationMap.end(); mIter != mIterEnd; ++mIter)
214  {
215  ClusterSet &forwardClusters = mIter->second.m_forwardAssociations;
216  ClusterSet &backwardClusters = mIter->second.m_backwardAssociations;
217 
218  ClusterSet::iterator fIter = forwardClusters.find(pCluster);
219  ClusterSet::iterator bIter = backwardClusters.find(pCluster);
220 
221  if (forwardClusters.end() != fIter)
222  forwardClusters.erase(fIter);
223 
224  if (backwardClusters.end() != bIter)
225  backwardClusters.erase(bIter);
226  }
227 
228  clusterAssociationMap.erase(pCluster);
229 }
intermediate_table::iterator iterator
void lar_content::ClusterAssociationAlgorithm::UpdateForUnambiguousMerge ( const pandora::Cluster *const  pClusterToEnlarge,
const pandora::Cluster *const  pClusterToDelete,
const bool  isForwardMerge,
ClusterAssociationMap clusterAssociationMap 
) const
private

Update cluster association map to reflect an unambiguous cluster merge.

Parameters
pClusterToEnlargeaddress of the cluster to be enlarged
pClusterToDeleteaddress of the cluster to be deleted
isForwardMergewhether merge is forward (pClusterToEnlarge is forward-associated with pClusterToDelete)
clusterAssociationMapthe cluster association map

Definition at line 168 of file ClusterAssociationAlgorithm.cc.

Referenced by UnambiguousPropagation().

170 {
171  ClusterAssociationMap::iterator iterEnlarge = clusterAssociationMap.find(pClusterToEnlarge);
172  ClusterAssociationMap::iterator iterDelete = clusterAssociationMap.find(pClusterToDelete);
173 
174  if ((clusterAssociationMap.end() == iterEnlarge) || (clusterAssociationMap.end() == iterDelete))
175  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
176 
177  ClusterSet &clusterSetToMove(isForwardMerge ? iterDelete->second.m_forwardAssociations : iterDelete->second.m_backwardAssociations);
178  ClusterSet &clusterSetToReplace(isForwardMerge ? iterEnlarge->second.m_forwardAssociations : iterEnlarge->second.m_backwardAssociations);
179  clusterSetToReplace = clusterSetToMove;
180  clusterAssociationMap.erase(iterDelete);
181 
182  for (ClusterAssociationMap::iterator iter = clusterAssociationMap.begin(), iterEnd = clusterAssociationMap.end(); iter != iterEnd; ++iter)
183  {
184  ClusterSet &forwardClusters = iter->second.m_forwardAssociations;
185  ClusterSet &backwardClusters = iter->second.m_backwardAssociations;
186 
187  ClusterSet::iterator forwardIter = forwardClusters.find(pClusterToDelete);
188  ClusterSet::iterator backwardIter = backwardClusters.find(pClusterToDelete);
189 
190  if (forwardClusters.end() != forwardIter)
191  {
192  forwardClusters.erase(forwardIter);
193  forwardClusters.insert(pClusterToEnlarge);
194  }
195 
196  if (backwardClusters.end() != backwardIter)
197  {
198  backwardClusters.erase(backwardIter);
199  backwardClusters.insert(pClusterToEnlarge);
200  }
201  }
202 }
intermediate_table::iterator iterator

Member Data Documentation

bool lar_content::ClusterAssociationAlgorithm::m_mergeMade
mutableprivate
bool lar_content::ClusterAssociationAlgorithm::m_resolveAmbiguousAssociations
private

Whether to resolve ambiguous associations.

Definition at line 125 of file ClusterAssociationAlgorithm.h.

Referenced by ReadSettings(), and Run().


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