LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
lar_content::StitchingCosmicRayMergingTool Class Reference

StitchingCosmicRayMergingTool class. More...

#include "StitchingCosmicRayMergingTool.h"

Inheritance diagram for lar_content::StitchingCosmicRayMergingTool:
lar_content::StitchingBaseTool

Classes

class  PfoAssociation
 PfoAssociation class. More...
 

Public Member Functions

 StitchingCosmicRayMergingTool ()
 Default constructor. More...
 
void Run (const MasterAlgorithm *const pAlgorithm, const pandora::PfoList *const pMultiPfoList, PfoToLArTPCMap &pfoToLArTPCMap, PfoToFloatMap &stitchedPfosToX0Map)
 Run the algorithm tool. More...
 

Private Types

typedef std::unordered_map< const pandora::ParticleFlowObject *, LArPointingClusterThreeDPointingClusterMap
 
typedef std::unordered_map< const pandora::LArTPC *, pandora::PfoList > LArTPCToPfoMap
 
typedef std::unordered_map< const pandora::ParticleFlowObject *, PfoAssociationPfoAssociationMap
 
typedef std::unordered_map< const pandora::ParticleFlowObject *, PfoAssociationMapPfoAssociationMatrix
 
typedef std::unordered_map< const pandora::ParticleFlowObject *, pandora::PfoList > PfoMergeMap
 
typedef std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster::VertexPfoToPointingVertexMap
 
typedef std::unordered_map< const pandora::ParticleFlowObject *, PfoToPointingVertexMapPfoToPointingVertexMatrix
 

Private Member Functions

pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
void SelectPrimaryPfos (const pandora::PfoList *pInputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, pandora::PfoList &outputPfoList) const
 Select primary Pfos from the input list of Pfos. More...
 
void BuildPointingClusterMaps (const pandora::PfoList &inputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, ThreeDPointingClusterMap &pointingClusterMap) const
 Build a 3D pointing cluster for each Pfo. More...
 
void BuildTPCMaps (const pandora::PfoList &inputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, LArTPCToPfoMap &larTPCToPfoMap) const
 Build a list of Pfos for each tpc. More...
 
void CreatePfoMatches (const LArTPCToPfoMap &larTPCToPfoMap, const ThreeDPointingClusterMap &pointingClusterMap, PfoAssociationMatrix &pfoAssociationMatrix) const
 Create associations between Pfos using 3D pointing clusters. More...
 
void CreatePfoMatches (const pandora::LArTPC &larTPC1, const pandora::LArTPC &larTPC2, const pandora::ParticleFlowObject *const pPfo1, const pandora::ParticleFlowObject *const pPfo2, const ThreeDPointingClusterMap &pointingClusterMap, PfoAssociationMatrix &pfoAssociationMatrix) const
 Create associations between Pfos using 3D pointing clusters. More...
 
void SelectPfoMatches (const PfoAssociationMatrix &pfoAssociationMatrix, PfoMergeMap &pfoSelectedMatches) const
 Select the best associations between Pfos; create a mapping between associated Pfos, handling any ambiguities. More...
 
void SelectPfoMerges (const PfoMergeMap &pfoMatches, PfoMergeMap &pfoMerges) const
 Create an initial map of Pfo merges to be made. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 

Private Attributes

bool m_useXcoordinate
 
bool m_alwaysApplyT0Calculation
 
int m_halfWindowLayers
 
float m_minLengthSquared
 
float m_minCosRelativeAngle
 
float m_relaxMinLongitudinalDisplacement
 The minimum value of the longitudinal impact parameter for association if both verticies fall in the detector gap. More...
 
float m_maxLongitudinalDisplacementX
 
float m_maxTransverseDisplacement
 
float m_relaxCosRelativeAngle
 
float m_relaxTransverseDisplacement
 
unsigned int m_minNCaloHits3D
 
float m_maxX0FractionalDeviation
 The maximum allowed fractional difference of an X0 contribution for matches to be stitched. More...
 
float m_boundaryToleranceWidth
 The distance from the APA/CPA boundary inside which the deviation consideration is ignored. More...
 

Detailed Description

Member Typedef Documentation

typedef std::unordered_map<const pandora::LArTPC *, pandora::PfoList> lar_content::StitchingCosmicRayMergingTool::LArTPCToPfoMap
private

Definition at line 111 of file StitchingCosmicRayMergingTool.h.

typedef std::unordered_map<const pandora::ParticleFlowObject *, PfoAssociation> lar_content::StitchingCosmicRayMergingTool::PfoAssociationMap
private

Definition at line 122 of file StitchingCosmicRayMergingTool.h.

typedef std::unordered_map<const pandora::ParticleFlowObject *, PfoAssociationMap> lar_content::StitchingCosmicRayMergingTool::PfoAssociationMatrix
private

Definition at line 123 of file StitchingCosmicRayMergingTool.h.

typedef std::unordered_map<const pandora::ParticleFlowObject *, pandora::PfoList> lar_content::StitchingCosmicRayMergingTool::PfoMergeMap
private

Definition at line 149 of file StitchingCosmicRayMergingTool.h.

typedef std::unordered_map<const pandora::ParticleFlowObject *, LArPointingCluster::Vertex> lar_content::StitchingCosmicRayMergingTool::PfoToPointingVertexMap
private

Definition at line 202 of file StitchingCosmicRayMergingTool.h.

typedef std::unordered_map<const pandora::ParticleFlowObject *, PfoToPointingVertexMap> lar_content::StitchingCosmicRayMergingTool::PfoToPointingVertexMatrix
private

Definition at line 203 of file StitchingCosmicRayMergingTool.h.

typedef std::unordered_map<const pandora::ParticleFlowObject *, LArPointingCluster> lar_content::StitchingCosmicRayMergingTool::ThreeDPointingClusterMap
private

Definition at line 99 of file StitchingCosmicRayMergingTool.h.

Constructor & Destructor Documentation

lar_content::StitchingCosmicRayMergingTool::StitchingCosmicRayMergingTool ( )

Default constructor.

Definition at line 25 of file StitchingCosmicRayMergingTool.cc.

25  :
26  m_useXcoordinate(false),
30  m_minCosRelativeAngle(0.966),
39 {
40 }
float m_boundaryToleranceWidth
The distance from the APA/CPA boundary inside which the deviation consideration is ignored...
TFile f
Definition: plotHisto.C:6
float m_maxX0FractionalDeviation
The maximum allowed fractional difference of an X0 contribution for matches to be stitched...
float m_relaxMinLongitudinalDisplacement
The minimum value of the longitudinal impact parameter for association if both verticies fall in the ...

Member Function Documentation

void lar_content::StitchingCosmicRayMergingTool::BuildPointingClusterMaps ( const pandora::PfoList &  inputPfoList,
const PfoToLArTPCMap pfoToLArTPCMap,
ThreeDPointingClusterMap pointingClusterMap 
) const
private

Build a 3D pointing cluster for each Pfo.

Parameters
inputPfoListthe input list of Pfos
pfoToLArTPCMapthe input mapping between Pfos and tpc
pointingClusterMapthe mapping between Pfos and their corresponding 3D pointing clusters

Definition at line 98 of file StitchingCosmicRayMergingTool.cc.

References lar_content::LArPfoHelper::GetThreeDClusterList(), and m_halfWindowLayers.

Referenced by Run().

100 {
101  for (const ParticleFlowObject *const pPfo : inputPfoList)
102  {
103  try
104  {
105  PfoToLArTPCMap::const_iterator tpcIter(pfoToLArTPCMap.find(pPfo));
106 
107  if (pfoToLArTPCMap.end() == tpcIter)
108  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
109 
110  const float slidingFitPitch(tpcIter->second->GetWirePitchW());
111 
112  ClusterList clusterList;
113  LArPfoHelper::GetThreeDClusterList(pPfo, clusterList);
114 
115  if (1 != clusterList.size())
116  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
117 
118  const ThreeDSlidingFitResult slidingFitResult(clusterList.front(), m_halfWindowLayers, slidingFitPitch);
119  (void)pointingClusterMap.insert(ThreeDPointingClusterMap::value_type(pPfo, LArPointingCluster(slidingFitResult)));
120  }
121  catch (const StatusCodeException &)
122  {
123  }
124  }
125 }
intermediate_table::const_iterator const_iterator
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
void lar_content::StitchingCosmicRayMergingTool::BuildTPCMaps ( const pandora::PfoList &  inputPfoList,
const PfoToLArTPCMap pfoToLArTPCMap,
LArTPCToPfoMap larTPCToPfoMap 
) const
private

Build a list of Pfos for each tpc.

Parameters
inputPfoListthe input list of Pfos
pfoToLArTPCMapthe input mapping between Pfos and tpc
larTPCToPfoMapthe output mapping between tpc and Pfos

Definition at line 129 of file StitchingCosmicRayMergingTool.cc.

Referenced by Run().

130 {
131  for (const ParticleFlowObject *const pPfo : inputPfoList)
132  {
133  PfoToLArTPCMap::const_iterator iter(pfoToLArTPCMap.find(pPfo));
134 
135  if (pfoToLArTPCMap.end() != iter)
136  larTPCToPfoMap[iter->second].push_back(pPfo);
137  }
138 }
intermediate_table::const_iterator const_iterator
bool lar_content::StitchingCosmicRayMergingTool::CalculateX0 ( const PfoToLArTPCMap pfoToLArTPCMap,
const ThreeDPointingClusterMap pointingClusterMap,
const pandora::PfoVector &  pfoVector,
float &  x0,
PfoToPointingVertexMatrix pfoToPointingVertexMatrix 
) const
private

Calculate x0 shift for a group of associated Pfos.

Parameters
pfoToLArTPCMapthe mapping between pfos and tpc
pointingClusterMapthe mapping between Pfos and their corresponding 3D pointing clusters
pfoVectorthe vector of parent Pfos to stitch together
x0the output x0 value
pfoToPointingVertexMatrixmap of pfo to a map of matched pfo and the corresponding pointing vertex used in stitching
Returns
bool true if all x0 contributions were consistent, false otherwise

Definition at line 666 of file StitchingCosmicRayMergingTool.cc.

References lar_content::LArStitchingHelper::CalculateX0(), lar_content::LArStitchingHelper::CanTPCsBeStitched(), f, lar_content::LArStitchingHelper::GetClosestVertices(), lar_content::LArPointingCluster::Vertex::GetPosition(), lar_content::LArStitchingHelper::GetTPCBoundaryCenterX(), m_boundaryToleranceWidth, and m_maxX0FractionalDeviation.

Referenced by StitchPfos().

668 {
669  float sumX(0.f), sumN(0.f);
670 
671  for (PfoVector::const_iterator iter1 = pfoVector.begin(), iterEnd = pfoVector.end(); iter1 != iterEnd; ++iter1)
672  {
673  const ParticleFlowObject *const pPfo1(*iter1);
674  PfoToLArTPCMap::const_iterator tpcIter1 = pfoToLArTPCMap.find(pPfo1);
675  ThreeDPointingClusterMap::const_iterator pointingIter1 = pointingClusterMap.find(pPfo1);
676 
677  if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
678  throw StatusCodeException(STATUS_CODE_FAILURE);
679 
680  const LArTPC *const pLArTPC1(tpcIter1->second);
681  const LArPointingCluster &pointingCluster1(pointingIter1->second);
682 
683  for (PfoVector::const_iterator iter2 = std::next(iter1); iter2 != iterEnd; ++iter2)
684  {
685  const ParticleFlowObject *const pPfo2(*iter2);
686  PfoToLArTPCMap::const_iterator tpcIter2 = pfoToLArTPCMap.find(pPfo2);
687  ThreeDPointingClusterMap::const_iterator pointingIter2 = pointingClusterMap.find(pPfo2);
688 
689  if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
690  throw StatusCodeException(STATUS_CODE_FAILURE);
691 
692  const LArTPC *const pLArTPC2(tpcIter2->second);
693  const LArPointingCluster &pointingCluster2(pointingIter2->second);
694 
695  if (!LArStitchingHelper::CanTPCsBeStitched(*pLArTPC1, *pLArTPC2))
696  continue;
697 
698  // Calculate X0 for the closest pair of vertices
699  LArPointingCluster::Vertex pointingVertex1, pointingVertex2;
700  try
701  {
702  LArStitchingHelper::GetClosestVertices(*pLArTPC1, *pLArTPC2, pointingCluster1, pointingCluster2, pointingVertex1, pointingVertex2);
703 
704  // Record pfo1 stitching vertex for pfo1<->pfo2 match, used to determine shifting direction in later step
705  const PfoToPointingVertexMatrix::iterator pfoToPointingVertexMatrixIter1(pfoToPointingVertexMatrix.find(pPfo1));
706  if (pfoToPointingVertexMatrixIter1 == pfoToPointingVertexMatrix.end())
707  {
708  // No matches present in map, add pfo1<->pfo2 match
709  const PfoToPointingVertexMap pfoToPointingVertexMap({{pPfo2, pointingVertex1}});
710  (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo1, pfoToPointingVertexMap));
711  }
712  else
713  {
714  // ATTN: another match for a different TPC boundary may be present, add pfo1<->pfo2 match
715  PfoToPointingVertexMap &pfoToPointingVertexMap(pfoToPointingVertexMatrixIter1->second);
716  const PfoToPointingVertexMap::iterator pfoToPointingVertexMapIter(pfoToPointingVertexMap.find(pPfo2));
717  if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
718  {
719  (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo2, pointingVertex1));
720  }
721  else
722  {
723  if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex1.GetPosition()).GetMagnitude() >
724  std::numeric_limits<float>::epsilon())
725  throw StatusCodeException(STATUS_CODE_FAILURE);
726  }
727  }
728 
729  // Record pfo2 stitching vertex for pfo1<->pfo2 match, used to determine shifting direction in later step
730  const PfoToPointingVertexMatrix::iterator pfoToPointingVertexMatrixIter2(pfoToPointingVertexMatrix.find(pPfo2));
731  if (pfoToPointingVertexMatrixIter2 == pfoToPointingVertexMatrix.end())
732  {
733  // No matches present in map, add pfo1<->pfo2 match
734  const PfoToPointingVertexMap pfoToPointingVertexMap({{pPfo1, pointingVertex2}});
735  (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo2, pfoToPointingVertexMap));
736  }
737  else
738  {
739  // ATTN: another match for a different TPC boundary may be present, add pfo1<->pfo2 match
740  PfoToPointingVertexMap &pfoToPointingVertexMap(pfoToPointingVertexMatrixIter2->second);
741  const PfoToPointingVertexMap::iterator pfoToPointingVertexMapIter(pfoToPointingVertexMap.find(pPfo1));
742  if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
743  {
744  (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo1, pointingVertex2));
745  }
746  else
747  {
748  if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex2.GetPosition()).GetMagnitude() >
749  std::numeric_limits<float>::epsilon())
750  throw StatusCodeException(STATUS_CODE_FAILURE);
751  }
752  }
753 
754  const float tpcBoundaryCenterX(LArStitchingHelper::GetTPCBoundaryCenterX(*pLArTPC1, *pLArTPC2));
755  const bool isCPAStitch(pLArTPC1->GetCenterX() < tpcBoundaryCenterX ? !pLArTPC1->IsDriftInPositiveX() : !pLArTPC2->IsDriftInPositiveX());
756  float thisX0(LArStitchingHelper::CalculateX0(*pLArTPC1, *pLArTPC2, pointingVertex1, pointingVertex2));
757 
758  thisX0 *= isCPAStitch ? -1.f : 1.f;
759 
760  // If multiple boundaries identified, check if stitching contribution is consistent
761  if ((sumN > std::numeric_limits<float>::epsilon()) && (sumX > std::numeric_limits<float>::epsilon()))
762  {
763  const float fractionalDiff(std::fabs((sumX - (thisX0 * sumN)) / sumX));
764 
765  if ((fractionalDiff > m_maxX0FractionalDeviation) && (std::fabs(sumX / sumN) > m_boundaryToleranceWidth))
766  return false;
767  }
768 
769  sumX += thisX0;
770  sumN += 1.f;
771  }
772  catch (const pandora::StatusCodeException &statusCodeException)
773  {
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;
776  }
777  }
778  }
779 
780  if ((sumN < std::numeric_limits<float>::epsilon()) || (std::fabs(sumX) < std::numeric_limits<float>::epsilon()))
781  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
782 
783  x0 = (sumX / sumN);
784 
785  return true;
786 }
intermediate_table::iterator iterator
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.
intermediate_table::const_iterator const_iterator
float m_boundaryToleranceWidth
The distance from the APA/CPA boundary inside which the deviation consideration is ignored...
TFile f
Definition: plotHisto.C:6
float m_maxX0FractionalDeviation
The maximum allowed fractional difference of an X0 contribution for matches to be stitched...
static bool CanTPCsBeStitched(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether particles from a given pair of tpcs can be stitched together.
static float GetTPCBoundaryCenterX(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Determine centre in X at the boundary between a pair of tpcs.
std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster::Vertex > PfoToPointingVertexMap
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
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.
void lar_content::StitchingCosmicRayMergingTool::CollectAssociatedPfos ( const pandora::ParticleFlowObject *const  pSeedPfo,
const pandora::ParticleFlowObject *const  pCurrentPfo,
const PfoMergeMap pfoMerges,
const pandora::PfoSet &  vetoSet,
pandora::PfoList &  associatedList 
) const
private

Collect up associations between Pfos.

Parameters
pSeedPfothe seed Pfo (will be enlarged after merging)
pCurrentPfothe target Pfo (will be deleted after merging)
pfoMergesthe list of associations between Pfos
vetoSetthe set of associated Pfos that have already been considered
associatedListthe output list of associated Pfos

Definition at line 436 of file StitchingCosmicRayMergingTool.cc.

Referenced by SelectPfoMerges().

438 {
439  if (vetoSet.count(pCurrentPfo))
440  return;
441 
442  PfoMergeMap::const_iterator iter1 = pfoMergeMap.find(pCurrentPfo);
443 
444  if (pfoMergeMap.end() == iter1)
445  return;
446 
447  for (PfoList::const_iterator iter2 = iter1->second.begin(), iterEnd2 = iter1->second.end(); iter2 != iterEnd2; ++iter2)
448  {
449  const ParticleFlowObject *const pAssociatedPfo = *iter2;
450 
451  if (pAssociatedPfo == pSeedPfo)
452  continue;
453 
454  if (associatedList.end() != std::find(associatedList.begin(), associatedList.end(), pAssociatedPfo))
455  continue;
456 
457  associatedList.push_back(pAssociatedPfo);
458 
459  this->CollectAssociatedPfos(pSeedPfo, pAssociatedPfo, pfoMergeMap, vetoSet, associatedList);
460  }
461 }
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.
intermediate_table::const_iterator const_iterator
void lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches ( const LArTPCToPfoMap larTPCToPfoMap,
const ThreeDPointingClusterMap pointingClusterMap,
PfoAssociationMatrix pfoAssociationMatrix 
) const
private

Create associations between Pfos using 3D pointing clusters.

Parameters
larTPCToPfoMapthe input mapping between tpc and Pfos
pointingClusterMapthe input mapping between Pfos and their corresponding 3D pointing clusters
pfoAssociationMatrixthe output matrix of associations between Pfos

Definition at line 142 of file StitchingCosmicRayMergingTool.cc.

References lar_content::LArStitchingHelper::CanTPCsBeStitched(), f, lar_content::LArPfoHelper::GetCaloHits(), lar_content::LArStitchingHelper::GetClosestVertices(), lar_content::LArPointingCluster::Vertex::GetDirection(), lar_content::LArPointingClusterHelper::GetImpactParameters(), lar_content::LArPointingClusterHelper::GetImpactParametersInYZ(), lar_content::LArPointingCluster::GetLengthSquared(), lar_content::LArPointingCluster::Vertex::GetPosition(), lar_content::LArStitchingHelper::GetTPCBoundaryCenterX(), lar_content::LArStitchingHelper::GetTPCBoundaryWidthX(), lar_content::StitchingCosmicRayMergingTool::PfoAssociation::INNER, lar_content::LArGeometryHelper::IsInGap(), lar_content::LArPointingCluster::Vertex::IsInnerVertex(), m_maxLongitudinalDisplacementX, m_maxTransverseDisplacement, m_minCosRelativeAngle, m_minLengthSquared, m_minNCaloHits3D, m_relaxCosRelativeAngle, m_relaxMinLongitudinalDisplacement, m_relaxTransverseDisplacement, m_useXcoordinate, lar_content::StitchingCosmicRayMergingTool::PfoAssociation::OUTER, and lar_content::LArStitchingHelper::SortTPCs().

Referenced by Run().

144 {
145  LArTPCVector larTPCVector;
146  for (const auto &mapEntry : larTPCToPfoMap)
147  larTPCVector.push_back(mapEntry.first);
148  std::sort(larTPCVector.begin(), larTPCVector.end(), LArStitchingHelper::SortTPCs);
149 
150  for (LArTPCVector::const_iterator tpcIter1 = larTPCVector.begin(), tpcIterEnd = larTPCVector.end(); tpcIter1 != tpcIterEnd; ++tpcIter1)
151  {
152  const LArTPC *const pLArTPC1(*tpcIter1);
153  const PfoList &pfoList1(larTPCToPfoMap.at(pLArTPC1));
154 
155  for (LArTPCVector::const_iterator tpcIter2 = tpcIter1; tpcIter2 != tpcIterEnd; ++tpcIter2)
156  {
157  const LArTPC *const pLArTPC2(*tpcIter2);
158  const PfoList &pfoList2(larTPCToPfoMap.at(pLArTPC2));
159 
160  if (!LArStitchingHelper::CanTPCsBeStitched(*pLArTPC1, *pLArTPC2))
161  continue;
162 
163  for (const ParticleFlowObject *const pPfo1 : pfoList1)
164  {
165  for (const ParticleFlowObject *const pPfo2 : pfoList2)
166  this->CreatePfoMatches(*pLArTPC1, *pLArTPC2, pPfo1, pPfo2, pointingClusterMap, pfoAssociationMatrix);
167  }
168  }
169  }
170 }
intermediate_table::const_iterator const_iterator
void CreatePfoMatches(const LArTPCToPfoMap &larTPCToPfoMap, const ThreeDPointingClusterMap &pointingClusterMap, PfoAssociationMatrix &pfoAssociationMatrix) const
Create associations between Pfos using 3D pointing clusters.
static bool CanTPCsBeStitched(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether particles from a given pair of tpcs can be stitched together.
static bool SortTPCs(const pandora::LArTPC *const pLhs, const pandora::LArTPC *const pRhs)
Sort tpcs by central positions.
void lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches ( const pandora::LArTPC &  larTPC1,
const pandora::LArTPC &  larTPC2,
const pandora::ParticleFlowObject *const  pPfo1,
const pandora::ParticleFlowObject *const  pPfo2,
const ThreeDPointingClusterMap pointingClusterMap,
PfoAssociationMatrix pfoAssociationMatrix 
) const
private

Create associations between Pfos using 3D pointing clusters.

Parameters
larTPC1the tpc description for the first Pfo
larTPC2the tpc description for the second Pfo
pPfo1the first Pfo
pPfo2the second Pfo
pointingClusterMapthe input mapping between Pfos and their corresponding 3D pointing clusters
pfoAssociationMatrixthe output matrix of associations between Pfos
void lar_content::StitchingCosmicRayMergingTool::OrderPfoMerges ( const PfoToLArTPCMap pfoToLArTPCMap,
const ThreeDPointingClusterMap pointingClusterMap,
const PfoMergeMap inputPfoMerges,
PfoMergeMap outputPfoMerges 
) const
private

Identify the vertex Pfo and then re-order the map of merges so that the vertex Pfo will be enlarged.

Parameters
pfoToLArTPCMapthe mapping between pfos and tpc
pointingClusterMapthe mapping between Pfos and their corresponding 3D pointing clusters
inputPfoMergesthe input map of Pfo merges
outputPfoMergesthe re-ordered map of Pfo merges

Definition at line 465 of file StitchingCosmicRayMergingTool.cc.

References util::begin(), f, lar_content::LArStitchingHelper::GetClosestVertices(), lar_content::LArPointingCluster::GetInnerVertex(), lar_content::LArPointingCluster::GetOuterVertex(), lar_content::LArStitchingHelper::GetTPCDisplacement(), lar_content::LArPointingCluster::Vertex::IsInnerVertex(), and lar_content::LArPfoHelper::SortByNHits().

Referenced by Run().

467 {
468  PfoVector inputPfoVector;
469  for (const auto &mapEntry : inputPfoMerges)
470  inputPfoVector.push_back(mapEntry.first);
471  std::sort(inputPfoVector.begin(), inputPfoVector.end(), LArPfoHelper::SortByNHits);
472 
473  for (const ParticleFlowObject *const pInputPfo : inputPfoVector)
474  {
475  const PfoList &pfoList(inputPfoMerges.at(pInputPfo));
476 
477  float bestLength(0.f);
478  const ParticleFlowObject *pVertexPfo = nullptr;
479 
480  for (PfoList::const_iterator iter1 = pfoList.begin(), iterEnd = pfoList.end(); iter1 != iterEnd; ++iter1)
481  {
482  const ParticleFlowObject *const pPfo1(*iter1);
483  PfoToLArTPCMap::const_iterator tpcIter1 = pfoToLArTPCMap.find(pPfo1);
484  ThreeDPointingClusterMap::const_iterator pointingIter1 = pointingClusterMap.find(pPfo1);
485 
486  if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
487  throw StatusCodeException(STATUS_CODE_FAILURE);
488 
489  const LArTPC *const pLArTPC1(tpcIter1->second);
490  const LArPointingCluster &pointingCluster1(pointingIter1->second);
491 
492  for (PfoList::const_iterator iter2 = iter1; iter2 != iterEnd; ++iter2)
493  {
494  const ParticleFlowObject *const pPfo2(*iter2);
495  PfoToLArTPCMap::const_iterator tpcIter2 = pfoToLArTPCMap.find(pPfo2);
496  ThreeDPointingClusterMap::const_iterator pointingIter2 = pointingClusterMap.find(pPfo2);
497 
498  if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
499  throw StatusCodeException(STATUS_CODE_FAILURE);
500 
501  const LArTPC *const pLArTPC2(tpcIter2->second);
502  const LArPointingCluster &pointingCluster2(pointingIter2->second);
503 
504  if (pLArTPC1 == pLArTPC2)
505  continue;
506 
507  const float thisLength(LArStitchingHelper::GetTPCDisplacement(*pLArTPC1, *pLArTPC2));
508 
509  if (thisLength < bestLength)
510  continue;
511 
512  bestLength = thisLength;
513 
514  try
515  {
516  pVertexPfo = nullptr;
517 
518  LArPointingCluster::Vertex nearVertex1, nearVertex2;
519  LArStitchingHelper::GetClosestVertices(*pLArTPC1, *pLArTPC2, pointingCluster1, pointingCluster2, nearVertex1, nearVertex2);
520 
521  const LArPointingCluster::Vertex &farVertex1(
522  nearVertex1.IsInnerVertex() ? pointingCluster1.GetOuterVertex() : pointingCluster1.GetInnerVertex());
523  const LArPointingCluster::Vertex &farVertex2(
524  nearVertex2.IsInnerVertex() ? pointingCluster2.GetOuterVertex() : pointingCluster2.GetInnerVertex());
525  const float deltaY(farVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
526 
527  if (std::fabs(deltaY) < std::numeric_limits<float>::epsilon())
528  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
529 
530  pVertexPfo = ((deltaY > 0.f) ? pPfo1 : pPfo2);
531  }
532  catch (const pandora::StatusCodeException &)
533  {
534  }
535  }
536  }
537 
538  if (pVertexPfo)
539  outputPfoMerges[pVertexPfo].insert(outputPfoMerges[pVertexPfo].begin(), pfoList.begin(), pfoList.end());
540  }
541 }
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
intermediate_table::const_iterator const_iterator
TFile f
Definition: plotHisto.C:6
static float GetTPCDisplacement(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Calculate distance between central positions of a pair of tpcs.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
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.
StatusCode lar_content::StitchingCosmicRayMergingTool::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
private

Definition at line 822 of file StitchingCosmicRayMergingTool.cc.

References m_alwaysApplyT0Calculation, m_boundaryToleranceWidth, m_halfWindowLayers, m_maxLongitudinalDisplacementX, m_maxTransverseDisplacement, m_maxX0FractionalDeviation, m_minCosRelativeAngle, m_minLengthSquared, m_minNCaloHits3D, m_relaxCosRelativeAngle, m_relaxMinLongitudinalDisplacement, m_relaxTransverseDisplacement, and m_useXcoordinate.

823 {
824  PANDORA_RETURN_RESULT_IF_AND_IF(
825  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ThreeDStitchingMode", m_useXcoordinate));
826 
827  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
828  XmlHelper::ReadValue(xmlHandle, "AlwaysApplyT0Calculation", m_alwaysApplyT0Calculation));
829 
830  PANDORA_RETURN_RESULT_IF_AND_IF(
831  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "HalfWindowLayers", m_halfWindowLayers));
832 
833  float minLength(std::sqrt(m_minLengthSquared));
834  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinPfoLength", minLength));
835  m_minLengthSquared = minLength * minLength;
836 
837  PANDORA_RETURN_RESULT_IF_AND_IF(
838  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCosRelativeAngle", m_minCosRelativeAngle));
839 
840  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
841  XmlHelper::ReadValue(xmlHandle, "RelaxMinLongitudinalDisplacement", m_relaxMinLongitudinalDisplacement));
842 
843  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
844  XmlHelper::ReadValue(xmlHandle, "MaxLongitudinalDisplacementX", m_maxLongitudinalDisplacementX));
845 
846  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
847  XmlHelper::ReadValue(xmlHandle, "MaxTransverseDisplacement", m_maxTransverseDisplacement));
848 
849  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
850  XmlHelper::ReadValue(xmlHandle, "LooserMinCosRelativeAngle", m_relaxCosRelativeAngle));
851 
852  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
853  XmlHelper::ReadValue(xmlHandle, "LooserMaxTransverseDisplacement", m_relaxTransverseDisplacement));
854 
855  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinNCaloHits3D", m_minNCaloHits3D));
856 
857  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
858  XmlHelper::ReadValue(xmlHandle, "MaxX0FractionalDeviation", m_maxX0FractionalDeviation));
859 
860  PANDORA_RETURN_RESULT_IF_AND_IF(
861  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "BoundaryToleranceWidth", m_boundaryToleranceWidth));
862 
863  return STATUS_CODE_SUCCESS;
864 }
float m_boundaryToleranceWidth
The distance from the APA/CPA boundary inside which the deviation consideration is ignored...
float m_maxX0FractionalDeviation
The maximum allowed fractional difference of an X0 contribution for matches to be stitched...
float m_relaxMinLongitudinalDisplacement
The minimum value of the longitudinal impact parameter for association if both verticies fall in the ...
void lar_content::StitchingCosmicRayMergingTool::Run ( const MasterAlgorithm *const  pAlgorithm,
const pandora::PfoList *const  pMultiPfoList,
PfoToLArTPCMap pfoToLArTPCMap,
PfoToFloatMap stitchedPfosToX0Map 
)
virtual

Run the algorithm tool.

Parameters
pAlgorithmaddress of the calling algorithm
pMultiPfoListthe list of pfos in multiple lar tpcs
pfoToLArTPCMapthe pfo to lar tpc map
stitchedPfosToX0Mapa map of cosmic-ray pfos that have been stitched between lar tpcs to the X0 shift

Implements lar_content::StitchingBaseTool.

Definition at line 42 of file StitchingCosmicRayMergingTool.cc.

References BuildPointingClusterMaps(), BuildTPCMaps(), CreatePfoMatches(), OrderPfoMerges(), SelectPfoMatches(), SelectPfoMerges(), SelectPrimaryPfos(), util::size(), and StitchPfos().

44 {
45  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
46  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
47 
48  if (this->GetPandora().GetGeometry()->GetLArTPCMap().size() < 2)
49  return;
50 
51  if (pfoToLArTPCMap.empty())
52  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
53 
54  PfoList primaryPfos;
55  this->SelectPrimaryPfos(pMultiPfoList, pfoToLArTPCMap, primaryPfos);
56 
57  ThreeDPointingClusterMap pointingClusterMap;
58  this->BuildPointingClusterMaps(primaryPfos, pfoToLArTPCMap, pointingClusterMap);
59 
60  LArTPCToPfoMap larTPCToPfoMap;
61  this->BuildTPCMaps(primaryPfos, pfoToLArTPCMap, larTPCToPfoMap);
62 
63  PfoAssociationMatrix pfoAssociationMatrix;
64  this->CreatePfoMatches(larTPCToPfoMap, pointingClusterMap, pfoAssociationMatrix);
65 
66  PfoMergeMap pfoSelectedMatches;
67  this->SelectPfoMatches(pfoAssociationMatrix, pfoSelectedMatches);
68 
69  PfoMergeMap pfoSelectedMerges;
70  this->SelectPfoMerges(pfoSelectedMatches, pfoSelectedMerges);
71 
72  PfoMergeMap pfoOrderedMerges;
73  this->OrderPfoMerges(pfoToLArTPCMap, pointingClusterMap, pfoSelectedMerges, pfoOrderedMerges);
74 
75  this->StitchPfos(pAlgorithm, pointingClusterMap, pfoOrderedMerges, pfoToLArTPCMap, stitchedPfosToX0Map);
76 }
void SelectPrimaryPfos(const pandora::PfoList *pInputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, pandora::PfoList &outputPfoList) const
Select primary Pfos from the input list of Pfos.
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.
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...
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
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.
void BuildPointingClusterMaps(const pandora::PfoList &inputPfoList, const PfoToLArTPCMap &pfoToLArTPCMap, ThreeDPointingClusterMap &pointingClusterMap) const
Build a 3D pointing cluster for each Pfo.
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::LArTPC *, pandora::PfoList > LArTPCToPfoMap
void SelectPfoMerges(const PfoMergeMap &pfoMatches, PfoMergeMap &pfoMerges) const
Create an initial map of Pfo merges to be made.
std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster > ThreeDPointingClusterMap
void lar_content::StitchingCosmicRayMergingTool::SelectPfoMatches ( const PfoAssociationMatrix pfoAssociationMatrix,
PfoMergeMap pfoSelectedMatches 
) const
private

Select the best associations between Pfos; create a mapping between associated Pfos, handling any ambiguities.

Parameters
pfoAssociationMatrixthe input list of all associations between Pfos
pfoSelectedMatchesthe output list of good associations between pfos (candidates for merging)

Definition at line 295 of file StitchingCosmicRayMergingTool.cc.

References f, lar_content::StitchingCosmicRayMergingTool::PfoAssociation::GetDaughter(), lar_content::StitchingCosmicRayMergingTool::PfoAssociation::GetFigureOfMerit(), lar_content::StitchingCosmicRayMergingTool::PfoAssociation::GetParent(), lar_content::StitchingCosmicRayMergingTool::PfoAssociation::INNER, lar_content::StitchingCosmicRayMergingTool::PfoAssociation::OUTER, lar_content::LArPfoHelper::SortByNHits(), and lar_content::StitchingCosmicRayMergingTool::PfoAssociation::UNDEFINED.

Referenced by Run().

296 {
297  // First step: loop over association matrix and find best associations A -> X and B -> Y
298  // =====================================================================================
299  PfoAssociationMatrix bestAssociationMatrix;
300 
301  PfoVector pfoVector1;
302  for (const auto &mapEntry : pfoAssociationMatrix)
303  pfoVector1.push_back(mapEntry.first);
304  std::sort(pfoVector1.begin(), pfoVector1.end(), LArPfoHelper::SortByNHits);
305 
306  for (const ParticleFlowObject *const pPfo1 : pfoVector1)
307  {
308  const PfoAssociationMap &pfoAssociationMap(pfoAssociationMatrix.at(pPfo1));
309 
310  const ParticleFlowObject *pBestPfoInner(nullptr);
311  PfoAssociation bestAssociationInner(PfoAssociation::UNDEFINED, PfoAssociation::UNDEFINED, 0.f);
312 
313  const ParticleFlowObject *pBestPfoOuter(nullptr);
314  PfoAssociation bestAssociationOuter(PfoAssociation::UNDEFINED, PfoAssociation::UNDEFINED, 0.f);
315 
316  PfoVector pfoVector2;
317  for (const auto &mapEntry : pfoAssociationMap)
318  pfoVector2.push_back(mapEntry.first);
319  std::sort(pfoVector2.begin(), pfoVector2.end(), LArPfoHelper::SortByNHits);
320 
321  for (const ParticleFlowObject *const pPfo2 : pfoVector2)
322  {
323  const PfoAssociation &pfoAssociation(pfoAssociationMap.at(pPfo2));
324 
325  // Inner associations
326  if (pfoAssociation.GetParent() == PfoAssociation::INNER)
327  {
328  if (pfoAssociation.GetFigureOfMerit() > bestAssociationInner.GetFigureOfMerit())
329  {
330  bestAssociationInner = pfoAssociation;
331  pBestPfoInner = pPfo2;
332  }
333  }
334 
335  // Outer associations
336  if (pfoAssociation.GetParent() == PfoAssociation::OUTER)
337  {
338  if (pfoAssociation.GetFigureOfMerit() > bestAssociationOuter.GetFigureOfMerit())
339  {
340  bestAssociationOuter = pfoAssociation;
341  pBestPfoOuter = pPfo2;
342  }
343  }
344  }
345 
346  if (pBestPfoInner)
347  (void)bestAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pBestPfoInner, bestAssociationInner));
348 
349  if (pBestPfoOuter)
350  (void)bestAssociationMatrix[pPfo1].insert(PfoAssociationMap::value_type(pBestPfoOuter, bestAssociationOuter));
351  }
352 
353  // Second step: make the merge if A -> X and B -> Y is in fact A -> B and B -> A
354  // =============================================================================
355  PfoVector pfoVector3;
356  for (const auto &mapEntry : bestAssociationMatrix)
357  pfoVector3.push_back(mapEntry.first);
358  std::sort(pfoVector3.begin(), pfoVector3.end(), LArPfoHelper::SortByNHits);
359 
360  for (const ParticleFlowObject *const pParentPfo : pfoVector3)
361  {
362  const PfoAssociationMap &parentAssociationMap(bestAssociationMatrix.at(pParentPfo));
363 
364  PfoVector pfoVector4;
365  for (const auto &mapEntry : parentAssociationMap)
366  pfoVector4.push_back(mapEntry.first);
367  std::sort(pfoVector4.begin(), pfoVector4.end(), LArPfoHelper::SortByNHits);
368 
369  for (const ParticleFlowObject *const pDaughterPfo : pfoVector4)
370  {
371  const PfoAssociation &parentToDaughterAssociation(parentAssociationMap.at(pDaughterPfo));
372  PfoAssociationMatrix::const_iterator iter5 = bestAssociationMatrix.find(pDaughterPfo);
373 
374  if (bestAssociationMatrix.end() == iter5)
375  continue;
376 
377  const PfoAssociationMap &daughterAssociationMap(iter5->second);
378 
379  PfoAssociationMap::const_iterator iter6 = daughterAssociationMap.find(pParentPfo);
380  if (daughterAssociationMap.end() == iter6)
381  continue;
382 
383  const PfoAssociation &daughterToParentAssociation(iter6->second);
384 
385  if (parentToDaughterAssociation.GetParent() == daughterToParentAssociation.GetDaughter() &&
386  parentToDaughterAssociation.GetDaughter() == daughterToParentAssociation.GetParent())
387  {
388  pfoMatches[pParentPfo].push_back(pDaughterPfo);
389  }
390  }
391  }
392 }
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
intermediate_table::const_iterator const_iterator
std::unordered_map< const pandora::ParticleFlowObject *, PfoAssociationMap > PfoAssociationMatrix
TFile f
Definition: plotHisto.C:6
std::unordered_map< const pandora::ParticleFlowObject *, PfoAssociation > PfoAssociationMap
void lar_content::StitchingCosmicRayMergingTool::SelectPfoMerges ( const PfoMergeMap pfoMatches,
PfoMergeMap pfoMerges 
) const
private

Create an initial map of Pfo merges to be made.

Parameters
pfoMatchesthe input list of associated Pfos
pfoMergesthe output mapping between Pfos to enlarge and Pfos to delete

Definition at line 396 of file StitchingCosmicRayMergingTool.cc.

References CollectAssociatedPfos(), and lar_content::LArPfoHelper::SortByNHits().

Referenced by Run().

397 {
398  PfoSet vetoSet;
399 
400  PfoVector inputPfoVector;
401  for (const auto &mapEntry : pfoMatches)
402  inputPfoVector.push_back(mapEntry.first);
403  std::sort(inputPfoVector.begin(), inputPfoVector.end(), LArPfoHelper::SortByNHits);
404 
405  for (const ParticleFlowObject *const pInputPfo : inputPfoVector)
406  {
407  const PfoList &pfoList(pfoMatches.at(pInputPfo));
408 
409  for (const ParticleFlowObject *const pSeedPfo : pfoList)
410  {
411  if (vetoSet.count(pSeedPfo))
412  continue;
413 
414  PfoList mergeList;
415  this->CollectAssociatedPfos(pSeedPfo, pSeedPfo, pfoMatches, vetoSet, mergeList);
416 
417  vetoSet.insert(pSeedPfo);
418  PfoList &selectedPfoList(pfoMerges[pSeedPfo]);
419  selectedPfoList.push_back(pSeedPfo);
420 
421  for (const ParticleFlowObject *const pAssociatedPfo : mergeList)
422  {
423  // Check if particle has already been counted
424  if (vetoSet.count(pAssociatedPfo) || (selectedPfoList.end() != std::find(selectedPfoList.begin(), selectedPfoList.end(), pAssociatedPfo)))
425  throw StatusCodeException(STATUS_CODE_FAILURE);
426 
427  vetoSet.insert(pAssociatedPfo);
428  selectedPfoList.push_back(pAssociatedPfo);
429  }
430  }
431  }
432 }
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
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.
void lar_content::StitchingCosmicRayMergingTool::SelectPrimaryPfos ( const pandora::PfoList *  pInputPfoList,
const PfoToLArTPCMap pfoToLArTPCMap,
pandora::PfoList &  outputPfoList 
) const
private

Select primary Pfos from the input list of Pfos.

Parameters
pInputPfoListthe input list of Pfos
pfoToLArTPCMapthe input mapping between Pfos and tpc
outputPfoListthe output list of Pfos

Definition at line 80 of file StitchingCosmicRayMergingTool.cc.

References lar_content::LArPfoHelper::IsFinalState(), lar_content::LArPfoHelper::IsTrack(), and lar_content::LArPfoHelper::SortByNHits().

Referenced by Run().

81 {
82  for (const ParticleFlowObject *const pPfo : *pInputPfoList)
83  {
85  continue;
86 
87  if (!pfoToLArTPCMap.count(pPfo))
88  continue;
89 
90  outputPfoList.push_back(pPfo);
91  }
92 
93  outputPfoList.sort(LArPfoHelper::SortByNHits);
94 }
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
static bool IsFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a primary parent particle.
void lar_content::StitchingCosmicRayMergingTool::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
private

Shift a pfo given its pfo stitching pair.

Parameters
pPfoToShiftthe pfo of the stitching pair to shift
pMatchedPfothe pfo of the stitching pair to remain stationary
x0the distance by which pPfoToShift is to be shifted (direction of shift is determined in method)
pfoToLArTPCMapthe pfo to lar tpc map
pfoToPointingVertexMatrixthe map [pfo -> map [matched pfo -> pfo stitching vertex]]

Definition at line 622 of file StitchingCosmicRayMergingTool.cc.

References f, lar_content::LArPfoHelper::GetAllDownstreamPfos(), lar_content::LArStitchingHelper::GetTPCBoundaryCenterX(), and lar_content::MasterAlgorithm::ShiftPfoHierarchy().

Referenced by StitchPfos().

625 {
626  // get stitching vertex for the pfo to be shifted
627  const PfoToPointingVertexMatrix::const_iterator pfoToPointingVertexMatrixIter(pfoToPointingVertexMatrix.find(pPfoToShift));
628  const LArPointingCluster::Vertex stitchingVertex(pfoToPointingVertexMatrixIter->second.at(pMatchedPfo));
629 
630  const LArTPC *const pShiftLArTPC(pfoToLArTPCMap.at(pPfoToShift));
631  const LArTPC *const pMatchedLArTPC(pfoToLArTPCMap.at(pMatchedPfo));
632 
633  // determine shift sign from the relative position of stitching vertex and the relevant TPC boundary position
634  const float tpcBoundaryCenterX(LArStitchingHelper::GetTPCBoundaryCenterX(*pShiftLArTPC, *pMatchedLArTPC));
635  float tpcBoundaryX(0.f);
636 
637  if (pShiftLArTPC->GetCenterX() < tpcBoundaryCenterX)
638  {
639  tpcBoundaryX = pShiftLArTPC->GetCenterX() + (pShiftLArTPC->GetWidthX() / 2.f);
640  }
641  else
642  {
643  tpcBoundaryX = pShiftLArTPC->GetCenterX() - (pShiftLArTPC->GetWidthX() / 2.f);
644  }
645 
646  const float positionShiftSign = stitchingVertex.GetPosition().GetX() < tpcBoundaryX ? 1.f : -1.f;
647 
648  // ATTN: No CPA/APA sign needed since x0 calculation corresponds to an APA
649  object_creation::ParticleFlowObject::Metadata metadata;
650  metadata.m_propertiesToAdd["X0"] = x0;
651 
652  // ATTN: Set the X0 shift for all particles in hierarchy
653  PfoList downstreamPfoList;
654  LArPfoHelper::GetAllDownstreamPfos(pPfoToShift, downstreamPfoList);
655 
656  for (const ParticleFlowObject *const pHierarchyPfo : downstreamPfoList)
657  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pHierarchyPfo, metadata));
658 
659  const float signedX0(std::fabs(x0) * positionShiftSign);
660 
661  pAlgorithm->ShiftPfoHierarchy(pPfoToShift, pfoToLArTPCMap, signedX0);
662 }
intermediate_table::const_iterator const_iterator
TFile f
Definition: plotHisto.C:6
static float GetTPCBoundaryCenterX(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Determine centre in X at the boundary between a pair of tpcs.
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...
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
void lar_content::StitchingCosmicRayMergingTool::StitchPfos ( const MasterAlgorithm *const  pAlgorithm,
const ThreeDPointingClusterMap pointingClusterMap,
const PfoMergeMap pfoMerges,
PfoToLArTPCMap pfoToLArTPCMap,
PfoToFloatMap stitchedPfosToX0Map 
) const
private

Apply X0 corrections, and then stitch together Pfos.

Parameters
pAlgorithmthe address of the parent stitching algorithm
pointingClusterMapthe mapping between Pfos and their corresponding 3D pointing clusters
pfoMergesthe input map of Pfo merges
pfoToLArTPCMapthe pfo to lar tpc map
stitchedPfosToX0Mapa map of cosmic-ray pfos that have been stitched between lar tpcs to the X0 shift

Definition at line 545 of file StitchingCosmicRayMergingTool.cc.

References CalculateX0(), lar_content::LArStitchingHelper::CanTPCsBeStitched(), f, m_alwaysApplyT0Calculation, m_useXcoordinate, ShiftPfo(), lar_content::LArPfoHelper::SortByNHits(), and lar_content::MasterAlgorithm::StitchPfos().

Referenced by Run().

547 {
548  PfoVector pfoVectorToEnlarge;
549  for (const auto &mapEntry : pfoMerges)
550  pfoVectorToEnlarge.push_back(mapEntry.first);
551  std::sort(pfoVectorToEnlarge.begin(), pfoVectorToEnlarge.end(), LArPfoHelper::SortByNHits);
552 
553  for (const ParticleFlowObject *const pPfoToEnlarge : pfoVectorToEnlarge)
554  {
555  const PfoList &pfoList(pfoMerges.at(pPfoToEnlarge));
556  const PfoVector pfoVector(pfoList.begin(), pfoList.end());
557  PfoToPointingVertexMatrix pfoToPointingVertexMatrix;
558  float x0(0.f);
559 
561  {
562  try
563  {
564  // If stitching contributions are inconsistent, abort
565  if (!this->CalculateX0(pfoToLArTPCMap, pointingClusterMap, pfoVector, x0, pfoToPointingVertexMatrix))
566  continue;
567  }
568  catch (const pandora::StatusCodeException &)
569  {
570  continue;
571  }
572  }
573 
574  // ATTN: shift the pfos one at a time
575  PfoSet shiftedPfos;
576  for (PfoVector::const_iterator iterI = pfoVector.begin(); iterI != pfoVector.end(); ++iterI)
577  {
578  const ParticleFlowObject *const pPfoI(*iterI);
579  const LArTPC *const pLArTPCI(pfoToLArTPCMap.at(pPfoI));
580 
581  for (PfoVector::const_iterator iterJ = std::next(iterI); iterJ != pfoVector.end(); ++iterJ)
582  {
583  const ParticleFlowObject *const pPfoJ(*iterJ);
584  const LArTPC *const pLArTPCJ(pfoToLArTPCMap.at(pPfoJ));
585 
586  if (!LArStitchingHelper::CanTPCsBeStitched(*pLArTPCI, *pLArTPCJ))
587  continue;
588 
589  if (std::find(shiftedPfos.begin(), shiftedPfos.end(), pPfoI) == shiftedPfos.end())
590  {
592  this->ShiftPfo(pAlgorithm, pPfoI, pPfoJ, x0, pfoToLArTPCMap, pfoToPointingVertexMatrix);
593 
594  shiftedPfos.insert(pPfoI);
595  }
596 
597  if (std::find(shiftedPfos.begin(), shiftedPfos.end(), pPfoJ) == shiftedPfos.end())
598  {
600  this->ShiftPfo(pAlgorithm, pPfoJ, pPfoI, x0, pfoToLArTPCMap, pfoToPointingVertexMatrix);
601 
602  shiftedPfos.insert(pPfoJ);
603  }
604  }
605  }
606 
607  // now merge all pfos
608  for (const ParticleFlowObject *const pPfoToDelete : shiftedPfos)
609  {
610  if (pPfoToDelete == pPfoToEnlarge)
611  continue;
612 
613  pAlgorithm->StitchPfos(pPfoToEnlarge, pPfoToDelete, pfoToLArTPCMap);
614  }
615 
616  stitchedPfosToX0Map.insert(PfoToFloatMap::value_type(pPfoToEnlarge, x0));
617  }
618 }
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.
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.
intermediate_table::const_iterator const_iterator
TFile f
Definition: plotHisto.C:6
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.
static bool CanTPCsBeStitched(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether particles from a given pair of tpcs can be stitched together.

Member Data Documentation

bool lar_content::StitchingCosmicRayMergingTool::m_alwaysApplyT0Calculation
private

Definition at line 233 of file StitchingCosmicRayMergingTool.h.

Referenced by ReadSettings(), and StitchPfos().

float lar_content::StitchingCosmicRayMergingTool::m_boundaryToleranceWidth
private

The distance from the APA/CPA boundary inside which the deviation consideration is ignored.

Definition at line 244 of file StitchingCosmicRayMergingTool.h.

Referenced by CalculateX0(), and ReadSettings().

int lar_content::StitchingCosmicRayMergingTool::m_halfWindowLayers
private

Definition at line 234 of file StitchingCosmicRayMergingTool.h.

Referenced by BuildPointingClusterMaps(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_maxLongitudinalDisplacementX
private

Definition at line 238 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_maxTransverseDisplacement
private

Definition at line 239 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_maxX0FractionalDeviation
private

The maximum allowed fractional difference of an X0 contribution for matches to be stitched.

Definition at line 243 of file StitchingCosmicRayMergingTool.h.

Referenced by CalculateX0(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_minCosRelativeAngle
private

Definition at line 236 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_minLengthSquared
private

Definition at line 235 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

unsigned int lar_content::StitchingCosmicRayMergingTool::m_minNCaloHits3D
private

Definition at line 242 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_relaxCosRelativeAngle
private

Definition at line 240 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_relaxMinLongitudinalDisplacement
private

The minimum value of the longitudinal impact parameter for association if both verticies fall in the detector gap.

Definition at line 237 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

float lar_content::StitchingCosmicRayMergingTool::m_relaxTransverseDisplacement
private

Definition at line 241 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), and ReadSettings().

bool lar_content::StitchingCosmicRayMergingTool::m_useXcoordinate
private

Definition at line 232 of file StitchingCosmicRayMergingTool.h.

Referenced by CreatePfoMatches(), ReadSettings(), and StitchPfos().


The documentation for this class was generated from the following files: