LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
SlidingConePfoMopUpAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
15 
17 
19 
20 using namespace pandora;
21 
22 namespace lar_content
23 {
24 
25 SlidingConePfoMopUpAlgorithm::SlidingConePfoMopUpAlgorithm() :
26  m_useVertex(true),
27  m_maxIterations(1000),
28  m_maxHitsToConsider3DTrack(100),
29  m_minHitsToConsider3DShower(20),
30  m_halfWindowLayers(20),
31  m_nConeFitLayers(20),
32  m_nConeFits(5),
33  m_coneLengthMultiplier(7.f),
34  m_maxConeLength(126.f),
35  m_coneTanHalfAngle1(0.5f),
36  m_coneBoundedFraction1(0.5f),
37  m_coneTanHalfAngle2(0.75f),
38  m_coneBoundedFraction2(0.75f),
39  m_minVertexLongitudinalDistance(-2.5f),
40  m_maxVertexTransverseDistance(3.5f)
41 {
42 }
43 
44 //------------------------------------------------------------------------------------------------------------------------------------------
45 
47 {
48  const Vertex *pVertex(nullptr);
49  this->GetInteractionVertex(pVertex);
50 
51  if (m_useVertex && !pVertex)
52  {
53  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
54  std::cout << "SlidingConePfoMopUpAlgorithm - interaction vertex not available for use." << std::endl;
55  return STATUS_CODE_SUCCESS;
56  }
57 
58  unsigned int nIterations(0);
59 
60  while (nIterations++ < m_maxIterations)
61  {
62  ClusterVector clusters3D;
63  ClusterToPfoMap clusterToPfoMap;
64  this->GetThreeDClusters(clusters3D, clusterToPfoMap);
65 
66  ClusterMergeMap clusterMergeMap;
67  this->GetClusterMergeMap(pVertex, clusters3D, clusterToPfoMap, clusterMergeMap);
68 
69  if (!this->MakePfoMerges(clusterToPfoMap, clusterMergeMap))
70  break;
71  }
72 
73  return STATUS_CODE_SUCCESS;
74 }
75 
76 //------------------------------------------------------------------------------------------------------------------------------------------
77 
79 {
80  if (!m_useVertex)
81  return;
82 
83  const VertexList *pVertexList = nullptr;
84  PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetCurrentList(*this, pVertexList));
85 
86  pVertex =
87  ((pVertexList && (pVertexList->size() == 1) && (VERTEX_3D == (*(pVertexList->begin()))->GetVertexType())) ? *(pVertexList->begin()) : nullptr);
88 }
89 
90 //------------------------------------------------------------------------------------------------------------------------------------------
91 
93 {
94  for (const std::string &pfoListName : m_inputPfoListNames)
95  {
96  const PfoList *pPfoList(nullptr);
97 
98  if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*this, pfoListName, pPfoList))
99  continue;
100 
101  for (const Pfo *const pPfo : *pPfoList)
102  {
103  ClusterList pfoClusters3D;
104  LArPfoHelper::GetThreeDClusterList(pPfo, pfoClusters3D);
105 
106  for (const Cluster *const pCluster3D : pfoClusters3D)
107  {
108  if (LArPfoHelper::IsTrack(pPfo) && (pCluster3D->GetNCaloHits() > m_maxHitsToConsider3DTrack))
109  continue;
110 
111  if (!clusterToPfoMap.insert(ClusterToPfoMap::value_type(pCluster3D, pPfo)).second)
112  throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
113 
114  clusters3D.push_back(pCluster3D);
115  }
116  }
117  }
118 
119  std::sort(clusters3D.begin(), clusters3D.end(), LArClusterHelper::SortByNHits);
120 }
121 
122 //------------------------------------------------------------------------------------------------------------------------------------------
123 
124 void SlidingConePfoMopUpAlgorithm::GetClusterMergeMap(const Vertex *const pVertex, const ClusterVector &clusters3D,
125  const ClusterToPfoMap &clusterToPfoMap, ClusterMergeMap &clusterMergeMap) const
126 {
127  VertexAssociationMap vertexAssociationMap;
128  const float pitchU{LArGeometryHelper::GetWirePitch(this->GetPandora(), TPC_VIEW_U)};
129  const float pitchV{LArGeometryHelper::GetWirePitch(this->GetPandora(), TPC_VIEW_V)};
130  const float pitchW{LArGeometryHelper::GetWirePitch(this->GetPandora(), TPC_VIEW_W)};
131  const float pitchMax{std::max({pitchU, pitchV, pitchW})};
132 
133  for (const Cluster *const pShowerCluster : clusters3D)
134  {
135  if ((pShowerCluster->GetNCaloHits() < m_minHitsToConsider3DShower) || !LArPfoHelper::IsShower(clusterToPfoMap.at(pShowerCluster)))
136  continue;
137 
138  float coneLength(0.f);
139  SimpleConeList simpleConeList;
140  bool isShowerVertexAssociated(false);
141 
142  try
143  {
144  float layerPitch{0.f};
145  const HitType view{LArClusterHelper::GetClusterHitType(pShowerCluster)};
146  if (view == TPC_VIEW_U || view == TPC_VIEW_V || view == TPC_VIEW_W)
147  layerPitch = LArGeometryHelper::GetWirePitch(this->GetPandora(), view);
148  else
149  layerPitch = pitchMax;
150 
151  const ThreeDSlidingConeFitResult slidingConeFitResult3D(pShowerCluster, m_halfWindowLayers, layerPitch);
152 
153  const CartesianVector &minLayerPosition(slidingConeFitResult3D.GetSlidingFitResult().GetGlobalMinLayerPosition());
154  const CartesianVector &maxLayerPosition(slidingConeFitResult3D.GetSlidingFitResult().GetGlobalMaxLayerPosition());
155  coneLength = std::min(m_coneLengthMultiplier * (maxLayerPosition - minLayerPosition).GetMagnitude(), m_maxConeLength);
156 
157  const float vertexToMinLayer(!pVertex ? 0.f : (pVertex->GetPosition() - minLayerPosition).GetMagnitude());
158  const float vertexToMaxLayer(!pVertex ? 0.f : (pVertex->GetPosition() - maxLayerPosition).GetMagnitude());
159  const ConeSelection coneSelection(!pVertex ? CONE_BOTH_DIRECTIONS
160  : (vertexToMaxLayer > vertexToMinLayer) ? CONE_FORWARD_ONLY
162 
163  slidingConeFitResult3D.GetSimpleConeList(m_nConeFitLayers, m_nConeFits, coneSelection, simpleConeList);
164  isShowerVertexAssociated =
165  this->IsVertexAssociated(pShowerCluster, pVertex, vertexAssociationMap, &(slidingConeFitResult3D.GetSlidingFitResult()));
166  }
167  catch (const StatusCodeException &)
168  {
169  continue;
170  }
171 
172  for (const Cluster *const pNearbyCluster : clusters3D)
173  {
174  if (pNearbyCluster == pShowerCluster)
175  continue;
176 
177  ClusterMerge bestClusterMerge(nullptr, 0.f, 0.f);
178 
179  for (const SimpleCone &simpleCone : simpleConeList)
180  {
181  const float boundedFraction1(simpleCone.GetBoundedHitFraction(pNearbyCluster, coneLength, m_coneTanHalfAngle1));
182  const float boundedFraction2(simpleCone.GetBoundedHitFraction(pNearbyCluster, coneLength, m_coneTanHalfAngle2));
183  const ClusterMerge clusterMerge(pShowerCluster, boundedFraction1, boundedFraction2);
184 
185  if (clusterMerge < bestClusterMerge)
186  bestClusterMerge = clusterMerge;
187  }
188 
189  if (isShowerVertexAssociated && this->IsVertexAssociated(pNearbyCluster, pVertex, vertexAssociationMap))
190  continue;
191 
192  if (bestClusterMerge.GetParentCluster() && (bestClusterMerge.GetBoundedFraction1() > m_coneBoundedFraction1) &&
193  (bestClusterMerge.GetBoundedFraction2() > m_coneBoundedFraction2))
194  clusterMergeMap[pNearbyCluster].push_back(bestClusterMerge);
195  }
196  }
197 
198  for (ClusterMergeMap::value_type &mapEntry : clusterMergeMap)
199  std::sort(mapEntry.second.begin(), mapEntry.second.end());
200 }
201 
202 //------------------------------------------------------------------------------------------------------------------------------------------
203 
204 bool SlidingConePfoMopUpAlgorithm::IsVertexAssociated(const Cluster *const pCluster, const Vertex *const pVertex,
205  VertexAssociationMap &vertexAssociationMap, const ThreeDSlidingFitResult *const pSlidingFitResult) const
206 {
207  if (!pVertex)
208  return false;
209 
210  VertexAssociationMap::const_iterator iter = vertexAssociationMap.find(pCluster);
211 
212  if (vertexAssociationMap.end() != iter)
213  return iter->second;
214 
215  const bool isVertexAssociated(this->IsVertexAssociated(pCluster, pVertex->GetPosition(), pSlidingFitResult));
216  (void)vertexAssociationMap.insert(VertexAssociationMap::value_type(pCluster, isVertexAssociated));
217 
218  return isVertexAssociated;
219 }
220 
221 //------------------------------------------------------------------------------------------------------------------------------------------
222 
224  const Cluster *const pCluster, const CartesianVector &vertexPosition, const ThreeDSlidingFitResult *const pSlidingFitResult) const
225 {
226  const float pitchU{LArGeometryHelper::GetWirePitch(this->GetPandora(), TPC_VIEW_U)};
227  const float pitchV{LArGeometryHelper::GetWirePitch(this->GetPandora(), TPC_VIEW_V)};
228  const float pitchW{LArGeometryHelper::GetWirePitch(this->GetPandora(), TPC_VIEW_W)};
229  const float pitchMax{std::max({pitchU, pitchV, pitchW})};
230 
231  try
232  {
233  float layerPitch{0.f};
234  const HitType view{LArClusterHelper::GetClusterHitType(pCluster)};
235  if (view == TPC_VIEW_U || view == TPC_VIEW_V || view == TPC_VIEW_W)
236  layerPitch = LArGeometryHelper::GetWirePitch(this->GetPandora(), view);
237  else
238  layerPitch = pitchMax;
239 
240  const LArPointingCluster pointingCluster(
241  pSlidingFitResult ? LArPointingCluster(*pSlidingFitResult) : LArPointingCluster(pCluster, m_halfWindowLayers, layerPitch));
242 
243  const bool useInner((pointingCluster.GetInnerVertex().GetPosition() - vertexPosition).GetMagnitudeSquared() <
244  (pointingCluster.GetOuterVertex().GetPosition() - vertexPosition).GetMagnitudeSquared());
245 
246  const LArPointingCluster::Vertex &daughterVertex(useInner ? pointingCluster.GetInnerVertex() : pointingCluster.GetOuterVertex());
248  }
249  catch (const StatusCodeException &)
250  {
251  }
252 
253  return false;
254 }
255 
256 //------------------------------------------------------------------------------------------------------------------------------------------
257 
258 bool SlidingConePfoMopUpAlgorithm::MakePfoMerges(const ClusterToPfoMap &clusterToPfoMap, const ClusterMergeMap &clusterMergeMap) const
259 {
260  ClusterVector daughterClusters;
261  for (const ClusterMergeMap::value_type &mapEntry : clusterMergeMap)
262  daughterClusters.push_back(mapEntry.first);
263  std::sort(daughterClusters.begin(), daughterClusters.end(), LArClusterHelper::SortByNHits);
264 
265  bool pfosMerged(false);
266  ClusterReplacementMap clusterReplacementMap;
267 
268  for (ClusterVector::const_reverse_iterator rIter = daughterClusters.rbegin(), rIterEnd = daughterClusters.rend(); rIter != rIterEnd; ++rIter)
269  {
270  const Cluster *const pDaughterCluster(*rIter);
271 
272  if (clusterReplacementMap.count(pDaughterCluster))
273  throw StatusCodeException(STATUS_CODE_FAILURE);
274 
275  const Cluster *pParentCluster(clusterMergeMap.at(pDaughterCluster).at(0).GetParentCluster());
276 
277  if (clusterReplacementMap.count(pParentCluster))
278  pParentCluster = clusterReplacementMap.at(pParentCluster);
279 
280  // ATTN Sign there was a reciprocal relationship in the cluster merge map (already actioned once)
281  if (pDaughterCluster == pParentCluster)
282  continue;
283 
284  // Key book-keeping on clusters and use cluster->pfo lookup
285  const Pfo *const pDaughterPfo(clusterToPfoMap.at(pDaughterCluster));
286  const Pfo *const pParentPfo(clusterToPfoMap.at(pParentCluster));
287  this->MergeAndDeletePfos(pParentPfo, pDaughterPfo);
288  pfosMerged = true;
289 
290  // Simple/placeholder book-keeping for reciprocal relationships and progressive merges
291  clusterReplacementMap[pDaughterCluster] = pParentCluster;
292 
293  for (ClusterReplacementMap::value_type &mapEntry : clusterReplacementMap)
294  {
295  if (pDaughterCluster == mapEntry.second)
296  mapEntry.second = pParentCluster;
297  }
298  }
299 
300  return pfosMerged;
301 }
302 
303 //------------------------------------------------------------------------------------------------------------------------------------------
304 //------------------------------------------------------------------------------------------------------------------------------------------
305 
307 {
308  if (!this->GetParentCluster() && !rhs.GetParentCluster())
309  return false;
310 
311  if (this->GetParentCluster() && !rhs.GetParentCluster())
312  return true;
313 
314  if (!this->GetParentCluster() && rhs.GetParentCluster())
315  return false;
316 
317  if (std::fabs(this->GetBoundedFraction1() - rhs.GetBoundedFraction1()) > std::numeric_limits<float>::epsilon())
318  return (this->GetBoundedFraction1() > rhs.GetBoundedFraction1());
319 
320  if (std::fabs(this->GetBoundedFraction2() - rhs.GetBoundedFraction2()) > std::numeric_limits<float>::epsilon())
321  return (this->GetBoundedFraction2() > rhs.GetBoundedFraction2());
322 
324 }
325 
326 //------------------------------------------------------------------------------------------------------------------------------------------
327 //------------------------------------------------------------------------------------------------------------------------------------------
328 
329 StatusCode SlidingConePfoMopUpAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
330 {
331  PANDORA_RETURN_RESULT_IF_AND_IF(
332  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "InputPfoListNames", m_inputPfoListNames));
333 
334  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "UseVertex", m_useVertex));
335 
336  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxIterations", m_maxIterations));
337 
338  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
339  XmlHelper::ReadValue(xmlHandle, "MaxHitsToConsider3DTrack", m_maxHitsToConsider3DTrack));
340 
341  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
342  XmlHelper::ReadValue(xmlHandle, "MinHitsToConsider3DShower", m_minHitsToConsider3DShower));
343 
344  PANDORA_RETURN_RESULT_IF_AND_IF(
345  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitHalfWindow", m_halfWindowLayers));
346 
347  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NConeFitLayers", m_nConeFitLayers));
348 
349  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NConeFits", m_nConeFits));
350 
351  PANDORA_RETURN_RESULT_IF_AND_IF(
352  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ConeLengthMultiplier", m_coneLengthMultiplier));
353 
354  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxConeLength", m_maxConeLength));
355 
356  PANDORA_RETURN_RESULT_IF_AND_IF(
357  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ConeTanHalfAngle1", m_coneTanHalfAngle1));
358 
359  PANDORA_RETURN_RESULT_IF_AND_IF(
360  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ConeBoundedFraction1", m_coneBoundedFraction1));
361 
362  PANDORA_RETURN_RESULT_IF_AND_IF(
363  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ConeTanHalfAngle2", m_coneTanHalfAngle2));
364 
365  PANDORA_RETURN_RESULT_IF_AND_IF(
366  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ConeBoundedFraction2", m_coneBoundedFraction2));
367 
368  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
369  XmlHelper::ReadValue(xmlHandle, "MinVertexLongitudinalDistance", m_minVertexLongitudinalDistance));
370 
371  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
372  XmlHelper::ReadValue(xmlHandle, "MaxVertexTransverseDistance", m_maxVertexTransverseDistance));
373 
375 
376  return PfoMopUpBaseAlgorithm::ReadSettings(xmlHandle);
377 }
378 
379 } // namespace lar_content
std::unordered_map< const pandora::Cluster *, const pandora::Cluster * > ClusterReplacementMap
float GetBoundedFraction2() const
Get the bounded fraction for algorithm-specified cone angle 2.
void GetClusterMergeMap(const pandora::Vertex *const pVertex, const pandora::ClusterVector &clusters3D, const ClusterToPfoMap &clusterToPfoMap, ClusterMergeMap &clusterMergeMap) const
Get the cluster merge map describing all potential 3d cluster merges.
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_coneBoundedFraction2
The minimum cluster bounded fraction for association 2.
void GetInteractionVertex(const pandora::Vertex *&pVertex) const
Get the neutrino interaction vertex if it is available and if the algorithm is configured to do so...
Header file for the pfo helper class.
float m_maxConeLength
The maximum allowed cone length to use when calculating bounded cluster fractions.
float m_maxVertexTransverseDistance
Vertex association check: max transverse distance cut.
std::unordered_map< const pandora::Cluster *, const pandora::ParticleFlowObject * > ClusterToPfoMap
float m_coneLengthMultiplier
The cone length multiplier to use when calculating bounded cluster fractions.
std::vector< SimpleCone > SimpleConeList
pandora::StringVector m_daughterListNames
The list of potential daughter object list names.
intermediate_table::const_iterator const_iterator
bool MakePfoMerges(const ClusterToPfoMap &clusterToPfoMap, const ClusterMergeMap &clusterMergeMap) const
Make pfo merges based on the provided cluster merge map.
const ThreeDSlidingFitResult & GetSlidingFitResult() const
Get the sliding fit result for the full cluster.
LArPointingCluster class.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
void GetThreeDClusters(pandora::ClusterVector &clusters3D, ClusterToPfoMap &clusterToPfoMap) const
Get all 3d clusters contained in the input pfo lists and a mapping from clusters to pfos...
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
bool m_useVertex
Whether to use the interaction vertex to select useful cone directions.
Header file for the lar three dimensional sliding cone fit result class.
float GetBoundedFraction1() const
Get the bounded fraction for algorithm-specified cone angle 1.
void GetSimpleConeList(const unsigned int nLayersForConeFit, const unsigned int nCones, const ConeSelection coneSelection, SimpleConeList &simpleConeList) const
Get the list of simple cones fitted to the three dimensional cluster.
TFile f
Definition: plotHisto.C:6
bool IsVertexAssociated(const pandora::Cluster *const pCluster, const pandora::Vertex *const pVertex, VertexAssociationMap &vertexAssociationMap, const ThreeDSlidingFitResult *const pSlidingFitResult=nullptr) const
Whether a 3D cluster is nodally associated with a provided vertex.
Header file for the geometry helper class.
float m_minVertexLongitudinalDistance
Vertex association check: min longitudinal distance cut.
static bool IsShower(const pandora::ParticleFlowObject *const pPfo)
Return shower flag based on Pfo Particle ID.
unsigned int m_nConeFitLayers
The number of layers over which to sum fitted direction to obtain cone fit.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
unsigned int m_maxHitsToConsider3DTrack
The maximum number of hits in a 3d track cluster to warrant inclusion in algorithm.
const Vertex & GetInnerVertex() const
Get the inner vertex.
float m_coneTanHalfAngle1
The cone tan half angle to use when calculating bounded cluster fractions 1.
pandora::StringVector m_inputPfoListNames
The input pfo list names.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
Header file for the sliding cone pfo mop up algorithm class.
static const pandora::Cluster * GetParentCluster(const pandora::ClusterList &clusterList, const pandora::HitType hitType)
Select the parent cluster (same hit type and most hits) using a provided cluster list and hit type...
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
const pandora::CartesianVector & GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
float m_coneBoundedFraction1
The minimum cluster bounded fraction for association 1.
std::unordered_map< const pandora::Cluster *, bool > VertexAssociationMap
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
HitType
Definition: HitType.h:12
unsigned int m_maxIterations
The maximum allowed number of algorithm iterations.
virtual void MergeAndDeletePfos(const pandora::ParticleFlowObject *const pPfoToEnlarge, const pandora::ParticleFlowObject *const pPfoToDelete) const
Merge and delete a pair of pfos, with a specific set of conventions for cluster merging, vertex use, etc.
ConeSelection
ConeSelection enum.
unsigned int m_minHitsToConsider3DShower
The minimum number of hits in a 3d shower cluster to attempt cone fits.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
std::vector< art::Ptr< recob::Cluster > > ClusterVector
bool operator<(const ClusterMerge &rhs) const
operator <
unsigned int m_nConeFits
The number of cone fits to perform, spread roughly uniformly along the shower length.
std::unordered_map< const pandora::Cluster *, ClusterMergeList > ClusterMergeMap
const pandora::Cluster * GetParentCluster() const
Get the address of the candidate parent (shower) cluster.
std::list< Vertex > VertexList
Definition: DCEL.h:169
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
static bool IsNode(const pandora::CartesianVector &parentVertex, const LArPointingCluster::Vertex &daughterVertex, const float minLongitudinalDistance, const float maxTransverseDistance)
Whether pointing vertex is adjacent to a given position.
float m_coneTanHalfAngle2
The cone tan half angle to use when calculating bounded cluster fractions 2.
unsigned int m_halfWindowLayers
The number of layers to use for half-window of sliding fit.
const pandora::CartesianVector & GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.