LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm Class Referenceabstract

TwoDSlidingFitSplittingAndSplicingAlgorithm class. More...

#include "TwoDSlidingFitSplittingAndSplicingAlgorithm.h"

Inheritance diagram for lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm:
lar_content::BranchSplittingAlgorithm lar_content::DeltaRaySplittingAlgorithm

Classes

class  ClusterExtension
 ClusterExtension class. More...
 

Public Member Functions

 TwoDSlidingFitSplittingAndSplicingAlgorithm ()
 Default constructor. More...
 

Protected Types

typedef std::vector< ClusterExtensionClusterExtensionList
 

Protected Member Functions

virtual pandora::StatusCode Run ()
 
virtual pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
virtual void FindBestSplitPosition (const TwoDSlidingFitResult &branchSlidingFit, const TwoDSlidingFitResult &replacementSlidingFit, pandora::CartesianVector &replacementStartPosition, pandora::CartesianVector &branchSplitPosition, pandora::CartesianVector &branchSplitDirection) const =0
 Output the best split positions in branch and replacement clusters. More...
 

Private Member Functions

void GetListOfCleanClusters (const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
 Populate cluster vector with subset of cluster list, containing clusters judged to be clean. More...
 
void BuildSlidingFitResultMap (const pandora::ClusterVector &clusterVector, const unsigned int halfWindowLayers, TwoDSlidingFitResultMap &slidingFitResultMap) const
 Build the map of sliding fit results. More...
 
void BuildClusterExtensionList (const pandora::ClusterVector &clusterVector, const TwoDSlidingFitResultMap &branchResultMap, const TwoDSlidingFitResultMap &replacementResultMap, ClusterExtensionList &clusterExtensionList) const
 Build a list of candidate splits. More...
 
void PruneClusterExtensionList (const ClusterExtensionList &inputList, const TwoDSlidingFitResultMap &branchResultMap, const TwoDSlidingFitResultMap &replacementResultMap, ClusterExtensionList &outputList) const
 Finalize the list of candidate splits. More...
 
float CalculateBranchChi2 (const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection) const
 Calculate RMS deviation of branch hits relative to the split direction. More...
 
void SplitBranchCluster (const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection, pandora::CaloHitList &principalCaloHitList, pandora::CaloHitList &branchCaloHitList) const
 Separate cluster into the branch hits to be split from the primary cluster. More...
 
pandora::StatusCode RunSplitAndExtension (const ClusterExtensionList &splitList, TwoDSlidingFitResultMap &branchResultMap, TwoDSlidingFitResultMap &replacementResultMap) const
 Run the machinary that performs the cluster splitting and extending. More...
 
pandora::StatusCode ReplaceBranch (const pandora::Cluster *const pBranchCluster, const pandora::Cluster *const pReplacementCluster, const pandora::CartesianVector &branchSplitPosition, const pandora::CartesianVector &branchSplitDirection) const
 Remove a branch from a cluster and replace it with a second cluster. More...
 

Private Attributes

unsigned int m_shortHalfWindowLayers
 
unsigned int m_longHalfWindowLayers
 
float m_minClusterLength
 
float m_vetoDisplacement
 
bool m_runCosmicMode
 

Detailed Description

Member Typedef Documentation

Constructor & Destructor Documentation

Member Function Documentation

void lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::BuildClusterExtensionList ( const pandora::ClusterVector &  clusterVector,
const TwoDSlidingFitResultMap branchResultMap,
const TwoDSlidingFitResultMap replacementResultMap,
ClusterExtensionList clusterExtensionList 
) const
private

Build a list of candidate splits.

Parameters
clusterVectorthe input cluster vector
branchResultMapthe sliding fit result map for branch clusters
replacementResultMapthe sliding fit result map for replacement clusters
clusterExtensionListthe output list of candidate splits

Definition at line 120 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References CalculateBranchChi2(), f, and FindBestSplitPosition().

Referenced by Run().

123 {
124  // Loop over each possible pair of clusters
125  for (ClusterVector::const_iterator iterI = clusterVector.begin(), iterEndI = clusterVector.end(); iterI != iterEndI; ++iterI)
126  {
127  const Cluster *const pClusterI = *iterI;
128 
129  for (ClusterVector::const_iterator iterJ = iterI, iterEndJ = clusterVector.end(); iterJ != iterEndJ; ++iterJ)
130  {
131  const Cluster *const pClusterJ = *iterJ;
132 
133  if (pClusterI == pClusterJ)
134  continue;
135 
136  // Get the branch and replacement sliding fits for this pair of clusters
137  TwoDSlidingFitResultMap::const_iterator iterBranchI = branchSlidingFitResultMap.find(*iterI);
138  TwoDSlidingFitResultMap::const_iterator iterBranchJ = branchSlidingFitResultMap.find(*iterJ);
139 
140  TwoDSlidingFitResultMap::const_iterator iterReplacementI = replacementSlidingFitResultMap.find(*iterI);
141  TwoDSlidingFitResultMap::const_iterator iterReplacementJ = replacementSlidingFitResultMap.find(*iterJ);
142 
143  if (branchSlidingFitResultMap.end() == iterBranchI || branchSlidingFitResultMap.end() == iterBranchJ ||
144  replacementSlidingFitResultMap.end() == iterReplacementI || replacementSlidingFitResultMap.end() == iterReplacementJ)
145  {
146  // TODO May want to raise an exception under certain conditions
147  continue;
148  }
149 
150  const TwoDSlidingFitResult &branchSlidingFitI(iterBranchI->second);
151  const TwoDSlidingFitResult &branchSlidingFitJ(iterBranchJ->second);
152 
153  const TwoDSlidingFitResult &replacementSlidingFitI(iterReplacementI->second);
154  const TwoDSlidingFitResult &replacementSlidingFitJ(iterReplacementJ->second);
155 
156  // Search for a split in clusterI
157  float branchChisqI(0.f);
158  CartesianVector branchSplitPositionI(0.f, 0.f, 0.f);
159  CartesianVector branchSplitDirectionI(0.f, 0.f, 0.f);
160  CartesianVector replacementStartPositionJ(0.f, 0.f, 0.f);
161 
162  try
163  {
164  this->FindBestSplitPosition(branchSlidingFitI, replacementSlidingFitJ, replacementStartPositionJ, branchSplitPositionI, branchSplitDirectionI);
165  branchChisqI = this->CalculateBranchChi2(pClusterI, branchSplitPositionI, branchSplitDirectionI);
166  }
167  catch (StatusCodeException &)
168  {
169  }
170 
171  // Search for a split in clusterJ
172  float branchChisqJ(0.f);
173  CartesianVector branchSplitPositionJ(0.f, 0.f, 0.f);
174  CartesianVector branchSplitDirectionJ(0.f, 0.f, 0.f);
175  CartesianVector replacementStartPositionI(0.f, 0.f, 0.f);
176 
177  try
178  {
179  this->FindBestSplitPosition(branchSlidingFitJ, replacementSlidingFitI, replacementStartPositionI, branchSplitPositionJ, branchSplitDirectionJ);
180  branchChisqJ = this->CalculateBranchChi2(pClusterJ, branchSplitPositionJ, branchSplitDirectionJ);
181  }
182  catch (StatusCodeException &)
183  {
184  }
185 
186  // Re-calculate chi2 values if both clusters have a split
187  if (branchChisqI > 0.f && branchChisqJ > 0.f)
188  {
189  const CartesianVector relativeDirection((branchSplitPositionJ - branchSplitPositionI).GetUnitVector());
190 
191  if (branchSplitDirectionI.GetDotProduct(relativeDirection) > 0.f && branchSplitDirectionJ.GetDotProduct(relativeDirection) < 0.f)
192  {
193  try
194  {
195  const float newBranchChisqI(this->CalculateBranchChi2(pClusterI, branchSplitPositionI, relativeDirection));
196  const float newBranchChisqJ(this->CalculateBranchChi2(pClusterJ, branchSplitPositionJ, relativeDirection * -1.f));
197  branchChisqI = newBranchChisqI;
198  branchChisqJ = newBranchChisqJ;
199  }
200  catch (StatusCodeException &)
201  {
202  }
203  }
204  }
205 
206  // Select the overall best split position
207  if (branchChisqI > branchChisqJ)
208  {
209  clusterExtensionList.push_back(
210  ClusterExtension(pClusterI, pClusterJ, replacementStartPositionJ, branchSplitPositionI, branchSplitDirectionI));
211  }
212 
213  else if (branchChisqJ > branchChisqI)
214  {
215  clusterExtensionList.push_back(
216  ClusterExtension(pClusterJ, pClusterI, replacementStartPositionI, branchSplitPositionJ, branchSplitDirectionJ));
217  }
218  }
219  }
220 }
virtual void FindBestSplitPosition(const TwoDSlidingFitResult &branchSlidingFit, const TwoDSlidingFitResult &replacementSlidingFit, pandora::CartesianVector &replacementStartPosition, pandora::CartesianVector &branchSplitPosition, pandora::CartesianVector &branchSplitDirection) const =0
Output the best split positions in branch and replacement clusters.
intermediate_table::const_iterator const_iterator
TFile f
Definition: plotHisto.C:6
float CalculateBranchChi2(const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection) const
Calculate RMS deviation of branch hits relative to the split direction.
void lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::BuildSlidingFitResultMap ( const pandora::ClusterVector &  clusterVector,
const unsigned int  halfWindowLayers,
TwoDSlidingFitResultMap slidingFitResultMap 
) const
private

Build the map of sliding fit results.

Parameters
clusterVectorthe input cluster vector
halfWindowLayersthe half-window to use for the sliding fits
slidingFitResultMapthe output sliding fit result map

Definition at line 94 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References lar_content::LArClusterHelper::GetClusterHitType(), and lar_content::LArGeometryHelper::GetWirePitch().

Referenced by Run().

96 {
97  for (ClusterVector::const_iterator iter = clusterVector.begin(), iterEnd = clusterVector.end(); iter != iterEnd; ++iter)
98  {
99  if (slidingFitResultMap.end() == slidingFitResultMap.find(*iter))
100  {
101  try
102  {
103  const float slidingFitPitch(LArGeometryHelper::GetWirePitch(this->GetPandora(), LArClusterHelper::GetClusterHitType(*iter)));
104  const TwoDSlidingFitResult slidingFitResult(*iter, halfWindowLayers, slidingFitPitch);
105 
106  if (!slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(*iter, slidingFitResult)).second)
107  throw StatusCodeException(STATUS_CODE_FAILURE);
108  }
109  catch (StatusCodeException &statusCodeException)
110  {
111  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
112  throw statusCodeException;
113  }
114  }
115  }
116 }
intermediate_table::const_iterator const_iterator
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
float lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::CalculateBranchChi2 ( const pandora::Cluster *const  pCluster,
const pandora::CartesianVector &  splitPosition,
const pandora::CartesianVector &  splitDirection 
) const
private

Calculate RMS deviation of branch hits relative to the split direction.

Parameters
pClusterthe input branch cluster
splitPositionthe start position of the branch
splitDirectionthe start direction of the branch

Definition at line 292 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References f, and SplitBranchCluster().

Referenced by BuildClusterExtensionList().

294 {
295  CaloHitList principalCaloHitList, branchCaloHitList;
296 
297  this->SplitBranchCluster(pCluster, splitPosition, splitDirection, principalCaloHitList, branchCaloHitList);
298 
299  float totalChi2(0.f);
300  float totalHits(0.f);
301 
302  for (CaloHitList::const_iterator iter = branchCaloHitList.begin(), iterEnd = branchCaloHitList.end(); iter != iterEnd; ++iter)
303  {
304  const CaloHit *const pCaloHit = *iter;
305 
306  const CartesianVector hitPosition(pCaloHit->GetPositionVector());
307  const CartesianVector projectedPosition(splitPosition + splitDirection * splitDirection.GetDotProduct(hitPosition - splitPosition));
308 
309  totalChi2 += (hitPosition - projectedPosition).GetMagnitudeSquared();
310  totalHits += 1.f;
311  }
312 
313  if (totalHits > 0.f)
314  return std::sqrt(totalChi2 / totalHits);
315 
316  throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
317 }
intermediate_table::const_iterator const_iterator
TFile f
Definition: plotHisto.C:6
void SplitBranchCluster(const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection, pandora::CaloHitList &principalCaloHitList, pandora::CaloHitList &branchCaloHitList) const
Separate cluster into the branch hits to be split from the primary cluster.
virtual void lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::FindBestSplitPosition ( const TwoDSlidingFitResult branchSlidingFit,
const TwoDSlidingFitResult replacementSlidingFit,
pandora::CartesianVector &  replacementStartPosition,
pandora::CartesianVector &  branchSplitPosition,
pandora::CartesianVector &  branchSplitDirection 
) const
protectedpure virtual

Output the best split positions in branch and replacement clusters.

Parameters
branchSlidingFitthe inputted sliding fit result for possible branch cluster
pReplacementClusterthe inputted sliding fit result for possible replacement cluster
replacementStartPositionthe outputted start position of the replacement
branchSplitPositionthe outputted start position of the branch
branchSplitDirectionthe outputted start direction of the branch

Implemented in lar_content::BranchSplittingAlgorithm, and lar_content::DeltaRaySplittingAlgorithm.

Referenced by BuildClusterExtensionList().

void lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::GetListOfCleanClusters ( const pandora::ClusterList *const  pClusterList,
pandora::ClusterVector &  clusterVector 
) const
private

Populate cluster vector with subset of cluster list, containing clusters judged to be clean.

Parameters
pClusterListaddress of the cluster list
clusterVectorto receive the populated cluster vector

Definition at line 77 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References lar_content::LArClusterHelper::GetLengthSquared(), m_minClusterLength, and lar_content::LArClusterHelper::SortByNHits().

Referenced by Run().

78 {
79  for (ClusterList::const_iterator iter = pClusterList->begin(), iterEnd = pClusterList->end(); iter != iterEnd; ++iter)
80  {
81  const Cluster *const pCluster = *iter;
82 
84  continue;
85 
86  clusterVector.push_back(pCluster);
87  }
88 
89  std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
90 }
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.
intermediate_table::const_iterator const_iterator
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
void lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::PruneClusterExtensionList ( const ClusterExtensionList inputList,
const TwoDSlidingFitResultMap branchResultMap,
const TwoDSlidingFitResultMap replacementResultMap,
ClusterExtensionList outputList 
) const
private

Finalize the list of candidate splits.

Parameters
inputListthe input list of possible splits
branchResultMapthe sliding fit result map for branch clusters
replacementResultMapthe sliding fit result map for replacement clusters
outputListthe output list of definite splits

Definition at line 224 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References m_vetoDisplacement, and lar_content::LArClusterHelper::SortByNHits().

Referenced by Run().

226 {
227  ClusterList branchList;
228  for (const auto &mapEntry : branchMap)
229  branchList.push_back(mapEntry.first);
230  branchList.sort(LArClusterHelper::SortByNHits);
231 
232  ClusterList replacementList;
233  for (const auto &mapEntry : replacementMap)
234  replacementList.push_back(mapEntry.first);
235  replacementList.sort(LArClusterHelper::SortByNHits);
236 
237  for (const ClusterExtension &thisSplit : inputList)
238  {
239  const CartesianVector &branchVertex = thisSplit.GetBranchVertex();
240  const CartesianVector &replacementVertex = thisSplit.GetReplacementVertex();
241 
242  const float distanceSquared((branchVertex - replacementVertex).GetMagnitudeSquared());
243  const float vetoDistanceSquared(m_vetoDisplacement * m_vetoDisplacement);
244 
245  bool branchVeto(false), replacementVeto(false);
246 
247  // Veto the merge if another cluster is closer to the replacement vertex
248  for (const Cluster *const pBranchCluster : branchList)
249  {
250  const TwoDSlidingFitResult &slidingFit(branchMap.at(pBranchCluster));
251 
252  if (slidingFit.GetCluster() == thisSplit.GetReplacementCluster() || slidingFit.GetCluster() == thisSplit.GetBranchCluster())
253  continue;
254 
255  const float minDistanceSquared((replacementVertex - slidingFit.GetGlobalMinLayerPosition()).GetMagnitudeSquared());
256  const float maxDistanceSquared((replacementVertex - slidingFit.GetGlobalMaxLayerPosition()).GetMagnitudeSquared());
257 
258  if (std::min(minDistanceSquared, maxDistanceSquared) < std::max(distanceSquared, vetoDistanceSquared))
259  {
260  branchVeto = true;
261  break;
262  }
263  }
264 
265  // Veto the merge if another cluster is closer to the branch vertex
266  for (const Cluster *const pReplacementCluster : replacementList)
267  {
268  const TwoDSlidingFitResult &slidingFit(replacementMap.at(pReplacementCluster));
269 
270  if (slidingFit.GetCluster() == thisSplit.GetReplacementCluster() || slidingFit.GetCluster() == thisSplit.GetBranchCluster())
271  continue;
272 
273  const float minDistanceSquared((branchVertex - slidingFit.GetGlobalMinLayerPosition()).GetMagnitudeSquared());
274  const float maxDistanceSquared((branchVertex - slidingFit.GetGlobalMaxLayerPosition()).GetMagnitudeSquared());
275 
276  if (std::min(minDistanceSquared, maxDistanceSquared) < std::max(distanceSquared, vetoDistanceSquared))
277  {
278  replacementVeto = true;
279  break;
280  }
281  }
282 
283  if (branchVeto || replacementVeto)
284  continue;
285 
286  outputList.push_back(thisSplit);
287  }
288 }
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.
StatusCode lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
protectedvirtual

Reimplemented in lar_content::BranchSplittingAlgorithm, and lar_content::DeltaRaySplittingAlgorithm.

Definition at line 421 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References m_longHalfWindowLayers, m_minClusterLength, m_runCosmicMode, m_shortHalfWindowLayers, and m_vetoDisplacement.

Referenced by lar_content::BranchSplittingAlgorithm::ReadSettings(), and lar_content::DeltaRaySplittingAlgorithm::ReadSettings().

422 {
423  PANDORA_RETURN_RESULT_IF_AND_IF(
424  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ShortHalfWindow", m_shortHalfWindowLayers));
425 
426  PANDORA_RETURN_RESULT_IF_AND_IF(
427  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "LongHalfWindow", m_longHalfWindowLayers));
428 
429  PANDORA_RETURN_RESULT_IF_AND_IF(
430  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLength", m_minClusterLength));
431 
432  PANDORA_RETURN_RESULT_IF_AND_IF(
433  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VetoDisplacement", m_vetoDisplacement));
434 
435  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CosmicMode", m_runCosmicMode));
436 
437  return STATUS_CODE_SUCCESS;
438 }
StatusCode lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::ReplaceBranch ( const pandora::Cluster *const  pBranchCluster,
const pandora::Cluster *const  pReplacementCluster,
const pandora::CartesianVector &  branchSplitPosition,
const pandora::CartesianVector &  branchSplitDirection 
) const
private

Remove a branch from a cluster and replace it with a second cluster.

Parameters
pBranchClusterthe cluster containing a branch to be removed
pReplacementClusterthe replacement cluster
branchSplitPositionthe position at the start of the branch
branchSplitDirectionthe direction at the start of the branch

Definition at line 391 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References SplitBranchCluster().

Referenced by RunSplitAndExtension().

393 {
394  ClusterList clusterList;
395  clusterList.push_back(pBranchCluster);
396  clusterList.push_back(pReplacementCluster);
397 
398  std::string clusterListToSaveName, clusterListToDeleteName;
399  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
400  PandoraContentApi::InitializeFragmentation(*this, clusterList, clusterListToDeleteName, clusterListToSaveName));
401 
402  // Entire replacement cluster goes into new principal cluster
403  PandoraContentApi::Cluster::Parameters principalParameters;
404  pReplacementCluster->GetOrderedCaloHitList().FillCaloHitList(principalParameters.m_caloHitList);
405 
406  // Distribute hits in branch cluster between new principal and residual clusters
407  PandoraContentApi::Cluster::Parameters residualParameters;
408  this->SplitBranchCluster(
409  pBranchCluster, branchSplitPosition, branchSplitDirection, principalParameters.m_caloHitList, residualParameters.m_caloHitList);
410 
411  const Cluster *pPrincipalCluster(NULL), *pResidualCluster(NULL);
412  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, principalParameters, pPrincipalCluster));
413  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, residualParameters, pResidualCluster));
414  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*this, clusterListToSaveName, clusterListToDeleteName));
415 
416  return STATUS_CODE_SUCCESS;
417 }
void SplitBranchCluster(const pandora::Cluster *const pCluster, const pandora::CartesianVector &splitPosition, const pandora::CartesianVector &splitDirection, pandora::CaloHitList &principalCaloHitList, pandora::CaloHitList &branchCaloHitList) const
Separate cluster into the branch hits to be split from the primary cluster.
StatusCode lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::Run ( )
protectedvirtual

Definition at line 32 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References BuildClusterExtensionList(), BuildSlidingFitResultMap(), GetListOfCleanClusters(), m_longHalfWindowLayers, m_runCosmicMode, m_shortHalfWindowLayers, PruneClusterExtensionList(), and RunSplitAndExtension().

33 {
34  const ClusterList *pClusterList = NULL;
35  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
36 
37  TwoDSlidingFitResultMap branchSlidingFitResultMap, replacementSlidingFitResultMap;
38 
39  unsigned int nIterations(0);
40 
41  while (++nIterations < 100) // Protect against flip-flopping between two answers
42  {
43  // Get ordered list of candidate clusters
44  ClusterVector clusterVector;
45  this->GetListOfCleanClusters(pClusterList, clusterVector);
46 
47  // Calculate sliding fit results for branch clusters (use a soft sliding fit for these)
48  this->BuildSlidingFitResultMap(clusterVector, m_shortHalfWindowLayers, branchSlidingFitResultMap);
49 
50  // Calculate sliding fit results for replacement clusters (use a hard linear fit for these)
51  this->BuildSlidingFitResultMap(clusterVector, m_longHalfWindowLayers, replacementSlidingFitResultMap);
52 
53  // Compile a list of possible splits
54  ClusterExtensionList splitList;
55 
56  if (m_runCosmicMode)
57  {
58  this->BuildClusterExtensionList(clusterVector, branchSlidingFitResultMap, replacementSlidingFitResultMap, splitList);
59  }
60  else
61  {
62  ClusterExtensionList intermediateList;
63  this->BuildClusterExtensionList(clusterVector, branchSlidingFitResultMap, replacementSlidingFitResultMap, intermediateList);
64  this->PruneClusterExtensionList(intermediateList, branchSlidingFitResultMap, replacementSlidingFitResultMap, splitList);
65  }
66 
67  // Run splitting and extension
68  if (STATUS_CODE_SUCCESS != this->RunSplitAndExtension(splitList, branchSlidingFitResultMap, replacementSlidingFitResultMap))
69  break;
70  }
71 
72  return STATUS_CODE_SUCCESS;
73 }
void BuildSlidingFitResultMap(const pandora::ClusterVector &clusterVector, const unsigned int halfWindowLayers, TwoDSlidingFitResultMap &slidingFitResultMap) const
Build the map of sliding fit results.
void BuildClusterExtensionList(const pandora::ClusterVector &clusterVector, const TwoDSlidingFitResultMap &branchResultMap, const TwoDSlidingFitResultMap &replacementResultMap, ClusterExtensionList &clusterExtensionList) const
Build a list of candidate splits.
void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with subset of cluster list, containing clusters judged to be clean...
pandora::StatusCode RunSplitAndExtension(const ClusterExtensionList &splitList, TwoDSlidingFitResultMap &branchResultMap, TwoDSlidingFitResultMap &replacementResultMap) const
Run the machinary that performs the cluster splitting and extending.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
std::vector< art::Ptr< recob::Cluster > > ClusterVector
void PruneClusterExtensionList(const ClusterExtensionList &inputList, const TwoDSlidingFitResultMap &branchResultMap, const TwoDSlidingFitResultMap &replacementResultMap, ClusterExtensionList &outputList) const
Finalize the list of candidate splits.
StatusCode lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::RunSplitAndExtension ( const ClusterExtensionList splitList,
TwoDSlidingFitResultMap branchResultMap,
TwoDSlidingFitResultMap replacementResultMap 
) const
private

Run the machinary that performs the cluster splitting and extending.

Parameters
splitListthe input list of candidate splits
branchResultMapthe sliding fit result map for branch clusters
replacementResultMapthe sliding fit result map for replacement clusters

Definition at line 348 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

References lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::ClusterExtension::GetBranchCluster(), lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::ClusterExtension::GetBranchDirection(), lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::ClusterExtension::GetBranchVertex(), lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::ClusterExtension::GetReplacementCluster(), and ReplaceBranch().

Referenced by Run().

350 {
351  bool foundSplit(false);
352 
353  for (ClusterExtensionList::const_iterator iter = splitList.begin(), iterEnd = splitList.end(); iter != iterEnd; ++iter)
354  {
355  const ClusterExtension &thisSplit = *iter;
356 
357  const Cluster *const pBranchCluster = thisSplit.GetBranchCluster();
358  const Cluster *const pReplacementCluster = thisSplit.GetReplacementCluster();
359  const CartesianVector &branchSplitPosition = thisSplit.GetBranchVertex();
360  const CartesianVector &branchSplitDirection = thisSplit.GetBranchDirection();
361 
362  TwoDSlidingFitResultMap::iterator iterBranch1 = branchResultMap.find(pBranchCluster);
363  TwoDSlidingFitResultMap::iterator iterBranch2 = branchResultMap.find(pReplacementCluster);
364 
365  TwoDSlidingFitResultMap::iterator iterReplacement1 = replacementResultMap.find(pBranchCluster);
366  TwoDSlidingFitResultMap::iterator iterReplacement2 = replacementResultMap.find(pReplacementCluster);
367 
368  if (branchResultMap.end() == iterBranch1 || branchResultMap.end() == iterBranch2 ||
369  replacementResultMap.end() == iterReplacement1 || replacementResultMap.end() == iterReplacement2)
370  continue;
371 
372  PANDORA_RETURN_RESULT_IF(
373  STATUS_CODE_SUCCESS, !=, this->ReplaceBranch(pBranchCluster, pReplacementCluster, branchSplitPosition, branchSplitDirection));
374  branchResultMap.erase(iterBranch1);
375  branchResultMap.erase(iterBranch2);
376 
377  replacementResultMap.erase(iterReplacement1);
378  replacementResultMap.erase(iterReplacement2);
379 
380  foundSplit = true;
381  }
382 
383  if (foundSplit)
384  return STATUS_CODE_SUCCESS;
385 
386  return STATUS_CODE_NOT_FOUND;
387 }
intermediate_table::iterator iterator
intermediate_table::const_iterator const_iterator
pandora::StatusCode ReplaceBranch(const pandora::Cluster *const pBranchCluster, const pandora::Cluster *const pReplacementCluster, const pandora::CartesianVector &branchSplitPosition, const pandora::CartesianVector &branchSplitDirection) const
Remove a branch from a cluster and replace it with a second cluster.
void lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::SplitBranchCluster ( const pandora::Cluster *const  pCluster,
const pandora::CartesianVector &  splitPosition,
const pandora::CartesianVector &  splitDirection,
pandora::CaloHitList &  principalCaloHitList,
pandora::CaloHitList &  branchCaloHitList 
) const
private

Separate cluster into the branch hits to be split from the primary cluster.

Parameters
pClusterthe input branch cluster
splitPositionthe start position of the branch
splitDirectionthe start direction of the branch
principalCaloHitListthe hits to be added to the principal cluster
branchCaloHitListthe hits to be split off into the output branch cluster

Definition at line 321 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

Referenced by CalculateBranchChi2(), and ReplaceBranch().

323 {
324  // Distribute hits in branch cluster between new principal and residual clusters
325  CaloHitList caloHitsToDistribute;
326  pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitsToDistribute);
327 
328  for (CaloHitList::const_iterator iter = caloHitsToDistribute.begin(), iterEnd = caloHitsToDistribute.end(); iter != iterEnd; ++iter)
329  {
330  const CaloHit *const pCaloHit = *iter;
331 
332  if (splitDirection.GetDotProduct((pCaloHit->GetPositionVector() - splitPosition)) > 0.f)
333  {
334  branchCaloHitList.push_back(pCaloHit);
335  }
336  else
337  {
338  principalCaloHitList.push_back(pCaloHit);
339  }
340  }
341 
342  if (branchCaloHitList.empty())
343  throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
344 }
intermediate_table::const_iterator const_iterator

Member Data Documentation

unsigned int lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_longHalfWindowLayers
private

Definition at line 185 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.h.

Referenced by ReadSettings(), and Run().

float lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_minClusterLength
private
bool lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_runCosmicMode
private

Definition at line 188 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.h.

Referenced by ReadSettings(), and Run().

unsigned int lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_shortHalfWindowLayers
private

Definition at line 184 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.h.

Referenced by ReadSettings(), and Run().

float lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_vetoDisplacement
private

The documentation for this class was generated from the following files: