CheatingNeutrinoCreationAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArCheating/CheatingNeutrinoCreationAlgorithm.cc
3  *
4  * @brief Implementation of the cheating neutrino creation algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 CheatingNeutrinoCreationAlgorithm::CheatingNeutrinoCreationAlgorithm() : m_collapseToPrimaryMCParticles(false), m_vertexTolerance(0.5f)
22 {
23 }
24 
25 //------------------------------------------------------------------------------------------------------------------------------------------
26 
28 {
29  MCParticleVector mcNeutrinoVector;
30  this->GetMCNeutrinoVector(mcNeutrinoVector);
31 
32  for (const MCParticle *const pMCNeutrino : mcNeutrinoVector)
33  {
34  const ParticleFlowObject *pNeutrinoPfo(nullptr);
35  this->CreateAndSaveNeutrinoPfo(pMCNeutrino, pNeutrinoPfo);
36 
37  if (!pNeutrinoPfo)
38  return STATUS_CODE_FAILURE;
39 
40  this->AddNeutrinoVertex(pMCNeutrino, pNeutrinoPfo);
41 
42  MCParticleToPfoMap mcParticleToPfoMap;
43  this->GetMCParticleToDaughterPfoMap(mcParticleToPfoMap);
44  this->CreatePfoHierarchy(pMCNeutrino, pNeutrinoPfo, mcParticleToPfoMap);
45  }
46 
47  return STATUS_CODE_SUCCESS;
48 }
49 
50 //------------------------------------------------------------------------------------------------------------------------------------------
51 
53 {
54  const MCParticleList *pMCParticleList(nullptr);
55  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
56 
57  MCParticleVector allMCNeutrinoVector;
58  LArMCParticleHelper::GetTrueNeutrinos(pMCParticleList, allMCNeutrinoVector);
59 
60  for (const MCParticle *const pMCNeutrino : allMCNeutrinoVector)
61  {
62  if (LArMCParticleHelper::IsNeutrino(pMCNeutrino) && (MC_3D == pMCNeutrino->GetMCParticleType()))
63  mcNeutrinoVector.push_back(pMCNeutrino);
64  }
65 }
66 
67 //------------------------------------------------------------------------------------------------------------------------------------------
68 
69 void CheatingNeutrinoCreationAlgorithm::CreateAndSaveNeutrinoPfo(const MCParticle *const pMCNeutrino, const ParticleFlowObject *&pNeutrinoPfo) const
70 {
71  pNeutrinoPfo = nullptr;
72 
73  PandoraContentApi::ParticleFlowObject::Parameters pfoParameters;
74  pfoParameters.m_particleId = pMCNeutrino->GetParticleId();
75  pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
76  pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
77  pfoParameters.m_energy = pMCNeutrino->GetEnergy();
78  pfoParameters.m_momentum = pMCNeutrino->GetMomentum();
79 
80  std::string neutrinoPfoListName;
81  const PfoList *pNeutrinoPfoList(nullptr);
82  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pNeutrinoPfoList, neutrinoPfoListName));
83  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*this, pfoParameters, pNeutrinoPfo));
84 
85  if (!pNeutrinoPfoList || pNeutrinoPfoList->empty())
86  throw StatusCodeException(STATUS_CODE_FAILURE);
87 
88  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Pfo>(*this, m_neutrinoPfoListName));
89  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Pfo>(*this, m_neutrinoPfoListName));
90 }
91 
92 //------------------------------------------------------------------------------------------------------------------------------------------
93 
94 void CheatingNeutrinoCreationAlgorithm::AddNeutrinoVertex(const MCParticle *const pMCNeutrino, const ParticleFlowObject *const pNeutrinoPfo) const
95 {
96  const VertexList *pVertexList(nullptr);
97  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pVertexList));
98 
99  const Vertex *pNeutrinoVertex(nullptr);
100  float closestVertexDistance(std::numeric_limits<float>::max());
101 
102  for (const Vertex *const pVertex : *pVertexList)
103  {
104  const float distance((pVertex->GetPosition() - pMCNeutrino->GetEndpoint()).GetMagnitude());
105 
106  if (distance < closestVertexDistance)
107  {
108  pNeutrinoVertex = pVertex;
109  closestVertexDistance = distance;
110  }
111  }
112 
113  if (!pNeutrinoVertex || (VERTEX_3D != pNeutrinoVertex->GetVertexType()) ||
114  ((pNeutrinoVertex->GetPosition() - pMCNeutrino->GetEndpoint()).GetMagnitude() > m_vertexTolerance))
115  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
116 
117  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pNeutrinoPfo, pNeutrinoVertex));
118 }
119 
120 //------------------------------------------------------------------------------------------------------------------------------------------
121 
123 {
125 
127  {
128  const MCParticleList *pMCParticleList(nullptr);
129  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
130 
131  LArMCParticleHelper::GetMCPrimaryMap(pMCParticleList, mcPrimaryMap);
132  }
133 
134  for (const std::string &daughterPfoListName : m_daughterPfoListNames)
135  {
136  const PfoList *pDaughterPfoList(nullptr);
137 
138  if (STATUS_CODE_SUCCESS != PandoraContentApi::GetList(*this, daughterPfoListName, pDaughterPfoList))
139  {
140  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
141  std::cout << "CheatingNeutrinoCreationAlgorithm: pfo list " << daughterPfoListName << " unavailable." << std::endl;
142 
143  continue;
144  }
145 
146  for (const ParticleFlowObject *const pDaughterPfo : *pDaughterPfoList)
147  {
148  const MCParticle *pMCParticle(LArMCParticleHelper::GetMainMCParticle(pDaughterPfo));
149 
151  {
152  LArMCParticleHelper::MCRelationMap::const_iterator primaryIter = mcPrimaryMap.find(pMCParticle);
153 
154  if (mcPrimaryMap.end() == primaryIter)
155  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
156 
157  pMCParticle = primaryIter->second;
158  }
159 
160  if (!mcParticleToPfoMap.insert(MCParticleToPfoMap::value_type(pMCParticle, pDaughterPfo)).second)
161  throw StatusCodeException(STATUS_CODE_OUT_OF_RANGE);
162  }
163  }
164 }
165 
166 //------------------------------------------------------------------------------------------------------------------------------------------
167 
168 void CheatingNeutrinoCreationAlgorithm::CreatePfoHierarchy(const MCParticle *const pParentMCParticle,
169  const ParticleFlowObject *const pParentPfo, const MCParticleToPfoMap &mcParticleToPfoMap) const
170 {
171  for (const MCParticle *const pDaughterMCParticle : pParentMCParticle->GetDaughterList())
172  {
173  MCParticleToPfoMap::const_iterator mapIter = mcParticleToPfoMap.find(pDaughterMCParticle);
174 
175  if (mcParticleToPfoMap.end() == mapIter)
176  {
177  this->CreatePfoHierarchy(pDaughterMCParticle, pParentPfo, mcParticleToPfoMap);
178  continue;
179  }
180 
181  const ParticleFlowObject *const pDaughterPfo(mapIter->second);
182  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pParentPfo, pDaughterPfo));
183  this->CreatePfoHierarchy(pDaughterMCParticle, pDaughterPfo, mcParticleToPfoMap);
184  }
185 }
186 
187 //------------------------------------------------------------------------------------------------------------------------------------------
188 
189 StatusCode CheatingNeutrinoCreationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
190 {
191  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
192  XmlHelper::ReadValue(xmlHandle, "CollapseToPrimaryMCParticles", m_collapseToPrimaryMCParticles));
193 
194  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
195 
196  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "NeutrinoPfoListName", m_neutrinoPfoListName));
197 
198  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "VertexListName", m_vertexListName));
199 
200  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "DaughterPfoListNames", m_daughterPfoListNames));
201 
202  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VertexTolerance", m_vertexTolerance));
203 
204  return STATUS_CODE_SUCCESS;
205 }
206 
207 } // namespace lar_content
Header file for the pfo helper class.
std::string string
Definition: nybbler.cc:12
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
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 const pandora::MCParticle * GetMainMCParticle(const pandora::ParticleFlowObject *const pPfo)
Find the mc particle making the largest contribution to 2D clusters in a specified pfo...
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.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
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:182
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.
QTextStream & endl(QTextStream &s)