CosmicRayRemovalTool.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArTransverseTrackMatching/CosmicRayRemovalTool.cc
3  *
4  * @brief Implementation of the cosmic ray removal tool class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
17 
18 using namespace pandora;
19 
20 namespace lar_content
21 {
22 
23 CosmicRayRemovalTool::CosmicRayRemovalTool() :
24  m_slidingFitWindow(10000),
25  m_minContaminationLength(3.f),
26  m_maxDistanceToHit(1.f),
27  m_minRemnantClusterSize(3),
28  m_maxDistanceToTrack(2.f)
29 {
30 }
31 
32 //------------------------------------------------------------------------------------------------------------------------------------------
33 
35 {
36  m_pParentAlgorithm = pAlgorithm;
37 
38  if (PandoraContentApi::GetSettings(*m_pParentAlgorithm)->ShouldDisplayAlgorithmInfo())
39  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
40 
41  bool changesMade(false);
42 
43  ClusterVector sortedKeyClusters;
44  overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
45 
46  ClusterSet usedKeyClusters;
47  for (const Cluster *const pKeyCluster : sortedKeyClusters)
48  {
49  if (usedKeyClusters.count(pKeyCluster))
50  continue;
51 
52  TensorType::ElementList elementList;
53  overlapTensor.GetConnectedElements(pKeyCluster, true, elementList);
54 
55  for (const TensorType::Element &element : elementList)
56  usedKeyClusters.insert(element.GetClusterU());
57 
58  const bool changesMadeInIteration = this->RemoveCosmicRayHits(elementList);
59 
60  changesMade = (changesMade ? changesMade : changesMadeInIteration);
61  }
62 
63  return changesMade;
64 }
65 
66 //------------------------------------------------------------------------------------------------------------------------------------------
67 
69 {
70  ClusterSet modifiedClusters, checkedClusters;
71 
72  for (const TensorType::Element &element : elementList)
73  {
74  for (const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
75  {
76  const Cluster *const pDeltaRayCluster(element.GetCluster(hitType));
77 
78  if (checkedClusters.count(pDeltaRayCluster))
79  continue;
80 
81  // ATTN: The underlying tensor will update during this loop, do not proceed if element has been modified
82  if ((modifiedClusters.count(element.GetClusterU())) || (modifiedClusters.count(element.GetClusterV())) ||
83  (modifiedClusters.count(element.GetClusterW())))
84  continue;
85 
86  if (!this->PassElementChecks(element, hitType))
87  continue;
88 
89  if (!this->IsContaminated(element, hitType))
90  continue;
91 
92  if (!this->IsBestElement(element, hitType, elementList, modifiedClusters))
93  continue;
94 
95  checkedClusters.insert(pDeltaRayCluster);
96 
97  CaloHitList deltaRayHits;
98  this->CreateSeed(element, hitType, deltaRayHits);
99 
100  if (deltaRayHits.empty())
101  continue;
102 
103  // ATTN: Abort if seed cannot be grown
104  CaloHitList remnantHits;
105  if (this->GrowSeed(element, hitType, deltaRayHits, remnantHits) != STATUS_CODE_SUCCESS)
106  continue;
107 
108  // ATTN: Abort if reformed DR cluster
109  if (deltaRayHits.size() == pDeltaRayCluster->GetNCaloHits())
110  continue;
111 
112  modifiedClusters.insert(pDeltaRayCluster);
113 
114  this->SplitDeltaRayCluster(element, hitType, deltaRayHits, remnantHits);
115  }
116  }
117 
118  return !modifiedClusters.empty();
119 }
120 
121 //------------------------------------------------------------------------------------------------------------------------------------------
122 
123 bool CosmicRayRemovalTool::PassElementChecks(const TensorType::Element &element, const HitType hitType) const
124 {
125  // ATTN: Avoid endpoints, topological michel reconstruction is very ambiguous
126  if (this->IsMuonEndpoint(element, true, hitType))
127  return false;
128 
129  return RemovalBaseTool::PassElementChecks(element, hitType);
130 }
131 
132 //------------------------------------------------------------------------------------------------------------------------------------------
133 
134 bool CosmicRayRemovalTool::IsContaminated(const TensorType::Element &element, const HitType hitType) const
135 {
136  const Cluster *pMuonCluster(nullptr), *const pDeltaRayCluster(element.GetCluster(hitType));
137 
138  if (m_pParentAlgorithm->GetMuonCluster(element.GetOverlapResult().GetCommonMuonPfoList(), hitType, pMuonCluster) != STATUS_CODE_SUCCESS)
139  return false;
140 
141  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
142  const TwoDSlidingFitResult slidingFitResult(pMuonCluster, m_slidingFitWindow, slidingFitPitch);
143 
144  CartesianVector muonDirection(0.f, 0.f, 0.f);
145  slidingFitResult.GetGlobalDirection(slidingFitResult.GetLayerFitResultMap().begin()->second.GetGradient(), muonDirection);
146 
147  CartesianVector deltaRayVertex(0.f, 0.f, 0.f), muonVertex(0.f, 0.f, 0.f);
148  LArClusterHelper::GetClosestPositions(pDeltaRayCluster, pMuonCluster, deltaRayVertex, muonVertex);
149 
150  // Find furthest point in DR cluster that lies on the projected muon track
151  float furthestSeparation(0.f);
152  CartesianVector extendedPoint(0.f, 0.f, 0.f);
153 
154  CaloHitList deltaRayHitList;
155  pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
156 
157  for (const CaloHit *const pCaloHit : deltaRayHitList)
158  {
159  const CartesianVector &position(pCaloHit->GetPositionVector());
160  const float separation((position - muonVertex).GetMagnitude());
161 
162  if (separation > furthestSeparation)
163  {
164  if (this->IsCloseToLine(position, muonVertex, muonVertex + muonDirection, m_distanceToLine))
165  {
166  furthestSeparation = separation;
167  extendedPoint = position;
168  }
169  }
170  }
171 
172  // Check if delta ray has significant track contamination
173  if (furthestSeparation < m_minContaminationLength)
174  return false;
175 
176  // ATTN: Avoid cases where opening angle is small - it is easy to make mistakes in these instances
177  CaloHitList muonHitList;
178  pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(muonHitList);
179 
180  for (const CaloHit *const pCaloHit : muonHitList)
181  {
182  if (this->IsInLineSegment(deltaRayVertex, extendedPoint, pCaloHit->GetPositionVector()))
183  return false;
184  }
185 
186  return true;
187 }
188 
189 //------------------------------------------------------------------------------------------------------------------------------------------
190 
191 void CosmicRayRemovalTool::CreateSeed(const TensorType::Element &element, const HitType hitType, CaloHitList &collectedHits) const
192 {
193  // To avoid fluctuations, parameterise the muon track
194  CartesianVector positionOnMuon(0.f, 0.f, 0.f), muonDirection(0.f, 0.f, 0.f);
195  if (m_pParentAlgorithm->ParameteriseMuon(element.GetOverlapResult().GetCommonMuonPfoList().front(), element.GetCluster(hitType),
196  positionOnMuon, muonDirection) != STATUS_CODE_SUCCESS)
197  return;
198 
199  CartesianPointVector deltaRayProjectedPositions;
200  if (this->ProjectDeltaRayPositions(element, hitType, deltaRayProjectedPositions) != STATUS_CODE_SUCCESS)
201  return;
202 
203  CaloHitList deltaRayHitList;
204  element.GetCluster(hitType)->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
205 
206  CaloHitVector deltaRayHitVector(deltaRayHitList.begin(), deltaRayHitList.end());
207  std::sort(deltaRayHitVector.begin(), deltaRayHitVector.end(), LArClusterHelper::SortHitsByPosition);
208 
209  for (const CaloHit *const pCaloHit : deltaRayHitVector)
210  {
211  const CartesianVector &position(pCaloHit->GetPositionVector());
212 
213  for (const CartesianVector &projectedPosition : deltaRayProjectedPositions)
214  {
215  const float distanceToProjectionSquared((position - projectedPosition).GetMagnitudeSquared());
216 
217  if (distanceToProjectionSquared < m_maxDistanceToHit * m_maxDistanceToHit)
218  {
219  // To prevent gappy seeds
220  if ((!collectedHits.empty()) && (LArClusterHelper::GetClosestDistance(position, collectedHits) > m_maxDistanceToHit))
221  continue;
222 
223  const float distanceToMuonHitsSquared(muonDirection.GetCrossProduct(position - positionOnMuon).GetMagnitudeSquared());
224 
225  if (distanceToMuonHitsSquared < m_maxDistanceToHit * m_maxDistanceToHit)
226  continue;
227 
228  collectedHits.push_back(pCaloHit);
229 
230  break;
231  }
232  }
233  }
234 }
235 
236 //------------------------------------------------------------------------------------------------------------------------------------------
237 
238 StatusCode CosmicRayRemovalTool::GrowSeed(const TensorType::Element &element, const HitType hitType, CaloHitList &deltaRayHits, CaloHitList &remnantHits) const
239 {
240  const Cluster *const pDeltaRayCluster(element.GetCluster(hitType)), *pMuonCluster(nullptr);
241 
242  if (m_pParentAlgorithm->GetMuonCluster(element.GetOverlapResult().GetCommonMuonPfoList(), hitType, pMuonCluster) != STATUS_CODE_SUCCESS)
243  return STATUS_CODE_NOT_FOUND;
244 
245  // To avoid fluctuatuions, parameterise the muon track
246  CartesianVector positionOnMuon(0.f, 0.f, 0.f), muonDirection(0.f, 0.f, 0.f);
247  if (m_pParentAlgorithm->ParameteriseMuon(element.GetOverlapResult().GetCommonMuonPfoList().front(), pDeltaRayCluster, positionOnMuon,
248  muonDirection) != STATUS_CODE_SUCCESS)
249  return STATUS_CODE_NOT_FOUND;
250 
251  // Identify delta ray hits
252  this->CollectHitsFromDeltaRay(positionOnMuon, muonDirection, pDeltaRayCluster, m_maxDistanceToHit, true, deltaRayHits, deltaRayHits);
253 
254  // Identify remnant hits
255  this->CollectHitsFromDeltaRay(positionOnMuon, muonDirection, pDeltaRayCluster, m_maxDistanceToHit, false, deltaRayHits, remnantHits);
256 
257  return STATUS_CODE_SUCCESS;
258 }
259 
260 //------------------------------------------------------------------------------------------------------------------------------------------
261 
262 void CosmicRayRemovalTool::CollectHitsFromDeltaRay(const CartesianVector &positionOnMuon, const CartesianVector &muonDirection,
263  const Cluster *const pDeltaRayCluster, const float &minDistanceFromMuon, const bool demandCloserToCollected,
264  const CaloHitList &protectedHits, CaloHitList &collectedHits) const
265 {
266  CaloHitList deltaRayHitList;
267  pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
268 
269  bool hitsAdded(false);
270 
271  do
272  {
273  hitsAdded = false;
274 
275  for (const CaloHit *const pCaloHit : deltaRayHitList)
276  {
277  if (std::find(protectedHits.begin(), protectedHits.end(), pCaloHit) != protectedHits.end())
278  continue;
279 
280  if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
281  continue;
282 
283  const float distanceToCollectedHits(collectedHits.empty()
285  : LArClusterHelper::GetClosestDistance(pCaloHit->GetPositionVector(), collectedHits));
286  const float distanceToMuonHits(muonDirection.GetCrossProduct(pCaloHit->GetPositionVector() - positionOnMuon).GetMagnitude());
287 
288  if ((distanceToMuonHits < minDistanceFromMuon) || (demandCloserToCollected && (distanceToCollectedHits > distanceToMuonHits)))
289  continue;
290 
291  collectedHits.push_back(pCaloHit);
292  hitsAdded = true;
293  }
294  } while (hitsAdded);
295 }
296 
297 //------------------------------------------------------------------------------------------------------------------------------------------
298 
300  const TensorType::Element &element, const HitType hitType, CaloHitList &collectedHits, CaloHitList &deltaRayRemnantHits) const
301 {
302  const Cluster *const pDeltaRayCluster(element.GetCluster(hitType)), *pMuonCluster(nullptr);
303 
304  if (m_pParentAlgorithm->GetMuonCluster(element.GetOverlapResult().GetCommonMuonPfoList(), hitType, pMuonCluster) != STATUS_CODE_SUCCESS)
305  return;
306 
307  m_pParentAlgorithm->UpdateUponDeletion(pMuonCluster);
308  m_pParentAlgorithm->UpdateUponDeletion(pDeltaRayCluster);
309 
310  std::string originalListName, fragmentListName;
311  ClusterList originalClusterList(1, pDeltaRayCluster);
312 
313  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
314  PandoraContentApi::ReplaceCurrentList<Cluster>(*m_pParentAlgorithm, m_pParentAlgorithm->GetClusterListName(hitType)));
315  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
316  PandoraContentApi::InitializeFragmentation(*m_pParentAlgorithm, originalClusterList, originalListName, fragmentListName));
317 
318  CaloHitList deltaRayHitList;
319  pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
320 
321  const Cluster *pDeltaRay(nullptr), *pDeltaRayRemnant(nullptr);
322 
323  for (const CaloHit *const pCaloHit : deltaRayHitList)
324  {
325  const bool isDeltaRay(std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end());
326  const bool isDeltaRayRemnant(
327  !isDeltaRay && (std::find(deltaRayRemnantHits.begin(), deltaRayRemnantHits.end(), pCaloHit) != deltaRayRemnantHits.end()));
328  const Cluster *&pCluster(isDeltaRay ? pDeltaRay : isDeltaRayRemnant ? pDeltaRayRemnant : pMuonCluster);
329 
330  if (!pCluster)
331  {
332  PandoraContentApi::Cluster::Parameters parameters;
333  parameters.m_caloHitList.push_back(pCaloHit);
334  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*m_pParentAlgorithm, parameters, pCluster));
335  }
336  else
337  {
338  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*m_pParentAlgorithm, pCluster, pCaloHit));
339  }
340  }
341 
342  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*m_pParentAlgorithm, fragmentListName, originalListName));
343 
344  ClusterVector clusterVector;
345  PfoVector pfoVector;
346  if (pDeltaRayRemnant)
347  this->ReclusterRemnant(hitType, pMuonCluster, pDeltaRayRemnant, clusterVector, pfoVector);
348 
349  clusterVector.push_back(pMuonCluster);
350  pfoVector.push_back(element.GetOverlapResult().GetCommonMuonPfoList().front());
351  clusterVector.push_back(pDeltaRay);
352  pfoVector.push_back(nullptr);
353 
354  m_pParentAlgorithm->UpdateForNewClusters(clusterVector, pfoVector);
355 }
356 
357 //------------------------------------------------------------------------------------------------------------------------------------------
358 
359 void CosmicRayRemovalTool::ReclusterRemnant(const HitType hitType, const Cluster *const pMuonCluster, const Cluster *const pDeltaRayRemnant,
360  ClusterVector &clusterVector, PfoVector &pfoVector) const
361 {
362  std::string caloHitListName(hitType == TPC_VIEW_U ? "CaloHitListU" : hitType == TPC_VIEW_V ? "CaloHitListV" : "CaloHitListW");
363 
364  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<CaloHit>(*m_pParentAlgorithm, caloHitListName));
365  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
366  PandoraContentApi::ReplaceCurrentList<Cluster>(*m_pParentAlgorithm, m_pParentAlgorithm->GetClusterListName(hitType)));
367  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete<Cluster>(*m_pParentAlgorithm, pDeltaRayRemnant));
368 
369  const ClusterList *pClusterList(nullptr);
370  std::string newClusterListName;
371  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
372  PandoraContentApi::RunClusteringAlgorithm(*m_pParentAlgorithm, m_pParentAlgorithm->GetClusteringAlgName(), pClusterList, newClusterListName));
373 
374  const ClusterList remnantClusters(pClusterList->begin(), pClusterList->end());
375 
376  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
377  PandoraContentApi::SaveList<Cluster>(*m_pParentAlgorithm, newClusterListName, m_pParentAlgorithm->GetClusterListName(hitType)));
378  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
379  PandoraContentApi::ReplaceCurrentList<Cluster>(*m_pParentAlgorithm, m_pParentAlgorithm->GetClusterListName(hitType)));
380 
381  for (const Cluster *const pRemnant : remnantClusters)
382  {
383  if (pRemnant->GetNCaloHits() < m_minRemnantClusterSize)
384  {
385  if (LArClusterHelper::GetClosestDistance(pRemnant, pMuonCluster) < m_maxDistanceToTrack)
386  {
387  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*m_pParentAlgorithm, pMuonCluster, pRemnant));
388  continue;
389  }
390  }
391 
392  clusterVector.push_back(pRemnant);
393  pfoVector.push_back(nullptr);
394  }
395 }
396 
397 //------------------------------------------------------------------------------------------------------------------------------------------
398 
399 StatusCode CosmicRayRemovalTool::ReadSettings(const TiXmlHandle xmlHandle)
400 {
401  PANDORA_RETURN_RESULT_IF_AND_IF(
402  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitWindow", m_slidingFitWindow));
403 
404  PANDORA_RETURN_RESULT_IF_AND_IF(
405  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinContaminationLength", m_minContaminationLength));
406 
407  PANDORA_RETURN_RESULT_IF_AND_IF(
408  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxDistanceToHit", m_maxDistanceToHit));
409 
410  PANDORA_RETURN_RESULT_IF_AND_IF(
411  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinRemnantClusterSize", m_minRemnantClusterSize));
412 
413  PANDORA_RETURN_RESULT_IF_AND_IF(
414  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxDistanceToTrack", m_maxDistanceToTrack));
415 
416  return RemovalBaseTool::ReadSettings(xmlHandle);
417 }
418 
419 } // namespace lar_content
void CollectHitsFromDeltaRay(const pandora::CartesianVector &positionOnMuon, const pandora::CartesianVector &muonDirection, const pandora::Cluster *const pDeltaRayCluster, const float &minDistanceFromMuon, const bool demandCloserToCollected, const pandora::CaloHitList &protectedHits, pandora::CaloHitList &collectedHits) const
Collect hits from the delta ray cluster to either keep (demandCloserToCollected == true) or separate ...
enum cvn::HType HitType
unsigned int m_slidingFitWindow
The sliding fit window used in cosmic ray parameterisations.
std::string string
Definition: nybbler.cc:12
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
void UpdateForNewClusters(const pandora::ClusterVector &newClusterVector, const pandora::PfoVector &pfoVector)
Add a new cluster to algorithm ownership maps and, if it a delta ray cluster, to the underlying match...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_distanceToLine
The maximum perpendicular distance of a position to a line for it to be considered close...
bool RemoveCosmicRayHits(const TensorType::ElementList &elementList) const
Remove hits from delta ray clusters that belong to the parent muon.
ThreeViewDeltaRayMatchingAlgorithm * m_pParentAlgorithm
Address of the parent matching algorithm.
static void GetClosestPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianVector &position1, pandora::CartesianVector &position2)
Get pair of closest positions for a pair of clusters.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
Header file for the cosmic ray removal tool class.
float m_maxDistanceToHit
The maximum distance of a hit from the cosmic ray track for it to be added into the CR...
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
Header file for the geometry helper class.
float m_maxDistanceToTrack
The minimum distance of an insignificant remnant cluster from the cosmic ray track for it to be merge...
bool IsContaminated(const TensorType::Element &element, const pandora::HitType hitType) const
Determine whether the cluster under investigation has muon contamination.
std::string GetClusteringAlgName() const
Get the name of the clustering algorithm to be used to recluster created delta ray remnants...
bool IsBestElement(const TensorType::Element &element, const pandora::HitType hitType, const TensorType::ElementList &elementList, const pandora::ClusterSet &modifiedClusters) const
Determine whether the input element is the best to use to modify the contaminated cluster (best is de...
bool IsInLineSegment(const pandora::CartesianVector &lowerBoundary, const pandora::CartesianVector &upperBoundary, const pandora::CartesianVector &point) const
Whether the projection of a given position lies on a defined line.
virtual bool PassElementChecks(const TensorType::Element &element, const pandora::HitType hitType) const
Determine whether element satifies simple checks.
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
virtual bool PassElementChecks(const TensorType::Element &element, const pandora::HitType hitType) const =0
Determine whether element satifies simple checks.
pandora::StatusCode ParameteriseMuon(const pandora::ParticleFlowObject *const pParentMuon, const pandora::Cluster *const pDeltaRayCluster, pandora::CartesianVector &positionOnMuon, pandora::CartesianVector &muonDirection) const
Parameterise the projection of a cosmic ray track in order to avoid poor/sparse projections.
Header file for the lar two dimensional sliding fit result class.
static int max(int a, int b)
bool IsCloseToLine(const pandora::CartesianVector &hitPosition, const pandora::CartesianVector &lineStart, const pandora::CartesianVector &lineEnd, const float distanceToLine) const
Whether a given position is close to a defined line.
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
pandora::StatusCode ProjectDeltaRayPositions(const TensorType::Element &element, const pandora::HitType hitType, pandora::CartesianPointVector &projectedPositions) const
Use two views of a delta ray pfo to calculate projected positions in a given third view...
void GetGlobalDirection(const float dTdL, pandora::CartesianVector &direction) const
Get global direction coordinates for given sliding linear fit gradient.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
void SplitDeltaRayCluster(const TensorType::Element &element, const pandora::HitType hitType, pandora::CaloHitList &collectedHits, pandora::CaloHitList &deltaRayRemnantHits) const
Fragment the delta ray cluster adding hits to the muon track and perhaps creating significant remnant...
pandora::StatusCode GrowSeed(const TensorType::Element &element, const pandora::HitType hitType, pandora::CaloHitList &collectedHits, pandora::CaloHitList &deltaRayRemantHits) const
Examine remaining hits in the delta ray cluster adding them to the delta ray seed or parent muon if a...
unsigned int m_minRemnantClusterSize
The minimum hit number of a remnant cluster for it to be considered significant.
bool Run(ThreeViewDeltaRayMatchingAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
void ReclusterRemnant(const pandora::HitType hitType, const pandora::Cluster *const pMuonCluster, const pandora::Cluster *const pDeltaRayRemnant, pandora::ClusterVector &clusterVector, pandora::PfoVector &pfoVector) const
Reculster a given remnant cluster, merging insignificant created clusters into the parent muon (if pr...
const std::string & GetClusterListName(const pandora::HitType hitType) const
Get the cluster list name corresponding to a specified hit type.
float m_minContaminationLength
The minimum projected length of a delta ray cluster onto the muon track for it to be considered conta...
std::vector< art::Ptr< recob::Cluster > > ClusterVector
bool IsMuonEndpoint(const TensorType::Element &element, const bool ignoreHitType, const pandora::HitType hitTypeToIgnore=pandora::TPC_VIEW_U) const
Determine whether the matched clusters suggest that the delta ray is at the endpoint of the cosmic ra...
void CreateSeed(const TensorType::Element &element, const pandora::HitType hitType, pandora::CaloHitList &collectedHits) const
Collect hits in the delta ray cluster that lie close to calculated projected positions forming a seed...
pandora::StatusCode GetMuonCluster(const pandora::PfoList &commonMuonPfoList, const pandora::HitType hitType, const pandora::Cluster *&pMuonCluster) const
Return the cluster of the common cosmic ray pfo in a given view (function demands there to be only on...
QTextStream & endl(QTextStream &s)
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)=0