LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CandidateVertexCreationAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 #include <utility>
17 
18 using namespace pandora;
19 
20 namespace lar_content
21 {
22 
23 CandidateVertexCreationAlgorithm::CandidateVertexCreationAlgorithm() :
24  m_replaceCurrentVertexList(true),
25  m_slidingFitWindow(20),
26  m_minClusterCaloHits(5),
27  m_minClusterLengthSquared(3.f * 3.f),
28  m_chiSquaredCut(2.f),
29  m_enableEndpointCandidates(true),
30  m_maxEndpointXDiscrepancy(4.f),
31  m_enableCrossingCandidates(false),
32  m_nMaxCrossingCandidates(500),
33  m_maxCrossingXDiscrepancy(0.5f),
34  m_extrapolationNSteps(200),
35  m_extrapolationStepSize(0.1f),
36  m_maxCrossingSeparationSquared(2.f * 2.f),
37  m_minNearbyCrossingDistanceSquared(0.5f * 0.5f)
38 {
39 }
40 
41 //------------------------------------------------------------------------------------------------------------------------------------------
42 
44 {
45  try
46  {
47  ClusterVector clusterVectorU, clusterVectorV, clusterVectorW;
48  this->SelectClusters(clusterVectorU, clusterVectorV, clusterVectorW);
49 
50  const VertexList *pVertexList(NULL); std::string temporaryListName;
51  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, temporaryListName));
52 
54  {
55  this->CreateEndpointCandidates(clusterVectorU, clusterVectorV);
56  this->CreateEndpointCandidates(clusterVectorU, clusterVectorW);
57  this->CreateEndpointCandidates(clusterVectorV, clusterVectorW);
58  }
59 
61  this->CreateCrossingCandidates(clusterVectorU, clusterVectorV, clusterVectorW);
62 
63  if (!pVertexList->empty())
64  {
65  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_outputVertexListName));
66 
68  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
69  }
70  }
71  catch (StatusCodeException &statusCodeException)
72  {
73  this->TidyUp();
74  throw statusCodeException;
75  }
76 
77  this->TidyUp();
78 
79  return STATUS_CODE_SUCCESS;
80 }
81 
82 //------------------------------------------------------------------------------------------------------------------------------------------
83 
84 void CandidateVertexCreationAlgorithm::SelectClusters(ClusterVector &clusterVectorU, ClusterVector &clusterVectorV, ClusterVector &clusterVectorW)
85 {
86  for (const std::string &clusterListName : m_inputClusterListNames)
87  {
88  const ClusterList *pClusterList(NULL);
89  PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, clusterListName, pClusterList));
90 
91  if (!pClusterList || pClusterList->empty())
92  {
93  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
94  std::cout << "CandidateVertexCreationAlgorithm: unable to find cluster list " << clusterListName << std::endl;
95 
96  continue;
97  }
98 
99  const HitType hitType(LArClusterHelper::GetClusterHitType(*(pClusterList->begin())));
100 
101  if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
102  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
103 
104  ClusterVector &selectedClusterVector((TPC_VIEW_U == hitType) ? clusterVectorU : (TPC_VIEW_V == hitType) ? clusterVectorV : clusterVectorW);
105 
106  if (!selectedClusterVector.empty())
107  throw StatusCodeException(STATUS_CODE_FAILURE);
108 
109  ClusterVector sortedClusters(pClusterList->begin(), pClusterList->end());
110  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
111 
112  for (const Cluster *const pCluster : sortedClusters)
113  {
114  if (pCluster->GetNCaloHits() < m_minClusterCaloHits)
115  continue;
116 
118  continue;
119 
120  try
121  {
122  this->AddToSlidingFitCache(pCluster);
123  selectedClusterVector.push_back(pCluster);
124  }
125  catch (StatusCodeException &statusCodeException)
126  {
127  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
128  throw statusCodeException;
129  }
130  }
131  }
132 }
133 
134 //------------------------------------------------------------------------------------------------------------------------------------------
135 
136 void CandidateVertexCreationAlgorithm::CreateEndpointCandidates(const ClusterVector &clusterVector1, const ClusterVector &clusterVector2) const
137 {
138  for (const Cluster *const pCluster1 : clusterVector1)
139  {
140  const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
141 
142  const TwoDSlidingFitResult &fitResult1(this->GetCachedSlidingFitResult(pCluster1));
143  const CartesianVector minLayerPosition1(fitResult1.GetGlobalMinLayerPosition());
144  const CartesianVector maxLayerPosition1(fitResult1.GetGlobalMaxLayerPosition());
145 
146  for (const Cluster *const pCluster2 : clusterVector2)
147  {
148  const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
149 
150  const TwoDSlidingFitResult &fitResult2(this->GetCachedSlidingFitResult(pCluster2));
151  const CartesianVector minLayerPosition2(fitResult2.GetGlobalMinLayerPosition());
152  const CartesianVector maxLayerPosition2(fitResult2.GetGlobalMaxLayerPosition());
153 
154  this->CreateEndpointVertex(maxLayerPosition1, hitType1, fitResult2);
155  this->CreateEndpointVertex(minLayerPosition1, hitType1, fitResult2);
156  this->CreateEndpointVertex(maxLayerPosition2, hitType2, fitResult1);
157  this->CreateEndpointVertex(minLayerPosition2, hitType2, fitResult1);
158  }
159  }
160 }
161 
162 //------------------------------------------------------------------------------------------------------------------------------------------
163 
164 void CandidateVertexCreationAlgorithm::CreateEndpointVertex(const CartesianVector &position1, const HitType hitType1, const TwoDSlidingFitResult &fitResult2) const
165 {
166  const CartesianVector minLayerPosition2(fitResult2.GetGlobalMinLayerPosition());
167  const CartesianVector maxLayerPosition2(fitResult2.GetGlobalMaxLayerPosition());
168 
169  if ((((position1.GetX() < minLayerPosition2.GetX()) && (position1.GetX() < maxLayerPosition2.GetX())) ||
170  ((position1.GetX() > minLayerPosition2.GetX()) && (position1.GetX() > maxLayerPosition2.GetX()))) &&
171  (std::fabs(position1.GetX() - minLayerPosition2.GetX()) > m_maxEndpointXDiscrepancy) &&
172  (std::fabs(position1.GetX() - maxLayerPosition2.GetX()) > m_maxEndpointXDiscrepancy))
173  {
174  return;
175  }
176 
177  CartesianVector position2(0.f, 0.f, 0.f);
178  if (STATUS_CODE_SUCCESS != fitResult2.GetExtrapolatedPositionAtX(position1.GetX(), position2))
179  return;
180 
181  const HitType hitType2(LArClusterHelper::GetClusterHitType(fitResult2.GetCluster()));
182 
183  float chiSquared(0.f);
184  CartesianVector position3D(0.f, 0.f, 0.f);
185  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, position1, position2, position3D, chiSquared);
186 
187  if (chiSquared > m_chiSquaredCut)
188  return;
189 
190  PandoraContentApi::Vertex::Parameters parameters;
191  parameters.m_position = position3D;
192  parameters.m_vertexLabel = VERTEX_INTERACTION;
193  parameters.m_vertexType = VERTEX_3D;
194 
195  const Vertex *pVertex(NULL);
196  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
197 }
198 
199 //------------------------------------------------------------------------------------------------------------------------------------------
200 
202  const ClusterVector &clusterVectorW) const
203 {
204  CartesianPointVector crossingsU, crossingsV, crossingsW;
205  this->FindCrossingPoints(clusterVectorU, crossingsU);
206  this->FindCrossingPoints(clusterVectorV, crossingsV);
207  this->FindCrossingPoints(clusterVectorW, crossingsW);
208 
209  unsigned int nCrossingCandidates(0);
210  this->CreateCrossingVertices(crossingsU, crossingsV, TPC_VIEW_U, TPC_VIEW_V, nCrossingCandidates);
211  this->CreateCrossingVertices(crossingsU, crossingsW, TPC_VIEW_U, TPC_VIEW_W, nCrossingCandidates);
212  this->CreateCrossingVertices(crossingsV, crossingsW, TPC_VIEW_V, TPC_VIEW_W, nCrossingCandidates);
213 }
214 
215 //------------------------------------------------------------------------------------------------------------------------------------------
216 
217 void CandidateVertexCreationAlgorithm::FindCrossingPoints(const ClusterVector &clusterVector, CartesianPointVector &crossingPoints) const
218 {
219  ClusterToSpacepointsMap clusterToSpacepointsMap;
220 
221  for (const Cluster *const pCluster : clusterVector)
222  {
223  ClusterToSpacepointsMap::iterator mapIter(clusterToSpacepointsMap.emplace(pCluster, CartesianPointVector()).first);
224  this->GetSpacepoints(pCluster, mapIter->second);
225  }
226 
227  for (const Cluster *const pCluster1 : clusterVector)
228  {
229  for (const Cluster *const pCluster2 : clusterVector)
230  {
231  if (pCluster1 == pCluster2)
232  continue;
233 
234  this->FindCrossingPoints(clusterToSpacepointsMap.at(pCluster1), clusterToSpacepointsMap.at(pCluster2), crossingPoints);
235  }
236  }
237 }
238 
239 //------------------------------------------------------------------------------------------------------------------------------------------
240 
241 void CandidateVertexCreationAlgorithm::GetSpacepoints(const Cluster *const pCluster, CartesianPointVector &spacepoints) const
242 {
243  LArClusterHelper::GetCoordinateVector(pCluster, spacepoints);
244 
245  const TwoDSlidingFitResult &fitResult(this->GetCachedSlidingFitResult(pCluster));
246  const float minLayerRL(fitResult.GetL(fitResult.GetMinLayer()));
247  const float maxLayerRL(fitResult.GetL(fitResult.GetMaxLayer()));
248 
249  for (unsigned int iStep = 0; iStep < m_extrapolationNSteps; ++ iStep)
250  {
251  const float deltaRL(static_cast<float>(iStep) * m_extrapolationStepSize);
252 
253  CartesianVector positionPositive(0.f, 0.f, 0.f), positionNegative(0.f, 0.f, 0.f);
254  fitResult.GetExtrapolatedPosition(maxLayerRL + deltaRL, positionPositive);
255  fitResult.GetExtrapolatedPosition(minLayerRL - deltaRL, positionNegative);
256 
257  spacepoints.push_back(positionPositive);
258  spacepoints.push_back(positionNegative);
259  }
260 
261  std::sort(spacepoints.begin(), spacepoints.end(), LArClusterHelper::SortCoordinatesByPosition);
262 }
263 
264 //------------------------------------------------------------------------------------------------------------------------------------------
265 
266 void CandidateVertexCreationAlgorithm::FindCrossingPoints(const CartesianPointVector &spacepoints1, const CartesianPointVector &spacepoints2,
267  CartesianPointVector &crossingPoints) const
268 {
269  bool bestCrossingFound(false);
270  float bestSeparationSquared(m_maxCrossingSeparationSquared);
271  CartesianVector bestPosition1(0.f, 0.f, 0.f), bestPosition2(0.f, 0.f, 0.f);
272 
273  for (const CartesianVector &position1: spacepoints1)
274  {
275  for (const CartesianVector &position2: spacepoints2)
276  {
277  const float separationSquared((position1 - position2).GetMagnitudeSquared());
278 
279  if (separationSquared < bestSeparationSquared)
280  {
281  bestCrossingFound = true;
282  bestSeparationSquared = separationSquared;
283  bestPosition1 = position1;
284  bestPosition2 = position2;
285  }
286  }
287  }
288 
289  if (bestCrossingFound)
290  {
291  bool alreadyPopulated(false);
292 
293  for (const CartesianVector &existingPosition: crossingPoints)
294  {
295  if (((existingPosition - bestPosition1).GetMagnitudeSquared() < m_minNearbyCrossingDistanceSquared) ||
296  ((existingPosition - bestPosition2).GetMagnitudeSquared() < m_minNearbyCrossingDistanceSquared))
297  {
298  alreadyPopulated = true;
299  break;
300  }
301  }
302 
303  if (!alreadyPopulated)
304  {
305  crossingPoints.push_back(bestPosition1);
306  crossingPoints.push_back(bestPosition2);
307  }
308  }
309 }
310 
311 //------------------------------------------------------------------------------------------------------------------------------------------
312 
313 void CandidateVertexCreationAlgorithm::CreateCrossingVertices(const CartesianPointVector &crossingPoints1, const CartesianPointVector &crossingPoints2,
314  const HitType hitType1, const HitType hitType2, unsigned int &nCrossingCandidates) const
315 {
316 
317  for (const CartesianVector &position1: crossingPoints1)
318  {
319  for (const CartesianVector &position2: crossingPoints2)
320  {
321  if (nCrossingCandidates > m_nMaxCrossingCandidates)
322  return;
323 
324  if (std::fabs(position1.GetX() - position2.GetX()) > m_maxCrossingXDiscrepancy)
325  continue;
326 
327  float chiSquared(0.f);
328  CartesianVector position3D(0.f, 0.f, 0.f);
329  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, position1, position2, position3D, chiSquared);
330 
331  if (chiSquared > m_chiSquaredCut)
332  continue;
333 
334  PandoraContentApi::Vertex::Parameters parameters;
335  parameters.m_position = position3D;
336  parameters.m_vertexLabel = VERTEX_INTERACTION;
337  parameters.m_vertexType = VERTEX_3D;
338 
339  const Vertex *pVertex(NULL);
340  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
341  ++nCrossingCandidates;
342  }
343  }
344 }
345 
346 //------------------------------------------------------------------------------------------------------------------------------------------
347 
349 {
350  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
351  const TwoDSlidingFitResult slidingFitResult(pCluster, m_slidingFitWindow, slidingFitPitch);
352 
353  if (!m_slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult)).second)
354  throw StatusCodeException(STATUS_CODE_FAILURE);
355 }
356 
357 //------------------------------------------------------------------------------------------------------------------------------------------
358 
360 {
362 
363  if (m_slidingFitResultMap.end() == iter)
364  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
365 
366  return iter->second;
367 }
368 
369 //------------------------------------------------------------------------------------------------------------------------------------------
370 
372 {
373  m_slidingFitResultMap.clear();
374 }
375 
376 //------------------------------------------------------------------------------------------------------------------------------------------
377 
378 StatusCode CandidateVertexCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
379 {
380  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
381  "InputClusterListNames", m_inputClusterListNames));
382 
383  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
384  "OutputVertexListName", m_outputVertexListName));
385 
386  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
387  "ReplaceCurrentVertexList", m_replaceCurrentVertexList));
388 
389  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
390  "SlidingFitWindow", m_slidingFitWindow));
391 
392  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
393  "MinClusterCaloHits", m_minClusterCaloHits));
394 
395  float minClusterLength = std::sqrt(m_minClusterLengthSquared);
396  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
397  "MinClusterLength", minClusterLength));
398  m_minClusterLengthSquared = minClusterLength * minClusterLength;
399 
400  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
401  "ChiSquaredCut", m_chiSquaredCut));
402 
403  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
404  "EnableEndpointCandidates", m_enableEndpointCandidates));
405 
406  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
407  "MaxEndpointXDiscrepancy", m_maxEndpointXDiscrepancy));
408 
409  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
410  "EnableCrossingCandidates", m_enableCrossingCandidates));
411 
412  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
413  "NMaxCrossingCandidates", m_nMaxCrossingCandidates));
414 
415  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
416  "MaxCrossingXDiscrepancy", m_maxCrossingXDiscrepancy));
417 
418  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
419  "ExtrapolationNSteps", m_extrapolationNSteps));
420 
421  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
422  "ExtrapolationStepSize", m_extrapolationStepSize));
423 
424  float maxCrossingSeparation = std::sqrt(m_maxCrossingSeparationSquared);
425  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
426  "MaxCrossingSeparation", maxCrossingSeparation));
427  m_maxCrossingSeparationSquared = maxCrossingSeparation * maxCrossingSeparation;
428 
429  float minNearbyCrossingDistance = std::sqrt(m_minNearbyCrossingDistanceSquared);
430  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
431  "MinNearbyCrossingDistance", minNearbyCrossingDistance));
432  m_minNearbyCrossingDistanceSquared = minNearbyCrossingDistance * minNearbyCrossingDistance;
433 
434  return STATUS_CODE_SUCCESS;
435 }
436 
437 } // namespace lar_content
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.
float m_minClusterLengthSquared
The min length (squared) in base cluster selection method.
void CreateEndpointVertex(const pandora::CartesianVector &position1, const pandora::HitType hitType1, const TwoDSlidingFitResult &fitResult2) const
Create a candidate vertex position, using an end-point position from one cluster and sliding fit to a...
void CreateCrossingCandidates(const pandora::ClusterVector &clusterVectorU, const pandora::ClusterVector &clusterVectorV, const pandora::ClusterVector &clusterVectorW) const
Extrapolate 2D clusters, find where they cross, and match crossing points between views to create ver...
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.
void GetSpacepoints(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &spacePoints) const
Get a list of spacepoints representing cluster 2D hit positions and extrapolated positions.
float m_extrapolationStepSize
The extrapolation step size in cm.
float m_maxCrossingSeparationSquared
The separation (squared) between spacepoints below which a crossing can be identified.
intermediate_table::iterator iterator
pandora::StatusCode GetExtrapolatedPositionAtX(const float x, pandora::CartesianVector &position) const
Get extrapolated position (beyond span) for a given input x coordinate.
bool m_enableEndpointCandidates
Whether to create endpoint-based candidates.
void AddToSlidingFitCache(const pandora::Cluster *const pCluster)
Creates a 2D sliding fit of a cluster and stores it for later use.
bool m_replaceCurrentVertexList
Whether to replace the current vertex list with the output list.
float m_maxEndpointXDiscrepancy
The max cluster endpoint discrepancy.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
void FindCrossingPoints(const pandora::ClusterVector &clusterVector, pandora::CartesianPointVector &crossingPoints) const
Identify where (extrapolated) clusters plausibly cross in 2D.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
TFile f
Definition: plotHisto.C:6
static bool SortCoordinatesByPosition(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
Sort cartesian vectors by their position (use Z, followed by X, followed by Y)
Header file for the geometry helper class.
Header file for the candidate vertex creation algorithm class.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
intermediate_table::const_iterator const_iterator
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
Header file for the cluster helper class.
bool m_enableCrossingCandidates
Whether to create crossing vertex candidates.
float m_maxCrossingXDiscrepancy
The max cluster endpoint discrepancy.
TwoDSlidingFitResultMap m_slidingFitResultMap
The sliding fit result map.
void CreateEndpointCandidates(const pandora::ClusterVector &clusterVector1, const pandora::ClusterVector &clusterVector2) const
Create candidate vertex positions by comparing pairs of cluster end positions.
pandora::StatusCode GetExtrapolatedPosition(const float rL, pandora::CartesianVector &position) const
Get extrapolated position (beyond span) for a given input coordinate.
float m_minNearbyCrossingDistanceSquared
The minimum allowed distance between identified crossing positions.
unsigned int m_minClusterCaloHits
The min number of hits in base cluster selection method.
void TidyUp()
Clear relevant algorithm member variables between events.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
unsigned int m_extrapolationNSteps
Number of extrapolation steps, at each end of cluster, of specified size.
std::string m_outputVertexListName
The name under which to save the output vertex list.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
pandora::StringVector m_inputClusterListNames
The list of cluster list names.
unsigned int m_nMaxCrossingCandidates
The max number of crossing candidates to create.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void SelectClusters(pandora::ClusterVector &clusterVectorU, pandora::ClusterVector &clusterVectorV, pandora::ClusterVector &clusterVectorW)
Select a subset of input clusters (contained in the input list names) for processing in this algorith...
float m_chiSquaredCut
The chi squared cut (accept only 3D vertex positions with values below cut)
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterToSpacepointsMap
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
static void GetCoordinateVector(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &coordinateVector)
Get vector of hit coordinates from an input cluster.
void CreateCrossingVertices(const pandora::CartesianPointVector &crossingPoints1, const pandora::CartesianPointVector &crossingPoints2, const pandora::HitType hitType1, const pandora::HitType hitType2, unsigned int &nCrossingCandidates) const
Attempt to create candidate vertex positions, using 2D crossing points in 2 views.
std::list< Vertex > VertexList
Definition: DCEL.h:178
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.