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