9 #include "Pandora/AlgorithmHeaders.h" 23 OneViewDeltaRayMatchingAlgorithm::OneViewDeltaRayMatchingAlgorithm() :
24 m_overlapExtension(1.
f),
36 allPfoList.insert(allPfoList.end(), muonPfoList.begin(), muonPfoList.end());
41 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
44 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
49 return STATUS_CODE_SUCCESS;
60 const ClusterList *pInputClusterList(
nullptr);
62 PANDORA_THROW_RESULT_IF_AND_IF(
63 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, inputClusterListName, pInputClusterList));
65 if (!pInputClusterList)
68 return *pInputClusterList;
75 const PfoList *pMuonPfoList(
nullptr);
77 PANDORA_THROW_RESULT_IF_AND_IF(
78 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_muonPfoListName, pMuonPfoList));
90 const PfoList *pDeltaRayPfoList(
nullptr);
92 PANDORA_THROW_RESULT_IF_AND_IF(
93 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_deltaRayPfoListName, pDeltaRayPfoList));
95 if (!pDeltaRayPfoList)
98 return *pDeltaRayPfoList;
109 for (
auto &entry : clusterProximityMap)
111 if (entry.first->IsAvailable())
112 availableClusterList.push_back(entry.first);
117 ClusterSet modifiedClusters;
119 for (
const Cluster *
const pAvailableCluster : availableClusterList)
121 if (modifiedClusters.count(pAvailableCluster))
127 if (iter == clusterProximityMap.end())
131 const ClusterList &nearbyClusters(clusterProximityMap.at(pAvailableCluster));
132 PfoVector nearbyMuonPfoVector;
138 const ParticleFlowObject *pClosestMuonPfo(
nullptr);
139 float closestDistance(std::numeric_limits<float>::max());
141 for (
const Cluster *
const pNearbyCluster : nearbyClusters)
146 if (std::find(nearbyMuonPfoVector.begin(), nearbyMuonPfoVector.end(), clusterToPfoMap.at(pNearbyCluster)) !=
147 nearbyMuonPfoVector.end())
154 if (separation < closestDistance)
156 closestDistance = separation;
157 pClosestMuonPfo = clusterToPfoMap.at(pNearbyCluster);
162 nearbyMuonPfoVector.push_back(pClosestMuonPfo);
165 if (nearbyMuonPfoVector.empty())
171 this->
CreateDeltaRay(pAvailableCluster, nearbyMuonPfoVector, modifiedClusters);
183 if (iter == clusterToPfoMap.end())
186 const ParticleFlowObject *
const pPfo(iter->second);
189 return (std::find(muonPfoList.begin(), muonPfoList.end(), pPfo) != muonPfoList.end());
197 const HitType projectedHitType1((hitType == TPC_VIEW_U) ? TPC_VIEW_V : (hitType == TPC_VIEW_V) ? TPC_VIEW_W : TPC_VIEW_U);
198 const HitType projectedHitType2((projectedHitType1 == TPC_VIEW_U) ? TPC_VIEW_V
199 : (projectedHitType1 == TPC_VIEW_V) ? TPC_VIEW_W
204 for (
const ParticleFlowObject *
const pNearbyMuonPfo : nearbyMuonPfoVector)
206 const Cluster *
const pProjectedCluster1(this->
GetBestProjectedCluster({pAvailableCluster}, pNearbyMuonPfo, projectedHitType1,
false));
207 const Cluster *
const pProjectedCluster2(this->
GetBestProjectedCluster({pAvailableCluster}, pNearbyMuonPfo, projectedHitType2,
false));
209 if ((!pProjectedCluster1) || (!pProjectedCluster2))
212 const ParticleFlowObject *
const pPfo1(clusterToPfoMap1.at(pProjectedCluster1));
213 const ParticleFlowObject *
const pPfo2(clusterToPfoMap2.at(pProjectedCluster2));
217 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*
this, pPfo1, pAvailableCluster));
231 const ClusterList &deltaRayClusterGroup,
const ParticleFlowObject *
const pNearbyMuonPfo,
const HitType hitType,
const bool findAvailable)
233 ClusterList muonClusterList;
236 if (muonClusterList.size() != 1)
240 auto muonProximityIter(clusterProximityMap.find(muonClusterList.front()));
242 if (muonProximityIter == clusterProximityMap.end())
245 float spanMinX(0.
f), spanMaxX(0.
f);
248 unsigned int highestHit(0);
249 const Cluster *pProjectedCluster(
nullptr);
251 for (
const Cluster *
const pNearbyCluster : muonProximityIter->second)
253 if (findAvailable && !pNearbyCluster->IsAvailable())
259 float minX(0.
f), maxX(0.
f);
260 pNearbyCluster->GetClusterSpanX(minX, maxX);
265 if (pNearbyCluster->GetNCaloHits() > highestHit)
267 highestHit = pNearbyCluster->GetNCaloHits();
268 pProjectedCluster = pNearbyCluster;
272 return pProjectedCluster;
284 if (iter == clusterToPfoMap.end())
287 const ParticleFlowObject *
const pDeltaRayPfo(iter->second);
290 return (std::find(deltaRayPfoList.begin(), deltaRayPfoList.end(), pDeltaRayPfo) != deltaRayPfoList.end());
297 spanMinX = std::numeric_limits<float>::max();
298 spanMaxX = -std::numeric_limits<float>::max();
300 for (
const Cluster *
const pCluster : clusterList)
302 float minX(0.
f), maxX(0.
f);
303 pCluster->GetClusterSpanX(minX, maxX);
317 ClusterList clusterGroup, consideredClusters;
320 for (
const Cluster *
const pModifiedCluster : clusterGroup)
321 modifiedClusters.insert(pModifiedCluster);
324 const HitType projectedHitType1((hitType == TPC_VIEW_U) ? TPC_VIEW_V : (hitType == TPC_VIEW_V) ? TPC_VIEW_W : TPC_VIEW_U);
325 const HitType projectedHitType2((projectedHitType1 == TPC_VIEW_U) ? TPC_VIEW_V
326 : (projectedHitType1 == TPC_VIEW_V) ? TPC_VIEW_W
328 ClusterList projectedClusters1, projectedClusters2;
330 for (
const ParticleFlowObject *
const pNearbyMuonPfo : nearbyMuonPfoVector)
332 const Cluster *
const pProjectedCluster1(this->
GetBestProjectedCluster(clusterGroup, pNearbyMuonPfo, projectedHitType1,
true));
333 const Cluster *
const pProjectedCluster2(this->
GetBestProjectedCluster(clusterGroup, pNearbyMuonPfo, projectedHitType2,
true));
335 if ((!pProjectedCluster1) && (!pProjectedCluster2))
338 ClusterList consideredClusters1;
339 if (pProjectedCluster1)
342 ClusterList consideredClusters2;
343 if (pProjectedCluster2)
351 this->
CreatePfo(pCluster1, pCluster2, pCluster3);
361 consideredClusters.push_back(pCluster);
363 if (!pCluster->IsAvailable())
366 if (std::find(foundClusters.begin(), foundClusters.end(), pCluster) == foundClusters.end())
367 foundClusters.push_back(pCluster);
371 if (proximityIter == clusterProximityMap.end())
374 for (
const Cluster *
const pNearbyCluster : proximityIter->second)
376 if (!pNearbyCluster->IsAvailable())
379 if (std::find(consideredClusters.begin(), consideredClusters.end(), pNearbyCluster) != consideredClusters.end())
382 if (std::find(foundClusters.begin(), foundClusters.end(), pNearbyCluster) != foundClusters.end())
393 if (clusterGroup.empty())
396 const Cluster *
const pClusterToEnlarge(clusterGroup.front());
398 if (clusterGroup.size() == 1)
399 return pClusterToEnlarge;
406 for (
const Cluster *
const pClusterToDelete : clusterGroup)
410 if (pClusterToDelete != pClusterToEnlarge)
412 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*
this, inputClusterListName));
413 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*
this, pClusterToEnlarge, pClusterToDelete));
419 return pClusterToEnlarge;
426 const PfoList *pPfoList(
nullptr);
427 std::string pfoListName;
428 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
430 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
431 pfoParameters.m_particleId = E_MINUS;
432 pfoParameters.m_charge = PdgTable::GetParticleCharge(E_MINUS);
433 pfoParameters.m_mass = PdgTable::GetParticleMass(E_MINUS);
434 pfoParameters.m_energy = 0.f;
435 pfoParameters.m_momentum = CartesianVector(0.
f, 0.
f, 0.
f);
438 pfoParameters.m_clusterList.push_back(pCluster1);
441 pfoParameters.m_clusterList.push_back(pCluster2);
444 pfoParameters.m_clusterList.push_back(pCluster3);
446 if (pfoParameters.m_clusterList.empty())
447 throw StatusCodeException(STATUS_CODE_FAILURE);
449 const ParticleFlowObject *pPfo(
nullptr);
451 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
452 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this,
m_outputPfoListName));
453 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Pfo>(*
this,
m_outputPfoListName));
464 for (
const Cluster *
const pCluster : inputClusterList)
466 if (!pCluster->IsAvailable())
472 this->
CreatePfo(pCluster,
nullptr,
nullptr);
480 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MuonPfoListName",
m_muonPfoListName));
482 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"DeltaRayPfoListName",
m_deltaRayPfoListName));
484 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
486 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
488 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
490 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
492 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
495 PANDORA_RETURN_RESULT_IF_AND_IF(
496 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"OverlapExtension",
m_overlapExtension));
498 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterHits",
m_minClusterHits));
500 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...
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.
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.