# Signal and background counts don't overlap with original entries

Hello I used gaussian function for the signal and a linear equation for the background to fit invariant mass distribution. All in all, the fitting it looks good but the problem is I got “Signal Counts: 778.322” and “Background Counts: 726.354” but on the original histogram there are 1.018574e+07 entries. Can someone please help me to fix it? Here is the macro

``````#include <TStyle.h>
#include <TCanvas.h>
#include <TH1.h>
#include <TF1.h>
#include <TFile.h>
#include <TLegend.h>

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

Double_t GAUSS(Double_t *x, Double_t *par) {
return par[0]*exp(-0.5*(((x[0]-par[1])/par[2])*((x[0]-par[1])/par[2])));
}

Double_t fitFunction(Double_t *x, Double_t *par) {
return background(x,par) + GAUSS(x,&par[3]);

}

void fit_hist() {
// Open the input file
TFile *tf = new TFile("outrfile.root");

// Get the histograms h_tp and h_m from the file
TH1F *h_tpp = (TH1F*)tf->Get("h_tpp");
TH1F *h_m = (TH1F*)tf->Get("h_m");

// Fit the h_m histogram using fitFunction
TCanvas *c_m = new TCanvas("c_m", "Invariant Mass", 800, 600);
h_m->SetYTitle("Number of #Lambda candidates");
h_m->SetXTitle("m_{inv} (GeV/c^2)");
h_m->Draw();

double minMass = 1.1025;
double maxMass = 1.13;
double maxBinContent = h_m->GetMaximum();

TF1 *fitFcn = new TF1("fitFcn", fitFunction, minMass, maxMass, 6);

// Initial parameters
fitFcn->SetParameter(0, 1);    // Roughly estimated
fitFcn->SetParameter(1, 1);    // Roughly estimated
fitFcn->SetParameter(2, 1);    // Roughly estimated
fitFcn->SetParameter(3, maxBinContent);  // Height of the peak
fitFcn->SetParameter(4, 1.115);          // Rough mean of the peak
fitFcn->SetParameter(5, 0.003);          // Rough width of the peak

h_m->Fit("fitFcn", "VR+", "ep");

TF1 *backFcn = new TF1("backFcn", background, minMass, maxMass, 3);
backFcn->SetLineColor(kRed);
TF1 *signalFcn = new TF1("signalFcn", GAUSS, minMass, maxMass, 3);
signalFcn->SetLineColor(kBlue);
signalFcn->SetNpx(500);

Double_t par[5];
fitFcn->GetParameters(par);
backFcn->SetParameters(par);
backFcn->Draw("same");
signalFcn->SetParameters(&par[3]);
signalFcn->Draw("same");

//New addings
// This part of the code explains the bacgorund in the signal region,
double mu = fitFcn->GetParameter(4);  // Mean of the Gaussian
double sigma = fitFcn->GetParameter(5);  // Standard deviation of the Gaussian

// Ranges for background sidebands and signal
double leftSidebandMin = minMass;
double leftSidebandMax = mu - sigma;

double signalMin = mu -2*sigma;
double signalMax = mu + 2*sigma;

double rightSidebandMin = mu + sigma;
double rightSidebandMax = maxMass;

double leftSidebandBackground = backFcn->Integral(leftSidebandMin, leftSidebandMax) / (leftSidebandMax - leftSidebandMin);
double rightSidebandBackground = backFcn->Integral(rightSidebandMin, rightSidebandMax) / (rightSidebandMax - rightSidebandMin);

// Average the sideband backgrounds to get an estimate for the background in the signal region
double backgroundEstimate = (leftSidebandBackground + rightSidebandBackground);

//  Calculate Signal Counts
double signalCounts = signalFcn->Integral(signalMin, signalMax);

// Background Counts
double backgroundCounts = backgroundEstimate * (signalMax - signalMin);
//Calculate S/(B + S)
double SoverB = signalCounts / ( backgroundCounts + signalCounts);

// Calculate (S + B) /B
double BoverS = (signalCounts  +  backgroundCounts) / backgroundCounts;

double chi2Total = fitFcn->GetChisquare();

std::cout << "Signal Counts: " << signalCounts << std::endl;
std::cout << "Background Counts: " << backgroundCounts << std::endl;
std::cout << "Signal-to-Background Ratio (S/B + S): " << SoverB << std::endl;
std::cout <<"Background -to Signal Ratio (S + B)/B:" << BoverS << std::endl;
std::cout <<" Total Chi Square: " << chi2Total << std::endl;

TLegend *legend_m = new TLegend(0.6,0.65,0.88,0.85);
legend_m->SetTextFont(72);
legend_m->SetTextSize(0.04);
legend_m->AddEntry(h_m, "Data", "lpe");
legend_m->AddEntry(backFcn, "Background fit", "l");
legend_m->AddEntry(signalFcn, "Signal fit", "l");
legend_m->AddEntry(fitFcn, "Global Fit", "l");
legend_m->Draw();

TPaveText *infoBox = new TPaveText(0.6, 0.2, 0.9, 0.6, "NDC");  // Adjust coordinates as needed

// Add each line of text to the box
infoBox->AddText(Form("Signal Counts: %.1f", signalCounts));
infoBox->AddText(Form("Background Counts: %.3f", backgroundCounts));
infoBox->AddText(Form("Signal-to-Background Ratio S/(B + S): %.6f", SoverB));
infoBox->AddText(Form("Background-to-Signal Ratio (S + B)/B: %.4f", BoverS));
infoBox->AddText(Form(" #chi^{2}: %.0f", chi2Total));

// Some optional styling
infoBox->SetFillColor(0);  // White background
infoBox->SetTextSize(0.03);  // Adjust text size if necessary
infoBox->SetBorderSize(1);  // Box border size

// Draw the box on the canvas
infoBox->Draw();

c_m->Update();

// Fit the h_tpp histogram for proper time
TCanvas *c_tpp = new TCanvas("c_tpp", "Proper Time", 800, 600);
c_tpp->SetLogy();

h_tpp->SetYTitle("Number of #Lambda candidates");
h_tpp->SetXTitle("tp cm/c");
h_tpp->Draw("E");

TF1 *fit_tpp = new TF1("fit_tpp", "[0]*exp(-x/[1])", 30, 40);
fit_tpp->SetParameters(0,1);
h_tpp->Fit(fit_tpp,"", "", 30, 40 );

fit_tpp->SetLineColor(kRed);
fit_tpp->Draw("same");

TLegend *legend_tpp = new TLegend(0.1, 0.7, 0.3, 0.9);
legend_tpp->AddEntry(h_tpp, "Data", "l");
legend_tpp->AddEntry(fit_tpp, "Exponential Fit", "l");
legend_tpp->Draw();

c_tpp->Update();

double chi2 = fit_tpp->GetChisquare();
int ndf = fit_tpp->GetNDF();
double reducedChi2 = chi2 / ndf;
std::cout << "Chi-square: " << chi2 << std::endl;
std::cout << "Degrees of Freedom: " << ndf << std::endl;
std::cout << "Reduced Chi-square: " << reducedChi2 << std::endl;

float tau = fit_tpp->GetParameter(1);
float tau_error = fit_tpp->GetParError(1);
std::cout << "Tau (proper time): " << tau << std::endl;
std::cout << "Error on Tau: " << tau_error << std::endl;

// Write histograms
TFile f("fit_hist.root", "recreate");
h_tpp->Write();
h_m->Write();
f.Close();
}
``````

Hi,

You cannot expect the sum of signal plus background to be the number of entries, since you count them in particular bands, see your code here:

``````    // Ranges for background sidebands and signal
double leftSidebandMin = minMass;
double leftSidebandMax = mu - sigma;

double signalMin = mu -2*sigma;
double signalMax = mu + 2*sigma;

double rightSidebandMin = mu + sigma;
double rightSidebandMax = maxMass;

double leftSidebandBackground = backFcn->Integral(leftSidebandMin, leftSidebandMax) / (leftSidebandMax - leftSidebandMin);
double rightSidebandBackground = backFcn->Integral(rightSidebandMin, rightSidebandMax) / (rightSidebandMax - rightSidebandMin);

// Average the sideband backgrounds to get an estimate for the background in the signal region
double backgroundEstimate = (leftSidebandBackground + rightSidebandBackground);

//  Calculate Signal Counts
double signalCounts = signalFcn->Integral(signalMin, signalMax);

// Background Counts
double backgroundCounts = backgroundEstimate * (signalMax - signalMin);
``````

Cheers,
Danilo

Yes this part is problematic but I couldn’t figure out how to define range for the signal and background and then remove background from the signal.

Hello,

This is not really ROOT related, however, looking at your code, it seems to me that the region in which the signal is integrated is defined by the variables `signalMax` and `signalMin`:

``````    double signalMin = mu -2*sigma;
double signalMax = mu + 2*sigma;
``````

Best,
D

Yes you are right I picked up special range for the signal

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