LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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, const pandora::HitType view, const float xMin, const float xMax, const float zMin, const float zMax, LArDLHelper::TorchInput &networkInput, PixelVector &pixelVector) const
 
pandora::StatusCode MakeWirePlaneCoordinatesFromCanvas (float **canvas, const int canvasWidth, const int canvasHeight, const int columnOffset, const int rowOffset, const pandora::HitType view, const float xMin, const float xMax, const float zMin, const float zMax, 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...
 

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_driftStep
 The size of a pixel in the drift direction in cm (most relevant in pass 2) 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...
 
std::string m_volumeType
 The name of the fiducial volume type for the monitoring output. 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.

References m_driftStep, m_event, m_height, m_nClasses, m_pass, m_rng, m_trainingOutputFile, m_visualise, m_volumeType, m_width, and m_writeTree.

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_driftStep{0.5f},
37  m_visualise{false},
38  m_writeTree{false},
39  m_rng(static_cast<std::mt19937::result_type>(std::chrono::high_resolution_clock::now().time_since_epoch().count())),
40  m_volumeType{"dune_fd_hd"}
41 {
42 }
bool m_visualise
Whether or not to visualise the candidate vertices.
int m_event
The current event number.
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.
float m_driftStep
The size of a pixel in the drift direction in cm (most relevant in pass 2)
int m_width
The width of the images.
std::string m_volumeType
The name of the fiducial volume type for the monitoring output.
lar_dl_content::DlVertexingAlgorithm::~DlVertexingAlgorithm ( )
virtual

Definition at line 44 of file DlVertexingAlgorithm.cc.

References e, m_rootFileName, m_rootTreeName, and m_writeTree.

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.
Float_t e
Definition: plot.C:35

Member Function Documentation

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

Definition at line 562 of file DlVertexingAlgorithm.cc.

References e, and hits().

Referenced by PrepareTrainingSample().

563 {
564  try
565  {
566  for (const auto &[mc, hits] : mcToHitsMap)
567  {
568  (void)hits;
569  mcHierarchy.push_back(mc);
570  LArMCParticleHelper::GetAllAncestorMCParticles(mc, mcHierarchy);
571  }
572  }
573  catch (const StatusCodeException &e)
574  {
575  return e.GetStatusCode();
576  }
577 
578  // Move the neutrino to the front of the list
579  auto pivot =
580  std::find_if(mcHierarchy.begin(), mcHierarchy.end(), [](const MCParticle *mc) -> bool { return LArMCParticleHelper::IsNeutrino(mc); });
581  (void)pivot;
582  if (pivot != mcHierarchy.end())
583  std::rotate(mcHierarchy.begin(), pivot, std::next(pivot));
584  else
585  return STATUS_CODE_NOT_FOUND;
586 
587  return STATUS_CODE_SUCCESS;
588 }
void hits()
Definition: readHits.C:15
Float_t e
Definition: plot.C:35
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 475 of file DlVertexingAlgorithm.cc.

References c1, c2, Update(), and weight.

Referenced by Infer().

476 {
477  // Set the starting position for each circle bounding the ring
478  int c1{inner}, r1{0}, c2{outer}, r2{0};
479  int inner2{inner * inner}, outer2{outer * outer};
480  while (c2 >= r2)
481  {
482  // Set the output pixel location
483  int rp2{r2}, cp2{c2};
484  // We're still within the octant for the inner ring, so use the inner pixel location (see Update comment below)
485  // Note also that the inner row is always the same as the outer row, so no need to define rp1
486  int cp1{c1};
487  if (c1 <= r1)
488  { // We've completed the arc of the inner ring already, so just move radially out from here (see Update comment below)
489  cp1 = r2;
490  }
491  // Fill the pixels from inner to outer in the current row and their mirror pixels in the other octants
492  for (int c = cp1; c <= cp2; ++c)
493  {
494  canvas[row + rp2][col + c] += weight;
495  if (rp2 != c)
496  canvas[row + c][col + rp2] += weight;
497  if (rp2 != 0 && cp2 != 0)
498  {
499  canvas[row - rp2][col - c] += weight;
500  if (rp2 != c)
501  canvas[row - c][col - rp2] += weight;
502  }
503  if (rp2 != 0)
504  {
505  canvas[row - rp2][col + c] += weight;
506  if (rp2 != c)
507  canvas[row + c][col - rp2] += weight;
508  }
509  if (cp2 != 0)
510  {
511  canvas[row + rp2][col - c] += weight;
512  if (rp2 != c)
513  canvas[row - c][col + rp2] += weight;
514  }
515  }
516  // Only update the inner location while it remains in the octant (outer ring also remains in the octant of course, but the logic of
517  // the update means that the inner ring can leave its octant before the outer ring is complete, so we need to stop that)
518  if (c1 > r1)
519  this->Update(inner2, c1, r1);
520  // Update the outer location - increase the row position with every step, decrease the column position if conditions are met
521  this->Update(outer2, c2, r2);
522  }
523 }
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...
TCanvas * c1
Definition: plotHisto.C:7
TCanvas * c2
Definition: plot_hist.C:75
Int_t col[ntarg]
Definition: Style.C:29
double weight
Definition: plottest35.C:25
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 440 of file DlVertexingAlgorithm.cc.

References col, m_height, m_thresholds, and m_width.

Referenced by Infer().

442 {
443  const double scaleFactor{std::sqrt(m_height * m_height + m_width * m_width)};
444  // output is a 1 x num_classes x height x width tensor
445  // we want the maximum value in the num_classes dimension (1) for every pixel
446  auto classes{torch::argmax(networkOutput, 1)};
447  // the argmax result is a 1 x height x width tensor where each element is a class id
448  auto classesAccessor{classes.accessor<long, 3>()};
449  int colOffsetMin{0}, colOffsetMax{0}, rowOffsetMin{0}, rowOffsetMax{0};
450  for (const auto &[row, col] : pixelVector)
451  {
452  const auto cls{classesAccessor[0][row][col]};
453  const double threshold{m_thresholds[cls]};
454  if (threshold > 0. && threshold < 1.)
455  {
456  const int distance = static_cast<int>(std::round(std::ceil(scaleFactor * threshold)));
457  if ((row - distance) < rowOffsetMin)
458  rowOffsetMin = row - distance;
459  if ((row + distance) > rowOffsetMax)
460  rowOffsetMax = row + distance;
461  if ((col - distance) < colOffsetMin)
462  colOffsetMin = col - distance;
463  if ((col + distance) > colOffsetMax)
464  colOffsetMax = col + distance;
465  }
466  }
467  colOffset = colOffsetMin < 0 ? -colOffsetMin : 0;
468  rowOffset = rowOffsetMin < 0 ? -rowOffsetMin : 0;
469  width = std::max(colOffsetMax + colOffset + 1, m_width);
470  height = std::max(rowOffsetMax + rowOffset + 1, m_height);
471 }
std::vector< double > m_thresholds
Distance class thresholds.
Int_t col[ntarg]
Definition: Style.C:29
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 592 of file DlVertexingAlgorithm.cc.

References util::begin(), m_caloHitListNames, m_driftStep, m_height, m_inputVertexListName, m_pass, m_width, x, and z.

Referenced by Infer(), and PrepareTrainingSample().

593 {
594  xMin = std::numeric_limits<float>::max();
595  xMax = -std::numeric_limits<float>::max();
596  zMin = std::numeric_limits<float>::max();
597  zMax = -std::numeric_limits<float>::max();
598  // Find the range of x and z values in the view
599  for (const CaloHit *pCaloHit : caloHitList)
600  {
601  const float x{pCaloHit->GetPositionVector().GetX()};
602  const float z{pCaloHit->GetPositionVector().GetZ()};
603  xMin = std::min(x, xMin);
604  xMax = std::max(x, xMax);
605  zMin = std::min(z, zMin);
606  zMax = std::max(z, zMax);
607  }
608 
609  if (caloHitList.empty())
610  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
611 
612  const HitType view{caloHitList.front()->GetHitType()};
613  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
614  if (!(isU || isV || isW))
615  throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
616 
617  // ATTN If wire w pitches vary between TPCs, exception will be raised in initialisation of lar pseudolayer plugin
618  const LArTPC *const pTPC(this->GetPandora().GetGeometry()->GetLArTPCMap().begin()->second);
619  const float pitch(view == TPC_VIEW_U ? pTPC->GetWirePitchU() : view == TPC_VIEW_V ? pTPC->GetWirePitchV() : pTPC->GetWirePitchW());
620 
621  if (m_pass > 1)
622  {
623  const VertexList *pVertexList(nullptr);
624  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_inputVertexListName, pVertexList));
625  if (pVertexList->empty())
626  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
627  const CartesianVector &vertex{pVertexList->front()->GetPosition()};
628 
629  // Get hit distribution left/right asymmetry
630  int nHitsLeft{0}, nHitsRight{0};
631  const double xVtx{vertex.GetX()};
632  for (const std::string &listname : m_caloHitListNames)
633  {
634  const CaloHitList *pCaloHitList(nullptr);
635  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
636  if (pCaloHitList->empty())
637  continue;
638  for (const CaloHit *const pCaloHit : *pCaloHitList)
639  {
640  const CartesianVector &pos{pCaloHit->GetPositionVector()};
641  if (pos.GetX() <= xVtx)
642  ++nHitsLeft;
643  else
644  ++nHitsRight;
645  }
646  }
647  const int nHitsTotal{nHitsLeft + nHitsRight};
648  if (nHitsTotal == 0)
649  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
650  const float xAsymmetry{nHitsLeft / static_cast<float>(nHitsTotal)};
651 
652  // Vertices
653  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
654  double zVtx{0.};
655  if (isW)
656  zVtx += transform->YZtoW(vertex.GetY(), vertex.GetZ());
657  else if (isV)
658  zVtx += transform->YZtoV(vertex.GetY(), vertex.GetZ());
659  else
660  zVtx = transform->YZtoU(vertex.GetY(), vertex.GetZ());
661 
662  // Get hit distribution upstream/downstream asymmetry
663  int nHitsUpstream{0}, nHitsDownstream{0};
664  for (const CaloHit *const pCaloHit : caloHitList)
665  {
666  const CartesianVector &pos{pCaloHit->GetPositionVector()};
667  if (pos.GetZ() <= zVtx)
668  ++nHitsUpstream;
669  else
670  ++nHitsDownstream;
671  }
672  const int nHitsViewTotal{nHitsUpstream + nHitsDownstream};
673  if (nHitsViewTotal == 0)
674  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
675  const float zAsymmetry{nHitsUpstream / static_cast<float>(nHitsViewTotal)};
676 
677  const float xSpan{m_driftStep * (m_width - 1)};
678  xMin = xVtx - xAsymmetry * xSpan;
679  xMax = xMin + (m_driftStep * (m_width - 1));
680  const float zSpan{pitch * (m_height - 1)};
681  zMin = zVtx - zAsymmetry * zSpan;
682  zMax = zMin + zSpan;
683  }
684 
685  // Avoid unreasonable rescaling of very small hit regions, pixels are assumed to be 0.5cm in x and wire pitch in z
686  // ATTN: Rescaling is to a size 1 pixel smaller than the intended image to ensure all hits fit within an imaged binned
687  // to be one pixel wider than this
688  const float xRange{xMax - xMin}, zRange{zMax - zMin};
689  const float minXSpan{m_driftStep * (m_width - 1)};
690  if (xRange < minXSpan)
691  {
692  const float padding{0.5f * (minXSpan - xRange)};
693  xMin -= padding;
694  xMax += padding;
695  }
696  const float minZSpan{pitch * (m_height - 1)};
697  if (zRange < minZSpan)
698  {
699  const float padding{0.5f * (minZSpan - zRange)};
700  zMin -= padding;
701  zMax += padding;
702  }
703 }
Float_t x
Definition: compare.C:6
Double_t z
Definition: plot.C:276
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
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.
HitType
Definition: HitType.h:12
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
float m_driftStep
The size of a pixel in the drift direction in cm (most relevant in pass 2)
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
int m_width
The width of the images.
std::list< Vertex > VertexList
Definition: DCEL.h:169
vertex reconstruction
StatusCode lar_dl_content::DlVertexingAlgorithm::GetMCToHitsMap ( LArMCParticleHelper::MCContributionMap mcToHitsMap) const
private

Definition at line 545 of file DlVertexingAlgorithm.cc.

References lar_content::LArMCParticleHelper::PrimaryParameters::m_maxPhotonPropagation.

Referenced by PrepareTrainingSample().

546 {
547  const CaloHitList *pCaloHitList2D(nullptr);
548  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, "CaloHitList2D", pCaloHitList2D));
549  const MCParticleList *pMCParticleList(nullptr);
550  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
551 
553  parameters.m_maxPhotonPropagation = std::numeric_limits<float>::max();
554  LArMCParticleHelper::SelectReconstructableMCParticles(
555  pMCParticleList, pCaloHitList2D, parameters, LArMCParticleHelper::IsBeamNeutrinoFinalState, mcToHitsMap);
556 
557  return STATUS_CODE_SUCCESS;
558 }
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 753 of file DlVertexingAlgorithm.cc.

References m_event, m_pass, m_rootTreeName, m_volumeType, and m_writeTree.

Referenced by GetTrueVertexPosition().

754 {
755  const MCParticleList *pMCParticleList{nullptr};
756  if (STATUS_CODE_SUCCESS == PandoraContentApi::GetCurrentList(*this, pMCParticleList) && pMCParticleList)
757  {
758  MCParticleVector primaries;
759  LArMCParticleHelper::GetPrimaryMCParticleList(pMCParticleList, primaries);
760  if (!primaries.empty())
761  {
762  const MCParticle *primary{primaries.front()};
763  const MCParticleList &parents{primary->GetParentList()};
764  if (parents.size() == 1)
765  {
766  const MCParticle *trueNeutrino{parents.front()};
767  if (LArMCParticleHelper::IsNeutrino(trueNeutrino))
768  return primaries.front()->GetVertex();
769  }
770  }
771  }
772 
773  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
774 }
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 731 of file DlVertexingAlgorithm.cc.

References GetTrueVertex().

Referenced by Infer().

732 {
733  const CartesianVector &trueVertex{this->GetTrueVertex()};
734  x = trueVertex.GetX();
735  y = trueVertex.GetY();
736  z = trueVertex.GetZ();
737 }
Float_t x
Definition: compare.C:6
const pandora::CartesianVector & GetTrueVertex() const
Retrieve the true neutrino vertex.
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
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 741 of file DlVertexingAlgorithm.cc.

References GetTrueVertex().

742 {
743  const CartesianVector &trueVertex{this->GetTrueVertex()};
744  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
745  x = trueVertex.GetX();
746  u = static_cast<float>(transform->YZtoU(trueVertex.GetY(), trueVertex.GetZ()));
747  v = static_cast<float>(transform->YZtoV(trueVertex.GetY(), trueVertex.GetZ()));
748  w = static_cast<float>(transform->YZtoW(trueVertex.GetY(), trueVertex.GetZ()));
749 }
Float_t x
Definition: compare.C:6
const pandora::CartesianVector & GetTrueVertex() const
Retrieve the true neutrino vertex.
Float_t w
Definition: plot.C:20
StatusCode lar_dl_content::DlVertexingAlgorithm::Infer ( )
private

Definition at line 171 of file DlVertexingAlgorithm.cc.

References col, DrawRing(), e, f, lar_dl_content::LArDLHelper::Forward(), GetCanvasParameters(), GetHitRegion(), GetTrueVertexPosition(), m_caloHitListNames, m_event, m_height, m_modelU, m_modelV, m_modelW, m_nClasses, m_pass, m_thresholds, m_visualise, m_width, MakeCandidateVertexList(), MakeNetworkInputFromHits(), MakeWirePlaneCoordinatesFromCanvas(), w, and x.

Referenced by Run().

172 {
173  if (m_pass == 1)
174  ++m_event;
175 
176  std::map<HitType, float> wireMin, wireMax;
177  float driftMin{std::numeric_limits<float>::max()}, driftMax{-std::numeric_limits<float>::max()};
178  for (const std::string &listname : m_caloHitListNames)
179  {
180  const CaloHitList *pCaloHitList{nullptr};
181  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
182  if (pCaloHitList->empty())
183  continue;
184 
185  HitType view{pCaloHitList->front()->GetHitType()};
186  float viewDriftMin{driftMin}, viewDriftMax{driftMax};
187  this->GetHitRegion(*pCaloHitList, viewDriftMin, viewDriftMax, wireMin[view], wireMax[view]);
188  driftMin = std::min(viewDriftMin, driftMin);
189  driftMax = std::max(viewDriftMax, driftMax);
190  }
191 
192  CartesianPointVector vertexCandidatesU, vertexCandidatesV, vertexCandidatesW;
193  for (const std::string &listName : m_caloHitListNames)
194  {
195  const CaloHitList *pCaloHitList{nullptr};
196  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listName, pCaloHitList));
197 
198  HitType view{pCaloHitList->front()->GetHitType()};
199  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
200  if (!isU && !isV && !isW)
201  return STATUS_CODE_NOT_ALLOWED;
202 
204  PixelVector pixelVector;
205  this->MakeNetworkInputFromHits(*pCaloHitList, view, driftMin, driftMax, wireMin[view], wireMax[view], input, pixelVector);
206 
207  // Run the input through the trained model
209  inputs.push_back(input);
211  if (isU)
212  LArDLHelper::Forward(m_modelU, inputs, output);
213  else if (isV)
214  LArDLHelper::Forward(m_modelV, inputs, output);
215  else
216  LArDLHelper::Forward(m_modelW, inputs, output);
217 
218  int colOffset{0}, rowOffset{0}, canvasWidth{m_width}, canvasHeight{m_height};
219  this->GetCanvasParameters(output, pixelVector, colOffset, rowOffset, canvasWidth, canvasHeight);
220 
221  float **canvas{new float *[canvasHeight]};
222  for (int row = 0; row < canvasHeight; ++row)
223  canvas[row] = new float[canvasWidth]{};
224 
225  // we want the maximum value in the num_classes dimension (1) for every pixel
226  auto classes{torch::argmax(output, 1)};
227  // the argmax result is a 1 x height x width tensor where each element is a class id
228  auto classesAccessor{classes.accessor<long, 3>()};
229  const double scaleFactor{std::sqrt(m_height * m_height + m_width * m_width)};
230  std::map<int, bool> haveSeenMap;
231  for (const auto &[row, col] : pixelVector)
232  {
233  const auto cls{classesAccessor[0][row][col]};
234  if (cls > 0 && cls < m_nClasses)
235  {
236  const int inner{static_cast<int>(std::round(std::ceil(scaleFactor * m_thresholds[cls - 1])))};
237  const int outer{static_cast<int>(std::round(std::ceil(scaleFactor * m_thresholds[cls])))};
238  this->DrawRing(canvas, row + rowOffset, col + colOffset, inner, outer, 1.f / (outer * outer - inner * inner));
239  }
240  }
241 
242  CartesianPointVector positionVector;
244  canvas, canvasWidth, canvasHeight, colOffset, rowOffset, view, driftMin, driftMax, wireMin[view], wireMax[view], positionVector);
245  if (isU)
246  vertexCandidatesU.emplace_back(positionVector.front());
247  else if (isV)
248  vertexCandidatesV.emplace_back(positionVector.front());
249  else
250  vertexCandidatesW.emplace_back(positionVector.front());
251 
252 #ifdef MONITORING
253  if (m_visualise)
254  {
255  PANDORA_MONITORING_API(SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, -1.f, 1.f, 1.f));
256  try
257  {
258  float x{0.f}, u{0.f}, v{0.f}, w{0.f};
259  this->GetTrueVertexPosition(x, u, v, w);
260  if (isU)
261  {
262  const CartesianVector trueVertex(x, 0.f, u);
263  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "U(true)", BLUE, 3));
264  }
265  else if (isV)
266  {
267  const CartesianVector trueVertex(x, 0.f, v);
268  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "V(true)", BLUE, 3));
269  }
270  else if (isW)
271  {
272  const CartesianVector trueVertex(x, 0.f, w);
273  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "W(true)", BLUE, 3));
274  }
275  }
276  catch (StatusCodeException &e)
277  {
278  std::cerr << "DlVertexingAlgorithm: Warning. Couldn't find true vertex." << std::endl;
279  }
280  for (const auto &pos : positionVector)
281  {
282  std::string label{isU ? "U" : isV ? "V" : "W"};
283  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &pos, label, RED, 3));
284  }
285  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
286  }
287 #endif
288 
289  for (int row = 0; row < canvasHeight; ++row)
290  delete[] canvas[row];
291  delete[] canvas;
292  }
293 
294  int nEmptyLists{0};
295  if (vertexCandidatesU.empty())
296  ++nEmptyLists;
297  if (vertexCandidatesV.empty())
298  ++nEmptyLists;
299  if (vertexCandidatesW.empty())
300  ++nEmptyLists;
301  std::vector<VertexTuple> vertexTuples;
302  CartesianPointVector candidates3D;
303  if (nEmptyLists == 0)
304  {
305  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), vertexCandidatesW.front()));
306  }
307  else if (nEmptyLists == 1)
308  {
309  if (vertexCandidatesU.empty())
310  { // V and W available
311  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesV.front(), vertexCandidatesW.front(), TPC_VIEW_V, TPC_VIEW_W));
312  }
313  else if (vertexCandidatesV.empty())
314  { // U and W available
315  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesW.front(), TPC_VIEW_U, TPC_VIEW_W));
316  }
317  else
318  { // U and V available
319  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), TPC_VIEW_U, TPC_VIEW_V));
320  }
321  }
322  else
323  { // Not enough views to reconstruct a 3D vertex
324  std::cout << "Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
325  return STATUS_CODE_NOT_FOUND;
326  }
327 
328  if (m_visualise)
329  {
330  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &vertexTuples.front().GetPosition(), "candidate", GREEN, 1));
331  }
332 
333  if (!vertexTuples.empty())
334  {
335  const CartesianVector &vertex{vertexTuples.front().GetPosition()};
336  CartesianPointVector vertexCandidates;
337  vertexCandidates.emplace_back(vertex);
338  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->MakeCandidateVertexList(vertexCandidates));
339  }
340  else
341  {
342  std::cout << "Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
343  return STATUS_CODE_NOT_FOUND;
344  }
345 
346  if (m_visualise)
347  {
348  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
349  }
350 
351  return STATUS_CODE_SUCCESS;
352 }
Float_t x
Definition: compare.C:6
LArDLHelper::TorchModel m_modelU
The model for the U view.
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
std::vector< double > m_thresholds
Distance class thresholds.
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.
TFile f
Definition: plotHisto.C:6
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_t col[ntarg]
Definition: Style.C:29
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.
pandora::StatusCode MakeWirePlaneCoordinatesFromCanvas(float **canvas, const int canvasWidth, const int canvasHeight, const int columnOffset, const int rowOffset, const pandora::HitType view, const float xMin, const float xMax, const float zMin, const float zMax, pandora::CartesianPointVector &positionVector) const
LArDLHelper::TorchModel m_modelW
The model for the W view.
pandora::StatusCode MakeNetworkInputFromHits(const pandora::CaloHitList &caloHits, const pandora::HitType view, const float xMin, const float xMax, const float zMin, const float zMax, LArDLHelper::TorchInput &networkInput, PixelVector &pixelVector) const
HitType
Definition: HitType.h:12
pandora::StatusCode MakeCandidateVertexList(const pandora::CartesianPointVector &positions)
Create a vertex list from the candidate vertices.
Float_t e
Definition: plot.C:35
int m_width
The width of the images.
Float_t w
Definition: plot.C:20
std::vector< torch::jit::IValue > TorchInputVector
Definition: LArDLHelper.h:27
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...
vertex reconstruction
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 707 of file DlVertexingAlgorithm.cc.

References m_outputVertexListName.

Referenced by Infer().

708 {
709  const VertexList *pVertexList{nullptr};
710  std::string temporaryListName;
711  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, temporaryListName));
712 
713  for (const CartesianVector &position : positions)
714  {
715  PandoraContentApi::Vertex::Parameters parameters;
716  parameters.m_position = position;
717  parameters.m_vertexLabel = VERTEX_INTERACTION;
718  parameters.m_vertexType = VERTEX_3D;
719 
720  const Vertex *pVertex(nullptr);
721  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
722  }
723  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_outputVertexListName));
724  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
725 
726  return STATUS_CODE_SUCCESS;
727 }
std::string m_outputVertexListName
Output vertex list name.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
std::list< Vertex > VertexList
Definition: DCEL.h:169
StatusCode lar_dl_content::DlVertexingAlgorithm::MakeNetworkInputFromHits ( const pandora::CaloHitList &  caloHits,
const pandora::HitType  view,
const float  xMin,
const float  xMax,
const float  zMin,
const float  zMax,
LArDLHelper::TorchInput networkInput,
PixelVector pixelVector 
) const
private

Definition at line 356 of file DlVertexingAlgorithm.cc.

References util::begin(), col, lar_dl_content::LArDLHelper::InitialiseInput(), m_driftStep, m_height, m_pass, m_width, value, x, and z.

Referenced by Infer().

358 {
359  // ATTN If wire w pitches vary between TPCs, exception will be raised in initialisation of lar pseudolayer plugin
360  const LArTPC *const pTPC(this->GetPandora().GetGeometry()->GetLArTPCMap().begin()->second);
361  const float pitch(view == TPC_VIEW_U ? pTPC->GetWirePitchU() : view == TPC_VIEW_V ? pTPC->GetWirePitchV() : pTPC->GetWirePitchW());
362 
363  // Determine the bin edges
364  std::vector<double> xBinEdges(m_width + 1);
365  std::vector<double> zBinEdges(m_height + 1);
366  xBinEdges[0] = xMin - 0.5f * m_driftStep;
367  const double dx = ((xMax + 0.5f * m_driftStep) - xBinEdges[0]) / m_width;
368  for (int i = 1; i < m_width + 1; ++i)
369  xBinEdges[i] = xBinEdges[i - 1] + dx;
370  zBinEdges[0] = zMin - 0.5f * pitch;
371  const double dz = ((zMax + 0.5f * pitch) - zBinEdges[0]) / m_height;
372  for (int i = 1; i < m_height + 1; ++i)
373  zBinEdges[i] = zBinEdges[i - 1] + dz;
374 
375  LArDLHelper::InitialiseInput({1, 1, m_height, m_width}, networkInput);
376  auto accessor = networkInput.accessor<float, 4>();
377 
378  for (const CaloHit *pCaloHit : caloHits)
379  {
380  const float x{pCaloHit->GetPositionVector().GetX()};
381  const float z{pCaloHit->GetPositionVector().GetZ()};
382  if (m_pass > 1)
383  {
384  if (x < xMin || x > xMax || z < zMin || z > zMax)
385  continue;
386  }
387  const float adc{pCaloHit->GetMipEquivalentEnergy()};
388  const int pixelX{static_cast<int>(std::floor((x - xBinEdges[0]) / dx))};
389  const int pixelZ{static_cast<int>(std::floor((z - zBinEdges[0]) / dz))};
390  accessor[0][0][pixelZ][pixelX] += adc;
391  }
392  for (int row = 0; row < m_height; ++row)
393  {
394  for (int col = 0; col < m_width; ++col)
395  {
396  const float value{accessor[0][0][row][col]};
397  if (value > 0)
398  pixelVector.emplace_back(std::make_pair(row, col));
399  }
400  }
401 
402  return STATUS_CODE_SUCCESS;
403 }
Float_t x
Definition: compare.C:6
Double_t z
Definition: plot.C:276
Int_t col[ntarg]
Definition: Style.C:29
int m_height
The height of the images.
int m_pass
The pass of the train/infer step.
double value
Definition: spectrum.C:18
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
float m_driftStep
The size of a pixel in the drift direction in cm (most relevant in pass 2)
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
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 ( float **  canvas,
const int  canvasWidth,
const int  canvasHeight,
const int  columnOffset,
const int  rowOffset,
const pandora::HitType  view,
const float  xMin,
const float  xMax,
const float  zMin,
const float  zMax,
pandora::CartesianPointVector &  positionVector 
) const
private

Definition at line 407 of file DlVertexingAlgorithm.cc.

References util::begin(), col, f, m_driftStep, m_height, m_width, pt, x, and z.

Referenced by Infer().

410 {
411  // ATTN If wire w pitches vary between TPCs, exception will be raised in initialisation of lar pseudolayer plugin
412  const LArTPC *const pTPC(this->GetPandora().GetGeometry()->GetLArTPCMap().begin()->second);
413  const float pitch(view == TPC_VIEW_U ? pTPC->GetWirePitchU() : view == TPC_VIEW_V ? pTPC->GetWirePitchV() : pTPC->GetWirePitchW());
414 
415  const double dx = ((xMax + 0.5f * m_driftStep) - (xMin - 0.5f * m_driftStep)) / m_width;
416  const double dz = ((zMax + 0.5f * pitch) - (zMin - 0.5f * pitch)) / m_height;
417 
418  float best{-1.f};
419  int rowBest{0}, colBest{0};
420  for (int row = 0; row < canvasHeight; ++row)
421  for (int col = 0; col < canvasWidth; ++col)
422  if (canvas[row][col] > 0 && canvas[row][col] > best)
423  {
424  best = canvas[row][col];
425  rowBest = row;
426  colBest = col;
427  }
428 
429  const float x{static_cast<float>((colBest - columnOffset) * dx + xMin)};
430  const float z{static_cast<float>((rowBest - rowOffset) * dz + zMin)};
431 
432  CartesianVector pt(x, 0.f, z);
433  positionVector.emplace_back(pt);
434 
435  return STATUS_CODE_SUCCESS;
436 }
Float_t x
Definition: compare.C:6
Double_t z
Definition: plot.C:276
TFile f
Definition: plotHisto.C:6
Int_t col[ntarg]
Definition: Style.C:29
int m_height
The height of the images.
TMarker * pt
Definition: egs.C:25
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
float m_driftStep
The size of a pixel in the drift direction in cm (most relevant in pass 2)
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
int m_width
The width of the images.
StatusCode lar_dl_content::DlVertexingAlgorithm::PrepareTrainingSample ( )
private

Definition at line 71 of file DlVertexingAlgorithm.cc.

References CompleteMCHierarchy(), f, GetHitRegion(), GetMCToHitsMap(), m_caloHitListNames, m_pass, m_trainingOutputFile, x, and z.

Referenced by Run().

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 
78  // Get boundaries for hits and make x dimension common
79  std::map<HitType, float> wireMin, wireMax;
80  float driftMin{std::numeric_limits<float>::max()}, driftMax{-std::numeric_limits<float>::max()};
81  for (const std::string &listname : m_caloHitListNames)
82  {
83  const CaloHitList *pCaloHitList{nullptr};
84  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
85  if (pCaloHitList->empty())
86  continue;
87 
88  HitType view{pCaloHitList->front()->GetHitType()};
89  float viewDriftMin{driftMin}, viewDriftMax{driftMax};
90  this->GetHitRegion(*pCaloHitList, viewDriftMin, viewDriftMax, wireMin[view], wireMax[view]);
91  driftMin = std::min(viewDriftMin, driftMin);
92  driftMax = std::max(viewDriftMax, driftMax);
93  }
94  for (const std::string &listname : m_caloHitListNames)
95  {
96  const CaloHitList *pCaloHitList(nullptr);
97  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
98  if (pCaloHitList->empty())
99  continue;
100 
101  HitType view{pCaloHitList->front()->GetHitType()};
102  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
103  if (!(isU || isV || isW))
104  return STATUS_CODE_NOT_ALLOWED;
105 
106  CartesianPointVector vertices;
107  for (const MCParticle *mc : hierarchy)
108  {
109  if (LArMCParticleHelper::IsNeutrino(mc))
110  vertices.push_back(mc->GetVertex());
111  }
112  if (vertices.empty())
113  continue;
114  const CartesianVector &vertex{vertices.front()};
115  const std::string trainingFilename{m_trainingOutputFile + "_" + listname + ".csv"};
116  const unsigned long nVertices{1};
117  unsigned long nHits{0};
118  const unsigned int nuance{LArMCParticleHelper::GetNuanceCode(hierarchy.front())};
119 
120  // Vertices
121  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
122  const double xVtx{vertex.GetX()};
123  double zVtx{0.};
124  if (isW)
125  zVtx = transform->YZtoW(vertex.GetY(), vertex.GetZ());
126  else if (isV)
127  zVtx = transform->YZtoV(vertex.GetY(), vertex.GetZ());
128  else
129  zVtx = transform->YZtoU(vertex.GetY(), vertex.GetZ());
130 
131  // Calo hits
132  double xMin{driftMin}, xMax{driftMax}, zMin{wireMin[view]}, zMax{wireMax[view]};
133 
134  // Only train on events where the vertex resides within the image - with a small tolerance
135  if (!(xVtx > (xMin - 1.f) && xVtx < (xMax + 1.f) && zVtx > (zMin - 1.f) && zVtx < (zMax + 1.f)))
136  continue;
137 
138  LArMvaHelper::MvaFeatureVector featureVector;
139  featureVector.emplace_back(static_cast<double>(nuance));
140  featureVector.emplace_back(static_cast<double>(nVertices));
141  featureVector.emplace_back(xVtx);
142  featureVector.emplace_back(zVtx);
143  // Retain the hit region
144  featureVector.emplace_back(xMin);
145  featureVector.emplace_back(xMax);
146  featureVector.emplace_back(zMin);
147  featureVector.emplace_back(zMax);
148 
149  for (const CaloHit *pCaloHit : *pCaloHitList)
150  {
151  const float x{pCaloHit->GetPositionVector().GetX()}, z{pCaloHit->GetPositionVector().GetZ()}, adc{pCaloHit->GetMipEquivalentEnergy()};
152  // If on a refinement pass, drop hits outside the region of interest
153  if (m_pass > 1 && (x < xMin || x > xMax || z < zMin || z > zMax))
154  continue;
155  featureVector.emplace_back(static_cast<double>(x));
156  featureVector.emplace_back(static_cast<double>(z));
157  featureVector.emplace_back(static_cast<double>(adc));
158  ++nHits;
159  }
160  featureVector.insert(featureVector.begin() + 8, static_cast<double>(nHits));
161  // Only write out the feature vector if there were enough hits in the region of interest
162  if (nHits > 10)
163  LArMvaHelper::ProduceTrainingExample(trainingFilename, true, featureVector);
164  }
165 
166  return STATUS_CODE_SUCCESS;
167 }
Float_t x
Definition: compare.C:6
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:75
pandora::StatusCode GetMCToHitsMap(LArMCParticleHelper::MCContributionMap &mcToHitsMap) const
Double_t z
Definition: plot.C:276
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
pandora::StatusCode CompleteMCHierarchy(const LArMCParticleHelper::MCContributionMap &mcToHitsMap, pandora::MCParticleList &mcHierarchy) const
TFile f
Definition: plotHisto.C:6
int m_pass
The pass of the train/infer step.
std::string m_trainingOutputFile
Output file name for training examples.
HitType
Definition: HitType.h:12
vertex reconstruction
StatusCode lar_dl_content::DlVertexingAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
private

Definition at line 842 of file DlVertexingAlgorithm.cc.

References f, lar_dl_content::LArDLHelper::LoadModel(), m_caloHitListNames, m_driftStep, m_height, m_inputVertexListName, m_modelU, m_modelV, m_modelW, m_nClasses, m_outputVertexListName, m_pass, m_rootFileName, m_rootTreeName, m_thresholds, m_trainingMode, m_trainingOutputFile, m_visualise, m_volumeType, m_width, m_writeTree, and lar_dl_content::DlVertexingAlgorithm::VertexTuple::VertexTuple().

843 {
844  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "TrainingMode", m_trainingMode));
845  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Visualise", m_visualise));
846  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Pass", m_pass));
847  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ImageHeight", m_height));
848  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ImageWidth", m_width));
849  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DriftStep", m_driftStep));
850  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "DistanceThresholds", m_thresholds));
851  m_nClasses = m_thresholds.size() - 1;
852  if (m_pass > 1)
853  {
854  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputVertexListName", m_inputVertexListName));
855  }
856 
857  if (m_trainingMode)
858  {
859  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "TrainingOutputFileName", m_trainingOutputFile));
860  }
861  else
862  {
863  std::string modelName;
864  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "ModelFileNameU", modelName));
865  modelName = LArFileHelper::FindFileInPath(modelName, "FW_SEARCH_PATH");
866  LArDLHelper::LoadModel(modelName, m_modelU);
867  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "ModelFileNameV", modelName));
868  modelName = LArFileHelper::FindFileInPath(modelName, "FW_SEARCH_PATH");
869  LArDLHelper::LoadModel(modelName, m_modelV);
870  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "ModelFileNameW", modelName));
871  modelName = LArFileHelper::FindFileInPath(modelName, "FW_SEARCH_PATH");
872  LArDLHelper::LoadModel(modelName, m_modelW);
873  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteTree", m_writeTree));
874  if (m_writeTree)
875  {
876  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RootTreeName", m_rootTreeName));
877  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RootFileName", m_rootFileName));
878  }
879  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_outputVertexListName));
880  }
881 
882  PANDORA_RETURN_RESULT_IF_AND_IF(
883  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "CaloHitListNames", m_caloHitListNames));
884  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VolumeType", m_volumeType));
885 
886  return STATUS_CODE_SUCCESS;
887 }
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.
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.
float m_driftStep
The size of a pixel in the drift direction in cm (most relevant in pass 2)
int m_width
The width of the images.
std::string m_volumeType
The name of the fiducial volume type for the monitoring output.
StatusCode lar_dl_content::DlVertexingAlgorithm::Run ( )
private

Definition at line 61 of file DlVertexingAlgorithm.cc.

References Infer(), m_trainingMode, and PrepareTrainingSample().

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 527 of file DlVertexingAlgorithm.cc.

References col.

Referenced by DrawRing().

528 {
529  // Bresenham midpoint circle algorithm to determine if we should update the column position
530  // This obscure looking block of code uses bit shifts and integer arithmetic to perform this check as efficiently as possible
531  const int a{1 - (col << 2)};
532  const int b{col * col + row * row - radius2 + (row << 2) + 1};
533  const int c{(a << 2) * b + a * a};
534  if (c < 0)
535  {
536  --col;
537  ++row;
538  }
539  else
540  ++row;
541 }
Int_t col[ntarg]
Definition: Style.C:29

Member Data Documentation

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

Names of input calo hit lists.

Definition at line 223 of file DlVertexingAlgorithm.h.

Referenced by GetHitRegion(), Infer(), PrepareTrainingSample(), and ReadSettings().

float lar_dl_content::DlVertexingAlgorithm::m_driftStep
private

The size of a pixel in the drift direction in cm (most relevant in pass 2)

Definition at line 232 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), GetHitRegion(), MakeNetworkInputFromHits(), MakeWirePlaneCoordinatesFromCanvas(), and ReadSettings().

int lar_dl_content::DlVertexingAlgorithm::m_event
private

The current event number.

Definition at line 227 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), GetTrueVertex(), and Infer().

int lar_dl_content::DlVertexingAlgorithm::m_height
private
std::string lar_dl_content::DlVertexingAlgorithm::m_inputVertexListName
private

Input vertex list name if 2nd pass.

Definition at line 221 of file DlVertexingAlgorithm.h.

Referenced by GetHitRegion(), and ReadSettings().

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

The model for the U view.

Definition at line 224 of file DlVertexingAlgorithm.h.

Referenced by Infer(), and ReadSettings().

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

The model for the V view.

Definition at line 225 of file DlVertexingAlgorithm.h.

Referenced by Infer(), and ReadSettings().

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

The model for the W view.

Definition at line 226 of file DlVertexingAlgorithm.h.

Referenced by Infer(), and ReadSettings().

int lar_dl_content::DlVertexingAlgorithm::m_nClasses
private

The number of distance classes.

Definition at line 229 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), Infer(), and ReadSettings().

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

Output vertex list name.

Definition at line 222 of file DlVertexingAlgorithm.h.

Referenced by MakeCandidateVertexList(), and ReadSettings().

int lar_dl_content::DlVertexingAlgorithm::m_pass
private
std::mt19937 lar_dl_content::DlVertexingAlgorithm::m_rng
private

The random number generator.

Definition at line 237 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm().

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

The ROOT file name.

Definition at line 236 of file DlVertexingAlgorithm.h.

Referenced by ReadSettings(), and ~DlVertexingAlgorithm().

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

The ROOT tree name.

Definition at line 235 of file DlVertexingAlgorithm.h.

Referenced by GetTrueVertex(), ReadSettings(), and ~DlVertexingAlgorithm().

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

Distance class thresholds.

Definition at line 238 of file DlVertexingAlgorithm.h.

Referenced by GetCanvasParameters(), Infer(), and ReadSettings().

bool lar_dl_content::DlVertexingAlgorithm::m_trainingMode
private

Training mode.

Definition at line 219 of file DlVertexingAlgorithm.h.

Referenced by ReadSettings(), and Run().

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

Output file name for training examples.

Definition at line 220 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), PrepareTrainingSample(), and ReadSettings().

bool lar_dl_content::DlVertexingAlgorithm::m_visualise
private

Whether or not to visualise the candidate vertices.

Definition at line 233 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), Infer(), and ReadSettings().

std::string lar_dl_content::DlVertexingAlgorithm::m_volumeType
private

The name of the fiducial volume type for the monitoring output.

Definition at line 239 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), GetTrueVertex(), and ReadSettings().

int lar_dl_content::DlVertexingAlgorithm::m_width
private
bool lar_dl_content::DlVertexingAlgorithm::m_writeTree
private

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

Definition at line 234 of file DlVertexingAlgorithm.h.

Referenced by DlVertexingAlgorithm(), GetTrueVertex(), ReadSettings(), and ~DlVertexingAlgorithm().


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