All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Member Functions | Private Attributes | List of all members
lar_content::TrackMergeRefinementAlgorithm Class Reference

TrackMergeRefinementAlgorithm class. More...

#include <TrackMergeRefinementAlgorithm.h>

Inheritance diagram for lar_content::TrackMergeRefinementAlgorithm:
lar_content::TrackRefinementBaseAlgorithm

Public Member Functions

 TrackMergeRefinementAlgorithm ()
 Default constructor. More...
 
- Public Member Functions inherited from lar_content::TrackRefinementBaseAlgorithm
 TrackRefinementBaseAlgorithm ()
 Default constructor. More...
 
template<typename T >
void InitialiseContainers (const ClusterList *pClusterList, const T sortFunction, ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
 
template<typename T >
void UpdateContainers (const ClusterList &clustersToAdd, const ClusterList &clustersToDelete, const T sortFunction, ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
 

Private Member Functions

pandora::StatusCode Run ()
 
pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
bool FindBestClusterAssociation (const pandora::ClusterVector &clusterVector, const SlidingFitResultMapPair &slidingFitResultMapPair, ClusterPairAssociation &clusterAssociation) const
 Find the best cluster association. More...
 
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. More...
 
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. More...
 
bool AreExtrapolatedHitsNearBoundaries (const pandora::CaloHitVector &extrapolatedHitVector, ClusterAssociation &clusterAssociation) const
 Check the separation of the extremal extrapolated hits with the cluster merge points or, in the case of no hits, the cluster merge point separation. More...
 
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 considered again. More...
 
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 hits. More...
 

Private Attributes

unsigned int m_maxLoopIterations
 The maximum number of main loop iterations. More...
 
float m_minClusterLengthSum
 The threshold cluster and associated cluster length sum. More...
 
float m_minSeparationDistance
 The threshold separation distance between associated clusters. More...
 
float m_minDirectionDeviationCosAngle
 The threshold cos opening angle of the associated cluster directions. More...
 
float m_maxPredictedMergePointOffset
 The threshold separation distance between the predicted and true cluster merge points. More...
 
float m_distanceToLine
 The threshold hit distance of an extrapolated hit from the segment connecting line. More...
 
float m_boundaryTolerance
 The maximum allowed distance of an extremal extrapolate hit to a cluster merge point. More...
 

Additional Inherited Members

- Protected Types inherited from lar_content::TrackRefinementBaseAlgorithm
typedef std::pair
< TwoDSlidingFitResultMap
*, TwoDSlidingFitResultMap * > 
SlidingFitResultMapPair
 
typedef std::unordered_map
< const pandora::Cluster
*, pandora::CaloHitList > 
ClusterToCaloHitListMap
 
- Protected Member Functions inherited from lar_content::TrackRefinementBaseAlgorithm
template<typename T >
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. More...
 
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. More...
 
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 the distance to the connecting line. More...
 
bool IsInBoundingBox (const float minX, const float maxX, const float minZ, const float maxZ, const pandora::CartesianVector &hitPosition) const
 check whether a hit is contained within a defined square region More...
 
bool IsCloseToLine (const pandora::CartesianVector &hitPosition, const pandora::CartesianVector &lineStart, const pandora::CartesianVector &lineDirection, const float distanceToLine) const
 Check whether a hit is close to a line. More...
 
bool AreExtrapolatedHitsGood (const ClusterToCaloHitListMap &clusterToCaloHitListMap, ClusterAssociation &clusterAssociation) const
 Perform topological checks on the collected hits to ensure no gaps are present. More...
 
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. More...
 
bool IsTrackContinuous (const ClusterAssociation &clusterAssociation, const pandora::CaloHitVector &extrapolatedCaloHitVector) const
 Check whether the extrapolatedCaloHitVector contains a continuous line of hits between the cluster merge points. More...
 
void GetTrackSegmentBoundaries (const ClusterAssociation &clusterAssociation, pandora::CartesianPointVector &trackSegmentBoundaries) const
 Obtain the segment boundaries of the connecting line to test whether extrapolated hits are continuous. More...
 
void RepositionIfInGap (const pandora::CartesianVector &mergeDirection, pandora::CartesianVector &trackPoint) const
 Move an input position to the higher line gap edge if it lies within a gap. More...
 
float DistanceInGap (const pandora::CartesianVector &upstreamPoint, const pandora::CartesianVector &downstreamPoint, const pandora::CartesianVector &connectingLine, pandora::DetectorGapList &consideredGaps) const
 Calculate the track length between two points that lies in gaps. More...
 
bool IsInLineSegment (const pandora::CartesianVector &lowerBoundary, const pandora::CartesianVector &upperBoundary, const pandora::CartesianVector &point) const
 Whether a position falls within a specified segment of the cluster connecting line. More...
 
const pandora::Cluster * RemoveOffAxisHitsFromTrack (const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const bool isEndUpstream, const ClusterToCaloHitListMap &clusterToCaloHitListMap, pandora::ClusterList &remnantClusterList, TwoDSlidingFitResultMap &microSlidingFitResultMap, TwoDSlidingFitResultMap &macroSlidingFitResultMap) const
 Remove any hits in the upstream/downstream cluster that lie off of the main track axis (i.e. clustering errors) More...
 
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 cluster. More...
 
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. More...
 
bool AddToNearestCluster (const pandora::Cluster *const pClusterToMerge, const pandora::Cluster *const pMainTrackCluster, const pandora::ClusterList *const pClusterList) const
 Add a cluster to the nearest cluster satisfying separation distance thresholds. More...
 
bool IsClusterRemnantDisconnected (const pandora::Cluster *const pRemnantCluster) const
 Whether a remnant cluster is considered to be disconnected and therefore should undergo further fragmentation. More...
 
void FragmentRemnantCluster (const pandora::Cluster *const pRemnantCluster, pandora::ClusterList &fragmentedClusterList) const
 Fragment a cluster using simple hit separation logic. More...
 
template<typename T >
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 are determined to be track-like. More...
 
void RemoveClusterFromContainers (const pandora::Cluster *const pClustertoRemove, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
 Remove a cluster from the cluster vector and sliding fit maps. More...
 
- Protected Attributes inherited from lar_content::TrackRefinementBaseAlgorithm
float m_minClusterLength
 The minimum length of a considered cluster. More...
 
unsigned int m_microSlidingFitWindow
 The sliding fit window used in the fits contained within the microSlidingFitResultMap. More...
 
unsigned int m_macroSlidingFitWindow
 The sliding fit window used in the fits contained within the macroSlidingFitResultMap. More...
 
float m_stableRegionClusterFraction
 The threshold fraction of fit contributing layers which defines the stable region. More...
 
float m_mergePointMinCosAngleDeviation
 The threshold cos opening angle between the cluster local gradient and the associated cluster global gradient used to determine merge points. More...
 
float m_minHitFractionForHitRemoval
 The threshold fraction of hits to be removed from the cluster for hit removal to proceed. More...
 
float m_maxDistanceFromMainTrack
 The threshold distance for a hit to be added to the main track. More...
 
float m_maxHitDistanceFromCluster
 The threshold separation between a hit and cluster for the hit to be merged into the cluster. More...
 
float m_maxHitSeparationForConnectedCluster
 The maximum separation between two adjacent (in z) hits in a connected cluster. More...
 
unsigned int m_maxTrackGaps
 The maximum number of graps allowed in the extrapolated hit vector. More...
 
float m_lineSegmentLength
 The length of a track gap. More...
 
bool m_hitWidthMode
 Whether to consider the width of hits. More...
 

Detailed Description

TrackMergeRefinementAlgorithm class.

Definition at line 18 of file TrackMergeRefinementAlgorithm.h.

Constructor & Destructor Documentation

lar_content::TrackMergeRefinementAlgorithm::TrackMergeRefinementAlgorithm ( )

Default constructor.

Definition at line 21 of file TrackMergeRefinementAlgorithm.cc.

21  :
27  m_distanceToLine(0.35f),
29 {
30 }
float m_maxPredictedMergePointOffset
The threshold separation distance between the predicted and true cluster merge points.
float m_minClusterLengthSum
The threshold cluster and associated cluster length sum.
float m_minSeparationDistance
The threshold separation distance between associated clusters.
unsigned int m_maxLoopIterations
The maximum number of main loop iterations.
float m_boundaryTolerance
The maximum allowed distance of an extremal extrapolate hit to a cluster merge point.
float m_distanceToLine
The threshold hit distance of an extrapolated hit from the segment connecting line.
float m_minDirectionDeviationCosAngle
The threshold cos opening angle of the associated cluster directions.

Member Function Documentation

bool lar_content::TrackMergeRefinementAlgorithm::AreClustersAssociated ( const pandora::CartesianVector &  upstreamPoint,
const pandora::CartesianVector &  upstreamDirection,
const pandora::CartesianVector &  downstreamPoint,
const pandora::CartesianVector &  downstreamDirection 
) const
private

Whether two clusters are assoicated to one another.

Parameters
upstreamPointthe merge point of the upstream cluster
upstreamDirectionthe local direction of the upstream cluster at the merge point
downstreamPointthe merge point of the downstream cluster
downstreamDirectionthe local direction of the downstrean cluster at the merge point
Returns
whether the clusters are associated

Definition at line 175 of file TrackMergeRefinementAlgorithm.cc.

177 {
178  if (downstreamPoint.GetZ() < upstreamPoint.GetZ())
179  return false;
180 
181  const float separationDistance(std::sqrt(upstreamPoint.GetDistanceSquared(downstreamPoint)));
182  if (separationDistance < m_minSeparationDistance)
183  return false;
184 
185  if (upstreamDirection.GetCosOpeningAngle(downstreamDirection) < m_minDirectionDeviationCosAngle)
186  return false;
187 
188  const CartesianVector predictedDownstreamPoint(upstreamPoint + (upstreamDirection * separationDistance));
189  const float predictedDownstreamOffset((predictedDownstreamPoint - downstreamPoint).GetMagnitude());
190 
191  if (predictedDownstreamOffset > m_maxPredictedMergePointOffset)
192  return false;
193 
194  const CartesianVector predictedUpstreamPoint(downstreamPoint - (downstreamDirection * separationDistance));
195  const float predictedUpstreamOffset((predictedUpstreamPoint - upstreamPoint).GetMagnitude());
196 
197  if (predictedUpstreamOffset > m_maxPredictedMergePointOffset)
198  return false;
199 
200  return true;
201 }
float m_maxPredictedMergePointOffset
The threshold separation distance between the predicted and true cluster merge points.
float m_minSeparationDistance
The threshold separation distance between associated clusters.
float m_minDirectionDeviationCosAngle
The threshold cos opening angle of the associated cluster directions.
bool lar_content::TrackMergeRefinementAlgorithm::AreExtrapolatedHitsNearBoundaries ( const pandora::CaloHitVector &  extrapolatedHitVector,
ClusterAssociation clusterAssociation 
) const
privatevirtual

Check the separation of the extremal extrapolated hits with the cluster merge points or, in the case of no hits, the cluster merge point separation.

Parameters
extrapolatedHitVectorthe extrapolated hit vector (ordered closest hit to the upstream merge point -> furthest hit)
clusterAssociationthe cluster association
Returns
whether the checks pass

Implements lar_content::TrackRefinementBaseAlgorithm.

Definition at line 217 of file TrackMergeRefinementAlgorithm.cc.

218 {
219  if (extrapolatedHitVector.empty())
220  {
221  const float separationDistance((clusterAssociation.GetUpstreamMergePoint() - clusterAssociation.GetDownstreamMergePoint()).GetMagnitude());
222  return (separationDistance < m_boundaryTolerance);
223  }
224 
225  if (!this->IsNearBoundary(extrapolatedHitVector.front(), clusterAssociation.GetUpstreamMergePoint(), m_boundaryTolerance))
226  return false;
227 
228  if (!this->IsNearBoundary(extrapolatedHitVector.back(), clusterAssociation.GetDownstreamMergePoint(), m_boundaryTolerance))
229  return false;
230 
231  return true;
232 }
float m_boundaryTolerance
The maximum allowed distance of an extremal extrapolate hit to a cluster merge point.
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 lar_content::TrackMergeRefinementAlgorithm::ConsiderClusterAssociation ( const ClusterPairAssociation clusterAssociation,
pandora::ClusterVector &  clusterVector,
SlidingFitResultMapPair slidingFitResultMapPair 
) const
private

Remove the cluster association from the cluster vector so that the same cluster pair is not considered again.

Parameters
clusterAssociationthe cluster pair association
clusterVectorthe vector of clusters considered in future iterations of the algorithm
slidingFitResultMapPairthe {micro, macro} pair of [cluster -> TwoDSlidingFitResult] maps

Definition at line 236 of file TrackMergeRefinementAlgorithm.cc.

238 {
239  const Cluster *const upstreamCluster(clusterAssociation.GetUpstreamCluster()), *const downstreamCluster(clusterAssociation.GetDownstreamCluster());
240  const Cluster *const pConsideredCluster(upstreamCluster->GetNCaloHits() > downstreamCluster->GetNCaloHits() ? downstreamCluster : upstreamCluster);
241  RemoveClusterFromContainers(pConsideredCluster, clusterVector, slidingFitResultMapPair);
242 }
void RemoveClusterFromContainers(const pandora::Cluster *const pClustertoRemove, pandora::ClusterVector &clusterVector, SlidingFitResultMapPair &slidingFitResultMapPair) const
Remove a cluster from the cluster vector and sliding fit maps.
const Cluster * lar_content::TrackMergeRefinementAlgorithm::CreateMainTrack ( const ClusterPairAssociation clusterAssociation,
const ClusterToCaloHitListMap clusterToCaloHitListMap,
const pandora::ClusterList *  pClusterList,
pandora::ClusterVector &  clusterVector,
SlidingFitResultMapPair slidingFitResultMapPair 
) const
private

Refine the cluster endpoints and merge together the associated clusters alongside any extrapolated hits.

Parameters
clusterAssociationthe cluster pair association
clusterToCaloHitListMapthe map [parent cluster -> list of hits which belong to the main track]
pClusterListthe list of all clusters
clusterVectorthe vector of clusters considered in future iterations of the algorithm
slidingFitResultMapPairthe {micro, macro} pair of [cluster -> TwoDSlidingFitResult] maps
Returns
the address of the created main track cluster

Definition at line 246 of file TrackMergeRefinementAlgorithm.cc.

249 {
250  // Determine the shower clusters which contain hits that belong to the main track
251  ClusterVector showerClustersToFragment;
252  for (const auto &entry : clusterToCaloHitListMap)
253  {
254  if ((entry.first != clusterAssociation.GetUpstreamCluster()) && (entry.first != clusterAssociation.GetDownstreamCluster()))
255  showerClustersToFragment.push_back(entry.first);
256  }
257 
258  std::sort(showerClustersToFragment.begin(), showerClustersToFragment.end(), LArClusterHelper::SortByNHits);
259 
260  ClusterList remnantClusterList;
261  const Cluster *const pMainTrackCluster(
262  this->RemoveOffAxisHitsFromTrack(clusterAssociation.GetUpstreamCluster(), clusterAssociation.GetUpstreamMergePoint(), false,
263  clusterToCaloHitListMap, remnantClusterList, *slidingFitResultMapPair.first, *slidingFitResultMapPair.second));
264  const Cluster *const pClusterToDelete(
265  this->RemoveOffAxisHitsFromTrack(clusterAssociation.GetDownstreamCluster(), clusterAssociation.GetDownstreamMergePoint(), true,
266  clusterToCaloHitListMap, remnantClusterList, *slidingFitResultMapPair.first, *slidingFitResultMapPair.second));
267 
268  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*this, pMainTrackCluster, pClusterToDelete));
269 
270  for (const Cluster *const pShowerCluster : showerClustersToFragment)
271  {
272  const CaloHitList &caloHitsToMerge(clusterToCaloHitListMap.at(pShowerCluster));
273  this->AddHitsToMainTrack(pMainTrackCluster, pShowerCluster, caloHitsToMerge, clusterAssociation, remnantClusterList);
274  }
275 
276  ClusterList createdClusters;
277  this->ProcessRemnantClusters(remnantClusterList, pMainTrackCluster, pClusterList, createdClusters);
278 
279  // ATTN: Cleanup containers - choose to add created clusters back into containers
280  ClusterList modifiedClusters(showerClustersToFragment.begin(), showerClustersToFragment.end());
281  modifiedClusters.push_back(clusterAssociation.GetUpstreamCluster());
282  modifiedClusters.push_back(clusterAssociation.GetDownstreamCluster());
283  createdClusters.push_back(pMainTrackCluster);
284  this->UpdateContainers(createdClusters, modifiedClusters, LArClusterHelper::SortByNHits, clusterVector, slidingFitResultMapPair);
285 
286  return pMainTrackCluster;
287 }
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.
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 ...
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...
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.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
const pandora::Cluster * RemoveOffAxisHitsFromTrack(const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const bool isEndUpstream, const ClusterToCaloHitListMap &clusterToCaloHitListMap, pandora::ClusterList &remnantClusterList, TwoDSlidingFitResultMap &microSlidingFitResultMap, TwoDSlidingFitResultMap &macroSlidingFitResultMap) const
Remove any hits in the upstream/downstream cluster that lie off of the main track axis (i...
bool lar_content::TrackMergeRefinementAlgorithm::FindBestClusterAssociation ( const pandora::ClusterVector &  clusterVector,
const SlidingFitResultMapPair slidingFitResultMapPair,
ClusterPairAssociation clusterAssociation 
) const
private

Find the best cluster association.

Parameters
clusterVectorthe vector of clusters to consider
slidingFitResultMapPairthe {micro, macro} pair of [cluster -> TwoDSlidingFitResult] maps
clusterAssociationthe cluster pair association
Returns
whether a cluster pair association was found

Definition at line 91 of file TrackMergeRefinementAlgorithm.cc.

93 {
94  bool foundAssociation(false);
95  float maxLength(0.f);
96 
97  // ATTN: Find the associated cluster pair with the longest length sum
98  for (ClusterVector::const_iterator currentIter = clusterVector.begin(); currentIter != clusterVector.end(); ++currentIter)
99  {
100  const Cluster *const pCurrentCluster(*currentIter);
101 
102  const TwoDSlidingFitResultMap::const_iterator currentMicroFitIter(slidingFitResultMapPair.first->find(pCurrentCluster));
103  if (currentMicroFitIter == slidingFitResultMapPair.first->end())
104  return false;
105 
106  const TwoDSlidingFitResultMap::const_iterator currentMacroFitIter(slidingFitResultMapPair.second->find(pCurrentCluster));
107  if (currentMacroFitIter == slidingFitResultMapPair.second->end())
108  return false;
109 
110  for (ClusterVector::const_iterator testIter = std::next(currentIter); testIter != clusterVector.end(); ++testIter)
111  {
112  const Cluster *const pTestCluster(*testIter);
113 
114  const float lengthSum(LArClusterHelper::GetLength(pCurrentCluster) + LArClusterHelper::GetLength(pTestCluster));
115  if ((lengthSum < maxLength) || (lengthSum < m_minClusterLengthSum))
116  continue;
117 
118  const TwoDSlidingFitResultMap::const_iterator testMicroFitIter(slidingFitResultMapPair.first->find(pTestCluster));
119  if (testMicroFitIter == slidingFitResultMapPair.first->end())
120  continue;
121 
122  const TwoDSlidingFitResultMap::const_iterator testMacroFitIter(slidingFitResultMapPair.second->find(pTestCluster));
123  if (testMacroFitIter == slidingFitResultMapPair.second->end())
124  continue;
125 
126  const bool isCurrentUpstream(LArClusterHelper::SortByPosition(pCurrentCluster, pTestCluster));
127 
128  // ATTN: Ensure that clusters are not contained within one another
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());
133 
134  if (((currentMinLayerZ > testMinLayerZ) && (currentMaxLayerZ < testMaxLayerZ)) ||
135  ((testMinLayerZ > currentMinLayerZ) && (testMaxLayerZ < currentMaxLayerZ)))
136  continue;
137 
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);
140  if (!this->GetClusterMergingCoordinates(currentMicroFitIter->second, currentMacroFitIter->second, testMacroFitIter->second,
141  !isCurrentUpstream, currentMergePoint, currentMergeDirection) ||
142  !this->GetClusterMergingCoordinates(testMicroFitIter->second, testMacroFitIter->second, currentMacroFitIter->second,
143  isCurrentUpstream, testMergePoint, testMergeDirection))
144  {
145  continue;
146  }
147 
148  if ((isCurrentUpstream && !this->AreClustersAssociated(currentMergePoint, currentMergeDirection, testMergePoint, testMergeDirection)) ||
149  (!isCurrentUpstream && !this->AreClustersAssociated(testMergePoint, testMergeDirection, currentMergePoint, currentMergeDirection)))
150  {
151  continue;
152  }
153 
154  if (isCurrentUpstream)
155  {
156  clusterAssociation = ClusterPairAssociation(
157  currentMergePoint, currentMergeDirection, testMergePoint, testMergeDirection * (-1.f), pCurrentCluster, pTestCluster);
158  }
159  else
160  {
161  clusterAssociation = ClusterPairAssociation(
162  testMergePoint, testMergeDirection, currentMergePoint, currentMergeDirection * (-1.f), pTestCluster, pCurrentCluster);
163  }
164 
165  foundAssociation = true;
166  maxLength = lengthSum;
167  }
168  }
169 
170  return foundAssociation;
171 }
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...
static bool SortByPosition(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by position, then pulse-height.
float m_minClusterLengthSum
The threshold cluster and associated cluster length sum.
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.
static float GetLength(const pandora::Cluster *const pCluster)
Get length of cluster.
createEngine this
void lar_content::TrackMergeRefinementAlgorithm::GetUnavailableProtectedClusters ( const ClusterPairAssociation clusterAssociation,
const pandora::ClusterList &  createdMainTrackClusters,
pandora::ClusterList &  unavailableProtectedClusters 
) const
private

Obtain a list of clusters whos hits are protected and cannot be reassigned.

Parameters
clusterAssociationthe clusterPairAssociation
createdMainTrackClustersthe list of main track clusters that have hitherto collected
unavailableProtectedClustersthe output list of protected clusters

Definition at line 205 of file TrackMergeRefinementAlgorithm.cc.

207 {
208  for (const Cluster *const pMainTrackCluster : createdMainTrackClusters)
209  {
210  if ((pMainTrackCluster != clusterAssociation.GetUpstreamCluster()) && (pMainTrackCluster != clusterAssociation.GetDownstreamCluster()))
211  protectedClusters.push_back(pMainTrackCluster);
212  }
213 }
StatusCode lar_content::TrackMergeRefinementAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
privatevirtual

Implements lar_content::TrackRefinementBaseAlgorithm.

Definition at line 291 of file TrackMergeRefinementAlgorithm.cc.

292 {
293  PANDORA_RETURN_RESULT_IF_AND_IF(
294  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxLoopIterations", m_maxLoopIterations));
295 
296  PANDORA_RETURN_RESULT_IF_AND_IF(
297  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLengthSum", m_minClusterLengthSum));
298 
299  PANDORA_RETURN_RESULT_IF_AND_IF(
300  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinSeparationDistance", m_minSeparationDistance));
301 
302  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
303  XmlHelper::ReadValue(xmlHandle, "MinDirectionDeviationCosAngle", m_minDirectionDeviationCosAngle));
304 
305  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
306  XmlHelper::ReadValue(xmlHandle, "MaxPredictedMergePointOffset", m_maxPredictedMergePointOffset));
307 
308  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DistanceToLine", m_distanceToLine));
309 
310  PANDORA_RETURN_RESULT_IF_AND_IF(
311  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "BoundaryTolerance", m_boundaryTolerance));
312 
314 }
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)=0
float m_maxPredictedMergePointOffset
The threshold separation distance between the predicted and true cluster merge points.
float m_minClusterLengthSum
The threshold cluster and associated cluster length sum.
float m_minSeparationDistance
The threshold separation distance between associated clusters.
unsigned int m_maxLoopIterations
The maximum number of main loop iterations.
float m_boundaryTolerance
The maximum allowed distance of an extremal extrapolate hit to a cluster merge point.
float m_distanceToLine
The threshold hit distance of an extrapolated hit from the segment connecting line.
float m_minDirectionDeviationCosAngle
The threshold cos opening angle of the associated cluster directions.
StatusCode lar_content::TrackMergeRefinementAlgorithm::Run ( )
privatevirtual

Implements lar_content::TrackRefinementBaseAlgorithm.

Definition at line 34 of file TrackMergeRefinementAlgorithm.cc.

35 {
36  const ClusterList *pClusterList(nullptr);
37  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
38 
39  const CaloHitList *pCaloHitList(nullptr);
40  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pCaloHitList));
41 
42  ClusterVector clusterVector;
43  TwoDSlidingFitResultMap microSlidingFitResultMap, macroSlidingFitResultMap;
44  SlidingFitResultMapPair slidingFitResultMapPair({&microSlidingFitResultMap, &macroSlidingFitResultMap});
45 
46  this->InitialiseContainers(pClusterList, LArClusterHelper::SortByNHits, clusterVector, slidingFitResultMapPair);
47 
48  // ATTN: Keep track of created main track clusters so their hits can be protected in future iterations
49  unsigned int loopIterations(0);
50  ClusterList createdMainTrackClusters;
51  while (loopIterations < m_maxLoopIterations)
52  {
53  ++loopIterations;
54 
55  ClusterPairAssociation clusterAssociation;
56  if (!this->FindBestClusterAssociation(clusterVector, slidingFitResultMapPair, clusterAssociation))
57  break;
58 
59  ClusterList unavailableProtectedClusters;
60  this->GetUnavailableProtectedClusters(clusterAssociation, createdMainTrackClusters, unavailableProtectedClusters);
61 
62  ClusterToCaloHitListMap clusterToCaloHitListMap;
63  this->GetHitsInBoundingBox(clusterAssociation.GetUpstreamMergePoint(), clusterAssociation.GetDownstreamMergePoint(), pClusterList,
64  clusterToCaloHitListMap, unavailableProtectedClusters, m_distanceToLine);
65 
66  if (!this->AreExtrapolatedHitsGood(clusterToCaloHitListMap, clusterAssociation))
67  {
68  this->ConsiderClusterAssociation(clusterAssociation, clusterVector, slidingFitResultMapPair);
69  continue;
70  }
71 
72  const ClusterList::const_iterator upstreamIter(
73  std::find(createdMainTrackClusters.begin(), createdMainTrackClusters.end(), clusterAssociation.GetUpstreamCluster()));
74  if (upstreamIter != createdMainTrackClusters.end())
75  createdMainTrackClusters.erase(upstreamIter);
76 
77  const ClusterList::const_iterator downstreamIter(
78  std::find(createdMainTrackClusters.begin(), createdMainTrackClusters.end(), clusterAssociation.GetDownstreamCluster()));
79  if (downstreamIter != createdMainTrackClusters.end())
80  createdMainTrackClusters.erase(downstreamIter);
81 
82  createdMainTrackClusters.push_back(
83  this->CreateMainTrack(clusterAssociation, clusterToCaloHitListMap, pClusterList, clusterVector, slidingFitResultMapPair));
84  }
85 
86  return STATUS_CODE_SUCCESS;
87 }
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.
std::pair< TwoDSlidingFitResultMap *, TwoDSlidingFitResultMap * > SlidingFitResultMapPair
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...
std::unordered_map< const pandora::Cluster *, pandora::CaloHitList > ClusterToCaloHitListMap
bool AreExtrapolatedHitsGood(const ClusterToCaloHitListMap &clusterToCaloHitListMap, ClusterAssociation &clusterAssociation) const
Perform topological checks on the collected hits to ensure no gaps are present.
bool FindBestClusterAssociation(const pandora::ClusterVector &clusterVector, const SlidingFitResultMapPair &slidingFitResultMapPair, ClusterPairAssociation &clusterAssociation) const
Find the best cluster association.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
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...
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...
unsigned int m_maxLoopIterations
The maximum number of main loop iterations.
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...
std::vector< art::Ptr< recob::Cluster > > ClusterVector
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.
float m_distanceToLine
The threshold hit distance of an extrapolated hit from the segment connecting line.

Member Data Documentation

float lar_content::TrackMergeRefinementAlgorithm::m_boundaryTolerance
private

The maximum allowed distance of an extremal extrapolate hit to a cluster merge point.

Definition at line 105 of file TrackMergeRefinementAlgorithm.h.

float lar_content::TrackMergeRefinementAlgorithm::m_distanceToLine
private

The threshold hit distance of an extrapolated hit from the segment connecting line.

Definition at line 104 of file TrackMergeRefinementAlgorithm.h.

unsigned int lar_content::TrackMergeRefinementAlgorithm::m_maxLoopIterations
private

The maximum number of main loop iterations.

Definition at line 99 of file TrackMergeRefinementAlgorithm.h.

float lar_content::TrackMergeRefinementAlgorithm::m_maxPredictedMergePointOffset
private

The threshold separation distance between the predicted and true cluster merge points.

Definition at line 103 of file TrackMergeRefinementAlgorithm.h.

float lar_content::TrackMergeRefinementAlgorithm::m_minClusterLengthSum
private

The threshold cluster and associated cluster length sum.

Definition at line 100 of file TrackMergeRefinementAlgorithm.h.

float lar_content::TrackMergeRefinementAlgorithm::m_minDirectionDeviationCosAngle
private

The threshold cos opening angle of the associated cluster directions.

Definition at line 102 of file TrackMergeRefinementAlgorithm.h.

float lar_content::TrackMergeRefinementAlgorithm::m_minSeparationDistance
private

The threshold separation distance between associated clusters.

Definition at line 101 of file TrackMergeRefinementAlgorithm.h.


The documentation for this class was generated from the following files: