Adding fit functions to h2proj.C example

Dear experts,

I am trying to add fit functions to the X and Y projection histograms of this example
https://root.cern/doc/v630/h2proj_8C.html

but I cannot get to plot the function for the histogram of the right (the one using hbar as drawing options). Do you have an idea how to solve this?

Thanks in advance.

Diego

Hello Diego,

could you upload the code that adds the functions? We could see how to go on from there.

Hi Stephan,

sure, I share with you my function:

void PlotMagPhase(TTree* tree, const std::vector<TString>& Mags, const std::vector<TString>& Phases, TString outputPath)
{
    gStyle->SetOptStat(0);
    gStyle->SetOptTitle(0);
    
    std::vector<double> true_mag(Mags.size());
    std::vector<double> true_phase(Phases.size());
    for (size_t j = 0; j < Mags.size(); ++j) {
        TCanvas* canv = new TCanvas("canv", "MagPhase", 1000, 1000);
        canv->Draw();

        // Main pad for the 2D histogram
        TPad *main_pad = new TPad("pMain", "pMain", 0.0, 0.0, 0.6, 0.6); 
        main_pad->Draw();
        //Right pad
        TPad *pR = new TPad("pR", "pR", 0.6, 0.0, 1, 0.6);
        pR->Draw();
        //Top pad
        TPad *pT = new TPad("pT", "pT", 0.0, 0.6, 0.6, 1.0);
        pT->Draw();

        main_pad->cd();
        gPad->SetLeftMargin(0.15);
        gPad->SetRightMargin(0.15);
        gPad->SetBottomMargin(0.15);
        gPad->SetTopMargin(0.15);

        double min_A = tree->GetMinimum(Form("A%i_A", j));
        double max_A = tree->GetMaximum(Form("A%i_A", j));
        double min_ph = tree->GetMinimum(Form("A%i_Delta", j));
        double max_ph = tree->GetMaximum(Form("A%i_Delta", j));
        tree->Draw(Form("A%i_Delta:A%i_A>>hist(35,%f,%f,35,%f,%f)", j, j, min_A, max_A, min_ph, max_ph));

        TH2F* hist = (TH2F*)gDirectory->Get("hist");
        hist->Draw("COLZ");

        tree->SetBranchAddress(Form("A%zu_A_True", j), &true_mag[j]);
        tree->SetBranchAddress(Form("A%zu_Delta_True", j), &true_phase[j]);
        tree->GetEntry(j);

        // Draw the lines for the true values
        if (true_mag[j] >= min_A && true_mag[j] <= max_A && true_phase[j] >= min_ph && true_phase[j] <= max_ph) {
            TLine* line_mag = new TLine(true_mag[j], min_ph, true_mag[j], max_ph);
            line_mag->SetLineColor(kRed);
            line_mag->SetLineWidth(2);
            line_mag->Draw();

            TLine* line_phase = new TLine(min_A, true_phase[j], max_A, true_phase[j]);
            line_phase->SetLineColor(kRed);
            line_phase->SetLineWidth(2);
            line_phase->Draw();
        } else {
            std::cout << "Lines are outside the visible range for index " << j << std::endl;
        }

        hist->SetTitle(Form(";%s;%s;Events", Mags[j].Data(), Phases[j].Data()));

        // Projection on X-axis
        canv->cd();
        pT->cd();
        gPad->SetLeftMargin(0.15);
        gPad->SetRightMargin(0.15);
        gPad->SetBottomMargin(0.15);
        gPad->SetTopMargin(0.15);
        tree->Draw(Form("A%i_A>>projX(35,%f,%f)", j, min_A, max_A));
        TH1F* projX = (TH1F*)gDirectory->Get("projX");
        projX->SetTitle(Form(";%s;Events", Mags[j].Data()));
        projX->SetFillColor(kBlue+1);
        projX->Draw("bar");
        projX->Fit("gaus");
        auto * fitFunc = projX->GetFunction("gaus");
        // Get parameters from the fit function
        double mean = fitFunc->GetParameter(1);
        double mean_err = fitFunc->GetParError(1);
        double sigma = fitFunc->GetParameter(2);
        double sigma_err = fitFunc->GetParError(2);
        double chiSquare = fitFunc->GetChisquare();
        int nbins = projX->GetNbinsX();
        // Get the number of parameters in the fit function
        int nParams = fitFunc->GetNpar();
        // Calculate degrees of freedom
        int dof = nbins - nParams;

        TLatex latex;
        latex.SetTextSize(0.03);
        // Add mean to the plot
        latex.DrawLatexNDC(0.7, 0.85, "Gaussian fit");
        latex.DrawLatexNDC(0.7, 0.8, Form("#mu: %.4f #pm %.4f", mean, mean_err));

        // Add standard deviation to the plot
        latex.DrawLatexNDC(0.7, 0.75, Form("#sigma: %.4f #pm %.4f", sigma, sigma_err));

        // Add chi-square to the plot
        latex.DrawLatexNDC(0.7, 0.70, Form("#chi^{2}/dof: %.2f/%.i = %.2f", chiSquare, dof,chiSquare/dof ));


        // Projection on Y-axis
        // canv->cd(2);
        // gPad->SetPad(0.7, 0.3, 1.0, 1.0); // Adjust the pad size
        canv->cd();
        pR->cd();
        gPad->SetLeftMargin(0.15);
        gPad->SetRightMargin(0.15);
        gPad->SetBottomMargin(0.15);
        gPad->SetTopMargin(0.15);
        tree->Draw(Form("A%i_Delta>>projY(35,%f,%f)", j, min_ph, max_ph));
        TH1F* projY = (TH1F*)gDirectory->Get("projY");
        projY->SetTitle(Form(";%s;Events", Phases[j].Data()));
        projY->SetFillColor(kBlue+1);
        projY->Draw("hbar");
        projY->Fit("gaus");
        auto * fitFuncy = projY->GetFunction("gaus");
        // Get parameters from the fit function
        mean = fitFuncy->GetParameter(1);
        mean_err = fitFuncy->GetParError(1);
        sigma = fitFuncy->GetParameter(2);
        sigma_err = fitFuncy->GetParError(2);
        chiSquare = fitFuncy->GetChisquare();
        nbins = projY->GetNbinsX();
        // Get the number of parameters in the fit function
        nParams = fitFuncy->GetNpar();
        // Calculate degrees of freedom
        dof = nbins - nParams;

        TLatex latexY;
        latexY.SetTextSize(0.03);
        // Add mean to the plot
        latexY.DrawLatexNDC(0.7, 0.85, "Gaussian fit");
        latexY.DrawLatexNDC(0.7, 0.8, Form("#mu: %.4f #pm %.4f", mean, mean_err));

        // Add standard deviation to the plot
        latexY.DrawLatexNDC(0.7, 0.75, Form("#sigma: %.4f #pm %.4f", sigma, sigma_err));

        // Add chi-square to the plot
        latexY.DrawLatexNDC(0.7, 0.70, Form("#chi^{2}/dof: %.2f/%.i = %.2f", chiSquare, dof,chiSquare/dof ));


        canv->SaveAs(Form("%s_resonance%zu_cut.pdf", outputPath.Data(), j));
        delete canv, hist, projX, projY, true_mag, true_phase;
    }
}

which works fine but does not plot the fit function for the Y projection of the 2D histogram.

lmk if you need any further info. Thanks!

Hello @mendoza,

I understand now what the problem is:
The hbar drawing option flips the histogram on the side, and the fit functions are not really ready for that. I can draw the function (see the red line below), but it’s transposed (because hbar swaps the axes):

root [8] hpx->Draw("hbar")
root [9] hpx->Draw("FUNC same")

If you want to see the fit function drawn on the side, you would have to transpose it yourself. You can retrieve it using
GetFunction, and then you could create a TGraph following e.g. the TGraph tutorial, taking care that you swap x and y.
You can evaluate the function using something like:

TF1* function = histogram->GetFunction("<name>");
for (.....) {
  tgraph.SetPoint(i, function->Eval(x), x);
}