9 #include "Pandora/AlgorithmHeaders.h" 20 DeltaRayExtensionAlgorithm::DeltaRayExtensionAlgorithm() :
21 m_minClusterLength(1.
f),
22 m_maxClusterLength(10.
f),
23 m_maxLongitudinalDisplacement(2.5
f),
24 m_maxTransverseDisplacement(1.5
f)
34 const Cluster *
const pCluster = *iter;
39 clusterVector.push_back(pCluster);
51 for (
const Cluster *
const pParentCluster : clusterVector)
53 for (
const Cluster *
const pDaughterCluster : clusterVector)
55 if (pParentCluster == pDaughterCluster)
66 ClusterToCoordinateMap &outerCoordinateMap, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
const 71 if ((innerCoordinateMap.end() == innerIter) || (outerCoordinateMap.end() == outerIter))
74 (void) innerCoordinateMap.insert(ClusterToCoordinateMap::value_type(pCluster, innerCoordinate));
75 (void) outerCoordinateMap.insert(ClusterToCoordinateMap::value_type(pCluster, outerCoordinate));
79 innerCoordinate = innerIter->second;
80 outerCoordinate = outerIter->second;
90 if (!PandoraContentApi::IsAvailable(*
this, pDaughterCluster))
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)))
124 const float figureOfMerit(daughterVertexDistanceSquared);
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)
142 if (!PandoraContentApi::IsAvailable(*
this, pParentCluster) || parentLengthSquared > m_maxClusterLength *
m_maxClusterLength)
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)));
155 const float sidewaysDistance(daughterDirection.GetCrossProduct((daughterVertex - projectedVertex)).GetMagnitude());
157 if (forwardDistance < 0.f || forwardDistance > m_maxLongitudinalDisplacement || sidewaysDistance > m_maxTransverseDisplacement)
160 if (-parentDirection.GetDotProduct(daughterDirection) < 0.25f)
169 (void) clusterAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(pDaughterCluster,
170 ClusterAssociation(parentVertexType, daughterVertexType, associationType, figureOfMerit)));
186 for (
const auto &mapEntry : parentToDaughterMatrix) sortedParentClusters.push_back(mapEntry.first);
189 for (
const Cluster *
const pParentCluster : sortedParentClusters)
194 for (
const auto &mapEntry : daughterToAssociationMap) sortedLocalDaughterClusters.push_back(mapEntry.first);
197 for (
const Cluster *
const pDaughterCluster : sortedLocalDaughterClusters)
199 const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
200 (void) daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
208 for (
const auto &mapEntry : daughterToParentMatrix) sortedDaughterClusters.push_back(mapEntry.first);
212 for (
const Cluster *
const pDaughterCluster : sortedDaughterClusters)
216 const Cluster *pBestInner(NULL);
217 const Cluster *pBestOuter(NULL);
223 for (
const auto &mapEntry : parentToAssociationMap) sortedLocalParentClusters.push_back(mapEntry.first);
226 for (
const Cluster *
const pParentCluster : sortedLocalParentClusters)
228 const ClusterAssociation &clusterAssociation(parentToAssociationMap.at(pParentCluster));
232 if (clusterAssociation.GetFigureOfMerit() < bestFomInner)
238 pBestInner = pParentCluster;
249 if (clusterAssociation.GetFigureOfMerit() < bestFomOuter)
251 bestFomOuter = clusterAssociation.GetFigureOfMerit();
255 pBestOuter = pParentCluster;
269 if (parentToDaughterMatrix.end() == iter3A)
270 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
275 if (parentToDaughterMap.end() == iter3B)
276 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
279 (void) reducedParentToDaughterMatrix[pBestInner].insert(ClusterAssociationMap::value_type(pDaughterCluster, bestAssociationInner));
286 if (parentToDaughterMatrix.end() == iter3A)
287 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
292 if (parentToDaughterMap.end() == iter3B)
293 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
296 (void) reducedParentToDaughterMatrix[pBestOuter].insert(ClusterAssociationMap::value_type(pDaughterCluster, bestAssociationOuter));
302 for (
const auto &mapEntry : reducedParentToDaughterMatrix) sortedReducedParentClusters.push_back(mapEntry.first);
305 for (
const Cluster *
const pParentCluster : sortedReducedParentClusters)
307 const ClusterAssociationMap &daughterToAssociationMap(reducedParentToDaughterMatrix.at(pParentCluster));
309 const Cluster *pBestInner(NULL);
310 const Cluster *pBestOuter(NULL);
316 for (
const auto &mapEntry : daughterToAssociationMap) sortedLocalDaughterClusters.push_back(mapEntry.first);
319 for (
const Cluster *
const pDaughterCluster : sortedLocalDaughterClusters)
321 const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
325 if (clusterAssociation.GetFigureOfMerit() < bestFomInner)
331 pBestInner = pDaughterCluster;
342 if (clusterAssociation.GetFigureOfMerit() < bestFomOuter)
344 bestFomOuter = clusterAssociation.GetFigureOfMerit();
348 pBestOuter = pDaughterCluster;
360 ClusterList &parentList(clusterMergeMap[pParentCluster]);
362 if (parentList.end() == std::find(parentList.begin(), parentList.end(), pBestInner))
363 parentList.push_back(pBestInner);
365 ClusterList &bestInnerList(clusterMergeMap[pBestInner]);
367 if (bestInnerList.end() == std::find(bestInnerList.begin(), bestInnerList.end(), pParentCluster))
368 bestInnerList.push_back(pParentCluster);
373 ClusterList &parentList(clusterMergeMap[pParentCluster]);
375 if (parentList.end() == std::find(parentList.begin(), parentList.end(), pBestOuter))
376 parentList.push_back(pBestOuter);
378 ClusterList &bestOuterList(clusterMergeMap[pBestOuter]);
380 if (bestOuterList.end() == std::find(bestOuterList.begin(), bestOuterList.end(), pParentCluster))
381 bestOuterList.push_back(pParentCluster);
390 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
393 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
396 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
399 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
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 *, ClusterAssociationMap > ClusterAssociationMatrix
float m_maxLongitudinalDisplacement
ClusterAssociation class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the delta ray extension algorithm class.
Header file for the cluster helper class.
AssociationType
Association enumeration.
std::unordered_map< const pandora::Cluster *, pandora::CartesianVector > ClusterToCoordinateMap
void FillClusterMergeMap(const ClusterAssociationMatrix &clusterAssociationMatrix, ClusterMergeMap &clusterMergeMap) const
Fill the cluster merge map.
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...
std::vector< art::Ptr< recob::Cluster > > ClusterVector
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
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) ...
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.
float m_maxTransverseDisplacement
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
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.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
VertexType
Vertex enumeration.
float GetFigureOfMerit() const
Get figure of merit.