9 #include "Pandora/AlgorithmHeaders.h" 20 CheatingPfoCreationAlgorithm::CheatingPfoCreationAlgorithm() :
21 m_collapseToPrimaryMCParticles(false),
22 m_useOnlyAvailableClusters(true),
24 m_replaceCurrentVertexList(false),
26 m_nHitsForGoodHitType(10)
38 const MCParticleList *pMCParticleList(
nullptr);
39 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_mcParticleListName, pMCParticleList));
48 const ClusterList *pClusterList(
nullptr);
50 if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*
this, clusterListName, pClusterList))
52 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
53 std::cout <<
"CheatingPfoCreationAlgorithm - Could not access cluster list with name " << clusterListName <<
std::endl;
62 return STATUS_CODE_SUCCESS;
70 for (
const Cluster *
const pCluster : *pClusterList)
77 const MCParticle *pMCParticle(MCParticleHelper::GetMainMCParticle(pCluster));
83 if (mcPrimaryMap.end() == primaryIter)
84 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
86 pMCParticle = primaryIter->second;
92 mcParticleToClusterListMap[pMCParticle].push_back(pCluster);
94 catch (
const StatusCodeException &)
104 if (mcParticleToClusterListMap.empty())
107 const PfoList *pPfoList(
nullptr);
109 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pPfoList, pfoListName));
113 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pVertexList, vertexListName));
116 for (
const auto &mapEntry : mcParticleToClusterListMap)
117 mcParticleVector.push_back(mapEntry.first);
120 for (
const MCParticle *
const pMCParticle : mcParticleVector)
122 const ClusterList &clusterList(mcParticleToClusterListMap.at(pMCParticle));
124 if (clusterList.empty())
132 PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
133 pfoParameters.m_particleId = pMCParticle->GetParticleId();
134 pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
135 pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
136 pfoParameters.m_energy = pMCParticle->GetEnergy();
137 pfoParameters.m_momentum = pMCParticle->GetMomentum();
138 pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), clusterList.begin(), clusterList.end());
140 const ParticleFlowObject *pPfo(
nullptr);
141 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*
this, pfoParameters, pPfo));
145 PandoraContentApi::Vertex::Parameters parameters;
146 parameters.m_position = pMCParticle->GetVertex();
147 parameters.m_vertexLabel = VERTEX_START;
148 parameters.m_vertexType = VERTEX_3D;
150 const Vertex *pVertex(
nullptr);
151 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
152 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*
this, pPfo, pVertex));
155 catch (
const StatusCodeException &)
157 std::cout <<
"CheatingPfoCreationAlgorithm: Could not create PFO for MCParticle with pdg code " << pMCParticle->GetParticleId()
162 if (!pPfoList->empty())
164 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*
this,
m_outputPfoListName));
165 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Pfo>(*
this,
m_outputPfoListName));
168 if (!pVertexList->empty())
170 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*
this,
m_outputVertexListName));
173 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*
this,
m_outputVertexListName));
183 for (
const Cluster *
const pCluster : clusterList)
188 unsigned int nGoodViews(0);
190 for (
const HitTypeMap::value_type &mapEntry : hitTypeMap)
192 if (mapEntry.second > nHitsThreshold)
203 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"InputClusterListNames",
m_inputClusterListNames));
205 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputPfoListName",
m_outputPfoListName));
207 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
212 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MCParticleListName",
m_mcParticleListName));
215 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
218 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"AddVertices",
m_addVertices));
222 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputVertexListName",
m_outputVertexListName));
224 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
229 PANDORA_RETURN_RESULT_IF_AND_IF(
230 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"ParticleIdList", particleIdVector));
234 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinGoodHitTypes",
m_minGoodHitTypes));
236 PANDORA_RETURN_RESULT_IF_AND_IF(
237 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NHitsForGoodHitType",
m_nHitsForGoodHitType));
239 return STATUS_CODE_SUCCESS;
std::string m_mcParticleListName
The mc particle list name.
pandora::StringVector m_inputClusterListNames
The names of the input cluster lists.
std::string m_outputVertexListName
The output vertex list name.
unsigned int m_minGoodHitTypes
The min number of good hit types in the clusters collected for a given mc particle.
std::vector< int > IntVector
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
static void GetMCPrimaryMap(const pandora::MCParticleList *const pMCParticleList, MCRelationMap &mcPrimaryMap)
Get mapping from individual mc particles (in a provided list) and their primary parent mc particles...
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
std::unordered_map< const pandora::MCParticle *, pandora::ClusterList > MCParticleToClusterListMap
pandora::StatusCode Run()
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
void CreatePfos(const MCParticleToClusterListMap &mcParticleToClusterListMap) const
Create pfos corresponding to the details in a provided mc particle to cluster list map...
std::string m_outputPfoListName
The output pfo list name.
std::map< pandora::HitType, unsigned int > HitTypeMap
Header file for the cluster helper class.
unsigned int m_nHitsForGoodHitType
The min number of hits of a particular hit type in order to declare the hit type is good...
Header file for the cheating cluster creation algorithm class.
void GetMCParticleToClusterListMap(const pandora::ClusterList *const pClusterList, const LArMCParticleHelper::MCRelationMap &mcPrimaryMap, MCParticleToClusterListMap &mcParticleToClusterListMap) const
Get a map relating mc particles to a list of daughter clusters.
bool m_addVertices
Whether to add the start vertex to the cheated pfo.
bool m_useOnlyAvailableClusters
Whether to consider unavailable clusters when identifying cheated pfos.
ParticleIdList m_particleIdList
The list of particle ids to consider for pfo creation; will consider all ids if empty.
unsigned int GetNHitTypesAboveThreshold(const pandora::ClusterList &clusterList, const unsigned int nHitsThreshold) const
Get the number of hit types containing more than a specified number of hits.
bool m_collapseToPrimaryMCParticles
Whether to collapse mc particle hierarchies to primary particles.
bool m_replaceCurrentVertexList
Whether to replace current vertex list.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
std::list< Vertex > VertexList
QTextStream & endl(QTextStream &s)