All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
lar_dl_content::DlVertexingAlgorithm Class Reference

DeepLearningTrackShowerIdAlgorithm class. More...

#include <DlVertexingAlgorithm.h>

Inheritance diagram for lar_dl_content::DlVertexingAlgorithm:

Classes

class  VertexTuple
 

Public Types

typedef std::map< std::pair
< int, int >, std::vector
< const pandora::CaloHit * > > 
PixelToCaloHitsMap
 

Public Member Functions

 DlVertexingAlgorithm ()
 Default constructor. More...
 
virtual ~DlVertexingAlgorithm ()
 

Private Types

typedef std::pair< int, int > Pixel
 
typedef std::vector< PixelPixelVector
 

Private Member Functions

pandora::StatusCode Run ()
 
pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
pandora::StatusCode PrepareTrainingSample ()
 
pandora::StatusCode Infer ()
 
pandora::StatusCode MakeNetworkInputFromHits (const pandora::CaloHitList &caloHits, LArDLHelper::TorchInput &networkInput, PixelVector &pixelVector) const
 
pandora::StatusCode MakeWirePlaneCoordinatesFromPixels (const pandora::CaloHitList &caloHits, const PixelVector &pixelVector, pandora::CartesianPointVector &positionVector) const
 
pandora::StatusCode MakeWirePlaneCoordinatesFromCanvas (const pandora::CaloHitList &caloHits, float **canvas, const int canvasWidth, const int canvasHeight, const int columnOffset, const int rowOffset, pandora::CartesianPointVector &positionVector) const
 
void GetCanvasParameters (const LArDLHelper::TorchOutput &networkOutput, const PixelVector &pixelVector, int &columnOffset, int &rowOffset, int &width, int &height) const
 Determines the parameters of the canvas for extracting the vertex location. The network predicts the distance that each pixel associated with a hit is located from the vertex, but says nothing about the direction. As a result, the ring describing the potential vertices associated with that hit can extend beyond the original canvas size. This function returns the size of the required canvas and the offset for the bottom left corner. More...
 
void DrawRing (float **canvas, const int row, const int col, const int inner, const int outer, const float weight) const
 Add a filled ring to the specified canvas. The ring has an inner radius based on the minimum predicted distance to the vertex and an outer radius based on the maximum predicted distance to the vertex. The centre of the ring is the location of the hit used to predict the distance to the vertex. Each pixel to be filled is augmented by the specified weight. In this way, once all hits have been considered, a consensus view emerges of the likely vertex location based on the overlap of various rings centred at different locations. More...
 
void Update (const int radius, int &col, int &row) const
 Update the coordinates along the loci of a circle. When drawing the ring we need an efficient means to determine the next pixel defining the inner and outer loci of the ring. This update function uses the Bresenham midpoint circle update function to determine this location. The row position is always incremented by 1 pixel, the column position is left unchanged, or decremented by 1 pixel to best follow the arc of the true underlying circle. More...
 
pandora::StatusCode GetMCToHitsMap (LArMCParticleHelper::MCContributionMap &mcToHitsMap) const
 
pandora::StatusCode CompleteMCHierarchy (const LArMCParticleHelper::MCContributionMap &mcToHitsMap, pandora::MCParticleList &mcHierarchy) const
 
void GetHitRegion (const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
 
pandora::StatusCode MakeCandidateVertexList (const pandora::CartesianPointVector &positions)
 Create a vertex list from the candidate vertices. More...
 
void GetTrueVertexPosition (float &x, float &y, float &z) const
 Retrieve the true neutrino vertex position. More...
 
void GetTrueVertexPosition (float &x, float &u, float &v, float &w) const
 Retrieve the true neutrino vertex position. More...
 
const pandora::CartesianVector & GetTrueVertex () const
 Retrieve the true neutrino vertex. More...
 
void PopulateRootTree (const std::vector< VertexTuple > &vertexTuples, const pandora::CartesianPointVector &vertexCandidatesU, const pandora::CartesianPointVector &vertexCandidatesV, const pandora::CartesianPointVector &vertexCandidatesW) const
 Populate a root true with vertex information. More...
 

Private Attributes

bool m_trainingMode
 Training mode. More...
 
std::string m_trainingOutputFile
 Output file name for training examples. More...
 
std::string m_inputVertexListName
 Input vertex list name if 2nd pass. More...
 
std::string m_outputVertexListName
 Output vertex list name. More...
 
pandora::StringVector m_caloHitListNames
 Names of input calo hit lists. More...
 
LArDLHelper::TorchModel m_modelU
 The model for the U view. More...
 
LArDLHelper::TorchModel m_modelV
 The model for the V view. More...
 
LArDLHelper::TorchModel m_modelW
 The model for the W view. More...
 
int m_event
 The current event number. More...
 
int m_pass
 The pass of the train/infer step. More...
 
int m_nClasses
 The number of distance classes. More...
 
int m_height
 The height of the images. More...
 
int m_width
 The width of the images. More...
 
float m_maxHitAdc
 Maximum ADC value to allow. More...
 
float m_regionSize
 The half width/height of the event region to consider in cm. More...
 
bool m_visualise
 Whether or not to visualise the candidate vertices. More...
 
bool m_writeTree
 Whether or not to write validation details to a ROOT tree. More...
 
std::string m_rootTreeName
 The ROOT tree name. More...
 
std::string m_rootFileName
 The ROOT file name. More...
 
std::mt19937 m_rng
 The random number generator. More...
 
std::vector< double > m_thresholds
 Distance class thresholds. More...
 
const double PY_EPSILON {1.1920929e-7}
 The value of epsilon in Python. More...
 

Detailed Description

DeepLearningTrackShowerIdAlgorithm class.

Definition at line 27 of file DlVertexingAlgorithm.h.

Member Typedef Documentation

typedef std::pair<int, int> lar_dl_content::DlVertexingAlgorithm::Pixel
private

Definition at line 58 of file DlVertexingAlgorithm.h.

typedef std::map<std::pair<int, int>, std::vector<const pandora::CaloHit *> > lar_dl_content::DlVertexingAlgorithm::PixelToCaloHitsMap

Definition at line 30 of file DlVertexingAlgorithm.h.

Definition at line 59 of file DlVertexingAlgorithm.h.

Constructor & Destructor Documentation

lar_dl_content::DlVertexingAlgorithm::DlVertexingAlgorithm ( )

Default constructor.

Definition at line 28 of file DlVertexingAlgorithm.cc.

28  :
29  m_trainingMode{false},
31  m_event{-1},
32  m_pass{1},
33  m_nClasses{0},
34  m_height{256},
35  m_width{256},
36  m_maxHitAdc{500.f},
37  m_regionSize{32.f},
38  m_visualise{false},
39  m_writeTree{false},
40  m_rng(static_cast<std::mt19937::result_type>(std::chrono::high_resolution_clock::now().time_since_epoch().count()))
41 {
42 }
bool m_visualise
Whether or not to visualise the candidate vertices.
int m_event
The current event number.
float m_regionSize
The half width/height of the event region to consider in cm.
float m_maxHitAdc
Maximum ADC value to allow.
std::mt19937 m_rng
The random number generator.
int m_nClasses
The number of distance classes.
bool m_writeTree
Whether or not to write validation details to a ROOT tree.
int m_height
The height of the images.
int m_pass
The pass of the train/infer step.
std::string m_trainingOutputFile
Output file name for training examples.
std::size_t count(Cont const &cont)
int m_width
The width of the images.
lar_dl_content::DlVertexingAlgorithm::~DlVertexingAlgorithm ( )
virtual

Definition at line 44 of file DlVertexingAlgorithm.cc.

45 {
46  if (m_writeTree)
47  {
48  try
49  {
50  PANDORA_MONITORING_API(SaveTree(this->GetPandora(), m_rootTreeName, m_rootFileName, "RECREATE"));
51  }
52  catch (StatusCodeException e)
53  {
54  std::cout << "VertexAssessmentAlgorithm: Unable to write to ROOT tree" << std::endl;
55  }
56  }
57 }
std::string m_rootTreeName
The ROOT tree name.
bool m_writeTree
Whether or not to write validation details to a ROOT tree.
std::string m_rootFileName
The ROOT file name.
do i e
BEGIN_PROLOG could also be cout

Member Function Documentation

StatusCode lar_dl_content::DlVertexingAlgorithm::CompleteMCHierarchy ( const LArMCParticleHelper::MCContributionMap mcToHitsMap,
pandora::MCParticleList &  mcHierarchy 
) const
private

Definition at line 568 of file DlVertexingAlgorithm.cc.

569 {
570  try
571  {
572  for (const auto [mc, hits] : mcToHitsMap)
573  {
574  (void)hits;
575  mcHierarchy.push_back(mc);
576  LArMCParticleHelper::GetAllAncestorMCParticles(mc, mcHierarchy);
577  }
578  }
579  catch (const StatusCodeException &e)
580  {
581  return e.GetStatusCode();
582  }
583 
584  // Move the neutrino to the front of the list
585  auto pivot =
586  std::find_if(mcHierarchy.begin(), mcHierarchy.end(), [](const MCParticle *mc) -> bool { return LArMCParticleHelper::IsNeutrino(mc); });
587  (void)pivot;
588  if (pivot != mcHierarchy.end())
589  std::rotate(mcHierarchy.begin(), pivot, std::next(pivot));
590  else
591  return STATUS_CODE_NOT_FOUND;
592 
593  return STATUS_CODE_SUCCESS;
594 }
j template void())
Definition: json.hpp:3108
do i e
void lar_dl_content::DlVertexingAlgorithm::DrawRing ( float **  canvas,
const int  row,
const int  col,
const int  inner,
const int  outer,
const float  weight 
) const
private

Add a filled ring to the specified canvas. The ring has an inner radius based on the minimum predicted distance to the vertex and an outer radius based on the maximum predicted distance to the vertex. The centre of the ring is the location of the hit used to predict the distance to the vertex. Each pixel to be filled is augmented by the specified weight. In this way, once all hits have been considered, a consensus view emerges of the likely vertex location based on the overlap of various rings centred at different locations.

    The underlying implementation is a variant of the Bresenham midpoint circle algorithm and therefore only computes pixel
    coordinates for one octant of each circle (one of radius 'inner', one of radius 'outer') and interpolates the fill between
    points using integer arithmetic, guaranteeing each pixel of the ring is filled once and only once, and then mirrored to the
    remaining seven octants.
Parameters
networkOutputThe TorchOutput object populated by the network inference step
pixelVectorThe vector of populated pixels
thresholdsThe fractional distance thresholds representing the classes predicted by the network
columnOffsetThe output column offset for the canvas
rowOffsetThe output row offset for the canvas
widthThe output width for the canvas
heightThe output height for the canvas

Definition at line 481 of file DlVertexingAlgorithm.cc.

482 {
483  // Set the starting position for each circle bounding the ring
484  int c1{inner}, r1{0}, c2{outer}, r2{0};
485  int inner2{inner * inner}, outer2{outer * outer};
486  while (c2 >= r2)
487  {
488  // Set the output pixel location
489  int rp2{r2}, cp2{c2};
490  // We're still within the octant for the inner ring, so use the inner pixel location (see Update comment below)
491  // Note also that the inner row is always the same as the outer row, so no need to define rp1
492  int cp1{c1};
493  if (c1 <= r1)
494  { // We've completed the arc of the inner ring already, so just move radially out from here (see Update comment below)
495  cp1 = r2;
496  }
497  // Fill the pixels from inner to outer in the current row and their mirror pixels in the other octants
498  for (int c = cp1; c <= cp2; ++c)
499  {
500  canvas[row + rp2][col + c] += weight;
501  if (rp2 != c)
502  canvas[row + c][col + rp2] += weight;
503  if (rp2 != 0 && cp2 != 0)
504  {
505  canvas[row - rp2][col - c] += weight;
506  if (rp2 != c)
507  canvas[row - c][col - rp2] += weight;
508  }
509  if (rp2 != 0)
510  {
511  canvas[row - rp2][col + c] += weight;
512  if (rp2 != c)
513  canvas[row + c][col - rp2] += weight;
514  }
515  if (cp2 != 0)
516  {
517  canvas[row + rp2][col - c] += weight;
518  if (rp2 != c)
519  canvas[row - c][col + rp2] += weight;
520  }
521  }
522  // Only update the inner location while it remains in the octant (outer ring also remains in the octant of course, but the logic of
523  // the update means that the inner ring can leave its octant before the outer ring is complete, so we need to stop that)
524  if (c1 > r1)
525  this->Update(inner2, c1, r1);
526  // Update the outer location - increase the row position with every step, decrease the column position if conditions are met
527  this->Update(outer2, c2, r2);
528  }
529 }
void Update(const int radius, int &col, int &row) const
Update the coordinates along the loci of a circle. When drawing the ring we need an efficient means t...
void lar_dl_content::DlVertexingAlgorithm::GetCanvasParameters ( const LArDLHelper::TorchOutput networkOutput,
const PixelVector pixelVector,
int &  columnOffset,
int &  rowOffset,
int &  width,
int &  height 
) const
private

Determines the parameters of the canvas for extracting the vertex location. The network predicts the distance that each pixel associated with a hit is located from the vertex, but says nothing about the direction. As a result, the ring describing the potential vertices associated with that hit can extend beyond the original canvas size. This function returns the size of the required canvas and the offset for the bottom left corner.

Parameters
networkOutputThe TorchOutput object populated by the network inference step
pixelVectorThe vector of populated pixels
columnOffsetThe output column offset for the canvas
rowOffsetThe output row offset for the canvas
widthThe output width for the canvas
heightThe output height for the canvas

Definition at line 446 of file DlVertexingAlgorithm.cc.

448 {
449  const double scaleFactor{std::sqrt(m_height * m_height + m_width * m_width)};
450  // output is a 1 x num_classes x height x width tensor
451  // we want the maximum value in the num_classes dimension (1) for every pixel
452  auto classes{torch::argmax(networkOutput, 1)};
453  // the argmax result is a 1 x height x width tensor where each element is a class id
454  auto classesAccessor{classes.accessor<long, 3>()};
455  int colOffsetMin{0}, colOffsetMax{0}, rowOffsetMin{0}, rowOffsetMax{0};
456  for (const auto [row, col] : pixelVector)
457  {
458  const auto cls{classesAccessor[0][row][col]};
459  const double threshold{m_thresholds[cls]};
460  if (threshold > 0. && threshold < 1.)
461  {
462  const int distance = static_cast<int>(std::round(std::ceil(scaleFactor * threshold)));
463  if ((row - distance) < rowOffsetMin)
464  rowOffsetMin = row - distance;
465  if ((row + distance) > rowOffsetMax)
466  rowOffsetMax = row + distance;
467  if ((col - distance) < colOffsetMin)
468  colOffsetMin = col - distance;
469  if ((col + distance) > colOffsetMax)
470  colOffsetMax = col + distance;
471  }
472  }
473  colOffset = colOffsetMin < 0 ? -colOffsetMin : 0;
474  rowOffset = rowOffsetMin < 0 ? -rowOffsetMin : 0;
475  width = std::max(colOffsetMax + colOffset + 1, m_width);
476  height = std::max(rowOffsetMax + rowOffset + 1, m_height);
477 }
std::vector< double > m_thresholds
Distance class thresholds.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
int m_height
The height of the images.
int m_width
The width of the images.
void lar_dl_content::DlVertexingAlgorithm::GetHitRegion ( const pandora::CaloHitList &  caloHitList,
float &  xMin,
float &  xMax,
float &  zMin,
float &  zMax 
) const
private

Definition at line 598 of file DlVertexingAlgorithm.cc.

599 {
600  xMin = std::numeric_limits<float>::max();
601  xMax = -std::numeric_limits<float>::max();
602  zMin = std::numeric_limits<float>::max();
603  zMax = -std::numeric_limits<float>::max();
604  // Find the range of x and z values in the view
605  for (const CaloHit *pCaloHit : caloHitList)
606  {
607  const float x{pCaloHit->GetPositionVector().GetX()};
608  const float z{pCaloHit->GetPositionVector().GetZ()};
609  xMin = std::min(x, xMin);
610  xMax = std::max(x, xMax);
611  zMin = std::min(z, zMin);
612  zMax = std::max(z, zMax);
613  }
614 
615  if (m_pass > 1)
616  {
617  // Constrain the hits to the allowed region if needed
618  const VertexList *pVertexList(nullptr);
619  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_inputVertexListName, pVertexList));
620  if (pVertexList->empty() || caloHitList.empty())
621  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
622  const CartesianVector &centroid{pVertexList->front()->GetPosition()};
623  const HitType view{caloHitList.front()->GetHitType()};
624  float xCentroid{centroid.GetX()}, zCentroid{0.f};
625  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
626  switch (view)
627  {
628  case TPC_VIEW_U:
629  zCentroid = transform->YZtoU(centroid.GetY(), centroid.GetZ());
630  break;
631  case TPC_VIEW_V:
632  zCentroid = transform->YZtoV(centroid.GetY(), centroid.GetZ());
633  break;
634  case TPC_VIEW_W:
635  zCentroid = transform->YZtoW(centroid.GetY(), centroid.GetZ());
636  break;
637  default:
638  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
639  break;
640  }
641 
642  xMin = std::max(xMin, xCentroid - m_regionSize);
643  xMax = std::min(xMax, xCentroid + m_regionSize);
644  zMin = std::max(zMin, zCentroid - m_regionSize);
645  zMax = std::min(zMax, zCentroid + m_regionSize);
646  }
647 
648  // Avoid unreasonable rescaling of very small hit regions
649  const float xRange{xMax - xMin}, zRange{zMax - zMin};
650  if (2.f * xRange < m_width)
651  {
652  const float padding{0.5f * (0.5f * m_width - xRange)};
653  xMin -= padding;
654  xMax += padding;
655  }
656  if (2.f * zRange < m_height)
657  {
658  const float padding{0.5f * (0.5f * m_height - zRange)};
659  zMin -= padding;
660  zMax += padding;
661  }
662 }
process_name opflash particleana ie ie ie z
static constexpr Sample_t transform(Sample_t sample)
process_name opflash particleana ie x
float m_regionSize
The half width/height of the event region to consider in cm.
int m_height
The height of the images.
int m_pass
The pass of the train/infer step.
std::string m_inputVertexListName
Input vertex list name if 2nd pass.
int m_width
The width of the images.
std::list< Vertex > VertexList
Definition: DCEL.h:182
StatusCode lar_dl_content::DlVertexingAlgorithm::GetMCToHitsMap ( LArMCParticleHelper::MCContributionMap mcToHitsMap) const
private

Definition at line 551 of file DlVertexingAlgorithm.cc.

552 {
553  const CaloHitList *pCaloHitList2D(nullptr);
554  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, "CaloHitList2D", pCaloHitList2D));
555  const MCParticleList *pMCParticleList(nullptr);
556  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
557 
559  parameters.m_maxPhotonPropagation = std::numeric_limits<float>::max();
560  LArMCParticleHelper::SelectReconstructableMCParticles(
561  pMCParticleList, pCaloHitList2D, parameters, LArMCParticleHelper::IsBeamNeutrinoFinalState, mcToHitsMap);
562 
563  return STATUS_CODE_SUCCESS;
564 }
float m_maxPhotonPropagation
the maximum photon propagation length
const CartesianVector & lar_dl_content::DlVertexingAlgorithm::GetTrueVertex ( ) const
private

Retrieve the true neutrino vertex.

Definition at line 712 of file DlVertexingAlgorithm.cc.

713 {
714  const MCParticleList *pMCParticleList{nullptr};
715  if (STATUS_CODE_SUCCESS == PandoraContentApi::GetCurrentList(*this, pMCParticleList) && pMCParticleList)
716  {
717  MCParticleVector primaries;
718  LArMCParticleHelper::GetPrimaryMCParticleList(pMCParticleList, primaries);
719  if (!primaries.empty())
720  {
721  const MCParticle *primary{primaries.front()};
722  const MCParticleList &parents{primary->GetParentList()};
723  if (parents.size() == 1)
724  {
725  const MCParticle *trueNeutrino{parents.front()};
726  if (LArMCParticleHelper::IsNeutrino(trueNeutrino))
727  return primaries.front()->GetVertex();
728  }
729  }
730  }
731 
732  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
733 }
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
void lar_dl_content::DlVertexingAlgorithm::GetTrueVertexPosition ( float &  x,
float &  y,
float &  z 
) const
private

Retrieve the true neutrino vertex position.

Definition at line 690 of file DlVertexingAlgorithm.cc.

691 {
692  const CartesianVector &trueVertex{this->GetTrueVertex()};
693  x = trueVertex.GetX();
694  y = trueVertex.GetY();
695  z = trueVertex.GetZ();
696 }
process_name opflash particleana ie ie ie z
const pandora::CartesianVector & GetTrueVertex() const
Retrieve the true neutrino vertex.
process_name opflash particleana ie x
process_name opflash particleana ie ie y
void lar_dl_content::DlVertexingAlgorithm::GetTrueVertexPosition ( float &  x,
float &  u,
float &  v,
float &  w 
) const
private

Retrieve the true neutrino vertex position.

Definition at line 700 of file DlVertexingAlgorithm.cc.

701 {
702  const CartesianVector &trueVertex{this->GetTrueVertex()};
703  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
704  x = trueVertex.GetX();
705  u = static_cast<float>(transform->YZtoU(trueVertex.GetY(), trueVertex.GetZ()));
706  v = static_cast<float>(transform->YZtoV(trueVertex.GetY(), trueVertex.GetZ()));
707  w = static_cast<float>(transform->YZtoW(trueVertex.GetY(), trueVertex.GetZ()));
708 }
const pandora::CartesianVector & GetTrueVertex() const
Retrieve the true neutrino vertex.
static constexpr Sample_t transform(Sample_t sample)
process_name opflash particleana ie x
StatusCode lar_dl_content::DlVertexingAlgorithm::Infer ( )
private

Definition at line 157 of file DlVertexingAlgorithm.cc.

158 {
159  if (m_pass == 1)
160  ++m_event;
161  CartesianPointVector vertexCandidatesU, vertexCandidatesV, vertexCandidatesW;
162  for (const std::string listName : m_caloHitListNames)
163  {
164  const CaloHitList *pCaloHitList{nullptr};
165  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listName, pCaloHitList));
166 
167  HitType view{pCaloHitList->front()->GetHitType()};
168  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
169  if (!isU && !isV && !isW)
170  return STATUS_CODE_NOT_ALLOWED;
171 
173  PixelVector pixelVector;
174  this->MakeNetworkInputFromHits(*pCaloHitList, input, pixelVector);
175 
176  // Run the input through the trained model
178  inputs.push_back(input);
180  if (isU)
181  LArDLHelper::Forward(m_modelU, inputs, output);
182  else if (isV)
183  LArDLHelper::Forward(m_modelV, inputs, output);
184  else
185  LArDLHelper::Forward(m_modelW, inputs, output);
186 
187  int colOffset{0}, rowOffset{0}, canvasWidth{m_width}, canvasHeight{m_height};
188  this->GetCanvasParameters(output, pixelVector, colOffset, rowOffset, canvasWidth, canvasHeight);
189 
190  float **canvas{new float *[canvasHeight]};
191  for (int row = 0; row < canvasHeight; ++row)
192  canvas[row] = new float[canvasWidth]{};
193 
194  // we want the maximum value in the num_classes dimension (1) for every pixel
195  auto classes{torch::argmax(output, 1)};
196  // the argmax result is a 1 x height x width tensor where each element is a class id
197  auto classesAccessor{classes.accessor<long, 3>()};
198  const double scaleFactor{std::sqrt(m_height * m_height + m_width * m_width)};
199  std::map<int, bool> haveSeenMap;
200  for (const auto [row, col] : pixelVector)
201  {
202  const auto cls{classesAccessor[0][row][col]};
203  if (cls > 0 && cls < m_nClasses)
204  {
205  const int inner{static_cast<int>(std::round(std::ceil(scaleFactor * m_thresholds[cls - 1])))};
206  const int outer{static_cast<int>(std::round(std::ceil(scaleFactor * m_thresholds[cls])))};
207  this->DrawRing(canvas, row + rowOffset, col + colOffset, inner, outer, 1.f / (outer * outer - inner * inner));
208  }
209  }
210 
211  CartesianPointVector positionVector;
212  this->MakeWirePlaneCoordinatesFromCanvas(*pCaloHitList, canvas, canvasWidth, canvasHeight, colOffset, rowOffset, positionVector);
213  if (isU)
214  vertexCandidatesU.emplace_back(positionVector.front());
215  else if (isV)
216  vertexCandidatesV.emplace_back(positionVector.front());
217  else
218  vertexCandidatesW.emplace_back(positionVector.front());
219 
220  if (m_visualise)
221  {
222  PANDORA_MONITORING_API(SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, -1.f, 1.f, 1.f));
223  try
224  {
225  float x{0.f}, u{0.f}, v{0.f}, w{0.f};
226  this->GetTrueVertexPosition(x, u, v, w);
227  if (isU)
228  {
229  const CartesianVector trueVertex(x, 0.f, u);
230  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "U(true)", BLUE, 3));
231  }
232  else if (isV)
233  {
234  const CartesianVector trueVertex(x, 0.f, v);
235  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "V(true)", BLUE, 3));
236  }
237  else if (isW)
238  {
239  const CartesianVector trueVertex(x, 0.f, w);
240  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "W(true)", BLUE, 3));
241  }
242  }
243  catch (StatusCodeException &e)
244  {
245  std::cerr << "DlVertexingAlgorithm: Warning. Couldn't find true vertex." << std::endl;
246  }
247  for (const auto pos : positionVector)
248  {
249  std::string label{isU ? "U" : isV ? "V" : "W"};
250  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &pos, label, RED, 3));
251  }
252  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
253  }
254 
255  for (int row = 0; row < canvasHeight; ++row)
256  delete[] canvas[row];
257  delete[] canvas;
258  }
259 
260  int nEmptyLists{0};
261  if (vertexCandidatesU.empty())
262  ++nEmptyLists;
263  if (vertexCandidatesV.empty())
264  ++nEmptyLists;
265  if (vertexCandidatesW.empty())
266  ++nEmptyLists;
267  std::vector<VertexTuple> vertexTuples;
268  CartesianPointVector candidates3D;
269  if (nEmptyLists == 0)
270  {
271  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), vertexCandidatesW.front()));
272  }
273  else if (nEmptyLists == 1)
274  {
275  if (vertexCandidatesU.empty())
276  { // V and W available
277  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesV.front(), vertexCandidatesW.front(), TPC_VIEW_V, TPC_VIEW_W));
278  }
279  else if (vertexCandidatesV.empty())
280  { // U and W available
281  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesW.front(), TPC_VIEW_U, TPC_VIEW_W));
282  }
283  else
284  { // U and V available
285  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), TPC_VIEW_U, TPC_VIEW_W));
286  }
287  }
288  else
289  { // Not enough views to reconstruct a 3D vertex
290  std::cout << "Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
291  return STATUS_CODE_NOT_FOUND;
292  }
293 
294  if (m_visualise)
295  {
296  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &vertexTuples.front().GetPosition(), "candidate", GREEN, 1));
297  }
298 
299  if (!vertexTuples.empty())
300  {
301  const CartesianVector &vertex{vertexTuples.front().GetPosition()};
302  CartesianPointVector vertexCandidates;
303  vertexCandidates.emplace_back(vertex);
304  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->MakeCandidateVertexList(vertexCandidates));
305  }
306  else
307  {
308  std::cout << "Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
309  return STATUS_CODE_NOT_FOUND;
310  }
311 
312  if (m_visualise)
313  {
314  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
315  }
316 
317  return STATUS_CODE_SUCCESS;
318 }
process_name vertex
Definition: cheaterreco.fcl:51
LArDLHelper::TorchModel m_modelU
The model for the U view.
std::vector< double > m_thresholds
Distance class thresholds.
pandora::StatusCode MakeNetworkInputFromHits(const pandora::CaloHitList &caloHits, LArDLHelper::TorchInput &networkInput, PixelVector &pixelVector) const
process_name opflash particleana ie x
BEGIN_PROLOG could also be cerr
bool m_visualise
Whether or not to visualise the candidate vertices.
int m_event
The current event number.
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
LArDLHelper::TorchModel m_modelV
The model for the V view.
void GetCanvasParameters(const LArDLHelper::TorchOutput &networkOutput, const PixelVector &pixelVector, int &columnOffset, int &rowOffset, int &width, int &height) const
Determines the parameters of the canvas for extracting the vertex location. The network predicts the ...
int m_nClasses
The number of distance classes.
int m_height
The height of the images.
int m_pass
The pass of the train/infer step.
static void Forward(TorchModel &model, const TorchInputVector &input, TorchOutput &output)
Run a deep learning model.
Definition: LArDLHelper.cc:41
void GetTrueVertexPosition(float &x, float &y, float &z) const
Retrieve the true neutrino vertex position.
LArDLHelper::TorchModel m_modelW
The model for the W view.
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
pandora::StatusCode MakeCandidateVertexList(const pandora::CartesianPointVector &positions)
Create a vertex list from the candidate vertices.
do i e
int m_width
The width of the images.
BEGIN_PROLOG could also be cout
std::vector< torch::jit::IValue > TorchInputVector
Definition: LArDLHelper.h:27
pandora::StatusCode MakeWirePlaneCoordinatesFromCanvas(const pandora::CaloHitList &caloHits, float **canvas, const int canvasWidth, const int canvasHeight, const int columnOffset, const int rowOffset, pandora::CartesianPointVector &positionVector) const
void DrawRing(float **canvas, const int row, const int col, const int inner, const int outer, const float weight) const
Add a filled ring to the specified canvas. The ring has an inner radius based on the minimum predicte...
StatusCode lar_dl_content::DlVertexingAlgorithm::MakeCandidateVertexList ( const pandora::CartesianPointVector &  positions)
private

Create a vertex list from the candidate vertices.

Parameters
candidatesThe candidate positions with which to create the list.
Returns
The StatusCode resulting from the function

Definition at line 666 of file DlVertexingAlgorithm.cc.

667 {
668  const VertexList *pVertexList{nullptr};
669  std::string temporaryListName;
670  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, temporaryListName));
671 
672  for (const CartesianVector position : positions)
673  {
675  parameters.m_position = position;
676  parameters.m_vertexLabel = VERTEX_INTERACTION;
677  parameters.m_vertexType = VERTEX_3D;
678 
679  const Vertex *pVertex(nullptr);
680  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
681  }
682  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_outputVertexListName));
683  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
684 
685  return STATUS_CODE_SUCCESS;
686 }
std::string m_outputVertexListName
Output vertex list name.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
std::list< Vertex > VertexList
Definition: DCEL.h:182
StatusCode lar_dl_content::DlVertexingAlgorithm::MakeNetworkInputFromHits ( const pandora::CaloHitList &  caloHits,
LArDLHelper::TorchInput networkInput,
PixelVector pixelVector 
) const
private

Definition at line 322 of file DlVertexingAlgorithm.cc.

324 {
325  // Determine the range of coordinates for the view
326  float xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
327  GetHitRegion(caloHits, xMin, xMax, zMin, zMax);
328 
329  // Determine the bin edges - need double precision here for consistency with Python binning
330  std::vector<double> xBinEdges(m_width + 1);
331  std::vector<double> zBinEdges(m_height + 1);
332  xBinEdges[0] = xMin - PY_EPSILON;
333  const double dx = ((xMax + PY_EPSILON) - (xMin - PY_EPSILON)) / m_width;
334  for (int i = 1; i < m_width + 1; ++i)
335  xBinEdges[i] = xBinEdges[i - 1] + dx;
336  zBinEdges[0] = zMin - PY_EPSILON;
337  const double dz = ((zMax + PY_EPSILON) - (zMin - PY_EPSILON)) / m_height;
338  for (int i = 1; i < m_height + 1; ++i)
339  zBinEdges[i] = zBinEdges[i - 1] + dz;
340 
341  LArDLHelper::InitialiseInput({1, 1, m_height, m_width}, networkInput);
342  auto accessor = networkInput.accessor<float, 4>();
343 
344  float maxValue{0.f};
345  for (const CaloHit *pCaloHit : caloHits)
346  {
347  const float x{pCaloHit->GetPositionVector().GetX()};
348  const float z{pCaloHit->GetPositionVector().GetZ()};
349  if (m_pass > 1)
350  {
351  if (x < xMin || x > xMax || z < zMin || z > zMax)
352  continue;
353  }
354  const float adc{pCaloHit->GetInputEnergy() < m_maxHitAdc ? pCaloHit->GetInputEnergy() : m_maxHitAdc};
355  const int pixelX{static_cast<int>(std::floor((x - xBinEdges[0]) / dx))};
356  const int pixelZ{(m_height - 1) - static_cast<int>(std::floor((z - zBinEdges[0]) / dz))};
357  accessor[0][0][pixelZ][pixelX] += adc;
358  if (accessor[0][0][pixelZ][pixelX] > maxValue)
359  maxValue = accessor[0][0][pixelZ][pixelX];
360  }
361  if (maxValue > 0)
362  {
363  for (int row = 0; row < m_height; ++row)
364  {
365  for (int col = 0; col < m_width; ++col)
366  {
367  const float value{accessor[0][0][row][col]};
368  accessor[0][0][row][col] = value / maxValue;
369  if (value > 0)
370  pixelVector.emplace_back(std::make_pair(row, col));
371  }
372  }
373  }
374 
375  return STATUS_CODE_SUCCESS;
376 }
process_name opflash particleana ie ie ie z
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
process_name opflash particleana ie x
float m_maxHitAdc
Maximum ADC value to allow.
const double PY_EPSILON
The value of epsilon in Python.
int m_height
The height of the images.
int m_pass
The pass of the train/infer step.
temporary value
int m_width
The width of the images.
static void InitialiseInput(const at::IntArrayRef dimensions, TorchInput &tensor)
Create a torch input tensor.
Definition: LArDLHelper.cc:34
StatusCode lar_dl_content::DlVertexingAlgorithm::MakeWirePlaneCoordinatesFromCanvas ( const pandora::CaloHitList &  caloHits,
float **  canvas,
const int  canvasWidth,
const int  canvasHeight,
const int  columnOffset,
const int  rowOffset,
pandora::CartesianPointVector &  positionVector 
) const
private

Definition at line 409 of file DlVertexingAlgorithm.cc.

411 {
412  // Determine the range of coordinates for the view
413  float xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
414  GetHitRegion(caloHits, xMin, xMax, zMin, zMax);
415 
416  // Determine the bin size - need double precision here for consistency with Python binning
417  const double dx{((xMax + PY_EPSILON) - (xMin - PY_EPSILON)) / m_width};
418  xMin -= PY_EPSILON;
419  const double dz{((zMax + PY_EPSILON) - (zMin - PY_EPSILON)) / m_height};
420  zMin -= PY_EPSILON;
421  // Original hit mapping applies a floor operation, so add half a pixel width to get pixel centre
422  const float xShift{static_cast<float>(dx * 0.5f)};
423  const float zShift{static_cast<float>(dz * 0.5f)};
424 
425  float best{-1.f};
426  int rowBest{0}, colBest{0};
427  for (int row = 0; row < canvasHeight; ++row)
428  for (int col = 0; col < canvasWidth; ++col)
429  if (canvas[row][col] > 0 && canvas[row][col] > best)
430  {
431  best = canvas[row][col];
432  rowBest = row;
433  colBest = col;
434  }
435 
436  const float x{static_cast<float>((colBest - columnOffset) * dx + xMin + xShift)};
437  const float z{static_cast<float>(dz * ((m_height - 1) - (rowBest - rowOffset)) + zMin + zShift)};
438  CartesianVector pt(x, 0.f, z);
439  positionVector.emplace_back(pt);
440 
441  return STATUS_CODE_SUCCESS;
442 }
process_name opflash particleana ie ie ie z
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
process_name opflash particleana ie x
const double PY_EPSILON
The value of epsilon in Python.
int m_height
The height of the images.
int m_width
The width of the images.
StatusCode lar_dl_content::DlVertexingAlgorithm::MakeWirePlaneCoordinatesFromPixels ( const pandora::CaloHitList &  caloHits,
const PixelVector pixelVector,
pandora::CartesianPointVector &  positionVector 
) const
private

Definition at line 380 of file DlVertexingAlgorithm.cc.

382 {
383  // Determine the range of coordinates for the view
384  float xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
385  GetHitRegion(caloHits, xMin, xMax, zMin, zMax);
386 
387  // Determine the bin size - need double precision here for consistency with Python binning
388  const double dx{((xMax + PY_EPSILON) - (xMin - PY_EPSILON)) / m_width};
389  xMin -= PY_EPSILON;
390  const double dz{((zMax + PY_EPSILON) - (zMin - PY_EPSILON)) / m_height};
391  zMin -= PY_EPSILON;
392  // Original hit mapping applies a floor operation, so add half a pixel width to get pixel centre
393  const float xShift{static_cast<float>(dx * 0.5f)};
394  const float zShift{static_cast<float>(dz * 0.5f)};
395 
396  for (const auto [row, col] : pixelVector)
397  {
398  const float x{static_cast<float>(col * dx + xMin + xShift)};
399  const float z{static_cast<float>(dz * ((m_height - 1) - row) + zMin + zShift)};
400  CartesianVector pt(x, 0.f, z);
401  positionVector.emplace_back(pt);
402  }
403 
404  return STATUS_CODE_SUCCESS;
405 }
process_name opflash particleana ie ie ie z
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
process_name opflash particleana ie x
const double PY_EPSILON
The value of epsilon in Python.
int m_height
The height of the images.
int m_width
The width of the images.
void lar_dl_content::DlVertexingAlgorithm::PopulateRootTree ( const std::vector< VertexTuple > &  vertexTuples,
const pandora::CartesianPointVector &  vertexCandidatesU,
const pandora::CartesianPointVector &  vertexCandidatesV,
const pandora::CartesianPointVector &  vertexCandidatesW 
) const
private

Populate a root true with vertex information.

Definition at line 735 of file DlVertexingAlgorithm.cc.

737 {
738  if (m_writeTree)
739  {
740  const MCParticleList *pMCParticleList{nullptr};
741  if (STATUS_CODE_SUCCESS == PandoraContentApi::GetCurrentList(*this, pMCParticleList))
742  {
743  if (pMCParticleList)
744  {
746  MCParticleVector primaries;
747  LArMCParticleHelper::GetPrimaryMCParticleList(pMCParticleList, primaries);
748  if (!primaries.empty())
749  {
750  const MCParticle *primary{primaries.front()};
751  const MCParticleList &parents{primary->GetParentList()};
752  if (parents.size() == 1)
753  {
754  const MCParticle *trueNeutrino{parents.front()};
755  if (LArMCParticleHelper::IsNeutrino(trueNeutrino))
756  {
757  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
758  const CartesianVector &trueVertex{primaries.front()->GetVertex()};
759  if (LArVertexHelper::IsInFiducialVolume(this->GetPandora(), trueVertex, "dune_fd_hd"))
760  {
761  const CartesianVector &recoVertex{vertexTuples.front().GetPosition()};
762  const float tx{trueVertex.GetX()};
763  const float tu{static_cast<float>(transform->YZtoU(trueVertex.GetY(), trueVertex.GetZ()))};
764  const float tv{static_cast<float>(transform->YZtoV(trueVertex.GetY(), trueVertex.GetZ()))};
765  const float tw{static_cast<float>(transform->YZtoW(trueVertex.GetY(), trueVertex.GetZ()))};
766  const float rx_u{vertexCandidatesU.front().GetX()};
767  const float ru{vertexCandidatesU.front().GetZ()};
768  const float rx_v{vertexCandidatesV.front().GetX()};
769  const float rv{vertexCandidatesV.front().GetZ()};
770  const float rx_w{vertexCandidatesW.front().GetX()};
771  const float rw{vertexCandidatesW.front().GetZ()};
772  const float dr_u{std::sqrt((rx_u - tx) * (rx_u - tx) + (ru - tu) * (ru - tu))};
773  const float dr_v{std::sqrt((rx_v - tx) * (rx_v - tx) + (rv - tv) * (rv - tv))};
774  const float dr_w{std::sqrt((rx_w - tx) * (rx_w - tx) + (rw - tw) * (rw - tw))};
775  const CartesianVector &dv{recoVertex - trueVertex};
776  const float dr{dv.GetMagnitude()};
777  const float dx{dv.GetX()}, dy{dv.GetY()}, dz{dv.GetZ()};
778  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "event", m_event));
779  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "pass", m_pass));
780  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr_u", dr_u));
781  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr_v", dr_v));
782  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr_w", dr_w));
783  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr", dr));
784  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dx", dx));
785  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dy", dy));
786  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dz", dz));
787  PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_rootTreeName));
788  }
789  }
790  }
791  }
792  }
793  }
794  }
795 }
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
static constexpr Sample_t transform(Sample_t sample)
int m_event
The current event number.
std::string m_rootTreeName
The ROOT tree name.
bool m_writeTree
Whether or not to write validation details to a ROOT tree.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
int m_pass
The pass of the train/infer step.
StatusCode lar_dl_content::DlVertexingAlgorithm::PrepareTrainingSample ( )
private

Definition at line 71 of file DlVertexingAlgorithm.cc.

72 {
74  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetMCToHitsMap(mcToHitsMap));
75  MCParticleList hierarchy;
76  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->CompleteMCHierarchy(mcToHitsMap, hierarchy));
77  std::normal_distribution<> gauss(0.f, 15.f);
78 
79  for (const std::string &listname : m_caloHitListNames)
80  {
81  const CaloHitList *pCaloHitList(nullptr);
82  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
83  if (pCaloHitList->empty())
84  continue;
85  m_rng.seed(static_cast<std::mt19937::result_type>(pCaloHitList->size()));
86 
87  HitType view{pCaloHitList->front()->GetHitType()};
88  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
89  if (!(isU || isV || isW))
90  return STATUS_CODE_NOT_ALLOWED;
91 
92  CartesianPointVector vertices;
93  for (const MCParticle *mc : hierarchy)
94  {
95  if (LArMCParticleHelper::IsNeutrino(mc))
96  vertices.push_back(mc->GetVertex());
97  }
98  if (vertices.empty())
99  continue;
100  const CartesianVector &vertex{vertices.front()};
101  const std::string trainingFilename{m_trainingOutputFile + "_" + listname + ".csv"};
102  const unsigned long nVertices{1};
103  unsigned long nHits{0};
104  const unsigned int nuance{LArMCParticleHelper::GetNuanceCode(hierarchy.front())};
105 
106  // Vertices
107  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
108  const double xVtx{vertex.GetX()};
109  double zVtx{0.};
110  if (isW)
111  zVtx = transform->YZtoW(vertex.GetY(), vertex.GetZ());
112  else if (isV)
113  zVtx = transform->YZtoV(vertex.GetY(), vertex.GetZ());
114  else
115  zVtx = transform->YZtoU(vertex.GetY(), vertex.GetZ());
116 
117  // Calo hits
118  double xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
119  // If we're on a refinement pass, constrain the region of interest
120  if (m_pass > 1)
121  {
122  const double xJitter{gauss(m_rng)}, zJitter{gauss(m_rng)};
123  xMin = (xVtx + xJitter) - m_regionSize;
124  xMax = (xVtx + xJitter) + m_regionSize;
125  zMin = (zVtx + zJitter) - m_regionSize;
126  zMax = (zVtx + zJitter) + m_regionSize;
127  }
128 
129  LArMvaHelper::MvaFeatureVector featureVector;
130  featureVector.emplace_back(static_cast<double>(nuance));
131  featureVector.emplace_back(static_cast<double>(nVertices));
132  featureVector.emplace_back(xVtx);
133  featureVector.emplace_back(zVtx);
134 
135  for (const CaloHit *pCaloHit : *pCaloHitList)
136  {
137  const float x{pCaloHit->GetPositionVector().GetX()}, z{pCaloHit->GetPositionVector().GetZ()}, adc{pCaloHit->GetInputEnergy()};
138  // If on a refinement pass, drop hits outside the region of interest
139  if (m_pass > 1 && (x < xMin || x > xMax || z < zMin || z > zMax))
140  continue;
141  featureVector.emplace_back(static_cast<double>(x));
142  featureVector.emplace_back(static_cast<double>(z));
143  featureVector.emplace_back(static_cast<double>(adc));
144  ++nHits;
145  }
146  featureVector.insert(featureVector.begin() + 2, static_cast<double>(nHits));
147  // Only write out the feature vector if there were enough hits in the (possibly perturbed) region of interest
148  if (nHits > 10)
149  LArMvaHelper::ProduceTrainingExample(trainingFilename, true, featureVector);
150  }
151 
152  return STATUS_CODE_SUCCESS;
153 }
process_name vertex
Definition: cheaterreco.fcl:51
process_name opflash particleana ie ie ie z
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:72
static constexpr Sample_t transform(Sample_t sample)
process_name opflash particleana ie x
pandora::StatusCode GetMCToHitsMap(LArMCParticleHelper::MCContributionMap &mcToHitsMap) const
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
float m_regionSize
The half width/height of the event region to consider in cm.
pandora::StatusCode CompleteMCHierarchy(const LArMCParticleHelper::MCContributionMap &mcToHitsMap, pandora::MCParticleList &mcHierarchy) const
std::mt19937 m_rng
The random number generator.
int m_pass
The pass of the train/infer step.
std::string m_trainingOutputFile
Output file name for training examples.
StatusCode lar_dl_content::DlVertexingAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
private

Definition at line 799 of file DlVertexingAlgorithm.cc.

800 {
801  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "TrainingMode", m_trainingMode));
802  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Visualise", m_visualise));
803  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Pass", m_pass));
804  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ImageHeight", m_height));
805  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ImageWidth", m_width));
806  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "DistanceThresholds", m_thresholds));
807  m_nClasses = m_thresholds.size() - 1;
808 
809  if (m_trainingMode)
810  {
811  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "TrainingOutputFileName", m_trainingOutputFile));
812  }
813  else
814  {
815  std::string modelName;
816  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "ModelFileNameU", modelName));
817  modelName = LArFileHelper::FindFileInPath(modelName, "FW_SEARCH_PATH");
818  LArDLHelper::LoadModel(modelName, m_modelU);
819  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "ModelFileNameV", modelName));
820  modelName = LArFileHelper::FindFileInPath(modelName, "FW_SEARCH_PATH");
821  LArDLHelper::LoadModel(modelName, m_modelV);
822  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "ModelFileNameW", modelName));
823  modelName = LArFileHelper::FindFileInPath(modelName, "FW_SEARCH_PATH");
824  LArDLHelper::LoadModel(modelName, m_modelW);
825  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MaxHitAdc", m_maxHitAdc));
826  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteTree", m_writeTree));
827  if (m_writeTree)
828  {
829  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RootTreeName", m_rootTreeName));
830  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RootFileName", m_rootFileName));
831  }
832 
833  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_outputVertexListName));
834  if (m_pass > 1)
835  {
836  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputVertexListName", m_inputVertexListName));
837  }
838  }
839 
840  PANDORA_RETURN_RESULT_IF_AND_IF(
841  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "CaloHitListNames", m_caloHitListNames));
842 
843  return STATUS_CODE_SUCCESS;
844 }
LArDLHelper::TorchModel m_modelU
The model for the U view.
std::vector< double > m_thresholds
Distance class thresholds.
bool m_visualise
Whether or not to visualise the candidate vertices.
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
LArDLHelper::TorchModel m_modelV
The model for the V view.
float m_maxHitAdc
Maximum ADC value to allow.
std::string m_outputVertexListName
Output vertex list name.
int m_nClasses
The number of distance classes.
std::string m_rootTreeName
The ROOT tree name.
bool m_writeTree
Whether or not to write validation details to a ROOT tree.
int m_height
The height of the images.
int m_pass
The pass of the train/infer step.
std::string m_inputVertexListName
Input vertex list name if 2nd pass.
LArDLHelper::TorchModel m_modelW
The model for the W view.
std::string m_trainingOutputFile
Output file name for training examples.
static pandora::StatusCode LoadModel(const std::string &filename, TorchModel &model)
Loads a deep learning model.
Definition: LArDLHelper.cc:16
std::string m_rootFileName
The ROOT file name.
int m_width
The width of the images.
StatusCode lar_dl_content::DlVertexingAlgorithm::Run ( )
private

Definition at line 61 of file DlVertexingAlgorithm.cc.

62 {
63  if (m_trainingMode)
64  return this->PrepareTrainingSample();
65  else
66  return this->Infer();
67 
68  return STATUS_CODE_SUCCESS;
69 }
void lar_dl_content::DlVertexingAlgorithm::Update ( const int  radius,
int &  col,
int &  row 
) const
private

Update the coordinates along the loci of a circle. When drawing the ring we need an efficient means to determine the next pixel defining the inner and outer loci of the ring. This update function uses the Bresenham midpoint circle update function to determine this location. The row position is always incremented by 1 pixel, the column position is left unchanged, or decremented by 1 pixel to best follow the arc of the true underlying circle.

Parameters
radius2The squared radius of the circle under consideration
colThe input/output column position to (potentially) update
rowThe input/output row position to update

Definition at line 533 of file DlVertexingAlgorithm.cc.

534 {
535  // Bresenham midpoint circle algorithm to determine if we should update the column position
536  // This obscure looking block of code uses bit shifts and integer arithmetic to perform this check as efficiently as possible
537  const int a{1 - (col << 2)};
538  const int b{col * col + row * row - radius2 + (row << 2) + 1};
539  const int c{(a << 2) * b + a * a};
540  if (c < 0)
541  {
542  --col;
543  ++row;
544  }
545  else
546  ++row;
547 }
process_name gaushit a

Member Data Documentation

pandora::StringVector lar_dl_content::DlVertexingAlgorithm::m_caloHitListNames
private

Names of input calo hit lists.

Definition at line 224 of file DlVertexingAlgorithm.h.

int lar_dl_content::DlVertexingAlgorithm::m_event
private

The current event number.

Definition at line 228 of file DlVertexingAlgorithm.h.

int lar_dl_content::DlVertexingAlgorithm::m_height
private

The height of the images.

Definition at line 231 of file DlVertexingAlgorithm.h.

std::string lar_dl_content::DlVertexingAlgorithm::m_inputVertexListName
private

Input vertex list name if 2nd pass.

Definition at line 222 of file DlVertexingAlgorithm.h.

float lar_dl_content::DlVertexingAlgorithm::m_maxHitAdc
private

Maximum ADC value to allow.

Definition at line 233 of file DlVertexingAlgorithm.h.

LArDLHelper::TorchModel lar_dl_content::DlVertexingAlgorithm::m_modelU
private

The model for the U view.

Definition at line 225 of file DlVertexingAlgorithm.h.

LArDLHelper::TorchModel lar_dl_content::DlVertexingAlgorithm::m_modelV
private

The model for the V view.

Definition at line 226 of file DlVertexingAlgorithm.h.

LArDLHelper::TorchModel lar_dl_content::DlVertexingAlgorithm::m_modelW
private

The model for the W view.

Definition at line 227 of file DlVertexingAlgorithm.h.

int lar_dl_content::DlVertexingAlgorithm::m_nClasses
private

The number of distance classes.

Definition at line 230 of file DlVertexingAlgorithm.h.

std::string lar_dl_content::DlVertexingAlgorithm::m_outputVertexListName
private

Output vertex list name.

Definition at line 223 of file DlVertexingAlgorithm.h.

int lar_dl_content::DlVertexingAlgorithm::m_pass
private

The pass of the train/infer step.

Definition at line 229 of file DlVertexingAlgorithm.h.

float lar_dl_content::DlVertexingAlgorithm::m_regionSize
private

The half width/height of the event region to consider in cm.

Definition at line 234 of file DlVertexingAlgorithm.h.

std::mt19937 lar_dl_content::DlVertexingAlgorithm::m_rng
private

The random number generator.

Definition at line 239 of file DlVertexingAlgorithm.h.

std::string lar_dl_content::DlVertexingAlgorithm::m_rootFileName
private

The ROOT file name.

Definition at line 238 of file DlVertexingAlgorithm.h.

std::string lar_dl_content::DlVertexingAlgorithm::m_rootTreeName
private

The ROOT tree name.

Definition at line 237 of file DlVertexingAlgorithm.h.

std::vector<double> lar_dl_content::DlVertexingAlgorithm::m_thresholds
private

Distance class thresholds.

Definition at line 240 of file DlVertexingAlgorithm.h.

bool lar_dl_content::DlVertexingAlgorithm::m_trainingMode
private

Training mode.

Definition at line 220 of file DlVertexingAlgorithm.h.

std::string lar_dl_content::DlVertexingAlgorithm::m_trainingOutputFile
private

Output file name for training examples.

Definition at line 221 of file DlVertexingAlgorithm.h.

bool lar_dl_content::DlVertexingAlgorithm::m_visualise
private

Whether or not to visualise the candidate vertices.

Definition at line 235 of file DlVertexingAlgorithm.h.

int lar_dl_content::DlVertexingAlgorithm::m_width
private

The width of the images.

Definition at line 232 of file DlVertexingAlgorithm.h.

bool lar_dl_content::DlVertexingAlgorithm::m_writeTree
private

Whether or not to write validation details to a ROOT tree.

Definition at line 236 of file DlVertexingAlgorithm.h.

const double lar_dl_content::DlVertexingAlgorithm::PY_EPSILON {1.1920929e-7}
private

The value of epsilon in Python.

Definition at line 241 of file DlVertexingAlgorithm.h.


The documentation for this class was generated from the following files: