LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
MissingTrackSegmentTool.cc
Go to the documentation of this file.
1 
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(((xOverlap.GetXSpanU() > shortSpan) && (xOverlap.GetXSpanU() < longSpan1)) ? xOverlap.GetXSpanU()
124  : ((xOverlap.GetXSpanV() > shortSpan) && (xOverlap.GetXSpanV() < longSpan1)) ? xOverlap.GetXSpanV()
125  : xOverlap.GetXSpanW());
126 
127  if ((xOverlap.GetXOverlapSpan() < std::numeric_limits<float>::epsilon()) || (longSpan1 < std::numeric_limits<float>::epsilon()))
128  continue;
129 
130  if (((shortSpan / xOverlap.GetXOverlapSpan()) < m_minInitialXOverlapFraction) || ((longSpan2 / longSpan1) < m_minInitialXOverlapFraction))
131  continue;
132 
133  iteratorList.push_back(eIter);
134  }
135 }
136 
137 //------------------------------------------------------------------------------------------------------------------------------------------
138 
139 bool MissingTrackSegmentTool::PassesParticleChecks(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element,
140  ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
141 {
142  try
143  {
144  const Particle particle(element);
145 
146  ClusterList candidateClusters;
147  this->GetCandidateClusters(pAlgorithm, particle, candidateClusters);
148 
149  if (candidateClusters.empty())
150  return false;
151 
152  TwoDSlidingFitResultMap slidingFitResultMap;
153  this->GetSlidingFitResultMap(pAlgorithm, candidateClusters, slidingFitResultMap);
154 
155  if (slidingFitResultMap.empty())
156  return false;
157 
158  SegmentOverlapMap segmentOverlapMap;
159  this->GetSegmentOverlapMap(pAlgorithm, particle, slidingFitResultMap, segmentOverlapMap);
160 
161  if (segmentOverlapMap.empty())
162  return false;
163 
164  return this->MakeDecisions(particle, slidingFitResultMap, segmentOverlapMap, usedClusters, clusterMergeMap);
165  }
166  catch (StatusCodeException &)
167  {
168  return false;
169  }
170 }
171 
172 //------------------------------------------------------------------------------------------------------------------------------------------
173 
175  ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const Particle &particle, ClusterList &candidateClusters) const
176 {
177  const ClusterList &clusterList(pAlgorithm->GetInputClusterList(particle.m_shortHitType));
178 
179  for (ClusterList::const_iterator iter = clusterList.begin(), iterEnd = clusterList.end(); iter != iterEnd; ++iter)
180  {
181  const Cluster *const pCluster(*iter);
182 
183  if (pCluster == particle.m_pShortCluster)
184  continue;
185 
186  if (pCluster->GetNCaloHits() < m_minCaloHitsInCandidateCluster)
187  continue;
188 
189  candidateClusters.push_back(pCluster);
190  }
191 }
192 
193 //------------------------------------------------------------------------------------------------------------------------------------------
194 
196  const ClusterList &candidateClusterList, TwoDSlidingFitResultMap &slidingFitResultMap) const
197 {
198  for (ClusterList::const_iterator iter = candidateClusterList.begin(), iterEnd = candidateClusterList.end(); iter != iterEnd; ++iter)
199  {
200  const Cluster *const pCluster(*iter);
201 
202  try
203  {
204  const TwoDSlidingFitResult &slidingFitResult(pAlgorithm->GetCachedSlidingFitResult(pCluster));
205  (void)slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult));
206  continue;
207  }
208  catch (StatusCodeException &)
209  {
210  }
211 
212  try
213  {
214  const float slidingFitPitch(LArGeometryHelper::GetWirePitch(this->GetPandora(), LArClusterHelper::GetClusterHitType(pCluster)));
215  const TwoDSlidingFitResult slidingFitResult(pCluster, pAlgorithm->GetSlidingFitWindow(), slidingFitPitch);
216  (void)slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult));
217  continue;
218  }
219  catch (StatusCodeException &)
220  {
221  }
222  }
223 }
224 
225 //------------------------------------------------------------------------------------------------------------------------------------------
226 
228  const TwoDSlidingFitResultMap &slidingFitResultMap, SegmentOverlapMap &segmentOverlapMap) const
229 {
230  const TwoDSlidingFitResult &fitResult1(pAlgorithm->GetCachedSlidingFitResult(particle.m_pCluster1));
231  const TwoDSlidingFitResult &fitResult2(pAlgorithm->GetCachedSlidingFitResult(particle.m_pCluster2));
232 
233  const float nPoints1(std::fabs(static_cast<float>(fitResult1.GetMaxLayer() - fitResult1.GetMinLayer())));
234  const float nPoints2(std::fabs(static_cast<float>(fitResult2.GetMaxLayer() - fitResult2.GetMinLayer())));
235 
236  const unsigned int nPoints(static_cast<unsigned int>(1.f + (nPoints1 + nPoints2) / 2.f));
237 
238  ClusterList clusterList;
239  for (const auto &mapEntry : slidingFitResultMap)
240  clusterList.push_back(mapEntry.first);
241  clusterList.sort(LArClusterHelper::SortByNHits);
242 
243  for (unsigned n = 0; n <= nPoints; ++n)
244  {
245  const float x(particle.m_longMinX + (particle.m_longMaxX - particle.m_longMinX) * static_cast<float>(n) / static_cast<float>(nPoints));
246 
247  if ((x > particle.m_shortMinX) && (x < particle.m_shortMaxX))
248  continue;
249 
250  CartesianVector fitVector1(0.f, 0.f, 0.f), fitVector2(0.f, 0.f, 0.f);
251 
252  if ((STATUS_CODE_SUCCESS != fitResult1.GetGlobalFitPositionAtX(x, fitVector1)) ||
253  (STATUS_CODE_SUCCESS != fitResult2.GetGlobalFitPositionAtX(x, fitVector2)))
254  {
255  continue;
256  }
257 
258  const float prediction(LArGeometryHelper::MergeTwoPositions(
259  this->GetPandora(), particle.m_hitType1, particle.m_hitType2, fitVector1.GetZ(), fitVector2.GetZ()));
260 
261  for (const Cluster *const pCluster : clusterList)
262  {
263  const TwoDSlidingFitResult &slidingFitResult(slidingFitResultMap.at(pCluster));
264  CartesianVector fitVector(0.f, 0.f, 0.f), fitDirection(0.f, 0.f, 0.f);
265 
266  if ((STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitPositionAtX(x, fitVector)) ||
267  (STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitDirectionAtX(x, fitDirection)))
268  {
269  continue;
270  }
271 
272  const float delta((prediction - fitVector.GetZ()) * fitDirection.GetX());
273  const float pseudoChi2(delta * delta);
274 
275  SegmentOverlap &segmentOverlap(segmentOverlapMap[pCluster]);
276  ++segmentOverlap.m_nSamplingPoints;
277  segmentOverlap.m_pseudoChi2Sum += pseudoChi2;
278 
279  if (pseudoChi2 < m_pseudoChi2Cut)
280  {
281  ++segmentOverlap.m_nMatchedSamplingPoints;
282  segmentOverlap.m_matchedSamplingMinX = std::min(x, segmentOverlap.m_matchedSamplingMinX);
283  segmentOverlap.m_matchedSamplingMaxX = std::max(x, segmentOverlap.m_matchedSamplingMaxX);
284  }
285  }
286  }
287 }
288 
289 //------------------------------------------------------------------------------------------------------------------------------------------
290 
291 bool MissingTrackSegmentTool::MakeDecisions(const Particle &particle, const TwoDSlidingFitResultMap &slidingFitResultMap,
292  const SegmentOverlapMap &segmentOverlapMap, ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
293 {
294  ClusterVector possibleMerges;
295  float shortMinX(particle.m_shortMinX), shortMaxX(particle.m_shortMaxX);
296  bool matchesACluster(false);
297 
298  ClusterVector sortedClusters;
299  for (const auto &mapEntry : segmentOverlapMap)
300  sortedClusters.push_back(mapEntry.first);
301  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
302 
303  for (const Cluster *const pCluster : sortedClusters)
304  {
305  const SegmentOverlap &segmentOverlap(segmentOverlapMap.at(pCluster));
306 
307  if (!this->PassesSamplingCuts(segmentOverlap))
308  continue;
309 
310  shortMinX = std::min(segmentOverlap.m_matchedSamplingMinX, shortMinX);
311  shortMaxX = std::max(segmentOverlap.m_matchedSamplingMaxX, shortMaxX);
312  matchesACluster = true;
313 
314  // Allow pfo construction if find hits in an unavailable cluster, but can't merge unavailable cluster into this pfo
315  if (!usedClusters.insert(pCluster).second || !pCluster->IsAvailable())
316  continue;
317 
318  if (!this->IsPossibleMerge(pCluster, particle, segmentOverlap, slidingFitResultMap))
319  continue;
320 
321  possibleMerges.push_back(pCluster);
322  }
323 
324  if (std::fabs(particle.m_longMaxX - particle.m_longMinX) < std::numeric_limits<float>::epsilon())
325  throw StatusCodeException(STATUS_CODE_FAILURE);
326 
327  if (!matchesACluster || possibleMerges.empty())
328  return false;
329 
330  if (((shortMaxX - shortMinX) / (particle.m_longMaxX - particle.m_longMinX)) < m_minFinalXOverlapFraction)
331  return false;
332 
333  ClusterList &clusterList(clusterMergeMap[particle.m_pShortCluster]);
334  clusterList.insert(clusterList.end(), possibleMerges.begin(), possibleMerges.end());
335  return true;
336 }
337 
338 //------------------------------------------------------------------------------------------------------------------------------------------
339 
341 {
342  if (0 == segmentOverlap.m_nSamplingPoints)
343  return false;
344 
346  return false;
347 
348  if ((static_cast<float>(segmentOverlap.m_nMatchedSamplingPoints) / static_cast<float>(segmentOverlap.m_nSamplingPoints)) < m_makePfoMinMatchedFraction)
349  return false;
350 
351  return true;
352 }
353 
354 //------------------------------------------------------------------------------------------------------------------------------------------
355 
356 bool MissingTrackSegmentTool::IsPossibleMerge(const Cluster *const pCluster, const Particle &particle, const SegmentOverlap &segmentOverlap,
357  const TwoDSlidingFitResultMap &slidingFitResultMap) const
358 {
359  if ((segmentOverlap.m_pseudoChi2Sum / static_cast<float>(segmentOverlap.m_nSamplingPoints)) > m_mergeMaxChi2PerSamplingPoint)
360  return false;
361 
362  TwoDSlidingFitResultMap::const_iterator fitIter = slidingFitResultMap.find(pCluster);
363 
364  if (slidingFitResultMap.end() == fitIter)
365  throw StatusCodeException(STATUS_CODE_FAILURE);
366 
367  float mergeMinX(std::numeric_limits<float>::max()), mergeMaxX(-std::numeric_limits<float>::max());
368  fitIter->second.GetMinAndMaxX(mergeMinX, mergeMaxX);
369 
370  // cluster should not be wider than the longest span
371  if ((mergeMinX < particle.m_longMinX - m_mergeXContainmentTolerance) || (mergeMaxX > particle.m_longMaxX + m_mergeXContainmentTolerance))
372  return false;
373 
374  // cluster should not overlap with the shortest span
375  if ((mergeMinX < particle.m_shortMaxX - m_mergeXContainmentTolerance) && (mergeMaxX > particle.m_shortMinX + m_mergeXContainmentTolerance))
376  return false;
377 
378  return true;
379 }
380 
381 //------------------------------------------------------------------------------------------------------------------------------------------
382 //------------------------------------------------------------------------------------------------------------------------------------------
383 
384 MissingTrackSegmentTool::Particle::Particle(const TensorType::Element &element)
385 {
386  const XOverlap &xOverlap(element.GetOverlapResult().GetXOverlap());
387 
388  m_shortHitType = ((xOverlap.GetXSpanU() < xOverlap.GetXSpanV()) && (xOverlap.GetXSpanU() < xOverlap.GetXSpanW())) ? TPC_VIEW_U
389  : ((xOverlap.GetXSpanV() < xOverlap.GetXSpanU()) && (xOverlap.GetXSpanV() < xOverlap.GetXSpanW())) ? TPC_VIEW_V
390  : ((xOverlap.GetXSpanW() < xOverlap.GetXSpanU()) && (xOverlap.GetXSpanW() < xOverlap.GetXSpanV())) ? TPC_VIEW_W
391  : HIT_CUSTOM;
392 
393  if (HIT_CUSTOM == m_shortHitType)
394  throw StatusCodeException(STATUS_CODE_FAILURE);
395 
396  m_pShortCluster = (TPC_VIEW_U == m_shortHitType) ? element.GetClusterU()
397  : (TPC_VIEW_V == m_shortHitType) ? element.GetClusterV()
398  : element.GetClusterW();
399  m_pCluster1 = (TPC_VIEW_U == m_shortHitType) ? element.GetClusterV() : element.GetClusterU();
400  m_pCluster2 = (TPC_VIEW_W == m_shortHitType) ? element.GetClusterV() : element.GetClusterW();
401  m_shortMinX = (TPC_VIEW_U == m_shortHitType) ? xOverlap.GetUMinX()
402  : (TPC_VIEW_V == m_shortHitType) ? xOverlap.GetVMinX()
403  : xOverlap.GetWMinX();
404  m_shortMaxX = (TPC_VIEW_U == m_shortHitType) ? xOverlap.GetUMaxX()
405  : (TPC_VIEW_V == m_shortHitType) ? xOverlap.GetVMaxX()
406  : xOverlap.GetWMaxX();
407  m_longMinX = (TPC_VIEW_U == m_shortHitType) ? std::min(xOverlap.GetVMinX(), xOverlap.GetWMinX())
408  : (TPC_VIEW_V == m_shortHitType) ? std::min(xOverlap.GetUMinX(), xOverlap.GetWMinX())
409  : std::min(xOverlap.GetUMinX(), xOverlap.GetVMinX());
410  m_longMaxX = (TPC_VIEW_U == m_shortHitType) ? std::max(xOverlap.GetVMaxX(), xOverlap.GetWMaxX())
411  : (TPC_VIEW_V == m_shortHitType) ? std::max(xOverlap.GetUMaxX(), xOverlap.GetWMaxX())
412  : std::max(xOverlap.GetUMaxX(), xOverlap.GetVMaxX());
413 
414  m_hitType1 = LArClusterHelper::GetClusterHitType(m_pCluster1);
415  m_hitType2 = LArClusterHelper::GetClusterHitType(m_pCluster2);
416 }
417 
418 //------------------------------------------------------------------------------------------------------------------------------------------
419 //------------------------------------------------------------------------------------------------------------------------------------------
420 
421 StatusCode MissingTrackSegmentTool::ReadSettings(const TiXmlHandle xmlHandle)
422 {
423  PANDORA_RETURN_RESULT_IF_AND_IF(
424  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
425 
426  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
427  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
428 
429  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
430  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPointRatio", m_minMatchedSamplingPointRatio));
431 
432  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
433  XmlHelper::ReadValue(xmlHandle, "MinInitialXOverlapFraction", m_minInitialXOverlapFraction));
434 
435  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
436  XmlHelper::ReadValue(xmlHandle, "MinFinalXOverlapFraction", m_minFinalXOverlapFraction));
437 
438  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
439  XmlHelper::ReadValue(xmlHandle, "MinCaloHitsInCandidateCluster", m_minCaloHitsInCandidateCluster));
440 
441  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PseudoChi2Cut", m_pseudoChi2Cut));
442 
443  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
444  XmlHelper::ReadValue(xmlHandle, "MakePfoMinSamplingPoints", m_makePfoMinSamplingPoints));
445 
446  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
447  XmlHelper::ReadValue(xmlHandle, "MakePfoMinMatchedSamplingPoints", m_makePfoMinMatchedSamplingPoints));
448 
449  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
450  XmlHelper::ReadValue(xmlHandle, "MakePfoMinMatchedFraction", m_makePfoMinMatchedFraction));
451 
452  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
453  XmlHelper::ReadValue(xmlHandle, "MakePfoMaxImpactParameter", m_makePfoMaxImpactParameter));
454 
455  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
456  XmlHelper::ReadValue(xmlHandle, "MergeMaxChi2PerSamplingPoint", m_mergeMaxChi2PerSamplingPoint));
457 
458  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
459  XmlHelper::ReadValue(xmlHandle, "MergeXContainmentTolerance", m_mergeXContainmentTolerance));
460 
461  return STATUS_CODE_SUCCESS;
462 }
463 
464 } // namespace lar_content
Float_t x
Definition: compare.C:6
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...
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...
TFile f
Definition: plotHisto.C:6
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::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).
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
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 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.
Char_t n[5]
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.
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.