29 std::cout <<
"----> Running Algorithm Tool: " << this->
GetInstanceName() <<
", " << this->
GetType() << std::endl;
39 overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
41 for (
const Cluster *
const pKeyCluster : sortedKeyClusters)
43 if (!pKeyCluster->IsAvailable())
46 TensorType::ElementList elementList;
53 if (iteratorList.empty())
58 TensorType::ElementList::const_iterator iter(iteratorList.front());
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());
68 const Cluster *pFragmentCluster(
nullptr);
71 if (!pFragmentCluster)
75 pClusterU = pFragmentCluster;
77 pClusterV = pFragmentCluster;
79 pClusterW = pFragmentCluster;
81 if (!(pClusterU->IsAvailable() && pClusterV->IsAvailable() && pClusterW->
IsAvailable()))
85 ClusterList fragmentClusterList, affectedKeyClusters;
86 fragmentClusterList.push_back(pClusterU);
87 fragmentClusterList.push_back(pClusterV);
88 fragmentClusterList.push_back(pClusterW);
91 for (
const Cluster *
const pCluster : affectedKeyClusters)
100 protoParticleVector.push_back(protoParticle);
112 unsigned int nU(0), nV(0), nW(0);
113 overlapTensor.GetConnectedElements(pCluster,
true, elementList, nU, nV, nW);
118 for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
120 const HitType thisHitType(eIter->GetOverlapResult().GetFragmentHitType());
125 if (thisHitType != fragmentHitType &&
HIT_CUSTOM != fragmentHitType)
128 fragmentHitType = thisHitType;
152 for (TensorType::ElementList::const_iterator eIter1 = elementList.begin(), eIterEnd1 = elementList.end(); eIter1 != eIterEnd1; ++eIter1)
154 const CaloHitList &fragmentHits1(eIter1->GetOverlapResult().GetFragmentCaloHitList());
155 const float nCaloHits1(
static_cast<float>(
156 eIter1->GetClusterU()->GetNCaloHits() + eIter1->GetClusterV()->GetNCaloHits() + eIter1->GetClusterW()->GetNCaloHits()));
158 bool isClearElement(
true);
160 for (TensorType::ElementList::const_iterator eIter2 = elementList.begin(), eIterEnd2 = elementList.end(); eIter2 != eIterEnd2; ++eIter2)
162 const CaloHitList &fragmentHits2(eIter2->GetOverlapResult().GetFragmentCaloHitList());
163 const float nCaloHits2(
static_cast<float>(
164 eIter2->GetClusterU()->GetNCaloHits() + eIter2->GetClusterV()->GetNCaloHits() + eIter2->GetClusterW()->GetNCaloHits()));
166 const bool commonClusterU(eIter1->GetClusterU() == eIter2->GetClusterU());
167 const bool commonClusterV(eIter1->GetClusterV() == eIter2->GetClusterV());
168 const bool commonClusterW(eIter1->GetClusterW() == eIter2->GetClusterW());
170 if (commonClusterU && commonClusterV && commonClusterW)
173 if (eIter1->GetOverlapResult().GetFragmentHitType() != eIter2->GetOverlapResult().GetFragmentHitType())
176 bool isAmbiguousElement(commonClusterU || commonClusterV || commonClusterW);
178 if (!isAmbiguousElement)
180 for (CaloHitList::const_iterator hIter2 = fragmentHits2.begin(), hIterEnd2 = fragmentHits2.end(); hIter2 != hIterEnd2; ++hIter2)
182 if (fragmentHits1.end() != std::find(fragmentHits1.begin(), fragmentHits1.end(), *hIter2))
184 isAmbiguousElement =
true;
190 if (isAmbiguousElement && nCaloHits2 > 0.25f * nCaloHits1)
192 isClearElement =
false;
198 iteratorList.push_back(eIter1);
205 const TensorType::OverlapResult &overlapResult,
const Cluster *&pFragmentCluster)
const
207 pFragmentCluster =
nullptr;
209 const HitType fragmentHitType(overlapResult.GetFragmentHitType());
214 ClusterList fragmentClusterList(overlapResult.GetFragmentClusterList());
216 const CaloHitSet caloHitSet(overlapResult.GetFragmentCaloHitList().begin(), overlapResult.GetFragmentCaloHitList().end());
222 for (
const Cluster *
const pCluster : affectedKeyClusters)
225 for (
const Cluster *
const pCluster : fragmentClusterList)
231 for (
const Cluster *
const pCluster : fragmentClusterList)
233 if (deletedClusters.count(pCluster))
236 if (!pCluster->IsAvailable())
240 pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterHitList);
243 for (
const CaloHit *
const pCaloHit : clusterHitList)
245 if (caloHitSet.count(pCaloHit))
247 daughterHits.push_back(pCaloHit);
251 separateHits.push_back(pCaloHit);
255 if (daughterHits.empty())
258 this->
Recluster(pAlgorithm, pCluster, daughterHits, separateHits, deletedClusters, badClusters, pFragmentCluster);
261 if (badClusters.count(pFragmentCluster) || deletedClusters.count(pFragmentCluster))
267 ClusterList::iterator rebuildIter(std::find(clustersToRebuild.begin(), clustersToRebuild.end(), pCluster));
268 if (deletedClusters.count(pCluster))
270 if (clustersToRebuild.end() != rebuildIter)
271 clustersToRebuild.erase(rebuildIter);
273 else if ((clustersToRebuild.end() == rebuildIter) && (pCluster != pFragmentCluster))
275 clustersToRebuild.push_back(pCluster);
279 if (!pFragmentCluster)
284 this->
RebuildClusters(pAlgorithm, clustersToRebuild, clustersToAddToTensor);
290 for (
const Cluster *
const pCluster : newKeyClusters)
293 for (
const Cluster *
const pCluster : affectedKeyClusters)
302 if (separateHits.empty())
304 if (!pFragmentCluster)
306 pFragmentCluster = pCluster;
311 if (!badClusters.insert(pCluster).second)
314 (void)deletedClusters.insert(pCluster);
320 for (
const CaloHit *
const pCaloHit : daughterHits)
323 if (!pFragmentCluster)
326 std::string temporaryListName, currentListName;
331 PandoraContentApi::Cluster::Parameters hitParameters;
332 hitParameters.m_caloHitList = daughterHits;
333 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*pAlgorithm, hitParameters, pFragmentCluster));
337 (void)badClusters.erase(pFragmentCluster);
353 for (
const Cluster *
const pCluster : modifiedClusters)
355 if (pCluster->IsAvailable())
356 rebuildList.push_back(pCluster);
359 if (!rebuildList.empty())
368 for (TensorType::const_iterator tIterU = overlapTensor.begin(), tIterUEnd = overlapTensor.end(); tIterU != tIterUEnd; ++tIterU)
370 for (TensorType::OverlapMatrix::const_iterator tIterV = tIterU->second.begin(), tIterVEnd = tIterU->second.end(); tIterV != tIterVEnd; ++tIterV)
372 for (TensorType::OverlapList::const_iterator tIterW = tIterV->second.begin(), tIterWEnd = tIterV->second.end(); tIterW != tIterWEnd; ++tIterW)
374 const TensorType::OverlapResult &overlapResult(tIterW->second);
375 const HitType fragmentHitType(overlapResult.GetFragmentHitType());
376 const ClusterList &fragmentClusters(overlapResult.GetFragmentClusterList());
378 for (ClusterList::const_iterator fIter = fragmentClusters.begin(), fIterEnd = fragmentClusters.end(); fIter != fIterEnd; ++fIter)
380 if (clustersToRemoveFromTensor.end() == std::find(clustersToRemoveFromTensor.begin(), clustersToRemoveFromTensor.end(), *fIter))
384 (affectedKeyClusters.end() == std::find(affectedKeyClusters.begin(), affectedKeyClusters.end(), tIterU->first)))
385 affectedKeyClusters.push_back(tIterU->first);
388 (affectedKeyClusters.end() == std::find(affectedKeyClusters.begin(), affectedKeyClusters.end(), tIterV->first)))
389 affectedKeyClusters.push_back(tIterV->first);
392 (affectedKeyClusters.end() == std::find(affectedKeyClusters.begin(), affectedKeyClusters.end(), tIterW->first)))
393 affectedKeyClusters.push_back(tIterW->first);
413 return STATUS_CODE_SUCCESS;
Header file for the cluster helper class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
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.
ClearTrackFragmentsTool()
Default constructor.
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.
ThreeViewTrackFragmentsAlgorithm class.
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.
bool IsAvailable() const
Whether the cluster is available to be added to a particle flow object.
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
const std::string & GetInstanceName() const
Get the instance name.
StatusCodeException class.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
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.