LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
IsolatedClusterMopUpAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
17 
18 using namespace pandora;
19 
20 namespace lar_content
21 {
22 
23 IsolatedClusterMopUpAlgorithm::IsolatedClusterMopUpAlgorithm() :
24  m_maxCaloHitsInCluster(20),
25  m_maxHitClusterDistance(5.f),
26  m_addHitsAsIsolated(true)
27 {
28  // ATTN Default value differs from base class
30 }
31 
32 //------------------------------------------------------------------------------------------------------------------------------------------
33 
34 void IsolatedClusterMopUpAlgorithm::ClusterMopUp(const ClusterList &pfoClusters, const ClusterList &remnantClusters) const
35 {
36  CaloHitList caloHitList;
37  this->DissolveClustersToHits(remnantClusters, caloHitList);
38 
39  // ATTN remnantClusters now contains dangling pointers
40  CaloHitToClusterMap caloHitToClusterMap;
41  this->GetCaloHitToClusterMap(caloHitList, pfoClusters, caloHitToClusterMap);
42 
43  CaloHitList sortedCaloHitList;
44  for (const auto &mapEntry : caloHitToClusterMap)
45  sortedCaloHitList.push_back(mapEntry.first);
46  sortedCaloHitList.sort(LArClusterHelper::SortHitsByPosition);
47 
48  for (const CaloHit *pCaloHit : sortedCaloHitList)
49  {
51  {
52  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddIsolatedToCluster(*this, caloHitToClusterMap.at(pCaloHit), pCaloHit));
53  }
54  else
55  {
56  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, caloHitToClusterMap.at(pCaloHit), pCaloHit));
57  }
58  }
59 }
60 
61 //------------------------------------------------------------------------------------------------------------------------------------------
62 
63 void IsolatedClusterMopUpAlgorithm::DissolveClustersToHits(const ClusterList &clusterList, CaloHitList &caloHitList) const
64 {
65  for (const Cluster *const pRemnantCluster : clusterList)
66  {
67  if (pRemnantCluster->GetNCaloHits() < m_maxCaloHitsInCluster)
68  {
69  const std::string listNameR(this->GetListName(pRemnantCluster));
70  pRemnantCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
71  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pRemnantCluster, listNameR));
72  }
73  }
74 }
75 
76 //------------------------------------------------------------------------------------------------------------------------------------------
77 
79  const CaloHitList &caloHitList, const ClusterList &clusterList, CaloHitToClusterMap &caloHitToClusterMap) const
80 {
81  CaloHitList allCaloHits;
82  CaloHitToClusterMap hitToParentClusterMap;
83 
84  for (const Cluster *const pCluster : clusterList)
85  {
86  CaloHitList daughterHits;
87  pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
88  allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
89 
90  for (const CaloHit *const pCaloHit : daughterHits)
91  (void)hitToParentClusterMap.insert(CaloHitToClusterMap::value_type(pCaloHit, pCluster));
92  }
93 
94  HitKDTree2D kdTree;
95  HitKDNode2DList hitKDNode2DList;
96 
97  KDTreeBox hitsBoundingRegion2D(fill_and_bound_2d_kd_tree(allCaloHits, hitKDNode2DList));
98  kdTree.build(hitKDNode2DList, hitsBoundingRegion2D);
99 
100  HitType view{TPC_3D};
101  if (!caloHitList.empty())
102  view = caloHitList.front()->GetHitType();
103  const float ratio{LArGeometryHelper::GetWirePitchRatio(this->GetPandora(), view)};
104  const float maxHitClusterDistanceAdjusted{ratio * m_maxHitClusterDistance};
105 
106  for (const CaloHit *const pCaloHit : caloHitList)
107  {
108  if (!PandoraContentApi::IsAvailable(*this, pCaloHit))
109  throw StatusCodeException(STATUS_CODE_FAILURE);
110 
111  const HitKDNode2D *pResultHit(nullptr);
112  float resultDistance(std::numeric_limits<float>::max());
113  const HitKDNode2D targetHit(pCaloHit, pCaloHit->GetPositionVector().GetX(), pCaloHit->GetPositionVector().GetZ());
114  kdTree.findNearestNeighbour(targetHit, pResultHit, resultDistance);
115 
116  if (pResultHit && (resultDistance < maxHitClusterDistanceAdjusted))
117  (void)caloHitToClusterMap.insert(CaloHitToClusterMap::value_type(pCaloHit, hitToParentClusterMap.at(pResultHit->data)));
118  }
119 }
120 
121 //------------------------------------------------------------------------------------------------------------------------------------------
122 
123 StatusCode IsolatedClusterMopUpAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
124 {
125  PANDORA_RETURN_RESULT_IF_AND_IF(
126  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxCaloHitsInCluster", m_maxCaloHitsInCluster));
127 
128  PANDORA_RETURN_RESULT_IF_AND_IF(
129  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxHitClusterDistance", m_maxHitClusterDistance));
130 
131  PANDORA_RETURN_RESULT_IF_AND_IF(
132  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "AddHitsAsIsolated", m_addHitsAsIsolated));
133 
134  return ClusterMopUpBaseAlgorithm::ReadSettings(xmlHandle);
135 }
136 
137 } // namespace lar_content
Header file for the kd tree linker algo template class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetWirePitchRatio(const pandora::Pandora &pandora, const pandora::HitType view)
Return the ratio of the wire pitch of the specified view to the minimum wire pitch for the detector...
void ClusterMopUp(const pandora::ClusterList &pfoClusters, const pandora::ClusterList &remnantClusters) const
Cluster mop up for a single view. This function is responsible for instructing pandora to make cluste...
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > CaloHitToClusterMap
Box structure used to define 2D field. It&#39;s used in KDTree building step to divide the detector space...
bool m_excludePfosContainingTracks
Whether to exclude any pfos containing clusters flagged as fixed tracks.
unsigned int m_maxCaloHitsInCluster
The maximum number of hits in a cluster to be dissolved.
void DissolveClustersToHits(const pandora::ClusterList &clusterList, pandora::CaloHitList &caloHitList) const
Examine a list of clusters, identify and delete remnants; receive the list of newly available hits...
void findNearestNeighbour(const KDTreeNodeInfoT< DATA, DIM > &point, const KDTreeNodeInfoT< DATA, DIM > *&result, float &distance)
findNearestNeighbour
Data stored in each KDTree node. The dim1/dim2 fields are usually the duplication of some PFRecHit va...
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const std::string GetListName(const T *const pT) const
Find the name of the list hosting a specific object.
bool m_addHitsAsIsolated
Whether to add hits to clusters as "isolated" (don&#39;t contribute to spatial properties) ...
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.
void build(std::vector< KDTreeNodeInfoT< DATA, DIM >> &eltList, const KDTreeBoxT< DIM > &region)
Build the KD tree from the "eltList" in the space define by "region".
Header file for the isolated cluster mop up algorithm class.
float m_maxHitClusterDistance
The maximum hit to cluster distance for isolated hit merging.
HitType
Definition: HitType.h:12
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 >> &nodes)
fill_and_bound_2d_kd_tree
void GetCaloHitToClusterMap(const pandora::CaloHitList &caloHitList, const pandora::ClusterList &clusterList, CaloHitToClusterMap &caloHitToClusterMap) const
Look for isolated hit additions, considering a list of candidate hits and a list of host clusters...