All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NeutrinoHierarchyAlgorithm.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArThreeDReco/LArEventBuilding/NeutrinoHierarchyAlgorithm.cc
3  *
4  * @brief Implementation of the neutrino hierarchy algorithm class.
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
14 
16 
17 using namespace pandora;
18 
19 namespace lar_content
20 {
21 
22 NeutrinoHierarchyAlgorithm::NeutrinoHierarchyAlgorithm() : m_halfWindowLayers(20), m_displayPfoInfoMap(false)
23 {
24 }
25 
26 //------------------------------------------------------------------------------------------------------------------------------------------
27 
28 void NeutrinoHierarchyAlgorithm::SeparatePfos(const PfoInfoMap &pfoInfoMap, PfoVector &assignedPfos, PfoVector &unassignedPfos) const
29 {
30  PfoVector sortedPfos;
31  for (const auto &mapEntry : pfoInfoMap)
32  sortedPfos.push_back(mapEntry.first);
33  std::sort(sortedPfos.begin(), sortedPfos.end(), LArPfoHelper::SortByNHits);
34 
35  for (const Pfo *const pPfo : sortedPfos)
36  {
37  const PfoInfo *const pPfoInfo(pfoInfoMap.at(pPfo));
38 
39  if (pPfoInfo->IsNeutrinoVertexAssociated() || pPfoInfo->GetParentPfo())
40  {
41  assignedPfos.push_back(pPfoInfo->GetThisPfo());
42  }
43  else
44  {
45  unassignedPfos.push_back(pPfoInfo->GetThisPfo());
46  }
47  }
48 }
49 
50 //------------------------------------------------------------------------------------------------------------------------------------------
51 
53 {
54  const ParticleFlowObject *pNeutrinoPfo(nullptr);
55  PfoList candidateDaughterPfoList;
56 
57  try
58  {
59  this->GetNeutrinoPfo(pNeutrinoPfo);
60  this->GetCandidateDaughterPfoList(candidateDaughterPfoList);
61  }
62  catch (StatusCodeException &statusCodeException)
63  {
64  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
65  std::cout << "NeutrinoHierarchyAlgorithm: required input pfos unavailable." << std::endl;
66 
67  if (STATUS_CODE_NOT_FOUND != statusCodeException.GetStatusCode())
68  throw statusCodeException;
69 
70  return STATUS_CODE_SUCCESS;
71  }
72 
73  PfoInfoMap pfoInfoMap;
74 
75  try
76  {
77  if (!pNeutrinoPfo->GetVertexList().empty())
78  {
79  const Vertex *const pNeutrinoVertex(LArPfoHelper::GetVertex(pNeutrinoPfo));
80  this->GetInitialPfoInfoMap(candidateDaughterPfoList, pfoInfoMap);
81 
82  for (PfoRelationTool *const pPfoRelationTool : m_algorithmToolVector)
83  pPfoRelationTool->Run(this, pNeutrinoVertex, pfoInfoMap);
84  }
85 
86  this->ProcessPfoInfoMap(pNeutrinoPfo, candidateDaughterPfoList, pfoInfoMap);
87  }
88  catch (StatusCodeException &statusCodeException)
89  {
90  std::cout << "NeutrinoHierarchyAlgorithm: unable to process input neutrino pfo, " << statusCodeException.ToString() << std::endl;
91  }
92 
94  this->DisplayPfoInfoMap(pNeutrinoPfo, pfoInfoMap);
95 
96  for (auto &mapIter : pfoInfoMap)
97  delete mapIter.second;
98 
99  return STATUS_CODE_SUCCESS;
100 }
101 
102 //------------------------------------------------------------------------------------------------------------------------------------------
103 
104 void NeutrinoHierarchyAlgorithm::GetNeutrinoPfo(const ParticleFlowObject *&pNeutrinoPfo) const
105 {
106  const PfoList *pPfoList = nullptr;
107  PANDORA_THROW_RESULT_IF_AND_IF(
108  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_neutrinoPfoListName, pPfoList));
109 
110  if (!pPfoList || pPfoList->empty())
111  {
112  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
113  std::cout << "NeutrinoHierarchyAlgorithm: unable to find pfo list " << m_neutrinoPfoListName << std::endl;
114 
115  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
116  }
117 
118  // ATTN Enforces that only one pfo, of neutrino-type, be in the specified input list
119  pNeutrinoPfo = ((1 == pPfoList->size()) ? *(pPfoList->begin()) : nullptr);
120 
121  if (!pNeutrinoPfo || !LArPfoHelper::IsNeutrino(pNeutrinoPfo))
122  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
123 }
124 
125 //------------------------------------------------------------------------------------------------------------------------------------------
126 
127 void NeutrinoHierarchyAlgorithm::GetCandidateDaughterPfoList(PfoList &candidateDaughterPfoList) const
128 {
129  for (const std::string &daughterPfoListName : m_daughterPfoListNames)
130  {
131  const PfoList *pCandidatePfoList(nullptr);
132 
133  if (STATUS_CODE_SUCCESS == PandoraContentApi::GetList(*this, daughterPfoListName, pCandidatePfoList))
134  {
135  candidateDaughterPfoList.insert(candidateDaughterPfoList.end(), pCandidatePfoList->begin(), pCandidatePfoList->end());
136  }
137  else if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
138  {
139  std::cout << "NeutrinoHierarchyAlgorithm: unable to find pfo list " << daughterPfoListName << std::endl;
140  }
141  }
142 
143  if (candidateDaughterPfoList.empty())
144  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
145 }
146 
147 //------------------------------------------------------------------------------------------------------------------------------------------
148 
149 void NeutrinoHierarchyAlgorithm::GetInitialPfoInfoMap(const PfoList &pfoList, PfoInfoMap &pfoInfoMap) const
150 {
151  const float layerPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
152 
153  for (const ParticleFlowObject *const pPfo : pfoList)
154  {
155  PfoInfo *pPfoInfo(nullptr);
156 
157  try
158  {
159  pPfoInfo = new PfoInfo(pPfo, m_halfWindowLayers, layerPitch);
160  (void)pfoInfoMap.insert(PfoInfoMap::value_type(pPfo, pPfoInfo));
161  }
162  catch (StatusCodeException &)
163  {
164  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
165  std::cout << "NeutrinoHierarchyAlgorithm: Unable to calculate pfo information " << std::endl;
166 
167  delete pPfoInfo;
168  }
169  }
170 }
171 
172 //------------------------------------------------------------------------------------------------------------------------------------------
173 
174 void NeutrinoHierarchyAlgorithm::ProcessPfoInfoMap(const ParticleFlowObject *const pNeutrinoPfo, const PfoList &candidateDaughterPfoList,
175  PfoInfoMap &pfoInfoMap, const unsigned int callDepth) const
176 {
177  PfoVector candidateDaughterPfoVector(candidateDaughterPfoList.begin(), candidateDaughterPfoList.end());
178  std::sort(candidateDaughterPfoVector.begin(), candidateDaughterPfoVector.end(), LArPfoHelper::SortByNHits);
179 
180  // Add neutrino->primary pfo links
181  for (const ParticleFlowObject *const pDaughterPfo : candidateDaughterPfoVector)
182  {
183  PfoInfoMap::const_iterator iter = pfoInfoMap.find(pDaughterPfo);
184 
185  if ((pfoInfoMap.end() != iter) && (iter->second->IsNeutrinoVertexAssociated()))
186  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pNeutrinoPfo, pDaughterPfo));
187  }
188 
189  // Handle exceptional case where vertex selected far from any other particle passing creation thresholds
190  if ((0 == callDepth) && (0 == pNeutrinoPfo->GetNDaughterPfos()))
191  {
192  this->AdjustVertexAndPfoInfo(pNeutrinoPfo, candidateDaughterPfoList, pfoInfoMap);
193  return this->ProcessPfoInfoMap(pNeutrinoPfo, candidateDaughterPfoList, pfoInfoMap, callDepth + 1);
194  }
195 
196  // Add primary pfo->daughter pfo links
197  PfoVector sortedPfos;
198  for (const auto &mapEntry : pfoInfoMap)
199  sortedPfos.push_back(mapEntry.first);
200  std::sort(sortedPfos.begin(), sortedPfos.end(), LArPfoHelper::SortByNHits);
201 
202  for (const Pfo *const pPfo : sortedPfos)
203  {
204  const PfoInfo *const pPfoInfo(pfoInfoMap.at(pPfo));
205 
206  PfoVector daughterPfos(pPfoInfo->GetDaughterPfoList().begin(), pPfoInfo->GetDaughterPfoList().end());
207  std::sort(daughterPfos.begin(), daughterPfos.end(), LArPfoHelper::SortByNHits);
208 
209  for (const ParticleFlowObject *const pDaughterPfo : daughterPfos)
210  PANDORA_THROW_RESULT_IF(
211  STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pPfoInfo->GetThisPfo(), pDaughterPfo));
212  }
213 
214  // Deal with any remaining parent-less pfos
215  for (const ParticleFlowObject *const pRemainingPfo : candidateDaughterPfoVector)
216  {
217  if (!pRemainingPfo->GetParentPfoList().empty())
218  continue;
219 
220  // TODO Most appropriate decision - add as daughter of either i) nearest pfo, or ii) the neutrino (current approach)
221  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pNeutrinoPfo, pRemainingPfo));
222  }
223 }
224 
225 //------------------------------------------------------------------------------------------------------------------------------------------
226 
228  const ParticleFlowObject *const pNeutrinoPfo, const PfoList &candidateDaughterPfoList, PfoInfoMap &pfoInfoMap) const
229 {
230  PfoVector candidateDaughterPfoVector(candidateDaughterPfoList.begin(), candidateDaughterPfoList.end());
231  std::sort(candidateDaughterPfoVector.begin(), candidateDaughterPfoVector.end(), LArPfoHelper::SortByNHits);
232 
233  // TODO Consider deleting the neutrino pfo if there are no daughter pfo candidates
234  if (candidateDaughterPfoVector.empty())
235  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
236 
237  ClusterList daughterClusterList3D;
238  LArPfoHelper::GetThreeDClusterList(candidateDaughterPfoVector.front(), daughterClusterList3D);
239  daughterClusterList3D.sort(LArClusterHelper::SortByNHits);
240 
241  // If no 3D hits, must leave vertex where it was
242  if (daughterClusterList3D.empty())
243  return;
244 
245  const Vertex *pOldNeutrinoVertex(LArPfoHelper::GetVertex(pNeutrinoPfo));
246  const CartesianVector newVertexPosition(LArClusterHelper::GetClosestPosition(pOldNeutrinoVertex->GetPosition(), daughterClusterList3D.front()));
247 
249  parameters.m_position = newVertexPosition;
250  parameters.m_vertexLabel = pOldNeutrinoVertex->GetVertexLabel();
251  parameters.m_vertexType = pOldNeutrinoVertex->GetVertexType();
252  parameters.m_x0 = pOldNeutrinoVertex->GetX0();
253 
254  std::string neutrinoVertexListName(m_neutrinoVertexListName);
255  if (neutrinoVertexListName.empty())
256  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentListName<Vertex>(*this, neutrinoVertexListName));
257 
258  std::string temporaryVertexListName;
259  const VertexList *pTemporaryVertexList(nullptr);
260  const Vertex *pNewNeutrinoVertex(nullptr);
261  PANDORA_THROW_RESULT_IF(
262  STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pTemporaryVertexList, temporaryVertexListName));
263  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pNewNeutrinoVertex));
264  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, neutrinoVertexListName));
265 
266  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RemoveFromPfo(*this, pNeutrinoPfo, pOldNeutrinoVertex));
267  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pNeutrinoPfo, pNewNeutrinoVertex));
268  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete<Vertex>(*this, pOldNeutrinoVertex, neutrinoVertexListName));
269 
270  for (auto &mapIter : pfoInfoMap)
271  delete mapIter.second;
272 
273  pfoInfoMap.clear();
274 
275  for (PfoRelationTool *const pPfoRelationTool : m_algorithmToolVector)
276  pPfoRelationTool->Run(this, pNewNeutrinoVertex, pfoInfoMap);
277 }
278 
279 //------------------------------------------------------------------------------------------------------------------------------------------
280 
281 void NeutrinoHierarchyAlgorithm::DisplayPfoInfoMap(const ParticleFlowObject *const pNeutrinoPfo, const PfoInfoMap &pfoInfoMap) const
282 {
283  bool display(false);
284  PANDORA_MONITORING_API(SetEveDisplayParameters(this->GetPandora(), false, DETECTOR_VIEW_XZ, -1.f, -1.f, 1.f));
285  std::cout << "-Neutrino Pfo, nDaughters " << pNeutrinoPfo->GetDaughterPfoList().size() << ", nVertices "
286  << pNeutrinoPfo->GetVertexList().size() << std::endl;
287 
288  PfoVector sortedPfos;
289  for (const auto &mapEntry : pfoInfoMap)
290  sortedPfos.push_back(mapEntry.first);
291  std::sort(sortedPfos.begin(), sortedPfos.end(), LArPfoHelper::SortByNHits);
292 
293  for (const Pfo *const pPfo : sortedPfos)
294  {
295  const PfoInfo *const pPfoInfo(pfoInfoMap.at(pPfo));
296 
297  std::cout << "Pfo " << pPfoInfo->GetThisPfo() << ", vtxAssoc " << pPfoInfo->IsNeutrinoVertexAssociated() << ", parent "
298  << pPfoInfo->GetParentPfo() << ", nDaughters " << pPfoInfo->GetDaughterPfoList().size() << " (";
299 
300  for (const ParticleFlowObject *const pDaughterPfo : pPfoInfo->GetDaughterPfoList())
301  std::cout << pDaughterPfo << " ";
302  std::cout << ") " << std::endl;
303 
304  if (pPfoInfo->IsNeutrinoVertexAssociated())
305  {
306  display = true;
307  const PfoList tempPfoList(1, pPfoInfo->GetThisPfo());
308  PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &tempPfoList, "VertexPfo", RED, true, false));
309  }
310  }
311 
312  if (display)
313  {
314  PANDORA_MONITORING_API(VisualizeVertices(this->GetPandora(), &(pNeutrinoPfo->GetVertexList()), "NeutrinoVertex", ORANGE));
315  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
316  display = false;
317  }
318 
319  for (const Pfo *const pPfo : sortedPfos)
320  {
321  const PfoInfo *const pPfoInfo(pfoInfoMap.at(pPfo));
322 
323  if (!pPfoInfo->GetDaughterPfoList().empty())
324  {
325  display = true;
326  const PfoList tempPfoList(1, pPfoInfo->GetThisPfo());
327  PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &tempPfoList, "ParentPfo", RED, true, false));
328  PANDORA_MONITORING_API(
329  VisualizeParticleFlowObjects(this->GetPandora(), &(pPfoInfo->GetDaughterPfoList()), "DaughterPfos", BLUE, true, false));
330  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
331  }
332  }
333 }
334 
335 //------------------------------------------------------------------------------------------------------------------------------------------
336 //------------------------------------------------------------------------------------------------------------------------------------------
337 
338 NeutrinoHierarchyAlgorithm::PfoInfo::PfoInfo(const pandora::ParticleFlowObject *const pPfo, const unsigned int halfWindowLayers, const float layerPitch) :
339  m_pThisPfo(pPfo),
340  m_pCluster3D(nullptr),
341  m_pVertex3D(nullptr),
342  m_pSlidingFitResult3D(nullptr),
343  m_isNeutrinoVertexAssociated(false),
344  m_isInnerLayerAssociated(false),
345  m_pParentPfo(nullptr)
346 {
347  ClusterList clusterList3D;
348  LArPfoHelper::GetThreeDClusterList(pPfo, clusterList3D);
349 
350  if (1 != clusterList3D.size())
351  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
352 
353  m_pCluster3D = *(clusterList3D.begin());
354  m_pSlidingFitResult3D = new ThreeDSlidingFitResult(m_pCluster3D, halfWindowLayers, layerPitch);
355 
357  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
358 }
359 
360 //------------------------------------------------------------------------------------------------------------------------------------------
361 
363  m_pThisPfo(rhs.m_pThisPfo),
364  m_pCluster3D(rhs.m_pCluster3D),
365  m_pVertex3D(rhs.m_pVertex3D),
366  m_pSlidingFitResult3D(nullptr),
367  m_isNeutrinoVertexAssociated(rhs.m_isNeutrinoVertexAssociated),
368  m_isInnerLayerAssociated(rhs.m_isInnerLayerAssociated),
369  m_pParentPfo(rhs.m_pParentPfo),
370  m_daughterPfoList(rhs.m_daughterPfoList)
371 {
372  if (!rhs.m_pSlidingFitResult3D)
373  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
374 
377 }
378 
379 //------------------------------------------------------------------------------------------------------------------------------------------
380 
382 {
383  if (this != &rhs)
384  {
385  if (!rhs.m_pSlidingFitResult3D)
386  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
387 
388  m_pThisPfo = rhs.m_pThisPfo;
389  m_pCluster3D = rhs.m_pCluster3D;
390  m_pVertex3D = rhs.m_pVertex3D;
391  m_isNeutrinoVertexAssociated = rhs.m_isNeutrinoVertexAssociated;
392  m_isInnerLayerAssociated = rhs.m_isInnerLayerAssociated;
393  m_pParentPfo = rhs.m_pParentPfo;
394  m_daughterPfoList = rhs.m_daughterPfoList;
395 
396  delete m_pSlidingFitResult3D;
397  m_pSlidingFitResult3D = new ThreeDSlidingFitResult(m_pCluster3D, rhs.m_pSlidingFitResult3D->GetFirstFitResult().GetLayerFitHalfWindow(),
399  }
400 
401  return *this;
402 }
403 
404 //------------------------------------------------------------------------------------------------------------------------------------------
405 
407 {
408  delete m_pSlidingFitResult3D;
409 }
410 
411 //------------------------------------------------------------------------------------------------------------------------------------------
412 
413 void NeutrinoHierarchyAlgorithm::PfoInfo::SetNeutrinoVertexAssociation(const bool isNeutrinoVertexAssociated)
414 {
415  m_isNeutrinoVertexAssociated = isNeutrinoVertexAssociated;
416 }
417 
418 //------------------------------------------------------------------------------------------------------------------------------------------
419 
421 {
422  m_isInnerLayerAssociated = isInnerLayerAssociated;
423 }
424 
425 //------------------------------------------------------------------------------------------------------------------------------------------
426 
427 void NeutrinoHierarchyAlgorithm::PfoInfo::SetParentPfo(const pandora::ParticleFlowObject *const pParentPfo)
428 {
429  if (m_pParentPfo)
430  throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
431 
432  m_pParentPfo = pParentPfo;
433 }
434 
435 //------------------------------------------------------------------------------------------------------------------------------------------
436 
438 {
439  m_pParentPfo = nullptr;
440 }
441 
442 //------------------------------------------------------------------------------------------------------------------------------------------
443 
444 void NeutrinoHierarchyAlgorithm::PfoInfo::AddDaughterPfo(const pandora::ParticleFlowObject *const pDaughterPfo)
445 {
446  if (m_daughterPfoList.end() != std::find(m_daughterPfoList.begin(), m_daughterPfoList.end(), pDaughterPfo))
447  throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
448 
449  m_daughterPfoList.push_back(pDaughterPfo);
450 }
451 
452 //------------------------------------------------------------------------------------------------------------------------------------------
453 
454 void NeutrinoHierarchyAlgorithm::PfoInfo::RemoveDaughterPfo(const pandora::ParticleFlowObject *const pDaughterPfo)
455 {
456  PfoList::iterator eraseIter = std::find(m_daughterPfoList.begin(), m_daughterPfoList.end(), pDaughterPfo);
457 
458  if (m_daughterPfoList.end() == eraseIter)
459  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
460 
461  m_daughterPfoList.erase(eraseIter);
462 }
463 
464 //------------------------------------------------------------------------------------------------------------------------------------------
465 //------------------------------------------------------------------------------------------------------------------------------------------
466 
467 StatusCode NeutrinoHierarchyAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
468 {
469  AlgorithmToolVector algorithmToolVector;
470  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "PfoRelationTools", algorithmToolVector));
471 
472  for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
473  {
474  PfoRelationTool *const pPfoRelationTool(dynamic_cast<PfoRelationTool *>(*iter));
475 
476  if (!pPfoRelationTool)
477  return STATUS_CODE_INVALID_PARAMETER;
478 
479  m_algorithmToolVector.push_back(pPfoRelationTool);
480  }
481 
482  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "NeutrinoPfoListName", m_neutrinoPfoListName));
483 
484  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "DaughterPfoListNames", m_daughterPfoListNames));
485 
486  PANDORA_RETURN_RESULT_IF_AND_IF(
487  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NeutrinoVertexListName", m_neutrinoVertexListName));
488 
489  PANDORA_RETURN_RESULT_IF_AND_IF(
490  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitHalfWindow", m_halfWindowLayers));
491 
492  PANDORA_RETURN_RESULT_IF_AND_IF(
493  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DisplayPfoInfoMap", m_displayPfoInfoMap));
494 
495  return STATUS_CODE_SUCCESS;
496 }
497 
498 } // namespace lar_content
void SetInnerLayerAssociation(const bool isInnerLayerAssociated)
Set the inner layer association flag.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int GetLayerFitHalfWindow() const
Get the layer fit half window.
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position, then pulse-height.
const pandora::Cluster * m_pCluster3D
The address of the three dimensional cluster.
PfoInfo & operator=(const PfoInfo &rhs)
Assignment operator.
void ProcessPfoInfoMap(const pandora::ParticleFlowObject *const pNeutrinoPfo, const pandora::PfoList &candidateDaughterPfoList, PfoInfoMap &pfoInfoMap, const unsigned int callDepth=0) const
Process the information in a pfo info map, creating pfo parent/daughter links.
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.
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 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.
std::string m_neutrinoVertexListName
The neutrino vertex list name - if not specified will assume current list.
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.
void AdjustVertexAndPfoInfo(const pandora::ParticleFlowObject *const pNeutrinoPfo, const pandora::PfoList &candidateDaughterPfoList, PfoInfoMap &pfoInfoMap) const
Adjust neutrino vertex to ensure agreement with at least one pfo (first in sorted input list) ...
Header file for the geometry helper class.
ThreeDSlidingFitResult * m_pSlidingFitResult3D
The three dimensional sliding fit result.
pandora::PfoList m_daughterPfoList
The daughter pfo list.
Header file for the cluster helper class.
void SetParentPfo(const pandora::ParticleFlowObject *const pParentPfo)
Set the parent pfo.
std::unordered_map< const pandora::ParticleFlowObject *, PfoInfo * > PfoInfoMap
float GetLayerPitch() const
Get the layer pitch, units cm.
j template void())
Definition: json.hpp:3108
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.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
Definition: reco_sbnd.fcl:182
void SetNeutrinoVertexAssociation(const bool isNeutrinoVertexAssociated)
Set the neutrino vertex association flag.
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.
static pandora::CartesianVector GetClosestPosition(const pandora::CartesianVector &position, const pandora::ClusterList &clusterList)
Get closest position in a list of clusters to a specified input position vector.
void GetCandidateDaughterPfoList(pandora::PfoList &candidateDaughterPfoList) const
Get the list of candidate daughter pfos.
NeutrinoHierarchyAlgorithm::PfoInfo PfoInfo
std::list< Vertex > VertexList
Definition: DCEL.h:182
BEGIN_PROLOG could also be cout
void GetInitialPfoInfoMap(const pandora::PfoList &pfoList, PfoInfoMap &pfoInfoMap) const
Process a provided pfo list and populate an initial pfo info map.