23 m_firstLengthCut(1.5f),
24 m_secondLengthCut(7.5f),
27 m_clusterCosAngle(std::cos(m_clusterAngle * M_PI / 180.f)),
28 m_clusterTanAngle(std::tan(m_clusterAngle * M_PI / 180.f)),
29 m_maxTransverseOverlap(0.5f),
30 m_maxProjectedOverlap(1.f),
31 m_maxLongitudinalOverlap(1.5f),
32 m_transverseClusterMinCosTheta(0.866f),
33 m_transverseClusterMinLength(0.5f),
34 m_transverseClusterMaxDisplacement(1.5f),
35 m_searchRegionX(3.5f),
44 clusterVector.clear();
45 clusterVector.insert(clusterVector.begin(), pClusterList->begin(), pClusterList->end());
60 if (nearbyClusters.empty())
67 ClusterVector shortClusters, transverseMediumClusters, longitudinalMediumClusters, longClusters;
68 this->
SortInputClusters(allClusters, shortClusters, transverseMediumClusters, longitudinalMediumClusters, longClusters);
70 ClusterVector transverseClusters(shortClusters.begin(), shortClusters.end());
71 transverseClusters.insert(transverseClusters.end(), transverseMediumClusters.begin(), transverseMediumClusters.end());
73 ClusterVector establishedClusters(transverseMediumClusters.begin(), transverseMediumClusters.end());
74 establishedClusters.insert(establishedClusters.end(), longitudinalMediumClusters.begin(), longitudinalMediumClusters.end());
75 establishedClusters.insert(establishedClusters.end(), longClusters.begin(), longClusters.end());
107 std::cout <<
"TransverseAssociationAlgorithm: exception " << statusCodeException.
ToString() << std::endl;
110 for (TransverseClusterList::const_iterator iter = transverseClusterList.begin(), iterEnd = transverseClusterList.end(); iter != iterEnd; ++iter)
123 for (
const Cluster *
const pCluster : allClusters)
126 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
127 allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
129 for (
const CaloHit *
const pCaloHit : daughterHits)
130 (
void)hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
137 kdTree.
build(hitKDNode2DList, hitsBoundingRegion2D);
139 for (
const Cluster *
const pCluster : allClusters)
142 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
144 for (
const CaloHit *
const pCaloHit : daughterHits)
149 kdTree.
search(searchRegionHits, found);
151 for (
const auto &hit : found)
152 (
void)nearbyClusters[pCluster].insert(hitToClusterMap.at(hit.data));
162 for (ClusterVector::const_iterator iter = inputVector.begin(), iterEnd = inputVector.end(); iter != iterEnd; ++iter)
164 const Cluster *
const pCluster = *iter;
168 const float clusterLengthSquared(clusterLengthT * clusterLengthT + clusterLengthL * clusterLengthL);
172 shortVector.push_back(pCluster);
177 transverseMediumVector.push_back(pCluster);
179 longitudinalMediumVector.push_back(pCluster);
183 longVector.push_back(pCluster);
205 this->
FillAssociationMap(nearbyClusters, firstVector, firstVector, firstAssociationMap, firstAssociationMapSwapped);
206 this->
FillAssociationMap(nearbyClusters, firstVector, secondVector, secondAssociationMap, secondAssociationMapSwapped);
207 this->
FillReducedAssociationMap(firstAssociationMap, secondAssociationMap, secondAssociationMapSwapped, clusterAssociationMap);
215 for (ClusterVector::const_iterator iterI = firstVector.begin(), iterEndI = firstVector.end(); iterI != iterEndI; ++iterI)
217 const Cluster *
const pClusterI = *iterI;
219 for (ClusterVector::const_iterator iterJ = secondVector.begin(), iterEndJ = secondVector.end(); iterJ != iterEndJ; ++iterJ)
221 const Cluster *
const pClusterJ = *iterJ;
223 if (pClusterI == pClusterJ)
226 if (this->
IsAssociated(
true, pClusterI, pClusterJ, nearbyClusters))
228 firstAssociationMap[pClusterI].m_forwardAssociations.insert(pClusterJ);
229 secondAssociationMap[pClusterJ].m_backwardAssociations.insert(pClusterI);
232 if (this->
IsAssociated(
false, pClusterI, pClusterJ, nearbyClusters))
234 firstAssociationMap[pClusterI].m_backwardAssociations.insert(pClusterJ);
235 secondAssociationMap[pClusterJ].m_forwardAssociations.insert(pClusterI);
246 for (ClusterVector::const_iterator iter = inputVector.begin(), iterEnd = inputVector.end(); iter != iterEnd; ++iter)
248 const Cluster *
const pCluster = *iter;
266 for (TransverseClusterList::const_iterator iter1 = transverseClusterList.begin(), iterEnd1 = transverseClusterList.end(); iter1 != iterEnd1; ++iter1)
271 ClusterAssociationMap::const_iterator iterInner = transverseAssociationMap.find(pInnerCluster);
272 if (transverseAssociationMap.end() == iterInner)
275 for (TransverseClusterList::const_iterator iter2 = transverseClusterList.begin(), iterEnd2 = transverseClusterList.end();
276 iter2 != iterEnd2; ++iter2)
281 ClusterAssociationMap::const_iterator iterOuter = transverseAssociationMap.find(pOuterCluster);
282 if (transverseAssociationMap.end() == iterOuter)
285 if (pInnerCluster == pOuterCluster)
288 if (iterInner->second.m_forwardAssociations.count(pOuterCluster) == 0 || iterOuter->second.m_backwardAssociations.count(pInnerCluster) == 0)
297 clusterAssociationMap[pInnerCluster].m_forwardAssociations.insert(pOuterCluster);
298 clusterAssociationMap[pOuterCluster].m_backwardAssociations.insert(pInnerCluster);
308 ClusterAssociationMap::const_iterator iterI = associationMap.find(pClusterI);
309 if (associationMap.end() == iterI)
312 for (ClusterSet::const_iterator iterJ = iterI->second.m_forwardAssociations.begin(), iterEndJ = iterI->second.m_forwardAssociations.end();
313 iterJ != iterEndJ; ++iterJ)
315 const Cluster *
const pClusterJ = *iterJ;
318 associatedVector.push_back(pClusterJ);
321 for (ClusterSet::const_iterator iterJ = iterI->second.m_backwardAssociations.begin(), iterEndJ = iterI->second.m_backwardAssociations.end();
322 iterJ != iterEndJ; ++iterJ)
324 const Cluster *
const pClusterJ = *iterJ;
327 associatedVector.push_back(pClusterJ);
338 if ((0 == nearbyClusters.at(pFirstCluster).count(pSecondCluster)) || (0 == nearbyClusters.at(pSecondCluster).count(pFirstCluster)))
342 CartesianVector secondInner(0.f, 0.f, 0.f), secondOuter(0.f, 0.f, 0.f);
346 const CartesianVector firstCoordinate(isForward ? firstOuter : firstInner);
347 const CartesianVector secondCoordinate(isForward ? secondOuter : secondInner);
353 if ((isForward && secondCoordinate.GetX() < firstCoordinate.
GetX()) || (!isForward && secondCoordinate.GetX() > firstCoordinate.
GetX()))
374 if ((0 == nearbyClusters.at(pInnerCluster).count(pOuterCluster)) || (0 == nearbyClusters.at(pOuterCluster).count(pInnerCluster)))
385 if ((std::fabs(innerCentroid.
GetZ() - outerInner.GetZ()) > std::fabs(innerCentroid.
GetX() - outerInner.GetX()) * std::fabs(
m_clusterTanAngle)) &&
389 if ((std::fabs(outerCentroid.
GetZ() - innerInner.GetZ()) > std::fabs(outerCentroid.
GetX() - innerInner.GetX()) * std::fabs(
m_clusterTanAngle)) &&
455 const float innerOverlapSquared((innerProjection - innerOuter).GetMagnitudeSquared());
456 const float outerOverlapSquared((outerProjection - outerInner).GetMagnitudeSquared());
465 float minX(+std::numeric_limits<float>::max());
466 float maxX(-std::numeric_limits<float>::max());
470 return (maxX - minX);
477 float minZ(+std::numeric_limits<float>::max());
478 float maxZ(-std::numeric_limits<float>::max());
482 return (maxZ - minZ);
489 float overallMinX(+std::numeric_limits<float>::max());
490 float overallMaxX(-std::numeric_limits<float>::max());
494 float localMinX(+std::numeric_limits<float>::max());
495 float localMaxX(-std::numeric_limits<float>::max());
497 for (ClusterVector::const_iterator iter = associatedClusters.begin(), iterEnd = associatedClusters.end(); iter != iterEnd; ++iter)
499 const Cluster *
const pAssociatedCluster = *iter;
503 if (localMinX < overallMinX)
504 overallMinX = localMinX;
506 if (localMaxX > overallMaxX)
507 overallMaxX = localMaxX;
510 return (overallMaxX - overallMinX);
517 float currentMinX(0.f), currentMaxX(0.f);
520 float testMinX(0.f), testMaxX(0.f);
525 if (std::fabs(testMaxX - currentMaxX) > std::numeric_limits<float>::epsilon())
526 return (testMaxX > currentMaxX);
530 if (std::fabs(testMinX - currentMaxX) > std::numeric_limits<float>::epsilon())
531 return (testMinX < currentMinX);
555 minXZ = +std::numeric_limits<float>::max();
556 maxXZ = -std::numeric_limits<float>::max();
562 for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
564 const float caloHitXZ(useX ? (*hitIter)->GetPositionVector().GetX() : (*hitIter)->GetPositionVector().GetZ());
566 if (caloHitXZ < minXZ)
569 if (caloHitXZ > maxXZ)
583 CartesianVector firstCoordinate(0.f, 0.f, 0.f), secondCoordinate(0.f, 0.f, 0.f);
586 innerCoordinate = (firstCoordinate.GetX() < secondCoordinate.
GetX() ? firstCoordinate : secondCoordinate);
587 outerCoordinate = (firstCoordinate.GetX() > secondCoordinate.
GetX() ? firstCoordinate : secondCoordinate);
595 return this->
FillReducedAssociationMap(inputAssociationMap, inputAssociationMap, inputAssociationMap, outputAssociationMap);
612 for (
const auto &mapEntry : firstAssociationMap)
613 sortedClusters.push_back(mapEntry.first);
616 for (
const Cluster *
const pCluster : sortedClusters)
626 ClusterAssociationMap::const_iterator iterSecond = secondAssociationMap.find(pCluster);
629 if (secondAssociationMap.end() != iterSecond)
631 sortedMiddleClustersF.insert(sortedMiddleClustersF.end(), iterSecond->second.m_forwardAssociations.begin(),
632 iterSecond->second.m_forwardAssociations.end());
633 sortedMiddleClustersB.insert(sortedMiddleClustersB.end(), iterSecond->second.m_backwardAssociations.begin(),
634 iterSecond->second.m_backwardAssociations.end());
639 for (
const Cluster *
const pOuterCluster : sortedOuterClusters)
641 bool isNeighbouringCluster(
true);
643 for (
const Cluster *
const pMiddleCluster : sortedMiddleClustersF)
645 ClusterAssociationMap::const_iterator iterSecondCheck = secondAssociationMapSwapped.find(pMiddleCluster);
646 if (secondAssociationMapSwapped.end() == iterSecondCheck)
649 if (iterSecondCheck->second.m_forwardAssociations.count(pOuterCluster) > 0)
651 isNeighbouringCluster =
false;
656 if (isNeighbouringCluster)
657 clusterAssociationMap[pCluster].m_forwardAssociations.insert(pOuterCluster);
660 for (
const Cluster *
const pInnerCluster : sortedInnerClusters)
662 bool isNeighbouringCluster(
true);
664 for (
const Cluster *
const pMiddleCluster : sortedMiddleClustersB)
666 ClusterAssociationMap::const_iterator iterSecondCheck = secondAssociationMapSwapped.find(pMiddleCluster);
667 if (secondAssociationMapSwapped.end() == iterSecondCheck)
670 if (iterSecondCheck->second.m_backwardAssociations.count(pInnerCluster) > 0)
672 isNeighbouringCluster =
false;
677 if (isNeighbouringCluster)
678 clusterAssociationMap[pCluster].m_backwardAssociations.insert(pInnerCluster);
693 for (
const auto &mapEntry : inputAssociationMap)
694 sortedClusters.push_back(mapEntry.first);
697 for (
const Cluster *
const pCluster : sortedClusters)
708 for (
const Cluster *
const pForwardCluster : sortedForwardClusters)
715 ClusterAssociationMap::const_iterator iterCheck = inputAssociationMap.find(pForwardCluster);
716 if (inputAssociationMap.end() != iterCheck)
718 if (iterCheck->second.m_forwardAssociations.count(pCluster))
721 if (iterCheck->second.m_backwardAssociations.count(pCluster))
727 if (!(outputAssociationMap[pCluster].m_backwardAssociations.count(pForwardCluster) == 0 &&
728 outputAssociationMap[pForwardCluster].m_forwardAssociations.count(pCluster) == 0))
731 outputAssociationMap[pCluster].m_forwardAssociations.insert(pForwardCluster);
732 outputAssociationMap[pForwardCluster].m_backwardAssociations.insert(pCluster);
737 for (
const Cluster *
const pBackwardCluster : sortedBackwardClusters)
744 ClusterAssociationMap::const_iterator iterCheck = inputAssociationMap.find(pBackwardCluster);
745 if (inputAssociationMap.end() != iterCheck)
747 if (iterCheck->second.m_backwardAssociations.count(pCluster))
750 if (iterCheck->second.m_forwardAssociations.count(pCluster))
756 if (!(outputAssociationMap[pCluster].m_forwardAssociations.count(pBackwardCluster) == 0 &&
757 outputAssociationMap[pBackwardCluster].m_backwardAssociations.count(pCluster) == 0))
760 outputAssociationMap[pCluster].m_backwardAssociations.insert(pBackwardCluster);
761 outputAssociationMap[pBackwardCluster].m_forwardAssociations.insert(pCluster);
781 m_pSeedCluster(pSeedCluster),
782 m_associatedClusters(associatedClusters),
783 m_innerVertex(0.f, 0.f, 0.f),
784 m_outerVertex(0.f, 0.f, 0.f),
785 m_direction(0.f, 0.f, 0.f)
787 double Swxx(0.), Swzx(0.), Swz(0.), Swx(0.), Sw(0.);
788 double minX(std::numeric_limits<double>::max());
789 double maxX(-std::numeric_limits<double>::max());
792 clusterList.insert(clusterList.end(), associatedClusters.begin(), associatedClusters.end());
794 for (ClusterList::const_iterator iterI = clusterList.begin(), iterEndI = clusterList.end(); iterI != iterEndI; ++iterI)
797 iterEndJ = (*iterI)->GetOrderedCaloHitList().end();
798 iterJ != iterEndJ; ++iterJ)
800 for (CaloHitList::const_iterator iterK = iterJ->second->begin(), iterEndK = iterJ->second->end(); iterK != iterEndK; ++iterK)
802 const CaloHit *
const pCaloHit = *iterK;
821 const double averageX(Swx / Sw);
822 const double averageZ(Swz / Sw);
824 if (Sw * Swxx - Swx * Swx > 0.)
826 double m((Sw * Swzx - Swx * Swz) / (Sw * Swxx - Swx * Swx));
827 double px(1. / std::sqrt(1. + m * m));
828 double pz(m / std::sqrt(1. + m * m));
830 m_innerVertex.
SetValues(
static_cast<float>(minX), 0.f,
static_cast<float>(averageZ + m * (minX - averageX)));
831 m_outerVertex.
SetValues(
static_cast<float>(maxX), 0.f,
static_cast<float>(averageZ + m * (maxX - averageX)));
860 if (STATUS_CODE_SUCCESS == angleStatusCode)
865 else if (STATUS_CODE_NOT_FOUND != angleStatusCode)
867 return angleStatusCode;
Header file for the kd tree linker algo template class.
Header file for the cluster helper class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Header file for the transverse association algorithm class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
pandora::ClusterSet m_forwardAssociations
The list of forward associations.
pandora::ClusterSet m_backwardAssociations
The list of backward associations.
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
ClusterAssociation class.
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > ®ion)
Build the KD tree from the "eltList" in the space define by "region".
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
static pandora::CartesianVector GetClosestPosition(const pandora::CartesianVector &position, const pandora::ClusterList &clusterList)
Get closest position in a list of clusters to a specified input position vector.
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 void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z)
LArTransverseCluster class.
const pandora::CartesianVector & GetOuterVertex() const
Get the outer vertex position.
const pandora::CartesianVector & GetDirection() const
Get the direction.
pandora::CartesianVector m_direction
LArTransverseCluster(const pandora::Cluster *const pSeedCluster, const pandora::ClusterVector &associatedClusters)
Constructor.
const pandora::CartesianVector & GetInnerVertex() const
Get the inner vertex position.
const pandora::Cluster * GetSeedCluster() const
Constructor.
pandora::CartesianVector m_innerVertex
pandora::CartesianVector m_outerVertex
void FillSymmetricAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const
Symmetrise an association map.
void FillTransverseAssociationMap(const ClusterToClustersMap &nearbyClusters, const TransverseClusterList &transverseClusterList, const ClusterAssociationMap &transverseAssociationMap, ClusterAssociationMap &clusterAssociationMap) const
Form associations between transverse cluster objects.
void FinalizeClusterAssociationMap(const ClusterAssociationMap &inputAssociationMap, ClusterAssociationMap &outputAssociationMap) const
Symmetrise and then remove double-counting from an association map.
std::vector< HitKDNode2D > HitKDNode2DList
bool IsOverlapping(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2) const
Determine whether two clusters are overlapping.
float m_maxTransverseOverlap
float m_searchRegionX
Search region, applied to x dimension, for look-up from kd-trees.
float m_maxLongitudinalOverlap
void SortInputClusters(const pandora::ClusterVector &inputClusters, pandora::ClusterVector &shortClusters, pandora::ClusterVector &transverseMediumClusters, pandora::ClusterVector &longitudinalMediumClusters, pandora::ClusterVector &longClusters) const
Separate input clusters by length.
float m_searchRegionZ
Search region, applied to u/v/w dimension, for look-up from kd-trees.
void GetAssociatedClusters(const ClusterToClustersMap &nearbyClusters, const pandora::Cluster *const pCluster, const ClusterAssociationMap &inputAssociationMap, pandora::ClusterVector &associatedClusters) const
Find the clusters that are transversely associated with a target cluster.
float GetLongitudinalSpan(const pandora::Cluster *const pCluster) const
Calculate the overall span in Z for a clusters.
bool IsTransverseAssociated(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const ClusterToClustersMap &nearbyClusters) const
Determine whether two clusters are within the same cluster window.
void PopulateClusterAssociationMap(const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const
Populate the cluster association map.
float m_transverseClusterMinLength
void GetExtremalCoordinatesZ(const pandora::Cluster *const pCluster, float &minZ, float &maxZ) const
Get minimum and maximum Z coordinates for a given cluster.
float GetTransverseSpan(const pandora::Cluster *const pCluster) const
Calculate the overall span in X for a clusters.
bool IsExtremalCluster(const bool isForward, const pandora::Cluster *const pCurrentCluster, const pandora::Cluster *const pTestCluster) const
Determine which of two clusters is extremal.
std::vector< LArTransverseCluster * > TransverseClusterList
bool IsAssociated(const bool isForward, const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const ClusterToClustersMap &nearbyClusters) const
Determine whether clusters are association.
TransverseAssociationAlgorithm()
Default constructor.
void GetNearbyClusterMap(const pandora::ClusterVector &allClusters, ClusterToClustersMap &nearbyClusters) const
Use a kd-tree to obtain details of all nearby cluster combinations.
float m_transverseClusterMinCosTheta
void GetExtremalCoordinatesXZ(const pandora::Cluster *const pCluster, const bool useX, float &minXZ, float &maxXZ) const
Get minimum and maximum X or Z coordinates for a given cluster.
float m_maxProjectedOverlap
float m_transverseClusterMaxDisplacement
void FillTransverseClusterList(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &inputClusters, const ClusterAssociationMap &inputAssociationMap, TransverseClusterList &transverseClusterList) const
Create transverse cluster objects, these are protoclusters with a direction and inner/outer vertices.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void FillAssociationMap(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &firstVector, const pandora::ClusterVector &secondVector, ClusterAssociationMap &firstAssociationMap, ClusterAssociationMap &secondAssociationMap) const
Form associations between two input lists of cluster.
void FillReducedAssociationMap(const ClusterToClustersMap &nearbyClusters, const pandora::ClusterVector &firstVector, const pandora::ClusterVector &secondVector, ClusterAssociationMap &clusterAssociationMap) const
Form a reduced set of associations between two input lists of clusters.
void GetExtremalCoordinatesX(const pandora::Cluster *const pCluster, float &minX, float &maxX) const
Get minimum and maximum X coordinates for a given cluster.
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.
std::unordered_map< const pandora::Cluster *, pandora::ClusterSet > ClusterToClustersMap
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
void SetValues(float x, float y, float z)
Set the values of cartesian vector components.
float GetMagnitudeSquared() const
Get the magnitude squared.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
float GetDotProduct(const CartesianVector &rhs) const
Get the dot product of the cartesian vector with a second cartesian vector.
CartesianVector GetCrossProduct(const CartesianVector &rhs) const
Get the cross product of the cartesian vector with a second cartesian vector.
const OrderedCaloHitList & GetOrderedCaloHitList() const
Get the ordered calo hit list.
Calo hit lists arranged by pseudo layer.
const_iterator end() const
Returns a const iterator referring to the past-the-end element in the ordered calo hit list.
const_iterator begin() const
Returns a const iterator referring to the first element in the ordered calo hit list.
TheList::const_iterator const_iterator
StatusCodeException class.
std::string ToString() const
Get status code as a string.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 > > &nodes)
fill_and_bound_2d_kd_tree
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.