LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
TracksCrossingGapsTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
16 
17 
18 using namespace pandora;
19 
20 namespace lar_content
21 {
22 
23 TracksCrossingGapsTool::TracksCrossingGapsTool() :
24  m_minMatchedFraction(0.5f),
25  m_minMatchedSamplingPoints(10),
26  m_minXOverlapFraction(0.9f),
27  m_minMatchedSamplingPointRatio(2),
28  m_maxGapTolerance(2.f),
29  m_sampleStepSize(0.5f),
30  m_maxAngleRatio(2)
31 {
32 }
33 
34 //------------------------------------------------------------------------------------------------------------------------------------------
35 
37 {
38  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
39  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
40 
41  if (PandoraContentApi::GetGeometry(*pAlgorithm)->GetDetectorGapList().empty())
42  return false;
43 
44  ProtoParticleVector protoParticleVector;
45  this->FindTracks(pAlgorithm, overlapTensor, protoParticleVector);
46 
47  const bool particlesMade(pAlgorithm->CreateThreeDParticles(protoParticleVector));
48  return particlesMade;
49 }
50 
51 //------------------------------------------------------------------------------------------------------------------------------------------
52 
53 void TracksCrossingGapsTool::FindTracks(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector) const
54 {
55  ClusterSet usedClusters;
56  ClusterVector sortedKeyClusters;
57  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
58 
59  for (const Cluster *const pKeyCluster : sortedKeyClusters)
60  {
61  if (!pKeyCluster->IsAvailable())
62  continue;
63 
64  unsigned int nU(0), nV(0), nW(0);
65  TensorType::ElementList elementList;
66  overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
67 
68  IteratorList iteratorList;
69  this->SelectElements(pAlgorithm, elementList, usedClusters, iteratorList);
70 
71  // Check that elements are not directly connected and are significantly longer than any other directly connected elements
72  for (IteratorList::const_iterator iIter = iteratorList.begin(), iIterEnd = iteratorList.end(); iIter != iIterEnd; ++iIter)
73  {
74  if (LongTracksTool::HasLongDirectConnections(iIter, iteratorList))
75  continue;
76 
78  continue;
79 
80  ProtoParticle protoParticle;
81  protoParticle.m_clusterListU.push_back((*iIter)->GetClusterU());
82  protoParticle.m_clusterListV.push_back((*iIter)->GetClusterV());
83  protoParticle.m_clusterListW.push_back((*iIter)->GetClusterW());
84  protoParticleVector.push_back(protoParticle);
85 
86  usedClusters.insert((*iIter)->GetClusterU());
87  usedClusters.insert((*iIter)->GetClusterV());
88  usedClusters.insert((*iIter)->GetClusterW());
89  }
90  }
91 }
92 
93 //------------------------------------------------------------------------------------------------------------------------------------------
94 
96  const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
97 {
98  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
99  {
100  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
101  continue;
102 
103  if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
104  continue;
105 
106  if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
107  continue;
108 
109  const XOverlap &xOverlap(eIter->GetOverlapResult().GetXOverlap());
110 
111  if (xOverlap.GetXOverlapSpan() < std::numeric_limits<float>::epsilon())
112  continue;
113 
114  // Calculate effective overlap fraction, including the information about gaps
115  float xOverlapFractionU(0.f), xOverlapFractionV(0.f), xOverlapFractionW(0.f);
116  this->CalculateEffectiveOverlapFractions(pAlgorithm, *eIter, xOverlapFractionU, xOverlapFractionV, xOverlapFractionW);
117 
118  if ((xOverlap.GetXSpanU() > std::numeric_limits<float>::epsilon()) && (xOverlapFractionU > m_minXOverlapFraction) &&
119  (xOverlap.GetXSpanV() > std::numeric_limits<float>::epsilon()) && (xOverlapFractionV > m_minXOverlapFraction) &&
120  (xOverlap.GetXSpanW() > std::numeric_limits<float>::epsilon()) && (xOverlapFractionW > m_minXOverlapFraction))
121  {
122  iteratorList.push_back(eIter);
123  }
124  }
125 }
126 
127 //------------------------------------------------------------------------------------------------------------------------------------------
128 
129 void TracksCrossingGapsTool::CalculateEffectiveOverlapFractions(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element,
130  float &xOverlapFractionU, float &xOverlapFractionV, float &xOverlapFractionW) const
131 {
132  float xMinEffU(element.GetOverlapResult().GetXOverlap().GetUMinX()), xMaxEffU(element.GetOverlapResult().GetXOverlap().GetUMaxX());
133  float xMinEffV(element.GetOverlapResult().GetXOverlap().GetVMinX()), xMaxEffV(element.GetOverlapResult().GetXOverlap().GetVMaxX());
134  float xMinEffW(element.GetOverlapResult().GetXOverlap().GetWMinX()), xMaxEffW(element.GetOverlapResult().GetXOverlap().GetWMaxX());
135  this->CalculateEffectiveOverlapSpan(pAlgorithm, element, xMinEffU, xMaxEffU, xMinEffV, xMaxEffV, xMinEffW, xMaxEffW);
136 
137  const float effectiveXSpanU(xMaxEffU - xMinEffU), effectiveXSpanV(xMaxEffV - xMinEffV), effectiveXSpanW(xMaxEffW - xMinEffW);
138  const float minCommonX(std::max(xMinEffU, std::max(xMinEffV, xMinEffW)));
139  const float maxCommonX(std::min(xMaxEffU, std::min(xMaxEffV, xMaxEffW)));
140  const float effectiveXOverlapSpan(maxCommonX - minCommonX);
141 
142  // TODO check that this shouldn't be greater than 1 any more
143  xOverlapFractionU = effectiveXSpanU > 0.f ? std::min(1.f, (effectiveXOverlapSpan / effectiveXSpanU)) : 0.f;
144  xOverlapFractionV = effectiveXSpanV > 0.f ? std::min(1.f, (effectiveXOverlapSpan / effectiveXSpanV)) : 0.f;
145  xOverlapFractionW = effectiveXSpanW > 0.f ? std::min(1.f, (effectiveXOverlapSpan / effectiveXSpanW)) : 0.f;
146 }
147 
148 //------------------------------------------------------------------------------------------------------------------------------------------
149 
150 void TracksCrossingGapsTool::CalculateEffectiveOverlapSpan(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element,
151  float &xMinEffU, float &xMaxEffU, float &xMinEffV, float &xMaxEffV, float &xMinEffW, float &xMaxEffW) const
152 {
153  const float xMinAll(std::min(xMinEffU, std::min(xMinEffV, xMinEffW)));
154  const float xMaxAll(std::max(xMaxEffU, std::max(xMaxEffV, xMaxEffW)));
155  const float minCommonX(std::max(xMinEffU, std::max(xMinEffV, xMinEffW)));
156  const float maxCommonX(std::min(xMaxEffU, std::min(xMaxEffV, xMaxEffW)));
157 
158  float dxUmin(0.f), dxVmin(0.f), dxWmin(0.f);
159  float dxUmax(0.f), dxVmax(0.f), dxWmax(0.f);
160 
161  // ATTN break out of loops to to avoid finding a non-related gap far from cluster itself
162  const int nSamplingPointsLeft(1 + static_cast<int>((minCommonX - xMinAll) / m_sampleStepSize));
163  const int nSamplingPointsRight(1 + static_cast<int>((xMaxAll - maxCommonX) / m_sampleStepSize));
164 
165  for (int iSample = 1; iSample <= nSamplingPointsLeft; ++iSample)
166  {
167  bool gapInU(false), gapInV(false), gapInW(false);
168  const float xSample(std::max(xMinAll, minCommonX - static_cast<float>(iSample) * m_sampleStepSize));
169 
170  if (!this->PassesGapChecks(pAlgorithm, element, xSample, gapInU, gapInV, gapInW))
171  break;
172 
173  if (gapInU) dxUmin = xMinEffU - xSample;
174  if (gapInV) dxVmin = xMinEffV - xSample;
175  if (gapInW) dxWmin = xMinEffW - xSample;
176  }
177 
178  for (int iSample = 1; iSample <= nSamplingPointsRight; ++iSample)
179  {
180  bool gapInU(false), gapInV(false), gapInW(false);
181  const float xSample(std::min(xMaxAll, maxCommonX + static_cast<float>(iSample) * m_sampleStepSize));
182 
183  if (!this->PassesGapChecks(pAlgorithm, element, xSample, gapInU, gapInV, gapInW))
184  break;
185 
186  if (gapInU) dxUmax = xSample - xMaxEffU;
187  if (gapInV) dxVmax = xSample - xMaxEffV;
188  if (gapInW) dxWmax = xSample - xMaxEffW;
189  }
190 
191  xMinEffU -= dxUmin;
192  xMaxEffU += dxUmax;
193  xMinEffV -= dxVmin;
194  xMaxEffV += dxVmax;
195  xMinEffW -= dxWmin;
196  xMaxEffW += dxWmax;
197 }
198 
199 //------------------------------------------------------------------------------------------------------------------------------------------
200 
201 bool TracksCrossingGapsTool::PassesGapChecks(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element, const float xSample,
202  bool &gapInU, bool &gapInV, bool &gapInW) const
203 {
204  const TwoDSlidingFitResult &slidingFitResultU(pAlgorithm->GetCachedSlidingFitResult(element.GetClusterU()));
205  const TwoDSlidingFitResult &slidingFitResultV(pAlgorithm->GetCachedSlidingFitResult(element.GetClusterV()));
206  const TwoDSlidingFitResult &slidingFitResultW(pAlgorithm->GetCachedSlidingFitResult(element.GetClusterW()));
207 
208  // If we have access to the global x position in all three clusters, there are no gaps involved (or cluster already spans small gaps)
209  CartesianVector fitUPosition(0.f, 0.f, 0.f), fitVPosition(0.f, 0.f, 0.f), fitWPosition(0.f, 0.f, 0.f);
210  const StatusCode statusCodeU(slidingFitResultU.GetGlobalFitPositionAtX(xSample, fitUPosition));
211  const StatusCode statusCodeV(slidingFitResultV.GetGlobalFitPositionAtX(xSample, fitVPosition));
212  const StatusCode statusCodeW(slidingFitResultW.GetGlobalFitPositionAtX(xSample, fitWPosition));
213 
214  if ((STATUS_CODE_SUCCESS == statusCodeU) && (STATUS_CODE_SUCCESS == statusCodeV) && (STATUS_CODE_SUCCESS == statusCodeW))
215  return false;
216 
217  // Note: argument order important - initially assume first view has a gap, but inside CheckXPositionInGap do check other two views
218  if ((STATUS_CODE_SUCCESS != statusCodeU) && (!this->IsEndOfCluster(xSample, slidingFitResultU)))
219  return this->CheckXPositionInGap(xSample, slidingFitResultU, slidingFitResultV, slidingFitResultW, gapInU, gapInV, gapInW);
220 
221  if ((STATUS_CODE_SUCCESS != statusCodeV) && (!this->IsEndOfCluster(xSample, slidingFitResultV)))
222  return this->CheckXPositionInGap(xSample, slidingFitResultV, slidingFitResultU, slidingFitResultW, gapInV, gapInU, gapInW);
223 
224  if ((STATUS_CODE_SUCCESS != statusCodeW) && (!this->IsEndOfCluster(xSample, slidingFitResultW)))
225  return this->CheckXPositionInGap(xSample, slidingFitResultW, slidingFitResultU, slidingFitResultV, gapInW, gapInU, gapInV);
226 
227  return false;
228 }
229 
230 //------------------------------------------------------------------------------------------------------------------------------------------
231 
232 bool TracksCrossingGapsTool::CheckXPositionInGap(const float xSample, const TwoDSlidingFitResult &slidingFitResult1, const TwoDSlidingFitResult &slidingFitResult2,
233  const TwoDSlidingFitResult &slidingFitResult3, bool &gapIn1, bool &gapIn2, bool &gapIn3) const
234 {
235  CartesianVector fitPosition2(0.f, 0.f, 0.f), fitPosition3(0.f, 0.f, 0.f);
236 
237  // If we have the global position at X from the two other clusters, calculate projection in the first view and check for gaps
238  if ((STATUS_CODE_SUCCESS == slidingFitResult2.GetGlobalFitPositionAtX(xSample, fitPosition2)) &&
239  (STATUS_CODE_SUCCESS == slidingFitResult3.GetGlobalFitPositionAtX(xSample, fitPosition3)))
240  {
241  const HitType hitType1(LArClusterHelper::GetClusterHitType(slidingFitResult1.GetCluster()));
242  const HitType hitType2(LArClusterHelper::GetClusterHitType(slidingFitResult2.GetCluster()));
243  const HitType hitType3(LArClusterHelper::GetClusterHitType(slidingFitResult3.GetCluster()));
244 
245  const float zSample(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitType2, hitType3, fitPosition2.GetZ(), fitPosition3.GetZ()));
246  const CartesianVector samplingPoint(xSample, 0.f, zSample);
247  return LArGeometryHelper::IsInGap(this->GetPandora(), CartesianVector(xSample, 0.f, zSample), hitType1, m_maxGapTolerance);
248  }
249 
250  // ATTN Only safe to return here (for efficiency) because gapIn2 and gapIn3 values aren't used by calling function if we return false
251  gapIn1 = LArGeometryHelper::IsXSamplingPointInGap(this->GetPandora(), xSample, slidingFitResult1, m_sampleStepSize);
252 
253  if (!gapIn1)
254  return false;
255 
256  // If we dont have a projection at x in the other two clusters, check if they are in gaps or at the end of the cluster
257  if ((STATUS_CODE_SUCCESS != slidingFitResult2.GetGlobalFitPositionAtX(xSample, fitPosition2)) &&
258  (STATUS_CODE_SUCCESS != slidingFitResult3.GetGlobalFitPositionAtX(xSample, fitPosition3)))
259  {
260  const bool endIn2(this->IsEndOfCluster(xSample, slidingFitResult2));
261  const bool endIn3(this->IsEndOfCluster(xSample, slidingFitResult3));
262 
263  if (!endIn2)
264  gapIn2 = LArGeometryHelper::IsXSamplingPointInGap(this->GetPandora(), xSample, slidingFitResult2, m_sampleStepSize);
265 
266  if (!endIn3)
267  gapIn3 = LArGeometryHelper::IsXSamplingPointInGap(this->GetPandora(), xSample, slidingFitResult3, m_sampleStepSize);
268 
269  return ((gapIn2 && endIn3) || (gapIn3 && endIn2) || (endIn2 && endIn3));
270  }
271 
272  // Finally, check whether there is a second gap involved
273  if (STATUS_CODE_SUCCESS != slidingFitResult2.GetGlobalFitPositionAtX(xSample, fitPosition2))
274  {
275  gapIn2 = LArGeometryHelper::IsXSamplingPointInGap(this->GetPandora(), xSample, slidingFitResult2, m_sampleStepSize);
276  return (gapIn2 || this->IsEndOfCluster(xSample, slidingFitResult2));
277  }
278  else
279  {
280  gapIn3 = LArGeometryHelper::IsXSamplingPointInGap(this->GetPandora(), xSample, slidingFitResult3, m_sampleStepSize);
281  return (gapIn3 || this->IsEndOfCluster(xSample, slidingFitResult3));
282  }
283 }
284 
285 //------------------------------------------------------------------------------------------------------------------------------------------
286 
287 bool TracksCrossingGapsTool::IsEndOfCluster(const float xSample, const TwoDSlidingFitResult &slidingFitResult) const
288 {
289  return ((std::fabs(slidingFitResult.GetGlobalMinLayerPosition().GetX() - xSample) < slidingFitResult.GetLayerPitch()) ||
290  (std::fabs(slidingFitResult.GetGlobalMaxLayerPosition().GetX() - xSample) < slidingFitResult.GetLayerPitch()));
291 }
292 
293 //------------------------------------------------------------------------------------------------------------------------------------------
294 
295 StatusCode TracksCrossingGapsTool::ReadSettings(const TiXmlHandle xmlHandle)
296 {
297  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
298  "MinMatchedFraction", m_minMatchedFraction));
299 
300  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
301  "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
302 
303  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
304  "MinXOverlapFraction", m_minXOverlapFraction));
305 
306  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
307  "MinMatchedSamplingPointRatio", m_minMatchedSamplingPointRatio));
308 
309  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
310  "MaxGapTolerance", m_maxGapTolerance));
311 
312  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
313  "SampleStepSize", m_sampleStepSize));
314 
315  if (m_sampleStepSize < std::numeric_limits<float>::epsilon())
316  {
317  std::cout << "TracksCrossingGapsTool: Invalid value for SampleStepSize " << m_sampleStepSize << std::endl;
318  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
319  }
320 
321  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
322  "MaxAngleRatio", m_maxAngleRatio));
323 
324  return STATUS_CODE_SUCCESS;
325 }
326 
327 } // namespace lar_content
void SelectElements(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select a list of track-like elements crossing a gap in one or more views from a set of connected tens...
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for particle creation.
std::vector< ProtoParticle > ProtoParticleVector
float m_maxGapTolerance
The max gap tolerance.
std::vector< TensorType::ElementList::const_iterator > IteratorList
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
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...
float m_minXOverlapFraction
The min x overlap fraction (in each view) 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.
void CalculateEffectiveOverlapFractions(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element, float &xOverlapFractionU, float &xOverlapFractionV, float &xOverlapFractionW) const
Calculate the effective overlap fractions given a set of clusters, taking gaps into account...
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
static bool IsInGap(const pandora::Pandora &pandora, const pandora::CartesianVector &testPoint2D, const pandora::HitType hitType, const float gapTolerance=0.f)
Whether a 2D test point lies in a registered gap with the associated hit type.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
pandora::ClusterList m_clusterListW
List of 2D W clusters in a 3D proto particle.
unsigned int m_minMatchedSamplingPointRatio
The min ratio between 1st and 2nd highest msps for simple ambiguity resolution.
bool CheckXPositionInGap(const float xSample, const TwoDSlidingFitResult &slidingFitResult1, const TwoDSlidingFitResult &slidingFitResult2, const TwoDSlidingFitResult &slidingFitResult3, bool &gapIn1, bool &gapIn2, bool &gapIn3) const
Check individually each cluster where a gap might be present.
bool IsEndOfCluster(const float xSample, const TwoDSlidingFitResult &slidingFitResult) const
Check whether a x position is at the end of the cluster.
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
float m_minMatchedFraction
The min matched sampling point fraction for particle creation.
pandora::ClusterList m_clusterListV
List of 2D V clusters in a 3D proto particle.
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).
float GetLayerPitch() const
Get the layer pitch, units cm.
pandora::ClusterList m_clusterListU
List of 2D U clusters in a 3D proto particle.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
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)
static bool IsXSamplingPointInGap(const pandora::Pandora &pandora, const float xSample, const TwoDSlidingFitResult &slidingFitResult, const float gapTolerance=0.f)
Whether there is a gap in a cluster (described via its sliding fit result) at a specified x sampling ...
std::vector< art::Ptr< recob::Cluster > > ClusterVector
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
bool Run(ThreeDTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
unsigned int m_maxAngleRatio
The max ratio allowed in the angle.
pandora::StatusCode GetGlobalFitPositionAtX(const float x, pandora::CartesianVector &position) const
Get global fit position for a given input x coordinate.
Int_t min
Definition: plot.C:26
bool PassesGapChecks(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element, const float xSample, bool &gapInU, bool &gapInV, bool &gapInW) const
Check whether there is any gap in the three U-V-W clusters combination.
void FindTracks(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector) const
Find tracks crossing gaps, with unambiguous connection but poor overlap due to gaps.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static bool HasLongDirectConnections(IteratorList::const_iterator iIter, const IteratorList &iteratorList)
Whether a long element shares clusters with any other long elements.
float m_sampleStepSize
The sampling step size used in association checks, units cm.
XOverlap class.
Definition: LArXOverlap.h:17
void CalculateEffectiveOverlapSpan(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element, float &xMinEffU, float &xMaxEffU, float &xMinEffV, float &xMaxEffV, float &xMinEffW, float &xMaxEffW) const
Calculate the effective overlap span given a set of clusters, taking gaps into account.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
Header file for the long tracks tool class.