TF1 identical CHI2 values for two different looking fits

hey everybody!

I have three different fitting methods for a TH1 and my intention was to compare the methods by extracting chi2/ndf.

the first method was to manually selecte a fiiting range for a gaussian curve, the second to fit a broader gaussian and extract the fitting range from that broad gaussian for a better, slimmer gaussian fit (see code and picture) and the last method was to fit the sum of two gaussians. Without doubt, the sum of two gaussians fits the best. My problem is that the extracted chi2 and ndf values always result to the absolute identical values for the first two methods, even though the fitting result clearly doesn’t look the same (see figure).


   int MaxBin_x = thx->GetMaximumBin(); 
   double mw_x = thx->GetMean(1);
   double ymax_x = thx->GetBinContent(MaxBin_x); 

   
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////// MANUALLY SELECTED FITTING RANGE  /////////
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    TF1 *gausx_selec = new TF1 ("gausx_selec", "gaus", -1., 0.);
    thx->Fit("gausx_selec", "RQ0");
  
		    
    TF1 *gausx_selec_plot = new TF1 ("gausx_selec_plot", "gaus", -30., 30.);
    gausx_selec_plot->SetNpx(hBin); 
    gausx_selec_plot->SetParameters(gausx_selec -> GetParameter(0), gausx_selec -> GetParameter(1), gausx_selec -> GetParameter(2));

    
    gausx_selec_plot->SetLineStyle(2); 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//////BROAD GAUSSIAN GRAPH AND SLIM GAUSSIAN GRAPH /////////
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    TF1 *gausx = new TF1 ("gausx", "gaus", -30., 30.);

     gausx->SetParameter(0, ymax_x);
     gausx->SetParameter(1, mw_x);
     gausx->SetParameter(2, 2.);

    thx->Fit("gausx", "RQ0");

///////SLIM GAUSSIAN////
double sigmax = gausx->GetParameter(2); 
double mw_x_broad = gausx->GetParameter(1); 
double ymax_x_broad = gausx->GetParameter(0); 


    TF1* mygaus = new TF1("mygaus", "[0]*exp(-(x-[1])*(x-[1])/2/([2]*[2]))", -15, 15);

    TF1 *thingausx = new TF1 ("thingausx", "mygaus", mw_x_broad-sigmax, mw_x_broad+sigmax);

   thingausx->SetParameter(0, ymax_x_broad);
   thingausx->SetParameter(1, mw_x_broad);
   thingausx->SetParameter(2, 1.);

    thx->Fit(thingausx, "RQ0");

/////////////for CHI2 and PLOT
    TF1 *thingausx_plot = new TF1 ("thingausx_plot", "mygaus", -30., 30.);
    thingausx_plot->SetNpx(hBin);  
    thingausx_plot->SetParameters(thingausx->GetParameter(0),thingausx->GetParameter(1),thingausx->GetParameter(2) );   

    
  gausx->SetLineColor(1); 
  gausx->SetLineStyle(9); 
  thingausx_plot->SetLineStyle(2); 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////
///// FIT OF TWO GAUSSIAN for X /////////
////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TF1 *doublefitx = new TF1 ("doublefitx", "gaus(0) + gaus(3)", -30., 30.);

  doublefitx->SetParameter(0, ymax_x);
  doublefitx->SetParameter(1, mw_x);
  doublefitx->SetParameter(2, 0.5*sigmax);
  
  doublefitx->SetParameter(3, ymax_x/2.);
  doublefitx->SetParameter(4, 0.);
  doublefitx->SetParameter(5, sigmax);


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////
////// PLOT /////////
//////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

thx->SetStats(0); 
TPaveLabel *pave = new TPaveLabel(); 


   tc->cd(1);
   thx->DrawCopy("pe"); //a:draw with axes
   pave->DrawPaveLabel(-25., 1., -5., 0.8, "x projection of data", "tl"); 
	      
   tc->cd(2);
   thx->DrawCopy("pe"); 
   gausx_selec->Draw("same");
   gausx_selec_plot->Draw("same");
   pave->DrawPaveLabel(-25., 1., -5., 0.8, "selected fit range", "tl"); 

   tc->cd(3); 
   thx->DrawCopy("pe"); 
   thingausx->Draw("same"); 
   thingausx_plot->Draw("same");
   gausx->Draw("same");
   pave->DrawPaveLabel(-25., 1., -3., 0.8, "determined fit range", "tl"); 

    
   tc->cd(4); 
   thx->DrawCopy("pe"); 
   doublefitx->Draw("same"); 
   pave->DrawPaveLabel(-25., 1., -5., 0.8, "sum of two gauss", "tl"); 

   tc->Update(); 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////
////// GOODNESS OF FIT /////////
//////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 cout << " ----------------- MANUALLY SELECTED -------------------------------- " << endl; 

 thx->Fit("gausx_selec_plot", "RQ0");
 
double chi2_x_selec = gausx_selec_plot-> GetChisquare(); 
int NDF_x_selec = gausx_selec_plot-> GetNDF(); 
cout<< " ch2 x SELECTED:" << chi2_x_selec << endl; 
cout << " NDF x SELECTED: " << NDF_x_selec << endl; 
double goodness_x_selec = chi2_x_selec/NDF_x_selec; 
cout << "Goodness of fit for x for MANUALLY SELECTED FIT:"<< goodness_x_selec << endl; 


cout << " --------------------- SLIM GAUSSIAN ---------------------------- " << endl; 

 thx->Fit("thingausx_plot", "RQ0");

double chi2_x_slim = thingausx_plot -> GetChisquare(); 
int NDF_x_slim = thingausx_plot -> GetNDF(); 
cout<< " ch2 x SLIM:" << chi2_x_slim << endl; 
cout << " NDF x SLIM: " << NDF_x_slim << endl; 
double goodness_x_slim = chi2_x_slim/NDF_x_slim; 
cout << "Goodness of fit for x for SLIM FIT:"<< goodness_x_slim << endl; 


cout << " --------------------SUM OF TWO GAUSSIAN ----------------------------- " << endl; 

thx->Fit(doublefitx, "RQ0"); 

double chi2_x_double = doublefitx -> GetChisquare(); 
int NDF_x_double = doublefitx -> GetNDF(); 
cout<< " ch2 x DOUBLE:" << chi2_x_double << endl; 
cout << " NDF x DOUBLE : " << NDF_x_double << endl; 
double goodness_x_double = chi2_x_double/NDF_x_double; 
cout << "Goodness of fit for x DOUBLE GAUSS:"<< goodness_x_double << endl; 

cout << " ------------------------------------------------- " << endl; 

thx is the TH1F of my data. And I defined hBin as 120. The example you see in the figure gives the following output:

----------------- MANUALLY SELECTED --------------------------------
ch2 x SELECTED:787.894
NDF x SELECTED: 20
Goodness of fit for x for MANUALLY SELECTED FIT:39.3947
--------------------- SLIM GAUSSIAN ----------------------------
ch2 x SLIM:787.894
NDF x SLIM: 20
Goodness of fit for x for SLIM FIT:39.3947
--------------------SUM OF TWO GAUSSIAN -----------------------------
ch2 x DOUBLE:25.5219
NDF x DOUBLE : 17
Goodness of fit for x DOUBLE GAUSS:1.50129

What am I doing wrong? Looking foward to your comments! Anna
fit_chi2_comparison.ps (28.4 KB)

Hi,

Looking at your code, you are not getting the chi2 values from the fitted functions (for example the TF1 with name “gausx_selec”), but from a second fit you perform later (function with name “gausx_selec_plot”).
The second time you are doing the same gaussian fit, and therefore you get the same results. Just do:

double chi2_x_selec = gausx_selec-> GetChisquare(); 
double chi2_x_slim = thingausx-> GetChisquare(); 

Best Regards

Lorenzo

hey lorenzo,

thanks for your reply!

the reason why i don’t use the functions gausx_selec and thingausx for the determination of chi2 is, that they don’t fit the whole data range. Thus i dont achieve a fair comparison between the three methods.

and as the picture shows, the two fits (gausx_plot and thingausx_plot) are not the same fit at all.

do i miss something in my macro which i just dont see right now? thanks again, anna

hey!

actually, you are right. it is the same fit. sorry. i changed my macro in order to get a plot of the fits “gausx_selec_plot” and “thingausx_plot” and this time also defined adn plotted “gausx_selec_total” and “thingausx_total”. From the latter two i extraced the chi2. same value, but as the plot showed, also same distribution. so everthing is running fine, i just got confused.

Thanks again!