9 #include "Pandora/AlgorithmHeaders.h" 24 DeltaRayMatchingAlgorithm::DeltaRayMatchingAlgorithm() :
25 m_minCaloHitsPerCluster(3),
26 m_xOverlapWindow(1.
f),
27 m_distanceForMatching(5.
f),
40 if (pfoVector.empty())
42 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
43 std::cout <<
"DeltaRayMatchingAlgorithm: pfo list " <<
m_parentPfoListName <<
" unavailable." << std::endl;
45 return STATUS_CODE_SUCCESS;
57 return STATUS_CODE_SUCCESS;
74 const ClusterList *pClusterList = NULL;
75 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, clusterListName, pClusterList))
77 if ((NULL == pClusterList) || pClusterList->empty())
81 CaloHitList allCaloHits;
83 for (
const Cluster *
const pCluster : *pClusterList)
85 CaloHitList daughterHits;
86 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
87 allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
89 for (
const CaloHit *
const pCaloHit : daughterHits)
90 (void)hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
97 kdTree.
build(hitKDNode2DList, hitsBoundingRegion2D);
99 for (
const Cluster *
const pCluster : *pClusterList)
101 CaloHitList daughterHits;
102 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
104 for (
const CaloHit *
const pCaloHit : daughterHits)
109 kdTree.
search(searchRegionHits, found);
111 for (
const auto &
hit : found)
113 ClusterList &nearbyClusterList(nearbyClusters[pCluster]);
114 const Cluster *
const pNearbyCluster(hitToClusterMap.at(
hit.data));
116 if (nearbyClusterList.end() == std::find(nearbyClusterList.begin(), nearbyClusterList.end(), pNearbyCluster))
117 nearbyClusterList.push_back(pNearbyCluster);
136 const PfoList *pPfoList = NULL;
137 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, inputPfoListName, pPfoList));
139 if (NULL == pPfoList)
143 pfoVector.push_back(*iter);
152 PfoVector inputVector;
153 this->
GetAllPfos(inputPfoListName, inputVector);
157 const ParticleFlowObject *
const pPfo = *iter;
162 pfoVector.push_back(pPfo);
172 const ClusterList *pClusterList = NULL;
173 PANDORA_THROW_RESULT_IF_AND_IF(
174 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, inputClusterListName, pClusterList))
176 if (NULL == pClusterList)
181 const Cluster *
const pCluster = *cIter;
186 clusterVector.push_back(pCluster);
203 this->
ThreeViewMatching(clustersU, clustersV, clustersW, clusterLengthMap, pfoLengthMap, initialParticleList);
204 this->
SelectParticles(initialParticleList, clusterLengthMap, finalParticleList);
219 this->
TwoViewMatching(clustersU, clustersV, clusterLengthMap, pfoLengthMap, initialParticleList);
220 this->
TwoViewMatching(clustersV, clustersW, clusterLengthMap, pfoLengthMap, initialParticleList);
221 this->
TwoViewMatching(clustersW, clustersU, clusterLengthMap, pfoLengthMap, initialParticleList);
222 this->
SelectParticles(initialParticleList, clusterLengthMap, finalParticleList);
237 this->
ThreeViewMatching(clustersU, clustersV, clustersW, clusterLengthMap, pfoLengthMap, initialParticleList);
238 this->
OneViewMatching(clustersU, clusterLengthMap, pfoLengthMap, initialParticleList);
239 this->
OneViewMatching(clustersV, clusterLengthMap, pfoLengthMap, initialParticleList);
240 this->
OneViewMatching(clustersW, clusterLengthMap, pfoLengthMap, initialParticleList);
241 this->
SelectParticles(initialParticleList, clusterLengthMap, finalParticleList);
250 if (clusters1.empty() || clusters2.empty() || clusters3.empty())
253 for (
const Cluster *
const pCluster1 : clusters1)
255 if (!pCluster1->IsAvailable())
258 for (
const Cluster *
const pCluster2 : clusters2)
260 if (!pCluster2->IsAvailable())
263 for (
const Cluster *
const pCluster3 : clusters3)
265 if (!pCluster3->IsAvailable())
271 const ParticleFlowObject *pBestPfo = NULL;
272 this->
FindBestParentPfo(pCluster1, pCluster2, pCluster3, clusterLengthMap, pfoLengthMap, pBestPfo);
275 particleList.push_back(
Particle(pCluster1, pCluster2, pCluster3, pBestPfo));
286 if (clusters1.empty() || clusters2.empty())
289 for (
const Cluster *
const pCluster1 : clusters1)
291 if (!pCluster1->IsAvailable())
294 for (
const Cluster *
const pCluster2 : clusters2)
296 if (!pCluster2->IsAvailable())
302 const ParticleFlowObject *pBestPfo = NULL;
303 this->
FindBestParentPfo(pCluster1, pCluster2, NULL, clusterLengthMap, pfoLengthMap, pBestPfo);
305 if (NULL == pBestPfo)
308 particleList.push_back(
Particle(pCluster1, pCluster2, NULL, pBestPfo));
318 if (clusters.empty())
321 for (
const Cluster *
const pCluster : clusters)
323 if (!pCluster->IsAvailable())
326 const ParticleFlowObject *pBestPfo = NULL;
327 this->
FindBestParentPfo(pCluster, NULL, NULL, clusterLengthMap, pfoLengthMap, pBestPfo);
329 if (NULL == pBestPfo)
332 particleList.push_back(
Particle(pCluster, NULL, NULL, pBestPfo));
340 for (
const Particle &particle1 : initialParticles)
342 bool isGoodParticle(
true);
344 for (
const Particle &particle2 : initialParticles)
346 const bool commonU(particle1.GetClusterU() == particle2.GetClusterU());
347 const bool commonV(particle1.GetClusterV() == particle2.GetClusterV());
348 const bool commonW(particle1.GetClusterW() == particle2.GetClusterW());
350 const bool ambiguousU(commonU && NULL != particle1.GetClusterU());
351 const bool ambiguousV(commonV && NULL != particle1.GetClusterV());
352 const bool ambiguousW(commonW && NULL != particle1.GetClusterW());
354 if (commonU && commonV && commonW)
357 if (ambiguousU || ambiguousV || ambiguousW)
359 if (particle2.GetNViews() > particle1.GetNViews())
361 isGoodParticle =
false;
363 else if (particle2.GetNViews() == particle1.GetNViews() && NULL != particle2.GetParentPfo())
365 if ((NULL == particle1.GetParentPfo()) || (particle2.GetNCaloHits() > particle1.GetNCaloHits()) ||
366 (particle2.GetNCaloHits() == particle1.GetNCaloHits() &&
367 this->
GetLength(particle2, clusterLengthMap) >= this->
GetLength(particle1, clusterLengthMap)))
369 isGoodParticle =
false;
378 if (isGoodParticle && NULL != particle1.GetParentPfo())
379 finalParticles.push_back(particle1);
387 PfoVector parentVector, daughterVector;
391 PfoList parentList(parentVector.begin(), parentVector.end());
392 PfoList daughterList(daughterVector.begin(), daughterVector.end());
394 for (
const Particle &particle : particleList)
396 const ParticleFlowObject *
const pParentPfo = particle.GetParentPfo();
398 if (NULL == pParentPfo)
401 const Cluster *
const pClusterU = particle.GetClusterU();
402 const Cluster *
const pClusterV = particle.GetClusterV();
403 const Cluster *
const pClusterW = particle.GetClusterW();
405 if (NULL == pClusterU && NULL == pClusterV && NULL == pClusterW)
406 throw StatusCodeException(STATUS_CODE_FAILURE);
408 ClusterList clusterList;
411 clusterList.push_back(pClusterU);
414 clusterList.push_back(pClusterV);
417 clusterList.push_back(pClusterW);
419 if (parentList.end() != std::find(parentList.begin(), parentList.end(), pParentPfo))
423 else if (daughterList.end() != std::find(daughterList.begin(), daughterList.end(), pParentPfo))
429 throw StatusCodeException(STATUS_CODE_FAILURE);
438 if (
nullptr == pCluster1 &&
nullptr == pCluster2 &&
nullptr == pCluster3)
439 throw StatusCodeException(STATUS_CODE_FAILURE);
442 float xMin1(-std::numeric_limits<float>::max()), xMax1(+std::numeric_limits<float>::max());
443 float xMin2(-std::numeric_limits<float>::max()), xMax2(+std::numeric_limits<float>::max());
444 float xMin3(-std::numeric_limits<float>::max()), xMax3(+std::numeric_limits<float>::max());
446 if (
nullptr != pCluster1)
447 pCluster1->GetClusterSpanX(xMin1, xMax1);
449 if (
nullptr != pCluster2)
450 pCluster2->GetClusterSpanX(xMin2, xMax2);
452 if (
nullptr != pCluster3)
453 pCluster3->GetClusterSpanX(xMin3, xMax3);
456 const float xMin(std::max(xMin1, std::max(xMin2, xMin3)) - xPitch);
457 const float xMax(std::min(xMax1, std::min(xMax2, xMax3)) + xPitch);
458 const float xOverlap(xMax - xMin);
460 if (xOverlap < std::numeric_limits<float>::epsilon())
463 if (
nullptr == pCluster1 ||
nullptr == pCluster2 ||
nullptr == pCluster3)
473 const float pitchMax{std::max({pitch1, pitch2, pitch3})};
475 if (hitType1 == hitType2 || hitType2 == hitType3 || hitType3 == hitType1)
476 throw StatusCodeException(STATUS_CODE_FAILURE);
478 const unsigned int nSamplingPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
480 for (
unsigned int n = 0;
n < nSamplingPoints; ++
n)
482 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nSamplingPoints));
483 const float xmin(x - xPitch);
484 const float xmax(x + xPitch);
488 float zMin1(0.
f), zMin2(0.
f), zMin3(0.
f), zMax1(0.
f), zMax2(0.
f), zMax3(0.
f);
489 pCluster1->GetClusterSpanZ(xmin, xmax, zMin1, zMax1);
490 pCluster2->GetClusterSpanZ(xmin, xmax, zMin2, zMax2);
491 pCluster3->GetClusterSpanZ(xmin, xmax, zMin3, zMax3);
493 const float z1(0.5
f * (zMin1 + zMax1));
494 const float z2(0.5
f * (zMin2 + zMax2));
495 const float z3(0.5
f * (zMin3 + zMax3));
497 const float dz1(zMax1 - zMin1);
498 const float dz2(zMax2 - zMin2);
499 const float dz3(zMax3 - zMin3);
500 const float dz4(pitchMax);
506 const float deltaSquared(((z1 - zproj1) * (z1 - zproj1) + (z2 - zproj2) * (z2 - zproj2) + (z3 - zproj3) * (z3 - zproj3)) / 3.
f);
507 const float sigmaSquared(dz1 * dz1 + dz2 * dz2 + dz3 * dz3 + dz4 * dz4);
508 const float pseudoChi2(deltaSquared / sigmaSquared);
513 catch (StatusCodeException &statusCodeException)
515 if (STATUS_CODE_NOT_FOUND != statusCodeException.GetStatusCode())
516 throw statusCodeException;
526 const Cluster *
const pCluster3,
ClusterLengthMap &clusterLengthMap,
PfoLengthMap &pfoLengthMap,
const ParticleFlowObject *&pBestPfo)
const 532 if (pfoVector.empty())
533 throw StatusCodeException(STATUS_CODE_FAILURE);
535 unsigned int numViews(0);
536 float lengthSquared(0.
f);
558 for (
const ParticleFlowObject *
const pPfo : pfoVector)
565 float distanceSquared(0.
f);
567 if (NULL != pCluster1)
570 if (NULL != pCluster2)
573 if (NULL != pCluster3)
576 if (distanceSquared < bestDistanceSquared)
579 bestDistanceSquared = distanceSquared;
582 catch (StatusCodeException &statusCodeException)
584 if (!(STATUS_CODE_NOT_FOUND == statusCodeException.GetStatusCode()))
585 throw statusCodeException;
596 if (clusterLengthMap.end() != iter)
600 (void)clusterLengthMap.insert(ClusterLengthMap::value_type(pCluster, lengthSquared));
601 return lengthSquared;
610 if (pfoLengthMap.end() != iter)
614 (void)pfoLengthMap.insert(PfoLengthMap::value_type(pPfo, lengthSquared));
615 return lengthSquared;
622 float lengthSquared(0.
f);
633 return lengthSquared;
642 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
643 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
645 ClusterList comparisonList;
650 if (!nearbyClusters.count(pCluster))
651 return std::numeric_limits<float>::max();
653 ClusterList pfoClusterList;
656 for (
const Cluster *
const pPfoCluster : pfoClusterList)
658 const ClusterList &clusterList(nearbyClusters.at(pCluster));
660 if ((clusterList.end() != std::find(clusterList.begin(), clusterList.end(), pPfoCluster)) &&
661 (comparisonList.end() == std::find(comparisonList.begin(), comparisonList.end(), pPfoCluster)))
663 comparisonList.push_back(pPfoCluster);
667 if (comparisonList.empty())
668 return std::numeric_limits<float>::max();
677 const PfoList *pPfoList = NULL;
678 std::string pfoListName;
679 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
682 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
683 pfoParameters.m_particleId = E_MINUS;
684 pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
685 pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
686 pfoParameters.m_energy = 0.f;
687 pfoParameters.m_momentum = CartesianVector(0.
f, 0.
f, 0.
f);
688 pfoParameters.m_clusterList = clusterList;
690 const ParticleFlowObject *pDaughterPfo(NULL);
691 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pDaughterPfo));
693 if (!pPfoList->empty())
695 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this,
m_daughterPfoListName));
696 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*
this, pParentPfo, pDaughterPfo));
704 for (
const Cluster *
const pDaughterCluster : clusterList)
711 ClusterList pfoClusters;
714 if (pfoClusters.empty())
715 throw StatusCodeException(STATUS_CODE_FAILURE);
717 const Cluster *
const pParentCluster = *(pfoClusters.begin());
719 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
720 PandoraContentApi::MergeAndDeleteClusters(*
this, pParentCluster, pDaughterCluster, clusterListName, clusterListName));
728 const Cluster *
const pCluster1,
const Cluster *
const pCluster2,
const Cluster *
const pCluster3,
const ParticleFlowObject *
const pPfo) :
738 m_pClusterU = ((TPC_VIEW_U == hitType1) ? pCluster1
739 : (TPC_VIEW_U == hitType2) ? pCluster2
740 : (TPC_VIEW_U == hitType3) ? pCluster3
742 m_pClusterV = ((TPC_VIEW_V == hitType1) ? pCluster1
743 : (TPC_VIEW_V == hitType2) ? pCluster2
744 : (TPC_VIEW_V == hitType3) ? pCluster3
746 m_pClusterW = ((TPC_VIEW_W == hitType1) ? pCluster1
747 : (TPC_VIEW_W == hitType2) ? pCluster2
748 : (TPC_VIEW_W == hitType3) ? pCluster3
753 throw StatusCodeException(STATUS_CODE_FAILURE);
760 unsigned int numViews(0);
778 unsigned int numCaloHits(0);
797 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ParentPfoListName",
m_parentPfoListName));
798 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"DaughterPfoListName",
m_daughterPfoListName));
799 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
800 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
801 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
803 PANDORA_RETURN_RESULT_IF_AND_IF(
804 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCaloHitsPerCluster",
m_minCaloHitsPerCluster));
806 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"OverlapWindow",
m_xOverlapWindow));
808 PANDORA_RETURN_RESULT_IF_AND_IF(
809 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DistanceForMatching",
m_distanceForMatching));
811 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PseudoChi2Cut",
m_pseudoChi2Cut));
813 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SearchRegion1D",
m_searchRegion1D));
815 return STATUS_CODE_SUCCESS;
void InitializeNearbyClusterMap(const std::string &clusterListName, ClusterToClustersMap &nearbyClusters)
Initialize a nearby cluster map with details relating to a specific cluster list. ...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_xOverlapWindow
The maximum allowed displacement in x position.
float m_pseudoChi2Cut
Pseudo chi2 cut for three view matching.
std::vector< HitKDNode2D > HitKDNode2DList
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.
Header file for the kd tree linker algo template class.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
Header file for the pfo helper class.
std::unordered_map< const pandora::Cluster *, float > ClusterLengthMap
const pandora::Cluster * GetClusterV() const
Get cluster in V view.
Particle(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::Cluster *const pCluster3, const pandora::ParticleFlowObject *const pPfo)
Constructor.
void GetTrackPfos(const std::string &inputPfoListName, pandora::PfoVector &pfoVector) const
Get a vector of track-like Pfos in the provided input Pfo lists.
ClusterToClustersMap m_nearbyClustersU
The nearby clusters map for the u view.
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
void TwoViewMatching(ClusterLengthMap &clusterLengthMap) const
Match clusters using pairs of views.
ClusterToClustersMap m_nearbyClustersV
The nearby clusters map for the v view.
void CreateParticles(const ParticleList &particleList) const
Build new particle flow objects.
ClusterToClustersMap m_nearbyClustersW
The nearby clusters map for the w view.
unsigned int GetNCaloHits() const
Get number of calo hits.
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
unsigned int m_minCaloHitsPerCluster
The min number of calo hits per candidate cluster.
std::string m_inputClusterListNameV
The input cluster list name for the v view.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
static float GetTwoDLengthSquared(const pandora::ParticleFlowObject *const pPfo)
Calculate length of Pfo using 2D clusters.
Header file for the geometry helper class.
const pandora::Cluster * m_pClusterU
Address of cluster in U view.
void GetAllPfos(const std::string &inputPfoListName, pandora::PfoVector &pfoVector) const
Get a vector of all Pfos in the provided input Pfo lists.
pandora::StatusCode Run()
std::string m_parentPfoListName
The parent pfo list name.
std::string m_inputClusterListNameW
The input cluster list name for the w view.
float m_searchRegion1D
Search region, applied to each dimension, for look-up from kd-trees.
void OneViewMatching(ClusterLengthMap &clusterLengthMap) const
Match clusters using single views.
Header file for the cluster helper class.
std::unordered_map< const pandora::ParticleFlowObject *, float > PfoLengthMap
void ThreeViewMatching(ClusterLengthMap &clusterLengthMap) const
Match clusters using all three views.
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".
void InitializeNearbyClusterMaps()
Initialize nearby cluster maps.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterToClustersMap
static float MergeTwoPositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const float position1, const float position2)
Merge two views (U,V) to give a third view (Z).
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
Header file for the delta ray matching algorithm class.
float GetDistanceSquaredToPfo(const pandora::Cluster *const pCluster, const pandora::ParticleFlowObject *const pPfo) const
Get displacementr between cluster and particle flow object.
bool AreClustersMatched(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::Cluster *const pCluster3) const
Look at consistency of a combination of clusters.
Detector simulation of raw signals on wires.
void FindBestParentPfo(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, ClusterLengthMap &clusterLengthMap, PfoLengthMap &pfoLengthMap, const pandora::ParticleFlowObject *&pBestPfo) const
Find best Pfo to associate a UVW triplet.
void AddToDaughterPfo(const pandora::ClusterList &clusterList, const pandora::ParticleFlowObject *const pParentPfo) const
Merge an input cluster list with an existing daughter Pfo.
std::string m_inputClusterListNameU
The input cluster list name for the u view.
float m_distanceForMatching
The maximum allowed distance between tracks and delta rays.
const pandora::Cluster * GetClusterW() const
Get cluster in W view.
void CreateDaughterPfo(const pandora::ClusterList &clusterList, const pandora::ParticleFlowObject *const pParentPfo) const
Create a new Pfo from an input cluster list and set up a parent/daughter relationship.
float GetLength(const Particle &particle, ClusterLengthMap &clusterLengthMap) const
Get the length (squared) of a candidate particle.
const pandora::ParticleFlowObject * m_pParentPfo
Address of parent Pfo.
void ClearNearbyClusterMaps()
Clear nearby cluster maps.
void SelectParticles(const ParticleList &inputParticles, ClusterLengthMap &clusterLengthMap, ParticleList &outputParticles) const
Resolve any ambiguities between candidate particles.
const pandora::Cluster * m_pClusterV
Address of cluster in V view.
void GetClusters(const std::string &clusterListName, pandora::ClusterVector &clusterVector) const
Get a vector containing all available input clusters in the provided cluster list, storing sliding linear fits in the algorithm cache.
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 GetLengthFromCache(const pandora::Cluster *const pCluster, ClusterLengthMap &clusterLengthMap) const
Reduce number of length (squared) calculations by caching results when they are first obtained...
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
const pandora::Cluster * m_pClusterW
Address of cluster in W view.
const pandora::Cluster * GetClusterU() const
Get cluster in U view.
std::vector< Particle > ParticleList
unsigned int GetNViews() const
Get number of views.
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM >> &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
std::string m_daughterPfoListName
The daughter pfo list name for new daughter particles.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.