Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
fit2dHist.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_fit
3/// \notebook
4///
5/// Example to fit two histograms at the same time via the Fitter class
6///
7/// To execute this tutorial, you can do:
8///
9/// ~~~{.cpp}
10/// root > .x fit2dHist.C (executing via cling, slow)
11/// ~~~
12///
13/// or
14/// ~~~{.cpp}
15/// root > .x fit2dHist.C+ (executing via ACLIC , fast, with Minuit)
16/// root > .x fit2dHist.C+(2) (executing via ACLIC , fast, with Minuit2)
17/// ~~~
18///
19/// or using the option to fit independently the 2 histos
20/// ~~~{.cpp}
21/// root > .x fit2dHist.C+(10) (via ACLIC, fast, independent fits with Minuit)
22/// root > .x fit2dHist.C+(12) (via ACLIC, fast, independent fits with Minuit2)
23/// ~~~
24///
25/// Note that you can also execute this script in batch with eg,
26/// ~~~{.cpp}
27/// root -b -q "fit2dHist.C+(12)"
28/// ~~~
29///
30/// or execute interactively from the shell
31/// ~~~{.cpp}
32/// root fit2dHist.C+
33/// root "fit2dHist.C+(12)"
34/// ~~~
35///
36/// \macro_image
37/// \macro_output
38/// \macro_code
39///
40/// \authors: Lorenzo Moneta, Rene Brun 18/01/2006
41
42#include "TH2D.h"
43#include "TF2.h"
44#include "TCanvas.h"
45#include "TStyle.h"
46#include "TRandom3.h"
47#include "Fit/Fitter.h"
48#include "TList.h"
49
50#include <iostream>
51
52double gauss2D(double *x, double *par) {
53 double z1 = double((x[0]-par[1])/par[2]);
54 double z2 = double((x[1]-par[3])/par[4]);
55 return par[0]*exp(-0.5*(z1*z1+z2*z2));
56}
57double my2Dfunc(double *x, double *par) {
58 return gauss2D(x,&par[0]) + gauss2D(x,&par[5]);
59}
60
61
62
63class MyFcn {
64 public:
65 TH2D *h1 = nullptr;
66 TH2D *h2 = nullptr;
67 int npfits = 0;
68
69 MyFcn(TH2D * _h1, TH2D * _h2) :
70 h1(_h1), h2(_h2) {}
71
72 double operator()(const double *p) {
73
74 TAxis *xaxis1 = h1->GetXaxis();
75 TAxis *yaxis1 = h1->GetYaxis();
76 TAxis *xaxis2 = h2->GetXaxis();
77 TAxis *yaxis2 = h2->GetYaxis();
78
79 int nbinX1 = h1->GetNbinsX();
80 int nbinY1 = h1->GetNbinsY();
81 int nbinX2 = h2->GetNbinsX();
82 int nbinY2 = h2->GetNbinsY();
83
84 double chi2 = 0;
85 double x[2];
86 double tmp;
87 npfits = 0;
88 for (int ix = 1; ix <= nbinX1; ++ix) {
89 x[0] = xaxis1->GetBinCenter(ix);
90 for (int iy = 1; iy <= nbinY1; ++iy) {
91 if ( h1->GetBinError(ix,iy) > 0 ) {
92 x[1] = yaxis1->GetBinCenter(iy);
93 tmp = (h1->GetBinContent(ix,iy) - my2Dfunc(x,(double*) p))/h1->GetBinError(ix,iy);
94 chi2 += tmp*tmp;
95 npfits++;
96 }
97 }
98 }
99 for (int ix = 1; ix <= nbinX2; ++ix) {
100 x[0] = xaxis2->GetBinCenter(ix);
101 for (int iy = 1; iy <= nbinY2; ++iy) {
102 if ( h2->GetBinError(ix,iy) > 0 ) {
103 x[1] = yaxis2->GetBinCenter(iy);
104 tmp = (h2->GetBinContent(ix,iy) - my2Dfunc(x,(double *) p))/h2->GetBinError(ix,iy);
105 chi2 += tmp*tmp;
106 npfits++;
107 }
108 }
109 }
110 return chi2;
111}
112};
113
114void FillHisto(TH2D * h, int n, double * p) {
115
116
117 const double mx1 = p[1];
118 const double my1 = p[3];
119 const double sx1 = p[2];
120 const double sy1 = p[4];
121 const double mx2 = p[6];
122 const double my2 = p[8];
123 const double sx2 = p[7];
124 const double sy2 = p[9];
125 //const double w1 = p[0]*sx1*sy1/(p[5]*sx2*sy2);
126 const double w1 = 0.5;
127
128 double x, y;
129 for (int i = 0; i < n; ++i) {
130 // generate randoms with larger Gaussians
131 gRandom->Rannor(x,y);
132
133 double r = gRandom->Rndm(1);
134 if (r < w1) {
135 x = x*sx1 + mx1;
136 y = y*sy1 + my1;
137 }
138 else {
139 x = x*sx2 + mx2;
140 y = y*sy2 + my2;
141 }
142 h->Fill(x,y);
143
144 }
145}
146
147
148
149
150int fit2dHist(int option=1) {
151
152 // create two histograms
153
154 int nbx1 = 50;
155 int nby1 = 50;
156 int nbx2 = 50;
157 int nby2 = 50;
158 double xlow1 = 0.;
159 double ylow1 = 0.;
160 double xup1 = 10.;
161 double yup1 = 10.;
162 double xlow2 = 5.;
163 double ylow2 = 5.;
164 double xup2 = 20.;
165 double yup2 = 20.;
166
167 auto h1 = new TH2D("h1","core",nbx1,xlow1,xup1,nby1,ylow1,yup1);
168 auto h2 = new TH2D("h2","tails",nbx2,xlow2,xup2,nby2,ylow2,yup2);
169
170 double iniParams[10] = { 100, 6., 2., 7., 3, 100, 12., 3., 11., 2. };
171 // create fit function
172 TF2 * func = new TF2("func",my2Dfunc,xlow2,xup2,ylow2,yup2, 10);
173 func->SetParameters(iniParams);
174
175 // fill Histos
176 int n1 = 1000000;
177 int n2 = 1000000;
178 FillHisto(h1,n1,iniParams);
179 FillHisto(h2,n2,iniParams);
180
181 // scale histograms to same heights (for fitting)
182 double dx1 = (xup1-xlow1)/double(nbx1);
183 double dy1 = (yup1-ylow1)/double(nby1);
184 double dx2 = (xup2-xlow2)/double(nbx2);
185 double dy2 = (yup2-ylow2)/double(nby2);
186 // scale histo 2 to scale of 1
187 h2->Sumw2();
188 h2->Scale( ( double(n1) * dx1 * dy1 ) / ( double(n2) * dx2 * dy2 ) );
189
190 bool global = false;
191 if (option > 10) global = true;
192 // do global combined fit
193 if (global) {
194 // fill data structure for fit (coordinates + values + errors)
195 std::cout << "Do global fit" << std::endl;
196 // fit now all the function together
197
198 ROOT::Fit::Fitter fitter;
199 //The default minimizer is Minuit, you can also try Minuit2
200
201 MyFcn myFcn(h1,h2);
202 fitter.SetFCN(10, myFcn);
203 if (option%10 == 2) fitter.Config().SetMinimizer("Minuit2");
204
205 // set parameter initial value, name and step size
206 for (int i = 0; i < 10; ++i) {
207 fitter.Config().ParSettings(i) = ROOT::Fit::ParameterSettings(func->GetParName(i), func->GetParameter(i), 0.01);
208 }
209
210 bool ret = fitter.FitFCN();
211 if (!ret) {
212 Error("fit2DHist","Fit Failed to converge");
213 return -1;
214 }
215
216 //get result
217 double minParams[10];
218 double parErrors[10];
219 for (int i = 0; i < 10; ++i) {
220 minParams[i] = fitter.Result().Parameter(i);
221 parErrors[i] = fitter.Result().Error(i);
222 }
223 double chi2 = fitter.Result().MinFcnValue();
224 double edm = fitter.Result().Edm();
225 int npfits = myFcn.npfits;
226
227 func->SetParameters(minParams);
228 func->SetParErrors(parErrors);
229 func->SetChisquare(chi2);
230 int ndf = npfits - fitter.Result().NFreeParameters();
231 func->SetNDF(ndf);
232
233 // add to list of functions
234 h1->GetListOfFunctions()->Add(func);
235 h2->GetListOfFunctions()->Add(func);
236 }
237 else {
238 // fit independently
239 h1->Fit(func, "0");
240 h2->Fit(func, "0");
241 }
242
243 // Create a new canvas.
244 TCanvas * c1 = new TCanvas("c1","Two HIstogram Fit example",100,10,900,800);
245 c1->Divide(2,2);
246 gStyle->SetOptFit();
247 gStyle->SetStatY(0.6);
248
249 c1->cd(1);
250 h1->Draw();
251 func->SetRange(xlow1,ylow1,xup1,yup1);
252 func->DrawCopy("cont3 same");
253 c1->cd(2);
254 h1->Draw("lego");
255 func->DrawCopy("surf1 same");
256 c1->cd(3);
257 func->SetRange(xlow2,ylow2,xup2,yup2);
258 h2->Draw();
259 func->DrawCopy("cont3 same");
260 c1->cd(4);
261 h2->Draw("lego");
262 gPad->SetLogz();
263 func->Draw("surf1 same");
264
265 return 0;
266}
#define h(i)
Definition RSha256.hxx:106
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
TRObject operator()(const T1 &t1) const
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define gPad
void SetMinimizer(const char *type, const char *algo=nullptr)
set minimizer type
Definition FitConfig.h:179
const ParameterSettings & ParSettings(unsigned int i) const
get the parameter settings for the i-th parameter (const method)
Definition FitConfig.h:76
double Error(unsigned int i) const
parameter error by index
Definition FitResult.h:179
double MinFcnValue() const
Return value of the objective function (chi2 or likelihood) used in the fit.
Definition FitResult.h:111
double Edm() const
Expected distance from minimum.
Definition FitResult.h:117
unsigned int NFreeParameters() const
get total number of free parameters
Definition FitResult.h:125
double Parameter(unsigned int i) const
parameter value by index
Definition FitResult.h:174
Fitter class, entry point for performing all type of fits.
Definition Fitter.h:77
const FitResult & Result() const
get fit result
Definition Fitter.h:394
bool FitFCN(unsigned int npar, Function &fcn, const double *params=nullptr, unsigned int dataSize=0, int fitType=0)
Fit using the a generic FCN function as a C++ callable object implementing double () (const double *)...
Definition Fitter.h:649
const FitConfig & Config() const
access to the fit configuration (const method)
Definition Fitter.h:422
bool SetFCN(unsigned int npar, Function &fcn, const double *params=nullptr, unsigned int dataSize=0, int fitType=0)
Set a generic FCN function as a C++ callable object implementing double () (const double *) Note that...
Definition Fitter.h:656
Class, describing value, limits and step size of the parameters Provides functionality also to set/re...
Class to manage histogram axis.
Definition TAxis.h:31
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
The Canvas class.
Definition TCanvas.h:23
virtual void SetNDF(Int_t ndf)
Set the number of degrees of freedom ndf should be the number of points used in a fit - the number of...
Definition TF1.cxx:3419
virtual void SetChisquare(Double_t chi2)
Definition TF1.h:638
virtual void SetParErrors(const Double_t *errors)
Set errors for all active parameters when calling this function, the array errors must have at least ...
Definition TF1.cxx:3490
virtual const char * GetParName(Int_t ipar) const
Definition TF1.h:555
virtual void SetParameters(const Double_t *params)
Definition TF1.h:670
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:538
A 2-Dim function with parameters.
Definition TF2.h:29
TF1 * DrawCopy(Option_t *option="") const override
Draw a copy of this function with its current attributes-*.
Definition TF2.cxx:286
void Draw(Option_t *option="") override
Draw this function with its current attributes.
Definition TF2.cxx:259
void SetRange(Double_t xmin, Double_t xmax) override
Initialize the upper and lower bounds to draw the function.
Definition TF2.h:146
virtual Int_t GetNbinsY() const
Definition TH1.h:298
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9031
TAxis * GetXaxis()
Definition TH1.h:324
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
Fit histogram with function fname.
Definition TH1.cxx:3898
virtual Int_t GetNbinsX() const
Definition TH1.h:297
TAxis * GetYaxis()
Definition TH1.h:325
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3066
TList * GetListOfFunctions() const
Definition TH1.h:244
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5029
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:357
void Add(TObject *obj) override
Definition TList.h:81
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:559
virtual void Rannor(Float_t &a, Float_t &b)
Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
Definition TRandom.cxx:507
void SetStatY(Float_t y=0)
Definition TStyle.h:395
void SetOptFit(Int_t fit=1)
The type of information about fit parameters printed in the histogram statistics box can be selected ...
Definition TStyle.cxx:1589
RVec< PromoteType< T > > exp(const RVec< T > &v)
Definition RVec.hxx:1800
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5