<commit_before>/// \file
/// \notebook
/// \brief Example for fitting a signal + background model to a histogram found in a file.
///
/// This example can be executed as:
///     root > .x FitHistoInFile.C
///
/// \macro_image
/// \macro_code
/// \macro_output
/// \author Author <NAME>
/// Based on FittingDemo.C by <NAME>

#include "TH1.h"
#include "TMath.h"
#include "TF1.h"
#include "TLegend.h"
#include "TCanvas.h"
#include "TFile.h"
#include "TStyle.h"

// How many parameters does the background model have?
// Update this number if you change the background function
constexpr int nbgdpar=3;

// Quadratic background function
Double_t background(Double_t *x, Double_t *par) {
   return par[0] + par[1]*x[0] + par[2]*x[0]*x[0];
}

// Gauss Peak function
Double_t signal(Double_t *x, Double_t *par) {
   // par[0] scale, par[1] sigma, par[2] peakposition
   return par[0]*TMath::Gaus(x[0], par[2], par[1], true);
}

// Sum of background and peak function. We pass x and the fit parameters
// down to the signal and background functions. Note that `nbgdpar` needs
// to be correct for this to work.
Double_t fitFunction(Double_t *x, Double_t *par) {
  return background(x,par) + signal(x,&par[nbgdpar]);
}

// Fit "fitFunction" to the histogram, and draw results on the canvas `c1`.
void FitRoutine(TCanvas* c1, TH1* histo, float fitxmin, float fitxmax, TString filename){
   c1->cd();
   // create a TF1 with the range from 0 to 3 and 6 parameters
   TF1 *fitFcn = new TF1("fitFcn",fitFunction,fitxmin,fitxmax,3+nbgdpar);
   fitFcn->SetNpx(500);
   fitFcn->SetLineWidth(2);
   fitFcn->SetLineColor(kBlue);

   // first try with ok-ish starting values for the parameters
   fitFcn->SetParameters(30,0,0,50.,0.1,1.);
   histo->GetXaxis()->SetRange(2,40);
   histo->Fit("fitFcn","VR+","ep");

   // improve the picture:
   TF1 *backFcn = new TF1("backFcn",background,fitxmin,fitxmax,3);
   backFcn->SetLineColor(kRed);
   TF1 *signalFcn = new TF1("signalFcn",signal,fitxmin,fitxmax,3);
   signalFcn->SetLineColor(kBlue);
   signalFcn->SetNpx(500);

   // Retrieve fit parameters, and copy them to the signal and background functions
   Double_t par[6];
   fitFcn->GetParameters(par);

   backFcn->SetParameters(par);
   backFcn->Draw("same");

   signalFcn->SetParameters(&par[nbgdpar]);

   const double binwidth = (histo->GetXaxis()->GetXmax()-histo->GetXaxis()->GetXmin())/histo->GetNbinsX();
   const double integral = signalFcn->Integral(0.,3.);
   cout << "number of signal events = " << integral/binwidth << endl;

   // draw the legend
   TLegend *legend=new TLegend(0.15,0.7,0.28,0.85);
   legend->SetTextFont(72);
   legend->SetTextSize(0.03);
   legend->AddEntry(histo,"Data","lpe");
   legend->AddEntry(backFcn,"Bgd","l");
   legend->AddEntry(fitFcn,"Sig+Bgd","l");
   legend->Draw();
   histo->Draw("esame");
   c1->SaveAs(filename);
}

// Create a file with example data
void CreateRootFile(){
   // The data in array form
   const int nBins = 60;
   Double_t data[nBins] = { 6, 1,10,12, 6,13,23,22,15,21,
                           23,26,36,25,27,35,40,44,66,81,
                           75,57,43,37,36,31,35,36,43,32,
                           40,37,38,33,36,44,42,37,32,32,
                           43,44,35,33,33,39,29,41,32,44,
                           26,39,29,35,32,21,21,15,25,15};

   TFile* f = new TFile("exampleRootFile.root","RECREATE");
   TH1D *histo = new TH1D("histo", "Gauss Peak on Quadratic Background",60,0,3);
   for(int i=0; i < nBins;  i++) histo->SetBinContent(i+1,data[i]);
   f->Write();
   f->Close();
}

// Show how to fit a histogram that's in a file.
void FitHistoInFile() {
   gStyle->SetOptFit(1111);
   gStyle->SetOptStat(0);

   // fit range from fitxmin to fitxmax
   float fitxmin=0.2;
   float fitxmax=2.7;

   TCanvas *c1 = new TCanvas("c1","Fitting Demo of Histogram in File",10,10,700,500);
   CreateRootFile();
   TFile* f = new TFile("exampleRootFile.root");
   TH1D* histo=0;
   f->GetObject("histo",histo);
   if (!histo){
      cout << "histo not found"<<endl;
      return;
   }
   histo->SetMarkerStyle(21);
   histo->SetMarkerSize(0.8);
   // now call the fit routine
   FitRoutine(c1,histo, fitxmin, fitxmax,"FitHistoInFile.pdf");
}<commit_msg>[Tutorial] Suggestions from code review.<commit_after>/// \file
/// \notebook
/// \brief Example for fitting a signal + background model to a histogram found in a file.
///
/// This example can be executed as:
///     root > .x FitHistoInFile.C
///
/// \macro_image
/// \macro_code
/// \macro_output
/// \author Author <NAME>
/// Based on FittingDemo.C by <NAME>

#include "TH1.h"
#include "TMath.h"
#include "TF1.h"
#include "TLegend.h"
#include "TCanvas.h"
#include "TFile.h"
#include "TStyle.h"

// How many parameters does the background model have?
// Update this number if you change the background function
constexpr int nbgdpar=3;

// Quadratic background function
Double_t background(Double_t *x, Double_t *par) {
   return par[0] + par[1]*x[0] + par[2]*x[0]*x[0];
}

// Gauss Peak function
Double_t signal(Double_t *x, Double_t *par) {
   // par[0] scale, par[1] sigma, par[2] peakposition
   return par[0]*TMath::Gaus(x[0], par[2], par[1], true);
}

// Sum of background and peak function. We pass x and the fit parameters
// down to the signal and background functions. Note that `nbgdpar` needs
// to be correct for this to work.
Double_t fitFunction(Double_t *x, Double_t *par) {
  return background(x,par) + signal(x,&par[nbgdpar]);
}

// Fit "fitFunction" to the histogram, and draw results on the canvas `c1`.
void FitRoutine(TCanvas* c1, TH1* histo, float fitxmin, float fitxmax, TString filename){
   c1->cd();
   // create a TF1 with the range from 0 to 3 and N_PAR parameters (six by default)
   TF1 fitFcn("fitFcn",fitFunction,fitxmin,fitxmax,N_PAR);
   fitFcn.SetNpx(500);
   fitFcn.SetLineWidth(2);
   fitFcn.SetLineColor(kBlue);

   // Fit. First set ok-ish starting values for the parameters
   fitFcn.SetParameters(30,0,0,50.,0.1,1.);
   histo->GetXaxis()->SetRange(2,40);
   histo->Fit("fitFcn","VR+","ep");

   // improve the picture:
   // Draw signal and background functions separately
   TF1 backFcn("backFcn",background,fitxmin,fitxmax,3);
   backFcn.SetLineColor(kRed);
   TF1 signalFcn("signalFcn",signal,fitxmin,fitxmax,3);
   signalFcn.SetLineColor(kBlue);
   signalFcn.SetNpx(500);

   // Retrieve fit parameters, and copy them to the signal and background functions
   Double_t par[6];
   fitFcn.GetParameters(par);

   backFcn.SetParameters(par);
   backFcn.DrawCopy("same");

   signalFcn.SetParameters(&par[nbgdpar]));

   const double binwidth = (histo->GetXaxis()->GetXmax()-histo->GetXaxis()->GetXmin())/histo->GetNbinsX();
   const double integral = signalFcn.Integral(0.,3.);
   cout << "number of signal events = " << integral/binwidth << endl;

   // draw the legend
   TLegend legend(0.15,0.7,0.28,0.85);
   legend.SetTextFont(72);
   legend.SetTextSize(0.03);
   legend.AddEntry(histo,"Data","lpe");
   legend.AddEntry(&backFcn,"Bgd","l");
   legend.AddEntry(&fitFcn,"Sig+Bgd","l");
   legend.DrawClone();
   histo->Draw("esame");
   c1->SaveAs(filename);
}

// Create a file with example data
void CreateRootFile(){
   // The data in array form
   const int nBins = 60;
   Double_t data[nBins] = { 6, 1,10,12, 6,13,23,22,15,21,
                           23,26,36,25,27,35,40,44,66,81,
                           75,57,43,37,36,31,35,36,43,32,
                           40,37,38,33,36,44,42,37,32,32,
                           43,44,35,33,33,39,29,41,32,44,
                           26,39,29,35,32,21,21,15,25,15};

   TFile* f = new TFile("exampleRootFile.root","RECREATE");
   TH1D *histo = new TH1D("histo", "Gauss Peak on Quadratic Background",60,0,3);
   for(int i=0; i < nBins;  i++) histo->SetBinContent(i+1,data[i]);
   f->Write();
   f->Close();
}

// Show how to fit a histogram that's in a file.
void FitHistoInFile() {
   gStyle->SetOptFit(1111);
   gStyle->SetOptStat(0);

   // fit range from fitxmin to fitxmax
   float fitxmin=0.2;
   float fitxmax=2.7;

   TCanvas *c1 = new TCanvas("c1","Fitting Demo of Histogram in File",10,10,700,500);
   CreateRootFile();
   TFile* f = new TFile("exampleRootFile.root");
   TH1D* histo= nullptr;
   f->GetObject("histo",histo);
   if (!histo){
      cout << "histo not found"<<endl;
      return;
   }
   histo->SetMarkerStyle(21);
   histo->SetMarkerSize(0.8);
   // now call the fit routine
   FitRoutine(c1,histo, fitxmin, fitxmax,"FitHistoInFile.pdf");
}
{'fraction_non_alphanumeric': 0.16138532218164683, 'fraction_numerical': 0.05277417834845094, 'mean_word_length': 3.480211081794195, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2244889', 'n_tokens_mistral': 3358, 'n_tokens_neox': 3116, 'n_words': 737}