BoundedClusterMopUpAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArTwoDReco/LArClusterMopUp/BoundedClusterMopUpAlgorithm.cc
3  *
4  * @brief Implementation of the bounded cluster mop up 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 BoundedClusterMopUpAlgorithm::BoundedClusterMopUpAlgorithm() :
22  m_slidingFitWindow(20),
23  m_showerEdgeMultiplier(1.5f),
24  m_minBoundedFraction(0.5f)
25 {
26 }
27 
28 //------------------------------------------------------------------------------------------------------------------------------------------
29 
30 void BoundedClusterMopUpAlgorithm::ClusterMopUp(const ClusterList &pfoClusters, const ClusterList &remnantClusters) const
31 {
32  ClusterAssociationMap clusterAssociationMap;
33  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
34 
35  ClusterVector sortedPfoClusters(pfoClusters.begin(), pfoClusters.end());
36  std::sort(sortedPfoClusters.begin(), sortedPfoClusters.end(), LArClusterHelper::SortByNHits);
37 
38  ClusterVector sortedRemnantClusters(remnantClusters.begin(), remnantClusters.end());
39  std::sort(sortedRemnantClusters.begin(), sortedRemnantClusters.end(), LArClusterHelper::SortByNHits);
40 
41  for (const Cluster *const pPfoCluster : sortedPfoClusters)
42  {
43  const TwoDSlidingShowerFitResult fitResult(pPfoCluster, m_slidingFitWindow, slidingFitPitch, m_showerEdgeMultiplier);
44 
45  ShowerPositionMap showerPositionMap;
46  const XSampling xSampling(fitResult.GetShowerFitResult());
47  this->GetShowerPositionMap(fitResult, xSampling, showerPositionMap);
48 
49  for (const Cluster *const pRemnantCluster : sortedRemnantClusters)
50  {
51  const float boundedFraction(this->GetBoundedFraction(pRemnantCluster, xSampling, showerPositionMap));
52 
53  if (boundedFraction < m_minBoundedFraction)
54  continue;
55 
56  AssociationDetails &associationDetails(clusterAssociationMap[pRemnantCluster]);
57 
58  if (!associationDetails.insert(AssociationDetails::value_type(pPfoCluster, boundedFraction)).second)
59  throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
60  }
61  }
62 
63  this->MakeClusterMerges(clusterAssociationMap);
64 }
65 
66 //------------------------------------------------------------------------------------------------------------------------------------------
67 
69  const TwoDSlidingShowerFitResult &fitResult, const XSampling &xSampling, ShowerPositionMap &showerPositionMap) const
70 {
71  for (int n = 0; n <= xSampling.m_nPoints; ++n)
72  {
73  const float x(xSampling.m_minX + (xSampling.m_maxX - xSampling.m_minX) * static_cast<float>(n) / static_cast<float>(xSampling.m_nPoints));
74 
75  FloatVector edgePositions;
76  fitResult.GetShowerEdges(x, false, edgePositions);
77 
78  if (edgePositions.size() < 2)
79  continue;
80 
81  std::sort(edgePositions.begin(), edgePositions.end());
82 
83  try
84  {
85  const int xBin(xSampling.GetBin(x));
86  showerPositionMap.insert(ShowerPositionMap::value_type(xBin, ShowerExtent(x, edgePositions.front(), edgePositions.back())));
87  }
88  catch (StatusCodeException &)
89  {
90  }
91  }
92 }
93 
94 //------------------------------------------------------------------------------------------------------------------------------------------
95 
97  const Cluster *const pCluster, const XSampling &xSampling, const ShowerPositionMap &showerPositionMap) const
98 {
99  if (((xSampling.m_maxX - xSampling.m_minX) < std::numeric_limits<float>::epsilon()) || (0 >= xSampling.m_nPoints) || (0 == pCluster->GetNCaloHits()))
100  {
101  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
102  }
103 
104  unsigned int nMatchedHits(0);
105  const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
106 
107  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
108  {
109  for (CaloHitList::const_iterator hIter = iter->second->begin(), hIterEnd = iter->second->end(); hIter != hIterEnd; ++hIter)
110  {
111  const CaloHit *const pCaloHit = *hIter;
112  const float x(pCaloHit->GetPositionVector().GetX());
113  const float z(pCaloHit->GetPositionVector().GetZ());
114 
115  try
116  {
117  const int xBin(xSampling.GetBin(x));
118 
119  ShowerPositionMap::const_iterator positionIter = showerPositionMap.find(xBin);
120 
121  if ((showerPositionMap.end() != positionIter) && (z > positionIter->second.GetLowEdgeZ()) && (z < positionIter->second.GetHighEdgeZ()))
122  ++nMatchedHits;
123  }
124  catch (StatusCodeException &)
125  {
126  }
127  }
128  }
129 
130  return (static_cast<float>(nMatchedHits) / static_cast<float>(pCluster->GetNCaloHits()));
131 }
132 
133 //------------------------------------------------------------------------------------------------------------------------------------------
134 //------------------------------------------------------------------------------------------------------------------------------------------
135 
137 {
138  fitResult.GetMinAndMaxX(m_minX, m_maxX);
139 
140  m_nPoints = 1 + fitResult.GetMaxLayer() - fitResult.GetMinLayer();
141 
142  if (((m_maxX - m_minX) < std::numeric_limits<float>::epsilon()) || (0 >= m_nPoints))
143  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
144 }
145 
146 //------------------------------------------------------------------------------------------------------------------------------------------
147 
149 {
150  if (((x - m_minX) < -std::numeric_limits<float>::epsilon()) || ((x - m_maxX) > +std::numeric_limits<float>::epsilon()))
151  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
152 
153  return static_cast<int>(0.5f + static_cast<float>(m_nPoints) * (x - m_minX) / (m_maxX - m_minX));
154 }
155 
156 //------------------------------------------------------------------------------------------------------------------------------------------
157 //------------------------------------------------------------------------------------------------------------------------------------------
158 
159 StatusCode BoundedClusterMopUpAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
160 {
161  PANDORA_RETURN_RESULT_IF_AND_IF(
162  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitWindow", m_slidingFitWindow));
163 
164  PANDORA_RETURN_RESULT_IF_AND_IF(
165  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ShowerEdgeMultiplier", m_showerEdgeMultiplier));
166 
167  PANDORA_RETURN_RESULT_IF_AND_IF(
168  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinBoundedFraction", m_minBoundedFraction));
169 
170  return ClusterMopUpBaseAlgorithm::ReadSettings(xmlHandle);
171 }
172 
173 } // 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.
virtual void MakeClusterMerges(const ClusterAssociationMap &clusterAssociationMap) const
Make the cluster merges specified in the cluster association map, using list name information in the ...
void GetMinAndMaxX(float &minX, float &maxX) const
Get the minimum and maximum x coordinates associated with the sliding fit.
XSampling(const TwoDSlidingFitResult &fitResult)
Constructor.
const TwoDSlidingFitResult & GetShowerFitResult() const
Get the sliding fit result for the full shower cluster.
Header file for the bounded cluster mop up algorithm class.
void ClusterMopUp(const pandora::ClusterList &pfoClusters, const pandora::ClusterList &remnantClusters) const
Cluster mop up for a single view. This function is responsible for instructing pandora to make cluste...
intermediate_table::const_iterator const_iterator
float m_minBoundedFraction
The minimum cluster bounded fraction for merging.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void GetShowerPositionMap(const TwoDSlidingShowerFitResult &fitResult, const XSampling &xSampling, ShowerPositionMap &showerPositionMap) const
Get the shower position map containing high and low edge z positions in bins of x.
std::unordered_map< const pandora::Cluster *, AssociationDetails > ClusterAssociationMap
Header file for the geometry helper class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::map< int, ShowerExtent > ShowerPositionMap
int GetBin(const float x) const
Convert an x position into a sampling bin.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
Header file for the cluster helper class.
std::void_t< T > n
float m_showerEdgeMultiplier
Artificially tune width of shower envelope so as to make it more/less inclusive.
float GetBoundedFraction(const pandora::Cluster *const pCluster, const XSampling &xSampling, const ShowerPositionMap &showerPositionMap) const
Get the fraction of hits in a cluster bounded by a specified shower position map. ...
std::unordered_map< const pandora::Cluster *, float > AssociationDetails
int m_nPoints
The number of sampling points to be used.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
list x
Definition: train.py:276
Dft::FloatVector FloatVector
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
void GetShowerEdges(const float x, const bool widenIfAmbiguity, pandora::FloatVector &edgePositions) const
Get the most appropriate shower edges at a given x coordinate.