Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members

WWFitterFast.C

Go to the documentation of this file.
00001 
00002 // Class WWFitterFast
00003 //
00004 // Author: Jenny Boehme, Benno List
00005 // Last update: $Date: 2005/01/12 10:11:46 $
00006 //          by: $Author: blist $
00007 // 
00008 // Description: kinematic fit a la WWFGO
00009 // DISCLAIMER: the only object oriented stuff in here is the
00010 //             interface to fit objects (jets, neutrinos,....)
00011 //             and constraints (px, py, M_W, ....)
00012 //             which replaces the calls to WWKCNS.
00013 //             The WWFitterFast::fit() method is almost an
00014 //             'F to C' translation of WWFGO. It is NOT
00015 //             considered to be good C++, but was done
00016 //             on purpose as a first implementation.
00017 //             An OO version might follow later!     
00018 //  
00019 //
00020 // This is a faster version of WWFitter,
00021 // which replaces (in  the iteration loop) all calculations
00022 // of inverse matrices with the solution of corresponding systems
00023 // of equations
00024 //
00025 // IMPORTANT: This Fitter is yet untested for the case of 
00026 // unmeasured quantities (i.e., neutrinos!)!!!
00027 //           
00029 
00030 #include<iostream>
00031 #include<cmath>
00032 
00033 #include "jbltools/kinfit/WWFitterFast.h" 
00034 
00035 #include "jbltools/kinfit/BaseFitObject.h"
00036 #include "jbltools/kinfit/BaseConstraint.h"
00037 #include "jbltools/kinfit/ftypes.h"
00038 #include "jbltools/kinfit/cernlib.h"
00039 
00040 using std::cout;
00041 using std::endl;
00042 
00043 // constructor
00044 WWFitterFast::WWFitterFast() : npar(0), nmea(0), nunm(0), ncon(0), ierr (0)  {};
00045 
00046 // destructor
00047 WWFitterFast::~WWFitterFast() {};
00048 
00049 // do it (~ transcription of WWFGO as of ww113)
00050 double WWFitterFast::fit() {
00051 
00052   // cout statements
00053   bool debug = false;
00054 
00055   // order parameters etc
00056   initialize();
00057   
00058   // initialize eta, etasv, y 
00059   FDouble eta[NPARMAX];
00060   FDouble etasv[NPARMAX];
00061   FDouble y[NPARMAX];           
00062   
00063   for (unsigned int i = 0; i < fitobjects.size(); ++i) {
00064     for (int ilocal = 0; ilocal < fitobjects[i]->getNPar(); ++ilocal) {
00065       int iglobal = fitobjects[i]->getGlobalParNum (ilocal);
00066       if (iglobal >= 0) y[iglobal] = eta[iglobal] = fitobjects[i]->getParam(ilocal);
00067       //if (debug) cout << "eta[" << iglobal << "] = " << eta[iglobal] 
00068       //                << " for jet " << i << " and ilocal = " << ilocal << endl;
00069     }
00070   }
00071 
00072   // initialize dfeta ( = d F / d eta)
00073   FDouble dfeta[NCONMAX][NPARMAX];   //  npar x nconstraint
00074   for (int k=0; k < ncon; k++) {
00075     for (int j=0; j < npar; j++) dfeta[k][j]=0;
00076     constraints[k]->getDerivatives(NPARMAX, dfeta[k]);
00077     //if (debug) for (int j=0; j < npar; j++) 
00078       //cout << "dfeta[" << k << "][" << j << 
00079       //                     "] = " << dfeta[k][j] << endl;
00080   }
00081   
00082 
00083   // R & S & W1
00084   FDouble R[NCONMAX];                      // list of constraints
00085   FDouble S[NCONMAX][NCONMAX];             // nconstraint  x  nconstraint
00086   FDouble W1[NUNMMAX][NUNMMAX];            // nunmeasured  x  nunmeasured
00087   FDouble V[NPARMAX][NPARMAX];             // error matrix of parameters
00088   FDouble dxi[NUNMMAX];                    // shift of unmeasured parameters
00089   FDouble alam[NCONMAX];                   // Lagrange multipliers
00090 
00091   // chi2's, step size, # iterations
00092   double chinew=0, chit=0, chik=0;
00093   double alph = 1.;
00094   nit = 0;
00095   // convergence criteria (as in WWINIT)
00096   // int nitmax = 20;
00097   int nitmax = 200;
00098   double chik0 = 100.;
00099   double chit0 = 100.;
00100   double dchikc = 1.0E-3;
00101   double dchitc = 1.0E-4;
00102   double dchikt = 1.0E-2;
00103   double dchik  = 1.05;
00104   double chimxw = 1000.;
00105   double almin = 0.05;
00106  
00107 
00108   // repeat with or with out smaller steps size 
00109   bool repeat = true;
00110   bool scut = false;
00111   bool calcerr = true;
00112  
00113   // start of iterations
00114   while (repeat) {
00115     bool updatesuccess = true;
00116   
00117 //*-- If necessary, retry smaller step, same direction
00118     if (scut) {
00119       for (int j=0; j < npar; j++) eta[j] = etasv[j];
00120       updatesuccess = updateFitObjects (eta);
00121       if (!updatesuccess) {
00122         std::cerr << "WWFitterFast::fit: old parameters are garbage!" << std::endl;
00123         return -1;
00124       }
00125       for (int k = 0; k < ncon; ++k)  {
00126         for (int j=0; j < npar; j++) dfeta[k][j]=0;
00127         constraints[k]->getDerivatives(NPARMAX, dfeta[k]);
00128       }
00129     } 
00130     else {
00131       for (int j=0; j < npar; j++) etasv[j] = eta[j];
00132       chik0 = chik;
00133       chit0 = chit;
00134     }
00135     
00136     // Get covariance matrix
00137     for (int i = 0; i < npar; ++i) 
00138       for (int j = 0; j < npar; ++j) V[i][j] = 0;
00139     for (unsigned int ifitobj = 0; ifitobj<fitobjects.size(); ++ifitobj) {
00140       fitobjects[ifitobj]->addToGlobCov (&V[0][0], NPARMAX);
00141     }  
00142     
00143     
00144 // *-- Evaluate r and S.
00145     for (int k = 0; k < ncon; ++k) R[k] = constraints[k]->getValue();
00146     for (int j = 0; j < nmea; ++j) {
00147       double dy = y[j]-eta[j];
00148       for (int k = 0; k < ncon; ++k) {
00149         R[k] += dfeta[k][j]*dy;
00150       }
00151     }
00152     
00153     for (int l = 0; l < ncon; ++l) {
00154       for (int k = 0; k < ncon; ++k) S[k][l] = 0;
00155     }
00156     for (int i = 0; i < nmea; ++i) {
00157       for (int j = 0; j < nmea; ++j) {
00158         double v=V[i][j];
00159         for (int k = 0; k < ncon; ++k){
00160           double dfetav = dfeta[k][i]*v;
00161           for (int l = 0; l < ncon; ++l) {
00162             S[k][l] += dfetav * dfeta[l][j]; 
00163           }
00164         }
00165       }
00166     }
00167     
00168 
00169 // *-- Calculate new unmeasured quantities:
00170 // Calculate W1_ij = dfeta_k,nmea+i * Sinv_kl * dfeta_l,nmea+j
00171 // This is the same as W1_ij = dfeta_k,nmea+i * xhelp_kj,
00172 // where x is the solution of S_ik * xhelp_kj = dfeta_i,nmea+j
00173   
00174     if (nunm > 0) {
00175       FDouble xhelp[NCONMAX][NPARMAX]; 
00176       for (int k=0; k < ncon; k++) {
00177         for (int j=0; j < npar; j++) xhelp[k][j] = dfeta[k][nmea+j];
00178       }
00179       dseqn (ncon, &S[0][0], NCONMAX, nunm, &xhelp[0][0]);
00180       
00181       for (int i = 0; i < nunm; ++i) {
00182         for (int j = 0; j < nunm; ++j) W1[i][j] = 0;
00183       }  
00184       for (int k = 0; k < ncon; ++k) {
00185        for (int j = 0; j < nunm; ++j) {
00186          for (int i = 0; i < nunm; ++i) {
00187            W1[i][j] += dfeta[k][nmea+i] * xhelp[j][k];
00188          }
00189        }
00190       }
00191       
00192 
00193       
00194       // calculate shift of unmeasured parameters
00195 
00196       // we need W^-1 just to calculate dxi = -W^-1 dfeta Sinv R,
00197       // so instead of inverting W, just solve the system
00198       // W*dxi = -dfeta Sinv R = work
00199       
00200       // Additionally, instead of evaluating Sr = Sinv * R, we solve
00201       // S * Sr = R
00202       
00203       std::cerr << "WWFitterFast::fit(): Untested!!!" << endl;
00204       
00205       for (int i = 0; i < nunm; ++i) dxi[i] = 0;
00206       
00207       FDouble Sr[NCONMAX];
00208       
00209       for (int l = 0; l < ncon; ++l) Sr[l] = R[l];
00210       dsfeqn (ncon, &S[0][0], NCONMAX, 1, Sr);
00211       
00212       for (int k = 0; k < ncon; ++k) {
00213         for (int i = 0; i < nunm; ++i) {
00214           dxi[i] -= dfeta[k][nmea+i]* Sr[k];
00215         }
00216       }
00217       
00218       dseqn (nunm, &W1[0][0], NUNMMAX, ierr, 1, dxi);
00219     }
00220     
00221     
00222 // *-- And now update unmeasured parameter.
00223     for (int i = 0; i < nunm; ++i) {
00224       eta[nmea+i] += dxi[i];
00225     }
00226     
00227 // *-- Calculate new Lagrange multipliers.
00228     // Again, instead of multiplying alam = Sinv * (R + dfeta*dx), 
00229     // we solve S*alam = R + dfeta*dx
00230     for (int k = 0; k < ncon; ++k) {
00231       alam[k] = R[k];
00232     }
00233     for (int j = 0; j < nunm; ++j) {
00234       double d = dxi[j];
00235       int nmeaj = nmea+j;
00236       for (int k = 0; k < ncon; ++k) {
00237         alam[k] += dfeta[k][nmeaj] * d;
00238       }
00239     }
00240     if (nunm > 0) {
00241       dsfeqn (ncon, &S[0][0], NCONMAX, 1, alam);
00242     }
00243     else {
00244       dseqn (ncon, &S[0][0], NCONMAX, 1, alam);
00245     }
00246 // *-- Calculate new fitted parameters.
00247     for (int i = 0; i < nmea; ++i) eta[i] = y[i];
00248     for (int k = 0; k < ncon; ++k) {
00249       double a = alam[k];
00250       for (int j = 0; j < nmea; ++j) {
00251         double dfetaa =  dfeta[k][j] * a;
00252         for (int i = 0; i < nmea; ++i) {
00253           eta[i] -= V[i][j] * dfetaa;
00254         }
00255       }
00256     }
00257     
00258 // *-- Calculate constraints and their derivatives.
00259     // since the constraints ask the fitobjects for their parameters, 
00260     // we need to update the fitobjects first!
00261     // COULD BE DONE: update also ERRORS! (now only in the very end!)
00262     updatesuccess = updateFitObjects (eta);
00263          
00264     if (debug) {
00265       cout << "After adjustment of all parameters:\n";
00266       for (int k = 0; k < ncon; ++k) {
00267         cout << "Value of constraint " << k << " = " << constraints[k]->getValue()
00268              << endl;
00269       }
00270     }
00271     for (int k=0; k < ncon; k++) {
00272       for (int j=0; j < npar; j++) dfeta[k][j]=0;
00273       constraints[k]->getDerivatives(NPARMAX, dfeta[k]);
00274     }
00275 
00276 // *-- Calculate new chisq.
00277 
00278     // Instead of evaluating Vinvdeta = Vinv * deta,
00279     // solve V * Vinvdeta = deta:
00280     
00281     FDouble deta[NPARMAX];
00282     FDouble Vinvdeta[NPARMAX];
00283     
00284     chit = 0;
00285     for (int i = 0; i < nmea; ++i) {
00286       Vinvdeta[i] = deta[i] = (y[i]-eta[i]);
00287     } 
00288     
00289     dseqn (nmea, &V[0][0], NPARMAX, 1, Vinvdeta);
00290      
00291     chit = 0;
00292     for (int i = 0; i < nmea; ++i) {
00293       chit  += deta[i] * Vinvdeta[i];
00294     }
00295     chik = 0;
00296     for (int k = 0; k < ncon; ++k) chik += std::abs(2*alam[k]*constraints[k]->getValue());
00297     
00298     chinew = chit + chik;
00299     
00300 //*-- Calculate change in chisq, and check constraints are satisfied.
00301     nit++;
00302     
00303     bool sconv = (std::abs(chik-chik0) < dchikc) 
00304               && (std::abs(chit-chit0) < dchitc*chit) 
00305               && (chik < dchikt*chit);
00306     // Second convergence criterium:
00307     // If all constraints are fulfilled to better than 1E-8,
00308     // and all parameters have changed by less than 1E-8,
00309     // assume convergence
00310     // This criterium assumes that all constraints and all parameters
00311     // are "of order 1", i.e. their natural values are around 1 to 100,
00312     // as for GeV or radians
00313     double eps = 1E-8;
00314     bool sconv2 = true;
00315     for (int k = 0; sconv2 && (k < ncon); ++k) 
00316       sconv2 &= (std::abs(constraints[k]->getValue()) < eps);
00317     if (sconv2 && debug) 
00318       cout << "All constraints fulfilled to better than " << eps << endl;
00319        
00320     for (int j = 0; sconv2 && (j < npar); ++j) 
00321       sconv2 &= (std::abs(eta[j] - etasv[j]) < eps);
00322     if (sconv2 && debug) 
00323       cout << "All parameters stable to better than " << eps << endl;
00324     sconv |= sconv2;
00325              
00326     bool sbad  = (chik > dchik*chik0) 
00327               && (chik > dchikt*chit)
00328               && (chik > chik0 + 1.E-10);
00329               
00330     if (nit > nitmax) {
00331 // *-- Out of iterations
00332       repeat = false;
00333       ierr = 1;
00334     }  
00335     else if (sconv && updatesuccess) {
00336 // *-- Converged
00337       repeat = false;
00338       ierr = 0;
00339     }  
00340     else if ( nit > 2 && chinew > chimxw  && updatesuccess) {
00341 // *-- Chi2  crazy ?
00342       repeat = false;
00343       calcerr = false;
00344       ierr = 2;
00345     }  
00346     else if (sbad && nit > 1  || !updatesuccess) {
00347 // *-- ChiK increased, try smaller step
00348       if ( alph == almin ) {
00349         repeat = false;
00350         calcerr = false;
00351         ierr = 3;
00352       }  
00353       else {
00354         alph  =  std::max (almin, 0.5 * alph);
00355         scut  =  true;
00356         repeat = true;
00357         ierr = 4;
00358       }
00359     }    
00360     else {
00361 // *-- Keep going..
00362       alph  =  std::min (alph+0.1, 1. );
00363       repeat = true;
00364       ierr = 5;
00365     }
00366     
00367     if (debug) cout << "======== NIT = " << nit << ",  CHI2 = " << chinew 
00368                                      << ",  ierr = " << ierr << endl;
00369                                      
00370     if (debug) 
00371       for (unsigned int i = 0; i < fitobjects.size(); ++i) 
00372         cout << "fitobject " << i << ": " << *fitobjects[i] << endl;                                 
00373 
00374   }   // end of while (repeat)
00375   
00376 // *-- End of iterations - calculate errors.
00377   FDouble VETA[NPARMAX][NPARMAX];
00378   for (int i = 0; i < npar; ++i) 
00379     for (int j = 0; j < npar; ++j) VETA[i][j] = 0;
00380     
00381   FDouble Sinv[NCONMAX][NCONMAX];             // nconstraint  x  nconstraint
00382  
00383   if (calcerr) {
00384   
00385 // *-- Evaluate S and invert.
00386     for (int k = 0; k < ncon; ++k) {
00387       for (int l = 0; l < ncon; ++l) {
00388         S[k][l] = 0;
00389       }
00390     }
00391     for (int i = 0; i < npar; ++i) {
00392       for (int j = 0; j < npar; ++j) {
00393         double v = V[i][j];
00394         for (int k = 0; k < ncon; ++k) {
00395           double dfetav = dfeta[k][i] * v;
00396           for (int l = 0; l < ncon; ++l) {
00397             S[k][l] += dfetav * dfeta[l][j]; 
00398           }
00399         }
00400       }
00401     }
00402     for (int k = 0; k < ncon; ++k) {
00403       for (int l = 0; l < ncon; ++l) {
00404         Sinv[k][l] = S[k][l];
00405       }
00406     }
00407    
00408 // *-- Invert S, testing for singularity first.
00409 // skip singularity test, since it only fixes some machine dependency
00410 // of DSINV/RSINV (-> cernlib)
00411     dsinv(ncon, &Sinv[0][0], NCONMAX, ierr);
00412 
00413 // *-- Calculate G.  
00414 //  (same as W1, but for measured parameters) 
00415     FDouble G[NPARMAX][NPARMAX];
00416     for (int i = 0; i < nmea; ++i) {
00417       for (int j = 0; j < nmea; ++j) G[i][j] = 0;
00418     }
00419     for (int k = 0; k < ncon; ++k) {
00420       for (int l = 0; l < ncon; ++l) {
00421         double s = Sinv[k][l];
00422         for (int i = 0; i < nmea; ++i) {
00423           double dfetas = s*dfeta[k][i];
00424           for (int j = 0; j < nmea; ++j) {
00425             G[i][j] += dfetas * dfeta[l][j];
00426           }
00427         }
00428       }
00429     }
00430     
00431     if (nunm > 0) {
00432 
00433 // *-- Calculate H.
00434       FDouble H[NPARMAX][NUNMMAX];
00435       for (int i = 0; i < nmea; ++i) {
00436         for (int j = 0; j < nunm; ++j) {
00437           H[i][j] = 0;
00438           for (int k = 0; k < ncon; ++k) {
00439             for (int l = 0; l < ncon; ++l) {
00440               H[i][j] += dfeta[k][i] * Sinv[k][l] * dfeta[l][nmea+j];
00441             }
00442           }
00443         }
00444       }
00445       
00446 // *-- Calculate U**-1 and invert.
00447 //   (same as W1)
00448       FDouble U[NUNMMAX][NUNMMAX];
00449       for (int i = 0; i < nunm; ++i) {
00450         for (int j = 0; j < nunm; ++j) {
00451           U[i][j] = 0;
00452           for (int k = 0; k < ncon; ++k) {
00453             for (int l = 0; l < ncon; ++l) {
00454               U[i][j] += dfeta[k][nmea+i] * Sinv[k][l] * dfeta[l][nmea+j];
00455             }
00456           }
00457         }
00458       }
00459       dsinv(nunm, &U[0][0], NUNMMAX, ierr);
00460      
00461 // *-- U is now error matrix of unmeasured parameters
00462       for (int i = 0; i < nunm; ++i) {
00463         for (int j = 0; j < nunm; ++j) {
00464           VETA[nmea+i][nmea+j] = U[i][j];
00465         }
00466       }
00467 
00468 // *-- Covariance matrix between measured and unmeasured parameters.
00469       for (int i = 0; i < nmea; ++i) {
00470         for (int j = 0; j < nunm; ++j) {
00471           VETA[i][nmea+j] = 0.;
00472           for (int ii = 0; ii < nmea; ++ii) {
00473             for (int jj = 0; jj < nunm; ++jj) {
00474               VETA[i][nmea+j] -= V[i][ii] * H[ii][jj] * U[jj][j];
00475             }
00476           }
00477         }
00478       }
00479       
00480 // *-- Fill in symmetric part:
00481       for (int i = 0; i < nmea; ++i) {
00482         for (int j = 0; j < nunm; ++j) {
00483           VETA[nmea+j][i] = VETA[i][nmea+j];
00484         }
00485       }
00486       
00487 // *-- Calculate G-HUH.
00488       for (int i = 0; i < nmea; ++i) {
00489         for (int j = 0; j < nmea; ++j) {
00490           for (int ii = 0; ii < nunm; ++ii) {
00491             for (int jj = 0; jj < nunm; ++jj) {
00492               G[i][j] -= H[i][ii] * U[ii][jj] * H[j][jj];
00493             }
00494           }
00495         }
00496       }
00497       
00498     }  // endif nunm > 0
00499 
00500 // *-- Calculate I-GV.
00501     FDouble GV[NPARMAX][NPARMAX];
00502     for (int i = 0; i < nmea; ++i) {
00503       for (int j = 0; j < nmea; ++j) {
00504         if (i == j) GV[i][j] = 1.;
00505         else GV[i][j] = 0.;
00506         for (int ii = 0; ii < nmea; ++ii) {
00507           GV[i][j] -= G[i][ii] * V[ii][j];
00508         }
00509       }
00510     }
00511 
00512 // *-- And finally error matrix on fitted parameters.
00513     for (int i = 0; i < nmea; ++i) {
00514       for (int j = 0; j < nmea; ++j) {
00515         VETA[i][j] = 0.;
00516         for (int ii = 0; ii < nmea; ++ii) {
00517           VETA[i][j] += V[i][ii] * GV[ii][j];
00518         }
00519       }
00520     }
00521 
00522     // update errors in fitobjects
00523     // (consider only diagonal elements of VETA for the moment...)
00524     for (unsigned int ifitobj = 0; ifitobj < fitobjects.size(); ++ifitobj) {
00525       for (int ilocal = 0; ilocal < fitobjects[ifitobj]->getNPar(); ++ilocal) {
00526         int iglobal = fitobjects[ifitobj]->getGlobalParNum (ilocal); 
00527         if (iglobal >= 0) fitobjects[ifitobj]->setError(ilocal, 
00528                              std::sqrt(std::fabs(VETA[iglobal][iglobal]))); 
00529       }
00530     }
00531     
00532   } // endif calcerr == true
00533 
00534 // *-- Turn chisq into probability.
00535   FReal chi = FReal(chinew);
00536   fitprob = (ncon-nunm > 0) ? prob(chi,ncon-nunm) : 0.5;
00537   chi2 = chinew;
00538 
00539   return fitprob;
00540     
00541 };
00542 
00543 bool WWFitterFast::initialize() {
00544   // tell fitobjects the global ordering of their parameters:
00545   int iglobal = 0;
00546   // measured parameters first!
00547   for (unsigned int ifitobj = 0; ifitobj < fitobjects.size(); ++ifitobj) {
00548     for (int ilocal = 0; ilocal < fitobjects[ifitobj]->getNPar(); ++ilocal) {
00549       if (fitobjects[ifitobj]->isParamMeasured(ilocal) &&
00550           !fitobjects[ifitobj]->isParamFixed(ilocal)) {
00551         fitobjects[ifitobj]->setGlobalParNum (ilocal, iglobal);
00552         ++iglobal;
00553       }
00554     }
00555   }
00556   nmea = iglobal;
00557   // now  unmeasured parameters!
00558   for (unsigned int ifitobj = 0; ifitobj < fitobjects.size(); ++ifitobj) {
00559     for (int ilocal = 0; ilocal < fitobjects[ifitobj]->getNPar(); ++ilocal) {
00560       if (!fitobjects[ifitobj]->isParamMeasured(ilocal) &&
00561           !fitobjects[ifitobj]->isParamFixed(ilocal)) {
00562         fitobjects[ifitobj]->setGlobalParNum (ilocal, iglobal);
00563         ++iglobal;
00564       }
00565     }
00566   }
00567   npar = iglobal;
00568   nunm = npar - nmea;
00569   
00570   // set number of constraints
00571   ncon = constraints.size();
00572   
00573   return true;
00574 
00575 };
00576   
00577 bool WWFitterFast::updateFitObjects (double eta[]) {
00578   bool debug = false;
00579   bool result = true;
00580   for (unsigned int ifitobj = 0; ifitobj < fitobjects.size(); ++ifitobj) {
00581     for (int ilocal = 0; ilocal < fitobjects[ifitobj]->getNPar(); ++ilocal) {
00582       int iglobal = fitobjects[ifitobj]->getGlobalParNum (ilocal); 
00583       if (!fitobjects[ifitobj]->isParamFixed (ilocal) && iglobal >= 0) {
00584         if (debug) cout << "Parameter " << iglobal 
00585                         << " (" << fitobjects[ifitobj]->getName()
00586                         << ": " << fitobjects[ifitobj]->getParamName(ilocal)
00587                         << ") set to " << eta[iglobal];
00588         result &= fitobjects[ifitobj]->setParam(ilocal, eta[iglobal]); 
00589         eta[iglobal] = fitobjects[ifitobj]->getParam(ilocal);
00590         if (debug) cout << " => " << eta[iglobal] << endl;
00591       }
00592     }
00593   }
00594   return result;
00595 };
00596 
00597 int WWFitterFast::getError() const {return ierr;}
00598 double WWFitterFast::getProbability() const {return fitprob;}
00599 double WWFitterFast::getChi2() const {return chi2;}
00600 int WWFitterFast::getIterations() const {return nit;}

Generated on Fri Sep 14 17:38:21 2007 for Kinfit by doxygen 1.3.2