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;
    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)
   114     ClusterSet modifiedClusters;
   116     for (
const Cluster *
const pAvailableCluster : availableClusterList)
   118         if (modifiedClusters.count(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);
   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;
   279     if (iter == clusterToPfoMap.end())
   282     const ParticleFlowObject *
const pDeltaRayPfo(iter->second);
   285     return (std::find(deltaRayPfoList.begin(), deltaRayPfoList.end(), pDeltaRayPfo) != deltaRayPfoList.end());
   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);
   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;
   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);
   420     PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
   422     PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
   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...
 
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...
 
QCollection::Item first()
 
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. 
 
static int max(int a, int b)
 
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.