Go to the documentation of this file.00001
00007 #include "CbmRichRingFitterCOP.h"
00008 #include "CbmRichRingLight.h"
00009
00010 #include <iostream>
00011 #include <cmath>
00012
00013 using namespace std;
00014
00015 CbmRichRingFitterCOP::CbmRichRingFitterCOP()
00016 {
00017
00018 }
00019
00020 CbmRichRingFitterCOP::~CbmRichRingFitterCOP()
00021 {
00022
00023 }
00024
00025 void CbmRichRingFitterCOP::DoFit(
00026 CbmRichRingLight *ring)
00027 {
00028 FitRing(ring);
00029 }
00030
00031 void CbmRichRingFitterCOP::FitRing(
00032 CbmRichRingLight* ring)
00033 {
00034 int nofHits = ring->GetNofHits();
00035 if (nofHits < 3) {
00036 ring->SetRadius(0.);
00037 ring->SetCenterX(0.);
00038 ring->SetCenterY(0.);
00039 return;
00040 }
00041
00042 if (nofHits >= MAX_NOF_HITS_IN_RING) {
00043 cout << "-E- CbmRichRingFitterCOP::DoFit(), too many hits in the ring:" << nofHits <<endl;
00044 ring->SetRadius(0.);
00045 ring->SetCenterX(0.);
00046 ring->SetCenterY(0.);
00047 return;
00048 }
00049 int iterMax = 4;
00050 float Xi, Yi, Zi;
00051 float M0, Mx, My, Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Mxz2, Myz2, Cov_xy;
00052 float A0, A1, A2, A22;
00053 float epsilon = 0.00001;
00054 float Dy, xnew, xold, ynew, yold = 10000000.;
00055
00056 M0 = nofHits;
00057 Mx = My = 0.;
00058
00059
00060 for (int i = 0; i < nofHits; i++) {
00061 Mx += ring->GetHit(i).fX;
00062 My += ring->GetHit(i).fY;
00063 }
00064 Mx /= M0;
00065 My /= M0;
00066
00067
00068 Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
00069
00070 for (int i = 0; i < nofHits; i++) {
00071
00072 Xi = ring->GetHit(i).fX - Mx;
00073 Yi = ring->GetHit(i).fY - My;
00074 Zi = Xi * Xi + Yi * Yi;
00075
00076 Mxy += Xi * Yi;
00077 Mxx += Xi * Xi;
00078 Myy += Yi * Yi;
00079 Mxz += Xi * Zi;
00080 Myz += Yi * Zi;
00081 Mzz += Zi * Zi;
00082 }
00083 Mxx /= M0;
00084 Myy /= M0;
00085 Mxy /= M0;
00086 Mxz /= M0;
00087 Myz /= M0;
00088 Mzz /= M0;
00089
00090
00091 Mz = Mxx + Myy;
00092 Cov_xy = Mxx * Myy - Mxy * Mxy;
00093 Mxz2 = Mxz * Mxz;
00094 Myz2 = Myz * Myz;
00095
00096 A2 = 4. * Cov_xy - 3. * Mz * Mz - Mzz;
00097 A1 = Mzz * Mz + 4. * Cov_xy * Mz - Mxz2 - Myz2 - Mz * Mz * Mz;
00098 A0 = Mxz2 * Myy + Myz2 * Mxx - Mzz * Cov_xy - 2. * Mxz * Myz * Mxy + Mz
00099 * Mz * Cov_xy;
00100
00101 A22 = A2 + A2;
00102 xnew = 0.;
00103
00104
00105 int iter;
00106 for (iter = 0; iter < iterMax; iter++) {
00107 ynew = A0 + xnew * (A1 + xnew * (A2 + 4. * xnew * xnew));
00108
00109 if (fabs(ynew) > fabs(yold)) {
00110
00111 xnew = 0.;
00112 break;
00113 }
00114
00115 Dy = A1 + xnew * (A22 + 16. * xnew * xnew);
00116 xold = xnew;
00117 xnew = xold - ynew / Dy;
00118
00119 if (xnew == 0 || fabs((xnew - xold) / xnew) < epsilon){
00120
00121 break;
00122 }
00123 }
00124
00125
00126
00127
00128
00129
00130 float radius = 0.;
00131 float centerX = 0.;
00132 float centerY = 0.;
00133
00134
00135 float GAM = -Mz - xnew - xnew;
00136 float DET = xnew * xnew - xnew * Mz + Cov_xy;
00137 if (DET != 0.) {
00138 centerX = (Mxz * (Myy - xnew) - Myz * Mxy) / DET / 2.;
00139 centerY = (Myz * (Mxx - xnew) - Mxz * Mxy) / DET / 2.;
00140 radius = sqrt(centerX * centerX + centerY * centerY - GAM);
00141 centerX += Mx;
00142 centerY += My;
00143 }
00144
00145 ring->SetRadius(radius);
00146 ring->SetCenterX(centerX);
00147 ring->SetCenterY(centerY);
00148
00149 CalcChi2(ring);
00150 }