9 #include "Pandora/AlgorithmHeaders.h" 32 ElectronInitialRegionRefinementAlgorithm::ElectronInitialRegionRefinementAlgorithm() :
33 m_minShowerHits3D(50),
34 m_showerSlidingFitWindow(1000),
35 m_maxCoincidenceTransverseSeparation(5.
f),
36 m_minSpinePurity(0.7
f),
37 m_trainingMode(false),
38 m_trainingFileName(
"ConnectionPathwayTrain.txt"),
39 m_unambiguousThreshold(0.5
f),
40 m_maxConnectionDistance(1.
f),
41 m_minNConnectedHits(2),
42 m_minElectronCompleteness(0.33
f),
43 m_minElectronPurity(0.5
f),
44 m_maxSeparationFromHit(3.
f),
45 m_maxProjectionSeparation(5.
f),
46 m_maxXSeparation(0.5
f)
54 PfoVector showerPfoVector;
57 if (showerPfoVector.empty())
58 return STATUS_CODE_SUCCESS;
60 for (
const ParticleFlowObject *
const pShowerPfo : showerPfoVector)
63 CaloHitList caloHits3D;
72 return STATUS_CODE_SUCCESS;
79 const PfoList *pPfoList(
nullptr);
81 if (PandoraContentApi::GetList(*
this,
m_showerPfoListName, pPfoList) != STATUS_CODE_SUCCESS)
84 if (!pPfoList || pPfoList->empty())
86 std::cout <<
"ElectronInitialRegionRefinementAlgorithm: unable to find shower pfo list " <<
m_showerPfoListName << std::endl;
90 showerPfoVector.insert(showerPfoVector.begin(), pPfoList->begin(), pPfoList->end());
99 CartesianVector nuVertex3D(0.
f, 0.
f, 0.
f);
115 if (protoShowerMatchVector.empty())
123 this->
BuildViewPathways(pShowerPfo, protoShowerMatch.GetProtoShowerU().GetSpineHitList(), nuVertex3D, TPC_VIEW_U, viewPathwaysU);
124 this->
BuildViewPathways(pShowerPfo, protoShowerMatch.GetProtoShowerV().GetSpineHitList(), nuVertex3D, TPC_VIEW_V, viewPathwaysV);
125 this->
BuildViewPathways(pShowerPfo, protoShowerMatch.GetProtoShowerW().GetSpineHitList(), nuVertex3D, TPC_VIEW_W, viewPathwaysW);
127 this->
RefineHitsToAdd(nuVertex3D, TPC_VIEW_U, viewPathwaysU, protoShowerMatch.GetProtoShowerToModify(TPC_VIEW_U));
128 this->
RefineHitsToAdd(nuVertex3D, TPC_VIEW_V, viewPathwaysV, protoShowerMatch.GetProtoShowerToModify(TPC_VIEW_V));
129 this->
RefineHitsToAdd(nuVertex3D, TPC_VIEW_W, viewPathwaysW, protoShowerMatch.GetProtoShowerToModify(TPC_VIEW_W));
132 CartesianPointVector showerStarts3D;
140 StringVector featureOrder;
152 if (this->
IsElectron(pShowerPfo, electronHitMap))
172 if (statusCode != STATUS_CODE_SUCCESS)
175 if (!pNuVertexList || (pNuVertexList->size() != 1))
177 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
179 <<
" if it does exist, it may have more than one nu vertex" << std::endl;
181 return STATUS_CODE_NOT_INITIALIZED;
184 nuVertex3D = pNuVertexList->front()->GetPosition();
186 return STATUS_CODE_SUCCESS;
194 const CaloHitList *pViewHitList(
nullptr);
199 CartesianVector showerVertexPosition(0.
f, 0.
f, 0.
f);
202 showerVertexPosition = this->
GetShowerVertex(pShowerPfo, hitType, nuVertex3D);
210 CartesianPointVector peakDirectionVector;
215 CaloHitList unavailableHitList;
216 for (CartesianVector &peakDirection : peakDirectionVector)
219 CaloHitList showerSpineHitList;
220 if (
m_pShowerSpineFinderTool->
Run(nuVertex3D, pViewHitList, hitType, peakDirection, unavailableHitList, showerSpineHitList) != STATUS_CODE_SUCCESS)
223 this->
RefineShowerVertex(pShowerPfo, hitType, nuVertex3D, peakDirection, showerVertexPosition);
226 if (!this->
IsSpineCoincident(pShowerPfo, nuVertex3D, hitType, showerVertexPosition, showerSpineHitList))
230 CartesianVector showerStartPosition(0.
f, 0.
f, 0.
f);
231 CartesianVector showerStartDirection(0.
f, 0.
f, 0.
f);
233 if (
m_pShowerStartFinderTool->
Run(pShowerPfo, peakDirection, hitType, showerSpineHitList, showerStartPosition, showerStartDirection) != STATUS_CODE_SUCCESS)
240 showerSpineHitList, CaloHitList(), CartesianPointVector(), CaloHitList());
243 CaloHitList viewShowerHitList;
246 const float showerVertexL(std::max(
247 peakDirection.GetDotProduct(showerStartPosition - nuVertex2D), peakDirection.GetDotProduct(showerVertexPosition - nuVertex2D)));
249 for (
const CaloHit *
const pCaloHit : showerSpineHitList)
251 if (std::find(viewShowerHitList.begin(), viewShowerHitList.end(), pCaloHit) != viewShowerHitList.end())
254 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
255 const float showerL(peakDirection.GetDotProduct(hitPosition - nuVertex2D));
257 if ((showerL > 0.
f) && (showerL < showerVertexL))
261 protoShowerVector.push_back(protoShower);
262 unavailableHitList.insert(unavailableHitList.begin(), showerSpineHitList.begin(), showerSpineHitList.end());
274 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, typeHitListName, pCaloHitList));
276 if (!pCaloHitList || pCaloHitList->empty())
278 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
279 std::cout <<
"ShowerStartRefinementBaseTool: unable to find calo hit list " << typeHitListName << std::endl;
281 return STATUS_CODE_NOT_INITIALIZED;
284 return STATUS_CODE_SUCCESS;
290 const ParticleFlowObject *
const pShowerPfo,
const HitType hitType,
const CartesianVector &nuVertex3D)
const 292 ClusterList viewCusterList;
295 if (viewCusterList.empty())
296 throw StatusCodeException(STATUS_CODE_FAILURE);
300 const CartesianVector &minLayerPosition(twoDShowerSlidingFit.GetShowerFitResult().GetGlobalMinLayerPosition());
301 const CartesianVector &maxLayerPosition(twoDShowerSlidingFit.GetShowerFitResult().GetGlobalMaxLayerPosition());
304 if ((nuVertex2D.GetZ() > minLayerPosition.GetZ()) && (nuVertex2D.GetZ() < maxLayerPosition.GetZ()))
307 const float minSeparation((nuVertex2D - minLayerPosition).GetMagnitudeSquared());
308 const float maxSeparation((nuVertex2D - maxLayerPosition).GetMagnitudeSquared());
309 CartesianVector showerVertexPosition(minSeparation < maxSeparation ? minLayerPosition : maxLayerPosition);
311 return (minSeparation < maxSeparation ? minLayerPosition : maxLayerPosition);
317 const CartesianVector &nuVertex3D,
const CartesianVector &peakDirection, CartesianVector &showerVertexPosition)
const 323 CaloHitList viewShowerHitList;
326 float minL(std::numeric_limits<float>::max());
328 for (
const CaloHit *
const pCaloHit : viewShowerHitList)
330 const CartesianVector displacement(pCaloHit->GetPositionVector() - nuVertex2D);
331 const float longitudinalSeparation(peakDirection.GetDotProduct(displacement));
333 if ((longitudinalSeparation < (-1.
f)) || (longitudinalSeparation > minL))
336 const float transverseSeparation((peakDirection.GetCrossProduct(displacement)).GetMagnitude());
340 showerVertexPosition = pCaloHit->GetPositionVector();
341 minL = longitudinalSeparation;
350 const CartesianVector &showerVertexPosition,
const CartesianVector &nuVertex2D,
const CartesianVector &peakDirection)
const 352 CartesianVector displacement(showerVertexPosition - nuVertex2D);
354 const float longitudinalSeparation(peakDirection.GetDotProduct(displacement));
356 if (longitudinalSeparation < (-1.
f))
359 const float transverseSeparation((peakDirection.GetCrossProduct(displacement)).GetMagnitude());
370 const CartesianVector &nuVertex3D,
const HitType hitType,
const CartesianVector &showerVertex,
const CaloHitList &showerSpineHitList)
const 374 CaloHitList viewShowerHitList;
377 CaloHitList postShowerVertexSpineHits;
378 const float showerDistanceFromNuSquared((showerVertex - nuVertex2D).GetMagnitudeSquared());
380 for (
const CaloHit *
const pSpineHit : showerSpineHitList)
382 const CartesianVector &hitPosition(pSpineHit->GetPositionVector());
383 const float separationSquared((hitPosition - nuVertex2D).GetMagnitudeSquared());
385 if (separationSquared > showerDistanceFromNuSquared)
386 postShowerVertexSpineHits.push_back(pSpineHit);
389 if (postShowerVertexSpineHits.size() == 0)
394 const float spinePurity(static_cast<float>(sharedHitList.size()) / static_cast<float>(postShowerVertexSpineHits.size()));
407 const CaloHitList *pViewHitList(
nullptr);
413 CartesianPointVector eventPeakDirectionVector;
416 CaloHitList unavailableHitList(protectedHits);
419 for (CartesianVector &eventPeakDirection : eventPeakDirectionVector)
421 CaloHitList pathwayHitList;
422 if (
m_pEventPathwayFinderTool->
Run(nuVertex3D, pViewHitList, hitType, eventPeakDirection, unavailableHitList, pathwayHitList) != STATUS_CODE_SUCCESS)
428 viewPathways.push_back(connectionPathway);
429 unavailableHitList.insert(unavailableHitList.begin(), pathwayHitList.begin(), pathwayHitList.end());
441 CaloHitList refinedHitList;
447 const CartesianVector &hitPosition(pHitToAdd->GetPositionVector());
448 const CartesianVector displacement(hitPosition - nuVertex2D);
449 const float thisT((peakDirection.GetCrossProduct(displacement)).GetMagnitudeSquared());
453 const CartesianVector &eventPeakDirection(connectionPathway.GetStartDirection());
455 if (peakDirection.GetOpeningAngle(eventPeakDirection) > (M_PI / 2))
458 const float otherT((eventPeakDirection.GetCrossProduct(displacement)).GetMagnitudeSquared());
472 found ? protoShower.
AddAmbiguousHit(pHitToAdd) : refinedHitList.push_back(pHitToAdd);
475 CaloHitList continuousHitList;
484 const CaloHitList &refinedHitList,
const CartesianVector &nuVertex2D, CaloHitList &continuousHitList)
const 486 continuousHitList.clear();
488 CaloHitVector refinedHitVector(refinedHitList.begin(), refinedHitList.end());
491 unsigned int startIndex(refinedHitVector.size());
493 for (
unsigned int i = 0; i < refinedHitVector.size(); ++i)
495 CaloHitList connectedHitList;
496 connectedHitList.push_back(refinedHitVector[i]);
504 for (
unsigned int j = (i + 1); j < refinedHitVector.size(); ++j)
506 const CaloHit *
const pCaloHit(refinedHitVector[j]);
508 if (std::find(connectedHitList.begin(), connectedHitList.end(), pCaloHit) != connectedHitList.end())
514 connectedHitList.push_back(pCaloHit);
520 if ((connectedHitList.size() >=
m_minNConnectedHits) || (connectedHitList.size() == refinedHitVector.size()))
527 for (
unsigned int i = startIndex; i < refinedHitVector.size(); ++i)
528 continuousHitList.push_back(refinedHitVector[i]);
535 object_creation::ParticleFlowObject::Metadata metadata;
537 metadata.m_propertiesToAdd[
"FoundConnectionPathway"] =
true;
539 if (featureMap.find(
"LArInitialRegionFeatureTool_initialGapSize") != featureMap.end())
540 metadata.m_propertiesToAdd[
"MaxInitialGapSize"] = featureMap.at(
"LArInitialRegionFeatureTool_initialGapSize").Get();
542 if (featureMap.find(
"LArInitialRegionFeatureTool_largestGapSize") != featureMap.end())
543 metadata.m_propertiesToAdd[
"MinLargestProjectedGapSize"] = featureMap.at(
"LArInitialRegionFeatureTool_largestGapSize").Get();
545 if (featureMap.find(
"LArConnectionRegionFeatureTool_pathwayLength") != featureMap.end())
546 metadata.m_propertiesToAdd[
"PathwayLengthMin"] = featureMap.at(
"LArConnectionRegionFeatureTool_pathwayLength").Get();
548 if (featureMap.find(
"LArConnectionRegionFeatureTool_pathwayScatteringAngle2D") != featureMap.end())
549 metadata.m_propertiesToAdd[
"MaxShowerStartPathwayScatteringAngle2D"] =
550 featureMap.at(
"LArConnectionRegionFeatureTool_pathwayScatteringAngle2D").Get();
552 if (featureMap.find(
"LArShowerRegionFeatureTool_nShowerHits") != featureMap.end())
553 metadata.m_propertiesToAdd[
"MaxNPostShowerStartHits"] = featureMap.at(
"LArShowerRegionFeatureTool_nShowerHits").Get();
555 if (featureMap.find(
"LArShowerRegionFeatureTool_foundHitRatio") != featureMap.end())
556 metadata.m_propertiesToAdd[
"MaxFoundHitRatio"] = featureMap.at(
"LArShowerRegionFeatureTool_foundHitRatio").Get();
558 if (featureMap.find(
"LArShowerRegionFeatureTool_scatterAngle") != featureMap.end())
559 metadata.m_propertiesToAdd[
"MaxPostShowerStartScatterAngle"] = featureMap.at(
"LArShowerRegionFeatureTool_scatterAngle").Get();
561 if (featureMap.find(
"LArShowerRegionFeatureTool_openingAngle") != featureMap.end())
562 metadata.m_propertiesToAdd[
"MaxPostShowerStartOpeningAngle"] = featureMap.at(
"LArShowerRegionFeatureTool_openingAngle").Get();
564 if (featureMap.find(
"LArShowerRegionFeatureTool_nuVertexEnergyAsymmetry") != featureMap.end())
565 metadata.m_propertiesToAdd[
"MaxPostShowerStartNuVertexEnergyAsymmetry"] =
566 featureMap.at(
"LArShowerRegionFeatureTool_nuVertexEnergyAsymmetry").Get();
568 if (featureMap.find(
"LArShowerRegionFeatureTool_nuVertexEnergyWeightedMeanRadialDistance") != featureMap.end())
569 metadata.m_propertiesToAdd[
"MaxPostShowerStartNuVertexEnergyWeightedMeanRadialDistance"] =
570 featureMap.at(
"LArShowerRegionFeatureTool_nuVertexEnergyWeightedMeanRadialDistance").Get();
572 if (featureMap.find(
"LArShowerRegionFeatureTool_showerStartEnergyAsymmetry") != featureMap.end())
573 metadata.m_propertiesToAdd[
"MaxPostShowerStartShowerStartEnergyAsymmetry"] =
574 featureMap.at(
"LArShowerRegionFeatureTool_showerStartEnergyAsymmetry").Get();
576 if (featureMap.find(
"LArShowerRegionFeatureTool_showerStartMoliereRadius") != featureMap.end())
577 metadata.m_propertiesToAdd[
"MinPostShowerStartShowerStartMoliereRadius"] =
578 featureMap.at(
"LArShowerRegionFeatureTool_showerStartMoliereRadius").Get();
580 if (featureMap.find(
"LArAmbiguousRegionFeatureTool_nAmbiguousViews") != featureMap.end())
581 metadata.m_propertiesToAdd[
"NViewsWithAmbiguousHits"] = featureMap.at(
"LArAmbiguousRegionFeatureTool_nAmbiguousViews").Get();
583 if (featureMap.find(
"LArAmbiguousRegionFeatureTool_maxUnaccountedEnergy") != featureMap.end())
584 metadata.m_propertiesToAdd[
"AmbiguousHitMaxUnaccountedEnergy"] = featureMap.at(
"LArAmbiguousRegionFeatureTool_maxUnaccountedEnergy").Get();
586 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*
this, pShowerPfo, metadata));
593 electronHitMap.clear();
595 for (
HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
597 const CaloHitList *pViewHitList(
nullptr);
602 for (
const CaloHit *
const pCaloHit : *pViewHitList)
605 const MCParticleWeightMap &weightMap(pCaloHit->GetMCParticleWeightMap());
607 for (
const auto &mapEntry : weightMap)
608 contributingMCParticleVector.push_back(mapEntry.first);
610 std::sort(contributingMCParticleVector.begin(), contributingMCParticleVector.end(), PointerLessThan<MCParticle>());
612 float highestWeight(0.
f);
613 const MCParticle *highestElectronContributor(
nullptr);
615 for (
const MCParticle *
const pMCParticle : contributingMCParticleVector)
617 const bool isLeadingElectron((
std::abs(pMCParticle->GetParticleId()) == 11) &&
620 if (isLeadingElectron)
622 const float weight(weightMap.at(pMCParticle));
624 if (
weight > highestWeight)
627 highestElectronContributor = pMCParticle;
632 if (highestElectronContributor)
633 electronHitMap[highestElectronContributor].push_back(pCaloHit);
644 for (
auto &entry : electronHitMap)
645 mcElectronVector.push_back(entry.first);
647 CaloHitList pfoHitList;
652 for (
const MCParticle *
const pMCElectron : mcElectronVector)
654 const CaloHitList &mcElectronHitList(electronHitMap.at(pMCElectron));
657 const float completeness(static_cast<float>(sharedHitList.size()) / static_cast<float>(mcElectronHitList.size()));
658 const float purity(static_cast<float>(sharedHitList.size()) / static_cast<float>(pfoHitList.size()));
676 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerPfoListName",
m_showerPfoListName));
677 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"NeutrinoVertexListName",
m_neutrinoVertexListName));
678 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListNameU",
m_caloHitListNameU));
679 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListNameV",
m_caloHitListNameV));
680 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListNameW",
m_caloHitListNameW));
682 AlgorithmTool *pAlgorithmTool1(
nullptr);
683 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmTool(*
this, xmlHandle,
"ShowerPeakDirectionFinder", pAlgorithmTool1));
687 return STATUS_CODE_INVALID_PARAMETER;
689 AlgorithmTool *pAlgorithmTool2(
nullptr);
690 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmTool(*
this, xmlHandle,
"EventPeakDirectionFinder", pAlgorithmTool2));
694 return STATUS_CODE_INVALID_PARAMETER;
696 AlgorithmTool *pAlgorithmTool3(
nullptr);
697 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmTool(*
this, xmlHandle,
"ShowerSpineFinder", pAlgorithmTool3));
701 return STATUS_CODE_INVALID_PARAMETER;
703 AlgorithmTool *pAlgorithmTool4(
nullptr);
704 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmTool(*
this, xmlHandle,
"EventPathwayFinder", pAlgorithmTool4));
708 return STATUS_CODE_INVALID_PARAMETER;
710 AlgorithmTool *pAlgorithmTool5(
nullptr);
711 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmTool(*
this, xmlHandle,
"ShowerStartFinder", pAlgorithmTool5));
715 return STATUS_CODE_INVALID_PARAMETER;
717 AlgorithmTool *pAlgorithmTool6(
nullptr);
718 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmTool(*
this, xmlHandle,
"ProtoShowerMatching", pAlgorithmTool6));
722 return STATUS_CODE_INVALID_PARAMETER;
724 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerHits3D",
m_minShowerHits3D));
726 PANDORA_RETURN_RESULT_IF_AND_IF(
727 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerSlidingFitWindow",
m_showerSlidingFitWindow));
729 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
732 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinSpinePurity",
m_minSpinePurity));
734 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingMode",
m_trainingMode));
736 PANDORA_RETURN_RESULT_IF_AND_IF(
737 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingFileName",
m_trainingFileName));
739 PANDORA_RETURN_RESULT_IF_AND_IF(
740 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"UnambiguousThreshold",
m_unambiguousThreshold));
742 PANDORA_RETURN_RESULT_IF_AND_IF(
743 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxConnectionDistance",
m_maxConnectionDistance));
745 PANDORA_RETURN_RESULT_IF_AND_IF(
746 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinNConnectedHits",
m_minNConnectedHits));
748 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
751 PANDORA_RETURN_RESULT_IF_AND_IF(
752 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinElectronPurity",
m_minElectronPurity));
754 PANDORA_RETURN_RESULT_IF_AND_IF(
755 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxSeparationFromHit",
m_maxSeparationFromHit));
757 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
760 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxXSeparation",
m_maxXSeparation));
762 AlgorithmToolVector algorithmToolVector;
763 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
"FeatureTools", algorithmToolVector));
766 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
769 for (
auto const &[pAlgorithmToolName, pAlgorithmTool] : algorithmToolMap)
772 return STATUS_CODE_SUCCESS;
pandora::StatusCode Run(const pandora::CartesianVector &nuVertex3D, const pandora::CaloHitList *const pViewHitList, const pandora::HitType hitType, const pandora::CartesianVector &peakDirection, pandora::CaloHitList &unavailableHitList, pandora::CaloHitList &showerSpineHitList)
Header file for the lar two dimensional sliding shower fit result class.
float m_unambiguousThreshold
The min. transverse distance of an unambiguous shower hit from another pathway direction.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
float m_maxSeparationFromHit
The max. separation between the projected 3D shower start and the closest 2D shower hit...
Header file for the ProtoShower class.
bool IsElectron(const pandora::ParticleFlowObject *const pShowerPfo, const HitOwnershipMap &electronHitMap) const
To determine whether a pfo is a true leading electron via its completeness and purity.
Header file for the electron initial region refinement algorithm class.
const pandora::CartesianPointVector & GetAmbiguousDirectionVector() const
Get the ambiguous direction vector.
void SetMetadata(const pandora::ParticleFlowObject *const pShowerPfo, const LArMvaHelper::MvaFeatureMap &featureMap) const
Add the shower characterisation information to the pfo metadata.
pandora::StringVector m_algorithmToolNames
The algorithm tool names.
pandora::StatusCode GetNeutrinoVertex(pandora::CartesianVector &nuVertex3D) const
Obtain the reconstructed neutrino vertex.
Header file for the connection pathway helper class.
std::map< std::string, pandora::AlgorithmTool * > AlgorithmToolMap
float m_minSpinePurity
The min. purity of a coincident shower spine downstream of the shower vertex.
ShowerSpineFinderTool * m_pShowerSpineFinderTool
The shower spine finder tool for the shower.
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
bool IsShowerConnected(const pandora::CartesianVector &showerVertexPosition, const pandora::CartesianVector &nuVertex2D, const pandora::CartesianVector &peakDirection) const
To determine whether the shower vertex lies on the connection pathway.
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TCONTAINER &&featureContainer)
Produce a training example with the given features and result.
float m_maxConnectionDistance
The max. distance between connected hits.
pandora::StatusCode Run(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const pandora::CaloHitList *const pViewHitList, const pandora::HitType hitType, pandora::CartesianPointVector &peakDirectionVector)
PeakDirectionFinderTool * m_pShowerPeakDirectionFinderTool
The shower initial pathway direction finder tool.
constexpr auto abs(T v)
Returns the absolute value of the argument.
const ConnectionPathway & GetConnectionPathway() const
Get the connection pathway.
pandora::StatusCode Run(const ProtoShowerVector &protoShowerVectorU, const ProtoShowerVector &protoShowerVectorV, const ProtoShowerVector &protoShowerVectorW, ProtoShowerMatchVector &protoShowerMatchVector)
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
static const pandora::MCParticle * GetPrimaryMCParticle(const pandora::MCParticle *const pMCParticle)
Get the primary parent mc particle.
void SetHitsToAddList(const pandora::CaloHitList &hitsToAddList)
Set the hits to add list.
float m_maxXSeparation
The max. drift-coordinate separation between a 3D shower start and a matched 2D shower hit...
static bool FindShowerStarts3D(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianVector &nuVertexPosition, const float maxSeparationFromHit, const float maxProjectionSeparation, const float maxXSeparation, pandora::CartesianPointVector &showerStarts3D)
Create 3D shower start position(s) from three input 2D positions.
void FillShowerPfoVector(pandora::PfoVector &showerPfoVector) const
Obtain a sorted vector of the reconstructed shower pfos.
void BuildViewProtoShowers(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, pandora::HitType hitType, ProtoShowerVector &protoShowerVector) const
Build the 2D ProtoShower objects for a given view.
MvaTypes::MvaFeatureMap MvaFeatureMap
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::string m_trainingFileName
The name of the output training file name.
unsigned int m_minNConnectedHits
The number of connected hits needed for a conntected pathway.
float m_maxCoincidenceTransverseSeparation
The max. transverse distance from the pathway direction of a coincident shower vertex.
float m_minElectronCompleteness
The min. completeness of an electron-like pfo.
ShowerStartFinderTool * m_pShowerStartFinderTool
The shower start finder tool.
bool m_trainingMode
Whether to run the algorithm to train the BDT.
void RefineShower(const pandora::ParticleFlowObject *const pShowerPfo) const
Find and evaluate shower connection pathway, removing if necessary.
TwoDSlidingShowerFitResult class.
Header file for the geometry helper class.
void AddAmbiguousHit(const pandora::CaloHit *const ambiguousHit)
Add an ambiguous hit to the ambiguous hit list.
void FillElectronHitMap(HitOwnershipMap &electronHitMap) const
Determine the one-to-one mapping of leading MCParticle electrons and the hits which contain their ene...
PeakDirectionFinderTool * m_pEventPeakDirectionFinderTool
The other (not incl. shower) initial pathway direction finder tool.
Header file for the lar monte carlo particle helper helper class.
std::vector< ConnectionPathway > ConnectionPathwayVector
pandora::CartesianVector GetShowerVertex(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, const pandora::CartesianVector &nuVertex3D) const
Fit the shower to obtain a 2D shower vertex.
Header file for the cluster helper class.
bool IsSpineCoincident(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const pandora::HitType hitType, const pandora::CartesianVector &showerVertex, const pandora::CaloHitList &showerSpineHitList) const
To determine if the hits downstream of the shower vertex lie within the shower.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
void FindContinuousPath(const pandora::CaloHitList &refinedHitList, const pandora::CartesianVector &nuVertex2D, pandora::CaloHitList &continuousHitList) const
Find the continuous path of hits that lies closest to a given point.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
unsigned int m_minShowerHits3D
The min. number of hits of a significant shower.
void BuildViewPathways(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CaloHitList &protectedHits, const pandora::CartesianVector &nuVertex3D, pandora::HitType hitType, ConnectionPathwayVector &viewPathways) const
Build the connection pathways of all other particles in the event.
float m_minElectronPurity
The min. purity of an electron-like pfo.
static pandora::StatusCode ProcessAlgorithmToolListToMap(const pandora::Algorithm &algorithm, const pandora::TiXmlHandle &xmlHandle, const std::string &listName, pandora::StringVector &algorithToolNameVector, AlgorithmToolMap &algorithmToolMap)
Process a list of algorithms tools in an xml file, using a map. Idea is for this to go to XmlHelper i...
ProtoShowerMatchingTool * m_pProtoShowerMatchingTool
The 2D -> 3D ProtoShower matching tool.
void RefineHitsToAdd(const pandora::CartesianVector &nuVertex3D, const pandora::HitType hitType, const ConnectionPathwayVector &viewPathways, ProtoShower &protoShower) const
Determine the continuous and unambiguous hits to add to an electron-like shower pfo.
SortByDistanceToPoint class.
std::string m_neutrinoVertexListName
The neutrino vertex list name.
float m_maxProjectionSeparation
The max. separation between the projected 3D shower start and the shower start of that view...
ConnectionPathwayFeatureTool::FeatureToolMap m_featureToolMap
The feature tool map.
std::string m_caloHitListNameW
The W calo hit list name.
std::string m_caloHitListNameU
The U calo hit list name.
std::vector< ProtoShowerMatch > ProtoShowerMatchVector
std::vector< ProtoShower > ProtoShowerVector
static MvaFeatureVector CalculateFeatures(const MvaFeatureToolVector< Ts... > &featureToolVector, TARGS &&...args)
Calculate the features in a given feature tool vector.
std::string m_caloHitListNameV
The V calo hit list name.
void AddHitToAdd(const pandora::CaloHit *const hitToAdd)
Add a hit to the hits to add list.
pandora::StatusCode GetHitListOfType(const pandora::HitType hitType, const pandora::CaloHitList *&pCaloHitList) const
Obtain the event hit list of a given view.
pandora::StatusCode Run(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &peakDirection, const pandora::HitType hitType, const pandora::CaloHitList &showerSpineHitList, pandora::CartesianVector &showerStartPosition, pandora::CartesianVector &showerStartDirection)
void AddAmbiguousDirection(const pandora::CartesianVector &ambiguousDirection)
Add an ambiguous direction to the ambiguous direction vector.
const pandora::CaloHitList & GetHitsToAddList() const
Get the hits to add list.
ShowerSpineFinderTool * m_pEventPathwayFinderTool
The shower spine finder tool for all other event particles.
pandora::StatusCode Run()
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
static pandora::CaloHitList GetSharedHits(const pandora::CaloHitList &hitListA, const pandora::CaloHitList &hitListB)
Get the hits in the intersection of two hit lists.
std::map< const pandora::MCParticle *, pandora::CaloHitList > HitOwnershipMap
std::list< Vertex > VertexList
unsigned int m_showerSlidingFitWindow
The sliding fit window for shower fits.
std::string m_showerPfoListName
The shower pfo list name.
static pandora::StatusCode AddFeatureToolToMap(pandora::AlgorithmTool *const pFeatureTool, std::string pFeatureToolName, MvaFeatureToolMap< Ts... > &featureToolMap)
Add a feature tool to a map of feature tools.
const pandora::CartesianVector & GetStartDirection() const
Get the start direction of the connection pathway.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
void RefineShowerVertex(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, const pandora::CartesianVector &nuVertex3D, const pandora::CartesianVector &peakDirection, pandora::CartesianVector &showerVertexPosition) const
Move the shower vertex closer to the connection pathway.