LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
VertexSelectionBaseAlgorithm.cc
Go to the documentation of this file.
1 
8 #include "Pandora/AlgorithmHeaders.h"
9 
12 
14 
16 
17 using namespace pandora;
18 
19 namespace lar_content
20 {
21 
22 VertexSelectionBaseAlgorithm::VertexSelectionBaseAlgorithm() :
23  m_inputVertexListName(""),
24  m_replaceCurrentVertexList(true),
25  m_beamMode(true),
26  m_nDecayLengthsInZSpan(2.f),
27  m_selectSingleVertex(true),
28  m_maxTopScoreSelections(3),
29  m_maxOnHitDisplacement(1.f),
30  m_minCandidateDisplacement(2.f),
31  m_minCandidateScoreFraction(0.5f),
32  m_useDetectorGaps(true),
33  m_gapTolerance(0.f),
34  m_isEmptyViewAcceptable(true),
35  m_minVertexAcceptableViews(3)
36 {
37 }
38 
39 //------------------------------------------------------------------------------------------------------------------------------------------
40 
41 void VertexSelectionBaseAlgorithm::FilterVertexList(const VertexList *const pInputVertexList, HitKDTree2D &kdTreeU, HitKDTree2D &kdTreeV,
42  HitKDTree2D &kdTreeW, VertexVector &filteredVertices) const
43 {
44  for (const Vertex *const pVertex : *pInputVertexList)
45  {
46  unsigned int nAcceptableViews(0);
47 
48  if ((m_isEmptyViewAcceptable && kdTreeU.empty()) || this->IsVertexOnHit(pVertex, TPC_VIEW_U, kdTreeU) || this->IsVertexInGap(pVertex, TPC_VIEW_U))
49  ++nAcceptableViews;
50 
51  if ((m_isEmptyViewAcceptable && kdTreeV.empty()) || this->IsVertexOnHit(pVertex, TPC_VIEW_V, kdTreeV) || this->IsVertexInGap(pVertex, TPC_VIEW_V))
52  ++nAcceptableViews;
53 
54  if ((m_isEmptyViewAcceptable && kdTreeW.empty()) || this->IsVertexOnHit(pVertex, TPC_VIEW_W, kdTreeW) || this->IsVertexInGap(pVertex, TPC_VIEW_W))
55  ++nAcceptableViews;
56 
57  if (nAcceptableViews >= m_minVertexAcceptableViews)
58  filteredVertices.push_back(pVertex);
59  }
60 
61  std::sort(filteredVertices.begin(), filteredVertices.end(), SortByVertexZPosition);
62 }
63 
64 //------------------------------------------------------------------------------------------------------------------------------------------
65 
66 void VertexSelectionBaseAlgorithm::GetBeamConstants(const VertexVector &vertexVector, BeamConstants &beamConstants) const
67 {
68  if (!m_beamMode)
69  return;
70 
71  if (vertexVector.empty())
72  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
73 
74  float minZCoordinate(std::numeric_limits<float>::max()), maxZCoordinate(-std::numeric_limits<float>::max());
75 
76  for (const Vertex *const pVertex : vertexVector)
77  {
78  if (pVertex->GetPosition().GetZ() < minZCoordinate)
79  minZCoordinate = pVertex->GetPosition().GetZ();
80 
81  if (pVertex->GetPosition().GetZ() > maxZCoordinate)
82  maxZCoordinate = pVertex->GetPosition().GetZ();
83  }
84 
85  const float zSpan(maxZCoordinate - minZCoordinate);
86  const float decayConstant((zSpan < std::numeric_limits<float>::epsilon()) ? 0.f : (m_nDecayLengthsInZSpan / zSpan));
87  beamConstants.SetConstants(minZCoordinate, decayConstant);
88 }
89 
90 //------------------------------------------------------------------------------------------------------------------------------------------
91 
93  const StringVector &inputClusterListNames, ClusterList &clusterListU, ClusterList &clusterListV, ClusterList &clusterListW) const
94 {
95  for (const std::string &clusterListName : inputClusterListNames)
96  {
97  const ClusterList *pClusterList(NULL);
98  PANDORA_THROW_RESULT_IF_AND_IF(
99  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, clusterListName, pClusterList));
100 
101  if (!pClusterList || pClusterList->empty())
102  {
103  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
104  std::cout << "EnergyKickVertexSelectionAlgorithm: unable to find cluster list " << clusterListName << std::endl;
105 
106  continue;
107  }
108 
109  const HitType hitType(LArClusterHelper::GetClusterHitType(*(pClusterList->begin())));
110 
111  if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
112  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
113 
114  ClusterList &clusterList((TPC_VIEW_U == hitType) ? clusterListU : (TPC_VIEW_V == hitType) ? clusterListV : clusterListW);
115  clusterList.insert(clusterList.end(), pClusterList->begin(), pClusterList->end());
116  }
117 }
118 
119 //------------------------------------------------------------------------------------------------------------------------------------------
120 
121 void VertexSelectionBaseAlgorithm::CalculateClusterSlidingFits(const ClusterList &inputClusterList, const unsigned int minClusterCaloHits,
122  const unsigned int slidingFitWindow, SlidingFitDataList &slidingFitDataList) const
123 {
124  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
125 
126  ClusterVector sortedClusters(inputClusterList.begin(), inputClusterList.end());
127  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
128 
129  for (const Cluster *const pCluster : sortedClusters)
130  {
131  if (pCluster->GetNCaloHits() < minClusterCaloHits)
132  continue;
133 
134  // Make sure the window size is such that there are not more layers than hits (following TwoDSlidingLinearFit calculation).
135  const unsigned int newSlidingFitWindow(
136  std::min(static_cast<int>(pCluster->GetNCaloHits()), static_cast<int>(slidingFitPitch * slidingFitWindow)));
137  slidingFitDataList.emplace_back(pCluster, newSlidingFitWindow, slidingFitPitch);
138  }
139 }
140 
141 //------------------------------------------------------------------------------------------------------------------------------------------
142 
144 {
145  const VertexList *pInputVertexList(NULL);
146 
147  if (m_inputVertexListName == "")
148  {
149  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pInputVertexList));
150  }
151  else
152  {
153  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
154  PandoraContentApi::GetList(*this, m_inputVertexListName, pInputVertexList));
155  }
156 
157  if (!pInputVertexList || pInputVertexList->empty())
158  {
159  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
160  std::cout << "VertexSelectionBaseAlgorithm: unable to find current vertex list " << std::endl;
161 
162  return STATUS_CODE_SUCCESS;
163  }
164 
165  HitKDTree2D kdTreeU, kdTreeV, kdTreeW;
166  this->InitializeKDTrees(kdTreeU, kdTreeV, kdTreeW);
167 
168  VertexVector filteredVertices;
169  this->FilterVertexList(pInputVertexList, kdTreeU, kdTreeV, kdTreeW, filteredVertices);
170 
171  if (filteredVertices.empty())
172  return STATUS_CODE_SUCCESS;
173 
174  BeamConstants beamConstants;
175  this->GetBeamConstants(filteredVertices, beamConstants);
176 
177  VertexScoreList vertexScoreList;
178  this->GetVertexScoreList(filteredVertices, beamConstants, kdTreeU, kdTreeV, kdTreeW, vertexScoreList);
179 
180  VertexList selectedVertexList;
181  this->SelectTopScoreVertices(vertexScoreList, selectedVertexList);
182 
183  if (!selectedVertexList.empty())
184  {
185  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, m_outputVertexListName, selectedVertexList));
186 
188  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
189  }
190 
191  return STATUS_CODE_SUCCESS;
192 }
193 
194 //------------------------------------------------------------------------------------------------------------------------------------------
195 
197 {
198  for (const std::string &caloHitListName : m_inputCaloHitListNames)
199  {
200  const CaloHitList *pCaloHitList = NULL;
201  PANDORA_THROW_RESULT_IF_AND_IF(
202  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, caloHitListName, pCaloHitList));
203 
204  if (!pCaloHitList || pCaloHitList->empty())
205  {
206  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
207  std::cout << "VertexSelectionBaseAlgorithm: unable to find calo hit list " << caloHitListName << std::endl;
208 
209  continue;
210  }
211 
212  const HitType hitType((*(pCaloHitList->begin()))->GetHitType());
213 
214  if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
215  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
216 
217  HitKDTree2D &kdTree((TPC_VIEW_U == hitType) ? kdTreeU : (TPC_VIEW_V == hitType) ? kdTreeV : kdTreeW);
218 
219  if (!kdTree.empty())
220  throw StatusCodeException(STATUS_CODE_FAILURE);
221 
222  HitKDNode2DList hitKDNode2DList;
223  KDTreeBox hitsBoundingRegion2D(fill_and_bound_2d_kd_tree(*pCaloHitList, hitKDNode2DList));
224  kdTree.build(hitKDNode2DList, hitsBoundingRegion2D);
225  }
226 }
227 
228 //------------------------------------------------------------------------------------------------------------------------------------------
229 
230 bool VertexSelectionBaseAlgorithm::IsVertexOnHit(const Vertex *const pVertex, const HitType hitType, HitKDTree2D &kdTree) const
231 {
232  const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
234 
235  HitKDNode2DList found;
236  kdTree.search(searchRegionHits, found);
237 
238  return (!found.empty());
239 }
240 
241 //------------------------------------------------------------------------------------------------------------------------------------------
242 
243 bool VertexSelectionBaseAlgorithm::IsVertexInGap(const Vertex *const pVertex, const HitType hitType) const
244 {
245  if (!m_useDetectorGaps)
246  return false;
247 
248  return LArGeometryHelper::IsInGap3D(this->GetPandora(), pVertex->GetPosition(), hitType, m_gapTolerance);
249 }
250 
251 //------------------------------------------------------------------------------------------------------------------------------------------
252 
253 float VertexSelectionBaseAlgorithm::GetVertexEnergy(const Vertex *const pVertex, const KDTreeMap &kdTreeMap) const
254 {
255  float totalEnergy(0.f);
256 
257  if (!this->IsVertexInGap(pVertex, TPC_VIEW_U))
258  totalEnergy += this->VertexHitEnergy(pVertex, TPC_VIEW_U, kdTreeMap.at(TPC_VIEW_U));
259 
260  if (!this->IsVertexInGap(pVertex, TPC_VIEW_V))
261  totalEnergy += this->VertexHitEnergy(pVertex, TPC_VIEW_V, kdTreeMap.at(TPC_VIEW_V));
262 
263  if (!this->IsVertexInGap(pVertex, TPC_VIEW_W))
264  totalEnergy += this->VertexHitEnergy(pVertex, TPC_VIEW_W, kdTreeMap.at(TPC_VIEW_W));
265 
266  return totalEnergy;
267 }
268 
269 //------------------------------------------------------------------------------------------------------------------------------------------
270 
271 float VertexSelectionBaseAlgorithm::VertexHitEnergy(const Vertex *const pVertex, const HitType hitType, HitKDTree2D &kdTree) const
272 {
273  const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
275 
276  HitKDNode2DList foundHits;
277  kdTree.search(searchRegionHits, foundHits);
278 
279  float dr(std::numeric_limits<float>::max());
280  float energy(0);
281 
282  for (auto hit : foundHits)
283  {
284  const float diff = (vertexPosition2D - hit.data->GetPositionVector()).GetMagnitude();
285  if (diff < dr)
286  {
287  dr = diff;
288  energy = hit.data->GetElectromagneticEnergy();
289  }
290  }
291  return energy;
292 }
293 
294 //------------------------------------------------------------------------------------------------------------------------------------------
295 
296 void VertexSelectionBaseAlgorithm::SelectTopScoreVertices(VertexScoreList &vertexScoreList, VertexList &selectedVertexList) const
297 {
298  float bestScore(0.f);
299  std::sort(vertexScoreList.begin(), vertexScoreList.end());
300 
301  for (const VertexScore &vertexScore : vertexScoreList)
302  {
303  if (selectedVertexList.size() >= m_maxTopScoreSelections)
304  break;
305 
306  if (!selectedVertexList.empty() && !this->AcceptVertexLocation(vertexScore.GetVertex(), selectedVertexList))
307  continue;
308 
309  if (!selectedVertexList.empty() && (vertexScore.GetScore() < m_minCandidateScoreFraction * bestScore))
310  continue;
311 
312  selectedVertexList.push_back(vertexScore.GetVertex());
313 
315  return;
316 
317  if (vertexScore.GetScore() > bestScore)
318  bestScore = vertexScore.GetScore();
319  }
320 }
321 
322 //------------------------------------------------------------------------------------------------------------------------------------------
323 
324 bool VertexSelectionBaseAlgorithm::AcceptVertexLocation(const Vertex *const pVertex, const VertexList &selectedVertexList) const
325 {
326  const CartesianVector &position(pVertex->GetPosition());
327  const float minCandidateDisplacementSquared(m_minCandidateDisplacement * m_minCandidateDisplacement);
328 
329  for (const Vertex *const pSelectedVertex : selectedVertexList)
330  {
331  if (pVertex == pSelectedVertex)
332  return false;
333 
334  if ((position - pSelectedVertex->GetPosition()).GetMagnitudeSquared() < minCandidateDisplacementSquared)
335  return false;
336  }
337 
338  return true;
339 }
340 
341 //------------------------------------------------------------------------------------------------------------------------------------------
342 
344 {
345  const CartesianVector deltaPosition(pRhs->GetPosition() - pLhs->GetPosition());
346 
347  if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
348  return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
349 
350  if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
351  return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
352 
353  // ATTN No way to distinguish between vertices if still have a tie in y coordinate
354  return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
355 }
356 
357 //------------------------------------------------------------------------------------------------------------------------------------------
358 
359 VertexSelectionBaseAlgorithm::SlidingFitData::SlidingFitData(const pandora::Cluster *const pCluster, const int slidingFitWindow, const float slidingFitPitch) :
360  m_minLayerDirection(0.f, 0.f, 0.f),
361  m_maxLayerDirection(0.f, 0.f, 0.f),
362  m_minLayerPosition(0.f, 0.f, 0.f),
363  m_maxLayerPosition(0.f, 0.f, 0.f),
364  m_pCluster(pCluster)
365 {
366  const TwoDSlidingFitResult slidingFitResult(pCluster, slidingFitWindow, slidingFitPitch);
367  m_minLayerDirection = slidingFitResult.GetGlobalMinLayerDirection();
368  m_maxLayerDirection = slidingFitResult.GetGlobalMaxLayerDirection();
369  m_minLayerPosition = slidingFitResult.GetGlobalMinLayerPosition();
370  m_maxLayerPosition = slidingFitResult.GetGlobalMaxLayerPosition();
371 }
372 
373 //------------------------------------------------------------------------------------------------------------------------------------------
374 
375 VertexSelectionBaseAlgorithm::ShowerCluster::ShowerCluster(const pandora::ClusterList &clusterList, const int slidingFitWindow, const float slidingFitPitch) :
376  m_clusterList(clusterList),
377  m_coordinateVector(this->GetClusterListCoordinateVector(clusterList)),
378  m_twoDSlidingFitResult(&m_coordinateVector, slidingFitWindow, slidingFitPitch)
379 {
380 }
381 
382 //------------------------------------------------------------------------------------------------------------------------------------------
383 
384 pandora::CartesianPointVector VertexSelectionBaseAlgorithm::ShowerCluster::GetClusterListCoordinateVector(const pandora::ClusterList &clusterList) const
385 {
386  CartesianPointVector coordinateVector;
387 
388  for (const Cluster *const pCluster : clusterList)
389  {
390  CartesianPointVector clusterCoordinateVector;
391  LArClusterHelper::GetCoordinateVector(pCluster, clusterCoordinateVector);
392 
393  coordinateVector.insert(coordinateVector.end(), std::make_move_iterator(clusterCoordinateVector.begin()),
394  std::make_move_iterator(clusterCoordinateVector.end()));
395  }
396 
397  return coordinateVector;
398 }
399 
400 //------------------------------------------------------------------------------------------------------------------------------------------
401 //------------------------------------------------------------------------------------------------------------------------------------------
402 
403 StatusCode VertexSelectionBaseAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
404 {
405  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "InputCaloHitListNames", m_inputCaloHitListNames));
406 
407  PANDORA_RETURN_RESULT_IF_AND_IF(
408  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "InputVertexListName", m_inputVertexListName));
409 
410  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_outputVertexListName));
411 
412  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
413  XmlHelper::ReadValue(xmlHandle, "ReplaceCurrentVertexList", m_replaceCurrentVertexList));
414 
415  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "BeamMode", m_beamMode));
416 
417  PANDORA_RETURN_RESULT_IF_AND_IF(
418  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NDecayLengthsInZSpan", m_nDecayLengthsInZSpan));
419 
420  PANDORA_RETURN_RESULT_IF_AND_IF(
421  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SelectSingleVertex", m_selectSingleVertex));
422 
423  PANDORA_RETURN_RESULT_IF_AND_IF(
424  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxTopScoreSelections", m_maxTopScoreSelections));
425 
426  PANDORA_RETURN_RESULT_IF_AND_IF(
427  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxOnHitDisplacement", m_maxOnHitDisplacement));
428 
429  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
430  XmlHelper::ReadValue(xmlHandle, "MinCandidateDisplacement", m_minCandidateDisplacement));
431 
432  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
433  XmlHelper::ReadValue(xmlHandle, "MinCandidateScoreFraction", m_minCandidateScoreFraction));
434 
435  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "UseDetectorGaps", m_useDetectorGaps));
436 
437  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "GapTolerance", m_gapTolerance));
438 
439  PANDORA_RETURN_RESULT_IF_AND_IF(
440  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "IsEmptyViewAcceptable", m_isEmptyViewAcceptable));
441 
442  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
443  XmlHelper::ReadValue(xmlHandle, "MinVertexAcceptableViews", m_minVertexAcceptableViews));
444 
445  return STATUS_CODE_SUCCESS;
446 }
447 
448 } // namespace lar_content
float m_minCandidateScoreFraction
Ignore other top-scoring candidates with score less than a fraction of original.
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.
Header file for the kd tree linker algo template class.
void SetConstants(const float minZCoordinate, const float decayConstant)
Set the beam constants.
pandora::CartesianPointVector GetClusterListCoordinateVector(const pandora::ClusterList &clusterList) const
Get the coordinate vector for a cluster list.
virtual void FilterVertexList(const pandora::VertexList *const pInputVertexList, HitKDTree2D &kdTreeU, HitKDTree2D &kdTreeV, HitKDTree2D &kdTreeW, pandora::VertexVector &filteredVertices) const
Filter the input list of vertices to obtain a reduced number of vertex candidates.
std::string m_outputVertexListName
The name under which to save the output vertex list.
pandora::StringVector m_inputCaloHitListNames
The list of calo hit list names.
void GetClusterLists(const pandora::StringVector &inputClusterListNames, pandora::ClusterList &clusterListU, pandora::ClusterList &clusterListV, pandora::ClusterList &clusterListW) const
Get the cluster lists.
void CalculateClusterSlidingFits(const pandora::ClusterList &inputClusterList, const unsigned int minClusterCaloHits, const unsigned int slidingFitWindow, SlidingFitDataList &slidingFitDataList) const
Calculate the cluster sliding fits.
Box structure used to define 2D field. It&#39;s used in KDTree building step to divide the detector space...
pandora::CartesianVector m_minLayerPosition
The position of the fit at the max layer.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
pandora::CartesianVector GetGlobalMinLayerDirection() const
Get global direction corresponding to the fit result in minimum fit layer.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
bool empty()
Whether the tree is empty.
bool IsVertexOnHit(const pandora::Vertex *const pVertex, const pandora::HitType hitType, HitKDTree2D &kdTree) const
Whether the vertex lies on a hit in the specified view.
TFile f
Definition: plotHisto.C:6
pandora::CartesianVector m_maxLayerDirection
The direction of the fit at the min layer.
bool AcceptVertexLocation(const pandora::Vertex *const pVertex, const pandora::VertexList &selectedVertexList) const
Whether to accept a candidate vertex, based on its spatial position in relation to other selected can...
Header file for the geometry helper class.
std::string m_inputVertexListName
The name of an input vertex list to check.
float VertexHitEnergy(const pandora::Vertex *const pVertex, const pandora::HitType hitType, HitKDTree2D &kdTree) const
Finds the energy of the nearest hit to the vertex candidate in this view.
virtual void GetBeamConstants(const pandora::VertexVector &vertexVector, BeamConstants &beamConstants) const
Get the beam score constants for a provided list of candidate vertices.
ShowerCluster(const pandora::ClusterList &clusterList, const int slidingFitWindow, const float slidingFitPitch)
Constructor.
unsigned int m_maxTopScoreSelections
Max number of top-scoring vertex candidate to select for output.
pandora::CartesianVector m_minLayerDirection
The direction of the fit at the min layer.
bool IsVertexInGap(const pandora::Vertex *const pVertex, const pandora::HitType hitType) const
Whether the vertex lies in a registered gap.
Header file for the cluster helper class.
SlidingFitData(const pandora::Cluster *const pCluster, const int slidingFitWindow, const float slidingFitPitch)
Constructor.
void build(std::vector< KDTreeNodeInfoT< DATA, DIM >> &eltList, const KDTreeBoxT< DIM > &region)
Build the KD tree from the "eltList" in the space define by "region".
double energy
Definition: plottest35.C:25
Header file for the vertex selection base algorithm class.
pandora::CartesianVector m_maxLayerPosition
The position of the fit at the max layer.
bool m_useDetectorGaps
Whether to account for registered detector gaps in vertex selection.
static bool SortByVertexZPosition(const pandora::Vertex *const pLhs, const pandora::Vertex *const pRhs)
Sort vertices by increasing z position.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
void InitializeKDTrees(HitKDTree2D &kdTreeU, HitKDTree2D &kdTreeV, HitKDTree2D &kdTreeW) const
Initialize kd trees with details of hits in algorithm-configured cluster lists.
Detector simulation of raw signals on wires.
bool m_beamMode
Whether to run in beam mode, assuming neutrinos travel in positive z-direction.
bool m_isEmptyViewAcceptable
Whether views entirely empty of hits are classed as &#39;acceptable&#39; for candidate filtration.
bool m_selectSingleVertex
Whether to make a final decision and select just one vertex candidate.
float GetVertexEnergy(const pandora::Vertex *const pVertex, const KDTreeMap &kdTreeMap) const
Calculate the energy of a vertex candidate by summing values from all three planes.
HitType
Definition: HitType.h:12
unsigned int m_minVertexAcceptableViews
The minimum number of views in which a candidate must sit on/near a hit or in a gap (or view can be e...
pandora::CartesianVector GetGlobalMaxLayerDirection() const
Get global direction corresponding to the fit result in maximum fit layer.
std::vector< art::Ptr< recob::Vertex > > VertexVector
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 >> &nodes)
fill_and_bound_2d_kd_tree
static void GetCoordinateVector(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &coordinateVector)
Get vector of hit coordinates from an input cluster.
virtual void GetVertexScoreList(const pandora::VertexVector &vertexVector, const BeamConstants &beamConstants, HitKDTree2D &kdTreeU, HitKDTree2D &kdTreeV, HitKDTree2D &kdTreeW, VertexScoreList &vertexScoreList) const =0
Get the vertex score list for a provided list of candidate vertices.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
void SelectTopScoreVertices(VertexScoreList &vertexScoreList, pandora::VertexList &selectedVertexList) const
From the top-scoring candidate vertices, select a subset for further investigation.
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
float m_nDecayLengthsInZSpan
The number of score decay lengths to use over the course of the vertex z-span.
float m_minCandidateDisplacement
Ignore other top-scoring candidates located in close proximity to original.
bool m_replaceCurrentVertexList
Whether to replace the current vertex list with the output list.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM >> &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
std::list< Vertex > VertexList
Definition: DCEL.h:169
float m_gapTolerance
The tolerance to use when querying whether a sampling point is in a gap, units cm.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
float m_maxOnHitDisplacement
Max hit-vertex displacement for declaring vertex to lie on a hit in each view.
static bool IsInGap3D(const pandora::Pandora &pandora, const pandora::CartesianVector &testPoint3D, const pandora::HitType hitType, const float gapTolerance=0.f)
Whether a 3D test point lies in a registered gap with the associated hit type.