9 #include "Pandora/AlgorithmHeaders.h"
23 OvershootSplittingAlgorithm::OvershootSplittingAlgorithm() :
25 m_minClusterLength(5.f),
26 m_maxClusterSeparation(5.f),
27 m_minVertexDisplacement(2.f),
28 m_maxIntersectDisplacement(1.5f),
29 m_minSplitDisplacement(10.f)
37 for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
39 const Cluster *
const pCluster = *iter;
44 clusterVector.push_back(pCluster);
70 ClusterList clusterList;
71 for (
const auto &mapEntry : slidingFitResultMap)
72 clusterList.push_back(mapEntry.first);
75 for (
const Cluster *
const pCluster1 : clusterList)
79 for (
const Cluster *
const pCluster2 : clusterList)
81 if (pCluster1 == pCluster2)
95 const bool useInner((innerDisplacement < outerDisplacement) ?
true :
false);
99 float rL2(0.f), rT2(0.f);
100 CartesianVector intersectPosition2(0.f, 0.f, 0.f);
106 catch (
const StatusCodeException &)
115 float rL1(0.f), rT1(0.f);
116 CartesianVector projectedPosition1(0.f, 0.f, 0.f), projectedDirection1(0.f, 0.f, 0.f);
117 slidingFitResult1.GetLocalPosition(intersectPosition2, rL1, rT1);
119 const StatusCode statusCodePosition(slidingFitResult1.GetGlobalFitPosition(rL1, projectedPosition1));
120 if (STATUS_CODE_SUCCESS != statusCodePosition)
121 throw pandora::StatusCodeException(statusCodePosition);
123 const StatusCode statusCodeDirection(slidingFitResult1.GetGlobalFitDirection(rL1, projectedDirection1));
124 if (STATUS_CODE_SUCCESS != statusCodeDirection)
125 throw pandora::StatusCodeException(statusCodeDirection);
127 const CartesianVector projectedPosition2(clusterVertex.
GetPosition());
128 const CartesianVector projectedDirection2(clusterVertex.
GetDirection());
131 float firstDisplacement(0.f), secondDisplacement(0.f);
132 CartesianVector intersectPosition1(0.f, 0.f, 0.f);
137 projectedDirection2, intersectPosition1, firstDisplacement, secondDisplacement);
139 catch (
const StatusCodeException &)
148 if (std::max(closestDisplacement1, closestDisplacement2) > m_maxClusterSeparation)
151 const CartesianVector minPosition(slidingFitResult1.GetGlobalMinLayerPosition());
152 const CartesianVector maxPosition(slidingFitResult1.GetGlobalMaxLayerPosition());
153 const float lengthSquared((maxPosition - minPosition).GetMagnitudeSquared());
155 const float minDisplacementSquared((minPosition - intersectPosition1).GetMagnitudeSquared());
156 const float maxDisplacementSquared((maxPosition - intersectPosition1).GetMagnitudeSquared());
159 std::max(minDisplacementSquared, maxDisplacementSquared) > lengthSquared)
162 clusterIntersectionMap[pCluster1].push_back(intersectPosition1);
164 catch (StatusCodeException &statusCodeException)
166 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
167 throw statusCodeException;
178 ClusterList clusterList;
179 for (
const auto &mapEntry : clusterIntersectionMap)
180 clusterList.push_back(mapEntry.first);
183 for (
const Cluster *
const pCluster : clusterList)
185 const CartesianPointVector &inputPositionVector(clusterIntersectionMap.at(pCluster));
187 if (inputPositionVector.empty())
190 TwoDSlidingFitResultMap::const_iterator sIter = slidingFitResultMap.find(pCluster);
191 if (slidingFitResultMap.end() == sIter)
192 throw StatusCodeException(STATUS_CODE_FAILURE);
197 for (CartesianPointVector::const_iterator pIter = inputPositionVector.begin(), pIterEnd = inputPositionVector.end(); pIter != pIterEnd; ++pIter)
199 const CartesianVector &position = *pIter;
200 float rL(0.f), rT(0.f);
207 if (trajectoryPointList.empty())
208 throw StatusCodeException(STATUS_CODE_FAILURE);
210 for (MyTrajectoryPointList::const_iterator qIter = trajectoryPointList.begin(), qIterEnd = trajectoryPointList.end(); qIter != qIterEnd; ++qIter)
212 const CartesianVector &clusterPosition = qIter->second;
213 sortedIntersectionMap[pCluster].push_back(clusterPosition);
222 ClusterList clusterList;
223 for (
const auto &mapEntry : clusterIntersectionMap)
224 clusterList.push_back(mapEntry.first);
227 for (
const Cluster *
const pCluster : clusterList)
229 const CartesianPointVector &inputPositionVector(clusterIntersectionMap.at(pCluster));
231 if (inputPositionVector.empty())
237 bool foundPrevPosition(
false);
238 CartesianVector prevPosition(0.f, 0.f, 0.f);
240 for (CartesianPointVector::const_iterator pIter = inputPositionVector.begin(), pIterEnd = inputPositionVector.end(); pIter != pIterEnd; ++pIter)
242 const CartesianVector &nextPosition = *pIter;
244 if (foundPrevPosition)
246 const CartesianVector averagePosition((nextPosition + prevPosition) * 0.5f);
247 const float displacementSquared((nextPosition - prevPosition).GetMagnitudeSquared());
250 candidatePositionList.push_back(
MyTrajectoryPoint(displacementSquared, averagePosition));
253 prevPosition = nextPosition;
254 foundPrevPosition =
true;
257 if (candidatePositionList.empty())
263 bool foundPrevCandidate(
false);
264 CartesianVector prevCandidate(0.f, 0.f, 0.f);
266 for (MyTrajectoryPointList::const_iterator pIter = candidatePositionList.begin(), pIterEnd = candidatePositionList.end();
267 pIter != pIterEnd; ++pIter)
269 const CartesianVector &nextCandidate = pIter->second;
271 if (foundPrevCandidate)
277 clusterSplittingMap[pCluster].push_back(nextCandidate);
278 prevCandidate = nextCandidate;
279 foundPrevCandidate =
true;
288 if (lhs.first != rhs.first)
289 return (lhs.first < rhs.first);
291 return (lhs.second.GetMagnitudeSquared() > rhs.second.GetMagnitudeSquared());
298 PANDORA_RETURN_RESULT_IF_AND_IF(
299 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterLength",
m_minClusterLength));
301 PANDORA_RETURN_RESULT_IF_AND_IF(
302 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxClusterSeparation",
m_maxClusterSeparation));
304 PANDORA_RETURN_RESULT_IF_AND_IF(
305 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinVertexDisplacement",
m_minVertexDisplacement));
307 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
310 PANDORA_RETURN_RESULT_IF_AND_IF(
311 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinSplitDisplacement",
m_minSplitDisplacement));
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_maxClusterSeparation
Header file for the lar pointing cluster class.
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 GetIntersection(const LArPointingCluster::Vertex &firstVertex, const LArPointingCluster::Vertex &secondVertex, pandora::CartesianVector &intersectPosition, float &firstDisplacement, float &secondDisplacement)
Get intersection of two vertices.
Header file for the overshoot splitting algorithm class.
LArPointingCluster class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterPositionMap
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const Vertex & GetInnerVertex() const
Get the inner vertex.
float m_maxIntersectDisplacement
float m_minVertexDisplacement
void BuildIntersectionMap(const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterPositionMap &clusterIntersectionMap) const
Use sliding fit results to calculate intersections of clusters.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
void FindBestSplitPositions(const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterPositionMap &clusterSplittingMap) const
Determine best split positions based on sliding fit result.
TwoDTrackSplittingAlgorithm class.
std::vector< MyTrajectoryPoint > MyTrajectoryPointList
float m_minSplitDisplacement
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::pair< float, pandora::CartesianVector > MyTrajectoryPoint
static bool SortByHitProjection(const MyTrajectoryPoint &lhs, const MyTrajectoryPoint &rhs)
Sort pfos by number of constituent hits.
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
void PopulateSplitPositionMap(const ClusterPositionMap &sortedIntersectionMap, ClusterPositionMap &clusterSplittingMap) const
Select split positions from sorted list of candidate positions.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
TwoDSlidingFitResult class.
void BuildSortedIntersectionMap(const TwoDSlidingFitResultMap &slidingFitResultMap, const ClusterPositionMap &clusterIntersectionMap, ClusterPositionMap &sortedIntersectionMap) const
Use intersection points to decide on splitting points.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.