CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/RecoVertex/BeamSpotProducer/src/BSFitter.cc

Go to the documentation of this file.
00001 
00015 #include "Minuit2/VariableMetricMinimizer.h"
00016 #include "Minuit2/FunctionMinimum.h"
00017 #include "Minuit2/MnPrint.h"
00018 #include "Minuit2/MnMigrad.h"
00019 #include "Minuit2/MnUserParameterState.h"
00020 //#include "CLHEP/config/CLHEP.h"
00021 
00022 // C++ standard
00023 #include <vector>
00024 #include <cmath>
00025 
00026 // CMS
00027 #include "RecoVertex/BeamSpotProducer/interface/BSFitter.h"
00028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00029 #include "FWCore/Utilities/interface/Exception.h"
00030 #include "FWCore/Utilities/interface/isFinite.h"
00031 
00032 // ROOT
00033 #include "TMatrixD.h"
00034 #include "TMatrixDSym.h"
00035 #include "TDecompBK.h"
00036 #include "TH1.h"
00037 #include "TF1.h"
00038 
00039 using namespace ROOT::Minuit2;
00040 
00041 
00042 //_____________________________________________________________________
00043 BSFitter::BSFitter() {
00044         fbeamtype = reco::BeamSpot::Unknown;
00045 }
00046 
00047 //_____________________________________________________________________
00048 BSFitter::BSFitter( std:: vector< BSTrkParameters > BSvector ) {
00049 
00050         ffit_type = "default";
00051         ffit_variable = "default";
00052         
00053         fBSvector = BSvector;
00054 
00055         fsqrt2pi = sqrt(2.* TMath::Pi());
00056         
00057         fpar_name[0] = "z0        ";
00058         fpar_name[1] = "SigmaZ0   ";
00059         fpar_name[2] = "X0        ";
00060         fpar_name[3] = "Y0        ";
00061         fpar_name[4] = "dxdz      ";
00062         fpar_name[5] = "dydz      ";
00063         fpar_name[6] = "SigmaBeam ";               
00064 
00065         //if (theGausszFcn == 0 ) {
00066         thePDF = new BSpdfsFcn();
00067                 
00068 
00069 //}
00070                 //if (theFitter == 0 ) {
00071                 
00072         theFitter    = new VariableMetricMinimizer();
00073                 
00074                 //}
00075     
00076         fapplyd0cut = false;
00077         fapplychi2cut = false;
00078         ftmprow = 0;
00079         ftmp.ResizeTo(4,1);
00080         ftmp.Zero();
00081         fnthite=0;
00082         fMaxZ = 50.; //cm
00083         fconvergence = 0.5; // stop fit when 50% of the input collection has been removed.
00084         fminNtrks = 100;
00085         finputBeamWidth = -1; // no input
00086 
00087     h1z = new TH1F("h1z","z distribution",200,-fMaxZ, fMaxZ);
00088         
00089 }
00090 
00091 //______________________________________________________________________
00092 BSFitter::~BSFitter()
00093 {
00094         //delete fBSvector;
00095         delete thePDF;
00096         delete theFitter;
00097 }
00098 
00099 
00100 //______________________________________________________________________
00101 reco::BeamSpot BSFitter::Fit() {
00102 
00103         return this->Fit(0);
00104         
00105 }
00106 
00107 //______________________________________________________________________
00108 reco::BeamSpot BSFitter::Fit(double *inipar = 0) {
00109         fbeamtype = reco::BeamSpot::Unknown;
00110         if ( ffit_variable == "z" ) {
00111 
00112                 if ( ffit_type == "chi2" ) {
00113 
00114                         return Fit_z_chi2(inipar);
00115                         
00116                 } else if ( ffit_type == "likelihood" ) {
00117 
00118                         return Fit_z_likelihood(inipar);
00119                         
00120                 } else if ( ffit_type == "combined" ) {
00121 
00122                         reco::BeamSpot tmp_beamspot = Fit_z_chi2(inipar);
00123                         double tmp_par[2] = {tmp_beamspot.z0(), tmp_beamspot.sigmaZ()};
00124                         return Fit_z_likelihood(tmp_par);
00125                         
00126                 } else {
00127 
00128                         throw cms::Exception("LogicError")
00129                         << "Error in BeamSpotProducer/BSFitter: "
00130                         << "Illegal fit type, options are chi2,likelihood or combined(ie. first chi2 then likelihood)";
00131                         
00132                 }               
00133         } else if ( ffit_variable == "d" ) {
00134 
00135                 if ( ffit_type == "d0phi" ) {
00136                         this->d0phi_Init();
00137                         return Fit_d0phi();
00138                         
00139                 } else if ( ffit_type == "likelihood" ) {
00140 
00141                         return Fit_d_likelihood(inipar);
00142                         
00143                 } else if ( ffit_type == "combined" ) {
00144 
00145                         this->d0phi_Init();
00146                         reco::BeamSpot tmp_beamspot = Fit_d0phi();
00147                         double tmp_par[4] = {tmp_beamspot.x0(), tmp_beamspot.y0(), tmp_beamspot.dxdz(), tmp_beamspot.dydz()};
00148                         return Fit_d_likelihood(tmp_par);
00149                         
00150                 } else {
00151                         throw cms::Exception("LogicError")
00152                                 << "Error in BeamSpotProducer/BSFitter: "
00153                                 << "Illegal fit type, options are d0phi, likelihood or combined";
00154                 }
00155         } else if ( ffit_variable == "d*z" || ffit_variable == "default" ) {
00156 
00157                 if ( ffit_type == "likelihood" || ffit_type == "default" ) {
00158 
00159                         reco::BeamSpot::CovarianceMatrix matrix;
00160             // we are now fitting Z inside d0phi fitter 
00161                         // first fit z distribution using a chi2 fit
00162                         //reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
00163                         //for (int j = 2 ; j < 4 ; ++j) {
00164             //for(int k = j ; k < 4 ; ++k) {
00165             //  matrix(j,k) = tmp_z.covariance()(j,k);
00166             //}
00167                         //}
00168                 
00169                         // use d0-phi algorithm to extract transverse position
00170                         this->d0phi_Init();
00171                         //reco::BeamSpot tmp_d0phi= Fit_d0phi(); // change to iterative procedure:
00172                         this->Setd0Cut_d0phi(4.0);
00173                         reco::BeamSpot tmp_d0phi= Fit_ited0phi();
00174                         
00175                         //for (int j = 0 ; j < 2 ; ++j) {
00176                         //      for(int k = j ; k < 2 ; ++k) {
00177                         //              matrix(j,k) = tmp_d0phi.covariance()(j,k);
00178             //}
00179                         //}
00180                         // slopes
00181                         //for (int j = 4 ; j < 6 ; ++j) {
00182             // for(int k = j ; k < 6 ; ++k) {
00183             //  matrix(j,k) = tmp_d0phi.covariance()(j,k);
00184                         //  }
00185                         //}
00186 
00187                 
00188                         // put everything into one object
00189                         reco::BeamSpot spot(reco::BeamSpot::Point(tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_d0phi.z0()),
00190                                                                 tmp_d0phi.sigmaZ(),
00191                                                                 tmp_d0phi.dxdz(),
00192                                                                 tmp_d0phi.dydz(),
00193                                                                 0.,
00194                                                                 tmp_d0phi.covariance(),
00195                                                                 fbeamtype );
00196 
00197 
00198                         
00199                         //reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
00200                         
00201                         //reco::BeamSpot tmp_d0phi = Fit_d0phi();
00202 
00203             // log-likelihood fit          
00204                         if (ffit_type == "likelihood") {
00205                 double tmp_par[7] = {tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_d0phi.z0(),
00206                                      tmp_d0phi.sigmaZ(), tmp_d0phi.dxdz(), tmp_d0phi.dydz(),0.0};
00207                 
00208                 double tmp_error_par[7];
00209                 for(int s=0;s<6;s++){ tmp_error_par[s] = pow( tmp_d0phi.covariance()(s,s),0.5);}
00210                 tmp_error_par[6]=0.0;
00211                 
00212                 reco::BeamSpot tmp_lh = Fit_d_z_likelihood(tmp_par,tmp_error_par);
00213                 
00214                 if (edm::isNotFinite(ff_minimum)) {
00215                     edm::LogWarning("BSFitter") << "BSFitter: Result is non physical. Log-Likelihood fit to extract beam width did not converge." << std::endl;
00216                     tmp_lh.setType(reco::BeamSpot::Unknown);
00217                     return tmp_lh;                    
00218                 }
00219                 return tmp_lh;
00220                 
00221                         } else {
00222             
00223                 edm::LogInfo("BSFitter") << "default track-based fit does not extract beam width." << std::endl;
00224                                 return spot;
00225             }
00226                         
00227                         
00228                 } else if ( ffit_type == "resolution" ) {
00229 
00230                         reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
00231                         this->d0phi_Init();                     
00232                         reco::BeamSpot tmp_d0phi = Fit_d0phi();
00233                         
00234                         double tmp_par[7] = {tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_z.z0(),
00235                                                                  tmp_z.sigmaZ(), tmp_d0phi.dxdz(), tmp_d0phi.dydz(),0.0};
00236             double tmp_error_par[7];
00237             for(int s=0;s<6;s++){ tmp_error_par[s] = pow(tmp_par[s],0.5);}
00238             tmp_error_par[6]=0.0;
00239  
00240                         reco::BeamSpot tmp_beam = Fit_d_z_likelihood(tmp_par,tmp_error_par);
00241             
00242                         double tmp_par2[7] = {tmp_beam.x0(), tmp_beam.y0(), tmp_beam.z0(),
00243                                                                  tmp_beam.sigmaZ(), tmp_beam.dxdz(), tmp_beam.dydz(),
00244                                                                  tmp_beam.BeamWidthX()};
00245                         
00246                         reco::BeamSpot tmp_lh = Fit_dres_z_likelihood(tmp_par2);
00247 
00248                         if (edm::isNotFinite(ff_minimum)) {
00249                         
00250                 edm::LogWarning("BSFitter") << "Result is non physical. Log-Likelihood fit did not converge." << std::endl;
00251                                 tmp_lh.setType(reco::BeamSpot::Unknown);
00252                                 return tmp_lh;
00253                         }
00254                         return tmp_lh;
00255                         
00256                 } else {
00257                         
00258                         throw cms::Exception("LogicError")
00259                                 << "Error in BeamSpotProducer/BSFitter: "
00260                                 << "Illegal fit type, options are likelihood or resolution";
00261                 }
00262         } else {
00263 
00264                 throw cms::Exception("LogicError")
00265                         << "Error in BeamSpotProducer/BSFitter: "
00266                         << "Illegal variable type, options are \"z\", \"d\", or \"d*z\"";
00267         }
00268         
00269         
00270 }
00271 
00272 //______________________________________________________________________
00273 reco::BeamSpot BSFitter::Fit_z_likelihood(double *inipar) {
00274 
00275         //std::cout << "Fit_z(double *) called" << std::endl;
00276         //std::cout << "inipar[0]= " << inipar[0] << std::endl;
00277         //std::cout << "inipar[1]= " << inipar[1] << std::endl;
00278         
00279         std::vector<double> par(2,0);
00280         std::vector<double> err(2,0);
00281 
00282         par.push_back(0.0);
00283         par.push_back(7.0);
00284         err.push_back(0.0001);
00285         err.push_back(0.0001);
00286         //par[0] = 0.0; err[0] = 0.0;
00287         //par[1] = 7.0; err[1] = 0.0;
00288 
00289         thePDF->SetPDFs("PDFGauss_z");
00290         thePDF->SetData(fBSvector);
00291         //std::cout << "data loaded"<< std::endl;
00292         
00293         //FunctionMinimum fmin = theFitter->Minimize(*theGausszFcn, par, err, 1, 500, 0.1);
00294         MnUserParameters upar;
00295         upar.Add("X0",    0.,0.);
00296         upar.Add("Y0",    0.,0.);
00297         upar.Add("Z0",    inipar[0],0.001);
00298         upar.Add("sigmaZ",inipar[1],0.001);
00299         
00300         MnMigrad migrad(*thePDF, upar);
00301         
00302         FunctionMinimum fmin = migrad();
00303         ff_minimum = fmin.Fval();
00304         //std::cout << " eval= " << ff_minimum
00305         //                << "/n params[0]= " << fmin.Parameters().Vec()(0) << std::endl;
00306         
00307         /*
00308         TMinuit *gmMinuit = new TMinuit(2); 
00309 
00310         //gmMinuit->SetFCN(z_fcn);
00311         gmMinuit->SetFCN(myFitz_fcn);
00312         
00313         
00314         int ierflg = 0;
00315         double step[2] = {0.001,0.001};
00316         
00317         for (int i = 0; i<2; i++) {   
00318                 gmMinuit->mnparm(i,fpar_name[i].c_str(),inipar[i],step[i],0,0,ierflg);
00319         }
00320         gmMinuit->Migrad();
00321         */
00322         reco::BeamSpot::CovarianceMatrix matrix;
00323 
00324         for (int j = 2 ; j < 4 ; ++j) {
00325                 for(int k = j ; k < 4 ; ++k) {
00326                   matrix(j,k) = fmin.Error().Matrix()(j,k);
00327                 }
00328         }
00329                 
00330         return reco::BeamSpot( reco::BeamSpot::Point(0.,
00331                                                      0.,
00332                                                      fmin.Parameters().Vec()(2)),
00333                                fmin.Parameters().Vec()(3),
00334                                0.,
00335                                0.,
00336                                0.,
00337                                matrix,
00338                                fbeamtype );
00339 }
00340 
00341 //______________________________________________________________________
00342 reco::BeamSpot BSFitter::Fit_z_chi2(double *inipar) {
00343 
00344     // N.B. this fit is not performed anymore but now
00345     // Z is fitted in the same track set used in the d0-phi fit after
00346     // each iteration
00347 
00348     
00349         //std::cout << "Fit_z_chi2() called" << std::endl;
00350         // FIXME: include whole tracker z length for the time being
00351         // ==> add protection and z0 cut
00352         h1z = new TH1F("h1z","z distribution",200,-fMaxZ, fMaxZ);
00353         
00354         std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
00355 
00356         // HERE check size of track vector
00357         
00358         for( iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
00359                 
00360                  h1z->Fill( iparam->z0() );
00361                  //std::cout<<"z0="<<iparam->z0()<<"; sigZ0="<<iparam->sigz0()<<std::endl;
00362         }
00363 
00364         h1z->Fit("gaus","QLM0");
00365         //std::cout << "fitted "<< std::endl;
00366         
00367         TF1 *fgaus = h1z->GetFunction("gaus");
00368         //std::cout << "got function" << std::endl;
00369         double fpar[2] = {fgaus->GetParameter(1), fgaus->GetParameter(2) };
00370         //std::cout<<"Debug fpar[2] = (" <<fpar[0]<<","<<fpar[1]<<")"<<std::endl;
00371         reco::BeamSpot::CovarianceMatrix matrix;
00372         // add matrix values.
00373         matrix(2,2) = fgaus->GetParError(1) * fgaus->GetParError(1);
00374         matrix(3,3) = fgaus->GetParError(2) * fgaus->GetParError(2);
00375         
00376         //delete h1z;
00377 
00378         return reco::BeamSpot( reco::BeamSpot::Point(0.,
00379                                                      0.,
00380                                                      fpar[0]),
00381                                fpar[1],
00382                                0.,
00383                                0.,
00384                                0.,
00385                                matrix,
00386                                fbeamtype );     
00387 
00388         
00389 }
00390 
00391 //______________________________________________________________________
00392 reco::BeamSpot BSFitter::Fit_ited0phi() {
00393 
00394         this->d0phi_Init();
00395     edm::LogInfo("BSFitter") << "number of total input tracks: " << fBSvector.size() << std::endl;
00396         
00397         reco::BeamSpot theanswer;
00398 
00399         if ( (int)fBSvector.size() <= fminNtrks ) {
00400         edm::LogWarning("BSFitter") << "need at least " << fminNtrks << " tracks to run beamline fitter." << std::endl;
00401                 fbeamtype = reco::BeamSpot::Fake;
00402                 theanswer.setType(fbeamtype);
00403                 return theanswer;
00404         }
00405         
00406         theanswer = Fit_d0phi(); //get initial ftmp and ftmprow
00407         if ( goodfit ) fnthite++;
00408         //std::cout << "Initial tempanswer (iteration 0): " << theanswer << std::endl;
00409         
00410         reco::BeamSpot preanswer = theanswer;
00411         
00412         while ( goodfit &&
00413                         ftmprow > fconvergence * fBSvector.size() &&
00414                         ftmprow > fminNtrks  ) {
00415                 
00416                 theanswer = Fit_d0phi();
00417                 fd0cut /= 1.5;
00418                 fchi2cut /= 1.5;
00419                 if ( goodfit &&
00420                         ftmprow > fconvergence * fBSvector.size() &&
00421                         ftmprow > fminNtrks ) {
00422                         preanswer = theanswer;
00423                         //std::cout << "Iteration " << fnthite << ": " << preanswer << std::endl;
00424                         fnthite++;
00425                 }
00426         }
00427         // FIXME: return fit results from previous iteration for both bad fit and for >50% tracks thrown away
00428         //std::cout << "The last iteration, theanswer: " << theanswer << std::endl;
00429         theanswer = preanswer;
00430         //std::cout << "Use previous results from iteration #" << ( fnthite > 0 ? fnthite-1 : 0 ) << std::endl;
00431         //if ( fnthite > 1 ) std::cout << theanswer << std::endl;
00432         
00433     edm::LogInfo("BSFitter") << "Total number of successful iterations = " << ( goodfit ? (fnthite+1) : fnthite ) << std::endl;
00434     if (goodfit) {
00435         fbeamtype = reco::BeamSpot::Tracker;
00436         theanswer.setType(fbeamtype);
00437     }
00438     else {
00439         edm::LogWarning("BSFitter") << "Fit doesn't converge!!!" << std::endl;
00440         fbeamtype = reco::BeamSpot::Unknown;
00441         theanswer.setType(fbeamtype);
00442     }
00443         return theanswer;
00444 }
00445 
00446 
00447 //______________________________________________________________________
00448 reco::BeamSpot BSFitter::Fit_d0phi() {
00449 
00450         //LogDebug ("BSFitter") << " we will use " << fBSvector.size() << " tracks.";
00451     if (fnthite > 0) edm::LogInfo("BSFitter") << " number of tracks used: " << ftmprow << std::endl;
00452         //std::cout << " ftmp = matrix("<<ftmp.GetNrows()<<","<<ftmp.GetNcols()<<")"<<std::endl;
00453         //std::cout << " ftmp(0,0)="<<ftmp(0,0)<<std::endl;
00454         //std::cout << " ftmp(1,0)="<<ftmp(1,0)<<std::endl;
00455         //std::cout << " ftmp(2,0)="<<ftmp(2,0)<<std::endl;
00456         //std::cout << " ftmp(3,0)="<<ftmp(3,0)<<std::endl;
00457         
00458         h1z->Reset();
00459         
00460         
00461         TMatrixD x_result(4,1);
00462         TMatrixDSym V_result(4);
00463         
00464         TMatrixDSym Vint(4);
00465         TMatrixD b(4,1);
00466         
00467         //Double_t weightsum = 0;
00468         
00469         Vint.Zero();
00470         b.Zero();
00471         
00472         TMatrixD g(4,1);
00473         TMatrixDSym temp(4);
00474         
00475         std::vector<BSTrkParameters>::iterator iparam = fBSvector.begin();
00476         ftmprow=0;
00477 
00478         
00479         //edm::LogInfo ("BSFitter") << " test";
00480                 
00481         //std::cout << "BSFitter: fit" << std::endl;
00482         
00483         for( iparam = fBSvector.begin() ;
00484                 iparam != fBSvector.end() ; ++iparam) {
00485                 
00486                 
00487                 //if(i->weight2 == 0) continue;
00488                 
00489                 //if (ftmprow==0) {
00490                 //std::cout << "d0=" << iparam->d0() << " sigd0=" << iparam->sigd0()
00491                 //<< " phi0="<< iparam->phi0() << " z0=" << iparam->z0() << std::endl;
00492                 //std::cout << "d0phi_d0=" << iparam->d0phi_d0() << " d0phi_chi2="<<iparam->d0phi_chi2() << std::endl; 
00493                 //}
00494                 g(0,0) = sin(iparam->phi0());
00495                 g(1,0) = -cos(iparam->phi0());
00496                 g(2,0) = iparam->z0() * g(0,0);
00497                 g(3,0) = iparam->z0() * g(1,0);
00498                 
00499                 
00500                 // average transverse beam width
00501                 double sigmabeam2 = 0.006 * 0.006;
00502                 if (finputBeamWidth > 0 ) sigmabeam2 = finputBeamWidth * finputBeamWidth;
00503         else { edm::LogWarning("BSFitter") << "using in fit beam width = " << sqrt(sigmabeam2) << std::endl; }
00504         
00505                 //double sigma2 = sigmabeam2 +  (iparam->sigd0())* (iparam->sigd0()) / iparam->weight2;
00506                 // this should be 2*sigmabeam2?
00507                 double sigma2 = sigmabeam2 +  (iparam->sigd0())* (iparam->sigd0());
00508 
00509                 TMatrixD ftmptrans(1,4);
00510                 ftmptrans = ftmptrans.Transpose(ftmp);
00511                 TMatrixD dcor = ftmptrans * g;
00512                 double chi2tmp = (iparam->d0() - dcor(0,0)) * (iparam->d0() - dcor(0,0))/sigma2;
00513                 (*iparam) = BSTrkParameters(iparam->z0(),iparam->sigz0(),iparam->d0(),iparam->sigd0(),
00514                                             iparam->phi0(), iparam->pt(),dcor(0,0),chi2tmp);
00515 
00516                 bool pass = true;
00517                 if (fapplyd0cut && fnthite>0 ) {
00518                         if ( std::abs(iparam->d0() - dcor(0,0)) > fd0cut ) pass = false;
00519                         
00520                 }
00521                 if (fapplychi2cut && fnthite>0 ) {
00522                         if ( chi2tmp > fchi2cut ) pass = false;
00523                         
00524                 }
00525                 
00526                 if (pass) {
00527                         temp.Zero();
00528                         for(int j = 0 ; j < 4 ; ++j) {
00529                                 for(int k = j ; k < 4 ; ++k) {
00530                                         temp(j,k) += g(j,0) * g(k,0);
00531                                 }
00532                         }
00533 
00534                 
00535                         Vint += (temp * (1 / sigma2));
00536                         b += (iparam->d0() / sigma2 * g);
00537                         //weightsum += sqrt(i->weight2);
00538                         ftmprow++;
00539             h1z->Fill( iparam->z0() );
00540                 }
00541 
00542                 
00543         }
00544         Double_t determinant;
00545         TDecompBK bk(Vint);
00546         bk.SetTol(1e-11); //FIXME: find a better way to solve x_result
00547         if (!bk.Decompose()) {
00548           goodfit = false;
00549       edm::LogWarning("BSFitter")
00550           << "Decomposition failed, matrix singular ?" << std::endl
00551           << "condition number = " << bk.Condition() << std::endl;
00552         }
00553         else {
00554           V_result = Vint.InvertFast(&determinant);
00555           x_result = V_result  * b;
00556         }
00557         //      for(int j = 0 ; j < 4 ; ++j) {
00558         //        for(int k = 0 ; k < 4 ; ++k) {
00559         //          std::cout<<"V_result("<<j<<","<<k<<")="<<V_result(j,k)<<std::endl;
00560         //        }
00561         //      }
00562         //         for (int j=0;j<4;++j){
00563         //        std::cout<<"x_result("<<j<<",0)="<<x_result(j,0)<<std::endl;
00564         //      }
00565         //LogDebug ("BSFitter") << " d0-phi fit done.";
00566         //std::cout<< " d0-phi fit done." << std::endl;
00567 
00568         h1z->Fit("gaus","QLM0","",h1z->GetMean() -2.*h1z->GetRMS(),h1z->GetMean() +2.*h1z->GetRMS());
00569 
00570         //std::cout << "fitted "<< std::endl;
00571         TF1 *fgaus = h1z->GetFunction("gaus");
00572         //std::cout << "got function" << std::endl;
00573         if (!fgaus){    
00574           edm::LogError("NoBeamSpotFit")<<"gaussian fit failed. no BS d0 fit";          
00575           return reco::BeamSpot();
00576         }
00577         double fpar[2] = {fgaus->GetParameter(1), fgaus->GetParameter(2) };
00578     
00579         reco::BeamSpot::CovarianceMatrix matrix;
00580         // first two parameters
00581         for (int j = 0 ; j < 2 ; ++j) {
00582                 for(int k = j ; k < 2 ; ++k) {
00583                         matrix(j,k) = V_result(j,k);
00584                 }
00585         }
00586         // slope parameters
00587         for (int j = 4 ; j < 6 ; ++j) {
00588                 for(int k = j ; k < 6 ; ++k) {
00589                         matrix(j,k) = V_result(j-2,k-2);
00590                 }
00591         }
00592 
00593     // Z0 and sigmaZ
00594         matrix(2,2) = fgaus->GetParError(1) * fgaus->GetParError(1);
00595         matrix(3,3) = fgaus->GetParError(2) * fgaus->GetParError(2);
00596     
00597         ftmp = x_result;
00598 
00599         // x0 and y0 are *not* x,y at z=0, but actually at z=0
00600         // to correct for this, we need to translate them to z=z0
00601         // using the measured slopes
00602         //
00603         double x0tmp = x_result(0,0);
00604         double y0tmp = x_result(1,0);
00605 
00606         x0tmp += x_result(2,0)*fpar[0];
00607         y0tmp += x_result(3,0)*fpar[0];
00608 
00609 
00610         return reco::BeamSpot( reco::BeamSpot::Point(x0tmp,
00611                                                      y0tmp,
00612                                                      fpar[0]),
00613                            fpar[1],
00614                                x_result(2,0),
00615                                x_result(3,0),
00616                                0.,
00617                                matrix,
00618                                fbeamtype );
00619         
00620 }
00621 
00622 
00623 //______________________________________________________________________
00624 void BSFitter::Setd0Cut_d0phi(double d0cut) {
00625 
00626         fapplyd0cut = true;
00627 
00628         //fBSforCuts = BSfitted;
00629         fd0cut = d0cut;
00630 }
00631 
00632 //______________________________________________________________________
00633 void BSFitter::SetChi2Cut_d0phi(double chi2cut) {
00634 
00635         fapplychi2cut = true;
00636 
00637         //fBSforCuts = BSfitted;
00638         fchi2cut = chi2cut;
00639 }
00640 
00641 //______________________________________________________________________
00642 reco::BeamSpot BSFitter::Fit_d_likelihood(double *inipar) {
00643         
00644 
00645         thePDF->SetPDFs("PDFGauss_d");
00646         thePDF->SetData(fBSvector);
00647 
00648         MnUserParameters upar;
00649         upar.Add("X0",  inipar[0],0.001);
00650         upar.Add("Y0",  inipar[1],0.001);
00651         upar.Add("Z0",    0.,0.001);
00652         upar.Add("sigmaZ",0.,0.001);
00653         upar.Add("dxdz",inipar[2],0.001);
00654         upar.Add("dydz",inipar[3],0.001);
00655                 
00656         
00657         MnMigrad migrad(*thePDF, upar);
00658         
00659         FunctionMinimum fmin = migrad();
00660         ff_minimum = fmin.Fval();
00661 
00662         reco::BeamSpot::CovarianceMatrix matrix;
00663         for (int j = 0 ; j < 6 ; ++j) {
00664                 for(int k = j ; k < 6 ; ++k) {
00665                         matrix(j,k) = 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                                                      0.),
00672                                0.,
00673                                fmin.Parameters().Vec()(4),
00674                                fmin.Parameters().Vec()(5),
00675                                0.,
00676                                matrix,
00677                                fbeamtype );
00678 }
00679 //______________________________________________________________________
00680 double BSFitter::scanPDF(double *init_pars, int & tracksfixed, int option){
00681 
00682    if(option==1)init_pars[6]=0.0005;  //starting value for any given configuration
00683 
00684    //local vairables with initial values
00685    double fsqrt2pi=0.0;
00686    double d_sig=0.0;
00687    double d_dprime=0.0;
00688    double d_result=0.0;
00689    double z_sig=0.0;
00690    double z_result=0.0;
00691    double function=0.0;
00692    double tot_pdf=0.0;
00693    double last_minvalue=1.0e+10;
00694    double init_bw=-99.99;
00695    int iters=0;
00696 
00697   //used to remove tracks if far away from bs by this
00698    double DeltadCut=0.1000;
00699    if(init_pars[6]<0.0200){DeltadCut=0.0900; } //worked for high 2.36TeV 
00700    if(init_pars[6]<0.0100){DeltadCut=0.0700;}  //just a guesss for 7 TeV but one should scan for actual values
00701 
00702 
00703 std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
00704 
00705 
00706 if(option==1)iters=500;
00707 if(option==2)iters=1;
00708 
00709 for(int p=0;p<iters;p++){
00710 
00711    if(iters==500)init_pars[6]+=0.0002;
00712     tracksfixed=0;
00713 
00714 for( iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam)
00715        {
00716                     fsqrt2pi = sqrt(2.* TMath::Pi());
00717                     d_sig = sqrt(init_pars[6]*init_pars[6] + (iparam->sigd0())*(iparam->sigd0()));
00718                     d_dprime = iparam->d0() - (   (  (init_pars[0] + iparam->z0()*(init_pars[4]))*sin(iparam->phi0()) )
00719                                                - (  (init_pars[1] + iparam->z0()*(init_pars[5]))*cos(iparam->phi0()) ) );
00720 
00721                     //***Remove tracks before the fit which gives low pdf values to blow up the pdf
00722                     if(std::abs(d_dprime)<DeltadCut && option==2){ fBSvectorBW.push_back(*iparam);}
00723 
00724                     d_result = (exp(-(d_dprime*d_dprime)/(2.0*d_sig*d_sig)))/(d_sig*fsqrt2pi);
00725                     z_sig = sqrt(iparam->sigz0() * iparam->sigz0() + init_pars[3]*init_pars[3]);
00726                     z_result = (exp(-((iparam->z0() - init_pars[2])*(iparam->z0() - init_pars[2]))/(2.0*z_sig*z_sig)))/(z_sig*fsqrt2pi);
00727                     tot_pdf=z_result*d_result;
00728 
00729                     //for those trcks which gives problems due to very tiny pdf_d values.
00730                     //Update: This protection will NOT be used with the dprime cut above but still kept here to get
00731                     // the intial value of beam width reasonably
00732                     //A warning will appear if there were any tracks with < 10^-5 for pdf_d so that (d-dprime) cut can be lowered
00733                     if(d_result < 1.0e-05){ tot_pdf=z_result*1.0e-05;
00734                                            //if(option==2)std::cout<<"last Iter  d-d'   =  "<<(std::abs(d_dprime))<<std::endl;
00735                                            tracksfixed++; }
00736 
00737                        function = function + log(tot_pdf);
00738                        tot_pdf=0.0;
00739 
00740 
00741        }//loop over tracks
00742 
00743 
00744        function= -2.0*function;
00745        if(function<last_minvalue){init_bw=init_pars[6];
00746                                   last_minvalue=function; }
00747        function=0.0;
00748    }//loop over beam width
00749 
00750    if(init_bw>0) {
00751     init_bw=init_bw+(0.20*init_bw); //start with 20 % more
00752 
00753    }
00754    else{
00755 
00756        if(option==1){
00757            edm::LogWarning("BSFitter")
00758                <<"scanPDF:====>>>> WARNING***: The initial guess value of Beam width is negative!!!!!!"<<std::endl
00759                <<"scanPDF:====>>>> Assigning beam width a starting value of "<<init_bw<<"  cm"<<std::endl;
00760            init_bw=0.0200;
00761                         
00762        }
00763       }
00764 
00765 
00766     return init_bw;
00767 
00768 }
00769 
00770 //________________________________________________________________________________
00771 reco::BeamSpot BSFitter::Fit_d_z_likelihood(double *inipar, double *error_par) {
00772 
00773       int tracksFailed=0;
00774 
00775       //estimate first guess of beam width and tame 20% extra of it to start
00776       inipar[6]=scanPDF(inipar,tracksFailed,1);
00777       error_par[6]=(inipar[6])*0.20;
00778 
00779 
00780      //Here remove the tracks which give low pdf and fill into a new vector
00781      //std::cout<<"Size of Old vector = "<<(fBSvector.size())<<std::endl;
00782      /* double junk= */ scanPDF(inipar,tracksFailed,2);
00783      //std::cout<<"Size of New vector = "<<(fBSvectorBW.size())<<std::endl;
00784 
00785      //Refill the fBSVector again with new sets of tracks
00786      fBSvector.clear();
00787      std::vector<BSTrkParameters>::const_iterator iparamBW = fBSvectorBW.begin();
00788      for( iparamBW = fBSvectorBW.begin(); iparamBW != fBSvectorBW.end(); ++iparamBW)
00789         {          fBSvector.push_back(*iparamBW); 
00790         }
00791 
00792 
00793         thePDF->SetPDFs("PDFGauss_d*PDFGauss_z");
00794         thePDF->SetData(fBSvector);
00795         MnUserParameters upar;
00796 
00797         upar.Add("X0",  inipar[0],error_par[0]);
00798         upar.Add("Y0",  inipar[1],error_par[1]);
00799         upar.Add("Z0",    inipar[2],error_par[2]);
00800         upar.Add("sigmaZ",inipar[3],error_par[3]);
00801         upar.Add("dxdz",inipar[4],error_par[4]);
00802         upar.Add("dydz",inipar[5],error_par[5]);
00803         upar.Add("BeamWidthX",inipar[6],error_par[6]);
00804 
00805 
00806         MnMigrad migrad(*thePDF, upar);
00807 
00808         FunctionMinimum fmin = migrad();
00809 
00810       // std::cout<<"-----how the fit evoves------"<<std::endl;
00811       // std::cout<<fmin<<std::endl;
00812 
00813         ff_minimum = fmin.Fval();
00814 
00815 
00816         bool ff_nfcn=fmin.HasReachedCallLimit();
00817         bool ff_cov=fmin.HasCovariance();
00818         bool testing=fmin.IsValid();
00819 
00820 
00821         //Print WARNINGS if minimum did not converged
00822         if( ! testing )
00823         {
00824             edm::LogWarning("BSFitter") <<"===========>>>>>** WARNING: MINUIT DID NOT CONVERGES PROPERLY !!!!!!"<<std::endl;
00825             if(ff_nfcn) edm::LogWarning("BSFitter") <<"===========>>>>>** WARNING: No. of Calls Exhausted"<<std::endl;
00826             if(!ff_cov) edm::LogWarning("BSFitter") <<"===========>>>>>** WARNING: Covariance did not found"<<std::endl;
00827         }
00828 
00829         edm::LogInfo("BSFitter") <<"The Total # Tracks used for beam width fit = "<<(fBSvectorBW.size())<<std::endl;
00830 
00831 
00832     //Checks after fit is performed 
00833     double lastIter_pars[7];
00834 
00835    for(int ip=0;ip<7;ip++){ lastIter_pars[ip]=fmin.Parameters().Vec()(ip);
00836                            }
00837 
00838 
00839 
00840     tracksFailed=0;
00841     /* double lastIter_scan= */ scanPDF(lastIter_pars,tracksFailed,2);
00842 
00843    
00844     edm::LogWarning("BSFitter") <<"WARNING: # of tracks which have very low pdf value (pdf_d < 1.0e-05) are  = "<<tracksFailed<<std::endl;
00845 
00846 
00847 
00848         //std::cout << " eval= " << ff_minimum
00849         //                << "/n params[0]= " << fmin.Parameters().Vec()(0) << std::endl;
00850 
00851         reco::BeamSpot::CovarianceMatrix matrix;
00852 
00853         for (int j = 0 ; j < 7 ; ++j) {
00854                 for(int k = j ; k < 7 ; ++k) {
00855                         matrix(j,k) = fmin.Error().Matrix()(j,k);
00856                 }
00857         }
00858 
00859 
00860         return reco::BeamSpot( reco::BeamSpot::Point(fmin.Parameters().Vec()(0),
00861                                                      fmin.Parameters().Vec()(1),
00862                                                      fmin.Parameters().Vec()(2)),
00863                                fmin.Parameters().Vec()(3),
00864                                fmin.Parameters().Vec()(4),
00865                                fmin.Parameters().Vec()(5),
00866                                fmin.Parameters().Vec()(6),
00867                                                               
00868                                matrix,
00869                                fbeamtype );
00870 }
00871 
00872 
00873 //______________________________________________________________________
00874 reco::BeamSpot BSFitter::Fit_dres_z_likelihood(double *inipar) {
00875         
00876         
00877         thePDF->SetPDFs("PDFGauss_d_resolution*PDFGauss_z");
00878         thePDF->SetData(fBSvector);
00879 
00880         MnUserParameters upar;
00881         upar.Add("X0",  inipar[0],0.001);
00882         upar.Add("Y0",  inipar[1],0.001);
00883         upar.Add("Z0",    inipar[2],0.001);
00884         upar.Add("sigmaZ",inipar[3],0.001);
00885         upar.Add("dxdz",inipar[4],0.001);
00886         upar.Add("dydz",inipar[5],0.001);
00887         upar.Add("BeamWidthX",inipar[6],0.0001);
00888         upar.Add("c0",0.0010,0.0001);
00889         upar.Add("c1",0.0090,0.0001);
00890 
00891         // fix beam width
00892         upar.Fix("BeamWidthX");
00893         // number of parameters in fit are 9-1 = 8
00894         
00895         MnMigrad migrad(*thePDF, upar);
00896                 
00897         FunctionMinimum fmin = migrad();
00898         ff_minimum = fmin.Fval();
00899 
00900         reco::BeamSpot::CovarianceMatrix matrix;
00901 
00902         for (int j = 0 ; j < 6 ; ++j) {
00903                 for(int k = j ; k < 6 ; ++k) {
00904                         matrix(j,k) = fmin.Error().Matrix()(j,k);
00905                 }
00906         }
00907 
00908         //std::cout << " fill resolution values" << std::endl;
00909         //std::cout << " matrix size= " << fmin.Error().Matrix().size() << std::endl;
00910         //std::cout << " vec(6)="<< fmin.Parameters().Vec()(6) << std::endl;
00911         //std::cout << " vec(7)="<< fmin.Parameters().Vec()(7) << std::endl;
00912         
00913         fresolution_c0 = fmin.Parameters().Vec()(6);
00914         fresolution_c1 = fmin.Parameters().Vec()(7);
00915         fres_c0_err = sqrt( fmin.Error().Matrix()(6,6) );
00916         fres_c1_err = sqrt( fmin.Error().Matrix()(7,7) );
00917         
00918         for (int j = 6 ; j < 8 ; ++j) {
00919                 for(int k = 6 ; k < 8 ; ++k) {
00920                         fres_matrix(j-6,k-6) = fmin.Error().Matrix()(j,k);
00921                 }
00922         }
00923 
00924         return reco::BeamSpot( reco::BeamSpot::Point(fmin.Parameters().Vec()(0),
00925                                                                          fmin.Parameters().Vec()(1),
00926                                                                          fmin.Parameters().Vec()(2)),
00927                                          fmin.Parameters().Vec()(3),
00928                                          fmin.Parameters().Vec()(4),
00929                                          fmin.Parameters().Vec()(5),
00930                                          inipar[6],
00931                                          matrix,
00932                                          fbeamtype );
00933 }
00934 
00935 
00936