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(
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));
235 if (clusterAssociation.GetFigureOfMerit() < bestFomInner)
241 pBestInner = pParentCluster;
252 if (clusterAssociation.GetFigureOfMerit() < bestFomOuter)
254 bestFomOuter = clusterAssociation.GetFigureOfMerit();
258 pBestOuter = pParentCluster;
272 if (parentToDaughterMatrix.end() == iter3A)
273 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
278 if (parentToDaughterMap.end() == iter3B)
279 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
282 (void)reducedParentToDaughterMatrix[pBestInner].insert(ClusterAssociationMap::value_type(pDaughterCluster, bestAssociationInner));
289 if (parentToDaughterMatrix.end() == iter3A)
290 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
295 if (parentToDaughterMap.end() == iter3B)
296 throw pandora::StatusCodeException(STATUS_CODE_FAILURE);
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));
329 if (clusterAssociation.GetFigureOfMerit() < bestFomInner)
335 pBestInner = pDaughterCluster;
346 if (clusterAssociation.GetFigureOfMerit() < bestFomOuter)
348 bestFomOuter = clusterAssociation.GetFigureOfMerit();
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);
394 PANDORA_RETURN_RESULT_IF_AND_IF(
395 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterLength",
m_minClusterLength));
397 PANDORA_RETURN_RESULT_IF_AND_IF(
398 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxClusterLength",
m_maxClusterLength));
400 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
403 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
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.
float m_maxLongitudinalDisplacement
ClusterAssociation class.
std::unordered_map< const pandora::Cluster *, pandora::CartesianVector > ClusterToCoordinateMap
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 *, ClusterAssociation > ClusterAssociationMap
std::unordered_map< const pandora::Cluster *, ClusterAssociationMap > ClusterAssociationMatrix
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...
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.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
std::vector< art::Ptr< recob::Cluster > > ClusterVector
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)
VertexType
Vertex enumeration.
float GetFigureOfMerit() const
Get figure of merit.