9 #include "Pandora/AlgorithmHeaders.h"
21 TwoDSlidingFitSplittingAndSwitchingAlgorithm::TwoDSlidingFitSplittingAndSwitchingAlgorithm() :
22 m_halfWindowLayers(25),
23 m_minClusterLength(10.f)
31 const ClusterList *pClusterList = NULL;
32 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*
this, pClusterList));
43 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->
PreparationStep(clusterVector));
46 for (ClusterVector::iterator iter1 = clusterVector.begin(), iterEnd1 = clusterVector.end(); iter1 != iterEnd1; ++iter1)
51 TwoDSlidingFitResultMap::iterator sIter1 = slidingFitResultMap.find(*iter1);
53 if (slidingFitResultMap.end() == sIter1)
58 for (ClusterVector::iterator iter2 = iter1, iterEnd2 = iterEnd1; iter2 != iterEnd2; ++iter2)
63 TwoDSlidingFitResultMap::iterator sIter2 = slidingFitResultMap.find(*iter2);
65 if (slidingFitResultMap.end() == sIter2)
73 CartesianVector splitPosition(0.f, 0.f, 0.f);
74 CartesianVector firstDirection(0.f, 0.f, 0.f);
75 CartesianVector secondDirection(0.f, 0.f, 0.f);
77 if (STATUS_CODE_SUCCESS != this->
FindBestSplitPosition(slidingFitResult1, slidingFitResult2, splitPosition, firstDirection, secondDirection))
80 const Cluster *
const pCluster1 = slidingFitResult1.
GetCluster();
81 const Cluster *
const pCluster2 = slidingFitResult2.
GetCluster();
83 if (STATUS_CODE_SUCCESS != this->
ReplaceClusters(pCluster1, pCluster2, splitPosition, firstDirection, secondDirection))
86 slidingFitResultMap.erase(sIter1);
87 slidingFitResultMap.erase(sIter2);
103 return STATUS_CODE_SUCCESS;
110 return STATUS_CODE_SUCCESS;
117 for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
119 const Cluster *
const pCluster = *iter;
124 clusterVector.push_back(pCluster);
137 for (ClusterVector::const_iterator iter = clusterVector.begin(), iterEnd = clusterVector.end(); iter != iterEnd; ++iter)
139 if (slidingFitResultMap.end() == slidingFitResultMap.find(*iter))
145 if (!slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(*iter, slidingFitResult)).second)
146 throw StatusCodeException(STATUS_CODE_FAILURE);
148 catch (StatusCodeException &statusCodeException)
150 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
151 throw statusCodeException;
160 const CartesianVector &splitDirection, CaloHitList &firstCaloHitList, CaloHitList &secondCaloHitList)
const
162 CaloHitList caloHitsToDistribute;
163 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitsToDistribute);
165 for (CaloHitList::const_iterator iter = caloHitsToDistribute.begin(), iterEnd = caloHitsToDistribute.end(); iter != iterEnd; ++iter)
167 const CaloHit *
const pCaloHit = *iter;
169 if (splitDirection.GetDotProduct((pCaloHit->GetPositionVector() - splitPosition)) > 0.f)
171 firstCaloHitList.push_back(pCaloHit);
175 secondCaloHitList.push_back(pCaloHit);
183 const CartesianVector &splitPosition,
const CartesianVector &firstDirection,
const CartesianVector &secondDirection)
const
188 this->
SplitCluster(pCluster1, splitPosition, firstDirection, firstParameters.m_caloHitList, secondParameters.m_caloHitList);
189 this->
SplitCluster(pCluster2, splitPosition, secondDirection, secondParameters.m_caloHitList, firstParameters.m_caloHitList);
191 if (firstParameters.m_caloHitList.empty() || secondParameters.m_caloHitList.empty())
192 return STATUS_CODE_NOT_ALLOWED;
195 ClusterList clusterList;
196 clusterList.push_back(pCluster1);
197 clusterList.push_back(pCluster2);
199 std::string clusterListToSaveName, clusterListToDeleteName;
200 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
201 PandoraContentApi::InitializeFragmentation(*
this, clusterList, clusterListToDeleteName, clusterListToSaveName));
204 const Cluster *pFirstCluster(NULL), *pSecondCluster(NULL);
205 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*
this, firstParameters, pFirstCluster));
206 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*
this, secondParameters, pSecondCluster));
209 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*
this, clusterListToSaveName, clusterListToDeleteName));
211 return STATUS_CODE_SUCCESS;
218 PANDORA_RETURN_RESULT_IF_AND_IF(
219 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HalfWindowLayers",
m_halfWindowLayers));
221 PANDORA_RETURN_RESULT_IF_AND_IF(
222 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterLength",
m_minClusterLength));
224 return STATUS_CODE_SUCCESS;
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.
unsigned int m_halfWindowLayers
half window layers for sliding linear fot
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the geometry helper class.
virtual pandora::StatusCode FindBestSplitPosition(const TwoDSlidingFitResult &slidingFit1, const TwoDSlidingFitResult &slidingFit2, pandora::CartesianVector &splitPosition, pandora::CartesianVector &direction1, pandora::CartesianVector &direction2) const =0
Find the best split position and direction for a pair of clusters.
float m_minClusterLength
minimum length of clusters
virtual pandora::StatusCode TidyUpStep()
Tidy up any information cached in e.g. the preparation step.
pandora::StatusCode ReplaceClusters(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &firstDirection, const pandora::CartesianVector &secondDirection) const
Replace crossed clusters with un-crossed clusters.
Header file for the cluster helper class.
void SplitCluster(const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection, pandora::CaloHitList &firstCaloHitList, pandora::CaloHitList &secondCaloHitList) const
Split cluster at a given position and direction.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
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...
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
virtual pandora::StatusCode Run()
virtual pandora::StatusCode PreparationStep(const pandora::ClusterVector &clusterVector)
Perform any preparatory actions, such as caching information for subsequent expensive calculations...
void BuildSlidingFitResultMap(const pandora::ClusterVector &clusterVector, TwoDSlidingFitResultMap &slidingFitResultMap) const
Build the map of sliding fit results.
Header file for the two dimensional sliding fit splitting and switching algorithm class...
TwoDSlidingFitResult class.