9 #include "Pandora/AlgorithmHeaders.h"
22 ThreeDKinkBaseTool::ThreeDKinkBaseTool(
const unsigned int nCommonClusters) :
23 m_nCommonClusters(nCommonClusters),
24 m_majorityRulesMode(
false),
25 m_minMatchedFraction(0.75f),
26 m_minMatchedSamplingPoints(10),
27 m_minLongitudinalImpactParameter(-1.f),
28 m_nLayersForKinkSearch(10),
29 m_additionalXStepForKinkSearch(0.01f)
32 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
45 if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
63 float xMin1(std::numeric_limits<float>::max()), xMax1(-std::numeric_limits<float>::max());
64 float xMin2(std::numeric_limits<float>::max()), xMax2(-std::numeric_limits<float>::max());
65 float xMin3(std::numeric_limits<float>::max()), xMax3(-std::numeric_limits<float>::max());
70 const float commonX(isForwardInX ? std::max(xMin1, std::max(xMin2, xMin3)) : std::min(xMax1, std::min(xMax2, xMax3)));
72 if (isForwardInX && ((commonX > xMax1) || (commonX > xMax2) || (commonX > xMax3)))
73 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
75 if (!isForwardInX && ((commonX < xMin1) || (commonX < xMin2) || (commonX < xMin3)))
76 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
79 float rL1(0.f), rT1(0.f);
81 const int splitLayer(fitResult1.
GetLayer(rL1));
86 CartesianVector minus(0.f, 0.f, 0.f), plus(0.f, 0.f, 0.f);
90 if (minus.GetX() > plus.GetX())
92 CartesianVector temporary(minus);
97 const float layerStepX(isForwardInX ? plus.GetX() : minus.GetX());
100 const float chosenX(isForwardInX ? std::max(layerStepX, commonX) : std::min(layerStepX, commonX));
128 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
129 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
133 const bool changesMade(this->
ApplyChanges(pAlgorithm, modificationList));
143 ClusterSet usedClusters;
147 for (
const Cluster *
const pKeyCluster : sortedKeyClusters)
149 if (!pKeyCluster->IsAvailable())
152 unsigned int nU(0), nV(0), nW(0);
156 if (nU * nV * nW < 2)
167 if (iteratorList.size() < 2)
173 if (localModificationList.empty())
176 for (ModificationList::const_iterator mIter = localModificationList.begin(), mIterEnd = localModificationList.end(); mIter != mIterEnd; ++mIter)
178 usedClusters.insert(mIter->m_affectedClusters.begin(), mIter->m_affectedClusters.end());
181 modificationList.insert(modificationList.end(), localModificationList.begin(), localModificationList.end());
193 for (
const Modification &modification : modificationList)
195 ClusterList parentClusters;
196 for (
const auto &mapEntry : modification.m_clusterMergeMap)
197 parentClusters.push_back(mapEntry.first);
200 for (
const Cluster *
const pParentCluster : parentClusters)
202 const ClusterList &daughterClusters(modification.m_clusterMergeMap.at(pParentCluster));
204 for (
const Cluster *
const pDaughterCluster : daughterClusters)
206 if (consolidatedMergeMap.count(pDaughterCluster))
207 throw StatusCodeException(STATUS_CODE_FAILURE);
210 ClusterList &targetClusterList(consolidatedMergeMap[pParentCluster]);
211 targetClusterList.insert(targetClusterList.end(), daughterClusters.begin(), daughterClusters.end());
214 ClusterList splitClusters;
215 for (
const auto &mapEntry : modification.m_splitPositionMap)
216 splitClusters.push_back(mapEntry.first);
219 for (
const Cluster *
const pSplitCluster : splitClusters)
221 const CartesianPointVector &splitPositions(modification.m_splitPositionMap.at(pSplitCluster));
223 CartesianPointVector &cartesianPointVector(consolidatedSplitMap[pSplitCluster]);
224 cartesianPointVector.insert(cartesianPointVector.end(), splitPositions.begin(), splitPositions.end());
228 bool changesMade(
false);
238 const ClusterSet &usedClusters,
IteratorList &iteratorList)
const
240 iteratorList.push_back(eIter);
250 for (IteratorList::const_iterator iIter = iteratorList.begin(); iIter != iteratorList.end(); ++iIter)
252 if ((*iIter) == eIter2)
255 unsigned int nMatchedClusters(0);
257 if ((*iIter)->GetClusterU() == eIter2->GetClusterU())
260 if ((*iIter)->GetClusterV() == eIter2->GetClusterV())
263 if ((*iIter)->GetClusterW() == eIter2->GetClusterW())
268 iteratorList.push_back(eIter2);
279 PANDORA_RETURN_RESULT_IF_AND_IF(
280 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MajorityRulesMode",
m_majorityRulesMode));
282 PANDORA_RETURN_RESULT_IF_AND_IF(
283 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinMatchedFraction",
m_minMatchedFraction));
285 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
288 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
291 PANDORA_RETURN_RESULT_IF_AND_IF(
292 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NLayersForKinkSearch",
m_nLayersForKinkSearch));
294 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
297 return STATUS_CODE_SUCCESS;
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::vector< Modification > ModificationList
bool ApplyChanges(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const ModificationList &modificationList) const
Apply the changes cached in a modification list and update the tensor accordingly.
float GetXSamplingPoint(const pandora::CartesianVector &splitPosition1, const bool isForwardInX, const TwoDSlidingFitResult &fitResult1, const TwoDSlidingFitResult &fitResult2, const TwoDSlidingFitResult &fitResult3) const
Get a sampling point in x that is common to sliding linear fit objects in three views.
virtual bool MakeClusterSplits(const SplitPositionMap &splitPositionMap)
Make cluster splits.
Header file for the lar pointing cluster class.
void GetMinAndMaxX(float &minX, float &maxX) const
Get the minimum and maximum x coordinates associated with the sliding fit.
std::vector< TensorType::ElementList::const_iterator > IteratorList
unsigned int m_nCommonClusters
The number of common clusters.
void GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
LArPointingCluster class.
virtual ~ThreeDKinkBaseTool()
Destructor.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
std::vector< Element > ElementList
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
int m_nLayersForKinkSearch
The number of sliding fit layers to step in the kink search.
Header file for the cluster helper class.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
const Vertex & GetOuterVertex() const
Get the outer vertex.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > SplitPositionMap
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const Vertex & GetInnerVertex() const
Get the inner vertex.
void GetModifications(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ModificationList &modificationList) const
Get modification objects, identifying required splits and merges for clusters.
void SelectTensorElements(TensorType::ElementList::const_iterator eIter, const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select elements representing possible components of interest due to overshoots or undershoots in clus...
virtual bool PassesElementCuts(TensorType::ElementList::const_iterator eIter, const pandora::ClusterSet &usedClusters) const
Whether a provided (iterator to a) tensor element passes the selection cuts for overshoot identificat...
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
bool Run(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
static bool IsALowestInX(const LArPointingCluster &pointingClusterA, const LArPointingCluster &pointingClusterB)
Whether pointing cluster labelled A extends to lowest x positions (as opposed to that labelled B) ...
float m_additionalXStepForKinkSearch
An additional (safety) step to tack-on when choosing x sampling points.
virtual void GetIteratorListModifications(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const IteratorList &iteratorList, ModificationList &modificationList) const =0
Get modification objects for a specific elements of the tensor, identifying required splits and merge...
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for use as a key tensor element.
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
bool m_majorityRulesMode
Whether to run in majority rules mode (always split overshoots, always merge undershoots) ...
float m_minLongitudinalImpactParameter
The min longitudinal impact parameter for connecting accompanying clusters.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
ThreeViewTransverseTracksAlgorithm class.
float m_minMatchedFraction
The min matched sampling point fraction for use as a key tensor element.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
TwoDSlidingFitResult class.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
BEGIN_PROLOG could also be cout
TheTensor::const_iterator const_iterator