Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
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...
 
- Public Member Functions inherited from lar_content::TwoDSlidingFitMultiSplitAlgorithm
 TwoDSlidingFitMultiSplitAlgorithm ()
 Default constructor. More...
 

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
 

Additional Inherited Members

- Protected Types inherited from lar_content::TwoDSlidingFitMultiSplitAlgorithm
typedef std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterPositionMap
 
- Protected Member Functions inherited from lar_content::TwoDSlidingFitMultiSplitAlgorithm
pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 

Detailed Description

OvershootSplittingAlgorithm class.

Definition at line 19 of file OvershootSplittingAlgorithm.h.

Member Typedef Documentation

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

Definition at line 31 of file OvershootSplittingAlgorithm.h.

Definition at line 32 of file OvershootSplittingAlgorithm.h.

Constructor & Destructor Documentation

lar_content::OvershootSplittingAlgorithm::OvershootSplittingAlgorithm ( )

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 68 of file OvershootSplittingAlgorithm.cc.

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

177 {
178  ClusterList clusterList;
179  for (const auto &mapEntry : clusterIntersectionMap)
180  clusterList.push_back(mapEntry.first);
181  clusterList.sort(LArClusterHelper::SortByNHits);
182 
183  for (const Cluster *const pCluster : clusterList)
184  {
185  const CartesianPointVector &inputPositionVector(clusterIntersectionMap.at(pCluster));
186 
187  if (inputPositionVector.empty())
188  continue;
189 
190  TwoDSlidingFitResultMap::const_iterator sIter = slidingFitResultMap.find(pCluster);
191  if (slidingFitResultMap.end() == sIter)
192  throw StatusCodeException(STATUS_CODE_FAILURE);
193 
194  const TwoDSlidingFitResult &slidingFitResult = sIter->second;
195 
196  MyTrajectoryPointList trajectoryPointList;
197  for (CartesianPointVector::const_iterator pIter = inputPositionVector.begin(), pIterEnd = inputPositionVector.end(); pIter != pIterEnd; ++pIter)
198  {
199  const CartesianVector &position = *pIter;
200  float rL(0.f), rT(0.f);
201  slidingFitResult.GetLocalPosition(position, rL, rT);
202  trajectoryPointList.push_back(MyTrajectoryPoint(rL, position));
203  }
204 
205  std::sort(trajectoryPointList.begin(), trajectoryPointList.end(), OvershootSplittingAlgorithm::SortByHitProjection);
206 
207  if (trajectoryPointList.empty())
208  throw StatusCodeException(STATUS_CODE_FAILURE);
209 
210  for (MyTrajectoryPointList::const_iterator qIter = trajectoryPointList.begin(), qIterEnd = trajectoryPointList.end(); qIter != qIterEnd; ++qIter)
211  {
212  const CartesianVector &clusterPosition = qIter->second;
213  sortedIntersectionMap[pCluster].push_back(clusterPosition);
214  }
215  }
216 }
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
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.

53 {
54  // Use sliding fit results to build a list of intersection points
55  ClusterPositionMap clusterIntersectionMap;
56  this->BuildIntersectionMap(slidingFitResultMap, clusterIntersectionMap);
57 
58  // Sort intersection points according to their position along the sliding fit
59  ClusterPositionMap sortedIntersectionMap;
60  this->BuildSortedIntersectionMap(slidingFitResultMap, clusterIntersectionMap, sortedIntersectionMap);
61 
62  // Use intersection points to decide where/if to split cluster
63  this->PopulateSplitPositionMap(sortedIntersectionMap, clusterSplittingMap);
64 }
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterPositionMap
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.
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.

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 220 of file OvershootSplittingAlgorithm.cc.

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

297 {
298  PANDORA_RETURN_RESULT_IF_AND_IF(
299  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLength", m_minClusterLength));
300 
301  PANDORA_RETURN_RESULT_IF_AND_IF(
302  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxClusterSeparation", m_maxClusterSeparation));
303 
304  PANDORA_RETURN_RESULT_IF_AND_IF(
305  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinVertexDisplacement", m_minVertexDisplacement));
306 
307  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
308  XmlHelper::ReadValue(xmlHandle, "MaxIntersectDisplacement", m_maxIntersectDisplacement));
309 
310  PANDORA_RETURN_RESULT_IF_AND_IF(
311  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinSplitDisplacement", m_minSplitDisplacement));
312 
314 }
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 286 of file OvershootSplittingAlgorithm.cc.

287 {
288  if (lhs.first != rhs.first)
289  return (lhs.first < rhs.first);
290 
291  return (lhs.second.GetMagnitudeSquared() > rhs.second.GetMagnitudeSquared());
292 }

Member Data Documentation

float lar_content::OvershootSplittingAlgorithm::m_maxClusterSeparation
private

Definition at line 71 of file OvershootSplittingAlgorithm.h.

float lar_content::OvershootSplittingAlgorithm::m_maxIntersectDisplacement
private

Definition at line 73 of file OvershootSplittingAlgorithm.h.

float lar_content::OvershootSplittingAlgorithm::m_minClusterLength
private

Definition at line 70 of file OvershootSplittingAlgorithm.h.

float lar_content::OvershootSplittingAlgorithm::m_minSplitDisplacement
private

Definition at line 74 of file OvershootSplittingAlgorithm.h.

float lar_content::OvershootSplittingAlgorithm::m_minVertexDisplacement
private

Definition at line 72 of file OvershootSplittingAlgorithm.h.


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