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;
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 &)
263 const float dXdL1(
m_useXcoordinate ? pX1 : (1.
f - pX1 * pX1 > std::numeric_limits<float>::epsilon()) ? pX1 / std::sqrt(1.
f - pX1 * pX1) : minL);
264 const float dXdL2(
m_useXcoordinate ? pX2 : (1.
f - pX2 * pX2 > std::numeric_limits<float>::epsilon()) ? pX2 / std::sqrt(1.
f - pX2 * pX2) : minL);
265 const float maxL1(maxLongitudinalDisplacementX / dXdL1);
266 const float maxL2(maxLongitudinalDisplacementX / dXdL2);
268 if (rL1 < minL || rL1 > maxL1 || rL2 < minL || rL2 > maxL2)
275 if (!minPass && !maxPass)
285 pfoAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pPfo2,
PfoAssociation(vertexType1, vertexType2, particleLength2)));
286 pfoAssociationMatrix[pPfo2].insert(PfoAssociationMap::value_type(pPfo1,
PfoAssociation(vertexType2, vertexType1, particleLength1)));
297 PfoVector pfoVector1;
298 for (
const auto &mapEntry : pfoAssociationMatrix)
299 pfoVector1.push_back(mapEntry.first);
302 for (
const ParticleFlowObject *
const pPfo1 : pfoVector1)
306 const ParticleFlowObject *pBestPfoInner(
nullptr);
309 const ParticleFlowObject *pBestPfoOuter(
nullptr);
312 PfoVector pfoVector2;
313 for (
const auto &mapEntry : pfoAssociationMap)
314 pfoVector2.push_back(mapEntry.first);
317 for (
const ParticleFlowObject *
const pPfo2 : pfoVector2)
319 const PfoAssociation &pfoAssociation(pfoAssociationMap.at(pPfo2));
324 if (pfoAssociation.GetFigureOfMerit() > bestAssociationInner.
GetFigureOfMerit())
326 bestAssociationInner = pfoAssociation;
327 pBestPfoInner = pPfo2;
334 if (pfoAssociation.GetFigureOfMerit() > bestAssociationOuter.
GetFigureOfMerit())
336 bestAssociationOuter = pfoAssociation;
337 pBestPfoOuter = pPfo2;
343 (void)bestAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pBestPfoInner, bestAssociationInner));
346 (void)bestAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pBestPfoOuter, bestAssociationOuter));
351 PfoVector pfoVector3;
352 for (
const auto &mapEntry : bestAssociationMatrix)
353 pfoVector3.push_back(mapEntry.first);
356 for (
const ParticleFlowObject *
const pParentPfo : pfoVector3)
358 const PfoAssociationMap &parentAssociationMap(bestAssociationMatrix.at(pParentPfo));
360 PfoVector pfoVector4;
361 for (
const auto &mapEntry : parentAssociationMap)
362 pfoVector4.push_back(mapEntry.first);
365 for (
const ParticleFlowObject *
const pDaughterPfo : pfoVector4)
367 const PfoAssociation &parentToDaughterAssociation(parentAssociationMap.at(pDaughterPfo));
370 if (bestAssociationMatrix.end() == iter5)
376 if (daughterAssociationMap.end() == iter6)
381 if (parentToDaughterAssociation.GetParent() == daughterToParentAssociation.
GetDaughter() &&
382 parentToDaughterAssociation.GetDaughter() == daughterToParentAssociation.
GetParent())
384 pfoMatches[pParentPfo].push_back(pDaughterPfo);
396 PfoVector inputPfoVector;
397 for (
const auto &mapEntry : pfoMatches)
398 inputPfoVector.push_back(mapEntry.first);
401 for (
const ParticleFlowObject *
const pInputPfo : inputPfoVector)
403 const PfoList &pfoList(pfoMatches.at(pInputPfo));
405 for (
const ParticleFlowObject *
const pSeedPfo : pfoList)
407 if (vetoSet.count(pSeedPfo))
413 vetoSet.insert(pSeedPfo);
414 PfoList &selectedPfoList(pfoMerges[pSeedPfo]);
415 selectedPfoList.push_back(pSeedPfo);
417 for (
const ParticleFlowObject *
const pAssociatedPfo : mergeList)
420 if (vetoSet.count(pAssociatedPfo) || (selectedPfoList.end() != std::find(selectedPfoList.begin(), selectedPfoList.end(), pAssociatedPfo)))
421 throw StatusCodeException(STATUS_CODE_FAILURE);
423 vetoSet.insert(pAssociatedPfo);
424 selectedPfoList.push_back(pAssociatedPfo);
433 const ParticleFlowObject *
const pCurrentPfo,
const PfoMergeMap &pfoMergeMap,
const PfoSet &vetoSet, PfoList &associatedList)
const 435 if (vetoSet.count(pCurrentPfo))
440 if (pfoMergeMap.end() == iter1)
443 for (
PfoList::const_iterator iter2 = iter1->second.begin(), iterEnd2 = iter1->second.end(); iter2 != iterEnd2; ++iter2)
445 const ParticleFlowObject *
const pAssociatedPfo = *iter2;
447 if (pAssociatedPfo == pSeedPfo)
450 if (associatedList.end() != std::find(associatedList.begin(), associatedList.end(), pAssociatedPfo))
453 associatedList.push_back(pAssociatedPfo);
464 PfoVector inputPfoVector;
465 for (
const auto &mapEntry : inputPfoMerges)
466 inputPfoVector.push_back(mapEntry.first);
469 for (
const ParticleFlowObject *
const pInputPfo : inputPfoVector)
471 const PfoList &pfoList(inputPfoMerges.at(pInputPfo));
473 float bestLength(0.
f);
474 const ParticleFlowObject *pVertexPfo =
nullptr;
478 const ParticleFlowObject *
const pPfo1(*iter1);
482 if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
483 throw StatusCodeException(STATUS_CODE_FAILURE);
485 const LArTPC *
const pLArTPC1(tpcIter1->second);
490 const ParticleFlowObject *
const pPfo2(*iter2);
494 if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
495 throw StatusCodeException(STATUS_CODE_FAILURE);
497 const LArTPC *
const pLArTPC2(tpcIter2->second);
500 if (pLArTPC1 == pLArTPC2)
505 if (thisLength < bestLength)
508 bestLength = thisLength;
512 pVertexPfo =
nullptr;
521 const float deltaY(farVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
523 if (std::fabs(deltaY) < std::numeric_limits<float>::epsilon())
524 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
526 pVertexPfo = ((deltaY > 0.f) ? pPfo1 : pPfo2);
528 catch (
const pandora::StatusCodeException &)
535 outputPfoMerges[pVertexPfo].insert(outputPfoMerges[pVertexPfo].
begin(), pfoList.begin(), pfoList.end());
544 PfoVector pfoVectorToEnlarge;
545 for (
const auto &mapEntry : pfoMerges)
546 pfoVectorToEnlarge.push_back(mapEntry.first);
549 for (
const ParticleFlowObject *
const pPfoToEnlarge : pfoVectorToEnlarge)
551 const PfoList &pfoList(pfoMerges.at(pPfoToEnlarge));
552 const PfoVector pfoVector(pfoList.begin(), pfoList.end());
561 if (!this->
CalculateX0(pfoToLArTPCMap, pointingClusterMap, pfoVector, x0, pfoToPointingVertexMatrix))
564 catch (
const pandora::StatusCodeException &)
574 const ParticleFlowObject *
const pPfoI(*iterI);
575 const LArTPC *
const pLArTPCI(pfoToLArTPCMap.at(pPfoI));
579 const ParticleFlowObject *
const pPfoJ(*iterJ);
580 const LArTPC *
const pLArTPCJ(pfoToLArTPCMap.at(pPfoJ));
585 if (std::find(shiftedPfos.begin(), shiftedPfos.end(), pPfoI) == shiftedPfos.end())
588 this->
ShiftPfo(pAlgorithm, pPfoI, pPfoJ, x0, pfoToLArTPCMap, pfoToPointingVertexMatrix);
590 shiftedPfos.insert(pPfoI);
593 if (std::find(shiftedPfos.begin(), shiftedPfos.end(), pPfoJ) == shiftedPfos.end())
596 this->
ShiftPfo(pAlgorithm, pPfoJ, pPfoI, x0, pfoToLArTPCMap, pfoToPointingVertexMatrix);
598 shiftedPfos.insert(pPfoJ);
604 for (
const ParticleFlowObject *
const pPfoToDelete : shiftedPfos)
606 if (pPfoToDelete == pPfoToEnlarge)
609 pAlgorithm->
StitchPfos(pPfoToEnlarge, pPfoToDelete, pfoToLArTPCMap);
612 stitchedPfosToX0Map.insert(PfoToFloatMap::value_type(pPfoToEnlarge, x0));
619 const ParticleFlowObject *
const pMatchedPfo,
const float x0,
const PfoToLArTPCMap &pfoToLArTPCMap,
626 const LArTPC *
const pShiftLArTPC(pfoToLArTPCMap.at(pPfoToShift));
627 const LArTPC *
const pMatchedLArTPC(pfoToLArTPCMap.at(pMatchedPfo));
631 float tpcBoundaryX(0.
f);
633 if (pShiftLArTPC->GetCenterX() < tpcBoundaryCenterX)
635 tpcBoundaryX = pShiftLArTPC->GetCenterX() + (pShiftLArTPC->GetWidthX() / 2.f);
639 tpcBoundaryX = pShiftLArTPC->GetCenterX() - (pShiftLArTPC->GetWidthX() / 2.f);
642 const float positionShiftSign = stitchingVertex.GetPosition().GetX() < tpcBoundaryX ? 1.f : -1.f;
645 object_creation::ParticleFlowObject::Metadata
metadata;
646 metadata.m_propertiesToAdd[
"X0"] = x0;
649 PfoList downstreamPfoList;
652 for (
const ParticleFlowObject *
const pHierarchyPfo : downstreamPfoList)
653 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pHierarchyPfo, metadata));
655 const float signedX0(std::fabs(x0) * positionShiftSign);
665 float sumX(0.
f), sumN(0.
f);
669 const ParticleFlowObject *
const pPfo1(*iter1);
673 if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
674 throw StatusCodeException(STATUS_CODE_FAILURE);
676 const LArTPC *
const pLArTPC1(tpcIter1->second);
681 const ParticleFlowObject *
const pPfo2(*iter2);
685 if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
686 throw StatusCodeException(STATUS_CODE_FAILURE);
688 const LArTPC *
const pLArTPC2(tpcIter2->second);
702 if (pfoToPointingVertexMatrixIter1 == pfoToPointingVertexMatrix.end())
706 (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo1, pfoToPointingVertexMap));
713 if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
715 (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo2, pointingVertex1));
719 if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex1.
GetPosition()).GetMagnitude() >
720 std::numeric_limits<float>::epsilon())
721 throw StatusCodeException(STATUS_CODE_FAILURE);
727 if (pfoToPointingVertexMatrixIter2 == pfoToPointingVertexMatrix.end())
731 (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo2, pfoToPointingVertexMap));
738 if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
740 (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo1, pointingVertex2));
744 if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex2.
GetPosition()).GetMagnitude() >
745 std::numeric_limits<float>::epsilon())
746 throw StatusCodeException(STATUS_CODE_FAILURE);
751 const bool isCPAStitch(pLArTPC1->GetCenterX() < tpcBoundaryCenterX ? !pLArTPC1->IsDriftInPositiveX() : !pLArTPC2->IsDriftInPositiveX());
754 thisX0 *= isCPAStitch ? -1.f : 1.f;
757 if ((sumN > std::numeric_limits<float>::epsilon()) && (sumX > std::numeric_limits<float>::epsilon()))
759 const float fractionalDiff(std::fabs((sumX - (thisX0 * sumN)) / sumX));
768 catch (
const pandora::StatusCodeException &statusCodeException)
770 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
771 std::cout <<
"StitchingCosmicRayMergingTool: Attempting to stitch a pfo with multiple vertices for the same match" <<
std::endl;
776 if ((sumN < std::numeric_limits<float>::epsilon()) || (std::fabs(sumX) < std::numeric_limits<float>::epsilon()))
777 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
789 m_daughter(daughter),
820 PANDORA_RETURN_RESULT_IF_AND_IF(
821 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ThreeDStitchingMode",
m_useXcoordinate));
823 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
826 PANDORA_RETURN_RESULT_IF_AND_IF(
827 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HalfWindowLayers",
m_halfWindowLayers));
830 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinPfoLength", minLength));
833 PANDORA_RETURN_RESULT_IF_AND_IF(
834 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCosRelativeAngle",
m_minCosRelativeAngle));
836 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
839 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
842 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
845 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
848 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
851 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinNCaloHits3D",
m_minNCaloHits3D));
853 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
856 PANDORA_RETURN_RESULT_IF_AND_IF(
857 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"BoundaryToleranceWidth",
m_boundaryToleranceWidth));
859 return STATUS_CODE_SUCCESS;
std::unordered_map< const pandora::ParticleFlowObject *, float > PfoToFloatMap
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.
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
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.
static int max(int a, int b)
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.
std::unordered_map< const pandora::ParticleFlowObject *, const pandora::LArTPC * > PfoToLArTPCMap
Header file for the helper class for multiple drift volumes.
float m_maxLongitudinalDisplacementX
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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.
def parent(G, child, parent_type)
QTextStream & endl(QTextStream &s)
std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster > ThreeDPointingClusterMap
GeomAnalyzerI * GetGeometry(void)