9 #include "Pandora/AlgorithmHeaders.h" 23 TrackSplittingTool::TrackSplittingTool() :
24 m_minMatchedFraction(0.75
f),
25 m_minMatchedSamplingPoints(10),
26 m_minXOverlapFraction(0.75
f),
27 m_minMatchedSamplingPointRatio(2),
28 m_maxShortDeltaXFraction(0.2
f),
29 m_maxAbsoluteShortDeltaX(5.
f),
30 m_minLongDeltaXFraction(0.2
f),
31 m_minAbsoluteLongDeltaX(1.
f),
32 m_minSplitToVertexProjection(1.
f),
33 m_maxSplitVsFitPositionDistance(1.5
f)
41 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
42 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
45 this->
FindTracks(pAlgorithm, overlapTensor, splitPositionMap);
56 ClusterSet usedClusters;
60 for (
const Cluster *
const pKeyCluster : sortedKeyClusters)
62 if (!pKeyCluster->IsAvailable())
65 unsigned int nU(0), nV(0), nW(0);
80 if (!this->
PassesChecks(pAlgorithm, *(*iIter),
true, usedClusters, splitPositionMap) &&
81 !this->
PassesChecks(pAlgorithm, *(*iIter),
false, usedClusters, splitPositionMap))
86 usedClusters.insert((*iIter)->GetClusterU());
87 usedClusters.insert((*iIter)->GetClusterV());
88 usedClusters.insert((*iIter)->GetClusterW());
99 if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
108 const XOverlap &xOverlap(eIter->GetOverlapResult().GetXOverlap());
109 const float longSpan(std::max(xOverlap.GetXSpanU(), std::max(xOverlap.GetXSpanV(), xOverlap.GetXSpanW())));
110 const float shortSpan1(std::min(xOverlap.GetXSpanU(), std::min(xOverlap.GetXSpanV(), xOverlap.GetXSpanW())));
111 const float shortSpan2(((xOverlap.GetXSpanU() > shortSpan1) && (xOverlap.GetXSpanU() < longSpan)) ? xOverlap.GetXSpanU()
112 : ((xOverlap.GetXSpanV() > shortSpan1) && (xOverlap.GetXSpanV() < longSpan)) ? xOverlap.GetXSpanV()
113 : xOverlap.GetXSpanW());
115 if ((shortSpan1 < std::numeric_limits<float>::epsilon()) || (longSpan < std::numeric_limits<float>::epsilon()))
127 iteratorList.push_back(eIter);
134 const bool isMinX, ClusterSet &usedClusters,
SplitPositionMap &splitPositionMap)
const 145 if (longXSpan < std::numeric_limits<float>::epsilon())
149 const float shortDeltaX(
151 const float longDeltaX(isMinX ? (splitX - particle.
m_longMinX) : (particle.
m_longMaxX - splitX));
163 const CartesianVector &minPos1{
165 ? pointingCluster1.GetInnerVertex().GetPosition()
166 : pointingCluster1.GetOuterVertex().GetPosition()};
167 const CartesianVector &minPos2{
168 pointingCluster2.GetInnerVertex().GetPosition().GetX() < pointingCluster2.GetOuterVertex().GetPosition().GetX()
169 ? pointingCluster2.GetInnerVertex().GetPosition()
170 : pointingCluster2.GetOuterVertex().GetPosition()};
171 const CartesianVector &maxPos1{
172 pointingCluster1.GetInnerVertex().GetPosition().GetX() > pointingCluster1.GetOuterVertex().GetPosition().GetX()
173 ? pointingCluster1.GetInnerVertex().GetPosition()
174 : pointingCluster1.GetOuterVertex().GetPosition()};
175 const CartesianVector &maxPos2{
176 pointingCluster2.GetInnerVertex().GetPosition().GetX() > pointingCluster2.GetOuterVertex().GetPosition().GetX()
177 ? pointingCluster2.GetInnerVertex().GetPosition()
178 : pointingCluster2.GetOuterVertex().GetPosition()};
179 const CartesianVector position1(isMinX ? minPos1 : maxPos1);
180 const CartesianVector position2(isMinX ? minPos2 : maxPos2);
182 CartesianVector splitPosition(0.
f, 0.
f, 0.
f);
183 float chiSquared(std::numeric_limits<float>::max());
190 const CartesianVector splitToInnerVertex(splitPosition - longPointingCluster.GetInnerVertex().GetPosition());
191 const CartesianVector outerVertexToSplit(longPointingCluster.GetOuterVertex().GetPosition() - splitPosition);
192 const CartesianVector outerToInnerUnitVector(
193 (longPointingCluster.GetOuterVertex().GetPosition() - longPointingCluster.GetInnerVertex().GetPosition()).GetUnitVector());
198 splitPositionMap[particle.
m_pLongCluster].push_back(splitPosition);
202 catch (StatusCodeException &)
213 CartesianPointVector fitPositionList;
231 const XOverlap &xOverlap(element.GetOverlapResult().GetXOverlap());
233 const HitType longHitType = ((xOverlap.GetXSpanU() > xOverlap.GetXSpanV()) && (xOverlap.GetXSpanU() > xOverlap.GetXSpanW())) ? TPC_VIEW_U
234 : ((xOverlap.GetXSpanV() > xOverlap.GetXSpanU()) && (xOverlap.GetXSpanV() > xOverlap.GetXSpanW())) ? TPC_VIEW_V
235 : ((xOverlap.GetXSpanW() > xOverlap.GetXSpanU()) && (xOverlap.GetXSpanW() > xOverlap.GetXSpanV())) ? TPC_VIEW_W
238 if (HIT_CUSTOM == longHitType)
239 throw StatusCodeException(STATUS_CODE_FAILURE);
241 m_pLongCluster = (TPC_VIEW_U == longHitType) ? element.GetClusterU()
242 : (TPC_VIEW_V == longHitType) ? element.GetClusterV()
243 : element.GetClusterW();
244 m_pCluster1 = (TPC_VIEW_U == longHitType) ? element.GetClusterV() : element.GetClusterU();
245 m_pCluster2 = (TPC_VIEW_W == longHitType) ? element.GetClusterV() : element.GetClusterW();
246 m_longMinX = (TPC_VIEW_U == longHitType) ? xOverlap.GetUMinX()
247 : (TPC_VIEW_V == longHitType) ? xOverlap.GetVMinX()
248 : xOverlap.GetWMinX();
249 m_longMaxX = (TPC_VIEW_U == longHitType) ? xOverlap.GetUMaxX()
250 : (TPC_VIEW_V == longHitType) ? xOverlap.GetVMaxX()
251 : xOverlap.GetWMaxX();
252 m_short1MinX = (TPC_VIEW_U == longHitType) ? xOverlap.GetVMinX() : xOverlap.GetUMinX();
253 m_short1MaxX = (TPC_VIEW_U == longHitType) ? xOverlap.GetVMaxX() : xOverlap.GetUMaxX();
254 m_short2MinX = (TPC_VIEW_W == longHitType) ? xOverlap.GetVMinX() : xOverlap.GetWMinX();
255 m_short2MaxX = (TPC_VIEW_W == longHitType) ? xOverlap.GetVMaxX() : xOverlap.GetWMaxX();
263 PANDORA_RETURN_RESULT_IF_AND_IF(
264 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinMatchedFraction",
m_minMatchedFraction));
266 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
269 PANDORA_RETURN_RESULT_IF_AND_IF(
270 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinXOverlapFraction",
m_minXOverlapFraction));
272 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
275 PANDORA_RETURN_RESULT_IF_AND_IF(
276 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxShortDeltaXFraction",
m_maxShortDeltaXFraction));
278 PANDORA_RETURN_RESULT_IF_AND_IF(
279 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxAbsoluteShortDeltaX",
m_maxAbsoluteShortDeltaX));
281 PANDORA_RETURN_RESULT_IF_AND_IF(
282 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinLongDeltaXFraction",
m_minLongDeltaXFraction));
284 PANDORA_RETURN_RESULT_IF_AND_IF(
285 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinAbsoluteLongDeltaX",
m_minAbsoluteLongDeltaX));
287 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
290 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
293 return STATUS_CODE_SUCCESS;
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for particle creation.
virtual bool MakeClusterSplits(const SplitPositionMap &splitPositionMap)
Make cluster splits.
Header file for the lar pointing cluster class.
bool CheckSplitPosition(const pandora::CartesianVector &splitPosition, const float splitX, const TwoDSlidingFitResult &longFitResult) const
Check a candidate split position for consistency with the associated track cluster sliding linear fit...
std::vector< TensorType::ElementList::const_iterator > IteratorList
static bool IsLongerThanDirectConnections(IteratorList::const_iterator iIter, const TensorType::ElementList &elementList, const unsigned int minMatchedSamplingPointRatio, const pandora::ClusterSet &usedClusters)
Whether a long element is significantly longer that other elements with which it shares a cluster...
float m_minSplitToVertexProjection
Min projected distance between split position and either inner or outer vertex of long cluster...
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
const pandora::Cluster * m_pCluster2
Address of short cluster in view 2.
bool Run(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
void FindTracks(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, SplitPositionMap &splitPositionMap) const
Find remaining tracks, hidden by spurious track segments (and maybe other ambiguities) in the tensor...
float m_short2MinX
The min x coordinate of short cluster 2.
LArPointingCluster class.
void SelectElements(const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select a list of the relevant elements from a set of connected tensor elements.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
float m_maxAbsoluteShortDeltaX
Max x distance between ends of two short clusters (measured as an absolute distance) ...
float m_minMatchedFraction
The min matched sampling point fraction for particle creation.
Header file for the geometry helper class.
float m_longMinX
The min x coordinate of the long cluster.
std::vector< Element > ElementList
float m_minAbsoluteLongDeltaX
Min x distance between ends of short and long clusters (measured as an absolute distance) ...
float m_maxShortDeltaXFraction
Max x distance between ends of two short clusters (measured as fraction of long cluster x length) ...
Header file for the cluster helper class.
float m_minLongDeltaXFraction
Min x distance between ends of short and long clusters (measured as fraction of long cluster x length...
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > SplitPositionMap
const Vertex & GetInnerVertex() const
Get the inner vertex.
static float MergeTwoPositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const float position1, const float position2)
Merge two views (U,V) to give a third view (Z).
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
float m_longMaxX
The max x coordinate of the long cluster.
bool PassesChecks(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element, const bool isMinX, pandora::ClusterSet &usedClusters, SplitPositionMap &splitPositionMap) const
Whether a provided tensor element can be used to construct a pfo.
float m_short2MaxX
The max x coordinate of short cluster 2.
const pandora::Cluster * m_pCluster1
Address of short cluster in view 1.
float m_short1MaxX
The max x coordinate of short cluster 1.
float m_minXOverlapFraction
The min x overlap fraction (between long clusters and short cluster vs. shared overlap) ...
unsigned int m_minMatchedSamplingPointRatio
The min ratio between 1st and 2nd highest msps for simple ambiguity resolution.
float m_short1MinX
The min x coordinate of short cluster 1.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
static bool HasLongDirectConnections(IteratorList::const_iterator iIter, const IteratorList &iteratorList)
Whether a long element shares clusters with any other long elements.
ThreeViewTransverseTracksAlgorithm class.
float m_maxSplitVsFitPositionDistance
Max allowed distance between split position and sliding linear fit position at the split x coordinate...
pandora::StatusCode GetGlobalFitPositionListAtX(const float x, pandora::CartesianPointVector &positionList) const
Get a list of projected positions for a given input x coordinate.
const pandora::Cluster * m_pLongCluster
Address of the long cluster.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
TwoDSlidingFitResult class.
Particle(const TensorType::Element &element)
Constructor.
TheTensor::const_iterator const_iterator