LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LocalAsymmetryFeatureTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 LocalAsymmetryFeatureTool::LocalAsymmetryFeatureTool() :
22  m_minAsymmetryCosAngle(0.9962),
23  m_maxAsymmetryNClusters(2)
24 {
25 }
26 
27 //------------------------------------------------------------------------------------------------------------------------------------------
28 
29 float LocalAsymmetryFeatureTool::GetAsymmetryForView(const CartesianVector &vertexPosition2D,
31 {
32  bool useEnergy(true), useAsymmetry(true);
33  CartesianVector energyWeightedDirectionSum(0.f, 0.f, 0.f), hitWeightedDirectionSum(0.f, 0.f, 0.f);
34  ClusterVector asymmetryClusters;
35 
36  for (const VertexSelectionBaseAlgorithm::SlidingFitData &slidingFitData : slidingFitDataList)
37  {
38  const Cluster *const pCluster(slidingFitData.GetCluster());
39 
40  if (pCluster->GetElectromagneticEnergy() < std::numeric_limits<float>::epsilon())
41  useEnergy = false;
42 
43  const CartesianVector vertexToMinLayer(slidingFitData.GetMinLayerPosition() - vertexPosition2D);
44  const CartesianVector vertexToMaxLayer(slidingFitData.GetMaxLayerPosition() - vertexPosition2D);
45 
46  const bool minLayerClosest(vertexToMinLayer.GetMagnitudeSquared() < vertexToMaxLayer.GetMagnitudeSquared());
47  const CartesianVector &clusterDirection((minLayerClosest) ? slidingFitData.GetMinLayerDirection() : slidingFitData.GetMaxLayerDirection());
48 
49  if (useAsymmetry && (LArClusterHelper::GetClosestDistance(vertexPosition2D, pCluster) < m_maxAsymmetryDistance))
50  {
51  useAsymmetry &= this->CheckAngle(energyWeightedDirectionSum, clusterDirection);
52  this->IncrementAsymmetryParameters(pCluster->GetElectromagneticEnergy(), clusterDirection, energyWeightedDirectionSum);
53 
54  useAsymmetry &= this->CheckAngle(hitWeightedDirectionSum, clusterDirection);
55  this->IncrementAsymmetryParameters(static_cast<float>(pCluster->GetNCaloHits()), clusterDirection, hitWeightedDirectionSum);
56 
57  asymmetryClusters.push_back(pCluster);
58  }
59 
60  if (!useAsymmetry)
61  return 1.f;
62  }
63 
64  // Default: maximum asymmetry (i.e. not suppressed), zero for energy kick (i.e. not suppressed)
65  if ((useEnergy && energyWeightedDirectionSum == CartesianVector(0.f, 0.f, 0.f)) ||
66  (!useEnergy && hitWeightedDirectionSum == CartesianVector(0.f, 0.f, 0.f)))
67  return 1.f;
68 
69  if (asymmetryClusters.empty() || (asymmetryClusters.size() > m_maxAsymmetryNClusters))
70  return 1.f;
71 
72  const CartesianVector &localWeightedDirectionSum(useEnergy ? energyWeightedDirectionSum : hitWeightedDirectionSum);
73  return this->CalculateAsymmetry(useEnergy, vertexPosition2D, asymmetryClusters, localWeightedDirectionSum);
74 }
75 
76 //------------------------------------------------------------------------------------------------------------------------------------------
77 
78 bool LocalAsymmetryFeatureTool::CheckAngle(const CartesianVector &weightedDirectionSum, const CartesianVector &clusterDirection) const
79 {
80  if (!(weightedDirectionSum.GetMagnitudeSquared() > std::numeric_limits<float>::epsilon()))
81  return true;
82 
83  const float cosOpeningAngle(weightedDirectionSum.GetCosOpeningAngle(clusterDirection));
84  return std::fabs(cosOpeningAngle) > m_minAsymmetryCosAngle;
85 }
86 
87 //------------------------------------------------------------------------------------------------------------------------------------------
88 
89 StatusCode LocalAsymmetryFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
90 {
91  PANDORA_RETURN_RESULT_IF_AND_IF(
92  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinAsymmetryCosAngle", m_minAsymmetryCosAngle));
93 
94  PANDORA_RETURN_RESULT_IF_AND_IF(
95  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxAsymmetryNClusters", m_maxAsymmetryNClusters));
96 
98 }
99 
100 } // namespace lar_content
float GetAsymmetryForView(const pandora::CartesianVector &vertexPosition2D, const VertexSelectionBaseAlgorithm::SlidingFitDataList &slidingFitDataList, const VertexSelectionBaseAlgorithm::ShowerClusterList &) const override
Get the local asymmetry feature in a given view.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle) override
virtual float CalculateAsymmetry(const bool useEnergyMetrics, const pandora::CartesianVector &vertexPosition2D, const pandora::ClusterVector &asymmetryClusters, const pandora::CartesianVector &localWeightedDirectionSum) const
Calculate the asymmetry feature.
bool CheckAngle(const pandora::CartesianVector &weightedDirectionSum, const pandora::CartesianVector &clusterDirection) const
Check whether a cluster&#39;s direction agrees with the current weighted direction.
float m_maxAsymmetryDistance
The max distance between cluster (any hit) and vertex to calculate asymmetry score.
TFile f
Definition: plotHisto.C:6
Header file for the cluster helper class.
Header file for the local asymmetry feature tool class.
AsymmetryFeatureBaseTool class.
void IncrementAsymmetryParameters(const float weight, const pandora::CartesianVector &clusterDirection, pandora::CartesianVector &localWeightedDirectionSum) const
Increment the asymmetry parameters.
float m_minAsymmetryCosAngle
The min opening angle cosine used to determine viability of asymmetry score.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
unsigned int m_maxAsymmetryNClusters
The max number of associated clusters to calculate the asymmetry.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.