LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
CheatingPfoCreationAlgorithm.cc
Go to the documentation of this file.
1 
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, const LArMCParticleHelper::MCRelationMap &mcPrimaryMap,
68  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 void CheatingPfoCreationAlgorithm::CreatePfos(const MCParticleToClusterListMap &mcParticleToClusterListMap) const
101 {
102  if (mcParticleToClusterListMap.empty())
103  return;
104 
105  const PfoList *pPfoList(nullptr); std::string pfoListName;
106  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pPfoList, pfoListName));
107 
108  const VertexList *pVertexList(nullptr); std::string vertexListName;
109  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
110 
111  MCParticleVector mcParticleVector;
112  for (const auto &mapEntry : mcParticleToClusterListMap) mcParticleVector.push_back(mapEntry.first);
113  std::sort(mcParticleVector.begin(), mcParticleVector.end(), LArMCParticleHelper::SortByMomentum);
114 
115  for (const MCParticle *const pMCParticle : mcParticleVector)
116  {
117  const ClusterList &clusterList(mcParticleToClusterListMap.at(pMCParticle));
118 
119  if (clusterList.empty())
120  continue;
121 
123  continue;
124 
125  try
126  {
127  PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
128  pfoParameters.m_particleId = pMCParticle->GetParticleId();
129  pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
130  pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
131  pfoParameters.m_energy = pMCParticle->GetEnergy();
132  pfoParameters.m_momentum = pMCParticle->GetMomentum();
133  pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), clusterList.begin(), clusterList.end());
134 
135  const ParticleFlowObject *pPfo(nullptr);
136  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*this, pfoParameters, pPfo));
137 
138  if (m_addVertices)
139  {
140  PandoraContentApi::Vertex::Parameters parameters;
141  parameters.m_position = pMCParticle->GetVertex();
142  parameters.m_vertexLabel = VERTEX_START;
143  parameters.m_vertexType = VERTEX_3D;
144 
145  const Vertex *pVertex(nullptr);
146  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
147  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*this, pPfo, pVertex));
148  }
149  }
150  catch (const StatusCodeException &)
151  {
152  std::cout << "CheatingPfoCreationAlgorithm: Could not create PFO for MCParticle with pdg code " << pMCParticle->GetParticleId() << std::endl;
153  }
154  }
155 
156  if (!pPfoList->empty())
157  {
158  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*this, m_outputPfoListName));
159  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Pfo>(*this, m_outputPfoListName));
160  }
161 
162  if (!pVertexList->empty())
163  {
164  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_outputVertexListName));
165 
167  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
168  }
169 }
170 
171 //------------------------------------------------------------------------------------------------------------------------------------------
172 
173 unsigned int CheatingPfoCreationAlgorithm::GetNHitTypesAboveThreshold(const ClusterList &clusterList, const unsigned int nHitsThreshold) const
174 {
175  HitTypeMap hitTypeMap;
176 
177  for (const Cluster *const pCluster : clusterList)
178  {
179  hitTypeMap[LArClusterHelper::GetClusterHitType(pCluster)] += pCluster->GetNCaloHits();
180  }
181 
182  unsigned int nGoodViews(0);
183 
184  for (const HitTypeMap::value_type &mapEntry : hitTypeMap)
185  {
186  if (mapEntry.second > nHitsThreshold)
187  ++nGoodViews;
188  }
189 
190  return nGoodViews;
191 }
192 
193 //------------------------------------------------------------------------------------------------------------------------------------------
194 
195 StatusCode CheatingPfoCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
196 {
197  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
198  "InputClusterListNames", m_inputClusterListNames));
199 
200  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
201  "OutputPfoListName", m_outputPfoListName));
202 
203  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
204  "CollapseToPrimaryMCParticles", m_collapseToPrimaryMCParticles));
205 
207  {
208  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
209  "MCParticleListName", m_mcParticleListName));
210  }
211 
212  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
213  "UseOnlyAvailableClusters", m_useOnlyAvailableClusters));
214 
215  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
216  "AddVertices", m_addVertices));
217 
218  if (m_addVertices)
219  {
220  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
221  "OutputVertexListName", m_outputVertexListName));
222 
223  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
224  "ReplaceCurrentVertexList", m_replaceCurrentVertexList));
225  }
226 
227  IntVector particleIdVector;
228  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
229  "ParticleIdList", particleIdVector));
230 
231  m_particleIdList.insert(particleIdVector.begin(), particleIdVector.end());
232 
233  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
234  "MinGoodHitTypes", m_minGoodHitTypes));
235 
236  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
237  "NHitsForGoodHitType", m_nHitsForGoodHitType));
238 
239  return STATUS_CODE_SUCCESS;
240 }
241 
242 } // namespace lar_content
std::string m_mcParticleListName
The mc particle list name.
pandora::StringVector m_inputClusterListNames
The names of the input cluster lists.
std::unordered_map< const pandora::MCParticle *, pandora::ClusterList > MCParticleToClusterListMap
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
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::vector< art::Ptr< simb::MCParticle > > MCParticleVector
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
intermediate_table::const_iterator const_iterator
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.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
std::list< Vertex > VertexList
Definition: DCEL.h:178