00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00047 int err = TLineFitter::fit(t);
00048 if (err) return err;
00049
00050
00051 const AList<TMLink> & links = t.links();
00052 _n = links.length();
00053 if (_n < 3) return 0;
00054
00055
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
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
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
00103
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
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
00221
00222
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
00243
00244
00245
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 }