Chi2/ndf is 1 even though fit is not good

Hi everyone, I have 5 efficiency graphs that I fit with a sigmoid function. What I would like to do is ‘show’ that my fit improves if I reduce the fitting range (only fit for efficiencies of 0.8 or higher). When I fit it, it can be clearly seen that reducing the fitting range improves my fit, however, I would like to ‘prove’ this, so I thought I would use the chi squared over number of degrees of freedom and show that it is closer to 1 for when I have a reduced fitting range.

For my plot with reduced fitting range I get that chi2/ndf is 1 to three decimal places. However, when I find the chi2/ndf for my full fitting range, I still find 1 (to 4 decimal places now), even though I can clearly see that the fit is far from perfect in that case. Thanks for the help!

#include "TFile.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TMultiGraph.h"
#include "TGraphAsymmErrors.h"
#include "TLegend.h"
#include "TString.h"
#include <vector>
#include <iostream>

void trigger_turnon(){
  
  auto f = new TFile ("HaddOutput_old.root");
  TCanvas *c = new TCanvas("c", "", 500, 500);
  TH1D *k1 = (TH1D*)f->Get("AfterCuts/yCut_0.6/pT1Cut_0/pT2Cut_0/LeadingJetPt");
  
  std::vector<std::string> TriggerCut = {"L1_J20", "L1_J40", "L1_J50", "L1_J75", "L1_J100"};
  int n = TriggerCut.size();
  TGraphAsymmErrors *eff[n];
  TH1D *h[n];  
  TF1 *fit[n];  
  TF1 *sigmoid[n];
      
  std::vector<int> offset = {50, 85, 100 , 135 , 160};
  std::vector<double> chi2(n);  
  std::vector<double> ndf(n);  
  
  for (unsigned i = 0; i < n; i++) {
       f->GetObject(TString::Format("%s/yCut_0.6/pT1Cut_0/pT2Cut_0/LeadingJetPt", TriggerCut[i].c_str()) , h[i]); 
       eff[i] = new TGraphAsymmErrors();
       eff[i]->Divide(h[i], k1);
       
// THIS IS WHERE I LIMIT MY FITTING RANGE
//        for (int j = (eff[i]->GetN() - 1); j >= 0; j--) {
// 	 if (eff[i]->GetY()[j] < 0.8) eff[i]->RemovePoint(j); 
//        }
    
       if (i==0) eff[i]->Draw("ap");
       else eff[i]->Draw("p same");
    
       fit[i] = new TF1("sigm_%d",  "(1/(1+ TMath::Exp(-[0]*(x-[1]))))", 0, 230); // Sigmoid fit to efficiency plots
       fit[i]->SetParameters(0.2, offset[i]);
       eff[i]->Fit("sigm_%d", "EX0");
     
       chi2[i] = fit[i]->GetChisquare();
       ndf[i] = fit[i]->GetNDF();
    }
  
  std::cout << "ch2 for J20= " << chi2[0]<< std::endl;
  std::cout << "ch2 for J40= " << chi2[1]<< std::endl;
  std::cout << "ch2 for J50= " << chi2[2]<< std::endl;
  std::cout << "ch2 for J75= " << chi2[3]<< std::endl;
  std::cout << "ch2 for J100= " << chi2[4]<< std::endl;

  std::cout << "ndf for J20= " << chi2[0]<< std::endl;
  std::cout << "ndf for J40= " << chi2[1]<< std::endl;
  std::cout << "ndf for J50= " << chi2[2]<< std::endl;
  std::cout << "ndf for J75= " << chi2[3]<< std::endl;
  std::cout << "ndf for J100= " << chi2[4]<< std::endl;  
}

Where do you see chi2/ndf is 1? :crazy_face:
Here? :rofl:

std::cout << "ch2 for J20= " << chi2[0]<< std::endl;
// ...
std::cout << "ndf for J20= " << chi2[0]<< std::endl;

BTW. You could add something like this:

if (eff[i]->GetY()[j] > 0.999999) eff[i]->RemovePoint(j);
if (eff[i]->GetY()[j] < 0.000001) eff[i]->RemovePoint(j);
1 Like

Ooh I see :rofl: sometimes you just need a different pair of eyes to point out the obvious I guess! Thanks for answering, I would have probably just kept staring at it and not seeing that!

I have edited my code, and now for my fitted range I get values between 1.1 and 1.8 for chi squared over ndf for the different plots and I was just wondering whether that’s a good value or not? Thanks!

Try with: eff[i]->Fit("sigm_%d", "EM");

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.