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);
356 for (
const Cluster *
const pCluster : clusterList)
358 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
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));
418 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_nHits));
419 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_nClusters));
420 featureVector.push_back(static_cast<double>(eventFeatureInfo.
m_nCandidates));
433 const double energyKick(LArMvaHelper::CalculateFeaturesOfType<EnergyKickFeatureTool>(
m_featureToolVector,
this, pVertex,
434 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
438 const double localAsymmetry(LArMvaHelper::CalculateFeaturesOfType<LocalAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
439 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
443 const double globalAsymmetry(LArMvaHelper::CalculateFeaturesOfType<GlobalAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
444 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
448 const double showerAsymmetry(LArMvaHelper::CalculateFeaturesOfType<ShowerAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
449 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
456 double dEdxAsymmetry(0.
f), vertexEnergy(0.
f);
460 dEdxAsymmetry = LArMvaHelper::CalculateFeaturesOfType<EnergyDepositionAsymmetryFeatureTool>(
m_featureToolVector,
this, pVertex,
461 slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore)
468 VertexFeatureInfo vertexFeatureInfo(beamDeweighting, 0.
f, energyKick, localAsymmetry, globalAsymmetry, showerAsymmetry, dEdxAsymmetry, vertexEnergy);
469 vertexFeatureInfoMap.emplace(pVertex, vertexFeatureInfo);
485 initialScoreList.emplace_back(pVertex, beamDeweightingScore + energyKickScore + localAsymmetryScore + globalAsymmetryScore + showerAsymmetryScore);
492 std::sort(initialScoreList.begin(), initialScoreList.end());
494 for (
const VertexScore &vertexScore : initialScoreList)
496 const Vertex *
const pVertex(vertexScore.GetVertex());
497 bool farEnoughAway(
true);
499 for (
const Vertex *
const pRegionVertex : bestRegionVertices)
501 if (pRegionVertex == pVertex)
503 farEnoughAway =
false;
507 const float distance = (pRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude();
511 farEnoughAway =
false;
517 bestRegionVertices.push_back(pVertex);
526 if (vertexVector.empty())
530 std::random_device device;
532 std::bernoulli_distribution coinFlip(0.5);
542 for (
const Vertex *
const pVertex : vertexVector)
544 if (pVertex == pBestRegionVertex)
547 if ((pBestRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude() <
m_regionRadius)
548 regionalVertices.push_back(pVertex);
554 if (!regionalVertices.empty())
568 for (
auto iter = vertexVector.begin(); iter != vertexVector.end(); )
577 iter = vertexVector.erase(iter);
589 const MCParticleList *pMCParticleList(
nullptr);
590 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_mcParticleListName, pMCParticleList));
592 const CaloHitList *pCaloHitList(
nullptr);
593 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_caloHitListName, pCaloHitList));
609 MCParticleList mcPrimaryList;
610 for (
const auto &mapEntry : targetMCParticlesToGoodHitsMap)
611 mcPrimaryList.push_back(mapEntry.first);
623 const KDTreeMap &kdTreeMap,
const float maxRadius,
const bool useRPhi)
const 625 const Vertex *pBestVertex(
nullptr);
629 this->
GetBestVertex(vertexVector, pBestVertex, bestVertexDr);
634 for (
const Vertex *
const pVertex : vertexVector)
636 if (pVertex == pBestVertex)
646 float separation(0.
f), axisHits(0.
f);
651 if (pBestVertex && (bestVertexDr < maxRadius))
653 if (coinFlip(generator))
655 bestVertexFeatureList, featureList, sharedFeatureList);
658 featureList, bestVertexFeatureList, sharedFeatureList);
663 if (pBestVertex && (bestVertexDr < maxRadius))
665 if (coinFlip(generator))
667 trainingOutputFile +
"_" + interactionType +
".txt",
true, eventFeatureList, bestVertexFeatureList, featureList);
670 trainingOutputFile +
"_" + interactionType +
".txt",
false, eventFeatureList, featureList, bestVertexFeatureList);
681 const Vertex *
const pVertex1,
const Vertex *
const pVertex2,
const KDTreeMap &kdTreeMap,
float &separation,
float &axisHits)
const 683 separation = (pVertex1->GetPosition() - pVertex2->GetPosition()).GetMagnitude();
694 axisHits = separation > std::numeric_limits<float>::epsilon() ? axisHits / separation : 0.f;
700 const CartesianVector pos1,
const CartesianVector pos2,
HitKDTree2D &kdTree,
float &axisHits)
const 706 const CartesianVector unitAxis = (pos1 - pos2).GetUnitVector();
707 const CartesianVector unitPerp(unitAxis.GetZ(), 0, -unitAxis.GetX());
710 const CartesianVector point1 = pos1 + unitPerp;
711 const CartesianVector point2 = pos1 - unitPerp;
712 const CartesianVector point3 = pos2 + unitPerp;
713 const CartesianVector point4 = pos2 - unitPerp;
716 const float xMin{
std::min({point1.GetX(), point2.GetX(), point3.GetX(), point4.GetX()})};
717 const float xMax{
std::max({point1.GetX(), point2.GetX(), point3.GetX(), point4.GetX()})};
718 const float zMin{
std::min({point1.GetZ(), point2.GetZ(), point3.GetZ(), point4.GetZ()})};
719 const float zMax{
std::max({point1.GetZ(), point2.GetZ(), point3.GetZ(), point4.GetZ()})};
722 KDTreeBox searchBox(xMin, zMin, xMax, zMax);
724 kdTree.
search(searchBox, found);
729 const CartesianVector &hitPos =
f.data->GetPositionVector();
730 bool inBox = this->
IsHitInBox(hitPos, point1, point2, point3, point4);
740 const CartesianVector &point2,
const CartesianVector &point3,
const CartesianVector &point4)
const 742 bool b1 = std::signbit(((point2 - point1).GetCrossProduct(point2 - hitPos)).GetY());
743 bool b2 = std::signbit(((point4 - point3).GetCrossProduct(point4 - hitPos)).GetY());
748 bool b3 = std::signbit(((point3 - point1).GetCrossProduct(point3 - hitPos)).GetY());
749 bool b4 = std::signbit(((point4 - point2).GetCrossProduct(point4 - hitPos)).GetY());
759 const MCParticleList *pMCParticleList(
nullptr);
760 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*
this,
m_mcParticleListName, pMCParticleList));
774 for (
const Vertex *
const pVertex : vertexVector)
777 for (
const MCParticle *
const pMCTarget : mcTargetVector)
779 const CartesianVector &mcTargetPosition(
780 (
m_testBeamMode && std::fabs(pMCTarget->GetParticleId()) == 11) ? pMCTarget->GetVertex() : pMCTarget->GetEndpoint());
781 const CartesianVector mcTargetCorrectedPosition(
783 const float dr = (mcTargetCorrectedPosition - pVertex->GetPosition()).GetMagnitude();
789 if (mcVertexDr < bestVertexDr)
791 bestVertexDr = mcVertexDr;
792 pBestVertex = pVertex;
802 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_beamDeweighting));
803 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_energyKick));
804 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_globalAsymmetry));
805 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_localAsymmetry));
806 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_showerAsymmetry));
810 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_dEdxAsymmetry));
811 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_vertexEnergy));
815 featureVector.push_back(static_cast<double>(vertexFeatureInfo.
m_rPhiFeature));
823 featureVector.push_back(static_cast<double>(vertexSharedFeatureInfo.
m_separation));
824 featureVector.push_back(static_cast<double>(vertexSharedFeatureInfo.
m_axisHits));
832 if (pFavouriteVertex)
834 const CartesianVector vertexPosition(pFavouriteVertex->GetPosition());
836 for (
const Vertex *
const pVertex : vertexVector)
840 const float rPhiScore(vertexFeatureInfoMap.at(pVertex).m_rPhiFeature);
841 finalVertexScoreList.emplace_back(pVertex, rPhiScore);
852 AlgorithmToolVector algorithmToolVector;
853 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
"FeatureTools", algorithmToolVector));
855 for (AlgorithmTool *
const pAlgorithmTool : algorithmToolVector)
858 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingSetMode",
m_trainingSetMode));
860 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
863 PANDORA_RETURN_RESULT_IF_AND_IF(
864 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MCVertexXCorrection",
m_mcVertexXCorrection));
866 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
869 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
874 std::cout <<
"TrainedVertexSelectionAlgorithm: TrainingOutputFileRegion and TrainingOutputFileVertex are required for training set " 876 return STATUS_CODE_INVALID_PARAMETER;
879 PANDORA_RETURN_RESULT_IF_AND_IF(
880 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MCParticleListName",
m_mcParticleListName));
882 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
886 std::cout <<
"TrainedVertexSelectionAlgorithm: MCParticleListName and CaloHitListName are required for training set mode" <<
std::endl;
887 return STATUS_CODE_INVALID_PARAMETER;
890 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"InputClusterListNames",
m_inputClusterListNames));
892 PANDORA_RETURN_RESULT_IF_AND_IF(
893 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterCaloHits",
m_minClusterCaloHits));
895 PANDORA_RETURN_RESULT_IF_AND_IF(
896 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitWindow",
m_slidingFitWindow));
898 PANDORA_RETURN_RESULT_IF_AND_IF(
899 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerSpineLength",
m_minShowerSpineLength));
901 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
904 PANDORA_RETURN_RESULT_IF_AND_IF(
905 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LocalAsymmetryConstant",
m_localAsymmetryConstant));
907 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
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,
"EnergyKickConstant",
m_energyKickConstant));
916 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
919 PANDORA_RETURN_RESULT_IF_AND_IF(
920 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerClusterHits",
m_minShowerClusterHits));
922 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
925 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"RegionRadius",
m_regionRadius));
927 PANDORA_RETURN_RESULT_IF_AND_IF(
928 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"RPhiFineTuningRadius",
m_rPhiFineTuningRadius));
930 PANDORA_RETURN_RESULT_IF_AND_IF(
931 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxTrueVertexRadius",
m_maxTrueVertexRadius));
933 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
936 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
939 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TestBeamMode",
m_testBeamMode));
941 PANDORA_RETURN_RESULT_IF_AND_IF(
942 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LegacyEventShapes",
m_legacyEventShapes));
944 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LegacyVariables",
m_legacyVariables));
947 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.
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...
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.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
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.
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.
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TLISTS &&...featureLists)
Produce a training example with the given features and result.
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
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 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.
VertexSelectionBaseAlgorithm class.
static float GetLength(const pandora::Cluster *const pCluster)
Get length of cluster.
static pandora::StatusCode AddFeatureToolToVector(pandora::AlgorithmTool *const pFeatureTool, MvaFeatureToolVector< Ts... > &featureToolVector)
Add a feature tool to a vector of feature tools.
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.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
Header file for the file helper class.
static int max(int a, int b)
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.
Detector simulation of raw signals on wires.
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.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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.
std::vector< art::Ptr< recob::Vertex > > VertexVector
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.
void GetShowerLikeClusterEndPoints(const pandora::ClusterList &clusterList, pandora::ClusterList &showerLikeClusters, ClusterEndPointsMap &clusterEndPointsMap) const
Add the endpoints of any shower-like clusters to the map.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
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.
Dft::FloatVector FloatVector
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::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.
QTextStream & endl(QTextStream &s)
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.