EndAssociatedPfosTool.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArEventBuilding/EndAssociatedPfosTool.cc
3  *
4  * @brief Implementation of the end associated pfos tool class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
15 
17 
18 using namespace pandora;
19 
20 namespace lar_content
21 {
22 
25 
26 EndAssociatedPfosTool::EndAssociatedPfosTool() :
27  m_minNeutrinoVertexDistance(5.f),
28  m_minVertexLongitudinalDistance(-2.5f),
29  m_maxVertexLongitudinalDistance(20.f),
30  m_maxVertexTransverseDistance(3.5f),
31  m_vertexAngularAllowance(3.f),
32  m_maxParentEndpointDistance(2.5f)
33 {
34 }
35 
36 //------------------------------------------------------------------------------------------------------------------------------------------
37 
38 void EndAssociatedPfosTool::Run(const NeutrinoHierarchyAlgorithm *const pAlgorithm, const Vertex *const pNeutrinoVertex, PfoInfoMap &pfoInfoMap)
39 {
40  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
41  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
42 
43  bool associationsMade(true);
44 
45  while (associationsMade)
46  {
47  associationsMade = false;
48  PfoVector assignedPfos, unassignedPfos;
49  pAlgorithm->SeparatePfos(pfoInfoMap, assignedPfos, unassignedPfos);
50 
51  if (unassignedPfos.empty())
52  break;
53 
54  // ATTN May want to reconsider precise association mechanics for complex situations
55  PfoSet recentlyAssigned;
56 
57  for (const ParticleFlowObject *const pParentPfo : assignedPfos)
58  {
59  PfoInfo *const pParentPfoInfo(pfoInfoMap.at(pParentPfo));
60  const LArPointingCluster parentPointingCluster(*(pParentPfoInfo->GetSlidingFitResult3D()));
61 
62  const LArPointingCluster::Vertex &parentEndpoint(
63  pParentPfoInfo->IsInnerLayerAssociated() ? parentPointingCluster.GetOuterVertex() : parentPointingCluster.GetInnerVertex());
64  const float neutrinoVertexDistance((parentEndpoint.GetPosition() - pNeutrinoVertex->GetPosition()).GetMagnitude());
65 
66  if (neutrinoVertexDistance < m_minNeutrinoVertexDistance)
67  continue;
68 
69  for (const ParticleFlowObject *const pPfo : unassignedPfos)
70  {
71  if (recentlyAssigned.count(pPfo))
72  continue;
73 
74  PfoInfo *const pPfoInfo(pfoInfoMap.at(pPfo));
75 
76  const LArPointingCluster pointingCluster(*(pPfoInfo->GetSlidingFitResult3D()));
77  const bool useInner((pointingCluster.GetInnerVertex().GetPosition() - parentEndpoint.GetPosition()).GetMagnitudeSquared() <
78  (pointingCluster.GetOuterVertex().GetPosition() - parentEndpoint.GetPosition()).GetMagnitudeSquared());
79 
80  const LArPointingCluster::Vertex &daughterVertex(useInner ? pointingCluster.GetInnerVertex() : pointingCluster.GetOuterVertex());
81 
82  if (LArPointingClusterHelper::IsNode(parentEndpoint.GetPosition(), daughterVertex, m_minVertexLongitudinalDistance, m_maxVertexTransverseDistance) ||
84  LArPointingClusterHelper::IsEmission(parentEndpoint.GetPosition(), daughterVertex, m_minVertexLongitudinalDistance,
86  LArPointingClusterHelper::IsEmission(daughterVertex.GetPosition(), parentEndpoint, m_minVertexLongitudinalDistance,
88  this->IsCloseToParentEndpoint(parentEndpoint.GetPosition(), pParentPfoInfo->GetCluster3D(), pPfoInfo->GetCluster3D()))
89  {
90  associationsMade = true;
91  pParentPfoInfo->AddDaughterPfo(pPfoInfo->GetThisPfo());
92  pPfoInfo->SetParentPfo(pParentPfoInfo->GetThisPfo());
93  pPfoInfo->SetInnerLayerAssociation(useInner);
94  recentlyAssigned.insert(pPfoInfo->GetThisPfo());
95  }
96  }
97  }
98  }
99 }
100 
101 //------------------------------------------------------------------------------------------------------------------------------------------
102 
104  const CartesianVector &parentEndpoint, const Cluster *const pParentCluster3D, const Cluster *const pDaughterCluster3D) const
105 {
106  try
107  {
108  CartesianVector parentPosition3D(0.f, 0.f, 0.f), daughterPosition3D(0.f, 0.f, 0.f);
109  LArClusterHelper::GetClosestPositions(pParentCluster3D, pDaughterCluster3D, parentPosition3D, daughterPosition3D);
110 
111  if (((parentPosition3D - parentEndpoint).GetMagnitude() < m_maxParentEndpointDistance) &&
112  ((parentPosition3D - daughterPosition3D).GetMagnitude() < m_maxParentEndpointDistance))
113  return true;
114  }
115  catch (const StatusCodeException &)
116  {
117  }
118 
119  return false;
120 }
121 
122 //------------------------------------------------------------------------------------------------------------------------------------------
123 
124 StatusCode EndAssociatedPfosTool::ReadSettings(const TiXmlHandle xmlHandle)
125 {
126  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
127  XmlHelper::ReadValue(xmlHandle, "MinNeutrinoVertexDistance", m_minNeutrinoVertexDistance));
128 
129  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
130  XmlHelper::ReadValue(xmlHandle, "MinVertexLongitudinalDistance", m_minVertexLongitudinalDistance));
131 
132  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
133  XmlHelper::ReadValue(xmlHandle, "MaxVertexLongitudinalDistance", m_maxVertexLongitudinalDistance));
134 
135  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
136  XmlHelper::ReadValue(xmlHandle, "MaxVertexTransverseDistance", m_maxVertexTransverseDistance));
137 
138  PANDORA_RETURN_RESULT_IF_AND_IF(
139  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VertexAngularAllowance", m_vertexAngularAllowance));
140 
141  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
142  XmlHelper::ReadValue(xmlHandle, "MaxParentEndpointDistance", m_maxParentEndpointDistance));
143 
144  return STATUS_CODE_SUCCESS;
145 }
146 
147 } // namespace lar_content
void Run(const NeutrinoHierarchyAlgorithm *const pAlgorithm, const pandora::Vertex *const pNeutrinoVertex, NeutrinoHierarchyAlgorithm::PfoInfoMap &pfoInfoMap)
Run the algorithm tool.
Header file for the lar pointing cluster class.
NeutrinoHierarchyAlgorithm::PfoInfoMap PfoInfoMap
static bool IsEmission(const pandora::CartesianVector &parentVertex, const LArPointingCluster::Vertex &daughterVertex, const float minLongitudinalDistance, const float maxLongitudinalDistance, const float maxTransverseDistance, const float angularAllowance)
Whether pointing vertex is emitted from a given position.
float m_minNeutrinoVertexDistance
Min distance between candidate parent endpoint and neutrino vertex.
void SeparatePfos(const NeutrinoHierarchyAlgorithm::PfoInfoMap &pfoInfoMap, pandora::PfoVector &assignedPfos, pandora::PfoVector &unassignedPfos) const
Query the pfo info map and separate/extract pfos currently either acting as parents or associated wit...
LArPointingCluster class.
static void GetClosestPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianVector &position1, pandora::CartesianVector &position2)
Get pair of closest positions for a pair of clusters.
float m_vertexAngularAllowance
Vertex association check: pointing angular allowance in degrees.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_maxVertexLongitudinalDistance
Vertex association check: max longitudinal distance cut.
Header file for the end associated pfos tool class.
Header file for the lar three dimensional sliding fit result class.
float m_maxParentEndpointDistance
Max distance between candidate parent endpoint and candidate daughter.
bool IsCloseToParentEndpoint(const pandora::CartesianVector &parentEndpoint, const pandora::Cluster *const pParentCluster3D, const pandora::Cluster *const pDaughterCluster3D) const
Whether a daughter 3D cluster is in close proximity to the endpoint of a parent 3D cluster...
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
float m_maxVertexTransverseDistance
Vertex association check: max transverse distance cut.
NeutrinoHierarchyAlgorithm::PfoInfo PfoInfo
float m_minVertexLongitudinalDistance
Vertex association check: min longitudinal distance cut.
QTextStream & endl(QTextStream &s)
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.