9 #include "Pandora/AlgorithmHeaders.h" 24 SlidingConeClusterMopUpAlgorithm::SlidingConeClusterMopUpAlgorithm() :
26 m_maxIterations(1000),
27 m_maxHitsToConsider3DTrack(100),
28 m_minHitsToConsider3DShower(20),
29 m_maxHitsToConsider2DCluster(50),
30 m_halfWindowLayers(20),
33 m_coneLengthMultiplier(3.
f),
34 m_maxConeLength(126.
f),
35 m_coneTanHalfAngle(0.2
f),
36 m_coneBoundedFraction(0.5
f)
44 const Vertex *pVertex(
nullptr);
49 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
50 std::cout <<
"SlidingConeClusterMopUpAlgorithm - interaction vertex not available for use." << std::endl;
51 return STATUS_CODE_SUCCESS;
66 return STATUS_CODE_SUCCESS;
77 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetCurrentList(*
this, pVertexList));
79 pVertex = ((pVertexList && (pVertexList->size() == 1) && (VERTEX_3D == (*(pVertexList->begin()))->GetVertexType())) ? *(pVertexList->begin()) :
nullptr);
88 const PfoList *pPfoList(
nullptr);
90 if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*
this, pfoListName, pPfoList))
93 for (
const Pfo *
const pPfo : *pPfoList)
95 ClusterList pfoClusters3D;
98 for (
const Cluster *
const pCluster3D : pfoClusters3D)
106 if (!clusterToPfoMap.insert(ClusterToPfoMap::value_type(pCluster3D, pPfo)).second)
107 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
109 clusters3D.push_back(pCluster3D);
123 const ClusterList *pClusterList(
nullptr);
125 if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*
this, clusterListName, pClusterList))
128 for (
const Cluster *
const pCluster : *pClusterList)
130 if (!PandoraContentApi::IsAvailable(*
this, pCluster))
136 availableClusters2D.push_back(pCluster);
150 for (
const Cluster *
const pShowerCluster : clusters3D)
152 float coneLength3D(0.
f);
163 const float vertexToMinLayer(!pVertex ? 0.
f : (pVertex->GetPosition() - minLayerPosition).GetMagnitude());
164 const float vertexToMaxLayer(!pVertex ? 0.
f : (pVertex->GetPosition() - maxLayerPosition).GetMagnitude());
169 catch (
const StatusCodeException &) {
continue;}
171 for (
const Cluster *
const pNearbyCluster2D : availableClusters2D)
176 for (
const SimpleCone &simpleCone3D : simpleConeList3D)
178 const CartesianVector coneBaseCentre3D(simpleCone3D.GetConeApex() + simpleCone3D.GetConeDirection() * coneLength3D);
182 const CartesianVector apexToBase2D(coneBaseCentre2D - coneApex2D);
184 const ClusterMerge clusterMerge(pShowerCluster, simpleCone2D.GetBoundedHitFraction(pNearbyCluster2D), simpleCone2D.GetMeanRT(pNearbyCluster2D));
186 if (clusterMerge < bestClusterMerge)
187 bestClusterMerge = clusterMerge;
191 clusterMergeMap[pNearbyCluster2D].push_back(bestClusterMerge);
195 for (ClusterMergeMap::value_type &mapEntry : clusterMergeMap)
196 std::sort(mapEntry.second.begin(), mapEntry.second.end());
204 for (
const ClusterMergeMap::value_type &mapEntry : clusterMergeMap) daughterClusters.push_back(mapEntry.first);
207 for (ClusterVector::const_reverse_iterator rIter = daughterClusters.rbegin(), rIterEnd = daughterClusters.rend(); rIter != rIterEnd; ++rIter)
209 const Cluster *
const pDaughterCluster(*rIter);
211 const Cluster *
const pParentCluster3D(clusterMergeMap.at(pDaughterCluster).at(0).GetParentCluster());
213 const Pfo *
const pParentPfo(clusterToPfoMap.at(pParentCluster3D));
214 const Cluster *
const pParentCluster(this->
GetParentCluster(pParentPfo->GetClusterList(), daughterHitType));
218 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::MergeAndDeleteClusters(*
this, pParentCluster, pDaughterCluster,
223 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*
this, pParentPfo, pDaughterCluster));
242 if (std::fabs(this->GetBoundedFraction() - rhs.
GetBoundedFraction()) > std::numeric_limits<float>::epsilon())
245 if (std::fabs(this->GetMeanRT() - rhs.
GetMeanRT()) > std::numeric_limits<float>::epsilon())
246 return (this->GetMeanRT() < rhs.
GetMeanRT());
256 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
259 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
262 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
265 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
268 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
271 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
274 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
277 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
280 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
283 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
286 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
289 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
292 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
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.
bool m_useVertex
Whether to use the interaction vertex to select useful cone directions.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the pfo helper class.
Header file for the sliding cone cluster mop up algorithm class.
std::unordered_map< const pandora::Cluster *, ClusterMergeList > ClusterMergeMap
void GetThreeDClusters(pandora::ClusterVector &clusters3D, ClusterToPfoMap &clusterToPfoMap) const
Get all 3d clusters contained in the input pfo lists and a mapping from clusters to pfos...
unsigned int m_nConeFits
The number of cone fits to perform, spread roughly uniformly along the shower length.
const pandora::Cluster * GetParentCluster() const
Get the address of the candidate parent (shower) cluster.
std::vector< SimpleCone > SimpleConeList
unsigned int m_maxIterations
The maximum allowed number of algorithm iterations.
float GetMeanRT() const
Get the mean transverse distance of all hits (whether contained or not)
pandora::StringVector m_daughterListNames
The list of potential daughter object list names.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
float GetBoundedFraction() const
Get the bounded fraction for algorithm-specified cone angle.
unsigned int m_nConeFitLayers
The number of layers over which to sum fitted direction to obtain cone fit.
const ThreeDSlidingFitResult & GetSlidingFitResult() const
Get the sliding fit result for the full cluster.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
std::unordered_map< const pandora::Cluster *, const pandora::ParticleFlowObject * > ClusterToPfoMap
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
unsigned int m_maxHitsToConsider2DCluster
The maximum number of hits in a 2d cluster to allow pick-up via sliding cone fits.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
Header file for the lar three dimensional sliding cone fit result class.
void GetSimpleConeList(const unsigned int nLayersForConeFit, const unsigned int nCones, const ConeSelection coneSelection, SimpleConeList &simpleConeList) const
Get the list of simple cones fitted to the three dimensional cluster.
Header file for the geometry helper class.
const std::string GetListName(const T *const pT) const
Find the name of the list hosting a specific object.
static bool IsShower(const pandora::ParticleFlowObject *const pPfo)
Return shower flag based on Pfo Particle ID.
void GetClusterMergeMap(const pandora::Vertex *const pVertex, const pandora::ClusterVector &clusters3D, const pandora::ClusterVector &availableClusters2D, ClusterMergeMap &clusterMergeMap) const
Get the cluster merge map describing all potential 3d cluster merges.
Header file for the cluster helper class.
float m_coneLengthMultiplier
The cone length multiplier to use when calculating bounded cluster fractions.
unsigned int m_halfWindowLayers
The number of layers to use for half-window of sliding fit.
unsigned int m_minHitsToConsider3DShower
The minimum number of hits in a 3d shower cluster to attempt cone fits.
unsigned int m_maxHitsToConsider3DTrack
The maximum number of hits in a 3d track cluster to warrant inclusion in algorithm.
void MakeClusterMerges(const ClusterToPfoMap &clusterToPfoMap, const ClusterMergeMap &clusterMergeMap) const
Make cluster merges based on the provided cluster merge map.
static const pandora::Cluster * GetParentCluster(const pandora::ClusterList &clusterList, const pandora::HitType hitType)
Select the parent cluster (same hit type and most hits) using a provided cluster list and hit type...
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
const pandora::CartesianVector & GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_coneBoundedFraction
The minimum cluster bounded fraction for association.
pandora::StringVector m_inputPfoListNames
The input pfo list names.
float m_coneTanHalfAngle
The cone tan half angle to use when calculating bounded cluster fractions.
ConeSelection
ConeSelection enum.
void GetAvailableTwoDClusters(pandora::ClusterVector &availableClusters2D) const
Get all available 2d clusters contained in the input cluster lists.
void GetInteractionVertex(const pandora::Vertex *&pVertex) const
Get the neutrino interaction vertex if it is available and if the algorithm is configured to do so...
ThreeDSlidingConeFitResult class.
float m_maxConeLength
The maximum allowed cone length to use when calculating bounded cluster fractions.
std::list< Vertex > VertexList
pandora::StatusCode Run()
const pandora::CartesianVector & GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
bool operator<(const ClusterMerge &rhs) const
operator <