Classes | Public Member Functions | Protected Types | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
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

ClusterAssociationAlgorithm class.

Definition at line 21 of file ClusterAssociationAlgorithm.h.

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.

21 {
22 }
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 121 of file ClusterAssociationAlgorithm.cc.

122 {
123  ClusterAssociationMap::iterator cIter = clusterAssociationMap.find(pCluster);
124 
125  if (clusterAssociationMap.end() == cIter)
126  throw StatusCodeException(STATUS_CODE_FAILURE);
127 
128  const Cluster *pExtremalCluster = pCluster;
129 
130  ClusterSet firstClusterSet;
131  this->NavigateAlongAssociations(clusterAssociationMap, pCluster, isForward, pExtremalCluster, firstClusterSet);
132 
133  ClusterSet secondClusterSet;
134  this->NavigateAlongAssociations(clusterAssociationMap, pExtremalCluster, !isForward, pExtremalCluster, secondClusterSet);
135 
136  ClusterVector daughterClusterVector;
137 
138  if (pCluster == pExtremalCluster)
139  {
140  for (const Cluster *const pFirstCluster : firstClusterSet)
141  {
142  if ((pCluster != pFirstCluster) && (secondClusterSet.count(pFirstCluster)) &&
143  (daughterClusterVector.end() == std::find(daughterClusterVector.begin(), daughterClusterVector.end(), pFirstCluster)))
144  {
145  daughterClusterVector.push_back(pFirstCluster);
146  }
147  }
148  }
149 
150  std::sort(daughterClusterVector.begin(), daughterClusterVector.end(), LArClusterHelper::SortByNHits);
151 
152  for (ClusterVector::iterator dIter = daughterClusterVector.begin(), dIterEnd = daughterClusterVector.end(); dIter != dIterEnd; ++dIter)
153  {
154  this->UpdateForAmbiguousMerge(*dIter, clusterAssociationMap);
155 
156  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pCluster, *dIter));
157  m_mergeMade = true;
158  *dIter = NULL;
159  }
160 
161  this->UpdateForAmbiguousMerge(pCluster, clusterAssociationMap);
162 }
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.

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.

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 231 of file ClusterAssociationAlgorithm.cc.

233 {
234  ClusterAssociationMap::const_iterator iterAssociation = clusterAssociationMap.find(pCluster);
235 
236  if (clusterAssociationMap.end() == iterAssociation)
237  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
238 
239  (void)clusterSet.insert(pCluster);
240 
241  if ((pCluster != pExtremalCluster) && this->IsExtremalCluster(isForward, pExtremalCluster, pCluster))
242  pExtremalCluster = pCluster;
243 
244  const ClusterSet &associatedClusterSet(isForward ? iterAssociation->second.m_forwardAssociations : iterAssociation->second.m_backwardAssociations);
245 
246  for (ClusterSet::const_iterator iter = associatedClusterSet.begin(), iterEnd = associatedClusterSet.end(); iter != iterEnd; ++iter)
247  {
248  this->NavigateAlongAssociations(clusterAssociationMap, *iter, isForward, pExtremalCluster, clusterSet);
249  }
250 }
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.

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

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

Definition at line 254 of file ClusterAssociationAlgorithm.cc.

255 {
256  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
257  XmlHelper::ReadValue(xmlHandle, "ResolveAmbiguousAssociations", m_resolveAmbiguousAssociations));
258 
259  return STATUS_CODE_SUCCESS;
260 }
bool m_resolveAmbiguousAssociations
Whether to resolve ambiguous associations.
StatusCode lar_content::ClusterAssociationAlgorithm::Run ( )
protectedvirtual

Definition at line 26 of file ClusterAssociationAlgorithm.cc.

27 {
28  const ClusterList *pClusterList = NULL;
29  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
30 
31  ClusterVector clusterVector;
32  this->GetListOfCleanClusters(pClusterList, clusterVector);
33 
34  ClusterAssociationMap clusterAssociationMap;
35  this->PopulateClusterAssociationMap(clusterVector, clusterAssociationMap);
36 
37  m_mergeMade = true;
38 
39  while (m_mergeMade)
40  {
41  // Unambiguous propagation
42  while (m_mergeMade)
43  {
44  m_mergeMade = false;
45 
46  for (const Cluster *const pCluster : clusterVector)
47  {
48  // ATTN The clusterVector may end up with dangling pointers; only protected by this check against managed cluster list
49  if (pClusterList->end() == std::find(pClusterList->begin(), pClusterList->end(), pCluster))
50  continue;
51 
52  this->UnambiguousPropagation(pCluster, true, clusterAssociationMap);
53  this->UnambiguousPropagation(pCluster, false, clusterAssociationMap);
54  }
55  }
56 
58  continue;
59 
60  // Propagation with ambiguities
61  for (const Cluster *const pCluster : clusterVector)
62  {
63  // ATTN The clusterVector may end up with dangling pointers; only protected by this check against up-to-date association list
64  ClusterAssociationMap::const_iterator mapIterFwd = clusterAssociationMap.find(pCluster);
65 
66  if (clusterAssociationMap.end() == mapIterFwd)
67  continue;
68 
69  if (mapIterFwd->second.m_backwardAssociations.empty() && !mapIterFwd->second.m_forwardAssociations.empty())
70  this->AmbiguousPropagation(pCluster, true, clusterAssociationMap);
71 
72  ClusterAssociationMap::const_iterator mapIterBwd = clusterAssociationMap.find(pCluster);
73 
74  if (clusterAssociationMap.end() == mapIterBwd)
75  continue;
76 
77  if (mapIterBwd->second.m_forwardAssociations.empty() && !mapIterBwd->second.m_backwardAssociations.empty())
78  this->AmbiguousPropagation(pCluster, false, clusterAssociationMap);
79  }
80  }
81 
82  return STATUS_CODE_SUCCESS;
83 }
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 87 of file ClusterAssociationAlgorithm.cc.

88 {
89  const Cluster *const pClusterToEnlarge = pCluster;
90  ClusterAssociationMap::iterator iterEnlarge = clusterAssociationMap.find(pClusterToEnlarge);
91 
92  if (clusterAssociationMap.end() == iterEnlarge)
93  return;
94 
95  ClusterSet &clusterSetEnlarge(isForward ? iterEnlarge->second.m_forwardAssociations : iterEnlarge->second.m_backwardAssociations);
96 
97  if (clusterSetEnlarge.size() != 1)
98  return;
99 
100  const Cluster *const pClusterToDelete = *(clusterSetEnlarge.begin());
101  ClusterAssociationMap::iterator iterDelete = clusterAssociationMap.find(pClusterToDelete);
102 
103  if (clusterAssociationMap.end() == iterDelete)
104  return;
105 
106  ClusterSet &clusterSetDelete(isForward ? iterDelete->second.m_backwardAssociations : iterDelete->second.m_forwardAssociations);
107 
108  if (clusterSetDelete.size() != 1)
109  return;
110 
111  this->UpdateForUnambiguousMerge(pClusterToEnlarge, pClusterToDelete, isForward, clusterAssociationMap);
112 
113  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pClusterToEnlarge, pClusterToDelete));
114  m_mergeMade = true;
115 
116  this->UnambiguousPropagation(pClusterToEnlarge, isForward, clusterAssociationMap);
117 }
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 204 of file ClusterAssociationAlgorithm.cc.

205 {
206  ClusterAssociationMap::iterator cIter = clusterAssociationMap.find(pCluster);
207 
208  if (clusterAssociationMap.end() == cIter)
209  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
210 
211  for (ClusterAssociationMap::iterator mIter = clusterAssociationMap.begin(), mIterEnd = clusterAssociationMap.end(); mIter != mIterEnd; ++mIter)
212  {
213  ClusterSet &forwardClusters = mIter->second.m_forwardAssociations;
214  ClusterSet &backwardClusters = mIter->second.m_backwardAssociations;
215 
216  ClusterSet::iterator fIter = forwardClusters.find(pCluster);
217  ClusterSet::iterator bIter = backwardClusters.find(pCluster);
218 
219  if (forwardClusters.end() != fIter)
220  forwardClusters.erase(fIter);
221 
222  if (backwardClusters.end() != bIter)
223  backwardClusters.erase(bIter);
224  }
225 
226  clusterAssociationMap.erase(pCluster);
227 }
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 166 of file ClusterAssociationAlgorithm.cc.

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

Member Data Documentation

bool lar_content::ClusterAssociationAlgorithm::m_mergeMade
mutableprivate

Definition at line 123 of file ClusterAssociationAlgorithm.h.

bool lar_content::ClusterAssociationAlgorithm::m_resolveAmbiguousAssociations
private

Whether to resolve ambiguous associations.

Definition at line 125 of file ClusterAssociationAlgorithm.h.


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