9 #include "Pandora/AlgorithmHeaders.h" 10 #include "Pandora/StatusCodes.h" 20 #include <torch/script.h> 21 #include <torch/torch.h> 31 void DLPrimaryHierarchyTool::DLPrimaryNetworkParams::AddCommonParamsToInput(
int &insertIndex,
LArDLHelper::TorchInput &modelInput)
const 33 modelInput[0][insertIndex] = m_nSpacepoints;
39 void DLPrimaryHierarchyTool::DLPrimaryNetworkParams::AddOrientationParamsToInput(
int &insertIndex,
LArDLHelper::TorchInput &modelInput)
const 41 for (
const float param : {m_nuSeparation, m_vertexRegionNHits, m_vertexRegionNParticles, m_dca, m_connectionExtrapDistance,
42 m_isPOIClosestToNu, m_parentConnectionDistance, m_childConnectionDistance})
44 modelInput[0][insertIndex] = param;
52 DLPrimaryHierarchyTool::DLPrimaryHierarchyTool() :
54 m_trainingMode(false),
55 m_extrapolationStepSize(1.
f),
63 const HierarchyPfoVector &trackPfos,
const HierarchyPfo &hierarchyPfo, std::vector<DLPrimaryNetworkParams> &networkParamVector,
float &primaryScore)
65 networkParamVector.clear();
66 primaryScore = std::numeric_limits<float>::lowest();
70 const bool isTrack(hierarchyPfo.
GetPfo()->GetParticleId() == 13);
71 std::vector<bool> orientationVector(isTrack ? std::vector<bool>({
true,
false}) : std::vector<bool>({
true}));
73 for (
const bool useUpstream : orientationVector)
78 const StatusCode statusCode(this->
CalculateNetworkVariables(pAlgorithm, hierarchyPfo, pNeutrinoPfo, trackPfos, useUpstream, primaryNetworkParams));
80 if (statusCode != STATUS_CODE_SUCCESS)
83 networkParamVector.emplace_back(primaryNetworkParams);
90 primaryScore = this->
ClassifyTrack(networkParamVector.at(0), networkParamVector.at(1));
95 return STATUS_CODE_SUCCESS;
101 const ParticleFlowObject *
const pNeutrinoPfo,
const HierarchyPfoVector &trackPfos,
const bool useUpstream,
105 if (pNeutrinoPfo->GetVertexList().empty())
106 return STATUS_CODE_NOT_INITIALIZED;
108 const Vertex *
const pNeutrinoVertex(LArPfoHelper::GetVertex(pNeutrinoPfo));
109 const CartesianVector nuVertex(
110 pNeutrinoVertex->GetPosition().GetX(), pNeutrinoVertex->GetPosition().GetY(), pNeutrinoVertex->GetPosition().GetZ());
116 if (!particlePoint.IsSet())
118 return STATUS_CODE_NOT_INITIALIZED;
123 primaryNetworkParams.
m_nSpacepoints = LArPfoHelper::GetNumberOfThreeDHits(hierarchyPfo.
GetPfo());
124 primaryNetworkParams.
m_nuSeparation = (particlePoint.GetPosition() - nuVertex).GetMagnitude();
133 return STATUS_CODE_SUCCESS;
153 const float extrapDistance((nuVertex - particlePoint.
GetPosition()).GetDotProduct(particlePoint.
GetDirection()));
154 const CartesianVector extrapolationPoint(particlePoint.
GetPosition() + (particlePoint.
GetDirection() * extrapDistance));
156 primaryNetworkParams.
m_dca = (nuVertex - extrapolationPoint).GetMagnitude();
166 const float nuVertexSepSq((particlePoint.
GetPosition() - nuVertex).GetMagnitudeSquared());
169 float parentConnectionDistance(std::numeric_limits<float>::max());
170 float childConnectionDistance(std::numeric_limits<float>::max());
175 if (hierarchyTrackPfo == pPfo)
179 const float thisNuVertexSepSq((hierarchyTrackPfo.GetDownstreamPoint().GetPosition() - nuVertex).GetMagnitudeSquared());
181 if (thisNuVertexSepSq > nuVertexSepSq)
184 float thisParentConnectionDistance(std::numeric_limits<float>::lowest());
185 float thisChildConnectionDistance(std::numeric_limits<float>::lowest());
187 this->
CalculateConnectionDistances(hierarchyTrackPfo.GetDownstreamPoint(), particlePoint, thisParentConnectionDistance, thisChildConnectionDistance);
189 if ((thisChildConnectionDistance > 0.
f) && (std::fabs(thisParentConnectionDistance) < std::fabs(parentConnectionDistance)))
192 parentConnectionDistance = thisParentConnectionDistance;
193 childConnectionDistance = thisChildConnectionDistance;
207 const ExtremalPoint &parentPoint,
const ExtremalPoint &childPoint,
float &parentConnectionDistance,
float &childConnectionDistance)
const 210 float smallestT(std::numeric_limits<float>::max());
211 bool isGettingCloser(
true);
213 CartesianVector connectionPoint(std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest());
216 CartesianVector extrapolatedPoint(childPoint.
GetPosition());
218 while (isGettingCloser)
220 isGettingCloser =
false;
227 (parentPoint.
GetDirection() * (-1.f)).GetCrossProduct((extrapolatedPoint - parentPoint.
GetPosition())).GetMagnitudeSquared());
229 if (parentT < smallestT)
232 connectionPoint = extrapolatedPoint;
233 isGettingCloser =
true;
239 parentConnectionDistance = found ? (parentPoint.
GetDirection() * (-1.f)).GetDotProduct(connectionPoint - parentPoint.
GetPosition())
240 : std::numeric_limits<float>::lowest();
242 childConnectionDistance = found ? (childPoint.
GetPosition() - connectionPoint).GetMagnitude() : std::numeric_limits<float>::lowest();
268 const FloatVector outputUp(this->
ClassifyTrackEdge(edgeParamsUp, edgeParamsDown));
269 const FloatVector outputDown(this->
ClassifyTrackEdge(edgeParamsDown, edgeParamsUp));
277 for (
const FloatVector &edgeOutput : {outputUp, outputDown})
279 for (
int i = 0; i < 3; ++i)
281 input[0][insertIndex] = edgeOutput.at(i);
288 torch::TensorAccessor<float, 2> outputAccessor = output.accessor<float, 2>();
290 return outputAccessor[0][0];
309 torch::TensorAccessor<float, 2> outputAccessor(output.accessor<
float, 2>());
311 return {outputAccessor[0][0], outputAccessor[0][1], outputAccessor[0][2]};
328 auto outputAccessor = output.accessor<float, 2>();
330 return outputAccessor[0][0];
337 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingMode",
m_trainingMode));
338 PANDORA_RETURN_RESULT_IF_AND_IF(
339 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"PfoListNames",
m_pfoListNames));
340 PANDORA_RETURN_RESULT_IF_AND_IF(
341 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ExtrapolationStepSize",
m_extrapolationStepSize));
342 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"Normalise",
m_normalise));
343 PANDORA_RETURN_RESULT_IF_AND_IF(
345 PANDORA_RETURN_RESULT_IF_AND_IF(
347 PANDORA_RETURN_RESULT_IF_AND_IF(
349 PANDORA_RETURN_RESULT_IF_AND_IF(
351 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
353 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
355 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
357 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
359 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DCAMin",
m_normLimits.
m_dcaMin));
360 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DCAMax",
m_normLimits.
m_dcaMax));
361 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
363 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
365 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
367 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
369 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
371 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
376 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"PrimaryTrackBranchModelName",
m_primaryTrackBranchModelName));
380 PANDORA_RETURN_RESULT_IF(
385 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the pfo helper class.
NormalisationLimits m_normLimits
struct of the normalisation limits
std::string m_primaryTrackBranchModelName
the name of the primary track edge model file
pandora::FloatVector ClassifyTrackEdge(const DLPrimaryNetworkParams &edgeParams, const DLPrimaryNetworkParams &otherEdgeParams)
Apply the primary track orientation edge network - determine whether an edge is signal (with correct ...
const pandora::ParticleFlowObject * GetPfo() const
Get the pfo.
float m_vertexRegionNParticlesMax
the m_vertexRegionNParticles maximum range boundary
std::string m_primaryShowerClassifierModelName
the name of the primary shower classification model file
float m_parentConnectionDistanceMax
the m_parentConnectionDistance maximum range boundary
float m_extrapolationStepSize
the step size used to trace back a child particle's path
float m_childConnectionDistanceMin
the m_childConnectionDistance minimum range boundary
float ClassifyTrack(const DLPrimaryNetworkParams &edgeParamsUp, const DLPrimaryNetworkParams &edgeParamsDown)
Apply the primary track classification network.
float m_connectionExtrapDistanceMin
the m_connectionExtrapDistance minimum range boundary
float m_parentConnectionDistanceMin
the m_parentConnectionDistance minimum range boundary
Header file for the HierarchyPfo class.
float m_vertexRegionNHitsMax
the m_vertexRegionNHits maximum range boundary
std::string m_primaryTrackClassifierModelName
the name of the primary track classification model file
std::vector< HierarchyPfo > HierarchyPfoVector
bool m_trainingMode
whether to run the tool in training mode
DLBaseHierarchyTool to calculate variables related to the initial shower region.
float m_vertexRegionNParticlesMin
the m_vertexRegionNParticles minimum range boundary
float m_childConnectionDistanceMax
the m_childConnectionDistance maximum range boundary
void NormaliseNetworkParams(DLPrimaryNetworkParams &primaryNetworkParams) const
Shift and normalise the primary network parameters.
float m_vertexRegionNHitsMin
the m_vertexRegionNHits minimum range boundary
float m_nSpacepointsMin
the m_nSpacepoints minimum range boundary
float m_vertexRegionNHits
the number of 3D hits 'close to' the POI
std::pair< float, float > GetParticleInfoAboutPfoPosition(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pPfo, const pandora::CartesianVector &pointOfInterest) const
Return the number of 3D hits and the number of corresponding pfos of a given pfo about a point...
float m_dcaMin
the m_dca minimum range boundary
float m_dcaMax
the m_dca maximum range boundary
float m_dca
the distance of closest approach from the POI to the nu vertex
void NormaliseNetworkParam(const float minLimit, const float maxLimit, float &networkParam) const
Shift and normalise a network parameter with respect to an input range.
void SetConnectionParams(const ExtremalPoint &particlePoint, const pandora::CartesianVector &nuVertex, DLPrimaryNetworkParams &primaryNetworkParams) const
Set the connection region DLPrimaryNetworkParams params (m_dca, m_connectionExtrapDistance) ...
const ExtremalPoint & GetUpstreamPoint() const
Get the upstream extremal point.
const ExtremalPoint & GetDownstreamPoint() const
Get the downstream extremal point.
Header file for the lar deep learning helper helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const pandora::CartesianVector & GetPosition() const
Get the position.
Header file for the file helper class.
float m_nSpacepoints
the number of 3D spacepoints
pandora::StatusCode Run(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pNeutrinoPfo, const HierarchyPfoVector &trackPfos, const HierarchyPfo &hierarchyPfo, std::vector< DLPrimaryNetworkParams > &networkParamVector, float &primaryScore)
static void Forward(TorchModel &model, const TorchInputVector &input, TorchOutput &output)
Run a deep learning model.
pandora::StringVector m_pfoListNames
the input pfo list name vector
void SetContextParams(const pandora::ParticleFlowObject *const pPfo, const ExtremalPoint &particlePoint, const pandora::CartesianVector &nuVertex, const HierarchyPfoVector &trackPfos, DLPrimaryNetworkParams &primaryNetworkParams) const
Set the event context DLPrimaryNetworkParams params (m_parentConnectionDistance, m_childConnectionDis...
float m_nSpacepointsMax
the m_nSpacepoints maximum range boundary
float m_nuSeparation
the sep. between the POI and the nu vertex
void AddCommonParamsToInput(int &insertIndex, LArDLHelper::TorchInput &modelInput) const
Add the orientation independent primary network parameters to the model input tensor.
float ClassifyShower(const DLPrimaryNetworkParams &primaryNetworkParams)
Apply the primary shower classification network.
float m_isPOIClosestToNu
whether the POI is that closest to the nu vertex
static pandora::StatusCode LoadModel(const std::string &filename, TorchModel &model)
Loads a deep learning model.
float m_connectionExtrapDistance
the sep. between the POI and the DCA point
float m_nuSeparationMin
the m_nuSeparation minimum range boundary
void CalculateConnectionDistances(const ExtremalPoint &parentPoint, const ExtremalPoint &childPoint, float &parentConnectionDistance, float &childConnectionDistance) const
Calculate the variables describing the extension of a child particle to a given parent (m_parentConne...
float m_childConnectionDistance
the sep. between the POI and the extension point for m_parentConnectionDistance
void SetVertexRegionParams(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pPfo, const pandora::CartesianVector &particleVertex, DLPrimaryNetworkParams &primaryNetworkParams) const
Set the vertex region DLPrimaryNetworkParams params (m_vertexRegionNHits, m_vertexRegionNParticles) ...
bool m_normalise
whether to normalise the network parameters
LArDLHelper::TorchModel m_primaryShowerClassifierModel
the primary shower classification model
const pandora::CartesianVector & GetDirection() const
Get the direction at the extremal point.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
float m_vertexRegionNParticles
the number of different particles 'close to' the POI
LArGeometryHelper::DetectorBoundaries m_detectorBoundaries
the detector boundaries
static void InitialiseInput(const at::IntArrayRef dimensions, TorchInput &tensor)
Create a torch input tensor.
LArDLHelper::TorchModel m_primaryTrackClassifierModel
the primary track classification model
float m_nuSeparationMax
the m_nuSeparation maximum range boundary
float m_parentConnectionDistance
the DCA to the most likely parent pfo endpoint
LArDLHelper::TorchModel m_primaryTrackBranchModel
the primary track edge model
void AddOrientationParamsToInput(int &insertIndex, LArDLHelper::TorchInput &modelInput) const
Add the orientation dependent primary network parameters to the model input tensor.
pandora::StatusCode CalculateNetworkVariables(const pandora::Algorithm *const pAlgorithm, const HierarchyPfo &hierarchyPfo, const pandora::ParticleFlowObject *const pNeutrinoPfo, const HierarchyPfoVector &trackPfos, const bool useUpstream, DLPrimaryNetworkParams &primaryNetworkParams) const
Function to calculate the DLPrimaryNetworkParams.
void SetDetectorBoundaries()
Set the detector boundaries.
float m_connectionExtrapDistanceMax
the m_connectionExtrapDistance maximum range boundary