ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtEstimatorMethods.cxx
Go to the documentation of this file.
1 #include "AtEstimatorMethods.h"
2 
3 #include "AtContainerManip.h"
4 #include "AtHit.h" // for AtHit
5 #include "AtPattern.h"
6 #include "AtPatternY.h"
7 
8 #include <algorithm> // for max_element, nth_element, max
9 #include <cassert>
10 #include <cmath> // for exp, sqrt, isinf, log, M_PI
11 using namespace SampleConsensus;
12 
13 int SampleConsensus::EvaluateChi2(AtPatterns::AtPattern *model, const std::vector<const AtHit *> &hitArray,
14  double distanceThreshold)
15 {
16  int nbInliers = 0;
17  double weight = 0;
18 
19  for (const auto &hit : hitArray) {
20  auto &pos = hit->GetPosition();
21  double error = model->DistanceToPattern(pos);
22  error = error * error;
23  if (error < (distanceThreshold * distanceThreshold)) {
24  nbInliers++;
25  weight += error;
26  }
27  }
28  model->SetChi2(weight / nbInliers);
29  return nbInliers;
30 }
31 int SampleConsensus::EvaluateRansac(AtPatterns::AtPattern *model, const std::vector<const AtHit *> &hitArray,
32  double distanceThreshold)
33 {
34  int nbInliers = 0;
35  for (const auto &hit : hitArray) {
36  auto &pos = hit->GetPosition();
37  double error = model->DistanceToPattern(pos);
38  error = error * error;
39  if (error < (distanceThreshold * distanceThreshold)) {
40  nbInliers++;
41  }
42  }
43  model->SetChi2(1.0 / nbInliers);
44  return nbInliers;
45 }
46 
47 int SampleConsensus::EvaluateYRansac(AtPatterns::AtPattern *model, const std::vector<const AtHit *> &hitArray,
48  double distanceThreshold)
49 {
50  auto *yModel = dynamic_cast<AtPatterns::AtPatternY *>(model);
51  assert(yModel != nullptr);
52 
53  int nbInliers = 0;
54  for (const auto &hit : hitArray) {
55  auto &pos = hit->GetPosition();
56  if (yModel->GetPointAssignment(pos) >= 2)
57  continue;
58  double error = model->DistanceToPattern(pos);
59  error = error * error;
60  if (error < (distanceThreshold * distanceThreshold)) {
61  nbInliers++;
62  }
63  }
64  model->SetChi2(1.0 / nbInliers);
65  return nbInliers;
66 }
67 
68 int SampleConsensus::EvaluateMlesac(AtPatterns::AtPattern *model, const std::vector<const AtHit *> &hitArray,
69  double distanceThreshold)
70 {
71  double sigma = distanceThreshold / 1.96;
72  double dataSigma2 = sigma * sigma;
73 
74  // Calculate min and max errors
75  double minError = 1e5, maxError = -1e5;
76  for (const auto &hit : hitArray) {
77  double error = model->DistanceToPattern(hit->GetPosition());
78  if (error < minError)
79  minError = error;
80  if (error > maxError)
81  maxError = error;
82  }
83 
84  // Estimate the inlier ratio using EM
85  const double nu = maxError - minError;
86  double gamma = 0.5;
87  for (int iter = 0; iter < 5; iter++) {
88  double sumPosteriorProb = 0;
89  const double probOutlier = (1 - gamma) / nu;
90  const double probInlierCoeff = gamma / sqrt(2 * M_PI * dataSigma2);
91 
92  for (const auto &hit : hitArray) {
93  double error = model->DistanceToPattern(hit->GetPosition());
94  double probInlier = probInlierCoeff * exp(-0.5 * error * error / dataSigma2);
95  sumPosteriorProb += probInlier / (probInlier + probOutlier);
96  }
97  gamma = sumPosteriorProb / hitArray.size();
98  }
99 
100  double sumLogLikelihood = 0;
101  int nbInliers = 0;
102 
103  // Evaluate the model
104  const double probOutlier = (1 - gamma) / nu;
105  const double probInlierCoeff = gamma / sqrt(2 * M_PI * dataSigma2);
106  for (const auto &hit : hitArray) {
107  double error = model->DistanceToPattern(hit->GetPosition());
108  double probInlier = probInlierCoeff * exp(-0.5 * error * error / dataSigma2);
109  // if((probInlier + probOutlier)>0) sumLogLikelihood = sumLogLikelihood - log(probInlier + probOutlier);
110 
111  if (error * error < dataSigma2) {
112  if ((probInlier + probOutlier) > 0)
113  sumLogLikelihood = sumLogLikelihood - log(probInlier + probOutlier);
114  nbInliers++;
115  }
116  }
117  double scale = sumLogLikelihood / nbInliers;
118  // std::cout <<sumLogLikelihood<< " Likelihood " << '\n';
119  if (sumLogLikelihood < 0 || std::isinf(sumLogLikelihood))
120  scale = 0;
121 
122  model->SetChi2(scale);
123  return nbInliers;
124 }
125 
126 int SampleConsensus::EvaluateLmeds(AtPatterns::AtPattern *model, const std::vector<const AtHit *> &hitArray,
127  double distanceThreshold)
128 {
129  std::vector<double> errorsVec;
130  // Loop through point and if it is an inlier, then add the error**2 to weight
131  for (const auto &hit : hitArray) {
132 
133  double error = model->DistanceToPattern(hit->GetPosition());
134  error = error * error;
135  if (error < (distanceThreshold * distanceThreshold))
136  errorsVec.push_back(error);
137  }
138  model->SetChi2(ContainerManip::GetMedian(errorsVec) / errorsVec.size());
139  return errorsVec.size();
140 }
141 
142 int SampleConsensus::EvaluateWeightedRansac(AtPatterns::AtPattern *model, const std::vector<const AtHit *> &hitArray,
143  double distanceThreshold)
144 {
145  int nbInliers = 0;
146  double totalCharge = 0;
147  double weight = 0;
148 
149  for (const auto &hit : hitArray) {
150  auto &pos = hit->GetPosition();
151  double error = model->DistanceToPattern(pos);
152  error = error * error;
153  if (error < (distanceThreshold * distanceThreshold)) {
154  nbInliers++;
155  totalCharge += hit->GetCharge();
156  weight += error * hit->GetCharge();
157  }
158  }
159  model->SetChi2(weight / totalCharge);
160  return nbInliers;
161 }
scale
constexpr auto scale
Definition: AtHitCluster.cxx:15
AtPattern.h
AtPatterns::AtPattern
Describes a shape in 3D space.
Definition: AtPattern.h:40
SampleConsensus::EvaluateRansac
int EvaluateRansac(AtPatterns::AtPattern *model, const std::vector< const AtHit * > &hitArray, double distanceThreshold)
Implementation of RANSAC estimator.
Definition: AtEstimatorMethods.cxx:31
SampleConsensus::EvaluateChi2
int EvaluateChi2(AtPatterns::AtPattern *model, const std::vector< const AtHit * > &hitArray, double distanceThreshold)
Implementation of estimator that minimizes chi2.
Definition: AtEstimatorMethods.cxx:13
AtHit.h
AtEstimatorMethods.h
SampleConsensus::EvaluateWeightedRansac
int EvaluateWeightedRansac(AtPatterns::AtPattern *model, const std::vector< const AtHit * > &hitArray, double distanceThreshold)
Implementation of RANSAC estimator using charge weighting.
Definition: AtEstimatorMethods.cxx:142
SampleConsensus::EvaluateLmeds
int EvaluateLmeds(AtPatterns::AtPattern *model, const std::vector< const AtHit * > &hitArray, double distanceThreshold)
Implementation of LMedS estimator.
Definition: AtEstimatorMethods.cxx:126
ContainerManip::GetMedian
T GetMedian(std::vector< T > &vec)
Definition: AtContainerManip.h:57
AtContainerManip.h
AtPatternY.h
AtPatterns::AtPattern::DistanceToPattern
virtual Double_t DistanceToPattern(const XYZPoint &point) const =0
Closest distance to pattern.
AtPatterns::AtPattern::SetChi2
void SetChi2(double chi2)
Definition: AtPattern.h:143
AtPatterns::AtPatternY
Describes a Y track.
Definition: AtPatternY.h:29
SampleConsensus
Definition: AtEstimatorMethods.h:9
SampleConsensus::EvaluateYRansac
int EvaluateYRansac(AtPatterns::AtPattern *model, const std::vector< const AtHit * > &hitArray, double distanceThreshold)
Implementation of RANSAC estimator ignoring beam component of y.
Definition: AtEstimatorMethods.cxx:47
SampleConsensus::EvaluateMlesac
int EvaluateMlesac(AtPatterns::AtPattern *model, const std::vector< const AtHit * > &hitArray, double distanceThreshold)
Implementation of MLESAC estimator.
Definition: AtEstimatorMethods.cxx:68