CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoPixelVertexing/PixelTrackFitting/src/ParabolaFit.cc

Go to the documentation of this file.
00001 #include "ParabolaFit.h"
00002 #include <iostream>
00003 using namespace std; 
00004 template <class T> T sqr( T t) {return t*t;}
00005 
00006 void ParabolaFit::addPoint(double x, double y)
00007 {
00008   hasWeights = false;
00009   addPoint(x,y,1.);
00010 }
00011 
00012 void ParabolaFit::addPoint(double x, double y, double w)
00013 {
00014   hasValues = false;
00015   hasErrors = false;
00016   Point p = {x,y,w};
00017   points.push_back(p);
00018 }
00019 
00020 const ParabolaFit::Result & ParabolaFit::result( bool doErrors ) const
00021 {
00022   if (hasErrors)  return theResult;
00023   if (hasValues && !doErrors) return theResult;
00024 
00025   double F0,  F1,  F2,  F3,  F4,  F0y,  F1y,  F2y;
00026          F0 = F1 = F2 = F3 = F4 = F0y = F1y = F2y = 0.;
00027 
00028   typedef vector<Point>::const_iterator IT;
00029   for (IT ip = points.begin(); ip != points.end(); ip++) {
00030  
00031     double pow;
00032     double x = ip->x;
00033     double y = ip->y;
00034     double w = ip->w;
00035 
00036                 F0 += w;         F0y += w*y;   
00037                 F1 += w*x;       F1y += w*x*y;
00038     pow = x*x;  F2 += w*pow;     F2y += w*pow*y;    // x^2
00039     pow *= x;   F3 += w*pow;                        // x^3
00040     pow *= x;   F4 += w*pow;                        // x^4
00041   }
00042 
00043   Column cA = { F0, F1, F2 };
00044   Column cB = { F1, F2, F3 };
00045   Column cC = { F2, F3, F4 };
00046   Column cY = { F0y, F1y, F2y };
00047 
00048   double det0 = det(cA, cB, cC);
00049 
00050   if ( !hasFixedParC) {
00051   theResult.parA = det(cY, cB, cC) / det0;
00052   theResult.parB = det(cA, cY, cC) / det0;
00053   theResult.parC = det(cA, cB, cY) / det0;
00054   } else {
00055     Column cCY = {F0y-theResult.parC*F2, F1y-theResult.parC*F3, F2y-theResult.parC*F4};
00056     double det0C   = det(cA, cB);
00057     theResult.parA = det(cCY, cB) / det0C;
00058     theResult.parB = det(cA, cCY) / det0C;
00059   } 
00060 
00061 //  std::cout <<" result: A="<<theResult.parA<<" B="<<theResult.parB<<" C="<<theResult.parC<<endl; 
00062   double vAA,  vBB,  vCC,  vAB,  vAC,  vBC;
00063          vAA = vBB = vCC = vAB = vAC = vBC = 0.;
00064 
00065   hasValues = true;
00066   if (!doErrors) return theResult;
00067 
00068   if( !hasWeights &&  dof() > 0) {
00069 //     cout <<" CHI2: " << chi2() <<" DOF: " << dof() << endl;
00070      double scale_w = 1./chi2()/dof();
00071      for (IT ip = points.begin(); ip != points.end(); ip++) ip->w *= scale_w; 
00072 //     cout <<" CHI2: " << chi2() <<" DOF: " << dof() << endl;
00073   }
00074   
00075   for (IT ip = points.begin(); ip != points.end(); ip++) {
00076 
00077     double w = ip->w;
00078     Column cX = {1., ip->x, sqr(ip->x) };
00079 
00080     double dXBC = det(cX, cB, cC);
00081     double dAXC = det(cA, cX, cC);
00082     double dABX = det(cA, cB, cX);
00083 
00084     vAA += w * sqr(dXBC);
00085     vBB += w * sqr(dAXC);
00086     vCC += w * sqr(dABX);
00087     vAB += w * dXBC * dAXC;
00088     vAC += w * dXBC * dABX;
00089     vBC += w * dAXC * dABX;
00090   }
00091    
00092   theResult.varAA = vAA/sqr(det0);
00093   theResult.varBB = vBB/sqr(det0);
00094   theResult.varCC = vCC/sqr(det0);
00095   theResult.varAB = vAB/sqr(det0);
00096   theResult.varAC = vAC/sqr(det0);
00097   theResult.varBC = vBC/sqr(det0);
00098 
00099   hasErrors = true;
00100   return theResult;
00101 }
00102 
00103 
00104 double ParabolaFit::chi2() const
00105 {
00106   double mychi2 = 0.;
00107   for ( vector<Point>::const_iterator 
00108       ip = points.begin(); ip != points.end(); ip++) {
00109      mychi2 += ip->w * sqr(ip->y - fun(ip->x)); 
00110   }
00111   return mychi2;
00112 }
00113 
00114 double ParabolaFit::fun(double x) const
00115 {
00116    return theResult.parA + theResult.parB*x + theResult.parC*x*x;
00117 }
00118 
00119 int ParabolaFit::dof() const
00120 {
00121   int nPar = 3; if (hasFixedParC) nPar--;
00122   int nDof = points.size() - nPar;
00123   return (nDof > 0) ? nDof : 0;
00124 }
00125 
00126 double ParabolaFit::det(
00127     const Column & c1, const Column & c2, const Column & c3) const
00128 {
00129   return   c1.r1 * c2.r2 * c3.r3
00130          + c2.r1 * c3.r2 * c1.r3
00131          + c3.r1 * c1.r2 * c2.r3
00132          - c1.r3 * c2.r2 * c3.r1
00133          - c2.r3 * c3.r2 * c1.r1
00134          - c3.r3 * c1.r2 * c2.r1;
00135 }
00136 
00137 double ParabolaFit::det( const Column & c1, const Column & c2) const
00138 {
00139   return c1.r1*c2.r2 - c1.r2*c2.r1;
00140 }