9 #include "Pandora/AlgorithmHeaders.h" 21 NeutrinoHierarchyAlgorithm::NeutrinoHierarchyAlgorithm() :
22 m_halfWindowLayers(20),
23 m_displayPfoInfoMap(false)
32 for (
const auto &mapEntry : pfoInfoMap) sortedPfos.push_back(mapEntry.first);
35 for (
const Pfo *
const pPfo : sortedPfos)
37 const PfoInfo *
const pPfoInfo(pfoInfoMap.at(pPfo));
39 if (pPfoInfo->IsNeutrinoVertexAssociated() || pPfoInfo->GetParentPfo())
41 assignedPfos.push_back(pPfoInfo->GetThisPfo());
45 unassignedPfos.push_back(pPfoInfo->GetThisPfo());
54 const ParticleFlowObject *pNeutrinoPfo(
nullptr);
55 PfoList candidateDaughterPfoList;
62 catch (StatusCodeException &statusCodeException)
64 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
65 std::cout <<
"NeutrinoHierarchyAlgorithm: required input pfos unavailable." << std::endl;
67 if (STATUS_CODE_NOT_FOUND != statusCodeException.GetStatusCode())
68 throw statusCodeException;
70 return STATUS_CODE_SUCCESS;
77 if (!pNeutrinoPfo->GetVertexList().empty())
83 pPfoRelationTool->Run(
this, pNeutrinoVertex, pfoInfoMap);
88 catch (StatusCodeException &statusCodeException)
90 std::cout <<
"NeutrinoHierarchyAlgorithm: unable to process input neutrino pfo, " << statusCodeException.ToString() << std::endl;
96 for (
auto &mapIter : pfoInfoMap)
97 delete mapIter.second;
99 return STATUS_CODE_SUCCESS;
106 const PfoList *pPfoList =
nullptr;
107 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_neutrinoPfoListName, pPfoList));
109 if (!pPfoList || pPfoList->empty())
111 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
112 std::cout <<
"NeutrinoHierarchyAlgorithm: unable to find pfo list " <<
m_neutrinoPfoListName << std::endl;
114 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
118 pNeutrinoPfo = ((1 == pPfoList->size()) ? *(pPfoList->begin()) :
nullptr);
121 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
130 const PfoList *pCandidatePfoList(
nullptr);
132 if (STATUS_CODE_SUCCESS == PandoraContentApi::GetList(*
this, daughterPfoListName, pCandidatePfoList))
134 candidateDaughterPfoList.insert(candidateDaughterPfoList.end(), pCandidatePfoList->begin(), pCandidatePfoList->end());
136 else if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
138 std::cout <<
"NeutrinoHierarchyAlgorithm: unable to find pfo list " << daughterPfoListName << std::endl;
142 if (candidateDaughterPfoList.empty())
143 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
152 for (
const ParticleFlowObject *
const pPfo : pfoList)
159 (void) pfoInfoMap.insert(PfoInfoMap::value_type(pPfo, pPfoInfo));
161 catch (StatusCodeException &)
163 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
164 std::cout <<
"NeutrinoHierarchyAlgorithm: Unable to calculate pfo information " << std::endl;
176 PfoVector candidateDaughterPfoVector(candidateDaughterPfoList.begin(), candidateDaughterPfoList.end());
180 for (
const ParticleFlowObject *
const pDaughterPfo : candidateDaughterPfoVector)
184 if ((pfoInfoMap.end() != iter) && (iter->second->IsNeutrinoVertexAssociated()))
185 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*
this, pNeutrinoPfo, pDaughterPfo));
189 PfoVector sortedPfos;
190 for (
const auto &mapEntry : pfoInfoMap) sortedPfos.push_back(mapEntry.first);
193 for (
const Pfo *
const pPfo : sortedPfos)
195 const PfoInfo *
const pPfoInfo(pfoInfoMap.at(pPfo));
197 PfoVector daughterPfos(pPfoInfo->GetDaughterPfoList().begin(), pPfoInfo->GetDaughterPfoList().end());
200 for (
const ParticleFlowObject *
const pDaughterPfo : daughterPfos)
201 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*
this, pPfoInfo->GetThisPfo(), pDaughterPfo));
205 for (
const ParticleFlowObject *
const pRemainingPfo : candidateDaughterPfoVector)
207 if (!pRemainingPfo->GetParentPfoList().empty())
211 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*
this, pNeutrinoPfo, pRemainingPfo));
220 PANDORA_MONITORING_API(SetEveDisplayParameters(this->GetPandora(),
false, DETECTOR_VIEW_XZ, -1.
f, -1.
f, 1.
f));
221 std::cout <<
"-Neutrino Pfo, nDaughters " << pNeutrinoPfo->GetDaughterPfoList().size() <<
", nVertices " << pNeutrinoPfo->GetVertexList().size() << std::endl;
223 PfoVector sortedPfos;
224 for (
const auto &mapEntry : pfoInfoMap) sortedPfos.push_back(mapEntry.first);
227 for (
const Pfo *
const pPfo : sortedPfos)
229 const PfoInfo *
const pPfoInfo(pfoInfoMap.at(pPfo));
231 std::cout <<
"Pfo " << pPfoInfo->
GetThisPfo() <<
", vtxAssoc " << pPfoInfo->IsNeutrinoVertexAssociated()
232 <<
", parent " << pPfoInfo->GetParentPfo() <<
", nDaughters " << pPfoInfo->GetDaughterPfoList().size() <<
" (";
234 for (
const ParticleFlowObject *
const pDaughterPfo : pPfoInfo->GetDaughterPfoList()) std::cout << pDaughterPfo <<
" ";
235 std::cout <<
") " << std::endl;
237 if (pPfoInfo->IsNeutrinoVertexAssociated())
240 const PfoList tempPfoList(1, pPfoInfo->GetThisPfo());
241 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &tempPfoList,
"VertexPfo", RED,
true,
false));
247 PANDORA_MONITORING_API(VisualizeVertices(this->GetPandora(), &(pNeutrinoPfo->GetVertexList()),
"NeutrinoVertex", ORANGE));
248 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
252 for (
const Pfo *
const pPfo : sortedPfos)
254 const PfoInfo *
const pPfoInfo(pfoInfoMap.at(pPfo));
256 if (!pPfoInfo->GetDaughterPfoList().empty())
259 const PfoList tempPfoList(1, pPfoInfo->GetThisPfo());
260 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &tempPfoList,
"ParentPfo", RED,
true,
false));
261 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &(pPfoInfo->GetDaughterPfoList()),
"DaughterPfos", BLUE,
true,
false));
262 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
271 const float layerPitch) :
273 m_pCluster3D(nullptr),
274 m_pVertex3D(nullptr),
275 m_pSlidingFitResult3D(nullptr),
276 m_isNeutrinoVertexAssociated(false),
277 m_isInnerLayerAssociated(false),
278 m_pParentPfo(nullptr)
280 ClusterList clusterList3D;
283 if (1 != clusterList3D.size())
284 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
290 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
306 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
319 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
363 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
380 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
392 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
402 AlgorithmToolVector algorithmToolVector;
403 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
404 "PfoRelationTools", algorithmToolVector));
408 PfoRelationTool *
const pPfoRelationTool(dynamic_cast<PfoRelationTool*>(*iter));
410 if (!pPfoRelationTool)
411 return STATUS_CODE_INVALID_PARAMETER;
416 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
419 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
422 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
425 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
428 return STATUS_CODE_SUCCESS;
void SetInnerLayerAssociation(const bool isInnerLayerAssociated)
Set the inner layer association flag.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const pandora::ParticleFlowObject * GetThisPfo() const
Get the address of the pfo.
unsigned int GetLayerFitHalfWindow() const
Get the layer fit half window.
const pandora::Cluster * m_pCluster3D
The address of the three dimensional cluster.
PfoInfo & operator=(const PfoInfo &rhs)
Assignment operator.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
bool m_isNeutrinoVertexAssociated
Whether the pfo is associated with the neutrino vertex.
std::unordered_map< const pandora::ParticleFlowObject *, PfoInfo * > PfoInfoMap
PfoRelationToolVector m_algorithmToolVector
The algorithm tool vector.
const pandora::ParticleFlowObject * m_pThisPfo
The address of the pfo.
bool m_displayPfoInfoMap
Whether to display the pfo info map (if monitoring is enabled)
void ProcessPfoInfoMap(const pandora::ParticleFlowObject *const pNeutrinoPfo, const pandora::PfoList &candidateDaughterPfoList, const PfoInfoMap &pfoInfoMap) const
Process the information in a pfo info map, creating pfo parent/daughter links.
void DisplayPfoInfoMap(const pandora::ParticleFlowObject *const pNeutrinoPfo, const PfoInfoMap &pfoInfoMap) const
Display the information in a pfo info map, visualising pfo parent/daughter links. ...
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
void SeparatePfos(const NeutrinoHierarchyAlgorithm::PfoInfoMap &pfoInfoMap, pandora::PfoVector &assignedPfos, pandora::PfoVector &unassignedPfos) const
Query the pfo info map and separate/extract pfos currently either acting as parents or associated wit...
unsigned int m_halfWindowLayers
The number of layers to use for half-window of sliding fit.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
bool m_isInnerLayerAssociated
If associated, whether association to parent (vtx or pfo) is at sliding fit inner layer...
void RemoveDaughterPfo(const pandora::ParticleFlowObject *const pDaughterPfo)
Remove a daughter pfo.
Header file for the geometry helper class.
ThreeDSlidingFitResult * m_pSlidingFitResult3D
The three dimensional sliding fit result.
pandora::StatusCode Run()
pandora::PfoList m_daughterPfoList
The daughter pfo list.
void SetParentPfo(const pandora::ParticleFlowObject *const pParentPfo)
Set the parent pfo.
float GetLayerPitch() const
Get the layer pitch, units cm.
void RemoveParentPfo()
Remove the parent pfo.
void GetNeutrinoPfo(const pandora::ParticleFlowObject *&pNeutrinoPfo) const
Get the address of the input neutrino pfo - enforces only one pfo present in input list; can return N...
static bool IsNeutrino(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a neutrino or (antineutrino)
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
PfoInfo(const pandora::ParticleFlowObject *const pPfo, const unsigned int halfWindowLayers, const float layerPitch)
Constructor.
Header file for the neutrino hierarchy algorithm class.
std::string m_neutrinoPfoListName
The neutrino pfo list name.
const pandora::Vertex * m_pVertex3D
The address of the three dimensional vertex.
pandora::StringVector m_daughterPfoListNames
The list of daughter pfo list names.
void SetNeutrinoVertexAssociation(const bool isNeutrinoVertexAssociated)
Set the neutrino vertex association flag.
ThreeDSlidingFitResult class.
const TwoDSlidingFitResult & GetFirstFitResult() const
Get the first sliding fit result for this cluster.
void AddDaughterPfo(const pandora::ParticleFlowObject *const pDaughterPfo)
Add a daughter pfo.
const pandora::ParticleFlowObject * m_pParentPfo
The address of the parent pfo.
void GetCandidateDaughterPfoList(pandora::PfoList &candidateDaughterPfoList) const
Get the list of candidate daughter pfos.
NeutrinoHierarchyAlgorithm::PfoInfo PfoInfo
void GetInitialPfoInfoMap(const pandora::PfoList &pfoList, PfoInfoMap &pfoInfoMap) const
Process a provided pfo list and populate an initial pfo info map.