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