CheatingPfoCreationAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArCheating/CheatingPfoCreationAlgorithm.cc
3  *
4  * @brief Implementation of the cheating cluster creation algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 CheatingPfoCreationAlgorithm::CheatingPfoCreationAlgorithm() :
21  m_collapseToPrimaryMCParticles(false),
22  m_useOnlyAvailableClusters(true),
23  m_addVertices(true),
24  m_replaceCurrentVertexList(false),
25  m_minGoodHitTypes(0),
26  m_nHitsForGoodHitType(10)
27 {
28 }
29 
30 //------------------------------------------------------------------------------------------------------------------------------------------
31 
33 {
35 
37  {
38  const MCParticleList *pMCParticleList(nullptr);
39  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
40 
41  LArMCParticleHelper::GetMCPrimaryMap(pMCParticleList, mcPrimaryMap);
42  }
43 
44  MCParticleToClusterListMap mcParticleToClusterListMap;
45 
46  for (const std::string &clusterListName : m_inputClusterListNames)
47  {
48  const ClusterList *pClusterList(nullptr);
49 
50  if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*this, clusterListName, pClusterList))
51  {
52  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
53  std::cout << "CheatingPfoCreationAlgorithm - Could not access cluster list with name " << clusterListName << std::endl;
54 
55  continue;
56  }
57 
58  this->GetMCParticleToClusterListMap(pClusterList, mcPrimaryMap, mcParticleToClusterListMap);
59  }
60 
61  this->CreatePfos(mcParticleToClusterListMap);
62  return STATUS_CODE_SUCCESS;
63 }
64 
65 //------------------------------------------------------------------------------------------------------------------------------------------
66 
67 void CheatingPfoCreationAlgorithm::GetMCParticleToClusterListMap(const ClusterList *const pClusterList,
68  const LArMCParticleHelper::MCRelationMap &mcPrimaryMap, MCParticleToClusterListMap &mcParticleToClusterListMap) const
69 {
70  for (const Cluster *const pCluster : *pClusterList)
71  {
72  try
73  {
74  if (m_useOnlyAvailableClusters && !PandoraContentApi::IsAvailable(*this, pCluster))
75  continue;
76 
77  const MCParticle *pMCParticle(MCParticleHelper::GetMainMCParticle(pCluster));
78 
80  {
81  LArMCParticleHelper::MCRelationMap::const_iterator primaryIter = mcPrimaryMap.find(pMCParticle);
82 
83  if (mcPrimaryMap.end() == primaryIter)
84  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
85 
86  pMCParticle = primaryIter->second;
87  }
88 
89  if (!m_particleIdList.empty() && !m_particleIdList.count(pMCParticle->GetParticleId()))
90  continue;
91 
92  mcParticleToClusterListMap[pMCParticle].push_back(pCluster);
93  }
94  catch (const StatusCodeException &)
95  {
96  }
97  }
98 }
99 
100 //------------------------------------------------------------------------------------------------------------------------------------------
101 
102 void CheatingPfoCreationAlgorithm::CreatePfos(const MCParticleToClusterListMap &mcParticleToClusterListMap) const
103 {
104  if (mcParticleToClusterListMap.empty())
105  return;
106 
107  const PfoList *pPfoList(nullptr);
108  std::string pfoListName;
109  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pPfoList, pfoListName));
110 
111  const VertexList *pVertexList(nullptr);
112  std::string vertexListName;
113  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
114 
115  MCParticleVector mcParticleVector;
116  for (const auto &mapEntry : mcParticleToClusterListMap)
117  mcParticleVector.push_back(mapEntry.first);
118  std::sort(mcParticleVector.begin(), mcParticleVector.end(), LArMCParticleHelper::SortByMomentum);
119 
120  for (const MCParticle *const pMCParticle : mcParticleVector)
121  {
122  const ClusterList &clusterList(mcParticleToClusterListMap.at(pMCParticle));
123 
124  if (clusterList.empty())
125  continue;
126 
128  continue;
129 
130  try
131  {
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());
139 
140  const ParticleFlowObject *pPfo(nullptr);
141  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*this, pfoParameters, pPfo));
142 
143  if (m_addVertices)
144  {
145  PandoraContentApi::Vertex::Parameters parameters;
146  parameters.m_position = pMCParticle->GetVertex();
147  parameters.m_vertexLabel = VERTEX_START;
148  parameters.m_vertexType = VERTEX_3D;
149 
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));
153  }
154  }
155  catch (const StatusCodeException &)
156  {
157  std::cout << "CheatingPfoCreationAlgorithm: Could not create PFO for MCParticle with pdg code " << pMCParticle->GetParticleId()
158  << std::endl;
159  }
160  }
161 
162  if (!pPfoList->empty())
163  {
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));
166  }
167 
168  if (!pVertexList->empty())
169  {
170  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_outputVertexListName));
171 
173  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
174  }
175 }
176 
177 //------------------------------------------------------------------------------------------------------------------------------------------
178 
179 unsigned int CheatingPfoCreationAlgorithm::GetNHitTypesAboveThreshold(const ClusterList &clusterList, const unsigned int nHitsThreshold) const
180 {
181  HitTypeMap hitTypeMap;
182 
183  for (const Cluster *const pCluster : clusterList)
184  {
185  hitTypeMap[LArClusterHelper::GetClusterHitType(pCluster)] += pCluster->GetNCaloHits();
186  }
187 
188  unsigned int nGoodViews(0);
189 
190  for (const HitTypeMap::value_type &mapEntry : hitTypeMap)
191  {
192  if (mapEntry.second > nHitsThreshold)
193  ++nGoodViews;
194  }
195 
196  return nGoodViews;
197 }
198 
199 //------------------------------------------------------------------------------------------------------------------------------------------
200 
201 StatusCode CheatingPfoCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
202 {
203  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "InputClusterListNames", m_inputClusterListNames));
204 
205  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputPfoListName", m_outputPfoListName));
206 
207  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
208  XmlHelper::ReadValue(xmlHandle, "CollapseToPrimaryMCParticles", m_collapseToPrimaryMCParticles));
209 
211  {
212  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
213  }
214 
215  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
216  XmlHelper::ReadValue(xmlHandle, "UseOnlyAvailableClusters", m_useOnlyAvailableClusters));
217 
218  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "AddVertices", m_addVertices));
219 
220  if (m_addVertices)
221  {
222  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_outputVertexListName));
223 
224  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
225  XmlHelper::ReadValue(xmlHandle, "ReplaceCurrentVertexList", m_replaceCurrentVertexList));
226  }
227 
228  IntVector particleIdVector;
229  PANDORA_RETURN_RESULT_IF_AND_IF(
230  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "ParticleIdList", particleIdVector));
231 
232  m_particleIdList.insert(particleIdVector.begin(), particleIdVector.end());
233 
234  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinGoodHitTypes", m_minGoodHitTypes));
235 
236  PANDORA_RETURN_RESULT_IF_AND_IF(
237  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NHitsForGoodHitType", m_nHitsForGoodHitType));
238 
239  return STATUS_CODE_SUCCESS;
240 }
241 
242 } // namespace lar_content
std::string m_mcParticleListName
The mc particle list name.
std::string string
Definition: nybbler.cc:12
pandora::StringVector m_inputClusterListNames
The names of the input cluster lists.
intermediate_table::const_iterator const_iterator
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
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
Definition: ModuleGraph.h:25
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
std::list< Vertex > VertexList
Definition: DCEL.h:182
QTextStream & endl(QTextStream &s)