38 const ClusterList *pClusterList = NULL;
39 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*
this, pClusterList));
50 ClusterSet splitClusters;
52 for (ClusterVector::const_iterator bIter = clusterVector.begin(), bIterEnd1 = clusterVector.end(); bIter != bIterEnd1; ++bIter)
54 if (splitClusters.count(*bIter) > 0)
57 TwoDSlidingFitResultMap::const_iterator bFitIter = slidingFitResultMap.find(*bIter);
59 if (slidingFitResultMap.end() == bFitIter)
62 const TwoDSlidingFitResult &branchSlidingFitResult(bFitIter->second);
65 CartesianVector splitPosition(0.f, 0.f, 0.f);
66 CartesianVector splitDirection1(0.f, 0.f, 0.f);
67 CartesianVector splitDirection2(0.f, 0.f, 0.f);
69 if (STATUS_CODE_SUCCESS != this->
FindBestSplitPosition(branchSlidingFitResult, splitPosition, splitDirection1, splitDirection2))
73 TwoDSlidingFitResultMap::const_iterator bestReplacementIter1(slidingFitResultMap.end());
74 TwoDSlidingFitResultMap::const_iterator bestReplacementIter2(slidingFitResultMap.end());
79 for (ClusterVector::const_iterator rIter = clusterVector.begin(), rIterEnd = clusterVector.end(); rIter != rIterEnd; ++rIter)
81 if (splitClusters.count(*rIter) > 0)
84 TwoDSlidingFitResultMap::const_iterator rFitIter = slidingFitResultMap.find(*rIter);
86 if (slidingFitResultMap.end() == rFitIter)
89 const TwoDSlidingFitResult &replacementSlidingFitResult(rFitIter->second);
91 if (branchSlidingFitResult.GetCluster() == replacementSlidingFitResult.GetCluster())
94 float lengthSquared1(std::numeric_limits<float>::max());
95 float lengthSquared2(std::numeric_limits<float>::max());
97 if (STATUS_CODE_SUCCESS != this->
ConfirmSplitPosition(branchSlidingFitResult, replacementSlidingFitResult, splitPosition,
98 splitDirection1, splitDirection2, lengthSquared1, lengthSquared2))
101 if (lengthSquared1 < bestLengthSquared1)
103 bestLengthSquared1 = lengthSquared1;
104 bestReplacementIter1 = rFitIter;
107 if (lengthSquared2 < bestLengthSquared2)
109 bestLengthSquared2 = lengthSquared2;
110 bestReplacementIter2 = rFitIter;
114 const Cluster *pReplacementCluster1 = NULL;
115 const Cluster *pReplacementCluster2 = NULL;
117 if (slidingFitResultMap.end() != bestReplacementIter1)
118 pReplacementCluster1 = bestReplacementIter1->first;
120 if (slidingFitResultMap.end() != bestReplacementIter2)
121 pReplacementCluster2 = bestReplacementIter2->first;
123 if (NULL == pReplacementCluster1 && NULL == pReplacementCluster2)
126 const Cluster *
const pBranchCluster = branchSlidingFitResult.GetCluster();
129 if (pReplacementCluster1 && pReplacementCluster2)
131 if (!(this->
IdentifyCrossedTracks(pBranchCluster, pReplacementCluster1, pReplacementCluster2, splitPosition)))
134 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
135 this->
PerformDoubleSplit(pBranchCluster, pReplacementCluster1, pReplacementCluster2, splitPosition, splitDirection1, splitDirection2));
138 else if (pReplacementCluster1)
140 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
141 this->
PerformSingleSplit(pBranchCluster, pReplacementCluster1, splitPosition, splitDirection1, splitDirection2));
143 else if (pReplacementCluster2)
145 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
146 this->
PerformSingleSplit(pBranchCluster, pReplacementCluster2, splitPosition, splitDirection2, splitDirection1));
150 if (pReplacementCluster1)
151 splitClusters.insert(pReplacementCluster1);
153 if (pReplacementCluster2)
154 splitClusters.insert(pReplacementCluster2);
156 splitClusters.insert(pBranchCluster);
159 return STATUS_CODE_SUCCESS;
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...
then if[["$THISISATEST"==1]]
bool IdentifyCrossedTracks(const pandora::Cluster *const pBranchCluster, const pandora::Cluster *const pReplacementCluster1, const pandora::Cluster *const pReplacementCluster2, const pandora::CartesianVector &splitPosition) const
Identify crossed tracks formed from the branch cluster and its replacement cluster.
pandora::StatusCode PerformSingleSplit(const pandora::Cluster *const pBranchCluster, const pandora::Cluster *const pReplacementCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &forwardDirection, const pandora::CartesianVector &backwardDirection) const
Split a branch cluster for case of one replacement cluster.
float m_maxLongitudinalDisplacementSquared
longitudinal displacement squared
pandora::StatusCode PerformDoubleSplit(const pandora::Cluster *const pBranchCluster, const pandora::Cluster *const pReplacementCluster1, const pandora::Cluster *const pReplacementCluster2, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection1, const pandora::CartesianVector &splitDirection2) const
Split a branch cluster for case of two replacement clusters.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
void BuildSlidingFitResultMap(const pandora::ClusterVector &clusterVector, TwoDSlidingFitResultMap &slidingFitResultMap) const
Build the map of sliding fit results.
pandora::StatusCode ConfirmSplitPosition(const TwoDSlidingFitResult &branchSlidingFitResult, const TwoDSlidingFitResult &replacementSlidingFitResult, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection1, const pandora::CartesianVector &splitDirection2, float &lengthSquared1, float &lengthSquared2) const
Find a second replacement cluster that aligns with the scatter of the first branch cluster...
std::vector< art::Ptr< recob::Cluster > > ClusterVector
pandora::StatusCode FindBestSplitPosition(const TwoDSlidingFitResult &slidingFitResult, pandora::CartesianVector &splitPosition, pandora::CartesianVector &splitDirection1, pandora::CartesianVector &splitDirection2) const
Find the position of greatest scatter along a sliding linear fit.