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)
133 if (matchedClusters23.end() == iter23)
136 const ClusterList &clusterList3 = iter23->second;
138 for (
const Cluster *
const pCluster3 : clusterList3)
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((TPC_VIEW_U == hitType1) ? pCluster1
156 : (TPC_VIEW_U == hitType2) ? pCluster2
157 : (TPC_VIEW_U == hitType3) ? pCluster3
159 const Cluster *
const pClusterV((TPC_VIEW_V == hitType1) ? pCluster1
160 : (TPC_VIEW_V == hitType2) ? pCluster2
161 : (TPC_VIEW_V == hitType3) ? pCluster3
163 const Cluster *
const pClusterW((TPC_VIEW_W == hitType1) ? pCluster1
164 : (TPC_VIEW_W == hitType2) ? pCluster2
165 : (TPC_VIEW_W == hitType3) ? pCluster3
168 candidateParticles.push_back(
Particle(pClusterU, pClusterV, pClusterW));
173 return this->ResolveAmbiguities(candidateParticles, matchedParticles);
182 this->MatchTwoViews(matchedClusters12, candidateParticles);
183 this->MatchTwoViews(matchedClusters23, candidateParticles);
184 this->MatchTwoViews(matchedClusters31, candidateParticles);
186 return this->ResolveAmbiguities(candidateParticles, matchedParticles);
193 if (matchedClusters12.empty())
196 ClusterList clusterList1;
197 for (
const auto &mapEntry : matchedClusters12)
198 clusterList1.push_back(mapEntry.first);
199 clusterList1.sort(LArClusterHelper::SortByNHits);
201 for (
const Cluster *
const pCluster1 : clusterList1)
203 const ClusterList &clusterList2(matchedClusters12.at(pCluster1));
205 for (
const Cluster *
const pCluster2 : clusterList2)
207 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
208 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
210 const Cluster *
const pClusterU((TPC_VIEW_U == hitType1) ? pCluster1 : (TPC_VIEW_U == hitType2) ? pCluster2 : NULL);
211 const Cluster *
const pClusterV((TPC_VIEW_V == hitType1) ? pCluster1 : (TPC_VIEW_V == hitType2) ? pCluster2 : NULL);
212 const Cluster *
const pClusterW((TPC_VIEW_W == hitType1) ? pCluster1 : (TPC_VIEW_W == hitType2) ? pCluster2 : NULL);
214 matchedParticles.push_back(
Particle(pClusterU, pClusterV, pClusterW));
221 void CosmicRayBaseMatchingAlgorithm::ResolveAmbiguities(
const ParticleList &candidateParticles,
ParticleList &matchedParticles)
const 223 for (
const Particle &particle1 : candidateParticles)
225 bool isGoodMatch(
true);
227 for (
const Particle &particle2 : candidateParticles)
229 const bool commonU(particle1.m_pClusterU == particle2.m_pClusterU);
230 const bool commonV(particle1.m_pClusterV == particle2.m_pClusterV);
231 const bool commonW(particle1.m_pClusterW == particle2.m_pClusterW);
233 const bool ambiguousU(commonU && NULL != particle1.m_pClusterU);
234 const bool ambiguousV(commonV && NULL != particle1.m_pClusterV);
235 const bool ambiguousW(commonW && NULL != particle1.m_pClusterW);
237 if (commonU && commonV && commonW)
240 if (ambiguousU || ambiguousV || ambiguousW)
248 matchedParticles.push_back(particle1);
254 void CosmicRayBaseMatchingAlgorithm::BuildParticles(
const ParticleList &particleList)
256 if (particleList.empty())
259 const PfoList *pPfoList = NULL;
260 std::string pfoListName;
261 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
263 for (
const Particle &particle : particleList)
265 const Cluster *
const pClusterU = particle.m_pClusterU;
266 const Cluster *
const pClusterV = particle.m_pClusterV;
267 const Cluster *
const pClusterW = particle.m_pClusterW;
269 const bool isAvailableU((NULL != pClusterU) ? pClusterU->IsAvailable() :
true);
270 const bool isAvailableV((NULL != pClusterV) ? pClusterV->IsAvailable() :
true);
271 const bool isAvailableW((NULL != pClusterW) ? pClusterW->IsAvailable() :
true);
273 if (!(isAvailableU && isAvailableV && isAvailableW))
274 throw StatusCodeException(STATUS_CODE_FAILURE);
276 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
277 this->SetPfoParameters(particle, pfoParameters);
279 if (pfoParameters.m_clusterList.empty())
280 throw StatusCodeException(STATUS_CODE_FAILURE);
282 const ParticleFlowObject *pPfo(NULL);
283 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
286 if (!pPfoList->empty())
287 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this, m_outputPfoListName));
292 CosmicRayBaseMatchingAlgorithm::Particle::Particle(
const Cluster *
const pClusterU,
const Cluster *
const pClusterV,
const Cluster *
const pClusterW) :
293 m_pClusterU(pClusterU),
294 m_pClusterV(pClusterV),
295 m_pClusterW(pClusterW)
298 throw StatusCodeException(STATUS_CODE_FAILURE);
304 if (!(TPC_VIEW_U == hitTypeU && TPC_VIEW_V == hitTypeV && TPC_VIEW_W == hitTypeW))
305 throw StatusCodeException(STATUS_CODE_FAILURE);
312 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
313 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
314 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
315 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
317 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.
std::set< unsigned int > UIntSet
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.
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
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterAssociationMap