LArSoft  v06_85_00
Liquid Argon Software toolkit - http://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((pVertexList && (pVertexList->size() == 1) && (VERTEX_3D == (*(pVertexList->begin()))->GetVertexType())) ? *(pVertexList->begin()) : nullptr);
51 
52  if (!pSelectedVertex)
53  {
54  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
55  std::cout << "VertexBasedPfoMopUp: unable to find vertex in current list " << std::endl;
56 
57  return STATUS_CODE_SUCCESS;
58  }
59 
60  while (true)
61  {
62  PfoList vertexPfos, nonVertexPfos;
63  this->GetInputPfos(pSelectedVertex, vertexPfos, nonVertexPfos);
64 
65  PfoAssociationList pfoAssociationList;
66  this->GetPfoAssociations(pSelectedVertex, vertexPfos, nonVertexPfos, pfoAssociationList);
67 
68  std::sort(pfoAssociationList.begin(), pfoAssociationList.end());
69  const bool pfoMergeMade(this->ProcessPfoAssociations(pfoAssociationList));
70 
71  if (!pfoMergeMade)
72  break;
73  }
74 
75  return STATUS_CODE_SUCCESS;
76 }
77 
78 //------------------------------------------------------------------------------------------------------------------------------------------
79 
80 bool VertexBasedPfoMopUpAlgorithm::IsVertexAssociated(const CartesianVector &vertex2D, const LArPointingCluster &pointingCluster) const
81 {
84 }
85 
86 //------------------------------------------------------------------------------------------------------------------------------------------
87 
88 VertexBasedPfoMopUpAlgorithm::PfoAssociation VertexBasedPfoMopUpAlgorithm::GetPfoAssociation(const Pfo *const pVertexPfo, const Pfo *const pDaughterPfo,
89  HitTypeToAssociationMap &hitTypeToAssociationMap) const
90 {
91  if ((pVertexPfo->GetClusterList().size() != pDaughterPfo->GetClusterList().size()) || (3 != pVertexPfo->GetClusterList().size()))
92  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
93 
94  return PfoAssociation(pVertexPfo, pDaughterPfo, hitTypeToAssociationMap.at(TPC_VIEW_U), hitTypeToAssociationMap.at(TPC_VIEW_V), hitTypeToAssociationMap.at(TPC_VIEW_W));
95 }
96 
97 //------------------------------------------------------------------------------------------------------------------------------------------
98 
99 void VertexBasedPfoMopUpAlgorithm::GetInputPfos(const Vertex *const pVertex, PfoList &vertexPfos, PfoList &nonVertexPfos) const
100 {
101  StringVector listNames;
102  listNames.push_back(m_trackPfoListName);
103  listNames.push_back(m_showerPfoListName);
104 
105  for (const std::string &listName : listNames)
106  {
107  const PfoList *pPfoList(nullptr);
108 
109  if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*this, listName, pPfoList))
110  continue;
111 
112  for (const Pfo *const pPfo : *pPfoList)
113  {
114  PfoList &pfoTargetList(this->IsVertexAssociated(pPfo, pVertex) ? vertexPfos : nonVertexPfos);
115  pfoTargetList.push_back(pPfo);
116  }
117  }
118 }
119 
120 //------------------------------------------------------------------------------------------------------------------------------------------
121 
122 bool VertexBasedPfoMopUpAlgorithm::IsVertexAssociated(const Pfo *const pPfo, const Vertex *const pVertex) const
123 {
124  if (VERTEX_3D != pVertex->GetVertexType())
125  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
126 
127  HitTypeSet hitTypeSet;
128 
129  for (const Cluster *const pCluster : pPfo->GetClusterList())
130  {
131  const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
132 
133  if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
134  continue;
135 
136  const CartesianVector vertex2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
137 
138  try
139  {
140  const LArPointingCluster pointingCluster(pCluster);
141 
142  if (this->IsVertexAssociated(vertex2D, pointingCluster))
143  hitTypeSet.insert(hitType);
144  }
145  catch (StatusCodeException &) {}
146  }
147 
148  const unsigned int nVertexAssociatedHitTypes(hitTypeSet.size());
149  return (nVertexAssociatedHitTypes >= m_minVertexAssociatedHitTypes);
150 }
151 
152 //------------------------------------------------------------------------------------------------------------------------------------------
153 
154 void VertexBasedPfoMopUpAlgorithm::GetPfoAssociations(const Vertex *const pVertex, const PfoList &vertexPfos, const PfoList &nonVertexPfos,
155  PfoAssociationList &pfoAssociationList) const
156 {
157  for (const Pfo *const pVertexPfo : vertexPfos)
158  {
159  for (const Pfo *const pDaughterPfo : nonVertexPfos)
160  {
161  try
162  {
163  const PfoAssociation pfoAssociation(this->GetPfoAssociation(pVertex, pVertexPfo, pDaughterPfo));
164  pfoAssociationList.push_back(pfoAssociation);
165  }
166  catch (StatusCodeException &) {}
167  }
168  }
169 }
170 
171 //------------------------------------------------------------------------------------------------------------------------------------------
172 
173 VertexBasedPfoMopUpAlgorithm::PfoAssociation VertexBasedPfoMopUpAlgorithm::GetPfoAssociation(const Vertex *const pVertex, const Pfo *const pVertexPfo,
174  const Pfo *const pDaughterPfo) const
175 {
176  if (pVertexPfo->GetClusterList().empty() || pDaughterPfo->GetClusterList().empty())
177  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
178 
179  HitTypeToAssociationMap hitTypeToAssociationMap;
180 
181  for (const Cluster *const pVertexCluster : pVertexPfo->GetClusterList())
182  {
183  const HitType vertexHitType(LArClusterHelper::GetClusterHitType(pVertexCluster));
184 
185  for (const Cluster *const pDaughterCluster : pDaughterPfo->GetClusterList())
186  {
187  const HitType daughterHitType(LArClusterHelper::GetClusterHitType(pDaughterCluster));
188 
189  if (vertexHitType != daughterHitType)
190  continue;
191 
192  const ClusterAssociation clusterAssociation(this->GetClusterAssociation(pVertex, pVertexCluster, pDaughterCluster));
193  hitTypeToAssociationMap[vertexHitType] = clusterAssociation;
194  }
195  }
196 
197  return this->GetPfoAssociation(pVertexPfo, pDaughterPfo, hitTypeToAssociationMap);
198 }
199 
200 //------------------------------------------------------------------------------------------------------------------------------------------
201 
203  const Cluster *const pVertexCluster, const Cluster *const pDaughterCluster) const
204 {
205  const HitType vertexHitType(LArClusterHelper::GetClusterHitType(pVertexCluster));
206  const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), vertexHitType));
207 
208  const ConeParameters coneParameters(pVertexCluster, vertexPosition2D, m_coneAngleCentile, m_maxConeCosHalfAngle);
209  const float boundedFraction(coneParameters.GetBoundedFraction(pDaughterCluster, m_maxConeLengthMultiplier));
210 
211  const LArVertexHelper::ClusterDirection vertexClusterDirection(LArVertexHelper::GetClusterDirectionInZ(this->GetPandora(), pVertex,
212  pVertexCluster, m_directionTanAngle, m_directionApexShift));
213  const LArVertexHelper::ClusterDirection daughterClusterDirection(LArVertexHelper::GetClusterDirectionInZ(this->GetPandora(), pVertex,
214  pDaughterCluster, m_directionTanAngle, m_directionApexShift));
215  const bool isConsistentDirection(vertexClusterDirection == daughterClusterDirection);
216 
217  return ClusterAssociation(pVertexCluster, pDaughterCluster, boundedFraction, isConsistentDirection);
218 }
219 
220 //------------------------------------------------------------------------------------------------------------------------------------------
221 
223 {
224  const PfoList *pTrackPfoList(nullptr);
225  (void) PandoraContentApi::GetList(*this, m_trackPfoListName, pTrackPfoList);
226 
227  for (const PfoAssociation &pfoAssociation : pfoAssociationList)
228  {
229  if ((pfoAssociation.GetMeanBoundedFraction() < m_meanBoundedFractionCut) ||
230  (pfoAssociation.GetMaxBoundedFraction() < m_maxBoundedFractionCut) ||
231  (pfoAssociation.GetMinBoundedFraction() < m_minBoundedFractionCut) ||
232  (pfoAssociation.GetNConsistentDirections() < m_minConsistentDirections))
233  {
234  continue;
235  }
236 
237  if (pTrackPfoList)
238  {
239  if ((pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetVertexPfo())) &&
240  (pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetDaughterPfo())))
241  {
242  continue;
243  }
244 
245  if (((pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetVertexPfo())) ||
246  (pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pfoAssociation.GetDaughterPfo()))) &&
247  (pfoAssociation.GetNConsistentDirections() < m_minConsistentDirectionsTrack))
248  {
249  continue;
250  }
251  }
252 
253  this->MergePfos(pfoAssociation);
254  return true;
255  }
256 
257  return false;
258 }
259 
260 //------------------------------------------------------------------------------------------------------------------------------------------
261 
263 {
264  const PfoList *pTrackPfoList(nullptr), *pShowerPfoList(nullptr);
265  (void) PandoraContentApi::GetList(*this, m_trackPfoListName, pTrackPfoList);
266  (void) PandoraContentApi::GetList(*this, m_showerPfoListName, pShowerPfoList);
267 
268  if (!pTrackPfoList && !pShowerPfoList)
269  throw StatusCodeException(STATUS_CODE_FAILURE);
270 
271  const Pfo *const pVertexPfo(pfoAssociation.GetVertexPfo());
272  const bool isvertexTrack(pTrackPfoList && (pTrackPfoList->end() != std::find(pTrackPfoList->begin(), pTrackPfoList->end(), pVertexPfo)));
273  const Pfo *pDaughterPfo(pfoAssociation.GetDaughterPfo());
274  const bool isDaughterShower(pShowerPfoList && (pShowerPfoList->end() != std::find(pShowerPfoList->begin(), pShowerPfoList->end(), pDaughterPfo)));
275 
276  this->MergeAndDeletePfos(pVertexPfo, pDaughterPfo);
277 
278  if (isvertexTrack && isDaughterShower)
279  {
280  const PfoList vertexPfoList(1, pVertexPfo);
281 
282  PandoraContentApi::ParticleFlowObject::Metadata metadata;
283  metadata.m_particleId = E_MINUS;
284  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pVertexPfo, metadata));
285 
286  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, m_trackPfoListName, m_showerPfoListName, vertexPfoList));
287  }
288 }
289 
290 //------------------------------------------------------------------------------------------------------------------------------------------
291 //------------------------------------------------------------------------------------------------------------------------------------------
292 
294  m_pVertexCluster(nullptr),
295  m_pDaughterCluster(nullptr),
296  m_boundedFraction(0.f),
297  m_isConsistentDirection(false)
298 {
299 }
300 
301 //------------------------------------------------------------------------------------------------------------------------------------------
302 
303 VertexBasedPfoMopUpAlgorithm::ClusterAssociation::ClusterAssociation(const Cluster *const pVertexCluster, const Cluster *const pDaughterCluster,
304  const float boundedFraction, const bool isConsistentDirection) :
305  m_pVertexCluster(pVertexCluster),
306  m_pDaughterCluster(pDaughterCluster),
307  m_boundedFraction(boundedFraction),
308  m_isConsistentDirection(isConsistentDirection)
309 {
310 }
311 
312 //------------------------------------------------------------------------------------------------------------------------------------------
313 //------------------------------------------------------------------------------------------------------------------------------------------
314 
315 VertexBasedPfoMopUpAlgorithm::PfoAssociation::PfoAssociation(const Pfo *const pVertexPfo, const Pfo *const pDaughterPfo, const ClusterAssociation &clusterAssociationU,
316  const ClusterAssociation &clusterAssociationV, const ClusterAssociation &clusterAssociationW) :
317  m_pVertexPfo(pVertexPfo),
318  m_pDaughterPfo(pDaughterPfo),
319  m_clusterAssociationU(clusterAssociationU),
320  m_clusterAssociationV(clusterAssociationV),
321  m_clusterAssociationW(clusterAssociationW)
322 {
323 }
324 
325 //------------------------------------------------------------------------------------------------------------------------------------------
326 
328 {
329  return ((this->GetClusterAssociationU().GetBoundedFraction() + this->GetClusterAssociationV().GetBoundedFraction() + this->GetClusterAssociationW().GetBoundedFraction()) / 3.f);
330 }
331 
332 //------------------------------------------------------------------------------------------------------------------------------------------
333 
335 {
336  return std::max(this->GetClusterAssociationU().GetBoundedFraction(), std::max(this->GetClusterAssociationV().GetBoundedFraction(), this->GetClusterAssociationW().GetBoundedFraction()));
337 }
338 
339 //------------------------------------------------------------------------------------------------------------------------------------------
340 
342 {
343  return std::min(this->GetClusterAssociationU().GetBoundedFraction(), std::min(this->GetClusterAssociationV().GetBoundedFraction(), this->GetClusterAssociationW().GetBoundedFraction()));
344 }
345 
346 //------------------------------------------------------------------------------------------------------------------------------------------
347 
349 {
350  unsigned int nConsistentDirections(0);
351 
352  if (this->GetClusterAssociationU().IsConsistentDirection())
353  ++nConsistentDirections;
354 
355  if (this->GetClusterAssociationV().IsConsistentDirection())
356  ++nConsistentDirections;
357 
358  if (this->GetClusterAssociationW().IsConsistentDirection())
359  ++nConsistentDirections;
360 
361  return nConsistentDirections;
362 }
363 
364 //------------------------------------------------------------------------------------------------------------------------------------------
365 
367 {
368  if (std::fabs(this->GetMeanBoundedFraction() - rhs.GetMeanBoundedFraction()) > std::numeric_limits<float>::epsilon())
369  return (this->GetMeanBoundedFraction() > rhs.GetMeanBoundedFraction());
370 
371  if (m_pVertexPfo != rhs.m_pVertexPfo)
373 
375 }
376 
377 //------------------------------------------------------------------------------------------------------------------------------------------
378 //------------------------------------------------------------------------------------------------------------------------------------------
379 
380 VertexBasedPfoMopUpAlgorithm::ConeParameters::ConeParameters(const Cluster *const pCluster, const CartesianVector &vertexPosition2D,
381  const float coneAngleCentile, const float maxCosHalfAngle) :
382  m_pCluster(pCluster),
383  m_apex(vertexPosition2D),
384  m_direction(0.f, 0.f, 0.f),
385  m_coneLength(0.f),
386  m_coneCosHalfAngle(0.f)
387 {
390 
391  // ATTN Compensate for coordinate shift when fitting with vertex constraint (cleaner way to do this?)
392  if (m_coneLength < std::numeric_limits<float>::epsilon())
393  {
394  m_direction = m_direction * -1.f;
395  m_coneLength = std::fabs(m_coneLength);
396  }
397 
398  m_coneCosHalfAngle = std::min(maxCosHalfAngle, this->GetCosHalfAngleEstimate(coneAngleCentile));
399 }
400 
401 //------------------------------------------------------------------------------------------------------------------------------------------
402 
403 float VertexBasedPfoMopUpAlgorithm::ConeParameters::GetBoundedFraction(const Cluster *const pDaughterCluster, const float coneLengthMultiplier) const
404 {
405  unsigned int nMatchedHits(0);
406  const OrderedCaloHitList &orderedCaloHitList(pDaughterCluster->GetOrderedCaloHitList());
407 
408  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
409  {
410  for (CaloHitList::const_iterator hIter = iter->second->begin(), hIterEnd = iter->second->end(); hIter != hIterEnd; ++hIter)
411  {
412  const CartesianVector &positionVector((*hIter)->GetPositionVector());
413 
414  if (m_direction.GetCosOpeningAngle(positionVector - m_apex) < m_coneCosHalfAngle)
415  continue;
416 
417  if (m_direction.GetDotProduct(positionVector - m_apex) > coneLengthMultiplier * m_coneLength)
418  continue;
419 
420  ++nMatchedHits;
421  }
422  }
423 
424  if (0 == pDaughterCluster->GetNCaloHits())
425  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
426 
427  return (static_cast<float>(nMatchedHits) / static_cast<float>(pDaughterCluster->GetNCaloHits()));
428 }
429 
430 //------------------------------------------------------------------------------------------------------------------------------------------
431 
433 {
434  const OrderedCaloHitList &orderedCaloHitList(m_pCluster->GetOrderedCaloHitList());
435  float sumDxDz(0.f), sumDxDx(0.f);
436 
437  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
438  {
439  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
440  {
441  const CartesianVector apexDisplacement((*hitIter)->GetPositionVector() - m_apex);
442  sumDxDz += apexDisplacement.GetX() * apexDisplacement.GetZ();
443  sumDxDx += apexDisplacement.GetX() * apexDisplacement.GetX();
444  }
445  }
446 
447  if (sumDxDx < std::numeric_limits<float>::epsilon())
448  return CartesianVector(0.f, 0.f, 1.f);
449 
450  return CartesianVector(1.f, 0.f, sumDxDz / sumDxDx).GetUnitVector();
451 }
452 
453 //------------------------------------------------------------------------------------------------------------------------------------------
454 
456 {
457  float maxProjectedLength(0.f);
458  const OrderedCaloHitList &orderedCaloHitList(m_pCluster->GetOrderedCaloHitList());
459 
460  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
461  {
462  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
463  {
464  const float projectedLength(m_direction.GetDotProduct((*hitIter)->GetPositionVector() - m_apex));
465 
466  if (std::fabs(projectedLength) > std::fabs(maxProjectedLength))
467  maxProjectedLength = projectedLength;
468  }
469  }
470 
471  return maxProjectedLength;
472 }
473 
474 //------------------------------------------------------------------------------------------------------------------------------------------
475 
477 {
478  FloatVector halfAngleValues;
479  const OrderedCaloHitList &orderedCaloHitList(m_pCluster->GetOrderedCaloHitList());
480 
481  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
482  {
483  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
484  halfAngleValues.push_back(m_direction.GetOpeningAngle((*hitIter)->GetPositionVector() - m_apex));
485  }
486 
487  std::sort(halfAngleValues.begin(), halfAngleValues.end());
488 
489  if (halfAngleValues.empty())
490  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
491 
492  const unsigned int halfAngleBin(coneAngleCentile * halfAngleValues.size());
493  return std::cos(halfAngleValues.at(halfAngleBin));
494 }
495 
496 //------------------------------------------------------------------------------------------------------------------------------------------
497 //------------------------------------------------------------------------------------------------------------------------------------------
498 
499 StatusCode VertexBasedPfoMopUpAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
500 {
501  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
502  "TrackPfoListName", m_trackPfoListName));
503 
504  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
505  "ShowerPfoListName", m_showerPfoListName));
506 
507  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
508  "MinVertexLongitudinalDistance", m_minVertexLongitudinalDistance));
509 
510  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
511  "MaxVertexTransverseDistance", m_maxVertexTransverseDistance));
512 
513  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
514  "MinVertexAssociatedHitTypes", m_minVertexAssociatedHitTypes));
515 
516  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
517  "ConeAngleCentile", m_coneAngleCentile));
518 
519  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
520  "MaxConeCosHalfAngle", m_maxConeCosHalfAngle));
521 
522  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
523  "MaxConeLengthMultiplier", m_maxConeLengthMultiplier));
524 
525  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
526  "DirectionTanAngle", m_directionTanAngle));
527 
528  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
529  "DirectionApexShift", m_directionApexShift));
530 
531  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
532  "MeanBoundedFractionCut", m_meanBoundedFractionCut));
533 
534  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
535  "MaxBoundedFractionCut", m_maxBoundedFractionCut));
536 
537  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
538  "MinBoundedFractionCut", m_minBoundedFractionCut));
539 
540  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
541  "MinConsistentDirections", m_minConsistentDirections));
542 
543  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
544  "MinConsistentDirectionsTrack", m_minConsistentDirectionsTrack));
545 
548 
549  return PfoMopUpBaseAlgorithm::ReadSettings(xmlHandle);
550 }
551 
552 } // 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...
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.
Int_t max
Definition: plot.C:27
std::map< pandora::HitType, ClusterAssociation > HitTypeToAssociationMap
intermediate_table::const_iterator const_iterator
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)
Int_t min
Definition: plot.C:26
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.
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:178
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.