# Linear fit residuals

Hello! I am trying to plot the residuals for a simple linear fit but the results I get are different from what I would expect. I can’t understand what I’m doing wrong, any help is very much appreciated

``````#include "TCanvas.h"
#include "TFile.h"
#include "TH1.h"
#include "TF1.h"
#include "TAxis.h"
#include "TStyle.h"
#include <cmath>
#include <string>
#include <iostream>
using namespace std;

void risoluzione() {

gStyle->SetOptFit(0011);
TCanvas *canvas=new TCanvas("canvas", "canvas", 800, 800);

double energy[4]={525.325,1310.73, 1169.89, 1328.57}; //ch0, no Cs
double ee[4]={0.05, 0.16, 0.343, 0.38};
double sigma[4]={18.3131, 29.0482, 28.6102, 28.269};
double esigma[4]={0.06, 0.202, 0.49, 0.53};
double FWHM[4]={};

double x[4] = {}; //ch0
double y[4] ={};
double ex[4]={0,0,0,0};
double ey[4]={}; //ch0

for(int i=0; i<4; i++){
FWHM[i]=2.355*sigma[i];
y[i]=FWHM[i]/energy[i];
x[i]=1/sqrt(energy[i]);
ey[i]=y[i]*sqrt(pow(esigma[i]/sigma[i],2)+pow(ee[i]/energy[i],2));
cout << y[i] << endl;
cout << x[i] << endl;
};

TGraphErrors *gr = new TGraphErrors(4,x,y,ex,ey);
gr->SetMarkerStyle(24);
gr->SetMarkerSize(0.5);
gr->Draw("AP");

gr->Fit("pol1");

gr->SetTitle("Risoluzione (ch0);1/#sqrt{E} [keV^{-1/2}];R");

canvas->Draw();

TCanvas *canvas1=new TCanvas("canvas1", "canvas", 800, 800);
TGraph *residual= new TGraph;

TF1 *fitFunc = new TF1("fitFunc", "pol1");
for (int i=0; i<4; i++){
Double_t y0 = fitFunc->Eval(x[i]);
Double_t yr = (gr->GetY()[i] - y0);
residual->SetPoint(i , x[i], yr);

}

residual->Draw("ape");

return;
}

``````

Hi @Liz,
you fitted your data with a `pol1` and after the fit you declare the TF1 to compute the residual. But in this way the parameters of your `fitFunc` are 0s. So your residual plot is the same of your graph.

I changed your code just a little bit,
I moved the `fitFunc` declaration before the fit of the TGraph and I used the function for the fit.
This is enough to create the residual plot.

• in the for cycle I have removed the declaration of `y0 ` and `yr` and compute everything in one line.
but if you prefer to use `y0` and `yr` for the readability of your code is completely fine.
• I added the SetMarkerStyle to see the data immediately (just aesthetic)

Best,
Stefano

``````#include "TCanvas.h"
#include "TFile.h"
#include "TH1.h"
#include "TF1.h"
#include "TAxis.h"
#include "TStyle.h"
#include <cmath>
#include <string>
#include <iostream>
using namespace std;

void risoluzione() {

gStyle->SetOptFit(0011);
TCanvas *canvas=new TCanvas("canvas", "canvas", 800, 800);

double energy[4]={525.325,1310.73, 1169.89, 1328.57}; //ch0, no Cs
double ee[4]={0.05, 0.16, 0.343, 0.38};
double sigma[4]={18.3131, 29.0482, 28.6102, 28.269};
double esigma[4]={0.06, 0.202, 0.49, 0.53};
double FWHM[4]={};

double x[4] = {}; //ch0
double y[4] ={};
double ex[4]={0,0,0,0};
double ey[4]={}; //ch0

for(int i=0; i<4; i++){
FWHM[i]=2.355*sigma[i];
y[i]=FWHM[i]/energy[i];
x[i]=1/sqrt(energy[i]);
ey[i]=y[i]*sqrt(pow(esigma[i]/sigma[i],2)+pow(ee[i]/energy[i],2));
cout << y[i] << endl;
cout << x[i] << endl;
};

TGraphErrors *gr = new TGraphErrors(4,x,y,ex,ey);
gr->SetMarkerStyle(24);
gr->SetMarkerSize(0.5);
gr->Draw("AP");
TF1 *fitFunc = new TF1("fitFunc", "pol1");
gr->Fit("fitFunc");

gr->SetTitle("Risoluzione (ch0);1/#sqrt{E} [keV^{-1/2}];R");

canvas->Draw();

TCanvas *canvas1=new TCanvas("canvas1", "canvas", 800, 800);
TGraph *residual= new TGraph;

for (int i=0; i<4; i++){
residual->SetPoint(i , x[i], y[i]-fitFunc->Eval(x[i]));

}
residual->SetMarkerStyle(21);
residual->Draw("ape");

return;
}

``````
1 Like

Thank you so so much!

1 Like