24 double gauss2D(
double *x,
double *par) {
25 double z1 = double((x[0]-par[1])/par[2]);
26 double z2 = double((x[1]-par[3])/par[4]);
27 return par[0]*exp(-0.5*(z1*z1+z2*z2));
29 double my2Dfunc(
double *x,
double *par) {
32 return gauss2D(x,p1) + gauss2D(x,p2);
39 std::vector<std::pair<double, double> > coords;
40 std::vector<double > values;
41 std::vector<double > errors;
43 void myFcn(Int_t & , Double_t * , Double_t &fval, Double_t *p, Int_t )
45 int n = coords.size();
48 for (
int i = 0; i <n; ++i ) {
49 x[0] = coords[i].first;
50 x[1] = coords[i].second;
51 tmp = ( values[i] - my2Dfunc(x,p))/errors[i];
57 void FillHisto(TH2D * h,
int n,
double * p) {
60 const double mx1 = p[1];
61 const double my1 = p[3];
62 const double sx1 = p[2];
63 const double sy1 = p[4];
64 const double mx2 = p[6];
65 const double my2 = p[8];
66 const double sx2 = p[7];
67 const double sy2 = p[9];
69 const double w1 = 0.5;
72 for (
int i = 0; i < n; ++i) {
76 double r = rndm.Rndm(1);
93 int TwoHistoFit2D(
bool global =
true) {
110 TH2D * h1 =
new TH2D(
"h1",
"core",nbx1,xlow1,xup1,nby1,ylow1,yup1);
111 TH2D * h2 =
new TH2D(
"h2",
"tails",nbx2,xlow2,xup2,nby2,ylow2,yup2);
113 double iniParams[10] = { 100, 6., 2., 7., 3, 100, 12., 3., 11., 2. };
115 TF2 * func =
new TF2(
"func",my2Dfunc,xlow2,xup2,ylow2,yup2, 10);
116 func->SetParameters(iniParams);
123 FillHisto(h1,n1,iniParams);
124 FillHisto(h2,n2,iniParams);
127 double dx1 = (xup1-xlow1)/
double(nbx1);
128 double dy1 = (yup1-ylow1)/
double(nby1);
129 double dx2 = (xup2-xlow2)/
double(nbx2);
130 double dy2 = (yup2-ylow2)/
double(nby2);
135 h2->Scale( (
double(n1) * dx1 * dy1 ) / (
double(n2) * dx2 * dy2 ) );
140 std::cout <<
"Do global fit" << std::endl;
144 TAxis *xaxis1 = h1->GetXaxis();
145 TAxis *yaxis1 = h1->GetYaxis();
146 TAxis *xaxis2 = h2->GetXaxis();
147 TAxis *yaxis2 = h2->GetYaxis();
149 int nbinX1 = h1->GetNbinsX();
150 int nbinY1 = h1->GetNbinsY();
151 int nbinX2 = h2->GetNbinsX();
152 int nbinY2 = h2->GetNbinsY();
155 coords = std::vector<std::pair<double,double> >();
156 values = std::vector<double>();
157 errors = std::vector<double>();
160 for (
int ix = 1; ix <= nbinX1; ++ix) {
161 for (
int iy = 1; iy <= nbinY1; ++iy) {
162 if ( h1->GetBinContent(ix,iy) > 0 ) {
163 coords.push_back( std::make_pair(xaxis1->GetBinCenter(ix), yaxis1->GetBinCenter(iy) ) );
164 values.push_back( h1->GetBinContent(ix,iy) );
165 errors.push_back( h1->GetBinError(ix,iy) );
169 for (
int ix = 1; ix <= nbinX2; ++ix) {
170 for (
int iy = 1; iy <= nbinY2; ++iy) {
171 if ( h2->GetBinContent(ix,iy) > 0 ) {
172 coords.push_back( std::make_pair(xaxis2->GetBinCenter(ix), yaxis2->GetBinCenter(iy) ) );
173 values.push_back( h2->GetBinContent(ix,iy) );
174 errors.push_back( h2->GetBinError(ix,iy) );
179 TVirtualFitter::SetDefaultFitter(
"Minuit");
180 TVirtualFitter * minuit = TVirtualFitter::Fitter(0,10);
181 for (
int i = 0; i < 10; ++i) {
182 minuit->SetParameter(i, func->GetParName(i), func->GetParameter(i), 0.01, 0,0);
184 minuit->SetFCN(myFcn);
189 minuit->ExecuteCommand(
"SET PRINT",arglist,2);
194 minuit->ExecuteCommand(
"MIGRAD",arglist,2);
197 double minParams[10];
198 double parErrors[10];
199 for (
int i = 0; i < 10; ++i) {
200 minParams[i] = minuit->GetParameter(i);
201 parErrors[i] = minuit->GetParError(i);
203 double chi2, edm, errdef;
205 minuit->GetStats(chi2,edm,errdef,nvpar,nparx);
207 func->SetParameters(minParams);
208 func->SetParErrors(parErrors);
209 func->SetChisquare(chi2);
210 int ndf = coords.size()-nvpar;
213 std::cout <<
"Chi2 Fit = " << chi2 <<
" ndf = " << ndf <<
" " << func->GetNDF() << std::endl;
216 h1->GetListOfFunctions()->Add(func);
217 h2->GetListOfFunctions()->Add(func);
228 TCanvas * c1 =
new TCanvas(
"c1",
"Two HIstogram Fit example",100,10,900,800);
231 gStyle->SetStatY(0.6);
235 func->SetRange(xlow1,ylow1,xup1,yup1);
236 func->DrawCopy(
"cont1 same");
239 func->DrawCopy(
"surf1 same");
241 func->SetRange(xlow2,ylow2,xup2,yup2);
243 func->DrawCopy(
"cont1 same");
247 func->Draw(
"surf1 same");