00001 #include "TH1.h"
00002 #include "TF1.h"
00003 #include "Fit/BinData.h"
00004 #include "Fit/Chi2FCN.h"
00005
00006 #include "Math/WrappedMultiTF1.h"
00007 #include "Math/Minimizer.h"
00008 #include "Math/GeneticMinimizer.h"
00009 #include "Math/Factory.h"
00010 #include "HFitInterface.h"
00011
00012 #include "TMath.h"
00013
00014 #include "TApplication.h"
00015 #include "TLegend.h"
00016 #include "TCanvas.h"
00017 #include "TStyle.h"
00018
00019
00020
00021
00022 Double_t background(Double_t *x, Double_t *par) {
00023 return par[0] + par[1]*x[0];
00024 }
00025
00026
00027 Double_t gaussianPeak(Double_t *x, Double_t *par) {
00028 return par[0]*TMath::Gaus(x[0],par[1], par[2]);
00029 }
00030
00031
00032 Double_t fitFunction(Double_t *x, Double_t *par) {
00033 return background(x,par) + gaussianPeak(x,&par[2]) + gaussianPeak(x,&par[5]);
00034 }
00035
00036
00037 double par0[8] = { 1, 0.05, 10 , 2, 0.5 , 10 , 7 , 1. };
00038 const int ndata = 10000;
00039 const double gAbsTolerance = 0.1;
00040 const int gVerbose = 0;
00041
00042 using std::cout;
00043 using std::endl;
00044
00045 int GAMinimize(ROOT::Math::IMultiGenFunction& chi2Func, double& xm1, double& xm2)
00046 {
00047
00048 ROOT::Math::GeneticMinimizer* min = new ROOT::Math::GeneticMinimizer();
00049 if (min == 0) {
00050 cout << "Error creating minimizer " << endl;
00051 return -1;
00052 }
00053
00054
00055 min->SetMaxFunctionCalls(1000000);
00056 min->SetMaxIterations(100000);
00057 min->SetTolerance(gAbsTolerance);
00058 min->SetPrintLevel(gVerbose);
00059 min->SetFunction(chi2Func);
00060 min->SetParameters(100, 300);
00061
00062
00063
00064 double x0[8];
00065 std::copy(par0, par0 + 8, x0);
00066 x0[3] = xm1;
00067 x0[6] = xm2;
00068
00069 for (unsigned int i = 0; i < chi2Func.NDim(); ++i) {
00070 #ifdef DEBUG
00071 cout << "set variable " << i << " to value " << x0[i] << endl;
00072 #endif
00073 if ( i == 3 || i == 6 )
00074 min->SetLimitedVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], 0.1,2,8);
00075 else
00076 min->SetLimitedVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], 0.1,x0[i]-2,x0[i]+2);
00077 }
00078
00079
00080
00081 if ( !min->Minimize() ) return 1;
00082 min->MinValue();
00083
00084
00085 cout << "Min values by GeneticMinimizer: " << min->X()[3] << " " << min->X()[6] << endl;
00086 xm1 = min->X()[3];
00087 xm2 = min->X()[6];
00088
00089 return 0;
00090 }
00091
00092
00093 const double* Min2Minimize(ROOT::Math::IMultiGenFunction& chi2Func, double xm1, double xm2) {
00094
00095
00096 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad");
00097 if (min == 0) {
00098 cout << "Error creating minimizer " << endl;
00099 exit(-1);
00100 }
00101
00102
00103 min->SetMaxFunctionCalls(1000000);
00104 min->SetMaxIterations(100000);
00105 min->SetTolerance(gAbsTolerance);
00106 min->SetPrintLevel(gVerbose);
00107 min->SetFunction(chi2Func);
00108
00109
00110 double x0[8];
00111 std::copy(par0, par0 + 8, x0);
00112 x0[3] = xm1;
00113 x0[6] = xm2;
00114
00115 for (unsigned int i = 0; i < chi2Func.NDim(); ++i) {
00116 #ifdef DEBUG
00117 cout << "set variable " << i << " to value " << x0[i] << endl;
00118 #endif
00119 min->SetVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], 0.1);
00120 }
00121
00122
00123 if ( !min->Minimize() ) exit(1);
00124 double minval = min->MinValue();
00125
00126
00127 cout << "--------------------------------------" << endl;
00128 cout << "Minuit2Minimizer(" << xm1 << "," << xm2 << ")" << endl;
00129 cout << "chi2 min value " << minval << endl;
00130 cout << " x minimum values " << min->X()[3] << " " << min->X()[6] << endl;
00131 for (unsigned int i = 0; i < chi2Func.NDim(); ++i)
00132 cout << min->X()[i] << " ";
00133 cout << endl;
00134
00135 return min->X();
00136 }
00137
00138 int GAMinTutorial()
00139 {
00140 double x1=0, x2=0;
00141
00142
00143
00144 TF1 * fitFunc = new TF1("fitFunc",fitFunction,0,10,8);
00145 fitFunc->SetParameters(par0);
00146
00147
00148 TH1D * h1 = new TH1D("h1","",100, 0, 10);
00149 for (int i = 0; i < ndata; ++i) {
00150 h1->Fill(fitFunc->GetRandom() );
00151 }
00152
00153 h1->Draw();
00154 gPad->SetFillColor(kYellow-10);
00155 h1->SetFillColor(kYellow-5);
00156 gStyle->SetOptStat(0);
00157
00158
00159 ROOT::Fit::BinData d;
00160 ROOT::Fit::FillData(d,h1);
00161 ROOT::Math::WrappedMultiTF1 f(*fitFunc);
00162
00163
00164 ROOT::Fit::Chi2FCN<ROOT::Math::IMultiGenFunction> chi2Func(d,f);
00165
00166
00167 const double* xmin1 = Min2Minimize(chi2Func, 0, 0);
00168 fitFunc->SetParameters(&xmin1[0]);
00169 fitFunc->SetLineColor(kBlue+3);
00170 TF1 * fitFunc0 = new TF1;
00171 fitFunc->Copy(*fitFunc0);
00172 fitFunc0->Draw("same");
00173
00174
00175 GAMinimize(chi2Func, x1,x2);
00176
00177
00178 const double* xmin2 = Min2Minimize(chi2Func, x1, x2);
00179 fitFunc->SetParameters(&xmin2[0]);
00180 fitFunc->SetLineColor(kRed+3);
00181 fitFunc->DrawCopy("same");
00182
00183 TLegend* legend = new TLegend(0.61,0.72,0.86,0.86);
00184 legend->AddEntry(h1, "Histogram Data","F");
00185 legend->AddEntry(fitFunc0, "Minuit only minimization");
00186 legend->AddEntry(fitFunc, "Minuit+Genetic minimization");
00187 legend->Draw();
00188
00189 return 0;
00190
00191
00192 }
00193
00194 int main(int argc, char **argv)
00195 {
00196 TApplication* theApp = new TApplication("App",&argc,argv);
00197
00198 int status = GAMinTutorial();
00199
00200 theApp->Run();
00201
00202 delete theApp;
00203 theApp = 0;
00204
00205 return status;
00206 }