Fill the cluster merge map. 
  170     for (
const auto &mapEntry : inputAssociationMatrix)
 
  171         sortedInputClusters.push_back(mapEntry.first);
 
  174     for (
const Cluster *
const pCluster1 : sortedInputClusters)
 
  178         for (
const Cluster *
const pCluster2 : sortedInputClusters)
 
  180             if (pCluster1 == pCluster2)
 
  185             ClusterAssociationMap::const_iterator iter12 = associationMap1.find(pCluster2);
 
  186             if (associationMap1.end() == iter12)
 
  189             ClusterAssociationMap::const_iterator iter21 = associationMap2.find(pCluster1);
 
  190             if (associationMap2.end() == iter21)
 
  193             const ClusterAssociation &association12(iter12->second);
 
  194             const ClusterAssociation &association21(iter21->second);
 
  196             bool isAssociated(
true);
 
  199             for (
const auto &mapEntry : associationMap1)
 
  200                 sortedAssociationClusters.push_back(mapEntry.first);
 
  203             for (
const Cluster *
const pCluster3 : sortedAssociationClusters)
 
  205                 const ClusterAssociation &association13(associationMap1.at(pCluster3));
 
  207                 ClusterAssociationMap::const_iterator iter23 = associationMap2.find(pCluster3);
 
  208                 if (associationMap2.end() == iter23)
 
  211                 const ClusterAssociation &association23(iter23->second);
 
  213                 if (association12.GetParent() == association13.GetParent() && association23.GetParent() == association21.GetParent() &&
 
  214                     association13.GetDaughter() != association23.GetDaughter())
 
  216                     isAssociated = 
false;
 
  223                 (
void)clusterAssociationMatrix[pCluster1].insert(ClusterAssociationMap::value_type(pCluster2, association12));
 
  224                 (
void)clusterAssociationMatrix[pCluster2].insert(ClusterAssociationMap::value_type(pCluster1, association21));
 
  233     for (
const auto &mapEntry : clusterAssociationMatrix)
 
  234         sortedClusters.push_back(mapEntry.first);
 
  237     for (
const Cluster *
const pParentCluster : sortedClusters)
 
  241         const Cluster *pBestClusterInner(
nullptr);
 
  244         const Cluster *pBestClusterOuter(
nullptr);
 
  248         for (
const auto &mapEntry : clusterAssociationMap)
 
  249             sortedAssociationClusters.push_back(mapEntry.first);
 
  252         for (
const Cluster *
const pDaughterCluster : sortedAssociationClusters)
 
  254             const ClusterAssociation &clusterAssociation(clusterAssociationMap.at(pDaughterCluster));
 
  259                 if (clusterAssociation.GetFigureOfMerit() > bestAssociationInner.GetFigureOfMerit())
 
  261                     bestAssociationInner = clusterAssociation;
 
  262                     pBestClusterInner = pDaughterCluster;
 
  269                 if (clusterAssociation.GetFigureOfMerit() > bestAssociationOuter.GetFigureOfMerit())
 
  271                     bestAssociationOuter = clusterAssociation;
 
  272                     pBestClusterOuter = pDaughterCluster;
 
  277         if (pBestClusterInner)
 
  278             (
void)intermediateAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(pBestClusterInner, bestAssociationInner));
 
  280         if (pBestClusterOuter)
 
  281             (
void)intermediateAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(pBestClusterOuter, bestAssociationOuter));
 
  286     for (
const auto &mapEntry : intermediateAssociationMatrix)
 
  287         intermediateSortedClusters.push_back(mapEntry.first);
 
  290     for (
const Cluster *
const pParentCluster : intermediateSortedClusters)
 
  295         for (
const auto &mapEntry : parentAssociationMap)
 
  296             sortedAssociationClusters.push_back(mapEntry.first);
 
  299         for (
const Cluster *
const pDaughterCluster : sortedAssociationClusters)
 
  301             const ClusterAssociation &parentToDaughterAssociation(parentAssociationMap.at(pDaughterCluster));
 
  303             ClusterAssociationMatrix::const_iterator iter5 = intermediateAssociationMatrix.find(pDaughterCluster);
 
  305             if (intermediateAssociationMatrix.end() == iter5)
 
  310             ClusterAssociationMap::const_iterator iter6 = daughterAssociationMap.find(pParentCluster);
 
  312             if (daughterAssociationMap.end() == iter6)
 
  315             const ClusterAssociation &daughterToParentAssociation(iter6->second);
 
  317             if (parentToDaughterAssociation.GetParent() == daughterToParentAssociation.GetDaughter() &&
 
  318                 parentToDaughterAssociation.GetDaughter() == daughterToParentAssociation.GetParent())
 
  320                 ClusterList &parentList(clusterMergeMap[pParentCluster]);
 
  322                 if (parentList.end() == std::find(parentList.begin(), parentList.end(), pDaughterCluster))
 
  323                     parentList.push_back(pDaughterCluster);
 
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. 
 
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
 
std::unordered_map< const pandora::Cluster *, ClusterAssociationMap > ClusterAssociationMatrix
 
std::vector< art::Ptr< recob::Cluster > > ClusterVector