00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "reconstruction/LSQFit.h"
00020
00021 #include "geometry/Ray.h"
00022
00023
00024 #include <cmath>
00025
00026 inline double sqr(double x){return x*x;}
00027
00028 LSQFit::LSQFit ()
00029 {
00030 }
00031
00032 LSQFit::LSQFit (const LSQFit& fit)
00033 {
00034 unsigned numData = fit.dataList.size();
00035 for(unsigned i=0; i<numData; i++) {
00036 dataList.push_back(FitData( fit.dataList[i]) );
00037 }
00038 chisq = fit.chisq;
00039 rmsResid = fit.rmsResid;
00040 x0 = fit.x0;
00041 slopeX = fit.slopeX;
00042 }
00043
00044
00045 LSQFit::~LSQFit ()
00046 {
00047 clear();
00048 }
00049
00050
00051
00052 void LSQFit::clear ()
00053 {
00054
00055 dataList.clear();
00056 }
00057
00058 float LSQFit::maxResidual (int* index)
00059 {
00060 float test, maxRes = 0.;
00061 int idx = -1;
00062
00063 for(unsigned i=0; i<dataList.size(); i++) {
00064 test = dataList[i].res*dataList[i].res;
00065 if(maxRes < test) {
00066 idx = (int)dataList[i].index;
00067 maxRes = test;
00068 }
00069 }
00070
00071 if(idx >= 0) maxRes = sqrt(maxRes);
00072 *index = idx;
00073 return maxRes;
00074
00075 }
00076
00077 unsigned int LSQFit::numDataPoints () const
00078 {
00079
00080 return (int)dataList.size();
00081 }
00082
00083 int LSQFit::compareFits (const LSQFit& fit)
00084 {
00085
00086 int numComData = 0;
00087 unsigned int fit_numHits = fit.dataList.size();
00088 unsigned int numHits = dataList.size();
00089 for(unsigned i=0; i<numHits; i++) {
00090 for(unsigned j=0; j<fit_numHits; j++) {
00091 if(dataList[i].index == fit.dataList[j].index) {
00092 numComData++;
00093 break;
00094 }
00095 }
00096 }
00097 return numComData;
00098
00099 }
00100
00101 Point LSQFit::getHit (unsigned int i)
00102 {
00103 if(i < dataList.size()) return Point(dataList[i].x, 0, dataList[i].z);
00104 else return Point(FLT_MAX, FLT_MAX, FLT_MAX);
00105 }
00106
00107 unsigned int LSQFit::getHitIndex (unsigned int i)
00108 {
00109 if(i < dataList.size()) return dataList[i].index;
00110 else return 0;
00111 }
00112
00113 float LSQFit::doFit ()
00114 {
00115
00116 chisq = -.5;
00117 if(dataList.size() < 3) {chisq = -1; rmsResid = -1; return chisq;}
00118
00119 double s1x, sx, szwx, szzwx, sxx, sxz, detx, fit;
00120 s1x = sx = szwx = szzwx = sxx = sxz = 0.0;
00121 unsigned i;
00122
00123 for(i=0; i<dataList.size(); i++) {
00124 float x = dataList[i].x;
00125 float z = dataList[i].z;
00126 s1x += dataList[i].wt;
00127
00128 szwx += dataList[i].wt*z;
00129 szzwx += dataList[i].wt*z*z;
00130
00131 sx += dataList[i].wt*x;
00132 sxx += dataList[i].wt*x*x;
00133 sxz += dataList[i].wt*z*x;
00134 }
00135
00136 detx = s1x*szzwx - szwx*szwx;
00137 if(detx == 0) {chisq = -2; rmsResid = 0.; return chisq;}
00138
00139 x0 = (sx*szzwx - szwx*sxz)/detx;
00140 slopeX = (s1x*sxz - szwx*sx) /detx;
00141
00142 chisq = 0; rmsResid = 0;
00143 float lst_slope = 0., this_slope, x_lst = 0., z_lst = 0.;
00144 for(i=0; i<dataList.size(); i++) {
00145
00146 float x = dataList[i].x;
00147 float z = dataList[i].z;
00148 fit = x0 + slopeX * z;
00149 dataList[i].res = sqrt(dataList[i].wt) * (x-fit);
00150 chisq += sqr( dataList[i].res );
00151
00152 if(i>0) {
00153 this_slope = fabs(atan((x-x_lst)/(z-z_lst)));
00154 if(i> 1) rmsResid += fabs(this_slope - lst_slope);
00155 lst_slope = this_slope;
00156 }
00157 x_lst = x;
00158 z_lst = z;
00159 }
00160
00161 chisq = chisq/(dataList.size() - 2);
00162 rmsResid = rmsResid/(dataList.size() - 2);
00163
00164 return chisq;
00165
00166 }
00167
00168 int LSQFit::addData (float x, float z, float wx)
00169 {
00170
00171 unsigned numData = dataList.size();
00172 dataList.push_back( FitData( numData, x, z, wx) );
00173 return dataList.size();
00174
00175 }
00176
00177 int LSQFit::addData (unsigned int idx, float x, float z, float wx)
00178 {
00179
00180 dataList.push_back( FitData( idx, x, z, wx) );
00181 return (int)dataList.size();
00182
00183 }
00184
00185 int LSQFit::removeData (unsigned int index)
00186 {
00187
00188 for(unsigned i=0; i <dataList.size(); i++) {
00189 if ( index == dataList[i].index ) {
00190 dataList.erase(&dataList[i]);
00191 break;
00192 }
00193 }
00194 return (int)dataList.size();
00195
00196 }
00197
00198 float LSQFit::truncateFit ()
00199 {
00200
00201 if(dataList.size() > 3) {
00202 int maxIndex;
00203 maxResidual(&maxIndex);
00204 removeData(maxIndex);
00205 return doFit();
00206 }
00207 return chisq;
00208
00209 }
00210
00211 void LSQFit::printOn (std::ostream& os) const
00212 {
00213 }
00214