22 m_maxLoopIterations(10),
23 m_minClusterLengthSum(75.f),
24 m_minSeparationDistance(0.f),
25 m_minDirectionDeviationCosAngle(0.99f),
26 m_maxPredictedMergePointOffset(5.f),
27 m_distanceToLine(0.35f),
28 m_boundaryTolerance(2.f)
49 unsigned int loopIterations(0);
72 const ClusterList::const_iterator upstreamIter(
73 std::find(createdMainTrackClusters.begin(), createdMainTrackClusters.end(), clusterAssociation.
GetUpstreamCluster()));
74 if (upstreamIter != createdMainTrackClusters.end())
75 createdMainTrackClusters.erase(upstreamIter);
77 const ClusterList::const_iterator downstreamIter(
78 std::find(createdMainTrackClusters.begin(), createdMainTrackClusters.end(), clusterAssociation.
GetDownstreamCluster()));
79 if (downstreamIter != createdMainTrackClusters.end())
80 createdMainTrackClusters.erase(downstreamIter);
82 createdMainTrackClusters.push_back(
83 this->
CreateMainTrack(clusterAssociation, clusterToCaloHitListMap, pClusterList, clusterVector, slidingFitResultMapPair));
86 return STATUS_CODE_SUCCESS;
94 bool foundAssociation(
false);
98 for (ClusterVector::const_iterator currentIter = clusterVector.begin(); currentIter != clusterVector.end(); ++currentIter)
100 const Cluster *
const pCurrentCluster(*currentIter);
102 const TwoDSlidingFitResultMap::const_iterator currentMicroFitIter(slidingFitResultMapPair.first->find(pCurrentCluster));
103 if (currentMicroFitIter == slidingFitResultMapPair.first->end())
106 const TwoDSlidingFitResultMap::const_iterator currentMacroFitIter(slidingFitResultMapPair.second->find(pCurrentCluster));
107 if (currentMacroFitIter == slidingFitResultMapPair.second->end())
110 for (ClusterVector::const_iterator testIter = std::next(currentIter); testIter != clusterVector.end(); ++testIter)
112 const Cluster *
const pTestCluster(*testIter);
118 const TwoDSlidingFitResultMap::const_iterator testMicroFitIter(slidingFitResultMapPair.first->find(pTestCluster));
119 if (testMicroFitIter == slidingFitResultMapPair.first->end())
122 const TwoDSlidingFitResultMap::const_iterator testMacroFitIter(slidingFitResultMapPair.second->find(pTestCluster));
123 if (testMacroFitIter == slidingFitResultMapPair.second->end())
129 const float currentMinLayerZ(currentMacroFitIter->second.GetGlobalMinLayerPosition().GetZ()),
130 currentMaxLayerZ(currentMacroFitIter->second.GetGlobalMaxLayerPosition().GetZ());
131 const float testMinLayerZ(testMacroFitIter->second.GetGlobalMinLayerPosition().GetZ()),
132 testMaxLayerZ(testMacroFitIter->second.GetGlobalMaxLayerPosition().GetZ());
134 if (((currentMinLayerZ > testMinLayerZ) && (currentMaxLayerZ < testMaxLayerZ)) ||
135 ((testMinLayerZ > currentMinLayerZ) && (testMaxLayerZ < currentMaxLayerZ)))
138 CartesianVector currentMergePoint(0.f, 0.f, 0.f), testMergePoint(0.f, 0.f, 0.f), currentMergeDirection(0.f, 0.f, 0.f),
139 testMergeDirection(0.f, 0.f, 0.f);
141 !isCurrentUpstream, currentMergePoint, currentMergeDirection) ||
142 !this->GetClusterMergingCoordinates(testMicroFitIter->second, testMacroFitIter->second, currentMacroFitIter->second,
143 isCurrentUpstream, testMergePoint, testMergeDirection))
148 if ((isCurrentUpstream && !this->
AreClustersAssociated(currentMergePoint, currentMergeDirection, testMergePoint, testMergeDirection)) ||
149 (!isCurrentUpstream && !this->
AreClustersAssociated(testMergePoint, testMergeDirection, currentMergePoint, currentMergeDirection)))
154 if (isCurrentUpstream)
157 currentMergePoint, currentMergeDirection, testMergePoint, testMergeDirection * (-1.f), pCurrentCluster, pTestCluster);
162 testMergePoint, testMergeDirection, currentMergePoint, currentMergeDirection * (-1.f), pTestCluster, pCurrentCluster);
165 foundAssociation =
true;
166 maxLength = lengthSum;
170 return foundAssociation;
178 if (downstreamPoint.
GetZ() < upstreamPoint.
GetZ())
181 const float separationDistance(std::sqrt(upstreamPoint.
GetDistanceSquared(downstreamPoint)));
188 const CartesianVector predictedDownstreamPoint(upstreamPoint + (upstreamDirection * separationDistance));
189 const float predictedDownstreamOffset((predictedDownstreamPoint - downstreamPoint).GetMagnitude());
194 const CartesianVector predictedUpstreamPoint(downstreamPoint - (downstreamDirection * separationDistance));
195 const float predictedUpstreamOffset((predictedUpstreamPoint - upstreamPoint).GetMagnitude());
208 for (
const Cluster *
const pMainTrackCluster : createdMainTrackClusters)
211 protectedClusters.push_back(pMainTrackCluster);
219 if (extrapolatedHitVector.empty())
240 const Cluster *
const pConsideredCluster(upstreamCluster->GetNCaloHits() > downstreamCluster->
GetNCaloHits() ? downstreamCluster : upstreamCluster);
252 for (
const auto &entry : clusterToCaloHitListMap)
255 showerClustersToFragment.push_back(entry.first);
261 const Cluster *
const pMainTrackCluster(
263 clusterToCaloHitListMap, remnantClusterList, *slidingFitResultMapPair.first, *slidingFitResultMapPair.second));
264 const Cluster *
const pClusterToDelete(
266 clusterToCaloHitListMap, remnantClusterList, *slidingFitResultMapPair.first, *slidingFitResultMapPair.second));
270 for (
const Cluster *
const pShowerCluster : showerClustersToFragment)
272 const CaloHitList &caloHitsToMerge(clusterToCaloHitListMap.at(pShowerCluster));
273 this->
AddHitsToMainTrack(pMainTrackCluster, pShowerCluster, caloHitsToMerge, clusterAssociation, remnantClusterList);
280 ClusterList modifiedClusters(showerClustersToFragment.begin(), showerClustersToFragment.end());
283 createdClusters.push_back(pMainTrackCluster);
286 return pMainTrackCluster;
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the lar hit width helper class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Header file for the track merge refinement class.
static pandora::StatusCode GetCurrentList(const pandora::Algorithm &algorithm, const T *&pT)
Get the current list.
static pandora::StatusCode MergeAndDeleteClusters(const pandora::Algorithm &algorithm, const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete)
Merge two clusters in the current list, enlarging one cluster and deleting the second.
ClusterAssociation class.
const pandora::CartesianVector GetUpstreamMergePoint() const
Returns the upstream cluster merge point.
const pandora::CartesianVector GetDownstreamMergePoint() const
Returns the downstream cluster merge point.
ClusterPairAssociation class.
const pandora::Cluster * GetUpstreamCluster() const
Returns the address of the upstream cluster.
const pandora::Cluster * GetDownstreamCluster() const
Returns the address of the downstream cluster.
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,...
static bool SortByPosition(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by position, then pulse-height.
static float GetLength(const pandora::Cluster *const pCluster)
Get length of cluster.
const pandora::Cluster * CreateMainTrack(const ClusterPairAssociation &clusterAssociation, const ClusterToCaloHitListMap &clusterToCaloHitListMap, const pandora::ClusterList *pClusterList, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
Refine the cluster endpoints and merge together the associated clusters alongside any extrapolated hi...
TrackMergeRefinementAlgorithm()
Default constructor.
float m_minClusterLengthSum
The threshold cluster and associated cluster length sum.
float m_boundaryTolerance
The maximum allowed distance of an extremal extrapolate hit to a cluster merge point.
float m_maxPredictedMergePointOffset
The threshold separation distance between the predicted and true cluster merge points.
bool AreClustersAssociated(const pandora::CartesianVector &upstreamPoint, const pandora::CartesianVector &upstreamDirection, const pandora::CartesianVector &downstreamPoint, const pandora::CartesianVector &downstreamDirection) const
Whether two clusters are assoicated to one another.
bool AreExtrapolatedHitsNearBoundaries(const pandora::CaloHitVector &extrapolatedHitVector, ClusterAssociation &clusterAssociation) const
Check the separation of the extremal extrapolated hits with the cluster merge points or,...
void ConsiderClusterAssociation(const ClusterPairAssociation &clusterAssociation, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
Remove the cluster association from the cluster vector so that the same cluster pair is not considere...
float m_distanceToLine
The threshold hit distance of an extrapolated hit from the segment connecting line.
unsigned int m_maxLoopIterations
The maximum number of main loop iterations.
bool FindBestClusterAssociation(const pandora::ClusterVector &clusterVector, const SlidingFitResultMapPair &slidingFitResultMapPair, ClusterPairAssociation &clusterAssociation) const
Find the best cluster association.
float m_minSeparationDistance
The threshold separation distance between associated clusters.
void GetUnavailableProtectedClusters(const ClusterPairAssociation &clusterAssociation, const pandora::ClusterList &createdMainTrackClusters, pandora::ClusterList &unavailableProtectedClusters) const
Obtain a list of clusters whos hits are protected and cannot be reassigned.
pandora::StatusCode Run()
Run the algorithm.
float m_minDirectionDeviationCosAngle
The threshold cos opening angle of the associated cluster directions.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
bool GetClusterMergingCoordinates(const TwoDSlidingFitResult &clusterMicroFitResult, const TwoDSlidingFitResult &clusterMacroFitResult, const TwoDSlidingFitResult &associatedMacroFitResult, const bool isEndUpstream, pandora::CartesianVector &clusterMergePosition, pandora::CartesianVector &clusterMergeDirection) const
Get the merging coordinate and direction for an input cluster with respect to an associated cluster.
std::pair< TwoDSlidingFitResultMap *, TwoDSlidingFitResultMap * > SlidingFitResultMapPair
void AddHitsToMainTrack(const pandora::Cluster *const pMainTrackCluster, const pandora::Cluster *const pShowerTrackCluster, const pandora::CaloHitList &caloHitsToMerge, const ClusterAssociation &clusterAssociation, pandora::ClusterList &remnantClusterList) const
Remove the hits from a shower cluster that belong to the main track and add them into the main track ...
std::unordered_map< const pandora::Cluster *, pandora::CaloHitList > ClusterToCaloHitListMap
const pandora::Cluster * RemoveOffAxisHitsFromTrack(const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const bool isEndUpstream, const ClusterToCaloHitListMap &clusterToCaloHitListMap, pandora::ClusterList &remnantClusterList, TwoDSlidingFitResultMap µSlidingFitResultMap, TwoDSlidingFitResultMap ¯oSlidingFitResultMap) const
Remove any hits in the upstream/downstream cluster that lie off of the main track axis (i....
bool IsNearBoundary(const pandora::CaloHit *const pCaloHit, const pandora::CartesianVector &boundaryPosition2D, const float boundaryTolerance) const
Check whether a hit is close to a boundary point.
void GetHitsInBoundingBox(const pandora::CartesianVector &firstCorner, const pandora::CartesianVector &secondCorner, const pandora::ClusterList *const pClusterList, ClusterToCaloHitListMap &clusterToCaloHitListMap, const pandora::ClusterList &unavailableProtectedClusters=pandora::ClusterList(), const float distanceToLine=-1.f) const
Find the unprotected hits that are contained within a defined box with the option to apply a cut on t...
void RemoveClusterFromContainers(const pandora::Cluster *const pClustertoRemove, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
Remove a cluster from the cluster vector and sliding fit maps.
void UpdateContainers(const pandora::ClusterList &clustersToAdd, const pandora::ClusterList &clustersToDelete, const T sortFunction, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
Remove deleted clusters from the cluster vector and sliding fit maps and add in created clusters that...
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)=0
Read the algorithm settings.
void InitialiseContainers(const pandora::ClusterList *pClusterList, const T sortFunction, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
Fill the cluster vector and sliding fit maps with clusters that are determined to be track-like.
void ProcessRemnantClusters(const pandora::ClusterList &remnantClusterList, const pandora::Cluster *const pMainTrackCluster, const pandora::ClusterList *const pClusterList, pandora::ClusterList &createdClusters) const
Process the remnant clusters separating those that stradle the main track.
bool AreExtrapolatedHitsGood(const ClusterToCaloHitListMap &clusterToCaloHitListMap, ClusterAssociation &clusterAssociation) const
Perform topological checks on the collected hits to ensure no gaps are present.
float GetCosOpeningAngle(const CartesianVector &rhs) const
Get the cosine of the opening angle of the cartesian vector with respect to a second cartesian vector...
float GetDistanceSquared(const CartesianVector &rhs) const
Get the distance squared of a cartesian vector with respect to a second cartesian vector.
float GetZ() const
Get the cartesian z coordinate.
unsigned int GetNCaloHits() const
Get the number of calo hits in the cluster.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
std::vector< const CaloHit * > CaloHitVector
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.