EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CbmRichRingFitterCOPLight.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CbmRichRingFitterCOPLight.h
1 #ifndef CBM_RICH_RING_FITTER_COP_LIGHT
2 #define CBM_RICH_RING_FITTER_COP_LIGHT 1
3 
4 #include <vector>
5 #include "CbmRichRingLight.h"
6 #include <cmath>
7 
9 {
10 public:
11 
15  }
17  fHitX.clear();
18  fHitY.clear();
19  }
20  void DoFit(CbmRichRingLight *ring);
21 
22 private:
23  void CalcChi2(CbmRichRingLight* ring);
24 
25  static const int MAX_NOF_HITS_IN_RING = 200;
26  std::vector<float> fHitX;
27  std::vector<float> fHitY;
28  int fNofHits;
29 }; //class
30 
31 #endif
32 
34 {
35  fNofHits = ring->GetNofHits();
36  if (fNofHits < 3) {
37  ring->SetRadius(0.);
38  ring->SetCenterX(0.);
39  ring->SetCenterY(0.);
40  return;
41  }
42 
44  //cout << "-E- CbmRichRingFitterCOP::DoFit() - Too many hits in the ring:"
45  //<<fNofHits <<endl;
46  ring->SetRadius(0.);
47  ring->SetCenterX(0.);
48  ring->SetCenterY(0.);
49  return;
50  }
51 
52  for (int i = 0; i < fNofHits; i++) {
53  fHitX[i] = ring->GetHit(i).fX;
54  fHitY[i] = ring->GetHit(i).fY;
55  }
56 
57  float radius = 0.;
58  float centerX = 0.;
59  float centerY = 0.;
60 
61  int iterMax = 4;
62  float Xi, Yi, Zi;
63  float M0, Mx, My, Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Mxz2, Myz2, Cov_xy;
64  float A0, A1, A2, A22;
65  float epsilon = 0.00001;
66  float Dy, xnew, xold, ynew, yold = 10000000.;
67 
68  M0 = fNofHits;
69  Mx = My = 0.;
70 
71  //calculate center of gravity
72  for (int i = 0; i < fNofHits; i++) {
73  Mx += fHitX[i];
74  My += fHitY[i];
75  }
76  Mx /= M0;
77  My /= M0;
78 
79  //computing moments (note: all moments are normed, i.e. divided by N)
80  Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
81 
82  for (int i = 0; i < fNofHits; i++) {
83  Xi = fHitX[i] - Mx; //transform to center of gravity coordinate system
84  Yi = fHitY[i] - My;
85  Zi = Xi * Xi + Yi * Yi;
86 
87  Mxy += Xi * Yi;
88  Mxx += Xi * Xi;
89  Myy += Yi * Yi;
90  Mxz += Xi * Zi;
91  Myz += Yi * Zi;
92  Mzz += Zi * Zi;
93  }
94  Mxx /= M0;
95  Myy /= M0;
96  Mxy /= M0;
97  Mxz /= M0;
98  Myz /= M0;
99  Mzz /= M0;
100 
101  //computing the coefficients of the characteristic polynomial
102  Mz = Mxx + Myy;
103  Cov_xy = Mxx * Myy - Mxy * Mxy;
104  Mxz2 = Mxz * Mxz;
105  Myz2 = Myz * Myz;
106 
107  A2 = 4. * Cov_xy - 3. * Mz * Mz - Mzz;
108  A1 = Mzz * Mz + 4. * Cov_xy * Mz - Mxz2 - Myz2 - Mz * Mz * Mz;
109  A0 = Mxz2 * Myy + Myz2 * Mxx - Mzz * Cov_xy - 2. * Mxz * Myz * Mxy + Mz
110  * Mz * Cov_xy;
111 
112  A22 = A2 + A2;
113  xnew = 0.;
114 
115  //Newton's method starting at x=0
116  int iter;
117  for (iter = 0; iter < iterMax; iter++) {
118  ynew = A0 + xnew * (A1 + xnew * (A2 + 4. * xnew * xnew));
119 
120  if (fabs(ynew) > fabs(yold)) {
121  // printf("Newton2 goes wrong direction: ynew=%f yold=%f\n",ynew,yold);
122  xnew = 0.;
123  break;
124  }
125 
126  Dy = A1 + xnew * (A22 + 16. * xnew * xnew);
127  xold = xnew;
128  xnew = xold - ynew / Dy;
129  //cout << " xnew = " << xnew ;
130  if (xnew == 0 || fabs((xnew - xold) / xnew) < epsilon){
131  //cout << "iter = " << iter << " N = " << fNhits << endl;
132  break;
133  }
134  }
135 
136  //if (iter == iterMax - 1) {
137  // printf("Newton2 does not converge in %d iterations\n",iterMax);
138  // xnew = 0.;
139  //}
140 
141  //computing the circle parameters
142  float GAM = -Mz - xnew - xnew;
143  float DET = xnew * xnew - xnew * Mz + Cov_xy;
144  if (DET != 0.) {
145  centerX = (Mxz * (Myy - xnew) - Myz * Mxy) / DET / 2.;
146  centerY = (Myz * (Mxx - xnew) - Mxz * Mxy) / DET / 2.;
147  radius = sqrt(centerX * centerX + centerY * centerY - GAM);
148  centerX += Mx;
149  centerY += My;
150  } else {
151  centerX = 0.;
152  centerY = 0.;
153  radius = 0.;
154  }
155 
156  ring->SetRadius(radius);
157  ring->SetCenterX(centerX);
158  ring->SetCenterY(centerY);
159 
160  CalcChi2(ring);
161 }
162 
164 {
165  int fNhits=pRing->GetNofHits();
166 
167  if (fNhits < 4) {
168  pRing->SetChi2(-1.);
169  return;
170  }
171 
172  float Xd2, Yd2;
173  float chi2 = 0.;
174 
175  float Radius = pRing->GetRadius();
176  float Xcenter = pRing->GetCenterX();
177  float Ycenter = pRing->GetCenterY();
178 
179  for (int i = 0; i < fNhits; i++) {
180  Xd2 = Xcenter - fHitX[i];
181  Yd2 = Ycenter - fHitY[i];
182  Xd2 *= Xd2;
183  Yd2 *= Yd2;
184 
185  float d = sqrt( Xd2 + Yd2 ) - Radius;
186  chi2 += d*d;
187  }
188 
189  pRing->SetChi2(chi2);
190 }
191 
192