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