9 #include "Pandora/AlgorithmHeaders.h" 34 EventSlicingTool::EventSlicingTool() :
35 m_minHitsPer3DCluster(20),
36 m_min3DHitsToSeedNewSlice(50),
37 m_halfWindowLayers(20),
38 m_usePointingAssociation(true),
39 m_minVertexLongitudinalDistance(-7.5
f),
40 m_maxVertexLongitudinalDistance(60.
f),
41 m_maxVertexTransverseDistance(10.5
f),
42 m_vertexAngularAllowance(9.
f),
43 m_maxClosestApproach(15.
f),
44 m_maxInterceptDistance(60.
f),
45 m_useProximityAssociation(true),
46 m_maxHitSeparationSquared(25.
f * 25.
f),
47 m_useShowerConeAssociation(true),
50 m_coneLengthMultiplier(7.
f),
51 m_maxConeLength(126.
f),
52 m_coneTanHalfAngle1(0.5
f),
53 m_coneBoundedFraction1(0.5
f),
54 m_coneTanHalfAngle2(0.75
f),
55 m_coneBoundedFraction2(0.75
f),
56 m_use3DProjectionsInHitPickUp(true)
63 const HitTypeToNameMap &clusterListNames, SliceList &sliceList)
65 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
66 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() <<
std::endl;
70 ClusterList trackClusters3D;
73 ClusterList showerClusters3D;
79 if (clusterSliceList.size() < 2)
86 this->
CreateSlices(clusterSliceList, sliceList, clusterToSliceIndexMap);
88 ClusterSet assignedClusters;
89 this->
CopyPfoHitsToSlices(clusterToSliceIndexMap, clusterToPfoMap, sliceList, assignedClusters);
91 ClusterList remainingClusters;
102 if (!sliceList.empty())
103 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
105 const CaloHitList *pCaloHitListU(
nullptr);
106 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
107 PandoraContentApi::GetList(*pAlgorithm, caloHitListNames.at(TPC_VIEW_U), pCaloHitListU));
109 const CaloHitList *pCaloHitListV(
nullptr);
110 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
111 PandoraContentApi::GetList(*pAlgorithm, caloHitListNames.at(TPC_VIEW_V), pCaloHitListV));
113 const CaloHitList *pCaloHitListW(
nullptr);
114 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
115 PandoraContentApi::GetList(*pAlgorithm, caloHitListNames.at(TPC_VIEW_W), pCaloHitListW));
117 if (pCaloHitListU || pCaloHitListV || pCaloHitListW)
119 sliceList.push_back(
Slice());
120 Slice &slice(sliceList.at(0));
123 slice.m_caloHitListU = *pCaloHitListU;
125 slice.m_caloHitListV = *pCaloHitListV;
127 slice.m_caloHitListW = *pCaloHitListW;
134 const Algorithm *
const pAlgorithm,
const std::string &pfoListName, ClusterList &clusters3D,
ClusterToPfoMap &clusterToPfoMap)
const 136 const PfoList *pPfoList(
nullptr);
137 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*pAlgorithm, pfoListName, pPfoList));
139 if (!pPfoList || pPfoList->empty())
141 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
142 std::cout <<
"EventSlicingTool: unable to find pfo list " << pfoListName <<
std::endl;
147 for (
const ParticleFlowObject *
const pPfo : *pPfoList)
149 ClusterList pfoClusters3D;
152 for (
const Cluster *
const pCluster3D : pfoClusters3D)
157 if (!clusterToPfoMap.insert(ClusterToPfoMap::value_type(pCluster3D, pPfo)).second)
158 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
160 if (clusters3D.end() != std::find(clusters3D.begin(), clusters3D.end(), pCluster3D))
161 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
163 clusters3D.push_back(pCluster3D);
176 for (
const Cluster *
const pCluster3D : trackClusters3D)
180 trackFitResults.insert(
183 catch (StatusCodeException &)
185 std::cout <<
"EventSlicingTool: ThreeDSlidingFitResult failure for track cluster." <<
std::endl;
191 for (
const Cluster *
const pCluster3D : showerClusters3D)
195 showerConeFitResults.insert(
198 catch (StatusCodeException &)
200 std::cout <<
"EventSlicingTool: ThreeDSlidingConeFitResult failure for shower cluster." <<
std::endl;
204 ClusterVector sortedClusters3D(trackClusters3D.begin(), trackClusters3D.end());
205 sortedClusters3D.insert(sortedClusters3D.end(), showerClusters3D.begin(), showerClusters3D.end());
208 ClusterSet usedClusters;
210 for (
const Cluster *
const pCluster3D : sortedClusters3D)
212 if (usedClusters.count(pCluster3D))
219 usedClusters.insert(pCluster3D);
222 this->
CollectAssociatedClusters(pCluster3D, sortedClusters3D, trackFitResults, showerConeFitResults, clusterSlice, usedClusters);
234 for (
const Cluster *
const pCandidateCluster : candidateClusters)
236 if (usedClusters.count(pCandidateCluster) || (pClusterInSlice == pCandidateCluster))
242 this->
PassShowerCone(pCandidateCluster, pClusterInSlice, showerConeFitResults))))
244 addedClusters.push_back(pCandidateCluster);
245 (void)usedClusters.insert(pCandidateCluster);
249 clusterSlice.insert(clusterSlice.end(), addedClusters.begin(), addedClusters.end());
251 for (
const Cluster *
const pAddedCluster : addedClusters)
252 this->
CollectAssociatedClusters(pAddedCluster, candidateClusters, trackFitResults, showerConeFitResults, clusterSlice, usedClusters);
258 const Cluster *
const pClusterInSlice,
const Cluster *
const pCandidateCluster,
const ThreeDSlidingFitResultMap &trackFitResults)
const 263 if ((trackFitResults.end() == inSliceIter) || (trackFitResults.end() == candidateIter))
270 this->
IsEmission(inSlicePointingCluster, candidatePointingCluster) || this->
IsNode(inSlicePointingCluster, candidatePointingCluster))
282 for (
const auto &orderedList1 : pClusterInSlice->GetOrderedCaloHitList())
284 for (
const CaloHit *
const pCaloHit1 : *(orderedList1.second))
286 const CartesianVector &positionVector1(pCaloHit1->GetPositionVector());
288 for (
const auto &orderedList2 : pCandidateCluster->GetOrderedCaloHitList())
290 for (
const CaloHit *
const pCaloHit2 : *(orderedList2.second))
309 if (showerConeFitResults.end() == fitIter)
312 float clusterLength(0.
f);
320 clusterLength = (slidingFitResult3D.GetGlobalMaxLayerPosition() - slidingFitResult3D.GetGlobalMinLayerPosition()).GetMagnitude();
322 catch (
const StatusCodeException &)
327 for (
const SimpleCone &simpleCone : simpleConeList)
357 CartesianVector intersectionPoint(0.
f, 0.
f, 0.
f);
364 catch (
const StatusCodeException &)
371 const float closestApproach((approach1 - approach2).GetMagnitude());
425 unsigned int index(0);
429 for (
const Cluster *
const pCluster3D : clusterList)
432 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
434 if (!clusterToSliceIndexMap.insert(ClusterToSliceIndexMap::value_type(pCluster3D, index)).second)
435 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
438 sliceList.push_back(
Slice());
446 SliceList &sliceList, ClusterSet &assignedClusters)
const 448 ClusterList clusterList;
449 for (
const auto &mapEntry : clusterToSliceIndexMap)
450 clusterList.push_back(mapEntry.first);
453 for (
const Cluster *
const pCluster3D : clusterList)
455 const unsigned int index(clusterToSliceIndexMap.at(pCluster3D));
457 const Pfo *
const pPfo(clusterToPfoMap.at(pCluster3D));
458 Slice &slice(sliceList.at(
index));
460 ClusterList clusters2D;
463 for (
const Cluster *
const pCluster2D : clusters2D)
467 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
468 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
470 CaloHitList &targetList((TPC_VIEW_U == hitType) ? slice.m_caloHitListU : (TPC_VIEW_V == hitType) ? slice.m_caloHitListV : slice.m_caloHitListW);
472 pCluster2D->GetOrderedCaloHitList().FillCaloHitList(targetList);
473 targetList.insert(targetList.end(), pCluster2D->GetIsolatedCaloHitList().begin(), pCluster2D->GetIsolatedCaloHitList().end());
475 if (!assignedClusters.insert(pCluster2D).second)
476 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
484 const ClusterSet &assignedClusters, ClusterList &remainingClusters)
const 486 this->
GetRemainingClusters(pAlgorithm, clusterListNames.at(TPC_VIEW_U), assignedClusters, remainingClusters);
487 this->
GetRemainingClusters(pAlgorithm, clusterListNames.at(TPC_VIEW_V), assignedClusters, remainingClusters);
488 this->
GetRemainingClusters(pAlgorithm, clusterListNames.at(TPC_VIEW_W), assignedClusters, remainingClusters);
494 const ClusterSet &assignedClusters, ClusterList &remainingClusters)
const 496 const ClusterList *pClusterList(
nullptr);
497 PANDORA_THROW_RESULT_IF_AND_IF(
498 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*pAlgorithm, clusterListName, pClusterList));
500 if (!pClusterList || pClusterList->empty())
502 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
503 std::cout <<
"EventSlicingTool: unable to find cluster list " << clusterListName <<
std::endl;
508 for (
const Cluster *
const pCluster2D : *pClusterList)
512 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
513 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
515 if (assignedClusters.count(pCluster2D))
518 if (remainingClusters.end() != std::find(remainingClusters.begin(), remainingClusters.end(), pCluster2D))
519 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
521 remainingClusters.push_back(pCluster2D);
528 const ClusterList &remainingClusters,
const ClusterToSliceIndexMap &clusterToSliceIndexMap, SliceList &sliceList)
const 538 this->
GetKDTreeEntries3D(clusterToSliceIndexMap, pointsU, pointsV, pointsW, pointToSliceIndexMap);
550 kdTreeU.
build(kDNode2DListU, boundingRegionU);
551 kdTreeV.
build(kDNode2DListV, boundingRegionV);
552 kdTreeW.
build(kDNode2DListW, boundingRegionW);
554 ClusterVector sortedRemainingClusters(remainingClusters.begin(), remainingClusters.end());
557 for (
const Cluster *
const pCluster2D : sortedRemainingClusters)
561 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
562 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
564 PointKDTree2D &kdTree((TPC_VIEW_U == hitType) ? kdTreeU : (TPC_VIEW_V == hitType) ? kdTreeV : kdTreeW);
567 if (!pBestResultPoint)
570 Slice &slice(sliceList.at(pointToSliceIndexMap.at(pBestResultPoint->
data)));
573 pCluster2D->GetOrderedCaloHitList().FillCaloHitList(targetList);
574 targetList.insert(targetList.end(), pCluster2D->GetIsolatedCaloHitList().begin(), pCluster2D->GetIsolatedCaloHitList().end());
579 std::cout <<
"EventSlicingTool::AssignRemainingHitsToSlices - exception " <<
std::endl;
580 for (
const auto &pointMap : pointToSliceIndexMap)
581 delete pointMap.first;
585 for (
const auto &pointMap : pointToSliceIndexMap)
586 delete pointMap.first;
594 unsigned int sliceIndex(0);
596 for (
const Slice &slice : sliceList)
598 for (
const CaloHit *
const pCaloHit : slice.m_caloHitListU)
600 const CartesianVector *
const pPoint(
new CartesianVector(pCaloHit->GetPositionVector()));
601 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pPoint, sliceIndex));
602 pointsU.push_back(pPoint);
605 for (
const CaloHit *
const pCaloHit : slice.m_caloHitListV)
607 const CartesianVector *
const pPoint(
new CartesianVector(pCaloHit->GetPositionVector()));
608 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pPoint, sliceIndex));
609 pointsV.push_back(pPoint);
612 for (
const CaloHit *
const pCaloHit : slice.m_caloHitListW)
614 const CartesianVector *
const pPoint(
new CartesianVector(pCaloHit->GetPositionVector()));
615 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pPoint, sliceIndex));
616 pointsW.push_back(pPoint);
628 ClusterList clusterList;
629 for (
const auto &mapEntry : clusterToSliceIndexMap)
630 clusterList.push_back(mapEntry.first);
633 for (
const Cluster *
const pCluster3D : clusterList)
635 const unsigned int sliceIndex(clusterToSliceIndexMap.at(pCluster3D));
637 CaloHitList caloHitList;
638 pCluster3D->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
640 for (
const CaloHit *
const pCaloHit3D : caloHitList)
642 if (TPC_3D != pCaloHit3D->GetHitType())
643 throw StatusCodeException(STATUS_CODE_FAILURE);
645 const CartesianVector &position3D(pCaloHit3D->GetPositionVector());
647 const CartesianVector *
const pProjectionU(
649 const CartesianVector *
const pProjectionV(
651 const CartesianVector *
const pProjectionW(
654 pointsU.push_back(pProjectionU);
655 pointsV.push_back(pProjectionV);
656 pointsW.push_back(pProjectionW);
658 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pProjectionU, sliceIndex));
659 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pProjectionV, sliceIndex));
660 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pProjectionW, sliceIndex));
674 clusterPointList.push_back(
new CartesianVector(pCluster2D->GetCentroid(pCluster2D->GetInnerPseudoLayer())));
675 clusterPointList.push_back(
new CartesianVector(pCluster2D->GetCentroid(pCluster2D->GetOuterPseudoLayer())));
676 clusterPointList.push_back(
new CartesianVector(
677 (pCluster2D->GetCentroid(pCluster2D->GetInnerPseudoLayer()) + pCluster2D->GetCentroid(pCluster2D->GetOuterPseudoLayer())) * 0.5f));
681 for (
const CartesianVector *
const pClusterPoint : clusterPointList)
685 const PointKDNode2D targetPoint(pClusterPoint, pClusterPoint->GetX(), pClusterPoint->GetZ());
688 if (pResultPoint && (resultDistance < bestDistance))
690 pBestResultPoint = pResultPoint;
691 bestDistance = resultDistance;
697 std::cout <<
"EventSlicingTool::MatchClusterToSlice - exception " <<
std::endl;
698 for (
const CartesianVector *
const pPoint : clusterPointList)
703 for (
const CartesianVector *
const pPoint : clusterPointList)
706 return pBestResultPoint;
713 const CartesianVector deltaPosition(*pRhs - *pLhs);
715 if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
716 return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
718 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
719 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
721 return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
728 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"TrackPfoListName",
m_trackPfoListName));
730 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerPfoListName",
m_showerPfoListName));
732 PANDORA_RETURN_RESULT_IF_AND_IF(
733 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinHitsPer3DCluster",
m_minHitsPer3DCluster));
735 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
738 PANDORA_RETURN_RESULT_IF_AND_IF(
739 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitHalfWindow",
m_halfWindowLayers));
741 PANDORA_RETURN_RESULT_IF_AND_IF(
742 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"UsePointingAssociation",
m_usePointingAssociation));
744 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
747 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
750 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
753 PANDORA_RETURN_RESULT_IF_AND_IF(
754 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VertexAngularAllowance",
m_vertexAngularAllowance));
756 PANDORA_RETURN_RESULT_IF_AND_IF(
757 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxClosestApproach",
m_maxClosestApproach));
759 PANDORA_RETURN_RESULT_IF_AND_IF(
760 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxInterceptDistance",
m_maxInterceptDistance));
762 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
766 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxHitSeparation", maxHitSeparation));
769 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
772 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NConeFitLayers",
m_nConeFitLayers));
774 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NConeFits",
m_nConeFits));
776 PANDORA_RETURN_RESULT_IF_AND_IF(
777 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeLengthMultiplier",
m_coneLengthMultiplier));
779 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxConeLength",
m_maxConeLength));
781 PANDORA_RETURN_RESULT_IF_AND_IF(
782 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeTanHalfAngle1",
m_coneTanHalfAngle1));
784 PANDORA_RETURN_RESULT_IF_AND_IF(
785 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeBoundedFraction1",
m_coneBoundedFraction1));
787 PANDORA_RETURN_RESULT_IF_AND_IF(
788 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeTanHalfAngle2",
m_coneTanHalfAngle2));
790 PANDORA_RETURN_RESULT_IF_AND_IF(
791 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeBoundedFraction2",
m_coneBoundedFraction2));
793 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
796 return STATUS_CODE_SUCCESS;
void GetThreeDClusters(const pandora::Algorithm *const pAlgorithm, const std::string &pfoListName, pandora::ClusterList &clusters3D, ClusterToPfoMap &clusterToPfoMap) const
Get the 3D clusters from a specified list of pfos, storing the 3D clusters in the provided list and p...
unsigned int m_nConeFits
The number of cone fits to perform, spread roughly uniformly along the shower length.
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.
void GetClusterSliceList(const pandora::ClusterList &trackClusters3D, const pandora::ClusterList &showerClusters3D, ClusterSliceList &clusterSliceList) const
Divide the provided lists of 3D track and shower clusters into slices.
unsigned int m_min3DHitsToSeedNewSlice
The minimum number of hits in a 3D cluster to seed a new slice.
void CopyPfoHitsToSlices(const ClusterToSliceIndexMap &clusterToSliceIndexMap, const ClusterToPfoMap &clusterToPfoMap, SlicingAlgorithm::SliceList &sliceList, pandora::ClusterSet &assignedClusters) const
Use 3D clusters in the cluster slice list, find their parent pfos and assign all hits in all 2D clust...
Header file for the kd tree linker algo template class.
Header file for the pfo helper class.
float m_maxHitSeparationSquared
Proximity association: max distance allowed between the closest pair of hits.
unsigned int m_nConeFitLayers
The number of layers over which to sum fitted direction to obtain cone fit.
float m_coneTanHalfAngle2
The cone tan half angle to use when calculating bounded cluster fractions 2.
SlicingAlgorithm::Slice Slice
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::Cluster *, const pandora::ParticleFlowObject * > ClusterToPfoMap
float m_maxVertexTransverseDistance
Pointing association check: max transverse distance cut.
static bool IsEmission(const pandora::CartesianVector &parentVertex, const LArPointingCluster::Vertex &daughterVertex, const float minLongitudinalDistance, const float maxLongitudinalDistance, const float maxTransverseDistance, const float angularAllowance)
Whether pointing vertex is emitted from a given position.
void AssignRemainingHitsToSlices(const pandora::ClusterList &remainingClusters, const ClusterToSliceIndexMap &clusterToSliceIndexMap, SlicingAlgorithm::SliceList &sliceList) const
Use the list of remaining 2D clusters to assign all remaining 2D hits to existing slices in the slice...
float m_coneBoundedFraction2
The minimum cluster bounded fraction for association 2.
std::string m_showerPfoListName
The name of the input shower pfo list.
static void GetIntersection(const LArPointingCluster::Vertex &firstVertex, const LArPointingCluster::Vertex &secondVertex, pandora::CartesianVector &intersectPosition, float &firstDisplacement, float &secondDisplacement)
Get intersection of two vertices.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
Class that implements the KDTree partition of 2D space and a closest point search algorithm...
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
void GetRemainingClusters(const pandora::Algorithm *const pAlgorithm, const SlicingAlgorithm::HitTypeToNameMap &clusterListNames, const pandora::ClusterSet &assignedClusters, pandora::ClusterList &remainingClusters) const
Get the list of 2D clusters with hits yets to be assigned to slices.
std::vector< SimpleCone > SimpleConeList
SlicingAlgorithm::SliceList SliceList
bool PassShowerCone(const pandora::Cluster *const pConeCluster, const pandora::Cluster *const pNearbyCluster, const ThreeDSlidingConeFitResultMap &showerConeFitResults) const
Compare the provided clusters to assess whether they are associated via cone fits to the shower clust...
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
bool PassPointing(const pandora::Cluster *const pClusterInSlice, const pandora::Cluster *const pCandidateCluster, const ThreeDSlidingFitResultMap &trackFitResults) const
Compare the provided clusters to assess whether they are associated via pointing (checks association ...
const ThreeDSlidingFitResult & GetSlidingFitResult() const
Get the sliding fit result for the full cluster.
unsigned int m_minHitsPer3DCluster
The minimum number of hits in a 3D cluster to warrant consideration in slicing.
LArPointingCluster class.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
float m_coneTanHalfAngle1
The cone tan half angle to use when calculating bounded cluster fractions 1.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void CollectAssociatedClusters(const pandora::Cluster *const pClusterInSlice, const pandora::ClusterVector &candidateClusters, const ThreeDSlidingFitResultMap &trackFitResults, const ThreeDSlidingConeFitResultMap &showerConeFitResults, pandora::ClusterVector &clusterSlice, pandora::ClusterSet &usedClusters) const
Collect all clusters associated with a provided cluster.
const PointKDNode2D * MatchClusterToSlice(const pandora::Cluster *const pCluster2D, PointKDTree2D &kdTree) const
Use the provided kd tree to efficiently identify the most appropriate slice for the provided 2D clust...
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.
float m_maxVertexLongitudinalDistance
Pointing association check: max longitudinal distance cut.
void findNearestNeighbour(const KDTreeNodeInfoT< DATA, DIM > &point, const KDTreeNodeInfoT< DATA, DIM > *&result, float &distance)
findNearestNeighbour
Data stored in each KDTree node. The dim1/dim2 fields are usually the duplication of some PFRecHit va...
std::unordered_map< const pandora::CartesianVector *, unsigned int > PointToSliceIndexMap
std::string m_trackPfoListName
The name of the input track pfo list.
Header file for the geometry helper class.
bool m_useProximityAssociation
Whether to use proximity association.
float m_maxClosestApproach
Pointing association: max distance of closest approach between straight line fits.
std::unordered_map< const pandora::Cluster *, ThreeDSlidingFitResult > ThreeDSlidingFitResultMap
bool IsNode(const LArPointingCluster &cluster1, const LArPointingCluster &cluster2) const
Check whether a pair of pointing clusters are nodally associated.
static bool SortPoints(const pandora::CartesianVector *const pLhs, const pandora::CartesianVector *const pRhs)
Sort points (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
bool m_usePointingAssociation
Whether to use pointing association.
float m_coneLengthMultiplier
The cone length multiplier to use when calculating bounded cluster fractions.
const Vertex & GetOuterVertex() const
Get the outer vertex.
void build(std::vector< KDTreeNodeInfoT< DATA, DIM >> &eltList, const KDTreeBoxT< DIM > ®ion)
Build the KD tree from the "eltList" in the space define by "region".
const Vertex & GetInnerVertex() const
Get the inner vertex.
bool PassProximity(const pandora::Cluster *const pClusterInSlice, const pandora::Cluster *const pCandidateCluster) const
Compare the provided clusters to assess whether they are associated via pointing. ...
static int max(int a, int b)
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
pandora::CaloHitList m_caloHitListU
The u calo hit list.
std::vector< pandora::ClusterVector > ClusterSliceList
Header file for the lar three dimensional sliding fit result class.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
void CopyAllHitsToSingleSlice(const pandora::Algorithm *const pAlgorithm, const SlicingAlgorithm::HitTypeToNameMap &caloHitListNames, SlicingAlgorithm::SliceList &sliceList) const
Copy all the input hits in an event into a single slice.
std::unordered_map< const pandora::Cluster *, ThreeDSlidingConeFitResult > ThreeDSlidingConeFitResultMap
std::list< const pandora::CartesianVector * > PointList
SlicingAlgorithm::HitTypeToNameMap HitTypeToNameMap
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
bool CheckClosestApproach(const LArPointingCluster &cluster1, const LArPointingCluster &cluster2) const
Check closest approach metrics for a pair of pointing clusters.
std::vector< PointKDNode2D > PointKDNode2DList
std::unordered_map< const pandora::Cluster *, unsigned int > ClusterToSliceIndexMap
ThreeDSlidingFitResult class.
pandora::CaloHitList m_caloHitListW
The w calo hit list.
float m_maxInterceptDistance
Pointing association: max distance from cluster vertex to point of closest approach.
void RunSlicing(const pandora::Algorithm *const pAlgorithm, const SlicingAlgorithm::HitTypeToNameMap &caloHitListNames, const SlicingAlgorithm::HitTypeToNameMap &clusterListNames, SlicingAlgorithm::SliceList &sliceList)
Run the slicing tool.
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 >> &nodes)
fill_and_bound_2d_kd_tree
float m_minVertexLongitudinalDistance
Pointing association check: min longitudinal distance cut.
bool IsEmission(const LArPointingCluster &cluster1, const LArPointingCluster &cluster2) const
Check whether a pair of pointing clusters are consistent with an emission.
bool m_use3DProjectionsInHitPickUp
Whether to include 3D cluster projections when assigning remaining clusters to slices.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
ThreeDSlidingConeFitResult class.
float m_maxConeLength
The maximum allowed cone length to use when calculating bounded cluster fractions.
bool m_useShowerConeAssociation
Whether to use shower cone association.
float m_vertexAngularAllowance
Pointing association check: pointing angular allowance in degrees.
pandora::CaloHitList m_caloHitListV
The v calo hit list.
void GetKDTreeEntries2D(const SlicingAlgorithm::SliceList &sliceList, PointList &pointsU, PointList &pointsV, PointList &pointsW, PointToSliceIndexMap &pointToSliceIndexMap) const
Use projections of 3D hits already assigned to slices to populate kd trees to aid assignment of remai...
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
void GetKDTreeEntries3D(const ClusterToSliceIndexMap &clusterToSliceIndexMap, PointList &pointsU, PointList &pointsV, PointList &pointsW, PointToSliceIndexMap &pointToSliceIndexMap) const
Use 2D hits already assigned to slices to populate kd trees to aid assignment of remaining clusters...
void CreateSlices(const ClusterSliceList &clusterSliceList, SlicingAlgorithm::SliceList &sliceList, ClusterToSliceIndexMap &clusterToSliceIndexMap) const
Create new slices for each of the groupings of 3D clusters in the provided cluster slice list...
float m_coneBoundedFraction1
The minimum cluster bounded fraction for association 1.
QTextStream & endl(QTextStream &s)
static bool IsNode(const pandora::CartesianVector &parentVertex, const LArPointingCluster::Vertex &daughterVertex, const float minLongitudinalDistance, const float maxTransverseDistance)
Whether pointing vertex is adjacent to a given position.
unsigned int m_halfWindowLayers
The number of layers to use for half-window of sliding fit.