CbmRoot
Loading...
Searching...
No Matches
CbmRichRingFitterTAU.cxx
Go to the documentation of this file.
1/* Copyright (C) 2006-2016 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Alexander Ayriyan, Gennadi Ososkov, Claudia Hoehne, Semen Lebedev, Denis Bertini [committer] */
4
12
13#include <cmath>
14#include <iostream>
15#include <vector>
16
17using std::cout;
18using std::endl;
19using std::fabs;
20using std::pow;
21using std::sqrt;
22using std::vector;
23
25
27
29{
30 int nofHits = ring->GetNofHits();
31
32 double radius = -1.;
33 double centerX = -1.;
34 double centerY = -1.;
35
36 if (nofHits < 3) {
37 ring->SetRadius(0.);
38 ring->SetCenterX(0.);
39 ring->SetCenterY(0.);
40 return;
41 }
42
43 int iter, iterMax = 20;
44
45 int riterMax = 4;
46
47 double Xi, Yi, Zi;
48 double M0, Mx, My, Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Mxz2, Myz2, Cov_xy;
49 double A0, A1, A2, A22, A3, A33, epsilon = 0.000000000001;
50 double Dy, xnew, xold, ynew, yold = 100000000000.;
51 double GAM, DET;
52 //double Xcenter = -1.,Ycenter = -1.,Radius = -1.;
53
54 double sigma;
55 double ctsigma;
56 double dist, weight;
57 const double ct = 3.;
58 const double copt = 0.2;
59 const double zero = 0.0001;
60 const double SigmaMin = 0.18;
61 double amax = -100000;
62 double amin = 100000;
63 double sig1 = 0.;
64 double sig2 = 0.;
65
66 vector<double> x; // x coordinates of hits;
67 vector<double> y; // y coordinates of hits;
68 vector<double> a; // amplitudes of hits;
69 vector<double> w; // weights of points;
70 vector<double> d; // distance between points and circle;
71
73 riterMax = 1;
74 }
75 if (fRobust == 1) {
76 riterMax = 4;
77 }
78 if (fRobust == 2) {
79 riterMax = 4;
80 }
81
82 for (int i = 0; i < nofHits; i++) {
83 x.push_back(ring->GetHit(i).fX);
84 y.push_back(ring->GetHit(i).fY);
85 a.push_back(1.);
86 }
87
88 for (int i = 0; i < nofHits; i++) {
89 if (a[i] > amax) amax = a[i];
90 if (a[i] < amin) amin = a[i];
91 }
92
93 for (int i = 0; i < nofHits; i++)
94 w.push_back(1.);
95
96 for (int riter = 0; riter < riterMax; riter++) {
97 M0 = 0;
98 Mx = My = 0.;
99
100 for (int i = 0; i < nofHits; i++) {
101 Mx += x[i] * w[i];
102 My += y[i] * w[i];
103 M0 += w[i];
104 }
105
106 Mx /= M0;
107 My /= M0;
108
109 //computing moments (note: all moments are normed, i.e. divided by N)
110 Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
111
112 for (int i = 0; i < nofHits; i++) {
113 Xi = x[i] - Mx;
114 Yi = y[i] - My;
115 Zi = Xi * Xi + Yi * Yi;
116
117 Mxy += Xi * Yi * w[i];
118 Mxx += Xi * Xi * w[i];
119 Myy += Yi * Yi * w[i];
120 Mxz += Xi * Zi * w[i];
121 Myz += Yi * Zi * w[i];
122 Mzz += Zi * Zi * w[i];
123 }
124 Mxx /= M0;
125 Myy /= M0;
126 Mxy /= M0;
127 Mxz /= M0;
128 Myz /= M0;
129 Mzz /= M0;
130
131 // computing the coefficients of the characteristic polynomial
132 Mz = Mxx + Myy;
133 Cov_xy = Mxx * Myy - Mxy * Mxy;
134 Mxz2 = Mxz * Mxz;
135 Myz2 = Myz * Myz;
136
137 A3 = 4. * Mz;
138 A2 = -3. * Mz * Mz - Mzz;
139 A1 = Mzz * Mz + 4. * Cov_xy * Mz - Mxz2 - Myz2 - Mz * Mz * Mz;
140 A0 = Mxz2 * Myy + Myz2 * Mxx - Mzz * Cov_xy - 2. * Mxz * Myz * Mxy + Mz * Mz * Cov_xy;
141
142 A22 = A2 + A2;
143 A33 = A3 + A3 + A3;
144 iter = 0;
145 xnew = 0.;
146
147 // Newton's method starting at x=0
148 for (iter = 0; iter < iterMax; iter++) {
149 ynew = A0 + xnew * (A1 + xnew * (A2 + xnew * A3));
150
151 if (fabs(ynew) > fabs(yold)) {
152 xnew = 0.;
153 break;
154 }
155
156 Dy = A1 + xnew * (A22 + xnew * A33);
157 xold = xnew;
158 xnew = xold - ynew / Dy;
159
160 if (fabs((xnew - xold) / xnew) < epsilon) break;
161 }
162
163 if (iter == iterMax - 1) {
164 //printf("Newton3 does not converge in %d iterations\n",iterMax);
165 xnew = 0.;
166 }
167 if (xnew < 0.) {
168 iter = 30;
169 // printf("Negative root: x=%f\n",xnew);
170 }
171
172 // computing the circle parameters
173 GAM = -Mz;
174 DET = xnew * xnew - xnew * Mz + Cov_xy;
175 centerX = (Mxz * (Myy - xnew) - Myz * Mxy) / DET / 2.;
176 centerY = (Myz * (Mxx - xnew) - Mxz * Mxy) / DET / 2.;
177 radius = sqrt(centerX * centerX + centerY * centerY - GAM);
178 centerX = (Mxz * (Myy - xnew) - Myz * Mxy) / DET / 2. + Mx;
179 centerY = (Myz * (Mxx - xnew) - Mxz * Mxy) / DET / 2. + My;
180
181 if (riter < riterMax - 1) {
182 for (int i = 0; i < nofHits; i++) {
183 dist = sqrt(pow((centerX - x[i]), 2) + pow((centerY - y[i]), 2)) - radius;
184 dist = fabs(dist);
185 d.push_back(dist);
186 }
187
188 for (unsigned int i = 0; i < d.size(); i++) {
189 sig1 += w[i] * d[i] * d[i];
190 sig2 += w[i];
191 }
192 sigma = sqrt(sig1 / sig2);
193 if (sigma < SigmaMin) sigma = SigmaMin;
194 ctsigma = ct * sigma;
195 sig1 = 0.;
196 sig2 = 0.;
197
198 w.clear();
199 for (unsigned int i = 0; i < d.size(); i++) {
200 if (fRobust == 1) {
201 if (d[i] <= ctsigma) {
202 weight = pow((1 - pow((d[i] / ctsigma), 2)), 2);
203 if (weight < zero) weight = zero;
204 }
205 else {
206 weight = zero;
207 }
208 w.push_back(weight);
209 }
210 if (fRobust == 2 || fRobust == 3) {
211 sigma *= 2;
212 weight = 1 + copt;
213 weight /= 1 + copt * exp(pow((d[i] / sigma), 2));
214 if (weight < zero) weight = zero;
215 w.push_back(weight);
216 }
217 }
218 d.clear();
219 }
220 }
221 x.clear();
222 y.clear();
223 a.clear();
224 w.clear();
225
226 ring->SetRadius(radius);
227 ring->SetCenterX(centerX);
228 ring->SetCenterY(centerY);
229
230 CalcChi2(ring);
231}
Here the ring is fitted with the TAU algorithm from A. Ayriyan/ G. Ososkov.
friend fvec sqrt(const fvec &a)
friend fvec exp(const fvec &a)
virtual void CalcChi2(CbmRichRingLight *ring)
Calculate chi2 for circle fitting algorithms.
CbmRichRingFitterTAU()
Default constructor.
virtual void DoFit(CbmRichRingLight *ring)
Inherited from CbmRichRingFitterBase.
virtual ~CbmRichRingFitterTAU()
Destructor.
void SetRadius(float r)
void SetCenterY(float y)
int GetNofHits() const
Return number of hits in ring.
CbmRichHitLight GetHit(int ind)
Return hit by the index.
void SetCenterX(float x)