/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Reconstruction/TrkReco/TrkReco-00-08-59-patch4-slc6tag/src/TRobustLineFitter.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // $Id: TRobustLineFitter.cxx,v 1.7 2010/03/31 09:58:59 liucy Exp $
00003 //-----------------------------------------------------------------------------
00004 // Filename : TRobustLineFitter.cc
00005 // Section  : Tracking
00006 // Owner    : Yoshi Iwasaki
00007 // Email    : yoshihito.iwasaki@kek.jp
00008 //-----------------------------------------------------------------------------
00009 // Description : A class to fit a TTrackBase object to a line.
00010 //               See http://bsunsrv1.kek.jp/~yiwasaki/tracking/
00011 //-----------------------------------------------------------------------------
00012 
00013 /* for copysign */
00014 #if defined(__sparc)
00015 #  if defined(__EXTENSIONS__)
00016 #    include <cmath>
00017 #  else
00018 #    define __EXTENSIONS__
00019 #    include <cmath>
00020 #    undef __EXTENSIONS__
00021 #  endif
00022 #elif defined(__GNUC__)
00023 #  if defined(_XOPEN_SOURCE)
00024 #    include <cmath>
00025 #  else
00026 #    define _XOPEN_SOURCE
00027 #    include <cmath>
00028 #    undef _XOPEN_SOURCE
00029 #  endif
00030 #endif
00031 
00032 #include "TrkReco/TRobustLineFitter.h"
00033 #include "TrkReco/TTrackBase.h"
00034 #include "TrkReco/TMLine.h"
00035 #include "TrkReco/TMLink.h"
00036 
00037 TRobustLineFitter::TRobustLineFitter(const std::string & name)
00038 : TLineFitter(name), _a(0.), _b(0.), _det(0.) {
00039 }
00040 
00041 TRobustLineFitter::~TRobustLineFitter() {
00042 }
00043 
00044 int
00045 TRobustLineFitter::fit(TTrackBase & t) const {
00046     //...Initial guess...
00047     int err = TLineFitter::fit(t);
00048     if (err) return err;
00049 
00050     //...Check # of hits...
00051     const AList<TMLink> & links = t.links();
00052     _n = links.length();
00053     if (_n < 3) return 0;
00054 
00055     //...Standard deviation...
00056     _a = TLineFitter::a();
00057     _b = TLineFitter::b();
00058     _det = TLineFitter::det();
00059     double chisq = 0.;
00060     for (unsigned i = 0; i < _n; i++) {
00061         const HepPoint3D & p = links[i]->position();
00062         double tmp = p.y() - (_a * p.x() + _b);
00063         chisq += tmp * tmp;
00064     }
00065     double siga = sqrt(chisq / _det);
00066 
00067     //...Decide iteration step...
00068     double a1 = _a;
00069     double f1 = rofunc(t, a1);
00070     double a2 = _a + copysign(3.0 * siga, f1);
00071     double f2 = rofunc(t, a2);
00072 
00073     // if initial value f2 >f1, change the search direction
00074     if( f1 * f2 > 0. && fabs(f2) > fabs(f1) ){
00075         a2 = _a - copysign(3.0 * siga, f1);
00076         f2 = rofunc(t, a2);
00077     }
00078 
00079     int backwardSearch=0;
00080     while (f1 * f2 > 0. ) {
00081       _a = 2.0 * a2 - a1;
00082       a1 = a2;
00083       f1 = f2;
00084       a2 = _a;
00085       f2 = rofunc(t, a2);
00086 
00087       if( f1 * f2 > 0. && ( fabs(f2) > fabs(f1) || fabs(f2-f1)<0.01 ) ){
00088         backwardSearch++;
00089         if(backwardSearch==2){
00090           break;
00091         }
00092 
00093         double f=f2;
00094         a2 = a1;
00095         f2 = f1;
00096         a1 = _a;
00097         f1 = f;
00098       }
00099     }
00100 
00101     if(backwardSearch==2){
00102       // for case of  no zero cross
00103       //search minimun fabs(f)
00104 
00105       double siga1 = 0.01 * siga;
00106       double a21(fabs(a2-a1));
00107       while (a21 > siga1) {
00108         _a = 0.5 * (a1 + a2);
00109         if (_a == a1 || _a == a2) break;
00110         double f = rofunc(t, _a);
00111 
00112         if( f * f1 <0 ){
00113           f1=f;
00114           a1=_a;
00115           backwardSearch--;
00116           break;
00117         }
00118 
00119         if ( fabs(f) <= fabs(f1) && fabs(f) <= fabs(f2)) {
00120           if( fabs(f-f1) > fabs(f-f2) ){
00121             f1 = f;
00122             a1 = _a;
00123           }else{
00124             f2 = f;
00125             a2 = _a;
00126           }
00127         }else if( fabs(f) <= fabs(f1) ){
00128           f1 = f;
00129           a1 = _a;
00130         }else if ( fabs(f) <= fabs(f2) ){
00131           f2 = f;
00132           a2 = _a;
00133         }else{
00134           if( fabs(f2) > fabs(f1) ){
00135             f1=f;
00136             a1 = _a;
00137           }else{
00138             f2 = f;
00139             a2 = _a;
00140           }
00141         }
00142         if (fabs(a2-a1) >= a21) break;
00143         a21 = fabs(a2-a1);
00144       }
00145     }
00146 
00147     if(backwardSearch<=1){
00148 
00149       //search zero cross
00150       siga = 0.01 * siga;
00151 
00152       double a21(fabs(a2-a1));
00153       while (a21 > siga) {
00154         _a = 0.5 * (a1 + a2);
00155         if (_a == a1 || _a == a2) break;
00156         double f = rofunc(t, _a);
00157         if (f * f1 >= 0.) {
00158           f1 = f;
00159           a1 = _a;
00160         }
00161         else {
00162           f2 = f;
00163           a2 = _a;
00164         }
00165         if (fabs(a2-a1) >= a21) break;
00166         a21 = fabs(a2-a1);
00167       }
00168     }
00169 
00170     _det = _det / double(_n);
00171 
00172     if (t.objectType() == Line)
00173         ((TMLine &) t).property(_a, _b, _det);
00174     fitDone(t);
00175     return 0;
00176 }
00177 
00178 double
00179 TRobustLineFitter::rofunc(const TTrackBase & t, double a) const {
00180     double * arr = (double *) malloc(_n * sizeof(double));
00181     for (unsigned i = 0; i < _n; i++)
00182         arr[i] = t.links()[i]->position().y()
00183             - a * t.links()[i]->position().x();
00184     if (_n & 1) {
00185         _b = select((_n + 1) >> 1, _n, arr);
00186     }
00187     else {
00188         unsigned j = _n >> 1;
00189         _b = 0.5 * (select(j, _n, arr) + select(j + 1, _n, arr));
00190     }
00191 
00192     _det = 0.;
00193     double sum = 0.;
00194     for (unsigned i = 0; i < _n; i++) {
00195         double x = t.links()[i]->position().x();
00196         double y = t.links()[i]->position().y();
00197         double d = y - (a * x + _b);
00198         _det += fabs(d);
00199         if (y != 0.) d /= fabs(y);
00200         if (fabs(d) > 1.0e-7) sum += d > 0.0 ? x : - x;
00201     }
00202     free(arr);
00203     return sum;
00204 }
00205 
00206 #define SWAP(a,b) tmp=(a);(a)=(b);(b)=tmp;
00207 
00208 double
00209 TRobustLineFitter::select(unsigned k, unsigned n, double * arr) const {
00210     --k;
00211     double tmp;
00212     unsigned l = 0;
00213     unsigned ir = n - 1;
00214     while (1) {
00215         if (ir <= l + 1) {
00216             if (ir == l + 1 && arr[ir] < arr[l]) {
00217                 SWAP(arr[l],arr[ir]);
00218             }
00219 
00220 //          std::cout << "k = " << k << std::endl;
00221 //          for (unsigned i = 0; i < _n; i++)
00222 //              std::cout << i << " : " << arr[i] << std::endl;
00223 
00224             return arr[k];
00225         }
00226         else {
00227             unsigned mid = (l + ir) >> 1;
00228             SWAP(arr[mid],arr[l+1]);
00229             if (arr[l + 1] > arr[ir]) {
00230                 SWAP(arr[l+1],arr[ir]);
00231             }
00232             if (arr[l] > arr[ir]) {
00233                 SWAP(arr[l],arr[ir]);
00234             }
00235             if (arr[l + 1] > arr[l]) {
00236                 SWAP(arr[l+1],arr[l]);
00237             }
00238             unsigned i = l + 1;
00239             unsigned j = ir;
00240             double a = arr[l];
00241             while (1) {
00242 //              do i++; while (arr[i] < a);
00243 //              do j--; while (arr[j] > a);
00244 //              while (arr[i] < a) ++i;
00245 //              while (arr[j] > a) --j;
00246                 while (arr[++i] < a);
00247                 while (arr[--j] > a);
00248                 if (j < i) break;
00249                 SWAP(arr[i],arr[j]);
00250             }
00251             arr[l] = arr[j];
00252             arr[j] = a;
00253             if (j >= k) ir = j - 1;
00254             if (j <= k) l = i;
00255         }
00256     }
00257 }

Generated on Tue Nov 29 23:14:16 2016 for BOSS_7.0.2 by  doxygen 1.4.7