LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TwoDSlidingFitConsolidationAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 TwoDSlidingFitConsolidationAlgorithm::TwoDSlidingFitConsolidationAlgorithm() :
22  m_minTrackLength(7.5f),
23  m_maxClusterLength(15.f),
24  m_halfWindowLayers(25)
25 {
26 }
27 
28 //------------------------------------------------------------------------------------------------------------------------------------------
29 
31 {
32  const ClusterList *pClusterList = NULL;
33  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
34 
35  // Select tracks and showers for re-clustering (Note: samples not mutually exclusive)
36  ClusterVector trackClusters, showerClusters;
37  this->SortInputClusters(pClusterList, trackClusters, showerClusters);
38 
39  // Build sliding linear fits from track clusters
40  TwoDSlidingFitResultList slidingFitResultList;
41  this->BuildSlidingLinearFits(trackClusters, slidingFitResultList);
42 
43  // Recluster the hits
44  ClusterToHitMap clustersToExpand, clustersToContract;
45  this->GetReclusteredHits(slidingFitResultList, showerClusters, clustersToExpand, clustersToContract);
46 
47  // Consolidate and re-build clusters
48  ClusterSet unavailableClusters;
49  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RemoveHitsFromClusters(clustersToContract, unavailableClusters));
50  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->AddHitsToClusters(clustersToExpand, unavailableClusters));
51  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RebuildClusters(clustersToContract, unavailableClusters));
52 
53  return STATUS_CODE_SUCCESS;
54 }
55 
56 //------------------------------------------------------------------------------------------------------------------------------------------
57 
58 void TwoDSlidingFitConsolidationAlgorithm::SortInputClusters(const ClusterList *const pClusterList, ClusterVector &trackClusters,
59  ClusterVector &showerClusters) const
60 {
61  for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
62  {
63  const Cluster *const pCluster = *iter;
64 
65  const float thisLengthSquared(LArClusterHelper::GetLengthSquared(pCluster));
66 
67  if (thisLengthSquared < m_maxClusterLength * m_maxClusterLength)
68  showerClusters.push_back(pCluster);
69 
70  if (thisLengthSquared > m_minTrackLength * m_minTrackLength)
71  trackClusters.push_back(pCluster);
72  }
73 
74  std::sort(trackClusters.begin(), trackClusters.end(), LArClusterHelper::SortByNHits);
75  std::sort(showerClusters.begin(), showerClusters.end(), LArClusterHelper::SortByNHits);
76 }
77 
78 //------------------------------------------------------------------------------------------------------------------------------------------
79 
81 {
82  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
83 
84  for (ClusterVector::const_iterator iter = trackClusters.begin(), iterEnd = trackClusters.end(); iter != iterEnd; ++iter)
85  {
86  try
87  {
88  const TwoDSlidingFitResult slidingFitResult(*iter, m_halfWindowLayers, slidingFitPitch);
89  slidingFitResultList.push_back(slidingFitResult);
90  }
91  catch (StatusCodeException &statusCodeException)
92  {
93  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
94  throw statusCodeException;
95  }
96  }
97 }
98 
99 //------------------------------------------------------------------------------------------------------------------------------------------
100 
101 StatusCode TwoDSlidingFitConsolidationAlgorithm::RemoveHitsFromClusters(const ClusterToHitMap &clustersToContract, ClusterSet &unavailableClusters) const
102 {
103  ClusterList clusterList;
104  for (const auto &mapEntry : clustersToContract) clusterList.push_back(mapEntry.first);
105  clusterList.sort(LArClusterHelper::SortByNHits);
106 
107  for (const Cluster *const pCluster : clusterList)
108  {
109  const CaloHitList &caloHitListToRemove(clustersToContract.at(pCluster));
110 
111  if (caloHitListToRemove.empty())
112  continue;
113 
114  if (unavailableClusters.count(pCluster))
115  continue;
116 
117  CaloHitList caloHitList, caloHitListToKeep;
118  pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
119 
120  for (const CaloHit *const pCaloHit : caloHitList)
121  {
122  if (caloHitListToRemove.end() == std::find(caloHitListToRemove.begin(), caloHitListToRemove.end(), pCaloHit))
123  caloHitListToKeep.push_back(pCaloHit);
124  }
125 
126  if (caloHitListToKeep.empty())
127  {
128  // ATTN clustersToContract and unavailable clusters now contain dangling pointers
129  unavailableClusters.insert(pCluster);
130  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete<Cluster>(*this, pCluster));
131  continue;
132  }
133 
134  for (const CaloHit *const pCaloHit : caloHitListToRemove)
135  {
136  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RemoveFromCluster(*this, pCluster, pCaloHit));
137  }
138  }
139 
140  return STATUS_CODE_SUCCESS;
141 }
142 
143 //------------------------------------------------------------------------------------------------------------------------------------------
144 
145 StatusCode TwoDSlidingFitConsolidationAlgorithm::AddHitsToClusters(const ClusterToHitMap &clustersToExpand, ClusterSet &unavailableClusters) const
146 {
147  ClusterList clusterList;
148  for (const auto &mapEntry : clustersToExpand) clusterList.push_back(mapEntry.first);
149  clusterList.sort(LArClusterHelper::SortByNHits);
150 
151  for (const Cluster *const pCluster : clusterList)
152  {
153  const CaloHitList &caloHitList(clustersToExpand.at(pCluster));
154 
155  if (caloHitList.empty())
156  continue;
157 
158  if (unavailableClusters.count(pCluster))
159  continue;
160 
161  unavailableClusters.insert(pCluster);
162 
163  for (const CaloHit *const pCaloHit : caloHitList)
164  {
165  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pCluster, pCaloHit));
166  }
167  }
168 
169  return STATUS_CODE_SUCCESS;
170 }
171 
172 //------------------------------------------------------------------------------------------------------------------------------------------
173 
174 StatusCode TwoDSlidingFitConsolidationAlgorithm::RebuildClusters(const ClusterToHitMap &clustersToRebuild, const ClusterSet &unavailableClusters) const
175 {
176  if (clustersToRebuild.empty())
177  return STATUS_CODE_SUCCESS;
178 
179  ClusterVector sortedClusters;
180  for (const auto &mapEntry : clustersToRebuild)
181  {
182  if (!unavailableClusters.count(mapEntry.first))
183  sortedClusters.push_back(mapEntry.first);
184  }
185 
186  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
187 
188  for (const Cluster *const pCluster : sortedClusters)
189  {
190  const CaloHitList &caloHitList(clustersToRebuild.at(pCluster));
191  const Cluster *const pClusterToDelete(pCluster);
192 
193  if (caloHitList.empty())
194  continue;
195 
196  std::string currentClusterListName;
197  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentListName<Cluster>(*this, currentClusterListName));
198  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete<Cluster>(*this, pClusterToDelete));
199 
200  const ClusterList *pClusterList = NULL;
201  std::string newClusterListName;
202  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RunClusteringAlgorithm(*this, m_reclusteringAlgorithmName,
203  pClusterList, newClusterListName));
204 
205  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Cluster>(*this, newClusterListName, currentClusterListName));
206  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*this, currentClusterListName));
207  }
208 
209  return STATUS_CODE_SUCCESS;
210 }
211 
212 //------------------------------------------------------------------------------------------------------------------------------------------
213 
214 StatusCode TwoDSlidingFitConsolidationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
215 {
216  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithm(*this, xmlHandle,
217  "ClusterRebuilding", m_reclusteringAlgorithmName));
218 
219  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
220  "MinTrackLength", m_minTrackLength));
221 
222  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
223  "MaxClusterLength", m_maxClusterLength));
224 
225  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
226  "SlidingFitHalfWindow", m_halfWindowLayers));
227 
228  return STATUS_CODE_SUCCESS;
229 }
230 
231 } // namespace lar_content
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.
unsigned int m_halfWindowLayers
Size of layer window for sliding fit results.
float m_maxClusterLength
Maximum length of shower clusters to use in re-building.
float m_minTrackLength
Minimum length of track clusters to consolidate.
Header file for the 2D sliding fit consolidation algorithm class.
std::unordered_map< const pandora::Cluster *, pandora::CaloHitList > ClusterToHitMap
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void BuildSlidingLinearFits(const pandora::ClusterVector &trackClusters, TwoDSlidingFitResultList &slidingFitResultList) const
Apply sliding linear fits to track clusters.
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
std::vector< TwoDSlidingFitResult > TwoDSlidingFitResultList
std::vector< art::Ptr< recob::Cluster > > ClusterVector
std::string m_reclusteringAlgorithmName
Name of daughter algorithm to use for cluster re-building.
void SortInputClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &trackClusters, pandora::ClusterVector &showerClusters) const
Sort input cluster list into track-like clusters and shower-like clusters.
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
virtual void GetReclusteredHits(const TwoDSlidingFitResultList &slidingFitResultList, const pandora::ClusterVector &showerClusters, ClusterToHitMap &caloHitsToAdd, ClusterToHitMap &caloHitsToRemove) const =0
Get the list of hits to be added or removed from clusters.
pandora::StatusCode AddHitsToClusters(const ClusterToHitMap &clustersToRebuild, pandora::ClusterSet &unavailableClusters) const
Add hits to clusters.
pandora::StatusCode RemoveHitsFromClusters(const ClusterToHitMap &clustersToRebuild, pandora::ClusterSet &unavailableClusters) const
Remove hits from clusters.
pandora::StatusCode RebuildClusters(const ClusterToHitMap &clustersAtStart, const pandora::ClusterSet &unavailableClusters) const
Re-build clusters.