stressHistoFit.cxx

Go to the documentation of this file.
00001 // @(#)root/test:$name:  $:$id: stressHistoFit.cxx,v 1.15 2002/10/25 10:47:51 rdm exp $
00002 // Authors: David Gonzalez Maline November 2008
00003 
00004 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//
00005 //                                                                               //
00006 //                                                                               //
00007 // Set of tests for different minimization algorithms and for                    //
00008 // different objects. The tests are divided into three types:                    //
00009 //                                                                               //
00010 // 1. 1D and 2D Objects, including 1D and 2D histograms, 1D and 2D               //
00011 //    histograms with variable bins, TGraph, TGraphErrors, TGraph2D,             //
00012 //    TGraph2DErrors                                                             //
00013 // 2. Same as before, but trying linear fitters.                                 //
00014 // 3. Unbinned fits with trees of different dimensions.                          //
00015 //                                                                               //
00016 // Each test will performed fits with different functions and                    //
00017 // different minimization algorithms selected. There is an error                 //
00018 // tolerance for each one of them. There is also the possibility to              //
00019 // inspect each one of the test individually changing the                        //
00020 // defaultOptions variable.                                                      //
00021 //                                                                               //
00022 //                                                                               //
00023 // An example of output when all the tests run OK is shown below:                //
00024 // ****************************************************************************
00025 // *  Starting  stress  H I S T O F I T                                       *
00026 // ****************************************************************************
00027 
00028 // Test 1D and 2D objects
00029 
00030 // Test   1:  'Histogram 1D Variable' with 'GAUS'...................OK
00031 // Test   2:  'Histogram 1D' with 'GAUS'............................OK
00032 // Test   3:  'TGraph 1D' with 'GAUS'...............................OK
00033 // Test   4:  'TGraphErrors 1D' with 'GAUS'.........................OK
00034 // Test   5:  'THnSparse 1D' with 'GAUS'............................OK
00035 // Test   6:  'Histogram 1D Variable' with 'Polynomial'.............OK
00036 // Test   7:  'Histogram 1D' with 'Polynomial'......................OK
00037 // Test   8:  'TGraph 1D' with 'Polynomial'.........................OK
00038 // Test   9:  'TGraphErrors 1D' with 'Polynomial'...................OK
00039 // Test  10:  'THnSparse 1D' with 'Polynomial'......................OK
00040 // Test  11:  'Histogram 2D Variable' with 'gaus2D'.................OK
00041 // Test  12:  'Histogram 2D' with 'gaus2D'..........................OK
00042 // Test  13:  'TGraph 2D' with 'gaus2D'.............................OK
00043 // Test  14:  'TGraphErrors 2DGE' with 'gaus2D'.....................OK
00044 // Test  15:  'THnSparse 2D' with 'gaus2D'..........................OK
00045 
00046 // Test Linear fits
00047 
00048 // Test  16:  'Histogram 1D Variable' with 'Polynomial'.............OK
00049 // Test  17:  'Histogram 1D' with 'Polynomial'......................OK
00050 // Test  18:  'TGraph 1D' with 'Polynomial'.........................OK
00051 // Test  19:  'TGraphErrors 1D' with 'Polynomial'...................OK
00052 // Test  20:  'THnSparse 1D' with 'Polynomial'......................OK
00053 // Test  21:  'Histogram 2D Variable' with 'Poly2D'.................OK
00054 // Test  22:  'Histogram 2D' with 'Poly2D'..........................OK
00055 // Test  23:  'TGraph 2D' with 'Poly2D'.............................OK
00056 // Test  24:  'TGraphErrors 2DGE' with 'Poly2D'.....................OK
00057 // Test  25:  'THnSparse 2D' with 'Poly2D'..........................OK
00058 
00059 // Test unbinned fits
00060 
00061 // Test  26:  'tree' with 'gausn'...................................OK
00062 // Test  27:  'tree' with 'gaus2Dn'.................................OK
00063 // Test  28:  'tree' with 'gausND'..................................OK
00064 
00065 // ****************************************************************************
00066 // stressHistoFit: Real Time =  37.49 seconds Cpu Time =  37.24 seconds
00067 //  ROOTMARKS = 2663.8 ROOT version: 5.27/01    trunk@32822
00068 // ****************************************************************************
00069 //
00070 //                                                                               //
00071 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//
00072 
00073 #include "TH1.h"
00074 #include "TH2.h"
00075 #include "THnSparse.h"
00076 #include "TGraph.h"
00077 #include "TGraph2D.h"
00078 #include "TGraphErrors.h"
00079 #include "TGraph2DErrors.h"
00080 #include "TTree.h"
00081 #include "TF1.h"
00082 #include "TF2.h"
00083 
00084 #include "Math/IFunction.h"
00085 #include "Math/IParamFunction.h"
00086 #include "TMath.h"
00087 #include "Math/DistFunc.h"
00088 
00089 #include "TUnuran.h"
00090 #include "TUnuranMultiContDist.h"
00091 #include "Math/MinimizerOptions.h"
00092 #include "TBackCompFitter.h"
00093 #include "TVirtualFitter.h"
00094 
00095 #include "Math/WrappedTF1.h"
00096 #include "Math/WrappedMultiTF1.h"
00097 #include "Fit/BinData.h"
00098 #include "Fit/UnBinData.h"
00099 #include "HFitInterface.h"
00100 #include "Fit/Fitter.h"
00101 
00102 #include "TRandom3.h"
00103 
00104 #include "TROOT.h"
00105 //#include "RConfigure.h"
00106 #include "TBenchmark.h"
00107 #include "TCanvas.h"
00108 #include "TApplication.h"
00109 
00110 #include <vector>
00111 #include <string>
00112 #include <cassert>
00113 #include <cmath>
00114 
00115 #include "Riostream.h"
00116 using namespace std;
00117 // Next line should not exist. It is now there for testing
00118 // pourpuses.
00119 #undef R__HAS_MATHMORE
00120 
00121 const unsigned int __DRAW__ = 0;
00122 
00123 TRandom3 rndm;
00124 
00125 enum cmpOpts {
00126    cmpNone = 0,
00127    cmpPars = 1,
00128    cmpDist = 2,
00129    cmpChi2 = 4,
00130    cmpErr  = 8,
00131 };
00132 
00133 // Reference structure to compare the fitting results
00134 struct RefValue {
00135    const double* pars;
00136    const double  chi;
00137    RefValue(const double* p = 0, const double c = 0.0): pars(p), chi(c) {};
00138 };
00139 
00140 // Class that keeps a reference structure and some tolerance values to
00141 // make a comparision between the reference and the result of a
00142 // fit. The options define what has to be compared.
00143 class CompareResult {
00144 public:
00145    struct RefValue* refValue;
00146    int opts;
00147    double tolPar;
00148    double tolChi2;
00149    CompareResult(int _opts = cmpPars, double _tolPar = 3, double _tolChi2 = 0.01):
00150       refValue(0), opts(_opts), tolPar(_tolPar), tolChi2(_tolChi2) {};
00151 
00152    CompareResult(CompareResult const& copy):
00153       refValue(copy.refValue), opts(copy.opts), 
00154       tolPar(copy.tolPar), tolChi2(copy.tolChi2) {};
00155 
00156    void setRefValue(struct RefValue* _refValue)
00157    { 
00158       refValue = _refValue; 
00159    };
00160 
00161    int parameters(int npar, double val, double ref) const
00162    { 
00163       int ret = 0;
00164       if ( refValue && (opts & cmpPars) ) 
00165       {
00166          ret = compareResult(val, refValue->pars[npar], tolPar*ref);
00167 //          printf("[TOL:%f]", ref);
00168       }
00169       return ret;
00170    };
00171 
00172    int chi2(double val) const
00173    { return ( refValue && (opts & cmpChi2) ) ? compareResult(val, refValue->chi, tolChi2) : 0; };
00174 
00175 public:
00176    // Compares two doubles with a given tolerence
00177    int compareResult(double v1, double v2, double tol = 0.01) const { 
00178       if (std::abs(v1-v2) > tol ) return 1; 
00179       return 0; 
00180    } 
00181 };
00182 
00183 // Create a variable range in a vector (to be passed to the histogram
00184 // constructor
00185 void FillVariableRange(Double_t v[], Int_t numberOfBins, Double_t minRange, Double_t maxRange)
00186 {
00187    Double_t minLimit = (maxRange-minRange)  / (numberOfBins*4);
00188    Double_t maxLimit = (maxRange-minRange)*4/ (numberOfBins);   
00189    v[0] = 0;
00190    for ( Int_t i = 1; i < numberOfBins + 1; ++i )
00191    {
00192       Double_t limit = rndm.Uniform(minLimit, maxLimit);
00193       v[i] = v[i-1] + limit;
00194    }
00195    
00196    Double_t k = (maxRange-minRange)/v[numberOfBins];
00197    for ( Int_t i = 0; i < numberOfBins + 1; ++i )
00198    {
00199       v[i] = v[i] * k + minRange;
00200    }
00201 }
00202 
00203 // Class defining the different algorithms. It contains the library,
00204 // the particular algorithm and the options which will be used to
00205 // invoke the algorithm. It also contains a CompareResult to indicate
00206 // what sort of checking has to be done once the algorithm has been
00207 // used.
00208 class algoType {
00209 public:
00210    const char* type;
00211    const char* algo;
00212    const char* opts;
00213    CompareResult cmpResult;
00214    
00215    algoType(): type(0), algo(0), opts(0), cmpResult(0) {}
00216 
00217    algoType(const char* s1, const char* s2, const char* s3, 
00218             CompareResult _cmpResult):
00219       type(s1), algo(s2), opts(s3), cmpResult(_cmpResult) {}
00220 };
00221 
00222 // Different vectors containing the list of algorithms to be used.
00223 vector<algoType> commonAlgos;
00224 vector<algoType> simplexAlgos;
00225 vector<algoType> specialAlgos;
00226 vector<algoType> noGraphAlgos;
00227 vector<algoType> noGraphErrorAlgos;
00228 vector<algoType> graphErrorAlgos;
00229 vector<algoType> histGaus2D;
00230 vector<algoType> linearAlgos;
00231 
00232 vector< vector<algoType> > listTH1DAlgos;
00233 vector< vector<algoType> > listAlgosTGraph;
00234 vector< vector<algoType> > listAlgosTGraphError;
00235 
00236 vector< vector<algoType> > listLinearAlgos;
00237 
00238 vector< vector<algoType> > listTH2DAlgos;
00239 vector< vector<algoType> > listAlgosTGraph2D;
00240 vector< vector<algoType> > listAlgosTGraph2DError;
00241 
00242 
00243 // Class defining the limits in the parameters of a function.
00244 class ParLimit {
00245 public:
00246    int npar;
00247    double min;
00248    double max;
00249    ParLimit(int _npar = 0, double _min = 0, double _max = 0): npar(_npar), min(_min), max(_max) {};
00250 };
00251 
00252 // Set the limits of a function given a vector of ParLimit
00253 void SetParsLimits(vector<ParLimit>& v, TF1* func)
00254 {
00255    for ( vector<ParLimit>::iterator it = v.begin();
00256          it !=  v.end(); ++it ) {
00257 //       printf("Setting parameters: %d, %f, %f\n", (*it)->npar, (*it)->min, (*it)->max);
00258       func->SetParLimits( it->npar, it->min, it->max);
00259    }
00260 }
00261 
00262 // Class that defined a fitting function. It will contain:
00263 //     The name of the function
00264 //     A pointer to the method that implements the function
00265 //     origPars is the original parameters used to fill the histogram/object
00266 //     fitPars parameters used right before fitting.
00267 //     parLimits limits of the parameters to be set before fitting
00268 class fitFunctions {
00269 public:
00270    const char* name;
00271    double (*func)(double*, double*);
00272    unsigned int npars;
00273    vector<double> origPars;
00274    vector<double> fitPars;
00275    vector<ParLimit> parLimits;
00276 
00277    fitFunctions() {}
00278 
00279    fitFunctions(const char* s1, double (*f)(double*, double*),
00280                 unsigned int n,
00281                 double* v1, double* v2,
00282                 vector<ParLimit>& limits):
00283       name(s1), func(f), npars(n), 
00284       origPars(npars), fitPars(npars), parLimits(limits.size())
00285    {
00286       copy(v1, v1 + npars, origPars.begin());
00287       copy(v2, v2 + npars, fitPars.begin());
00288       copy(limits.begin(), limits.end(), parLimits.begin());
00289    }
00290 };
00291 
00292 // List of functions that will be used in the test
00293 vector<fitFunctions> l1DFunctions;
00294 vector<fitFunctions> l2DFunctions;
00295 vector<fitFunctions> treeFunctions;
00296 vector<fitFunctions> l1DLinearFunctions;
00297 vector<fitFunctions> l2DLinearFunctions;
00298 
00299 // Gaus 1D implementation
00300 Double_t gaus1DImpl(Double_t* x, Double_t* p)
00301 {
00302    return p[2]*TMath::Gaus(x[0], p[0], p[1]);
00303 }
00304 
00305 // 1D Polynomial implementation
00306 Double_t poly1DImpl(Double_t *x, Double_t *p)
00307 {
00308    Double_t xx = x[0];
00309    return p[0]*xx*xx*xx+p[1]*xx*xx+p[2]*xx+p[3];
00310 }
00311 
00312 // 2D Polynomial implementation
00313 Double_t poly2DImpl(Double_t *x, Double_t *p)
00314 {
00315    Double_t xx = x[0];
00316    Double_t yy = x[1];
00317    return p[0]*xx*xx*xx+p[1]*xx*xx+p[2]*xx +
00318           p[3]*yy*yy*yy+p[4]*yy*yy+p[5]*yy +
00319           p[6];
00320 }
00321 
00322 // Gaus 2D Implementation
00323 Double_t gaus2DImpl(Double_t *x, Double_t *p)
00324 {
00325    return p[0]*TMath::Gaus(x[0], p[1], p[2])*TMath::Gaus(x[1], p[3], p[4]);
00326 }
00327 
00328 // Gaus 1D Normalized Implementation
00329 double gausNormal(Double_t* x, Double_t* p)
00330 {
00331    return p[2]*TMath::Gaus(x[0],p[0],p[1],1);
00332 }
00333 
00334 // Gaus 2D Normalized Implementation
00335 double gaus2dnormal(double *x, double *p) { 
00336   
00337    double mu_x = p[0];
00338    double sigma_x = p[1];
00339    double mu_y = p[2];
00340    double sigma_y = p[3];
00341    double rho = p[4]; 
00342    double u = (x[0] - mu_x)/ sigma_x ;
00343    double v = (x[1] - mu_y)/ sigma_y ;
00344    double c = 1 - rho*rho ;
00345    double result = (1 / (2 * TMath::Pi() * sigma_x * sigma_y * sqrt(c))) 
00346       * exp (-(u * u - 2 * rho * u * v + v * v ) / (2 * c));
00347    return result;
00348 }
00349 
00350 // N-dimensional Gaus
00351 double gausNd(double *x, double *p) { 
00352 
00353    double f = gaus2dnormal(x,p); 
00354    f *= ROOT::Math::normal_pdf(x[2],p[6],p[5]); 
00355    f *= ROOT::Math::normal_pdf(x[3],p[8],p[7]); 
00356    f *= ROOT::Math::normal_pdf(x[4],p[10],p[9]); 
00357    f *= ROOT::Math::normal_pdf(x[5],p[12],p[11]); 
00358 
00359    if (f <= 0) { 
00360       std::cout << "invalid f value " << f << " for x "; 
00361       for (int i = 0; i < 6; ++i) std::cout << "  " << x[i]; 
00362       std::cout << "\t P = "; 
00363       for (int i = 0; i < 11; ++i) std::cout << "  " << p[i]; 
00364       std::cout << "\n\n ";
00365       return 1.E-300;
00366    } 
00367    else if (f > 0) return f; 
00368    
00369    std::cout << " f is a nan " << f << std::endl; 
00370    for (int i = 0; i < 6; ++i) std::cout << "  " << x[i]; 
00371    std::cout << "\t P = "; 
00372    for (int i = 0; i < 11; ++i) std::cout << "  " << p[i]; 
00373    std::cout << "\n\n ";
00374    Error("gausNd","f is a nan");
00375    assert(1);
00376    return 0; 
00377 }
00378 
00379 const double minX = -5.;
00380 const double maxX = +5.;
00381 const double minY = -5.;
00382 const double maxY = +5.;
00383 const int nbinsX = 30;
00384 const int nbinsY = 30;
00385 
00386 // Options to indicate how the test has to be run
00387 enum testOpt {
00388    testOptPars  = 1,  // Check parameters
00389    testOptChi   = 2,  // Check Chi2 Test
00390    testOptErr   = 4,  // Show the errors
00391    testOptColor = 8,  // Show wrong output in color
00392    testOptDebug = 16, // Print out debug version
00393    testOptCheck = 32, // Make the checkings
00394 };
00395 
00396 // Default options that all tests will have
00397 int defaultOptions = testOptColor | testOptCheck; // | testOptDebug;
00398 
00399 // Object to manage the fitter depending on the optiones used
00400 template <typename T>
00401 class ObjectWrapper {
00402 public:
00403    T object;
00404    ObjectWrapper(T _obj): object(_obj) {};
00405    template <typename F>
00406    Int_t Fit(F func, const char* opts) 
00407    {
00408       if ( opts[0] == 'G' )
00409       {
00410          ROOT::Fit::BinData d; 
00411          ROOT::Fit::FillData(d,object,func);
00412 //         ROOT::Math::WrappedTF1 f(*func);
00413          ROOT::Math::WrappedMultiTF1 f(*func);
00414 //          f->SetDerivPrecision(10e-6);
00415          ROOT::Fit::Fitter fitter; 
00416 //          printf("Gradient? FIT?!?\n");
00417          fitter.Fit(d, f);
00418          const ROOT::Fit::FitResult & fitResult = fitter.Result(); 
00419          // one could set directly the fit result in TF1
00420          Int_t iret = fitResult.Status(); 
00421          if (!fitResult.IsEmpty() ) { 
00422             // set in f1 the result of the fit      
00423             func->SetChisquare( fitResult.Chi2() );
00424             func->SetNDF( fitResult.Ndf() );
00425             func->SetNumberFitPoints( d.Size() );
00426             
00427             func->SetParameters( &(fitResult.Parameters().front()) ); 
00428             if ( int( fitResult.Errors().size()) >= func->GetNpar() ) 
00429                func->SetParErrors( &(fitResult.Errors().front()) ); 
00430             
00431          }
00432          // Next line only for debug
00433 //          fitResult.Print(std::cout);
00434          return iret;
00435       } else {
00436 //          printf("Normal FIT\n");
00437          return object->Fit(func, opts);
00438       }
00439    };
00440    const char* GetName() { return object->GetName(); }
00441 };
00442 
00443 // Print the Name of the test
00444 int gTestIndex = 0; 
00445 template <typename T>
00446 void printTestName(T* object, TF1* func)
00447 {
00448    gTestIndex++;
00449    string str = "Test  ";
00450    if (gTestIndex < 10) str += " ";  // add an extra space
00451    str += ROOT::Math::Util::ToString(gTestIndex);
00452    str += ":  '";
00453    str += object->GetName();
00454    str += "' with '";
00455    str += func->GetName();
00456    str += "'...";
00457    while ( str.length() != 65 )
00458       str += '.';
00459    printf("%s", str.c_str());
00460    fflush(stdout);
00461 }
00462 
00463 // In debug mode, prints the title of the debug table.
00464 void printTitle(TF1* func)
00465 {
00466    printf("\nMin Type    | Min Algo    | OPT  | PARAMETERS             ");
00467    int n = func->GetNpar();
00468    for ( int i = 1; i < n; ++i ) {
00469       printf("                       ");
00470    }
00471    printf(" | CHI2TEST        | ERRORS \n");
00472    fflush(stdout);
00473 }
00474 
00475 // In debug mode, separator for the different tests
00476 void printSeparator()
00477 {
00478    fflush(stdout);
00479    printf("*********************************************************************"
00480           "********************************************************************\n");
00481    fflush(stdout);
00482 }
00483 
00484 // Sets the color of the ouput to red or normal
00485 void setColor(int red = 0)
00486 {
00487    char command[13];
00488    if ( red ) 
00489       sprintf(command, "%c[%d;%d;%dm", 0x1B, 1, 1 + 30, 8 + 40);
00490    else 
00491       sprintf(command, "%c[%d;%d;%dm", 0x1B, 0, 0 + 30, 8 + 40);
00492    printf("%s", command);
00493 }
00494 
00495 // Test a fit once it has been done:
00496 //     @str1 Name of the library used
00497 //     @str2 Name of the algorithm used
00498 //     @str3 Options used when fitting
00499 //     @func Fitted function
00500 //     @cmpResult Object to compare the result. It contains all the reference 
00501 //               objects as well as the method to compare. It will know whether something has to be tested or not.
00502 //     @opts Options of the test, to know what has to be printed or tested.
00503 int testFit(const char* str1, const char* str2, const char* str3,
00504                TF1* func, CompareResult const& cmpResult, int opts)
00505 {
00506    bool debug = opts & testOptDebug;
00507    // so far, status will just count the number of parameters wronly
00508    // calculated. There is no other test of the fitters
00509    int status = 0;
00510    int diff = 0;
00511 
00512    double chi2 = 0;
00513    if (  opts & testOptChi || opts & testOptCheck )
00514       chi2 = func->GetChisquare();
00515 
00516    fflush(stdout);
00517    if ( opts & testOptPars ) 
00518    {
00519       int n = func->GetNpar();
00520       double* values = func->GetParameters();
00521       if ( debug )
00522          printf("%-11s | %-11s | %-4s | ", str1, str2, str3);
00523       for ( int i = 0; i < n; ++i ) {
00524          if ( opts & testOptCheck )
00525             diff = cmpResult.parameters(i,
00526                                         values[i], 
00527                                         std::max(std::sqrt(chi2/func->GetNDF()),1.0)*func->GetParError(i));
00528          status += diff;
00529          if ( opts & testOptColor )
00530             setColor ( diff );
00531          if ( debug )
00532             printf("%10.6f +/-(%-6.3f) ", values[i], func->GetParError(i));
00533          fflush(stdout);
00534       }
00535       setColor(0);
00536    }
00537 
00538    if ( opts & testOptChi )
00539    {
00540       if ( debug )
00541          printf(" | chi2: %9.4f | ",  chi2);
00542    }
00543 
00544    if ( opts & testOptErr )
00545    {
00546       assert(TVirtualFitter::GetFitter() != 0 ); 
00547       TBackCompFitter* fitter = dynamic_cast<TBackCompFitter*>( TVirtualFitter::GetFitter() );
00548       assert(fitter != 0);
00549       const ROOT::Fit::FitResult& fitResult = fitter->GetFitResult();
00550       if ( debug )
00551          printf("err: ");
00552       int n = func->GetNpar();
00553       for ( int i = 0; i < n; ++i ) {
00554          if ( debug )
00555             printf("%c ", (fitResult.LowerError(i) == fitResult.UpperError(i))?'E':'D');
00556       }
00557       if ( debug )
00558          printf("| ");
00559    }
00560 
00561    if ( opts != 0 ) 
00562    {
00563       setColor(0);
00564       if ( debug )
00565          printf("\n");
00566    }
00567    fflush(stdout);
00568 
00569    return status;
00570 }
00571 
00572 // Makes all the tests combinations for:
00573 //      @object The object to be fitted
00574 //      @func The function to be used for the fitting
00575 //      @listAlgos All the algorithms that should be tested
00576 //      @fitFunction Parameters of the function used to fill the object
00577 template <typename T, typename F>
00578 int testFitters(T* object, F* func, vector< vector<algoType> >& listAlgos, fitFunctions const& fitFunction)
00579 {
00580    // counts the number of parameters wronly calculated
00581    int status = 0;
00582    int numberOfTests = 0;
00583    const double* origpars = &(fitFunction.origPars[0]);
00584    const double* fitpars = &(fitFunction.fitPars[0]);
00585 
00586    func->SetParameters(fitpars);
00587    
00588    printTestName(object, func);
00589    ROOT::Math::MinimizerOptions::SetDefaultMinimizer(commonAlgos[0].type, commonAlgos[0].algo);
00590    object->Fit(func, "Q0");
00591    if ( defaultOptions & testOptDebug ) printTitle(func);
00592    struct RefValue ref(origpars, func->GetChisquare());
00593    commonAlgos[0].cmpResult.setRefValue(&ref);
00594    int defMinOptions = testOptPars | testOptChi | testOptErr | defaultOptions;
00595    status += testFit(commonAlgos[0].type, commonAlgos[0].algo
00596                      , commonAlgos[0].opts, func
00597                      , commonAlgos[0].cmpResult, defMinOptions);
00598    numberOfTests += 1;
00599 
00600    if ( defaultOptions & testOptDebug )
00601    {
00602       printSeparator();
00603       func->SetParameters(origpars);
00604       status += testFit("Parameters", "Original", "", func, commonAlgos[0].cmpResult, testOptPars | testOptDebug);
00605       func->SetParameters(fitpars);
00606       status += testFit("Parameters", "Initial",  "", func, commonAlgos[0].cmpResult, testOptPars | testOptDebug);
00607       printSeparator();
00608    }
00609 
00610    for ( unsigned int j = 0; j < listAlgos.size(); ++j )
00611    {
00612       for ( unsigned int i = 0; i < listAlgos[j].size(); ++i ) 
00613       {
00614          int testFitOptions = testOptPars | testOptChi | testOptErr | defaultOptions;
00615          ROOT::Math::MinimizerOptions::SetDefaultMinimizer(listAlgos[j][i].type, listAlgos[j][i].algo);
00616          func->SetParameters(fitpars);
00617          fflush(stdout);
00618          object->Fit(func, listAlgos[j][i].opts);
00619          listAlgos[j][i].cmpResult.setRefValue(&ref);
00620          status += testFit(listAlgos[j][i].type, listAlgos[j][i].algo, listAlgos[j][i].opts
00621                            , func, listAlgos[j][i].cmpResult, testFitOptions);
00622          numberOfTests += 1;
00623          fflush(stdout);
00624       }
00625    }
00626    
00627    double percentageFailure = double( status * 100 ) / double( numberOfTests*func->GetNpar() );
00628 
00629    if ( defaultOptions & testOptDebug ) 
00630    {
00631       printSeparator();
00632       printf("Number of fails: %d Total Number of tests %d", status, numberOfTests);
00633       printf(" Percentage of failure: %f\n", percentageFailure );
00634    }
00635 
00636    // limit in the percentage of failure!
00637    return (percentageFailure < 4)?0:1;
00638 }
00639 
00640 // Test the diferent objects in 1D
00641 int test1DObjects(vector< vector<algoType> >& listH,
00642                   vector< vector<algoType> >& listG,
00643                   vector< vector<algoType> >& listGE,
00644                   vector<fitFunctions>& listOfFunctions)
00645 {
00646    // Counts how many tests failed.
00647    int globalStatus = 0;
00648    // To control if an individual test failed
00649    int status = 0;
00650 
00651    TF1* func = 0;
00652    TH1D* h1 = 0;
00653    TH1D* h2 = 0;
00654    THnSparse* s1 = 0;
00655    TGraph* g1 = 0;
00656    TGraphErrors* ge1 = 0;
00657    TCanvas *c0 = 0, *c1 = 0, *c2 = 0, *c3 = 0;
00658    for ( unsigned int j = 0; j < listOfFunctions.size(); ++j )
00659    {
00660       if ( func ) delete func;
00661       func = new TF1( listOfFunctions[j].name, listOfFunctions[j].func, minX, maxX, listOfFunctions[j].npars);
00662       func->SetParameters(&(listOfFunctions[j].origPars[0]));
00663       SetParsLimits(listOfFunctions[j].parLimits, func);
00664 
00665       // fill an histogram 
00666       if ( h1 ) delete h1;
00667       h1 = new TH1D("Histogram 1D","h1-title",nbinsX,minX,maxX);
00668       for ( int i = 0; i <= h1->GetNbinsX() + 1; ++i )
00669          h1->Fill( h1->GetBinCenter(i), rndm.Poisson( func->Eval( h1->GetBinCenter(i) ) ) );
00670 
00671       double v[nbinsX + 1];
00672       FillVariableRange(v, nbinsX, minX, maxX);
00673       if ( h2 ) delete h2;
00674       h2 = new TH1D("Histogram 1D Variable","h2-title",nbinsX, v);
00675       for ( int i = 0; i <= h2->GetNbinsX() + 1; ++i )
00676          h2->Fill( h2->GetBinCenter(i), rndm.Poisson( func->Eval( h2->GetBinCenter(i) ) ) );
00677 
00678       delete c0; c0 = new TCanvas("c0-1D", "Histogram1D Variable");
00679       if ( __DRAW__ ) h2->Draw();
00680       ObjectWrapper<TH1D*> owh2(h2);
00681       globalStatus += status = testFitters(&owh2, func, listH, listOfFunctions[j]);
00682       printf("%s\n", (status?"FAILED":"OK"));
00683 
00684       delete c1; c1 = new TCanvas("c1-1D", "Histogram1D");
00685       if ( __DRAW__ ) h1->Draw();
00686       ObjectWrapper<TH1D*> owh1(h1);
00687       globalStatus += status = testFitters(&owh1, func, listH, listOfFunctions[j]);
00688       printf("%s\n", (status?"FAILED":"OK"));
00689       
00690       delete g1; g1 = new TGraph(h1);
00691       g1->SetName("TGraph 1D");
00692       g1->SetTitle("TGraph 1D - title");
00693       if ( c2 ) delete c2;
00694       c2 = new TCanvas("c2-1D","TGraph");
00695       if ( __DRAW__ ) g1->Draw("AB*");
00696       ObjectWrapper<TGraph*> owg1(g1);
00697       globalStatus += status = testFitters(&owg1, func, listG, listOfFunctions[j]);
00698       printf("%s\n", (status?"FAILED":"OK"));
00699 
00700       delete ge1; ge1 = new TGraphErrors(h1);
00701       ge1->SetName("TGraphErrors 1D");
00702       ge1->SetTitle("TGraphErrors 1D - title");
00703       if ( c3 ) delete c3;
00704       c3 = new TCanvas("c3-1D","TGraphError");
00705       if ( __DRAW__ ) ge1->Draw("AB*");
00706       ObjectWrapper<TGraphErrors*> owge1(ge1);
00707       globalStatus += status = testFitters(&owge1, func, listGE, listOfFunctions[j]);
00708       printf("%s\n", (status?"FAILED":"OK"));
00709 
00710       delete s1; s1 = THnSparse::CreateSparse("THnSparse 1D", "THnSparse 1D - title", h1);
00711       ObjectWrapper<THnSparse*> ows1(s1);
00712       globalStatus += status = testFitters(&ows1, func, listH, listOfFunctions[j]);
00713       printf("%s\n", (status?"FAILED":"OK"));
00714    }
00715 
00716    if ( ! __DRAW__ )
00717    {
00718       delete func;
00719       delete h1;
00720       delete h2;
00721       delete g1;
00722       delete ge1;
00723       delete c0;
00724       delete c1;
00725       delete c2;
00726       delete c3;
00727    }
00728 
00729    return globalStatus;
00730 }
00731 
00732 // Test the different objects in 2S
00733 int test2DObjects(vector< vector<algoType> >& listH,
00734                   vector< vector<algoType> >& listG,
00735                   vector< vector<algoType> >& listGE,
00736                   vector<fitFunctions>& listOfFunctions)
00737 {
00738    // Counts how many tests failed.
00739    int globalStatus = 0;
00740    // To control if an individual test failed
00741    int status = 0;
00742 
00743    TF2* func = 0;
00744    TH2D* h1 = 0;
00745    TH2D* h2 = 0;
00746    THnSparse* s1 = 0;
00747    TGraph2D* g1 = 0;
00748    TGraph2DErrors* ge1 = 0;
00749    TCanvas *c0 = 0, *c1 = 0, *c2 = 0, *c3 = 0;
00750    for ( unsigned int h = 0; h < listOfFunctions.size(); ++h )
00751    {
00752       if ( func ) delete func;
00753       func = new TF2( listOfFunctions[h].name, listOfFunctions[h].func, minX, maxX, minY, maxY, listOfFunctions[h].npars);
00754       func->SetParameters(&(listOfFunctions[h].origPars[0]));
00755       SetParsLimits(listOfFunctions[h].parLimits, func);
00756       
00757       // fill an histogram 
00758       if ( h1 ) delete h1;
00759       h1 = new TH2D("Histogram 2D","h1-title",nbinsX,minX,maxX,nbinsY,minY,maxY);
00760       if ( ge1 ) delete ge1;
00761       ge1 = new TGraph2DErrors((h1->GetNbinsX() + 1) * (h1->GetNbinsY() + 1));
00762       ge1->SetName("Graph2D with Errors");
00763       ge1->SetTitle("Graph2D with Errors");
00764       unsigned int counter = 0;
00765       for ( int i = 0; i <= h1->GetNbinsX() + 1; ++i )
00766          for ( int j = 0; j <= h1->GetNbinsY() + 1; ++j ) 
00767          {
00768             double xc = h1->GetXaxis()->GetBinCenter(i);
00769             double yc = h1->GetYaxis()->GetBinCenter(j);
00770             double content = rndm.Poisson( func->Eval( xc, yc ) );
00771             h1->Fill( xc, yc, content );
00772             ge1->SetPoint(counter, xc, yc, content);
00773             ge1->SetPointError(counter, 
00774                                h1->GetXaxis()->GetBinWidth(i) / 2,
00775                                h1->GetYaxis()->GetBinWidth(j) / 2,
00776                                h1->GetBinError(i,j));
00777             counter += 1;
00778          }
00779 
00780       if ( h2 ) delete h2;
00781       double x[nbinsX + 1];
00782       FillVariableRange(x, nbinsX, minX, maxX);
00783       double y[nbinsY + 1];
00784       FillVariableRange(y, nbinsY, minY, maxY);
00785       h2 = new TH2D("Histogram 2D Variable","h2-title",nbinsX, x, nbinsY, y);
00786       for ( int i = 0; i <= h2->GetNbinsX() + 1; ++i )
00787          for ( int j = 0; j <= h2->GetNbinsY() + 1; ++j ) 
00788          {
00789             double xc = h2->GetXaxis()->GetBinCenter(i);
00790             double yc = h2->GetYaxis()->GetBinCenter(j);
00791             double content = rndm.Poisson( func->Eval( xc, yc ) );
00792             h2->Fill( xc, yc, content );
00793          }
00794 
00795       if ( c0 ) delete c0;
00796       c0 = new TCanvas("c0-2D", "Histogram2D Variable");
00797       if ( __DRAW__ ) h2->Draw();
00798       ObjectWrapper<TH2D*> owh2(h2);
00799       globalStatus += status = testFitters(&owh2, func, listH, listOfFunctions[h]);
00800       printf("%s\n", (status?"FAILED":"OK"));
00801 
00802       if ( c1 ) delete c1;
00803       c1 = new TCanvas("c1-2D", "Histogram2D");
00804       if ( __DRAW__ ) h1->Draw();
00805       ObjectWrapper<TH2D*> owh1(h1);
00806       globalStatus += status = testFitters(&owh1, func, listH, listOfFunctions[h]);
00807       printf("%s\n", (status?"FAILED":"OK"));
00808 
00809       if ( g1 ) delete g1;
00810       g1 = new TGraph2D(h1);
00811       g1->SetName("TGraph 2D");
00812       g1->SetTitle("TGraph 2D - title");
00813 
00814       if ( c2 ) delete c2;
00815       c2 = new TCanvas("c2-2D","TGraph");
00816       if ( __DRAW__ ) g1->Draw("AB*");
00817       ObjectWrapper<TGraph2D*> owg1(g1);
00818       globalStatus += status = testFitters(&owg1, func, listG, listOfFunctions[h]);
00819       printf("%s\n", (status?"FAILED":"OK"));
00820 
00821       
00822       ge1->SetName("TGraphErrors 2DGE");
00823       ge1->SetTitle("TGraphErrors 2DGE - title");
00824       if ( c3 ) delete c3;
00825       c3 = new TCanvas("c3-2DGE","TGraphError");
00826       if ( __DRAW__ ) ge1->Draw("AB*");
00827       ObjectWrapper<TGraph2DErrors*> owge1(ge1);
00828       globalStatus += status = testFitters(&owge1, func, listGE, listOfFunctions[h]);
00829       printf("%s\n", (status?"FAILED":"OK"));
00830 
00831       delete s1; s1 = THnSparse::CreateSparse("THnSparse 2D", "THnSparse 2D - title", h1);
00832       ObjectWrapper<THnSparse*> ows1(s1);
00833       globalStatus += status = testFitters(&ows1, func, listH, listOfFunctions[h]);
00834       printf("%s\n", (status?"FAILED":"OK"));
00835    }
00836 
00837    if ( ! __DRAW__ )
00838    {
00839       delete func;
00840       delete h1;
00841       delete h2;
00842       delete g1;
00843       delete ge1;
00844       delete c0;
00845       delete c1;
00846       delete c2;
00847       delete c3;
00848    }
00849 
00850    return globalStatus;
00851 }
00852 
00853 // Make a wrapper for the TTree, as the interface for fitting
00854 // differs. This way, the same algorithms (testFit and testFitters)
00855 // can be used for all the objects.
00856 class TreeWrapper {
00857 public:
00858 
00859    const char* vars;
00860    const char* cuts;
00861    TTree *tree;
00862 
00863    void set(TTree* t, const char* v, const char* c)
00864    {
00865       tree = t;
00866       vars = v;
00867       cuts = c;
00868    }
00869 
00870    const char* GetName() const {
00871       return tree->GetName();
00872    }
00873 
00874    Int_t Fit(TF1* f1, Option_t* option = "")
00875    {
00876       return tree->UnbinnedFit(f1->GetName(), vars, cuts, option);
00877    }
00878 };
00879 
00880 // Test the fittig algorithms for a TTree
00881 int testUnBinnedFit(int n = 10000)
00882 {
00883    // Counts how many tests failed.
00884    int globalStatus = 0;
00885    // To control if an individual test failed
00886    int status = 0;
00887 
00888    double origPars[13] = {1,2,3,0.5, 0.5, 0, 3, 0, 4, 0, 5, 1, 10 };
00889 //   double fitPars[13] =  {1,1,1,  1, 0.1, 0, 2, 0, 3, 0, 4, 0,  9 };
00890 
00891    TF2 * func = new TF2("gaus2Dn",gaus2dnormal,-10,-10,-10,10,5);
00892    func->SetParameters(origPars);
00893 
00894    TUnuranMultiContDist dist(func);
00895    TUnuran unr(&rndm); 
00896 
00897    // sampling with vnrou methods
00898    if (! unr.Init(dist,"vnrou")) {
00899          std::cerr << "error in init unuran " << std::endl; return -1;
00900    }
00901 
00902    TTree * tree =  new  TTree("tree","2 var gaus tree"); 
00903    double x,y,z,u,v,w;
00904    tree->Branch("x",&x,"x/D");
00905    tree->Branch("y",&y,"y/D");
00906    tree->Branch("z",&z,"z/D");
00907    tree->Branch("u",&u,"u/D");
00908    tree->Branch("v",&v,"v/D");
00909    tree->Branch("w",&w,"w/D");
00910    double xx[2];
00911    for (Int_t i=0;i<n;i++) {
00912       unr.SampleMulti(xx);
00913       x = xx[0];
00914       y = xx[1];
00915       z = rndm.Gaus(origPars[5],origPars[6]);
00916       u = rndm.Gaus(origPars[7],origPars[8]);
00917       v = rndm.Gaus(origPars[9],origPars[10]);
00918       w = rndm.Gaus(origPars[11],origPars[12]);
00919  
00920       tree->Fill();
00921       
00922    }
00923 
00924    delete func;
00925 
00926    vector< vector<algoType> > listAlgos(2);
00927    listAlgos[0] = commonAlgos;
00928    listAlgos[1] = simplexAlgos;
00929 
00930    TreeWrapper tw;
00931 
00932    TF1 * f1 = new TF1(treeFunctions[0].name,treeFunctions[0].func,minX,maxY,treeFunctions[0].npars);   
00933    f1->SetParameters( &(treeFunctions[0].fitPars[0]) ); 
00934    f1->FixParameter(2,1);
00935    tw.set(tree, "x", "");
00936    globalStatus += status = testFitters(&tw, f1, listAlgos, treeFunctions[0]);
00937    printf("%s\n", (status?"FAILED":"OK"));
00938 
00939    vector<algoType> noCompareInTree;
00940    // exclude Simplex in tree
00941    //noCompareInTree.push_back(algoType( "Minuit2",     "Simplex",     "Q0", CompareResult(0)));
00942 
00943    vector< vector<algoType> > listAlgosND(2);
00944    listAlgosND[0] = commonAlgos;
00945    listAlgosND[1] = noCompareInTree;
00946 
00947    TF2 * f2 = new TF2(treeFunctions[1].name,treeFunctions[1].func,minX,maxX,minY,maxY,treeFunctions[1].npars);   
00948    f2->SetParameters( &(treeFunctions[1].fitPars[0]) ); 
00949    tw.set(tree, "x:y", "");
00950    globalStatus += status = testFitters(&tw, f2, listAlgosND, treeFunctions[1]);
00951    printf("%s\n", (status?"FAILED":"OK"));
00952 
00953    TF1 * f4 = new TF1("gausND",gausNd,0,1,13);   
00954    f4->SetParameters(&(treeFunctions[2].fitPars[0]));
00955    tw.set(tree, "x:y:z:u:v:w", "");
00956    globalStatus += status = testFitters(&tw, f4, listAlgosND, treeFunctions[2]);
00957    printf("%s\n", (status?"FAILED":"OK"));
00958 
00959    delete tree;
00960    delete f1;
00961    delete f2;
00962    delete f4;
00963 
00964    return globalStatus;
00965 }
00966 
00967 // Initialize the data for the tests: List of different algorithms and
00968 // fitting functions.
00969 void init_structures()
00970 {
00971    commonAlgos.push_back( algoType( "Minuit",      "Migrad",      "Q0", CompareResult())  );
00972    commonAlgos.push_back( algoType( "Minuit",      "Minimize",    "Q0", CompareResult())  );
00973    commonAlgos.push_back( algoType( "Minuit",      "Scan",        "Q0", CompareResult(0)) );
00974    commonAlgos.push_back( algoType( "Minuit",      "Seek",        "Q0", CompareResult())  );
00975    commonAlgos.push_back( algoType( "Minuit2",     "Migrad",      "Q0", CompareResult())  );
00976    commonAlgos.push_back( algoType( "Minuit2",     "Minimize",    "Q0", CompareResult())  );
00977    commonAlgos.push_back( algoType( "Minuit2",     "Scan",        "Q0", CompareResult(0)) );
00978    commonAlgos.push_back( algoType( "Minuit2",     "Fumili2",     "Q0", CompareResult())  );
00979 #ifdef R__HAS_MATHMORE
00980    commonAlgos.push_back( algoType( "GSLMultiMin", "conjugatefr", "Q0", CompareResult()) );
00981    commonAlgos.push_back( algoType( "GSLMultiMin", "conjugatepr", "Q0", CompareResult()) );
00982    commonAlgos.push_back( algoType( "GSLMultiMin", "bfgs2",       "Q0", CompareResult()) );
00983    commonAlgos.push_back( algoType( "GSLSimAn",    "",            "Q0", CompareResult()) );
00984 #endif
00985 
00986 // simplex
00987    simplexAlgos.push_back( algoType( "Minuit",      "Simplex",     "Q0", CompareResult()) );
00988    simplexAlgos.push_back( algoType( "Minuit2",     "Simplex",     "Q0", CompareResult())  );
00989 
00990    specialAlgos.push_back( algoType( "Minuit",      "Migrad",      "QE0", CompareResult()) );
00991    specialAlgos.push_back( algoType( "Minuit",      "Migrad",      "QW0", CompareResult()) );
00992 
00993    noGraphAlgos.push_back( algoType( "Minuit",      "Migrad",      "Q0I",  CompareResult()) );
00994    noGraphAlgos.push_back( algoType( "Minuit",      "Migrad",      "QL0",  CompareResult()) );
00995    noGraphAlgos.push_back( algoType( "Minuit",      "Migrad",      "QLI0", CompareResult()) );
00996 
00997 // Gradient algorithms
00998 // No Minuit algorithms to use with the 'G' options until some stuff is fixed.
00999    noGraphAlgos.push_back( algoType( "Minuit",      "Migrad",      "GQ0", CompareResult()) );
01000 //    noGraphAlgos.push_back( algoType( "Minuit",      "Minimize",    "GQ0", CompareResult()) );
01001    noGraphAlgos.push_back( algoType( "Minuit2",     "Migrad",      "GQ0", CompareResult()) );
01002    noGraphAlgos.push_back( algoType( "Minuit2",     "Minimize",    "GQ0", CompareResult()) );
01003    noGraphAlgos.push_back( algoType( "Fumili",      "Fumili",      "GQ0", CompareResult()) );
01004    noGraphAlgos.push_back( algoType( "Minuit2",     "Fumili",      "GQ0", CompareResult()) );
01005 //    noGraphAlgos.push_back( algoType( "Minuit",      "Migrad",      "GQE0", CompareResult()) );
01006     noGraphAlgos.push_back( algoType( "Minuit",      "Migrad",      "GQL0", CompareResult()) );
01007 
01008    noGraphErrorAlgos.push_back( algoType( "Fumili",      "Fumili",      "Q0", CompareResult()) );
01009 #ifdef R__HAS_MATHMORE
01010    noGraphErrorAlgos.push_back( algoType( "GSLMultiFit", "",            "Q0", CompareResult()) ); // Not in TGraphError
01011 #endif
01012 
01013    // Same as TH1D (but different comparision scheme!): commonAlgos, 
01014    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "Q0",   CompareResult(cmpPars,6)) );
01015    histGaus2D.push_back( algoType( "Minuit",      "Minimize",    "Q0",   CompareResult(cmpPars,6)) );
01016    histGaus2D.push_back( algoType( "Minuit",      "Scan",        "Q0",   CompareResult(0))         );
01017    histGaus2D.push_back( algoType( "Minuit",      "Seek",        "Q0",   CompareResult(cmpPars,6)) );
01018    histGaus2D.push_back( algoType( "Minuit2",     "Migrad",      "Q0",   CompareResult(cmpPars,6)) );
01019    histGaus2D.push_back( algoType( "Minuit2",     "Minimize",    "Q0",   CompareResult(cmpPars,6)) );
01020    histGaus2D.push_back( algoType( "Minuit2",     "Scan",        "Q0",   CompareResult(0))         );
01021    histGaus2D.push_back( algoType( "Minuit2",     "Fumili2",     "Q0",   CompareResult(cmpPars,6)) );
01022 #ifdef R__HAS_MATHMORE
01023    histGaus2D.push_back( algoType( "GSLMultiMin", "conjugatefr", "Q0", CompareResult(cmpPars,6)) );
01024    histGaus2D.push_back( algoType( "GSLMultiMin", "conjugatepr", "Q0", CompareResult(cmpPars,6)) );
01025    histGaus2D.push_back( algoType( "GSLMultiMin", "bfgs2",       "Q0", CompareResult(cmpPars,6)) );
01026    histGaus2D.push_back( algoType( "GSLSimAn",    "",            "Q0", CompareResult(cmpPars,6)) );
01027 #endif   // treeFail
01028    histGaus2D.push_back( algoType( "Minuit",      "Simplex",     "Q0",   CompareResult(cmpPars,6)) );
01029    // minuit2 simplex fails in 2d 
01030    //histGaus2D.push_back( algoType( "Minuit2",     "Simplex",     "Q0",   CompareResult(cmpPars,6)) );
01031    // special algos
01032    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "QE0",  CompareResult(cmpPars,6)) );
01033    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "QW0",  CompareResult())          );
01034    // noGraphAlgos
01035    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "Q0I",  CompareResult(cmpPars,6)) );
01036    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "QL0",  CompareResult())          );
01037    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "QLI0", CompareResult())          );
01038 
01039 // Gradient algorithms
01040    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "GQ0", CompareResult()) );
01041    histGaus2D.push_back( algoType( "Minuit",      "Minimize",    "GQ0", CompareResult()) );
01042    histGaus2D.push_back( algoType( "Minuit2",     "Migrad",      "GQ0", CompareResult()) );
01043    histGaus2D.push_back( algoType( "Minuit2",     "Minimize",    "GQ0", CompareResult()) );
01044    histGaus2D.push_back( algoType( "Fumili",      "Fumili",      "GQ0", CompareResult()) );
01045    histGaus2D.push_back( algoType( "Minuit2",     "Fumili",      "GQ0", CompareResult()) );
01046 //    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "GQE0", CompareResult()) );
01047    histGaus2D.push_back( algoType( "Minuit",      "Migrad",      "GQL0", CompareResult()) );
01048 
01049    // noGraphErrorAlgos
01050    histGaus2D.push_back( algoType( "Fumili",      "Fumili",      "Q0",   CompareResult(cmpPars,6)) );
01051 #ifdef R__HAS_MATHMORE
01052    histGaus2D.push_back( algoType( "GSLMultiFit", "",            "Q0",   CompareResult(cmpPars,6)) );
01053 #endif
01054 
01055    graphErrorAlgos.push_back( algoType( "Minuit",      "Migrad",      "Q0EX0", CompareResult()) );
01056    graphErrorAlgos.push_back( algoType( "Minuit2",      "Migrad",      "Q0EX0", CompareResult()) );
01057 
01058 
01059    // For testing the liear fitter we can force the use by setting Linear the default minimizer and use
01060    // teh G option. In this case the fit is linearized using the gradient as the linear components
01061    // Option "G" has not to be set as first option character to avoid using Fitter class in 
01062    // the test program 
01063    // Use option "X" to force Chi2 calculations
01064    linearAlgos.push_back( algoType( "Linear",      "",            "Q0XG", CompareResult()) );
01065    listLinearAlgos.push_back( linearAlgos );
01066 
01067    listTH1DAlgos.push_back( commonAlgos );
01068    listTH1DAlgos.push_back( simplexAlgos );
01069    listTH1DAlgos.push_back( specialAlgos );
01070    listTH1DAlgos.push_back( noGraphAlgos );
01071    listTH1DAlgos.push_back( noGraphErrorAlgos );
01072 
01073    listAlgosTGraph.push_back( commonAlgos );
01074    listAlgosTGraph.push_back( simplexAlgos );
01075    listAlgosTGraph.push_back( specialAlgos );
01076    listAlgosTGraph.push_back( noGraphErrorAlgos );
01077 
01078    listAlgosTGraphError.push_back( commonAlgos );
01079    listAlgosTGraphError.push_back( simplexAlgos );
01080    listAlgosTGraphError.push_back( specialAlgos );
01081    listAlgosTGraphError.push_back( graphErrorAlgos );
01082 
01083    listTH2DAlgos.push_back( histGaus2D );
01084    
01085    listAlgosTGraph2D.push_back( commonAlgos );
01086    listAlgosTGraph2D.push_back( specialAlgos );
01087    listAlgosTGraph2D.push_back( noGraphErrorAlgos );
01088 
01089    listAlgosTGraph2DError.push_back( commonAlgos );
01090    listAlgosTGraph2DError.push_back( specialAlgos );
01091    listAlgosTGraph2DError.push_back( graphErrorAlgos );
01092 
01093    vector<ParLimit> emptyLimits(0);
01094 
01095    double gausOrig[] = {  0.,  3., 200.};
01096    double gausFit[] =  {0.5, 3.7,  250.};
01097    vector<ParLimit> gaus1DLimits;
01098    gaus1DLimits.push_back( ParLimit(1, 0, 5) );
01099    l1DFunctions.push_back( fitFunctions("GAUS",       gaus1DImpl, 3, gausOrig,  gausFit, gaus1DLimits) );
01100    double poly1DOrig[] = { 2, 3, 4, 200};
01101    double poly1DFit[] = { 6.4, -2.3, 15.4, 210.5};
01102    l1DFunctions.push_back( fitFunctions("Polynomial", poly1DImpl, 4, poly1DOrig, poly1DFit, emptyLimits) );
01103 
01104    // range os -5,5
01105    double gaus2DOrig[] = { 500., +.5, 2.7, -.5, 3.0 };
01106    double gaus2DFit[] = { 510., .0, 1.8, -1.0, 1.6};
01107    l2DFunctions.push_back( fitFunctions("gaus2D", gaus2DImpl, 5, gaus2DOrig, gaus2DFit, emptyLimits) );
01108 
01109    double gausnOrig[3] = {1,2,1};
01110    double treeOrig[13] = {1,2,3,0.5, 0.5, 0, 3, 0, 4, 0, 5, 1, 10 };
01111    double treeFit[13]  = {1,1,1,  1, 0.1, 0, 2, 0, 3, 0, 4, 0,  9 };
01112    treeFunctions.push_back( fitFunctions("gausn", gausNormal, 3, gausnOrig, treeFit, emptyLimits ));
01113    treeFunctions.push_back( fitFunctions("gaus2Dn", gaus2dnormal, 5, treeOrig, treeFit, emptyLimits));
01114    treeFunctions.push_back( fitFunctions("gausND", gausNd, 13, treeOrig, treeFit, emptyLimits));
01115 
01116    l1DLinearFunctions.push_back( fitFunctions("Polynomial", poly1DImpl, 4, poly1DOrig, poly1DFit, emptyLimits) );
01117 
01118    double poly2DOrig[] = { 2, 3, 4, 5, 6, 7, 200, };
01119    double poly2DFit[] = { 6.4, -2.3, 15.4, 3, 10, -3, 210.5};
01120    l2DLinearFunctions.push_back( fitFunctions("Poly2D", poly2DImpl, 7, poly2DOrig, poly2DFit, emptyLimits) );
01121 }
01122 
01123 int stressFit() 
01124 { 
01125    rndm.SetSeed(10);
01126 
01127    init_structures();
01128 
01129    int iret = 0; 
01130 
01131    TBenchmark bm;
01132    bm.Start("stressHistoFit");
01133 
01134    cout << "****************************************************************************" <<endl;
01135    cout << "*  Starting  stress  H I S T O F I T                                       *" <<endl;
01136    cout << "****************************************************************************" <<endl;
01137 
01138    std::cout << "\nTest 1D and 2D objects\n\n";
01139    iret += test1DObjects(listTH1DAlgos, listAlgosTGraph, listAlgosTGraphError, l1DFunctions);
01140    iret += test2DObjects(listTH2DAlgos, listAlgosTGraph2D, listAlgosTGraph2DError, l2DFunctions);
01141    std::cout << "\nTest Linear fits\n\n";
01142    iret += test1DObjects(listLinearAlgos, listLinearAlgos, listLinearAlgos, l1DLinearFunctions);
01143    iret += test2DObjects(listLinearAlgos, listLinearAlgos, listLinearAlgos, l2DLinearFunctions);
01144    //defaultOptions = testOptColor | testOptCheck;
01145    // tree test
01146    std::cout << "\nTest unbinned fits\n\n";
01147    iret += testUnBinnedFit(2000);  // reduce statistics
01148    
01149    bm.Stop("stressHistoFit");
01150    std::cout <<"\n****************************************************************************\n";
01151    bm.Print("stressHistoFit");
01152    const double reftime = 124; // ref time on  pcbrun4
01153    double rootmarks = 800 * reftime / bm.GetCpuTime("stressHistoFit");
01154    std::cout << " ROOTMARKS = " << rootmarks << " ROOT version: " << gROOT->GetVersion() << "\t" 
01155              << gROOT->GetSvnBranch() << "@" << gROOT->GetSvnRevision() << std::endl;
01156    std::cout <<"****************************************************************************\n";
01157 
01158    return iret; 
01159 }
01160    
01161 int main(int argc, char** argv)
01162 {
01163    TApplication* theApp = 0;
01164 
01165    if ( __DRAW__ )
01166       theApp = new TApplication("App",&argc,argv);
01167 
01168    int ret = stressFit();
01169 
01170    if ( __DRAW__ ) {
01171       theApp->Run();
01172       delete theApp;
01173       theApp = 0;
01174    }
01175 
01176    return ret;
01177 }

Generated on Tue Jul 5 15:15:16 2011 for ROOT_528-00b_version by  doxygen 1.5.1