LongTracksTool.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArTransverseTrackMatching/LongTracksTool.cc
3  *
4  * @brief Implementation of the long tracks 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 LongTracksTool::LongTracksTool() :
19  m_minMatchedFraction(0.9f),
20  m_minMatchedSamplingPoints(20),
21  m_minXOverlapFraction(0.9f),
22  m_minMatchedSamplingPointRatio(2)
23 {
24 }
25 
26 //------------------------------------------------------------------------------------------------------------------------------------------
27 
29 {
30  for (IteratorList::const_iterator iIter2 = iteratorList.begin(), iIter2End = iteratorList.end(); iIter2 != iIter2End; ++iIter2)
31  {
32  if (iIter == iIter2)
33  continue;
34 
35  if (((*iIter)->GetClusterU() == (*iIter2)->GetClusterU()) || ((*iIter)->GetClusterV() == (*iIter2)->GetClusterV()) ||
36  ((*iIter)->GetClusterW() == (*iIter2)->GetClusterW()))
37  return true;
38  }
39 
40  return false;
41 }
42 
43 //------------------------------------------------------------------------------------------------------------------------------------------
44 
46  const unsigned int minMatchedSamplingPointRatio, const pandora::ClusterSet &usedClusters)
47 {
48  const unsigned int nMatchedSamplingPoints((*iIter)->GetOverlapResult().GetNMatchedSamplingPoints());
49 
50  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
51  {
52  if ((*iIter) == eIter)
53  continue;
54 
55  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
56  continue;
57 
58  if (((*iIter)->GetClusterU() != eIter->GetClusterU()) && ((*iIter)->GetClusterV() != eIter->GetClusterV()) &&
59  ((*iIter)->GetClusterW() != eIter->GetClusterW()))
60  continue;
61 
62  if (nMatchedSamplingPoints < minMatchedSamplingPointRatio * eIter->GetOverlapResult().GetNMatchedSamplingPoints())
63  return false;
64  }
65 
66  return true;
67 }
68 
69 //------------------------------------------------------------------------------------------------------------------------------------------
70 
71 bool LongTracksTool::Run(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
72 {
73  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
74  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
75 
76  ProtoParticleVector protoParticleVector;
77  this->FindLongTracks(overlapTensor, protoParticleVector);
78 
79  const bool particlesMade(pAlgorithm->CreateThreeDParticles(protoParticleVector));
80  return particlesMade;
81 }
82 
83 //------------------------------------------------------------------------------------------------------------------------------------------
84 
85 void LongTracksTool::FindLongTracks(const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector) const
86 {
87  ClusterSet usedClusters;
88  ClusterVector sortedKeyClusters;
89  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
90 
91  for (const Cluster *const pKeyCluster : sortedKeyClusters)
92  {
93  if (!pKeyCluster->IsAvailable())
94  continue;
95 
96  unsigned int nU(0), nV(0), nW(0);
97  TensorType::ElementList elementList;
98  overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
99 
100  IteratorList iteratorList;
101  this->SelectLongElements(elementList, usedClusters, iteratorList);
102 
103  // Check that elements are not directly connected and are significantly longer than any other directly connected elements
104  for (IteratorList::const_iterator iIter = iteratorList.begin(), iIterEnd = iteratorList.end(); iIter != iIterEnd; ++iIter)
105  {
106  if (LongTracksTool::HasLongDirectConnections(iIter, iteratorList))
107  continue;
108 
110  continue;
111 
112  ProtoParticle protoParticle;
113  protoParticle.m_clusterList.push_back((*iIter)->GetClusterU());
114  protoParticle.m_clusterList.push_back((*iIter)->GetClusterV());
115  protoParticle.m_clusterList.push_back((*iIter)->GetClusterW());
116  protoParticleVector.push_back(protoParticle);
117 
118  usedClusters.insert((*iIter)->GetClusterU());
119  usedClusters.insert((*iIter)->GetClusterV());
120  usedClusters.insert((*iIter)->GetClusterW());
121  }
122  }
123 }
124 
125 //------------------------------------------------------------------------------------------------------------------------------------------
126 
127 void LongTracksTool::SelectLongElements(const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
128 {
129  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
130  {
131  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
132  continue;
133 
134  if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
135  continue;
136 
137  if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
138  continue;
139 
140  const XOverlap &xOverlap(eIter->GetOverlapResult().GetXOverlap());
141 
142  if ((xOverlap.GetXSpanU() > std::numeric_limits<float>::epsilon()) && (xOverlap.GetXOverlapSpan() / xOverlap.GetXSpanU() > m_minXOverlapFraction) &&
143  (xOverlap.GetXSpanV() > std::numeric_limits<float>::epsilon()) && (xOverlap.GetXOverlapSpan() / xOverlap.GetXSpanV() > m_minXOverlapFraction) &&
144  (xOverlap.GetXSpanW() > std::numeric_limits<float>::epsilon()) && (xOverlap.GetXOverlapSpan() / xOverlap.GetXSpanW() > m_minXOverlapFraction))
145  {
146  iteratorList.push_back(eIter);
147  }
148  }
149 }
150 
151 //------------------------------------------------------------------------------------------------------------------------------------------
152 
153 StatusCode LongTracksTool::ReadSettings(const TiXmlHandle xmlHandle)
154 {
155  PANDORA_RETURN_RESULT_IF_AND_IF(
156  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
157 
158  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
159  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
160 
161  PANDORA_RETURN_RESULT_IF_AND_IF(
162  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinXOverlapFraction", m_minXOverlapFraction));
163 
164  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
165  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPointRatio", m_minMatchedSamplingPointRatio));
166 
167  return STATUS_CODE_SUCCESS;
168 }
169 
170 } // namespace lar_content
std::vector< ProtoParticle > ProtoParticleVector
std::vector< TensorType::ElementList::const_iterator > IteratorList
static bool IsLongerThanDirectConnections(IteratorList::const_iterator iIter, const TensorType::ElementList &elementList, const unsigned int minMatchedSamplingPointRatio, const pandora::ClusterSet &usedClusters)
Whether a long element is significantly longer that other elements with which it shares a cluster...
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for particle creation.
unsigned int m_minMatchedSamplingPointRatio
The min ratio between 1st and 2nd highest msps for simple ambiguity resolution.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
intermediate_table::const_iterator const_iterator
bool Run(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
float m_minXOverlapFraction
The min x overlap fraction (in each view) for particle creation.
void FindLongTracks(const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector) const
Find long tracks, hidden by simple ambiguities in the tensor.
void SelectLongElements(const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select a list of long track-like elements from a set of connected tensor elements.
pandora::ClusterList m_clusterList
List of 2D clusters in a 3D proto particle.
Header file for the long tracks tool class.
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
float m_minMatchedFraction
The min matched sampling point fraction for particle creation.
static bool HasLongDirectConnections(IteratorList::const_iterator iIter, const IteratorList &iteratorList)
Whether a long element shares clusters with any other long elements.
XOverlap class.
Definition: LArXOverlap.h:17
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
QTextStream & endl(QTextStream &s)