96 CartesianVector innerCoordinateP(0.f, 0.f, 0.f), outerCoordinateP(0.f, 0.f, 0.f);
99 CartesianVector innerCoordinateD(0.f, 0.f, 0.f), outerCoordinateD(0.f, 0.f, 0.f);
102 for (
unsigned int useInnerD = 0; useInnerD < 2; ++useInnerD)
104 const CartesianVector daughterVertex(useInnerD == 1 ? innerCoordinateD : outerCoordinateD);
105 const CartesianVector daughterEnd(useInnerD == 1 ? outerCoordinateD : innerCoordinateD);
107 const float daughterLengthSquared((daughterEnd - daughterVertex).GetMagnitudeSquared());
115 const float daughterVertexDistanceSquared((projectedVertex - daughterVertex).GetMagnitudeSquared());
116 const float daughterEndDistanceSquared((projectedVertex - daughterEnd).GetMagnitudeSquared());
120 std::min(daughterEndDistanceSquared, daughterLengthSquared)))
123 const ClusterAssociation::VertexType daughterVertexType(useInnerD == 1 ? ClusterAssociation::INNER : ClusterAssociation::OUTER);
124 const float figureOfMerit(daughterVertexDistanceSquared);
126 ClusterAssociation::AssociationType associationType(ClusterAssociation::WEAK);
127 ClusterAssociation::VertexType parentVertexType(ClusterAssociation::UNDEFINED);
129 for (
unsigned int useInnerP = 0; useInnerP < 2; ++useInnerP)
131 const CartesianVector parentVertex(useInnerP == 1 ? innerCoordinateP : outerCoordinateP);
132 const CartesianVector parentEnd(useInnerP == 1 ? outerCoordinateP : innerCoordinateP);
134 const float parentVertexDistanceSquared((projectedVertex - parentVertex).GetMagnitudeSquared());
135 const float parentEndDistanceSquared((projectedVertex - parentEnd).GetMagnitudeSquared());
136 const float parentLengthSquared((parentEnd - parentVertex).GetMagnitudeSquared());
138 if (parentVertexDistanceSquared < parentEndDistanceSquared)
139 parentVertexType = (useInnerP == 1 ? ClusterAssociation::INNER : ClusterAssociation::OUTER);
147 std::min(parentEndDistanceSquared, daughterEndDistanceSquared)))
151 const CartesianVector daughterDirection((daughterEnd - daughterVertex).GetUnitVector());
152 const CartesianVector parentDirection((parentEnd - projectedVertex).GetUnitVector());
154 const float forwardDistance(daughterDirection.
GetDotProduct((daughterVertex - projectedVertex)));
160 if (-parentDirection.
GetDotProduct(daughterDirection) < 0.25f)
163 associationType = ClusterAssociation::STRONG;
167 if (parentVertexType > ClusterAssociation::UNDEFINED)
169 (void)clusterAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(
170 pDaughterCluster,
ClusterAssociation(parentVertexType, daughterVertexType, associationType, figureOfMerit)));
186 for (
const auto &mapEntry : parentToDaughterMatrix)
187 sortedParentClusters.push_back(mapEntry.first);
190 for (
const Cluster *
const pParentCluster : sortedParentClusters)
195 for (
const auto &mapEntry : daughterToAssociationMap)
196 sortedLocalDaughterClusters.push_back(mapEntry.first);
199 for (
const Cluster *
const pDaughterCluster : sortedLocalDaughterClusters)
201 const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
202 (void)daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
209 for (
const auto &mapEntry : daughterToParentMatrix)
210 sortedDaughterClusters.push_back(mapEntry.first);
214 for (
const Cluster *
const pDaughterCluster : sortedDaughterClusters)
218 const Cluster *pBestInner(NULL);
219 const Cluster *pBestOuter(NULL);
221 float bestFomInner(std::numeric_limits<float>::max());
222 float bestFomOuter(std::numeric_limits<float>::max());
225 for (
const auto &mapEntry : parentToAssociationMap)
226 sortedLocalParentClusters.push_back(mapEntry.first);
229 for (
const Cluster *
const pParentCluster : sortedLocalParentClusters)
231 const ClusterAssociation &clusterAssociation(parentToAssociationMap.at(pParentCluster));
233 if (clusterAssociation.
GetParent() == ClusterAssociation::INNER)
239 if (clusterAssociation.
GetAssociation() == ClusterAssociation::STRONG)
241 pBestInner = pParentCluster;
250 if (clusterAssociation.
GetParent() == ClusterAssociation::OUTER)
256 if (clusterAssociation.
GetAssociation() == ClusterAssociation::STRONG)
258 pBestOuter = pParentCluster;
270 ClusterAssociationMatrix::const_iterator iter3A = parentToDaughterMatrix.find(pBestInner);
272 if (parentToDaughterMatrix.end() == iter3A)
276 ClusterAssociationMap::const_iterator iter3B = parentToDaughterMap.find(pDaughterCluster);
278 if (parentToDaughterMap.end() == iter3B)
282 (void)reducedParentToDaughterMatrix[pBestInner].insert(ClusterAssociationMap::value_type(pDaughterCluster, bestAssociationInner));
287 ClusterAssociationMatrix::const_iterator iter3A = parentToDaughterMatrix.find(pBestOuter);
289 if (parentToDaughterMatrix.end() == iter3A)
293 ClusterAssociationMap::const_iterator iter3B = parentToDaughterMap.find(pDaughterCluster);
295 if (parentToDaughterMap.end() == iter3B)
299 (void)reducedParentToDaughterMatrix[pBestOuter].insert(ClusterAssociationMap::value_type(pDaughterCluster, bestAssociationOuter));
304 for (
const auto &mapEntry : reducedParentToDaughterMatrix)
305 sortedReducedParentClusters.push_back(mapEntry.first);
308 for (
const Cluster *
const pParentCluster : sortedReducedParentClusters)
310 const ClusterAssociationMap &daughterToAssociationMap(reducedParentToDaughterMatrix.at(pParentCluster));
312 const Cluster *pBestInner(NULL);
313 const Cluster *pBestOuter(NULL);
315 float bestFomInner(std::numeric_limits<float>::max());
316 float bestFomOuter(std::numeric_limits<float>::max());
319 for (
const auto &mapEntry : daughterToAssociationMap)
320 sortedLocalDaughterClusters.push_back(mapEntry.first);
323 for (
const Cluster *
const pDaughterCluster : sortedLocalDaughterClusters)
325 const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
327 if (clusterAssociation.
GetParent() == ClusterAssociation::INNER)
333 if (clusterAssociation.
GetAssociation() == ClusterAssociation::STRONG)
335 pBestInner = pDaughterCluster;
344 if (clusterAssociation.
GetParent() == ClusterAssociation::OUTER)
350 if (clusterAssociation.
GetAssociation() == ClusterAssociation::STRONG)
352 pBestOuter = pDaughterCluster;
364 ClusterList &parentList(clusterMergeMap[pParentCluster]);
366 if (parentList.end() == std::find(parentList.begin(), parentList.end(), pBestInner))
367 parentList.push_back(pBestInner);
369 ClusterList &bestInnerList(clusterMergeMap[pBestInner]);
371 if (bestInnerList.end() == std::find(bestInnerList.begin(), bestInnerList.end(), pParentCluster))
372 bestInnerList.push_back(pParentCluster);
377 ClusterList &parentList(clusterMergeMap[pParentCluster]);
379 if (parentList.end() == std::find(parentList.begin(), parentList.end(), pBestOuter))
380 parentList.push_back(pBestOuter);
382 ClusterList &bestOuterList(clusterMergeMap[pBestOuter]);
384 if (bestOuterList.end() == std::find(bestOuterList.begin(), bestOuterList.end(), pParentCluster))
385 bestOuterList.push_back(pParentCluster);
static bool IsAvailable(const pandora::Algorithm &algorithm, const T *const pT)
Is object, or a list of objects, available as a building block.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void GetExtremalCoordinatesFromCache(const pandora::Cluster *const pCluster, ClusterToCoordinateMap &innerCoordinateMap, ClusterToCoordinateMap &outerCoordinateMap, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate) const
Reduce number of extremal coordinates calculations by caching results when they are first obtained.
void FillClusterAssociationMatrix(const pandora::ClusterVector &clusterVector, ClusterAssociationMatrix &clusterAssociationMatrix) const
Fill the cluster association matrix.
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.
void FillClusterMergeMap(const ClusterAssociationMatrix &clusterAssociationMatrix, ClusterMergeMap &clusterMergeMap) const
Fill the cluster merge map.
static pandora::CartesianVector GetClosestPosition(const pandora::CartesianVector &position, const pandora::ClusterList &clusterList)
Get closest position in a list of clusters to a specified input position vector.
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 void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z)
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap