9 #include "Pandora/AlgorithmHeaders.h" 23 CrossedTrackSplittingAlgorithm::CrossedTrackSplittingAlgorithm() :
24 m_maxClusterSeparation(2.
f),
25 m_maxClusterSeparationSquared(m_maxClusterSeparation * m_maxClusterSeparation),
26 m_minCosRelativeAngle(0.966
f),
37 CaloHitList allCaloHits;
39 for (
const Cluster *
const pCluster : clusterVector)
41 CaloHitList daughterHits;
42 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
43 allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
45 for (
const CaloHit *
const pCaloHit : daughterHits)
46 (void) hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
53 kdTree.
build(hitKDNode2DList, hitsBoundingRegion2D);
55 for (
const Cluster *
const pCluster : clusterVector)
57 CaloHitList daughterHits;
58 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
60 for (
const CaloHit *
const pCaloHit : daughterHits)
65 kdTree.
search(searchRegionHits, found);
67 for (
const auto &
hit : found)
72 return STATUS_CODE_SUCCESS;
81 return STATUS_CODE_SUCCESS;
87 CartesianVector &splitPosition, CartesianVector &firstDirection, CartesianVector &secondDirection)
const 95 return STATUS_CODE_NOT_FOUND;
110 return STATUS_CODE_NOT_FOUND;
114 return STATUS_CODE_NOT_FOUND;
116 CartesianPointVector candidateVector;
119 if (candidateVector.empty())
120 return STATUS_CODE_NOT_FOUND;
124 bool foundSplit(
false);
132 const CartesianVector &candidatePosition(*iter);
135 float rL1(0.
f), rT1(0.
f);
136 CartesianVector R1(0.
f, 0.
f, 0.
f);
137 CartesianVector F1(0.
f, 0.
f, 0.
f);
138 CartesianVector B1(0.
f, 0.
f, 0.
f);
144 if ((STATUS_CODE_SUCCESS != slidingFitResult1.
GetGlobalFitPosition(rL1 + halfWindowLength1, F1)) ||
151 float rL2(0.
f), rT2(0.
f);
152 CartesianVector R2(0.
f, 0.
f, 0.
f);
153 CartesianVector F2(0.
f, 0.
f, 0.
f);
154 CartesianVector B2(0.
f, 0.
f, 0.
f);
160 if ((STATUS_CODE_SUCCESS != slidingFitResult2.
GetGlobalFitPosition(rL2 + halfWindowLength2, F2)) ||
167 const CartesianVector C0((R1 + R2) * 0.5);
187 const CartesianVector
a1(B1);
188 const CartesianVector
a2(F1);
190 for (
unsigned int iForward = 0; iForward<2; ++iForward)
192 const CartesianVector b1((0 == iForward) ? F2 : B2);
193 const CartesianVector b2((0 == iForward) ? B2 : F2);
195 const CartesianVector s1((b1 - R2).GetUnitVector());
196 const CartesianVector
t1((R1 - a1).GetUnitVector());
197 const CartesianVector s2((b2 - R2).GetUnitVector());
198 const CartesianVector
t2((R1 - a2).GetUnitVector());
204 const CartesianVector p1((b1 - a1).GetUnitVector());
205 const CartesianVector p2((b2 - a2).GetUnitVector());
207 float mu1(0.
f), mu2(0.
f);
208 CartesianVector C1(0.
f,0.
f,0.
f);
214 catch (
const StatusCodeException &)
219 if (mu1 < 0.
f || mu2 < 0.f || mu1 > (b1 - a1).GetMagnitude() || mu2 > (b2 - a2).GetMagnitude())
222 const float thisSeparationSquared((C0 - C1).GetMagnitudeSquared());
224 if (thisSeparationSquared < closestSeparationSquared)
226 closestSeparationSquared = thisSeparationSquared;
227 splitPosition = (C0 + C1) * 0.5;
228 firstDirection = t2 * -1.f;
229 secondDirection =
t1;
236 return STATUS_CODE_NOT_FOUND;
238 return STATUS_CODE_SUCCESS;
244 CartesianPointVector &candidateVector)
const 247 CaloHitList caloHitList1, caloHitList2;
248 pCluster1->GetOrderedCaloHitList().FillCaloHitList(caloHitList1);
249 pCluster2->GetOrderedCaloHitList().FillCaloHitList(caloHitList2);
251 CaloHitVector caloHitVector1(caloHitList1.begin(), caloHitList1.end()), caloHitVector2(caloHitList2.begin(), caloHitList2.end());
255 for (
const CaloHit *
const pCaloHit : caloHitVector1)
257 const CartesianVector position1(pCaloHit->GetPositionVector());
261 candidateVector.push_back((position1 + position2) * 0.5);
264 for (
const CaloHit *
const pCaloHit : caloHitVector2)
266 const CartesianVector position2(pCaloHit->GetPositionVector());
270 candidateVector.push_back((position2 + position1) * 0.5);
278 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
282 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
285 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
std::vector< HitKDNode2D > HitKDNode2DList
Header file for the kd tree linker algo template class.
pandora::StatusCode FindBestSplitPosition(const TwoDSlidingFitResult &slidingFit1, const TwoDSlidingFitResult &slidingFit2, pandora::CartesianVector &splitPosition, pandora::CartesianVector &direction1, pandora::CartesianVector &direction2) const
Find the best split position and direction for a pair of clusters.
static void GetIntersection(const LArPointingCluster::Vertex &firstVertex, const LArPointingCluster::Vertex &secondVertex, pandora::CartesianVector &intersectPosition, float &firstDisplacement, float &secondDisplacement)
Get intersection of two vertices.
Class that implements the KDTree partition of 2D space and a closest point search algorithm...
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
Header file for the crossed track splitting algorithm class.
float GetLayerFitHalfWindowLength() const
Get the layer fit half window length.
float m_minCosRelativeAngle
maximum relative angle between tracks after un-crossing
float m_maxClusterSeparationSquared
maximum separation of two clusters (squared)
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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 bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
pandora::StatusCode TidyUpStep()
Tidy up any information cached in e.g. the preparation step.
void FindCandidateSplitPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianPointVector &candidateVector) const
Find average positions of pairs of hits within a maximum separation.
Detector simulation of raw signals on wires.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
pandora::StatusCode PreparationStep(const pandora::ClusterVector &clusterVector)
Perform any preparatory actions, such as caching information for subsequent expensive calculations...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_maxClusterSeparation
maximum separation of two clusters
pandora::StatusCode GetGlobalFitProjection(const pandora::CartesianVector &inputPosition, pandora::CartesianVector &projectedPosition) const
Get projected position on global fit for a given position vector.
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
ClusterToClustersMap m_nearbyClusters
The nearby clusters map.
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.
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
float m_searchRegion1D
Search region, applied to each dimension, for look-up from kd-trees.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
TwoDSlidingFitResult class.
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".
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.