All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ClearShowersTool.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArShowerMatching/ClearShowersTool.cc
3  *
4  * @brief Implementation of the clear showers tool class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
13 using namespace pandora;
14 
15 namespace lar_content
16 {
17 
18 ClearShowersTool::ClearShowersTool() :
19  m_minMatchedFraction(0.2f),
20  m_minMatchedSamplingPoints(40),
21  m_minXOverlapFraction(0.5f),
22  m_minMatchedSamplingPointRatio(3),
23  m_minXOverlapSpanRatio(3.f),
24  m_visualize(false)
25 {
26 }
27 
28 //------------------------------------------------------------------------------------------------------------------------------------------
29 
30 bool ClearShowersTool::HasLargeDirectConnections(IteratorList::const_iterator iIter, const IteratorList &iteratorList)
31 {
32  for (IteratorList::const_iterator iIter2 = iteratorList.begin(), iIter2End = iteratorList.end(); iIter2 != iIter2End; ++iIter2)
33  {
34  if (iIter == iIter2)
35  continue;
36 
37  if (((*iIter)->GetClusterU() == (*iIter2)->GetClusterU()) || ((*iIter)->GetClusterV() == (*iIter2)->GetClusterV()) ||
38  ((*iIter)->GetClusterW() == (*iIter2)->GetClusterW()))
39  return true;
40  }
41 
42  return false;
43 }
44 
45 //------------------------------------------------------------------------------------------------------------------------------------------
46 
47 bool ClearShowersTool::IsLargerThanDirectConnections(IteratorList::const_iterator iIter, const TensorType::ElementList &elementList,
48  const unsigned int minMatchedSamplingPointRatio, const float minXOverlapSpanRatio, const ClusterSet &usedClusters)
49 {
50  const unsigned int nMatchedSamplingPoints((*iIter)->GetOverlapResult().GetNMatchedSamplingPoints());
51  const unsigned int xOverlapSpan((*iIter)->GetOverlapResult().GetXOverlap().GetXOverlapSpan());
52 
53  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
54  {
55  if ((*iIter) == eIter)
56  continue;
57 
58  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
59  continue;
60 
61  if (((*iIter)->GetClusterU() != eIter->GetClusterU()) && ((*iIter)->GetClusterV() != eIter->GetClusterV()) &&
62  ((*iIter)->GetClusterW() != eIter->GetClusterW()))
63  continue;
64 
65  if (nMatchedSamplingPoints < minMatchedSamplingPointRatio * eIter->GetOverlapResult().GetNMatchedSamplingPoints())
66  return false;
67 
68  if (xOverlapSpan < minXOverlapSpanRatio * eIter->GetOverlapResult().GetXOverlap().GetXOverlapSpan())
69  return false;
70  }
71 
72  return true;
73 }
74 
75 //------------------------------------------------------------------------------------------------------------------------------------------
76 
77 bool ClearShowersTool::Run(ThreeViewShowersAlgorithm *const pAlgorithm, TensorType &overlapTensor)
78 {
79  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
80  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
81 
82  ProtoParticleVector protoParticleVector;
83  this->FindClearShowers(overlapTensor, protoParticleVector);
84 
85  const bool particlesMade(pAlgorithm->CreateThreeDParticles(protoParticleVector));
86  return particlesMade;
87 }
88 
89 //------------------------------------------------------------------------------------------------------------------------------------------
90 
91 void ClearShowersTool::FindClearShowers(const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector) const
92 {
93  ClusterSet usedClusters;
94  ClusterVector sortedKeyClusters;
95  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
96 
97  for (const Cluster *const pKeyCluster : sortedKeyClusters)
98  {
99  if (!pKeyCluster->IsAvailable())
100  continue;
101 
102  unsigned int nU(0), nV(0), nW(0);
103  TensorType::ElementList elementList;
104  overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
105 
106  IteratorList iteratorList;
107  this->SelectLargeShowerElements(elementList, usedClusters, iteratorList);
108 
109  // Check that elements are not directly connected and are significantly longer than any other directly connected elements
110  for (IteratorList::const_iterator iIter = iteratorList.begin(), iIterEnd = iteratorList.end(); iIter != iIterEnd; ++iIter)
111  {
112  if (ClearShowersTool::HasLargeDirectConnections(iIter, iteratorList))
113  continue;
114 
116  continue;
117 
118  if (m_visualize)
119  {
120  ClusterList clusterList{(*iIter)->GetClusterU(), (*iIter)->GetClusterV(), (*iIter)->GetClusterW()};
121  PANDORA_MONITORING_API(VisualizeClusters(this->GetPandora(), &clusterList, "Selected", BLUE));
122  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
123  }
124 
125  ProtoParticle protoParticle;
126  protoParticle.m_clusterList.push_back((*iIter)->GetClusterU());
127  protoParticle.m_clusterList.push_back((*iIter)->GetClusterV());
128  protoParticle.m_clusterList.push_back((*iIter)->GetClusterW());
129  protoParticleVector.push_back(protoParticle);
130 
131  usedClusters.insert((*iIter)->GetClusterU());
132  usedClusters.insert((*iIter)->GetClusterV());
133  usedClusters.insert((*iIter)->GetClusterW());
134  }
135  }
136 }
137 
138 //------------------------------------------------------------------------------------------------------------------------------------------
139 
141  const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
142 {
143  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
144  {
145  if (m_visualize)
146  {
147  ClusterList clusterList{eIter->GetClusterU(), eIter->GetClusterV(), eIter->GetClusterW()};
148  PANDORA_MONITORING_API(VisualizeClusters(this->GetPandora(), &clusterList, "Considered", RED));
149  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
150  }
151 
152  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
153  continue;
154 
155  if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
156  continue;
157 
158  if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
159  continue;
160 
161  const XOverlap &xOverlap(eIter->GetOverlapResult().GetXOverlap());
162 
163  if ((xOverlap.GetXSpanU() > std::numeric_limits<float>::epsilon()) && (xOverlap.GetXOverlapSpan() / xOverlap.GetXSpanU() > m_minXOverlapFraction) &&
164  (xOverlap.GetXSpanV() > std::numeric_limits<float>::epsilon()) && (xOverlap.GetXOverlapSpan() / xOverlap.GetXSpanV() > m_minXOverlapFraction) &&
165  (xOverlap.GetXSpanW() > std::numeric_limits<float>::epsilon()) && (xOverlap.GetXOverlapSpan() / xOverlap.GetXSpanW() > m_minXOverlapFraction))
166  {
167  iteratorList.push_back(eIter);
168  if (m_visualize)
169  {
170  ClusterList clusterList{eIter->GetClusterU(), eIter->GetClusterV(), eIter->GetClusterW()};
171  PANDORA_MONITORING_API(VisualizeClusters(this->GetPandora(), &clusterList, "Large", GREEN));
172  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
173  }
174  }
175  }
176 }
177 
178 //------------------------------------------------------------------------------------------------------------------------------------------
179 
180 StatusCode ClearShowersTool::ReadSettings(const TiXmlHandle xmlHandle)
181 {
182  PANDORA_RETURN_RESULT_IF_AND_IF(
183  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
184 
185  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
186  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
187 
188  PANDORA_RETURN_RESULT_IF_AND_IF(
189  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinXOverlapFraction", m_minXOverlapFraction));
190 
191  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
192  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPointRatio", m_minMatchedSamplingPointRatio));
193 
194  PANDORA_RETURN_RESULT_IF_AND_IF(
195  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinXOverlapSpanRatio", m_minXOverlapSpanRatio));
196 
197  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Visualize", m_visualize));
198 
199  return STATUS_CODE_SUCCESS;
200 }
201 
202 } // namespace lar_content
std::vector< ProtoParticle > ProtoParticleVector
void FindClearShowers(const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector) const
Find clear shower matches, hidden by simple ambiguities in the tensor.
static bool IsLargerThanDirectConnections(IteratorList::const_iterator iIter, const TensorType::ElementList &elementList, const unsigned int minMatchedSamplingPointRatio, const float minXOverlapSpanRatio, const pandora::ClusterSet &usedClusters)
Whether a large shower-like element is significantly larger that other elements with which it shares ...
Header file for the clear showers tool class.
void SelectLargeShowerElements(const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select a list of large shower-like elements from a set of connected tensor elements.
float m_minMatchedFraction
The min matched sampling point fraction for particle creation.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
float m_minXOverlapSpanRatio
The min ratio between 1st and 2nd highest x-overlap spans for simple ambiguity resolution.
std::vector< TensorType::ElementList::const_iterator > IteratorList
static bool HasLargeDirectConnections(IteratorList::const_iterator iIter, const IteratorList &iteratorList)
Whether a large shower-like element shares clusters with any other long elements. ...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::ClusterList m_clusterList
List of 2D clusters in a 3D proto particle.
bool Run(ThreeViewShowersAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
Definition: reco_sbnd.fcl:182
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for particle creation.
float m_minXOverlapFraction
The min x overlap fraction (in each view) for particle creation.
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
XOverlap class.
Definition: LArXOverlap.h:17
bool m_visualize
Visualize cluster split locations.
BEGIN_PROLOG could also be cout
unsigned int m_minMatchedSamplingPointRatio
The min ratio between 1st and 2nd highest msps for simple ambiguity resolution.