LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
DlVertexingAlgorithm.cc
Go to the documentation of this file.
1 
9 #include <chrono>
10 #include <cmath>
11 
12 #include <torch/script.h>
13 #include <torch/torch.h>
14 
19 
21 
23 
24 using namespace pandora;
25 using namespace lar_content;
26 
27 namespace lar_dl_content
28 {
29 
30 DlVertexingAlgorithm::DlVertexingAlgorithm() :
31  m_event{-1},
32  m_visualise{false},
33  m_writeTree{false},
34  m_rng(static_cast<std::mt19937::result_type>(std::chrono::high_resolution_clock::now().time_since_epoch().count()))
35 {
36 }
37 
39 {
40  if (m_writeTree)
41  {
42  try
43  {
44  PANDORA_MONITORING_API(SaveTree(this->GetPandora(), m_rootTreeName, m_rootFileName, "RECREATE"));
45  }
46  catch (StatusCodeException e)
47  {
48  std::cout << "VertexAssessmentAlgorithm: Unable to write to ROOT tree" << std::endl;
49  }
50  }
51 }
52 
53 //-----------------------------------------------------------------------------------------------------------------------------------------
54 
56 {
57  if (m_trainingMode)
58  return this->PrepareTrainingSample();
59  else
60  return this->Infer();
61 
62  return STATUS_CODE_SUCCESS;
63 }
64 
66 {
67  const CaloHitList *pCaloHitList2D(nullptr);
68  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, "CaloHitList2D", pCaloHitList2D));
69  const MCParticleList *pMCParticleList(nullptr);
70  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
72  LArMCParticleHelper::GetMCToHitsMap(pCaloHitList2D, pMCParticleList, mcToHitsMap);
73  MCParticleList hierarchy;
74  LArMCParticleHelper::CompleteMCHierarchy(mcToHitsMap, hierarchy);
75 
76  // Get boundaries for hits and make x dimension common
77  std::map<HitType, float> wireMin, wireMax;
78  float driftMin{std::numeric_limits<float>::max()}, driftMax{-std::numeric_limits<float>::max()};
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 
86  HitType view{pCaloHitList->front()->GetHitType()};
87  float viewDriftMin{driftMin}, viewDriftMax{driftMax};
88  this->GetHitRegion(*pCaloHitList, viewDriftMin, viewDriftMax, wireMin[view], wireMax[view]);
89  driftMin = std::min(viewDriftMin, driftMin);
90  driftMax = std::max(viewDriftMax, driftMax);
91  }
92  for (const std::string &listname : m_caloHitListNames)
93  {
94  const CaloHitList *pCaloHitList(nullptr);
95  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
96  if (pCaloHitList->empty())
97  continue;
98 
99  HitType view{pCaloHitList->front()->GetHitType()};
100  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
101  if (!(isU || isV || isW))
102  return STATUS_CODE_NOT_ALLOWED;
103 
104  CartesianPointVector vertices;
105  for (const MCParticle *mc : hierarchy)
106  {
107  if (LArMCParticleHelper::IsNeutrino(mc))
108  vertices.push_back(mc->GetVertex());
109  }
110  if (vertices.empty())
111  continue;
112  const CartesianVector &vertex{vertices.front()};
113  const std::string trainingFilename{m_trainingOutputFile + "_" + listname + ".csv"};
114  const unsigned long nVertices{1};
115  unsigned long nHits{0};
116  const unsigned int nuance{LArMCParticleHelper::GetNuanceCode(hierarchy.front())};
117 
118  // Vertices
119  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
120  const double xVtx{vertex.GetX()};
121  double zVtx{0.};
122  if (isW)
123  zVtx = transform->YZtoW(vertex.GetY(), vertex.GetZ());
124  else if (isV)
125  zVtx = transform->YZtoV(vertex.GetY(), vertex.GetZ());
126  else
127  zVtx = transform->YZtoU(vertex.GetY(), vertex.GetZ());
128 
129  // Calo hits
130  double xMin{driftMin}, xMax{driftMax}, zMin{wireMin[view]}, zMax{wireMax[view]};
131 
132  // Only train on events where the vertex resides within the image - with a small tolerance
133  if (!(xVtx > (xMin - 1.f) && xVtx < (xMax + 1.f) && zVtx > (zMin - 1.f) && zVtx < (zMax + 1.f)))
134  continue;
135 
136  LArMvaHelper::MvaFeatureVector featureVector;
137  featureVector.emplace_back(static_cast<double>(nuance));
138  featureVector.emplace_back(static_cast<double>(nVertices));
139  featureVector.emplace_back(xVtx);
140  featureVector.emplace_back(zVtx);
141  // Retain the hit region
142  featureVector.emplace_back(xMin);
143  featureVector.emplace_back(xMax);
144  featureVector.emplace_back(zMin);
145  featureVector.emplace_back(zMax);
146 
147  for (const CaloHit *pCaloHit : *pCaloHitList)
148  {
149  const float x{pCaloHit->GetPositionVector().GetX()}, z{pCaloHit->GetPositionVector().GetZ()}, adc{pCaloHit->GetMipEquivalentEnergy()};
150  // If on a refinement pass, drop hits outside the region of interest
151  if (m_pass > 1 && (x < xMin || x > xMax || z < zMin || z > zMax))
152  continue;
153  featureVector.emplace_back(static_cast<double>(x));
154  featureVector.emplace_back(static_cast<double>(z));
155  featureVector.emplace_back(static_cast<double>(adc));
156  ++nHits;
157  }
158  featureVector.insert(featureVector.begin() + 8, static_cast<double>(nHits));
159  // Only write out the feature vector if there were enough hits in the region of interest
160  if (nHits > 10)
161  LArMvaHelper::ProduceTrainingExample(trainingFilename, true, featureVector);
162  }
163 
164  return STATUS_CODE_SUCCESS;
165 }
166 
167 //-----------------------------------------------------------------------------------------------------------------------------------------
168 
170 {
171  if (m_pass == 1)
172  {
173  ++m_event;
174  }
175  else
176  {
177  // INFO: Check if there is a zoom in region for the second pass.
178  const VertexList *pVertexList(nullptr);
179  PandoraContentApi::GetList(*this, m_inputVertexListName, pVertexList);
180  if (pVertexList == nullptr || pVertexList->empty())
181  {
182  std::cout << "DLVertexing: Input vertex list is empty! Can't perform pass " << m_pass << std::endl;
183  return STATUS_CODE_SUCCESS;
184  }
185  }
186 
187  std::map<HitType, float> wireMin, wireMax;
188  float driftMin{std::numeric_limits<float>::max()}, driftMax{-std::numeric_limits<float>::max()};
189  for (const std::string &listname : m_caloHitListNames)
190  {
191  const CaloHitList *pCaloHitList{nullptr};
192  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listname, pCaloHitList));
193  if (pCaloHitList->empty())
194  continue;
195 
196  HitType view{pCaloHitList->front()->GetHitType()};
197  float viewDriftMin{driftMin}, viewDriftMax{driftMax};
198  this->GetHitRegion(*pCaloHitList, viewDriftMin, viewDriftMax, wireMin[view], wireMax[view]);
199  driftMin = std::min(viewDriftMin, driftMin);
200  driftMax = std::max(viewDriftMax, driftMax);
201  }
202 
203  CartesianPointVector vertexCandidatesU, vertexCandidatesV, vertexCandidatesW;
204  for (const std::string &listName : m_caloHitListNames)
205  {
206  const CaloHitList *pCaloHitList{nullptr};
207  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, listName, pCaloHitList));
208 
209  HitType view{pCaloHitList->front()->GetHitType()};
210  const bool isU{view == TPC_VIEW_U}, isV{view == TPC_VIEW_V}, isW{view == TPC_VIEW_W};
211  if (!isU && !isV && !isW)
212  return STATUS_CODE_NOT_ALLOWED;
213 
215  PixelVector pixelVector;
216  this->MakeNetworkInputFromHits(*pCaloHitList, view, driftMin, driftMax, wireMin[view], wireMax[view], input, pixelVector);
217 
218  // Run the input through the trained model
220  inputs.push_back(input);
222  if (isU)
223  LArDLHelper::Forward(m_modelU, inputs, output);
224  else if (isV)
225  LArDLHelper::Forward(m_modelV, inputs, output);
226  else
227  LArDLHelper::Forward(m_modelW, inputs, output);
228 
229  int colOffset{0}, rowOffset{0}, canvasWidth{m_width}, canvasHeight{m_height};
230  this->GetCanvasParameters(output, pixelVector, colOffset, rowOffset, canvasWidth, canvasHeight);
231 
232  float **canvas{new float *[canvasHeight]};
233  for (int row = 0; row < canvasHeight; ++row)
234  canvas[row] = new float[canvasWidth]{};
235 
236  // we want the maximum value in the num_classes dimension (1) for every pixel
237  auto classes{torch::argmax(output, 1)};
238  // the argmax result is a 1 x height x width tensor where each element is a class id
239  auto classesAccessor{classes.accessor<int64_t, 3>()};
240  const double scaleFactor{std::sqrt(m_height * m_height + m_width * m_width)};
241  std::map<int, bool> haveSeenMap;
242  for (const auto &[row, col] : pixelVector)
243  {
244  const auto cls{classesAccessor[0][row][col]};
245  if (cls > 0 && cls < m_nClasses)
246  {
247  const int inner{static_cast<int>(std::round(std::ceil(scaleFactor * m_thresholds[cls - 1])))};
248  const int outer{static_cast<int>(std::round(std::ceil(scaleFactor * m_thresholds[cls])))};
249  LArCanvasHelper::DrawRing(canvas, row + rowOffset, col + colOffset, inner, outer, 1.f / (outer * outer - inner * inner));
250  }
251  }
252 
253  CartesianPointVector positionVector;
255  canvas, canvasWidth, canvasHeight, colOffset, rowOffset, view, driftMin, driftMax, wireMin[view], wireMax[view], positionVector);
256  if (isU)
257  vertexCandidatesU.emplace_back(positionVector.front());
258  else if (isV)
259  vertexCandidatesV.emplace_back(positionVector.front());
260  else
261  vertexCandidatesW.emplace_back(positionVector.front());
262 
263 #ifdef MONITORING
264  if (m_visualise)
265  {
266  PANDORA_MONITORING_API(SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_XZ, -1.f, 1.f, 1.f));
267  const MCParticleList *pMCParticleList{nullptr};
268  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
269 
270  CartesianVector trueVertex3D(0, 0, 0);
271  if (LArMCParticleHelper::GetTrueVertex(pMCParticleList, trueVertex3D))
272  {
273  float x{0.f}, u{0.f}, v{0.f}, w{0.f};
274  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
275  LArVertexHelper::GetTrueVertexPosition(trueVertex3D, transform, x, u, v, w);
276  if (isU)
277  {
278  const CartesianVector trueVertex(x, 0.f, u);
279  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "U(true)", BLUE, 3));
280  }
281  else if (isV)
282  {
283  const CartesianVector trueVertex(x, 0.f, v);
284  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "V(true)", BLUE, 3));
285  }
286  else if (isW)
287  {
288  const CartesianVector trueVertex(x, 0.f, w);
289  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex, "W(true)", BLUE, 3));
290  }
291  for (const auto &pos : positionVector)
292  {
293  std::string label{isU ? "U" : isV ? "V" : "W"};
294  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &pos, label, RED, 3));
295  }
296  }
297  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
298  }
299 #endif
300 
301  for (int row = 0; row < canvasHeight; ++row)
302  delete[] canvas[row];
303  delete[] canvas;
304  }
305 
306  int nEmptyLists{0};
307  if (vertexCandidatesU.empty())
308  ++nEmptyLists;
309  if (vertexCandidatesV.empty())
310  ++nEmptyLists;
311  if (vertexCandidatesW.empty())
312  ++nEmptyLists;
313  std::vector<VertexTuple> vertexTuples;
314  CartesianPointVector candidates3D;
315  if (nEmptyLists == 0)
316  {
317  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), vertexCandidatesW.front()));
318  }
319  else if (nEmptyLists == 1)
320  {
321  if (vertexCandidatesU.empty())
322  { // V and W available
323  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesV.front(), vertexCandidatesW.front(), TPC_VIEW_V, TPC_VIEW_W));
324  }
325  else if (vertexCandidatesV.empty())
326  { // U and W available
327  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesW.front(), TPC_VIEW_U, TPC_VIEW_W));
328  }
329  else
330  { // U and V available
331  vertexTuples.emplace_back(VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), TPC_VIEW_U, TPC_VIEW_V));
332  }
333  }
334  else
335  { // Not enough views to reconstruct a 3D vertex
336  std::cout << "Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
337  return STATUS_CODE_NOT_FOUND;
338  }
339 
340  if (m_visualise)
341  {
342  PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &vertexTuples.front().GetPosition(), "candidate", GREEN, 1));
343  }
344 
345  if (!vertexTuples.empty())
346  {
347  const CartesianVector &vertex{vertexTuples.front().GetPosition()};
348  CartesianPointVector vertexCandidates;
349  vertexCandidates.emplace_back(vertex);
350  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->MakeCandidateVertexList(vertexCandidates));
351  }
352  else
353  {
354  std::cout << "Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
355  return STATUS_CODE_NOT_FOUND;
356  }
357 
358  if (m_visualise)
359  {
360  PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
361  }
362 
363  return STATUS_CODE_SUCCESS;
364 }
365 
366 //-----------------------------------------------------------------------------------------------------------------------------------------
367 
368 StatusCode DlVertexingAlgorithm::MakeNetworkInputFromHits(const CaloHitList &caloHits, const HitType view, const float xMin,
369  const float xMax, const float zMin, const float zMax, LArDLHelper::TorchInput &networkInput, PixelVector &pixelVector) const
370 {
371  // ATTN If wire w pitches vary between TPCs, exception will be raised in initialisation of lar pseudolayer plugin
372  const LArTPC *const pTPC(this->GetPandora().GetGeometry()->GetLArTPCMap().begin()->second);
373  const float pitch(view == TPC_VIEW_U ? pTPC->GetWirePitchU() : view == TPC_VIEW_V ? pTPC->GetWirePitchV() : pTPC->GetWirePitchW());
374 
375  // Determine the bin edges
376  std::vector<double> xBinEdges(m_width + 1);
377  std::vector<double> zBinEdges(m_height + 1);
378  xBinEdges[0] = xMin - 0.5f * m_driftStep;
379  const double dx = ((xMax + 0.5f * m_driftStep) - xBinEdges[0]) / m_width;
380  for (int i = 1; i < m_width + 1; ++i)
381  xBinEdges[i] = xBinEdges[i - 1] + dx;
382  zBinEdges[0] = zMin - 0.5f * pitch;
383  const double dz = ((zMax + 0.5f * pitch) - zBinEdges[0]) / m_height;
384  for (int i = 1; i < m_height + 1; ++i)
385  zBinEdges[i] = zBinEdges[i - 1] + dz;
386 
387  LArDLHelper::InitialiseInput({1, 1, m_height, m_width}, networkInput);
388  auto accessor = networkInput.accessor<float, 4>();
389 
390  for (const CaloHit *pCaloHit : caloHits)
391  {
392  const float x{pCaloHit->GetPositionVector().GetX()};
393  const float z{pCaloHit->GetPositionVector().GetZ()};
394  if (m_pass > 1)
395  {
396  if (x < xMin || x > xMax || z < zMin || z > zMax)
397  continue;
398  }
399  const float adc{pCaloHit->GetMipEquivalentEnergy()};
400  const int pixelX{static_cast<int>(std::floor((x - xBinEdges[0]) / dx))};
401  const int pixelZ{static_cast<int>(std::floor((z - zBinEdges[0]) / dz))};
402  accessor[0][0][pixelZ][pixelX] += adc;
403  }
404  for (int row = 0; row < m_height; ++row)
405  {
406  for (int col = 0; col < m_width; ++col)
407  {
408  const float value{accessor[0][0][row][col]};
409  if (value > 0)
410  pixelVector.emplace_back(std::make_pair(row, col));
411  }
412  }
413 
414  return STATUS_CODE_SUCCESS;
415 }
416 
417 //-----------------------------------------------------------------------------------------------------------------------------------------
418 
419 StatusCode DlVertexingAlgorithm::MakeWirePlaneCoordinatesFromCanvas(float **canvas, const int canvasWidth, const int canvasHeight,
420  const int columnOffset, const int rowOffset, const HitType view, const float xMin, const float xMax, const float zMin, const float zMax,
421  CartesianPointVector &positionVector) const
422 {
423  // ATTN If wire w pitches vary between TPCs, exception will be raised in initialisation of lar pseudolayer plugin
424  const LArTPC *const pTPC(this->GetPandora().GetGeometry()->GetLArTPCMap().begin()->second);
425  const float pitch(view == TPC_VIEW_U ? pTPC->GetWirePitchU() : view == TPC_VIEW_V ? pTPC->GetWirePitchV() : pTPC->GetWirePitchW());
426 
427  const double dx = ((xMax + 0.5f * m_driftStep) - (xMin - 0.5f * m_driftStep)) / m_width;
428  const double dz = ((zMax + 0.5f * pitch) - (zMin - 0.5f * pitch)) / m_height;
429 
430  float best{-1.f};
431  int rowBest{0}, colBest{0};
432  for (int row = 0; row < canvasHeight; ++row)
433  for (int col = 0; col < canvasWidth; ++col)
434  if (canvas[row][col] > 0 && canvas[row][col] > best)
435  {
436  best = canvas[row][col];
437  rowBest = row;
438  colBest = col;
439  }
440 
441  const float x{static_cast<float>((colBest - columnOffset) * dx + xMin)};
442  const float z{static_cast<float>((rowBest - rowOffset) * dz + zMin)};
443 
444  CartesianVector pt(x, 0.f, z);
445  positionVector.emplace_back(pt);
446 
447  return STATUS_CODE_SUCCESS;
448 }
449 
450 //-----------------------------------------------------------------------------------------------------------------------------------------
451 
452 StatusCode DlVertexingAlgorithm::MakeCandidateVertexList(const CartesianPointVector &positions)
453 {
454  const VertexList *pVertexList{nullptr};
455  std::string temporaryListName;
456  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, temporaryListName));
457 
458  for (const CartesianVector &position : positions)
459  {
460  PandoraContentApi::Vertex::Parameters parameters;
461  parameters.m_position = position;
462  parameters.m_vertexLabel = VERTEX_INTERACTION;
463  parameters.m_vertexType = VERTEX_3D;
464 
465  const Vertex *pVertex(nullptr);
466  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
467  }
468  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_outputVertexListName));
469  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Vertex>(*this, m_outputVertexListName));
470 
471  return STATUS_CODE_SUCCESS;
472 }
473 
474 #ifdef MONITORING
475 void DlVertexingAlgorithm::PopulateRootTree(const std::vector<VertexTuple> &vertexTuples, const pandora::CartesianPointVector &vertexCandidatesU,
476  const pandora::CartesianPointVector &vertexCandidatesV, const pandora::CartesianPointVector &vertexCandidatesW) const
477 {
478  if (m_writeTree)
479  {
480  const MCParticleList *pMCParticleList{nullptr};
481  if (STATUS_CODE_SUCCESS == PandoraContentApi::GetCurrentList(*this, pMCParticleList))
482  {
483  if (pMCParticleList)
484  {
486  MCParticleVector primaries;
487  LArMCParticleHelper::GetPrimaryMCParticleList(pMCParticleList, primaries);
488  if (!primaries.empty())
489  {
490  const MCParticle *primary{primaries.front()};
491  const MCParticleList &parents{primary->GetParentList()};
492  if (parents.size() == 1)
493  {
494  const MCParticle *trueNeutrino{parents.front()};
495  if (LArMCParticleHelper::IsNeutrino(trueNeutrino))
496  {
497  const LArTransformationPlugin *transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
498  const CartesianVector &trueVertex{primaries.front()->GetVertex()};
499  if (LArVertexHelper::IsInFiducialVolume(this->GetPandora(), trueVertex, m_volumeType))
500  {
501  const CartesianVector &recoVertex{vertexTuples.front().GetPosition()};
502  const float tx{trueVertex.GetX()};
503  const float tu{static_cast<float>(transform->YZtoU(trueVertex.GetY(), trueVertex.GetZ()))};
504  const float tv{static_cast<float>(transform->YZtoV(trueVertex.GetY(), trueVertex.GetZ()))};
505  const float tw{static_cast<float>(transform->YZtoW(trueVertex.GetY(), trueVertex.GetZ()))};
506  const float rx_u{vertexCandidatesU.front().GetX()};
507  const float ru{vertexCandidatesU.front().GetZ()};
508  const float rx_v{vertexCandidatesV.front().GetX()};
509  const float rv{vertexCandidatesV.front().GetZ()};
510  const float rx_w{vertexCandidatesW.front().GetX()};
511  const float rw{vertexCandidatesW.front().GetZ()};
512  const float dr_u{std::sqrt((rx_u - tx) * (rx_u - tx) + (ru - tu) * (ru - tu))};
513  const float dr_v{std::sqrt((rx_v - tx) * (rx_v - tx) + (rv - tv) * (rv - tv))};
514  const float dr_w{std::sqrt((rx_w - tx) * (rx_w - tx) + (rw - tw) * (rw - tw))};
515  const CartesianVector &dv{recoVertex - trueVertex};
516  const float dr{dv.GetMagnitude()};
517  const float dx{dv.GetX()}, dy{dv.GetY()}, dz{dv.GetZ()};
518  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "event", m_event));
519  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "pass", m_pass));
520  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr_u", dr_u));
521  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr_v", dr_v));
522  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr_w", dr_w));
523  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dr", dr));
524  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dx", dx));
525  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dy", dy));
526  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_rootTreeName, "dz", dz));
527  PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_rootTreeName));
528  }
529  }
530  }
531  }
532  }
533  }
534  }
535 }
536 #endif
537 
538 //-----------------------------------------------------------------------------------------------------------------------------------------
539 
540 StatusCode DlVertexingAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
541 {
542  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, DlVertexingBaseAlgorithm::ReadSettings(xmlHandle));
543 
544  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Visualise", m_visualise));
545 
546  if (!m_trainingMode)
547  {
548  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteTree", m_writeTree));
549  if (m_writeTree)
550  {
551  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RootTreeName", m_rootTreeName));
552  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RootFileName", m_rootFileName));
553  }
554  }
555 
556  return STATUS_CODE_SUCCESS;
557 }
558 
559 } // namespace lar_dl_content
Float_t x
Definition: compare.C:6
int m_pass
The pass of the train/infer step.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
Header file for the lar deep learning helper helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:75
LArDLHelper::TorchModel m_modelU
The model for the U view.
Double_t z
Definition: plot.C:276
bool m_visualise
Whether or not to visualise the candidate vertices.
int m_event
The current event number.
std::vector< double > m_thresholds
Distance class thresholds.
float m_driftStep
The size of a pixel in the drift direction in cm (most relevant in pass 2)
std::string m_trainingOutputFile
Output file name for training examples.
TFile f
Definition: plotHisto.C:6
std::string m_outputVertexListName
Output vertex list name.
Header file for the geometry helper class.
std::mt19937 m_rng
The random number generator.
static void DrawRing(float **canvas, const int row, const int col, const int inner, const int outer, const float weight)
Add a filled ring to the specified canvas. The ring has an inner radius based on the minimum predicte...
std::string m_rootTreeName
The ROOT tree name.
Int_t col[ntarg]
Definition: Style.C:29
bool m_writeTree
Whether or not to write validation details to a ROOT tree.
TMarker * pt
Definition: egs.C:25
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
Header file for the file helper class.
std::string m_inputVertexListName
Input vertex list name if 2nd pass.
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
static void Forward(TorchModel &model, const TorchInputVector &input, TorchOutput &output)
Run a deep learning model.
Definition: LArDLHelper.cc:41
double value
Definition: spectrum.C:18
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 ...
Header file for the vertex helper class.
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
VertexTuple class.
Definition: VertexTuple.h:18
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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
std::string m_rootFileName
The ROOT file name.
HitType
Definition: HitType.h:12
pandora::StatusCode MakeCandidateVertexList(const pandora::CartesianPointVector &positions)
Create a vertex list from the candidate vertices.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
int m_nClasses
The number of distance classes.
Float_t e
Definition: plot.C:35
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
static void InitialiseInput(const at::IntArrayRef dimensions, TorchInput &tensor)
Create a torch input tensor.
Definition: LArDLHelper.cc:34
Float_t w
Definition: plot.C:20
std::list< Vertex > VertexList
Definition: DCEL.h:169
std::string m_volumeType
The name of the fiducial volume type for the monitoring output.
LArDLHelper::TorchModel m_modelV
The model for the V view.
std::vector< torch::jit::IValue > TorchInputVector
Definition: LArDLHelper.h:27
vertex reconstruction