TrackClusterCreationAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArTwoDReco/LArClusterCreation/TrackClusterCreationAlgorithm.cc
3  *
4  * @brief Implementation of the cluster creation algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 TrackClusterCreationAlgorithm::TrackClusterCreationAlgorithm() :
21  m_mergeBackFilteredHits(true),
22  m_maxGapLayers(2),
23  m_maxCaloHitSeparationSquared(1.3f * 1.3f),
24  m_minCaloHitSeparationSquared(0.4f * 0.4f),
25  m_closeSeparationSquared(0.9f * 0.9f)
26 {
27 }
28 
29 //------------------------------------------------------------------------------------------------------------------------------------------
30 
32 {
33  const CaloHitList *pCaloHitList = NULL;
34  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pCaloHitList));
35 
36  OrderedCaloHitList selectedCaloHitList, rejectedCaloHitList;
37  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->FilterCaloHits(pCaloHitList, selectedCaloHitList, rejectedCaloHitList));
38 
39  HitAssociationMap forwardHitAssociationMap, backwardHitAssociationMap;
40  this->MakePrimaryAssociations(selectedCaloHitList, forwardHitAssociationMap, backwardHitAssociationMap);
41  this->MakeSecondaryAssociations(selectedCaloHitList, forwardHitAssociationMap, backwardHitAssociationMap);
42 
43  HitJoinMap hitJoinMap;
44  HitToClusterMap hitToClusterMap;
45  this->IdentifyJoins(selectedCaloHitList, forwardHitAssociationMap, backwardHitAssociationMap, hitJoinMap);
46  this->CreateClusters(selectedCaloHitList, hitJoinMap, hitToClusterMap);
47 
49  this->CreateClusters(rejectedCaloHitList, hitJoinMap, hitToClusterMap);
50 
51  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->AddFilteredCaloHits(selectedCaloHitList, rejectedCaloHitList, hitToClusterMap));
52 
53  return STATUS_CODE_SUCCESS;
54 }
55 
56 //------------------------------------------------------------------------------------------------------------------------------------------
57 
59  const CaloHitList *const pCaloHitList, OrderedCaloHitList &selectedCaloHitList, OrderedCaloHitList &rejectedCaloHitList) const
60 {
61  CaloHitList availableHitList;
62 
63  for (const CaloHit *const pCaloHit : *pCaloHitList)
64  {
65  if (PandoraContentApi::IsAvailable(*this, pCaloHit))
66  availableHitList.push_back(pCaloHit);
67  }
68 
69  if (availableHitList.empty())
70  return STATUS_CODE_SUCCESS;
71 
72  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, selectedCaloHitList.Add(availableHitList));
73 
74  for (OrderedCaloHitList::const_iterator iter = selectedCaloHitList.begin(), iterEnd = selectedCaloHitList.end(); iter != iterEnd; ++iter)
75  {
76  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
77  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
78 
79  for (const CaloHit *const pCaloHitI : caloHits)
80  {
81  bool useCaloHit(true);
82 
83  for (const CaloHit *const pCaloHitJ : caloHits)
84  {
85  if (pCaloHitI == pCaloHitJ)
86  continue;
87 
88  if ((pCaloHitI->GetMipEquivalentEnergy() < pCaloHitJ->GetMipEquivalentEnergy()) &&
89  ((pCaloHitI->GetPositionVector() - pCaloHitJ->GetPositionVector()).GetMagnitudeSquared() < m_minCaloHitSeparationSquared))
90  {
91  useCaloHit = false;
92  break;
93  }
94  }
95 
96  if (!useCaloHit)
97  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, rejectedCaloHitList.Add(pCaloHitI));
98  }
99  }
100 
101  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, selectedCaloHitList.Remove(rejectedCaloHitList));
102  return STATUS_CODE_SUCCESS;
103 }
104 
105 //------------------------------------------------------------------------------------------------------------------------------------------
106 
108  const OrderedCaloHitList &selectedCaloHitList, const OrderedCaloHitList &rejectedCaloHitList, HitToClusterMap &hitToClusterMap) const
109 {
110  for (OrderedCaloHitList::const_iterator iter = rejectedCaloHitList.begin(), iterEnd = rejectedCaloHitList.end(); iter != iterEnd; ++iter)
111  {
112  CaloHitList *pCaloHitList = NULL;
113  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, selectedCaloHitList.GetCaloHitsInPseudoLayer(iter->first, pCaloHitList));
114 
115  CaloHitSet unavailableHits;
116 
117  CaloHitVector inputAvailableHits(iter->second->begin(), iter->second->end());
118  std::sort(inputAvailableHits.begin(), inputAvailableHits.end(), LArClusterHelper::SortHitsByPosition);
119 
120  CaloHitVector clusteredHits(pCaloHitList->begin(), pCaloHitList->end());
121  std::sort(clusteredHits.begin(), clusteredHits.end(), LArClusterHelper::SortHitsByPosition);
122 
123  bool carryOn(true);
124 
125  while (carryOn)
126  {
127  carryOn = false;
128  CaloHitVector newClusteredHits;
129 
130  for (const CaloHit *const pCaloHitI : inputAvailableHits)
131  {
132  if (unavailableHits.count(pCaloHitI))
133  continue;
134 
135  if (hitToClusterMap.end() != hitToClusterMap.find(pCaloHitI))
136  continue;
137 
138  const CaloHit *pClosestHit = NULL;
139  float closestSeparationSquared(m_minCaloHitSeparationSquared);
140 
141  for (const CaloHit *const pCaloHitJ : clusteredHits)
142  {
143  if (pCaloHitI->GetMipEquivalentEnergy() > pCaloHitJ->GetMipEquivalentEnergy())
144  continue;
145 
146  const float separationSquared((pCaloHitI->GetPositionVector() - pCaloHitJ->GetPositionVector()).GetMagnitudeSquared());
147 
148  if (separationSquared < closestSeparationSquared)
149  {
150  closestSeparationSquared = separationSquared;
151  pClosestHit = pCaloHitJ;
152  }
153  }
154 
155  if (!pClosestHit)
156  continue;
157 
158  HitToClusterMap::const_iterator mapIter = hitToClusterMap.find(pClosestHit);
159 
160  if (hitToClusterMap.end() == mapIter)
161  throw StatusCodeException(STATUS_CODE_FAILURE);
162 
163  const Cluster *const pCluster = mapIter->second;
164  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pCluster, pCaloHitI));
165  (void)hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHitI, pCluster));
166 
167  newClusteredHits.push_back(pCaloHitI);
168  carryOn = true;
169  }
170 
171  for (const CaloHit *const pCaloHit : newClusteredHits)
172  {
173  clusteredHits.push_back(pCaloHit);
174  unavailableHits.insert(pCaloHit);
175  }
176  }
177  }
178 
179  return STATUS_CODE_SUCCESS;
180 }
181 
182 //------------------------------------------------------------------------------------------------------------------------------------------
183 
184 void TrackClusterCreationAlgorithm::MakePrimaryAssociations(const OrderedCaloHitList &orderedCaloHitList,
185  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
186 {
187  for (OrderedCaloHitList::const_iterator iterI = orderedCaloHitList.begin(), iterIEnd = orderedCaloHitList.end(); iterI != iterIEnd; ++iterI)
188  {
189  unsigned int nLayersConsidered(0);
190 
191  CaloHitVector caloHitsI(iterI->second->begin(), iterI->second->end());
192  std::sort(caloHitsI.begin(), caloHitsI.end(), LArClusterHelper::SortHitsByPosition);
193 
194  for (OrderedCaloHitList::const_iterator iterJ = iterI, iterJEnd = orderedCaloHitList.end();
195  (nLayersConsidered++ <= m_maxGapLayers + 1) && (iterJ != iterJEnd); ++iterJ)
196  {
197  if (iterJ->first == iterI->first || iterJ->first > iterI->first + m_maxGapLayers + 1)
198  continue;
199 
200  CaloHitVector caloHitsJ(iterJ->second->begin(), iterJ->second->end());
201  std::sort(caloHitsJ.begin(), caloHitsJ.end(), LArClusterHelper::SortHitsByPosition);
202 
203  for (const CaloHit *const pCaloHitI : caloHitsI)
204  {
205  for (const CaloHit *const pCaloHitJ : caloHitsJ)
206  this->CreatePrimaryAssociation(pCaloHitI, pCaloHitJ, forwardHitAssociationMap, backwardHitAssociationMap);
207  }
208  }
209  }
210 }
211 
212 //------------------------------------------------------------------------------------------------------------------------------------------
213 
214 void TrackClusterCreationAlgorithm::MakeSecondaryAssociations(const OrderedCaloHitList &orderedCaloHitList,
215  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
216 {
217  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
218  {
219  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
220  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
221 
222  for (const CaloHit *const pCaloHit : caloHits)
223  {
224  HitAssociationMap::const_iterator fwdIter = forwardHitAssociationMap.find(pCaloHit);
225  const CaloHit *const pForwardHit((forwardHitAssociationMap.end() == fwdIter) ? NULL : fwdIter->second.GetPrimaryTarget());
226 
227  HitAssociationMap::const_iterator fwdCheckIter = backwardHitAssociationMap.find(pForwardHit);
228  const CaloHit *const pForwardHitCheck((backwardHitAssociationMap.end() == fwdCheckIter) ? NULL : fwdCheckIter->second.GetPrimaryTarget());
229 
230  if ((NULL != pForwardHit) && (pForwardHitCheck != pCaloHit))
231  this->CreateSecondaryAssociation(pCaloHit, pForwardHit, forwardHitAssociationMap, backwardHitAssociationMap);
232 
233  HitAssociationMap::const_iterator bwdIter = backwardHitAssociationMap.find(pCaloHit);
234  const CaloHit *const pBackwardHit((backwardHitAssociationMap.end() == bwdIter) ? NULL : bwdIter->second.GetPrimaryTarget());
235 
236  HitAssociationMap::const_iterator bwdCheckIter = forwardHitAssociationMap.find(pBackwardHit);
237  const CaloHit *const pBackwardHitCheck((forwardHitAssociationMap.end() == bwdCheckIter) ? NULL : bwdCheckIter->second.GetPrimaryTarget());
238 
239  if ((NULL != pBackwardHit) && (pBackwardHitCheck != pCaloHit))
240  this->CreateSecondaryAssociation(pBackwardHit, pCaloHit, forwardHitAssociationMap, backwardHitAssociationMap);
241  }
242  }
243 }
244 
245 //------------------------------------------------------------------------------------------------------------------------------------------
246 
247 void TrackClusterCreationAlgorithm::IdentifyJoins(const OrderedCaloHitList &orderedCaloHitList,
248  const HitAssociationMap &forwardHitAssociationMap, const HitAssociationMap &backwardHitAssociationMap, HitJoinMap &hitJoinMap) const
249 {
250  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
251  {
252  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
253  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
254 
255  for (const CaloHit *const pCaloHit : caloHits)
256  {
257  const CaloHit *const pForwardJoinHit = this->GetJoinHit(pCaloHit, forwardHitAssociationMap, backwardHitAssociationMap);
258  const CaloHit *const pBackwardJoinHit = this->GetJoinHit(pForwardJoinHit, backwardHitAssociationMap, forwardHitAssociationMap);
259 
260  if ((NULL == pForwardJoinHit) || (NULL == pBackwardJoinHit) || (pBackwardJoinHit != pCaloHit))
261  continue;
262 
263  HitJoinMap::const_iterator joinIter = hitJoinMap.find(pCaloHit);
264 
265  if (hitJoinMap.end() == joinIter)
266  hitJoinMap.insert(HitJoinMap::value_type(pCaloHit, pForwardJoinHit));
267 
268  if ((hitJoinMap.end() != joinIter) && (joinIter->second != pForwardJoinHit))
269  throw StatusCodeException(STATUS_CODE_FAILURE);
270  }
271  }
272 }
273 
274 //------------------------------------------------------------------------------------------------------------------------------------------
275 
277  const OrderedCaloHitList &orderedCaloHitList, const HitJoinMap &hitJoinMap, HitToClusterMap &hitToClusterMap) const
278 {
279  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
280  {
281  CaloHitVector caloHits(iter->second->begin(), iter->second->end());
282  std::sort(caloHits.begin(), caloHits.end(), LArClusterHelper::SortHitsByPosition);
283 
284  for (const CaloHit *const pCaloHit : caloHits)
285  {
286  const Cluster *pCluster = NULL;
287 
288  HitToClusterMap::const_iterator mapIter = hitToClusterMap.find(pCaloHit);
289 
290  if (hitToClusterMap.end() == mapIter)
291  {
292  PandoraContentApi::Cluster::Parameters parameters;
293  parameters.m_caloHitList.push_back(pCaloHit);
294  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pCluster));
295  hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
296  }
297  else
298  {
299  pCluster = mapIter->second;
300  }
301 
302  HitJoinMap::const_iterator joinIter = hitJoinMap.find(pCaloHit);
303 
304  if (hitJoinMap.end() == joinIter)
305  continue;
306 
307  if (hitToClusterMap.end() != hitToClusterMap.find(joinIter->second))
308  throw StatusCodeException(STATUS_CODE_FAILURE);
309 
310  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pCluster, joinIter->second));
311  hitToClusterMap.insert(HitToClusterMap::value_type(joinIter->second, pCluster));
312  }
313  }
314 }
315 
316 //------------------------------------------------------------------------------------------------------------------------------------------
317 
318 void TrackClusterCreationAlgorithm::CreatePrimaryAssociation(const CaloHit *const pCaloHitI, const CaloHit *const pCaloHitJ,
319  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
320 {
321  const float distanceSquared((pCaloHitJ->GetPositionVector() - pCaloHitI->GetPositionVector()).GetMagnitudeSquared());
322 
323  if (distanceSquared > m_maxCaloHitSeparationSquared)
324  return;
325 
326  HitAssociationMap::iterator forwardIter = forwardHitAssociationMap.find(pCaloHitI);
327 
328  if (forwardHitAssociationMap.end() == forwardIter)
329  {
330  forwardHitAssociationMap.insert(HitAssociationMap::value_type(pCaloHitI, HitAssociation(pCaloHitJ, distanceSquared)));
331  }
332  else if (distanceSquared < forwardIter->second.GetPrimaryDistanceSquared())
333  {
334  forwardIter->second = HitAssociation(pCaloHitJ, distanceSquared);
335  }
336 
337  HitAssociationMap::iterator backwardIter = backwardHitAssociationMap.find(pCaloHitJ);
338 
339  if (backwardHitAssociationMap.end() == backwardIter)
340  {
341  backwardHitAssociationMap.insert(HitAssociationMap::value_type(pCaloHitJ, HitAssociation(pCaloHitI, distanceSquared)));
342  }
343  else if (distanceSquared < backwardIter->second.GetPrimaryDistanceSquared())
344  {
345  backwardIter->second = HitAssociation(pCaloHitI, distanceSquared);
346  }
347 }
348 
349 //------------------------------------------------------------------------------------------------------------------------------------------
350 
351 void TrackClusterCreationAlgorithm::CreateSecondaryAssociation(const CaloHit *const pCaloHitI, const CaloHit *const pCaloHitJ,
352  HitAssociationMap &forwardHitAssociationMap, HitAssociationMap &backwardHitAssociationMap) const
353 {
354  HitAssociationMap::iterator forwardIter = forwardHitAssociationMap.find(pCaloHitI);
355  HitAssociationMap::iterator backwardIter = backwardHitAssociationMap.find(pCaloHitJ);
356 
357  if ((forwardHitAssociationMap.end() == forwardIter) || (backwardHitAssociationMap.end() == backwardIter))
358  return;
359 
360  HitAssociation &forwardAssociation(forwardIter->second);
361  HitAssociation &backwardAssociation(backwardIter->second);
362 
363  if ((forwardAssociation.GetPrimaryTarget() != pCaloHitJ) && (backwardAssociation.GetPrimaryTarget() == pCaloHitI))
364  {
365  if ((backwardAssociation.GetPrimaryDistanceSquared() < forwardAssociation.GetSecondaryDistanceSquared()) &&
366  (backwardAssociation.GetPrimaryDistanceSquared() < m_closeSeparationSquared))
367  {
368  forwardAssociation.SetSecondaryTarget(pCaloHitJ, backwardAssociation.GetPrimaryDistanceSquared());
369  }
370  }
371 
372  if ((backwardAssociation.GetPrimaryTarget() != pCaloHitI) && (forwardAssociation.GetPrimaryTarget() == pCaloHitJ))
373  {
374  if ((forwardAssociation.GetPrimaryDistanceSquared() < backwardAssociation.GetSecondaryDistanceSquared()) &&
375  (forwardAssociation.GetPrimaryDistanceSquared() < m_closeSeparationSquared))
376  {
377  backwardAssociation.SetSecondaryTarget(pCaloHitI, forwardAssociation.GetPrimaryDistanceSquared());
378  }
379  }
380 }
381 
382 //------------------------------------------------------------------------------------------------------------------------------------------
383 
385  const CaloHit *const pCaloHit, const HitAssociationMap &hitAssociationMapI, const HitAssociationMap &hitAssociationMapJ) const
386 {
387  HitAssociationMap::const_iterator iterI = hitAssociationMapI.find(pCaloHit);
388 
389  if (hitAssociationMapI.end() == iterI)
390  return NULL;
391 
392  const CaloHit *const pPrimaryTarget = iterI->second.GetPrimaryTarget();
393  const CaloHit *const pSecondaryTarget = iterI->second.GetSecondaryTarget();
394 
395  if (NULL == pSecondaryTarget)
396  return pPrimaryTarget;
397 
398  unsigned int primaryNSteps(0), secondaryNSteps(0);
399  const CaloHit *const pPrimaryTrace = this->TraceHitAssociation(pPrimaryTarget, hitAssociationMapI, hitAssociationMapJ, primaryNSteps);
400  const CaloHit *const pSecondaryTrace = this->TraceHitAssociation(pSecondaryTarget, hitAssociationMapI, hitAssociationMapJ, secondaryNSteps);
401 
402  if ((pPrimaryTrace == pSecondaryTrace) || (secondaryNSteps < 5))
403  return pPrimaryTarget;
404 
405  return NULL;
406 }
407 
408 //------------------------------------------------------------------------------------------------------------------------------------------
409 
410 const CaloHit *TrackClusterCreationAlgorithm::TraceHitAssociation(const CaloHit *const pCaloHit,
411  const HitAssociationMap &hitAssociationMapI, const HitAssociationMap &hitAssociationMapJ, unsigned int &nSteps) const
412 {
413  nSteps = 0;
414  const CaloHit *pThisHit = pCaloHit;
415  const CaloHit *pLastHit = pCaloHit;
416 
417  while (true)
418  {
419  ++nSteps;
420  pThisHit = pLastHit;
421  HitAssociationMap::const_iterator iterI = hitAssociationMapI.find(pThisHit);
422 
423  if (hitAssociationMapI.end() == iterI)
424  break;
425 
426  pLastHit = iterI->second.GetPrimaryTarget();
427  HitAssociationMap::const_iterator iterJ = hitAssociationMapJ.find(pLastHit);
428 
429  if (hitAssociationMapJ.end() == iterJ)
430  break;
431 
432  if (iterJ->second.GetPrimaryTarget() != pThisHit)
433  break;
434  }
435 
436  return pThisHit;
437 }
438 
439 //------------------------------------------------------------------------------------------------------------------------------------------
440 
441 StatusCode TrackClusterCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
442 {
443  PANDORA_RETURN_RESULT_IF_AND_IF(
444  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MergeBackFilteredHits", m_mergeBackFilteredHits));
445 
446  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxGapLayers", m_maxGapLayers));
447 
448  float maxCaloHitSeparation = std::sqrt(m_maxCaloHitSeparationSquared);
449  PANDORA_RETURN_RESULT_IF_AND_IF(
450  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxCaloHitSeparation", maxCaloHitSeparation));
451  m_maxCaloHitSeparationSquared = maxCaloHitSeparation * maxCaloHitSeparation;
452 
453  float minCaloHitSeparation = std::sqrt(m_minCaloHitSeparationSquared);
454  PANDORA_RETURN_RESULT_IF_AND_IF(
455  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCaloHitSeparation", minCaloHitSeparation));
456  m_minCaloHitSeparationSquared = minCaloHitSeparation * minCaloHitSeparation;
457 
458  float closeSeparation = std::sqrt(m_closeSeparationSquared);
459  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CloseSeparation", closeSeparation));
460  m_closeSeparationSquared = closeSeparation * closeSeparation;
461 
462  return STATUS_CODE_SUCCESS;
463 }
464 
465 } // 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.
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.
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.
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:85
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.