24 m_slidingFitWindow(10000),
25 m_distanceToLine(0.5f),
26 m_minContaminationLength(3.f),
27 m_maxDistanceToHit(1.f),
28 m_minRemnantClusterSize(3),
29 m_maxDistanceToTrack(2.f)
40 std::cout <<
"----> Running Algorithm Tool: " << this->
GetInstanceName() <<
", " << this->
GetType() << std::endl;
42 bool changesMade(
false);
45 overlapMatrix.GetSortedKeyClusters(sortedKeyClusters);
48 for (
const Cluster *
const pKeyCluster : sortedKeyClusters)
50 if (usedKeyClusters.count(pKeyCluster))
53 MatrixType::ElementList elementList;
54 overlapMatrix.GetConnectedElements(pKeyCluster,
true, elementList);
56 for (
const MatrixType::Element &element : elementList)
57 usedKeyClusters.insert(element.GetCluster1());
61 changesMade = (changesMade ? changesMade : changesMadeInIteration);
73 for (
const MatrixType::Element &element : elementList)
79 if (checkedClusters.count(pDeltaRayCluster))
83 if ((modifiedClusters.count(element.GetCluster1())) || (modifiedClusters.count(element.GetCluster2())))
95 checkedClusters.insert(pDeltaRayCluster);
99 this->
CreateSeed(element, hitType, deltaRayHits);
101 if (deltaRayHits.empty())
106 if (this->
GrowSeed(element, hitType, deltaRayHits, deltaRayRemnantHits) != STATUS_CODE_SUCCESS)
109 if (deltaRayHits.size() == pDeltaRayCluster->
GetNCaloHits())
112 modifiedClusters.insert(pDeltaRayCluster);
118 return !modifiedClusters.empty();
145 if (otherHitType == hitType)
153 float xMinDR(+std::numeric_limits<float>::max()), xMaxDR(-std::numeric_limits<float>::max());
156 float xMinCR(-std::numeric_limits<float>::max()), xMaxCR(+std::numeric_limits<float>::max());
157 pMuonCluster->GetClusterSpanX(xMinCR, xMaxCR);
159 if ((xMinDR < xMinCR) || (xMaxDR > xMaxCR))
162 float zMinDR(+std::numeric_limits<float>::max()), zMaxDR(-std::numeric_limits<float>::max());
165 float zMinCR(-std::numeric_limits<float>::max()), zMaxCR(+std::numeric_limits<float>::max());
166 pMuonCluster->GetClusterSpanZ(xMinCR, xMaxCR, zMinCR, zMaxCR);
168 if ((zMinDR < zMinCR) || (zMaxDR > zMaxCR))
190 CartesianVector deltaRayVertex(0.f, 0.f, 0.f), muonVertex(0.f, 0.f, 0.f);
194 float furthestSeparation(0.f);
200 for (
const CaloHit *
const pCaloHit : deltaRayHitList)
203 const float separation((position - muonVertex).GetMagnitude());
205 if (separation > furthestSeparation)
209 furthestSeparation = separation;
210 extendedPoint = position;
221 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(muonHitList);
223 for (
const CaloHit *
const pCaloHit : muonHitList)
225 if (this->
IsInLineSegment(deltaRayVertex, extendedPoint, pCaloHit->GetPositionVector()))
242 if (transverseDistanceFromLine > distanceToLine)
253 const float segmentBoundaryGradient = (-1.f) * (upperBoundary.
GetX() - lowerBoundary.
GetX()) / (upperBoundary.
GetZ() - lowerBoundary.
GetZ());
254 const float xPointOnUpperLine((point.
GetZ() - upperBoundary.
GetZ()) / segmentBoundaryGradient + upperBoundary.
GetX());
255 const float xPointOnLowerLine((point.
GetZ() - lowerBoundary.
GetZ()) / segmentBoundaryGradient + lowerBoundary.
GetX());
257 if (std::fabs(xPointOnUpperLine - point.
GetX()) < std::numeric_limits<float>::epsilon())
260 if (std::fabs(xPointOnLowerLine - point.
GetX()) < std::numeric_limits<float>::epsilon())
263 if ((point.
GetX() > xPointOnUpperLine) && (point.
GetX() > xPointOnLowerLine))
266 if ((point.
GetX() < xPointOnUpperLine) && (point.
GetX() < xPointOnLowerLine))
276 const float chiSquared(element.GetOverlapResult().GetReducedChiSquared());
277 const unsigned int hitSum(element.GetCluster1()->GetNCaloHits() + element.GetCluster2()->GetNCaloHits());
279 for (
const MatrixType::Element &testElement : elementList)
284 if ((testElement.GetCluster1() == element.GetCluster1()) && (testElement.GetCluster2() == element.GetCluster2()))
287 const float testChiSquared(testElement.GetOverlapResult().GetReducedChiSquared());
288 const unsigned int testHitSum(testElement.GetCluster1()->GetNCaloHits() + testElement.GetCluster2()->GetNCaloHits());
290 if ((testHitSum < hitSum) || ((testHitSum == hitSum) && (testChiSquared > chiSquared)))
305 CartesianVector positionOnMuon(0.f, 0.f, 0.f), muonDirection(0.f, 0.f, 0.f);
317 CaloHitVector deltaRayHitVector(deltaRayHitList.begin(), deltaRayHitList.end());
320 for (
const CaloHit *
const pCaloHit : deltaRayHitVector)
324 for (
const CartesianVector &projectedPosition : deltaRayProjectedPositions)
326 const float distanceToProjectionSquared((position - projectedPosition).GetMagnitudeSquared());
339 collectedHits.push_back(pCaloHit);
355 return STATUS_CODE_NOT_FOUND;
358 CartesianVector positionOnMuon(0.f, 0.f, 0.f), muonDirection(0.f, 0.f, 0.f);
360 muonDirection) != STATUS_CODE_SUCCESS)
361 return STATUS_CODE_NOT_FOUND;
369 return STATUS_CODE_SUCCESS;
375 const Cluster *
const pDeltaRayCluster,
const float &minDistanceFromMuon,
const bool demandCloserToCollected,
381 bool hitsAdded(
false);
387 for (
const CaloHit *
const pCaloHit : deltaRayHitList)
389 if (std::find(protectedHits.begin(), protectedHits.end(), pCaloHit) != protectedHits.end())
392 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
395 const float distanceToCollectedHits(collectedHits.empty()
396 ? std::numeric_limits<float>::max()
400 if ((distanceToMuonHits < minDistanceFromMuon) || (demandCloserToCollected && (distanceToCollectedHits > distanceToMuonHits)))
403 collectedHits.push_back(pCaloHit);
422 std::string originalListName, fragmentListName;
423 ClusterList originalClusterList(1, pDeltaRayCluster);
431 pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
433 const Cluster *pDeltaRay(
nullptr), *pDeltaRayRemnant(
nullptr);
435 for (
const CaloHit *
const pCaloHit : deltaRayHitList)
437 const bool isDeltaRay(std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end());
438 const bool isDeltaRayRemnant(
439 !isDeltaRay && (std::find(deltaRayRemnantHits.begin(), deltaRayRemnantHits.end(), pCaloHit) != deltaRayRemnantHits.end()));
440 const Cluster *&pCluster(isDeltaRay ? pDeltaRay : isDeltaRayRemnant ? pDeltaRayRemnant : pMuonCluster);
444 PandoraContentApi::Cluster::Parameters parameters;
445 parameters.m_caloHitList.push_back(pCaloHit);
458 if (pDeltaRayRemnant)
459 this->
ReclusterRemnant(hitType, pMuonCluster, pDeltaRayRemnant, clusterVector, pfoVector);
461 clusterVector.push_back(pMuonCluster);
462 pfoVector.push_back(element.GetOverlapResult().GetCommonMuonPfoList().front());
463 clusterVector.push_back(pDeltaRay);
464 pfoVector.push_back(
nullptr);
474 std::string caloHitListName(hitType ==
TPC_VIEW_U ?
"CaloHitListU" : hitType ==
TPC_VIEW_V ?
"CaloHitListV" :
"CaloHitListW");
482 std::string newClusterListName;
486 const ClusterList remnantClusters(pClusterList->begin(), pClusterList->end());
493 for (
const Cluster *
const pRemnant : remnantClusters)
504 clusterVector.push_back(pRemnant);
505 pfoVector.push_back(
nullptr);
516 hitTypes.erase(std::find(hitTypes.begin(), hitTypes.end(), hitType));
521 if (!pCluster1 || !pCluster2)
522 return STATUS_CODE_NOT_FOUND;
550 return STATUS_CODE_SUCCESS;
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the pfo helper class.
Header file for the lar two dimensional sliding fit result class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, 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 RunClusteringAlgorithm(const pandora::Algorithm &algorithm, const std::string &clusteringAlgorithmName, const pandora::ClusterList *&pNewClusterList, std::string &newClusterListName)
Run a clustering algorithm (an algorithm that will create new cluster objects)
static pandora::StatusCode InitializeFragmentation(const pandora::Algorithm &algorithm, const pandora::ClusterList &inputClusterList, std::string &originalClustersListName, std::string &fragmentClustersListName)
Initialize cluster fragmentation operations on clusters in the algorithm input list....
static pandora::StatusCode EndFragmentation(const pandora::Algorithm &algorithm, const std::string &clusterListToSaveName, const std::string &clusterListToDeleteName)
End cluster fragmentation operations on clusters in the algorithm input list.
static pandora::StatusCode MergeAndDeleteClusters(const pandora::Algorithm &algorithm, const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete)
Merge two clusters in the current list, enlarging one cluster and deleting the second.
static pandora::StatusCode AddToCluster(const pandora::Algorithm &algorithm, const pandora::Cluster *const pCluster, const T *const pT)
Add a calo hit, or a list of calo hits, to a cluster.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
TwoViewDeltaRayMatchingAlgorithm * m_pParentAlgorithm
Address of the parent matching algorithm.
TwoViewDeltaRayMatchingAlgorithm::MatchingType::MatrixType MatrixType
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
static void GetClosestPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianVector &position1, pandora::CartesianVector &position2)
Get pair of closest positions for a pair of clusters.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
void UpdateForNewClusters(const pandora::ClusterVector &newClusterVector, const pandora::PfoVector &pfoVector)
Add a new cluster to algorithm ownership maps and, if it a delta ray cluster, to the underlying match...
pandora::StatusCode ParameteriseMuon(const pandora::ParticleFlowObject *const pParentMuon, const pandora::Cluster *const pDeltaRayCluster, pandora::CartesianVector &positionOnMuon, pandora::CartesianVector &muonDirection) const
Parameterise the projection of a cosmic ray track in order to avoid poor/sparse projections.
pandora::StatusCode GetProjectedPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianPointVector &projectedPositions) const
Use two clusters from different views to calculate projected positions in the remaining third view.
pandora::StatusCode GetMuonCluster(const pandora::PfoList &commonMuonPfoList, const pandora::HitType hitType, const pandora::Cluster *&pMuonCluster) const
Return the cluster of the common cosmic ray pfo in a given view (function demands there to be only on...
const std::string & GetClusterListName(const pandora::HitType hitType) const
Get the cluster list name corresponding to a specified hit type.
TwoDSlidingFitResult class.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
void GetGlobalDirection(const float dTdL, pandora::CartesianVector &direction) const
Get global direction coordinates for given sliding linear fit gradient.
float m_minSeparation
The minimum delta ray - parent muon cluster separation required to investigate delta ray cluster.
float m_distanceToLine
The maximum perpendicular distance of a position to a line for it to be considered close.
bool IsContaminated(const MatrixType::Element &element, const pandora::HitType hitType) const
Determine whether the cluster under investigation has muon contamination.
void SplitDeltaRayCluster(const MatrixType::Element &element, const pandora::HitType hitType, pandora::CaloHitList &collectedHits, pandora::CaloHitList &deltaRayRemnantHits) const
Fragment the delta ray cluster, refining the matched delta ray cluster perhaps creating significant r...
bool Run(TwoViewDeltaRayMatchingAlgorithm *const pAlgorithm, MatrixType &overlapMatrix)
Run the algorithm tool.
pandora::StatusCode GrowSeed(const MatrixType::Element &element, const pandora::HitType hitType, pandora::CaloHitList &collectedHits, pandora::CaloHitList &deltaRayRemantHits) const
Examine remaining hits in the delta ray cluster adding them to the delta ray seed or parent muon if a...
void CollectHitsFromDeltaRay(const pandora::CartesianVector &positionOnMuon, const pandora::CartesianVector &muonDirection, const pandora::Cluster *const pDeltaRayCluster, const float &minDistanceFromMuon, const bool demandCloserToCollected, const pandora::CaloHitList &protectedHits, pandora::CaloHitList &collectedHits) const
Collect hits from the delta ray cluster to either keep (demandCloserToCollected == true) or separate ...
unsigned int m_minRemnantClusterSize
The minimum hit number of a remnant cluster for it to be considered significant.
float m_maxDistanceToTrack
The minimum distance of an insignificant remnant cluster from the cosmic ray track for it to be merge...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
TwoViewCosmicRayRemovalTool()
Default constructor.
bool RemoveCosmicRayHits(const MatrixType::ElementList &elementList) const
Remove hits from delta ray clusters that belong to the parent muon.
bool IsMuonEndpoint(const MatrixType::Element &element, const pandora::HitType hitType) const
Determine whether the matched clusters suggest that the delta ray is at the endpoint of the cosmic ra...
void CreateSeed(const MatrixType::Element &element, const pandora::HitType hitType, pandora::CaloHitList &collectedHits) const
Collect hits in the delta ray cluster that lie close to calculated projected positions forming a seed...
pandora::StatusCode ProjectDeltaRayPositions(const MatrixType::Element &element, const pandora::HitType hitType, pandora::CartesianPointVector &projectedPositions) const
Use two views of a delta ray pfo to calculate projected positions in a given third view.
bool IsInLineSegment(const pandora::CartesianVector &lowerBoundary, const pandora::CartesianVector &upperBoundary, const pandora::CartesianVector &point) const
Whether the projection of a given position lies on a defined line.
bool IsCloseToLine(const pandora::CartesianVector &hitPosition, const pandora::CartesianVector &lineStart, const pandora::CartesianVector &lineEnd, const float distanceToLine) const
Whether a given position is close to a defined line.
float m_maxDistanceToHit
The maximum distance of a hit from the cosmic ray track for it to be added into the CR.
bool IsBestElement(const MatrixType::Element &element, const pandora::HitType hitType, const MatrixType::ElementList &elementList) const
Determine whether the input element is the best to use to modify the contaminated cluster (best is de...
float m_minContaminationLength
The minimum projected length of a delta ray cluster onto the muon track for it to be considered conta...
std::vector< pandora::HitType > HitTypeVector
unsigned int m_slidingFitWindow
The sliding fit window used in cosmic ray parameterisations.
void ReclusterRemnant(const pandora::HitType hitType, const pandora::Cluster *const pMuonCluster, const pandora::Cluster *const pDeltaRayRemnant, pandora::ClusterVector &clusterVector, pandora::PfoVector &pfoVector) const
Reculster the remnant cluster, merging insignificant created clusters into the parent muon (if proxim...
bool PassElementChecks(const MatrixType::Element &element, const pandora::HitType hitType) const
Determine whether element satifies simple checks.
TwoViewDeltaRayMatchingAlgorithm class.
const std::string & GetClusteringAlgName() const
Get the name of the clustering algorithm to be used to recluster created delta ray remnants.
const pandora::Cluster * GetCluster(const MatrixType::Element &element, const pandora::HitType hitType)
Get the address of the given hit type cluster.
HitTypeVector GetHitTypeVector()
Obtain the HitTypeVector of input views.
float GetMagnitudeSquared() const
Get the magnitude squared.
float GetX() const
Get the cartesian x coordinate.
CartesianVector GetUnitVector() const
Get a unit vector in the direction of the cartesian vector.
float GetZ() const
Get the cartesian z coordinate.
float GetMagnitude() const
Get the magnitude.
CartesianVector GetCrossProduct(const CartesianVector &rhs) const
Get the cross product of the cartesian vector with a second cartesian vector.
unsigned int GetNCaloHits() const
Get the number of calo hits in the cluster.
const OrderedCaloHitList & GetOrderedCaloHitList() const
Get the ordered calo hit list.
void GetClusterSpanX(float &xmin, float &xmax) const
Get minimum and maximum X positions of the calo hits in this cluster.
void GetClusterSpanZ(const float xmin, const float xmax, float &zmin, float &zmax) const
Get upper and lower Z positions of the calo hits in a cluster in range xmin to xmax.
void FillCaloHitList(CaloHitList &caloHitList) const
Fill a provided calo hit list with all the calo hits in the ordered calo hit list.
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
const Pandora & GetPandora() const
Get the associated pandora instance.
const std::string & GetInstanceName() const
Get the instance name.
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 CaloHit * > CaloHitVector
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< const ParticleFlowObject * > PfoVector
std::vector< CartesianVector > CartesianPointVector
std::unordered_set< const Cluster * > ClusterSet
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.