9 #include "Pandora/AlgorithmHeaders.h"
23 OneViewDeltaRayMatchingAlgorithm::OneViewDeltaRayMatchingAlgorithm() : m_overlapExtension(1.f), m_minClusterHits(3)
34 allPfoList.insert(allPfoList.end(), muonPfoList.begin(), muonPfoList.end());
39 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
42 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
47 return STATUS_CODE_SUCCESS;
54 const std::string inputClusterListName(
57 const ClusterList *pInputClusterList(
nullptr);
59 PANDORA_THROW_RESULT_IF_AND_IF(
60 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, inputClusterListName, pInputClusterList));
62 if (!pInputClusterList)
65 return *pInputClusterList;
72 const PfoList *pMuonPfoList(
nullptr);
74 PANDORA_THROW_RESULT_IF_AND_IF(
75 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_muonPfoListName, pMuonPfoList));
87 const PfoList *pDeltaRayPfoList(
nullptr);
89 PANDORA_THROW_RESULT_IF_AND_IF(
90 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_deltaRayPfoListName, pDeltaRayPfoList));
92 if (!pDeltaRayPfoList)
95 return *pDeltaRayPfoList;
106 for (
auto &entry : clusterProximityMap)
108 if (entry.first->IsAvailable())
109 availableClusterList.push_back(entry.first);
114 ClusterSet modifiedClusters;
116 for (
const Cluster *
const pAvailableCluster : availableClusterList)
118 if (modifiedClusters.count(pAvailableCluster))
121 const DeltaRayMatchingContainers::ClusterProximityMap::const_iterator iter(clusterProximityMap.find(pAvailableCluster));
124 if (iter == clusterProximityMap.end())
128 const ClusterList &nearbyClusters(clusterProximityMap.at(pAvailableCluster));
129 PfoVector nearbyMuonPfoVector;
135 const ParticleFlowObject *pClosestMuonPfo(
nullptr);
138 for (
const Cluster *
const pNearbyCluster : nearbyClusters)
143 if (std::find(nearbyMuonPfoVector.begin(), nearbyMuonPfoVector.end(), clusterToPfoMap.at(pNearbyCluster)) !=
144 nearbyMuonPfoVector.end())
151 if (separation < closestDistance)
153 closestDistance = separation;
154 pClosestMuonPfo = clusterToPfoMap.at(pNearbyCluster);
159 nearbyMuonPfoVector.push_back(pClosestMuonPfo);
162 if (nearbyMuonPfoVector.empty())
168 this->
CreateDeltaRay(pAvailableCluster, nearbyMuonPfoVector, modifiedClusters);
178 const DeltaRayMatchingContainers::ClusterToPfoMap::const_iterator iter(clusterToPfoMap.find(pCluster));
180 if (iter == clusterToPfoMap.end())
183 const ParticleFlowObject *
const pPfo(iter->second);
186 return (std::find(muonPfoList.begin(), muonPfoList.end(), pPfo) != muonPfoList.end());
194 const HitType projectedHitType1((hitType == TPC_VIEW_U) ? TPC_VIEW_V : (hitType == TPC_VIEW_V) ? TPC_VIEW_W : TPC_VIEW_U);
195 const HitType projectedHitType2((projectedHitType1 == TPC_VIEW_U) ? TPC_VIEW_V : (projectedHitType1 == TPC_VIEW_V) ? TPC_VIEW_W : TPC_VIEW_U);
199 for (
const ParticleFlowObject *
const pNearbyMuonPfo : nearbyMuonPfoVector)
201 const Cluster *
const pProjectedCluster1(this->
GetBestProjectedCluster({pAvailableCluster}, pNearbyMuonPfo, projectedHitType1,
false));
202 const Cluster *
const pProjectedCluster2(this->
GetBestProjectedCluster({pAvailableCluster}, pNearbyMuonPfo, projectedHitType2,
false));
204 if ((!pProjectedCluster1) || (!pProjectedCluster2))
207 const ParticleFlowObject *
const pPfo1(clusterToPfoMap1.at(pProjectedCluster1));
208 const ParticleFlowObject *
const pPfo2(clusterToPfoMap2.at(pProjectedCluster2));
212 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*
this, pPfo1, pAvailableCluster));
226 const ClusterList &deltaRayClusterGroup,
const ParticleFlowObject *
const pNearbyMuonPfo,
const HitType hitType,
const bool findAvailable)
228 ClusterList muonClusterList;
231 if (muonClusterList.size() != 1)
235 auto muonProximityIter(clusterProximityMap.find(muonClusterList.front()));
237 if (muonProximityIter == clusterProximityMap.end())
240 float spanMinX(0.f), spanMaxX(0.f);
243 unsigned int highestHit(0);
244 const Cluster *pProjectedCluster(
nullptr);
246 for (
const Cluster *
const pNearbyCluster : muonProximityIter->second)
248 if (findAvailable && !pNearbyCluster->IsAvailable())
254 float minX(0.f), maxX(0.f);
255 pNearbyCluster->GetClusterSpanX(minX, maxX);
260 if (pNearbyCluster->GetNCaloHits() > highestHit)
262 highestHit = pNearbyCluster->GetNCaloHits();
263 pProjectedCluster = pNearbyCluster;
267 return pProjectedCluster;
277 const DeltaRayMatchingContainers::ClusterToPfoMap::const_iterator iter(clusterToPfoMap.find(pCluster));
279 if (iter == clusterToPfoMap.end())
282 const ParticleFlowObject *
const pDeltaRayPfo(iter->second);
285 return (std::find(deltaRayPfoList.begin(), deltaRayPfoList.end(), pDeltaRayPfo) != deltaRayPfoList.end());
292 spanMinX = std::numeric_limits<float>::max();
293 spanMaxX = -std::numeric_limits<float>::max();
295 for (
const Cluster *
const pCluster : clusterList)
297 float minX(0.f), maxX(0.f);
298 pCluster->GetClusterSpanX(minX, maxX);
312 ClusterList clusterGroup, consideredClusters;
315 for (
const Cluster *
const pModifiedCluster : clusterGroup)
316 modifiedClusters.insert(pModifiedCluster);
319 const HitType projectedHitType1((hitType == TPC_VIEW_U) ? TPC_VIEW_V : (hitType == TPC_VIEW_V) ? TPC_VIEW_W : TPC_VIEW_U);
320 const HitType projectedHitType2((projectedHitType1 == TPC_VIEW_U) ? TPC_VIEW_V : (projectedHitType1 == TPC_VIEW_V) ? TPC_VIEW_W : TPC_VIEW_U);
321 ClusterList projectedClusters1, projectedClusters2;
323 for (
const ParticleFlowObject *
const pNearbyMuonPfo : nearbyMuonPfoVector)
325 const Cluster *
const pProjectedCluster1(this->
GetBestProjectedCluster(clusterGroup, pNearbyMuonPfo, projectedHitType1,
true));
326 const Cluster *
const pProjectedCluster2(this->
GetBestProjectedCluster(clusterGroup, pNearbyMuonPfo, projectedHitType2,
true));
328 if ((!pProjectedCluster1) && (!pProjectedCluster2))
331 ClusterList consideredClusters1;
332 if (pProjectedCluster1)
335 ClusterList consideredClusters2;
336 if (pProjectedCluster2)
344 this->
CreatePfo(pCluster1, pCluster2, pCluster3);
354 consideredClusters.push_back(pCluster);
356 if (!pCluster->IsAvailable())
359 if (std::find(foundClusters.begin(), foundClusters.end(), pCluster) == foundClusters.end())
360 foundClusters.push_back(pCluster);
362 const DeltaRayMatchingContainers::ClusterProximityMap::const_iterator proximityIter(clusterProximityMap.find(pCluster));
364 if (proximityIter == clusterProximityMap.end())
367 for (
const Cluster *
const pNearbyCluster : proximityIter->second)
369 if (!pNearbyCluster->IsAvailable())
372 if (std::find(consideredClusters.begin(), consideredClusters.end(), pNearbyCluster) != consideredClusters.end())
375 if (std::find(foundClusters.begin(), foundClusters.end(), pNearbyCluster) != foundClusters.end())
386 if (clusterGroup.empty())
389 const Cluster *
const pClusterToEnlarge(clusterGroup.front());
391 if (clusterGroup.size() == 1)
392 return pClusterToEnlarge;
395 const std::string inputClusterListName(
398 for (
const Cluster *
const pClusterToDelete : clusterGroup)
402 if (pClusterToDelete != pClusterToEnlarge)
404 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*
this, inputClusterListName));
405 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*
this, pClusterToEnlarge, pClusterToDelete));
411 return pClusterToEnlarge;
418 const PfoList *pPfoList(
nullptr);
419 std::string pfoListName;
420 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
423 pfoParameters.m_particleId = E_MINUS;
424 pfoParameters.m_charge = PdgTable::GetParticleCharge(E_MINUS);
425 pfoParameters.m_mass = PdgTable::GetParticleMass(E_MINUS);
426 pfoParameters.m_energy = 0.f;
427 pfoParameters.m_momentum = CartesianVector(0.f, 0.f, 0.f);
430 pfoParameters.m_clusterList.push_back(pCluster1);
433 pfoParameters.m_clusterList.push_back(pCluster2);
436 pfoParameters.m_clusterList.push_back(pCluster3);
438 if (pfoParameters.m_clusterList.empty())
439 throw StatusCodeException(STATUS_CODE_FAILURE);
441 const ParticleFlowObject *pPfo(
nullptr);
443 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
444 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this,
m_outputPfoListName));
445 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Pfo>(*
this,
m_outputPfoListName));
456 for (
const Cluster *
const pCluster : inputClusterList)
458 if (!pCluster->IsAvailable())
464 this->
CreatePfo(pCluster,
nullptr,
nullptr);
472 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MuonPfoListName",
m_muonPfoListName));
474 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"DeltaRayPfoListName",
m_deltaRayPfoListName));
476 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
478 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
480 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
482 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
484 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
487 PANDORA_RETURN_RESULT_IF_AND_IF(
488 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"OverlapExtension",
m_overlapExtension));
490 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterHits",
m_minClusterHits));
492 return STATUS_CODE_SUCCESS;
Header file for the one viw delta ray matching algorithm.
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.
std::string m_inputClusterListNameW
The list of reconstructed W clusters.
const pandora::ClusterList GetInputClusterList(const pandora::HitType hitType)
Get the input cluster list of a given hit type.
Header file for the kd tree linker algo template class.
std::map< const pandora::Cluster *, const pandora::ParticleFlowObject * > ClusterToPfoMap
Header file for the pfo helper class.
const ClusterProximityMap & GetClusterProximityMap(const pandora::HitType hitType) const
Get the mapping of clusters to to their neighbouring clusters.
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const pandora::PfoList GetDeltaRayPfoList()
Get the input delta ray pfo list.
bool AddIntoExistingDeltaRay(const pandora::Cluster *const pAvailableCluster, const pandora::PfoVector &nearbyMuonPfoVector)
Use nearby muon pfos to project into other views and attempt to add a remaining delta ray cluster int...
double closestDistance(const TVector3 &line0, const TVector3 &line1, const TVector3 &p)
void AddClustersToPfoMaps(const pandora::ParticleFlowObject *const pPfo)
Add the clusters of a cosmic ray/delta ray pfo to the cluster to pfo maps.
void CreateDeltaRay(const pandora::Cluster *const pAvailableCluster, const pandora::PfoVector &nearbyMuonPfoVector, pandora::ClusterSet &modifiedClusters)
Use nearby muon pfos to project into other views and attempt to match a remaining delta ray cluster t...
bool IsDeltaRayPfo(const pandora::Cluster *const pCluster)
Determine whether an input cluster belongs to a delta ray pfo.
unsigned int m_minClusterHits
The minimum number of hits for a cluster to be significant.
void CreatePfo(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::Cluster *const pCluster3)
Create a pfo from the input clusters updating the cluster to pfo map accordingly. ...
std::string m_inputClusterListNameU
The list of reconstructed U clusters.
std::string m_muonPfoListName
The list of reconstructed cosmic ray pfos.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
void FillContainers(const pandora::PfoList &inputPfoList, const pandora::ClusterList &inputClusterList1, const pandora::ClusterList &inputClusterList2=pandora::ClusterList(), const pandora::ClusterList &inputClusterList3=pandora::ClusterList())
Fill the HitToClusterMap, the ClusterProximityMap and the ClusterToPfoMap in all input views...
std::string m_inputClusterListNameV
The list of reconstructed V clusters.
const pandora::Cluster * GetBestProjectedCluster(const pandora::ClusterList &deltaRayClusterGroup, const pandora::ParticleFlowObject *const pNearbyMuonPfo, const pandora::HitType hitType, const bool findAvailable)
Get the best matched available or unavailable cluster of a remaining delta ray cluster group wrt a co...
Header file for the cluster helper class.
void GetClusterSpanX(const pandora::ClusterList &clusterList, float &spanMinX, float &spanMaxX)
Determine cluster span (in x) of a group of clusters.
pandora::StatusCode Run()
void AddClustersToContainers(const pandora::ClusterVector &newClusterVector, const pandora::PfoVector &pfoVector)
Add a list of clusters to the hit to cluster and cluster proximity maps and, if appropriate, to the cluster to pfo map.
void PerformOneViewMatching(const pandora::HitType hitType)
Use nearby muon pfos to project into other views and attempt to match the remaining delta ray cluster...
const pandora::Cluster * MergeClusterGroup(const pandora::ClusterList &clusterGroup)
Merge a collection of available clusters together updating hit containers accordingly.
const ClusterToPfoMap & GetClusterToPfoMap(const pandora::HitType hitType) const
Get the mapping of clusters to the pfos to which they belong.
DeltaRayMatchingContainers m_deltaRayMatchingContainers
The class of hit, cluster and pfo ownership and proximity maps.
bool IsMuonPfo(const pandora::Cluster *const pCluster)
Determine whether an input cluster belongs to a cosmic ray pfo.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::map< const pandora::Cluster *, pandora::ClusterList > ClusterProximityMap
float m_overlapExtension
The extension to each side of the x overlap region in which to search for matched clusters...
void GetNearbyAvailableClusters(const pandora::Cluster *const pCluster, pandora::ClusterList &consideredClusters, pandora::ClusterList &foundClusters)
In the view of the input available cluster, gather nearby available clusters.
std::string m_deltaRayPfoListName
The list of reconstructed delta ray pfos.
std::string m_outputPfoListName
The list to receive the created delta ray pfos.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
void PerformRecovery(const pandora::HitType hitType)
Create a delta ray pfo from any remaining, significant clusters.
const pandora::PfoList GetMuonPfoList()
Get the input cosmic ray pfo list.
void ClearContainers()
Empty all algorithm containers.
void RemoveClusterFromContainers(const pandora::Cluster *const pDeletedCluster)
Remove an input cluster's hits from the hit to cluster and cluster proximity maps and...
float m_searchRegion1D
Search region, applied to each dimension, for look-up from kd-tree.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.