00001
00014 #include "Minuit2/VariableMetricMinimizer.h"
00015 #include "Minuit2/FunctionMinimum.h"
00016 #include "Minuit2/MnPrint.h"
00017 #include "Minuit2/MnMigrad.h"
00018 #include "Minuit2/MnUserParameterState.h"
00019 #include "CLHEP/config/CLHEP.h"
00020
00021
00022 #include <vector>
00023 #include <cmath>
00024
00025
00026 #include "RecoVertex/BeamSpotProducer/interface/BSFitter.h"
00027 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00028 #include "FWCore/Utilities/interface/Exception.h"
00029
00030
00031 #include "TMatrixD.h"
00032 #include "TMatrixDSym.h"
00033 #include "TH1.h"
00034 #include "TF1.h"
00035
00036 using namespace ROOT::Minuit2;
00037
00038
00039
00040 BSFitter::BSFitter() {
00041 }
00042
00043
00044 BSFitter::BSFitter( std:: vector< BSTrkParameters > BSvector ) {
00045
00046 ffit_type = "default";
00047 ffit_variable = "default";
00048
00049 fBSvector = BSvector;
00050
00051 fsqrt2pi = sqrt(2.* TMath::Pi());
00052
00053 fpar_name[0] = "z0 ";
00054 fpar_name[1] = "SigmaZ0 ";
00055 fpar_name[2] = "X0 ";
00056 fpar_name[3] = "Y0 ";
00057 fpar_name[4] = "dxdz ";
00058 fpar_name[5] = "dydz ";
00059 fpar_name[6] = "SigmaBeam ";
00060
00061
00062 thePDF = new BSpdfsFcn();
00063
00064
00065
00066
00067
00068 theFitter = new VariableMetricMinimizer();
00069
00070
00071
00072
00073
00074
00075 fapplyd0cut = false;
00076 fapplychi2cut = false;
00077 ftmprow = 0;
00078 ftmp.ResizeTo(4,1);
00079 ftmp.Zero();
00080 fnthite=0;
00081 }
00082
00083
00084 BSFitter::~BSFitter()
00085 {
00086
00087 delete thePDF;
00088 delete theFitter;
00089 }
00090
00091
00092
00093 reco::BeamSpot BSFitter::Fit() {
00094
00095 return this->Fit(0);
00096
00097 }
00098
00099
00100 reco::BeamSpot BSFitter::Fit(double *inipar = 0) {
00101
00102 if ( ffit_variable == "z" ) {
00103
00104 if ( ffit_type == "chi2" ) {
00105
00106 return Fit_z_chi2(inipar);
00107
00108 } else if ( ffit_type == "likelihood" ) {
00109
00110 return Fit_z_likelihood(inipar);
00111
00112 } else if ( ffit_type == "combined" ) {
00113
00114 reco::BeamSpot tmp_beamspot = Fit_z_chi2(inipar);
00115 double tmp_par[2] = {tmp_beamspot.z0(), tmp_beamspot.sigmaZ()};
00116 return Fit_z_likelihood(tmp_par);
00117
00118 } else {
00119
00120 throw cms::Exception("LogicError")
00121 << "Error in BeamSpotProducer/BSFitter: "
00122 << "Illegal fit type, options are chi2,likelihood or combined(ie. first chi2 then likelihood)";
00123
00124 }
00125 } else if ( ffit_variable == "d" ) {
00126
00127 if ( ffit_type == "d0phi" ) {
00128 this->d0phi_Init();
00129 return Fit_d0phi();
00130
00131 } else if ( ffit_type == "likelihood" ) {
00132
00133 return Fit_d_likelihood(inipar);
00134
00135 } else if ( ffit_type == "combined" ) {
00136
00137 this->d0phi_Init();
00138 reco::BeamSpot tmp_beamspot = Fit_d0phi();
00139 double tmp_par[4] = {tmp_beamspot.x0(), tmp_beamspot.y0(), tmp_beamspot.dxdz(), tmp_beamspot.dydz()};
00140 return Fit_d_likelihood(tmp_par);
00141
00142 } else {
00143 throw cms::Exception("LogicError")
00144 << "Error in BeamSpotProducer/BSFitter: "
00145 << "Illegal fit type, options are d0phi, likelihood or combined";
00146 }
00147 } else if ( ffit_variable == "d*z" || ffit_variable == "default" ) {
00148
00149 if ( ffit_type == "likelihood" || ffit_type == "default" ) {
00150
00151 reco::BeamSpot::CovarianceMatrix matrix;
00152
00153 reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
00154 for (int j = 2 ; j < 4 ; ++j) {
00155 for(int k = j ; k < 4 ; ++k) {
00156 matrix(j,k) = tmp_z.covariance()(j,k);
00157 }
00158 }
00159
00160
00161 this->d0phi_Init();
00162
00163 this->Setd0Cut_d0phi(4.0);
00164 reco::BeamSpot tmp_d0phi= Fit_ited0phi();
00165
00166 for (int j = 0 ; j < 2 ; ++j) {
00167 for(int k = j ; k < 2 ; ++k) {
00168 matrix(j,k) = tmp_d0phi.covariance()(j,k);
00169 }
00170 }
00171
00172 for (int j = 4 ; j < 6 ; ++j) {
00173 for(int k = j ; k < 6 ; ++k) {
00174 matrix(j,k) = tmp_d0phi.covariance()(j,k);
00175 }
00176 }
00177
00178
00179
00180 reco::BeamSpot spot(reco::BeamSpot::Point(tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_z.z0()),
00181 tmp_z.sigmaZ(),
00182 tmp_d0phi.dxdz(),
00183 tmp_d0phi.dydz(),
00184 0.,
00185 matrix);
00186
00187
00188
00189
00190
00191
00192
00193 double tmp_par[6] = {tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_z.z0(),
00194 tmp_z.sigmaZ(), tmp_d0phi.dxdz(), tmp_d0phi.dydz()};
00195 reco::BeamSpot tmp_lh = Fit_d_z_likelihood(tmp_par);
00196
00197 if ( isnan(ff_minimum) || isinf(ff_minimum) ) {
00198
00199 if (ffit_type == "likelihood" ) {
00200 std::cout << "BSFitter: Result is non physical. Log-Likelihood fit to extract beam width did not converge." << std::endl;
00201 return tmp_lh;
00202 }
00203
00204 }
00205
00206 if (ffit_type == "likelihood") {
00207 return tmp_lh;
00208 } else {
00209 std::cout << "BSFitter: default fit does not extract beam width, assigning a width of zero." << std::endl;
00210 return spot;
00211 }
00212
00213
00214 } else if ( ffit_type == "resolution" ) {
00215
00216 reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
00217
00218 reco::BeamSpot tmp_d0phi = Fit_d0phi();
00219
00220 double tmp_par[6] = {tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_z.z0(),
00221 tmp_z.sigmaZ(), tmp_d0phi.dxdz(), tmp_d0phi.dydz()};
00222
00223 reco::BeamSpot tmp_beam = Fit_d_z_likelihood(tmp_par);
00224
00225 double tmp_par2[7] = {tmp_beam.x0(), tmp_beam.y0(), tmp_beam.z0(),
00226 tmp_beam.sigmaZ(), tmp_beam.dxdz(), tmp_beam.dydz(),
00227 tmp_beam.BeamWidth()};
00228
00229 reco::BeamSpot tmp_lh = Fit_dres_z_likelihood(tmp_par2);
00230
00231 if ( isnan(ff_minimum) || isinf(ff_minimum) ) {
00232
00233 std::cout << "BSFitter: Result is non physical. Log-Likelihood fit did not converge." << std::endl;
00234 }
00235 return tmp_lh;
00236
00237 } else {
00238
00239 throw cms::Exception("LogicError")
00240 << "Error in BeamSpotProducer/BSFitter: "
00241 << "Illegal fit type, options are likelihood or resolution";
00242 }
00243 } else {
00244
00245 throw cms::Exception("LogicError")
00246 << "Error in BeamSpotProducer/BSFitter: "
00247 << "Illegal variable type, options are \"z\", \"d\", or \"d*z\"";
00248 }
00249
00250
00251 }
00252
00253
00254 reco::BeamSpot BSFitter::Fit_z_likelihood(double *inipar) {
00255
00256
00257
00258
00259
00260 std::vector<double> par(2,0);
00261 std::vector<double> err(2,0);
00262
00263 par.push_back(0.0);
00264 par.push_back(7.0);
00265 err.push_back(0.0001);
00266 err.push_back(0.0001);
00267
00268
00269
00270 thePDF->SetPDFs("PDFGauss_z");
00271 thePDF->SetData(fBSvector);
00272
00273
00274
00275 MnUserParameters upar;
00276 upar.Add("X0", 0.,0.);
00277 upar.Add("Y0", 0.,0.);
00278 upar.Add("Z0", inipar[0],0.001);
00279 upar.Add("sigmaZ",inipar[1],0.001);
00280
00281 MnMigrad migrad(*thePDF, upar);
00282
00283 FunctionMinimum fmin = migrad();
00284 ff_minimum = fmin.Fval();
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 reco::BeamSpot::CovarianceMatrix matrix;
00304
00305 for (int j = 2 ; j < 4 ; ++j) {
00306 for(int k = j ; k < 4 ; ++k) {
00307 matrix(j,k) = fmin.Error().Matrix()(j,k);
00308 }
00309 }
00310
00311 return reco::BeamSpot( reco::BeamSpot::Point(0.,
00312 0.,
00313 fmin.Parameters().Vec()(2)),
00314 fmin.Parameters().Vec()(3),
00315 0.,
00316 0.,
00317 0.,
00318 matrix );
00319 }
00320
00321
00322 reco::BeamSpot BSFitter::Fit_z_chi2(double *inipar) {
00323
00324
00325
00326 TH1F *h1z = new TH1F("h1z","z distribution",100,-50.,50.);
00327
00328 std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
00329
00330 for( iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
00331
00332 h1z->Fill(iparam->z0(), iparam->sigz0());
00333 }
00334
00335 h1z->Fit("gaus","Q0");
00336
00337
00338 TF1 *fgaus = h1z->GetFunction("gaus");
00339
00340 double fpar[2] = {fgaus->GetParameter(1), fgaus->GetParameter(2) };
00341
00342 reco::BeamSpot::CovarianceMatrix matrix;
00343
00344 matrix(2,2) = fgaus->GetParError(1);
00345 matrix(3,3) = fgaus->GetParError(2);
00346
00347 delete h1z;
00348
00349 return reco::BeamSpot( reco::BeamSpot::Point(0.,
00350 0.,
00351 fpar[0]),
00352 fpar[1],
00353 0.,
00354 0.,
00355 0.,
00356 matrix );
00357
00358
00359 }
00360
00361
00362 reco::BeamSpot BSFitter::Fit_ited0phi() {
00363
00364 this->d0phi_Init();
00365 reco::BeamSpot theanswer = Fit_d0phi();
00366 fnthite++;
00367
00368 reco::BeamSpot preanswer;
00369
00370 while ( ftmprow > 0.5 * fBSvector.size() ) {
00371
00372 theanswer = Fit_d0phi();
00373 fd0cut /= 1.5;
00374 fchi2cut /= 1.5;
00375 if (ftmprow > 0.5 * fBSvector.size() ) {
00376 preanswer = theanswer;
00377 fnthite++;
00378 }
00379
00380 }
00381 std::cout << " total number of iterations = " << fnthite << std::endl;
00382
00383 return theanswer;
00384 }
00385
00386
00387
00388 reco::BeamSpot BSFitter::Fit_d0phi() {
00389
00390
00391 std::cout << " number of tracks used: " << ftmprow << std::endl;
00392
00393
00394
00395
00396
00397
00398
00399 TMatrixD x_result(4,1);
00400 TMatrixDSym V_result(4);
00401
00402 TMatrixDSym Vint(4);
00403 TMatrixD b(4,1);
00404
00405
00406
00407 Vint.Zero();
00408 b.Zero();
00409
00410 TMatrixD g(4,1);
00411 TMatrixDSym temp(4);
00412
00413 std::vector<BSTrkParameters>::iterator iparam = fBSvector.begin();
00414 ftmprow=0;
00415
00416
00417
00418
00419
00420
00421 for( iparam = fBSvector.begin() ;
00422 iparam != fBSvector.end() ; ++iparam) {
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 g(0,0) = sin(iparam->phi0());
00433 g(1,0) = -cos(iparam->phi0());
00434 g(2,0) = iparam->z0() * g(0,0);
00435 g(3,0) = iparam->z0() * g(1,0);
00436
00437
00438
00439 double sigmabeam2 = 0.002 * 0.002;
00440
00441
00442
00443 double sigma2 = sigmabeam2 + (iparam->sigd0())* (iparam->sigd0());
00444
00445 TMatrixD ftmptrans(1,4);
00446 ftmptrans = ftmptrans.Transpose(ftmp);
00447 TMatrixD dcor = ftmptrans * g;
00448 double chi2tmp = (iparam->d0() - dcor(0,0)) * (iparam->d0() - dcor(0,0))/sigma2;
00449 (*iparam) = BSTrkParameters(iparam->z0(),iparam->sigz0(),iparam->d0(),iparam->sigd0(),
00450 iparam->phi0(), iparam->pt(),dcor(0,0),chi2tmp);
00451
00452 bool pass = true;
00453 if (fapplyd0cut && fnthite>0 ) {
00454 if ( std::abs(iparam->d0() - dcor(0,0)) > fd0cut ) pass = false;
00455
00456 }
00457 if (fapplychi2cut && fnthite>0 ) {
00458 if ( chi2tmp > fchi2cut ) pass = false;
00459
00460 }
00461
00462 if (pass) {
00463 temp.Zero();
00464 for(int j = 0 ; j < 4 ; ++j) {
00465 for(int k = j ; k < 4 ; ++k) {
00466 temp(j,k) += g(j,0) * g(k,0);
00467 }
00468 }
00469
00470
00471 Vint += (temp * (1 / sigma2));
00472 b += (iparam->d0() / sigma2 * g);
00473
00474 ftmprow++;
00475 }
00476
00477
00478 }
00479 Double_t determinant;
00480 V_result = Vint.InvertFast(&determinant);
00481 x_result = V_result * b;
00482
00483
00484
00485
00486 reco::BeamSpot::CovarianceMatrix matrix;
00487
00488 for (int j = 0 ; j < 2 ; ++j) {
00489 for(int k = j ; k < 2 ; ++k) {
00490 matrix(j,k) = V_result(j,k);
00491 }
00492 }
00493
00494 for (int j = 4 ; j < 6 ; ++j) {
00495 for(int k = j ; k < 6 ; ++k) {
00496 matrix(j,k) = V_result(j-2,k-2);
00497 }
00498 }
00499
00500 ftmp = x_result;
00501
00502 return reco::BeamSpot( reco::BeamSpot::Point(x_result(0,0),
00503 x_result(1,0),
00504 0.0),
00505 0.,
00506 x_result(2,0),
00507 x_result(3,0),
00508 0.,
00509 matrix );
00510
00511 }
00512
00513
00514
00515 void BSFitter::Setd0Cut_d0phi(double d0cut) {
00516
00517 fapplyd0cut = true;
00518
00519
00520 fd0cut = d0cut;
00521 }
00522
00523
00524 void BSFitter::SetChi2Cut_d0phi(double chi2cut) {
00525
00526 fapplychi2cut = true;
00527
00528
00529 fchi2cut = chi2cut;
00530 }
00531
00532
00533 reco::BeamSpot BSFitter::Fit_d_likelihood(double *inipar) {
00534
00535
00536 thePDF->SetPDFs("PDFGauss_d");
00537 thePDF->SetData(fBSvector);
00538
00539 MnUserParameters upar;
00540 upar.Add("X0", inipar[0],0.001);
00541 upar.Add("Y0", inipar[1],0.001);
00542 upar.Add("Z0", 0.,0.001);
00543 upar.Add("sigmaZ",0.,0.001);
00544 upar.Add("dxdz",inipar[2],0.001);
00545 upar.Add("dydz",inipar[3],0.001);
00546
00547
00548 MnMigrad migrad(*thePDF, upar);
00549
00550 FunctionMinimum fmin = migrad();
00551 ff_minimum = fmin.Fval();
00552
00553 reco::BeamSpot::CovarianceMatrix matrix;
00554 for (int j = 0 ; j < 6 ; ++j) {
00555 for(int k = j ; k < 6 ; ++k) {
00556 matrix(j,k) = fmin.Error().Matrix()(j,k);
00557 }
00558 }
00559
00560 return reco::BeamSpot( reco::BeamSpot::Point(fmin.Parameters().Vec()(0),
00561 fmin.Parameters().Vec()(1),
00562 0.),
00563 0.,
00564 fmin.Parameters().Vec()(4),
00565 fmin.Parameters().Vec()(5),
00566 0.,
00567 matrix );
00568 }
00569
00570
00571 reco::BeamSpot BSFitter::Fit_d_z_likelihood(double *inipar) {
00572
00573
00574
00575
00576
00577 thePDF->SetPDFs("PDFGauss_d*PDFGauss_z");
00578 thePDF->SetData(fBSvector);
00579
00580 MnUserParameters upar;
00581 upar.Add("X0", inipar[0],0.001);
00582 upar.Add("Y0", inipar[1],0.001);
00583 upar.Add("Z0", inipar[2],0.001);
00584 upar.Add("sigmaZ",inipar[3],0.001);
00585 upar.Add("dxdz",inipar[4],0.001);
00586 upar.Add("dydz",inipar[5],0.001);
00587 upar.Add("BeamWidth",0.0020,0.0001);
00588
00589 MnMigrad migrad(*thePDF, upar);
00590
00591 FunctionMinimum fmin = migrad();
00592
00593 ff_minimum = fmin.Fval();
00594
00595
00596
00597
00598 reco::BeamSpot::CovarianceMatrix matrix;
00599
00600 for (int j = 0 ; j < 7 ; ++j) {
00601 for(int k = j ; k < 7 ; ++k) {
00602 matrix(j,k) = fmin.Error().Matrix()(j,k);
00603 }
00604 }
00605
00606
00607 return reco::BeamSpot( reco::BeamSpot::Point(fmin.Parameters().Vec()(0),
00608 fmin.Parameters().Vec()(1),
00609 fmin.Parameters().Vec()(2)),
00610 fmin.Parameters().Vec()(3),
00611 fmin.Parameters().Vec()(4),
00612 fmin.Parameters().Vec()(5),
00613 fmin.Parameters().Vec()(6),
00614 matrix );
00615 }
00616
00617
00618
00619 reco::BeamSpot BSFitter::Fit_dres_z_likelihood(double *inipar) {
00620
00621
00622 thePDF->SetPDFs("PDFGauss_d_resolution*PDFGauss_z");
00623 thePDF->SetData(fBSvector);
00624
00625 MnUserParameters upar;
00626 upar.Add("X0", inipar[0],0.001);
00627 upar.Add("Y0", inipar[1],0.001);
00628 upar.Add("Z0", inipar[2],0.001);
00629 upar.Add("sigmaZ",inipar[3],0.001);
00630 upar.Add("dxdz",inipar[4],0.001);
00631 upar.Add("dydz",inipar[5],0.001);
00632 upar.Add("BeamWidth",inipar[6],0.0001);
00633 upar.Add("c0",0.0010,0.0001);
00634 upar.Add("c1",0.0090,0.0001);
00635
00636
00637 upar.Fix("BeamWidth");
00638
00639
00640 MnMigrad migrad(*thePDF, upar);
00641
00642 FunctionMinimum fmin = migrad();
00643 ff_minimum = fmin.Fval();
00644
00645 reco::BeamSpot::CovarianceMatrix matrix;
00646
00647 for (int j = 0 ; j < 6 ; ++j) {
00648 for(int k = j ; k < 6 ; ++k) {
00649 matrix(j,k) = fmin.Error().Matrix()(j,k);
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658 fresolution_c0 = fmin.Parameters().Vec()(6);
00659 fresolution_c1 = fmin.Parameters().Vec()(7);
00660 fres_c0_err = sqrt( fmin.Error().Matrix()(6,6) );
00661 fres_c1_err = sqrt( fmin.Error().Matrix()(7,7) );
00662
00663 for (int j = 6 ; j < 8 ; ++j) {
00664 for(int k = 6 ; k < 8 ; ++k) {
00665 fres_matrix(j-7,k-7) = fmin.Error().Matrix()(j,k);
00666 }
00667 }
00668
00669 return reco::BeamSpot( reco::BeamSpot::Point(fmin.Parameters().Vec()(0),
00670 fmin.Parameters().Vec()(1),
00671 fmin.Parameters().Vec()(2)),
00672 fmin.Parameters().Vec()(3),
00673 fmin.Parameters().Vec()(4),
00674 fmin.Parameters().Vec()(5),
00675 inipar[6],
00676 matrix );
00677 }
00678
00679
00680