{ "cells": [ { "cell_type": "markdown", "id": "1e5e507f", "metadata": {}, "source": [ "# langaus\n", "Convoluted Landau and Gaussian Fitting Function\n", " (using ROOT's Landau and Gauss functions)\n", "\n", " Based on a Fortran code by R.Fruehwirth (fruhwirth@hephy.oeaw.ac.at)\n", "\n", " to execute this example, do:\n", "\n", "```cpp\n", " root > .x langaus.C\n", "```\n", "\n", "or\n", "\n", "```cpp\n", " root > .x langaus.C++\n", "```\n", "\n", "\n", "\n", "\n", "**Author:** H.Pernegger, Markus Friedl \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:25 PM." ] }, { "cell_type": "markdown", "id": "13ff097f", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 1, "id": "54b2c066", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:05.631087Z", "iopub.status.busy": "2026-05-19T20:25:05.630975Z", "iopub.status.idle": "2026-05-19T20:25:05.635874Z", "shell.execute_reply": "2026-05-19T20:25:05.635287Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "\n", "#include \"TH1.h\"\n", "#include \"TF1.h\"\n", "#include \"TROOT.h\"\n", "#include \"TStyle.h\"\n", "#include \"TMath.h\"\n", "\n", "double langaufun(double *x, double *par) {\n", "\n", " //Fit parameters:\n", " //par[0]=Width (scale) parameter of Landau density\n", " //par[1]=Most Probable (MP, location) parameter of Landau density\n", " //par[2]=Total area (integral -inf to inf, normalization constant)\n", " //par[3]=Width (sigma) of convoluted Gaussian function\n", " //\n", " //In the Landau distribution (represented by the CERNLIB approximation),\n", " //the maximum is located at x=-0.22278298 with the location parameter=0.\n", " //This shift is corrected within this function, so that the actual\n", " //maximum is identical to the MP parameter.\n", "\n", " // Numeric constants\n", " double invsq2pi = 0.3989422804014; // (2 pi)^(-1/2)\n", " double mpshift = -0.22278298; // Landau maximum location\n", "\n", " // Control constants\n", " double np = 100.0; // number of convolution steps\n", " double sc = 5.0; // convolution extends to +-sc Gaussian sigmas\n", "\n", " // Variables\n", " double xx;\n", " double mpc;\n", " double fland;\n", " double sum = 0.0;\n", " double xlow,xupp;\n", " double step;\n", " double i;\n", "\n", "\n", " // MP shift correction\n", " mpc = par[1] - mpshift * par[0];\n", "\n", " // Range of convolution integral\n", " xlow = x[0] - sc * par[3];\n", " xupp = x[0] + sc * par[3];\n", "\n", " step = (xupp-xlow) / np;\n", "\n", " // Convolution integral of Landau and Gaussian by sum\n", " for(i=1.0; i<=np/2; i++) {\n", " xx = xlow + (i-.5) * step;\n", " fland = TMath::Landau(xx,mpc,par[0]) / par[0];\n", " sum += fland * TMath::Gaus(x[0],xx,par[3]);\n", "\n", " xx = xupp - (i-.5) * step;\n", " fland = TMath::Landau(xx,mpc,par[0]) / par[0];\n", " sum += fland * TMath::Gaus(x[0],xx,par[3]);\n", " }\n", "\n", " return (par[2] * step * sum * invsq2pi / par[3]);\n", "}" ] }, { "cell_type": "markdown", "id": "a3cf9308", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 2, "id": "02e34423", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:05.637128Z", "iopub.status.busy": "2026-05-19T20:25:05.637008Z", "iopub.status.idle": "2026-05-19T20:25:05.647966Z", "shell.execute_reply": "2026-05-19T20:25:05.647375Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "TF1 *langaufit(TH1F *his, double *fitrange, double *startvalues, double *parlimitslo, double *parlimitshi, double *fitparams, double *fiterrors, double *ChiSqr, int *NDF)\n", "{\n", " // Once again, here are the Landau * Gaussian parameters:\n", " // par[0]=Width (scale) parameter of Landau density\n", " // par[1]=Most Probable (MP, location) parameter of Landau density\n", " // par[2]=Total area (integral -inf to inf, normalization constant)\n", " // par[3]=Width (sigma) of convoluted Gaussian function\n", " //\n", " // Variables for langaufit call:\n", " // his histogram to fit\n", " // fitrange[2] lo and hi boundaries of fit range\n", " // startvalues[4] reasonable start values for the fit\n", " // parlimitslo[4] lower parameter limits\n", " // parlimitshi[4] upper parameter limits\n", " // fitparams[4] returns the final fit parameters\n", " // fiterrors[4] returns the final fit errors\n", " // ChiSqr returns the chi square\n", " // NDF returns ndf\n", "\n", " int i;\n", " char FunName[100];\n", "\n", " sprintf(FunName,\"Fitfcn_%s\",his->GetName());\n", "\n", " TF1 *ffitold = (TF1*)gROOT->GetListOfFunctions()->FindObject(FunName);\n", " if (ffitold) delete ffitold;\n", "\n", " TF1 *ffit = new TF1(FunName,langaufun,fitrange[0],fitrange[1],4);\n", " ffit->SetParameters(startvalues);\n", " ffit->SetParNames(\"Width\",\"MP\",\"Area\",\"GSigma\");\n", "\n", " for (i=0; i<4; i++) {\n", " ffit->SetParLimits(i, parlimitslo[i], parlimitshi[i]);\n", " }\n", "\n", " his->Fit(FunName,\"RB0\"); // fit within specified range, use ParLimits, do not plot\n", "\n", " ffit->GetParameters(fitparams); // obtain fit parameters\n", " for (i=0; i<4; i++) {\n", " fiterrors[i] = ffit->GetParError(i); // obtain fit parameter errors\n", " }\n", " ChiSqr[0] = ffit->GetChisquare(); // obtain chi^2\n", " NDF[0] = ffit->GetNDF(); // obtain ndf\n", "\n", " return (ffit); // return fit function\n", "\n", "}" ] }, { "cell_type": "markdown", "id": "6dc7df8f", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 3, "id": "c9209263", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:05.649203Z", "iopub.status.busy": "2026-05-19T20:25:05.649085Z", "iopub.status.idle": "2026-05-19T20:25:05.653173Z", "shell.execute_reply": "2026-05-19T20:25:05.652639Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "int langaupro(double *params, double &maxx, double &FWHM) {\n", "\n", " // Searches for the location (x value) at the maximum of the\n", " // Landau-Gaussian convolute and its full width at half-maximum.\n", " //\n", " // The search is probably not very efficient, but it's a first try.\n", "\n", " double p,x,fy,fxr,fxl;\n", " double step;\n", " double l,lold;\n", " int i = 0;\n", " int MAXCALLS = 10000;\n", "\n", "\n", " // Search for maximum\n", "\n", " p = params[1] - 0.1 * params[0];\n", " step = 0.05 * params[0];\n", " lold = -2.0;\n", " l = -1.0;\n", "\n", "\n", " while ( (l != lold) && (i < MAXCALLS) ) {\n", " i++;\n", "\n", " lold = l;\n", " x = p + step;\n", " l = langaufun(&x,params);\n", "\n", " if (l < lold)\n", " step = -step/10;\n", "\n", " p += step;\n", " }\n", "\n", " if (i == MAXCALLS)\n", " return (-1);\n", "\n", " maxx = x;\n", "\n", " fy = l/2;\n", "\n", "\n", " // Search for right x location of fy\n", "\n", " p = maxx + params[0];\n", " step = params[0];\n", " lold = -2.0;\n", " l = -1e300;\n", " i = 0;\n", "\n", "\n", " while ( (l != lold) && (i < MAXCALLS) ) {\n", " i++;\n", "\n", " lold = l;\n", " x = p + step;\n", " l = TMath::Abs(langaufun(&x,params) - fy);\n", "\n", " if (l > lold)\n", " step = -step/10;\n", "\n", " p += step;\n", " }\n", "\n", " if (i == MAXCALLS)\n", " return (-2);\n", "\n", " fxr = x;\n", "\n", "\n", " // Search for left x location of fy\n", "\n", " p = maxx - 0.5 * params[0];\n", " step = -params[0];\n", " lold = -2.0;\n", " l = -1e300;\n", " i = 0;\n", "\n", " while ( (l != lold) && (i < MAXCALLS) ) {\n", " i++;\n", "\n", " lold = l;\n", " x = p + step;\n", " l = TMath::Abs(langaufun(&x,params) - fy);\n", "\n", " if (l > lold)\n", " step = -step/10;\n", "\n", " p += step;\n", " }\n", "\n", " if (i == MAXCALLS)\n", " return (-3);\n", "\n", "\n", " fxl = x;\n", "\n", " FWHM = fxr - fxl;\n", " return (0);\n", "}" ] }, { "cell_type": "markdown", "id": "a02160eb", "metadata": {}, "source": [ "Fill Histogram" ] }, { "cell_type": "code", "execution_count": 4, "id": "3b0b8d3c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:05.654385Z", "iopub.status.busy": "2026-05-19T20:25:05.654269Z", "iopub.status.idle": "2026-05-19T20:25:05.969278Z", "shell.execute_reply": "2026-05-19T20:25:05.968686Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_47:2:2: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n", " int data[100] = {0,0,0,0,0,0,2,6,11,18,18,55,90,141,255,323,454,563,681,\n", " ^\n" ] } ], "source": [ "int data[100] = {0,0,0,0,0,0,2,6,11,18,18,55,90,141,255,323,454,563,681,\n", " 737,821,796,832,720,637,558,519,460,357,291,279,241,212,\n", " 153,164,139,106,95,91,76,80,80,59,58,51,30,49,23,35,28,23,\n", " 22,27,27,24,20,16,17,14,20,12,12,13,10,17,7,6,12,6,12,4,\n", " 9,9,10,3,4,5,2,4,1,5,5,1,7,1,6,3,3,3,4,5,4,4,2,2,7,2,4};\n", "TH1F *hSNR = new TH1F(\"snr\",\"Signal-to-noise\",400,0,400);\n", "\n", "for (int i=0; i<100; i++) hSNR->Fill(i,data[i]);" ] }, { "cell_type": "markdown", "id": "137eeb82", "metadata": {}, "source": [ "Fitting SNR histo" ] }, { "cell_type": "code", "execution_count": 5, "id": "24528b08", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:05.970786Z", "iopub.status.busy": "2026-05-19T20:25:05.970667Z", "iopub.status.idle": "2026-05-19T20:25:06.175471Z", "shell.execute_reply": "2026-05-19T20:25:06.174826Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitting...\n" ] } ], "source": [ "printf(\"Fitting...\\n\");" ] }, { "cell_type": "markdown", "id": "db8c4171", "metadata": {}, "source": [ "Setting fit range and start values" ] }, { "cell_type": "code", "execution_count": 6, "id": "905fb761", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:06.176970Z", "iopub.status.busy": "2026-05-19T20:25:06.176851Z", "iopub.status.idle": "2026-05-19T20:25:06.384005Z", "shell.execute_reply": "2026-05-19T20:25:06.383519Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "Minimizer is Minuit2 / Migrad\n", "Chi2 = 5.25252\n", "NDf = 64\n", "Edm = 6.48548e-07\n", "NCalls = 184\n", "Width = 1.25725 +/- 0.304795 \t (limited)\n", "MP = 20.8889 +/- 1.2821 \t (limited)\n", "Area = 11552.8 +/- 2422.85 \t (limited)\n", "GSigma = 4.0632 +/- 0.758575 \t (limited)\n", "Fitting done\n", "Plotting results...\n" ] } ], "source": [ "double fr[2];\n", "double sv[4], pllo[4], plhi[4], fp[4], fpe[4];\n", "fr[0]=0.3*hSNR->GetMean();\n", "fr[1]=3.0*hSNR->GetMean();\n", "\n", "pllo[0]=0.5; pllo[1]=5.0; pllo[2]=1.0; pllo[3]=0.4;\n", "plhi[0]=5.0; plhi[1]=50.0; plhi[2]=1000000.0; plhi[3]=5.0;\n", "sv[0]=1.8; sv[1]=20.0; sv[2]=50000.0; sv[3]=3.0;\n", "\n", "double chisqr;\n", "int ndf;\n", "TF1 *fitsnr = langaufit(hSNR,fr,sv,pllo,plhi,fp,fpe,&chisqr,&ndf);\n", "\n", "double SNRPeak, SNRFWHM;\n", "langaupro(fp,SNRPeak,SNRFWHM);\n", "\n", "printf(\"Fitting done\\nPlotting results...\\n\");" ] }, { "cell_type": "markdown", "id": "98de4f91", "metadata": {}, "source": [ "Global style settings" ] }, { "cell_type": "code", "execution_count": 7, "id": "5758584e", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:06.399419Z", "iopub.status.busy": "2026-05-19T20:25:06.399281Z", "iopub.status.idle": "2026-05-19T20:25:06.604278Z", "shell.execute_reply": "2026-05-19T20:25:06.603651Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Info in : created default TCanvas with name c1\n" ] } ], "source": [ "gStyle->SetOptStat(1111);\n", "gStyle->SetOptFit(111);\n", "gStyle->SetLabelSize(0.03,\"x\");\n", "gStyle->SetLabelSize(0.03,\"y\");\n", "\n", "hSNR->GetXaxis()->SetRange(0,70);\n", "hSNR->Draw();\n", "fitsnr->Draw(\"lsame\");" ] }, { "cell_type": "markdown", "id": "608f4e04", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 8, "id": "cb603315", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:25:06.614493Z", "iopub.status.busy": "2026-05-19T20:25:06.614365Z", "iopub.status.idle": "2026-05-19T20:25:06.835904Z", "shell.execute_reply": "2026-05-19T20:25:06.832667Z" } }, "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 }