00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00148 _maxNbIter = 50;
00149 _maxDeltaS = 5e-3;
00150 _maxF = 1e-4;
00151
00152 }
00153
00154 void TKinFitter::resetStatus() {
00155
00156
00157 _status = -1;
00158 _nbIter = 0;
00159
00160 }
00161
00162 void TKinFitter::resetParams() {
00163
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
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
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
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
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
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
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
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
00294
00295
00296
00297
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
00309
00310
00311
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
00324 calcV();
00325
00326
00327 if ( _verbosity >= 1 ) {
00328 print();
00329 }
00330
00331 do {
00332
00333
00334 _status = 10;
00335
00336
00337 calcB();
00338 calcVB();
00339 calcC31();
00340 calcC33();
00341 calcC();
00342
00343
00344 if ( _nParA > 0 ) {
00345 calcA();
00346 calcVA();
00347 calcC32();
00348 calcDeltaA();
00349 }
00350
00351
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
00372 if ( _nParA > 0 ) {
00373 applyDeltaA();
00374 }
00375 applyDeltaY();
00376
00377 _nbIter++;
00378
00379
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
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 isConverged = converged(currF, prevS, currS);
00412
00413
00414 } while ( (! isConverged) && (_nbIter < _maxNbIter) && (_status != -10) );
00415
00416
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
00434 if (isConverged) {
00435 _status = 0;
00436 }
00437 else if (_status != -10) {
00438 _status = 1;
00439 }
00440
00441
00442 if ( _verbosity >= 1 ) {
00443 print();
00444 }
00445
00446 return _status;
00447
00448 }
00449
00450 void TKinFitter::setCovMatrix( TMatrixD &V ) {
00451
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
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
00516
00517
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
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
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
00555
00556
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
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
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
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
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
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
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
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
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
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
00793
00794 int offsetParam = 0;
00795
00796
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
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
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
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
00887
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
00899
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
00911
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
00927
00928
00929
00930
00931
00932
00933
00934 _lambdaVFit.ResizeTo( _C33 );
00935 _lambdaVFit = _C33;
00936 _lambdaVFit *= -1.;
00937
00938
00939
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
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
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( ¶ms );
01032 offsetParam+=nbParams;
01033
01034 }
01035
01036 return true;
01037
01038 }
01039
01040 Bool_t TKinFitter::applyDeltaY() {
01041
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( ¶ms );
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( ¶ms );
01067 offsetParam+=nbParams;
01068 }
01069
01070 }
01071
01072 return true;
01073
01074 }
01075
01076 Double_t TKinFitter::getF() {
01077
01078
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
01091
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
01109
01110 Bool_t isConverged = false;
01111
01112
01113 isConverged = (F < _maxF);
01114
01115
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
01161 log << "Status: " << getStatusString()
01162 << " F=" << getF() << " S=" << getS() << " N=" << _nbIter << " NDF=" << getNDF() << "\n";
01163
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
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
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
01239
01240
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 }