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);
138 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()));
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());
369 (matchedClusters12_pCluster1.size() + matchedClusters12_pCluster2.size() > 0) &&
370 ((matchedClusters12_pCluster1.size() == 1 && std::find(matchedClusters12_pCluster1.begin(), matchedClusters12_pCluster1.end(),
371 pCluster2) != matchedClusters12_pCluster1.end()) ||
372 (matchedClusters12_pCluster1.size() == 0)) &&
373 ((matchedClusters12_pCluster2.size() == 1 && std::find(matchedClusters12_pCluster2.begin(), matchedClusters12_pCluster2.end(),
374 pCluster1) != matchedClusters12_pCluster2.end()) ||
375 (matchedClusters12_pCluster2.size() == 0)));
378 (matchedClusters23_pCluster2.size() + matchedClusters23_pCluster3.size() > 0) &&
379 ((matchedClusters23_pCluster2.size() == 1 && std::find(matchedClusters23_pCluster2.begin(), matchedClusters23_pCluster2.end(),
380 pCluster3) != matchedClusters23_pCluster2.end()) ||
381 (matchedClusters23_pCluster2.size() == 0)) &&
382 ((matchedClusters23_pCluster3.size() == 1 && std::find(matchedClusters23_pCluster3.begin(), matchedClusters23_pCluster3.end(),
383 pCluster2) != matchedClusters23_pCluster3.end()) ||
384 (matchedClusters23_pCluster3.size() == 0)));
387 (matchedClusters31_pCluster3.size() + matchedClusters31_pCluster1.size() > 0) &&
388 ((matchedClusters31_pCluster3.size() == 1 && std::find(matchedClusters31_pCluster3.begin(), matchedClusters31_pCluster3.end(),
389 pCluster1) != matchedClusters31_pCluster3.end()) ||
390 (matchedClusters31_pCluster3.size() == 0)) &&
391 ((matchedClusters31_pCluster1.size() == 1 && std::find(matchedClusters31_pCluster1.begin(), matchedClusters31_pCluster1.end(),
392 pCluster3) != matchedClusters31_pCluster1.end()) ||
393 (matchedClusters31_pCluster1.size() == 0)));
395 if (match12 && match23 && match31)
401 newParticleList.push_back(newParticle);
421 for (
unsigned int iView = 0; iView < 3; ++iView)
423 const ClusterVector &clusterVector1((0 == iView) ? clusterVectorU : (1 == iView) ? clusterVectorV : clusterVectorW);
424 const ClusterVector &clusterVector2((0 == iView) ? clusterVectorV : (1 == iView) ? clusterVectorW : clusterVectorU);
425 const ClusterVector &clusterVector3((0 == iView) ? clusterVectorW : (1 == iView) ? clusterVectorU : clusterVectorV);
427 const ClusterAssociationMap &matchedClusters12(((0 == iView) ? matchedClustersUV : (1 == iView) ? matchedClustersVW : matchedClustersWU));
428 const ClusterAssociationMap &matchedClusters23(((0 == iView) ? matchedClustersVW : (1 == iView) ? matchedClustersWU : matchedClustersUV));
429 const ClusterAssociationMap &matchedClusters31(((0 == iView) ? matchedClustersWU : (1 == iView) ? matchedClustersUV : matchedClustersVW));
433 const Cluster *
const pCluster1 = *iter1;
435 if (vetoList.count(pCluster1))
439 const ClusterList matchedClusters31_pCluster1(iter311 != matchedClusters31.end() ? iter311->second : ClusterList());
442 const ClusterList matchedClusters12_pCluster1(iter121 != matchedClusters12.end() ? iter121->second : ClusterList());
446 const Cluster *
const pCluster2 = *iter2;
448 if (vetoList.count(pCluster2))
452 const ClusterList matchedClusters12_pCluster2(iter122 != matchedClusters12.end() ? iter122->second : ClusterList());
455 const ClusterList matchedClusters23_pCluster2(iter232 != matchedClusters23.end() ? iter232->second : ClusterList());
458 (matchedClusters12_pCluster1.size() == 1 && std::find(matchedClusters12_pCluster1.begin(), matchedClusters12_pCluster1.end(),
459 pCluster2) != matchedClusters12_pCluster1.end()) &&
460 (matchedClusters12_pCluster2.size() == 1 && std::find(matchedClusters12_pCluster2.begin(), matchedClusters12_pCluster2.end(),
461 pCluster1) != matchedClusters12_pCluster2.end()) &&
462 (matchedClusters23_pCluster2.size() == 0 && matchedClusters31_pCluster1.size() == 0));
473 const Cluster *
const pCluster3 = *iter3;
475 if (vetoList.count(pCluster3))
479 const ClusterList matchedClusters23_pCluster3(iter233 != matchedClusters23.end() ? iter233->second : ClusterList());
482 const ClusterList matchedClusters31_pCluster3(iter313 != matchedClusters31.end() ? iter313->second : ClusterList());
484 const bool match3((matchedClusters31_pCluster3.size() + matchedClusters23_pCluster3.size() > 0) &&
485 ((matchedClusters31_pCluster3.size() == 1 &&
486 std::find(matchedClusters31_pCluster3.begin(), matchedClusters31_pCluster3.end(), pCluster1) !=
487 matchedClusters31_pCluster3.end()) ||
488 (matchedClusters31_pCluster3.size() == 0)) &&
489 ((matchedClusters23_pCluster3.size() == 1 &&
490 std::find(matchedClusters23_pCluster3.begin(), matchedClusters23_pCluster3.end(), pCluster2) !=
491 matchedClusters23_pCluster3.end()) ||
492 (matchedClusters23_pCluster3.size() == 0)));
498 newParticleList.push_back(newParticle);
517 for (
unsigned int iView = 0; iView < 3; ++iView)
519 const ClusterVector &clusterVector1((0 == iView) ? clusterVectorU : (1 == iView) ? clusterVectorV : clusterVectorW);
520 const ClusterVector &clusterVector2((0 == iView) ? clusterVectorV : (1 == iView) ? clusterVectorW : clusterVectorU);
521 const ClusterVector &clusterVector3((0 == iView) ? clusterVectorW : (1 == iView) ? clusterVectorU : clusterVectorV);
523 const ClusterAssociationMap &matchedClusters12(((0 == iView) ? matchedClustersUV : (1 == iView) ? matchedClustersVW : matchedClustersWU));
524 const ClusterAssociationMap &matchedClusters23(((0 == iView) ? matchedClustersVW : (1 == iView) ? matchedClustersWU : matchedClustersUV));
525 const ClusterAssociationMap &matchedClusters31(((0 == iView) ? matchedClustersWU : (1 == iView) ? matchedClustersUV : matchedClustersVW));
529 const Cluster *
const pCluster1 = *iter1;
531 if (vetoList.count(pCluster1))
535 const ClusterList matchedClusters31_pCluster1(iter311 != matchedClusters31.end() ? iter311->second : ClusterList());
538 const ClusterList matchedClusters12_pCluster1(iter121 != matchedClusters12.end() ? iter121->second : ClusterList());
540 if (matchedClusters12_pCluster1.size() + matchedClusters31_pCluster1.size() > 0)
548 const Cluster *
const pCluster2 = *iter2;
550 if (vetoList.count(pCluster2))
554 const ClusterList matchedClusters12_pCluster2(iter122 != matchedClusters12.end() ? iter122->second : ClusterList());
557 const ClusterList matchedClusters23_pCluster2(iter232 != matchedClusters23.end() ? iter232->second : ClusterList());
559 if (matchedClusters12_pCluster2.size() == 1 &&
560 std::find(matchedClusters12_pCluster2.begin(), matchedClusters12_pCluster2.end(), pCluster1) !=
561 matchedClusters12_pCluster2.end() &&
562 matchedClusters23_pCluster2.size() == 0)
568 const Cluster *
const pCluster3 = *iter3;
570 if (vetoList.count(pCluster3))
574 const ClusterList matchedClusters23_pCluster3(iter233 != matchedClusters23.end() ? iter233->second : ClusterList());
577 const ClusterList matchedClusters31_pCluster3(iter313 != matchedClusters31.end() ? iter313->second : ClusterList());
579 if (matchedClusters31_pCluster3.size() == 1 &&
580 std::find(matchedClusters31_pCluster3.begin(), matchedClusters31_pCluster3.end(), pCluster1) !=
581 matchedClusters31_pCluster3.end() &&
582 matchedClusters23_pCluster3.size() == 0)
587 newParticleList.push_back(newParticle);
609 for (
ParticleList::const_iterator pIter1 = inputParticleList.begin(), pIterEnd1 = inputParticleList.end(); pIter1 != pIterEnd1; ++pIter1)
611 const Particle &particle1 = *pIter1;
620 const Particle &particle2 = *pIter2;
623 ClusterSet duplicateSet;
627 const Cluster *pCluster = *cIter1;
629 if (clusterList2.end() != std::find(clusterList2.begin(), clusterList2.end(), pCluster))
630 duplicateSet.insert(pCluster);
633 if (duplicateSet.size() > 0 && clusterList1.size() != clusterList2.size())
641 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
643 outputParticleList.push_back(particle1);
645 catch (StatusCodeException &)
647 std::cout <<
" Warning in CosmicRayTrackRecoveryAlgorithm: found duplicate particles in candidate list " <<
std::endl;
656 if (particleList.empty())
659 const PfoList *pPfoList(
nullptr);
661 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
663 for (
const Particle &particle : particleList)
665 if (!PandoraContentApi::IsAvailable(*
this, &particle.m_clusterList))
668 ClusterList clusterList;
671 if (clusterList.empty())
672 throw StatusCodeException(STATUS_CODE_FAILURE);
674 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
675 pfoParameters.m_particleId = MU_MINUS;
676 pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
677 pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
678 pfoParameters.m_energy = 0.f;
679 pfoParameters.m_momentum = CartesianVector(0.
f, 0.
f, 0.
f);
680 pfoParameters.m_clusterList = clusterList;
682 const ParticleFlowObject *pPfo(
nullptr);
683 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
686 if (!pPfoList->empty())
687 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this,
m_outputPfoListName));
694 ClusterList clusterListU, clusterListV, clusterListW;
699 for (
unsigned int iView = 0; iView < 3; ++iView)
701 const ClusterList clusterList((0 == iView) ? clusterListU : (1 == iView) ? clusterListV : clusterListW);
704 if (clusterList.empty())
707 const Cluster *
const pSeedCluster(clusterList.front());
709 if (!PandoraContentApi::IsAvailable(*
this, pSeedCluster))
710 throw StatusCodeException(STATUS_CODE_FAILURE);
712 for (
const Cluster *
const pAssociatedCluster : clusterList)
714 if (pAssociatedCluster == pSeedCluster)
717 if (!PandoraContentApi::IsAvailable(*
this, pAssociatedCluster))
720 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
721 PandoraContentApi::MergeAndDeleteClusters(*
this, pSeedCluster, pAssociatedCluster, inputClusterListName, inputClusterListName));
724 outputClusterList.push_back(pSeedCluster);
732 PANDORA_RETURN_RESULT_IF_AND_IF(
733 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinLength",
m_clusterMinLength));
735 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinSpanZ",
m_clusterMinSpanZ));
737 PANDORA_RETURN_RESULT_IF_AND_IF(
738 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinOverlapX",
m_clusterMinOverlapX));
740 PANDORA_RETURN_RESULT_IF_AND_IF(
741 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMaxDeltaX",
m_clusterMaxDeltaX));
743 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ClusterMinHits",
m_clusterMinHits));
745 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
746 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
747 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
748 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
750 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 float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
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.
std::vector< Particle > ParticleList
static int max(int a, int b)
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
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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.
QTextStream & endl(QTextStream &s)