00001
00014 #include "jbltools/kinfit/TrackFitObject.h"
00015 #include "jbltools/kinfit/ThreeVector.h"
00016 #include "jbltools/kinfit/FourVector.h"
00017 #include "cernlib.h"
00018
00019 #include <iostream>
00020 #include <cassert>
00021 #include <cmath>
00022 using std::isfinite;
00023
00024 #include <cstring>
00025
00026 TrackFitObject::TrackFitObject(const char *name_ )
00027 : cachevalid (false), covinvvalid (false), name (0)
00028 {
00029 for (int i = 0; i < NPARMAX; ++i) {
00030 fixed[i] = true;
00031 measured [i] = false;
00032 par[i] = mpar[ i] = err [i] = 0;
00033 globalParNum[i] = -1;
00034 for (int j = 0; j < NPARMAX; ++j) cov[i][j] = covinv[i][j] = 0;
00035 }
00036 setName (name_);
00037 }
00038
00039 TrackFitObject::TrackFitObject (const TrackFitObject& rhs)
00040 : cachevalid (false), covinvvalid (false), name (0)
00041 {
00042 copy (rhs);
00043 }
00044 TrackFitObject& TrackFitObject::operator= (const TrackFitObject& rhs) {
00045 if (&rhs != this) copy (rhs);
00046 return *this;
00047 }
00048
00049 void TrackFitObject::copy (const TrackFitObject& source)
00050 {
00051 cachevalid = false;
00052 covinvvalid =false;
00053 name = 0;
00054 for (int i = 0; i < NPARMAX; i++) {
00055 par[i] = source.par[i];
00056 mpar[i] = source.mpar[i];
00057 err[i] = source.err[i];
00058 measured[i] = source.measured[i];
00059 fixed[i] = source.fixed[i];
00060 globalParNum[i] = source.globalParNum[i];
00061 for (int j = 0; j < NPARMAX; j++) {
00062 cov[i][j] = source.cov[i][j];
00063 }
00064 }
00065 setName (source.name);
00066 }
00067
00068 TrackFitObject::~TrackFitObject()
00069 {
00070 delete[] name;
00071 }
00072
00073 bool TrackFitObject::setParam (int i, double par_,
00074 bool measured_, bool fixed_) {
00075 assert (i >= 0 && i < NPARMAX);
00076 if (measured[i] != measured_ || fixed[i] != fixed_) invalidateCache();
00077 measured[i] = measured_;
00078 fixed[i] = fixed_;
00079 return setParam (i, par_);
00080 };
00081
00082 bool TrackFitObject::setParam (int i, double par_ ) {
00083 if (!isfinite(par_)) return false;
00084 assert (i >= 0 && i < NPARMAX);
00085 if (par[i] == par_) return true;
00086 invalidateCache();
00087 par[i] = par_;
00088 return true;
00089 }
00090 bool TrackFitObject::setMParam (int i, double mpar_ ) {
00091 if (!isfinite(mpar_)) return false;
00092 assert (i >= 0 && i < NPARMAX);
00093 if (mpar[i] == mpar_) return true;
00094 invalidateCache();
00095 mpar[i] = mpar_;
00096 return true;
00097 }
00098
00099 bool TrackFitObject::setError (int ilocal, double err_) {
00100 if (!isfinite(err_)) return false;
00101 assert (ilocal >= 0 && ilocal < NPARMAX);
00102 invalidateCache();
00103 cov[ilocal][ilocal] = err_*err_;
00104 covinvvalid = false;
00105 return true;
00106 }
00107
00108 bool TrackFitObject::setCov (int ilocal, int jlocal, double cov_) {
00109 if (!isfinite(cov_)) return false;
00110 assert (ilocal >= 0 && ilocal < NPARMAX);
00111 assert (jlocal >= 0 && jlocal < NPARMAX);
00112 invalidateCache();
00113 covinvvalid = false;
00114 cov[ilocal][jlocal] = cov[jlocal][ilocal] = cov_;
00115 return true;
00116 }
00117
00118 const char *TrackFitObject::getName() const {
00119 return name ? name : "???";
00120 }
00121
00122 void TrackFitObject::setName(const char *name_) {
00123 if (!name_) return;
00124 delete[] name;
00125 name = 0;
00126
00127 size_t len = strlen(name_)+1;
00128 name = new char[len];
00129 strncpy (name, name_, len);
00130 }
00131
00132
00133 double TrackFitObject::bfield = 1.14;
00134
00135
00136 double TrackFitObject::setBfield (double bfield_) {
00137 return bfield = bfield_;
00138 }
00139
00140 bool TrackFitObject::setGlobalParNum (int ilocal, int iglobal) {
00141 assert (ilocal >= 0 && ilocal < NPARMAX);
00142 assert (!isParamFixed(ilocal));
00143 globalParNum[ilocal] = iglobal;
00144 return true;
00145 }
00146 bool TrackFitObject::fixParam (int ilocal, bool fix) {
00147 assert (ilocal >= 0 && ilocal < NPARMAX);
00148 return fixed [ilocal] = fix;
00149 }
00150 int TrackFitObject::getGlobalParNum(int ilocal) const {
00151 if (ilocal < 0 || ilocal >= getNPar()) return -1;
00152 return globalParNum[ilocal];
00153 }
00154
00155 double TrackFitObject::getParam (int ilocal) const {
00156 assert (ilocal >= 0 && ilocal < NPARMAX);
00157 return par[ilocal];
00158 }
00159 double TrackFitObject::getMParam (int ilocal) const {
00160 assert (ilocal >= 0 && ilocal < NPARMAX);
00161 assert (isParamMeasured(ilocal));
00162 return mpar[ilocal];
00163 }
00164
00165 double TrackFitObject::getError (int ilocal) const {
00166 assert (ilocal >= 0 && ilocal < NPARMAX);
00167 return std::sqrt(cov[ilocal][ilocal]);
00168 }
00169
00170 double TrackFitObject::getCov (int ilocal, int jlocal) const {
00171 assert (ilocal >= 0 && ilocal < NPARMAX);
00172 assert (jlocal >= 0 && jlocal < NPARMAX);
00173 return cov[ilocal][jlocal];
00174 }
00175
00176 bool TrackFitObject::isParamMeasured (int ilocal) const {
00177 assert (ilocal >= 0 && ilocal < NPARMAX);
00178 return measured[ilocal];
00179 }
00180
00181 bool TrackFitObject::isParamFixed (int ilocal) const {
00182 assert (ilocal >= 0 && ilocal < NPARMAX);
00183 return fixed[ilocal];
00184 }
00185
00186 std::ostream& TrackFitObject::print (std::ostream& os) const {
00187 os << getName() << ":\n";
00188 printParams(os);
00189 os << "\n 4-vect(0): " << getMomentum (0);
00190 os << "\n vertex(0): " << getVertex (0);
00191 return os;
00192 }
00193
00194 void TrackFitObject::invalidateCache() {
00195 cachevalid = false;
00196 }
00197
00198 ThreeVector TrackFitObject::getTrajectoryPoint (double s) const {
00199 ThreeVector result;
00200 getTrajectoryPointEx (s, result);
00201 return result;
00202 }
00203
00204 ThreeVector TrackFitObject::getVertex (int i) const {
00205 ThreeVector result;
00206 getVertexEx (i, result);
00207 return result;
00208 }
00209
00210 ThreeVector TrackFitObject::getTrajectoryDerivative (double s,
00211 int ilocal
00212 ) const {
00213 ThreeVector result;
00214 getTrajectoryDerivativeEx (s, ilocal, result);
00215 return result;
00216 }
00217
00218 ThreeVector TrackFitObject::getVertexDerivative (int i,
00219 int ilocal
00220 ) const {
00221 ThreeVector result;
00222 getVertexDerivativeEx (i, ilocal, result);
00223 return result;
00224 }
00225
00226 FourVector TrackFitObject::getMomentumAtTrajectory (double s) const {
00227 FourVector result;
00228 getMomentumAtTrajectoryEx (s, result);
00229 return result;
00230 }
00231
00232 FourVector TrackFitObject::getMomentum (int i) const {
00233 FourVector result;
00234 getMomentumEx (i, result);
00235 return result;
00236 }
00237
00238 FourVector TrackFitObject::getMomentumDerivativeAtTrajectory (double s,
00239 int ilocal
00240 ) const {
00241 FourVector result;
00242 getMomentumDerivativeAtTrajectoryEx (s, ilocal, result);
00243 return result;
00244 }
00245
00246 FourVector TrackFitObject::getMomentumDerivative (int i,
00247 int ilocal
00248 ) const {
00249 FourVector result;
00250 getMomentumDerivativeEx (i, ilocal, result);
00251 return result;
00252 }
00253
00254 void TrackFitObject::addToGlobCov(double *glcov, int idim) const {
00255 int globalnum[NPARMAX];
00256 bool ok [NPARMAX];
00257 for (int ilocal = 0; ilocal < getNPar(); ilocal++) {
00258 int iglobal = globalnum[ilocal] = getGlobalParNum(ilocal);
00259 if (ok [ilocal] = (iglobal >= 0 && !isParamFixed(ilocal) && isParamMeasured (ilocal))) {
00260 for (int jlocal = 0; jlocal < ilocal; jlocal++) {
00261 if (ok [jlocal]) {
00262 int jglobal = globalnum[jlocal];
00263 glcov[jglobal+iglobal*idim] += cov[ilocal][jlocal];
00264 glcov[iglobal+jglobal*idim] += cov[ilocal][jlocal];
00265 }
00266 }
00267 glcov[iglobal*(idim+1)] += cov[ilocal][ilocal];
00268 }
00269 }
00270
00271 }
00272
00273
00274 void TrackFitObject::initCov() {
00275 int n = getNPar();
00276 for (int i = 0; i < n; ++i) {
00277 for (int j = 0; j < n; ++j) {
00278 cov[i][j] = static_cast<double>(i == j);
00279 }
00280 }
00281 covinvvalid = false;
00282 }
00283
00284 void TrackFitObject::checkCov() {
00285
00286
00287 int n = getNPar();
00288 for (int i = 0; i < n; ++i) {
00289 if (isParamMeasured (i)) {
00290 for (int j = 0; j < n; ++j) {
00291 if (isParamMeasured (j)) {
00292 double cc = cov[i][i]*cov[j][j];
00293 if (cov[i][j]*cov[i][j] > cc) {
00294 cov[i][j] = cov[j][i] = (cov[i][j] > 0 ? 0.999 : -0.999) *
00295 std::sqrt(cc);
00296 covinvvalid = false;
00297 }
00298 }
00299 }
00300 }
00301 }
00302 int it = 0;
00303 while (it++ < 10) {
00304 if (calculateCovInv()) break;
00305 std::cout << "TrackFitObject::checkCov: rescaling" << std::endl;
00306 int imax = 0;
00307 int jmax = 1;
00308 double rmax = 0;
00309 for (int i = 0; i < n; ++i) {
00310 if (isParamMeasured (i)) {
00311 for (int j = i+1; j < n; ++j) {
00312 if (isParamMeasured (j)) {
00313 double r = std::abs(cov[i][j]/(std::sqrt(cov[i][i]*cov[j][j])));
00314 if (r > rmax) {
00315 rmax = r;
00316 imax = i;
00317 jmax = j;
00318 }
00319 }
00320 }
00321 }
00322 }
00323 cov[imax][jmax] *= 0.99;
00324 cov[jmax][imax] *= 0.99;
00325 }
00326 }
00327
00328 double TrackFitObject::getChi2() const {
00329 calculateChi2();
00330 return chi2;
00331 }
00332
00333 bool TrackFitObject::calculateCovInv() const {
00334 int n = getNPar();
00335 int idim = 0;
00336 for (int i = 0; i < n; ++i) {
00337 if (isParamMeasured (i)) {
00338 idim = i;
00339 for (int j = 0; j < n; ++j) {
00340 covinv[i][j] = isParamMeasured (j) ? cov[i][j] : 0;
00341 }
00342 }
00343 else {
00344 for (int j = 0; j < n; ++j) {
00345 covinv[i][j] = static_cast<double>(i == j);
00346 }
00347 }
00348 }
00349 int ierr = (idim == 0) ? 0 : dsinv(idim, &covinv[0][0], NPARMAX);
00350
00351
00352
00353
00354
00355 return covinvvalid = (ierr == 0);
00356 }
00357
00358
00359 void TrackFitObject::calculateChi2() const {
00360 if (!covinvvalid) calculateCovInv();
00361 if (!covinvvalid) {
00362 chi2 = -1;
00363 return;
00364 }
00365 chi2 = 0;
00366 for (int i = 0; i < getNPar(); ++i) {
00367 resid[i] = par[i]-mpar[i];
00368 if (chi2contr[i] = isParamMeasured(i) && !isParamFixed(i)) {
00369 chi2 += resid[i]*covinv[i][i]*resid[i];
00370 for (int j = 0; j < i; ++j) {
00371 if (chi2contr[j]) chi2 += 2*(resid[i])*covinv[i][j]*(resid[j]);
00372 }
00373 }
00374 }
00375 }
00376
00377 bool TrackFitObject::releaseVertexParam (int ivertex) {
00378 return fixVertexParam (ivertex, false);
00379 }
00380
00381 void TrackFitObject::printCov (std::ostream& os) const {
00382 os << "Covariance matrix of " << name << "\n";
00383 for(int k = 0; k < getNPar(); ++k) {
00384 for (int l = 0; l < getNPar(); ++l) {
00385 static char str[20];
00386 if (l <= k) {
00387 snprintf (str, 20, " %10.6f", cov[k][l]);
00388 }
00389 else if (l == k+1) {
00390 snprintf (str, 20, " |%9.6f", cov[k][l]/std::sqrt(cov[k][k]*cov[l][l]));
00391 }
00392 else {
00393 snprintf (str, 20, " %10.6f", cov[k][l]/std::sqrt(cov[k][k]*cov[l][l]));
00394 }
00395 os << str;
00396 }
00397 os << " " << getParamName (k) << "\n";
00398 }
00399 }