LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TransverseExtensionAlgorithm.cc
Go to the documentation of this file.
1 
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 
80 void TransverseExtensionAlgorithm::FillClusterAssociationMatrix(const LArPointingCluster &pointingCluster, const Cluster* const pDaughterCluster, ClusterAssociationMatrix &clusterAssociationMatrix) const
81 {
82  const Cluster *const pParentCluster(pointingCluster.GetCluster());
83 
84  if (pParentCluster == pDaughterCluster)
85  return;
86 
87  for (unsigned int useInner = 0; useInner < 2; ++useInner)
88  {
89  const LArPointingCluster::Vertex &pointingVertex(useInner==1 ? pointingCluster.GetInnerVertex() : pointingCluster.GetOuterVertex());
91 
92  if (pointingVertex.GetRms() > 0.5f)
93  continue;
94 
95  const float projectedDisplacement(LArClusterHelper::GetClosestDistance(pointingVertex.GetPosition(), pDaughterCluster));
96 
97  if (projectedDisplacement > m_maxLongitudinalDisplacement)
98  continue;
99 
101  float figureOfMerit(projectedDisplacement);
102 
103  CartesianVector firstCoordinate(0.f, 0.f, 0.f);
104  CartesianVector secondCoordinate(0.f, 0.f, 0.f);
105  LArClusterHelper::GetExtremalCoordinates(pDaughterCluster, firstCoordinate, secondCoordinate);
106 
107  float firstL(0.f), firstT(0.f), secondT(0.f), secondL(0.f);
108  LArPointingClusterHelper::GetImpactParameters(pointingVertex, firstCoordinate, firstL, firstT);
109  LArPointingClusterHelper::GetImpactParameters(pointingVertex, secondCoordinate, secondL, secondT);
110 
111  const float innerL(firstL < secondL ? firstL : secondL);
112  const float innerT(firstL < secondL ? firstT : secondT);
113  const float outerL(firstL > secondL ? firstL : secondL);
114  const float outerT(firstL > secondL ? firstT : secondT);
115 
116  if (innerL > 0.f && innerL < 2.5f && outerL < m_maxLongitudinalDisplacement &&
118  {
119  associationType = ClusterAssociation::STRONG;
120  figureOfMerit = outerL;
121  }
122 
123  (void) clusterAssociationMatrix[pParentCluster].insert(ClusterAssociationMap::value_type(pDaughterCluster,
124  ClusterAssociation(vertexType, vertexType, associationType, figureOfMerit)));
125  }
126 }
127 
128 //------------------------------------------------------------------------------------------------------------------------------------------
129 
130 void TransverseExtensionAlgorithm::FillClusterMergeMap(const ClusterAssociationMatrix &parentToDaughterMatrix, ClusterMergeMap &clusterMergeMap) const
131 {
132  ClusterAssociationMatrix daughterToParentMatrix;
133 
134  // Loop over parent clusters and select nearby daughter clusters that are closer than another parent cluster
135  ClusterVector sortedParentClusters;
136  for (const auto &mapEntry : parentToDaughterMatrix) sortedParentClusters.push_back(mapEntry.first);
137  std::sort(sortedParentClusters.begin(), sortedParentClusters.end(), LArClusterHelper::SortByNHits);
138 
139  for (const Cluster *const pParentCluster : sortedParentClusters)
140  {
141  const ClusterAssociationMap &daughterToAssociationMap(parentToDaughterMatrix.at(pParentCluster));
142 
143  float maxDisplacementInner(std::numeric_limits<float>::max());
144  float maxDisplacementOuter(std::numeric_limits<float>::max());
145 
146  // Find the nearest parent cluster
147  ClusterVector sortedLocalDaughterClusters;
148  for (const auto &mapEntry : daughterToAssociationMap) sortedLocalDaughterClusters.push_back(mapEntry.first);
149  std::sort(sortedLocalDaughterClusters.begin(), sortedLocalDaughterClusters.end(), LArClusterHelper::SortByNHits);
150 
151  for (const Cluster *const pDaughterCluster : sortedLocalDaughterClusters)
152  {
153  const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
154 
155  if (clusterAssociation.GetAssociation() == ClusterAssociation::WEAK)
156  {
157  if (clusterAssociation.GetParent() == ClusterAssociation::INNER && clusterAssociation.GetFigureOfMerit() < maxDisplacementInner)
158  maxDisplacementInner = clusterAssociation.GetFigureOfMerit();
159 
160  if (clusterAssociation.GetParent() == ClusterAssociation::OUTER && clusterAssociation.GetFigureOfMerit() < maxDisplacementOuter)
161  maxDisplacementOuter = clusterAssociation.GetFigureOfMerit();
162  }
163  }
164 
165  // Select daughter clusters that are closer than the nearest parent cluster
166  for (const Cluster *const pDaughterCluster : sortedLocalDaughterClusters)
167  {
168  const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
169 
170  if (clusterAssociation.GetAssociation() == ClusterAssociation::STRONG)
171  {
172  if (clusterAssociation.GetParent() == ClusterAssociation::INNER && clusterAssociation.GetFigureOfMerit() < maxDisplacementInner)
173  (void) daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
174 
175  if (clusterAssociation.GetParent() == ClusterAssociation::OUTER && clusterAssociation.GetFigureOfMerit() < maxDisplacementOuter)
176  (void) daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
177  }
178  }
179  }
180 
181  // Loop over daughter clusters and select the nearest parent clusters
182  ClusterVector sortedDaughterClusters;
183  for (const auto &mapEntry : daughterToParentMatrix) sortedDaughterClusters.push_back(mapEntry.first);
184  std::sort(sortedDaughterClusters.begin(), sortedDaughterClusters.end(), LArClusterHelper::SortByNHits);
185 
186  // Loop over parent clusters and select nearby daughter clusters that are closer than another parent cluster
187  for (const Cluster *const pDaughterCluster : sortedDaughterClusters)
188  {
189  const ClusterAssociationMap &parentToAssociationMap(daughterToParentMatrix.at(pDaughterCluster));
190 
191  const Cluster *pParentCluster(nullptr);
192  float minDisplacement(std::numeric_limits<float>::max());
193 
194  ClusterVector sortedLocalParentClusters;
195  for (const auto &mapEntry : parentToAssociationMap) sortedLocalParentClusters.push_back(mapEntry.first);
196  std::sort(sortedLocalParentClusters.begin(), sortedLocalParentClusters.end(), LArClusterHelper::SortByNHits);
197 
198  for (const Cluster *const pCandidateParentCluster : sortedLocalParentClusters)
199  {
200  const ClusterAssociation &clusterAssociation(parentToAssociationMap.at(pCandidateParentCluster));
201 
202  if (clusterAssociation.GetFigureOfMerit() < minDisplacement)
203  {
204  minDisplacement = clusterAssociation.GetFigureOfMerit();
205  pParentCluster = pCandidateParentCluster;
206  }
207  }
208 
209  if (pParentCluster)
210  {
211  ClusterList &parentList(clusterMergeMap[pParentCluster]);
212 
213  if (parentList.end() == std::find(parentList.begin(), parentList.end(), pDaughterCluster))
214  parentList.push_back(pDaughterCluster);
215 
216  ClusterList &daughterList(clusterMergeMap[pDaughterCluster]);
217 
218  if (daughterList.end() == std::find(daughterList.begin(), daughterList.end(), pParentCluster))
219  daughterList.push_back(pParentCluster);
220  }
221  }
222 }
223 
224 //------------------------------------------------------------------------------------------------------------------------------------------
225 
226 StatusCode TransverseExtensionAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
227 {
228  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
229  "MinClusterLength", m_minClusterLength));
230 
231  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
232  "MaxLongitudinalDisplacement", m_maxLongitudinalDisplacement));
233 
234  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
235  "MaxTransverseDisplacement", m_maxTransverseDisplacement));
236 
237  return ClusterExtensionAlgorithm::ReadSettings(xmlHandle);
238 }
239 
240 } // 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::unordered_map< const pandora::Cluster *, ClusterAssociationMap > ClusterAssociationMatrix
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.
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.
TFile f
Definition: plotHisto.C:6
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
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...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::vector< art::Ptr< recob::Cluster > > ClusterVector
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
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.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.