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