{
"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
}