TransverseExtensionAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArTwoDReco/LArClusterAssociation/TransverseExtensionAlgorithm.cc
3  *
4  * @brief Implementation of the transverse extension algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 TransverseExtensionAlgorithm::TransverseExtensionAlgorithm() :
22  m_minClusterLength(5.f),
23  m_maxLongitudinalDisplacement(10.f),
24  m_maxTransverseDisplacement(1.f)
25 {
26 }
27 
28 //------------------------------------------------------------------------------------------------------------------------------------------
29 
30 void TransverseExtensionAlgorithm::GetListOfCleanClusters(const ClusterList *const pClusterList, ClusterVector &clusterVector) const
31 {
32  for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
33  clusterVector.push_back(*iter);
34 
35  std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
36 }
37 
38 //------------------------------------------------------------------------------------------------------------------------------------------
39 
40 void TransverseExtensionAlgorithm::FillClusterAssociationMatrix(const ClusterVector &clusterVector, ClusterAssociationMatrix &clusterAssociationMatrix) const
41 {
42  // Convert long clusters into pointing clusters
43  LArPointingClusterList pointingClusterList;
44 
45  for (ClusterVector::const_iterator iter = clusterVector.begin(), iterEnd = clusterVector.end(); iter != iterEnd; ++iter)
46  {
47  const Cluster *const pCluster(*iter);
48 
50  continue;
51 
52  try
53  {
54  pointingClusterList.push_back(LArPointingCluster(*iter));
55  }
56  catch (StatusCodeException &)
57  {
58  }
59  }
60 
61  // Form associations between clusters
62  for (LArPointingClusterList::const_iterator iter1 = pointingClusterList.begin(), iterEnd1 = pointingClusterList.end(); iter1 != iterEnd1; ++iter1)
63  {
64  const LArPointingCluster &parentCluster = *iter1;
65 
66  for (ClusterVector::const_iterator iter2 = clusterVector.begin(), iterEnd2 = clusterVector.end(); iter2 != iterEnd2; ++iter2)
67  {
68  const Cluster *const pDaughterCluster(*iter2);
69 
70  if (parentCluster.GetCluster() == pDaughterCluster)
71  continue;
72 
73  this->FillClusterAssociationMatrix(parentCluster, pDaughterCluster, clusterAssociationMatrix);
74  }
75  }
76 }
77 
78 //------------------------------------------------------------------------------------------------------------------------------------------
79 
81  const Cluster *const pDaughterCluster, ClusterAssociationMatrix &clusterAssociationMatrix) const
82 {
83  const Cluster *const pParentCluster(pointingCluster.GetCluster());
84 
85  if (pParentCluster == pDaughterCluster)
86  return;
87 
88  for (unsigned int useInner = 0; useInner < 2; ++useInner)
89  {
90  const LArPointingCluster::Vertex &pointingVertex(useInner == 1 ? pointingCluster.GetInnerVertex() : pointingCluster.GetOuterVertex());
92 
93  if (pointingVertex.GetRms() > 0.5f)
94  continue;
95 
96  const float projectedDisplacement(LArClusterHelper::GetClosestDistance(pointingVertex.GetPosition(), pDaughterCluster));
97 
98  if (projectedDisplacement > m_maxLongitudinalDisplacement)
99  continue;
100 
102  float figureOfMerit(projectedDisplacement);
103 
104  CartesianVector firstCoordinate(0.f, 0.f, 0.f);
105  CartesianVector secondCoordinate(0.f, 0.f, 0.f);
106  LArClusterHelper::GetExtremalCoordinates(pDaughterCluster, firstCoordinate, secondCoordinate);
107 
108  float firstL(0.f), firstT(0.f), secondT(0.f), secondL(0.f);
109  LArPointingClusterHelper::GetImpactParameters(pointingVertex, firstCoordinate, firstL, firstT);
110  LArPointingClusterHelper::GetImpactParameters(pointingVertex, secondCoordinate, secondL, secondT);
111 
112  const float innerL(firstL < secondL ? firstL : secondL);
113  const float innerT(firstL < secondL ? firstT : secondT);
114  const float outerL(firstL > secondL ? firstL : secondL);
115  const float outerT(firstL > secondL ? firstT : secondT);
116 
117  if (innerL > 0.f && innerL < 2.5f && outerL < m_maxLongitudinalDisplacement && innerT < m_maxTransverseDisplacement &&
118  outerT < 1.5f * m_maxTransverseDisplacement)
119  {
120  associationType = ClusterAssociation::STRONG;
121  figureOfMerit = outerL;
122  }
123 
124  (void)clusterAssociationMatrix[pParentCluster].insert(
125  ClusterAssociationMap::value_type(pDaughterCluster, ClusterAssociation(vertexType, vertexType, associationType, figureOfMerit)));
126  }
127 }
128 
129 //------------------------------------------------------------------------------------------------------------------------------------------
130 
131 void TransverseExtensionAlgorithm::FillClusterMergeMap(const ClusterAssociationMatrix &parentToDaughterMatrix, ClusterMergeMap &clusterMergeMap) const
132 {
133  ClusterAssociationMatrix daughterToParentMatrix;
134 
135  // Loop over parent clusters and select nearby daughter clusters that are closer than another parent cluster
136  ClusterVector sortedParentClusters;
137  for (const auto &mapEntry : parentToDaughterMatrix)
138  sortedParentClusters.push_back(mapEntry.first);
139  std::sort(sortedParentClusters.begin(), sortedParentClusters.end(), LArClusterHelper::SortByNHits);
140 
141  for (const Cluster *const pParentCluster : sortedParentClusters)
142  {
143  const ClusterAssociationMap &daughterToAssociationMap(parentToDaughterMatrix.at(pParentCluster));
144 
145  float maxDisplacementInner(std::numeric_limits<float>::max());
146  float maxDisplacementOuter(std::numeric_limits<float>::max());
147 
148  // Find the nearest parent cluster
149  ClusterVector sortedLocalDaughterClusters;
150  for (const auto &mapEntry : daughterToAssociationMap)
151  sortedLocalDaughterClusters.push_back(mapEntry.first);
152  std::sort(sortedLocalDaughterClusters.begin(), sortedLocalDaughterClusters.end(), LArClusterHelper::SortByNHits);
153 
154  for (const Cluster *const pDaughterCluster : sortedLocalDaughterClusters)
155  {
156  const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
157 
158  if (clusterAssociation.GetAssociation() == ClusterAssociation::WEAK)
159  {
160  if (clusterAssociation.GetParent() == ClusterAssociation::INNER && clusterAssociation.GetFigureOfMerit() < maxDisplacementInner)
161  maxDisplacementInner = clusterAssociation.GetFigureOfMerit();
162 
163  if (clusterAssociation.GetParent() == ClusterAssociation::OUTER && clusterAssociation.GetFigureOfMerit() < maxDisplacementOuter)
164  maxDisplacementOuter = clusterAssociation.GetFigureOfMerit();
165  }
166  }
167 
168  // Select daughter clusters that are closer than the nearest parent cluster
169  for (const Cluster *const pDaughterCluster : sortedLocalDaughterClusters)
170  {
171  const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
172 
173  if (clusterAssociation.GetAssociation() == ClusterAssociation::STRONG)
174  {
175  if (clusterAssociation.GetParent() == ClusterAssociation::INNER && clusterAssociation.GetFigureOfMerit() < maxDisplacementInner)
176  (void)daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
177 
178  if (clusterAssociation.GetParent() == ClusterAssociation::OUTER && clusterAssociation.GetFigureOfMerit() < maxDisplacementOuter)
179  (void)daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
180  }
181  }
182  }
183 
184  // Loop over daughter clusters and select the nearest parent clusters
185  ClusterVector sortedDaughterClusters;
186  for (const auto &mapEntry : daughterToParentMatrix)
187  sortedDaughterClusters.push_back(mapEntry.first);
188  std::sort(sortedDaughterClusters.begin(), sortedDaughterClusters.end(), LArClusterHelper::SortByNHits);
189 
190  // Loop over parent clusters and select nearby daughter clusters that are closer than another parent cluster
191  for (const Cluster *const pDaughterCluster : sortedDaughterClusters)
192  {
193  const ClusterAssociationMap &parentToAssociationMap(daughterToParentMatrix.at(pDaughterCluster));
194 
195  const Cluster *pParentCluster(nullptr);
196  float minDisplacement(std::numeric_limits<float>::max());
197 
198  ClusterVector sortedLocalParentClusters;
199  for (const auto &mapEntry : parentToAssociationMap)
200  sortedLocalParentClusters.push_back(mapEntry.first);
201  std::sort(sortedLocalParentClusters.begin(), sortedLocalParentClusters.end(), LArClusterHelper::SortByNHits);
202 
203  for (const Cluster *const pCandidateParentCluster : sortedLocalParentClusters)
204  {
205  const ClusterAssociation &clusterAssociation(parentToAssociationMap.at(pCandidateParentCluster));
206 
207  if (clusterAssociation.GetFigureOfMerit() < minDisplacement)
208  {
209  minDisplacement = clusterAssociation.GetFigureOfMerit();
210  pParentCluster = pCandidateParentCluster;
211  }
212  }
213 
214  if (pParentCluster)
215  {
216  ClusterList &parentList(clusterMergeMap[pParentCluster]);
217 
218  if (parentList.end() == std::find(parentList.begin(), parentList.end(), pDaughterCluster))
219  parentList.push_back(pDaughterCluster);
220 
221  ClusterList &daughterList(clusterMergeMap[pDaughterCluster]);
222 
223  if (daughterList.end() == std::find(daughterList.begin(), daughterList.end(), pParentCluster))
224  daughterList.push_back(pParentCluster);
225  }
226  }
227 }
228 
229 //------------------------------------------------------------------------------------------------------------------------------------------
230 
231 StatusCode TransverseExtensionAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
232 {
233  PANDORA_RETURN_RESULT_IF_AND_IF(
234  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLength", m_minClusterLength));
235 
236  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
237  XmlHelper::ReadValue(xmlHandle, "MaxLongitudinalDisplacement", m_maxLongitudinalDisplacement));
238 
239  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
240  XmlHelper::ReadValue(xmlHandle, "MaxTransverseDisplacement", m_maxTransverseDisplacement));
241 
242  return ClusterExtensionAlgorithm::ReadSettings(xmlHandle);
243 }
244 
245 } // namespace lar_content
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.
std::vector< LArPointingCluster > LArPointingClusterList
static void GetImpactParameters(const LArPointingCluster::Vertex &pointingVertex, const LArPointingCluster::Vertex &targetVertex, float &longitudinal, float &transverse)
Calculate impact parameters between a pair of pointing vertices.
intermediate_table::const_iterator const_iterator
void FillClusterAssociationMatrix(const pandora::ClusterVector &clusterVector, ClusterAssociationMatrix &clusterAssociationMatrix) const
Fill the cluster association matrix.
LArPointingCluster class.
void FillClusterMergeMap(const ClusterAssociationMatrix &clusterAssociationMatrix, ClusterMergeMap &clusterMergeMap) const
Fill the cluster merge map.
const pandora::Cluster * GetCluster() const
Get the address of the cluster.
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with subset of cluster list, containing clusters judged to be clean...
std::unordered_map< const pandora::Cluster *, ClusterAssociationMap > ClusterAssociationMatrix
static int max(int a, int b)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z) ...
Header file for the transverse extension algorithm class.
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
std::vector< art::Ptr< recob::Cluster > > ClusterVector
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.