• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

beamtime/cern-oct12/go4/RICH/CbmRichRingFitterCOP.cxx (r4864/r3568)

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         // calculate center of gravity
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         // computing moments (note: all moments are normed, i.e. divided by N)
00068         Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
00069 
00070         for (int i = 0; i < nofHits; i++) {
00071            // transform to center of gravity coordinate system
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         //computing the coefficients of the characteristic polynomial
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         //Newton's method starting at x=0
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                         //  printf("Newton2 goes wrong direction: ynew=%f  yold=%f\n",ynew,yold);
00111                         xnew = 0.;
00112                         break;
00113                 }
00114 
00115                 Dy = A1 + xnew * (A22 + 16. * xnew * xnew);
00116                 xold = xnew;
00117                 xnew = xold - ynew / Dy;
00118                 //cout << " xnew = " << xnew ;
00119                 if (xnew == 0 || fabs((xnew - xold) / xnew) < epsilon){
00120                         //cout << "iter = " << iter << " N = " << fNhits << endl;
00121                         break;
00122                 }
00123         }
00124 
00125         //if (iter == iterMax - 1) {
00126                 //  printf("Newton2 does not converge in %d iterations\n",iterMax);
00127         //      xnew = 0.;
00128         //}
00129 
00130    float radius = 0.;
00131    float centerX = 0.;
00132    float centerY = 0.;
00133 
00134         //computing the circle parameters
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 }

Generated on Tue Dec 10 2013 04:52:17 for ROCsoft by  doxygen 1.7.1