LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
ThreeDTransverseTracksAlgorithm.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 ThreeDTransverseTracksAlgorithm::ThreeDTransverseTracksAlgorithm() :
22  m_nMaxTensorToolRepeats(1000),
23  m_maxFitSegmentIndex(50),
24  m_pseudoChi2Cut(3.f),
25  m_minSegmentMatchedFraction(0.1f),
26  m_minSegmentMatchedPoints(3),
27  m_minOverallMatchedFraction(0.5f),
28  m_minOverallMatchedPoints(10),
29  m_minSamplingPointsPerLayer(0.1f)
30 {
31 }
32 
33 //------------------------------------------------------------------------------------------------------------------------------------------
34 
35 void ThreeDTransverseTracksAlgorithm::CalculateOverlapResult(const Cluster *const pClusterU, const Cluster *const pClusterV, const Cluster *const pClusterW)
36 {
37  TransverseOverlapResult overlapResult;
38  PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->CalculateOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult));
39 
40  if (overlapResult.IsInitialized())
41  m_overlapTensor.SetOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult);
42 }
43 
44 //------------------------------------------------------------------------------------------------------------------------------------------
45 
46 StatusCode ThreeDTransverseTracksAlgorithm::CalculateOverlapResult(const Cluster *const pClusterU, const Cluster *const pClusterV, const Cluster *const pClusterW,
47  TransverseOverlapResult &overlapResult)
48 {
49  const TwoDSlidingFitResult &slidingFitResultU(this->GetCachedSlidingFitResult(pClusterU));
50  const TwoDSlidingFitResult &slidingFitResultV(this->GetCachedSlidingFitResult(pClusterV));
51  const TwoDSlidingFitResult &slidingFitResultW(this->GetCachedSlidingFitResult(pClusterW));
52 
53  FitSegmentTensor fitSegmentTensor;
54  this->GetFitSegmentTensor(slidingFitResultU, slidingFitResultV, slidingFitResultW, fitSegmentTensor);
55 
56  TransverseOverlapResult transverseOverlapResult;
57  this->GetBestOverlapResult(fitSegmentTensor, transverseOverlapResult);
58 
59  if (!transverseOverlapResult.IsInitialized())
60  return STATUS_CODE_NOT_FOUND;
61 
62  if ((transverseOverlapResult.GetMatchedFraction() < m_minOverallMatchedFraction) || (transverseOverlapResult.GetNMatchedSamplingPoints() < m_minOverallMatchedPoints))
63  return STATUS_CODE_NOT_FOUND;
64 
65  const int nLayersSpannedU(slidingFitResultU.GetMaxLayer() - slidingFitResultU.GetMinLayer());
66  const int nLayersSpannedV(slidingFitResultV.GetMaxLayer() - slidingFitResultV.GetMinLayer());
67  const int nLayersSpannedW(slidingFitResultW.GetMaxLayer() - slidingFitResultW.GetMinLayer());
68  const unsigned int meanLayersSpanned(static_cast<unsigned int>((1.f / 3.f) * static_cast<float>(nLayersSpannedU + nLayersSpannedV + nLayersSpannedW)));
69 
70  if (0 == meanLayersSpanned)
71  return STATUS_CODE_FAILURE;
72 
73  const float nSamplingPointsPerLayer(static_cast<float>(transverseOverlapResult.GetNSamplingPoints()) / static_cast<float>(meanLayersSpanned));
74 
75  if (nSamplingPointsPerLayer < m_minSamplingPointsPerLayer)
76  return STATUS_CODE_NOT_FOUND;
77 
78  overlapResult = transverseOverlapResult;
79  return STATUS_CODE_SUCCESS;
80 }
81 
82 //------------------------------------------------------------------------------------------------------------------------------------------
83 
85  const TwoDSlidingFitResult &slidingFitResultW, FitSegmentTensor &fitSegmentTensor) const
86 {
87  FitSegmentList fitSegmentListU(slidingFitResultU.GetFitSegmentList());
88  FitSegmentList fitSegmentListV(slidingFitResultV.GetFitSegmentList());
89  FitSegmentList fitSegmentListW(slidingFitResultW.GetFitSegmentList());
90 
91  for (unsigned int indexU = 0, indexUEnd = fitSegmentListU.size(); indexU < indexUEnd; ++indexU)
92  {
93  const FitSegment &fitSegmentU(fitSegmentListU.at(indexU));
94 
95  for (unsigned int indexV = 0, indexVEnd = fitSegmentListV.size(); indexV < indexVEnd; ++indexV)
96  {
97  const FitSegment &fitSegmentV(fitSegmentListV.at(indexV));
98 
99  for (unsigned int indexW = 0, indexWEnd = fitSegmentListW.size(); indexW < indexWEnd; ++indexW)
100  {
101  const FitSegment &fitSegmentW(fitSegmentListW.at(indexW));
102 
103  TransverseOverlapResult segmentOverlap;
104  if (STATUS_CODE_SUCCESS != this->GetSegmentOverlap(fitSegmentU, fitSegmentV, fitSegmentW, slidingFitResultU, slidingFitResultV, slidingFitResultW, segmentOverlap))
105  continue;
106 
107  if ((segmentOverlap.GetMatchedFraction() < m_minSegmentMatchedFraction) || (segmentOverlap.GetNMatchedSamplingPoints() < m_minSegmentMatchedPoints))
108  continue;
109 
110  fitSegmentTensor[indexU][indexV][indexW] = segmentOverlap;
111  }
112  }
113  }
114 }
115 
116 //------------------------------------------------------------------------------------------------------------------------------------------
117 
118 StatusCode ThreeDTransverseTracksAlgorithm::GetSegmentOverlap(const FitSegment &fitSegmentU, const FitSegment &fitSegmentV, const FitSegment &fitSegmentW,
119  const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV, const TwoDSlidingFitResult &slidingFitResultW,
120  TransverseOverlapResult &transverseOverlapResult) const
121 {
122  // Assess x-overlap
123  const float xSpanU(fitSegmentU.GetMaxX() - fitSegmentU.GetMinX());
124  const float xSpanV(fitSegmentV.GetMaxX() - fitSegmentV.GetMinX());
125  const float xSpanW(fitSegmentW.GetMaxX() - fitSegmentW.GetMinX());
126 
127  const float minX(std::max(fitSegmentU.GetMinX(), std::max(fitSegmentV.GetMinX(), fitSegmentW.GetMinX())));
128  const float maxX(std::min(fitSegmentU.GetMaxX(), std::min(fitSegmentV.GetMaxX(), fitSegmentW.GetMaxX())));
129  const float xOverlap(maxX - minX);
130 
131  if (xOverlap < std::numeric_limits<float>::epsilon())
132  return STATUS_CODE_NOT_FOUND;
133 
134  // Sampling in x
135  const float nPointsU(std::fabs((xOverlap / xSpanU) * static_cast<float>(fitSegmentU.GetEndLayer() - fitSegmentU.GetStartLayer())));
136  const float nPointsV(std::fabs((xOverlap / xSpanV) * static_cast<float>(fitSegmentV.GetEndLayer() - fitSegmentV.GetStartLayer())));
137  const float nPointsW(std::fabs((xOverlap / xSpanW) * static_cast<float>(fitSegmentW.GetEndLayer() - fitSegmentW.GetStartLayer())));
138 
139  const unsigned int nPoints(1 + static_cast<unsigned int>((nPointsU + nPointsV + nPointsW) / 3.f));
140 
141  // Chi2 calculations
142  float pseudoChi2Sum(0.f);
143  unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
144 
145  for (unsigned int n = 0; n <= nPoints; ++n)
146  {
147  const float x(minX + (maxX - minX) * static_cast<float>(n) / static_cast<float>(nPoints));
148 
149  CartesianVector fitUVector(0.f, 0.f, 0.f), fitVVector(0.f, 0.f, 0.f), fitWVector(0.f, 0.f, 0.f);
150  CartesianVector fitUDirection(0.f, 0.f, 0.f), fitVDirection(0.f, 0.f, 0.f), fitWDirection(0.f, 0.f, 0.f);
151 
152  if ((STATUS_CODE_SUCCESS != slidingFitResultU.GetTransverseProjection(x, fitSegmentU, fitUVector, fitUDirection)) ||
153  (STATUS_CODE_SUCCESS != slidingFitResultV.GetTransverseProjection(x, fitSegmentV, fitVVector, fitVDirection)) ||
154  (STATUS_CODE_SUCCESS != slidingFitResultW.GetTransverseProjection(x, fitSegmentW, fitWVector, fitWDirection)))
155  {
156  continue;
157  }
158 
159  const float u(fitUVector.GetZ()), v(fitVVector.GetZ()), w(fitWVector.GetZ());
160  const float uv2w(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, u, v));
161  const float uw2v(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_W, u, w));
162  const float vw2u(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_V, TPC_VIEW_W, v, w));
163 
164  ++nSamplingPoints;
165  const float deltaU((vw2u - u) * fitUDirection.GetX());
166  const float deltaV((uw2v - v) * fitVDirection.GetX());
167  const float deltaW((uv2w - w) * fitWDirection.GetX());
168 
169  const float pseudoChi2(deltaW * deltaW + deltaV * deltaV + deltaU * deltaU);
170  pseudoChi2Sum += pseudoChi2;
171 
172  if (pseudoChi2 < m_pseudoChi2Cut)
173  ++nMatchedSamplingPoints;
174  }
175 
176  if (0 == nSamplingPoints)
177  return STATUS_CODE_NOT_FOUND;
178 
179  const XOverlap xOverlapObject(fitSegmentU.GetMinX(), fitSegmentU.GetMaxX(), fitSegmentV.GetMinX(),
180  fitSegmentV.GetMaxX(), fitSegmentW.GetMinX(), fitSegmentW.GetMaxX(), xOverlap);
181 
182  transverseOverlapResult = TransverseOverlapResult(nMatchedSamplingPoints, nSamplingPoints, pseudoChi2Sum, xOverlapObject);
183  return STATUS_CODE_SUCCESS;
184 }
185 
186 //------------------------------------------------------------------------------------------------------------------------------------------
187 
188 void ThreeDTransverseTracksAlgorithm::GetBestOverlapResult(const FitSegmentTensor &fitSegmentTensor, TransverseOverlapResult &bestTransverseOverlapResult) const
189 {
190  if (fitSegmentTensor.empty())
191  {
192  bestTransverseOverlapResult = TransverseOverlapResult();
193  return;
194  }
195 
196  unsigned int maxIndexU(0), maxIndexV(0), maxIndexW(0);
197  for (FitSegmentTensor::const_iterator tIter = fitSegmentTensor.begin(), tIterEnd = fitSegmentTensor.end(); tIter != tIterEnd; ++tIter)
198  {
199  maxIndexU = std::max(tIter->first, maxIndexU);
200 
201  for (FitSegmentMatrix::const_iterator mIter = tIter->second.begin(), mIterEnd = tIter->second.end(); mIter != mIterEnd; ++mIter)
202  {
203  maxIndexV = std::max(mIter->first, maxIndexV);
204 
205  for (FitSegmentToOverlapResultMap::const_iterator rIter = mIter->second.begin(), rIterEnd = mIter->second.end(); rIter != rIterEnd; ++rIter)
206  maxIndexW = std::max(rIter->first, maxIndexW);
207  }
208  }
209 
210  // ATTN Protect against longitudinal tracks winding back and forth; can cause large number of memory allocations
211  maxIndexU = std::min(m_maxFitSegmentIndex, maxIndexU);
212  maxIndexV = std::min(m_maxFitSegmentIndex, maxIndexV);
213  maxIndexW = std::min(m_maxFitSegmentIndex, maxIndexW);
214 
215  FitSegmentTensor fitSegmentSumTensor;
216  for (unsigned int indexU = 0; indexU <= maxIndexU; ++indexU)
217  {
218  for (unsigned int indexV = 0; indexV <= maxIndexV; ++indexV)
219  {
220  for (unsigned int indexW = 0; indexW <= maxIndexW; ++indexW)
221  {
222  TransverseOverlapResultVector transverseOverlapResultVector;
223  this->GetPreviousOverlapResults(indexU, indexV, indexW, fitSegmentSumTensor, transverseOverlapResultVector);
224 
225  TransverseOverlapResultVector::const_iterator maxElement = std::max_element(transverseOverlapResultVector.begin(), transverseOverlapResultVector.end());
226  TransverseOverlapResult maxTransverseOverlapResult((transverseOverlapResultVector.end() != maxElement) ? *maxElement : TransverseOverlapResult());
227 
228  TransverseOverlapResult thisOverlapResult;
229  if (fitSegmentTensor.count(indexU) && (fitSegmentTensor.find(indexU))->second.count(indexV) && ((fitSegmentTensor.find(indexU))->second.find(indexV))->second.count(indexW))
230  thisOverlapResult = (((fitSegmentTensor.find(indexU))->second.find(indexV))->second.find(indexW))->second;
231 
232  if (!thisOverlapResult.IsInitialized() && !maxTransverseOverlapResult.IsInitialized())
233  continue;
234 
235  fitSegmentSumTensor[indexU][indexV][indexW] = thisOverlapResult + maxTransverseOverlapResult;
236  }
237  }
238  }
239 
240  for (unsigned int indexU = 0; indexU <= maxIndexU; ++indexU)
241  {
242  for (unsigned int indexV = 0; indexV <= maxIndexV; ++indexV)
243  {
244  for (unsigned int indexW = 0; indexW <= maxIndexW; ++indexW)
245  {
246  const TransverseOverlapResult &transverseOverlapResult(fitSegmentSumTensor[indexU][indexV][indexW]);
247 
248  if (!transverseOverlapResult.IsInitialized())
249  continue;
250 
251  if (transverseOverlapResult > bestTransverseOverlapResult)
252  bestTransverseOverlapResult = transverseOverlapResult;
253  }
254  }
255  }
256 }
257 
258 //------------------------------------------------------------------------------------------------------------------------------------------
259 
260 void ThreeDTransverseTracksAlgorithm::GetPreviousOverlapResults(const unsigned int indexU, const unsigned int indexV, const unsigned int indexW,
261  FitSegmentTensor &fitSegmentSumTensor, TransverseOverlapResultVector &transverseOverlapResultVector) const
262 {
263  for (unsigned int iPermutation = 1; iPermutation < 8; ++iPermutation)
264  {
265  const bool decrementU((iPermutation >> 0) & 0x1);
266  const bool decrementV((iPermutation >> 1) & 0x1);
267  const bool decrementW((iPermutation >> 2) & 0x1);
268 
269  if ((decrementU && (0 == indexU)) || (decrementV && (0 == indexV)) || (decrementW && (0 == indexW)))
270  continue;
271 
272  const unsigned int newIndexU(decrementU ? indexU - 1 : indexU);
273  const unsigned int newIndexV(decrementV ? indexV - 1 : indexV);
274  const unsigned int newIndexW(decrementW ? indexW - 1 : indexW);
275 
276  const TransverseOverlapResult &transverseOverlapResult(fitSegmentSumTensor[newIndexU][newIndexV][newIndexW]);
277 
278  if (transverseOverlapResult.IsInitialized())
279  transverseOverlapResultVector.push_back(transverseOverlapResult);
280  }
281 
282  if (transverseOverlapResultVector.empty())
283  transverseOverlapResultVector.push_back(TransverseOverlapResult());
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
289 {
290  unsigned int repeatCounter(0);
291 
292  for (TensorToolVector::const_iterator iter = m_algorithmToolVector.begin(), iterEnd = m_algorithmToolVector.end(); iter != iterEnd; )
293  {
294  if ((*iter)->Run(this, m_overlapTensor))
295  {
296  iter = m_algorithmToolVector.begin();
297 
298  if (++repeatCounter > m_nMaxTensorToolRepeats)
299  break;
300  }
301  else
302  {
303  ++iter;
304  }
305  }
306 }
307 
308 //------------------------------------------------------------------------------------------------------------------------------------------
309 //------------------------------------------------------------------------------------------------------------------------------------------
310 
311 StatusCode ThreeDTransverseTracksAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
312 {
313  AlgorithmToolVector algorithmToolVector;
314  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle,
315  "TrackTools", algorithmToolVector));
316 
317  for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
318  {
319  TransverseTensorTool *const pTransverseTensorTool(dynamic_cast<TransverseTensorTool*>(*iter));
320 
321  if (NULL == pTransverseTensorTool)
322  return STATUS_CODE_INVALID_PARAMETER;
323 
324  m_algorithmToolVector.push_back(pTransverseTensorTool);
325  }
326 
327  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
328  "NMaxTensorToolRepeats", m_nMaxTensorToolRepeats));
329 
330  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
331  "MaxFitSegmentIndex", m_maxFitSegmentIndex));
332 
333  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
334  "PseudoChi2Cut", m_pseudoChi2Cut));
335 
336  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
337  "MinSegmentMatchedFraction", m_minSegmentMatchedFraction));
338 
339  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
340  "MinSegmentMatchedPoints", m_minSegmentMatchedPoints));
341 
342  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
343  "MinOverallMatchedFraction", m_minOverallMatchedFraction));
344 
345  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
346  "MinOverallMatchedPoints", m_minOverallMatchedPoints));
347 
348  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
349  "MinSamplingPointsPerLayer", m_minSamplingPointsPerLayer));
350 
352 }
353 
354 } // namespace lar_content
Float_t x
Definition: compare.C:6
float m_minSegmentMatchedFraction
The minimum segment matched sampling fraction to allow segment grouping.
float m_pseudoChi2Cut
The pseudo chi2 cut to identify matched sampling points.
int GetStartLayer() const
Get start layer.
void GetBestOverlapResult(const FitSegmentTensor &fitSegmentTensor, TransverseOverlapResult &bestTransverseOverlapResult) const
Get the best overlap result, by examining the fit segment tensor.
unsigned int m_maxFitSegmentIndex
The maximum number of fit segments used when identifying best overlap result.
unsigned int GetNMatchedSamplingPoints() const
Get the number of matched sampling points.
bool IsInitialized() const
Whether the track overlap result has been initialized.
unsigned int m_minOverallMatchedPoints
The minimum number of matched segment sampling points to allow particle creation. ...
Float_t x1[n_points_granero]
Definition: compare.C:5
std::vector< FitSegment > FitSegmentList
TensorToolVector m_algorithmToolVector
The algorithm tool vector.
std::vector< TransverseOverlapResult > TransverseOverlapResultVector
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Set overlap result.
unsigned int GetNSamplingPoints() const
Get the number of sampling points.
Int_t max
Definition: plot.C:27
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
intermediate_table::const_iterator const_iterator
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
Header file for the cluster helper class.
float GetMatchedFraction() const
Get the fraction of sampling points resulting in a match.
void GetFitSegmentTensor(const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV, const TwoDSlidingFitResult &slidingFitResultW, FitSegmentTensor &fitSegmentTensor) const
Get the number of matched points for three fit segments and accompanying sliding fit results...
static float MergeTwoPositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const float position1, const float position2)
Merge two views (U,V) to give a third view (Z).
const FitSegmentList & GetFitSegmentList() const
Get the fit segment list.
TransverseOverlapResult class.
void CalculateOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
Calculate cluster overlap result and store in tensor.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
Header file for the three dimensional transverse tracks algorithm class.
Int_t min
Definition: plot.C:26
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
double GetMinX() const
Get the minimum x value.
pandora::StatusCode GetTransverseProjection(const float x, const FitSegment &fitSegment, pandora::CartesianVector &position) const
Get projected position for a given input x coordinate and fit segment.
void GetPreviousOverlapResults(const unsigned int indexU, const unsigned int indexV, const unsigned int indexW, FitSegmentTensor &fitSegmentSumTensor, TransverseOverlapResultVector &transverseOverlapResultVector) const
Get track overlap results for possible connected segments.
float m_minOverallMatchedFraction
The minimum matched sampling fraction to allow particle creation.
Char_t n[5]
void ExamineTensor()
Examine contents of tensor, collect together best-matching 2D particles and modify clusters as requir...
float m_minSamplingPointsPerLayer
The minimum number of sampling points per layer to allow particle creation.
XOverlap class.
Definition: LArXOverlap.h:17
Float_t w
Definition: plot.C:23
std::map< unsigned int, FitSegmentMatrix > FitSegmentTensor
int GetEndLayer() const
Get end layer.
pandora::StatusCode GetSegmentOverlap(const FitSegment &fitSegmentU, const FitSegment &fitSegmentV, const FitSegment &fitSegmentW, const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV, const TwoDSlidingFitResult &slidingFitResultW, TransverseOverlapResult &transverseOverlapResult) const
Get the overlap result for three fit segments and the accompanying sliding fit results.
unsigned int m_minSegmentMatchedPoints
The minimum number of matched segment sampling points to allow segment grouping.
double GetMaxX() const
Get the maximum x value.