ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtPatternCircle2D.cxx
Go to the documentation of this file.
1 #include "AtPatternCircle2D.h"
2 
3 #include <Math/Point2D.h>
4 #include <Math/Point2Dfwd.h> // for XYPoint
5 #include <Math/Point3D.h>
6 #include <Math/Vector2D.h> // for DisplacementVector2D
7 #include <Math/Vector3D.h> // for DisplacementVector3D
8 #include <Math/Vector3Dfwd.h> // for RhoZPhiVector
9 #include <TEveLine.h>
10 
11 #include <algorithm> // for max
12 #include <cmath> // for fabs, isfinite, sqrt
13 #include <memory> // for allocator_traits<>::value_type
14 
15 class TEveElement;
17 using namespace AtPatterns;
18 
21 {
22  return AtPattern::GetEveLine(0, 2 * M_PI, 1000);
23 }
24 
25 void AtPatternCircle2D::DefinePattern(const std::vector<XYZPoint> &points)
26 {
27  XYPoint p1 = {points[0].X(), points[0].Y()};
28  XYPoint p2 = {points[1].X(), points[1].Y()};
29  XYPoint p3 = {points[2].X(), points[2].Y()};
30 
31  double a = 2 * (p2 - p1).X();
32  double b = 2 * (p2 - p1).Y();
33  double c = p2.Mag2() - p1.Mag2();
34  double d = 2 * (p3 - p2).X();
35  double e = 2 * (p3 - p2).Y();
36  double f = p3.Mag2() - p2.Mag2();
37 
38  XYPoint center((b * f - e * c), (d * c - a * f));
39  center /= (b * d - e * a);
40 
41  fPatternPar.clear();
42  fPatternPar.push_back(center.X());
43  fPatternPar.push_back(center.Y());
44  fPatternPar.push_back((center - p1).R());
45 }
46 
47 Double_t AtPatternCircle2D::DistanceToPattern(const XYZPoint &point) const
48 {
49  auto pointToCenter = point - GetCenter();
50  return std::abs(pointToCenter.Rho() - GetRadius());
51 }
52 
54 {
55  auto pointToCenter = point - GetCenter();
56  return GetPointAt(pointToCenter.Phi());
57 }
58 
60 {
61  return XYZPoint(GetCenter() + ROOT::Math::RhoZPhiVector(GetRadius(), 0, theta));
62 }
63 
64 void AtPatternCircle2D::FitPattern(const std::vector<XYZPoint> &points, const std::vector<double> &charge)
65 {
66 
67  // 2D circle fit, due to Taubin, based on the journal article
68  // G. Taubin, "Estimation Of Planar Curves, Surfaces And Nonplanar
69  // Space Curves Defined By Implicit Equations, With
70  // Applications To Edge And Range Image Segmentation",
71  // IEEE Trans. PAMI, Vol. 13, pages 1115-1138, (1991)
72  //----- adapted from: https://people.cas.uab.edu/~mosya/cl/CPPcircle.html
73 
74  int iter, IterMAX = 99;
75  int Niliers = 0;
76  double Xi, Yi, Zi;
77  double Xm = 0, Ym = 0, Zm = 0;
78  double Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Cov_xy, Var_z;
79  double A0, A1, A2, A22, A3, A33;
80  double Dy, xnew, x, ynew, y;
81  double DET, Xcenter, Ycenter;
82  double Q = 0;
83  double a, b, r;
84 
85  bool doChargeWeight = points.size() == charge.size();
86 
87  for (int i = 0; i < points.size(); ++i) {
88  const auto hitQ = doChargeWeight ? charge[i] : 1;
89  const auto &pos = points[i];
90  Q += hitQ / 10.;
91  Xm += pos.X() * hitQ / 10.;
92  Ym += pos.Y() * hitQ / 10.;
93  // Zm += pos.Z() * hitQ / 10.;
94  }
95 
96  Xm /= Q;
97  Ym /= Q;
98  // Zm /= Q;
99 
100  Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
101 
102  for (const auto &pos : points) {
103  Xi = pos.X() - Xm; // centered x-coordinates
104  Yi = pos.Y() - Ym; // centered y-coordinates
105  Zi = Xi * Xi + Yi * Yi;
106 
107  Mxy += Xi * Yi;
108  Mxx += Xi * Xi;
109  Myy += Yi * Yi;
110  Mxz += Xi * Zi;
111  Myz += Yi * Zi;
112  Mzz += Zi * Zi;
113  }
114 
115  Mxx /= points.size();
116  Myy /= points.size();
117  Mxy /= points.size();
118  Mxz /= points.size();
119  Myz /= points.size();
120  Mzz /= points.size();
121 
122  // computing coefficients of the characteristic polynomial
123 
124  Mz = Mxx + Myy;
125  Cov_xy = Mxx * Myy - Mxy * Mxy;
126  Var_z = Mzz - Mz * Mz;
127  A3 = 4.0 * Mz;
128  A2 = -3.0 * Mz * Mz - Mzz;
129  A1 = Var_z * Mz + 4.0 * Cov_xy * Mz - Mxz * Mxz - Myz * Myz;
130  A0 = Mxz * (Mxz * Myy - Myz * Mxy) + Myz * (Myz * Mxx - Mxz * Mxy) - Var_z * Cov_xy;
131  A22 = A2 + A2;
132  A33 = A3 + A3 + A3;
133 
134  // finding the root of the characteristic polynomial
135  // using Newton's method starting at x=0
136  // (it is guaranteed to converge to the right root)
137 
138  for (x = 0., y = A0, iter = 0; iter < IterMAX; iter++) // usually, 4-6 iterations are enough
139  {
140  Dy = A1 + x * (A22 + A33 * x);
141  xnew = x - y / Dy;
142  if ((xnew == x) || (!std::isfinite(xnew)))
143  break;
144  ynew = A0 + xnew * (A1 + xnew * (A2 + xnew * A3));
145  if (std::abs(ynew) >= std::abs(y))
146  break;
147  x = xnew;
148  y = ynew;
149  }
150 
151  // computing paramters of the fitting circle
152 
153  DET = x * x - x * Mz + Cov_xy;
154  Xcenter = (Mxz * (Myy - x) - Myz * Mxy) / DET / 2.0;
155  Ycenter = (Myz * (Mxx - x) - Mxz * Mxy) / DET / 2.0;
156 
157  // assembling the output
158 
159  a = Xcenter + Xm;
160  b = Ycenter + Ym;
161  r = sqrt(Xcenter * Xcenter + Ycenter * Ycenter + Mz);
162 
163  fPatternPar.clear();
164  fPatternPar.push_back(a);
165  fPatternPar.push_back(b);
166  fPatternPar.push_back(r);
167  fChi2 = fabs(Mz - r * r); // TODO: Is this a chi2 value?
168 
169  // return fabs(Mz - r * r);
170 }
f
double(* f)(double t, const double *par)
Definition: lmcurve.cxx:21
AtPatterns::AtPatternCircle2D::DistanceToPattern
virtual Double_t DistanceToPattern(const XYZPoint &point) const override
Closest distance to pattern.
Definition: AtPatternCircle2D.cxx:47
XYPoint
ROOT::Math::XYPoint XYPoint
Definition: AtPatternCircle2D.cxx:16
AtPatterns::AtPatternCircle2D::FitPattern
virtual void FitPattern(const std::vector< XYZPoint > &points, const std::vector< double > &charge) override
Definition: AtPatternCircle2D.cxx:64
AtPatterns::AtPattern
Describes a shape in 3D space.
Definition: AtPattern.h:40
AtPatterns::AtPatternCircle2D::GetRadius
double GetRadius() const
Definition: AtPatternCircle2D.h:31
AtPatterns::AtPatternCircle2D::AtPatternCircle2D
AtPatternCircle2D()
Definition: AtPatternCircle2D.cxx:19
AtPatterns::AtPatternCircle2D::ClosestPointOnPattern
virtual XYZPoint ClosestPointOnPattern(const XYZPoint &point) const override
Closest point on pattern.
Definition: AtPatternCircle2D.cxx:53
y
const double * y
Definition: lmcurve.cxx:20
AtPatterns::AtPattern::GetEveLine
TEveLine * GetEveLine(double tMin, double tMax, int n) const
Get visual representation of pattern.
Definition: AtPattern.cxx:63
AtPatterns::AtPattern::fChi2
Double_t fChi2
Definition: AtPattern.h:46
AtPatterns::AtPatternCircle2D::GetCenter
XYZPoint GetCenter() const
Definition: AtPatternCircle2D.h:30
AtPatterns
Definition: AtFissionEvent.h:21
AtPatterns::AtPatternCircle2D::GetEveElement
virtual TEveElement * GetEveElement() const override
Get visual representation of pattern.
Definition: AtPatternCircle2D.cxx:20
AtPatternCircle2D.h
AtPatterns::AtPattern::fPatternPar
std::vector< Double_t > fPatternPar
Definition: AtPattern.h:45
AtPatterns::AtPatternCircle2D::GetPointAt
virtual XYZPoint GetPointAt(double theta) const override
Point on pattern at t.
Definition: AtPatternCircle2D.cxx:59
c
constexpr auto c
Definition: AtRadialChargeModel.cxx:20
AtPatterns::AtPattern::XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtPattern.h:42
AtPatterns::AtPatternCircle2D::DefinePattern
virtual void DefinePattern(const std::vector< XYZPoint > &points) override
Define based on points.
Definition: AtPatternCircle2D.cxx:25