9 #include "Pandora/AlgorithmHeaders.h" 20 StatusCode CosmicRayBaseMatchingAlgorithm::Run()
23 ClusterVector availableClustersU, availableClustersV, availableClustersW;
24 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetAvailableClusters(m_inputClusterListNameU, availableClustersU));
25 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetAvailableClusters(m_inputClusterListNameV, availableClustersV));
26 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetAvailableClusters(m_inputClusterListNameW, availableClustersW));
30 this->SelectCleanClusters(availableClustersU, cleanClustersU);
31 this->SelectCleanClusters(availableClustersV, cleanClustersV);
32 this->SelectCleanClusters(availableClustersW, cleanClustersW);
36 this->MatchClusters(cleanClustersU, cleanClustersV, matchedClusterUV);
37 this->MatchClusters(cleanClustersV, cleanClustersW, matchedClusterVW);
38 this->MatchClusters(cleanClustersW, cleanClustersU, matchedClusterWU);
42 this->MatchThreeViews(matchedClusterUV, matchedClusterVW, matchedClusterWU, particleList);
43 this->MatchTwoViews(matchedClusterUV, matchedClusterVW, matchedClusterWU, particleList);
44 this->BuildParticles(particleList);
46 return STATUS_CODE_SUCCESS;
51 StatusCode CosmicRayBaseMatchingAlgorithm::GetAvailableClusters(
const std::string inputClusterListName,
ClusterVector &clusterVector)
const 53 const ClusterList *pClusterList = NULL;
54 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
55 inputClusterListName, pClusterList))
57 if (!pClusterList || pClusterList->empty())
59 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
60 std::cout <<
"CosmicRayBaseMatchingAlgorithm: unable to find cluster list " << inputClusterListName << std::endl;
62 return STATUS_CODE_SUCCESS;
65 for (
const Cluster *
const pCluster : *pClusterList)
67 if (!pCluster->IsAvailable())
70 clusterVector.push_back(pCluster);
73 std::sort(clusterVector.begin(), clusterVector.end(), LArClusterHelper::SortByNHits);
75 return STATUS_CODE_SUCCESS;
84 if (clusterVector1.empty() || clusterVector2.empty())
87 const HitType hitType1(LArClusterHelper::GetClusterHitType(*clusterVector1.begin()));
88 const HitType hitType2(LArClusterHelper::GetClusterHitType(*clusterVector2.begin()));
90 if (hitType1 == hitType2)
91 throw StatusCodeException(STATUS_CODE_FAILURE);
93 for (
const Cluster *
const pCluster1 : clusterVector1)
95 for (
const Cluster *
const pCluster2 : clusterVector2)
97 if (this->MatchClusters(pCluster1, pCluster2))
99 matchedClusters12[pCluster1].push_back(pCluster2);
110 if (matchedClusters12.empty() || matchedClusters23.empty() || matchedClusters31.empty())
115 ClusterList clusterList1;
116 for (
const auto &mapEntry : matchedClusters12) clusterList1.push_back(mapEntry.first);
117 clusterList1.sort(LArClusterHelper::SortByNHits);
119 for (
const Cluster *
const pCluster1 : clusterList1)
121 const ClusterList &clusterList2(matchedClusters12.at(pCluster1));
123 for (
const Cluster *
const pCluster2 : clusterList2)
127 if (matchedClusters23.end() == iter23)
130 const ClusterList &clusterList3 = iter23->second;
132 for (
const Cluster *
const pCluster3 : clusterList3)
136 if (matchedClusters31.end() == iter31)
139 if (iter31->second.end() == std::find(iter31->second.begin(), iter31->second.end(), pCluster1))
142 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
143 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
144 const HitType hitType3(LArClusterHelper::GetClusterHitType(pCluster3));
146 if (!this->CheckMatchedClusters3D(pCluster1, pCluster2, pCluster3))
149 const Cluster *
const pClusterU((TPC_VIEW_U == hitType1) ? pCluster1 : (TPC_VIEW_U == hitType2) ? pCluster2 : (TPC_VIEW_U == hitType3) ? pCluster3 : NULL);
150 const Cluster *
const pClusterV((TPC_VIEW_V == hitType1) ? pCluster1 : (TPC_VIEW_V == hitType2) ? pCluster2 : (TPC_VIEW_V == hitType3) ? pCluster3 : NULL);
151 const Cluster *
const pClusterW((TPC_VIEW_W == hitType1) ? pCluster1 : (TPC_VIEW_W == hitType2) ? pCluster2 : (TPC_VIEW_W == hitType3) ? pCluster3 : NULL);
153 candidateParticles.push_back(
Particle(pClusterU, pClusterV, pClusterW));
158 return this->ResolveAmbiguities(candidateParticles, matchedParticles);
167 this->MatchTwoViews(matchedClusters12, candidateParticles);
168 this->MatchTwoViews(matchedClusters23, candidateParticles);
169 this->MatchTwoViews(matchedClusters31, candidateParticles);
171 return this->ResolveAmbiguities(candidateParticles, matchedParticles);
178 if (matchedClusters12.empty())
181 ClusterList clusterList1;
182 for (
const auto &mapEntry : matchedClusters12) clusterList1.push_back(mapEntry.first);
183 clusterList1.sort(LArClusterHelper::SortByNHits);
185 for (
const Cluster *
const pCluster1 : clusterList1)
187 const ClusterList &clusterList2(matchedClusters12.at(pCluster1));
189 for (
const Cluster *
const pCluster2 : clusterList2)
191 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
192 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
194 const Cluster *
const pClusterU((TPC_VIEW_U == hitType1) ? pCluster1 : (TPC_VIEW_U == hitType2) ? pCluster2 : NULL);
195 const Cluster *
const pClusterV((TPC_VIEW_V == hitType1) ? pCluster1 : (TPC_VIEW_V == hitType2) ? pCluster2 : NULL);
196 const Cluster *
const pClusterW((TPC_VIEW_W == hitType1) ? pCluster1 : (TPC_VIEW_W == hitType2) ? pCluster2 : NULL);
198 matchedParticles.push_back(
Particle(pClusterU, pClusterV, pClusterW));
205 void CosmicRayBaseMatchingAlgorithm::ResolveAmbiguities(
const ParticleList &candidateParticles,
ParticleList &matchedParticles)
const 207 for (
const Particle &particle1 : candidateParticles)
209 bool isGoodMatch(
true);
211 for (
const Particle &particle2 : candidateParticles)
213 const bool commonU(particle1.m_pClusterU == particle2.m_pClusterU);
214 const bool commonV(particle1.m_pClusterV == particle2.m_pClusterV);
215 const bool commonW(particle1.m_pClusterW == particle2.m_pClusterW);
217 const bool ambiguousU(commonU && NULL != particle1.m_pClusterU);
218 const bool ambiguousV(commonV && NULL != particle1.m_pClusterV);
219 const bool ambiguousW(commonW && NULL != particle1.m_pClusterW);
221 if (commonU && commonV && commonW)
224 if (ambiguousU || ambiguousV || ambiguousW)
232 matchedParticles.push_back(particle1);
238 void CosmicRayBaseMatchingAlgorithm::BuildParticles(
const ParticleList &particleList)
240 if (particleList.empty())
243 const PfoList *pPfoList = NULL; std::string pfoListName;
244 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
246 for (
const Particle &particle : particleList)
248 const Cluster *
const pClusterU = particle.m_pClusterU;
249 const Cluster *
const pClusterV = particle.m_pClusterV;
250 const Cluster *
const pClusterW = particle.m_pClusterW;
252 const bool isAvailableU((NULL != pClusterU) ? pClusterU->IsAvailable() :
true);
253 const bool isAvailableV((NULL != pClusterV) ? pClusterV->IsAvailable() :
true);
254 const bool isAvailableW((NULL != pClusterW) ? pClusterW->IsAvailable() :
true);
256 if(!(isAvailableU && isAvailableV && isAvailableW))
257 throw StatusCodeException(STATUS_CODE_FAILURE);
259 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
260 this->SetPfoParameters(particle, pfoParameters);
262 if (pfoParameters.m_clusterList.empty())
263 throw StatusCodeException(STATUS_CODE_FAILURE);
265 const ParticleFlowObject *pPfo(NULL);
266 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
269 if (!pPfoList->empty())
270 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this, m_outputPfoListName));
275 CosmicRayBaseMatchingAlgorithm::Particle::Particle(
const Cluster *
const pClusterU,
const Cluster *
const pClusterV,
const Cluster *
const pClusterW) :
276 m_pClusterU(pClusterU),
277 m_pClusterV(pClusterV),
278 m_pClusterW(pClusterW)
281 throw StatusCodeException(STATUS_CODE_FAILURE);
287 if (!(TPC_VIEW_U == hitTypeU && TPC_VIEW_V == hitTypeV && TPC_VIEW_W == hitTypeW))
288 throw StatusCodeException(STATUS_CODE_FAILURE);
295 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
296 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameU",
m_inputClusterListNameU));
297 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameV",
m_inputClusterListNameV));
298 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputClusterListNameW",
m_inputClusterListNameW));
300 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.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterAssociationMap
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::vector< art::Ptr< recob::Cluster > > ClusterVector
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)