Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
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

StitchingCosmicRayMergingTool class.

Definition at line 23 of file StitchingCosmicRayMergingTool.h.

Member Typedef Documentation

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

Definition at line 110 of file StitchingCosmicRayMergingTool.h.

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

Definition at line 121 of file StitchingCosmicRayMergingTool.h.

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

Definition at line 122 of file StitchingCosmicRayMergingTool.h.

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

Definition at line 148 of file StitchingCosmicRayMergingTool.h.

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

Definition at line 201 of file StitchingCosmicRayMergingTool.h.

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

Definition at line 202 of file StitchingCosmicRayMergingTool.h.

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

Definition at line 98 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...
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.

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.

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 662 of file StitchingCosmicRayMergingTool.cc.

664 {
665  float sumX(0.f), sumN(0.f);
666 
667  for (PfoVector::const_iterator iter1 = pfoVector.begin(), iterEnd = pfoVector.end(); iter1 != iterEnd; ++iter1)
668  {
669  const ParticleFlowObject *const pPfo1(*iter1);
670  PfoToLArTPCMap::const_iterator tpcIter1 = pfoToLArTPCMap.find(pPfo1);
671  ThreeDPointingClusterMap::const_iterator pointingIter1 = pointingClusterMap.find(pPfo1);
672 
673  if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
674  throw StatusCodeException(STATUS_CODE_FAILURE);
675 
676  const LArTPC *const pLArTPC1(tpcIter1->second);
677  const LArPointingCluster &pointingCluster1(pointingIter1->second);
678 
679  for (PfoVector::const_iterator iter2 = std::next(iter1); iter2 != iterEnd; ++iter2)
680  {
681  const ParticleFlowObject *const pPfo2(*iter2);
682  PfoToLArTPCMap::const_iterator tpcIter2 = pfoToLArTPCMap.find(pPfo2);
683  ThreeDPointingClusterMap::const_iterator pointingIter2 = pointingClusterMap.find(pPfo2);
684 
685  if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
686  throw StatusCodeException(STATUS_CODE_FAILURE);
687 
688  const LArTPC *const pLArTPC2(tpcIter2->second);
689  const LArPointingCluster &pointingCluster2(pointingIter2->second);
690 
691  if (!LArStitchingHelper::CanTPCsBeStitched(*pLArTPC1, *pLArTPC2))
692  continue;
693 
694  // Calculate X0 for the closest pair of vertices
695  LArPointingCluster::Vertex pointingVertex1, pointingVertex2;
696  try
697  {
698  LArStitchingHelper::GetClosestVertices(*pLArTPC1, *pLArTPC2, pointingCluster1, pointingCluster2, pointingVertex1, pointingVertex2);
699 
700  // Record pfo1 stitching vertex for pfo1<->pfo2 match, used to determine shifting direction in later step
701  const PfoToPointingVertexMatrix::iterator pfoToPointingVertexMatrixIter1(pfoToPointingVertexMatrix.find(pPfo1));
702  if (pfoToPointingVertexMatrixIter1 == pfoToPointingVertexMatrix.end())
703  {
704  // No matches present in map, add pfo1<->pfo2 match
705  const PfoToPointingVertexMap pfoToPointingVertexMap({{pPfo2, pointingVertex1}});
706  (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo1, pfoToPointingVertexMap));
707  }
708  else
709  {
710  // ATTN: another match for a different TPC boundary may be present, add pfo1<->pfo2 match
711  PfoToPointingVertexMap &pfoToPointingVertexMap(pfoToPointingVertexMatrixIter1->second);
712  const PfoToPointingVertexMap::iterator pfoToPointingVertexMapIter(pfoToPointingVertexMap.find(pPfo2));
713  if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
714  {
715  (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo2, pointingVertex1));
716  }
717  else
718  {
719  if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex1.GetPosition()).GetMagnitude() >
720  std::numeric_limits<float>::epsilon())
721  throw StatusCodeException(STATUS_CODE_FAILURE);
722  }
723  }
724 
725  // Record pfo2 stitching vertex for pfo1<->pfo2 match, used to determine shifting direction in later step
726  const PfoToPointingVertexMatrix::iterator pfoToPointingVertexMatrixIter2(pfoToPointingVertexMatrix.find(pPfo2));
727  if (pfoToPointingVertexMatrixIter2 == pfoToPointingVertexMatrix.end())
728  {
729  // No matches present in map, add pfo1<->pfo2 match
730  const PfoToPointingVertexMap pfoToPointingVertexMap({{pPfo1, pointingVertex2}});
731  (void)pfoToPointingVertexMatrix.insert(PfoToPointingVertexMatrix::value_type(pPfo2, pfoToPointingVertexMap));
732  }
733  else
734  {
735  // ATTN: another match for a different TPC boundary may be present, add pfo1<->pfo2 match
736  PfoToPointingVertexMap &pfoToPointingVertexMap(pfoToPointingVertexMatrixIter2->second);
737  const PfoToPointingVertexMap::iterator pfoToPointingVertexMapIter(pfoToPointingVertexMap.find(pPfo1));
738  if (pfoToPointingVertexMapIter == pfoToPointingVertexMap.end())
739  {
740  (void)pfoToPointingVertexMap.insert(PfoToPointingVertexMap::value_type(pPfo1, pointingVertex2));
741  }
742  else
743  {
744  if ((pfoToPointingVertexMapIter->second.GetPosition() - pointingVertex2.GetPosition()).GetMagnitude() >
745  std::numeric_limits<float>::epsilon())
746  throw StatusCodeException(STATUS_CODE_FAILURE);
747  }
748  }
749 
750  const float tpcBoundaryCenterX(LArStitchingHelper::GetTPCBoundaryCenterX(*pLArTPC1, *pLArTPC2));
751  const bool isCPAStitch(pLArTPC1->GetCenterX() < tpcBoundaryCenterX ? !pLArTPC1->IsDriftInPositiveX() : !pLArTPC2->IsDriftInPositiveX());
752  float thisX0(LArStitchingHelper::CalculateX0(*pLArTPC1, *pLArTPC2, pointingVertex1, pointingVertex2));
753 
754  thisX0 *= isCPAStitch ? -1.f : 1.f;
755 
756  // If multiple boundaries identified, check if stitching contribution is consistent
757  if ((sumN > std::numeric_limits<float>::epsilon()) && (sumX > std::numeric_limits<float>::epsilon()))
758  {
759  const float fractionalDiff(std::fabs((sumX - (thisX0 * sumN)) / sumX));
760 
761  if ((fractionalDiff > m_maxX0FractionalDeviation) && (std::fabs(sumX / sumN) > m_boundaryToleranceWidth))
762  return false;
763  }
764 
765  sumX += thisX0;
766  sumN += 1.f;
767  }
768  catch (const pandora::StatusCodeException &statusCodeException)
769  {
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;
772  }
773  }
774  }
775 
776  if ((sumN < std::numeric_limits<float>::epsilon()) || (std::fabs(sumX) < std::numeric_limits<float>::epsilon()))
777  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
778 
779  x0 = (sumX / sumN);
780 
781  return true;
782 }
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...
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.
QTextStream & endl(QTextStream &s)
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 432 of file StitchingCosmicRayMergingTool.cc.

434 {
435  if (vetoSet.count(pCurrentPfo))
436  return;
437 
438  PfoMergeMap::const_iterator iter1 = pfoMergeMap.find(pCurrentPfo);
439 
440  if (pfoMergeMap.end() == iter1)
441  return;
442 
443  for (PfoList::const_iterator iter2 = iter1->second.begin(), iterEnd2 = iter1->second.end(); iter2 != iterEnd2; ++iter2)
444  {
445  const ParticleFlowObject *const pAssociatedPfo = *iter2;
446 
447  if (pAssociatedPfo == pSeedPfo)
448  continue;
449 
450  if (associatedList.end() != std::find(associatedList.begin(), associatedList.end(), pAssociatedPfo))
451  continue;
452 
453  associatedList.push_back(pAssociatedPfo);
454 
455  this->CollectAssociatedPfos(pSeedPfo, pAssociatedPfo, pfoMergeMap, vetoSet, associatedList);
456  }
457 }
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.

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 461 of file StitchingCosmicRayMergingTool.cc.

463 {
464  PfoVector inputPfoVector;
465  for (const auto &mapEntry : inputPfoMerges)
466  inputPfoVector.push_back(mapEntry.first);
467  std::sort(inputPfoVector.begin(), inputPfoVector.end(), LArPfoHelper::SortByNHits);
468 
469  for (const ParticleFlowObject *const pInputPfo : inputPfoVector)
470  {
471  const PfoList &pfoList(inputPfoMerges.at(pInputPfo));
472 
473  float bestLength(0.f);
474  const ParticleFlowObject *pVertexPfo = nullptr;
475 
476  for (PfoList::const_iterator iter1 = pfoList.begin(), iterEnd = pfoList.end(); iter1 != iterEnd; ++iter1)
477  {
478  const ParticleFlowObject *const pPfo1(*iter1);
479  PfoToLArTPCMap::const_iterator tpcIter1 = pfoToLArTPCMap.find(pPfo1);
480  ThreeDPointingClusterMap::const_iterator pointingIter1 = pointingClusterMap.find(pPfo1);
481 
482  if (pfoToLArTPCMap.end() == tpcIter1 || pointingClusterMap.end() == pointingIter1)
483  throw StatusCodeException(STATUS_CODE_FAILURE);
484 
485  const LArTPC *const pLArTPC1(tpcIter1->second);
486  const LArPointingCluster &pointingCluster1(pointingIter1->second);
487 
488  for (PfoList::const_iterator iter2 = iter1; iter2 != iterEnd; ++iter2)
489  {
490  const ParticleFlowObject *const pPfo2(*iter2);
491  PfoToLArTPCMap::const_iterator tpcIter2 = pfoToLArTPCMap.find(pPfo2);
492  ThreeDPointingClusterMap::const_iterator pointingIter2 = pointingClusterMap.find(pPfo2);
493 
494  if (pfoToLArTPCMap.end() == tpcIter2 || pointingClusterMap.end() == pointingIter2)
495  throw StatusCodeException(STATUS_CODE_FAILURE);
496 
497  const LArTPC *const pLArTPC2(tpcIter2->second);
498  const LArPointingCluster &pointingCluster2(pointingIter2->second);
499 
500  if (pLArTPC1 == pLArTPC2)
501  continue;
502 
503  const float thisLength(LArStitchingHelper::GetTPCDisplacement(*pLArTPC1, *pLArTPC2));
504 
505  if (thisLength < bestLength)
506  continue;
507 
508  bestLength = thisLength;
509 
510  try
511  {
512  pVertexPfo = nullptr;
513 
514  LArPointingCluster::Vertex nearVertex1, nearVertex2;
515  LArStitchingHelper::GetClosestVertices(*pLArTPC1, *pLArTPC2, pointingCluster1, pointingCluster2, nearVertex1, nearVertex2);
516 
517  const LArPointingCluster::Vertex &farVertex1(
518  nearVertex1.IsInnerVertex() ? pointingCluster1.GetOuterVertex() : pointingCluster1.GetInnerVertex());
519  const LArPointingCluster::Vertex &farVertex2(
520  nearVertex2.IsInnerVertex() ? pointingCluster2.GetOuterVertex() : pointingCluster2.GetInnerVertex());
521  const float deltaY(farVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
522 
523  if (std::fabs(deltaY) < std::numeric_limits<float>::epsilon())
524  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
525 
526  pVertexPfo = ((deltaY > 0.f) ? pPfo1 : pPfo2);
527  }
528  catch (const pandora::StatusCodeException &)
529  {
530  }
531  }
532  }
533 
534  if (pVertexPfo)
535  outputPfoMerges[pVertexPfo].insert(outputPfoMerges[pVertexPfo].begin(), pfoList.begin(), pfoList.end());
536  }
537 }
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
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:72
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 818 of file StitchingCosmicRayMergingTool.cc.

819 {
820  PANDORA_RETURN_RESULT_IF_AND_IF(
821  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ThreeDStitchingMode", m_useXcoordinate));
822 
823  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
824  XmlHelper::ReadValue(xmlHandle, "AlwaysApplyT0Calculation", m_alwaysApplyT0Calculation));
825 
826  PANDORA_RETURN_RESULT_IF_AND_IF(
827  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "HalfWindowLayers", m_halfWindowLayers));
828 
829  float minLength(std::sqrt(m_minLengthSquared));
830  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinPfoLength", minLength));
831  m_minLengthSquared = minLength * minLength;
832 
833  PANDORA_RETURN_RESULT_IF_AND_IF(
834  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCosRelativeAngle", m_minCosRelativeAngle));
835 
836  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
837  XmlHelper::ReadValue(xmlHandle, "RelaxMinLongitudinalDisplacement", m_relaxMinLongitudinalDisplacement));
838 
839  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
840  XmlHelper::ReadValue(xmlHandle, "MaxLongitudinalDisplacementX", m_maxLongitudinalDisplacementX));
841 
842  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
843  XmlHelper::ReadValue(xmlHandle, "MaxTransverseDisplacement", m_maxTransverseDisplacement));
844 
845  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
846  XmlHelper::ReadValue(xmlHandle, "LooserMinCosRelativeAngle", m_relaxCosRelativeAngle));
847 
848  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
849  XmlHelper::ReadValue(xmlHandle, "LooserMaxTransverseDisplacement", m_relaxTransverseDisplacement));
850 
851  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinNCaloHits3D", m_minNCaloHits3D));
852 
853  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
854  XmlHelper::ReadValue(xmlHandle, "MaxX0FractionalDeviation", m_maxX0FractionalDeviation));
855 
856  PANDORA_RETURN_RESULT_IF_AND_IF(
857  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "BoundaryToleranceWidth", m_boundaryToleranceWidth));
858 
859  return STATUS_CODE_SUCCESS;
860 }
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.

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:92
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.
QTextStream & endl(QTextStream &s)
std::unordered_map< const pandora::ParticleFlowObject *, LArPointingCluster > ThreeDPointingClusterMap
GeomAnalyzerI * GetGeometry(void)
Definition: gAtmoEvGen.cxx:433
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 291 of file StitchingCosmicRayMergingTool.cc.

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

393 {
394  PfoSet vetoSet;
395 
396  PfoVector inputPfoVector;
397  for (const auto &mapEntry : pfoMatches)
398  inputPfoVector.push_back(mapEntry.first);
399  std::sort(inputPfoVector.begin(), inputPfoVector.end(), LArPfoHelper::SortByNHits);
400 
401  for (const ParticleFlowObject *const pInputPfo : inputPfoVector)
402  {
403  const PfoList &pfoList(pfoMatches.at(pInputPfo));
404 
405  for (const ParticleFlowObject *const pSeedPfo : pfoList)
406  {
407  if (vetoSet.count(pSeedPfo))
408  continue;
409 
410  PfoList mergeList;
411  this->CollectAssociatedPfos(pSeedPfo, pSeedPfo, pfoMatches, vetoSet, mergeList);
412 
413  vetoSet.insert(pSeedPfo);
414  PfoList &selectedPfoList(pfoMerges[pSeedPfo]);
415  selectedPfoList.push_back(pSeedPfo);
416 
417  for (const ParticleFlowObject *const pAssociatedPfo : mergeList)
418  {
419  // Check if particle has already been counted
420  if (vetoSet.count(pAssociatedPfo) || (selectedPfoList.end() != std::find(selectedPfoList.begin(), selectedPfoList.end(), pAssociatedPfo)))
421  throw StatusCodeException(STATUS_CODE_FAILURE);
422 
423  vetoSet.insert(pAssociatedPfo);
424  selectedPfoList.push_back(pAssociatedPfo);
425  }
426  }
427  }
428 }
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.

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 618 of file StitchingCosmicRayMergingTool.cc.

621 {
622  // get stitching vertex for the pfo to be shifted
623  const PfoToPointingVertexMatrix::const_iterator pfoToPointingVertexMatrixIter(pfoToPointingVertexMatrix.find(pPfoToShift));
624  const LArPointingCluster::Vertex stitchingVertex(pfoToPointingVertexMatrixIter->second.at(pMatchedPfo));
625 
626  const LArTPC *const pShiftLArTPC(pfoToLArTPCMap.at(pPfoToShift));
627  const LArTPC *const pMatchedLArTPC(pfoToLArTPCMap.at(pMatchedPfo));
628 
629  // determine shift sign from the relative position of stitching vertex and the relevant TPC boundary position
630  const float tpcBoundaryCenterX(LArStitchingHelper::GetTPCBoundaryCenterX(*pShiftLArTPC, *pMatchedLArTPC));
631  float tpcBoundaryX(0.f);
632 
633  if (pShiftLArTPC->GetCenterX() < tpcBoundaryCenterX)
634  {
635  tpcBoundaryX = pShiftLArTPC->GetCenterX() + (pShiftLArTPC->GetWidthX() / 2.f);
636  }
637  else
638  {
639  tpcBoundaryX = pShiftLArTPC->GetCenterX() - (pShiftLArTPC->GetWidthX() / 2.f);
640  }
641 
642  const float positionShiftSign = stitchingVertex.GetPosition().GetX() < tpcBoundaryX ? 1.f : -1.f;
643 
644  // ATTN: No CPA/APA sign needed since x0 calculation corresponds to an APA
645  object_creation::ParticleFlowObject::Metadata metadata;
646  metadata.m_propertiesToAdd["X0"] = x0;
647 
648  // ATTN: Set the X0 shift for all particles in hierarchy
649  PfoList downstreamPfoList;
650  LArPfoHelper::GetAllDownstreamPfos(pPfoToShift, downstreamPfoList);
651 
652  for (const ParticleFlowObject *const pHierarchyPfo : downstreamPfoList)
653  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pHierarchyPfo, metadata));
654 
655  const float signedX0(std::fabs(x0) * positionShiftSign);
656 
657  pAlgorithm->ShiftPfoHierarchy(pPfoToShift, pfoToLArTPCMap, signedX0);
658 }
intermediate_table::const_iterator const_iterator
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 541 of file StitchingCosmicRayMergingTool.cc.

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

float lar_content::StitchingCosmicRayMergingTool::m_boundaryToleranceWidth
private

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

Definition at line 243 of file StitchingCosmicRayMergingTool.h.

int lar_content::StitchingCosmicRayMergingTool::m_halfWindowLayers
private

Definition at line 233 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_maxLongitudinalDisplacementX
private

Definition at line 237 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_maxTransverseDisplacement
private

Definition at line 238 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_maxX0FractionalDeviation
private

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

Definition at line 242 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_minCosRelativeAngle
private

Definition at line 235 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_minLengthSquared
private

Definition at line 234 of file StitchingCosmicRayMergingTool.h.

unsigned int lar_content::StitchingCosmicRayMergingTool::m_minNCaloHits3D
private

Definition at line 241 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_relaxCosRelativeAngle
private

Definition at line 239 of file StitchingCosmicRayMergingTool.h.

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 236 of file StitchingCosmicRayMergingTool.h.

float lar_content::StitchingCosmicRayMergingTool::m_relaxTransverseDisplacement
private

Definition at line 240 of file StitchingCosmicRayMergingTool.h.

bool lar_content::StitchingCosmicRayMergingTool::m_useXcoordinate
private

Definition at line 231 of file StitchingCosmicRayMergingTool.h.


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