testFitPerf.cxx

Go to the documentation of this file.
00001 #include "TH1.h"
00002 #include "TF1.h"
00003 #include "TF2.h"
00004 #include "TMath.h"
00005 #include "TSystem.h"
00006 #include "TRandom3.h"
00007 #include "TTree.h"
00008 #include "TROOT.h"
00009 
00010 #include "Fit/BinData.h"
00011 #include "Fit/UnBinData.h"
00012 //#include "Fit/BinPoint.h"
00013 #include "Fit/Fitter.h"
00014 #include "HFitInterface.h"
00015 
00016 #include "Math/IParamFunction.h"
00017 #include "Math/WrappedTF1.h"
00018 #include "Math/WrappedMultiTF1.h"
00019 #include "Math/WrappedParamFunction.h"
00020 #include "Math/MultiDimParamFunctionAdapter.h"
00021 
00022 #include "TGraphErrors.h"
00023 
00024 #include "TStyle.h"
00025 
00026 #include "TSeqCollection.h"
00027 
00028 #include "Math/Polynomial.h"
00029 #include "Math/DistFunc.h"
00030 
00031 #include <string>
00032 #include <iostream>
00033 
00034 #include "TStopwatch.h"
00035 
00036 #include "TVirtualFitter.h"
00037 #include "TFitterMinuit.h"
00038 // #include "TFitterFumili.h"
00039 // #include "TFumili.h"
00040 
00041 #include "GaussFunction.h"
00042 
00043 #include "RooDataHist.h"
00044 #include "RooDataSet.h"
00045 #include "RooRealVar.h"
00046 #include "RooGaussian.h"
00047 #include "RooMinuit.h"
00048 #include "RooChi2Var.h"
00049 #include "RooGlobalFunc.h"
00050 #include "RooFitResult.h"
00051 #include "RooProdPdf.h"
00052 
00053 #include <cassert>
00054 
00055 #include "MinimizerTypes.h"
00056 
00057 //#define DEBUG
00058 
00059 int nfit;
00060 const int N = 20; 
00061 double iniPar[2*N]; 
00062 
00063 
00064 void printData(const ROOT::Fit::UnBinData & data) {
00065    for (unsigned int i = 0; i < data.Size(); ++i) { 
00066       std::cout << data.Coords(i)[0] << "\t"; 
00067    }
00068    std::cout << "\ndata size is " << data.Size() << std::endl;
00069 }    
00070 
00071 void printResult(int iret) { 
00072    std::cout << "\n************************************************************\n"; 
00073    std::cout << "Test\t\t\t\t";
00074    if (iret == 0) std::cout << "OK"; 
00075    else std::cout << "FAILED"; 
00076    std::cout << "\n************************************************************\n"; 
00077 }
00078 
00079 bool USE_BRANCH = false;
00080 ROOT::Fit::UnBinData * FillUnBinData(TTree * tree, bool copyData = true, unsigned int dim = 1 ) { 
00081 
00082    // fill the unbin data set from a TTree
00083    ROOT::Fit::UnBinData * d = 0; 
00084    // for the large tree
00085    if (std::string(tree->GetName()) == "t2") { 
00086       d = new ROOT::Fit::UnBinData();
00087       // large tree 
00088       unsigned int n = tree->GetEntries(); 
00089 #ifdef DEBUG
00090       std::cout << "number of unbin data is " << n << " of dim " << N << std::endl;
00091 #endif
00092       d->Initialize(n,N);
00093       TBranch * bx = tree->GetBranch("x"); 
00094       double vx[N];
00095       bx->SetAddress(vx); 
00096       std::vector<double>  m(N);
00097       for (int unsigned i = 0; i < n; ++i) {
00098          bx->GetEntry(i);
00099          d->Add(vx);
00100          for (int j = 0; j < N; ++j) 
00101             m[j] += vx[j];
00102       }
00103 
00104 #ifdef DEBUG
00105       std::cout << "average values of means :\n"; 
00106       for (int j = 0; j < N; ++j) 
00107          std::cout << m[j]/n << "  ";
00108       std::cout << "\n";
00109 #endif
00110       
00111       return d; 
00112    }
00113    if (USE_BRANCH) 
00114    {
00115       d = new ROOT::Fit::UnBinData();
00116       unsigned int n = tree->GetEntries(); 
00117       //std::cout << "number of unbin data is " << n << std::endl;
00118 
00119       if (dim == 2) { 
00120          d->Initialize(n,2);
00121          TBranch * bx = tree->GetBranch("x"); 
00122          TBranch * by = tree->GetBranch("y"); 
00123          double v[2];
00124          bx->SetAddress(&v[0]); 
00125          by->SetAddress(&v[1]); 
00126          for (int unsigned i = 0; i < n; ++i) {
00127             bx->GetEntry(i);
00128             by->GetEntry(i);
00129             d->Add(v);
00130          }
00131       }
00132       else if (dim == 1) { 
00133          d->Initialize(n,1);
00134          TBranch * bx = tree->GetBranch("x"); 
00135          double v[1];
00136          bx->SetAddress(&v[0]); 
00137          for (int unsigned i = 0; i < n; ++i) {
00138             bx->GetEntry(i);
00139             d->Add(v);
00140          }
00141       }
00142 
00143       return d; 
00144 
00145       //printData(d);
00146    }
00147    else {
00148       tree->SetEstimate(tree->GetEntries());
00149 
00150       // use TTREE::Draw
00151       if (dim == 2) { 
00152          tree->Draw("x:y",0,"goff");  // goff is used to turn off the graphics
00153          double * x = tree->GetV1(); 
00154          double * y = tree->GetV2(); 
00155 
00156          if (x == 0 || y == 0) { 
00157             USE_BRANCH= true;
00158             return FillUnBinData(tree, true, dim);
00159          }
00160 
00161          // use array pre-allocated in tree->Draw . This is faster
00162          //assert(x != 0); 
00163          unsigned int n = tree->GetSelectedRows(); 
00164 
00165          if (copyData) { 
00166             d = new ROOT::Fit::UnBinData(n,2);
00167             double vx[2]; 
00168             for (int unsigned i = 0; i < n; ++i) {         
00169                vx[0] = x[i]; 
00170                vx[1] = y[i];
00171                d->Add(vx);
00172             }
00173          }  
00174          else  // use data pointers directly 
00175             d = new ROOT::Fit::UnBinData(n,x,y);
00176          
00177       }
00178       else if ( dim == 1) { 
00179 
00180             tree->Draw("x",0,"goff");  // goff is used to turn off the graphics
00181             double * x = tree->GetV1(); 
00182 
00183             if (x == 0) { 
00184                USE_BRANCH= true;
00185                return FillUnBinData(tree, true, dim);
00186             }
00187             unsigned int n = tree->GetSelectedRows(); 
00188 
00189             if (copyData) { 
00190                d = new ROOT::Fit::UnBinData(n,1);
00191                for (int unsigned i = 0; i < n; ++i) {         
00192                   d->Add(x[i]);
00193                }
00194             }  
00195             else
00196                d = new ROOT::Fit::UnBinData(n,x);
00197          }
00198       return d;
00199    }
00200       
00201    //std::copy(x,x+n, d.begin() );
00202    return 0; 
00203 } 
00204 
00205 
00206 
00207 
00208 // print the data
00209 template <class T> 
00210 void printData(const T & data) {
00211    for (typename T::const_iterator itr = data.begin(); itr != data.end(); ++itr) { 
00212       std::cout << itr->Coords()[0] << "   " << itr->Value() << "   " << itr->Error() << std::endl; 
00213    }
00214    std::cout << "\ndata size is " << data.Size() << std::endl;
00215 }    
00216 
00217 
00218 
00219 // fitting using new fitter
00220 typedef ROOT::Math::IParamMultiFunction Func;  
00221 template <class MinType, class T>
00222 int DoBinFit(T * hist, Func & func, bool debug = false, bool useGrad = false) {  
00223 
00224    //std::cout << "Fit histogram " << std::endl;
00225 
00226    ROOT::Fit::BinData d; 
00227    ROOT::Fit::FillData(d,hist);
00228 
00229    //printData(d);
00230 
00231    // create the fitter 
00232 
00233    ROOT::Fit::Fitter fitter; 
00234    fitter.Config().SetMinimizer(MinType::name().c_str(),MinType::name2().c_str());
00235 
00236    if (debug) 
00237       fitter.Config().MinimizerOptions().SetPrintLevel(3);
00238 
00239 
00240    // create the function
00241    if (!useGrad) { 
00242 
00243       // use simply TF1 wrapper 
00244       //ROOT::Math::WrappedMultiTF1 f(*func); 
00245       //ROOT::Math::WrappedTF1 f(*func); 
00246       fitter.SetFunction(func); 
00247 
00248    } else { // only for gaus fits
00249       // use function gradient
00250 #ifdef USE_MATHMORE_FUNC
00251    // use mathmore for polynomial
00252       ROOT::Math::Polynomial pol(2); 
00253       assert(pol.NPar() == func->GetNpar());
00254       pol.SetParameters(func->GetParameters() );
00255       ROOT::Math::WrappedParamFunction<ROOT::Math::Polynomial> f(pol,1,func->GetParameters(),func->GetParameters()+func->GetNpar() );
00256 #endif
00257       GaussFunction f; 
00258       f.SetParameters(func.Parameters());
00259       fitter.SetFunction(f);
00260    }
00261 
00262 
00263    bool ret = fitter.Fit(d);
00264    if (!ret) {
00265       std::cout << " Fit Failed " << std::endl;
00266       return -1; 
00267    }
00268    if (debug) 
00269       fitter.Result().Print(std::cout);    
00270    return 0; 
00271 }
00272 
00273 // unbin fit
00274 template <class MinType, class T>
00275 int DoUnBinFit(T * tree, Func & func, bool debug = false, bool copyData = false ) {  
00276 
00277    ROOT::Fit::UnBinData * d  = FillUnBinData(tree, copyData, func.NDim() );  
00278    // need to have done Tree->Draw() before fit
00279    //FillUnBinData(d,tree);
00280 
00281    //std::cout << "data size type and size  is " << typeid(*d).name() <<  "   " << d->Size() << std::endl;
00282    if (copyData) 
00283       std::cout << "\tcopy data in FitData\n";
00284    else
00285       std::cout << "\tre-use original data \n";
00286 
00287          
00288          
00289    //printData(d);
00290 
00291    // create the fitter 
00292    //std::cout << "Fit parameter 2  " << f.Parameters()[2] << std::endl;
00293 
00294    ROOT::Fit::Fitter fitter; 
00295    fitter.Config().SetMinimizer(MinType::name().c_str(),MinType::name2().c_str());
00296 
00297    if (debug) 
00298       fitter.Config().MinimizerOptions().SetPrintLevel(3);
00299 
00300    // set tolerance 1 for tree to be same as in TTTreePlayer::UnBinFIt
00301    fitter.Config().MinimizerOptions().SetTolerance(1);
00302 
00303 
00304    // create the function
00305 
00306    fitter.SetFunction(func); 
00307    // need to fix param 0 , normalization in the unbinned fits
00308    //fitter.Config().ParSettings(0).Fix();
00309 
00310    bool ret = fitter.Fit(*d);
00311    if (!ret) {
00312       std::cout << " Fit Failed " << std::endl;
00313       return -1; 
00314    }
00315    if (debug) 
00316       fitter.Result().Print(std::cout);    
00317 
00318    delete d; 
00319 
00320    return 0; 
00321 
00322 }
00323 
00324 template <class MinType>
00325 int DoFit(TTree * tree, Func & func, bool debug = false, bool copyData = false ) {  
00326    return DoUnBinFit<MinType, TTree>(tree, func, debug, copyData); 
00327 }
00328 template <class MinType>
00329 int DoFit(TH1 * h1, Func & func, bool debug = false, bool copyData = false ) {  
00330    return DoBinFit<MinType, TH1>(h1, func, debug, copyData); 
00331 }
00332 template <class MinType>
00333 int DoFit(TGraph * gr, Func & func, bool debug = false, bool copyData = false ) {  
00334    return DoBinFit<MinType, TGraph>(gr, func, debug, copyData); 
00335 }
00336 
00337 template <class MinType, class FitObj>
00338 int FitUsingNewFitter(FitObj * fitobj, Func & func, bool useGrad=false) { 
00339 
00340    std::cout << "\n************************************************************\n"; 
00341    std::cout << "\tFit using new Fit::Fitter  " << typeid(*fitobj).name() << std::endl;
00342    std::cout << "\tMinimizer is " << MinType::name() << "  " << MinType::name2() << " func dim = " << func.NDim() << std::endl; 
00343 
00344    int iret = 0; 
00345    TStopwatch w; w.Start(); 
00346 
00347 #ifdef DEBUG
00348    // std::cout << "initial Parameters " << iniPar << "  " << *iniPar << "   " <<  *(iniPar+1) << std::endl;
00349    func.SetParameters(iniPar);
00350    iret |= DoFit<MinType>(fitobj,func,true, useGrad);
00351    if (iret != 0) {
00352       std::cout << "Fit failed " << std::endl;
00353    }
00354 
00355 #else
00356    for (int i = 0; i < nfit; ++i) { 
00357       func.SetParameters(iniPar);
00358       iret = DoFit<MinType>(fitobj,func, false, useGrad);
00359       if (iret != 0) {
00360          std::cout << "Fit failed " << std::endl;
00361          break; 
00362       }
00363    }
00364 #endif
00365    w.Stop(); 
00366    std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;  
00367    std::cout << "\n************************************************************\n"; 
00368 
00369    return iret; 
00370 }
00371 
00372 
00373 //------------old fit methods 
00374 
00375 // fit using Fit method
00376 template <class T, class MinType>
00377 int FitUsingTFit(T * hist, TF1 * func) { 
00378 
00379    std::cout << "\n************************************************************\n"; 
00380    std::cout << "\tFit using " << hist->ClassName() << "::Fit\n";
00381    std::cout << "\tMinimizer is " << MinType::name() << std::endl; 
00382 
00383    std::string opt = "BFQ0"; 
00384    if (MinType::name() == "Linear")
00385       opt = "Q0"; 
00386 
00387    // check gminuit
00388 //    TSeqCollection * l = gROOT->GetListOfSpecials();
00389 //    for (int i = 0; i < l->GetEntries(); ++i)  { 
00390 //       TObject * obj = l->At(i); 
00391 //       std::cout << " entries for i " << i << " of " << l->GetEntries() << " is " << obj << std::endl;      
00392 //       if (obj != 0)     std::cout << " object name is " <<  obj->GetName() << std::endl; 
00393 //    }
00394 
00395    int iret = 0;
00396    TVirtualFitter::SetDefaultFitter(MinType::name().c_str());
00397 
00398    TStopwatch w; w.Start(); 
00399    for (int i = 0; i < nfit; ++i) { 
00400       func->SetParameters(iniPar);
00401       iret |= hist->Fit(func,opt.c_str());
00402       if (iret != 0) { 
00403          std::cout << "Fit failed " << std::endl;
00404          return iret; 
00405       }
00406    }
00407    // std::cout << "iret " << iret << std::endl;
00408 #ifdef DEBUG
00409    func->SetParameters(iniPar);
00410 //    if (fitter == "Minuit2") { 
00411 //       // increase print level 
00412 //       TVirtualFitter * tvf = TVirtualFitter::GetFitter(); 
00413 //       TFitterMinuit * minuit2 = dynamic_cast<TFitterMinuit * >(tvf);
00414 //       assert (minuit2 != 0); 
00415 //       minuit2->SetPrintLevel(3);
00416 //    }
00417    if (MinType::name() != "Linear") 
00418       iret |= hist->Fit(func,"BFV0");
00419    else 
00420       iret |= hist->Fit(func,"V0");
00421    // get precice value of minimum
00422    int pr = std::cout.precision(18);
00423    std::cout << "Chi2 value = " << func->GetChisquare() << std::endl; 
00424    std::cout.precision(pr);
00425 
00426 #endif
00427    w.Stop(); 
00428    std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;  
00429    std::cout << "\n************************************************************\n"; 
00430 
00431    return iret; 
00432 }
00433 
00434 
00435 // unbinned fit using Fit of trees
00436 template <class MinType>
00437 int FitUsingTTreeFit(TTree * tree, TF1 * func, const std::string & vars = "x") { 
00438 
00439    std::cout << "\n************************************************************\n"; 
00440    std::cout << "\tFit using TTree::UnbinnedFit\n";
00441    std::cout << "\tMinimizer is " << MinType::name() << std::endl; 
00442 
00443       
00444    std::string sel = "";
00445 
00446    int iret = 0;
00447    TVirtualFitter::SetDefaultFitter(MinType::name().c_str());
00448 
00449    TStopwatch w; w.Start(); 
00450    for (int i = 0; i < nfit; ++i) { 
00451       func->SetParameters(iniPar);
00452       iret |= tree->UnbinnedFit(func->GetName(),vars.c_str(),sel.c_str(),"Q");
00453       if (iret != 0) { 
00454          std::cout << "Fit failed : iret = " << iret << std::endl;
00455          return iret; 
00456       }
00457    }
00458    // std::cout << "iret " << iret << std::endl;
00459 #ifdef DEBUG
00460    func->SetParameters(iniPar);
00461 
00462    iret |= tree->UnbinnedFit(func->GetName(),vars.c_str(),sel.c_str(),"V");
00463 
00464 #endif
00465    w.Stop(); 
00466    std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;  
00467    std::cout << "\n************************************************************\n"; 
00468 
00469    return iret; 
00470 }
00471 
00472 
00473 // int FitUsingTVirtualFitter(TH1 * hist, TF1 * func, const std::string & fitter) { 
00474 
00475 //    TVirtualFitter::SetDefaultFitter(fitter.c_str());
00476 //    std::cout << "Fit using TVirtualFitter and " << fitter << "\t Time: \t" << w.RealTime() << " , " << w.CpuTime() < std::endl;  
00477 // }
00478 
00479 
00480 // ROoFit
00481 
00482 
00483 //binned roo fit 
00484 int  FitUsingRooFit(TH1 * hist, TF1 * func) { 
00485 
00486    int iret = 0; 
00487    std::cout << "\n************************************************************\n"; 
00488    std::cout << "\tFit using RooFit (Chi2 Fit)\n";
00489    std::cout << "\twith function " << func->GetName() << "\n";
00490 
00491 
00492    // start counting t he time
00493    TStopwatch w; w.Start(); 
00494 
00495    for (int i = 0; i < nfit; ++i) { 
00496 
00497       RooRealVar x("x","x",-5,5) ;
00498       
00499       RooDataHist data("bindata","bin dataset with x",x,hist) ;
00500      // define params
00501       RooAbsPdf * pdf = 0; 
00502       RooRealVar * mean = 0; 
00503       RooRealVar * sigma = 0; 
00504 
00505       func->SetParameters(iniPar);
00506       std::string fname = func->GetName(); 
00507       if (fname == "gaussian") { 
00508          double val,pmin,pmax; 
00509          val = func->GetParameter(1); //func->GetParLimits(1,-100,100); 
00510          RooRealVar * mean = new RooRealVar("mean","Mean of Gaussian",val) ;
00511          val = func->GetParameter(2); func->GetParLimits(1,pmin,pmax); 
00512          RooRealVar * sigma = new RooRealVar("sigma","Width of Gaussian",val) ;
00513          
00514          pdf = new RooGaussian("gauss","gauss(x,mean,sigma)",x,*mean,*sigma) ; 
00515       }
00516      
00517       assert(pdf != 0);
00518 #define USE_CHI2_FIT
00519 #ifdef USE_CHI2_FIT
00520       RooChi2Var chi2("chi2","chi2",*pdf,data) ;
00521       RooMinuit m(chi2) ;
00522       m.setPrintLevel(-1);
00523       m.fit("mh") ;
00524 #else
00525       pdf->fitTo(data);
00526 #endif
00527 //      if (iret != 0) return iret; 
00528       delete pdf; 
00529       delete mean; delete sigma; 
00530    }
00531 
00532    w.Stop(); 
00533    std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;  
00534    std::cout << "\n************************************************************\n"; 
00535    return iret; 
00536 }
00537 
00538 //unbinned roo fit 
00539 int  FitUsingRooFit(TTree * tree, TF1 * func) { 
00540 
00541    int iret = 0; 
00542    std::cout << "\n************************************************************\n"; 
00543    std::cout << "\tFit using RooFit (Likelihood Fit)\n";
00544    std::cout << "\twith function " << func->GetName() << "\n";
00545 
00546 
00547    // start counting t he time
00548    TStopwatch w; w.Start(); 
00549 
00550    for (int i = 0; i < nfit; ++i) { 
00551 
00552       RooRealVar x("x","x",-100,100) ;
00553       RooRealVar y("y","y",-100,100);
00554 
00555       RooDataSet data("unbindata","unbin dataset with x",tree,RooArgSet(x,y)) ;       
00556 
00557 
00558       RooRealVar mean("mean","Mean of Gaussian",iniPar[0], -100,100) ;
00559       RooRealVar sigma("sigma","Width of Gaussian",iniPar[1], -100, 100) ;
00560          
00561       RooGaussian pdfx("gaussx","gauss(x,mean,sigma)",x,mean,sigma);
00562 
00563       // for 2d data
00564       RooRealVar meany("meanx","Mean of Gaussian",iniPar[2], -100,100) ;
00565       RooRealVar sigmay("sigmay","Width of Gaussian",iniPar[3], -100, 100) ;         
00566       RooGaussian pdfy("gaussy","gauss(y,meanx,sigmay)",y,meany,sigmay);
00567 
00568       RooProdPdf pdf("gausxy","gausxy",RooArgSet(pdfx,pdfy) );
00569 
00570 
00571 #ifdef DEBUG
00572       int level = 3; 
00573       std::cout << "num entries = " << data.numEntries() << std::endl;
00574       bool save = true; 
00575       (pdf.getVariables())->Print("v"); // print the parameters 
00576 #else 
00577       int level = -1; 
00578       bool save = false; 
00579 #endif
00580 
00581 //#ifndef _WIN32 // until a bug 30762 is fixed
00582       RooFitResult * result = pdf.fitTo(data, RooFit::Minos(0), RooFit::Hesse(1) , RooFit::PrintLevel(level), RooFit::Save(save) );
00583 // #else
00584 //       RooFitResult * result = pdf.fitTo(data );
00585 // #endif
00586 
00587 #ifdef DEBUG
00588       mean.Print(); 
00589       sigma.Print();
00590       assert(result != 0); 
00591       std::cout << " Roofit status " << result->status() << std::endl; 
00592       result->Print();
00593 #endif
00594       if (save) iret |= (result == 0);
00595 
00596       if (iret != 0) { 
00597          std::cout << "Fit failed " << std::endl;
00598          return iret; 
00599       }
00600 
00601    }
00602 
00603    w.Stop(); 
00604    std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;  
00605    std::cout << "\n************************************************************\n"; 
00606    return iret; 
00607 }
00608 
00609 //unbinned roo fit (large tree)
00610 int  FitUsingRooFit2(TTree * tree) { 
00611 
00612    int iret = 0; 
00613    std::cout << "\n************************************************************\n"; 
00614    std::cout << "\tFit using RooFit (Likelihood Fit)\n";
00615 
00616 
00617    // start counting t he time
00618    TStopwatch w; w.Start(); 
00619 
00620    for (int i = 0; i < nfit; ++i) { 
00621 
00622       RooArgSet xvars; 
00623       std::vector<RooRealVar *> x(N);
00624       std::vector<RooRealVar *> m(N);
00625       std::vector<RooRealVar *> s(N);
00626 
00627       std::vector<RooGaussian *> g(N);
00628       std::vector<RooProdPdf *> pdf(N);
00629 
00630       for (int j = 0; j < N; ++j) { 
00631          std::string xname = "x_" + ROOT::Math::Util::ToString(j);
00632          x[j] = new RooRealVar(xname.c_str(),xname.c_str(),-10000,10000) ;
00633          xvars.add( *x[j] );
00634       } 
00635 
00636 
00637       RooDataSet data("unbindata","unbin dataset with x",tree,xvars) ;       
00638 
00639       // create the gaussians
00640       for (int j = 0; j < N; ++j) { 
00641          std::string mname = "m_" + ROOT::Math::Util::ToString(j);
00642          std::string sname = "s_" + ROOT::Math::Util::ToString(j);
00643 
00644          
00645          m[j] = new RooRealVar(mname.c_str(),mname.c_str(),iniPar[2*j],-100,100) ;  
00646          s[j] = new RooRealVar(sname.c_str(),sname.c_str(),iniPar[2*j+1],-100,100) ;  
00647 
00648          std::string gname = "g_" + ROOT::Math::Util::ToString(j);
00649          g[j] = new RooGaussian(gname.c_str(),"gauss(x,mean,sigma)",*x[j],*m[j],*s[j]);
00650 
00651          std::string pname = "prod_" + ROOT::Math::Util::ToString(j);
00652          if (j == 1) { 
00653             pdf[1] = new RooProdPdf(pname.c_str(),pname.c_str(),RooArgSet(*g[1],*g[0]) );
00654          }
00655          else if (j > 1) { 
00656             pdf[j] = new RooProdPdf(pname.c_str(),pname.c_str(),RooArgSet(*g[j],*pdf[j-1]) );
00657          }
00658       } 
00659 
00660          
00661 
00662      
00663 #ifdef DEBUG
00664       int level = 3; 
00665       std::cout << "num entries = " << data.numEntries() << std::endl;
00666       bool save = true; 
00667       (pdf[N-1]->getVariables())->Print("v"); // print the parameters 
00668       std::cout << "\n\nDo the fit now \n\n"; 
00669 #else 
00670       int level = -1; 
00671       bool save = false; 
00672 #endif
00673 
00674 
00675 #ifndef _WIN32 // until a bug 30762 is fixed
00676       RooFitResult * result = pdf[N-1]->fitTo(data, RooFit::Minos(0), RooFit::Hesse(1) , RooFit::PrintLevel(level), RooFit::Save(save) );
00677 #else 
00678       RooFitResult * result = pdf[N-1]->fitTo(data);
00679 #endif
00680 
00681 #ifdef DEBUG
00682       assert(result != 0); 
00683       std::cout << " Roofit status " << result->status() << std::endl; 
00684       result->Print();
00685 #endif
00686 
00687 
00688       iret |= (result == 0);
00689 
00690       // free
00691       for (int j = 0; j < N; ++j) { 
00692          delete x[j]; 
00693          delete m[j]; 
00694          delete s[j]; 
00695          delete g[j];
00696          delete pdf[j]; 
00697       }
00698 
00699       if (iret != 0) return iret; 
00700       //assert(iret == 0); 
00701 
00702 
00703    }
00704 
00705    w.Stop(); 
00706    std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;  
00707    std::cout << "\n************************************************************\n"; 
00708    return iret; 
00709 }
00710 
00711 
00712 double poly2(const double *x, const double *p) { 
00713    return p[0] + (p[1]+p[2]*x[0] ) * x[0]; 
00714 }
00715 
00716 int testPolyFit() { 
00717 
00718    int iret = 0;
00719 
00720 
00721    std::cout << "\n\n************************************************************\n"; 
00722    std::cout << "\t POLYNOMIAL FIT\n";
00723    std::cout << "************************************************************\n"; 
00724 
00725    std::string fname("pol2");
00726    //TF1 * func = (TF1*)gROOT->GetFunction(fname.c_str());
00727    TF1 * f1 = new TF1("pol2",fname.c_str(),-5,5.);
00728 
00729    f1->SetParameter(0,1);
00730    f1->SetParameter(1,0.0);
00731    f1->SetParameter(2,1.0);
00732 
00733 
00734    // fill an histogram 
00735    TH1D * h1 = new TH1D("h1","h1",20,-5.,5.);
00736 //      h1->FillRandom(fname.c_str(),100);
00737    for (int i = 0; i <1000; ++i) 
00738       h1->Fill( f1->GetRandom() );
00739 
00740    //h1->Print();
00741    //h1->Draw();
00742    iniPar[0] = 2.; iniPar[1] = 2.; iniPar[2] = 2.;
00743 
00744 
00745    iret |= FitUsingTFit<TH1,TMINUIT>(h1,f1);
00746    iret |= FitUsingTFit<TH1,MINUIT2>(h1,f1);
00747    // dummy for testing
00748    //iret |= FitUsingNewFitter<DUMMY>(h1,f1);
00749 
00750    // use simply TF1 wrapper 
00751    //ROOT::Math::WrappedMultiTF1 f2(*f1); 
00752    ROOT::Math::WrappedParamFunction<> f2(&poly2,1,iniPar,iniPar+3); 
00753 
00754 
00755    // if Minuit2 is later than TMinuit on Interl is much slower , why ??
00756    iret |= FitUsingNewFitter<MINUIT2>(h1,f2);
00757    iret |= FitUsingNewFitter<TMINUIT>(h1,f2);
00758 
00759    // test with linear fitter 
00760    // for this test need to pass a multi-dim function
00761    ROOT::Math::WrappedTF1 wf(*f1); 
00762    ROOT::Math::MultiDimParamGradFunctionAdapter lfunc(wf); 
00763    iret |= FitUsingNewFitter<LINEAR>(h1,lfunc,true);
00764    iret |= FitUsingTFit<TH1,LINEAR>(h1,f1);
00765 
00766    // test with a graph 
00767 
00768    gStyle->SetErrorX(0.); // to seto zero error on X
00769    TGraphErrors * gr = new TGraphErrors(h1);
00770    iret |= FitUsingTFit<TGraph,TMINUIT>(gr,f1);
00771 
00772    iret |= FitUsingTFit<TGraph,MINUIT2>(gr,f1);
00773 
00774    iret |= FitUsingNewFitter<MINUIT2>(gr,f2);
00775 
00776 
00777    std::cout << "\n-----> test now TGraphErrors with errors in X coordinates\n\n"; 
00778    // try with error in X
00779    gStyle->SetErrorX(0.5); // to set zero error on X
00780    TGraphErrors * gr2 = new TGraphErrors(h1);
00781    iret |= FitUsingTFit<TGraph,TMINUIT>(gr2,f1);
00782    iret |= FitUsingTFit<TGraph,MINUIT2>(gr2,f1);
00783 
00784    iret |= FitUsingNewFitter<MINUIT2>(gr2,f2);
00785 
00786    printResult(iret);
00787 
00788    return iret;
00789 }
00790 
00791 double gaussian(const double *x, const double *p) { 
00792    //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
00793    double tmp = (x[0]-p[1])/p[2];
00794    return p[0] * std::exp(-tmp*tmp/2);
00795 }
00796 
00797 double gausnorm(const double *x, const double *p) { 
00798    //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
00799    double invsig = 1./p[1]; 
00800    double tmp = (x[0]-p[0]) * invsig; 
00801    const double sqrt_2pi = 1./std::sqrt(2.* 3.14159 );
00802    return std::exp(-0.5 * tmp*tmp ) * sqrt_2pi * invsig; 
00803 }
00804 double gausnorm2D(const double *x, const double *p) { 
00805    //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
00806    return gausnorm(x,p)*gausnorm(x+1,p+2);
00807 }
00808 double gausnormN(const double *x, const double *p) { 
00809    //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
00810    double f = 1; 
00811    for (int i = 0; i < N; ++i) 
00812       f *= gausnorm(x+i,p+2*i);
00813 
00814    return f; 
00815 }
00816 
00817 int testGausFit() { 
00818 
00819    int iret = 0; 
00820 
00821    std::cout << "\n\n************************************************************\n"; 
00822    std::cout << "\t GAUSSIAN FIT\n";
00823    std::cout << "************************************************************\n"; 
00824 
00825 
00826 
00827    //std::string fname = std::string("gaus");
00828    //TF1 * func = (TF1*)gROOT->GetFunction(fname.c_str());
00829    //TF1 * f1 = new TF1("gaus",fname.c_str(),-5,5.);
00830    TF1 * f1 = new TF1("gaussian",gaussian,-5,5.,3);
00831    //f2->SetParameters(0,1,1);
00832 
00833    // fill an histogram 
00834    int nbin = 10000; 
00835    TH1D * h2 = new TH1D("h2","h2",nbin,-5.,5.);
00836 //      h1->FillRandom(fname.c_str(),100);
00837    for (int i = 0; i < 10000000; ++i) 
00838       h2->Fill( gRandom->Gaus(0,10) );
00839 
00840    iniPar[0] = 100.; iniPar[1] = 2.; iniPar[2] = 2.;
00841 
00842 
00843    // use simply TF1 wrapper 
00844    //ROOT::Math::WrappedMultiTF1 f2(*f1); 
00845    ROOT::Math::WrappedParamFunction<> f2(&gaussian,1,iniPar,iniPar+3); 
00846 
00847 
00848    iret |= FitUsingNewFitter<MINUIT2>(h2,f2);
00849    iret |= FitUsingNewFitter<TMINUIT>(h2,f2);
00850 
00851 //    iret |= FitUsingNewFitter<GSL_PR>(h2,f2);
00852 
00853 
00854    iret |= FitUsingTFit<TH1,TMINUIT>(h2,f1);
00855    iret |= FitUsingTFit<TH1,MINUIT2>(h2,f1);
00856 
00857 
00858     iret |= FitUsingNewFitter<GSL_FR>(h2,f2);
00859     iret |= FitUsingNewFitter<GSL_PR>(h2,f2);
00860     iret |= FitUsingNewFitter<GSL_BFGS>(h2,f2);
00861     iret |= FitUsingNewFitter<GSL_BFGS2>(h2,f2);
00862 
00863 
00864    // test also fitting a TGraphErrors with histogram data
00865    gStyle->SetErrorX(0.); // to seto zero error on X
00866    TGraphErrors * gr = new TGraphErrors(h2);
00867 
00868    iret |= FitUsingTFit<TGraph,TMINUIT>(gr,f1);
00869    iret |= FitUsingTFit<TGraph,MINUIT2>(gr,f1);
00870 
00871    iret |= FitUsingNewFitter<MINUIT2>(gr,f2);
00872 
00873    // try with error in X
00874    gStyle->SetErrorX(0.5); // to seto zero error on X
00875    TGraphErrors * gr2 = new TGraphErrors(h2);
00876    iret |= FitUsingTFit<TGraph,TMINUIT>(gr2,f1);
00877 
00878    iret |= FitUsingNewFitter<MINUIT2>(gr2,f2);
00879 
00880 
00881 
00882 //#ifdef LATER
00883    // test using grad function
00884    std::cout << "\n\nTest Using pre-calculated gradients\n\n";
00885    bool useGrad=true; 
00886    iret |= FitUsingNewFitter<MINUIT2>(h2,f2,useGrad);
00887    iret |= FitUsingNewFitter<TMINUIT>(h2,f2,useGrad);
00888    iret |= FitUsingNewFitter<GSL_FR>(h2,f2,useGrad);
00889    iret |= FitUsingNewFitter<GSL_PR>(h2,f2,useGrad);
00890    iret |= FitUsingNewFitter<GSL_BFGS>(h2,f2,useGrad);
00891    iret |= FitUsingNewFitter<GSL_BFGS2>(h2,f2,useGrad);
00892 
00893 
00894    // test LS algorithm 
00895    std::cout << "\n\nTest Least Square algorithms\n\n";
00896    iret |= FitUsingNewFitter<GSL_NLS>(h2,f2);
00897    iret |= FitUsingNewFitter<FUMILI2>(h2,f2);
00898    iret |= FitUsingNewFitter<TFUMILI>(h2,f2);
00899 
00900 //    iret |= FitUsingTFit<TH1,FUMILI2>(h2,f1);
00901 //    iret |= FitUsingTFit<TH1,TFUMILI>(h2,f1);
00902 //#endif
00903 
00904    //iret |= FitUsingRooFit(h2,f1);
00905 
00906    printResult(iret);
00907 
00908    return iret; 
00909 }
00910 
00911 int testTreeFit() { 
00912 
00913    std::cout << "\n\n************************************************************\n"; 
00914    std::cout << "\t UNBINNED TREE (GAUSSIAN)  FIT\n";
00915    std::cout << "************************************************************\n"; 
00916 
00917 
00918    TTree t1("t1","a simple Tree with simple variables");
00919    double  x, y; 
00920    Int_t ev;
00921    t1.Branch("x",&x,"x/D");
00922    t1.Branch("y",&y,"y/D");
00923 //          t1.Branch("pz",&pz,"pz/F");
00924 //          t1.Branch("random",&random,"random/D");
00925    t1.Branch("ev",&ev,"ev/I");
00926    
00927    //fill the tree
00928    int nrows = 10000;
00929 #ifdef TREE_FIT2D
00930    nrows = 10000;
00931 #endif
00932    for (Int_t i=0;i<nrows;i++) {
00933       gRandom->Rannor(x,y);
00934       x *= 2; x += 1.;
00935       y *= 3; y -= 2; 
00936 
00937       ev = i;
00938       t1.Fill();
00939       
00940    }
00941    //t1.Draw("x"); // to select fit variable 
00942 
00943    TF1 * f1 = new TF1("gausnorm", gausnorm, -10,10, 2);
00944    TF2 * f2 = new TF2("gausnorm2D", gausnorm2D, -10,10, -10,10, 4); 
00945 
00946    ROOT::Math::WrappedParamFunction<> wf1(&gausnorm,1,iniPar,iniPar+2); 
00947    ROOT::Math::WrappedParamFunction<> wf2(&gausnorm2D,2,iniPar,iniPar+4); 
00948 
00949  
00950    iniPar[0] = 0; 
00951    iniPar[1] = 1; 
00952    iniPar[2] = 0; 
00953    iniPar[3] = 1; 
00954 
00955    // use simply TF1 wrapper 
00956    //ROOT::Math::WrappedMultiTF1 f2(*f1); 
00957 
00958    int iret = 0; 
00959 
00960    // fit 1D first
00961 
00962 
00963    iret |= FitUsingTTreeFit<MINUIT2>(&t1,f1,"x");
00964    iret |= FitUsingTTreeFit<MINUIT2>(&t1,f1,"x");
00965    
00966    iret |= FitUsingTTreeFit<TMINUIT>(&t1,f1,"x");
00967 
00968    iret |= FitUsingNewFitter<MINUIT2>(&t1,wf1,false); // not copying the data
00969    iret |= FitUsingNewFitter<TMINUIT>(&t1,wf1,false); // not copying the data
00970    iret |= FitUsingNewFitter<MINUIT2>(&t1,wf1,true); // copying the data
00971    iret |= FitUsingNewFitter<TMINUIT>(&t1,wf1,true); // copying the data
00972 
00973    // fit 2D 
00974 
00975 
00976 
00977    iret |= FitUsingTTreeFit<MINUIT2>(&t1,f2,"x:y");
00978    iret |= FitUsingTTreeFit<TMINUIT>(&t1,f2,"x:y");
00979 
00980    iret |= FitUsingNewFitter<MINUIT2>(&t1,wf2, true);
00981    iret |= FitUsingNewFitter<MINUIT2>(&t1,wf2, false);
00982 
00983 
00984 
00985    iret |= FitUsingRooFit(&t1,f1);
00986 
00987    printResult(iret);
00988    return iret; 
00989 
00990 }
00991 
00992 int testLargeTreeFit(int nevt = 1000) { 
00993 
00994    std::cout << "\n\n************************************************************\n"; 
00995    std::cout << "\t UNBINNED TREE (GAUSSIAN MULTI-DIM)  FIT\n";
00996    std::cout << "************************************************************\n"; 
00997 
00998    TTree t1("t2","a large Tree with simple variables");
00999    double  x[N];
01000    Int_t ev;
01001    t1.Branch("x",x,"x[20]/D");
01002    t1.Branch("ev",&ev,"ev/I");
01003    
01004    //fill the tree
01005    TRandom3 r; 
01006    for (Int_t i=0;i<nevt;i++) {
01007       for (int j = 0;  j < N; ++j) { 
01008          double mu = double(j)/10.; 
01009          double s  = 1.0 + double(j)/10.;  
01010          x[j] = r.Gaus(mu,s);
01011       }
01012 
01013       ev = i;
01014       t1.Fill();
01015       
01016    }
01017    //t1.Draw("x"); // to select fit variable 
01018 
01019 
01020    for (int i = 0; i <N; ++i) {
01021       iniPar[2*i] = 0; 
01022       iniPar[2*i+1] = 1; 
01023    }
01024 
01025    // use simply TF1 wrapper 
01026    //ROOT::Math::WrappedMultiTF1 f2(*f1); 
01027    ROOT::Math::WrappedParamFunction<> f2(&gausnormN,N,2*N,iniPar); 
01028 
01029    int iret = 0; 
01030    iret |= FitUsingNewFitter<MINUIT2>(&t1,f2);
01031    iret |= FitUsingNewFitter<TMINUIT>(&t1,f2);
01032    iret |= FitUsingNewFitter<GSL_BFGS2>(&t1,f2);
01033 
01034 
01035 
01036    printResult(iret);
01037    return iret; 
01038 
01039 }
01040 int testLargeTreeRooFit(int nevt = 1000) { 
01041 
01042    int iret = 0; 
01043 
01044    TTree t2("t2b","a large Tree with simple variables");
01045    double  x[N];
01046    Int_t ev;
01047    for (int j = 0; j < N; ++j) { 
01048       std::string xname = "x_" + ROOT::Math::Util::ToString(j);
01049       std::string xname2 = "x_" + ROOT::Math::Util::ToString(j) + "/D";
01050       t2.Branch(xname.c_str(),&x[j],xname2.c_str());
01051    }
01052    t2.Branch("ev",&ev,"ev/I");
01053    //fill the tree
01054    TRandom3 r; 
01055    for (Int_t i=0;i<nevt;i++) {
01056       for (int j = 0;  j < N; ++j) { 
01057          double mu = double(j)/10.; 
01058          double s  = 1.0 + double(j)/10.;  
01059          x[j] = r.Gaus(mu,s);
01060       }
01061 
01062       ev = i;
01063       t2.Fill();      
01064    }   
01065 
01066 
01067    for (int i = 0; i <N; ++i) {
01068       iniPar[2*i] = 0; 
01069       iniPar[2*i+1] = 1; 
01070    }
01071 
01072 
01073    //TF1 * f = new TF1("gausnormN", gausnormN, -100,100, 2*N); 
01074    
01075    iret |= FitUsingRooFit2(&t2);
01076 
01077 
01078    printResult(iret);
01079    
01080    return iret; 
01081 
01082 }
01083 
01084 int testFitPerf() { 
01085 
01086    int iret = 0; 
01087 
01088 
01089 
01090 #ifndef DEBUG
01091    nfit = 10; 
01092 #endif
01093   iret |= testGausFit(); 
01094 
01095 
01096 #ifdef DEBUG
01097    nfit = 1; 
01098 #else 
01099    nfit = 1; 
01100 #endif
01101   iret |= testTreeFit(); 
01102 
01103 
01104 
01105  //return iret; 
01106 
01107 #ifndef DEBUG
01108    nfit = 1000; 
01109 #endif
01110    iret |= testPolyFit(); 
01111 
01112 
01113 
01114 
01115   nfit = 1;
01116  iret |= testLargeTreeRooFit(500); 
01117  iret |= testLargeTreeFit(500); 
01118 
01119 
01120    if (iret != 0) 
01121       std::cerr << "testFitPerf :\t FAILED " << std::endl; 
01122    else 
01123       std::cerr << "testFitPerf :\t OK " << std::endl; 
01124    return iret;
01125 }
01126 
01127 int main() { 
01128    return testFitPerf();
01129 }
01130    

Generated on Tue Jul 5 14:34:30 2011 for ROOT_528-00b_version by  doxygen 1.5.1