9 #include "Pandora/AlgorithmHeaders.h"
36 TrainedVertexSelectionAlgorithm::TrainedVertexSelectionAlgorithm() :
38 m_trainingSetMode(
false),
39 m_allowClassifyDuringTraining(
false),
40 m_mcVertexXCorrection(0.f),
41 m_minClusterCaloHits(12),
42 m_slidingFitWindow(100),
43 m_minShowerSpineLength(15.f),
44 m_beamDeweightingConstant(0.4),
45 m_localAsymmetryConstant(3.f),
46 m_globalAsymmetryConstant(1.f),
47 m_showerAsymmetryConstant(1.f),
48 m_energyKickConstant(0.06),
49 m_showerClusteringDistance(3.f),
50 m_minShowerClusterHits(1),
51 m_useShowerClusteringApproximation(
false),
53 m_rPhiFineTuningRadius(2.f),
54 m_maxTrueVertexRadius(1.f),
55 m_useRPhiFeatureForRegion(
false),
56 m_dropFailedRPhiFastScoreCandidates(
true),
57 m_testBeamMode(
false),
58 m_legacyEventShapes(
true),
59 m_legacyVariables(
true)
68 ClusterList showerLikeClusters;
72 ClusterList availableShowerLikeClusters(showerLikeClusters.begin(), showerLikeClusters.end());
78 this->
PopulateKdTree(availableShowerLikeClusters, kdTree, hitToClusterMap);
80 while (!availableShowerLikeClusters.empty())
82 ClusterList showerCluster;
83 showerCluster.push_back(availableShowerLikeClusters.back());
84 availableShowerLikeClusters.pop_back();
86 bool addedCluster(
true);
87 while (addedCluster && !availableShowerLikeClusters.empty())
90 for (
const Cluster *
const pCluster : showerCluster)
94 addedCluster = this->
AddClusterToShower(kdTree, hitToClusterMap, availableShowerLikeClusters, pCluster, showerCluster);
98 addedCluster = this->
AddClusterToShower(clusterEndPointsMap, availableShowerLikeClusters, pCluster, showerCluster);
106 unsigned int totHits(0);
107 for (
const Cluster *
const pCluster : showerCluster)
108 totHits += pCluster->GetNCaloHits();
120 const ClusterList &clusterList, ClusterList &showerLikeClusters,
ClusterEndPointsMap &clusterEndPointsMap)
const
122 for (
const Cluster *
const pCluster : clusterList)
128 showerLikeClusters.push_back(pCluster);
130 CaloHitList clusterCaloHitList;
131 pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
133 CaloHitVector clusterCaloHitVector(clusterCaloHitList.begin(), clusterCaloHitList.end());
136 if (clusterCaloHitVector.empty())
139 ClusterEndPoints clusterEndPoints(clusterCaloHitVector.front()->GetPositionVector(), clusterCaloHitVector.back()->GetPositionVector());
140 clusterEndPointsMap.emplace(pCluster, clusterEndPoints);
148 CaloHitList allCaloHits;
150 for (
const Cluster *
const pCluster : clusterList)
152 CaloHitList daughterHits;
153 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
154 allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
156 for (
const CaloHit *
const pCaloHit : daughterHits)
157 (
void)hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
162 kdTree.
build(hitKDNode2DList, hitsBoundingRegion2D);
168 ClusterList &availableShowerLikeClusters,
const Cluster *
const pCluster, ClusterList &showerCluster)
const
170 const auto existingEndPointsIter(clusterEndPointsMap.find(pCluster));
171 if (existingEndPointsIter == clusterEndPointsMap.end())
174 const ClusterEndPoints &existingClusterEndPoints(existingEndPointsIter->second);
176 for (
auto iter = availableShowerLikeClusters.begin(); iter != availableShowerLikeClusters.end(); ++iter)
178 const Cluster *
const pAvailableShowerLikeCluster(*iter);
179 const auto &newEndPointsIter(clusterEndPointsMap.find(pAvailableShowerLikeCluster));
181 if (newEndPointsIter == clusterEndPointsMap.end())
185 const float startStartDistance((newClusterEndPoints.first - existingClusterEndPoints.first).GetMagnitude());
186 const float startEndDistance((newClusterEndPoints.first - existingClusterEndPoints.second).GetMagnitude());
187 const float endStartDistance((newClusterEndPoints.second - existingClusterEndPoints.first).GetMagnitude());
188 const float endEndDistance((newClusterEndPoints.second - existingClusterEndPoints.second).GetMagnitude());
190 const float smallestDistance(std::min(std::min(startStartDistance, startEndDistance), std::min(endStartDistance, endEndDistance)));
194 showerCluster.push_back(pAvailableShowerLikeCluster);
195 availableShowerLikeClusters.erase(iter);
206 ClusterList &availableShowerLikeClusters,
const Cluster *
const pCluster, ClusterList &showerCluster)
const
208 ClusterSet nearbyClusters;
209 CaloHitList daughterHits;
210 pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
212 for (
const CaloHit *
const pCaloHit : daughterHits)
217 kdTree.search(searchRegionHits, found);
219 for (
const auto &
hit : found)
220 (
void)nearbyClusters.insert(hitToClusterMap.at(
hit.data));
223 for (
auto iter = availableShowerLikeClusters.begin(); iter != availableShowerLikeClusters.end(); ++iter)
225 const Cluster *
const pAvailableShowerLikeCluster(*iter);
227 if ((pAvailableShowerLikeCluster != pCluster) && nearbyClusters.count(pAvailableShowerLikeCluster))
229 showerCluster.push_back(pAvailableShowerLikeCluster);
230 availableShowerLikeClusters.erase(iter);
241 const ClusterList &clusterListU,
const ClusterList &clusterListV,
const ClusterList &clusterListW,
const VertexVector &vertexVector)
const
243 float eventEnergy(0.f);
244 unsigned int nShoweryHits(0), nHits(0);
250 const unsigned int nClusters(clusterListU.size() + clusterListV.size() + clusterListW.size());
251 const float eventShoweryness((nHits > 0) ? static_cast<float>(nShoweryHits) / static_cast<float>(nHits) : 0.f);
253 ClusterList allClusters(clusterListU);
254 allClusters.insert(allClusters.end(), clusterListV.begin(), clusterListV.end());
255 allClusters.insert(allClusters.end(), clusterListW.begin(), clusterListW.end());
257 const ClusterListMap clusterListMap{{TPC_VIEW_U, clusterListU}, {TPC_VIEW_V, clusterListV}, {TPC_VIEW_W, clusterListW}};
259 float eventArea(0.f), longitudinality(0.f);
265 return EventFeatureInfo(eventShoweryness, eventEnergy, eventArea, longitudinality, nHits, nClusters, vertexVector.size());
271 const ClusterList &clusterList,
unsigned int &nShoweryHits,
unsigned int &nHits,
float &eventEnergy)
const
273 for (
const Cluster *
const pCluster : clusterList)
276 nShoweryHits += pCluster->GetNCaloHits();
278 eventEnergy += pCluster->GetElectromagneticEnergy();
279 nHits += pCluster->GetNCaloHits();
294 InputFloat xMin, yMin, zMin, xMax, yMax, zMax;
296 for (
const Cluster *
const pCluster : clusterList)
298 CartesianVector minPosition(0.f, 0.f, 0.f), maxPosition(0.f, 0.f, 0.f);
311 if ((xSpan > std::numeric_limits<float>::epsilon()) && (ySpan > std::numeric_limits<float>::epsilon()))
313 eventVolume = xSpan * ySpan * zSpan;
314 longitudinality = zSpan / (xSpan + ySpan);
317 else if (ySpan > std::numeric_limits<float>::epsilon())
319 eventVolume = ySpan * ySpan * zSpan;
320 longitudinality = zSpan / (ySpan + ySpan);
323 else if (xSpan > std::numeric_limits<float>::epsilon())
325 eventVolume = xSpan * xSpan * zSpan;
326 longitudinality = zSpan / (xSpan + xSpan);
334 float xSpanU(0.f), zSpanU(0.f), xSpanV(0.f), zSpanV(0.f), xSpanW(0.f), zSpanW(0.f);
336 this->
Get2DSpan(clusterListMap.at(TPC_VIEW_U), xSpanU, zSpanU);
337 this->
Get2DSpan(clusterListMap.at(TPC_VIEW_V), xSpanV, zSpanV);
338 this->
Get2DSpan(clusterListMap.at(TPC_VIEW_W), xSpanW, zSpanW);
340 const float xSpan = (xSpanU + xSpanV + xSpanW) / 3.f;
341 const float zSpan = (zSpanU + zSpanV + zSpanW) / 3.f;
343 if ((xSpan > std::numeric_limits<float>::epsilon()) && (zSpan > std::numeric_limits<float>::epsilon()))
345 eventArea = xSpan * zSpan;
346 longitudinality = zSpan / (xSpan + zSpan);
354 FloatVector xPositions, zPositions;
356 for (
const Cluster *
const pCluster : clusterList)
358 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
360 for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(), iterEnd = orderedCaloHitList.end(); iter != iterEnd; ++iter)
362 for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
364 xPositions.push_back((*hitIter)->GetPositionVector().GetX());
365 zPositions.push_back((*hitIter)->GetPositionVector().GetZ());
370 std::sort(xPositions.begin(), xPositions.end());
371 std::sort(zPositions.begin(), zPositions.end());
373 if (xPositions.empty())
380 const int low = std::round(0.05 * xPositions.size());
381 const int high = std::round(0.95 * xPositions.size()) - 1;
383 xSpan = xPositions[high] - xPositions[
low];
384 zSpan = zPositions[high] - zPositions[
low];
391 const float minPositionCoord,
const float maxPositionCoord, InputFloat &minCoord, InputFloat &maxCoord)
const
393 if (!minCoord.IsInitialized() || minPositionCoord < minCoord.Get())
394 minCoord = minPositionCoord;
396 if (!maxCoord.IsInitialized() || maxPositionCoord > maxCoord.Get())
397 maxCoord = maxPositionCoord;
404 if (minCoord.IsInitialized() && maxCoord.IsInitialized())
405 return std::fabs(maxCoord.Get() - minCoord.Get());
415 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_eventEnergy));
416 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_eventArea));
417 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_longitudinality));
420 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_nHits));
421 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_nClusters));
422 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_nCandidates));
432 float bestFastScore(-std::numeric_limits<float>::max());
435 double tempBeamDeweight{0.f};
439 const double beamDeweighting(tempBeamDeweight);
441 const double energyKick(LArMvaHelper::CalculateFeaturesOfType<EnergyKickFeatureTool>(
m_featureToolVector,
this, pVertex,
442 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
446 const double localAsymmetry(LArMvaHelper::CalculateFeaturesOfType<LocalAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
447 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
451 const double globalAsymmetry(LArMvaHelper::CalculateFeaturesOfType<GlobalAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
452 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
456 const double showerAsymmetry(LArMvaHelper::CalculateFeaturesOfType<ShowerAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
457 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
464 double dEdxAsymmetry(0.f), vertexEnergy(0.f);
468 dEdxAsymmetry = LArMvaHelper::CalculateFeaturesOfType<EnergyDepositionAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
469 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
476 VertexFeatureInfo vertexFeatureInfo(beamDeweighting, 0.f, energyKick, localAsymmetry, globalAsymmetry, showerAsymmetry, dEdxAsymmetry, vertexEnergy);
477 vertexFeatureInfoMap.emplace(pVertex, vertexFeatureInfo);
493 initialScoreList.emplace_back(pVertex, beamDeweightingScore + energyKickScore + localAsymmetryScore + globalAsymmetryScore + showerAsymmetryScore);
500 std::sort(initialScoreList.begin(), initialScoreList.end());
502 for (
const VertexScore &vertexScore : initialScoreList)
504 const Vertex *
const pVertex(vertexScore.GetVertex());
505 bool farEnoughAway(
true);
507 for (
const Vertex *
const pRegionVertex : bestRegionVertices)
509 if (pRegionVertex == pVertex)
511 farEnoughAway =
false;
515 const float distance = (pRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude();
519 farEnoughAway =
false;
525 bestRegionVertices.push_back(pVertex);
534 if (vertexVector.empty())
538 std::random_device device;
540 std::bernoulli_distribution coinFlip(0.5);
545 const Vertex *
const pBestRegionVertex(this->
ProduceTrainingExamples(bestRegionVertices, vertexFeatureInfoMap, coinFlip, generator,
550 for (
const Vertex *
const pVertex : vertexVector)
552 if (pVertex == pBestRegionVertex)
555 if ((pBestRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude() <
m_regionRadius)
556 regionalVertices.push_back(pVertex);
562 if (!regionalVertices.empty())
574 float bestFastScore(-std::numeric_limits<float>::max());
576 for (
auto iter = vertexVector.begin(); iter != vertexVector.end(); )
585 iter = vertexVector.erase(iter);
597 const MCParticleList *pMCParticleList(
nullptr);
598 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_mcParticleListName, pMCParticleList));
600 const CaloHitList *pCaloHitList(
nullptr);
601 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_caloHitListName, pCaloHitList));
617 MCParticleList mcPrimaryList;
618 for (
const auto &mapEntry : targetMCParticlesToGoodHitsMap)
619 mcPrimaryList.push_back(mapEntry.first);
631 const KDTreeMap &kdTreeMap,
const float maxRadius,
const bool useRPhi)
const
633 const Vertex *pBestVertex(
nullptr);
634 float bestVertexDr(std::numeric_limits<float>::max());
637 this->
GetBestVertex(vertexVector, pBestVertex, bestVertexDr);
642 for (
const Vertex *
const pVertex : vertexVector)
644 if (pVertex == pBestVertex)
654 float separation(0.f), axisHits(0.f);
659 if (pBestVertex && (bestVertexDr < maxRadius))
661 if (coinFlip(generator))
671 if (pBestVertex && (bestVertexDr < maxRadius))
673 if (coinFlip(generator))
689 const Vertex *
const pVertex1,
const Vertex *
const pVertex2,
const KDTreeMap &kdTreeMap,
float &separation,
float &axisHits)
const
691 separation = (pVertex1->GetPosition() - pVertex2->GetPosition()).GetMagnitude();
702 axisHits = separation > std::numeric_limits<float>::epsilon() ? axisHits / separation : 0.f;
708 const CartesianVector pos1,
const CartesianVector pos2,
HitKDTree2D &kdTree,
float &axisHits)
const
714 const CartesianVector unitAxis = (pos1 - pos2).GetUnitVector();
715 const CartesianVector unitPerp(unitAxis.GetZ(), 0, -unitAxis.GetX());
718 const CartesianVector point1 = pos1 + unitPerp;
719 const CartesianVector point2 = pos1 - unitPerp;
720 const CartesianVector point3 = pos2 + unitPerp;
721 const CartesianVector point4 = pos2 - unitPerp;
724 const float xMin{std::min({point1.GetX(), point2.GetX(), point3.GetX(), point4.GetX()})};
725 const float xMax{std::max({point1.GetX(), point2.GetX(), point3.GetX(), point4.GetX()})};
726 const float zMin{std::min({point1.GetZ(), point2.GetZ(), point3.GetZ(), point4.GetZ()})};
727 const float zMax{std::max({point1.GetZ(), point2.GetZ(), point3.GetZ(), point4.GetZ()})};
730 KDTreeBox searchBox(xMin, zMin, xMax, zMax);
732 kdTree.
search(searchBox, found);
737 const CartesianVector &hitPos = f.data->GetPositionVector();
738 bool inBox = this->
IsHitInBox(hitPos, point1, point2, point3, point4);
748 const CartesianVector &point2,
const CartesianVector &point3,
const CartesianVector &point4)
const
750 bool b1 = std::signbit(((point2 - point1).GetCrossProduct(point2 - hitPos)).GetY());
751 bool b2 = std::signbit(((point4 - point3).GetCrossProduct(point4 - hitPos)).GetY());
756 bool b3 = std::signbit(((point3 - point1).GetCrossProduct(point3 - hitPos)).GetY());
757 bool b4 = std::signbit(((point4 - point2).GetCrossProduct(point4 - hitPos)).GetY());
767 const MCParticleList *pMCParticleList(
nullptr);
768 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_mcParticleListName, pMCParticleList));
782 for (
const Vertex *
const pVertex : vertexVector)
784 float mcVertexDr(std::numeric_limits<float>::max());
785 for (
const MCParticle *
const pMCTarget : mcTargetVector)
787 const CartesianVector &mcTargetPosition(
788 (
m_testBeamMode && std::fabs(pMCTarget->GetParticleId()) == 11) ? pMCTarget->GetVertex() : pMCTarget->GetEndpoint());
789 const CartesianVector mcTargetCorrectedPosition(
791 const float dr = (mcTargetCorrectedPosition - pVertex->GetPosition()).GetMagnitude();
797 if (mcVertexDr < bestVertexDr)
799 bestVertexDr = mcVertexDr;
800 pBestVertex = pVertex;
811 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_beamDeweighting));
812 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_energyKick));
813 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_globalAsymmetry));
814 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_localAsymmetry));
815 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_showerAsymmetry));
819 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_dEdxAsymmetry));
820 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_vertexEnergy));
824 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_rPhiFeature));
832 featureVector.push_back(static_cast<double>(vertexSharedFeatureInfo.
m_separation));
833 featureVector.push_back(static_cast<double>(vertexSharedFeatureInfo.
m_axisHits));
841 if (pFavouriteVertex)
843 const CartesianVector vertexPosition(pFavouriteVertex->GetPosition());
845 for (
const Vertex *
const pVertex : vertexVector)
849 const float rPhiScore(vertexFeatureInfoMap.at(pVertex).m_rPhiFeature);
850 finalVertexScoreList.emplace_back(pVertex, rPhiScore);
861 AlgorithmToolVector algorithmToolVector;
862 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
"FeatureTools", algorithmToolVector));
864 for (AlgorithmTool *
const pAlgorithmTool : algorithmToolVector)
867 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingSetMode",
m_trainingSetMode));
869 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
872 PANDORA_RETURN_RESULT_IF_AND_IF(
873 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MCVertexXCorrection",
m_mcVertexXCorrection));
875 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
878 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
883 std::cout <<
"TrainedVertexSelectionAlgorithm: TrainingOutputFileRegion and TrainingOutputFileVertex are required for training set "
884 <<
"mode" << std::endl;
885 return STATUS_CODE_INVALID_PARAMETER;
888 PANDORA_RETURN_RESULT_IF_AND_IF(
889 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MCParticleListName",
m_mcParticleListName));
891 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
895 std::cout <<
"TrainedVertexSelectionAlgorithm: MCParticleListName and CaloHitListName are required for training set mode" << std::endl;
896 return STATUS_CODE_INVALID_PARAMETER;
899 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"InputClusterListNames",
m_inputClusterListNames));
901 PANDORA_RETURN_RESULT_IF_AND_IF(
902 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterCaloHits",
m_minClusterCaloHits));
904 PANDORA_RETURN_RESULT_IF_AND_IF(
905 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitWindow",
m_slidingFitWindow));
907 PANDORA_RETURN_RESULT_IF_AND_IF(
908 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerSpineLength",
m_minShowerSpineLength));
910 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
913 PANDORA_RETURN_RESULT_IF_AND_IF(
914 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LocalAsymmetryConstant",
m_localAsymmetryConstant));
916 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
919 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
922 PANDORA_RETURN_RESULT_IF_AND_IF(
923 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"EnergyKickConstant",
m_energyKickConstant));
925 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
928 PANDORA_RETURN_RESULT_IF_AND_IF(
929 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerClusterHits",
m_minShowerClusterHits));
931 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
934 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"RegionRadius",
m_regionRadius));
936 PANDORA_RETURN_RESULT_IF_AND_IF(
937 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"RPhiFineTuningRadius",
m_rPhiFineTuningRadius));
939 PANDORA_RETURN_RESULT_IF_AND_IF(
940 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxTrueVertexRadius",
m_maxTrueVertexRadius));
942 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
945 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
948 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TestBeamMode",
m_testBeamMode));
950 PANDORA_RETURN_RESULT_IF_AND_IF(
951 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LegacyEventShapes",
m_legacyEventShapes));
953 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LegacyVariables",
m_legacyVariables));
956 std::cout <<
"TrainedVertexSelectionAlgorithm: WARNING -- Producing training sample using incorrect legacy event shapes, consider turning LegacyEventShapes off"
void AddEventFeaturesToVector(const EventFeatureInfo &eventFeatureInfo, LArMvaHelper::MvaFeatureVector &featureVector) const
Add the event features to a vector in the correct order.
void GetLegacyEventShapeFeatures(const pandora::ClusterList &clusterList, float &eventVolume, float &longitudinality) const
Get the event shape features.
std::string m_trainingOutputFileVertex
The training output file for the vertex mva.
unsigned int m_nCandidates
The total number of vertex candidates.
bool m_useShowerClusteringApproximation
Whether to use the shower clustering distance approximation.
unsigned int m_nHits
The number of hits in the event.
bool m_useRPhiFeatureForRegion
Whether to use the r/phi feature for the region vertex.
float m_vertexEnergy
The vertex energy feature.
Header file for the kd tree linker algo template class.
void GetBestRegionVertices(VertexScoreList &initialScoreList, pandora::VertexVector &bestRegionVertices) const
Get the list of top-N separated vertices.
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
MvaTypes::MvaFeatureVector MvaFeatureVector
unsigned int m_minClusterCaloHits
The min number of hits parameter in the energy score.
std::vector< ShowerCluster > ShowerClusterList
Header file for the interaction type helper class.
float m_dEdxAsymmetry
The dE/dx asymmetry feature.
void PopulateInitialScoreList(VertexFeatureInfoMap &vertexFeatureInfoMap, const pandora::Vertex *const pVertex, VertexScoreList &initialScoreList) const
Populate the initial vertex score list for a given vertex.
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TCONTAINER &&featureContainer)
Produce a training example with the given features and result.
VertexFeatureTool::FeatureToolVector m_featureToolVector
The feature tool vector.
float m_beamDeweighting
The beam deweighting feature.
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
void PopulateFinalVertexScoreList(const VertexFeatureInfoMap &vertexFeatureInfoMap, const pandora::Vertex *const pFavouriteVertex, const pandora::VertexVector &vertexVector, VertexScoreList &finalVertexScoreList) const
Populate the final vertex score list using the r/phi score to find the best vertex in the vicinity...
bool IsBeamModeOn() const
Whether algorithm is running in beam mode, assuming neutrinos travel in positive z-direction.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
bool m_legacyEventShapes
Whether to use the old event shapes calculation.
Vertex feature info class.
float m_regionRadius
The radius for a vertex region.
void AddVertexFeaturesToVector(const VertexFeatureInfo &vertexFeatureInfo, LArMvaHelper::MvaFeatureVector &featureVector, const bool useRPhi) const
Add the vertex features to a vector in the correct order.
void IncrementSharedAxisValues(const pandora::CartesianVector pos1, const pandora::CartesianVector pos2, HitKDTree2D &kdTree, float &axisHits) const
Increments the axis hits information for one view.
const pandora::Vertex * ProduceTrainingExamples(const pandora::VertexVector &vertexVector, const VertexFeatureInfoMap &vertexFeatureInfoMap, std::bernoulli_distribution &coinFlip, std::mt19937 &generator, const std::string &interactionType, const std::string &trainingOutputFile, const LArMvaHelper::MvaFeatureVector &eventFeatureList, const KDTreeMap &kdTreeMap, const float maxRadius, const bool useRPhi) const
Produce a set of training examples for a binary classifier.
bool IsClusterShowerLike(const pandora::Cluster *const pCluster) const
Find whether a cluster is shower-like.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static InteractionType GetInteractionType(const pandora::MCParticleList &mcPrimaryList)
Get the interaction type of an event.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void CalculateRPhiScores(pandora::VertexVector &vertexVector, VertexFeatureInfoMap &vertexFeatureInfoMap, const KDTreeMap &kdTreeMap) const
Calculate the r/phi scores for the vertices in a vector, possibly erasing those that fail the fast sc...
Header file for the trained vertex selection algorithm class.
unsigned int m_nClusters
The number of clusters in the event.
void Get2DSpan(const pandora::ClusterList &clusterList, float &xSpan, float &zSpan) const
Get the coordinate span in one view.
float m_localAsymmetryConstant
The local asymmetry constant for the initial region score list.
standard_dbscan3dalg useful for diagnostics hits not in a line will not be clustered on on only for track like only for track like on on the smaller the less shower like tracks low
float m_longitudinality
The longitudinality of the event.
bool IsHitInBox(const pandora::CartesianVector &hitPos, const pandora::CartesianVector &point1, const pandora::CartesianVector &point2, const pandora::CartesianVector &point3, const pandora::CartesianVector &point4) const
Determines whether a hit lies within the box defined by four other positions.
unsigned int m_minShowerClusterHits
The minimum number of shower cluster hits.
Header file for the geometry helper class.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
static void GetClusterBoundingBox(const pandora::Cluster *const pCluster, pandora::CartesianVector &minimumCoordinate, pandora::CartesianVector &maximumCoordinate)
Get minimum and maximum X, Y and Z positions of the calo hits in a cluster.
float m_eventArea
The area of the event.
void ProduceTrainingSets(const pandora::VertexVector &vertexVector, const pandora::VertexVector &bestRegionVertices, VertexFeatureInfoMap &vertexFeatureInfoMap, const LArMvaHelper::MvaFeatureVector &eventFeatureList, const KDTreeMap &kdTreeMap) const
Produce the region and vertex training sets.
static void SelectReconstructableMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters ¶meters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles that match given criteria.
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
std::string m_mcParticleListName
The MC particle list for creating training examples.
void PopulateVertexFeatureInfoMap(const BeamConstants &beamConstants, const ClusterListMap &clusterListMap, const SlidingFitDataListMap &slidingFitDataListMap, const ShowerClusterListMap &showerClusterListMap, const KDTreeMap &kdTreeMap, const pandora::Vertex *const pVertex, VertexFeatureInfoMap &vertexFeatureInfoMap) const
Populate the vertex feature info map for a given vertex.
float m_globalAsymmetryConstant
The global asymmetry constant for the initial region score list.
Header file for the lar monte carlo particle helper helper class.
std::pair< pandora::CartesianVector, pandora::CartesianVector > ClusterEndPoints
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
float m_eventEnergy
The event energy.
static pandora::StatusCode AddFeatureToolToVector(pandora::AlgorithmTool *const pFeatureTool, MvaFeatureToolVector< Ts...> &featureToolVector)
Add a feature tool to a vector of feature tools.
static std::string ToString(const InteractionType interactionType)
Get a string representation of an interaction type.
EventFeatureInfo CalculateEventFeatures(const pandora::ClusterList &clusterListU, const pandora::ClusterList &clusterListV, const pandora::ClusterList &clusterListW, const pandora::VertexVector &vertexVector) const
Calculate the event parameters.
float m_localAsymmetry
The local asymmetry feature.
void build(std::vector< KDTreeNodeInfoT< DATA, DIM >> &eltList, const KDTreeBoxT< DIM > ®ion)
Build the KD tree from the "eltList" in the space define by "region".
float m_maxTrueVertexRadius
The maximum distance at which a vertex candidate can be considered the 'true' vertex.
std::map< pandora::HitType, const pandora::ClusterList & > ClusterListMap
Map array of cluster lists for passing to tools.
float m_energyKick
The energy kick feature.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
VertexSelectionBaseAlgorithm class.
static float GetLength(const pandora::Cluster *const pCluster)
Get length of cluster.
float m_showerAsymmetryConstant
The shower asymmetry constant for the initial region score list.
static bool IsTriggeredBeamParticle(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary triggered beam MCParticle.
Header file for the file helper class.
std::vector< VertexScore > VertexScoreList
void PopulateKdTree(const pandora::ClusterList &clusterList, HitKDTree2D &kdTree, HitToClusterMap &hitToClusterMap) const
Populate kd tree with information about hits in a provided list of clusters.
std::vector< HitKDNode2D > HitKDNode2DList
InteractionType
InteractionType enum.
float m_beamDeweightingConstant
The beam deweighting constant for the initial region score list.
bool m_trainingSetMode
Whether to train.
bool m_allowClassifyDuringTraining
Whether classification is allowed during training.
void CalculateShowerClusterList(const pandora::ClusterList &inputClusterList, ShowerClusterList &showerClusterList) const
Calculate the shower cluster map for a cluster list.
std::string m_trainingOutputFileRegion
The training output file for the region mva.
float m_separation
The distance between the two vertices.
bool m_testBeamMode
Test beam mode.
bool m_dropFailedRPhiFastScoreCandidates
Whether to drop candidates that fail the r/phi fast score test.
void AddSharedFeaturesToVector(const VertexSharedFeatureInfo &vertexSharedFeatureInfo, LArMvaHelper::MvaFeatureVector &featureVector) const
Add the shared features to a vector in the correct order.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
float m_energyKickConstant
The energy kick constant for the initial region score list.
void GetSharedFeatures(const pandora::Vertex *const pVertex1, const pandora::Vertex *const pVertex2, const KDTreeMap &kdTreeMap, float &separation, float &axisHits) const
Calculates the shared features of a pair of vertex candidates.
static void GetTrueNeutrinos(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &trueNeutrinos)
Get neutrino MC particles from an input MC particle list.
std::map< pandora::HitType, const SlidingFitDataList > SlidingFitDataListMap
Map of sliding fit data lists for passing to tools.
float GetVertexEnergy(const pandora::Vertex *const pVertex, const KDTreeMap &kdTreeMap) const
Calculate the energy of a vertex candidate by summing values from all three planes.
void UpdateSpanCoordinate(const float minPositionCoord, const float maxPositionCoord, pandora::InputFloat &minCoord, pandora::InputFloat &maxCoord) const
Update the min/max coordinate spans.
float m_mcVertexXCorrection
The correction to the x-coordinate of the MC vertex position.
float m_showerAsymmetry
The shower asymmetry feature.
void IncrementShoweryParameters(const pandora::ClusterList &clusterList, unsigned int &nShoweryHits, unsigned int &nHits, float &eventEnergy) const
Increment the showery hit parameters for a cluster list.
float GetCoordinateSpan(const pandora::InputFloat &minCoord, const pandora::InputFloat &maxCoord) const
Get the coordinate span.
bool m_legacyVariables
Whether to only use the old variables.
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
std::map< const pandora::Cluster *const, ClusterEndPoints > ClusterEndPointsMap
void GetEventShapeFeatures(const ClusterListMap &clusterListMap, float &eventArea, float &longitudinality) const
Get the event shape features.
std::string m_caloHitListName
The 2D CaloHit list name.
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 >> &nodes)
fill_and_bound_2d_kd_tree
bool AddClusterToShower(const ClusterEndPointsMap &clusterEndPointsMap, pandora::ClusterList &availableShowerLikeClusters, const pandora::Cluster *const pCluster, pandora::ClusterList &showerCluster) const
Try to add an available cluster to a given shower cluster, using shower clustering approximation...
float m_minShowerSpineLength
The minimum length at which all are considered to be tracks.
static MvaFeatureVector ConcatenateFeatureLists()
Recursively concatenate vectors of features (terminating method)
void GetShowerLikeClusterEndPoints(const pandora::ClusterList &clusterList, pandora::ClusterList &showerLikeClusters, ClusterEndPointsMap &clusterEndPointsMap) const
Add the endpoints of any shower-like clusters to the map.
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
Shared vertex feature info class.
float GetBeamDeweightingScore(const BeamConstants &beamConstants, const pandora::Vertex *const pVertex) const
Get the beam deweighting score for a vertex.
static void GetTrueTestBeamParticles(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &trueTestBeamParticles)
Get triggered test beam MC particles from an input MC particle list.
float m_rPhiFeature
The r/phi feature.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_showerClusteringDistance
The shower clustering distance.
float m_axisHits
The hit density along the axis between the two vertices.
float m_eventShoweryness
The event showeryness feature.
static bool IsBeamNeutrinoFinalState(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary neutrino final state MCParticle.
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
pandora::StringVector m_inputClusterListNames
The list of cluster list names.
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM >> &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
std::array< float, 2 > VertexVector(const recob::Vertex &vert, const geo::PlaneID &plane, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true
KDTreeBoxT< 2 > KDTreeBox
BEGIN_PROLOG could also be cout
std::map< const pandora::Vertex *const, VertexFeatureInfo > VertexFeatureInfoMap
float m_rPhiFineTuningRadius
The maximum distance the r/phi tune can move a vertex.
Event feature info class.
void GetBestVertex(const pandora::VertexVector &vertexVector, const pandora::Vertex *&pBestVertex, float &bestVertexDr) const
Use the MC information to get the best vertex from a list.
std::string GetInteractionType() const
Get the interaction type string.
float m_globalAsymmetry
The global asymmetry feature.