91 if (pClusterI == pClusterJ)
124 const float distanceSquaredIJ((vertexI - vertexJ).GetMagnitudeSquared());
136 if (cosTheta < cosThetaCut)
143 const float overlapL(directionIJ.
GetDotProduct(vertexJ - vertexI));
146 if (overlapL < -1.f || overlapL * overlapL > 2.f * std::min(lengthSquaredI, lengthSquaredJ) ||
151 const float rms1(this->
CalculateRms(pClusterI, endI, directionIJ));
152 const float rms2(this->
CalculateRms(pClusterJ, endJ, directionJI));
154 const float rms(0.5f * (rms1 + rms2));
155 const float rmsCut(2.f *
m_maxAverageRms * (cosTheta - cosThetaCut) / (1.0 - cosThetaCut));
161 const ClusterAssociation::VertexType vertexTypeI(clusterVertexI.
IsInnerVertex() ? ClusterAssociation::INNER : ClusterAssociation::OUTER);
162 const ClusterAssociation::VertexType vertexTypeJ(clusterVertexJ.
IsInnerVertex() ? ClusterAssociation::INNER : ClusterAssociation::OUTER);
163 const ClusterAssociation::AssociationType associationType(ClusterAssociation::STRONG);
165 (void)clusterAssociationMatrix[pClusterI].insert(
166 ClusterAssociationMap::value_type(pClusterJ,
ClusterAssociation(vertexTypeI, vertexTypeJ, associationType, lengthSquaredJ)));
168 (void)clusterAssociationMatrix[pClusterJ].insert(
169 ClusterAssociationMap::value_type(pClusterI,
ClusterAssociation(vertexTypeJ, vertexTypeI, associationType, lengthSquaredI)));
185 for (
const auto &mapEntry : inputAssociationMatrix)
186 sortedInputClusters.push_back(mapEntry.first);
189 for (
const Cluster *
const pCluster1 : sortedInputClusters)
193 for (
const Cluster *
const pCluster2 : sortedInputClusters)
195 if (pCluster1 == pCluster2)
200 ClusterAssociationMap::const_iterator iter12 = associationMap1.find(pCluster2);
201 if (associationMap1.end() == iter12)
204 ClusterAssociationMap::const_iterator iter21 = associationMap2.find(pCluster1);
205 if (associationMap2.end() == iter21)
211 bool isAssociated(
true);
214 for (
const auto &mapEntry : associationMap1)
215 sortedAssociationClusters.push_back(mapEntry.first);
218 for (
const Cluster *
const pCluster3 : sortedAssociationClusters)
222 ClusterAssociationMap::const_iterator iter23 = associationMap2.find(pCluster3);
223 if (associationMap2.end() == iter23)
231 isAssociated =
false;
238 (void)clusterAssociationMatrix[pCluster1].insert(ClusterAssociationMap::value_type(pCluster2, association12));
239 (void)clusterAssociationMatrix[pCluster2].insert(ClusterAssociationMap::value_type(pCluster1, association21));
248 for (
const auto &mapEntry : clusterAssociationMatrix)
249 sortedClusters.push_back(mapEntry.first);
252 for (
const Cluster *
const pParentCluster : sortedClusters)
256 const Cluster *pBestClusterInner(
nullptr);
257 ClusterAssociation bestAssociationInner(ClusterAssociation::UNDEFINED, ClusterAssociation::UNDEFINED, ClusterAssociation::NONE, 0.f);
259 const Cluster *pBestClusterOuter(
nullptr);
260 ClusterAssociation bestAssociationOuter(ClusterAssociation::UNDEFINED, ClusterAssociation::UNDEFINED, ClusterAssociation::NONE, 0.f);
263 for (
const auto &mapEntry : clusterAssociationMap)
264 sortedAssociationClusters.push_back(mapEntry.first);
267 for (
const Cluster *
const pDaughterCluster : sortedAssociationClusters)
269 const ClusterAssociation &clusterAssociation(clusterAssociationMap.at(pDaughterCluster));
272 if (clusterAssociation.
GetParent() == ClusterAssociation::INNER)
276 bestAssociationInner = clusterAssociation;
277 pBestClusterInner = pDaughterCluster;
282 if (clusterAssociation.
GetParent() == ClusterAssociation::OUTER)
286 bestAssociationOuter = clusterAssociation;
287 pBestClusterOuter = pDaughterCluster;
292 if (pBestClusterInner)
293 (void)intermediateAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(pBestClusterInner, bestAssociationInner));
295 if (pBestClusterOuter)
296 (void)intermediateAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(pBestClusterOuter, bestAssociationOuter));
301 for (
const auto &mapEntry : intermediateAssociationMatrix)
302 intermediateSortedClusters.push_back(mapEntry.first);
305 for (
const Cluster *
const pParentCluster : intermediateSortedClusters)
310 for (
const auto &mapEntry : parentAssociationMap)
311 sortedAssociationClusters.push_back(mapEntry.first);
314 for (
const Cluster *
const pDaughterCluster : sortedAssociationClusters)
316 const ClusterAssociation &parentToDaughterAssociation(parentAssociationMap.at(pDaughterCluster));
318 ClusterAssociationMatrix::const_iterator iter5 = intermediateAssociationMatrix.find(pDaughterCluster);
320 if (intermediateAssociationMatrix.end() == iter5)
325 ClusterAssociationMap::const_iterator iter6 = daughterAssociationMap.find(pParentCluster);
327 if (daughterAssociationMap.end() == iter6)
335 ClusterList &parentList(clusterMergeMap[pParentCluster]);
337 if (parentList.end() == std::find(parentList.begin(), parentList.end(), pDaughterCluster))
338 parentList.push_back(pDaughterCluster);
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
float CalculateRms(const pandora::Cluster *const pCluster, const pandora::CartesianVector &position, const pandora::CartesianVector &direction) const
Calculate RMS deviation of a cluster with respect to the reference line.
void FillClusterMergeMap(const ClusterAssociationMatrix &clusterAssociationMatrix, ClusterMergeMap &clusterMergeMap) const
Fill the cluster merge map.
void FillClusterAssociationMatrix(const pandora::ClusterVector &clusterVector, ClusterAssociationMatrix &clusterAssociationMatrix) const
Fill the cluster association matrix.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with subset of cluster list, containing clusters judged to be clean.
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 GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
static void GetClosestVertices(const bool useX, const bool useY, const bool useZ, const LArPointingCluster &pointingClusterI, const LArPointingCluster &pointingClusterJ, LArPointingCluster::Vertex &closestVertexI, LArPointingCluster::Vertex &closestVertexJ)
Given a pair of pointing clusters, receive the closest or farthest pair of vertices.
static float GetLengthSquared(const LArPointingCluster &pointingCluster)
Calculate distance squared between inner and outer vertices of pointing cluster.
const pandora::Cluster * GetCluster() const
Get the address of the cluster.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap