9 #include "Pandora/AlgorithmHeaders.h"
23 ConeClusterMopUpAlgorithm::ConeClusterMopUpAlgorithm() :
24 m_slidingFitWindow(20),
25 m_showerEdgeMultiplier(1.5f),
26 m_coneAngleCentile(0.85f),
27 m_maxConeLengthMultiplier(1.5f),
28 m_minBoundedFraction(0.5f)
40 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*
this, pVertexList));
42 if ((pVertexList->size() != 1) || (VERTEX_3D != (*(pVertexList->begin()))->GetVertexType()))
45 const Vertex *
const pVertex(*(pVertexList->begin()));
47 ClusterVector sortedPfoClusters(pfoClusters.begin(), pfoClusters.end());
50 ClusterVector sortedRemnantClusters(remnantClusters.begin(), remnantClusters.end());
53 for (
const Cluster *
const pPfoCluster : sortedPfoClusters)
63 if (layerFitResultMapS.size() < 2)
67 CartesianVector minLayerPositionOnAxis(0.f, 0.f, 0.f), maxLayerPositionOnAxis(0.f, 0.f, 0.f);
73 const bool vertexAtMinL((vertexPosition2D - minLayerPositionOnAxis).GetMagnitudeSquared() <
74 (vertexPosition2D - maxLayerPositionOnAxis).GetMagnitudeSquared());
79 for (LayerFitResultMap::const_iterator iterS = layerFitResultMapS.begin(); iterS != layerFitResultMapS.end(); ++iterS)
81 LayerFitResultMap::const_iterator iterP = layerFitResultMapP.find(iterS->first);
82 LayerFitResultMap::const_iterator iterN = layerFitResultMapN.find(iterS->first);
84 if (layerFitResultMapP.end() != iterP)
85 coordinateListP.push_back(
Coordinate(iterP->second.GetL(), iterP->second.GetFitT()));
87 if (layerFitResultMapN.end() != iterN)
88 coordinateListN.push_back(
Coordinate(iterN->second.GetL(), iterN->second.GetFitT()));
91 if (coordinateListP.empty() || coordinateListN.empty())
99 ?
Coordinate(layerFitResultMapP.begin()->second.GetL(), layerFitResultMapP.begin()->second.GetFitT())
100 :
Coordinate(layerFitResultMapP.rbegin()->second.GetL(), layerFitResultMapP.rbegin()->second.GetFitT()));
104 ?
Coordinate(layerFitResultMapN.begin()->second.GetL(), layerFitResultMapN.begin()->second.GetFitT())
105 :
Coordinate(layerFitResultMapN.rbegin()->second.GetL(), layerFitResultMapN.rbegin()->second.GetFitT()));
107 const float minL(layerFitResultMapS.begin()->second.GetL());
110 if ((std::fabs(maxP.first - minP.first) < std::numeric_limits<float>::epsilon()) ||
111 (std::fabs(maxN.first - minN.first) < std::numeric_limits<float>::epsilon()) ||
112 (std::fabs(maxL - minL) < std::numeric_limits<float>::epsilon()))
118 for (
const Cluster *
const pRemnantCluster : sortedRemnantClusters)
120 const unsigned int nHits(pRemnantCluster->GetNCaloHits());
122 unsigned int nMatchedHits(0);
123 const OrderedCaloHitList &orderedCaloHitList(pRemnantCluster->GetOrderedCaloHitList());
125 for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
127 for (CaloHitList::const_iterator hIter = iter->second->begin(), hIterEnd = iter->second->end(); hIter != hIterEnd; ++hIter)
129 float rL(0.f), rT(0.f);
132 if ((rL < minL) || (rL > maxL))
135 const float rTP(minP.second + (rL - minP.first) * ((maxP.second - minP.second) / (maxP.first - minP.first)));
136 const float rTN(minN.second + (rL - minN.first) * ((maxN.second - minN.second) / (maxN.first - minN.first)));
138 if ((rT > rTP) || (rT < rTN))
145 const float boundedFraction((nHits > 0) ? static_cast<float>(nMatchedHits) / static_cast<float>(nHits) : 0.f);
152 if (!associationDetails.insert(AssociationDetails::value_type(pPfoCluster, boundedFraction)).second)
153 throw StatusCodeException(STATUS_CODE_FAILURE);
156 catch (StatusCodeException &statusCodeException)
158 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
159 throw statusCodeException;
170 return (lhs.second < rhs.second);
177 PANDORA_RETURN_RESULT_IF_AND_IF(
178 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitWindow",
m_slidingFitWindow));
180 PANDORA_RETURN_RESULT_IF_AND_IF(
181 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerEdgeMultiplier",
m_showerEdgeMultiplier));
183 PANDORA_RETURN_RESULT_IF_AND_IF(
184 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeAngleCentile",
m_coneAngleCentile));
186 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
189 PANDORA_RETURN_RESULT_IF_AND_IF(
190 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinBoundedFraction",
m_minBoundedFraction));
Header file for the lar two dimensional sliding shower fit result class.
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.
virtual void MakeClusterMerges(const ClusterAssociationMap &clusterAssociationMap) const
Make the cluster merges specified in the cluster association map, using list name information in the ...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static bool SortCoordinates(const Coordinate &lhs, const Coordinate &rhs)
Sort coordinates by increasing transverse displacement.
const TwoDSlidingFitResult & GetShowerFitResult() const
Get the sliding fit result for the full shower cluster.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
std::unordered_map< const pandora::Cluster *, AssociationDetails > ClusterAssociationMap
float m_maxConeLengthMultiplier
Consider hits as bound if inside cone, with projected distance less than N times cone length...
float m_minBoundedFraction
The minimum cluster bounded fraction for merging.
TwoDSlidingShowerFitResult class.
Header file for the geometry helper class.
Header file for the cone cluster mop up algorithm class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::pair< float, float > Coordinate
Header file for the cluster helper class.
float m_showerEdgeMultiplier
Artificially tune width of shower envelope so as to make it more/less inclusive.
std::map< int, LayerFitResult > LayerFitResultMap
std::unordered_map< const pandora::Cluster *, float > AssociationDetails
const TwoDSlidingFitResult & GetPositiveEdgeFitResult() const
Get the sliding fit result for the positive shower edge.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
std::vector< Coordinate > CoordinateList
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
const TwoDSlidingFitResult & GetNegativeEdgeFitResult() const
Get the sliding fit result for the negative shower edge.
void GetGlobalPosition(const float rL, const float rT, pandora::CartesianVector &position) const
Get global coordinates for given sliding linear fit coordinates.
void ClusterMopUp(const pandora::ClusterList &pfoClusters, const pandora::ClusterList &remnantClusters) const
Cluster mop up for a single view. This function is responsible for instructing pandora to make cluste...
float m_coneAngleCentile
Cluster cone angle is defined using specified centile of distribution of hit half angles...
std::vector< art::Ptr< recob::Cluster > > ClusterVector
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
std::list< Vertex > VertexList