LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
TrackClusterCreationAlgorithm.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 TrackClusterCreationAlgorithm::TrackClusterCreationAlgorithm() :
22  m_mergeBackFilteredHits(true),
23  m_maxGapLayers(2),
24  m_maxCaloHitSeparationSquared(1.3f * 1.3f),
25  m_minCaloHitSeparationSquared(0.4f * 0.4f),
26  m_closeSeparationSquared(0.9f * 0.9f),
27  m_minMipFraction{0.f}
28 {
29 }
30 
31 //------------------------------------------------------------------------------------------------------------------------------------------
32 
34 {
35  const CaloHitList *pCaloHitList = NULL;
36  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pCaloHitList));
37 
38  OrderedCaloHitList selectedCaloHitList, rejectedCaloHitList;
39  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->FilterCaloHits(pCaloHitList, selectedCaloHitList, rejectedCaloHitList));
40 
41  HitAssociationMap forwardHitAssociationMap, backwardHitAssociationMap;
42  this->MakePrimaryAssociations(selectedCaloHitList, forwardHitAssociationMap, backwardHitAssociationMap);
43  this->MakeSecondaryAssociations(selectedCaloHitList, forwardHitAssociationMap, backwardHitAssociationMap);
44 
45  HitJoinMap hitJoinMap;
46  HitToClusterMap hitToClusterMap;
47  this->IdentifyJoins(selectedCaloHitList, forwardHitAssociationMap, backwardHitAssociationMap, hitJoinMap);
48  this->CreateClusters(selectedCaloHitList, hitJoinMap, hitToClusterMap);
49 
51  this->CreateClusters(rejectedCaloHitList, hitJoinMap, hitToClusterMap);
52 
53  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->AddFilteredCaloHits(selectedCaloHitList, rejectedCaloHitList, hitToClusterMap));
54 
55  return STATUS_CODE_SUCCESS;
56 }
57 
58 //------------------------------------------------------------------------------------------------------------------------------------------
59 
61  const CaloHitList *const pCaloHitList, OrderedCaloHitList &selectedCaloHitList, OrderedCaloHitList &rejectedCaloHitList) const
62 {
63  CaloHitList availableHitList;
64 
65  for (const CaloHit *const pCaloHit : *pCaloHitList)
66  {
67  if (PandoraContentApi::IsAvailable(*this, pCaloHit) && pCaloHit->GetMipEquivalentEnergy() >= m_minMipFraction)
68  availableHitList.push_back(pCaloHit);
69  }
70 
71  if (availableHitList.empty())
72  return STATUS_CODE_SUCCESS;
73 
74  HitType view{availableHitList.front()->GetHitType()};
75  const float ratio{LArGeometryHelper::GetWirePitchRatio(this->GetPandora(), view)};
76  const float minSeparationSquaredAdjusted{ratio * ratio * m_minCaloHitSeparationSquared};
77 
78  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, selectedCaloHitList.Add(availableHitList));
79 
80  for (OrderedCaloHitList::const_iterator iter = selectedCaloHitList.begin(), iterEnd = selectedCaloHitList.end(); iter != iterEnd; ++iter)
81  {
82  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
83  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
84 
85  for (const CaloHit *const pCaloHitI : caloHits)
86  {
87  bool useCaloHit(true);
88 
89  for (const CaloHit *const pCaloHitJ : caloHits)
90  {
91  if (pCaloHitI == pCaloHitJ)
92  continue;
93 
94  if ((pCaloHitI->GetMipEquivalentEnergy() < pCaloHitJ->GetMipEquivalentEnergy()) &&
95  ((pCaloHitI->GetPositionVector() - pCaloHitJ->GetPositionVector()).GetMagnitudeSquared() < minSeparationSquaredAdjusted))
96  {
97  useCaloHit = false;
98  break;
99  }
100  }
101 
102  if (!useCaloHit)
103  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, rejectedCaloHitList.Add(pCaloHitI));
104  }
105  }
106 
107  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, selectedCaloHitList.Remove(rejectedCaloHitList));
108  return STATUS_CODE_SUCCESS;
109 }
110 
111 //------------------------------------------------------------------------------------------------------------------------------------------
112 
114  const OrderedCaloHitList &selectedCaloHitList, const OrderedCaloHitList &rejectedCaloHitList, HitToClusterMap &hitToClusterMap) const
115 {
116  for (OrderedCaloHitList::const_iterator iter = rejectedCaloHitList.begin(), iterEnd = rejectedCaloHitList.end(); iter != iterEnd; ++iter)
117  {
118  CaloHitList *pCaloHitList = NULL;
119  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, selectedCaloHitList.GetCaloHitsInPseudoLayer(iter->first, pCaloHitList));
120 
121  if (!pCaloHitList || pCaloHitList->empty())
122  continue;
123  HitType view{pCaloHitList->front()->GetHitType()};
124  const float ratio{LArGeometryHelper::GetWirePitchRatio(this->GetPandora(), view)};
125  const float minSeparationSquaredAdjusted{ratio * ratio * m_minCaloHitSeparationSquared};
126 
127  CaloHitSet unavailableHits;
128 
129  CaloHitVector inputAvailableHits(iter->second->begin(), iter->second->end());
130  std::sort(inputAvailableHits.begin(), inputAvailableHits.end(), LArClusterHelper::SortHitsByPosition);
131 
132  CaloHitVector clusteredHits(pCaloHitList->begin(), pCaloHitList->end());
133  std::sort(clusteredHits.begin(), clusteredHits.end(), LArClusterHelper::SortHitsByPosition);
134 
135  bool carryOn(true);
136 
137  while (carryOn)
138  {
139  carryOn = false;
140  CaloHitVector newClusteredHits;
141 
142  for (const CaloHit *const pCaloHitI : inputAvailableHits)
143  {
144  if (unavailableHits.count(pCaloHitI))
145  continue;
146 
147  if (hitToClusterMap.end() != hitToClusterMap.find(pCaloHitI))
148  continue;
149 
150  const CaloHit *pClosestHit = NULL;
151  float closestSeparationSquared(minSeparationSquaredAdjusted);
152 
153  for (const CaloHit *const pCaloHitJ : clusteredHits)
154  {
155  if (pCaloHitI->GetMipEquivalentEnergy() > pCaloHitJ->GetMipEquivalentEnergy())
156  continue;
157 
158  const float separationSquared((pCaloHitI->GetPositionVector() - pCaloHitJ->GetPositionVector()).GetMagnitudeSquared());
159 
160  if (separationSquared < closestSeparationSquared)
161  {
162  closestSeparationSquared = separationSquared;
163  pClosestHit = pCaloHitJ;
164  }
165  }
166 
167  if (!pClosestHit)
168  continue;
169 
170  HitToClusterMap::const_iterator mapIter = hitToClusterMap.find(pClosestHit);
171 
172  if (hitToClusterMap.end() == mapIter)
173  throw StatusCodeException(STATUS_CODE_FAILURE);
174 
175  const Cluster *const pCluster = mapIter->second;
176  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pCluster, pCaloHitI));
177  (void)hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHitI, pCluster));
178 
179  newClusteredHits.push_back(pCaloHitI);
180  carryOn = true;
181  }
182 
183  for (const CaloHit *const pCaloHit : newClusteredHits)
184  {
185  clusteredHits.push_back(pCaloHit);
186  unavailableHits.insert(pCaloHit);
187  }
188  }
189  }
190 
191  return STATUS_CODE_SUCCESS;
192 }
193 
194 //------------------------------------------------------------------------------------------------------------------------------------------
195 
196 void TrackClusterCreationAlgorithm::MakePrimaryAssociations(const OrderedCaloHitList &orderedCaloHitList,
197  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
198 {
199  for (OrderedCaloHitList::const_iterator iterI = orderedCaloHitList.begin(), iterIEnd = orderedCaloHitList.end(); iterI != iterIEnd; ++iterI)
200  {
201  unsigned int nLayersConsidered(0);
202 
203  CaloHitVector caloHitsI(iterI->second->begin(), iterI->second->end());
204  std::sort(caloHitsI.begin(), caloHitsI.end(), LArClusterHelper::SortHitsByPosition);
205 
206  for (OrderedCaloHitList::const_iterator iterJ = iterI, iterJEnd = orderedCaloHitList.end();
207  (nLayersConsidered++ <= m_maxGapLayers + 1) && (iterJ != iterJEnd); ++iterJ)
208  {
209  if (iterJ->first == iterI->first || iterJ->first > iterI->first + m_maxGapLayers + 1)
210  continue;
211 
212  CaloHitVector caloHitsJ(iterJ->second->begin(), iterJ->second->end());
213  std::sort(caloHitsJ.begin(), caloHitsJ.end(), LArClusterHelper::SortHitsByPosition);
214 
215  for (const CaloHit *const pCaloHitI : caloHitsI)
216  {
217  for (const CaloHit *const pCaloHitJ : caloHitsJ)
218  this->CreatePrimaryAssociation(pCaloHitI, pCaloHitJ, forwardHitAssociationMap, backwardHitAssociationMap);
219  }
220  }
221  }
222 }
223 
224 //------------------------------------------------------------------------------------------------------------------------------------------
225 
226 void TrackClusterCreationAlgorithm::MakeSecondaryAssociations(const OrderedCaloHitList &orderedCaloHitList,
227  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
228 {
229  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
230  {
231  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
232  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
233 
234  for (const CaloHit *const pCaloHit : caloHits)
235  {
236  HitAssociationMap::const_iterator fwdIter = forwardHitAssociationMap.find(pCaloHit);
237  const CaloHit *const pForwardHit((forwardHitAssociationMap.end() == fwdIter) ? NULL : fwdIter->second.GetPrimaryTarget());
238 
239  HitAssociationMap::const_iterator fwdCheckIter = backwardHitAssociationMap.find(pForwardHit);
240  const CaloHit *const pForwardHitCheck((backwardHitAssociationMap.end() == fwdCheckIter) ? NULL : fwdCheckIter->second.GetPrimaryTarget());
241 
242  if ((NULL != pForwardHit) && (pForwardHitCheck != pCaloHit))
243  this->CreateSecondaryAssociation(pCaloHit, pForwardHit, forwardHitAssociationMap, backwardHitAssociationMap);
244 
245  HitAssociationMap::const_iterator bwdIter = backwardHitAssociationMap.find(pCaloHit);
246  const CaloHit *const pBackwardHit((backwardHitAssociationMap.end() == bwdIter) ? NULL : bwdIter->second.GetPrimaryTarget());
247 
248  HitAssociationMap::const_iterator bwdCheckIter = forwardHitAssociationMap.find(pBackwardHit);
249  const CaloHit *const pBackwardHitCheck((forwardHitAssociationMap.end() == bwdCheckIter) ? NULL : bwdCheckIter->second.GetPrimaryTarget());
250 
251  if ((NULL != pBackwardHit) && (pBackwardHitCheck != pCaloHit))
252  this->CreateSecondaryAssociation(pBackwardHit, pCaloHit, forwardHitAssociationMap, backwardHitAssociationMap);
253  }
254  }
255 }
256 
257 //------------------------------------------------------------------------------------------------------------------------------------------
258 
259 void TrackClusterCreationAlgorithm::IdentifyJoins(const OrderedCaloHitList &orderedCaloHitList,
260  const HitAssociationMap &forwardHitAssociationMap, const HitAssociationMap &backwardHitAssociationMap, HitJoinMap &hitJoinMap) const
261 {
262  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
263  {
264  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
265  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
266 
267  for (const CaloHit *const pCaloHit : caloHits)
268  {
269  const CaloHit *const pForwardJoinHit = this->GetJoinHit(pCaloHit, forwardHitAssociationMap, backwardHitAssociationMap);
270  const CaloHit *const pBackwardJoinHit = this->GetJoinHit(pForwardJoinHit, backwardHitAssociationMap, forwardHitAssociationMap);
271 
272  if ((NULL == pForwardJoinHit) || (NULL == pBackwardJoinHit) || (pBackwardJoinHit != pCaloHit))
273  continue;
274 
275  HitJoinMap::const_iterator joinIter = hitJoinMap.find(pCaloHit);
276 
277  if (hitJoinMap.end() == joinIter)
278  hitJoinMap.insert(HitJoinMap::value_type(pCaloHit, pForwardJoinHit));
279 
280  if ((hitJoinMap.end() != joinIter) && (joinIter->second != pForwardJoinHit))
281  throw StatusCodeException(STATUS_CODE_FAILURE);
282  }
283  }
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
289  const OrderedCaloHitList &orderedCaloHitList, const HitJoinMap &hitJoinMap, HitToClusterMap &hitToClusterMap) const
290 {
291  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
292  {
293  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
294  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
295 
296  for (const CaloHit *const pCaloHit : caloHits)
297  {
298  const Cluster *pCluster = NULL;
299 
300  HitToClusterMap::const_iterator mapIter = hitToClusterMap.find(pCaloHit);
301 
302  if (hitToClusterMap.end() == mapIter)
303  {
304  PandoraContentApi::Cluster::Parameters parameters;
305  parameters.m_caloHitList.push_back(pCaloHit);
306  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pCluster));
307  hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
308  }
309  else
310  {
311  pCluster = mapIter->second;
312  }
313 
314  HitJoinMap::const_iterator joinIter = hitJoinMap.find(pCaloHit);
315 
316  if (hitJoinMap.end() == joinIter)
317  continue;
318 
319  if (hitToClusterMap.end() != hitToClusterMap.find(joinIter->second))
320  throw StatusCodeException(STATUS_CODE_FAILURE);
321 
322  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pCluster, joinIter->second));
323  hitToClusterMap.insert(HitToClusterMap::value_type(joinIter->second, pCluster));
324  }
325  }
326 }
327 
328 //------------------------------------------------------------------------------------------------------------------------------------------
329 
330 void TrackClusterCreationAlgorithm::CreatePrimaryAssociation(const CaloHit *const pCaloHitI, const CaloHit *const pCaloHitJ,
331  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
332 {
333  HitType view{pCaloHitI->GetHitType()};
334  const float ratio{LArGeometryHelper::GetWirePitchRatio(this->GetPandora(), view)};
335  const float maxSeparationSquaredAdjusted{ratio * ratio * m_maxCaloHitSeparationSquared};
336 
337  const float distanceSquared((pCaloHitJ->GetPositionVector() - pCaloHitI->GetPositionVector()).GetMagnitudeSquared());
338 
339  if (distanceSquared > maxSeparationSquaredAdjusted)
340  return;
341 
342  HitAssociationMap::iterator forwardIter = forwardHitAssociationMap.find(pCaloHitI);
343 
344  if (forwardHitAssociationMap.end() == forwardIter)
345  {
346  forwardHitAssociationMap.insert(HitAssociationMap::value_type(pCaloHitI, HitAssociation(pCaloHitJ, distanceSquared)));
347  }
348  else if (distanceSquared < forwardIter->second.GetPrimaryDistanceSquared())
349  {
350  forwardIter->second = HitAssociation(pCaloHitJ, distanceSquared);
351  }
352 
353  HitAssociationMap::iterator backwardIter = backwardHitAssociationMap.find(pCaloHitJ);
354 
355  if (backwardHitAssociationMap.end() == backwardIter)
356  {
357  backwardHitAssociationMap.insert(HitAssociationMap::value_type(pCaloHitJ, HitAssociation(pCaloHitI, distanceSquared)));
358  }
359  else if (distanceSquared < backwardIter->second.GetPrimaryDistanceSquared())
360  {
361  backwardIter->second = HitAssociation(pCaloHitI, distanceSquared);
362  }
363 }
364 
365 //------------------------------------------------------------------------------------------------------------------------------------------
366 
367 void TrackClusterCreationAlgorithm::CreateSecondaryAssociation(const CaloHit *const pCaloHitI, const CaloHit *const pCaloHitJ,
368  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
369 {
370  HitType view{pCaloHitI->GetHitType()};
371  const float ratio{LArGeometryHelper::GetWirePitchRatio(this->GetPandora(), view)};
372  const float closeSeparationSquaredAdjusted{ratio * ratio * m_closeSeparationSquared};
373 
374  HitAssociationMap::iterator forwardIter = forwardHitAssociationMap.find(pCaloHitI);
375  HitAssociationMap::iterator backwardIter = backwardHitAssociationMap.find(pCaloHitJ);
376 
377  if ((forwardHitAssociationMap.end() == forwardIter) || (backwardHitAssociationMap.end() == backwardIter))
378  return;
379 
380  HitAssociation &forwardAssociation(forwardIter->second);
381  HitAssociation &backwardAssociation(backwardIter->second);
382 
383  if ((forwardAssociation.GetPrimaryTarget() != pCaloHitJ) && (backwardAssociation.GetPrimaryTarget() == pCaloHitI))
384  {
385  if ((backwardAssociation.GetPrimaryDistanceSquared() < forwardAssociation.GetSecondaryDistanceSquared()) &&
386  (backwardAssociation.GetPrimaryDistanceSquared() < closeSeparationSquaredAdjusted))
387  {
388  forwardAssociation.SetSecondaryTarget(pCaloHitJ, backwardAssociation.GetPrimaryDistanceSquared());
389  }
390  }
391 
392  if ((backwardAssociation.GetPrimaryTarget() != pCaloHitI) && (forwardAssociation.GetPrimaryTarget() == pCaloHitJ))
393  {
394  if ((forwardAssociation.GetPrimaryDistanceSquared() < backwardAssociation.GetSecondaryDistanceSquared()) &&
395  (forwardAssociation.GetPrimaryDistanceSquared() < closeSeparationSquaredAdjusted))
396  {
397  backwardAssociation.SetSecondaryTarget(pCaloHitI, forwardAssociation.GetPrimaryDistanceSquared());
398  }
399  }
400 }
401 
402 //------------------------------------------------------------------------------------------------------------------------------------------
403 
405  const CaloHit *const pCaloHit, const HitAssociationMap &hitAssociationMapI, const HitAssociationMap &hitAssociationMapJ) const
406 {
407  HitAssociationMap::const_iterator iterI = hitAssociationMapI.find(pCaloHit);
408 
409  if (hitAssociationMapI.end() == iterI)
410  return NULL;
411 
412  const CaloHit *const pPrimaryTarget = iterI->second.GetPrimaryTarget();
413  const CaloHit *const pSecondaryTarget = iterI->second.GetSecondaryTarget();
414 
415  if (NULL == pSecondaryTarget)
416  return pPrimaryTarget;
417 
418  unsigned int primaryNSteps(0), secondaryNSteps(0);
419  const CaloHit *const pPrimaryTrace = this->TraceHitAssociation(pPrimaryTarget, hitAssociationMapI, hitAssociationMapJ, primaryNSteps);
420  const CaloHit *const pSecondaryTrace = this->TraceHitAssociation(pSecondaryTarget, hitAssociationMapI, hitAssociationMapJ, secondaryNSteps);
421 
422  if ((pPrimaryTrace == pSecondaryTrace) || (secondaryNSteps < 5))
423  return pPrimaryTarget;
424 
425  return NULL;
426 }
427 
428 //------------------------------------------------------------------------------------------------------------------------------------------
429 
430 const CaloHit *TrackClusterCreationAlgorithm::TraceHitAssociation(const CaloHit *const pCaloHit,
431  const HitAssociationMap &hitAssociationMapI, const HitAssociationMap &hitAssociationMapJ, unsigned int &nSteps) const
432 {
433  nSteps = 0;
434  const CaloHit *pThisHit = pCaloHit;
435  const CaloHit *pLastHit = pCaloHit;
436 
437  while (true)
438  {
439  ++nSteps;
440  pThisHit = pLastHit;
441  HitAssociationMap::const_iterator iterI = hitAssociationMapI.find(pThisHit);
442 
443  if (hitAssociationMapI.end() == iterI)
444  break;
445 
446  pLastHit = iterI->second.GetPrimaryTarget();
447  HitAssociationMap::const_iterator iterJ = hitAssociationMapJ.find(pLastHit);
448 
449  if (hitAssociationMapJ.end() == iterJ)
450  break;
451 
452  if (iterJ->second.GetPrimaryTarget() != pThisHit)
453  break;
454  }
455 
456  return pThisHit;
457 }
458 
459 //------------------------------------------------------------------------------------------------------------------------------------------
460 
461 StatusCode TrackClusterCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
462 {
463  PANDORA_RETURN_RESULT_IF_AND_IF(
464  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MergeBackFilteredHits", m_mergeBackFilteredHits));
465 
466  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxGapLayers", m_maxGapLayers));
467 
468  float maxCaloHitSeparation = std::sqrt(m_maxCaloHitSeparationSquared);
469  PANDORA_RETURN_RESULT_IF_AND_IF(
470  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxCaloHitSeparation", maxCaloHitSeparation));
471  m_maxCaloHitSeparationSquared = maxCaloHitSeparation * maxCaloHitSeparation;
472 
473  float minCaloHitSeparation = std::sqrt(m_minCaloHitSeparationSquared);
474  PANDORA_RETURN_RESULT_IF_AND_IF(
475  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCaloHitSeparation", minCaloHitSeparation));
476  m_minCaloHitSeparationSquared = minCaloHitSeparation * minCaloHitSeparation;
477 
478  float closeSeparation = std::sqrt(m_closeSeparationSquared);
479  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CloseSeparation", closeSeparation));
480  m_closeSeparationSquared = closeSeparation * closeSeparation;
481 
482  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMipFraction", m_minMipFraction));
483 
484  return STATUS_CODE_SUCCESS;
485 }
486 
487 } // namespace lar_content
intermediate_table::iterator iterator
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
pandora::StatusCode FilterCaloHits(const pandora::CaloHitList *const pCaloHitList, pandora::OrderedCaloHitList &selectedCaloHitList, pandora::OrderedCaloHitList &rejectedCaloHitList) const
Filter out low pulse height hits in close proximity to high pulse height hits.
static float GetWirePitchRatio(const pandora::Pandora &pandora, const pandora::HitType view)
Return the ratio of the wire pitch of the specified view to the minimum wire pitch for the detector...
float m_maxCaloHitSeparationSquared
Square of maximum calo hit separation.
intermediate_table::const_iterator const_iterator
pandora::StatusCode AddFilteredCaloHits(const pandora::OrderedCaloHitList &selectedCaloHitList, const pandora::OrderedCaloHitList &rejectedCaloHitList, HitToClusterMap &hitToClusterMap) const
Merge previously filtered hits back into their associated clusters.
void IdentifyJoins(const pandora::OrderedCaloHitList &orderedCaloHitList, const HitAssociationMap &forwardHitAssociationMap, const HitAssociationMap &backwardHitAssociationMap, HitJoinMap &hitJoinMap) const
Identify final hit joins for use in cluster formation.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
float m_minMipFraction
Minimum fraction of a MIP to consider a hit.
float GetSecondaryDistanceSquared() const
Get the secondary distance squared.
Header file for the cluster creation algorithm class.
std::unordered_map< const pandora::CaloHit *, HitAssociation > HitAssociationMap
void MakePrimaryAssociations(const pandora::OrderedCaloHitList &orderedCaloHitList, HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
Control primary association formation.
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.
const pandora::CaloHit * GetPrimaryTarget() const
Get the primary target.
std::unordered_map< const pandora::CaloHit *, const pandora::CaloHit * > HitJoinMap
float GetPrimaryDistanceSquared() const
Get the primary distance squared.
void SetSecondaryTarget(const pandora::CaloHit *const pSecondaryTarget, const float secondaryDistanceSquared)
Set secondary target.
void CreateClusters(const pandora::OrderedCaloHitList &orderedCaloHitList, const HitJoinMap &hitJoinMap, HitToClusterMap &hitToClusterMap) const
Final cluster formation.
void CreatePrimaryAssociation(const pandora::CaloHit *const pCaloHitI, const pandora::CaloHit *const pCaloHitJ, HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
Create primary association if appropriate, hitI<->hitJ.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int m_maxGapLayers
Maximum number of layers for a gap.
HitType
Definition: HitType.h:12
const pandora::CaloHit * GetJoinHit(const pandora::CaloHit *const pCaloHit, const HitAssociationMap &hitAssociationMapI, const HitAssociationMap &hitAssociationMapJ) const
Get hit to join by tracing associations via map I, checking via map J.
bool m_mergeBackFilteredHits
Merge rejected hits into their associated clusters.
void MakeSecondaryAssociations(const pandora::OrderedCaloHitList &orderedCaloHitList, HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
Control secondary association formation.
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
void CreateSecondaryAssociation(const pandora::CaloHit *const pCaloHitI, const pandora::CaloHit *const pCaloHitJ, HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
Create secondary association if appropriate, hitI<->hitJ.
float m_minCaloHitSeparationSquared
Square of minimum calo hit separation.
float m_closeSeparationSquared
Length scale (squared) for close hit separation.
const pandora::CaloHit * TraceHitAssociation(const pandora::CaloHit *const pCaloHit, const HitAssociationMap &hitAssociationMapI, const HitAssociationMap &hitAssociationMapJ, unsigned int &nSteps) const
Get last hit obtained by tracing associations via map I, checking via map J.