LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
CheatingNeutrinoCreationAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 CheatingNeutrinoCreationAlgorithm::CheatingNeutrinoCreationAlgorithm() :
22  m_collapseToPrimaryMCParticles(false),
23  m_vertexTolerance(0.5f)
24 {
25 }
26 
27 //------------------------------------------------------------------------------------------------------------------------------------------
28 
30 {
31  MCParticleVector mcNeutrinoVector;
32  this->GetMCNeutrinoVector(mcNeutrinoVector);
33 
34  for (const MCParticle *const pMCNeutrino : mcNeutrinoVector)
35  {
36  const ParticleFlowObject *pNeutrinoPfo(nullptr);
37  this->CreateAndSaveNeutrinoPfo(pMCNeutrino, pNeutrinoPfo);
38 
39  if (!pNeutrinoPfo)
40  return STATUS_CODE_FAILURE;
41 
42  this->AddNeutrinoVertex(pMCNeutrino, pNeutrinoPfo);
43 
44  MCParticleToPfoMap mcParticleToPfoMap;
45  this->GetMCParticleToDaughterPfoMap(mcParticleToPfoMap);
46  this->CreatePfoHierarchy(pMCNeutrino, pNeutrinoPfo, mcParticleToPfoMap);
47  }
48 
49  return STATUS_CODE_SUCCESS;
50 }
51 
52 //------------------------------------------------------------------------------------------------------------------------------------------
53 
55 {
56  const MCParticleList *pMCParticleList(nullptr);
57  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
58 
59  MCParticleVector allMCNeutrinoVector;
60  LArMCParticleHelper::GetTrueNeutrinos(pMCParticleList, allMCNeutrinoVector);
61 
62  for (const MCParticle *const pMCNeutrino : allMCNeutrinoVector)
63  {
64  if (LArMCParticleHelper::IsNeutrino(pMCNeutrino) && (MC_3D == pMCNeutrino->GetMCParticleType()))
65  mcNeutrinoVector.push_back(pMCNeutrino);
66  }
67 }
68 
69 //------------------------------------------------------------------------------------------------------------------------------------------
70 
71 void CheatingNeutrinoCreationAlgorithm::CreateAndSaveNeutrinoPfo(const MCParticle *const pMCNeutrino, const ParticleFlowObject *&pNeutrinoPfo) const
72 {
73  pNeutrinoPfo = nullptr;
74 
75  PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
76  pfoParameters.m_particleId = pMCNeutrino->GetParticleId();
77  pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
78  pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
79  pfoParameters.m_energy = pMCNeutrino->GetEnergy();
80  pfoParameters.m_momentum = pMCNeutrino->GetMomentum();
81 
82  std::string neutrinoPfoListName;
83  const PfoList *pNeutrinoPfoList(nullptr);
84  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pNeutrinoPfoList, neutrinoPfoListName));
85  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*this, pfoParameters, pNeutrinoPfo));
86 
87  if (!pNeutrinoPfoList || pNeutrinoPfoList->empty())
88  throw StatusCodeException(STATUS_CODE_FAILURE);
89 
90  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*this, m_neutrinoPfoListName));
91  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Pfo>(*this, m_neutrinoPfoListName));
92 }
93 
94 //------------------------------------------------------------------------------------------------------------------------------------------
95 
96 void CheatingNeutrinoCreationAlgorithm::AddNeutrinoVertex(const MCParticle *const pMCNeutrino, const ParticleFlowObject *const pNeutrinoPfo) const
97 {
98  const VertexList *pVertexList(nullptr);
99  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pVertexList));
100 
101  const Vertex *pNeutrinoVertex(nullptr);
102  float closestVertexDistance(std::numeric_limits<float>::max());
103 
104  for (const Vertex *const pVertex : *pVertexList)
105  {
106  const float distance((pVertex->GetPosition() - pMCNeutrino->GetEndpoint()).GetMagnitude());
107 
108  if (distance < closestVertexDistance)
109  {
110  pNeutrinoVertex = pVertex;
111  closestVertexDistance = distance;
112  }
113  }
114 
115  if (!pNeutrinoVertex || (VERTEX_3D != pNeutrinoVertex->GetVertexType()) ||
116  ((pNeutrinoVertex->GetPosition() - pMCNeutrino->GetEndpoint()).GetMagnitude() > m_vertexTolerance))
117  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
118 
119  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pNeutrinoPfo, pNeutrinoVertex));
120 }
121 
122 //------------------------------------------------------------------------------------------------------------------------------------------
123 
125 {
127 
129  {
130  const MCParticleList *pMCParticleList(nullptr);
131  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
132 
133  LArMCParticleHelper::GetMCPrimaryMap(pMCParticleList, mcPrimaryMap);
134  }
135 
136  for (const std::string &daughterPfoListName : m_daughterPfoListNames)
137  {
138  const PfoList *pDaughterPfoList(nullptr);
139 
140  if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*this, daughterPfoListName, pDaughterPfoList))
141  {
142  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
143  std::cout << "CheatingNeutrinoCreationAlgorithm: pfo list " << daughterPfoListName << " unavailable." << std::endl;
144 
145  continue;
146  }
147 
148  for (const ParticleFlowObject *const pDaughterPfo : *pDaughterPfoList)
149  {
150  const MCParticle *pMCParticle(LArMCParticleHelper::GetMainMCParticle(pDaughterPfo));
151 
153  {
154  LArMCParticleHelper::MCRelationMap::const_iterator primaryIter = mcPrimaryMap.find(pMCParticle);
155 
156  if (mcPrimaryMap.end() == primaryIter)
157  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
158 
159  pMCParticle = primaryIter->second;
160  }
161 
162  if (!mcParticleToPfoMap.insert(MCParticleToPfoMap::value_type(pMCParticle, pDaughterPfo)).second)
163  throw StatusCodeException(STATUS_CODE_OUT_OF_RANGE);
164  }
165  }
166 }
167 
168 //------------------------------------------------------------------------------------------------------------------------------------------
169 
170 void CheatingNeutrinoCreationAlgorithm::CreatePfoHierarchy(const MCParticle *const pParentMCParticle,
171  const ParticleFlowObject *const pParentPfo, const MCParticleToPfoMap &mcParticleToPfoMap) const
172 {
173  for (const MCParticle *const pDaughterMCParticle : pParentMCParticle->GetDaughterList())
174  {
175  MCParticleToPfoMap::const_iterator mapIter = mcParticleToPfoMap.find(pDaughterMCParticle);
176 
177  if (mcParticleToPfoMap.end() == mapIter)
178  {
179  this->CreatePfoHierarchy(pDaughterMCParticle, pParentPfo, mcParticleToPfoMap);
180  continue;
181  }
182 
183  const ParticleFlowObject *const pDaughterPfo(mapIter->second);
184  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pParentPfo, pDaughterPfo));
185  this->CreatePfoHierarchy(pDaughterMCParticle, pDaughterPfo, mcParticleToPfoMap);
186  }
187 }
188 
189 //------------------------------------------------------------------------------------------------------------------------------------------
190 
191 StatusCode CheatingNeutrinoCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
192 {
193  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
194  XmlHelper::ReadValue(xmlHandle, "CollapseToPrimaryMCParticles", m_collapseToPrimaryMCParticles));
195 
196  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
197 
198  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "NeutrinoPfoListName", m_neutrinoPfoListName));
199 
200  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "VertexListName", m_vertexListName));
201 
202  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "DaughterPfoListNames", m_daughterPfoListNames));
203 
204  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VertexTolerance", m_vertexTolerance));
205 
206  return STATUS_CODE_SUCCESS;
207 }
208 
209 } // namespace lar_content
Header file for the pfo helper class.
std::string m_neutrinoPfoListName
The name of the neutrino pfo list.
std::unordered_map< const pandora::MCParticle *, const pandora::ParticleFlowObject * > MCParticleToPfoMap
float m_vertexTolerance
Tolerance, 3d displacement, allowed between reco neutrino vertex and mc neutrino endpoint.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
intermediate_table::const_iterator const_iterator
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 const pandora::MCParticle * GetMainMCParticle(const pandora::ParticleFlowObject *const pPfo)
Find the mc particle making the largest contribution to 2D clusters in a specified pfo...
TFile f
Definition: plotHisto.C:6
std::string m_mcParticleListName
The name of the three d mc particle list name.
void CreatePfoHierarchy(const pandora::MCParticle *const pParentMCParticle, const pandora::ParticleFlowObject *const pParentPfo, const MCParticleToPfoMap &mcParticleToPfoMap) const
Use information from mc particles and the mc particle to pfo map to fully-reconstruct the daughter pf...
Header file for the lar monte carlo particle helper helper class.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
pandora::StringVector m_daughterPfoListNames
The list of daughter pfo list names.
void GetMCParticleToDaughterPfoMap(MCParticleToPfoMap &mcParticleToPfoMap) const
Extract candidate daughter pfos from external lists and populate a map from main mc particle (or prim...
static void GetTrueNeutrinos(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &trueNeutrinos)
Get neutrino MC particles from an input MC particle list.
Header file for the cheating neutrino creation algorithm class.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
std::string m_vertexListName
The name of the neutrino vertex list.
bool m_collapseToPrimaryMCParticles
Whether to collapse mc particle hierarchies to primary particles.
void GetMCNeutrinoVector(pandora::MCParticleVector &mcNeutrinoVector) const
Get the mc neutrino vector.
void AddNeutrinoVertex(const pandora::MCParticle *const pMCNeutrino, const pandora::ParticleFlowObject *const pNeutrinoPfo) const
Extract reconstructed vertex from external list, check its position agrees with mc neutrino...
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
std::list< Vertex > VertexList
Definition: DCEL.h:169
static bool IsNeutrino(const pandora::MCParticle *const pMCParticle)
Whether a mc particle is a neutrino or antineutrino.
void CreateAndSaveNeutrinoPfo(const pandora::MCParticle *const pMCNeutrino, const pandora::ParticleFlowObject *&pNeutrinoPfo) const
Create and save a neutrino pfo with properties dictated by the mc neutrino.