CbmRoot
CbmRichRingFitterCOP.cxx
Go to the documentation of this file.
1 
7 #include "CbmRichRingFitterCOP.h"
8 #include "CbmRichRingLight.h"
9 
10 #include <cmath>
11 #include <iostream>
12 
13 using namespace std;
14 
16 
18 
19 void CbmRichRingFitterCOP::DoFit(CbmRichRingLight* ring) { FitRing(ring); }
20 
22  int nofHits = ring->GetNofHits();
23  if (nofHits < 3) {
24  ring->SetRadius(0.);
25  ring->SetCenterX(0.);
26  ring->SetCenterY(0.);
27  return;
28  }
29 
30  if (nofHits >= MAX_NOF_HITS_IN_RING) {
31  cout << "-E- CbmRichRingFitterCOP::DoFit(), too many hits in the ring:"
32  << nofHits << endl;
33  ring->SetRadius(0.);
34  ring->SetCenterX(0.);
35  ring->SetCenterY(0.);
36  return;
37  }
38  int iterMax = 4;
39  float Xi, Yi, Zi;
40  float M0, Mx, My, Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Mxz2, Myz2, Cov_xy;
41  float A0, A1, A2, A22;
42  float epsilon = 0.00001;
43  float Dy, xnew, xold, ynew, yold = 10000000.;
44 
45  M0 = nofHits;
46  Mx = My = 0.;
47 
48  // calculate center of gravity
49  for (int i = 0; i < nofHits; i++) {
50  Mx += ring->GetHit(i).fX;
51  My += ring->GetHit(i).fY;
52  }
53  Mx /= M0;
54  My /= M0;
55 
56  // computing moments (note: all moments are normed, i.e. divided by N)
57  Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
58 
59  for (int i = 0; i < nofHits; i++) {
60  // transform to center of gravity coordinate system
61  Xi = ring->GetHit(i).fX - Mx;
62  Yi = ring->GetHit(i).fY - My;
63  Zi = Xi * Xi + Yi * Yi;
64 
65  Mxy += Xi * Yi;
66  Mxx += Xi * Xi;
67  Myy += Yi * Yi;
68  Mxz += Xi * Zi;
69  Myz += Yi * Zi;
70  Mzz += Zi * Zi;
71  }
72  Mxx /= M0;
73  Myy /= M0;
74  Mxy /= M0;
75  Mxz /= M0;
76  Myz /= M0;
77  Mzz /= M0;
78 
79  //computing the coefficients of the characteristic polynomial
80  Mz = Mxx + Myy;
81  Cov_xy = Mxx * Myy - Mxy * Mxy;
82  Mxz2 = Mxz * Mxz;
83  Myz2 = Myz * Myz;
84 
85  A2 = 4. * Cov_xy - 3. * Mz * Mz - Mzz;
86  A1 = Mzz * Mz + 4. * Cov_xy * Mz - Mxz2 - Myz2 - Mz * Mz * Mz;
87  A0 = Mxz2 * Myy + Myz2 * Mxx - Mzz * Cov_xy - 2. * Mxz * Myz * Mxy
88  + Mz * Mz * Cov_xy;
89 
90  A22 = A2 + A2;
91  xnew = 0.;
92 
93  //Newton's method starting at x=0
94  int iter;
95  for (iter = 0; iter < iterMax; iter++) {
96  ynew = A0 + xnew * (A1 + xnew * (A2 + 4. * xnew * xnew));
97 
98  if (fabs(ynew) > fabs(yold)) {
99  // printf("Newton2 goes wrong direction: ynew=%f yold=%f\n",ynew,yold);
100  xnew = 0.;
101  break;
102  }
103 
104  Dy = A1 + xnew * (A22 + 16. * xnew * xnew);
105  xold = xnew;
106  xnew = xold - ynew / Dy;
107  //cout << " xnew = " << xnew ;
108  if (xnew == 0 || fabs((xnew - xold) / xnew) < epsilon) {
109  //cout << "iter = " << iter << " N = " << fNhits << endl;
110  break;
111  }
112  }
113 
114  //if (iter == iterMax - 1) {
115  // printf("Newton2 does not converge in %d iterations\n",iterMax);
116  // xnew = 0.;
117  //}
118 
119  float radius = 0.;
120  float centerX = 0.;
121  float centerY = 0.;
122 
123  //computing the circle parameters
124  float GAM = -Mz - xnew - xnew;
125  float DET = xnew * xnew - xnew * Mz + Cov_xy;
126  if (DET != 0.) {
127  centerX = (Mxz * (Myy - xnew) - Myz * Mxy) / DET / 2.;
128  centerY = (Myz * (Mxx - xnew) - Mxz * Mxy) / DET / 2.;
129  radius = sqrt(centerX * centerX + centerY * centerY - GAM);
130  centerX += Mx;
131  centerY += My;
132  }
133 
134  ring->SetRadius(radius);
135  ring->SetCenterX(centerX);
136  ring->SetCenterY(centerY);
137 
138  CalcChi2(ring);
139 }
CbmRichRingFitterCOP::~CbmRichRingFitterCOP
~CbmRichRingFitterCOP()
Destructor.
Definition: CbmRichRingFitterCOP.cxx:17
CbmRichRingFitterCOP::CbmRichRingFitterCOP
CbmRichRingFitterCOP()
Standard constructor.
Definition: CbmRichRingFitterCOP.cxx:15
sqrt
friend F32vec4 sqrt(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:41
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
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
CbmRichRingLight.h
CbmRichRingFitterCOP.h
Here the ring is fitted with the COP algorithm from A. Ayriyan/G. Ososkov.
CbmRichRingFitterCOP::DoFit
virtual void DoFit(CbmRichRingLight *ring)
Inherited from CbmRichRingFitterBase.
Definition: CbmRichRingFitterCOP.cxx:19
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
CbmRichRingFitterCOP::FitRing
void FitRing(CbmRichRingLight *ring)
Execute ring fitting algorithm.
Definition: CbmRichRingFitterCOP.cxx:21
CbmRichRingLight
Definition: CbmRichRingLight.h:39