12 #include <torch/script.h>
13 #include <torch/torch.h>
23 using namespace lar_content;
25 namespace lar_dl_content
28 DlVertexingAlgorithm::DlVertexingAlgorithm() :
29 m_trainingMode{
false},
30 m_trainingOutputFile{
""},
52 catch (StatusCodeException
e)
54 std::cout <<
"VertexAssessmentAlgorithm: Unable to write to ROOT tree" << std::endl;
68 return STATUS_CODE_SUCCESS;
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);
81 const CaloHitList *pCaloHitList(
nullptr);
82 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this, listname, pCaloHitList));
83 if (pCaloHitList->empty())
85 m_rng.seed(static_cast<std::mt19937::result_type>(pCaloHitList->size()));
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;
92 CartesianPointVector vertices;
93 for (
const MCParticle *mc : hierarchy)
95 if (LArMCParticleHelper::IsNeutrino(mc))
96 vertices.push_back(mc->GetVertex());
100 const CartesianVector &
vertex{vertices.front()};
102 const unsigned long nVertices{1};
103 unsigned long nHits{0};
104 const unsigned int nuance{LArMCParticleHelper::GetNuanceCode(hierarchy.front())};
107 const LArTransformationPlugin *
transform{this->GetPandora().GetPlugins()->GetLArTransformationPlugin()};
108 const double xVtx{
vertex.GetX()};
118 double xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
122 const double xJitter{gauss(
m_rng)}, zJitter{gauss(
m_rng)};
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);
135 for (
const CaloHit *pCaloHit : *pCaloHitList)
137 const float x{pCaloHit->GetPositionVector().GetX()},
z{pCaloHit->GetPositionVector().GetZ()}, adc{pCaloHit->GetInputEnergy()};
139 if (
m_pass > 1 && (x < xMin || x > xMax || z < zMin || z > zMax))
141 featureVector.emplace_back(static_cast<double>(
x));
142 featureVector.emplace_back(static_cast<double>(
z));
143 featureVector.emplace_back(static_cast<double>(adc));
146 featureVector.insert(featureVector.begin() + 2,
static_cast<double>(nHits));
149 LArMvaHelper::ProduceTrainingExample(trainingFilename,
true, featureVector);
152 return STATUS_CODE_SUCCESS;
161 CartesianPointVector vertexCandidatesU, vertexCandidatesV, vertexCandidatesW;
162 for (
const std::string listName : m_caloHitListNames)
164 const CaloHitList *pCaloHitList{
nullptr};
165 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this, listName, pCaloHitList));
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;
178 inputs.push_back(input);
187 int colOffset{0}, rowOffset{0}, canvasWidth{
m_width}, canvasHeight{
m_height};
188 this->
GetCanvasParameters(output, pixelVector, colOffset, rowOffset, canvasWidth, canvasHeight);
190 float **canvas{
new float *[canvasHeight]};
191 for (
int row = 0;
row < canvasHeight; ++
row)
192 canvas[
row] =
new float[canvasWidth]{};
195 auto classes{torch::argmax(output, 1)};
197 auto classesAccessor{classes.accessor<long, 3>()};
199 std::map<int, bool> haveSeenMap;
200 for (
const auto [
row, col] : pixelVector)
202 const auto cls{classesAccessor[0][
row][col]};
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));
211 CartesianPointVector positionVector;
214 vertexCandidatesU.emplace_back(positionVector.front());
216 vertexCandidatesV.emplace_back(positionVector.front());
218 vertexCandidatesW.emplace_back(positionVector.front());
222 PANDORA_MONITORING_API(SetEveDisplayParameters(this->GetPandora(),
true, DETECTOR_VIEW_XZ, -1.f, 1.f, 1.f));
225 float x{0.f}, u{0.f}, v{0.f},
w{0.f};
229 const CartesianVector trueVertex(
x, 0.f, u);
230 PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex,
"U(true)",
BLUE, 3));
234 const CartesianVector trueVertex(
x, 0.f, v);
235 PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex,
"V(true)",
BLUE, 3));
239 const CartesianVector trueVertex(
x, 0.f,
w);
240 PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &trueVertex,
"W(true)",
BLUE, 3));
243 catch (StatusCodeException &
e)
245 std::cerr <<
"DlVertexingAlgorithm: Warning. Couldn't find true vertex." << std::endl;
247 for (
const auto pos : positionVector)
249 std::string label{isU ?
"U" : isV ?
"V" :
"W"};
250 PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &pos, label, RED, 3));
252 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
255 for (
int row = 0;
row < canvasHeight; ++
row)
256 delete[] canvas[
row];
261 if (vertexCandidatesU.empty())
263 if (vertexCandidatesV.empty())
265 if (vertexCandidatesW.empty())
267 std::vector<VertexTuple> vertexTuples;
268 CartesianPointVector candidates3D;
269 if (nEmptyLists == 0)
271 vertexTuples.emplace_back(
VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), vertexCandidatesW.front()));
273 else if (nEmptyLists == 1)
275 if (vertexCandidatesU.empty())
277 vertexTuples.emplace_back(
VertexTuple(this->GetPandora(), vertexCandidatesV.front(), vertexCandidatesW.front(), TPC_VIEW_V, TPC_VIEW_W));
279 else if (vertexCandidatesV.empty())
281 vertexTuples.emplace_back(
VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesW.front(), TPC_VIEW_U, TPC_VIEW_W));
285 vertexTuples.emplace_back(
VertexTuple(this->GetPandora(), vertexCandidatesU.front(), vertexCandidatesV.front(), TPC_VIEW_U, TPC_VIEW_W));
290 std::cout <<
"Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
291 return STATUS_CODE_NOT_FOUND;
296 PANDORA_MONITORING_API(AddMarkerToVisualization(this->GetPandora(), &vertexTuples.front().GetPosition(),
"candidate", GREEN, 1));
299 if (!vertexTuples.empty())
301 const CartesianVector &
vertex{vertexTuples.front().GetPosition()};
302 CartesianPointVector vertexCandidates;
303 vertexCandidates.emplace_back(
vertex);
308 std::cout <<
"Insufficient 2D vertices to reconstruct a 3D vertex" << std::endl;
309 return STATUS_CODE_NOT_FOUND;
314 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
317 return STATUS_CODE_SUCCESS;
326 float xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
330 std::vector<double> xBinEdges(
m_width + 1);
331 std::vector<double> zBinEdges(
m_height + 1);
334 for (
int i = 1; i <
m_width + 1; ++i)
335 xBinEdges[i] = xBinEdges[i - 1] + dx;
338 for (
int i = 1; i <
m_height + 1; ++i)
339 zBinEdges[i] = zBinEdges[i - 1] + dz;
342 auto accessor = networkInput.accessor<float, 4>();
345 for (
const CaloHit *pCaloHit : caloHits)
347 const float x{pCaloHit->GetPositionVector().GetX()};
348 const float z{pCaloHit->GetPositionVector().GetZ()};
351 if (x < xMin || x > xMax || z < zMin || z > zMax)
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];
365 for (
int col = 0; col <
m_width; ++col)
367 const float value{accessor[0][0][
row][col]};
368 accessor[0][0][
row][col] =
value / maxValue;
370 pixelVector.emplace_back(std::make_pair(
row, col));
375 return STATUS_CODE_SUCCESS;
381 const CaloHitList &caloHits,
const PixelVector &pixelVector, CartesianPointVector &positionVector)
const
384 float xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
388 const double dx{((xMax +
PY_EPSILON) - (xMin - PY_EPSILON)) / m_width};
390 const double dz{((zMax +
PY_EPSILON) - (zMin - PY_EPSILON)) / m_height};
393 const float xShift{
static_cast<float>(dx * 0.5f)};
394 const float zShift{
static_cast<float>(dz * 0.5f)};
396 for (
const auto [
row, col] : pixelVector)
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);
404 return STATUS_CODE_SUCCESS;
410 const int canvasHeight,
const int columnOffset,
const int rowOffset, CartesianPointVector &positionVector)
const
413 float xMin{0.f}, xMax{0.f}, zMin{0.f}, zMax{0.f};
417 const double dx{((xMax +
PY_EPSILON) - (xMin - PY_EPSILON)) / m_width};
419 const double dz{((zMax +
PY_EPSILON) - (zMin - PY_EPSILON)) / m_height};
422 const float xShift{
static_cast<float>(dx * 0.5f)};
423 const float zShift{
static_cast<float>(dz * 0.5f)};
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)
431 best = canvas[
row][col];
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);
441 return STATUS_CODE_SUCCESS;
447 int &colOffset,
int &rowOffset,
int &width,
int &height)
const
449 const double scaleFactor{std::sqrt(m_height * m_height + m_width * m_width)};
452 auto classes{torch::argmax(networkOutput, 1)};
454 auto classesAccessor{classes.accessor<long, 3>()};
455 int colOffsetMin{0}, colOffsetMax{0}, rowOffsetMin{0}, rowOffsetMax{0};
456 for (
const auto [
row, col] : pixelVector)
458 const auto cls{classesAccessor[0][
row][col]};
460 if (threshold > 0. && threshold < 1.)
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;
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);
484 int c1{inner}, r1{0}, c2{outer}, r2{0};
485 int inner2{inner * inner}, outer2{outer * outer};
489 int rp2{r2}, cp2{c2};
498 for (
int c = cp1; c <= cp2; ++c)
500 canvas[row + rp2][col + c] += weight;
502 canvas[row + c][col + rp2] += weight;
503 if (rp2 != 0 && cp2 != 0)
505 canvas[row - rp2][col - c] += weight;
507 canvas[row - c][col - rp2] += weight;
511 canvas[row - rp2][col + c] += weight;
513 canvas[row + c][col - rp2] += weight;
517 canvas[row + rp2][col - c] += weight;
519 canvas[row - c][col + rp2] += weight;
525 this->
Update(inner2, c1, r1);
527 this->
Update(outer2, c2, r2);
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};
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));
560 LArMCParticleHelper::SelectReconstructableMCParticles(
561 pMCParticleList, pCaloHitList2D, parameters, LArMCParticleHelper::IsBeamNeutrinoFinalState, mcToHitsMap);
563 return STATUS_CODE_SUCCESS;
572 for (
const auto [mc, hits] : mcToHitsMap)
575 mcHierarchy.push_back(mc);
576 LArMCParticleHelper::GetAllAncestorMCParticles(mc, mcHierarchy);
579 catch (
const StatusCodeException &
e)
581 return e.GetStatusCode();
586 std::find_if(mcHierarchy.begin(), mcHierarchy.end(), [](
const MCParticle *mc) ->
bool {
return LArMCParticleHelper::IsNeutrino(mc); });
588 if (pivot != mcHierarchy.end())
589 std::rotate(mcHierarchy.begin(), pivot, std::next(pivot));
591 return STATUS_CODE_NOT_FOUND;
593 return STATUS_CODE_SUCCESS;
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();
605 for (
const CaloHit *pCaloHit : caloHitList)
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);
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 ¢roid{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()};
629 zCentroid =
transform->YZtoU(centroid.GetY(), centroid.GetZ());
632 zCentroid =
transform->YZtoV(centroid.GetY(), centroid.GetZ());
635 zCentroid =
transform->YZtoW(centroid.GetY(), centroid.GetZ());
638 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
649 const float xRange{xMax - xMin}, zRange{zMax - zMin};
650 if (2.f * xRange < m_width)
652 const float padding{0.5f * (0.5f * m_width - xRange)};
656 if (2.f * zRange < m_height)
658 const float padding{0.5f * (0.5f * m_height - zRange)};
669 std::string temporaryListName;
670 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pVertexList, temporaryListName));
672 for (
const CartesianVector position : positions)
675 parameters.m_position = position;
676 parameters.m_vertexLabel = VERTEX_INTERACTION;
677 parameters.m_vertexType = VERTEX_3D;
679 const Vertex *pVertex(
nullptr);
680 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
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));
685 return STATUS_CODE_SUCCESS;
693 x = trueVertex.GetX();
694 y = trueVertex.GetY();
695 z = trueVertex.GetZ();
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()));
714 const MCParticleList *pMCParticleList{
nullptr};
715 if (STATUS_CODE_SUCCESS == PandoraContentApi::GetCurrentList(*
this, pMCParticleList) && pMCParticleList)
718 LArMCParticleHelper::GetPrimaryMCParticleList(pMCParticleList, primaries);
719 if (!primaries.empty())
721 const MCParticle *primary{primaries.front()};
722 const MCParticleList &parents{primary->GetParentList()};
723 if (parents.size() == 1)
725 const MCParticle *trueNeutrino{parents.front()};
726 if (LArMCParticleHelper::IsNeutrino(trueNeutrino))
727 return primaries.front()->GetVertex();
732 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
736 const pandora::CartesianPointVector &vertexCandidatesV,
const pandora::CartesianPointVector &vertexCandidatesW)
const
740 const MCParticleList *pMCParticleList{
nullptr};
741 if (STATUS_CODE_SUCCESS == PandoraContentApi::GetCurrentList(*
this, pMCParticleList))
747 LArMCParticleHelper::GetPrimaryMCParticleList(pMCParticleList, primaries);
748 if (!primaries.empty())
750 const MCParticle *primary{primaries.front()};
751 const MCParticleList &parents{primary->GetParentList()};
752 if (parents.size() == 1)
754 const MCParticle *trueNeutrino{parents.front()};
755 if (LArMCParticleHelper::IsNeutrino(trueNeutrino))
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"))
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()};
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));
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));
811 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingOutputFileName",
m_trainingOutputFile));
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");
819 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ModelFileNameV", modelName));
820 modelName = LArFileHelper::FindFileInPath(modelName,
"FW_SEARCH_PATH");
822 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ModelFileNameW", modelName));
823 modelName = LArFileHelper::FindFileInPath(modelName,
"FW_SEARCH_PATH");
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));
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));
833 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"OutputVertexListName",
m_outputVertexListName));
836 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"InputVertexListName",
m_inputVertexListName));
840 PANDORA_RETURN_RESULT_IF_AND_IF(
841 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"CaloHitListNames", m_caloHitListNames));
843 return STATUS_CODE_SUCCESS;
850 const Pandora &
pandora,
const CartesianVector &vertexU,
const CartesianVector &vertexV,
const CartesianVector &vertexW) :
851 m_pos{0.f, 0.f, 0.f},
854 LArGeometryHelper::MergeThreePositions3D(
pandora, TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, vertexU, vertexV, vertexW, m_pos, m_chi2);
857 CartesianVector vertexUV(0.f, 0.f, 0.f);
859 LArGeometryHelper::MergeTwoPositions3D(
pandora, TPC_VIEW_U, TPC_VIEW_V, vertexU, vertexV, vertexUV, chi2UV);
861 CartesianVector vertexUW(0.f, 0.f, 0.f);
863 LArGeometryHelper::MergeTwoPositions3D(
pandora, TPC_VIEW_U, TPC_VIEW_W, vertexU, vertexW, vertexUW, chi2UW);
865 CartesianVector vertexVW(0.f, 0.f, 0.f);
867 LArGeometryHelper::MergeTwoPositions3D(
pandora, TPC_VIEW_V, TPC_VIEW_W, vertexV, vertexW, vertexVW, chi2VW);
892 const Pandora &
pandora,
const CartesianVector &vertex1,
const CartesianVector &vertex2,
const HitType view1,
const HitType view2) :
893 m_pos{0.f, 0.f, 0.f},
896 LArGeometryHelper::MergeTwoPositions3D(
pandora, view1, view2, vertex1, vertex2, m_pos, m_chi2);
897 std::cout <<
"Merging 2, position (" << m_pos.GetX() <<
", " << m_pos.GetY() <<
", " << m_pos.GetZ() <<
") with chi2 " << m_chi2 << std::endl;
918 const float x{m_pos.GetX()},
y{m_pos.GetY()},
z{m_pos.GetZ()};
pandora::CartesianVector m_pos
Calculated 3D position.
LArDLHelper::TorchModel m_modelU
The model for the U view.
process_name opflash particleana ie ie ie z
const pandora::CartesianVector & GetTrueVertex() const
Retrieve the true neutrino vertex.
void GetHitRegion(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax, float &zMin, float &zMax) const
std::vector< double > m_thresholds
Distance class thresholds.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
pandora::StatusCode MakeNetworkInputFromHits(const pandora::CaloHitList &caloHits, LArDLHelper::TorchInput &networkInput, PixelVector &pixelVector) const
MvaTypes::MvaFeatureVector MvaFeatureVector
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...
process_name opflash particleana ie x
BEGIN_PROLOG could also be cerr
pandora::StatusCode GetMCToHitsMap(LArMCParticleHelper::MCContributionMap &mcToHitsMap) const
bool m_visualise
Whether or not to visualise the candidate vertices.
int m_event
The current event number.
pandora::StatusCode PrepareTrainingSample()
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.
pandora::StringVector m_caloHitListNames
Names of input calo hit lists.
std::string ToString() const
LArDLHelper::TorchModel m_modelV
The model for the V view.
float m_regionSize
The half width/height of the event region to consider in cm.
float m_maxHitAdc
Maximum ADC value to allow.
float m_maxPhotonPropagation
the maximum photon propagation length
pandora::StatusCode CompleteMCHierarchy(const LArMCParticleHelper::MCContributionMap &mcToHitsMap, pandora::MCParticleList &mcHierarchy) const
std::string m_outputVertexListName
Output vertex list name.
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 geometry helper class.
std::mt19937 m_rng
The random number generator.
int m_nClasses
The number of distance classes.
process_name opflash particleana ie ie y
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
std::string m_rootTreeName
The ROOT tree name.
const double PY_EPSILON
The value of epsilon in Python.
bool m_writeTree
Whether or not to write validation details to a ROOT tree.
int m_height
The height of the images.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
const pandora::CartesianVector & GetPosition() const
int m_pass
The pass of the train/infer step.
Header file for the file helper class.
pandora::StatusCode Run()
pandora::StatusCode MakeWirePlaneCoordinatesFromPixels(const pandora::CaloHitList &caloHits, const PixelVector &pixelVector, pandora::CartesianPointVector &positionVector) const
static void Forward(TorchModel &model, const TorchInputVector &input, TorchOutput &output)
Run a deep learning model.
void GetTrueVertexPosition(float &x, float &y, float &z) const
Retrieve the true neutrino vertex position.
std::string m_inputVertexListName
Input vertex list name if 2nd pass.
Header file for the vertex helper class.
bool m_trainingMode
Training mode.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
LArDLHelper::TorchModel m_modelW
The model for the W view.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
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.
std::string m_rootFileName
The ROOT file name.
pandora::StatusCode Infer()
std::string to_string(WindowPattern const &pattern)
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
pandora::StatusCode MakeCandidateVertexList(const pandora::CartesianPointVector &positions)
Create a vertex list from the candidate vertices.
std::vector< Pixel > PixelVector
std::size_t count(Cont const &cont)
int m_width
The width of the images.
static void InitialiseInput(const at::IntArrayRef dimensions, TorchInput &tensor)
Create a torch input tensor.
std::list< Vertex > VertexList
virtual ~DlVertexingAlgorithm()
BEGIN_PROLOG could also be cout
std::vector< torch::jit::IValue > TorchInputVector
VertexTuple(const pandora::Pandora &pandora, const pandora::CartesianVector &vertexU, const pandora::CartesianVector &vertexV, const pandora::CartesianVector &vertexW)
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...