ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
fit2dHist.C
Go to the documentation of this file.
1 //
2 //+ Example to fit two histograms at the same time via TVirtualFitter
3 //
4 // To execute this tutorial, you can do:
5 //
6 // root > .x fit2dHist.C (executing via CINT, slow)
7 // or
8 // root > .x fit2dHist.C+ (executing via ACLIC , fast, with Minuit)
9 // root > .x fit2dHist.C+(2) (executing via ACLIC , fast, with Minuit2)
10 // or using the option to fit independently the 2 histos
11 // root > .x fit2dHist.C+(10) (via ACLIC, fast, independent fits with Minuit)
12 // root > .x fit2dHist.C+(12) (via ACLIC, fast, independent fits with Minuit2)
13 //
14 // Note that you can also execute this script in batch with eg,
15 // root -b -q "fit2dHist.C+(12)"
16 //
17 // or execute interactively from the shell
18 // root fit2dHist.C+
19 // root "fit2dHist.C+(12)"
20 //
21 // Authors: Lorenzo Moneta, Rene Brun 18/01/2006
22 
23 #include "TH2D.h"
24 #include "TF2.h"
25 #include "TCanvas.h"
26 #include "TStyle.h"
27 #include "TRandom3.h"
28 #include "TVirtualFitter.h"
29 #include "TList.h"
30 
31 #include <iostream>
32 
33 double gauss2D(double *x, double *par) {
34  double z1 = double((x[0]-par[1])/par[2]);
35  double z2 = double((x[1]-par[3])/par[4]);
36  return par[0]*exp(-0.5*(z1*z1+z2*z2));
37 }
38 double my2Dfunc(double *x, double *par) {
39  return gauss2D(x,&par[0]) + gauss2D(x,&par[5]);
40 }
41 
42 
43 // data need to be globals to be visible by fcn
45 TH2D *h1, *h2;
47 
48 void myFcn(Int_t & /*nPar*/, Double_t * /*grad*/ , Double_t &fval, Double_t *p, Int_t /*iflag */ )
49 {
50  TAxis *xaxis1 = h1->GetXaxis();
51  TAxis *yaxis1 = h1->GetYaxis();
52  TAxis *xaxis2 = h2->GetXaxis();
53  TAxis *yaxis2 = h2->GetYaxis();
54 
55  int nbinX1 = h1->GetNbinsX();
56  int nbinY1 = h1->GetNbinsY();
57  int nbinX2 = h2->GetNbinsX();
58  int nbinY2 = h2->GetNbinsY();
59 
60  double chi2 = 0;
61  double x[2];
62  double tmp;
63  npfits = 0;
64  for (int ix = 1; ix <= nbinX1; ++ix) {
65  x[0] = xaxis1->GetBinCenter(ix);
66  for (int iy = 1; iy <= nbinY1; ++iy) {
67  if ( h1->GetBinError(ix,iy) > 0 ) {
68  x[1] = yaxis1->GetBinCenter(iy);
69  tmp = (h1->GetBinContent(ix,iy) - my2Dfunc(x,p))/h1->GetBinError(ix,iy);
70  chi2 += tmp*tmp;
71  npfits++;
72  }
73  }
74  }
75  for (int ix = 1; ix <= nbinX2; ++ix) {
76  x[0] = xaxis2->GetBinCenter(ix);
77  for (int iy = 1; iy <= nbinY2; ++iy) {
78  if ( h2->GetBinError(ix,iy) > 0 ) {
79  x[1] = yaxis2->GetBinCenter(iy);
80  tmp = (h2->GetBinContent(ix,iy) - my2Dfunc(x,p))/h2->GetBinError(ix,iy);
81  chi2 += tmp*tmp;
82  npfits++;
83  }
84  }
85  }
86  fval = chi2;
87 }
88 
89 void FillHisto(TH2D * h, int n, double * p) {
90 
91 
92  const double mx1 = p[1];
93  const double my1 = p[3];
94  const double sx1 = p[2];
95  const double sy1 = p[4];
96  const double mx2 = p[6];
97  const double my2 = p[8];
98  const double sx2 = p[7];
99  const double sy2 = p[9];
100  //const double w1 = p[0]*sx1*sy1/(p[5]*sx2*sy2);
101  const double w1 = 0.5;
102 
103  double x, y;
104  for (int i = 0; i < n; ++i) {
105  // generate randoms with larger gaussians
106  rndm.Rannor(x,y);
107 
108  double r = rndm.Rndm(1);
109  if (r < w1) {
110  x = x*sx1 + mx1;
111  y = y*sy1 + my1;
112  }
113  else {
114  x = x*sx2 + mx2;
115  y = y*sy2 + my2;
116  }
117  h->Fill(x,y);
118 
119  }
120 }
121 
122 
123 
124 
125 int fit2dHist(int option=1) {
126 
127  // create two histograms
128 
129  int nbx1 = 50;
130  int nby1 = 50;
131  int nbx2 = 50;
132  int nby2 = 50;
133  double xlow1 = 0.;
134  double ylow1 = 0.;
135  double xup1 = 10.;
136  double yup1 = 10.;
137  double xlow2 = 5.;
138  double ylow2 = 5.;
139  double xup2 = 20.;
140  double yup2 = 20.;
141 
142  h1 = new TH2D("h1","core",nbx1,xlow1,xup1,nby1,ylow1,yup1);
143  h2 = new TH2D("h2","tails",nbx2,xlow2,xup2,nby2,ylow2,yup2);
144 
145  double iniParams[10] = { 100, 6., 2., 7., 3, 100, 12., 3., 11., 2. };
146  // create fit function
147  TF2 * func = new TF2("func",my2Dfunc,xlow2,xup2,ylow2,yup2, 10);
148  func->SetParameters(iniParams);
149 
150  // fill Histos
151  int n1 = 1000000;
152  int n2 = 1000000;
153  FillHisto(h1,n1,iniParams);
154  FillHisto(h2,n2,iniParams);
155 
156  // scale histograms to same heights (for fitting)
157  double dx1 = (xup1-xlow1)/double(nbx1);
158  double dy1 = (yup1-ylow1)/double(nby1);
159  double dx2 = (xup2-xlow2)/double(nbx2);
160  double dy2 = (yup2-ylow2)/double(nby2);
161  // scale histo 2 to scale of 1
162  h2->Sumw2();
163  h2->Scale( ( double(n1) * dx1 * dy1 ) / ( double(n2) * dx2 * dy2 ) );
164 
165  bool global = false;
166  if (option > 10) global = true;
167  if (global) {
168  // fill data structure for fit (coordinates + values + errors)
169  std::cout << "Do global fit" << std::endl;
170  // fit now all the function together
171 
172  //The default minimizer is Minuit, you can also try Minuit2
173  if (option%10 == 2) TVirtualFitter::SetDefaultFitter("Minuit2");
174  else TVirtualFitter::SetDefaultFitter("Minuit");
175  TVirtualFitter * minuit = TVirtualFitter::Fitter(0,10);
176  for (int i = 0; i < 10; ++i) {
177  minuit->SetParameter(i, func->GetParName(i), func->GetParameter(i), 0.01, 0,0);
178  }
179  minuit->SetFCN(myFcn);
180 
181  double arglist[100];
182  arglist[0] = 0;
183  // set print level
184  minuit->ExecuteCommand("SET PRINT",arglist,2);
185 
186  // minimize
187  arglist[0] = 5000; // number of function calls
188  arglist[1] = 0.01; // tolerance
189  minuit->ExecuteCommand("MIGRAD",arglist,2);
190 
191  //get result
192  double minParams[10];
193  double parErrors[10];
194  for (int i = 0; i < 10; ++i) {
195  minParams[i] = minuit->GetParameter(i);
196  parErrors[i] = minuit->GetParError(i);
197  }
198  double chi2, edm, errdef;
199  int nvpar, nparx;
200  minuit->GetStats(chi2,edm,errdef,nvpar,nparx);
201 
202  func->SetParameters(minParams);
203  func->SetParErrors(parErrors);
204  func->SetChisquare(chi2);
205  int ndf = npfits-nvpar;
206  func->SetNDF(ndf);
207 
208  // add to list of functions
209  h1->GetListOfFunctions()->Add(func);
210  h2->GetListOfFunctions()->Add(func);
211  }
212  else {
213  // fit independently
214  h1->Fit(func);
215  h2->Fit(func);
216  }
217 
218  // Create a new canvas.
219  TCanvas * c1 = new TCanvas("c1","Two HIstogram Fit example",100,10,900,800);
220  c1->Divide(2,2);
221  gStyle->SetOptFit();
222  gStyle->SetStatY(0.6);
223 
224  c1->cd(1);
225  h1->Draw();
226  func->SetRange(xlow1,ylow1,xup1,yup1);
227  func->DrawCopy("cont1 same");
228  c1->cd(2);
229  h1->Draw("lego");
230  func->DrawCopy("surf1 same");
231  c1->cd(3);
232  func->SetRange(xlow2,ylow2,xup2,yup2);
233  h2->Draw();
234  func->DrawCopy("cont1 same");
235  c1->cd(4);
236  h2->Draw("lego");
237  gPad->SetLogz();
238  func->Draw("surf1 same");
239 
240  return 0;
241 }
double par[1]
Definition: unuranDistr.cxx:38
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:6174
TList * GetListOfFunctions() const
Definition: TH1.h:244
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:432
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:460
Random number generator class based on M.
Definition: TRandom3.h:29
virtual void Draw(Option_t *option="")
Draw this function with its current attributes.
Definition: TF2.cxx:216
TCanvas * c1
Definition: legend1.C:2
virtual Int_t SetParameter(Int_t ipar, const char *parname, Double_t value, Double_t verr, Double_t vlow, Double_t vhigh)=0
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:363
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
TH1 * h
Definition: legend2.C:5
static void SetDefaultFitter(const char *name="")
static: set name of default fitter
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:659
virtual Double_t GetParameter(Int_t ipar) const =0
int Int_t
Definition: RtypesCore.h:41
virtual void SetFCN(void *fcn)
To set the address of the minimization objective function.
void SetStatY(Float_t y=0)
Definition: TStyle.h:392
virtual Int_t GetNbinsX() const
Definition: TH1.h:296
TH2D * h1
Definition: fit2dHist.C:45
Double_t x[n]
Definition: legend1.C:17
double gauss2D(double *x, double *par)
Definition: fit2dHist.C:33
TH2D * h2
Definition: fit2dHist.C:45
virtual Double_t Rndm(Int_t i=0)
Machine independent random number generator.
Definition: TRandom3.cxx:94
virtual Double_t GetParError(Int_t ipar) const =0
virtual TF1 * DrawCopy(Option_t *option="") const
Draw a copy of this function with its current attributes-*.
Definition: TF2.cxx:243
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH2.h:90
virtual void SetChisquare(Double_t chi2)
Definition: TF1.h:412
int fit2dHist(int option=1)
Definition: fit2dHist.C:125
ROOT::R::TRInterface & r
Definition: Object.C:4
Class to manage histogram axis.
Definition: TAxis.h:36
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2878
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:1204
void FillHisto(TH2D *h, int n, double *p)
Definition: fit2dHist.C:89
virtual Int_t ExecuteCommand(const char *command, Double_t *args, Int_t nargs)=0
TAxis * GetYaxis()
Definition: TH1.h:320
A 2-Dim function with parameters.
Definition: TF2.h:33
virtual Int_t GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx) const =0
The Canvas class.
Definition: TCanvas.h:48
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:154
double Double_t
Definition: RtypesCore.h:55
Double_t y[n]
Definition: legend1.C:17
double func(double *x, double *p)
Definition: stressTF1.cxx:213
Abstract Base Class for Fitting.
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:352
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:449
virtual Int_t GetNbinsY() const
Definition: TH1.h:297
static TVirtualFitter * Fitter(TObject *obj, Int_t maxpar=25)
Static function returning a pointer to the current fitter.
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1073
TRandom3 rndm
Definition: fit2dHist.C:44
virtual void Add(TObject *obj)
Definition: TList.h:81
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:3169
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8350
#define gPad
Definition: TVirtualPad.h:288
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:3102
double exp(double)
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8395
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:287
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:3607
void myFcn(Int_t &, Double_t *, Double_t &fval, Double_t *p, Int_t)
Definition: fit2dHist.C:48
const Int_t n
Definition: legend1.C:16
Int_t npfits
Definition: fit2dHist.C:46
TAxis * GetXaxis()
Definition: TH1.h:319
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:297
double my2Dfunc(double *x, double *par)
Definition: fit2dHist.C:38