24 m_minXOverlapFraction(0.1f),
25 m_minMatchingScore(0.95f),
26 m_minLocallyMatchedFraction(0.3f),
27 m_minLongitudinalImpactParameter(-1.f),
28 m_nLayersForKinkSearch(10),
29 m_additionalXStepForKinkSearch(0.01f),
30 m_maxTransverseImpactParameter(5.f),
31 m_minImpactParameterCosTheta(0.5f),
32 m_cosThetaCutForKinkSearch(0.75f)
47 std::cout <<
"----> Running Algorithm Tool: " << this->
GetInstanceName() <<
", " << this->
GetType() << std::endl;
51 const bool changesMade(this->
ApplyChanges(pAlgorithm, modificationList));
60 if (usedClusters.count(eIter->GetCluster1()) || usedClusters.count(eIter->GetCluster2()))
63 if (eIter->GetOverlapResult().GetTwoViewXOverlap().GetXOverlapFraction0() -
m_minXOverlapFraction < std::numeric_limits<float>::epsilon())
66 if (eIter->GetOverlapResult().GetTwoViewXOverlap().GetXOverlapFraction1() -
m_minXOverlapFraction < std::numeric_limits<float>::epsilon())
69 if (eIter->GetOverlapResult().GetMatchingScore() -
m_minMatchingScore < std::numeric_limits<float>::epsilon())
84 float xMin1(std::numeric_limits<float>::max()), xMax1(std::numeric_limits<float>::lowest());
85 float xMin2(std::numeric_limits<float>::max()), xMax2(std::numeric_limits<float>::lowest());
89 const float commonX(isForwardInX ? std::max(xMin1, xMin2) : std::min(xMax1, xMax2));
91 if (isForwardInX && ((commonX > xMax1) || (commonX > xMax2)))
94 if (!isForwardInX && ((commonX < xMin1) || (commonX < xMin2)))
98 float rL1(0.f), rT1(0.f);
100 const int splitLayer(fitResult1.
GetLayer(rL1));
109 if (minus.GetX() > plus.
GetX())
110 std::swap(minus, plus);
112 const float layerStepX(isForwardInX ? plus.
GetX() : minus.GetX());
115 const float chosenX(isForwardInX ? std::max(layerStepX, commonX) : std::min(layerStepX, commonX));
126 return xMinA < xMinB;
136 overlapMatrix.GetSortedKeyClusters(sortedKeyClusters);
138 for (
const Cluster *
const pKeyCluster : sortedKeyClusters)
140 if (!pKeyCluster->IsAvailable())
143 unsigned int n1(0), n2(0);
144 MatrixType::ElementList elementList;
145 overlapMatrix.GetConnectedElements(pKeyCluster,
true, elementList, n1, n2);
150 for (MatrixType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
158 if (iteratorList.size() < 2)
164 if (localModificationList.empty())
167 for (ModificationList::const_iterator mIter = localModificationList.begin(), mIterEnd = localModificationList.end(); mIter != mIterEnd; ++mIter)
169 usedClusters.insert(mIter->m_affectedClusters.begin(), mIter->m_affectedClusters.end());
172 modificationList.insert(modificationList.end(), localModificationList.begin(), localModificationList.end());
184 for (
const Modification &modification : modificationList)
187 for (
const auto &mapEntry : modification.m_clusterMergeMap)
188 parentClusters.push_back(mapEntry.first);
191 for (
const Cluster *
const pParentCluster : parentClusters)
193 const ClusterList &daughterClusters(modification.m_clusterMergeMap.at(pParentCluster));
195 for (
const Cluster *
const pDaughterCluster : daughterClusters)
197 if (consolidatedMergeMap.count(pDaughterCluster))
201 ClusterList &targetClusterList(consolidatedMergeMap[pParentCluster]);
202 targetClusterList.insert(targetClusterList.end(), daughterClusters.begin(), daughterClusters.end());
206 for (
const auto &mapEntry : modification.m_splitPositionMap)
207 splitClusters.push_back(mapEntry.first);
210 for (
const Cluster *
const pSplitCluster : splitClusters)
215 cartesianPointVector.insert(cartesianPointVector.end(), splitPositions.begin(), splitPositions.end());
219 bool changesMade(
false);
231 iteratorList.push_back(eIter);
233 for (MatrixType::ElementList::const_iterator eIter2 = elementList.begin(); eIter2 != elementList.end(); ++eIter2)
241 for (IteratorList::const_iterator iIter = iteratorList.begin(); iIter != iteratorList.end(); ++iIter)
243 if ((*iIter) == eIter2)
246 unsigned int nMatchedClusters(0);
248 if ((*iIter)->GetCluster1() == eIter2->GetCluster1())
251 if ((*iIter)->GetCluster2() == eIter2->GetCluster2())
254 if (nMatchedClusters > 1)
257 if (nMatchedClusters)
259 iteratorList.push_back(eIter2);
271 for (IteratorList::const_iterator iIter1 = iteratorList.begin(), iIter1End = iteratorList.end(); iIter1 != iIter1End; ++iIter1)
273 for (IteratorList::const_iterator iIter2 = std::next(iIter1); iIter2 != iIter1End; ++iIter2)
277 const unsigned int nMatchedReUpsampledSamplingPoints1((*iIter1)->GetOverlapResult().GetNMatchedReUpsampledSamplingPoints());
278 const unsigned int nMatchedReUpsampledSamplingPoints2((*iIter2)->GetOverlapResult().GetNMatchedReUpsampledSamplingPoints());
279 IteratorList::const_iterator iIterA((nMatchedReUpsampledSamplingPoints1 >= nMatchedReUpsampledSamplingPoints2) ? iIter1 : iIter2);
280 IteratorList::const_iterator iIterB((nMatchedReUpsampledSamplingPoints1 >= nMatchedReUpsampledSamplingPoints2) ? iIter2 : iIter1);
282 Particle particle(*(*iIterA), *(*iIterB));
289 float transverseAB(std::numeric_limits<float>::max()), transverseBA(std::numeric_limits<float>::max());
290 float longitudinalAB(-std::numeric_limits<float>::max()), longitudinalBA(-std::numeric_limits<float>::max());
306 const bool isALowestInX(this->
IsALowestInX(pointingClusterA, pointingClusterB));
308 const bool isThreeDKink(this->
IsThreeDKink(pAlgorithm, particle, splitPosition, isALowestInX));
323 modification.
m_splitPositionMap[particle.m_pCommonCluster].push_back(splitPositionCommon);
328 const Cluster *
const pLowXCluster(vertexAIsLowX ? particle.m_pClusterA : particle.m_pClusterB);
329 const Cluster *
const pHighXCluster(vertexAIsLowX ? particle.m_pClusterB : particle.m_pClusterA);
337 modificationList.push_back(modification);
341 if (STATUS_CODE_FAILURE == statusCodeException.
GetStatusCode())
342 throw statusCodeException;
363 const float minusX(this->
GetXSamplingPoint(splitPosition,
false, lowXFitResult, fitResultCommon));
364 const float plusX(this->
GetXSamplingPoint(splitPosition,
true, highXFitResult, fitResultCommon));
365 const float splitX(splitPosition.
GetX());
367 CartesianVector minus1(0.f, 0.f, 0.f), split1(0.f, 0.f, 0.f), plus1(0.f, 0.f, 0.f);
368 CartesianVector minus2(0.f, 0.f, 0.f), split2(splitPosition), plus2(0.f, 0.f, 0.f);
373 (STATUS_CODE_SUCCESS != lowXFitResult.GetGlobalFitPositionAtX(minusX, minus2)) ||
374 (STATUS_CODE_SUCCESS != highXFitResult.GetGlobalFitPositionAtX(plusX, plus2)))
383 CartesianVector minus(0.f, 0.f, 0.f), split(0.f, 0.f, 0.f), plus(0.f, 0.f, 0.f);
384 float chi2Dummy(std::numeric_limits<float>::max());
392 const float dotProduct(minusToSplit.
GetDotProduct(splitToPlus));
409 m_pClusterA = (elementA.GetCluster1() != elementB.GetCluster1()) ? elementA.GetCluster1() : elementA.GetCluster2();
410 m_pClusterB = (elementA.GetCluster1() != elementB.GetCluster1()) ? elementB.GetCluster1() : elementB.GetCluster2();
411 m_pCommonCluster = (elementA.GetCluster1() == elementB.GetCluster1()) ? elementA.GetCluster1() : elementA.GetCluster2();
448 return STATUS_CODE_SUCCESS;
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the lar pointing cluster class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional 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 void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
static void GetClosestVertices(const bool useX, const bool useY, const bool useZ, const LArPointingCluster &pointingClusterI, const LArPointingCluster &pointingClusterJ, LArPointingCluster::Vertex &closestVertexI, LArPointingCluster::Vertex &closestVertexJ)
Given a pair of pointing clusters, receive the closest or farthest pair of vertices.
static void GetImpactParameters(const LArPointingCluster::Vertex &pointingVertex, const LArPointingCluster::Vertex &targetVertex, float &longitudinal, float &transverse)
Calculate impact parameters between a pair of pointing vertices.
LArPointingCluster class.
const Vertex & GetInnerVertex() const
Get the inner vertex.
const Vertex & GetOuterVertex() const
Get the outer vertex.
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
virtual bool MakeClusterSplits(const SplitPositionMap &splitPositionMap)
Make cluster splits.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
TwoViewTransverseTracksAlgorithm::MatchingType::MatrixType MatrixType
std::vector< MatrixType::ElementList::const_iterator > IteratorList
TwoDSlidingFitResult class.
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
pandora::StatusCode GetGlobalFitPositionAtX(const float x, pandora::CartesianVector &position) const
Get global fit position for a given input x coordinate.
void GetMinAndMaxX(float &minX, float &maxX) const
Get the minimum and maximum x coordinates associated with the sliding fit.
const pandora::Cluster * m_pClusterA
Address of non-shared cluster in element A.
Particle(const MatrixType::Element &elementA, const MatrixType::Element &elementB)
Constructor.
const pandora::Cluster * m_pCommonCluster
Address of the common cluster.
const pandora::Cluster * m_pClusterB
Address of non-shared cluster in element B.
float GetXSamplingPoint(const pandora::CartesianVector &splitPosition1, const bool isForwardInX, const TwoDSlidingFitResult &fitResult1, const TwoDSlidingFitResult &fitResult2) const
Get a sampling point in x that is common to sliding linear fit objects in two views.
SplitPositionMap m_splitPositionMap
The split position map.
bool IsThreeDKink(TwoViewTransverseTracksAlgorithm *const pAlgorithm, const Particle &particle, const pandora::CartesianVector &splitPosition, const bool isALowestInX) const
Whether the provided particle is consistent with being a kink, when examined in three dimensions at t...
TwoViewThreeDKinkTool()
Constructor.
bool PassesElementCuts(MatrixType::ElementList::const_iterator eIter, const pandora::ClusterSet &usedClusters) const
Whether a provided (iterator to a) matrix element passes the selection cuts for overshoot identificat...
float m_additionalXStepForKinkSearch
An additional (safety) step to tack-on when choosing x sampling.
std::vector< Modification > ModificationList
int m_nLayersForKinkSearch
The number of sliding fit layers to step in the kink search.
void GetIteratorListModifications(TwoViewTransverseTracksAlgorithm *const pAlgorithm, const IteratorList &iteratorList, ModificationList &modificationList) const
Get modification objects for specific elements of the matrix, identifying required splits and merges ...
ClusterMergeMap m_clusterMergeMap
The cluster merge map.
virtual ~TwoViewThreeDKinkTool()
Destructor.
float m_minMatchingScore
The min global matching score for particle creation.
float m_maxTransverseImpactParameter
The maximum transverse impact parameter for connecting broken clusters.
float m_minXOverlapFraction
The min x overlap fraction value for particle creation.
void SelectMatrixElements(MatrixType::ElementList::const_iterator eIter, const MatrixType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select elements representing possible components of interest due to overshoots or undershoots in clus...
bool Run(TwoViewTransverseTracksAlgorithm *const pAlgorithm, MatrixType &overlapMatrix)
Run the algorithm tool.
float m_minLongitudinalImpactParameter
The min longitudinal impact parameter for connecting accompanying clusters.
static bool IsALowestInX(const LArPointingCluster &pointingClusterA, const LArPointingCluster &pointingClusterB)
Whether pointing cluster labelled A extends to lowest x positions (as opposed to that labelled B)
float m_minLocallyMatchedFraction
The min locally matched fraction for particle creation.
pandora::ClusterList m_affectedClusters
The list of affected clusters.
float m_minImpactParameterCosTheta
The minimum cos theta (angle between vertex directions) for connecting broken clusters.
float m_cosThetaCutForKinkSearch
The cos theta cut used for the kink search in three dimensions.
bool ApplyChanges(TwoViewTransverseTracksAlgorithm *const pAlgorithm, const ModificationList &modificationList) const
Apply the changes cached in a modification list and update the matrix accordingly.
void GetModifications(TwoViewTransverseTracksAlgorithm *const pAlgorithm, const MatrixType &overlapMatrix, ModificationList &modificationList) const
Get modification objects, identifying required splits and merges for clusters.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
TwoViewTransverseTracksAlgorithm class.
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 GetX() const
Get the cartesian x coordinate.
float GetDotProduct(const CartesianVector &rhs) const
Get the dot product of the cartesian vector with a second cartesian vector.
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
const Pandora & GetPandora() const
Get the associated pandora instance.
const std::string & GetInstanceName() const
Get the instance name.
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
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 *, pandora::ClusterList > ClusterMergeMap
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > SplitPositionMap
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< CartesianVector > CartesianPointVector
std::unordered_set< const Cluster * > ClusterSet
StatusCode
The StatusCode enum.