{ "cells": [ { "cell_type": "markdown", "id": "dc21fea5", "metadata": {}, "source": [ "# fitNormSum\n", "Tutorial for normalized sum of two functions\n", "Here: a background exponential and a crystalball function\n", "Parameters can be set:\n", " 1. with the TF1 object before adding the function (for 3) and 4))\n", " 2. with the TF1NormSum object (first two are the coefficients, then the non constant parameters)\n", " 3. with the TF1 object after adding the function\n", "\n", "Sum can be constructed by:\n", " 1. by a string containing the names of the functions and/or the coefficient in front\n", " 2. by a string containg formulas like expo, gaus...\n", " 3. by the list of functions and coefficients (which are 1 by default)\n", " 4. by a std::vector for functions and coefficients\n", "\n", "\n", "\n", "\n", "**Author:** Lorenzo Moneta \n", "This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:24 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "84c437e4", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:01.058381Z", "iopub.status.busy": "2026-05-19T20:25:01.058247Z", "iopub.status.idle": "2026-05-19T20:25:01.372104Z", "shell.execute_reply": "2026-05-19T20:25:01.371662Z" } }, "outputs": [], "source": [ "const int nsig = 5.E4;\n", "const int nbkg = 1.e6;\n", "int nEvents = nsig + nbkg;\n", "int nBins = 1e3;\n", "\n", "double signal_mean = 3;\n", "TF1 *f_cb = new TF1(\"MyCrystalBall\", \"crystalball\", -5., 5.);\n", "TF1 *f_exp = new TF1(\"MyExponential\", \"expo\", -5., 5.);" ] }, { "cell_type": "markdown", "id": "01c02c81", "metadata": {}, "source": [ "I.:" ] }, { "cell_type": "code", "execution_count": 2, "id": "f333d852", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:01.381375Z", "iopub.status.busy": "2026-05-19T20:25:01.381243Z", "iopub.status.idle": "2026-05-19T20:25:01.588004Z", "shell.execute_reply": "2026-05-19T20:25:01.587304Z" } }, "outputs": [], "source": [ "f_exp->SetParameters(1., -0.3);\n", "f_cb->SetParameters(1, signal_mean, 0.3, 2, 1.5);" ] }, { "cell_type": "markdown", "id": "4462d04a", "metadata": {}, "source": [ "CONSTRUCTION OF THE TF1NORMSUM OBJECT ........................................\n", "1) :" ] }, { "cell_type": "code", "execution_count": 3, "id": "5a7df721", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:01.589448Z", "iopub.status.busy": "2026-05-19T20:25:01.589331Z", "iopub.status.idle": "2026-05-19T20:25:01.795938Z", "shell.execute_reply": "2026-05-19T20:25:01.795245Z" } }, "outputs": [], "source": [ "TF1NormSum *fnorm_exp_cb = new TF1NormSum(f_cb, f_exp, nsig, nbkg);" ] }, { "cell_type": "markdown", "id": "691e881a", "metadata": {}, "source": [ "4) :" ] }, { "cell_type": "code", "execution_count": 4, "id": "f5b03a2d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:01.797427Z", "iopub.status.busy": "2026-05-19T20:25:01.797312Z", "iopub.status.idle": "2026-05-19T20:25:02.003934Z", "shell.execute_reply": "2026-05-19T20:25:02.003259Z" } }, "outputs": [], "source": [ "TF1 *f_sum = new TF1(\"fsum\", *fnorm_exp_cb, -5., 5., fnorm_exp_cb->GetNpar());" ] }, { "cell_type": "markdown", "id": "54f323af", "metadata": {}, "source": [ "III.:" ] }, { "cell_type": "code", "execution_count": 5, "id": "c08379c8", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:02.005421Z", "iopub.status.busy": "2026-05-19T20:25:02.005304Z", "iopub.status.idle": "2026-05-19T20:25:02.211870Z", "shell.execute_reply": "2026-05-19T20:25:02.211200Z" } }, "outputs": [], "source": [ "f_sum->SetParameters(fnorm_exp_cb->GetParameters().data());\n", "f_sum->SetParName(1, \"NBackground\");\n", "f_sum->SetParName(0, \"NSignal\");\n", "for (int i = 2; i < f_sum->GetNpar(); ++i)\n", " f_sum->SetParName(i, fnorm_exp_cb->GetParName(i));" ] }, { "cell_type": "markdown", "id": "0b5b5a88", "metadata": {}, "source": [ "GENERATE HISTOGRAM TO FIT .............................................................." ] }, { "cell_type": "code", "execution_count": 6, "id": "6bf6b2af", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:02.213199Z", "iopub.status.busy": "2026-05-19T20:25:02.213076Z", "iopub.status.idle": "2026-05-19T20:25:02.419854Z", "shell.execute_reply": "2026-05-19T20:25:02.419227Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Time to generate 1050000 events: Real time 0:00:00, CP time 0.090\n" ] } ], "source": [ "TStopwatch w;\n", "w.Start();\n", "TH1D *h_sum = new TH1D(\"h_ExpCB\", \"Exponential Bkg + CrystalBall function\", nBins, -5., 5.);\n", "h_sum->FillRandom(\"fsum\", nEvents);\n", "printf(\"Time to generate %d events: \", nEvents);\n", "w.Print();" ] }, { "cell_type": "markdown", "id": "ca706ca8", "metadata": {}, "source": [ "need to scale histogram with width since we are fitting a density" ] }, { "cell_type": "code", "execution_count": 7, "id": "e4619d2a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:02.421378Z", "iopub.status.busy": "2026-05-19T20:25:02.421250Z", "iopub.status.idle": "2026-05-19T20:25:02.640053Z", "shell.execute_reply": "2026-05-19T20:25:02.637601Z" } }, "outputs": [], "source": [ "h_sum->Sumw2();\n", "h_sum->Scale(1., \"width\");" ] }, { "cell_type": "markdown", "id": "89c3c04c", "metadata": {}, "source": [ "fit - use Minuit2 if available" ] }, { "cell_type": "code", "execution_count": 8, "id": "b5acf9d2", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:02.642241Z", "iopub.status.busy": "2026-05-19T20:25:02.642120Z", "iopub.status.idle": "2026-05-19T20:25:02.849684Z", "shell.execute_reply": "2026-05-19T20:25:02.848621Z" } }, "outputs": [], "source": [ "ROOT::Math::MinimizerOptions::SetDefaultMinimizer(\"Minuit2\");\n", "new TCanvas(\"Fit\", \"Fit\", 800, 1000);" ] }, { "cell_type": "markdown", "id": "131251ee", "metadata": {}, "source": [ "do a least-square fit of the spectrum" ] }, { "cell_type": "code", "execution_count": 9, "id": "dad860e8", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:02.851287Z", "iopub.status.busy": "2026-05-19T20:25:02.851164Z", "iopub.status.idle": "2026-05-19T20:25:03.065786Z", "shell.execute_reply": "2026-05-19T20:25:03.065241Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "Minimizer is Minuit2 / Migrad\n", "Chi2 = 1018.73\n", "NDf = 993\n", "Edm = 9.65559e-06\n", "NCalls = 233\n", "NSignal = 50082 +/- 1231.21 \n", "NBackground = 998899 +/- 1569.86 \n", "Mean = 2.99896 +/- 0.0022426 \n", "Sigma = 0.297871 +/- 0.00230279 \n", "Alpha = 2.12493 +/- 0.1368 \n", "N = 1.1562 +/- 0.468136 \n", "Slope = -0.300341 +/- 0.000644187 \n", "Time to fit using ROOT TF1Normsum: Real time 0:00:00, CP time 0.090\n" ] } ], "source": [ "auto result = h_sum->Fit(\"fsum\", \"SQ\");\n", "result->Print();\n", "h_sum->Draw();\n", "printf(\"Time to fit using ROOT TF1Normsum: \");\n", "w.Print();" ] }, { "cell_type": "markdown", "id": "10d2f799", "metadata": {}, "source": [ "test if parameters are fine" ] }, { "cell_type": "code", "execution_count": 10, "id": "b1dcf868", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:03.067307Z", "iopub.status.busy": "2026-05-19T20:25:03.067187Z", "iopub.status.idle": "2026-05-19T20:25:03.273283Z", "shell.execute_reply": "2026-05-19T20:25:03.272797Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "std::vector pref = {nsig, nbkg, signal_mean};\n", "for (unsigned int i = 0; i < pref.size(); ++i) {\n", " if (!TMath::AreEqualAbs(pref[i], f_sum->GetParameter(i), f_sum->GetParError(i) * 10.))\n", " Error(\"testFitNormSum\", \"Difference found in fitted %s - difference is %g sigma\", f_sum->GetParName(i),\n", " (f_sum->GetParameter(i) - pref[i]) / f_sum->GetParError(i));\n", "}\n", "\n", "gStyle->SetOptStat(0);" ] }, { "cell_type": "markdown", "id": "737eac06", "metadata": {}, "source": [ "add parameters" ] }, { "cell_type": "code", "execution_count": 11, "id": "7c28dbb8", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:03.274955Z", "iopub.status.busy": "2026-05-19T20:25:03.274829Z", "iopub.status.idle": "2026-05-19T20:25:03.481559Z", "shell.execute_reply": "2026-05-19T20:25:03.480642Z" } }, "outputs": [], "source": [ "auto t1 = new TLatex(\n", " -2.5, 300000, TString::Format(\"%s = %8.0f #pm %4.0f\", \"NSignal\", f_sum->GetParameter(0), f_sum->GetParError(0)));\n", "auto t2 = new TLatex(\n", " -2.5, 270000, TString::Format(\"%s = %8.0f #pm %4.0f\", \"Nbackgr\", f_sum->GetParameter(1), f_sum->GetParError(1)));\n", "t1->Draw();\n", "t2->Draw();" ] }, { "cell_type": "markdown", "id": "c5e1560e", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 12, "id": "d0ae070d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:03.484096Z", "iopub.status.busy": "2026-05-19T20:25:03.483977Z", "iopub.status.idle": "2026-05-19T20:25:03.708872Z", "shell.execute_reply": "2026-05-19T20:25:03.707783Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "gROOT->GetListOfCanvases()->Draw()" ] } ], "metadata": { "kernelspec": { "display_name": "ROOT C++", "language": "c++", "name": "root" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".C", "mimetype": " text/x-c++src", "name": "c++" } }, "nbformat": 4, "nbformat_minor": 5 }