24 m_replaceCurrentVertexList(true),
25 m_slidingFitWindow(20),
26 m_minClusterCaloHits(5),
27 m_minClusterLengthSquared(3.f * 3.f),
29 m_enableEndpointCandidates(true),
30 m_maxEndpointXDiscrepancy(4.f),
31 m_enableCrossingCandidates(false),
32 m_nMaxCrossingCandidates(500),
33 m_maxCrossingXDiscrepancy(0.5f),
34 m_extrapolationNSteps(200),
35 m_extrapolationStepSize(0.1f),
36 m_maxCrossingSeparationSquared(2.f * 2.f),
37 m_minNearbyCrossingDistanceSquared(0.5f * 0.5f),
38 m_reducedCandidates(false),
39 m_selectionCutFactorMax(2.f),
40 m_nClustersPassingMaxCutsPar(26.f)
51 this->
SelectClusters(clusterVectorU, clusterVectorV, clusterVectorW);
54 std::string temporaryListName;
70 if (!pVertexList->empty())
81 throw statusCodeException;
86 return STATUS_CODE_SUCCESS;
99 if (!pClusterList || pClusterList->empty())
102 std::cout <<
"CandidateVertexCreationAlgorithm: unable to find cluster list " << clusterListName << std::endl;
114 if (!selectedClusterVector.empty())
117 ClusterVector sortedClusters(pClusterList->begin(), pClusterList->end());
120 unsigned int nClustersPassingMaxCuts(0);
123 for (
const Cluster *
const pCluster : sortedClusters)
125 float selectionCutFactor(1.f);
127 if (pCluster->GetParticleId() == E_MINUS)
136 nClustersPassingMaxCuts++;
140 for (
const Cluster *
const pCluster : sortedClusters)
142 float selectionCutFactor(1.f);
160 selectedClusterVector.push_back(pCluster);
164 if (STATUS_CODE_FAILURE == statusCodeException.
GetStatusCode())
165 throw statusCodeException;
175 for (
const Cluster *
const pCluster1 : clusterVector1)
183 for (
const Cluster *
const pCluster2 : clusterVector2)
207 if ((((position1.
GetX() < minLayerPosition2.
GetX()) && (position1.
GetX() < maxLayerPosition2.
GetX())) ||
208 ((position1.
GetX() > minLayerPosition2.
GetX()) && (position1.
GetX() > maxLayerPosition2.
GetX()))) &&
221 float chiSquared(0.f);
228 PandoraContentApi::Vertex::Parameters parameters;
229 parameters.m_position = position3D;
233 const Vertex *pVertex(NULL);
234 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
247 unsigned int nCrossingCandidates(0);
259 for (
const Cluster *
const pCluster : clusterVector)
261 ClusterToSpacepointsMap::iterator mapIter(clusterToSpacepointsMap.emplace(pCluster,
CartesianPointVector()).first);
265 for (
const Cluster *
const pCluster1 : clusterVector)
267 for (
const Cluster *
const pCluster2 : clusterVector)
269 if (pCluster1 == pCluster2)
272 this->
FindCrossingPoints(clusterToSpacepointsMap.at(pCluster1), clusterToSpacepointsMap.at(pCluster2), crossingPoints);
291 CartesianVector positionPositive(0.f, 0.f, 0.f), positionNegative(0.f, 0.f, 0.f);
295 spacepoints.push_back(positionPositive);
296 spacepoints.push_back(positionNegative);
307 bool bestCrossingFound(
false);
309 CartesianVector bestPosition1(0.f, 0.f, 0.f), bestPosition2(0.f, 0.f, 0.f);
315 const float separationSquared((position1 - position2).GetMagnitudeSquared());
317 if (separationSquared < bestSeparationSquared)
319 bestCrossingFound =
true;
320 bestSeparationSquared = separationSquared;
321 bestPosition1 = position1;
322 bestPosition2 = position2;
327 if (bestCrossingFound)
329 bool alreadyPopulated(
false);
336 alreadyPopulated =
true;
341 if (!alreadyPopulated)
343 crossingPoints.push_back(bestPosition1);
344 crossingPoints.push_back(bestPosition2);
365 float chiSquared(0.f);
372 PandoraContentApi::Vertex::Parameters parameters;
373 parameters.m_position = position3D;
377 const Vertex *pVertex(NULL);
378 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
379 ++nCrossingCandidates;
392 if (!pInputVertexList)
395 for (
const Vertex *pInputVertex : *pInputVertexList)
397 PandoraContentApi::Vertex::Parameters parameters;
398 parameters.m_position = pInputVertex->GetPosition();
402 const Vertex *pVertex(
nullptr);
403 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
419 if (!
m_slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult)).second)
500 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
XmlHelper::ReadValue(xmlHandle,
"MaxCrossingSeparation", maxCrossingSeparation));
508 return STATUS_CODE_SUCCESS;
Header file for the candidate vertex creation algorithm class.
Header file for the cluster helper class.
Header file for the geometry helper class.
#define PANDORA_THROW_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
static pandora::StatusCode ReplaceCurrentList(const pandora::Algorithm &algorithm, const std::string &newListName)
Replace the current list with a pre-saved list; use this new list as a permanent replacement for the ...
static pandora::StatusCode CreateTemporaryListAndSetCurrent(const pandora::Algorithm &algorithm, const T *&pT, std::string &temporaryListName)
Create a temporary list and set it to be the current list, enabling object creation.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
void CreateEndpointVertex(const pandora::CartesianVector &position1, const pandora::HitType hitType1, const TwoDSlidingFitResult &fitResult2) const
Create a candidate vertex position, using an end-point position from one cluster and sliding fit to a...
float m_selectionCutFactorMax
Maximum factor to multiply the base cluster selection cuts.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void AddInputVertices() const
Add candidate vertices from any input vertices.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
unsigned int m_extrapolationNSteps
Number of extrapolation steps, at each end of cluster, of specified size.
void FindCrossingPoints(const pandora::ClusterVector &clusterVector, pandora::CartesianPointVector &crossingPoints) const
Identify where (extrapolated) clusters plausibly cross in 2D.
bool m_enableEndpointCandidates
Whether to create endpoint-based candidates.
float m_maxCrossingXDiscrepancy
The max cluster endpoint discrepancy.
bool m_enableCrossingCandidates
Whether to create crossing vertex candidates.
float m_maxCrossingSeparationSquared
The separation (squared) between spacepoints below which a crossing can be identified.
void GetSpacepoints(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &spacePoints) const
Get a list of spacepoints representing cluster 2D hit positions and extrapolated positions.
void SelectClusters(pandora::ClusterVector &clusterVectorU, pandora::ClusterVector &clusterVectorV, pandora::ClusterVector &clusterVectorW)
Select a subset of input clusters (contained in the input list names) for processing in this algorith...
void CreateEndpointCandidates(const pandora::ClusterVector &clusterVector1, const pandora::ClusterVector &clusterVector2) const
Create candidate vertex positions by comparing pairs of cluster end positions.
TwoDSlidingFitResultMap m_slidingFitResultMap
The sliding fit result map.
float m_nClustersPassingMaxCutsPar
Parameter for number of clusters passing the max base cluster selection cuts.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterToSpacepointsMap
void CreateCrossingCandidates(const pandora::ClusterVector &clusterVectorU, const pandora::ClusterVector &clusterVectorV, const pandora::ClusterVector &clusterVectorW) const
Extrapolate 2D clusters, find where they cross, and match crossing points between views to create ver...
void CreateCrossingVertices(const pandora::CartesianPointVector &crossingPoints1, const pandora::CartesianPointVector &crossingPoints2, const pandora::HitType hitType1, const pandora::HitType hitType2, unsigned int &nCrossingCandidates) const
Attempt to create candidate vertex positions, using 2D crossing points in 2 views.
void TidyUp()
Clear relevant algorithm member variables between events.
float m_maxEndpointXDiscrepancy
The max cluster endpoint discrepancy.
std::string m_outputVertexListName
The name under which to save the output vertex list.
bool m_replaceCurrentVertexList
Whether to replace the current vertex list with the output list.
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
unsigned int m_nMaxCrossingCandidates
The max number of crossing candidates to create.
float m_minClusterLengthSquared
The min length (squared) in base cluster selection method.
std::string m_inputVertexListName
The list name for existing candidate vertices.
CandidateVertexCreationAlgorithm()
Default constructor.
bool m_reducedCandidates
Whether to reduce the number of candidates.
pandora::StringVector m_inputClusterListNames
The list of cluster list names.
float m_minNearbyCrossingDistanceSquared
The minimum allowed distance between identified crossing positions.
unsigned int m_minClusterCaloHits
The min number of hits in base cluster selection method.
void AddToSlidingFitCache(const pandora::Cluster *const pCluster)
Creates a 2D sliding fit of a cluster and stores it for later use.
float m_chiSquaredCut
The chi squared cut (accept only 3D vertex positions with values below cut)
float m_extrapolationStepSize
The extrapolation step size in cm.
pandora::StatusCode Run()
Run the algorithm.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static void GetCoordinateVector(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &coordinateVector)
Get vector of hit coordinates from an input cluster.
static bool SortCoordinatesByPosition(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
Sort cartesian vectors by their position (use Z, followed by X, followed by Y)
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,...
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
static void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
TwoDSlidingFitResult class.
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
pandora::StatusCode GetExtrapolatedPositionAtX(const float x, pandora::CartesianVector &position) const
Get extrapolated position (beyond span) for a given input x coordinate.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
pandora::StatusCode GetExtrapolatedPosition(const float rL, pandora::CartesianVector &position) const
Get extrapolated position (beyond span) for a given input coordinate.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
float GetX() const
Get the cartesian x coordinate.
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const Pandora & GetPandora() const
Get the associated pandora instance.
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
static StatusCode ReadVectorOfValues(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, std::vector< T > &vector)
Read a vector of values from a (space separated) list in an xml element.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< CartesianVector > CartesianPointVector
MANAGED_CONTAINER< const Vertex * > VertexList
StatusCode
The StatusCode enum.