9 #include "Pandora/AlgorithmHeaders.h" 25 StitchingCosmicRayMergingTool::StitchingCosmicRayMergingTool() :
26 m_useXcoordinate(false),
27 m_alwaysApplyT0Calculation(true),
28 m_halfWindowLayers(30),
29 m_minLengthSquared(50.
f),
30 m_minCosRelativeAngle(0.966),
31 m_relaxMinLongitudinalDisplacement(-5.
f),
32 m_maxLongitudinalDisplacementX(15.
f),
33 m_maxTransverseDisplacement(5.
f),
34 m_relaxCosRelativeAngle(0.906),
35 m_relaxTransverseDisplacement(2.5
f),
37 m_maxX0FractionalDeviation(0.3
f),
38 m_boundaryToleranceWidth(10.
f)
45 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
46 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
48 if (this->GetPandora().GetGeometry()->GetLArTPCMap().
size() < 2)
51 if (pfoToLArTPCMap.empty())
52 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
61 this->
BuildTPCMaps(primaryPfos, pfoToLArTPCMap, larTPCToPfoMap);
64 this->
CreatePfoMatches(larTPCToPfoMap, pointingClusterMap, pfoAssociationMatrix);
73 this->
OrderPfoMerges(pfoToLArTPCMap, pointingClusterMap, pfoSelectedMerges, pfoOrderedMerges);
75 this->
StitchPfos(pAlgorithm, pointingClusterMap, pfoOrderedMerges, pfoToLArTPCMap, stitchedPfosToX0Map);
82 for (
const ParticleFlowObject *
const pPfo : *pInputPfoList)
87 if (!pfoToLArTPCMap.count(pPfo))
90 outputPfoList.push_back(pPfo);
101 for (
const ParticleFlowObject *
const pPfo : inputPfoList)
107 if (pfoToLArTPCMap.end() == tpcIter)
108 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
110 const float slidingFitPitch(tpcIter->second->GetWirePitchW());
112 ClusterList clusterList;
115 if (1 != clusterList.size())
116 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
119 (void)pointingClusterMap.insert(ThreeDPointingClusterMap::value_type(pPfo,
LArPointingCluster(slidingFitResult)));
121 catch (
const StatusCodeException &)
131 for (
const ParticleFlowObject *
const pPfo : inputPfoList)
135 if (pfoToLArTPCMap.end() != iter)
136 larTPCToPfoMap[iter->second].push_back(pPfo);
145 LArTPCVector larTPCVector;
146 for (
const auto &mapEntry : larTPCToPfoMap)
147 larTPCVector.push_back(mapEntry.first);
152 const LArTPC *
const pLArTPC1(*tpcIter1);
153 const PfoList &pfoList1(larTPCToPfoMap.at(pLArTPC1));
157 const LArTPC *
const pLArTPC2(*tpcIter2);
158 const PfoList &pfoList2(larTPCToPfoMap.at(pLArTPC2));
163 for (
const ParticleFlowObject *
const pPfo1 : pfoList1)
165 for (
const ParticleFlowObject *
const pPfo2 : pfoList2)
166 this->
CreatePfoMatches(*pLArTPC1, *pLArTPC2, pPfo1, pPfo2, pointingClusterMap, pfoAssociationMatrix);
186 if (pointingClusterMap.end() == iter1 || pointingClusterMap.end() == iter2)
197 CaloHitList caloHitList3D1;
200 CaloHitList caloHitList3D2;
214 catch (
const pandora::StatusCodeException &)
226 const float pX1(std::fabs(pointingVertex1.
GetDirection().GetX()));
227 const float pX2(std::fabs(pointingVertex2.
GetDirection().GetX()));
229 if (pX1 < std::numeric_limits<float>::epsilon() || pX2 < std::numeric_limits<float>::epsilon())
233 const float intersectX(0.5 * (pointingVertex1.
GetPosition().GetX() + pointingVertex2.
GetPosition().GetX()));
235 if (std::fabs(intersectX - boundaryCenterX) > maxLongitudinalDisplacementX)
239 float rT1(0.
f), rL1(0.
f), rT2(0.
f), rL2(0.
f);
254 catch (
const pandora::StatusCodeException &)
264 : (1.
f - pX1 * pX1 > std::numeric_limits<float>::epsilon()) ? pX1 / std::sqrt(1.
f - pX1 * pX1)
267 : (1.
f - pX2 * pX2 > std::numeric_limits<float>::epsilon()) ? pX2 / std::sqrt(1.
f - pX2 * pX2)
269 const float maxL1(maxLongitudinalDisplacementX / dXdL1);
270 const float maxL2(maxLongitudinalDisplacementX / dXdL2);
272 if (rL1 < minL || rL1 > maxL1 || rL2 < minL || rL2 > maxL2)
279 if (!minPass && !maxPass)
289 pfoAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pPfo2,
PfoAssociation(vertexType1, vertexType2, particleLength2)));
290 pfoAssociationMatrix[pPfo2].insert(PfoAssociationMap::value_type(pPfo1,
PfoAssociation(vertexType2, vertexType1, particleLength1)));
301 PfoVector pfoVector1;
302 for (
const auto &mapEntry : pfoAssociationMatrix)
303 pfoVector1.push_back(mapEntry.first);
306 for (
const ParticleFlowObject *
const pPfo1 : pfoVector1)
310 const ParticleFlowObject *pBestPfoInner(
nullptr);
313 const ParticleFlowObject *pBestPfoOuter(
nullptr);
316 PfoVector pfoVector2;
317 for (
const auto &mapEntry : pfoAssociationMap)
318 pfoVector2.push_back(mapEntry.first);
321 for (
const ParticleFlowObject *
const pPfo2 : pfoVector2)
323 const PfoAssociation &pfoAssociation(pfoAssociationMap.at(pPfo2));
328 if (pfoAssociation.GetFigureOfMerit() > bestAssociationInner.
GetFigureOfMerit())
330 bestAssociationInner = pfoAssociation;
331 pBestPfoInner = pPfo2;
338 if (pfoAssociation.GetFigureOfMerit() > bestAssociationOuter.
GetFigureOfMerit())
340 bestAssociationOuter = pfoAssociation;
341 pBestPfoOuter = pPfo2;
347 (void)bestAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pBestPfoInner, bestAssociationInner));
350 (void)bestAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pBestPfoOuter, bestAssociationOuter));
355 PfoVector pfoVector3;
356 for (
const auto &mapEntry : bestAssociationMatrix)
357 pfoVector3.push_back(mapEntry.first);
360 for (
const ParticleFlowObject *
const pParentPfo : pfoVector3)
362 const PfoAssociationMap &parentAssociationMap(bestAssociationMatrix.at(pParentPfo));
364 PfoVector pfoVector4;
365 for (
const auto &mapEntry : parentAssociationMap)
366 pfoVector4.push_back(mapEntry.first);
369 for (
const ParticleFlowObject *
const pDaughterPfo : pfoVector4)
371 const PfoAssociation &parentToDaughterAssociation(parentAssociationMap.at(pDaughterPfo));
374 if (bestAssociationMatrix.end() == iter5)
380 if (daughterAssociationMap.end() == iter6)
385 if (parentToDaughterAssociation.GetParent() == daughterToParentAssociation.
GetDaughter() &&
386 parentToDaughterAssociation.GetDaughter() == daughterToParentAssociation.
GetParent())
388 pfoMatches[pParentPfo].push_back(pDaughterPfo);
400 PfoVector inputPfoVector;
401 for (
const auto &mapEntry : pfoMatches)
402 inputPfoVector.push_back(mapEntry.first);
405 for (
const ParticleFlowObject *
const pInputPfo : inputPfoVector)
407 const PfoList &pfoList(pfoMatches.at(pInputPfo));
409 for (
const ParticleFlowObject *
const pSeedPfo : pfoList)
411 if (vetoSet.count(pSeedPfo))
417 vetoSet.insert(pSeedPfo);
418 PfoList &selectedPfoList(pfoMerges[pSeedPfo]);
419 selectedPfoList.push_back(pSeedPfo);
421 for (
const ParticleFlowObject *
const pAssociatedPfo : mergeList)
424 if (vetoSet.count(pAssociatedPfo) || (selectedPfoList.end() != std::find(selectedPfoList.begin(), selectedPfoList.end(), pAssociatedPfo)))
425 throw StatusCodeException(STATUS_CODE_FAILURE);
427 vetoSet.insert(pAssociatedPfo);
428 selectedPfoList.push_back(pAssociatedPfo);
437 const ParticleFlowObject *
const pCurrentPfo,
const PfoMergeMap &pfoMergeMap,
const PfoSet &vetoSet, PfoList &associatedList)
const 439 if (vetoSet.count(pCurrentPfo))
444 if (pfoMergeMap.end() == iter1)
447 for (
PfoList::const_iterator iter2 = iter1->second.begin(), iterEnd2 = iter1->second.end(); iter2 != iterEnd2; ++iter2)
449 const ParticleFlowObject *
const pAssociatedPfo = *iter2;
451 if (pAssociatedPfo == pSeedPfo)
454 if (associatedList.end() != std::find(associatedList.begin(), associatedList.end(), pAssociatedPfo))
457 associatedList.push_back(pAssociatedPfo);
468 PfoVector inputPfoVector;
469 for (
const auto &mapEntry : inputPfoMerges)
470 inputPfoVector.push_back(mapEntry.first);
473 for (
const ParticleFlowObject *
const pInputPfo : inputPfoVector)
475 const PfoList &pfoList(inputPfoMerges.at(pInputPfo));
477 float bestLength(0.
f);
478 const ParticleFlowObject *pVertexPfo =
nullptr;
482 const ParticleFlowObject *
const pPfo1(*iter1);
486 if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
487 throw StatusCodeException(STATUS_CODE_FAILURE);
489 const LArTPC *
const pLArTPC1(tpcIter1->second);
494 const ParticleFlowObject *
const pPfo2(*iter2);
498 if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
499 throw StatusCodeException(STATUS_CODE_FAILURE);
501 const LArTPC *
const pLArTPC2(tpcIter2->second);
504 if (pLArTPC1 == pLArTPC2)
509 if (thisLength < bestLength)
512 bestLength = thisLength;
516 pVertexPfo =
nullptr;
525 const float deltaY(farVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
527 if (std::fabs(deltaY) < std::numeric_limits<float>::epsilon())
528 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
530 pVertexPfo = ((deltaY > 0.f) ? pPfo1 : pPfo2);
532 catch (
const pandora::StatusCodeException &)
539 outputPfoMerges[pVertexPfo].insert(outputPfoMerges[pVertexPfo].
begin(), pfoList.begin(), pfoList.end());
548 PfoVector pfoVectorToEnlarge;
549 for (
const auto &mapEntry : pfoMerges)
550 pfoVectorToEnlarge.push_back(mapEntry.first);
553 for (
const ParticleFlowObject *
const pPfoToEnlarge : pfoVectorToEnlarge)
555 const PfoList &pfoList(pfoMerges.at(pPfoToEnlarge));
556 const PfoVector pfoVector(pfoList.begin(), pfoList.end());
565 if (!this->
CalculateX0(pfoToLArTPCMap, pointingClusterMap, pfoVector, x0, pfoToPointingVertexMatrix))
568 catch (
const pandora::StatusCodeException &)
578 const ParticleFlowObject *
const pPfoI(*iterI);
579 const LArTPC *
const pLArTPCI(pfoToLArTPCMap.at(pPfoI));
583 const ParticleFlowObject *
const pPfoJ(*iterJ);
584 const LArTPC *
const pLArTPCJ(pfoToLArTPCMap.at(pPfoJ));
589 if (std::find(shiftedPfos.begin(), shiftedPfos.end(), pPfoI) == shiftedPfos.end())
592 this->
ShiftPfo(pAlgorithm, pPfoI, pPfoJ, x0, pfoToLArTPCMap, pfoToPointingVertexMatrix);
594 shiftedPfos.insert(pPfoI);
597 if (std::find(shiftedPfos.begin(), shiftedPfos.end(), pPfoJ) == shiftedPfos.end())
600 this->
ShiftPfo(pAlgorithm, pPfoJ, pPfoI, x0, pfoToLArTPCMap, pfoToPointingVertexMatrix);
602 shiftedPfos.insert(pPfoJ);
608 for (
const ParticleFlowObject *
const pPfoToDelete : shiftedPfos)
610 if (pPfoToDelete == pPfoToEnlarge)
613 pAlgorithm->
StitchPfos(pPfoToEnlarge, pPfoToDelete, pfoToLArTPCMap);
616 stitchedPfosToX0Map.insert(PfoToFloatMap::value_type(pPfoToEnlarge, x0));
623 const ParticleFlowObject *
const pMatchedPfo,
const float x0,
const PfoToLArTPCMap &pfoToLArTPCMap,
630 const LArTPC *
const pShiftLArTPC(pfoToLArTPCMap.at(pPfoToShift));
631 const LArTPC *
const pMatchedLArTPC(pfoToLArTPCMap.at(pMatchedPfo));
635 float tpcBoundaryX(0.
f);
637 if (pShiftLArTPC->GetCenterX() < tpcBoundaryCenterX)
639 tpcBoundaryX = pShiftLArTPC->GetCenterX() + (pShiftLArTPC->GetWidthX() / 2.f);
643 tpcBoundaryX = pShiftLArTPC->GetCenterX() - (pShiftLArTPC->GetWidthX() / 2.f);
646 const float positionShiftSign = stitchingVertex.GetPosition().GetX() < tpcBoundaryX ? 1.f : -1.f;
649 object_creation::ParticleFlowObject::Metadata metadata;
650 metadata.m_propertiesToAdd[
"X0"] = x0;
653 PfoList downstreamPfoList;
656 for (
const ParticleFlowObject *
const pHierarchyPfo : downstreamPfoList)
657 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pHierarchyPfo, metadata));
659 const float signedX0(std::fabs(x0) * positionShiftSign);
669 float sumX(0.
f), sumN(0.
f);
673 const ParticleFlowObject *
const pPfo1(*iter1);
677 if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
678 throw StatusCodeException(STATUS_CODE_FAILURE);
680 const LArTPC *
const pLArTPC1(tpcIter1->second);
685 const ParticleFlowObject *
const pPfo2(*iter2);
689 if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
690 throw StatusCodeException(STATUS_CODE_FAILURE);
692 const LArTPC *
const pLArTPC2(tpcIter2->second);
706 if (pfoToPointingVertexMatrixIter1 == pfoToPointingVertexMatrix.end())
710 (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo1, pfoToPointingVertexMap));
717 if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
719 (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo2, pointingVertex1));
723 if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex1.
GetPosition()).GetMagnitude() >
724 std::numeric_limits<float>::epsilon())
725 throw StatusCodeException(STATUS_CODE_FAILURE);
731 if (pfoToPointingVertexMatrixIter2 == pfoToPointingVertexMatrix.end())
735 (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo2, pfoToPointingVertexMap));
742 if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
744 (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo1, pointingVertex2));
748 if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex2.
GetPosition()).GetMagnitude() >
749 std::numeric_limits<float>::epsilon())
750 throw StatusCodeException(STATUS_CODE_FAILURE);
755 const bool isCPAStitch(pLArTPC1->GetCenterX() < tpcBoundaryCenterX ? !pLArTPC1->IsDriftInPositiveX() : !pLArTPC2->IsDriftInPositiveX());
758 thisX0 *= isCPAStitch ? -1.f : 1.f;
761 if ((sumN > std::numeric_limits<float>::epsilon()) && (sumX > std::numeric_limits<float>::epsilon()))
763 const float fractionalDiff(std::fabs((sumX - (thisX0 * sumN)) / sumX));
772 catch (
const pandora::StatusCodeException &statusCodeException)
774 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
775 std::cout <<
"StitchingCosmicRayMergingTool: Attempting to stitch a pfo with multiple vertices for the same match" << std::endl;
780 if ((sumN < std::numeric_limits<float>::epsilon()) || (std::fabs(sumX) < std::numeric_limits<float>::epsilon()))
781 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
793 m_daughter(daughter),
824 PANDORA_RETURN_RESULT_IF_AND_IF(
825 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ThreeDStitchingMode",
m_useXcoordinate));
827 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
830 PANDORA_RETURN_RESULT_IF_AND_IF(
831 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HalfWindowLayers",
m_halfWindowLayers));
834 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinPfoLength", minLength));
837 PANDORA_RETURN_RESULT_IF_AND_IF(
838 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCosRelativeAngle",
m_minCosRelativeAngle));
840 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
843 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
846 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
849 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
852 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
855 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinNCaloHits3D",
m_minNCaloHits3D));
857 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
860 PANDORA_RETURN_RESULT_IF_AND_IF(
861 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"BoundaryToleranceWidth",
m_boundaryToleranceWidth));
863 return STATUS_CODE_SUCCESS;
void SelectPrimaryPfos(const pandora::PfoList *pInputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, pandora::PfoList &outputPfoList) const
Select primary Pfos from the input list of Pfos.
std::unordered_map< const pandora::ParticleFlowObject *, PfoToPointingVertexMap > PfoToPointingVertexMatrix
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.
static float CalculateX0(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC, const LArPointingCluster::Vertex &firstVertex, const LArPointingCluster::Vertex &secondVertex)
Calculate X0 for a pair of vertices.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
PfoAssociation(const VertexType parent, const VertexType daughter, const float fom)
Constructor.
void CollectAssociatedPfos(const pandora::ParticleFlowObject *const pSeedPfo, const pandora::ParticleFlowObject *const pCurrentPfo, const PfoMergeMap &pfoMerges, const pandora::PfoSet &vetoSet, pandora::PfoList &associatedList) const
Collect up associations between Pfos.
unsigned int m_minNCaloHits3D
static void GetImpactParametersInYZ(const LArPointingCluster::Vertex &pointingVertex, const LArPointingCluster::Vertex &targetVertex, float &longitudinal, float &transverse)
Calculate impact parameters between a pair of pointing vertices using yz-coordinates.
static void GetImpactParameters(const LArPointingCluster::Vertex &pointingVertex, const LArPointingCluster::Vertex &targetVertex, float &longitudinal, float &transverse)
Calculate impact parameters between a pair of pointing vertices.
bool CalculateX0(const PfoToLArTPCMap &pfoToLArTPCMap, const ThreeDPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector, float &x0, PfoToPointingVertexMatrix &pfoToPointingVertexMatrix) const
Calculate x0 shift for a group of associated Pfos.
LArPointingCluster class.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
float m_relaxCosRelativeAngle
void CreatePfoMatches(const LArTPCToPfoMap &larTPCToPfoMap, const ThreeDPointingClusterMap &pointingClusterMap, PfoAssociationMatrix &pfoAssociationMatrix) const
Create associations between Pfos using 3D pointing clusters.
std::unordered_map< const pandora::ParticleFlowObject *, pandora::PfoList > PfoMergeMap
std::unordered_map< const pandora::ParticleFlowObject *, PfoAssociationMap > PfoAssociationMatrix
void BuildTPCMaps(const pandora::PfoList &inputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, LArTPCToPfoMap &larTPCToPfoMap) const
Build a list of Pfos for each tpc.
float m_boundaryToleranceWidth
The distance from the APA/CPA boundary inside which the deviation consideration is ignored...
VertexType
Vertex enumeration.
VertexType GetDaughter() const
Get daughter.
float m_relaxTransverseDisplacement
void OrderPfoMerges(const PfoToLArTPCMap &pfoToLArTPCMap, const ThreeDPointingClusterMap &pointingClusterMap, const PfoMergeMap &inputPfoMerges, PfoMergeMap &outputPfoMerges) const
Identify the vertex Pfo and then re-order the map of merges so that the vertex Pfo will be enlarged...
static bool IsInGap(const pandora::Pandora &pandora, const pandora::CartesianVector &testPoint2D, const pandora::HitType hitType, const float gapTolerance=0.f)
Whether a 2D test point lies in a registered gap with the associated hit type.
std::unordered_map< const pandora::ParticleFlowObject *, const pandora::LArTPC * > PfoToLArTPCMap
float m_maxX0FractionalDeviation
The maximum allowed fractional difference of an X0 contribution for matches to be stitched...
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
bool m_alwaysApplyT0Calculation
void ShiftPfo(const MasterAlgorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pPfoToShift, const pandora::ParticleFlowObject *const pMatchedPfo, const float x0, const PfoToLArTPCMap &pfoToLArTPCMap, const PfoToPointingVertexMatrix &pfoToPointingVertexMatrix) const
Shift a pfo given its pfo stitching pair.
Header file for the geometry helper class.
VertexType m_daughter
The daughter vertex type.
float m_minCosRelativeAngle
std::unordered_map< const pandora::ParticleFlowObject *, float > PfoToFloatMap
static bool CanTPCsBeStitched(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether particles from a given pair of tpcs can be stitched together.
const Vertex & GetOuterVertex() const
Get the outer vertex.
float m_maxTransverseDisplacement
static float GetTPCDisplacement(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Calculate distance between central positions of a pair of tpcs.
VertexType m_parent
The parent vertex type.
static float GetTPCBoundaryCenterX(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Determine centre in X at the boundary between a pair of tpcs.
const Vertex & GetInnerVertex() const
Get the inner vertex.
void ShiftPfoHierarchy(const pandora::ParticleFlowObject *const pParentPfo, const PfoToLArTPCMap &pfoToLArTPCMap, const float x0) const
Shift a Pfo hierarchy by a specified x0 value.
float m_fom
The figure of merit.
void StitchPfos(const pandora::ParticleFlowObject *const pPfoToEnlarge, const pandora::ParticleFlowObject *const pPfoToDelete, PfoToLArTPCMap &pfoToLArTPCMap) const
Stitch together a pair of pfos.
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
float GetLengthSquared() const
Get length squared of pointing cluster.
static float GetTPCBoundaryWidthX(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Determine width in X at the boundary between a pair of tpcs.
void StitchPfos(const MasterAlgorithm *const pAlgorithm, const ThreeDPointingClusterMap &pointingClusterMap, const PfoMergeMap &pfoMerges, PfoToLArTPCMap &pfoToLArTPCMap, PfoToFloatMap &stitchedPfosToX0Map) const
Apply X0 corrections, and then stitch together Pfos.
Header file for the lar three dimensional sliding fit result class.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
void BuildPointingClusterMaps(const pandora::PfoList &inputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, ThreeDPointingClusterMap &pointingClusterMap) const
Build a 3D pointing cluster for each Pfo.
Header file for the helper class for multiple drift volumes.
float m_maxLongitudinalDisplacementX
void SelectPfoMatches(const PfoAssociationMatrix &pfoAssociationMatrix, PfoMergeMap &pfoSelectedMatches) const
Select the best associations between Pfos; create a mapping between associated Pfos, handling any ambiguities.
std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster::Vertex > PfoToPointingVertexMap
static bool IsFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a primary parent particle.
std::unordered_map< const pandora::ParticleFlowObject *, PfoAssociation > PfoAssociationMap
ThreeDSlidingFitResult class.
float m_relaxMinLongitudinalDisplacement
The minimum value of the longitudinal impact parameter for association if both verticies fall in the ...
static void GetAllDownstreamPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively, of all daughters associated with those pfos in an input lis...
VertexType GetParent() const
Get parent.
void Run(const MasterAlgorithm *const pAlgorithm, const pandora::PfoList *const pMultiPfoList, PfoToLArTPCMap &pfoToLArTPCMap, PfoToFloatMap &stitchedPfosToX0Map)
Run the algorithm tool.
static bool SortTPCs(const pandora::LArTPC *const pLhs, const pandora::LArTPC *const pRhs)
Sort tpcs by central positions.
std::unordered_map< const pandora::LArTPC *, pandora::PfoList > LArTPCToPfoMap
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
bool IsInnerVertex() const
Is this the inner vertex.
float GetFigureOfMerit() const
Get figure of merit.
void SelectPfoMerges(const PfoMergeMap &pfoMatches, PfoMergeMap &pfoMerges) const
Create an initial map of Pfo merges to be made.
static void GetClosestVertices(const pandora::LArTPC &larTPC1, const pandora::LArTPC &larTPC2, const LArPointingCluster &pointingCluster1, const LArPointingCluster &pointingCluster2, LArPointingCluster::Vertex &closestVertex1, LArPointingCluster::Vertex &closestVertex2)
Given a pair of pointing clusters, find the pair of vertices with smallest yz-separation.
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.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster > ThreeDPointingClusterMap