SimpleClusterCreationAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArTwoDReco/LArClusterCreation/SimpleClusterCreationAlgorithm.cc
3  *
4  * @brief Implementation of the cluster creation algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 SimpleClusterCreationAlgorithm::SimpleClusterCreationAlgorithm() : m_clusteringWindowSquared(1.f)
21 {
22 }
23 
24 //------------------------------------------------------------------------------------------------------------------------------------------
25 
27 {
28  const CaloHitList *pCaloHitList = NULL;
29  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pCaloHitList));
30 
31  // Select available calo hits for clustering
32  CaloHitList caloHitList;
33  this->SelectCaloHits(pCaloHitList, caloHitList);
34 
35  if (caloHitList.empty())
36  return STATUS_CODE_SUCCESS;
37 
38  // Build map of associations between selected calo hits
39  HitAssociationMap hitAssociationMap;
40  this->BuildAssociationMap(caloHitList, hitAssociationMap);
41 
42  // Create new clusters
43  this->CreateClusters(caloHitList, hitAssociationMap);
44 
45  return STATUS_CODE_SUCCESS;
46 }
47 
48 //------------------------------------------------------------------------------------------------------------------------------------------
49 
50 void SimpleClusterCreationAlgorithm::SelectCaloHits(const CaloHitList *const pInputList, CaloHitList &outputList) const
51 {
52  for (const CaloHit *const pCaloHit : *pInputList)
53  {
54  if (PandoraContentApi::IsAvailable(*this, pCaloHit))
55  outputList.push_back(pCaloHit);
56  }
57 }
58 
59 //------------------------------------------------------------------------------------------------------------------------------------------
60 
61 void SimpleClusterCreationAlgorithm::BuildAssociationMap(const CaloHitList &caloHitList, HitAssociationMap &hitAssociationMap) const
62 {
63  for (const CaloHit *const pCaloHitI : caloHitList)
64  {
65  for (const CaloHit *const pCaloHitJ : caloHitList)
66  {
67  if (pCaloHitI == pCaloHitJ)
68  continue;
69 
70  if ((pCaloHitI->GetPositionVector() - pCaloHitJ->GetPositionVector()).GetMagnitudeSquared() < m_clusteringWindowSquared)
71  {
72  CaloHitList &caloHitListI(hitAssociationMap[pCaloHitI]);
73 
74  if (caloHitListI.end() == std::find(caloHitListI.begin(), caloHitListI.end(), pCaloHitJ))
75  caloHitListI.push_back(pCaloHitJ);
76 
77  CaloHitList &caloHitListJ(hitAssociationMap[pCaloHitI]);
78 
79  if (caloHitListJ.end() == std::find(caloHitListJ.begin(), caloHitListJ.end(), pCaloHitI))
80  caloHitListJ.push_back(pCaloHitI);
81  }
82  }
83  }
84 }
85 
86 //------------------------------------------------------------------------------------------------------------------------------------------
87 
88 void SimpleClusterCreationAlgorithm::CreateClusters(const CaloHitList &caloHitList, const HitAssociationMap &hitAssociationMap) const
89 {
90  CaloHitSet vetoList;
91  CaloHitVector caloHitVector(caloHitList.begin(), caloHitList.end());
92  std::sort(caloHitVector.begin(), caloHitVector.end(), LArClusterHelper::SortHitsByPosition);
93 
94  for (const CaloHit *const pSeedCaloHit : caloHitVector)
95  {
96  if (vetoList.count(pSeedCaloHit))
97  continue;
98 
99  CaloHitList mergeList;
100  this->CollectAssociatedHits(pSeedCaloHit, pSeedCaloHit, hitAssociationMap, vetoList, mergeList);
101 
102  const Cluster *pCluster = NULL;
103  PandoraContentApi::Cluster::Parameters parameters;
104  parameters.m_caloHitList.push_back(pSeedCaloHit);
105  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pCluster));
106  vetoList.insert(pSeedCaloHit);
107 
108  for (const CaloHit *const pAssociatedCaloHit : mergeList)
109  {
110  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pCluster, pAssociatedCaloHit));
111  vetoList.insert(pAssociatedCaloHit);
112  }
113  }
114 }
115 
116 //------------------------------------------------------------------------------------------------------------------------------------------
117 
118 void SimpleClusterCreationAlgorithm::CollectAssociatedHits(const CaloHit *const pSeedCaloHit, const CaloHit *const pCurrentCaloHit,
119  const HitAssociationMap &hitAssociationMap, const CaloHitSet &vetoList, CaloHitList &mergeList) const
120 {
121  if (vetoList.count(pCurrentCaloHit))
122  return;
123 
124  HitAssociationMap::const_iterator iter1 = hitAssociationMap.find(pCurrentCaloHit);
125  if (iter1 == hitAssociationMap.end())
126  return;
127 
128  CaloHitVector caloHitVector(iter1->second.begin(), iter1->second.end());
129  std::sort(caloHitVector.begin(), caloHitVector.end(), LArClusterHelper::SortHitsByPosition);
130 
131  for (const CaloHit *const pAssociatedCaloHit : caloHitVector)
132  {
133  if (pAssociatedCaloHit == pSeedCaloHit)
134  continue;
135 
136  if (mergeList.end() != std::find(mergeList.begin(), mergeList.end(), pAssociatedCaloHit))
137  continue;
138 
139  mergeList.push_back(pAssociatedCaloHit);
140 
141  this->CollectAssociatedHits(pSeedCaloHit, pAssociatedCaloHit, hitAssociationMap, vetoList, mergeList);
142  }
143 }
144 //------------------------------------------------------------------------------------------------------------------------------------------
145 
146 StatusCode SimpleClusterCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
147 {
148  float clusteringWindow = std::sqrt(m_clusteringWindowSquared);
149  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ClusteringWindow", clusteringWindow));
150  m_clusteringWindowSquared = clusteringWindow * clusteringWindow;
151 
152  return STATUS_CODE_SUCCESS;
153 }
154 
155 } // namespace lar_content
void BuildAssociationMap(const pandora::CaloHitList &caloHitList, HitAssociationMap &hitAssociationMap) const
Create map of associations between calo hits.
void SelectCaloHits(const pandora::CaloHitList *const pInputList, pandora::CaloHitList &outputList) const
Select calo hits for clustering.
intermediate_table::const_iterator const_iterator
void CreateClusters(const pandora::CaloHitList &caloHitList, const HitAssociationMap &hitAssociationMap) const
Create clusters from selected calo hits and their associations.
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.
std::unordered_map< const pandora::CaloHit *, pandora::CaloHitList > HitAssociationMap
float m_clusteringWindowSquared
Maximum distance (squared) for two hits to be joined.
void CollectAssociatedHits(const pandora::CaloHit *const pSeedCaloHit, const pandora::CaloHit *const pCurrentCaloHit, const HitAssociationMap &hitAssociationMap, const pandora::CaloHitSet &vetoList, pandora::CaloHitList &mergeList) const
For a given seed calo hits, collect up all the associated calo hits.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the cluster creation algorithm class.