LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
BranchGrowingAlgorithm.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 void BranchGrowingAlgorithm::FindAssociatedClusters(const Cluster *const pParticleSeed, ClusterVector &candidateClusters,
21  ClusterUsageMap &forwardUsageMap, ClusterUsageMap &backwardUsageMap) const
22 {
23  ClusterVector currentSeedAssociations, newSeedAssociations;
24  currentSeedAssociations.push_back(pParticleSeed);
25 
26  unsigned int associationOrder(1);
27 
28  while (!currentSeedAssociations.empty())
29  {
30  for (ClusterVector::iterator iterI = candidateClusters.begin(), iterIEnd = candidateClusters.end(); iterI != iterIEnd; ++iterI)
31  {
32  const Cluster *const pCandidateCluster = *iterI;
33 
34  if (NULL == pCandidateCluster)
35  continue;
36 
37  for (ClusterVector::iterator iterJ = currentSeedAssociations.begin(), iterJEnd = currentSeedAssociations.end(); iterJ != iterJEnd; ++iterJ)
38  {
39  const Cluster *const pAssociatedCluster = *iterJ;
40 
41  const AssociationType associationType(this->AreClustersAssociated(pAssociatedCluster, pCandidateCluster));
42 
43  if (NONE == associationType)
44  continue;
45 
46  // Check we store best association between this seed and candidate
47  Association association(associationOrder, associationType);
48  const Association &existingAssociation = forwardUsageMap[pParticleSeed][pCandidateCluster];
49 
50  if (association.GetType() > existingAssociation.GetType())
51  {
52  // If not first association, check strength of previous association in chain
53  if (pParticleSeed != pAssociatedCluster)
54  association.SetType(std::min(association.GetType(), backwardUsageMap[pAssociatedCluster][pParticleSeed].GetType()));
55 
56  forwardUsageMap[pParticleSeed][pCandidateCluster] = association;
57  backwardUsageMap[pCandidateCluster][pParticleSeed] = association;
58  }
59 
60  newSeedAssociations.push_back(pCandidateCluster);
61  *iterI = NULL;
62  }
63  }
64 
65  currentSeedAssociations = newSeedAssociations;
66  newSeedAssociations.clear();
67  ++associationOrder;
68  }
69 }
70 
71 //------------------------------------------------------------------------------------------------------------------------------------------
72 
73 void BranchGrowingAlgorithm::IdentifyClusterMerges(const ClusterVector &particleSeedVector, const ClusterUsageMap &backwardUsageMap,
74  SeedAssociationList &seedAssociationList) const
75 {
76  ClusterVector sortedCandidates;
77  for (const auto &mapEntry : backwardUsageMap) sortedCandidates.push_back(mapEntry.first);
78  std::sort(sortedCandidates.begin(), sortedCandidates.end(), LArClusterHelper::SortByNHits);
79 
80  for (const Cluster *const pCluster : sortedCandidates)
81  {
82  const ClusterAssociationMap &particleSeedUsageMap(backwardUsageMap.at(pCluster));
83 
84  if (particleSeedUsageMap.empty())
85  throw StatusCodeException(STATUS_CODE_FAILURE);
86 
87  ClusterVector sortedSeeds;
88  for (const auto &mapEntry : particleSeedUsageMap) sortedSeeds.push_back(mapEntry.first);
89  std::sort(sortedSeeds.begin(), sortedSeeds.end(), LArClusterHelper::SortByNHits);
90 
91  const Cluster *pBestParticleSeed = NULL;
92  AssociationType bestType(NONE);
93  unsigned int bestOrder(std::numeric_limits<unsigned int>::max());
94 
95  for (const Cluster *const pParticleSeed : sortedSeeds)
96  {
97  const Association &association(particleSeedUsageMap.at(pParticleSeed));
98 
99  if ((association.GetType() > bestType) || ((association.GetType() == bestType) && (association.GetOrder() < bestOrder)))
100  {
101  // Break-out condition for single order associations
102  if ((SINGLE_ORDER == association.GetType()) && (association.GetOrder() > 1))
103  continue;
104 
105  // Type is primary consideration; order breaks ties
106  pBestParticleSeed = pParticleSeed;
107  bestType = association.GetType();
108  bestOrder = association.GetOrder();
109  }
110  else if ((association.GetType() == bestType) && (association.GetOrder() == bestOrder))
111  {
112  // Remove ambiguous cluster from algorithm
113  pBestParticleSeed = NULL;
114  }
115  }
116 
117  if (NULL == pBestParticleSeed)
118  continue;
119 
120  seedAssociationList[pBestParticleSeed].push_back(pCluster);
121  }
122 
123  // Now deal with seeds that have no associations
124  for (ClusterVector::const_iterator iter = particleSeedVector.begin(), iterEnd = particleSeedVector.end(); iter != iterEnd; ++iter)
125  {
126  const Cluster *const pParticleSeed = *iter;
127 
128  if (seedAssociationList.end() == seedAssociationList.find(pParticleSeed))
129  seedAssociationList[pParticleSeed] = ClusterVector();
130  }
131 }
132 
133 //------------------------------------------------------------------------------------------------------------------------------------------
134 
135 StatusCode BranchGrowingAlgorithm::ReadSettings(const TiXmlHandle /*xmlHandle*/)
136 {
137  return STATUS_CODE_SUCCESS;
138 }
139 
140 } // namespace lar_content
void SetType(const AssociationType associationType)
Set association type.
intermediate_table::iterator iterator
std::unordered_map< const pandora::Cluster *, ClusterAssociationMap > ClusterUsageMap
AssociationType GetType() const
Get association type.
std::unordered_map< const pandora::Cluster *, pandora::ClusterVector > SeedAssociationList
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
Int_t min
Definition: plot.C:26
std::unordered_map< const pandora::Cluster *, Association > ClusterAssociationMap
Header file for the branch growing algorithm base class.