All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
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 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)
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...
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
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.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
void GetMCParticleToDaughterPfoMap(MCParticleToPfoMap &mcParticleToPfoMap) const
Extract candidate daughter pfos from external lists and populate a map from main mc particle (or prim...
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
Definition: reco_sbnd.fcl:182
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.
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
BEGIN_PROLOG could also be cout
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.