LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
TransverseExtensionAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
14 
16 
17 using namespace pandora;
18 
19 namespace lar_content
20 {
21 
22 TransverseExtensionAlgorithm::TransverseExtensionAlgorithm() :
23  m_minClusterLength(5.f),
24  m_maxLongitudinalDisplacement(10.f),
25  m_maxTransverseDisplacement(1.f)
26 {
27 }
28 
29 //------------------------------------------------------------------------------------------------------------------------------------------
30 
31 void TransverseExtensionAlgorithm::GetListOfCleanClusters(const ClusterList *const pClusterList, ClusterVector &clusterVector) const
32 {
33  for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
34  clusterVector.push_back(*iter);
35 
36  std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
37 }
38 
39 //------------------------------------------------------------------------------------------------------------------------------------------
40 
41 void TransverseExtensionAlgorithm::FillClusterAssociationMatrix(const ClusterVector &clusterVector, ClusterAssociationMatrix &clusterAssociationMatrix) const
42 {
43  // Convert long clusters into pointing clusters
44  LArPointingClusterList pointingClusterList;
45 
46  for (ClusterVector::const_iterator iter = clusterVector.begin(), iterEnd = clusterVector.end(); iter != iterEnd; ++iter)
47  {
48  const Cluster *const pCluster(*iter);
49 
51  continue;
52 
53  try
54  {
55  pointingClusterList.push_back(LArPointingCluster(*iter));
56  }
57  catch (StatusCodeException &)
58  {
59  }
60  }
61 
62  // Form associations between clusters
63  for (LArPointingClusterList::const_iterator iter1 = pointingClusterList.begin(), iterEnd1 = pointingClusterList.end(); iter1 != iterEnd1; ++iter1)
64  {
65  const LArPointingCluster &parentCluster = *iter1;
66 
67  for (ClusterVector::const_iterator iter2 = clusterVector.begin(), iterEnd2 = clusterVector.end(); iter2 != iterEnd2; ++iter2)
68  {
69  const Cluster *const pDaughterCluster(*iter2);
70 
71  if (parentCluster.GetCluster() == pDaughterCluster)
72  continue;
73 
74  this->FillClusterAssociationMatrix(parentCluster, pDaughterCluster, clusterAssociationMatrix);
75  }
76  }
77 }
78 
79 //------------------------------------------------------------------------------------------------------------------------------------------
80 
82  const Cluster *const pDaughterCluster, ClusterAssociationMatrix &clusterAssociationMatrix) const
83 {
84  const Cluster *const pParentCluster(pointingCluster.GetCluster());
85 
86  if (pParentCluster == pDaughterCluster)
87  return;
88 
89  const float ratio{LArGeometryHelper::GetWirePitchRatio(this->GetPandora(), LArClusterHelper::GetClusterHitType(pParentCluster))};
90  const float maxLongitudinalDisplacementAdjusted{ratio * m_maxLongitudinalDisplacement};
91  const float maxTransverseDisplacementAdjusted{ratio * m_maxTransverseDisplacement};
92 
93  for (unsigned int useInner = 0; useInner < 2; ++useInner)
94  {
95  const LArPointingCluster::Vertex &pointingVertex(useInner == 1 ? pointingCluster.GetInnerVertex() : pointingCluster.GetOuterVertex());
97 
98  if (pointingVertex.GetRms() > 0.5f)
99  continue;
100 
101  const float projectedDisplacement(LArClusterHelper::GetClosestDistance(pointingVertex.GetPosition(), pDaughterCluster));
102 
103  if (projectedDisplacement > maxLongitudinalDisplacementAdjusted)
104  continue;
105 
107  float figureOfMerit(projectedDisplacement);
108 
109  CartesianVector firstCoordinate(0.f, 0.f, 0.f);
110  CartesianVector secondCoordinate(0.f, 0.f, 0.f);
111  LArClusterHelper::GetExtremalCoordinates(pDaughterCluster, firstCoordinate, secondCoordinate);
112 
113  float firstL(0.f), firstT(0.f), secondT(0.f), secondL(0.f);
114  LArPointingClusterHelper::GetImpactParameters(pointingVertex, firstCoordinate, firstL, firstT);
115  LArPointingClusterHelper::GetImpactParameters(pointingVertex, secondCoordinate, secondL, secondT);
116 
117  const float innerL(firstL < secondL ? firstL : secondL);
118  const float innerT(firstL < secondL ? firstT : secondT);
119  const float outerL(firstL > secondL ? firstL : secondL);
120  const float outerT(firstL > secondL ? firstT : secondT);
121 
122  if (innerL > 0.f && innerL < 2.5f && outerL < maxLongitudinalDisplacementAdjusted && innerT < maxTransverseDisplacementAdjusted &&
123  outerT < 1.5f * maxTransverseDisplacementAdjusted)
124  {
125  associationType = ClusterAssociation::STRONG;
126  figureOfMerit = outerL;
127  }
128 
129  (void)clusterAssociationMatrix[pParentCluster].insert(
130  ClusterAssociationMap::value_type(pDaughterCluster, ClusterAssociation(vertexType, vertexType, associationType, figureOfMerit)));
131  }
132 }
133 
134 //------------------------------------------------------------------------------------------------------------------------------------------
135 
136 void TransverseExtensionAlgorithm::FillClusterMergeMap(const ClusterAssociationMatrix &parentToDaughterMatrix, ClusterMergeMap &clusterMergeMap) const
137 {
138  ClusterAssociationMatrix daughterToParentMatrix;
139 
140  // Loop over parent clusters and select nearby daughter clusters that are closer than another parent cluster
141  ClusterVector sortedParentClusters;
142  for (const auto &mapEntry : parentToDaughterMatrix)
143  sortedParentClusters.push_back(mapEntry.first);
144  std::sort(sortedParentClusters.begin(), sortedParentClusters.end(), LArClusterHelper::SortByNHits);
145 
146  for (const Cluster *const pParentCluster : sortedParentClusters)
147  {
148  const ClusterAssociationMap &daughterToAssociationMap(parentToDaughterMatrix.at(pParentCluster));
149 
150  float maxDisplacementInner(std::numeric_limits<float>::max());
151  float maxDisplacementOuter(std::numeric_limits<float>::max());
152 
153  // Find the nearest parent cluster
154  ClusterVector sortedLocalDaughterClusters;
155  for (const auto &mapEntry : daughterToAssociationMap)
156  sortedLocalDaughterClusters.push_back(mapEntry.first);
157  std::sort(sortedLocalDaughterClusters.begin(), sortedLocalDaughterClusters.end(), LArClusterHelper::SortByNHits);
158 
159  for (const Cluster *const pDaughterCluster : sortedLocalDaughterClusters)
160  {
161  const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
162 
163  if (clusterAssociation.GetAssociation() == ClusterAssociation::WEAK)
164  {
165  if (clusterAssociation.GetParent() == ClusterAssociation::INNER && clusterAssociation.GetFigureOfMerit() < maxDisplacementInner)
166  maxDisplacementInner = clusterAssociation.GetFigureOfMerit();
167 
168  if (clusterAssociation.GetParent() == ClusterAssociation::OUTER && clusterAssociation.GetFigureOfMerit() < maxDisplacementOuter)
169  maxDisplacementOuter = clusterAssociation.GetFigureOfMerit();
170  }
171  }
172 
173  // Select daughter clusters that are closer than the nearest parent cluster
174  for (const Cluster *const pDaughterCluster : sortedLocalDaughterClusters)
175  {
176  const ClusterAssociation &clusterAssociation(daughterToAssociationMap.at(pDaughterCluster));
177 
178  if (clusterAssociation.GetAssociation() == ClusterAssociation::STRONG)
179  {
180  if (clusterAssociation.GetParent() == ClusterAssociation::INNER && clusterAssociation.GetFigureOfMerit() < maxDisplacementInner)
181  (void)daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
182 
183  if (clusterAssociation.GetParent() == ClusterAssociation::OUTER && clusterAssociation.GetFigureOfMerit() < maxDisplacementOuter)
184  (void)daughterToParentMatrix[pDaughterCluster].insert(ClusterAssociationMap::value_type(pParentCluster, clusterAssociation));
185  }
186  }
187  }
188 
189  // Loop over daughter clusters and select the nearest parent clusters
190  ClusterVector sortedDaughterClusters;
191  for (const auto &mapEntry : daughterToParentMatrix)
192  sortedDaughterClusters.push_back(mapEntry.first);
193  std::sort(sortedDaughterClusters.begin(), sortedDaughterClusters.end(), LArClusterHelper::SortByNHits);
194 
195  // Loop over parent clusters and select nearby daughter clusters that are closer than another parent cluster
196  for (const Cluster *const pDaughterCluster : sortedDaughterClusters)
197  {
198  const ClusterAssociationMap &parentToAssociationMap(daughterToParentMatrix.at(pDaughterCluster));
199 
200  const Cluster *pParentCluster(nullptr);
201  float minDisplacement(std::numeric_limits<float>::max());
202 
203  ClusterVector sortedLocalParentClusters;
204  for (const auto &mapEntry : parentToAssociationMap)
205  sortedLocalParentClusters.push_back(mapEntry.first);
206  std::sort(sortedLocalParentClusters.begin(), sortedLocalParentClusters.end(), LArClusterHelper::SortByNHits);
207 
208  for (const Cluster *const pCandidateParentCluster : sortedLocalParentClusters)
209  {
210  const ClusterAssociation &clusterAssociation(parentToAssociationMap.at(pCandidateParentCluster));
211 
212  if (clusterAssociation.GetFigureOfMerit() < minDisplacement)
213  {
214  minDisplacement = clusterAssociation.GetFigureOfMerit();
215  pParentCluster = pCandidateParentCluster;
216  }
217  }
218 
219  if (pParentCluster)
220  {
221  ClusterList &parentList(clusterMergeMap[pParentCluster]);
222 
223  if (parentList.end() == std::find(parentList.begin(), parentList.end(), pDaughterCluster))
224  parentList.push_back(pDaughterCluster);
225 
226  ClusterList &daughterList(clusterMergeMap[pDaughterCluster]);
227 
228  if (daughterList.end() == std::find(daughterList.begin(), daughterList.end(), pParentCluster))
229  daughterList.push_back(pParentCluster);
230  }
231  }
232 }
233 
234 //------------------------------------------------------------------------------------------------------------------------------------------
235 
236 StatusCode TransverseExtensionAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
237 {
238  PANDORA_RETURN_RESULT_IF_AND_IF(
239  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLength", m_minClusterLength));
240 
241  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
242  XmlHelper::ReadValue(xmlHandle, "MaxLongitudinalDisplacement", m_maxLongitudinalDisplacement));
243 
244  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
245  XmlHelper::ReadValue(xmlHandle, "MaxTransverseDisplacement", m_maxTransverseDisplacement));
246 
247  return ClusterExtensionAlgorithm::ReadSettings(xmlHandle);
248 }
249 
250 } // 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.
static float GetWirePitchRatio(const pandora::Pandora &pandora, const pandora::HitType view)
Return the ratio of the wire pitch of the specified view to the minimum wire pitch for the detector...
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.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
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
Header file for the geometry helper class.
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
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.