LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
AsymmetryFeatureBaseTool.cc
Go to the documentation of this file.
1 
10 #include "Pandora/AlgorithmHeaders.h"
13 
14 using namespace pandora;
15 
16 namespace lar_content
17 {
18 
19 AsymmetryFeatureBaseTool::AsymmetryFeatureBaseTool() :
20  m_maxAsymmetryDistance(5.f)
21 {
22 }
23 
24 //------------------------------------------------------------------------------------------------------------------------------------------
25 
27  const Vertex *const pVertex, const VertexSelectionBaseAlgorithm::SlidingFitDataListMap &slidingFitDataListMap,
29  const VertexSelectionBaseAlgorithm::ShowerClusterListMap &showerClusterListMap, const float, float &)
30 {
31  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
32  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
33 
34  float asymmetry(0.f);
35 
36  asymmetry += this->GetAsymmetryForView(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), TPC_VIEW_U),
37  slidingFitDataListMap.at(TPC_VIEW_U),
38  showerClusterListMap.empty() ? VertexSelectionBaseAlgorithm::ShowerClusterList() : showerClusterListMap.at(TPC_VIEW_U));
39 
40  asymmetry += this->GetAsymmetryForView(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), TPC_VIEW_V),
41  slidingFitDataListMap.at(TPC_VIEW_V),
42  showerClusterListMap.empty() ? VertexSelectionBaseAlgorithm::ShowerClusterList() : showerClusterListMap.at(TPC_VIEW_V));
43 
44  asymmetry += this->GetAsymmetryForView(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), TPC_VIEW_W),
45  slidingFitDataListMap.at(TPC_VIEW_W),
46  showerClusterListMap.empty() ? VertexSelectionBaseAlgorithm::ShowerClusterList() : showerClusterListMap.at(TPC_VIEW_W));
47 
48  featureVector.push_back(asymmetry);
49 }
50 
51 //------------------------------------------------------------------------------------------------------------------------------------------
52 
54  const float weight, const CartesianVector &clusterDirection, CartesianVector &localWeightedDirectionSum) const
55 {
56  // If the new axis direction is at an angle of greater than 90 deg to the current axis direction, flip it 180 degs.
57  CartesianVector newDirection(clusterDirection);
58 
59  if (localWeightedDirectionSum.GetMagnitudeSquared() > std::numeric_limits<float>::epsilon())
60  {
61  if (localWeightedDirectionSum.GetCosOpeningAngle(clusterDirection) < 0.f)
62  newDirection *= -1.f;
63  }
64 
65  localWeightedDirectionSum += newDirection * weight;
66 }
67 
68 //------------------------------------------------------------------------------------------------------------------------------------------
69 
70 float AsymmetryFeatureBaseTool::CalculateAsymmetry(const bool useEnergyMetrics, const CartesianVector &vertexPosition2D,
71  const ClusterVector &asymmetryClusters, const CartesianVector &localWeightedDirectionSum) const
72 {
73  // Project every hit onto local event axis direction and record side of the projected vtx position on which it falls
74  float beforeVtxHitEnergy(0.f), afterVtxHitEnergy(0.f);
75  unsigned int beforeVtxHitCount(0), afterVtxHitCount(0);
76 
77  const CartesianVector localWeightedDirection(localWeightedDirectionSum.GetUnitVector());
78  const float evtProjectedVtxPos(vertexPosition2D.GetDotProduct(localWeightedDirection));
79 
80  for (const Cluster *const pCluster : asymmetryClusters)
81  {
82  CaloHitList caloHitList;
83  pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
84 
85  CaloHitVector caloHitVector(caloHitList.begin(), caloHitList.end());
86  std::sort(caloHitVector.begin(), caloHitVector.end(), LArClusterHelper::SortHitsByPosition);
87 
88  for (const CaloHit *const pCaloHit : caloHitVector)
89  {
90  if (pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection) < evtProjectedVtxPos)
91  {
92  beforeVtxHitEnergy += pCaloHit->GetElectromagneticEnergy();
93  ++beforeVtxHitCount;
94  }
95  else
96  {
97  afterVtxHitEnergy += pCaloHit->GetElectromagneticEnergy();
98  ++afterVtxHitCount;
99  }
100  }
101  }
102 
103  // Use energy metrics if possible, otherwise fall back on hit counting.
104  const float totHitEnergy(beforeVtxHitEnergy + afterVtxHitEnergy);
105  const unsigned int totHitCount(beforeVtxHitCount + afterVtxHitCount);
106 
107  if (useEnergyMetrics && (totHitEnergy > std::numeric_limits<float>::epsilon()))
108  return std::fabs((afterVtxHitEnergy - beforeVtxHitEnergy)) / totHitEnergy;
109 
110  if (0 == totHitCount)
111  throw StatusCodeException(STATUS_CODE_FAILURE);
112 
113  return std::fabs((static_cast<float>(afterVtxHitCount) - static_cast<float>(beforeVtxHitCount))) / static_cast<float>(totHitCount);
114 }
115 
116 //------------------------------------------------------------------------------------------------------------------------------------------
117 
118 StatusCode AsymmetryFeatureBaseTool::ReadSettings(const TiXmlHandle xmlHandle)
119 {
120  PANDORA_RETURN_RESULT_IF_AND_IF(
121  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxAsymmetryDistance", m_maxAsymmetryDistance));
122 
123  return STATUS_CODE_SUCCESS;
124 }
125 
126 } // namespace lar_content
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:75
virtual float CalculateAsymmetry(const bool useEnergyMetrics, const pandora::CartesianVector &vertexPosition2D, const pandora::ClusterVector &asymmetryClusters, const pandora::CartesianVector &localWeightedDirectionSum) const
Calculate the asymmetry feature.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
virtual float GetAsymmetryForView(const pandora::CartesianVector &vertexPosition2D, const VertexSelectionBaseAlgorithm::SlidingFitDataList &slidingFitDataList, const VertexSelectionBaseAlgorithm::ShowerClusterList &showerClusterList) const =0
Get the asymmetry feature for a given view.
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 geometry helper class.
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
std::map< pandora::HitType, const pandora::ClusterList & > ClusterListMap
Map array of cluster lists for passing to tools.
double weight
Definition: plottest35.C:25
Header file for the global asymmetry feature tool class.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const VertexSelectionBaseAlgorithm *const pAlgorithm, const pandora::Vertex *const pVertex, const VertexSelectionBaseAlgorithm::SlidingFitDataListMap &slidingFitDataListMap, const VertexSelectionBaseAlgorithm::ClusterListMap &, const VertexSelectionBaseAlgorithm::KDTreeMap &, const VertexSelectionBaseAlgorithm::ShowerClusterListMap &showerClusterListMap, const float, float &)
Run the tool.
std::map< pandora::HitType, const SlidingFitDataList > SlidingFitDataListMap
Map of sliding fit data lists for passing to tools.
void IncrementAsymmetryParameters(const float weight, const pandora::CartesianVector &clusterDirection, pandora::CartesianVector &localWeightedDirectionSum) const
Increment the asymmetry parameters.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)