9 #include "Pandora/AlgorithmHeaders.h" 22 CosmicRayVertexBuildingAlgorithm::CosmicRayVertexBuildingAlgorithm() :
23 m_useParentShowerVertex(false),
25 m_halfWindowLayers(30),
26 m_maxVertexDisplacementFromTrack(1.
f)
34 const PfoList *pPfoList = NULL;
35 PANDORA_THROW_RESULT_IF_AND_IF(
36 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_parentPfoListName, pPfoList));
40 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
41 std::cout <<
"CosmicRayVertexBuildingAlgorithm: pfo list unavailable." << std::endl;
43 return STATUS_CODE_SUCCESS;
53 return STATUS_CODE_SUCCESS;
65 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
70 for (
PfoList::const_iterator pIter = outputList.begin(), pIterEnd = outputList.end(); pIter != pIterEnd; ++pIter)
72 ClusterList clusterList;
75 if (clusterList.empty())
78 pfoVector.push_back(*pIter);
89 const float slidingFitPitch(std::max({pitchU, pitchV, pitchW}));
93 const ParticleFlowObject *
const pPfo = *pIter;
98 ClusterList clusterList;
103 const Cluster *
const pCluster = *cIter;
109 if (!pointingClusterMap.insert(LArPointingClusterMap::value_type(pCluster, pointingCluster)).second)
110 throw StatusCodeException(STATUS_CODE_FAILURE);
112 catch (StatusCodeException &statusCodeException)
114 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
115 throw statusCodeException;
127 const ParticleFlowObject *
const pPfo = *iter;
144 ClusterList clusterList;
147 if (clusterList.empty())
151 bool foundVtx(
false);
152 CartesianVector vtxPosition(0.
f, 0.
f, 0.
f);
153 CartesianVector vtxDirection(0.
f, 0.
f, 0.
f);
155 bool foundEnd(
false);
156 CartesianVector endPosition(0.
f, 0.
f, 0.
f);
157 CartesianVector endDirection(0.
f, 0.
f, 0.
f);
161 const Cluster *
const pCluster = *cIter1;
165 CartesianVector minPosition(0.
f, 0.
f, 0.
f), maxPosition(0.
f, 0.
f, 0.
f);
166 CartesianVector minDirection(0.
f, 0.
f, 0.
f), maxDirection(0.
f, 0.
f, 0.
f);
170 if (pointingClusterMap.end() != cIter2)
182 minDirection = (maxPosition - minPosition).GetUnitVector();
183 maxDirection = (minPosition - maxPosition).GetUnitVector();
186 if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
187 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
190 const float minVerticalCoordinate(
m_isDualPhase ? minPosition.GetX() : minPosition.GetY());
191 const float maxVerticalCoordinate(
m_isDualPhase ? maxPosition.GetX() : maxPosition.GetY());
193 if (!foundVtx || (minVerticalCoordinate > std::max(maxVerticalCoordinate,
m_isDualPhase ? vtxPosition.GetX() : vtxPosition.GetY())))
196 vtxPosition = minPosition;
197 vtxDirection = minDirection;
200 if (!foundVtx || (maxVerticalCoordinate > std::max(minVerticalCoordinate,
m_isDualPhase ? vtxPosition.GetX() : vtxPosition.GetY())))
203 vtxPosition = maxPosition;
204 vtxDirection = maxDirection;
207 if (!foundEnd || (minVerticalCoordinate < std::min(maxVerticalCoordinate,
m_isDualPhase ? endPosition.GetX() : endPosition.GetY())))
210 endPosition = minPosition;
211 endDirection = minDirection;
214 if (!foundEnd || (maxVerticalCoordinate < std::min(minVerticalCoordinate,
m_isDualPhase ? endPosition.GetX() : endPosition.GetY())))
217 endPosition = maxPosition;
218 endDirection = maxDirection;
221 catch (StatusCodeException &statusCodeException)
223 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
224 throw statusCodeException;
230 if (!(foundVtx && foundEnd))
240 if (pDaughterPfo->GetParentPfoList().size() != 1)
241 throw StatusCodeException(STATUS_CODE_FAILURE);
243 const ParticleFlowObject *
const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
245 ClusterList parentList, daughterList;
249 if (daughterList.empty() || parentList.empty())
253 float closestMaxVerticalCoordinate(-std::numeric_limits<float>::max()), maxVerticalCoordinate(-std::numeric_limits<float>::max());
254 CartesianVector closestMaxVerticalVertex(0.
f, 0.
f, 0.
f), maxVerticalVertex(0.
f, 0.
f, 0.
f);
256 for (
const Cluster *
const pDaughterCluster : daughterList)
258 CaloHitList daughterCaloHitList;
259 pDaughterCluster->GetOrderedCaloHitList().FillCaloHitList(daughterCaloHitList);
261 for (
const Cluster *
const pParentCluster : parentList)
263 CaloHitList parentCaloHitList;
264 pParentCluster->GetOrderedCaloHitList().FillCaloHitList(parentCaloHitList);
266 for (
const CaloHit *
const pDaughterCaloHit : daughterCaloHitList)
268 const CartesianVector &daughterPosition(pDaughterCaloHit->GetPositionVector());
270 for (
const CaloHit *
const pParentCaloHit : parentCaloHitList)
272 const CartesianVector &parentPosition(pParentCaloHit->GetPositionVector());
273 const float separationSquared((daughterPosition - parentPosition).GetMagnitudeSquared());
274 const float verticalCoordinate(
m_isDualPhase ? daughterPosition.GetX() : daughterPosition.GetY());
276 if (verticalCoordinate > maxVerticalCoordinate)
278 maxVerticalCoordinate = verticalCoordinate;
279 maxVerticalVertex = daughterPosition;
284 if (verticalCoordinate > closestMaxVerticalCoordinate)
287 closestMaxVerticalCoordinate = verticalCoordinate;
288 closestMaxVerticalVertex = daughterPosition;
296 const CartesianVector &daughterVertex(found ? closestMaxVerticalVertex : maxVerticalVertex);
305 const CartesianVector &vtxPosition,
const CartesianVector &vtxDirection,
const ParticleFlowObject *
const pPfo)
const 307 if (!pPfo->GetVertexList().empty())
308 throw StatusCodeException(STATUS_CODE_FAILURE);
310 PandoraContentApi::ParticleFlowObject::Metadata metadata;
311 metadata.m_momentum = vtxDirection;
312 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*
this, pPfo, metadata));
315 std::string vertexListName;
316 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pVertexList, vertexListName));
318 PandoraContentApi::Vertex::Parameters parameters;
319 parameters.m_position = vtxPosition;
320 parameters.m_vertexLabel = VERTEX_START;
321 parameters.m_vertexType = VERTEX_3D;
323 const Vertex *pVertex(NULL);
324 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
326 if (!pVertexList->empty())
328 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*
this,
m_vertexListName));
329 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*
this, pPfo, pVertex));
337 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputPfoListName",
m_parentPfoListName));
339 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputVertexListName",
m_vertexListName));
341 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
344 PANDORA_RETURN_RESULT_IF_AND_IF(
345 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitHalfWindow",
m_halfWindowLayers));
347 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"IsDualPhase",
m_isDualPhase));
349 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
352 return STATUS_CODE_SUCCESS;
std::unordered_map< const pandora::Cluster *, LArPointingCluster > LArPointingClusterMap
Header file for the pfo helper class.
bool m_useParentShowerVertex
use the parent pfo for the shower vertices
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.
void SetParticleParameters(const pandora::CartesianVector &vtxPosition, const pandora::CartesianVector &vtxDirection, const pandora::ParticleFlowObject *const pPfo) const
Set the vertex and direction of the Pfos.
bool m_isDualPhase
type of geometry
LArPointingCluster class.
std::string m_vertexListName
The name of the output vertex list.
Header file for the cosmic-ray vertex building algorithm class.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
void BuildCosmicRayParent(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pPfo) const
Reconstruct the vertex and direction of a parent cosmic-ray Pfo.
Header file for the geometry helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void BuildCosmicRayParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const
Reconstruct the vertex and direction of a list of cosmic-ray Pfos.
pandora::StatusCode Run()
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
std::string m_parentPfoListName
The name of the input pfo list.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
unsigned int m_halfWindowLayers
number of layers to use for half-window of sliding fit
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) ...
float m_maxVertexDisplacementFromTrack
The maximum separation of a close vertex from the cosmic ray track.
static bool IsFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a primary parent particle.
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 GetCosmicPfos(const pandora::PfoList *const pPfoList, pandora::PfoVector &pfoVector) const
Get the list of input pfos to this algorithm.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
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 BuildCosmicRayDaughter(const pandora::ParticleFlowObject *const pPfo) const
Reconstruct the vertex and direction of a daughter cosmic-ray Pfo.
void BuildPointingClusterMap(const pandora::PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const
Build a map of 3D sliding fits from the input Pfos.
std::list< Vertex > VertexList
const pandora::CartesianVector & GetPosition() const
Get the vertex position.