CbmRoot
CbmRichRingFitterRobustCOP.cxx
Go to the documentation of this file.
1 
10 
11 #include <cmath>
12 #include <iostream>
13 
14 using std::cout;
15 using std::endl;
16 using std::fabs;
17 using std::sqrt;
18 
20 
22 
24  int nofHits = ring->GetNofHits();
25 
26  double radius = 0.;
27  double centerX = 0.;
28  double centerY = 0.;
29 
30  if (nofHits < 3) {
31  ring->SetCenterX(0.);
32  ring->SetCenterY(0.);
33  ring->SetRadius(0.);
34  return;
35  }
36 
37  int iter, iterMax = 20;
38  int i_iter, i_max_Robust = 4;
39  const int MinNuberOfHits = 3;
40  const int MaxNuberOfHits = 2000;
41  double Xi, Yi, Zi;
42  double M0, Mx, My, Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Mxz2, Myz2,
43  Cov_xy; //,temp;
44  double A0, A1, A2, A22, epsilon = 0.000000000001;
45  double Dy, xnew, xold, ynew, yold = 100000000000.;
46  double GAM, DET;
47  double SumS1 = 0., SumS2 = 0.;
48  double sigma;
49  double ctsigma;
50  double sigma_min = 0.05;
51  double dx, dy;
52  double d[MaxNuberOfHits];
53  double w[MaxNuberOfHits];
54  double ct = 7.;
55 
56  for (int i = 0; i < MaxNuberOfHits; i++)
57  w[i] = 1.;
58 
59  Mx = My = 0.;
60  for (int i = 0; i < nofHits; i++) {
61  Mx += ring->GetHit(i).fX;
62  My += ring->GetHit(i).fY;
63  }
64 
65  M0 = nofHits;
66  Mx /= M0;
67  My /= M0;
68 
69  for (i_iter = 0; i_iter < i_max_Robust; i_iter++) {
70  sigma = sigma_min;
71  if (i_iter != 0) {
72  for (int i = 0; i < nofHits; i++) {
73  dx = Mx - ring->GetHit(i).fX;
74  dy = My - ring->GetHit(i).fY;
75  d[i] = sqrt(dx * dx + dy * dy) - radius;
76  SumS1 += w[i] * d[i] * d[i];
77  SumS2 += w[i];
78  }
79  if (SumS2 == 0.) {
80  sigma = sigma_min;
81  } else {
82  sigma = sqrt(SumS1 / SumS2);
83  }
84  if (sigma < sigma_min) sigma = sigma_min;
85  ctsigma = ct * sigma;
86  SumS1 = 0.;
87  SumS2 = 0.;
88  for (int i = 0; i < nofHits; i++) {
89  if (d[i] <= ctsigma) {
90  w[i] = (1 - (d[i] / (ctsigma)) * (d[i] / (ctsigma)))
91  * (1 - (d[i] / (ctsigma)) * (d[i] / (ctsigma)));
92  } else {
93  w[i] = 0.;
94  }
95  }
96  }
97  //computing moments (note: all moments are normed, i.e. divided by N)
98  M0 = 0;
99  Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
100  for (int i = 0; i < nofHits; i++) {
101  if (w[i] != 0.) {
102  Xi = ring->GetHit(i).fX - Mx;
103  Yi = ring->GetHit(i).fY - My;
104  Zi = Xi * Xi + Yi * Yi;
105  Mxy += Xi * Yi;
106  Mxx += Xi * Xi;
107  Myy += Yi * Yi;
108  Mxz += Xi * Zi;
109  Myz += Yi * Zi;
110  Mzz += Zi * Zi;
111  M0++;
112  }
113  }
114  if (M0 < MinNuberOfHits) {
115  M0 = 0;
116  Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
117  M0 = 0;
118  for (int i = 0; i < nofHits; i++) {
119  Xi = ring->GetHit(i).fX - Mx;
120  Yi = ring->GetHit(i).fY - My;
121  Zi = Xi * Xi + Yi * Yi;
122  Mxy += Xi * Yi;
123  Mxx += Xi * Xi;
124  Myy += Yi * Yi;
125  Mxz += Xi * Zi;
126  Myz += Yi * Zi;
127  Mzz += Zi * Zi;
128  M0++;
129  }
130  }
131  Mxx /= M0;
132  Myy /= M0;
133  Mxy /= M0;
134  Mxz /= M0;
135  Myz /= M0;
136  Mzz /= M0;
137 
138  //computing the coefficients of the characteristic polynomial
139  Mz = Mxx + Myy;
140  Cov_xy = Mxx * Myy - Mxy * Mxy;
141  Mxz2 = Mxz * Mxz;
142  Myz2 = Myz * Myz;
143 
144  A2 = 4. * Cov_xy - 3. * Mz * Mz - Mzz;
145  A1 = Mzz * Mz + 4. * Cov_xy * Mz - Mxz2 - Myz2 - Mz * Mz * Mz;
146  A0 = Mxz2 * Myy + Myz2 * Mxx - Mzz * Cov_xy - 2. * Mxz * Myz * Mxy
147  + Mz * Mz * Cov_xy;
148 
149  A22 = A2 + A2;
150  iter = 0;
151  xnew = 0.;
152 
153  //Newton's method starting at x=0
154  for (iter = 0; iter < iterMax; iter++) {
155  ynew = A0 + xnew * (A1 + xnew * (A2 + 4. * xnew * xnew));
156 
157  if (fabs(ynew) > fabs(yold)) {
158  // printf("Newton2 goes wrong direction: ynew=%f yold=%f\n",ynew,yold);
159  xnew = 0.;
160  break;
161  }
162 
163  Dy = A1 + xnew * (A22 + 16. * xnew * xnew);
164  xold = xnew;
165  xnew = xold - ynew / Dy;
166 
167  if (fabs((xnew - xold) / xnew) < epsilon) break;
168  }
169 
170  if (iter == iterMax - 1) {
171  //printf("Newton2 does not converge in %d iterations\n",iterMax);
172  xnew = 0.;
173  }
174  if (xnew < 0.) {
175  iter = 30;
176  //printf("Negative root: x=%f\n",xnew);
177  }
178 
179  // computing the circle parameters
180  GAM = -Mz - xnew - xnew;
181  DET = xnew * xnew - xnew * Mz + Cov_xy;
182  centerX = (Mxz * (Myy - xnew) - Myz * Mxy) / DET / 2.;
183  centerY = (Myz * (Mxx - xnew) - Mxz * Mxy) / DET / 2.;
184  radius = sqrt(centerX * centerX + centerY * centerY - GAM);
185  centerX = centerX + Mx;
186  centerY = centerY + My;
187  Mx = centerX;
188  My = centerY;
189 
190  if (DET == 0.) {
191  radius = 0.;
192  centerX = 0.;
193  centerY = 0.;
194  return;
195  }
196  }
197  ring->SetRadius(radius);
198  ring->SetCenterX(centerX);
199  ring->SetCenterY(centerY);
200 
201  CalcChi2(ring);
202 }
sqrt
friend F32vec4 sqrt(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:41
CbmRichRingFitterRobustCOP::CbmRichRingFitterRobustCOP
CbmRichRingFitterRobustCOP()
Default constructor.
Definition: CbmRichRingFitterRobustCOP.cxx:19
i
int i
Definition: L1/vectors/P4_F32vec4.h:25
CbmRichHitLight::fX
float fX
Definition: CbmRichRingLight.h:34
CbmRichRingLight::SetRadius
void SetRadius(float r)
Definition: CbmRichRingLight.h:124
CbmRichRingFitterBase::CalcChi2
virtual void CalcChi2(CbmRichRingLight *ring)
Calculate chi2 for circle fitting algorithms.
Definition: CbmRichRingFitterBase.h:48
CbmRichRingLight::GetNofHits
int GetNofHits() const
Return number of hits in ring.
Definition: CbmRichRingLight.h:108
CbmRichRingLight::SetCenterY
void SetCenterY(float y)
Definition: CbmRichRingLight.h:123
CbmRichRingLight::SetCenterX
void SetCenterX(float x)
Definition: CbmRichRingLight.h:122
d
double d
Definition: P4_F64vec2.h:24
CbmRichRingFitterRobustCOP.h
Here the ring is fitted with the RobustCOP algorithm from A. Ayriyan/G. Ososkov.
CbmRichRingFitterRobustCOP::~CbmRichRingFitterRobustCOP
virtual ~CbmRichRingFitterRobustCOP()
Destructor.
Definition: CbmRichRingFitterRobustCOP.cxx:21
CbmRichRingFitterRobustCOP::DoFit
virtual void DoFit(CbmRichRingLight *ring)
Inherited from CbmRichRingFitterBase.
Definition: CbmRichRingFitterRobustCOP.cxx:23
CbmRichHitLight::fY
float fY
Definition: CbmRichRingLight.h:35
fabs
friend F32vec4 fabs(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:60
CbmRichRingLight::GetHit
CbmRichHitLight GetHit(int ind)
Return hit by the index.
Definition: CbmRichRingLight.h:114
CbmRichRingLight
Definition: CbmRichRingLight.h:39