Classes | Public Member Functions | Protected Types | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
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

TwoDSlidingFitSplittingAndSplicingAlgorithm class.

Definition at line 21 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.h.

Member Typedef Documentation

Constructor & Destructor Documentation

lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::TwoDSlidingFitSplittingAndSplicingAlgorithm ( )

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 121 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

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

96 {
97  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
98 
99  for (ClusterVector::const_iterator iter = clusterVector.begin(), iterEnd = clusterVector.end(); iter != iterEnd; ++iter)
100  {
101  if (slidingFitResultMap.end() == slidingFitResultMap.find(*iter))
102  {
103  try
104  {
105  const TwoDSlidingFitResult slidingFitResult(*iter, halfWindowLayers, slidingFitPitch);
106 
107  if (!slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(*iter, slidingFitResult)).second)
108  throw StatusCodeException(STATUS_CODE_FAILURE);
109  }
110  catch (StatusCodeException &statusCodeException)
111  {
112  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
113  throw statusCodeException;
114  }
115  }
116  }
117 }
intermediate_table::const_iterator const_iterator
static float GetWireZPitch(const pandora::Pandora &pandora, 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 293 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

295 {
296  CaloHitList principalCaloHitList, branchCaloHitList;
297 
298  this->SplitBranchCluster(pCluster, splitPosition, splitDirection, principalCaloHitList, branchCaloHitList);
299 
300  float totalChi2(0.f);
301  float totalHits(0.f);
302 
303  for (CaloHitList::const_iterator iter = branchCaloHitList.begin(), iterEnd = branchCaloHitList.end(); iter != iterEnd; ++iter)
304  {
305  const CaloHit *const pCaloHit = *iter;
306 
307  const CartesianVector hitPosition(pCaloHit->GetPositionVector());
308  const CartesianVector projectedPosition(splitPosition + splitDirection * splitDirection.GetDotProduct(hitPosition - splitPosition));
309 
310  totalChi2 += (hitPosition - projectedPosition).GetMagnitudeSquared();
311  totalHits += 1.f;
312  }
313 
314  if (totalHits > 0.f)
315  return std::sqrt(totalChi2 / totalHits);
316 
317  throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
318 }
intermediate_table::const_iterator const_iterator
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.

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.

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 225 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

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

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

Definition at line 422 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

423 {
424  PANDORA_RETURN_RESULT_IF_AND_IF(
425  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ShortHalfWindow", m_shortHalfWindowLayers));
426 
427  PANDORA_RETURN_RESULT_IF_AND_IF(
428  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "LongHalfWindow", m_longHalfWindowLayers));
429 
430  PANDORA_RETURN_RESULT_IF_AND_IF(
431  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLength", m_minClusterLength));
432 
433  PANDORA_RETURN_RESULT_IF_AND_IF(
434  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VetoDisplacement", m_vetoDisplacement));
435 
436  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CosmicMode", m_runCosmicMode));
437 
438  return STATUS_CODE_SUCCESS;
439 }
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 392 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

394 {
395  ClusterList clusterList;
396  clusterList.push_back(pBranchCluster);
397  clusterList.push_back(pReplacementCluster);
398 
399  std::string clusterListToSaveName, clusterListToDeleteName;
400  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
401  PandoraContentApi::InitializeFragmentation(*this, clusterList, clusterListToDeleteName, clusterListToSaveName));
402 
403  // Entire replacement cluster goes into new principal cluster
404  PandoraContentApi::Cluster::Parameters principalParameters;
405  pReplacementCluster->GetOrderedCaloHitList().FillCaloHitList(principalParameters.m_caloHitList);
406 
407  // Distribute hits in branch cluster between new principal and residual clusters
408  PandoraContentApi::Cluster::Parameters residualParameters;
409  this->SplitBranchCluster(
410  pBranchCluster, branchSplitPosition, branchSplitDirection, principalParameters.m_caloHitList, residualParameters.m_caloHitList);
411 
412  const Cluster *pPrincipalCluster(NULL), *pResidualCluster(NULL);
413  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, principalParameters, pPrincipalCluster));
414  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, residualParameters, pResidualCluster));
415  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*this, clusterListToSaveName, clusterListToDeleteName));
416 
417  return STATUS_CODE_SUCCESS;
418 }
std::string string
Definition: nybbler.cc:12
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.

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 349 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

351 {
352  bool foundSplit(false);
353 
354  for (ClusterExtensionList::const_iterator iter = splitList.begin(), iterEnd = splitList.end(); iter != iterEnd; ++iter)
355  {
356  const ClusterExtension &thisSplit = *iter;
357 
358  const Cluster *const pBranchCluster = thisSplit.GetBranchCluster();
359  const Cluster *const pReplacementCluster = thisSplit.GetReplacementCluster();
360  const CartesianVector &branchSplitPosition = thisSplit.GetBranchVertex();
361  const CartesianVector &branchSplitDirection = thisSplit.GetBranchDirection();
362 
363  TwoDSlidingFitResultMap::iterator iterBranch1 = branchResultMap.find(pBranchCluster);
364  TwoDSlidingFitResultMap::iterator iterBranch2 = branchResultMap.find(pReplacementCluster);
365 
366  TwoDSlidingFitResultMap::iterator iterReplacement1 = replacementResultMap.find(pBranchCluster);
367  TwoDSlidingFitResultMap::iterator iterReplacement2 = replacementResultMap.find(pReplacementCluster);
368 
369  if (branchResultMap.end() == iterBranch1 || branchResultMap.end() == iterBranch2 ||
370  replacementResultMap.end() == iterReplacement1 || replacementResultMap.end() == iterReplacement2)
371  continue;
372 
373  PANDORA_RETURN_RESULT_IF(
374  STATUS_CODE_SUCCESS, !=, this->ReplaceBranch(pBranchCluster, pReplacementCluster, branchSplitPosition, branchSplitDirection));
375  branchResultMap.erase(iterBranch1);
376  branchResultMap.erase(iterBranch2);
377 
378  replacementResultMap.erase(iterReplacement1);
379  replacementResultMap.erase(iterReplacement2);
380 
381  foundSplit = true;
382  }
383 
384  if (foundSplit)
385  return STATUS_CODE_SUCCESS;
386 
387  return STATUS_CODE_NOT_FOUND;
388 }
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 322 of file TwoDSlidingFitSplittingAndSplicingAlgorithm.cc.

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

Member Data Documentation

unsigned int lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_longHalfWindowLayers
private
float lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_minClusterLength
private
bool lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_runCosmicMode
private
unsigned int lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_shortHalfWindowLayers
private
float lar_content::TwoDSlidingFitSplittingAndSplicingAlgorithm::m_vetoDisplacement
private

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