liz
April 9, 2024, 7:50pm
1
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 addition:
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