MissingTrackSegmentTool.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArTransverseTrackMatching/MissingTrackSegmentTool.cc
3  *
4  * @brief Implementation of the missing track segment tool class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
14 
16 
19 
20 using namespace pandora;
21 
22 namespace lar_content
23 {
24 
25 MissingTrackSegmentTool::MissingTrackSegmentTool() :
26  m_minMatchedFraction(0.9f),
27  m_minMatchedSamplingPoints(10),
28  m_minMatchedSamplingPointRatio(2),
29  m_minInitialXOverlapFraction(0.75f),
30  m_minFinalXOverlapFraction(0.75f),
31  m_minCaloHitsInCandidateCluster(5),
32  m_pseudoChi2Cut(1.f),
33  m_makePfoMinSamplingPoints(5),
34  m_makePfoMinMatchedSamplingPoints(5),
35  m_makePfoMinMatchedFraction(0.8f),
36  m_makePfoMaxImpactParameter(3.f),
37  m_mergeMaxChi2PerSamplingPoint(0.25f),
38  m_mergeXContainmentTolerance(1.f)
39 {
40 }
41 
42 //------------------------------------------------------------------------------------------------------------------------------------------
43 
45 {
46  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
47  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
48 
49  ProtoParticleVector protoParticleVector;
50  ClusterMergeMap clusterMergeMap;
51  this->FindTracks(pAlgorithm, overlapTensor, protoParticleVector, clusterMergeMap);
52 
53  const bool particlesMade(pAlgorithm->CreateThreeDParticles(protoParticleVector));
54  const bool mergesMade(pAlgorithm->MakeClusterMerges(clusterMergeMap));
55 
56  return (particlesMade || mergesMade);
57 }
58 
59 //------------------------------------------------------------------------------------------------------------------------------------------
60 
62  ProtoParticleVector &protoParticleVector, ClusterMergeMap &clusterMergeMap) const
63 {
64  ClusterSet usedClusters;
65  ClusterVector sortedKeyClusters;
66  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
67 
68  for (const Cluster *const pKeyCluster : sortedKeyClusters)
69  {
70  if (!pKeyCluster->IsAvailable())
71  continue;
72 
73  unsigned int nU(0), nV(0), nW(0);
74  TensorType::ElementList elementList;
75  overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
76 
77  IteratorList iteratorList;
78  this->SelectElements(elementList, usedClusters, iteratorList);
79 
80  for (IteratorList::const_iterator iIter = iteratorList.begin(), iIterEnd = iteratorList.end(); iIter != iIterEnd; ++iIter)
81  {
82  if (LongTracksTool::HasLongDirectConnections(iIter, iteratorList))
83  continue;
84 
86  continue;
87 
88  if (!this->PassesParticleChecks(pAlgorithm, *(*iIter), usedClusters, clusterMergeMap))
89  continue;
90 
91  ProtoParticle protoParticle;
92  protoParticle.m_clusterList.push_back((*iIter)->GetClusterU());
93  protoParticle.m_clusterList.push_back((*iIter)->GetClusterV());
94  protoParticle.m_clusterList.push_back((*iIter)->GetClusterW());
95  protoParticleVector.push_back(protoParticle);
96 
97  usedClusters.insert((*iIter)->GetClusterU());
98  usedClusters.insert((*iIter)->GetClusterV());
99  usedClusters.insert((*iIter)->GetClusterW());
100  }
101  }
102 }
103 
104 //------------------------------------------------------------------------------------------------------------------------------------------
105 
107  const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
108 {
109  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
110  {
111  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
112  continue;
113 
114  if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
115  continue;
116 
117  if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
118  continue;
119 
120  const XOverlap &xOverlap(eIter->GetOverlapResult().GetXOverlap());
121  const float shortSpan(std::min(xOverlap.GetXSpanU(), std::min(xOverlap.GetXSpanV(), xOverlap.GetXSpanW())));
122  const float longSpan1(std::max(xOverlap.GetXSpanU(), std::max(xOverlap.GetXSpanV(), xOverlap.GetXSpanW())));
123  const float longSpan2(
124  ((xOverlap.GetXSpanU() > shortSpan) && (xOverlap.GetXSpanU() < longSpan1))
125  ? xOverlap.GetXSpanU()
126  : ((xOverlap.GetXSpanV() > shortSpan) && (xOverlap.GetXSpanV() < longSpan1)) ? xOverlap.GetXSpanV() : xOverlap.GetXSpanW());
127 
128  if ((xOverlap.GetXOverlapSpan() < std::numeric_limits<float>::epsilon()) || (longSpan1 < std::numeric_limits<float>::epsilon()))
129  continue;
130 
131  if (((shortSpan / xOverlap.GetXOverlapSpan()) < m_minInitialXOverlapFraction) || ((longSpan2 / longSpan1) < m_minInitialXOverlapFraction))
132  continue;
133 
134  iteratorList.push_back(eIter);
135  }
136 }
137 
138 //------------------------------------------------------------------------------------------------------------------------------------------
139 
140 bool MissingTrackSegmentTool::PassesParticleChecks(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element,
141  ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
142 {
143  try
144  {
145  const Particle particle(element);
146 
147  ClusterList candidateClusters;
148  this->GetCandidateClusters(pAlgorithm, particle, candidateClusters);
149 
150  if (candidateClusters.empty())
151  return false;
152 
153  TwoDSlidingFitResultMap slidingFitResultMap;
154  this->GetSlidingFitResultMap(pAlgorithm, candidateClusters, slidingFitResultMap);
155 
156  if (slidingFitResultMap.empty())
157  return false;
158 
159  SegmentOverlapMap segmentOverlapMap;
160  this->GetSegmentOverlapMap(pAlgorithm, particle, slidingFitResultMap, segmentOverlapMap);
161 
162  if (segmentOverlapMap.empty())
163  return false;
164 
165  return this->MakeDecisions(particle, slidingFitResultMap, segmentOverlapMap, usedClusters, clusterMergeMap);
166  }
167  catch (StatusCodeException &)
168  {
169  return false;
170  }
171 }
172 
173 //------------------------------------------------------------------------------------------------------------------------------------------
174 
176  ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const Particle &particle, ClusterList &candidateClusters) const
177 {
178  const ClusterList &clusterList(pAlgorithm->GetInputClusterList(particle.m_shortHitType));
179 
180  for (ClusterList::const_iterator iter = clusterList.begin(), iterEnd = clusterList.end(); iter != iterEnd; ++iter)
181  {
182  const Cluster *const pCluster(*iter);
183 
184  if (pCluster == particle.m_pShortCluster)
185  continue;
186 
187  if (pCluster->GetNCaloHits() < m_minCaloHitsInCandidateCluster)
188  continue;
189 
190  candidateClusters.push_back(pCluster);
191  }
192 }
193 
194 //------------------------------------------------------------------------------------------------------------------------------------------
195 
197  const ClusterList &candidateClusterList, TwoDSlidingFitResultMap &slidingFitResultMap) const
198 {
199  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
200 
201  for (ClusterList::const_iterator iter = candidateClusterList.begin(), iterEnd = candidateClusterList.end(); iter != iterEnd; ++iter)
202  {
203  const Cluster *const pCluster(*iter);
204 
205  try
206  {
207  const TwoDSlidingFitResult &slidingFitResult(pAlgorithm->GetCachedSlidingFitResult(pCluster));
208  (void)slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult));
209  continue;
210  }
211  catch (StatusCodeException &)
212  {
213  }
214 
215  try
216  {
217  const TwoDSlidingFitResult slidingFitResult(pCluster, pAlgorithm->GetSlidingFitWindow(), slidingFitPitch);
218  (void)slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult));
219  continue;
220  }
221  catch (StatusCodeException &)
222  {
223  }
224  }
225 }
226 
227 //------------------------------------------------------------------------------------------------------------------------------------------
228 
230  const TwoDSlidingFitResultMap &slidingFitResultMap, SegmentOverlapMap &segmentOverlapMap) const
231 {
232  const TwoDSlidingFitResult &fitResult1(pAlgorithm->GetCachedSlidingFitResult(particle.m_pCluster1));
233  const TwoDSlidingFitResult &fitResult2(pAlgorithm->GetCachedSlidingFitResult(particle.m_pCluster2));
234 
235  const float nPoints1(std::fabs(static_cast<float>(fitResult1.GetMaxLayer() - fitResult1.GetMinLayer())));
236  const float nPoints2(std::fabs(static_cast<float>(fitResult2.GetMaxLayer() - fitResult2.GetMinLayer())));
237 
238  const unsigned int nPoints(static_cast<unsigned int>(1.f + (nPoints1 + nPoints2) / 2.f));
239 
240  ClusterList clusterList;
241  for (const auto &mapEntry : slidingFitResultMap)
242  clusterList.push_back(mapEntry.first);
243  clusterList.sort(LArClusterHelper::SortByNHits);
244 
245  for (unsigned n = 0; n <= nPoints; ++n)
246  {
247  const float x(particle.m_longMinX + (particle.m_longMaxX - particle.m_longMinX) * static_cast<float>(n) / static_cast<float>(nPoints));
248 
249  if ((x > particle.m_shortMinX) && (x < particle.m_shortMaxX))
250  continue;
251 
252  CartesianVector fitVector1(0.f, 0.f, 0.f), fitVector2(0.f, 0.f, 0.f);
253 
254  if ((STATUS_CODE_SUCCESS != fitResult1.GetGlobalFitPositionAtX(x, fitVector1)) ||
255  (STATUS_CODE_SUCCESS != fitResult2.GetGlobalFitPositionAtX(x, fitVector2)))
256  {
257  continue;
258  }
259 
260  const float prediction(LArGeometryHelper::MergeTwoPositions(
261  this->GetPandora(), particle.m_hitType1, particle.m_hitType2, fitVector1.GetZ(), fitVector2.GetZ()));
262 
263  for (const Cluster *const pCluster : clusterList)
264  {
265  const TwoDSlidingFitResult &slidingFitResult(slidingFitResultMap.at(pCluster));
266  CartesianVector fitVector(0.f, 0.f, 0.f), fitDirection(0.f, 0.f, 0.f);
267 
268  if ((STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitPositionAtX(x, fitVector)) ||
269  (STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitDirectionAtX(x, fitDirection)))
270  {
271  continue;
272  }
273 
274  const float delta((prediction - fitVector.GetZ()) * fitDirection.GetX());
275  const float pseudoChi2(delta * delta);
276 
277  SegmentOverlap &segmentOverlap(segmentOverlapMap[pCluster]);
278  ++segmentOverlap.m_nSamplingPoints;
279  segmentOverlap.m_pseudoChi2Sum += pseudoChi2;
280 
281  if (pseudoChi2 < m_pseudoChi2Cut)
282  {
283  ++segmentOverlap.m_nMatchedSamplingPoints;
284  segmentOverlap.m_matchedSamplingMinX = std::min(x, segmentOverlap.m_matchedSamplingMinX);
285  segmentOverlap.m_matchedSamplingMaxX = std::max(x, segmentOverlap.m_matchedSamplingMaxX);
286  }
287  }
288  }
289 }
290 
291 //------------------------------------------------------------------------------------------------------------------------------------------
292 
293 bool MissingTrackSegmentTool::MakeDecisions(const Particle &particle, const TwoDSlidingFitResultMap &slidingFitResultMap,
294  const SegmentOverlapMap &segmentOverlapMap, ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
295 {
296  ClusterVector possibleMerges;
297  float shortMinX(particle.m_shortMinX), shortMaxX(particle.m_shortMaxX);
298  bool matchesACluster(false);
299 
300  ClusterVector sortedClusters;
301  for (const auto &mapEntry : segmentOverlapMap)
302  sortedClusters.push_back(mapEntry.first);
303  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
304 
305  for (const Cluster *const pCluster : sortedClusters)
306  {
307  const SegmentOverlap &segmentOverlap(segmentOverlapMap.at(pCluster));
308 
309  if (!this->PassesSamplingCuts(segmentOverlap))
310  continue;
311 
312  shortMinX = std::min(segmentOverlap.m_matchedSamplingMinX, shortMinX);
313  shortMaxX = std::max(segmentOverlap.m_matchedSamplingMaxX, shortMaxX);
314  matchesACluster = true;
315 
316  // Allow pfo construction if find hits in an unavailable cluster, but can't merge unavailable cluster into this pfo
317  if (!usedClusters.insert(pCluster).second || !pCluster->IsAvailable())
318  continue;
319 
320  if (!this->IsPossibleMerge(pCluster, particle, segmentOverlap, slidingFitResultMap))
321  continue;
322 
323  possibleMerges.push_back(pCluster);
324  }
325 
326  if (std::fabs(particle.m_longMaxX - particle.m_longMinX) < std::numeric_limits<float>::epsilon())
327  throw StatusCodeException(STATUS_CODE_FAILURE);
328 
329  if (!matchesACluster || possibleMerges.empty())
330  return false;
331 
332  if (((shortMaxX - shortMinX) / (particle.m_longMaxX - particle.m_longMinX)) < m_minFinalXOverlapFraction)
333  return false;
334 
335  ClusterList &clusterList(clusterMergeMap[particle.m_pShortCluster]);
336  clusterList.insert(clusterList.end(), possibleMerges.begin(), possibleMerges.end());
337  return true;
338 }
339 
340 //------------------------------------------------------------------------------------------------------------------------------------------
341 
343 {
344  if (0 == segmentOverlap.m_nSamplingPoints)
345  return false;
346 
348  return false;
349 
350  if ((static_cast<float>(segmentOverlap.m_nMatchedSamplingPoints) / static_cast<float>(segmentOverlap.m_nSamplingPoints)) < m_makePfoMinMatchedFraction)
351  return false;
352 
353  return true;
354 }
355 
356 //------------------------------------------------------------------------------------------------------------------------------------------
357 
358 bool MissingTrackSegmentTool::IsPossibleMerge(const Cluster *const pCluster, const Particle &particle, const SegmentOverlap &segmentOverlap,
359  const TwoDSlidingFitResultMap &slidingFitResultMap) const
360 {
361  if ((segmentOverlap.m_pseudoChi2Sum / static_cast<float>(segmentOverlap.m_nSamplingPoints)) > m_mergeMaxChi2PerSamplingPoint)
362  return false;
363 
364  TwoDSlidingFitResultMap::const_iterator fitIter = slidingFitResultMap.find(pCluster);
365 
366  if (slidingFitResultMap.end() == fitIter)
367  throw StatusCodeException(STATUS_CODE_FAILURE);
368 
369  float mergeMinX(std::numeric_limits<float>::max()), mergeMaxX(-std::numeric_limits<float>::max());
370  fitIter->second.GetMinAndMaxX(mergeMinX, mergeMaxX);
371 
372  // cluster should not be wider than the longest span
373  if ((mergeMinX < particle.m_longMinX - m_mergeXContainmentTolerance) || (mergeMaxX > particle.m_longMaxX + m_mergeXContainmentTolerance))
374  return false;
375 
376  // cluster should not overlap with the shortest span
377  if ((mergeMinX < particle.m_shortMaxX - m_mergeXContainmentTolerance) && (mergeMaxX > particle.m_shortMinX + m_mergeXContainmentTolerance))
378  return false;
379 
380  return true;
381 }
382 
383 //------------------------------------------------------------------------------------------------------------------------------------------
384 //------------------------------------------------------------------------------------------------------------------------------------------
385 
386 MissingTrackSegmentTool::Particle::Particle(const TensorType::Element &element)
387 {
388  const XOverlap &xOverlap(element.GetOverlapResult().GetXOverlap());
389 
390  m_shortHitType = ((xOverlap.GetXSpanU() < xOverlap.GetXSpanV()) && (xOverlap.GetXSpanU() < xOverlap.GetXSpanW()))
391  ? TPC_VIEW_U
392  : ((xOverlap.GetXSpanV() < xOverlap.GetXSpanU()) && (xOverlap.GetXSpanV() < xOverlap.GetXSpanW()))
393  ? TPC_VIEW_V
394  : ((xOverlap.GetXSpanW() < xOverlap.GetXSpanU()) && (xOverlap.GetXSpanW() < xOverlap.GetXSpanV())) ? TPC_VIEW_W : HIT_CUSTOM;
395 
396  if (HIT_CUSTOM == m_shortHitType)
397  throw StatusCodeException(STATUS_CODE_FAILURE);
398 
399  m_pShortCluster = (TPC_VIEW_U == m_shortHitType) ? element.GetClusterU()
400  : (TPC_VIEW_V == m_shortHitType) ? element.GetClusterV() : element.GetClusterW();
401  m_pCluster1 = (TPC_VIEW_U == m_shortHitType) ? element.GetClusterV() : element.GetClusterU();
402  m_pCluster2 = (TPC_VIEW_W == m_shortHitType) ? element.GetClusterV() : element.GetClusterW();
403  m_shortMinX = (TPC_VIEW_U == m_shortHitType) ? xOverlap.GetUMinX() : (TPC_VIEW_V == m_shortHitType) ? xOverlap.GetVMinX() : xOverlap.GetWMinX();
404  m_shortMaxX = (TPC_VIEW_U == m_shortHitType) ? xOverlap.GetUMaxX() : (TPC_VIEW_V == m_shortHitType) ? xOverlap.GetVMaxX() : xOverlap.GetWMaxX();
405  m_longMinX = (TPC_VIEW_U == m_shortHitType) ? std::min(xOverlap.GetVMinX(), xOverlap.GetWMinX())
406  : (TPC_VIEW_V == m_shortHitType) ? std::min(xOverlap.GetUMinX(), xOverlap.GetWMinX())
407  : std::min(xOverlap.GetUMinX(), xOverlap.GetVMinX());
408  m_longMaxX = (TPC_VIEW_U == m_shortHitType) ? std::max(xOverlap.GetVMaxX(), xOverlap.GetWMaxX())
409  : (TPC_VIEW_V == m_shortHitType) ? std::max(xOverlap.GetUMaxX(), xOverlap.GetWMaxX())
410  : std::max(xOverlap.GetUMaxX(), xOverlap.GetVMaxX());
411 
412  m_hitType1 = LArClusterHelper::GetClusterHitType(m_pCluster1);
413  m_hitType2 = LArClusterHelper::GetClusterHitType(m_pCluster2);
414 }
415 
416 //------------------------------------------------------------------------------------------------------------------------------------------
417 //------------------------------------------------------------------------------------------------------------------------------------------
418 
419 StatusCode MissingTrackSegmentTool::ReadSettings(const TiXmlHandle xmlHandle)
420 {
421  PANDORA_RETURN_RESULT_IF_AND_IF(
422  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
423 
424  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
425  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
426 
427  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
428  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPointRatio", m_minMatchedSamplingPointRatio));
429 
430  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
431  XmlHelper::ReadValue(xmlHandle, "MinInitialXOverlapFraction", m_minInitialXOverlapFraction));
432 
433  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
434  XmlHelper::ReadValue(xmlHandle, "MinFinalXOverlapFraction", m_minFinalXOverlapFraction));
435 
436  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
437  XmlHelper::ReadValue(xmlHandle, "MinCaloHitsInCandidateCluster", m_minCaloHitsInCandidateCluster));
438 
439  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PseudoChi2Cut", m_pseudoChi2Cut));
440 
441  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
442  XmlHelper::ReadValue(xmlHandle, "MakePfoMinSamplingPoints", m_makePfoMinSamplingPoints));
443 
444  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
445  XmlHelper::ReadValue(xmlHandle, "MakePfoMinMatchedSamplingPoints", m_makePfoMinMatchedSamplingPoints));
446 
447  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
448  XmlHelper::ReadValue(xmlHandle, "MakePfoMinMatchedFraction", m_makePfoMinMatchedFraction));
449 
450  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
451  XmlHelper::ReadValue(xmlHandle, "MakePfoMaxImpactParameter", m_makePfoMaxImpactParameter));
452 
453  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
454  XmlHelper::ReadValue(xmlHandle, "MergeMaxChi2PerSamplingPoint", m_mergeMaxChi2PerSamplingPoint));
455 
456  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
457  XmlHelper::ReadValue(xmlHandle, "MergeXContainmentTolerance", m_mergeXContainmentTolerance));
458 
459  return STATUS_CODE_SUCCESS;
460 }
461 
462 } // namespace lar_content
float m_minMatchedFraction
The min matched sampling point fraction for particle creation.
float m_longMaxX
The max x coordinate of the long clusters.
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.
std::vector< ProtoParticle > ProtoParticleVector
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for particle creation.
const pandora::Cluster * m_pShortCluster
Address of the short cluster.
Header file for the lar pointing cluster class.
std::vector< TensorType::ElementList::const_iterator > IteratorList
Header file for the missing track segment tool class.
void GetSegmentOverlapMap(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const Particle &particle, const TwoDSlidingFitResultMap &slidingFitResultMap, SegmentOverlapMap &segmentOverlapMap) const
Get a segment overlap map, describing overlap between a provided particle and all clusters in a slidi...
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...
bool IsPossibleMerge(const pandora::Cluster *const pCluster, const Particle &particle, const SegmentOverlap &segmentOverlap, const TwoDSlidingFitResultMap &slidingFitResultMap) const
Whether the cluster could be merged with the candidate particle.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
intermediate_table::const_iterator const_iterator
float m_matchedSamplingMaxX
The max matched sampling point x coordinate.
float m_minInitialXOverlapFraction
The min x overlap fraction (between long clusters and short cluster vs. shared overlap) ...
bool PassesParticleChecks(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element, pandora::ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
Whether a provided tensor element can be used to construct a pfo.
float m_matchedSamplingMinX
The min matched sampling point x coordinate.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
void GetCandidateClusters(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const Particle &particle, pandora::ClusterList &candidateClusters) const
Get a list of candidate clusters, which may represent missing track segments for a provided particle...
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
bool Run(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
bool MakeDecisions(const Particle &particle, const TwoDSlidingFitResultMap &slidingFitResultMap, const SegmentOverlapMap &segmentOverlapMap, pandora::ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
Make decisions about whether to create a pfo for a provided particle and whether to make cluster merg...
Header file for the geometry helper class.
unsigned int m_makePfoMinMatchedSamplingPoints
The min number of matched sampling points in order to be able to make pfo.
float m_makePfoMaxImpactParameter
The max transverse impact parameter in order to be able to make pfo.
const pandora::Cluster * m_pCluster1
Address of long cluster in view 1.
unsigned int m_minCaloHitsInCandidateCluster
The min no. of calo hits in a candidate cluster, for matching with long clusters. ...
Header file for the cluster helper class.
std::void_t< T > n
std::unordered_map< const pandora::Cluster *, SegmentOverlap > SegmentOverlapMap
unsigned int m_nSamplingPoints
The number of sampling points.
void SelectElements(const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select a list of the relevant elements from a set of connected tensor elements.
void FindTracks(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ProtoParticleVector &protoParticleVector, ClusterMergeMap &clusterMergeMap) const
Find remaining tracks, hidden by missing track segments (and maybe other ambiguities) in the tensor...
pandora::ClusterList m_clusterList
List of 2D clusters in a 3D proto particle.
const pandora::Cluster * m_pCluster2
Address of long cluster in view 2.
const pandora::ClusterList & GetInputClusterList(const pandora::HitType hitType) const
Get the input cluster list corresponding to a specified hit type.
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).
Header file for the long tracks tool class.
static int max(int a, int b)
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
float m_pseudoChi2Cut
The pseudo chi2 cut to determine whether a sampling point is matched.
pandora::HitType m_hitType1
The hit type of the long cluster in view 1.
unsigned int m_minMatchedSamplingPointRatio
The min ratio between 1st and 2nd highest msps for simple ambiguity resolution.
unsigned int m_makePfoMinSamplingPoints
The min number of sampling points in order to be able to make pfo.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
float m_minFinalXOverlapFraction
The min x overlap fraction between extended short cluster and the long clusters.
float m_longMinX
The min x coordinate of the long clusters.
float m_mergeXContainmentTolerance
The tolerance in determining whether candidate cluster is contained in x window.
unsigned int m_nMatchedSamplingPoints
The number of matched sampling points.
pandora::HitType m_shortHitType
The hit type of the short cluster.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
list x
Definition: train.py:276
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
Particle(const TensorType::Element &element)
Constructor.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
static bool HasLongDirectConnections(IteratorList::const_iterator iIter, const IteratorList &iteratorList)
Whether a long element shares clusters with any other long elements.
bool PassesSamplingCuts(const SegmentOverlap &segmentOverlap) const
Whether the segment overlap object passes cuts on matched sampling points, etc.
float m_makePfoMinMatchedFraction
The min matched sampling point fraction in order to be able to make pfo.
XOverlap class.
Definition: LArXOverlap.h:17
float m_shortMaxX
The max x coordinate of the short cluster.
float m_mergeMaxChi2PerSamplingPoint
The max value of chi2 per sampling point in order to merge cluster with parent.
float m_shortMinX
The min x coordinate of the short cluster.
unsigned int GetSlidingFitWindow() const
Get the layer window for the sliding linear fits.
QTextStream & endl(QTextStream &s)
void GetSlidingFitResultMap(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const pandora::ClusterList &candidateClusterList, TwoDSlidingFitResultMap &slidingFitResultMap) const
Get a sliding fit result map for the list of candidate clusters.
pandora::HitType m_hitType2
The hit type of the long cluster in view 2.