9 #include "Pandora/AlgorithmHeaders.h" 30 EventSlicingTool::EventSlicingTool() :
31 m_minHitsPer3DCluster(20),
32 m_min3DHitsToSeedNewSlice(50),
33 m_halfWindowLayers(20),
34 m_usePointingAssociation(true),
35 m_minVertexLongitudinalDistance(-7.5
f),
36 m_maxVertexLongitudinalDistance(60.
f),
37 m_maxVertexTransverseDistance(10.5
f),
38 m_vertexAngularAllowance(9.
f),
39 m_maxClosestApproach(15.
f),
40 m_maxInterceptDistance(60.
f),
41 m_useProximityAssociation(true),
42 m_maxHitSeparationSquared(25.
f * 25.
f),
43 m_useShowerConeAssociation(true),
46 m_coneLengthMultiplier(7.
f),
47 m_maxConeLength(126.
f),
48 m_coneTanHalfAngle1(0.5
f),
49 m_coneBoundedFraction1(0.5
f),
50 m_coneTanHalfAngle2(0.75
f),
51 m_coneBoundedFraction2(0.75
f),
52 m_use3DProjectionsInHitPickUp(true),
53 m_unassoc2DClusterMaxDist(
std::numeric_limits<float>::max())
62 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
63 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
67 ClusterList trackClusters3D;
70 ClusterList showerClusters3D;
76 if (clusterSliceList.size() < 2)
83 this->
CreateSlices(clusterSliceList, sliceList, clusterToSliceIndexMap);
85 ClusterSet assignedClusters;
86 this->
CopyPfoHitsToSlices(clusterToSliceIndexMap, clusterToPfoMap, sliceList, assignedClusters);
88 ClusterList remainingClusters;
99 if (!sliceList.empty())
100 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
102 const CaloHitList *pCaloHitListU(
nullptr);
103 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
104 PandoraContentApi::GetList(*pAlgorithm, caloHitListNames.at(TPC_VIEW_U), pCaloHitListU));
106 const CaloHitList *pCaloHitListV(
nullptr);
107 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
108 PandoraContentApi::GetList(*pAlgorithm, caloHitListNames.at(TPC_VIEW_V), pCaloHitListV));
110 const CaloHitList *pCaloHitListW(
nullptr);
111 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=,
112 PandoraContentApi::GetList(*pAlgorithm, caloHitListNames.at(TPC_VIEW_W), pCaloHitListW));
114 if (pCaloHitListU || pCaloHitListV || pCaloHitListW)
116 sliceList.push_back(
Slice());
117 Slice &slice(sliceList.at(0));
122 slice.m_caloHitListV = *pCaloHitListV;
124 slice.m_caloHitListW = *pCaloHitListW;
131 const Algorithm *
const pAlgorithm,
const std::string &pfoListName, ClusterList &clusters3D,
ClusterToPfoMap &clusterToPfoMap)
const 133 const PfoList *pPfoList(
nullptr);
134 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*pAlgorithm, pfoListName, pPfoList));
136 if (!pPfoList || pPfoList->empty())
138 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
139 std::cout <<
"EventSlicingTool: unable to find pfo list " << pfoListName << std::endl;
144 for (
const ParticleFlowObject *
const pPfo : *pPfoList)
146 ClusterList pfoClusters3D;
149 for (
const Cluster *
const pCluster3D : pfoClusters3D)
154 if (!clusterToPfoMap.insert(ClusterToPfoMap::value_type(pCluster3D, pPfo)).second)
155 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
157 if (clusters3D.end() != std::find(clusters3D.begin(), clusters3D.end(), pCluster3D))
158 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
160 clusters3D.push_back(pCluster3D);
172 const float pitchMax{std::max({pitchU, pitchV, pitchW})};
173 const float layerPitch(pitchMax);
177 for (
const Cluster *
const pCluster3D : trackClusters3D)
181 trackFitResults.insert(
184 catch (StatusCodeException &)
186 std::cout <<
"EventSlicingTool: ThreeDSlidingFitResult failure for track cluster." << std::endl;
192 for (
const Cluster *
const pCluster3D : showerClusters3D)
196 showerConeFitResults.insert(
199 catch (StatusCodeException &)
201 std::cout <<
"EventSlicingTool: ThreeDSlidingConeFitResult failure for shower cluster." << std::endl;
205 ClusterVector sortedClusters3D(trackClusters3D.begin(), trackClusters3D.end());
206 sortedClusters3D.insert(sortedClusters3D.end(), showerClusters3D.begin(), showerClusters3D.end());
209 ClusterSet usedClusters;
211 for (
const Cluster *
const pCluster3D : sortedClusters3D)
213 if (usedClusters.count(pCluster3D))
220 usedClusters.insert(pCluster3D);
223 this->
CollectAssociatedClusters(pCluster3D, sortedClusters3D, trackFitResults, showerConeFitResults, clusterSlice, usedClusters);
235 for (
const Cluster *
const pCandidateCluster : candidateClusters)
237 if (usedClusters.count(pCandidateCluster) || (pClusterInSlice == pCandidateCluster))
243 (this->
PassShowerCone(pClusterInSlice, pCandidateCluster, showerConeFitResults) ||
244 this->
PassShowerCone(pCandidateCluster, pClusterInSlice, showerConeFitResults))))
246 addedClusters.push_back(pCandidateCluster);
247 (void)usedClusters.insert(pCandidateCluster);
251 clusterSlice.insert(clusterSlice.end(), addedClusters.begin(), addedClusters.end());
253 for (
const Cluster *
const pAddedCluster : addedClusters)
254 this->
CollectAssociatedClusters(pAddedCluster, candidateClusters, trackFitResults, showerConeFitResults, clusterSlice, usedClusters);
260 const Cluster *
const pClusterInSlice,
const Cluster *
const pCandidateCluster,
const ThreeDSlidingFitResultMap &trackFitResults)
const 265 if ((trackFitResults.end() == inSliceIter) || (trackFitResults.end() == candidateIter))
272 this->
IsEmission(inSlicePointingCluster, candidatePointingCluster) || this->
IsNode(inSlicePointingCluster, candidatePointingCluster))
284 for (
const auto &orderedList1 : pClusterInSlice->GetOrderedCaloHitList())
286 for (
const CaloHit *
const pCaloHit1 : *(orderedList1.second))
288 const CartesianVector &positionVector1(pCaloHit1->GetPositionVector());
290 for (
const auto &orderedList2 : pCandidateCluster->GetOrderedCaloHitList())
292 for (
const CaloHit *
const pCaloHit2 : *(orderedList2.second))
311 if (showerConeFitResults.end() == fitIter)
314 float clusterLength(0.
f);
322 clusterLength = (slidingFitResult3D.GetGlobalMaxLayerPosition() - slidingFitResult3D.GetGlobalMinLayerPosition()).GetMagnitude();
324 catch (
const StatusCodeException &)
329 for (
const SimpleCone &simpleCone : simpleConeList)
359 CartesianVector intersectionPoint(0.
f, 0.
f, 0.
f);
360 float displacement1(std::numeric_limits<float>::max()), displacement2(std::numeric_limits<float>::max());
366 catch (
const StatusCodeException &)
373 const float closestApproach((approach1 - approach2).GetMagnitude());
427 unsigned int index(0);
431 for (
const Cluster *
const pCluster3D : clusterList)
434 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
436 if (!clusterToSliceIndexMap.insert(ClusterToSliceIndexMap::value_type(pCluster3D, index)).second)
437 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
440 sliceList.push_back(
Slice());
448 SliceList &sliceList, ClusterSet &assignedClusters)
const 450 ClusterList clusterList;
451 for (
const auto &mapEntry : clusterToSliceIndexMap)
452 clusterList.push_back(mapEntry.first);
455 for (
const Cluster *
const pCluster3D : clusterList)
457 const unsigned int index(clusterToSliceIndexMap.at(pCluster3D));
459 const Pfo *
const pPfo(clusterToPfoMap.at(pCluster3D));
460 Slice &slice(sliceList.at(index));
462 ClusterList clusters2D;
465 for (
const Cluster *
const pCluster2D : clusters2D)
469 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
470 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
472 CaloHitList &targetList((TPC_VIEW_U == hitType) ? slice.m_caloHitListU
473 : (TPC_VIEW_V == hitType) ? slice.m_caloHitListV
474 : slice.m_caloHitListW);
476 pCluster2D->GetOrderedCaloHitList().FillCaloHitList(targetList);
477 targetList.insert(targetList.end(), pCluster2D->GetIsolatedCaloHitList().begin(), pCluster2D->GetIsolatedCaloHitList().end());
479 if (!assignedClusters.insert(pCluster2D).second)
480 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
488 const ClusterSet &assignedClusters, ClusterList &remainingClusters)
const 490 this->
GetRemainingClusters(pAlgorithm, clusterListNames.at(TPC_VIEW_U), assignedClusters, remainingClusters);
491 this->
GetRemainingClusters(pAlgorithm, clusterListNames.at(TPC_VIEW_V), assignedClusters, remainingClusters);
492 this->
GetRemainingClusters(pAlgorithm, clusterListNames.at(TPC_VIEW_W), assignedClusters, remainingClusters);
498 const ClusterSet &assignedClusters, ClusterList &remainingClusters)
const 500 const ClusterList *pClusterList(
nullptr);
501 PANDORA_THROW_RESULT_IF_AND_IF(
502 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*pAlgorithm, clusterListName, pClusterList));
504 if (!pClusterList || pClusterList->empty())
506 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
507 std::cout <<
"EventSlicingTool: unable to find cluster list " << clusterListName << std::endl;
512 for (
const Cluster *
const pCluster2D : *pClusterList)
516 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
517 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
519 if (assignedClusters.count(pCluster2D))
522 if (remainingClusters.end() != std::find(remainingClusters.begin(), remainingClusters.end(), pCluster2D))
523 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
525 remainingClusters.push_back(pCluster2D);
542 this->
GetKDTreeEntries3D(clusterToSliceIndexMap, pointsU, pointsV, pointsW, pointToSliceIndexMap);
554 kdTreeU.
build(kDNode2DListU, boundingRegionU);
555 kdTreeV.
build(kDNode2DListV, boundingRegionV);
556 kdTreeW.
build(kDNode2DListW, boundingRegionW);
558 ClusterVector sortedRemainingClusters(remainingClusters.begin(), remainingClusters.end());
561 for (
const Cluster *
const pCluster2D : sortedRemainingClusters)
565 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
566 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
568 PointKDTree2D &kdTree((TPC_VIEW_U == hitType) ? kdTreeU : (TPC_VIEW_V == hitType) ? kdTreeV : kdTreeW);
571 if (!pBestResultPoint)
574 Slice &slice(sliceList.at(pointToSliceIndexMap.at(pBestResultPoint->
data)));
575 CaloHitList &targetList((TPC_VIEW_U == hitType) ? slice.
m_caloHitListU 579 pCluster2D->GetOrderedCaloHitList().FillCaloHitList(targetList);
580 targetList.insert(targetList.end(), pCluster2D->GetIsolatedCaloHitList().begin(), pCluster2D->GetIsolatedCaloHitList().end());
585 std::cout <<
"EventSlicingTool::AssignRemainingHitsToSlices - exception " << std::endl;
586 for (
const auto &pointMap : pointToSliceIndexMap)
587 delete pointMap.first;
591 for (
const auto &pointMap : pointToSliceIndexMap)
592 delete pointMap.first;
600 unsigned int sliceIndex(0);
602 for (
const Slice &slice : sliceList)
604 for (
const CaloHit *
const pCaloHit : slice.m_caloHitListU)
606 const CartesianVector *
const pPoint(
new CartesianVector(pCaloHit->GetPositionVector()));
607 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pPoint, sliceIndex));
608 pointsU.push_back(pPoint);
611 for (
const CaloHit *
const pCaloHit : slice.m_caloHitListV)
613 const CartesianVector *
const pPoint(
new CartesianVector(pCaloHit->GetPositionVector()));
614 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pPoint, sliceIndex));
615 pointsV.push_back(pPoint);
618 for (
const CaloHit *
const pCaloHit : slice.m_caloHitListW)
620 const CartesianVector *
const pPoint(
new CartesianVector(pCaloHit->GetPositionVector()));
621 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pPoint, sliceIndex));
622 pointsW.push_back(pPoint);
634 ClusterList clusterList;
635 for (
const auto &mapEntry : clusterToSliceIndexMap)
636 clusterList.push_back(mapEntry.first);
639 for (
const Cluster *
const pCluster3D : clusterList)
641 const unsigned int sliceIndex(clusterToSliceIndexMap.at(pCluster3D));
643 CaloHitList caloHitList;
644 pCluster3D->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
646 for (
const CaloHit *
const pCaloHit3D : caloHitList)
648 if (TPC_3D != pCaloHit3D->GetHitType())
649 throw StatusCodeException(STATUS_CODE_FAILURE);
651 const CartesianVector &position3D(pCaloHit3D->GetPositionVector());
653 const CartesianVector *
const pProjectionU(
655 const CartesianVector *
const pProjectionV(
657 const CartesianVector *
const pProjectionW(
660 pointsU.push_back(pProjectionU);
661 pointsV.push_back(pProjectionV);
662 pointsW.push_back(pProjectionW);
664 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pProjectionU, sliceIndex));
665 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pProjectionV, sliceIndex));
666 pointToSliceIndexMap.insert(PointToSliceIndexMap::value_type(pProjectionW, sliceIndex));
680 clusterPointList.push_back(
new CartesianVector(pCluster2D->GetCentroid(pCluster2D->GetInnerPseudoLayer())));
681 clusterPointList.push_back(
new CartesianVector(pCluster2D->GetCentroid(pCluster2D->GetOuterPseudoLayer())));
682 clusterPointList.push_back(
new CartesianVector(
683 (pCluster2D->GetCentroid(pCluster2D->GetInnerPseudoLayer()) + pCluster2D->GetCentroid(pCluster2D->GetOuterPseudoLayer())) * 0.5f));
685 float bestDistance(std::numeric_limits<float>::max());
687 for (
const CartesianVector *
const pClusterPoint : clusterPointList)
690 float resultDistance(std::numeric_limits<float>::max());
691 const PointKDNode2D targetPoint(pClusterPoint, pClusterPoint->GetX(), pClusterPoint->GetZ());
696 pBestResultPoint = pResultPoint;
697 bestDistance = resultDistance;
703 std::cout <<
"EventSlicingTool::MatchClusterToSlice - exception " << std::endl;
704 for (
const CartesianVector *
const pPoint : clusterPointList)
709 for (
const CartesianVector *
const pPoint : clusterPointList)
712 return pBestResultPoint;
719 const CartesianVector deltaPosition(*pRhs - *pLhs);
721 if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
722 return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
724 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
725 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
727 return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
734 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"TrackPfoListName",
m_trackPfoListName));
736 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerPfoListName",
m_showerPfoListName));
738 PANDORA_RETURN_RESULT_IF_AND_IF(
739 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinHitsPer3DCluster",
m_minHitsPer3DCluster));
741 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
744 PANDORA_RETURN_RESULT_IF_AND_IF(
745 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitHalfWindow",
m_halfWindowLayers));
747 PANDORA_RETURN_RESULT_IF_AND_IF(
748 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"UsePointingAssociation",
m_usePointingAssociation));
750 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
753 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
756 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
759 PANDORA_RETURN_RESULT_IF_AND_IF(
760 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VertexAngularAllowance",
m_vertexAngularAllowance));
762 PANDORA_RETURN_RESULT_IF_AND_IF(
763 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxClosestApproach",
m_maxClosestApproach));
765 PANDORA_RETURN_RESULT_IF_AND_IF(
766 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxInterceptDistance",
m_maxInterceptDistance));
768 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,
"MaxHitSeparation", maxHitSeparation));
775 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
778 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NConeFitLayers",
m_nConeFitLayers));
780 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NConeFits",
m_nConeFits));
782 PANDORA_RETURN_RESULT_IF_AND_IF(
783 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeLengthMultiplier",
m_coneLengthMultiplier));
785 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxConeLength",
m_maxConeLength));
787 PANDORA_RETURN_RESULT_IF_AND_IF(
788 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeTanHalfAngle1",
m_coneTanHalfAngle1));
790 PANDORA_RETURN_RESULT_IF_AND_IF(
791 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeBoundedFraction1",
m_coneBoundedFraction1));
793 PANDORA_RETURN_RESULT_IF_AND_IF(
794 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeTanHalfAngle2",
m_coneTanHalfAngle2));
796 PANDORA_RETURN_RESULT_IF_AND_IF(
797 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConeBoundedFraction2",
m_coneBoundedFraction2));
799 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
802 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
805 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.
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.
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.
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...
void CopyPfoHitsToSlices(const ClusterToSliceIndexMap &clusterToSliceIndexMap, const ClusterToPfoMap &clusterToPfoMap, 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...
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
std::vector< SimpleCone > SimpleConeList
void CopyAllHitsToSingleSlice(const pandora::Algorithm *const pAlgorithm, const HitTypeToNameMap &caloHitListNames, SliceList &sliceList) const
Copy all the input hits in an event into a single slice.
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.
void GetSimpleConeList(const unsigned int nLayersForConeFit, const unsigned int nCones, const ConeSelection coneSelection, SimpleConeList &simpleConeList, const float tanHalfAngle=0.5f, const bool legacyMode=true) const
Get the list of simple cones fitted to the three dimensional cluster.
std::vector< Slice > SliceList
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.
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...
pandora::CaloHitList m_caloHitListW
The w calo hit list.
Header file for the lar three dimensional sliding cone fit result class.
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.
pandora::CaloHitList m_caloHitListU
The u calo hit 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.
pandora::CaloHitList m_caloHitListV
The v calo hit list.
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)
std::map< pandora::HitType, std::string > HitTypeToNameMap
Header file for the cluster helper class.
float m_unassoc2DClusterMaxDist
Maximum distance to attach unassociated 2D Clusters to 3D slices.
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 float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void GetKDTreeEntries2D(const 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...
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
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.
std::unordered_map< const pandora::Cluster *, ThreeDSlidingConeFitResult > ThreeDSlidingConeFitResultMap
std::list< const pandora::CartesianVector * > PointList
void RunSlicing(const pandora::Algorithm *const pAlgorithm, const HitTypeToNameMap &caloHitListNames, const HitTypeToNameMap &clusterListNames, SliceList &sliceList)
Run the slicing tool.
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.
float m_maxInterceptDistance
Pointing association: max distance from cluster vertex to point of closest approach.
void GetRemainingClusters(const pandora::Algorithm *const pAlgorithm, const HitTypeToNameMap &clusterListNames, const pandora::ClusterSet &assignedClusters, pandora::ClusterList &remainingClusters) const
Get the list of 2D clusters with hits yets to be assigned to slices.
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.
void CreateSlices(const ClusterSliceList &clusterSliceList, SliceList &sliceList, ClusterToSliceIndexMap &clusterToSliceIndexMap) const
Create new slices for each of the groupings of 3D clusters in the provided cluster slice list...
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...
float m_coneBoundedFraction1
The minimum cluster bounded fraction for association 1.
void AssignRemainingHitsToSlices(const pandora::ClusterList &remainingClusters, const ClusterToSliceIndexMap &clusterToSliceIndexMap, SliceList &sliceList) const
Use the list of remaining 2D clusters to assign all remaining 2D hits to existing slices in the slice...
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.