9 #include "Pandora/AlgorithmHeaders.h"
21 StatusCode CosmicRayBaseMatchingAlgorithm::Run()
24 ClusterVector availableClustersU, availableClustersV, availableClustersW;
25 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetAvailableClusters(m_inputClusterListNameU, availableClustersU));
26 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetAvailableClusters(m_inputClusterListNameV, availableClustersV));
27 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetAvailableClusters(m_inputClusterListNameW, availableClustersW));
31 this->SelectCleanClusters(availableClustersU, cleanClustersU);
32 this->SelectCleanClusters(availableClustersV, cleanClustersV);
33 this->SelectCleanClusters(availableClustersW, cleanClustersW);
37 this->MatchClusters(cleanClustersU, cleanClustersV, matchedClusterUV);
38 this->MatchClusters(cleanClustersV, cleanClustersW, matchedClusterVW);
39 this->MatchClusters(cleanClustersW, cleanClustersU, matchedClusterWU);
43 this->MatchThreeViews(matchedClusterUV, matchedClusterVW, matchedClusterWU, particleList);
44 this->MatchTwoViews(matchedClusterUV, matchedClusterVW, matchedClusterWU, particleList);
45 this->BuildParticles(particleList);
47 return STATUS_CODE_SUCCESS;
52 StatusCode CosmicRayBaseMatchingAlgorithm::GetAvailableClusters(
const std::string inputClusterListName,
ClusterVector &clusterVector)
const
54 const ClusterList *pClusterList = NULL;
55 PANDORA_RETURN_RESULT_IF_AND_IF(
56 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, inputClusterListName, pClusterList))
58 if (!pClusterList || pClusterList->empty())
60 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
61 std::cout <<
"CosmicRayBaseMatchingAlgorithm: unable to find cluster list " << inputClusterListName << std::endl;
63 return STATUS_CODE_SUCCESS;
66 for (
const Cluster *
const pCluster : *pClusterList)
68 if (!pCluster->IsAvailable())
71 clusterVector.push_back(pCluster);
74 std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
76 return STATUS_CODE_SUCCESS;
81 void CosmicRayBaseMatchingAlgorithm::MatchClusters(
85 if (clusterVector1.empty() || clusterVector2.empty())
88 const HitType hitType1(LArClusterHelper::GetClusterHitType(*clusterVector1.begin()));
89 const HitType hitType2(LArClusterHelper::GetClusterHitType(*clusterVector2.begin()));
91 if (hitType1 == hitType2)
92 throw StatusCodeException(STATUS_CODE_FAILURE);
94 for (
const Cluster *
const pCluster1 : clusterVector1)
96 for (
const Cluster *
const pCluster2 : clusterVector2)
98 if (this->MatchClusters(pCluster1, pCluster2))
100 UIntSet daughterVolumeIntersection;
101 LArGeometryHelper::GetCommonDaughterVolumes(pCluster1, pCluster2, daughterVolumeIntersection);
103 if (!daughterVolumeIntersection.empty())
104 matchedClusters12[pCluster1].push_back(pCluster2);
115 if (matchedClusters12.empty() || matchedClusters23.empty() || matchedClusters31.empty())
120 ClusterList clusterList1;
121 for (
const auto &mapEntry : matchedClusters12)
122 clusterList1.push_back(mapEntry.first);
123 clusterList1.sort(LArClusterHelper::SortByNHits);
125 for (
const Cluster *
const pCluster1 : clusterList1)
127 const ClusterList &clusterList2(matchedClusters12.at(pCluster1));
129 for (
const Cluster *
const pCluster2 : clusterList2)
131 ClusterAssociationMap::const_iterator iter23 = matchedClusters23.find(pCluster2);
133 if (matchedClusters23.end() == iter23)
136 const ClusterList &clusterList3 = iter23->second;
138 for (
const Cluster *
const pCluster3 : clusterList3)
140 ClusterAssociationMap::const_iterator iter31 = matchedClusters31.find(pCluster3);
142 if (matchedClusters31.end() == iter31)
145 if (iter31->second.end() == std::find(iter31->second.begin(), iter31->second.end(), pCluster1))
148 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
149 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
150 const HitType hitType3(LArClusterHelper::GetClusterHitType(pCluster3));
152 if (!this->CheckMatchedClusters3D(pCluster1, pCluster2, pCluster3))
155 const Cluster *
const pClusterU(
156 (TPC_VIEW_U == hitType1) ? pCluster1 : (TPC_VIEW_U == hitType2) ? pCluster2 : (TPC_VIEW_U == hitType3) ? pCluster3 : NULL);
157 const Cluster *
const pClusterV(
158 (TPC_VIEW_V == hitType1) ? pCluster1 : (TPC_VIEW_V == hitType2) ? pCluster2 : (TPC_VIEW_V == hitType3) ? pCluster3 : NULL);
159 const Cluster *
const pClusterW(
160 (TPC_VIEW_W == hitType1) ? pCluster1 : (TPC_VIEW_W == hitType2) ? pCluster2 : (TPC_VIEW_W == hitType3) ? pCluster3 : NULL);
162 candidateParticles.push_back(
Particle(pClusterU, pClusterV, pClusterW));
167 return this->ResolveAmbiguities(candidateParticles, matchedParticles);
176 this->MatchTwoViews(matchedClusters12, candidateParticles);
177 this->MatchTwoViews(matchedClusters23, candidateParticles);
178 this->MatchTwoViews(matchedClusters31, candidateParticles);
180 return this->ResolveAmbiguities(candidateParticles, matchedParticles);
187 if (matchedClusters12.empty())
190 ClusterList clusterList1;
191 for (
const auto &mapEntry : matchedClusters12)
192 clusterList1.push_back(mapEntry.first);
193 clusterList1.sort(LArClusterHelper::SortByNHits);
195 for (
const Cluster *
const pCluster1 : clusterList1)
197 const ClusterList &clusterList2(matchedClusters12.at(pCluster1));
199 for (
const Cluster *
const pCluster2 : clusterList2)
201 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
202 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
204 const Cluster *
const pClusterU((TPC_VIEW_U == hitType1) ? pCluster1 : (TPC_VIEW_U == hitType2) ? pCluster2 : NULL);
205 const Cluster *
const pClusterV((TPC_VIEW_V == hitType1) ? pCluster1 : (TPC_VIEW_V == hitType2) ? pCluster2 : NULL);
206 const Cluster *
const pClusterW((TPC_VIEW_W == hitType1) ? pCluster1 : (TPC_VIEW_W == hitType2) ? pCluster2 : NULL);
208 matchedParticles.push_back(
Particle(pClusterU, pClusterV, pClusterW));
215 void CosmicRayBaseMatchingAlgorithm::ResolveAmbiguities(
const ParticleList &candidateParticles,
ParticleList &matchedParticles)
const
217 for (
const Particle &particle1 : candidateParticles)
219 bool isGoodMatch(
true);
221 for (
const Particle &particle2 : candidateParticles)
223 const bool commonU(particle1.m_pClusterU == particle2.m_pClusterU);
224 const bool commonV(particle1.m_pClusterV == particle2.m_pClusterV);
225 const bool commonW(particle1.m_pClusterW == particle2.m_pClusterW);
227 const bool ambiguousU(commonU && NULL != particle1.m_pClusterU);
228 const bool ambiguousV(commonV && NULL != particle1.m_pClusterV);
229 const bool ambiguousW(commonW && NULL != particle1.m_pClusterW);
231 if (commonU && commonV && commonW)
234 if (ambiguousU || ambiguousV || ambiguousW)
242 matchedParticles.push_back(particle1);
248 void CosmicRayBaseMatchingAlgorithm::BuildParticles(
const ParticleList &particleList)
250 if (particleList.empty())
253 const PfoList *pPfoList = NULL;
254 std::string pfoListName;
255 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
257 for (
const Particle &particle : particleList)
259 const Cluster *
const pClusterU = particle.m_pClusterU;
260 const Cluster *
const pClusterV = particle.m_pClusterV;
261 const Cluster *
const pClusterW = particle.m_pClusterW;
263 const bool isAvailableU((NULL != pClusterU) ? pClusterU->IsAvailable() :
true);
264 const bool isAvailableV((NULL != pClusterV) ? pClusterV->IsAvailable() :
true);
265 const bool isAvailableW((NULL != pClusterW) ? pClusterW->IsAvailable() :
true);
267 if (!(isAvailableU && isAvailableV && isAvailableW))
268 throw StatusCodeException(STATUS_CODE_FAILURE);
271 this->SetPfoParameters(particle, pfoParameters);
273 if (pfoParameters.m_clusterList.empty())
274 throw StatusCodeException(STATUS_CODE_FAILURE);
276 const ParticleFlowObject *pPfo(NULL);
277 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
280 if (!pPfoList->empty())
281 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this, m_outputPfoListName));
286 CosmicRayBaseMatchingAlgorithm::Particle::Particle(
const Cluster *
const pClusterU,
const Cluster *
const pClusterV,
const Cluster *
const pClusterW) :
287 m_pClusterU(pClusterU),
288 m_pClusterV(pClusterV),
289 m_pClusterW(pClusterW)
292 throw StatusCodeException(STATUS_CODE_FAILURE);
298 if (!(TPC_VIEW_U == hitTypeU && TPC_VIEW_V == hitTypeV && TPC_VIEW_W == hitTypeW))
299 throw StatusCodeException(STATUS_CODE_FAILURE);
306 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
307 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
308 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
309 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
311 return STATUS_CODE_SUCCESS;
std::string m_inputClusterListNameV
The name of the view V cluster list.
Header file for the cosmic ray base matching algorithm class.
std::vector< Particle > ParticleList
const pandora::Cluster * m_pClusterV
Address of cluster in V view.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
Header file for the geometry helper class.
Header file for the cluster helper class.
const pandora::Cluster * m_pClusterW
Address of cluster in W view.
std::string m_outputPfoListName
The name of the output PFO list.
const pandora::Cluster * m_pClusterU
Address of cluster in U view.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::string m_inputClusterListNameU
The name of the view U cluster list.
std::string m_inputClusterListNameW
The name of the view W cluster list.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::vector< art::Ptr< recob::Cluster > > ClusterVector
BEGIN_PROLOG could also be cout
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterAssociationMap