CMS 3D CMS Logo

TKinFitter.cc

Go to the documentation of this file.
00001 // Classname: TKinFitter
00002 // Author: Jan E. Sundermann, Verena Klose (TU Dresden)      
00003 
00004 
00005 //________________________________________________________________
00006 // 
00007 // TKinFitter::
00008 // --------------------
00009 //
00010 // Class to perform kinematic fit with non-linear constraints
00011 //
00012 
00013 
00014 using namespace std;
00015 
00016 #include <iostream>
00017 #include <iomanip>
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 #include "PhysicsTools/KinFitter/interface/TKinFitter.h"
00020 #include "PhysicsTools/KinFitter/interface/TAbsFitParticle.h"
00021 #include "PhysicsTools/KinFitter/interface/TAbsFitConstraint.h"
00022 
00023 ClassImp(TKinFitter)
00024 
00025 TKinFitter::TKinFitter():
00026   TNamed("UnNamed", "UnTitled"),
00027   _A(1, 1),
00028   _AT(1, 1),
00029   _B(1, 1),
00030   _BT(1, 1),
00031   _V(1, 1),
00032   _Vinv(1, 1),
00033   _VB(1, 1),
00034   _VBinv(1, 1),
00035   _VA(1, 1),
00036   _VAinv(1, 1),
00037   _c(1, 1),
00038   _C11(1, 1),
00039   _C11T(1, 1),
00040   _C21(1, 1),
00041   _C21T(1, 1),
00042   _C22(1, 1),
00043   _C22T(1, 1),
00044   _C31(1, 1),
00045   _C31T(1, 1),
00046   _C32(1, 1),
00047   _C32T(1, 1),
00048   _C33(1, 1),
00049   _C33T(1, 1),
00050   _deltaA(1, 1),
00051   _deltaY(1, 1),
00052   _lambda(1, 1),
00053   _lambdaT(1, 1),
00054   _lambdaVFit(1, 1),
00055   _yaVFit(1, 1),
00056   _constraints(0),
00057   _measParticles(0),
00058   _unmeasParticles(0)
00059 {
00060 
00061   reset();
00062 
00063 }
00064 
00065 TKinFitter::TKinFitter(const TString &name, const TString &title):
00066   TNamed(name, title),
00067   _A(1, 1),
00068   _AT(1, 1),
00069   _B(1, 1),
00070   _BT(1, 1),
00071   _V(1, 1),
00072   _Vinv(1, 1),
00073   _VB(1, 1),
00074   _VBinv(1, 1),
00075   _VA(1, 1),
00076   _VAinv(1, 1),
00077   _c(1, 1),
00078   _C11(1, 1),
00079   _C11T(1, 1),
00080   _C21(1, 1),
00081   _C21T(1, 1),
00082   _C22(1, 1),
00083   _C22T(1, 1),
00084   _C31(1, 1),
00085   _C31T(1, 1),
00086   _C32(1, 1),
00087   _C32T(1, 1),
00088   _C33(1, 1),
00089   _C33T(1, 1),
00090   _deltaA(1, 1),
00091   _deltaY(1, 1),
00092   _lambda(1, 1),
00093   _lambdaT(1, 1),
00094   _lambdaVFit(1, 1),
00095   _yaVFit(1, 1),
00096   _constraints(0),
00097   _measParticles(0),
00098   _unmeasParticles(0)
00099 {
00100 
00101   reset();
00102 
00103 }
00104 
00105 void TKinFitter::reset() {
00106   // reset all internal parameters of the fitter
00107 
00108   _status = -1;
00109   _nbIter = 0;
00110   _nParA = 0;
00111   _nParB = 0;
00112   _verbosity = 1;
00113   _A.ResizeTo(1, 1);
00114   _AT.ResizeTo(1, 1);
00115   _B.ResizeTo(1, 1);
00116   _BT.ResizeTo(1, 1);
00117   _V.ResizeTo(1, 1);
00118   _Vinv.ResizeTo(1, 1);
00119   _VB.ResizeTo(1, 1);
00120   _VBinv.ResizeTo(1, 1);
00121   _VA.ResizeTo(1, 1);
00122   _VAinv.ResizeTo(1, 1);
00123   _c.ResizeTo(1, 1);
00124   _C11.ResizeTo(1, 1);
00125   _C11T.ResizeTo(1, 1);
00126   _C21.ResizeTo(1, 1);
00127   _C21T.ResizeTo(1, 1);
00128   _C22.ResizeTo(1, 1);
00129   _C22T.ResizeTo(1, 1);
00130   _C31.ResizeTo(1, 1);
00131   _C31T.ResizeTo(1, 1);
00132   _C32.ResizeTo(1, 1);
00133   _C32T.ResizeTo(1, 1);
00134   _C33.ResizeTo(1, 1);
00135   _C33T.ResizeTo(1, 1);
00136   _deltaA.ResizeTo(1, 1);
00137   _deltaY.ResizeTo(1, 1);
00138   _lambda.ResizeTo(1, 1);
00139   _lambdaT.ResizeTo(1, 1);
00140   _lambdaVFit.ResizeTo(1, 1);
00141   _yaVFit.ResizeTo(1, 1);
00142 
00143   _constraints.clear();
00144   _measParticles.clear();
00145   _unmeasParticles.clear();
00146 
00147   // Set to default values
00148   _maxNbIter = 50;
00149   _maxDeltaS = 5e-3;
00150   _maxF =  1e-4;
00151 
00152 }
00153 
00154 void TKinFitter::resetStatus() {
00155   // reset status of the fit
00156 
00157   _status = -1;
00158   _nbIter = 0;
00159 
00160 }
00161 
00162 void TKinFitter::resetParams() {
00163   // reset all particles to their initial parameters
00164 
00165   for (unsigned int iP = 0; iP < _measParticles.size(); iP++) {
00166     TAbsFitParticle* particle = _measParticles[iP];
00167     particle->reset();
00168   }
00169   for (unsigned int iP = 0; iP < _unmeasParticles.size(); iP++) {
00170     TAbsFitParticle* particle = _unmeasParticles[iP];
00171     particle->reset();
00172   }
00173   for (unsigned int iC = 0; iC < _constraints.size(); iC++) {
00174     TAbsFitConstraint* constraint = _constraints[iC];
00175     constraint->reset();
00176   }
00177 
00178 }
00179 
00180 TKinFitter::~TKinFitter() {
00181 
00182 }
00183 
00184 void TKinFitter::countMeasParams() {
00185   // count number of measured parameters
00186 
00187   _nParB = 0;
00188   for (unsigned int indexParticle = 0; indexParticle < _measParticles.size(); indexParticle++) {
00189     _nParB += _measParticles[indexParticle]->getNPar();
00190   }
00191   for (unsigned int indexConstraint = 0; indexConstraint < _constraints.size(); indexConstraint++) {
00192     _nParB += _constraints[indexConstraint]->getNPar();
00193   }
00194 
00195 }
00196 
00197 void TKinFitter::countUnmeasParams() {
00198   // count number of unmeasured parameters
00199 
00200   _nParA = 0;
00201   for (unsigned int indexParticle = 0; indexParticle < _unmeasParticles.size(); indexParticle++) {
00202     _nParA += _unmeasParticles[indexParticle]->getNPar();
00203   }
00204 
00205 }
00206 
00207 void TKinFitter::addMeasParticle( TAbsFitParticle* particle ) {
00208   // add one measured particle
00209 
00210   resetStatus();
00211 
00212   if ( particle != 0 ) {
00213     _measParticles.push_back( particle );
00214   } else {
00215     edm::LogError ("NullPointer") << "Measured particle points to NULL. It will not be added to the KinFitter.";
00216   }
00217 
00218   countMeasParams();
00219 
00220 }
00221 
00222 void TKinFitter::addMeasParticles( TAbsFitParticle* p1, TAbsFitParticle* p2, TAbsFitParticle* p3, 
00223                               TAbsFitParticle* p4, TAbsFitParticle* p5, TAbsFitParticle* p6,
00224                               TAbsFitParticle* p7, TAbsFitParticle* p8, TAbsFitParticle* p9) {
00225   // add many measured particles
00226 
00227   resetStatus();
00228 
00229   if ( p1 != 0 ) _measParticles.push_back( p1 );
00230   if ( p2 != 0 ) _measParticles.push_back( p2 );
00231   if ( p3 != 0 ) _measParticles.push_back( p3 );
00232   if ( p4 != 0 ) _measParticles.push_back( p4 );
00233   if ( p5 != 0 ) _measParticles.push_back( p5 );
00234   if ( p6 != 0 ) _measParticles.push_back( p6 );
00235   if ( p7 != 0 ) _measParticles.push_back( p7 );
00236   if ( p8 != 0 ) _measParticles.push_back( p8 );
00237   if ( p9 != 0 ) _measParticles.push_back( p9 );
00238 
00239   countMeasParams();
00240 
00241 }
00242 
00243 void TKinFitter::addUnmeasParticle( TAbsFitParticle* particle ) {
00244   // add one unmeasured particle
00245 
00246   resetStatus();
00247 
00248   if ( particle != 0 ) {
00249     _unmeasParticles.push_back( particle );
00250   } else {
00251     edm::LogError ("NullPointer") << "Unmeasured particle points to NULL. It will not be added to the KinFitter.";
00252   }
00253 
00254   countUnmeasParams();
00255 
00256 }
00257 
00258 void TKinFitter::addUnmeasParticles( TAbsFitParticle* p1, TAbsFitParticle* p2, TAbsFitParticle* p3, 
00259                                      TAbsFitParticle* p4, TAbsFitParticle* p5, TAbsFitParticle* p6,
00260                                      TAbsFitParticle* p7, TAbsFitParticle* p8, TAbsFitParticle* p9) {
00261   // add many unmeasured particles
00262 
00263   resetStatus();
00264 
00265   if ( p1 != 0 ) _unmeasParticles.push_back( p1 );
00266   if ( p2 != 0 ) _unmeasParticles.push_back( p2 );
00267   if ( p3 != 0 ) _unmeasParticles.push_back( p3 );
00268   if ( p4 != 0 ) _unmeasParticles.push_back( p4 );
00269   if ( p5 != 0 ) _unmeasParticles.push_back( p5 );
00270   if ( p6 != 0 ) _unmeasParticles.push_back( p6 );
00271   if ( p7 != 0 ) _unmeasParticles.push_back( p7 );
00272   if ( p8 != 0 ) _unmeasParticles.push_back( p8 );
00273   if ( p9 != 0 ) _unmeasParticles.push_back( p9 );
00274 
00275   countUnmeasParams();
00276 
00277 }
00278 
00279 void TKinFitter::addConstraint( TAbsFitConstraint* constraint ) {
00280   // add a constraint
00281 
00282   resetStatus();
00283 
00284   if ( constraint != 0 ) {
00285     _constraints.push_back( constraint );
00286   }
00287 
00288   countMeasParams();
00289 
00290 }
00291 
00292 void TKinFitter::setVerbosity( Int_t verbosity ) { 
00293   // Set verbosity of the fitter:
00294   // 0: quiet
00295   // 1: print information before and after the fit
00296   // 2: print output for every iteration of the fit
00297   // 3: print debug information
00298 
00299 
00300   if ( verbosity < 0 ) verbosity = 0;
00301   if ( verbosity > 3 ) verbosity = 3;
00302   _verbosity = verbosity;
00303 
00304 }
00305 
00306 
00307 Int_t TKinFitter::fit() {
00308   // Perform the fit
00309   // Returns:
00310   // 0: converged
00311   // 1: not converged
00312 
00313   resetParams();
00314   resetStatus();
00315 
00316   _nbIter = 0;
00317   Bool_t isConverged = false;
00318   Double_t prevF;
00319   Double_t currF = getF();
00320   Double_t prevS;
00321   Double_t currS = 0.;
00322 
00323   // Calculate covariance matrix V
00324   calcV();
00325 
00326   // print status
00327   if ( _verbosity >= 1 ) {
00328     print();
00329   }
00330 
00331   do {
00332 
00333     // Reset status to "RUNNING"
00334     _status = 10;
00335 
00336     // Calculate measured matrices
00337     calcB();
00338     calcVB();
00339     calcC31();
00340     calcC33();
00341     calcC();
00342 
00343     // Calculate unmeasured
00344     if ( _nParA > 0 ) {
00345       calcA();
00346       calcVA();
00347       calcC32();
00348       calcDeltaA();
00349     }
00350 
00351     // Calculate corretion for a, y, and lambda
00352     calcDeltaY();
00353     calcLambda();
00354    
00355     if( _verbosity >= 3 ) {
00356       printMatrix( _A      , "A"      );
00357       printMatrix( _B      , "B"      );
00358       printMatrix( _VBinv  , "VBinv"  );
00359       printMatrix( _VB     , "VB"     );
00360       printMatrix( _V      , "V"      );
00361       printMatrix( _deltaY , "deltaY" );
00362       printMatrix( _deltaA , "deltaA" );
00363       printMatrix( _C32T   , "C32T"   );
00364       printMatrix( _c      , "C"      );
00365     }
00366 
00367     if( _verbosity >= 2 ) {
00368       print();   
00369     }
00370 
00371     // Apply calculated corrections to measured and unmeasured particles
00372     if ( _nParA > 0 ) {
00373       applyDeltaA();
00374     }
00375     applyDeltaY();
00376 
00377     _nbIter++;
00378     
00379     //calculate F and S
00380     prevF = currF;
00381     currF = getF();
00382     prevS = currS;
00383     currS = getS();
00384 
00385     if( TMath::IsNaN(currF) ) {
00386       edm::LogInfo ("KinFitter") << "The current value of F is NaN. Fit will be aborted.";
00387       _status = -10;
00388     }
00389     if( TMath::IsNaN(currS) ) {
00390       edm::LogInfo ("KinFitter") << "The current value of S is NaN. Fit will be aborted.";
00391       _status = -10;
00392     }
00393 
00394     // If S or F are getting bigger reduce step width
00395 //     Int_t nstep =0;
00396 //     while ( currF >= prevF ) {
00397 //       nstep++;
00398 //       if (nstep < 6) {cout <<nstep <<" : currF: "<< currF << "\t , prevF: " << prevF << endl;}
00399 //       //      cout << "Reducing step width ..." << endl;
00400 //       _deltaA *= (1.-0.001);
00401 //       _deltaY *= (1.-0.001);
00402 // //       _lambda *= 0.00001;
00403 // //       _lambdaT *= 0.00001;
00404 //       applyDeltaA();
00405 //       applyDeltaY();
00406 //       currF = getF();
00407 //       currS = getS();
00408 //     }
00409     
00410     // Test convergence
00411     isConverged = converged(currF, prevS, currS);
00412 
00413  
00414   } while ( (! isConverged) && (_nbIter < _maxNbIter) && (_status != -10) );
00415 
00416   // Calculate covariance matrices
00417   calcB();
00418   calcVB();
00419   
00420   if ( _nParA > 0 ) {
00421     calcA();
00422     calcVA();
00423     calcC21();
00424     calcC22();
00425     calcC32();
00426   }
00427   calcC11();
00428   calcC31();
00429   calcC33();
00430   calcVFit();
00431   applyVFit();
00432   
00433   // Set status information
00434   if (isConverged) {
00435     _status = 0;
00436   }
00437   else if (_status != -10) {
00438     _status = 1;
00439   }
00440   
00441   // print status
00442   if ( _verbosity >= 1 ) {
00443     print();
00444   }
00445 
00446   return _status;
00447 
00448 }
00449 
00450 void TKinFitter::setCovMatrix( TMatrixD &V ) {
00451   // Set the covariance matrix of the measured particles
00452 
00453   if ( (V.GetNrows() != _nParB) || (V.GetNcols() != _nParB) ) {
00454     edm::LogError ("WrongMatrixSize")
00455       << "Covariance matrix of measured particles needs to be a " << _nParB << "x" << _nParB << " matrix.";
00456   } else {
00457     _V.ResizeTo( V );
00458     _V = V;
00459   }
00460 
00461 }
00462 
00463 Bool_t TKinFitter::calcV() {
00464   // Combines the covariance matrices of all measured particles
00465 
00466   _V.ResizeTo( _nParB, _nParB );
00467   _V.Zero();
00468 
00469   Int_t offsetP = 0;
00470   for (unsigned int iP = 0; iP < _measParticles.size(); iP++) {
00471     TAbsFitParticle* particle = _measParticles[iP];
00472     Int_t nParP = particle->getNPar();
00473     const TMatrixD* covMatrix =  particle->getCovMatrix();
00474 
00475     for (int iX = offsetP; iX < offsetP + nParP; iX++) {
00476       for (int iY = offsetP; iY < offsetP + nParP; iY++) {
00477 
00478         _V(iX, iY) = (*covMatrix)(iX-offsetP, iY-offsetP);
00479 
00480       }
00481     }
00482 
00483     offsetP += nParP;
00484   }
00485 
00486   for (unsigned int iC = 0; iC < _constraints.size(); iC++) {
00487     TAbsFitConstraint* constraint = _constraints[iC];
00488     Int_t nParP = constraint->getNPar();
00489     const TMatrixD* covMatrix =  constraint->getCovMatrix();
00490 
00491     for (int iX = offsetP; iX < offsetP + nParP; iX++) {
00492       for (int iY = offsetP; iY < offsetP + nParP; iY++) {
00493 
00494         _V(iX, iY) = (*covMatrix)(iX-offsetP, iY-offsetP);
00495 
00496       }
00497     }
00498 
00499     offsetP += nParP;
00500   }
00501 
00502   _Vinv.ResizeTo( _V );
00503   _Vinv = _V;
00504   try {
00505     _Vinv.Invert();
00506   } catch (cms::Exception& e) {
00507     edm::LogInfo ("KinFitter") << "Failed to invert covariance matrix V.";
00508   }
00509 
00510   return true;
00511 
00512 }
00513 
00514 Bool_t TKinFitter::calcA() {
00515   // Calculate the Jacobi matrix of unmeasured parameters df_i/da_i
00516   // Row i contains the derivatives of constraint f_i. Column q contains
00517   // the derivative wrt. a_q.
00518 
00519   _A.ResizeTo( _constraints.size(), _nParA );
00520 
00521   for (unsigned int indexConstr = 0; indexConstr < _constraints.size(); indexConstr++) {
00522 
00523     int offsetParam = 0;
00524     for (unsigned int indexParticle = 0; indexParticle < _unmeasParticles.size(); indexParticle++) {
00525 
00526       // Calculate matrix product  df/dP * dP/dy = (df/dr, df/dtheta, df/dphi, ...)
00527 
00528       TAbsFitParticle* particle = _unmeasParticles[indexParticle];
00529       TMatrixD* derivParticle = particle->getDerivative();
00530       TMatrixD* derivConstr = _constraints[indexConstr]->getDerivative( particle );
00531       TMatrixD deriv( *derivConstr, TMatrixD::kMult, *derivParticle );
00532 
00533       for (int indexParam = 0; indexParam < deriv.GetNcols(); indexParam++) {
00534         _A(indexConstr,indexParam+offsetParam) = deriv(0, indexParam);
00535       }
00536       offsetParam += deriv.GetNcols();
00537 
00538       delete derivParticle;
00539       delete derivConstr;
00540 
00541     }
00542   }
00543 
00544   // Calculate transposed matrix
00545   TMatrixD AT(TMatrixD::kTransposed, _A);
00546   _AT.ResizeTo( AT );
00547   _AT = AT;
00548 
00549   return true;
00550 
00551 }
00552 
00553 Bool_t TKinFitter::calcB() {
00554   // Calculate the Jacobi matrix of measured parameters df_i/da_i
00555   // Row i contains the derivatives of constraint f_i. Column q contains
00556   // the derivative wrt. a_q.
00557 
00558   _B.ResizeTo( _constraints.size(), _nParB );
00559 
00560   int offsetParam = 0;
00561   for (unsigned int indexConstr = 0; indexConstr < _constraints.size(); indexConstr++) {
00562 
00563     offsetParam = 0;
00564     for (unsigned int indexParticle = 0; indexParticle < _measParticles.size(); indexParticle++) {
00565 
00566       // Calculate matrix product  df/dP * dP/dy = (df/dr, df/dtheta, df/dphi, ...)
00567       TAbsFitParticle* particle = _measParticles[indexParticle];
00568       TMatrixD* derivParticle = particle->getDerivative();
00569       TMatrixD* derivConstr = _constraints[indexConstr]->getDerivative( particle );
00570       TMatrixD deriv( *derivConstr,  TMatrixD::kMult, *derivParticle );
00571       if (_verbosity >= 3) {
00572         TString matrixName = "B deriv: Particle -> ";
00573         matrixName += particle->GetName();
00574         printMatrix( *derivParticle, matrixName );
00575         matrixName = "B deriv: Constraint -> ";
00576         matrixName += _constraints[indexConstr]->GetName();
00577         matrixName += " , Particle -> ";
00578         matrixName += particle->GetName();
00579         printMatrix( *derivConstr, matrixName );
00580       } 
00581       for (int indexParam = 0; indexParam < deriv.GetNcols(); indexParam++) {
00582         _B(indexConstr,indexParam+offsetParam) = deriv(0, indexParam);
00583       }
00584       offsetParam += deriv.GetNcols();
00585 
00586       delete derivParticle;
00587       delete derivConstr;
00588 
00589     }
00590   }
00591 
00592   for (unsigned int iC = 0; iC < _constraints.size(); iC++) {
00593 
00594     TAbsFitConstraint* constraint = _constraints[iC];
00595     TMatrixD* deriv = constraint->getDerivativeAlpha();
00596 
00597     if (deriv != 0) {
00598 
00599       if (_verbosity >= 3) {
00600         TString matrixName = "B deriv alpha: Constraint -> ";
00601         matrixName += constraint->GetName();
00602         printMatrix( *deriv, matrixName );
00603       } 
00604       for (int indexParam = 0; indexParam < deriv->GetNcols(); indexParam++) {
00605         _B( iC, indexParam+offsetParam ) = (*deriv)(0, indexParam);
00606       }
00607       offsetParam += deriv->GetNcols();
00608       
00609       delete deriv;
00610     }
00611   }
00612 
00613   TMatrixD BT( TMatrixD::kTransposed,  _B );
00614   _BT.ResizeTo( BT );
00615   _BT = BT;
00616 
00617   return true;
00618 
00619 }
00620 
00621 Bool_t TKinFitter::calcVB() {
00622   // Calculate the matrix V_B = (B*V*B^T)^-1
00623 
00624   TMatrixD BV( _B, TMatrixD::kMult, _V );
00625   TMatrixD VBinv( BV, TMatrixD::kMult, _BT );
00626   _VBinv.ResizeTo( VBinv );
00627   _VBinv = VBinv;
00628 
00629   _VB.ResizeTo( _VBinv );
00630   _VB = _VBinv;
00631   try {
00632     _VB.Invert();
00633   } catch (cms::Exception& e) {
00634     edm::LogInfo ("KinFitter") << "Failed to invert matrix VB. Fit will be aborted.";
00635     _status = -10;
00636   }
00637 
00638   return true;
00639 
00640 }
00641 
00642 Bool_t TKinFitter::calcVA() {
00643   // Calculate the matrix VA = (A^T*VB*A)
00644 
00645   TMatrixD ATVB( _AT, TMatrixD::kMult, _VB );
00646   TMatrixD VA(ATVB, TMatrixD::kMult, _A);
00647   _VA.ResizeTo( VA );
00648   _VA = VA;
00649 
00650   _VAinv.ResizeTo( _VA );
00651   _VAinv = _VA;
00652   try {
00653     _VAinv.Invert();
00654   } catch (cms::Exception& e) {
00655     edm::LogInfo ("KinFitter") << "Failed to invert matrix VA. Fit will be aborted.";
00656     _status = -10;
00657   }
00658 
00659   return true;
00660 
00661 }
00662 
00663 Bool_t TKinFitter::calcC11() {
00664   // Calculate the matrix C11 = V^(-1) - V^(-1)*BT*VB*B*V^(-1) + V^(-1)*BT*VB*A*VA^(-1)*AT*VB*B*V^(-1)
00665 
00666   TMatrixD VBT( _V, TMatrixD::kMult, _BT );
00667   TMatrixD VBB( _VB, TMatrixD::kMult, _B );
00668   TMatrixD VBTVBB( VBT, TMatrixD::kMult, VBB );
00669   TMatrixD m2( VBTVBB,  TMatrixD::kMult, _V );
00670 
00671   _C11.ResizeTo( _V );
00672   _C11 = _V;
00673   _C11 -= m2;
00674 
00675   if ( _nParA > 0 ) {
00676     TMatrixD VBA( _VB, TMatrixD::kMult, _A );
00677     TMatrixD VBTVBA( VBT, TMatrixD::kMult, VBA );
00678     TMatrixD VAinvAT( _VAinv, TMatrixD::kMult, _AT );
00679     TMatrixD VBTVBAVAinvAT( VBTVBA, TMatrixD::kMult, VAinvAT );
00680     TMatrixD VBTVBAVAinvATVBB( VBTVBAVAinvAT, TMatrixD::kMult, VBB );
00681     TMatrixD m3( VBTVBAVAinvATVBB, TMatrixD::kMult, _V );
00682     _C11 += m3;
00683   }
00684 
00685   TMatrixD C11T( TMatrixD::kTransposed,  _C11 );
00686   _C11T.ResizeTo( C11T );
00687   _C11T = C11T;
00688 
00689   return true;
00690 
00691 }
00692 
00693 Bool_t TKinFitter::calcC21() {
00694   // Calculate the matrix  C21 = -VA^(-1)*AT*VB*B*V^(-1)
00695 
00696   TMatrixD VAinvAT( _VAinv, TMatrixD::kMult, _AT );
00697   TMatrixD VBB( _VB, TMatrixD::kMult, _B );
00698   TMatrixD VAinvATVBB( VAinvAT, TMatrixD::kMult, VBB );
00699   TMatrixD C21( VAinvATVBB, TMatrixD::kMult, _V );
00700   C21 *= -1.;
00701   _C21.ResizeTo( C21 );
00702   _C21 = C21;
00703   
00704   TMatrixD C21T( TMatrixD::kTransposed,  _C21 );
00705   _C21T.ResizeTo( C21T );
00706   _C21T = C21T;
00707 
00708   return true;
00709 
00710 }
00711 
00712 Bool_t TKinFitter::calcC22() {
00713   //  Calculate the matrix C22 = VA^(-1)
00714 
00715   _C22.ResizeTo( _VAinv );
00716   _C22 = _VAinv;
00717 
00718   TMatrixD C22T( TMatrixD::kTransposed,  _C22 );
00719   _C22T.ResizeTo( C22T );
00720   _C22T = C22T;
00721 
00722   return true;
00723 
00724 }
00725 
00726 Bool_t TKinFitter::calcC31() {
00727   // Calculate the matrix  C31 = VB*B*V^(-1) - VB*A*VA^(-1)*AT*VB*B*V^(-1)
00728 
00729   TMatrixD VbB(_VB, TMatrixD::kMult, _B);
00730   TMatrixD m1( VbB, TMatrixD::kMult, _V );
00731 
00732   _C31.ResizeTo( m1 );
00733   _C31 = m1;
00734 
00735   if ( _nParA > 0 ) {
00736     TMatrixD VbA(_VB, TMatrixD::kMult, _A);
00737     TMatrixD VAinvAT( _VAinv, TMatrixD::kMult, _AT );
00738     TMatrixD VbBV( VbB,  TMatrixD::kMult, _V );
00739     TMatrixD VbAVAinvAT(VbA, TMatrixD::kMult, VAinvAT); 
00740     TMatrixD m2(VbAVAinvAT, TMatrixD::kMult, VbBV);
00741 
00742     _C31 -= m2;
00743   }
00744 
00745   TMatrixD C31T( TMatrixD::kTransposed,  _C31 );
00746   _C31T.ResizeTo( C31T );
00747   _C31T = C31T;
00748 
00749   return true;
00750 
00751 }
00752 
00753 Bool_t TKinFitter::calcC32() {
00754   // Calculate the matrix  C32 = VB*A*VA^(-1)
00755 
00756   TMatrixD VbA( _VB, TMatrixD::kMult, _A );
00757   TMatrixD C32( VbA, TMatrixD::kMult, _VAinv );
00758   _C32.ResizeTo( C32 );
00759   _C32 = C32;
00760 
00761   TMatrixD C32T( TMatrixD::kTransposed,  _C32 );
00762   _C32T.ResizeTo( C32T );
00763   _C32T = C32T;
00764 
00765   return true;
00766 
00767 }
00768 
00769 Bool_t TKinFitter::calcC33() {
00770   // Calculate the matrix C33 = -VB + VB*A*VA^(-1)*AT*VB
00771 
00772   _C33.ResizeTo( _VB );
00773   _C33 = _VB;
00774   _C33 *= -1.;
00775 
00776   if ( _nParA > 0 ) {
00777     TMatrixD VbA(_VB, TMatrixD::kMult, _A );
00778     TMatrixD VAinvAT( _VAinv, TMatrixD::kMult, _AT );
00779     TMatrixD VbAVAinvAT( VbA, TMatrixD::kMult, VAinvAT );
00780     TMatrixD C33( VbAVAinvAT,  TMatrixD::kMult, _VB );
00781     _C33 += C33;
00782   }
00783 
00784   TMatrixD C33T( TMatrixD::kTransposed,  _C33 );
00785   _C33T.ResizeTo( C33T );
00786   _C33T = C33T;
00787 
00788   return true;
00789 }
00790 
00791 Bool_t TKinFitter::calcC() {
00792   // Calculate the matrix c = A*deltaAStar + B*deltaYStar - fStar
00793 
00794   int offsetParam = 0;
00795 
00796   // calculate delta(a*), = 0 in the first iteration
00797   TMatrixD deltaastar( 1, 1 );
00798   if ( _nParA > 0 ) {
00799 
00800     deltaastar.ResizeTo( _nParA, 1 );
00801     for (unsigned int indexParticle = 0; indexParticle < _unmeasParticles.size(); indexParticle++) {
00802     
00803       TAbsFitParticle* particle = _unmeasParticles[indexParticle];
00804       const TMatrixD* astar = particle->getParCurr();
00805       const TMatrixD* a = particle->getParIni();
00806       TMatrixD deltaastarpart(*astar);
00807       deltaastarpart -= *a;
00808       
00809       for (int indexParam = 0; indexParam < deltaastarpart.GetNrows(); indexParam++) {
00810         deltaastar(indexParam+offsetParam, 0) = deltaastarpart(indexParam, 0);
00811       }
00812       offsetParam += deltaastarpart.GetNrows();
00813       
00814     }
00815 
00816     if ( _verbosity >= 3 ) {
00817       printMatrix( deltaastar, "deltaastar" );
00818     }
00819 
00820   }
00821 
00822   // calculate delta(y*), = 0 in the first iteration
00823   TMatrixD deltaystar( _nParB, 1 );
00824   offsetParam = 0;
00825   for (unsigned int indexParticle = 0; indexParticle < _measParticles.size(); indexParticle++) {
00826 
00827     TAbsFitParticle* particle = _measParticles[indexParticle];
00828     const TMatrixD* ystar = particle->getParCurr();
00829     const TMatrixD* y = particle->getParIni();
00830     TMatrixD deltaystarpart(*ystar);
00831     deltaystarpart -= *y;
00832 
00833     for (int indexParam = 0; indexParam < deltaystarpart.GetNrows(); indexParam++) {
00834       deltaystar(indexParam+offsetParam, 0) = deltaystarpart(indexParam, 0);
00835     }
00836     offsetParam += deltaystarpart.GetNrows();
00837 
00838   } 
00839 
00840   for (unsigned int iC = 0; iC < _constraints.size(); iC++) {
00841 
00842     TAbsFitConstraint* constraint = _constraints[iC];
00843     
00844     if ( constraint->getNPar() > 0 ) {
00845 
00846       const TMatrixD* alphastar = constraint->getParCurr();
00847       const TMatrixD* alpha = constraint->getParIni();
00848 
00849       TMatrixD deltaalphastarpart(*alphastar);
00850       deltaalphastarpart -= *alpha;
00851 
00852       for (int indexParam = 0; indexParam < deltaalphastarpart.GetNrows(); indexParam++) {
00853         deltaystar(indexParam+offsetParam, 0) = deltaalphastarpart(indexParam, 0);
00854       }
00855       offsetParam += deltaalphastarpart.GetNrows();
00856 
00857     }
00858   }
00859 
00860   if ( _verbosity >= 3 ) {
00861     printMatrix( deltaystar, "deltaystar" );
00862   }
00863 
00864   // calculate f*
00865   TMatrixD fstar( _constraints.size(), 1 );
00866   for (unsigned int indexConstr = 0; indexConstr < _constraints.size(); indexConstr++) {
00867     fstar( indexConstr, 0 ) = _constraints[indexConstr]->getCurrentValue();
00868   }
00869 
00870   // calculate c
00871   _c.ResizeTo( fstar );
00872   _c = fstar;
00873   _c *= (-1.);
00874   TMatrixD Bdeltaystar( _B, TMatrixD::kMult, deltaystar );
00875   _c += Bdeltaystar;
00876   if ( _nParA ) {
00877     TMatrixD Adeltaastar( _A, TMatrixD::kMult, deltaastar );
00878     _c += Adeltaastar;
00879   }
00880 
00881   return true;
00882 
00883 }
00884 
00885 Bool_t TKinFitter::calcDeltaA() {
00886   // Calculate the matrix deltaA = C32T * c
00887   // (corrections to unmeasured parameters)
00888 
00889   TMatrixD deltaA( _C32T, TMatrixD::kMult, _c );
00890   _deltaA.ResizeTo( deltaA );
00891   _deltaA = deltaA;
00892 
00893   return true;
00894 
00895 }
00896 
00897 Bool_t TKinFitter::calcDeltaY() {
00898   // Calculate the matrix deltaY = C31T * c 
00899   // (corrections to measured parameters)
00900 
00901   TMatrixD deltaY( _C31T, TMatrixD::kMult, _c );
00902   _deltaY.ResizeTo( deltaY );
00903   _deltaY = deltaY;
00904 
00905   return true;
00906 
00907 }
00908 
00909 Bool_t TKinFitter::calcLambda() {
00910   // Calculate the matrix Lambda = C33 * c 
00911   // (Lagrange Multipliers)
00912 
00913   TMatrixD lambda( _C33,  TMatrixD::kMult, _c );
00914   _lambda.ResizeTo( lambda );
00915   _lambda = lambda;
00916 
00917   TMatrixD lambdaT( TMatrixD::kTransposed,  _lambda );
00918   _lambdaT.ResizeTo( lambdaT );
00919   _lambdaT = lambdaT;
00920 
00921   return true;
00922 
00923 }
00924 
00925 Bool_t TKinFitter::calcVFit() {
00926   // Calculate the covariance matrix of fitted parameters
00927   //
00928   // Vfit(y) = ( C11  C21T )
00929   //     (a)   ( C21  C22  )
00930   //
00931   // Vfit(lambda) = (-C33)
00932   
00933   // Calculate covariance matrix of lambda
00934   _lambdaVFit.ResizeTo( _C33 );
00935   _lambdaVFit = _C33;
00936   _lambdaVFit *= -1.;
00937 
00938 
00939   // Calculate combined covariance matrix of y and a
00940   Int_t nbRows = _C11.GetNrows();
00941   Int_t nbCols = _C11.GetNcols();
00942   if ( _nParA > 0 ) {
00943     nbRows += _C21.GetNrows();
00944     nbCols += _C21T.GetNcols();
00945   }
00946   _yaVFit.ResizeTo( nbRows, nbCols );
00947 
00948   for (int iRow = 0; iRow < nbRows; iRow++) {
00949     for (int iCol = 0; iCol < nbCols; iCol++) {
00950 
00951       if (iRow >= _C11.GetNrows()) {
00952         if (iCol >= _C11.GetNcols()) {
00953           _yaVFit(iRow, iCol) = _C22(iRow-_C11.GetNrows(), iCol-_C11.GetNcols());
00954         } else {
00955           _yaVFit(iRow, iCol) = _C21(iRow-_C11.GetNrows(), iCol);
00956         }
00957       } else {
00958         if (iCol >= _C11.GetNcols()) {
00959           _yaVFit(iRow, iCol) = _C21T(iRow, iCol-_C11.GetNcols());
00960         } else {
00961           _yaVFit(iRow, iCol) = _C11(iRow, iCol);
00962         }
00963       }
00964 
00965     }
00966   }
00967 
00968   return true;
00969 
00970 }
00971 
00972 void TKinFitter::applyVFit() {
00973   // apply fit covariance matrix to measured and unmeasured  particles
00974 
00975   int offsetParam = 0;
00976   for (unsigned int indexParticle = 0; indexParticle < _measParticles.size(); indexParticle++) {
00977     TAbsFitParticle* particle = _measParticles[indexParticle];
00978     Int_t nbParams = particle->getNPar();
00979     TMatrixD vfit( nbParams, nbParams );
00980     for (Int_t c = 0; c < nbParams; c++) {
00981       for (Int_t r = 0; r < nbParams; r++) {
00982         vfit(r, c) = _yaVFit(r + offsetParam, c + offsetParam);
00983       }
00984     }
00985     particle->setCovMatrixFit( &vfit );
00986     offsetParam += nbParams;
00987   }
00988 
00989   for (unsigned int indexConstraint = 0; indexConstraint < _constraints.size(); indexConstraint++) {
00990     TAbsFitConstraint* constraint = _constraints[indexConstraint];
00991     Int_t nbParams = constraint->getNPar();
00992     if (nbParams > 0) {
00993       TMatrixD vfit( nbParams, nbParams );
00994       for (Int_t c = 0; c < nbParams; c++) {
00995         for (Int_t r = 0; r < nbParams; r++) {
00996           vfit(r, c) = _yaVFit(r + offsetParam, c + offsetParam);
00997         }
00998       }
00999       constraint->setCovMatrixFit( &vfit );
01000       offsetParam += nbParams;
01001     }
01002   }
01003 
01004   for (unsigned int indexParticle = 0; indexParticle < _unmeasParticles.size(); indexParticle++) {
01005     TAbsFitParticle* particle = _unmeasParticles[indexParticle];
01006     Int_t nbParams = particle->getNPar();
01007     TMatrixD vfit( nbParams, nbParams );
01008     for (Int_t c = 0; c < nbParams; c++) {
01009       for (Int_t r = 0; r < nbParams; r++) {
01010         vfit(r, c) = _yaVFit(r + offsetParam, c + offsetParam);
01011       }
01012     }
01013     particle->setCovMatrixFit( &vfit );
01014     offsetParam += nbParams;
01015   }
01016 
01017 }
01018 
01019 Bool_t TKinFitter::applyDeltaA() {
01020   //apply corrections to unmeasured particles
01021 
01022   int offsetParam = 0;
01023   for (unsigned int indexParticle = 0; indexParticle < _unmeasParticles.size(); indexParticle++) {
01024 
01025     TAbsFitParticle* particle = _unmeasParticles[indexParticle];
01026     Int_t nbParams = particle->getNPar();
01027     TMatrixD params( nbParams, 1 );
01028     for (Int_t index = 0; index < nbParams; index++) {
01029       params(index, 0) = _deltaA(index+offsetParam, 0);
01030     }
01031     particle->applycorr( &params );
01032     offsetParam+=nbParams;
01033 
01034   }
01035 
01036   return true;
01037 
01038 }
01039 
01040 Bool_t TKinFitter::applyDeltaY() {
01041   //apply corrections to measured particles
01042 
01043   int offsetParam = 0;
01044   for (unsigned int indexParticle = 0; indexParticle < _measParticles.size(); indexParticle++) {
01045 
01046     TAbsFitParticle* particle = _measParticles[indexParticle];
01047     Int_t nbParams = particle->getNPar();
01048     TMatrixD params( nbParams, 1 );
01049     for (Int_t index = 0; index < nbParams; index++) {
01050       params(index, 0) = _deltaY(index+offsetParam, 0);
01051     }
01052     particle->applycorr( &params );
01053     offsetParam+=nbParams;
01054 
01055   }
01056 
01057   for (unsigned int indexConstraint = 0; indexConstraint < _constraints.size(); indexConstraint++) {
01058 
01059     TAbsFitConstraint* constraint = _constraints[indexConstraint];
01060     Int_t nbParams = constraint->getNPar();
01061     if ( nbParams > 0 ) {
01062       TMatrixD params( nbParams, 1 );
01063       for (Int_t index = 0; index < nbParams; index++) {
01064         params(index, 0) = _deltaY(index+offsetParam, 0);
01065       }
01066       constraint->applyDeltaAlpha( &params );
01067       offsetParam+=nbParams;
01068     }
01069 
01070   }
01071 
01072   return true;
01073 
01074 }
01075   
01076 Double_t TKinFitter::getF() {
01077   // calculate current absolut value of constraints
01078   // F = Sum[ Abs(f_k( aStar, yStar)) ] 
01079 
01080   Double_t F = 0.;
01081   for (unsigned int indexConstr = 0; indexConstr < _constraints.size(); indexConstr++) {
01082     F += TMath::Abs( _constraints[indexConstr]->getCurrentValue() );
01083   }
01084   
01085   return F;
01086 
01087 }
01088 
01089 Double_t TKinFitter::getS() {
01090   // calculate current value of Chi2
01091   // S = deltaYT * V^-1 * deltaY
01092 
01093   Double_t S = 0.;
01094 
01095   if ( _nbIter > 0 ) {
01096     
01097     TMatrixD deltaYTVinv(_deltaY, TMatrixD::kTransposeMult, _Vinv);
01098     TMatrixD S2(deltaYTVinv, TMatrixD::kMult, _deltaY);
01099     S = S2(0,0);
01100          
01101   }
01102 
01103   return S;
01104 
01105 }
01106 
01107 Bool_t TKinFitter::converged( Double_t F, Double_t prevS, Double_t currS ) {
01108   // check whether convergence criteria are fulfilled
01109 
01110   Bool_t isConverged = false;
01111   
01112   // calculate F, delta(a) and delta(y) already applied
01113   isConverged = (F < _maxF);
01114 
01115   // Calculate current Chi^2 and delta(S)
01116   Double_t deltaS = currS - prevS;
01117   isConverged = isConverged && (TMath::Abs(deltaS) < _maxDeltaS);
01118 
01119   return isConverged;
01120 
01121 }
01122 
01123 TString TKinFitter::getStatusString() {
01124 
01125   TString statusstring = "";
01126 
01127   switch ( _status ) {
01128       
01129     case -1: {
01130       statusstring = "NO FIT PERFORMED";
01131       break;
01132     }
01133     case 10: {
01134       statusstring = "RUNNING";
01135       break;
01136     }
01137     case -10: {
01138       statusstring = "ABORTED";
01139       break;
01140     }
01141     case 0: {
01142       statusstring = "CONVERGED";
01143       break;
01144     }
01145     case 1: {
01146       statusstring = "NOT CONVERGED";
01147       break;
01148     }
01149   }
01150     
01151   return statusstring;
01152 
01153 }
01154 
01155 void TKinFitter::print() {
01156 
01157   edm::LogVerbatim log("KinFitter");
01158   log << "\n"
01159       << "\n";
01160   // Print status of fit
01161   log << "Status: " << getStatusString()
01162       << "   F=" << getF() << "   S=" << getS() << "   N=" << _nbIter << "   NDF=" << getNDF() << "\n";
01163   // Print measured particles
01164   log << "measured particles: \n";
01165   Int_t parIndex = 0;
01166   for (unsigned int iP = 0; iP < _measParticles.size(); iP++) {
01167     TAbsFitParticle* particle = _measParticles[iP];
01168     Int_t nParP = particle->getNPar();
01169     const TMatrixD* par = particle->getParCurr();
01170     const TMatrixD* covP = particle->getCovMatrix();
01171     log << setw(3) << setiosflags(ios::right) << iP;
01172     log << setw(15) << setiosflags(ios::right) << particle->GetName();
01173     log << setw(3) << " ";
01174     for (int iPar = 0; iPar < nParP; iPar++) {
01175       if (iPar > 0) {
01176         log << setiosflags(ios::right) << setw(21) << " ";
01177       }
01178       TString colstr = "";
01179       colstr += parIndex;
01180       colstr += ":";
01181       log << setw(4) << colstr;
01182       log << setw(2) << " ";   
01183       log << setiosflags(ios::left) << setiosflags(ios::scientific) << setprecision(3);
01184       log << setw(15) << (*par)(iPar, 0);
01185       if(_nbIter > 0 && _status < 10) {
01186         log << setw(15) << TMath::Sqrt( _yaVFit(iPar, iPar) );
01187       } else {
01188         log << setw(15) << " ";
01189       }
01190       log << setw(15) << TMath::Sqrt( (*covP)(iPar, iPar) );
01191       log << "\n";
01192       parIndex++;
01193     }
01194     log << particle->getInfoString();
01195   }
01196   // Print unmeasured particles
01197   log << "unmeasured particles: \n";
01198   parIndex = 0;
01199   for (unsigned int iP = 0; iP < _unmeasParticles.size(); iP++) {
01200     TAbsFitParticle* particle = _unmeasParticles[iP];
01201     Int_t nParP = particle->getNPar();
01202     const TMatrixD* par = particle->getParCurr();
01203     log << setw(3) << setiosflags(ios::right) << iP;
01204     log << setw(15) << particle->GetName();
01205     log << setw(3) << " ";
01206     for (int iPar = 0; iPar < nParP; iPar++) {
01207       if (iPar > 0) {
01208         log << setiosflags(ios::right) << setw(21) << " ";
01209       }
01210       TString colstr = "";
01211       colstr += parIndex;
01212       colstr += ":";
01213       log << setw(4) << colstr;
01214       log << setw(2) << " ";
01215       log << setiosflags(ios::left) << setiosflags(ios::scientific) << setprecision(3);
01216       log << setw(15) << (*par)(iPar, 0);
01217       if(_nbIter > 0 && _status < 10) {
01218         log << setw(15) << TMath::Sqrt( _yaVFit(iPar+_nParB, iPar+_nParB) );
01219       } else {
01220         log << setw(15) << " ";
01221       }
01222       log << "\n";
01223       parIndex++;
01224     }
01225     log << particle->getInfoString();
01226   }
01227   log << "\n";
01228   // Print constraints
01229   log << "constraints: \n";
01230   for (unsigned int indexConstr = 0; indexConstr < _constraints.size(); indexConstr++) {
01231     log << _constraints[indexConstr]->getInfoString();
01232   }
01233   log << "\n";
01234 
01235 }
01236 
01237 void TKinFitter::printMatrix(const TMatrixD &matrix, const TString name) {
01238   // produce a tabular printout for matrices
01239   // this function is a modified version of Root's TMatrixTBase<Element>::Print method
01240   // which could not be used together with the MessageLogger
01241 
01242   if (!matrix.IsValid()) {
01243     edm::LogWarning ("InvalidMatrix") << "Matrix " << name << " is invalid.";
01244     return;
01245   }
01246 
01247   edm::LogVerbatim log("KinFitter");
01248 
01249   const Int_t nCols  = matrix.GetNcols();
01250   const Int_t nRows  = matrix.GetNrows();
01251   const Int_t colsPerSheet = 5;
01252   char topbar[100];
01253   Int_t nk = 6+13*TMath::Min(colsPerSheet, nCols);
01254   for(Int_t i = 0; i < nk; i++) topbar[i] = '-';
01255   topbar[nk] = 0;
01256 
01257   Int_t sw = (70-name.Length())/2;
01258  
01259   log << setfill('=') << setw(sw) << "=  " << name << setw(sw) << left << "  ="  << "\n"
01260       << setfill(' ') << right << "\n";
01261 
01262   log << nRows << "x" << nCols << " matrix is as follows \n";
01263 
01264   for (Int_t iSheet = 0; iSheet < nCols; iSheet += colsPerSheet) {
01265     log << "\n"
01266         << "     |";
01267     for (Int_t iCol = iSheet; iCol < iSheet+colsPerSheet && iCol < nCols; iCol++)
01268       log << setw(8) << iCol << "    |";
01269     log << "\n"
01270         << topbar << " \n";
01271     for(Int_t iRow = 0; iRow < nRows; iRow++) {
01272       log << setw(4) << iRow << " |";
01273       for (Int_t iCol = iSheet; iCol < iSheet+colsPerSheet && iCol < nCols; iCol++)
01274         log << setw(12) << matrix(iRow, iCol) << " ";
01275       log << "\n";
01276     }
01277   }
01278 
01279 }

Generated on Tue Jun 9 17:41:16 2009 for CMSSW by  doxygen 1.5.4