LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
IsolatedClusterMopUpAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
16 
17 using namespace pandora;
18 
19 namespace lar_content
20 {
21 
22 IsolatedClusterMopUpAlgorithm::IsolatedClusterMopUpAlgorithm() :
23  m_maxCaloHitsInCluster(20),
24  m_maxHitClusterDistance(5.f),
25  m_addHitsAsIsolated(true)
26 {
27  // ATTN Default value differs from base class
29 }
30 
31 //------------------------------------------------------------------------------------------------------------------------------------------
32 
33 void IsolatedClusterMopUpAlgorithm::ClusterMopUp(const ClusterList &pfoClusters, const ClusterList &remnantClusters) const
34 {
35  CaloHitList caloHitList;
36  this->DissolveClustersToHits(remnantClusters, caloHitList);
37 
38  // ATTN remnantClusters now contains dangling pointers
39  CaloHitToClusterMap caloHitToClusterMap;
40  this->GetCaloHitToClusterMap(caloHitList, pfoClusters, caloHitToClusterMap);
41 
42  CaloHitList sortedCaloHitList;
43  for (const auto &mapEntry : caloHitToClusterMap) sortedCaloHitList.push_back(mapEntry.first);
44  sortedCaloHitList.sort(LArClusterHelper::SortHitsByPosition);
45 
46  for (const CaloHit *pCaloHit : sortedCaloHitList)
47  {
49  {
50  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddIsolatedToCluster(*this, caloHitToClusterMap.at(pCaloHit), pCaloHit));
51  }
52  else
53  {
54  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, caloHitToClusterMap.at(pCaloHit), pCaloHit));
55  }
56  }
57 }
58 
59 //------------------------------------------------------------------------------------------------------------------------------------------
60 
61 void IsolatedClusterMopUpAlgorithm::DissolveClustersToHits(const ClusterList &clusterList, CaloHitList &caloHitList) const
62 {
63  for (const Cluster *const pRemnantCluster : clusterList)
64  {
65  if (pRemnantCluster->GetNCaloHits() < m_maxCaloHitsInCluster)
66  {
67  const std::string listNameR(this->GetListName(pRemnantCluster));
68  pRemnantCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
69  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pRemnantCluster, listNameR));
70  }
71  }
72 }
73 
74 //------------------------------------------------------------------------------------------------------------------------------------------
75 
76 void IsolatedClusterMopUpAlgorithm::GetCaloHitToClusterMap(const CaloHitList &caloHitList, const ClusterList &clusterList, CaloHitToClusterMap &caloHitToClusterMap) const
77 {
78  CaloHitList allCaloHits;
79  CaloHitToClusterMap hitToParentClusterMap;
80 
81  for (const Cluster *const pCluster : clusterList)
82  {
83  CaloHitList daughterHits;
84  pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
85  allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
86 
87  for (const CaloHit *const pCaloHit : daughterHits)
88  (void) hitToParentClusterMap.insert(CaloHitToClusterMap::value_type(pCaloHit, pCluster));
89  }
90 
91  HitKDTree2D kdTree;
92  HitKDNode2DList hitKDNode2DList;
93 
94  KDTreeBox hitsBoundingRegion2D(fill_and_bound_2d_kd_tree(allCaloHits, hitKDNode2DList));
95  kdTree.build(hitKDNode2DList, hitsBoundingRegion2D);
96 
97  for (const CaloHit *const pCaloHit : caloHitList)
98  {
99  if (!PandoraContentApi::IsAvailable(*this, pCaloHit))
100  throw StatusCodeException(STATUS_CODE_FAILURE);
101 
102  const HitKDNode2D *pResultHit(nullptr);
103  float resultDistance(std::numeric_limits<float>::max());
104  const HitKDNode2D targetHit(pCaloHit, pCaloHit->GetPositionVector().GetX(), pCaloHit->GetPositionVector().GetZ());
105  kdTree.findNearestNeighbour(targetHit, pResultHit, resultDistance);
106 
107  if (pResultHit && (resultDistance < m_maxHitClusterDistance))
108  (void) caloHitToClusterMap.insert(CaloHitToClusterMap::value_type(pCaloHit, hitToParentClusterMap.at(pResultHit->data)));
109  }
110 }
111 
112 //------------------------------------------------------------------------------------------------------------------------------------------
113 
114 StatusCode IsolatedClusterMopUpAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
115 {
116  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
117  "MaxCaloHitsInCluster", m_maxCaloHitsInCluster));
118 
119  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
120  "MaxHitClusterDistance", m_maxHitClusterDistance));
121 
122  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
123  "AddHitsAsIsolated", m_addHitsAsIsolated));
124 
125  return ClusterMopUpBaseAlgorithm::ReadSettings(xmlHandle);
126 }
127 
128 } // namespace lar_content
Header file for the kd tree linker algo template class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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...
Class that implements the KDTree partition of 2D space and a closest point search algorithm...
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
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.
Int_t max
Definition: plot.C:27
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.
Header file for the isolated cluster mop up algorithm class.
float m_maxHitClusterDistance
The maximum hit to cluster distance for isolated hit merging.
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > CaloHitToClusterMap
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...
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".