LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
VertexBasedPfoMopUpAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
16 
18 
20 
21 using namespace pandora;
22 
23 namespace lar_content
24 {
25 
26 VertexBasedPfoMopUpAlgorithm::VertexBasedPfoMopUpAlgorithm() :
27  m_minVertexLongitudinalDistance(-2.5f),
28  m_maxVertexTransverseDistance(1.5f),
29  m_minVertexAssociatedHitTypes(2),
30  m_coneAngleCentile(0.8f),
31  m_maxConeCosHalfAngle(0.95f),
32  m_maxConeLengthMultiplier(3.f),
33  m_directionTanAngle(1.732f),
34  m_directionApexShift(0.333f),
35  m_meanBoundedFractionCut(0.6f),
36  m_maxBoundedFractionCut(0.7f),
37  m_minBoundedFractionCut(0.3f),
38  m_minConsistentDirections(2),
39  m_minConsistentDirectionsTrack(3)
40 {
41 }
42 
43 //------------------------------------------------------------------------------------------------------------------------------------------
44 
46 {
47  const VertexList *pVertexList = nullptr;
48  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetCurrentList(*this, pVertexList));
49 
50  const Vertex *const pSelectedVertex(
51  (pVertexList && (pVertexList->size() == 1) && (VERTEX_3D == (*(pVertexList->begin()))->GetVertexType())) ? *(pVertexList->begin()) : nullptr);
52 
53  if (!pSelectedVertex)
54  {
55  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
56  std::cout << "VertexBasedPfoMopUp: unable to find vertex in current list " << std::endl;
57 
58  return STATUS_CODE_SUCCESS;
59  }
60 
61  while (true)
62  {
63  PfoList vertexPfos, nonVertexPfos;
64  this->GetInputPfos(pSelectedVertex, vertexPfos, nonVertexPfos);
65 
66  PfoAssociationList pfoAssociationList;
67  this->GetPfoAssociations(pSelectedVertex, vertexPfos, nonVertexPfos, pfoAssociationList);
68 
69  std::sort(pfoAssociationList.begin(), pfoAssociationList.end());
70  const bool pfoMergeMade(this->ProcessPfoAssociations(pfoAssociationList));
71 
72  if (!pfoMergeMade)
73  break;
74  }
75 
76  return STATUS_CODE_SUCCESS;
77 }
78 
79 //------------------------------------------------------------------------------------------------------------------------------------------
80 
81 bool VertexBasedPfoMopUpAlgorithm::IsVertexAssociated(const CartesianVector &vertex2D, const LArPointingCluster &pointingCluster) const
82 {
85 }
86 
87 //------------------------------------------------------------------------------------------------------------------------------------------
88 
90  const Pfo *const pVertexPfo, const Pfo *const pDaughterPfo, HitTypeToAssociationMap &hitTypeToAssociationMap) const
91 {
92  if ((pVertexPfo->GetClusterList().size() != pDaughterPfo->GetClusterList().size()) || (3 != pVertexPfo->GetClusterList().size()))
93  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
94 
95  return PfoAssociation(pVertexPfo, pDaughterPfo, hitTypeToAssociationMap.at(TPC_VIEW_U), hitTypeToAssociationMap.at(TPC_VIEW_V),
96  hitTypeToAssociationMap.at(TPC_VIEW_W));
97 }
98 
99 //------------------------------------------------------------------------------------------------------------------------------------------
100 
101 void VertexBasedPfoMopUpAlgorithm::GetInputPfos(const Vertex *const pVertex, PfoList &vertexPfos, PfoList &nonVertexPfos) const
102 {
103  StringVector listNames;
104  listNames.push_back(m_trackPfoListName);
105  listNames.push_back(m_showerPfoListName);
106 
107  for (const std::string &listName : listNames)
108  {
109  const PfoList *pPfoList(nullptr);
110 
111  if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*this, listName, pPfoList))
112  continue;
113 
114  for (const Pfo *const pPfo : *pPfoList)
115  {
116  PfoList &pfoTargetList(this->IsVertexAssociated(pPfo, pVertex) ? vertexPfos : nonVertexPfos);
117  pfoTargetList.push_back(pPfo);
118  }
119  }
120 }
121 
122 //------------------------------------------------------------------------------------------------------------------------------------------
123 
124 bool VertexBasedPfoMopUpAlgorithm::IsVertexAssociated(const Pfo *const pPfo, const Vertex *const pVertex) const
125 {
126  if (VERTEX_3D != pVertex->GetVertexType())
127  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
128 
129  HitTypeSet hitTypeSet;
130 
131  for (const Cluster *const pCluster : pPfo->GetClusterList())
132  {
133  const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
134 
135  if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
136  continue;
137 
138  const CartesianVector vertex2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
139 
140  try
141  {
142  const LArPointingCluster pointingCluster(pCluster);
143 
144  if (this->IsVertexAssociated(vertex2D, pointingCluster))
145  hitTypeSet.insert(hitType);
146  }
147  catch (StatusCodeException &)
148  {
149  }
150  }
151 
152  const unsigned int nVertexAssociatedHitTypes(hitTypeSet.size());
153  return (nVertexAssociatedHitTypes >= m_minVertexAssociatedHitTypes);
154 }
155 
156 //------------------------------------------------------------------------------------------------------------------------------------------
157 
159  const Vertex *const pVertex, const PfoList &vertexPfos, const PfoList &nonVertexPfos, PfoAssociationList &pfoAssociationList) const
160 {
161  for (const Pfo *const pVertexPfo : vertexPfos)
162  {
163  for (const Pfo *const pDaughterPfo : nonVertexPfos)
164  {
165  try
166  {
167  const PfoAssociation pfoAssociation(this->GetPfoAssociation(pVertex, pVertexPfo, pDaughterPfo));
168  pfoAssociationList.push_back(pfoAssociation);
169  }
170  catch (StatusCodeException &)
171  {
172  }
173  }
174  }
175 }
176 
177 //------------------------------------------------------------------------------------------------------------------------------------------
178 
180  const Vertex *const pVertex, const Pfo *const pVertexPfo, const Pfo *const pDaughterPfo) const
181 {
182  if (pVertexPfo->GetClusterList().empty() || pDaughterPfo->GetClusterList().empty())
183  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
184 
185  HitTypeToAssociationMap hitTypeToAssociationMap;
186 
187  for (const Cluster *const pVertexCluster : pVertexPfo->GetClusterList())
188  {
189  const HitType vertexHitType(LArClusterHelper::GetClusterHitType(pVertexCluster));
190 
191  for (const Cluster *const pDaughterCluster : pDaughterPfo->GetClusterList())
192  {
193  const HitType daughterHitType(LArClusterHelper::GetClusterHitType(pDaughterCluster));
194 
195  if (vertexHitType != daughterHitType)
196  continue;
197 
198  const ClusterAssociation clusterAssociation(this->GetClusterAssociation(pVertex, pVertexCluster, pDaughterCluster));
199  hitTypeToAssociationMap[vertexHitType] = clusterAssociation;
200  }
201  }
202 
203  return this->GetPfoAssociation(pVertexPfo, pDaughterPfo, hitTypeToAssociationMap);
204 }
205 
206 //------------------------------------------------------------------------------------------------------------------------------------------
207 
209  const Vertex *const pVertex, const Cluster *const pVertexCluster, const Cluster *const pDaughterCluster) const
210 {
211  const HitType vertexHitType(LArClusterHelper::GetClusterHitType(pVertexCluster));
212  const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), vertexHitType));
213 
214  const ConeParameters coneParameters(pVertexCluster, vertexPosition2D, m_coneAngleCentile, m_maxConeCosHalfAngle);
215  const float boundedFraction(coneParameters.GetBoundedFraction(pDaughterCluster, m_maxConeLengthMultiplier));
216 
217  const LArVertexHelper::ClusterDirection vertexClusterDirection(
218  LArVertexHelper::GetClusterDirectionInZ(this->GetPandora(), pVertex, pVertexCluster, m_directionTanAngle, m_directionApexShift));
219  const LArVertexHelper::ClusterDirection daughterClusterDirection(
220  LArVertexHelper::GetClusterDirectionInZ(this->GetPandora(), pVertex, pDaughterCluster, m_directionTanAngle, m_directionApexShift));
221  const bool isConsistentDirection(vertexClusterDirection == daughterClusterDirection);
222 
223  return ClusterAssociation(pVertexCluster, pDaughterCluster, boundedFraction, isConsistentDirection);
224 }
225 
226 //------------------------------------------------------------------------------------------------------------------------------------------
227 
229 {
230  const PfoList *pTrackPfoList(nullptr);
231  (void)PandoraContentApi::GetList(*this, m_trackPfoListName, pTrackPfoList);
232 
233  for (const PfoAssociation &pfoAssociation : pfoAssociationList)
234  {
235  if ((pfoAssociation.GetMeanBoundedFraction() < m_meanBoundedFractionCut) ||
236  (pfoAssociation.GetMaxBoundedFraction() < m_maxBoundedFractionCut) || (pfoAssociation.GetMinBoundedFraction() < m_minBoundedFractionCut) ||
237  (pfoAssociation.GetNConsistentDirections() < m_minConsistentDirections))
238  {
239  continue;
240  }
241 
242  if (pTrackPfoList)
243  {
244  if ((pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetVertexPfo())) &&
245  (pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetDaughterPfo())))
246  {
247  continue;
248  }
249 
250  if (((pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetVertexPfo())) ||
251  (pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetDaughterPfo()))) &&
252  (pfoAssociation.GetNConsistentDirections() < m_minConsistentDirectionsTrack))
253  {
254  continue;
255  }
256  }
257 
258  this->MergePfos(pfoAssociation);
259  return true;
260  }
261 
262  return false;
263 }
264 
265 //------------------------------------------------------------------------------------------------------------------------------------------
266 
268 {
269  const PfoList *pTrackPfoList(nullptr), *pShowerPfoList(nullptr);
270  (void)PandoraContentApi::GetList(*this, m_trackPfoListName, pTrackPfoList);
271  (void)PandoraContentApi::GetList(*this, m_showerPfoListName, pShowerPfoList);
272 
273  if (!pTrackPfoList && !pShowerPfoList)
274  throw StatusCodeException(STATUS_CODE_FAILURE);
275 
276  const Pfo *const pVertexPfo(pfoAssociation.GetVertexPfo());
277  const bool isvertexTrack(pTrackPfoList && (pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pVertexPfo)));
278  const Pfo *pDaughterPfo(pfoAssociation.GetDaughterPfo());
279  const bool isDaughterShower(pShowerPfoList && (pShowerPfoList->end() != std::find(pShowerPfoList->begin(), pShowerPfoList->end(), pDaughterPfo)));
280 
281  this->MergeAndDeletePfos(pVertexPfo, pDaughterPfo);
282 
283  if (isvertexTrack && isDaughterShower)
284  {
285  const PfoList vertexPfoList(1, pVertexPfo);
286 
287  PandoraContentApi::ParticleFlowObject::Metadata metadata;
288  metadata.m_particleId = E_MINUS;
289  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pVertexPfo, metadata));
290 
291  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, m_trackPfoListName, m_showerPfoListName, vertexPfoList));
292  }
293 }
294 
295 //------------------------------------------------------------------------------------------------------------------------------------------
296 //------------------------------------------------------------------------------------------------------------------------------------------
297 
299  m_pVertexCluster(nullptr),
300  m_pDaughterCluster(nullptr),
301  m_boundedFraction(0.f),
302  m_isConsistentDirection(false)
303 {
304 }
305 
306 //------------------------------------------------------------------------------------------------------------------------------------------
307 
309  const Cluster *const pDaughterCluster, const float boundedFraction, const bool isConsistentDirection) :
310  m_pVertexCluster(pVertexCluster),
311  m_pDaughterCluster(pDaughterCluster),
312  m_boundedFraction(boundedFraction),
313  m_isConsistentDirection(isConsistentDirection)
314 {
315 }
316 
317 //------------------------------------------------------------------------------------------------------------------------------------------
318 //------------------------------------------------------------------------------------------------------------------------------------------
319 
320 VertexBasedPfoMopUpAlgorithm::PfoAssociation::PfoAssociation(const Pfo *const pVertexPfo, const Pfo *const pDaughterPfo,
321  const ClusterAssociation &clusterAssociationU, const ClusterAssociation &clusterAssociationV, const ClusterAssociation &clusterAssociationW) :
322  m_pVertexPfo(pVertexPfo),
323  m_pDaughterPfo(pDaughterPfo),
324  m_clusterAssociationU(clusterAssociationU),
325  m_clusterAssociationV(clusterAssociationV),
326  m_clusterAssociationW(clusterAssociationW)
327 {
328 }
329 
330 //------------------------------------------------------------------------------------------------------------------------------------------
331 
333 {
334  return ((this->GetClusterAssociationU().GetBoundedFraction() + this->GetClusterAssociationV().GetBoundedFraction() +
335  this->GetClusterAssociationW().GetBoundedFraction()) /
336  3.f);
337 }
338 
339 //------------------------------------------------------------------------------------------------------------------------------------------
340 
342 {
343  return std::max(this->GetClusterAssociationU().GetBoundedFraction(),
344  std::max(this->GetClusterAssociationV().GetBoundedFraction(), this->GetClusterAssociationW().GetBoundedFraction()));
345 }
346 
347 //------------------------------------------------------------------------------------------------------------------------------------------
348 
350 {
351  return std::min(this->GetClusterAssociationU().GetBoundedFraction(),
352  std::min(this->GetClusterAssociationV().GetBoundedFraction(), this->GetClusterAssociationW().GetBoundedFraction()));
353 }
354 
355 //------------------------------------------------------------------------------------------------------------------------------------------
356 
358 {
359  unsigned int nConsistentDirections(0);
360 
361  if (this->GetClusterAssociationU().IsConsistentDirection())
362  ++nConsistentDirections;
363 
364  if (this->GetClusterAssociationV().IsConsistentDirection())
365  ++nConsistentDirections;
366 
367  if (this->GetClusterAssociationW().IsConsistentDirection())
368  ++nConsistentDirections;
369 
370  return nConsistentDirections;
371 }
372 
373 //------------------------------------------------------------------------------------------------------------------------------------------
374 
376 {
377  if (std::fabs(this->GetMeanBoundedFraction() - rhs.GetMeanBoundedFraction()) > std::numeric_limits<float>::epsilon())
378  return (this->GetMeanBoundedFraction() > rhs.GetMeanBoundedFraction());
379 
380  if (m_pVertexPfo != rhs.m_pVertexPfo)
382 
384 }
385 
386 //------------------------------------------------------------------------------------------------------------------------------------------
387 //------------------------------------------------------------------------------------------------------------------------------------------
388 
390  const Cluster *const pCluster, const CartesianVector &vertexPosition2D, const float coneAngleCentile, const float maxCosHalfAngle) :
391  m_pCluster(pCluster),
392  m_apex(vertexPosition2D),
393  m_direction(0.f, 0.f, 0.f),
394  m_coneLength(0.f),
395  m_coneCosHalfAngle(0.f)
396 {
399 
400  // ATTN Compensate for coordinate shift when fitting with vertex constraint (cleaner way to do this?)
401  if (m_coneLength < std::numeric_limits<float>::epsilon())
402  {
403  m_direction = m_direction * -1.f;
404  m_coneLength = std::fabs(m_coneLength);
405  }
406 
407  m_coneCosHalfAngle = std::min(maxCosHalfAngle, this->GetCosHalfAngleEstimate(coneAngleCentile));
408 }
409 
410 //------------------------------------------------------------------------------------------------------------------------------------------
411 
412 float VertexBasedPfoMopUpAlgorithm::ConeParameters::GetBoundedFraction(const Cluster *const pDaughterCluster, const float coneLengthMultiplier) const
413 {
414  unsigned int nMatchedHits(0);
415  const OrderedCaloHitList &orderedCaloHitList(pDaughterCluster->GetOrderedCaloHitList());
416 
417  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
418  {
419  for (CaloHitList::const_iterator hIter = iter->second->begin(), hIterEnd = iter->second->end(); hIter != hIterEnd; ++hIter)
420  {
421  const CartesianVector &positionVector((*hIter)->GetPositionVector());
422 
423  if (m_direction.GetCosOpeningAngle(positionVector - m_apex) < m_coneCosHalfAngle)
424  continue;
425 
426  if (m_direction.GetDotProduct(positionVector - m_apex) > coneLengthMultiplier * m_coneLength)
427  continue;
428 
429  ++nMatchedHits;
430  }
431  }
432 
433  if (0 == pDaughterCluster->GetNCaloHits())
434  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
435 
436  return (static_cast<float>(nMatchedHits) / static_cast<float>(pDaughterCluster->GetNCaloHits()));
437 }
438 
439 //------------------------------------------------------------------------------------------------------------------------------------------
440 
442 {
443  const OrderedCaloHitList &orderedCaloHitList(m_pCluster->GetOrderedCaloHitList());
444  float sumDxDz(0.f), sumDxDx(0.f);
445 
446  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
447  {
448  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
449  {
450  const CartesianVector apexDisplacement((*hitIter)->GetPositionVector() - m_apex);
451  sumDxDz += apexDisplacement.GetX() * apexDisplacement.GetZ();
452  sumDxDx += apexDisplacement.GetX() * apexDisplacement.GetX();
453  }
454  }
455 
456  if (sumDxDx < std::numeric_limits<float>::epsilon())
457  return CartesianVector(0.f, 0.f, 1.f);
458 
459  return CartesianVector(1.f, 0.f, sumDxDz / sumDxDx).GetUnitVector();
460 }
461 
462 //------------------------------------------------------------------------------------------------------------------------------------------
463 
465 {
466  float maxProjectedLength(0.f);
467  const OrderedCaloHitList &orderedCaloHitList(m_pCluster->GetOrderedCaloHitList());
468 
469  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
470  {
471  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
472  {
473  const float projectedLength(m_direction.GetDotProduct((*hitIter)->GetPositionVector() - m_apex));
474 
475  if (std::fabs(projectedLength) > std::fabs(maxProjectedLength))
476  maxProjectedLength = projectedLength;
477  }
478  }
479 
480  return maxProjectedLength;
481 }
482 
483 //------------------------------------------------------------------------------------------------------------------------------------------
484 
486 {
487  FloatVector halfAngleValues;
488  const OrderedCaloHitList &orderedCaloHitList(m_pCluster->GetOrderedCaloHitList());
489 
490  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
491  {
492  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
493  halfAngleValues.push_back(m_direction.GetOpeningAngle((*hitIter)->GetPositionVector() - m_apex));
494  }
495 
496  std::sort(halfAngleValues.begin(), halfAngleValues.end());
497 
498  if (halfAngleValues.empty())
499  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
500 
501  const unsigned int halfAngleBin(coneAngleCentile * halfAngleValues.size());
502  return std::cos(halfAngleValues.at(halfAngleBin));
503 }
504 
505 //------------------------------------------------------------------------------------------------------------------------------------------
506 //------------------------------------------------------------------------------------------------------------------------------------------
507 
508 StatusCode VertexBasedPfoMopUpAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
509 {
510  PANDORA_RETURN_RESULT_IF_AND_IF(
511  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "TrackPfoListName", m_trackPfoListName));
512 
513  PANDORA_RETURN_RESULT_IF_AND_IF(
514  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ShowerPfoListName", m_showerPfoListName));
515 
516  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
517  XmlHelper::ReadValue(xmlHandle, "MinVertexLongitudinalDistance", m_minVertexLongitudinalDistance));
518 
519  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
520  XmlHelper::ReadValue(xmlHandle, "MaxVertexTransverseDistance", m_maxVertexTransverseDistance));
521 
522  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
523  XmlHelper::ReadValue(xmlHandle, "MinVertexAssociatedHitTypes", m_minVertexAssociatedHitTypes));
524 
525  PANDORA_RETURN_RESULT_IF_AND_IF(
526  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ConeAngleCentile", m_coneAngleCentile));
527 
528  PANDORA_RETURN_RESULT_IF_AND_IF(
529  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxConeCosHalfAngle", m_maxConeCosHalfAngle));
530 
531  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
532  XmlHelper::ReadValue(xmlHandle, "MaxConeLengthMultiplier", m_maxConeLengthMultiplier));
533 
534  PANDORA_RETURN_RESULT_IF_AND_IF(
535  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DirectionTanAngle", m_directionTanAngle));
536 
537  PANDORA_RETURN_RESULT_IF_AND_IF(
538  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DirectionApexShift", m_directionApexShift));
539 
540  PANDORA_RETURN_RESULT_IF_AND_IF(
541  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MeanBoundedFractionCut", m_meanBoundedFractionCut));
542 
543  PANDORA_RETURN_RESULT_IF_AND_IF(
544  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxBoundedFractionCut", m_maxBoundedFractionCut));
545 
546  PANDORA_RETURN_RESULT_IF_AND_IF(
547  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinBoundedFractionCut", m_minBoundedFractionCut));
548 
549  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
550  XmlHelper::ReadValue(xmlHandle, "MinConsistentDirections", m_minConsistentDirections));
551 
552  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
553  XmlHelper::ReadValue(xmlHandle, "MinConsistentDirectionsTrack", m_minConsistentDirectionsTrack));
554 
557 
558  return PfoMopUpBaseAlgorithm::ReadSettings(xmlHandle);
559 }
560 
561 } // namespace lar_content
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float GetBoundedFraction(const pandora::Cluster *const pDaughterCluster, const float coneLengthMultiplier) const
Get the fraction of hits in a candidate daughter cluster bounded by the cone.
void GetPfoAssociations(const pandora::Vertex *const pVertex, const pandora::PfoList &vertexPfos, const pandora::PfoList &nonVertexPfos, PfoAssociationList &pfoAssociationList) const
Get the list of associations between vertex-associated pfos and non-vertex-associated pfos...
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
unsigned int m_minVertexAssociatedHitTypes
The min number of vertex associated hit types for a vertex associated pfo.
float m_maxConeLengthMultiplier
Consider hits as bound if inside cone, with projected distance less than N times cone length...
PfoAssociation(const pandora::Pfo *const pVertexPfo, const pandora::Pfo *const pDaughterPfo, const ClusterAssociation &clusterAssociationU, const ClusterAssociation &clusterAssociationV, const ClusterAssociation &clusterAssociationW)
Constructor.
ClusterAssociation GetClusterAssociation(const pandora::Vertex *const pVertex, const pandora::Cluster *const pVertexCluster, const pandora::Cluster *const pDaughterCluster) const
Get cluster association details between a vertex-associated cluster and a non-vertex associated daugh...
ConeParameters(const pandora::Cluster *const pCluster, const pandora::CartesianVector &vertexPosition2D, const float coneAngleCentile, const float maxConeCosHalfAngle)
Constructor.
Header file for the lar pointing cluster class.
const pandora::Cluster * m_pDaughterCluster
The address of the daughter cluster.
unsigned int GetNConsistentDirections() const
Get the number of views for which the vertex and daughter cluster directions are consistent.
float m_coneAngleCentile
Cluster cone angle is defined using specified centile of distribution of hit half angles...
float GetCosHalfAngleEstimate(const float coneAngleCentile) const
Get the cone cos half angle estimate.
unsigned int m_minConsistentDirections
The minimum number of consistent cluster directions to allow a pfo merge.
pandora::StringVector m_daughterListNames
The list of potential daughter object list names.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
void MergePfos(const PfoAssociation &pfoAssociation) const
Merge the vertex and daughter pfos (deleting daughter pfo, merging clusters, etc.) described in the s...
intermediate_table::const_iterator const_iterator
LArPointingCluster class.
float GetMaxBoundedFraction() const
Get the maximum bounded fraction from the u, v and w views.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
bool m_isConsistentDirection
Whether the vertex and daughter clusters have consistent directions.
float m_maxVertexTransverseDistance
Vertex association check: max transverse distance cut.
float m_minVertexLongitudinalDistance
Vertex association check: min longitudinal distance cut.
float m_maxBoundedFractionCut
Cut on association info (max bounded fraction) for determining pfo merges.
float GetSignedConeLength() const
Get the cone length (signed, by projections of hits onto initial direction estimate) ...
bool ProcessPfoAssociations(const PfoAssociationList &pfoAssociationList) const
Process the list of pfo associations, merging the best-matching pfo.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
std::map< pandora::HitType, ClusterAssociation > HitTypeToAssociationMap
Header file for the cluster helper class.
float m_directionApexShift
Direction determination, look for vertex inside triangle with apex shifted along the cluster length...
const Vertex & GetOuterVertex() const
Get the outer vertex.
float m_meanBoundedFractionCut
Cut on association info (mean bounded fraction) for determining pfo merges.
const Vertex & GetInnerVertex() const
Get the inner vertex.
virtual PfoAssociation GetPfoAssociation(const pandora::Pfo *const pVertexPfo, const pandora::Pfo *const pDaughterPfo, HitTypeToAssociationMap &hitTypeToAssociationMap) const
Get pfo association details between a vertex-associated pfo and a non-vertex associated daughter cand...
pandora::CartesianVector GetDirectionEstimate() const
Get the cone direction estimate, with apex fixed at the 2d vertex position.
float m_boundedFraction
The fraction of daughter hits bounded by the cone defined by the vertex cluster.
const ClusterAssociation & GetClusterAssociationW() const
Get the cluster association in the w view.
const pandora::Pfo * m_pDaughterPfo
The address of the non-vertex-associated candidate daughter pfo.
float m_directionTanAngle
Direction determination, look for vertex inside triangle with apex shifted along the cluster length...
void GetInputPfos(const pandora::Vertex *const pVertex, pandora::PfoList &vertexPfos, pandora::PfoList &nonVertexPfos) const
Get the list of input pfos and divide them into vertex-associated and non-vertex-associated lists...
Header file for the vertex helper class.
virtual bool IsVertexAssociated(const pandora::CartesianVector &vertex2D, const LArPointingCluster &pointingCluster) const
Whether a specified pfo is associated with a specified vertex.
unsigned int m_minConsistentDirectionsTrack
The minimum number of consistent cluster directions to allow a merge involving a track pfo...
float m_maxConeCosHalfAngle
Maximum value for cosine of cone half angle.
const pandora::Pfo * GetDaughterPfo() const
Get the address of the non-vertex-associated candidate daughter pfo.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
HitType
Definition: HitType.h:12
const ClusterAssociation & GetClusterAssociationU() const
Get the cluster association in the u view.
std::string m_trackPfoListName
The input track pfo list name.
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.
const pandora::Pfo * GetVertexPfo() const
Get the address of the vertex-associated pfo.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
float GetMinBoundedFraction() const
Get the minimum bounded fraction from the u, v and w views.
const ClusterAssociation & GetClusterAssociationV() const
Get the cluster association in the v view.
const pandora::Cluster * m_pVertexCluster
The address of the vertex cluster.
const pandora::Pfo * m_pVertexPfo
The address of the vertex-associated pfo.
float GetMeanBoundedFraction() const
Get the mean bounded fraction, averaging over the u, v and w views.
bool operator<(const PfoAssociation &rhs) const
operator<
std::list< Vertex > VertexList
Definition: DCEL.h:169
Header file for the vertex based pfo mop up algorithm class.
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.
static ClusterDirection GetClusterDirectionInZ(const pandora::Pandora &pandora, const pandora::Vertex *const pVertex, const pandora::Cluster *const pCluster, const float tanAngle, const float apexShift)
Get the direction of the cluster in z, using a projection of the provided vertex. ...
std::string m_showerPfoListName
The input shower pfo list name.
float m_minBoundedFractionCut
Cut on association info (min bounded fraction) for determining pfo merges.