LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
EnergyDepositionAsymmetryFeatureTool.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 EnergyDepositionAsymmetryFeatureTool::EnergyDepositionAsymmetryFeatureTool() :
21 {
22 }
23 
24 //------------------------------------------------------------------------------------------------------------------------------------------
25 
26 float EnergyDepositionAsymmetryFeatureTool::CalculateAsymmetry(const bool useEnergyMetrics, const CartesianVector &vertexPosition2D,
27  const ClusterVector &clusterVector, const CartesianVector &localWeightedDirectionSum) const
28 {
29  // Project every hit onto local event axis direction and record side of the projected vtx position on which it falls
30  float beforeVtxEnergy(0.f), afterVtxEnergy(0.f);
31  unsigned int beforeVtxHits(0), afterVtxHits(0);
32 
33  const CartesianVector localWeightedDirection(localWeightedDirectionSum.GetUnitVector());
34  const float evtProjectedVtxPos(vertexPosition2D.GetDotProduct(localWeightedDirection));
35 
36  float minBeforeProjectedPos(std::numeric_limits<float>::max());
37  float maxBeforeProjectedPos(-std::numeric_limits<float>::max());
38 
39  float minAfterProjectedPos(std::numeric_limits<float>::max());
40  float maxAfterProjectedPos(-std::numeric_limits<float>::max());
41 
42  for (const Cluster *const pCluster : clusterVector)
43  {
44  CaloHitList caloHitList;
45  pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
46 
47  CaloHitVector caloHitVector(caloHitList.begin(), caloHitList.end());
48  std::sort(caloHitVector.begin(), caloHitVector.end(), LArClusterHelper::SortHitsByPosition);
49 
50  for (const CaloHit *const pCaloHit : caloHitVector)
51  {
52  if (pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection) < evtProjectedVtxPos)
53  {
54  minBeforeProjectedPos = std::min(minBeforeProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
55  maxBeforeProjectedPos = std::max(maxBeforeProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
56 
57  beforeVtxEnergy += pCaloHit->GetElectromagneticEnergy();
58  ++beforeVtxHits;
59  }
60 
61  else
62  {
63  minAfterProjectedPos = std::min(minAfterProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
64  maxAfterProjectedPos = std::max(maxAfterProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
65 
66  afterVtxEnergy += pCaloHit->GetElectromagneticEnergy();
67  ++afterVtxHits;
68  }
69  }
70  }
71 
72  // Use energy metrics if possible, otherwise fall back on hit counting.
73  const unsigned int totalHits(beforeVtxHits + afterVtxHits);
74 
75  const float beforeLength(std::fabs(maxBeforeProjectedPos - minBeforeProjectedPos));
76  const float afterLength(std::fabs(maxAfterProjectedPos - minAfterProjectedPos));
77 
78  const float beforeVtxEnergyDeposition(beforeLength < std::numeric_limits<float>::epsilon() ? 0 : beforeVtxEnergy / beforeLength);
79 
80  const float afterVtxEnergyDeposition(afterLength < std::numeric_limits<float>::epsilon() ? 0 : afterVtxEnergy / afterLength);
81 
82  const float totalEnergyDeposition(beforeVtxEnergyDeposition + afterVtxEnergyDeposition);
83 
84  if (useEnergyMetrics && totalEnergyDeposition > std::numeric_limits<float>::epsilon())
85  return std::fabs((afterVtxEnergyDeposition - beforeVtxEnergyDeposition)) / totalEnergyDeposition;
86 
87  if (0 == totalHits)
88  throw StatusCodeException(STATUS_CODE_FAILURE);
89 
90  const float beforeVtxHitDeposition(beforeLength < std::numeric_limits<float>::epsilon() ? 0 : beforeVtxHits / beforeLength);
91 
92  const float afterVtxHitDeposition(afterLength < std::numeric_limits<float>::epsilon() ? 0 : afterVtxHits / afterLength);
93 
94  const float totalHitDeposition(beforeVtxHitDeposition + afterVtxHitDeposition);
95 
96  if (totalHitDeposition > std::numeric_limits<float>::epsilon())
97  return std::fabs((afterVtxHitDeposition - beforeVtxHitDeposition)) / totalHitDeposition;
98 
99  return 0.f;
100 }
101 
102 //------------------------------------------------------------------------------------------------------------------------------------------
103 
104 StatusCode EnergyDepositionAsymmetryFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
105 {
107 }
108 
109 } // namespace lar_content
float CalculateAsymmetry(const bool useEnergyMetrics, const pandora::CartesianVector &vertexPosition2D, const pandora::ClusterVector &clusterVector, const pandora::CartesianVector &localWeightedDirectionSum) const override
Calculate the energy deposition asymmetry feature.
Header file for the energy deposition asymmetry feature tool class.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
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.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle) override
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle) override
std::vector< art::Ptr< recob::Cluster > > ClusterVector