LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
lar_content::OvershootSplittingAlgorithm Class Reference

OvershootSplittingAlgorithm class. More...

#include "OvershootSplittingAlgorithm.h"

Inheritance diagram for lar_content::OvershootSplittingAlgorithm:
lar_content::TwoDSlidingFitMultiSplitAlgorithm

Public Member Functions

 OvershootSplittingAlgorithm ()
 Default constructor. More...
 

Protected Types

typedef std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterPositionMap
 

Private Types

typedef std::pair< float, pandora::CartesianVector > MyTrajectoryPoint
 
typedef std::vector< MyTrajectoryPointMyTrajectoryPointList
 

Private Member Functions

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. More...
 
void FindBestSplitPositions (const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterPositionMap &clusterSplittingMap) const
 Determine best split positions based on sliding fit result. More...
 
void BuildIntersectionMap (const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterPositionMap &clusterIntersectionMap) const
 Use sliding fit results to calculate intersections of clusters. More...
 
void BuildSortedIntersectionMap (const TwoDSlidingFitResultMap &slidingFitResultMap, const ClusterPositionMap &clusterIntersectionMap, ClusterPositionMap &sortedIntersectionMap) const
 Use intersection points to decide on splitting points. More...
 
void PopulateSplitPositionMap (const ClusterPositionMap &sortedIntersectionMap, ClusterPositionMap &clusterSplittingMap) const
 Select split positions from sorted list of candidate positions. More...
 
pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 

Static Private Member Functions

static bool SortByHitProjection (const MyTrajectoryPoint &lhs, const MyTrajectoryPoint &rhs)
 Sort pfos by number of constituent hits. More...
 

Private Attributes

float m_minClusterLength
 
float m_maxClusterSeparation
 
float m_minVertexDisplacement
 
float m_maxIntersectDisplacement
 
float m_minSplitDisplacement
 

Detailed Description

Member Typedef Documentation

typedef std::unordered_map<const pandora::Cluster*, pandora::CartesianPointVector> lar_content::TwoDSlidingFitMultiSplitAlgorithm::ClusterPositionMap
protectedinherited

Definition at line 30 of file TwoDSlidingFitMultiSplitAlgorithm.h.

typedef std::pair<float, pandora::CartesianVector> lar_content::OvershootSplittingAlgorithm::MyTrajectoryPoint
private

Definition at line 31 of file OvershootSplittingAlgorithm.h.

Constructor & Destructor Documentation

Member Function Documentation

void lar_content::OvershootSplittingAlgorithm::BuildIntersectionMap ( const TwoDSlidingFitResultMap slidingFitResultMap,
ClusterPositionMap clusterIntersectionMap 
) const
private

Use sliding fit results to calculate intersections of clusters.

Parameters
slidingFitResultMapthe sliding fit result map
clusterIntersectionMapthe map of cluster intersection points

Definition at line 69 of file OvershootSplittingAlgorithm.cc.

References f, lar_content::LArClusterHelper::GetClosestDistance(), lar_content::LArPointingCluster::Vertex::GetDirection(), lar_content::LArPointingCluster::GetInnerVertex(), lar_content::LArPointingClusterHelper::GetIntersection(), lar_content::LArPointingCluster::GetOuterVertex(), lar_content::LArPointingCluster::Vertex::GetPosition(), m_maxClusterSeparation, m_minVertexDisplacement, max, min, and lar_content::LArClusterHelper::SortByNHits().

Referenced by FindBestSplitPositions().

71 {
72  ClusterList clusterList;
73  for (const auto &mapEntry : slidingFitResultMap) clusterList.push_back(mapEntry.first);
74  clusterList.sort(LArClusterHelper::SortByNHits);
75 
76  for (const Cluster *const pCluster1 : clusterList)
77  {
78  const TwoDSlidingFitResult &slidingFitResult1(slidingFitResultMap.at(pCluster1));
79 
80  for (const Cluster *const pCluster2 : clusterList)
81  {
82  if (pCluster1 == pCluster2)
83  continue;
84 
85  const TwoDSlidingFitResult &slidingFitResult2(slidingFitResultMap.at(pCluster2));
86 
87  try
88  {
89  const LArPointingCluster pointingCluster(slidingFitResult2);
90 
91  // Project pointing cluster onto target cluster
92  const CartesianVector innerPosition(pointingCluster.GetInnerVertex().GetPosition());
93  const CartesianVector outerPosition(pointingCluster.GetOuterVertex().GetPosition());
94  const float innerDisplacement(LArClusterHelper::GetClosestDistance(innerPosition, pCluster1));
95  const float outerDisplacement(LArClusterHelper::GetClosestDistance(outerPosition, pCluster1));
96  const bool useInner((innerDisplacement < outerDisplacement) ? true : false);
97 
98  const LArPointingCluster::Vertex &clusterVertex = (useInner ? pointingCluster.GetInnerVertex() :
99  pointingCluster.GetOuterVertex());
100 
101  float rL2(0.f), rT2(0.f);
102  CartesianVector intersectPosition2(0.f, 0.f, 0.f);
103 
104  try
105  {
106  LArPointingClusterHelper::GetIntersection(clusterVertex, pCluster1, intersectPosition2, rL2, rT2);
107  }
108  catch (const StatusCodeException &)
109  {
110  continue;
111  }
112 
113  if (rL2 < -m_maxIntersectDisplacement || rL2 > m_maxClusterSeparation)
114  continue;
115 
116  // Find projected position and direction on target cluster
117  float rL1(0.f), rT1(0.f);
118  CartesianVector projectedPosition1(0.f, 0.f, 0.f), projectedDirection1(0.f, 0.f, 0.f);
119  slidingFitResult1.GetLocalPosition(intersectPosition2, rL1, rT1);
120 
121  const StatusCode statusCodePosition(slidingFitResult1.GetGlobalFitPosition(rL1, projectedPosition1));
122  if (STATUS_CODE_SUCCESS != statusCodePosition)
123  throw pandora::StatusCodeException(statusCodePosition);
124 
125  const StatusCode statusCodeDirection(slidingFitResult1.GetGlobalFitDirection(rL1, projectedDirection1));
126  if (STATUS_CODE_SUCCESS != statusCodeDirection)
127  throw pandora::StatusCodeException(statusCodeDirection);
128 
129  const CartesianVector projectedPosition2(clusterVertex.GetPosition());
130  const CartesianVector projectedDirection2(clusterVertex.GetDirection());
131 
132  // Find intersection of pointing cluster and target cluster
133  float firstDisplacement(0.f), secondDisplacement(0.f);
134  CartesianVector intersectPosition1(0.f, 0.f, 0.f);
135 
136  try
137  {
138  LArPointingClusterHelper::GetIntersection(projectedPosition1, projectedDirection1, projectedPosition2, projectedDirection2,
139  intersectPosition1, firstDisplacement, secondDisplacement);
140  }
141  catch (const StatusCodeException &)
142  {
143  continue;
144  }
145 
146  // Store intersections if they're sufficiently far along the cluster trajectory
147  const float closestDisplacement1(LArClusterHelper::GetClosestDistance(intersectPosition1, pCluster1));
148  const float closestDisplacement2(LArClusterHelper::GetClosestDistance(intersectPosition1, pCluster2));
149 
150  if (std::max(closestDisplacement1, closestDisplacement2) > m_maxClusterSeparation)
151  continue;
152 
153  const CartesianVector minPosition(slidingFitResult1.GetGlobalMinLayerPosition());
154  const CartesianVector maxPosition(slidingFitResult1.GetGlobalMaxLayerPosition());
155  const float lengthSquared((maxPosition - minPosition).GetMagnitudeSquared());
156 
157  const float minDisplacementSquared((minPosition - intersectPosition1).GetMagnitudeSquared());
158  const float maxDisplacementSquared((maxPosition - intersectPosition1).GetMagnitudeSquared());
159 
160  if (std::min(minDisplacementSquared, maxDisplacementSquared) < (m_minVertexDisplacement * m_minVertexDisplacement) ||
161  std::max(minDisplacementSquared, maxDisplacementSquared) > lengthSquared)
162  continue;
163 
164  clusterIntersectionMap[pCluster1].push_back(intersectPosition1);
165  }
166  catch (StatusCodeException &statusCodeException)
167  {
168  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
169  throw statusCodeException;
170  }
171  }
172  }
173 }
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.
static void GetIntersection(const LArPointingCluster::Vertex &firstVertex, const LArPointingCluster::Vertex &secondVertex, pandora::CartesianVector &intersectPosition, float &firstDisplacement, float &secondDisplacement)
Get intersection of two vertices.
TFile f
Definition: plotHisto.C:6
Int_t max
Definition: plot.C:27
Int_t min
Definition: plot.C:26
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
void lar_content::OvershootSplittingAlgorithm::BuildSortedIntersectionMap ( const TwoDSlidingFitResultMap slidingFitResultMap,
const ClusterPositionMap clusterIntersectionMap,
ClusterPositionMap sortedIntersectionMap 
) const
private

Use intersection points to decide on splitting points.

Parameters
slidingFitResultMapthe sliding fit result map
clusterIntersectionMapthe input map of cluster intersection points
sortedIntersectionMapthe output map of sorted cluster intersection points

Definition at line 177 of file OvershootSplittingAlgorithm.cc.

References f, lar_content::TwoDSlidingFitResult::GetLocalPosition(), SortByHitProjection(), and lar_content::LArClusterHelper::SortByNHits().

Referenced by FindBestSplitPositions().

179 {
180  ClusterList clusterList;
181  for (const auto &mapEntry : clusterIntersectionMap) clusterList.push_back(mapEntry.first);
182  clusterList.sort(LArClusterHelper::SortByNHits);
183 
184  for (const Cluster *const pCluster : clusterList)
185  {
186  const CartesianPointVector &inputPositionVector(clusterIntersectionMap.at(pCluster));
187 
188  if (inputPositionVector.empty())
189  continue;
190 
191  TwoDSlidingFitResultMap::const_iterator sIter = slidingFitResultMap.find(pCluster);
192  if (slidingFitResultMap.end() == sIter)
193  throw StatusCodeException(STATUS_CODE_FAILURE);
194 
195  const TwoDSlidingFitResult &slidingFitResult = sIter->second;
196 
197  MyTrajectoryPointList trajectoryPointList;
198  for (CartesianPointVector::const_iterator pIter = inputPositionVector.begin(), pIterEnd = inputPositionVector.end();
199  pIter != pIterEnd; ++pIter)
200  {
201  const CartesianVector &position = *pIter;
202  float rL(0.f), rT(0.f);
203  slidingFitResult.GetLocalPosition(position, rL, rT);
204  trajectoryPointList.push_back(MyTrajectoryPoint(rL, position));
205  }
206 
207  std::sort(trajectoryPointList.begin(), trajectoryPointList.end(), OvershootSplittingAlgorithm::SortByHitProjection);
208 
209  if (trajectoryPointList.empty())
210  throw StatusCodeException(STATUS_CODE_FAILURE);
211 
212  for (MyTrajectoryPointList::const_iterator qIter = trajectoryPointList.begin(), qIterEnd = trajectoryPointList.end();
213  qIter != qIterEnd; ++qIter)
214  {
215  const CartesianVector &clusterPosition = qIter->second;
216  sortedIntersectionMap[pCluster].push_back(clusterPosition);
217  }
218  }
219 }
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.
TFile f
Definition: plotHisto.C:6
intermediate_table::const_iterator const_iterator
std::vector< MyTrajectoryPoint > MyTrajectoryPointList
std::pair< float, pandora::CartesianVector > MyTrajectoryPoint
static bool SortByHitProjection(const MyTrajectoryPoint &lhs, const MyTrajectoryPoint &rhs)
Sort pfos by number of constituent hits.
void lar_content::OvershootSplittingAlgorithm::FindBestSplitPositions ( const TwoDSlidingFitResultMap slidingFitResultMap,
ClusterPositionMap clusterSplittingMap 
) const
privatevirtual

Determine best split positions based on sliding fit result.

Parameters
slidingFitResultMapmapping from clusters to sliding fit results
clusterSplittingMapmapping from clusters to split positions

Implements lar_content::TwoDSlidingFitMultiSplitAlgorithm.

Definition at line 52 of file OvershootSplittingAlgorithm.cc.

References BuildIntersectionMap(), BuildSortedIntersectionMap(), and PopulateSplitPositionMap().

54 {
55  // Use sliding fit results to build a list of intersection points
56  ClusterPositionMap clusterIntersectionMap;
57  this->BuildIntersectionMap(slidingFitResultMap, clusterIntersectionMap);
58 
59  // Sort intersection points according to their position along the sliding fit
60  ClusterPositionMap sortedIntersectionMap;
61  this->BuildSortedIntersectionMap(slidingFitResultMap, clusterIntersectionMap, sortedIntersectionMap);
62 
63  // Use intersection points to decide where/if to split cluster
64  this->PopulateSplitPositionMap(sortedIntersectionMap, clusterSplittingMap);
65 }
void BuildIntersectionMap(const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterPositionMap &clusterIntersectionMap) const
Use sliding fit results to calculate intersections of clusters.
void PopulateSplitPositionMap(const ClusterPositionMap &sortedIntersectionMap, ClusterPositionMap &clusterSplittingMap) const
Select split positions from sorted list of candidate positions.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterPositionMap
void BuildSortedIntersectionMap(const TwoDSlidingFitResultMap &slidingFitResultMap, const ClusterPositionMap &clusterIntersectionMap, ClusterPositionMap &sortedIntersectionMap) const
Use intersection points to decide on splitting points.
void lar_content::OvershootSplittingAlgorithm::GetListOfCleanClusters ( const pandora::ClusterList *const  pClusterList,
pandora::ClusterVector &  clusterVector 
) const
privatevirtual

Populate cluster vector with subset of cluster list, containing clusters judged to be clean.

Parameters
pClusterListaddress of the cluster list
clusterVectorto receive the populated cluster vector

Implements lar_content::TwoDSlidingFitMultiSplitAlgorithm.

Definition at line 35 of file OvershootSplittingAlgorithm.cc.

References lar_content::LArClusterHelper::GetLengthSquared(), m_minClusterLength, and lar_content::LArClusterHelper::SortByNHits().

36 {
37  for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
38  {
39  const Cluster *const pCluster = *iter;
40 
42  continue;
43 
44  clusterVector.push_back(pCluster);
45  }
46 
47  std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
48 }
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.
intermediate_table::const_iterator const_iterator
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
void lar_content::OvershootSplittingAlgorithm::PopulateSplitPositionMap ( const ClusterPositionMap sortedIntersectionMap,
ClusterPositionMap clusterSplittingMap 
) const
private

Select split positions from sorted list of candidate positions.

Parameters
sortedIntersectionMapthe input map of candidate split positions
clusterSplittingMapthe output map of selected split positions

Definition at line 223 of file OvershootSplittingAlgorithm.cc.

References f, m_maxIntersectDisplacement, m_minSplitDisplacement, SortByHitProjection(), and lar_content::LArClusterHelper::SortByNHits().

Referenced by FindBestSplitPositions().

225 {
226  ClusterList clusterList;
227  for (const auto &mapEntry : clusterIntersectionMap) clusterList.push_back(mapEntry.first);
228  clusterList.sort(LArClusterHelper::SortByNHits);
229 
230  for (const Cluster *const pCluster : clusterList)
231  {
232  const CartesianPointVector &inputPositionVector(clusterIntersectionMap.at(pCluster));
233 
234  if (inputPositionVector.empty())
235  continue;
236 
237  // Select pairs of positions within a given separation, and calculate their average position
238  MyTrajectoryPointList candidatePositionList;
239 
240  bool foundPrevPosition(false);
241  CartesianVector prevPosition(0.f, 0.f, 0.f);
242 
243  for (CartesianPointVector::const_iterator pIter = inputPositionVector.begin(), pIterEnd = inputPositionVector.end();
244  pIter != pIterEnd; ++pIter)
245  {
246  const CartesianVector &nextPosition = *pIter;
247 
248  if (foundPrevPosition)
249  {
250  const CartesianVector averagePosition((nextPosition + prevPosition) * 0.5f);
251  const float displacementSquared((nextPosition - prevPosition).GetMagnitudeSquared());
252 
253  if (displacementSquared < m_maxIntersectDisplacement * m_maxIntersectDisplacement)
254  candidatePositionList.push_back(MyTrajectoryPoint(displacementSquared, averagePosition));
255  }
256 
257  prevPosition = nextPosition;
258  foundPrevPosition = true;
259  }
260 
261  if (candidatePositionList.empty())
262  continue;
263 
264  std::sort(candidatePositionList.begin(), candidatePositionList.end(), OvershootSplittingAlgorithm::SortByHitProjection);
265 
266  // Use the average positions of the closest pairs of points as the split position
267  bool foundPrevCandidate(false);
268  CartesianVector prevCandidate(0.f, 0.f, 0.f);
269 
270  for (MyTrajectoryPointList::const_iterator pIter = candidatePositionList.begin(), pIterEnd = candidatePositionList.end();
271  pIter != pIterEnd; ++pIter)
272  {
273  const CartesianVector &nextCandidate = pIter->second;
274 
275  if (foundPrevCandidate)
276  {
277  if((nextCandidate - prevCandidate).GetMagnitudeSquared() < m_minSplitDisplacement * m_minSplitDisplacement)
278  continue;
279  }
280 
281  clusterSplittingMap[pCluster].push_back(nextCandidate);
282  prevCandidate = nextCandidate;
283  foundPrevCandidate = true;
284  }
285  }
286 }
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.
TFile f
Definition: plotHisto.C:6
intermediate_table::const_iterator const_iterator
std::vector< MyTrajectoryPoint > MyTrajectoryPointList
std::pair< float, pandora::CartesianVector > MyTrajectoryPoint
static bool SortByHitProjection(const MyTrajectoryPoint &lhs, const MyTrajectoryPoint &rhs)
Sort pfos by number of constituent hits.
StatusCode lar_content::OvershootSplittingAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
private

Definition at line 300 of file OvershootSplittingAlgorithm.cc.

References m_maxClusterSeparation, m_maxIntersectDisplacement, m_minClusterLength, m_minSplitDisplacement, m_minVertexDisplacement, and lar_content::TwoDSlidingFitMultiSplitAlgorithm::ReadSettings().

301 {
302  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
303  "MinClusterLength", m_minClusterLength));
304 
305  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
306  "MaxClusterSeparation", m_maxClusterSeparation));
307 
308  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
309  "MinVertexDisplacement", m_minVertexDisplacement));
310 
311  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
312  "MaxIntersectDisplacement", m_maxIntersectDisplacement));
313 
314  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
315  "MinSplitDisplacement", m_minSplitDisplacement));
316 
318 }
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
bool lar_content::OvershootSplittingAlgorithm::SortByHitProjection ( const MyTrajectoryPoint lhs,
const MyTrajectoryPoint rhs 
)
staticprivate

Sort pfos by number of constituent hits.

Parameters
pLhsaddress of first pfo
pRhsaddress of second pfo

Definition at line 290 of file OvershootSplittingAlgorithm.cc.

Referenced by BuildSortedIntersectionMap(), and PopulateSplitPositionMap().

291 {
292  if (lhs.first != rhs.first)
293  return (lhs.first < rhs.first);
294 
295  return (lhs.second.GetMagnitudeSquared() > rhs.second.GetMagnitudeSquared());
296 }

Member Data Documentation

float lar_content::OvershootSplittingAlgorithm::m_maxClusterSeparation
private

Definition at line 71 of file OvershootSplittingAlgorithm.h.

Referenced by BuildIntersectionMap(), and ReadSettings().

float lar_content::OvershootSplittingAlgorithm::m_maxIntersectDisplacement
private

Definition at line 73 of file OvershootSplittingAlgorithm.h.

Referenced by PopulateSplitPositionMap(), and ReadSettings().

float lar_content::OvershootSplittingAlgorithm::m_minClusterLength
private

Definition at line 70 of file OvershootSplittingAlgorithm.h.

Referenced by GetListOfCleanClusters(), and ReadSettings().

float lar_content::OvershootSplittingAlgorithm::m_minSplitDisplacement
private

Definition at line 74 of file OvershootSplittingAlgorithm.h.

Referenced by PopulateSplitPositionMap(), and ReadSettings().

float lar_content::OvershootSplittingAlgorithm::m_minVertexDisplacement
private

Definition at line 72 of file OvershootSplittingAlgorithm.h.

Referenced by BuildIntersectionMap(), and ReadSettings().


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