Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ClearTrackFragmentsTool.cc
Go to the documentation of this file.
1
10
12
14
15using namespace pandora;
16
17namespace lar_content
18{
19
20ClearTrackFragmentsTool::ClearTrackFragmentsTool() : m_minMatchedSamplingPointFraction(0.5f), m_minMatchedHits(5)
21{
22}
23
24//------------------------------------------------------------------------------------------------------------------------------------------
25
27{
29 std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
30
31 return this->FindTrackFragments(pAlgorithm, overlapTensor);
32}
33
34//------------------------------------------------------------------------------------------------------------------------------------------
35
37{
38 ClusterVector sortedKeyClusters;
39 overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
40
41 for (const Cluster *const pKeyCluster : sortedKeyClusters)
42 {
43 if (!pKeyCluster->IsAvailable())
44 continue;
45
46 TensorType::ElementList elementList;
47 if (!this->GetAndCheckElementList(overlapTensor, pKeyCluster, elementList))
48 continue;
49
50 IteratorList iteratorList;
51 this->SelectClearElements(elementList, iteratorList);
52
53 if (iteratorList.empty())
54 return false;
55
56 // ATTN Cache information as will later modify tensor during reclustering. Approach relies on updating tensor
57 // prior to reclustering operations and then exiting from tool (which will be scheduled to run again by algorithm)
58 TensorType::ElementList::const_iterator iter(iteratorList.front());
59
60 const TensorType::OverlapResult overlapResult(iter->GetOverlapResult());
61 const HitType fragmentHitType(overlapResult.GetFragmentHitType());
62 const Cluster *pClusterU(iter->GetClusterU()), *pClusterV(iter->GetClusterV()), *pClusterW(iter->GetClusterW());
63
64 if (!this->CheckOverlapResult(overlapResult))
65 continue;
66
67 // ATTN No longer guaranteed safe to use iterator after processing tensor element, hence caching results above
68 const Cluster *pFragmentCluster(nullptr);
69 this->ProcessTensorElement(pAlgorithm, overlapTensor, overlapResult, pFragmentCluster);
70
71 if (!pFragmentCluster)
72 throw StatusCodeException(STATUS_CODE_FAILURE);
73
74 if (TPC_VIEW_U == fragmentHitType)
75 pClusterU = pFragmentCluster;
76 if (TPC_VIEW_V == fragmentHitType)
77 pClusterV = pFragmentCluster;
78 if (TPC_VIEW_W == fragmentHitType)
79 pClusterW = pFragmentCluster;
80
81 if (!(pClusterU->IsAvailable() && pClusterV->IsAvailable() && pClusterW->IsAvailable()))
82 throw StatusCodeException(STATUS_CODE_FAILURE);
83
84 // ATTN For safety, remove all clusters associated with this fragment particle from the tensor
85 ClusterList fragmentClusterList, affectedKeyClusters;
86 fragmentClusterList.push_back(pClusterU);
87 fragmentClusterList.push_back(pClusterV);
88 fragmentClusterList.push_back(pClusterW);
89 this->GetAffectedKeyClusters(overlapTensor, fragmentClusterList, affectedKeyClusters);
90
91 for (const Cluster *const pCluster : affectedKeyClusters)
92 pAlgorithm->UpdateUponDeletion(pCluster);
93
94 // Now make the particle
95 ProtoParticle protoParticle;
96 ProtoParticleVector protoParticleVector;
97 protoParticle.m_clusterList.push_back(pClusterU);
98 protoParticle.m_clusterList.push_back(pClusterV);
99 protoParticle.m_clusterList.push_back(pClusterW);
100 protoParticleVector.push_back(protoParticle);
101 return pAlgorithm->CreateThreeDParticles(protoParticleVector);
102 }
103
104 return false;
105}
106
107//------------------------------------------------------------------------------------------------------------------------------------------
108
109bool ClearTrackFragmentsTool::GetAndCheckElementList(const TensorType &overlapTensor, const Cluster *const pCluster, TensorType::ElementList &elementList) const
110{
111 // Get list of connected elements from tensor
112 unsigned int nU(0), nV(0), nW(0);
113 overlapTensor.GetConnectedElements(pCluster, true, elementList, nU, nV, nW);
114
115 // Only allow one fragment hit type
116 HitType fragmentHitType(HIT_CUSTOM);
117
118 for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
119 {
120 const HitType thisHitType(eIter->GetOverlapResult().GetFragmentHitType());
121
122 if (!((TPC_VIEW_U == thisHitType) || (TPC_VIEW_V == thisHitType) || (TPC_VIEW_W == thisHitType)))
123 throw StatusCodeException(STATUS_CODE_FAILURE);
124
125 if (thisHitType != fragmentHitType && HIT_CUSTOM != fragmentHitType)
126 return false;
127
128 fragmentHitType = thisHitType;
129 }
130
131 return true;
132}
133
134//------------------------------------------------------------------------------------------------------------------------------------------
135
136bool ClearTrackFragmentsTool::CheckOverlapResult(const TensorType::OverlapResult &overlapResult) const
137{
138 // ATTN This method is currently mirrored in ThreeViewTrackFragmentsAlgorithm algorithm
139 if (overlapResult.GetMatchedFraction() < m_minMatchedSamplingPointFraction)
140 return false;
141
142 if (overlapResult.GetFragmentCaloHitList().size() < m_minMatchedHits)
143 return false;
144
145 return true;
146}
147
148//------------------------------------------------------------------------------------------------------------------------------------------
149
150void ClearTrackFragmentsTool::SelectClearElements(const TensorType::ElementList &elementList, IteratorList &iteratorList) const
151{
152 for (TensorType::ElementList::const_iterator eIter1 = elementList.begin(), eIterEnd1 = elementList.end(); eIter1 != eIterEnd1; ++eIter1)
153 {
154 const CaloHitList &fragmentHits1(eIter1->GetOverlapResult().GetFragmentCaloHitList());
155 const float nCaloHits1(static_cast<float>(
156 eIter1->GetClusterU()->GetNCaloHits() + eIter1->GetClusterV()->GetNCaloHits() + eIter1->GetClusterW()->GetNCaloHits()));
157
158 bool isClearElement(true);
159
160 for (TensorType::ElementList::const_iterator eIter2 = elementList.begin(), eIterEnd2 = elementList.end(); eIter2 != eIterEnd2; ++eIter2)
161 {
162 const CaloHitList &fragmentHits2(eIter2->GetOverlapResult().GetFragmentCaloHitList());
163 const float nCaloHits2(static_cast<float>(
164 eIter2->GetClusterU()->GetNCaloHits() + eIter2->GetClusterV()->GetNCaloHits() + eIter2->GetClusterW()->GetNCaloHits()));
165
166 const bool commonClusterU(eIter1->GetClusterU() == eIter2->GetClusterU());
167 const bool commonClusterV(eIter1->GetClusterV() == eIter2->GetClusterV());
168 const bool commonClusterW(eIter1->GetClusterW() == eIter2->GetClusterW());
169
170 if (commonClusterU && commonClusterV && commonClusterW)
171 continue;
172
173 if (eIter1->GetOverlapResult().GetFragmentHitType() != eIter2->GetOverlapResult().GetFragmentHitType())
174 throw StatusCodeException(STATUS_CODE_FAILURE);
175
176 bool isAmbiguousElement(commonClusterU || commonClusterV || commonClusterW);
177
178 if (!isAmbiguousElement)
179 {
180 for (CaloHitList::const_iterator hIter2 = fragmentHits2.begin(), hIterEnd2 = fragmentHits2.end(); hIter2 != hIterEnd2; ++hIter2)
181 {
182 if (fragmentHits1.end() != std::find(fragmentHits1.begin(), fragmentHits1.end(), *hIter2))
183 {
184 isAmbiguousElement = true;
185 break;
186 }
187 }
188 }
189
190 if (isAmbiguousElement && nCaloHits2 > 0.25f * nCaloHits1)
191 {
192 isClearElement = false;
193 break;
194 }
195 }
196
197 if (isClearElement)
198 iteratorList.push_back(eIter1);
199 }
200}
201
202//------------------------------------------------------------------------------------------------------------------------------------------
203
205 const TensorType::OverlapResult &overlapResult, const Cluster *&pFragmentCluster) const
206{
207 pFragmentCluster = nullptr;
208
209 const HitType fragmentHitType(overlapResult.GetFragmentHitType());
210 const std::string &currentListName(pAlgorithm->GetClusterListName(fragmentHitType));
211
212 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*pAlgorithm, currentListName));
213
214 ClusterList fragmentClusterList(overlapResult.GetFragmentClusterList());
215 fragmentClusterList.sort(LArClusterHelper::SortByNHits);
216 const CaloHitSet caloHitSet(overlapResult.GetFragmentCaloHitList().begin(), overlapResult.GetFragmentCaloHitList().end());
217
218 // Remove any clusters to be modified (or affected by modifications) from tensor
219 ClusterList affectedKeyClusters;
220 this->GetAffectedKeyClusters(overlapTensor, fragmentClusterList, affectedKeyClusters);
221
222 for (const Cluster *const pCluster : affectedKeyClusters)
223 pAlgorithm->UpdateUponDeletion(pCluster);
224
225 for (const Cluster *const pCluster : fragmentClusterList)
226 pAlgorithm->UpdateUponDeletion(pCluster);
227
228 ClusterList clustersToRebuild;
229 ClusterSet badClusters, deletedClusters;
230
231 for (const Cluster *const pCluster : fragmentClusterList)
232 {
233 if (deletedClusters.count(pCluster))
234 continue;
235
236 if (!pCluster->IsAvailable())
237 throw StatusCodeException(STATUS_CODE_FAILURE);
238
239 CaloHitList clusterHitList;
240 pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterHitList);
241
242 CaloHitList daughterHits, separateHits;
243 for (const CaloHit *const pCaloHit : clusterHitList)
244 {
245 if (caloHitSet.count(pCaloHit))
246 {
247 daughterHits.push_back(pCaloHit);
248 }
249 else
250 {
251 separateHits.push_back(pCaloHit);
252 }
253 }
254
255 if (daughterHits.empty())
256 throw StatusCodeException(STATUS_CODE_FAILURE);
257
258 this->Recluster(pAlgorithm, pCluster, daughterHits, separateHits, deletedClusters, badClusters, pFragmentCluster);
259
260 // ATTN Fragment cluster will be used to build particle, so it shouldn't ever be bad, or deleted
261 if (badClusters.count(pFragmentCluster) || deletedClusters.count(pFragmentCluster))
262 throw StatusCodeException(STATUS_CODE_FAILURE);
263
264 // ATTN Keep track of clusters to be rebuilt; does not include those for which address has been deleted at any time.
265 // Note distinction between list of all deletions and the up-to-date list of bad clusters.
266 // Fragment cluster will be automatically added to the output particle and never rebuilt.
267 ClusterList::iterator rebuildIter(std::find(clustersToRebuild.begin(), clustersToRebuild.end(), pCluster));
268 if (deletedClusters.count(pCluster))
269 {
270 if (clustersToRebuild.end() != rebuildIter)
271 clustersToRebuild.erase(rebuildIter);
272 }
273 else if ((clustersToRebuild.end() == rebuildIter) && (pCluster != pFragmentCluster))
274 {
275 clustersToRebuild.push_back(pCluster);
276 }
277 }
278
279 if (!pFragmentCluster)
280 throw StatusCodeException(STATUS_CODE_FAILURE);
281
282 // Rebuild fragmented clusters into something better defined
283 ClusterList clustersToAddToTensor;
284 this->RebuildClusters(pAlgorithm, clustersToRebuild, clustersToAddToTensor);
285
286 // ATTN Repopulate tensor according to modifications performed above
287 ClusterList newKeyClusters;
288 pAlgorithm->SelectInputClusters(&clustersToAddToTensor, newKeyClusters);
289
290 for (const Cluster *const pCluster : newKeyClusters)
291 pAlgorithm->UpdateForNewCluster(pCluster);
292
293 for (const Cluster *const pCluster : affectedKeyClusters)
294 pAlgorithm->UpdateForNewCluster(pCluster);
295}
296
297//------------------------------------------------------------------------------------------------------------------------------------------
298
299void ClearTrackFragmentsTool::Recluster(ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, const Cluster *const pCluster, const CaloHitList &daughterHits,
300 const CaloHitList &separateHits, ClusterSet &deletedClusters, ClusterSet &badClusters, const Cluster *&pFragmentCluster) const
301{
302 if (separateHits.empty())
303 {
304 if (!pFragmentCluster)
305 {
306 pFragmentCluster = pCluster;
307 }
308 else
309 {
310 // ATTN Addresses can be re-used by new allocations, so can't just use list of all cluster deletions; keep track of "bad" clusters
311 if (!badClusters.insert(pCluster).second)
312 throw StatusCodeException(STATUS_CODE_FAILURE);
313
314 (void)deletedClusters.insert(pCluster);
315 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*pAlgorithm, pFragmentCluster, pCluster));
316 }
317 }
318 else
319 {
320 for (const CaloHit *const pCaloHit : daughterHits)
321 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RemoveFromCluster(*pAlgorithm, pCluster, pCaloHit));
322
323 if (!pFragmentCluster)
324 {
325 const ClusterList *pTemporaryList(nullptr);
326 std::string temporaryListName, currentListName;
327 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentListName<Cluster>(*pAlgorithm, currentListName));
328 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
329 PandoraContentApi::CreateTemporaryListAndSetCurrent<ClusterList>(*pAlgorithm, pTemporaryList, temporaryListName));
330
331 PandoraContentApi::Cluster::Parameters hitParameters;
332 hitParameters.m_caloHitList = daughterHits;
333 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*pAlgorithm, hitParameters, pFragmentCluster));
334 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Cluster>(*pAlgorithm, temporaryListName, currentListName));
335 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*pAlgorithm, currentListName));
336
337 (void)badClusters.erase(pFragmentCluster);
338 }
339 else
340 {
341 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*pAlgorithm, pFragmentCluster, &daughterHits));
342 }
343 }
344}
345
346//------------------------------------------------------------------------------------------------------------------------------------------
347
349 ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, const ClusterList &modifiedClusters, ClusterList &newClusters) const
350{
351 ClusterList rebuildList;
352
353 for (const Cluster *const pCluster : modifiedClusters)
354 {
355 if (pCluster->IsAvailable())
356 rebuildList.push_back(pCluster);
357 }
358
359 if (!rebuildList.empty())
360 pAlgorithm->RebuildClusters(rebuildList, newClusters);
361}
362
363//------------------------------------------------------------------------------------------------------------------------------------------
364
366 const TensorType &overlapTensor, const ClusterList &clustersToRemoveFromTensor, ClusterList &affectedKeyClusters) const
367{
368 for (TensorType::const_iterator tIterU = overlapTensor.begin(), tIterUEnd = overlapTensor.end(); tIterU != tIterUEnd; ++tIterU)
369 {
370 for (TensorType::OverlapMatrix::const_iterator tIterV = tIterU->second.begin(), tIterVEnd = tIterU->second.end(); tIterV != tIterVEnd; ++tIterV)
371 {
372 for (TensorType::OverlapList::const_iterator tIterW = tIterV->second.begin(), tIterWEnd = tIterV->second.end(); tIterW != tIterWEnd; ++tIterW)
373 {
374 const TensorType::OverlapResult &overlapResult(tIterW->second);
375 const HitType fragmentHitType(overlapResult.GetFragmentHitType());
376 const ClusterList &fragmentClusters(overlapResult.GetFragmentClusterList());
377
378 for (ClusterList::const_iterator fIter = fragmentClusters.begin(), fIterEnd = fragmentClusters.end(); fIter != fIterEnd; ++fIter)
379 {
380 if (clustersToRemoveFromTensor.end() == std::find(clustersToRemoveFromTensor.begin(), clustersToRemoveFromTensor.end(), *fIter))
381 continue;
382
383 if ((TPC_VIEW_U != fragmentHitType) &&
384 (affectedKeyClusters.end() == std::find(affectedKeyClusters.begin(), affectedKeyClusters.end(), tIterU->first)))
385 affectedKeyClusters.push_back(tIterU->first);
386
387 if ((TPC_VIEW_V != fragmentHitType) &&
388 (affectedKeyClusters.end() == std::find(affectedKeyClusters.begin(), affectedKeyClusters.end(), tIterV->first)))
389 affectedKeyClusters.push_back(tIterV->first);
390
391 if ((TPC_VIEW_W != fragmentHitType) &&
392 (affectedKeyClusters.end() == std::find(affectedKeyClusters.begin(), affectedKeyClusters.end(), tIterW->first)))
393 affectedKeyClusters.push_back(tIterW->first);
394
395 break;
396 }
397 }
398 }
399 }
400
401 affectedKeyClusters.sort(LArClusterHelper::SortByNHits);
402}
403
404//------------------------------------------------------------------------------------------------------------------------------------------
405
407{
408 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
409 XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPointFraction", m_minMatchedSamplingPointFraction));
410
411 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedHits", m_minMatchedHits));
412
413 return STATUS_CODE_SUCCESS;
414}
415
416} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the clear track fragments tool class.
Header file for the cluster helper class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
static pandora::StatusCode ReplaceCurrentList(const pandora::Algorithm &algorithm, const std::string &newListName)
Replace the current list with a pre-saved list; use this new list as a permanent replacement for the ...
static pandora::StatusCode MergeAndDeleteClusters(const pandora::Algorithm &algorithm, const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete)
Merge two clusters in the current list, enlarging one cluster and deleting the second.
static pandora::StatusCode AddToCluster(const pandora::Algorithm &algorithm, const pandora::Cluster *const pCluster, const T *const pT)
Add a calo hit, or a list of calo hits, to a cluster.
static pandora::StatusCode RemoveFromCluster(const pandora::Algorithm &algorithm, const pandora::Cluster *const pCluster, const pandora::CaloHit *const pCaloHit)
Remove a calo hit from a cluster. Note this function will not remove the final calo hit from a cluste...
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
bool Run(ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
unsigned int m_minMatchedHits
The minimum number of matched calo hits.
float m_minMatchedSamplingPointFraction
The minimum fraction of matched sampling points.
bool FindTrackFragments(ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, const TensorType &overlapTensor) const
Find suitable matching track fragments in the overlap tensor to use for 3D particle creation,...
bool GetAndCheckElementList(const TensorType &overlapTensor, const pandora::Cluster *const pCluster, TensorType::ElementList &elementList) const
Get the list of elements connected to a given cluster and check its suitability (no ambiguities)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
bool CheckOverlapResult(const TensorType::OverlapResult &overlapResult) const
Check whether the overlap result passes matched sampling point and number of matched hit checks.
void ProcessTensorElement(ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, const TensorType &overlapTensor, const TensorType::OverlapResult &overlapResult, const pandora::Cluster *&pFragmentCluster) const
Process a tensor element, reclustering the fragments as required.
void RebuildClusters(ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, const pandora::ClusterList &modifiedClusters, pandora::ClusterList &newClusters) const
Rebuild clusters after fragmentation.
void Recluster(ThreeViewTrackFragmentsAlgorithm *const pAlgorithm, const pandora::Cluster *const pCluster, const pandora::CaloHitList &daughterHits, const pandora::CaloHitList &separateHits, pandora::ClusterSet &deletedClusters, pandora::ClusterSet &badClusters, const pandora::Cluster *&pFragmentCluster) const
Rearrange the hits in a cluster from the fragment list, using the Pandora fragmentation mechanism.
void GetAffectedKeyClusters(const TensorType &overlapTensor, const pandora::ClusterList &clustersToRemoveFromTensor, pandora::ClusterList &affectedKeyClusters) const
Get a list of the tensor key clusters for which tensor elements have been impacted by fragmentation o...
void SelectClearElements(const TensorType::ElementList &elementList, IteratorList &iteratorList) const
Select a list of clear track-like elements from a set of connected tensor elements.
ThreeViewTrackFragmentsAlgorithm::MatchingType::TensorType TensorType
std::vector< TensorType::ElementList::const_iterator > IteratorList
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,...
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
const std::string & GetClusterListName(const pandora::HitType hitType) const
Get the cluster list name corresponding to a specified hit type.
virtual void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
virtual void SelectInputClusters(const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
Select a subset of input clusters for processing in this algorithm.
void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
void RebuildClusters(const pandora::ClusterList &rebuildList, pandora::ClusterList &newClusters) const
Rebuild clusters after fragmentation.
CaloHit class.
Definition CaloHit.h:26
Cluster class.
Definition Cluster.h:31
bool IsAvailable() const
Whether the cluster is available to be added to a particle flow object.
Definition Cluster.h:582
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
Definition Process.h:102
const std::string & GetInstanceName() const
Get the instance name.
Definition Process.h:109
StatusCodeException class.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::vector< ProtoParticle > ProtoParticleVector
pandora::ClusterList m_clusterList
List of 2D clusters in a 3D proto particle.
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::unordered_set< const CaloHit * > CaloHitSet
std::unordered_set< const Cluster * > ClusterSet
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.