9 #include "Pandora/AlgorithmHeaders.h" 22 NeutrinoDaughterVerticesAlgorithm::NeutrinoDaughterVerticesAlgorithm() :
23 m_useParentShowerVertex(false),
24 m_halfWindowLayers(20)
32 const PfoList *pPfoList = NULL;
33 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_neutrinoListName, pPfoList));
35 if (!pPfoList || pPfoList->empty())
37 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
38 std::cout <<
"NeutrinoDaughterVerticesAlgorithm: unable to find pfo list " <<
m_neutrinoListName << std::endl;
40 return STATUS_CODE_SUCCESS;
50 return STATUS_CODE_SUCCESS;
62 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
67 for (
PfoList::const_iterator pIter = outputList.begin(), pIterEnd = outputList.end(); pIter != pIterEnd; ++pIter)
69 ClusterList clusterList;
72 if (clusterList.empty())
75 pfoVector.push_back(*pIter);
86 const float pitchMax{std::max({pitchU, pitchV, pitchW})};
87 const float slidingFitPitch(pitchMax);
91 const ParticleFlowObject *
const pPfo = *pIter;
96 ClusterList clusterList;
101 const Cluster *
const pCluster = *cIter;
107 if (!pointingClusterMap.insert(LArPointingClusterMap::value_type(pCluster, pointingCluster)).second)
108 throw StatusCodeException(STATUS_CODE_FAILURE);
110 catch (StatusCodeException &statusCodeException)
112 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
113 throw statusCodeException;
125 const ParticleFlowObject *
const pPfo = *iter;
142 if (pDaughterPfo->GetParentPfoList().size() != 1)
143 throw StatusCodeException(STATUS_CODE_FAILURE);
145 const ParticleFlowObject *
const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
147 ClusterList parentList, daughterList;
151 if (parentList.empty() && pParentPfo->GetVertexList().empty())
154 bool foundVtx(
false);
155 float vtxDistance(0.
f);
156 CartesianVector vtxPosition(0.
f, 0.
f, 0.
f);
157 CartesianVector vtxDirection(0.
f, 0.
f, 0.
f);
161 const Cluster *
const pDaughterCluster = *dIter;
163 CartesianVector minPosition(0.
f, 0.
f, 0.
f), maxPosition(0.
f, 0.
f, 0.
f);
164 CartesianVector minDirection(0.
f, 0.
f, 0.
f), maxDirection(0.
f, 0.
f, 0.
f);
165 bool foundDirection(
false);
169 if (pointingClusterMap.end() != cIter)
177 foundDirection =
true;
184 if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
189 minDirection = (maxPosition - minPosition).GetUnitVector();
190 maxDirection = (minPosition - maxPosition).GetUnitVector();
193 float minDistance(std::numeric_limits<float>::max());
194 float maxDistance(std::numeric_limits<float>::max());
198 const Cluster *
const pParentCluster = *pIter;
205 const Vertex *
const pVertex = *(pParentPfo->GetVertexList().begin());
206 minDistance = std::min(minDistance, (pVertex->GetPosition() - minPosition).GetMagnitude());
207 maxDistance = std::min(maxDistance, (pVertex->GetPosition() - maxPosition).GetMagnitude());
210 if (!foundVtx || (minDistance < vtxDistance))
213 vtxDistance = minDistance;
214 vtxPosition = minPosition;
215 vtxDirection = minDirection;
218 if (!foundVtx || (maxDistance < vtxDistance))
221 vtxDistance = maxDistance;
222 vtxPosition = maxPosition;
223 vtxDirection = maxDirection;
237 if (pDaughterPfo->GetParentPfoList().size() != 1)
238 throw StatusCodeException(STATUS_CODE_FAILURE);
240 const ParticleFlowObject *
const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
243 throw StatusCodeException(STATUS_CODE_FAILURE);
245 ClusterList parentList, daughterList;
249 if (daughterList.empty())
254 const Vertex *
const pVertex = *(pParentPfo->GetVertexList().begin());
255 const CartesianVector vtxPosition(
261 if (parentList.empty())
264 bool foundVtx(
false);
265 float vtxDistanceSquared(0.
f);
266 CartesianVector vtxPosition(0.
f, 0.
f, 0.
f);
270 const Cluster *
const pDaughterCluster = *dIter;
274 const Cluster *
const pParentCluster = *pIter;
276 CartesianVector closestDaughterPosition(0.
f, 0.
f, 0.
f), closestParentPosition(0.
f, 0.
f, 0.
f);
279 const float closestDistanceSquared((closestDaughterPosition - closestParentPosition).GetMagnitudeSquared());
281 if (!foundVtx || closestDistanceSquared < vtxDistanceSquared)
284 vtxDistanceSquared = closestDistanceSquared;
299 const CartesianVector &vtxPosition,
const CartesianVector &vtxDirection,
const ParticleFlowObject *
const pPfo)
const 301 if (!pPfo->GetVertexList().empty())
302 throw StatusCodeException(STATUS_CODE_FAILURE);
304 PandoraContentApi::ParticleFlowObject::Metadata metadata;
305 metadata.m_momentum = vtxDirection;
306 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*
this, pPfo, metadata));
309 std::string vertexListName;
310 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pVertexList, vertexListName));
312 PandoraContentApi::Vertex::Parameters parameters;
313 parameters.m_position = vtxPosition;
314 parameters.m_vertexLabel = VERTEX_INTERACTION;
315 parameters.m_vertexType = VERTEX_3D;
317 const Vertex *pVertex(NULL);
318 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
320 if (!pVertexList->empty())
322 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*
this,
m_vertexListName));
323 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*
this, pPfo, pVertex));
331 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"NeutrinoPfoListName",
m_neutrinoListName));
333 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputVertexListName",
m_vertexListName));
335 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
338 PANDORA_RETURN_RESULT_IF_AND_IF(
339 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitHalfWindow",
m_halfWindowLayers));
341 return STATUS_CODE_SUCCESS;
unsigned int m_halfWindowLayers
number of layers to use for half-window of sliding fit
std::unordered_map< const pandora::Cluster *, LArPointingCluster > LArPointingClusterMap
std::string m_vertexListName
The name of the output cosmic-ray vertex list.
Header file for the pfo helper class.
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
Header file for the neutrino daughter vertices algorithm class.
LArPointingCluster class.
static void GetClosestPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianVector &position1, pandora::CartesianVector &position2)
Get pair of closest positions for a pair of clusters.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
Header file for the geometry helper class.
void GetDaughterPfos(const pandora::PfoList *const pfoList, pandora::PfoVector &pfoVector) const
Get the vector of daughter pfos.
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
static bool IsNeutrino(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a neutrino or (antineutrino)
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
bool m_useParentShowerVertex
use the parent pfo for the shower vertices
static void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z) ...
void SetParticleParameters(const pandora::CartesianVector &vtxPosition, const pandora::CartesianVector &vtxDirection, const pandora::ParticleFlowObject *const pPfo) const
Set the vertex and direction of the Pfos.
pandora::StatusCode Run()
void BuildDaughterShower(const pandora::ParticleFlowObject *const pDaughterPfo) const
Reconstruct the vertex and direction of a shower-like Pfos.
static void GetAllDownstreamPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively, of all daughters associated with those pfos in an input lis...
void BuildDaughterParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const
Reconstruct the vertex and direction of daughter Pfos.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
void BuildPointingClusterMap(const pandora::PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const
Build a map of 3D sliding fits from the input Pfos.
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.
std::string m_neutrinoListName
The input list of pfo list names.
std::list< Vertex > VertexList
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
void BuildDaughterTrack(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pDaughterPfo) const
Reconstruct the vertex and direction of a track-like Pfos.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.