9 #include "Pandora/AlgorithmHeaders.h" 22 CosmicRayTrackRecoveryAlgorithm::CosmicRayTrackRecoveryAlgorithm() :
23 m_clusterMinLength(10.
f),
24 m_clusterMinSpanZ(2.
f),
25 m_clusterMinOverlapX(6.
f),
26 m_clusterMaxDeltaX(3.
f),
36 ClusterVector availableClustersU, availableClustersV, availableClustersW;
55 this->
MatchViews(cleanClustersU, cleanClustersV, slidingFitResultMap, matchedClustersUV);
56 this->
MatchViews(cleanClustersV, cleanClustersW, slidingFitResultMap, matchedClustersVW);
57 this->
MatchViews(cleanClustersW, cleanClustersU, slidingFitResultMap, matchedClustersWU);
62 this->
MatchThreeViews(cleanClustersU, cleanClustersV, cleanClustersW, matchedClustersUV, matchedClustersVW, matchedClustersWU, candidateParticles);
64 this->
MatchTwoViews(cleanClustersU, cleanClustersV, cleanClustersW, matchedClustersUV, matchedClustersVW, matchedClustersWU, candidateParticles);
66 this->
MatchOneView(cleanClustersU, cleanClustersV, cleanClustersW, matchedClustersUV, matchedClustersVW, matchedClustersWU, candidateParticles);
71 return STATUS_CODE_SUCCESS;
78 const ClusterList *pClusterList = NULL;
79 PANDORA_RETURN_RESULT_IF_AND_IF(
80 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, inputClusterListName, pClusterList))
82 if (!pClusterList || pClusterList->empty())
84 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
85 std::cout <<
"CosmicRayTrackRecoveryAlgorithm: unable to find cluster list " << inputClusterListName << std::endl;
87 return STATUS_CODE_SUCCESS;
90 for (
const Cluster *
const pCluster : *pClusterList)
92 if (PandoraContentApi::IsAvailable(*
this, pCluster))
93 clusterVector.push_back(pCluster);
98 return STATUS_CODE_SUCCESS;
107 const Cluster *
const pCluster = *iter;
117 CartesianVector minCoordinate(0.
f, 0.
f, 0.
f);
118 CartesianVector maxCoordinate(0.
f, 0.
f, 0.
f);
121 const CartesianVector deltaCoordinate(maxCoordinate - minCoordinate);
125 outputVector.push_back(pCluster);
133 const unsigned int m_halfWindowLayers(25);
137 if (slidingFitResultMap.end() == slidingFitResultMap.find(*iter))
144 if (!slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(*iter, slidingFitResult)).second)
145 throw StatusCodeException(STATUS_CODE_FAILURE);
147 catch (StatusCodeException &statusCodeException)
149 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
150 throw statusCodeException;
162 this->
MatchClusters(*iter1, clusterVector2, slidingFitResultMap, clusterAssociationMap);
165 this->
MatchClusters(*iter2, clusterVector1, slidingFitResultMap, clusterAssociationMap);
180 if (slidingFitResultMap.end() == fsIter)
181 throw StatusCodeException(STATUS_CODE_FAILURE);
186 const float xSpan1(std::fabs(outerVertex1.GetX() - innerVertex1.GetX()));
188 const Cluster *pBestClusterInner(NULL);
189 const Cluster *pBestClusterOuter(NULL);
190 const Cluster *pBestCluster(NULL);
198 const Cluster *
const pTargetCluster = *tIter;
200 UIntSet daughterVolumeIntersection;
203 if (daughterVolumeIntersection.empty())
207 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
211 if (slidingFitResultMap.end() == ftIter)
212 throw StatusCodeException(STATUS_CODE_FAILURE);
217 const float xSpan2(std::fabs(outerVertex2.GetX() - innerVertex2.GetX()));
219 if (xSpan2 > 1.5
f * xSpan1)
222 const float xMin1(std::min(innerVertex1.GetX(), outerVertex1.GetX()));
223 const float xMax1(std::max(innerVertex1.GetX(), outerVertex1.GetX()));
224 const float xMin2(std::min(innerVertex2.GetX(), outerVertex2.GetX()));
225 const float xMax2(std::max(innerVertex2.GetX(), outerVertex2.GetX()));
226 const float xOverlap(std::min(xMax1, xMax2) - std::max(xMin1, xMin2));
231 const float dxMin(std::fabs(xMin2 - xMin1));
232 const float dxMax(std::fabs(xMax2 - xMax1));
234 if (dxMin < bestDisplacementInner)
236 pBestClusterInner = pTargetCluster;
237 bestDisplacementInner = dxMin;
240 if (dxMax < bestDisplacementOuter)
242 pBestClusterOuter = pTargetCluster;
243 bestDisplacementOuter = dxMax;
246 if (dxMin + dxMax < bestDisplacement)
248 pBestCluster = pTargetCluster;
249 bestDisplacement = dxMin + dxMax;
255 ClusterList &seedList(clusterAssociationMap[pSeedCluster]);
257 if (seedList.end() == std::find(seedList.begin(), seedList.end(), pBestCluster))
258 seedList.push_back(pBestCluster);
260 ClusterList &bestList(clusterAssociationMap[pBestCluster]);
262 if (bestList.end() == std::find(bestList.begin(), bestList.end(), pSeedCluster))
263 bestList.push_back(pSeedCluster);
265 else if (pBestClusterInner && pBestClusterOuter)
270 if (slidingFitResultMap.end() == iterInner || slidingFitResultMap.end() == iterOuter)
271 throw StatusCodeException(STATUS_CODE_FAILURE);
282 catch (StatusCodeException &)
292 const float rSpan((pointingEndInner.GetPosition() - pointingEndOuter.GetPosition()).GetMagnitude());
297 ClusterList &bestInnerList(clusterAssociationMap[pBestClusterInner]);
299 if (bestInnerList.end() == std::find(bestInnerList.begin(), bestInnerList.end(), pSeedCluster))
300 bestInnerList.push_back(pSeedCluster);
302 ClusterList &bestOuterList(clusterAssociationMap[pBestClusterOuter]);
304 if (bestOuterList.end() == std::find(bestOuterList.begin(), bestOuterList.end(), pSeedCluster))
305 bestOuterList.push_back(pSeedCluster);
331 const Cluster *
const pCluster1 = *iter1;
333 if (vetoList.count(pCluster1))
337 const ClusterList matchedClusters31_pCluster1(iter311 != matchedClusters31.end() ? iter311->second : ClusterList());
340 const ClusterList matchedClusters12_pCluster1(iter121 != matchedClusters12.end() ? iter121->second : ClusterList());
344 const Cluster *
const pCluster2 = *iter2;
346 if (vetoList.count(pCluster2))
350 const ClusterList matchedClusters12_pCluster2(iter122 != matchedClusters12.end() ? iter122->second : ClusterList());
353 const ClusterList matchedClusters23_pCluster2(iter232 != matchedClusters23.end() ? iter232->second : ClusterList());
357 const Cluster *
const pCluster3 = *iter3;
359 if (vetoList.count(pCluster3))
363 const ClusterList matchedClusters23_pCluster3(iter233 != matchedClusters23.end() ? iter233->second : ClusterList());
366 const ClusterList matchedClusters31_pCluster3(iter313 != matchedClusters31.end() ? iter313->second : ClusterList());
368 const bool match12((matchedClusters12_pCluster1.size() + matchedClusters12_pCluster2.size() > 0) &&
369 ((matchedClusters12_pCluster1.size() == 1 &&
370 std::find(matchedClusters12_pCluster1.begin(), matchedClusters12_pCluster1.end(), pCluster2) !=
371 matchedClusters12_pCluster1.end()) ||
372 (matchedClusters12_pCluster1.size() == 0)) &&
373 ((matchedClusters12_pCluster2.size() == 1 &&
374 std::find(matchedClusters12_pCluster2.begin(), matchedClusters12_pCluster2.end(), pCluster1) !=
375 matchedClusters12_pCluster2.end()) ||
376 (matchedClusters12_pCluster2.size() == 0)));
378 const bool match23((matchedClusters23_pCluster2.size() + matchedClusters23_pCluster3.size() > 0) &&
379 ((matchedClusters23_pCluster2.size() == 1 &&
380 std::find(matchedClusters23_pCluster2.begin(), matchedClusters23_pCluster2.end(), pCluster3) !=
381 matchedClusters23_pCluster2.end()) ||
382 (matchedClusters23_pCluster2.size() == 0)) &&
383 ((matchedClusters23_pCluster3.size() == 1 &&
384 std::find(matchedClusters23_pCluster3.begin(), matchedClusters23_pCluster3.end(), pCluster2) !=
385 matchedClusters23_pCluster3.end()) ||
386 (matchedClusters23_pCluster3.size() == 0)));
388 const bool match31((matchedClusters31_pCluster3.size() + matchedClusters31_pCluster1.size() > 0) &&
389 ((matchedClusters31_pCluster3.size() == 1 &&
390 std::find(matchedClusters31_pCluster3.begin(), matchedClusters31_pCluster3.end(), pCluster1) !=
391 matchedClusters31_pCluster3.end()) ||
392 (matchedClusters31_pCluster3.size() == 0)) &&
393 ((matchedClusters31_pCluster1.size() == 1 &&
394 std::find(matchedClusters31_pCluster1.begin(), matchedClusters31_pCluster1.end(), pCluster3) !=
395 matchedClusters31_pCluster1.end()) ||
396 (matchedClusters31_pCluster1.size() == 0)));
398 if (match12 && match23 && match31)
404 newParticleList.push_back(newParticle);
424 for (
unsigned int iView = 0; iView < 3; ++iView)
426 const ClusterVector &clusterVector1((0 == iView) ? clusterVectorU : (1 == iView) ? clusterVectorV : clusterVectorW);
427 const ClusterVector &clusterVector2((0 == iView) ? clusterVectorV : (1 == iView) ? clusterVectorW : clusterVectorU);
428 const ClusterVector &clusterVector3((0 == iView) ? clusterVectorW : (1 == iView) ? clusterVectorU : clusterVectorV);
431 : (1 == iView) ? matchedClustersVW
432 : matchedClustersWU));
434 : (1 == iView) ? matchedClustersWU
435 : matchedClustersUV));
437 : (1 == iView) ? matchedClustersUV
438 : matchedClustersVW));
442 const Cluster *
const pCluster1 = *iter1;
444 if (vetoList.count(pCluster1))
448 const ClusterList matchedClusters31_pCluster1(iter311 != matchedClusters31.end() ? iter311->second : ClusterList());
451 const ClusterList matchedClusters12_pCluster1(iter121 != matchedClusters12.end() ? iter121->second : ClusterList());
455 const Cluster *
const pCluster2 = *iter2;
457 if (vetoList.count(pCluster2))
461 const ClusterList matchedClusters12_pCluster2(iter122 != matchedClusters12.end() ? iter122->second : ClusterList());
464 const ClusterList matchedClusters23_pCluster2(iter232 != matchedClusters23.end() ? iter232->second : ClusterList());
466 const bool match12((matchedClusters12_pCluster1.size() == 1 &&
467 std::find(matchedClusters12_pCluster1.begin(), matchedClusters12_pCluster1.end(), pCluster2) !=
468 matchedClusters12_pCluster1.end()) &&
469 (matchedClusters12_pCluster2.size() == 1 &&
470 std::find(matchedClusters12_pCluster2.begin(), matchedClusters12_pCluster2.end(), pCluster1) !=
471 matchedClusters12_pCluster2.end()) &&
472 (matchedClusters23_pCluster2.size() == 0 && matchedClusters31_pCluster1.size() == 0));
483 const Cluster *
const pCluster3 = *iter3;
485 if (vetoList.count(pCluster3))
489 const ClusterList matchedClusters23_pCluster3(iter233 != matchedClusters23.end() ? iter233->second : ClusterList());
492 const ClusterList matchedClusters31_pCluster3(iter313 != matchedClusters31.end() ? iter313->second : ClusterList());
494 const bool match3((matchedClusters31_pCluster3.size() + matchedClusters23_pCluster3.size() > 0) &&
495 ((matchedClusters31_pCluster3.size() == 1 &&
496 std::find(matchedClusters31_pCluster3.begin(), matchedClusters31_pCluster3.end(), pCluster1) !=
497 matchedClusters31_pCluster3.end()) ||
498 (matchedClusters31_pCluster3.size() == 0)) &&
499 ((matchedClusters23_pCluster3.size() == 1 &&
500 std::find(matchedClusters23_pCluster3.begin(), matchedClusters23_pCluster3.end(), pCluster2) !=
501 matchedClusters23_pCluster3.end()) ||
502 (matchedClusters23_pCluster3.size() == 0)));
508 newParticleList.push_back(newParticle);
527 for (
unsigned int iView = 0; iView < 3; ++iView)
529 const ClusterVector &clusterVector1((0 == iView) ? clusterVectorU : (1 == iView) ? clusterVectorV : clusterVectorW);
530 const ClusterVector &clusterVector2((0 == iView) ? clusterVectorV : (1 == iView) ? clusterVectorW : clusterVectorU);
531 const ClusterVector &clusterVector3((0 == iView) ? clusterVectorW : (1 == iView) ? clusterVectorU : clusterVectorV);
534 : (1 == iView) ? matchedClustersVW
535 : matchedClustersWU));
537 : (1 == iView) ? matchedClustersWU
538 : matchedClustersUV));
540 : (1 == iView) ? matchedClustersUV
541 : matchedClustersVW));
545 const Cluster *
const pCluster1 = *iter1;
547 if (vetoList.count(pCluster1))
551 const ClusterList matchedClusters31_pCluster1(iter311 != matchedClusters31.end() ? iter311->second : ClusterList());
554 const ClusterList matchedClusters12_pCluster1(iter121 != matchedClusters12.end() ? iter121->second : ClusterList());
556 if (matchedClusters12_pCluster1.size() + matchedClusters31_pCluster1.size() > 0)
564 const Cluster *
const pCluster2 = *iter2;
566 if (vetoList.count(pCluster2))
570 const ClusterList matchedClusters12_pCluster2(iter122 != matchedClusters12.end() ? iter122->second : ClusterList());
573 const ClusterList matchedClusters23_pCluster2(iter232 != matchedClusters23.end() ? iter232->second : ClusterList());
575 if (matchedClusters12_pCluster2.size() == 1 &&
576 std::find(matchedClusters12_pCluster2.begin(), matchedClusters12_pCluster2.end(), pCluster1) !=
577 matchedClusters12_pCluster2.end() &&
578 matchedClusters23_pCluster2.size() == 0)
584 const Cluster *
const pCluster3 = *iter3;
586 if (vetoList.count(pCluster3))
590 const ClusterList matchedClusters23_pCluster3(iter233 != matchedClusters23.end() ? iter233->second : ClusterList());
593 const ClusterList matchedClusters31_pCluster3(iter313 != matchedClusters31.end() ? iter313->second : ClusterList());
595 if (matchedClusters31_pCluster3.size() == 1 &&
596 std::find(matchedClusters31_pCluster3.begin(), matchedClusters31_pCluster3.end(), pCluster1) !=
597 matchedClusters31_pCluster3.end() &&
598 matchedClusters23_pCluster3.size() == 0)
603 newParticleList.push_back(newParticle);
625 for (
ParticleList::const_iterator pIter1 = inputParticleList.begin(), pIterEnd1 = inputParticleList.end(); pIter1 != pIterEnd1; ++pIter1)
627 const Particle &particle1 = *pIter1;
636 const Particle &particle2 = *pIter2;
639 ClusterSet duplicateSet;
643 const Cluster *pCluster = *cIter1;
645 if (clusterList2.end() != std::find(clusterList2.begin(), clusterList2.end(), pCluster))
646 duplicateSet.insert(pCluster);
649 if (duplicateSet.size() > 0 && clusterList1.size() != clusterList2.size())
657 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
659 outputParticleList.push_back(particle1);
661 catch (StatusCodeException &)
663 std::cout <<
" Warning in CosmicRayTrackRecoveryAlgorithm: found duplicate particles in candidate list " << std::endl;
672 if (particleList.empty())
675 const PfoList *pPfoList(
nullptr);
676 std::string pfoListName;
677 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
679 for (
const Particle &particle : particleList)
681 if (!PandoraContentApi::IsAvailable(*
this, &particle.m_clusterList))
684 ClusterList clusterList;
687 if (clusterList.empty())
688 throw StatusCodeException(STATUS_CODE_FAILURE);
690 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
691 pfoParameters.m_particleId = MU_MINUS;
692 pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
693 pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
694 pfoParameters.m_energy = 0.f;
695 pfoParameters.m_momentum = CartesianVector(0.
f, 0.
f, 0.
f);
696 pfoParameters.m_clusterList = clusterList;
698 const ParticleFlowObject *pPfo(
nullptr);
699 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
702 if (!pPfoList->empty())
703 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this,
m_outputPfoListName));
710 ClusterList clusterListU, clusterListV, clusterListW;
715 for (
unsigned int iView = 0; iView < 3; ++iView)
717 const ClusterList clusterList((0 == iView) ? clusterListU : (1 == iView) ? clusterListV : clusterListW);
722 if (clusterList.empty())
725 const Cluster *
const pSeedCluster(clusterList.front());
727 if (!PandoraContentApi::IsAvailable(*
this, pSeedCluster))
728 throw StatusCodeException(STATUS_CODE_FAILURE);
730 for (
const Cluster *
const pAssociatedCluster : clusterList)
732 if (pAssociatedCluster == pSeedCluster)
735 if (!PandoraContentApi::IsAvailable(*
this, pAssociatedCluster))
738 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
739 PandoraContentApi::MergeAndDeleteClusters(*
this, pSeedCluster, pAssociatedCluster, inputClusterListName, inputClusterListName));
742 outputClusterList.push_back(pSeedCluster);
750 PANDORA_RETURN_RESULT_IF_AND_IF(
751 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinLength",
m_clusterMinLength));
753 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinSpanZ",
m_clusterMinSpanZ));
755 PANDORA_RETURN_RESULT_IF_AND_IF(
756 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinOverlapX",
m_clusterMinOverlapX));
758 PANDORA_RETURN_RESULT_IF_AND_IF(
759 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMaxDeltaX",
m_clusterMaxDeltaX));
761 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinHits",
m_clusterMinHits));
763 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
764 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
765 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
766 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
768 return STATUS_CODE_SUCCESS;
std::string m_inputClusterListNameU
void BuildSlidingFitResultMap(const pandora::ClusterVector &clusterVector, TwoDSlidingFitResultMap &slidingFitResultMap) const
Build the map of sliding fit results.
void RemoveAmbiguities(const ParticleList &inputParticleList, ParticleList &outputParticleList) const
Remove particles with duplicate clusters.
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 MatchTwoViews(const pandora::ClusterVector &clusterVectorU, const pandora::ClusterVector &clusterVectorV, const pandora::ClusterVector &clusterVectorW, const ClusterAssociationMap &clusterAssociationMapUV, const ClusterAssociationMap &clusterAssociationMapVW, const ClusterAssociationMap &clusterAssociationMapWU, ParticleList &particleList) const
Create candidate particles using two primary clusters and one pair of broken clusters.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterAssociationMap
void BuildParticles(const ParticleList &particleList)
Build particle flow objects.
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.
std::string m_outputPfoListName
void MatchOneView(const pandora::ClusterVector &clusterVectorU, const pandora::ClusterVector &clusterVectorV, const pandora::ClusterVector &clusterVectorW, const ClusterAssociationMap &clusterAssociationMapUV, const ClusterAssociationMap &clusterAssociationMapVW, const ClusterAssociationMap &clusterAssociationMapWU, ParticleList &particleList) const
Create candidate particles using one primary cluster and one pair of broken clusters.
void MatchClusters(const pandora::Cluster *const pSeedCluster, const pandora::ClusterVector &targetClusters, const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterAssociationMap &clusterAssociationMap) const
Match a seed cluster with a list of target clusters and populate the cluster association map...
void BuildVetoList(const ParticleList &particleList, pandora::ClusterSet &vetoList) const
Build the list of clusters already used to create particles.
static void GetClustersByHitType(const pandora::ClusterList &inputClusters, const pandora::HitType hitType, pandora::ClusterList &clusterList)
Get the subset of clusters, from a provided list, that match the specified hit type.
pandora::StatusCode Run()
LArPointingCluster class.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static void GetClosestVertices(const bool useX, const bool useY, const bool useZ, const LArPointingCluster &pointingClusterI, const LArPointingCluster &pointingClusterJ, LArPointingCluster::Vertex &closestVertexI, LArPointingCluster::Vertex &closestVertexJ)
Given a pair of pointing clusters, receive the closest or farthest pair of vertices.
Header file for the geometry helper class.
static void GetClusterBoundingBox(const pandora::Cluster *const pCluster, pandora::CartesianVector &minimumCoordinate, pandora::CartesianVector &maximumCoordinate)
Get minimum and maximum X, Y and Z positions of the calo hits in a cluster.
void MatchThreeViews(const pandora::ClusterVector &clusterVectorU, const pandora::ClusterVector &clusterVectorV, const pandora::ClusterVector &clusterVectorW, const ClusterAssociationMap &clusterAssociationMapUV, const ClusterAssociationMap &clusterAssociationMapVW, const ClusterAssociationMap &clusterAssociationMapWU, ParticleList &particleList) const
Create candidate particles using three primary clusters.
pandora::StatusCode GetAvailableClusters(const std::string &inputClusterListName, pandora::ClusterVector &clusterVector) const
Get a vector of available clusters.
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
std::vector< Particle > ParticleList
pandora::ClusterList m_clusterList
std::set< unsigned int > UIntSet
void SelectCleanClusters(const pandora::ClusterVector &inputVector, pandora::ClusterVector &outputVector) const
Select a set of clusters judged to be clean.
std::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
std::string m_inputClusterListNameW
unsigned int m_clusterMinHits
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
std::string m_inputClusterListNameV
bool IsInnerVertex() const
Is this the inner vertex.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
void MatchViews(const pandora::ClusterVector &clusterVector1, const pandora::ClusterVector &clusterVector2, const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterAssociationMap &clusterAssociationMap) const
Match a pair of cluster vectors and populate the cluster association map.
void MergeClusters(const pandora::ClusterList &inputClusterList, pandora::ClusterList &outputClusterList) const
Merge broken clusters into a single cluster.
float m_clusterMinOverlapX
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
TwoDSlidingFitResult class.
static void GetCommonDaughterVolumes(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, UIntSet &intersect)
Return the set of common daughter volumes between two 2D clusters.
Header file for the cosmic ray longitudinal track recovery algorithm class.