LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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; ClusterMergeMap clusterMergeMap;
50  this->FindTracks(pAlgorithm, overlapTensor, protoParticleVector, clusterMergeMap);
51 
52  const bool particlesMade(pAlgorithm->CreateThreeDParticles(protoParticleVector));
53  const bool mergesMade(pAlgorithm->MakeClusterMerges(clusterMergeMap));
54 
55  return (particlesMade || mergesMade);
56 }
57 
58 //------------------------------------------------------------------------------------------------------------------------------------------
59 
61  ProtoParticleVector &protoParticleVector, ClusterMergeMap &clusterMergeMap) const
62 {
63  ClusterSet usedClusters;
64  ClusterVector sortedKeyClusters;
65  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
66 
67  for (const Cluster *const pKeyCluster : sortedKeyClusters)
68  {
69  if (!pKeyCluster->IsAvailable())
70  continue;
71 
72  unsigned int nU(0), nV(0), nW(0);
73  TensorType::ElementList elementList;
74  overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
75 
76  IteratorList iteratorList;
77  this->SelectElements(elementList, usedClusters, iteratorList);
78 
79  for (IteratorList::const_iterator iIter = iteratorList.begin(), iIterEnd = iteratorList.end(); iIter != iIterEnd; ++iIter)
80  {
81  if (LongTracksTool::HasLongDirectConnections(iIter, iteratorList))
82  continue;
83 
85  continue;
86 
87  if (!this->PassesParticleChecks(pAlgorithm, *(*iIter), usedClusters, clusterMergeMap))
88  continue;
89 
90  ProtoParticle protoParticle;
91  protoParticle.m_clusterListU.push_back((*iIter)->GetClusterU());
92  protoParticle.m_clusterListV.push_back((*iIter)->GetClusterV());
93  protoParticle.m_clusterListW.push_back((*iIter)->GetClusterW());
94  protoParticleVector.push_back(protoParticle);
95 
96  usedClusters.insert((*iIter)->GetClusterU());
97  usedClusters.insert((*iIter)->GetClusterV());
98  usedClusters.insert((*iIter)->GetClusterW());
99  }
100  }
101 }
102 
103 //------------------------------------------------------------------------------------------------------------------------------------------
104 
105 void MissingTrackSegmentTool::SelectElements(const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
106 {
107  for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
108  {
109  if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
110  continue;
111 
112  if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
113  continue;
114 
115  if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
116  continue;
117 
118  const XOverlap &xOverlap(eIter->GetOverlapResult().GetXOverlap());
119  const float shortSpan(std::min(xOverlap.GetXSpanU(), std::min(xOverlap.GetXSpanV(), xOverlap.GetXSpanW())));
120  const float longSpan1(std::max(xOverlap.GetXSpanU(), std::max(xOverlap.GetXSpanV(), xOverlap.GetXSpanW())));
121  const float longSpan2(((xOverlap.GetXSpanU() > shortSpan) && (xOverlap.GetXSpanU() < longSpan1)) ? xOverlap.GetXSpanU() :
122  ((xOverlap.GetXSpanV() > shortSpan) && (xOverlap.GetXSpanV() < longSpan1)) ? xOverlap.GetXSpanV() : xOverlap.GetXSpanW());
123 
124  if ((xOverlap.GetXOverlapSpan() < std::numeric_limits<float>::epsilon()) || (longSpan1 < std::numeric_limits<float>::epsilon()))
125  continue;
126 
127  if (((shortSpan / xOverlap.GetXOverlapSpan()) < m_minInitialXOverlapFraction) || ((longSpan2 / longSpan1) < m_minInitialXOverlapFraction))
128  continue;
129 
130  iteratorList.push_back(eIter);
131  }
132 }
133 
134 //------------------------------------------------------------------------------------------------------------------------------------------
135 
136 bool MissingTrackSegmentTool::PassesParticleChecks(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const TensorType::Element &element,
137  ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
138 {
139  try
140  {
141  const Particle particle(element);
142 
143  ClusterList candidateClusters;
144  this->GetCandidateClusters(pAlgorithm, particle, candidateClusters);
145 
146  if (candidateClusters.empty())
147  return false;
148 
149  TwoDSlidingFitResultMap slidingFitResultMap;
150  this->GetSlidingFitResultMap(pAlgorithm, candidateClusters, slidingFitResultMap);
151 
152  if (slidingFitResultMap.empty())
153  return false;
154 
155  SegmentOverlapMap segmentOverlapMap;
156  this->GetSegmentOverlapMap(pAlgorithm, particle, slidingFitResultMap, segmentOverlapMap);
157 
158  if (segmentOverlapMap.empty())
159  return false;
160 
161  return this->MakeDecisions(particle, slidingFitResultMap, segmentOverlapMap, usedClusters, clusterMergeMap);
162  }
163  catch (StatusCodeException &)
164  {
165  return false;
166  }
167 }
168 
169 //------------------------------------------------------------------------------------------------------------------------------------------
170 
172  ClusterList &candidateClusters) const
173 {
174  const ClusterList &clusterList((TPC_VIEW_U == particle.m_shortHitType) ? pAlgorithm->GetInputClusterListU() :
175  (TPC_VIEW_V == particle.m_shortHitType) ? pAlgorithm->GetInputClusterListV() : pAlgorithm->GetInputClusterListW());
176 
177  for (ClusterList::const_iterator iter = clusterList.begin(), iterEnd = clusterList.end(); iter != iterEnd; ++iter)
178  {
179  const Cluster *const pCluster(*iter);
180 
181  if (pCluster == particle.m_pShortCluster)
182  continue;
183 
184  if (pCluster->GetNCaloHits() < m_minCaloHitsInCandidateCluster)
185  continue;
186 
187  candidateClusters.push_back(pCluster);
188  }
189 }
190 
191 //------------------------------------------------------------------------------------------------------------------------------------------
192 
193 void MissingTrackSegmentTool::GetSlidingFitResultMap(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const ClusterList &candidateClusterList,
194  TwoDSlidingFitResultMap &slidingFitResultMap) const
195 {
196  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
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 TwoDSlidingFitResult slidingFitResult(pCluster, pAlgorithm->GetSlidingFitWindow(), slidingFitPitch);
215  (void) slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult));
216  continue;
217  }
218  catch (StatusCodeException &)
219  {
220  }
221  }
222 }
223 
224 //------------------------------------------------------------------------------------------------------------------------------------------
225 
227  const TwoDSlidingFitResultMap &slidingFitResultMap, SegmentOverlapMap &segmentOverlapMap) const
228 {
229  const TwoDSlidingFitResult &fitResult1(pAlgorithm->GetCachedSlidingFitResult(particle.m_pCluster1));
230  const TwoDSlidingFitResult &fitResult2(pAlgorithm->GetCachedSlidingFitResult(particle.m_pCluster2));
231 
232  const float nPoints1(std::fabs(static_cast<float>(fitResult1.GetMaxLayer() - fitResult1.GetMinLayer())));
233  const float nPoints2(std::fabs(static_cast<float>(fitResult2.GetMaxLayer() - fitResult2.GetMinLayer())));
234 
235  const unsigned int nPoints(static_cast<unsigned int>(1.f + (nPoints1 + nPoints2) / 2.f));
236 
237  ClusterList clusterList;
238  for (const auto &mapEntry : slidingFitResultMap) clusterList.push_back(mapEntry.first);
239  clusterList.sort(LArClusterHelper::SortByNHits);
240 
241  for (unsigned n = 0; n <= nPoints; ++n)
242  {
243  const float x(particle.m_longMinX + (particle.m_longMaxX - particle.m_longMinX) * static_cast<float>(n) / static_cast<float>(nPoints));
244 
245  if ((x > particle.m_shortMinX) && (x < particle.m_shortMaxX))
246  continue;
247 
248  CartesianVector fitVector1(0.f, 0.f, 0.f), fitVector2(0.f, 0.f, 0.f);
249 
250  if ((STATUS_CODE_SUCCESS != fitResult1.GetGlobalFitPositionAtX(x, fitVector1)) ||
251  (STATUS_CODE_SUCCESS != fitResult2.GetGlobalFitPositionAtX(x, fitVector2)))
252  {
253  continue;
254  }
255 
256  const float prediction(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), particle.m_hitType1, particle.m_hitType2, fitVector1.GetZ(), fitVector2.GetZ()));
257 
258  for (const Cluster *const pCluster : clusterList)
259  {
260  const TwoDSlidingFitResult &slidingFitResult(slidingFitResultMap.at(pCluster));
261  CartesianVector fitVector(0.f, 0.f, 0.f), fitDirection(0.f, 0.f, 0.f);
262 
263  if ((STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitPositionAtX(x, fitVector)) ||
264  (STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitDirectionAtX(x, fitDirection)))
265  {
266  continue;
267  }
268 
269  const float delta((prediction - fitVector.GetZ()) * fitDirection.GetX());
270  const float pseudoChi2(delta * delta);
271 
272  SegmentOverlap &segmentOverlap(segmentOverlapMap[pCluster]);
273  ++segmentOverlap.m_nSamplingPoints;
274  segmentOverlap.m_pseudoChi2Sum += pseudoChi2;
275 
276  if (pseudoChi2 < m_pseudoChi2Cut)
277  {
278  ++segmentOverlap.m_nMatchedSamplingPoints;
279  segmentOverlap.m_matchedSamplingMinX = std::min(x, segmentOverlap.m_matchedSamplingMinX);
280  segmentOverlap.m_matchedSamplingMaxX = std::max(x, segmentOverlap.m_matchedSamplingMaxX);
281  }
282  }
283  }
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
288 bool MissingTrackSegmentTool::MakeDecisions(const Particle &particle, const TwoDSlidingFitResultMap &slidingFitResultMap,
289  const SegmentOverlapMap &segmentOverlapMap, ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
290 {
291  ClusterVector possibleMerges;
292  float shortMinX(particle.m_shortMinX), shortMaxX(particle.m_shortMaxX);
293  bool matchesACluster(false);
294 
295  ClusterVector sortedClusters;
296  for (const auto &mapEntry : segmentOverlapMap) sortedClusters.push_back(mapEntry.first);
297  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
298 
299  for (const Cluster *const pCluster : sortedClusters)
300  {
301  const SegmentOverlap &segmentOverlap(segmentOverlapMap.at(pCluster));
302 
303  if (!this->PassesSamplingCuts(segmentOverlap))
304  continue;
305 
306  shortMinX = std::min(segmentOverlap.m_matchedSamplingMinX, shortMinX);
307  shortMaxX = std::max(segmentOverlap.m_matchedSamplingMaxX, shortMaxX);
308  matchesACluster = true;
309 
310  // Allow pfo construction if find hits in an unavailable cluster, but can't merge unavailable cluster into this pfo
311  if (!usedClusters.insert(pCluster).second || !pCluster->IsAvailable())
312  continue;
313 
314  if (!this->IsPossibleMerge(pCluster, particle, segmentOverlap, slidingFitResultMap))
315  continue;
316 
317  possibleMerges.push_back(pCluster);
318  }
319 
320  if (std::fabs(particle.m_longMaxX - particle.m_longMinX) < std::numeric_limits<float>::epsilon())
321  throw StatusCodeException(STATUS_CODE_FAILURE);
322 
323  if (!matchesACluster || possibleMerges.empty())
324  return false;
325 
326  if (((shortMaxX - shortMinX) / (particle.m_longMaxX - particle.m_longMinX)) < m_minFinalXOverlapFraction)
327  return false;
328 
329  ClusterList &clusterList(clusterMergeMap[particle.m_pShortCluster]);
330  clusterList.insert(clusterList.end(), possibleMerges.begin(), possibleMerges.end());
331  return true;
332 }
333 
334 //------------------------------------------------------------------------------------------------------------------------------------------
335 
337 {
338  if (0 == segmentOverlap.m_nSamplingPoints)
339  return false;
340 
342  return false;
343 
344  if ((static_cast<float>(segmentOverlap.m_nMatchedSamplingPoints) / static_cast<float>(segmentOverlap.m_nSamplingPoints)) < m_makePfoMinMatchedFraction)
345  return false;
346 
347  return true;
348 }
349 
350 //------------------------------------------------------------------------------------------------------------------------------------------
351 
352 bool MissingTrackSegmentTool::IsPossibleMerge(const Cluster *const pCluster, const Particle &particle, const SegmentOverlap &segmentOverlap,
353  const TwoDSlidingFitResultMap &slidingFitResultMap) const
354 {
355  if ((segmentOverlap.m_pseudoChi2Sum / static_cast<float>(segmentOverlap.m_nSamplingPoints)) > m_mergeMaxChi2PerSamplingPoint)
356  return false;
357 
358  TwoDSlidingFitResultMap::const_iterator fitIter = slidingFitResultMap.find(pCluster);
359 
360  if (slidingFitResultMap.end() == fitIter)
361  throw StatusCodeException(STATUS_CODE_FAILURE);
362 
363  float mergeMinX(std::numeric_limits<float>::max()), mergeMaxX(-std::numeric_limits<float>::max());
364  fitIter->second.GetMinAndMaxX(mergeMinX, mergeMaxX);
365 
366  // cluster should not be wider than the longest span
367  if ((mergeMinX < particle.m_longMinX - m_mergeXContainmentTolerance) || (mergeMaxX > particle.m_longMaxX + m_mergeXContainmentTolerance))
368  return false;
369 
370  // cluster should not overlap with the shortest span
371  if ((mergeMinX < particle.m_shortMaxX - m_mergeXContainmentTolerance) && (mergeMaxX > particle.m_shortMinX + m_mergeXContainmentTolerance))
372  return false;
373 
374  return true;
375 }
376 
377 //------------------------------------------------------------------------------------------------------------------------------------------
378 //------------------------------------------------------------------------------------------------------------------------------------------
379 
380 MissingTrackSegmentTool::Particle::Particle(const TensorType::Element &element)
381 {
382  const XOverlap &xOverlap(element.GetOverlapResult().GetXOverlap());
383 
384  m_shortHitType = ((xOverlap.GetXSpanU() < xOverlap.GetXSpanV()) && (xOverlap.GetXSpanU() < xOverlap.GetXSpanW())) ? TPC_VIEW_U :
385  ((xOverlap.GetXSpanV() < xOverlap.GetXSpanU()) && (xOverlap.GetXSpanV() < xOverlap.GetXSpanW())) ? TPC_VIEW_V :
386  ((xOverlap.GetXSpanW() < xOverlap.GetXSpanU()) && (xOverlap.GetXSpanW() < xOverlap.GetXSpanV())) ? TPC_VIEW_W : HIT_CUSTOM;
387 
388  if (HIT_CUSTOM == m_shortHitType)
389  throw StatusCodeException(STATUS_CODE_FAILURE);
390 
391  m_pShortCluster = (TPC_VIEW_U == m_shortHitType) ? element.GetClusterU() : (TPC_VIEW_V == m_shortHitType) ? element.GetClusterV() : element.GetClusterW();
392  m_pCluster1 = (TPC_VIEW_U == m_shortHitType) ? element.GetClusterV() : element.GetClusterU();
393  m_pCluster2 = (TPC_VIEW_W == m_shortHitType) ? element.GetClusterV() : element.GetClusterW();
394  m_shortMinX = (TPC_VIEW_U == m_shortHitType) ? xOverlap.GetUMinX() : (TPC_VIEW_V == m_shortHitType) ? xOverlap.GetVMinX() : xOverlap.GetWMinX();
395  m_shortMaxX = (TPC_VIEW_U == m_shortHitType) ? xOverlap.GetUMaxX() : (TPC_VIEW_V == m_shortHitType) ? xOverlap.GetVMaxX() : xOverlap.GetWMaxX();
396  m_longMinX = (TPC_VIEW_U == m_shortHitType) ? std::min(xOverlap.GetVMinX(), xOverlap.GetWMinX()) : (TPC_VIEW_V == m_shortHitType) ? std::min(xOverlap.GetUMinX(), xOverlap.GetWMinX()) : std::min(xOverlap.GetUMinX(), xOverlap.GetVMinX());
397  m_longMaxX = (TPC_VIEW_U == m_shortHitType) ? std::max(xOverlap.GetVMaxX(), xOverlap.GetWMaxX()) : (TPC_VIEW_V == m_shortHitType) ? std::max(xOverlap.GetUMaxX(), xOverlap.GetWMaxX()) : std::max(xOverlap.GetUMaxX(), xOverlap.GetVMaxX());
398 
399  m_hitType1 = LArClusterHelper::GetClusterHitType(m_pCluster1);
400  m_hitType2 = LArClusterHelper::GetClusterHitType(m_pCluster2);
401 }
402 
403 //------------------------------------------------------------------------------------------------------------------------------------------
404 //------------------------------------------------------------------------------------------------------------------------------------------
405 
406 StatusCode MissingTrackSegmentTool::ReadSettings(const TiXmlHandle xmlHandle)
407 {
408  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
409  "MinMatchedFraction", m_minMatchedFraction));
410 
411  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
412  "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
413 
414  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
415  "MinMatchedSamplingPointRatio", m_minMatchedSamplingPointRatio));
416 
417  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
418  "MinInitialXOverlapFraction", m_minInitialXOverlapFraction));
419 
420  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
421  "MinFinalXOverlapFraction", m_minFinalXOverlapFraction));
422 
423  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
424  "MinCaloHitsInCandidateCluster", m_minCaloHitsInCandidateCluster));
425 
426  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
427  "PseudoChi2Cut", m_pseudoChi2Cut));
428 
429  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
430  "MakePfoMinSamplingPoints", m_makePfoMinSamplingPoints));
431 
432  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
433  "MakePfoMinMatchedSamplingPoints", m_makePfoMinMatchedSamplingPoints));
434 
435  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
436  "MakePfoMinMatchedFraction", m_makePfoMinMatchedFraction));
437 
438  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
439  "MakePfoMaxImpactParameter", m_makePfoMaxImpactParameter));
440 
441  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
442  "MergeMaxChi2PerSamplingPoint", m_mergeMaxChi2PerSamplingPoint));
443 
444  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
445  "MergeXContainmentTolerance", m_mergeXContainmentTolerance));
446 
447  return STATUS_CODE_SUCCESS;
448 }
449 
450 } // 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.
void GetSlidingFitResultMap(ThreeDTransverseTracksAlgorithm *const pAlgorithm, const pandora::ClusterList &candidateClusterList, TwoDSlidingFitResultMap &slidingFitResultMap) const
Get a sliding fit result map for the list of candidate clusters.
std::vector< ProtoParticle > ProtoParticleVector
const pandora::ClusterList & GetInputClusterListW() const
Get the input w cluster list.
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.
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...
void GetSegmentOverlapMap(ThreeDTransverseTracksAlgorithm *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...
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.
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)
void GetCandidateClusters(ThreeDTransverseTracksAlgorithm *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...
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) ...
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.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
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.
pandora::ClusterList m_clusterListW
List of 2D W clusters in a 3D proto particle.
unsigned int m_makePfoMinMatchedSamplingPoints
The min number of matched sampling points in order to be able to make pfo.
Int_t max
Definition: plot.C:27
const pandora::ClusterList & GetInputClusterListV() const
Get the input v cluster list.
intermediate_table::const_iterator const_iterator
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.
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.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
bool Run(ThreeDTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
const pandora::Cluster * m_pCluster2
Address of long cluster in view 2.
pandora::ClusterList m_clusterListV
List of 2D V clusters in a 3D proto particle.
const pandora::ClusterList & GetInputClusterListU() const
Get the input u cluster list.
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).
pandora::ClusterList m_clusterListU
List of 2D U clusters in a 3D proto particle.
Header file for the long tracks tool class.
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
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::vector< art::Ptr< recob::Cluster > > ClusterVector
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.
Int_t min
Definition: plot.C:26
void FindTracks(ThreeDTransverseTracksAlgorithm *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...
Char_t n[5]
Particle(const TensorType::Element &element)
Constructor.
std::unordered_map< const pandora::Cluster *, SegmentOverlap > SegmentOverlapMap
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.
bool PassesParticleChecks(ThreeDTransverseTracksAlgorithm *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_shortMinX
The min x coordinate of the short cluster.
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
pandora::HitType m_hitType2
The hit type of the long cluster in view 2.
unsigned int GetSlidingFitWindow() const
Get the layer window for the sliding linear fits.