{
"cells": [
{
"cell_type": "markdown",
"id": "95904730",
"metadata": {},
"source": [
"# rf619_discrete_profiling\n",
"Basic functionality: demonstrate fitting multiple models using RooMultiPdf and selecting the best one via Discrete\n",
"Profiling method.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Galin Bistrev \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:34 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e67a1f08",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:05.587807Z",
"iopub.status.busy": "2026-05-19T20:34:05.587698Z",
"iopub.status.idle": "2026-05-19T20:34:05.911927Z",
"shell.execute_reply": "2026-05-19T20:34:05.911211Z"
}
},
"outputs": [],
"source": [
"using namespace RooFit;"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a04a7f38",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:05.914282Z",
"iopub.status.busy": "2026-05-19T20:34:05.914160Z",
"iopub.status.idle": "2026-05-19T20:34:06.123079Z",
"shell.execute_reply": "2026-05-19T20:34:06.122281Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"Observable\", 0, 50);"
]
},
{
"cell_type": "markdown",
"id": "fe6fddd7",
"metadata": {},
"source": [
"Category 0 Pdf-s: Exponential + Chebyshev."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d1421898",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:06.125024Z",
"iopub.status.busy": "2026-05-19T20:34:06.124904Z",
"iopub.status.idle": "2026-05-19T20:34:06.333710Z",
"shell.execute_reply": "2026-05-19T20:34:06.333023Z"
}
},
"outputs": [],
"source": [
"RooRealVar lambda1(\"lambda1\", \"slope1\", -0.025, -0.1, -0.02);\n",
"RooExponential expo1(\"expo1\", \"Exponential 1\", x, lambda1);\n",
"\n",
"RooRealVar c0(\"c0\", \"Cheby coeff 0\", -1.0, -1.0, 1.0);\n",
"RooRealVar c1(\"c1\", \"Cheby coeff 1\", 0.4, 0.05, 0.5);\n",
"RooArgList chebCoeffs(c0, c1);\n",
"RooChebychev cheb(\"cheb\", \"Chebyshev PDF\", x, chebCoeffs);\n",
"\n",
"RooCategory pdfIndex0(\"pdfIndex0\", \"pdf index 0\");\n",
"RooMultiPdf multiPdf0(\"multiPdf0\", \"multiPdf0\", pdfIndex0, RooArgList(expo1, cheb));"
]
},
{
"cell_type": "markdown",
"id": "82e09d9d",
"metadata": {},
"source": [
"Adding complexity to the model via introdcing exponential pdf."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "0fd8b363",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:06.336100Z",
"iopub.status.busy": "2026-05-19T20:34:06.335973Z",
"iopub.status.idle": "2026-05-19T20:34:06.545158Z",
"shell.execute_reply": "2026-05-19T20:34:06.544338Z"
}
},
"outputs": [],
"source": [
"RooRealVar lambdaExtra(\"lambdaExtra\", \"extra slope\", -0.05, -1.0, -0.01);\n",
"RooExponential expoExtra(\"expoExtra\", \"extra exponential\", x, lambdaExtra);"
]
},
{
"cell_type": "markdown",
"id": "793703c9",
"metadata": {},
"source": [
"Category 1 Pdf-s: Gaussian + Landau."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "96443ebb",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:06.547412Z",
"iopub.status.busy": "2026-05-19T20:34:06.547289Z",
"iopub.status.idle": "2026-05-19T20:34:06.756172Z",
"shell.execute_reply": "2026-05-19T20:34:06.755497Z"
}
},
"outputs": [],
"source": [
"RooRealVar mean(\"mean\", \"shared mean\", 25, 0, 50);\n",
"RooRealVar sigmaG(\"sigmaG\", \"Gaussian width\", 2.0, 0.01, 5.0);\n",
"RooRealVar sigmaL(\"sigmaL\", \"Landau width\", 3.0, 1.0, 8.0);\n",
"\n",
"RooGaussian gauss1(\"gauss1\", \"Gaussian\", x, mean, sigmaG);\n",
"RooLandau landau1(\"landau1\", \"Landau\", x, mean, sigmaL);\n",
"\n",
"RooCategory pdfIndex1(\"pdfIndex1\", \"pdf index 1\");\n",
"RooMultiPdf multiPdf1(\"multiPdf1\", \"multiPdf1\", pdfIndex1, RooArgList(gauss1, landau1));"
]
},
{
"cell_type": "markdown",
"id": "730a1675",
"metadata": {},
"source": [
"Adding complexity to the model via introdcing gaussExtra pdf. Profile scan in this model\n",
"will also be done over a shared parameter from both models (mean)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "cd2eebf7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:06.758111Z",
"iopub.status.busy": "2026-05-19T20:34:06.757988Z",
"iopub.status.idle": "2026-05-19T20:34:06.966844Z",
"shell.execute_reply": "2026-05-19T20:34:06.966127Z"
}
},
"outputs": [],
"source": [
"RooRealVar sigmaExtra(\"sigmaExtra\", \"extra Gaussian width\", 3.0, 1.0, 6.0);\n",
"RooGaussian gaussExtra(\"gaussExtra\", \"extra Gaussian\", x, mean, sigmaExtra);"
]
},
{
"cell_type": "markdown",
"id": "c76f1303",
"metadata": {},
"source": [
"Creation of AddPdf objects.Add multiple PDFs into a single model for each category."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c2d70823",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:06.968654Z",
"iopub.status.busy": "2026-05-19T20:34:06.968514Z",
"iopub.status.idle": "2026-05-19T20:34:07.177339Z",
"shell.execute_reply": "2026-05-19T20:34:07.176725Z"
}
},
"outputs": [],
"source": [
"RooRealVar frac0(\"frac0\", \"fraction for cat0\", 0.7, 0.0, 1.0);\n",
"RooAddPdf addPdf0(\"addPdf0\", \"multiPdf0 + extra expo\", RooArgList(multiPdf0, gaussExtra), frac0);\n",
"\n",
"RooRealVar frac1(\"frac1\", \"fraction for cat1\", 0.5, 0.0, 1.0);\n",
"RooAddPdf addPdf1(\"addPdf1\", \"multiPdf1 + extra gauss\", RooArgList(multiPdf1, expoExtra), frac1);"
]
},
{
"cell_type": "markdown",
"id": "e6094a16",
"metadata": {},
"source": [
"Simultaneous Pdf across categories."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "eaa4f4b0",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:07.179422Z",
"iopub.status.busy": "2026-05-19T20:34:07.179307Z",
"iopub.status.idle": "2026-05-19T20:34:07.385101Z",
"shell.execute_reply": "2026-05-19T20:34:07.384424Z"
}
},
"outputs": [],
"source": [
"RooCategory catIndex(\"catIndex\", \"Category\");\n",
"catIndex.defineType(\"cat0\", 0);\n",
"catIndex.defineType(\"cat1\", 1);\n",
"\n",
"RooSimultaneous simPdf(\"simPdf\", \"simultaneous model\", catIndex);\n",
"simPdf.addPdf(addPdf0, \"cat0\");\n",
"simPdf.addPdf(addPdf1, \"cat1\");"
]
},
{
"cell_type": "markdown",
"id": "35a405d8",
"metadata": {},
"source": [
"Generate toy data for each AddPdf."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "e37605a6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:07.386817Z",
"iopub.status.busy": "2026-05-19T20:34:07.386702Z",
"iopub.status.idle": "2026-05-19T20:34:07.595365Z",
"shell.execute_reply": "2026-05-19T20:34:07.594713Z"
}
},
"outputs": [],
"source": [
"RooDataSet *data0 = addPdf0.generate(x, 800);\n",
"RooDataSet *data1 = addPdf1.generate(x, 1000);"
]
},
{
"cell_type": "markdown",
"id": "8fc9fc69",
"metadata": {},
"source": [
"Ploting individual Pdf-s"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "46cb0320",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:07.597131Z",
"iopub.status.busy": "2026-05-19T20:34:07.597014Z",
"iopub.status.idle": "2026-05-19T20:34:07.802849Z",
"shell.execute_reply": "2026-05-19T20:34:07.802132Z"
}
},
"outputs": [],
"source": [
"RooPlot *frame0 = x.frame();\n",
"data0->plotOn(frame0);\n",
"addPdf0.plotOn(frame0);\n",
"pdfIndex0.setIndex(1);\n",
"addPdf0.plotOn(frame0, LineColor(kRed));\n",
"frame0->SetTitle(\"\");\n",
"frame0->GetXaxis()->SetTitle(\"Observable\");\n",
"frame0->GetYaxis()->SetTitle(\"Events\");\n",
"\n",
"TLegend *leg0 = new TLegend(0.6, 0.7, 0.9, 0.9);\n",
"leg0->AddEntry(frame0->getObject(0), \"Data\", \"lep\"); // Data points\n",
"leg0->AddEntry(frame0->getObject(1), \"Expo \", \"l\");\n",
"leg0->AddEntry(frame0->getObject(2), \"Poly\", \"l\");"
]
},
{
"cell_type": "markdown",
"id": "11aad103",
"metadata": {},
"source": [
"Ploting individual Pdf-s - Category 1"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "5e1f6bc6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:07.804547Z",
"iopub.status.busy": "2026-05-19T20:34:07.804434Z",
"iopub.status.idle": "2026-05-19T20:34:08.010248Z",
"shell.execute_reply": "2026-05-19T20:34:08.009619Z"
}
},
"outputs": [],
"source": [
"RooPlot *frame1 = x.frame();\n",
"data1->plotOn(frame1);\n",
"addPdf1.plotOn(frame1);\n",
"pdfIndex1.setIndex(1);\n",
"addPdf1.plotOn(frame1, LineColor(kRed));\n",
"frame1->SetTitle(\"\");\n",
"frame1->GetXaxis()->SetTitle(\"Observable\");\n",
"frame1->GetYaxis()->SetTitle(\"Events\");"
]
},
{
"cell_type": "markdown",
"id": "0d730586",
"metadata": {},
"source": [
"Create legend for Category 1"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "62c02c0c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:08.012130Z",
"iopub.status.busy": "2026-05-19T20:34:08.012014Z",
"iopub.status.idle": "2026-05-19T20:34:08.217824Z",
"shell.execute_reply": "2026-05-19T20:34:08.217118Z"
}
},
"outputs": [],
"source": [
"TLegend *leg1 = new TLegend(0.6, 0.7, 0.9, 0.9);\n",
"leg1->AddEntry(frame1->getObject(0), \"Data\", \"lep\"); // Data points\n",
"leg1->AddEntry(frame1->getObject(1), \"Gauss\", \"l\");\n",
"leg1->AddEntry(frame1->getObject(2), \"Landau\", \"l\");"
]
},
{
"cell_type": "markdown",
"id": "d7c5f7f4",
"metadata": {},
"source": [
"Combine datasets for simultaneous fit."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "3fdf931f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:08.219424Z",
"iopub.status.busy": "2026-05-19T20:34:08.219310Z",
"iopub.status.idle": "2026-05-19T20:34:08.421739Z",
"shell.execute_reply": "2026-05-19T20:34:08.421158Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_60:2:2: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n",
" RooDataSet *data = new RooDataSet(\"data\", \"combined\", RooArgSet(x, catIndex));\n",
" ^\n"
]
}
],
"source": [
"RooDataSet *data = new RooDataSet(\"data\", \"combined\", RooArgSet(x, catIndex));\n",
"\n",
"RooArgSet vars(x, catIndex);\n",
"\n",
"for (int i = 0; i < data0->numEntries(); ++i) {\n",
" x.setVal(data0->get(i)->getRealValue(\"x\"));\n",
" catIndex.setLabel(\"cat0\");\n",
" data->add(vars);\n",
"}\n",
"for (int i = 0; i < data1->numEntries(); ++i) {\n",
" x.setVal(data1->get(i)->getRealValue(\"x\"));\n",
" catIndex.setLabel(\"cat1\");\n",
" data->add(vars);\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "a968f4b0",
"metadata": {},
"source": [
"Create an NLL and minimize it via the discrete profiling method."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "512f4d3c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:08.423090Z",
"iopub.status.busy": "2026-05-19T20:34:08.422979Z",
"iopub.status.idle": "2026-05-19T20:34:08.678497Z",
"shell.execute_reply": "2026-05-19T20:34:08.654843Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_61:2:53: error: reference to 'data' is ambiguous\n",
" std::unique_ptr nll1(simPdf.createNLL(*data));\n",
" ^\n",
"input_line_60:2:14: note: candidate found by name lookup is 'data'\n",
" RooDataSet *data = new RooDataSet(\"data\", \"combined\", RooArgSet(x, catIndex));\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n",
" data(initializer_list<_Tp> __il) noexcept\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:323:5: note: candidate found by name lookup is 'std::data'\n",
" data(const _Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:334:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Tp (&__array)[_Nm]) noexcept\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr nll1(simPdf.createNLL(*data));\n",
"RooMinimizer minim(*nll1);\n",
"\n",
"minim.setStrategy(1);\n",
"minim.setEps(1e-7);\n",
"minim.setPrintLevel(-1);"
]
},
{
"cell_type": "markdown",
"id": "cdca3d4e",
"metadata": {},
"source": [
"Setup profiling of 'mean' over discrete combinations."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "ce298b11",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:08.694882Z",
"iopub.status.busy": "2026-05-19T20:34:08.694746Z",
"iopub.status.idle": "2026-05-19T20:34:08.950337Z",
"shell.execute_reply": "2026-05-19T20:34:08.947640Z"
}
},
"outputs": [],
"source": [
"const int nMeanPoints = 40;\n",
"const double meanMin = 17;\n",
"const double meanMax = 33;"
]
},
{
"cell_type": "markdown",
"id": "afd31239",
"metadata": {},
"source": [
"Generate all discrete combinations of PDF indices for profiling."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "fe9ecd4d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:08.969752Z",
"iopub.status.busy": "2026-05-19T20:34:08.969599Z",
"iopub.status.idle": "2026-05-19T20:34:09.280151Z",
"shell.execute_reply": "2026-05-19T20:34:09.279520Z"
}
},
"outputs": [],
"source": [
"std::vector> combosToPlot;\n",
"for (int i = 0; i < pdfIndex0.size(); ++i) {\n",
" for (int j = 0; j < pdfIndex1.size(); ++j) {\n",
" combosToPlot.push_back({i, j});\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "cb621ba1",
"metadata": {},
"source": [
"Creates a canvas where all NLL vs mean will be drawn."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "2a296c37",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:09.292362Z",
"iopub.status.busy": "2026-05-19T20:34:09.292232Z",
"iopub.status.idle": "2026-05-19T20:34:09.500756Z",
"shell.execute_reply": "2026-05-19T20:34:09.500358Z"
}
},
"outputs": [],
"source": [
"TCanvas *c = new TCanvas(\"c_rf619\", \"NLL vs Mean for Different Discrete Combinations\", 1200, 400);\n",
"c->Divide(3, 1);"
]
},
{
"cell_type": "markdown",
"id": "18fc13f7",
"metadata": {},
"source": [
"Define arrays of ROOT colors and marker styles."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "5251c1b3",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:09.506410Z",
"iopub.status.busy": "2026-05-19T20:34:09.506296Z",
"iopub.status.idle": "2026-05-19T20:34:09.714781Z",
"shell.execute_reply": "2026-05-19T20:34:09.714197Z"
}
},
"outputs": [],
"source": [
"int colors[] = {kRed, kBlue, kGreen + 2, kMagenta, kOrange + 7};\n",
"int markers[] = {20, 21, 22, 23, 33};"
]
},
{
"cell_type": "markdown",
"id": "c8566ee2",
"metadata": {},
"source": [
"Container to store all TGraph objects:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "687adbcf",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:09.716097Z",
"iopub.status.busy": "2026-05-19T20:34:09.715987Z",
"iopub.status.idle": "2026-05-19T20:34:09.924353Z",
"shell.execute_reply": "2026-05-19T20:34:09.923896Z"
}
},
"outputs": [],
"source": [
"std::vector graphs;"
]
},
{
"cell_type": "markdown",
"id": "3964b377",
"metadata": {},
"source": [
"Create one TGraph for each discrete combination of indices.\n",
"Each graph will hold the NLL vs mean curve for that combination.\n",
"Colors and marker styles are cycled through the predefined arrays."
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "c5528e2c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:09.926209Z",
"iopub.status.busy": "2026-05-19T20:34:09.926099Z",
"iopub.status.idle": "2026-05-19T20:34:10.128197Z",
"shell.execute_reply": "2026-05-19T20:34:10.127623Z"
}
},
"outputs": [],
"source": [
"for (size_t idx = 0; idx < combosToPlot.size(); ++idx) {\n",
" TGraph *g = new TGraph(nMeanPoints);\n",
" g->SetLineColor(colors[idx % 5]);\n",
" g->SetMarkerColor(colors[idx % 5]);\n",
" g->SetMarkerStyle(markers[idx % 5]);\n",
" g->SetTitle(Form(\"Combo [%d,%d]\", combosToPlot[idx][0], combosToPlot[idx][1]));\n",
" graphs.push_back(g);\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "f55bc2f6",
"metadata": {},
"source": [
"Create a special TGraph for the profiled NLL curve across all combinations.\n",
"Drawn in bold black to stand out."
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "2256dd8f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:10.129568Z",
"iopub.status.busy": "2026-05-19T20:34:10.129455Z",
"iopub.status.idle": "2026-05-19T20:34:10.337988Z",
"shell.execute_reply": "2026-05-19T20:34:10.337408Z"
}
},
"outputs": [],
"source": [
"TGraph *profileGraph = new TGraph(nMeanPoints);\n",
"profileGraph->SetLineColor(kBlack);\n",
"profileGraph->SetLineWidth(4);\n",
"profileGraph->SetMarkerColor(kBlack);\n",
"profileGraph->SetMarkerStyle(22);\n",
"profileGraph->SetTitle(\"Profile\");\n",
"graphs.push_back(profileGraph);"
]
},
{
"cell_type": "markdown",
"id": "c93139a1",
"metadata": {},
"source": [
"Loop over mean values, compute NLL and profile likelihood."
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "42cde871",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:10.339311Z",
"iopub.status.busy": "2026-05-19T20:34:10.339190Z",
"iopub.status.idle": "2026-05-19T20:34:10.554186Z",
"shell.execute_reply": "2026-05-19T20:34:10.547713Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_72:2:3: error: use of undeclared identifier 'minim'\n",
" (minim.minimize(\"Minuit2\", \"Migrad\"))\n",
" ^\n",
"Error in : Error evaluating expression (minim.minimize(\"Minuit2\", \"Migrad\"))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"for (int i = 0; i < nMeanPoints; ++i) {\n",
"\n",
" // Fix the \"mean\" parameter at this scan point\n",
" double meanVal = meanMin + i * (meanMax - meanMin) / (nMeanPoints - 1);\n",
" mean.setVal(meanVal);\n",
"\n",
" // Loop over all discrete PDF index combinations\n",
" for (size_t comboIdx = 0; comboIdx < combosToPlot.size(); ++comboIdx) {\n",
" const auto &combo = combosToPlot[comboIdx];\n",
"\n",
" // Fix both category indices to this combination\n",
" pdfIndex0.setIndex(combo[0]);\n",
" pdfIndex1.setIndex(combo[1]);\n",
"\n",
" // Freeze discrete indices and the mean parameter\n",
" // so the minimizer only optimizes continuous parameters\n",
" pdfIndex0.setConstant(true);\n",
" pdfIndex1.setConstant(true);\n",
" mean.setConstant(true);\n",
"\n",
" // Minimize over the continuous parameters\n",
" // Evaluate NLL at this configuration\n",
" minim.minimize(\"Minuit2\", \"Migrad\");\n",
" double nllVal = nll1->getVal();\n",
"\n",
" // Store NLL vs. mean value in the corresponding graph\n",
" graphs[comboIdx]->SetPoint(i, meanVal, nllVal);\n",
"\n",
" // Unfreeze categories and mean so the next loop iteration can change thems\n",
" pdfIndex0.setConstant(false);\n",
" pdfIndex1.setConstant(false);\n",
" mean.setConstant(false);\n",
" }\n",
"\n",
" // Freeze mean (profiling at this value)\n",
" mean.setConstant(true);\n",
"\n",
" // Scan all discrete combinations internally\n",
" minim.minimize(\"Minuit2\", \"Migrad\");\n",
"\n",
" // Store profiled NLL and plot it\n",
" double profNLL = nll1->getVal();\n",
" graphs.back()->SetPoint(i, meanVal, profNLL);\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "fd8800a0",
"metadata": {},
"source": [
"Panel 1: Category 0"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "d22e3fb1",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:10.559467Z",
"iopub.status.busy": "2026-05-19T20:34:10.559346Z",
"iopub.status.idle": "2026-05-19T20:34:10.767925Z",
"shell.execute_reply": "2026-05-19T20:34:10.767328Z"
}
},
"outputs": [],
"source": [
"c->cd(1);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame0->GetYaxis()->SetTitleOffset(1.4);\n",
"frame0->Draw();\n",
"if (leg0)\n",
" leg0->Draw();"
]
},
{
"cell_type": "markdown",
"id": "e02f1abf",
"metadata": {},
"source": [
"Panel 2: Category 1"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "5954d025",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:10.769288Z",
"iopub.status.busy": "2026-05-19T20:34:10.769177Z",
"iopub.status.idle": "2026-05-19T20:34:10.977596Z",
"shell.execute_reply": "2026-05-19T20:34:10.977045Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"c->cd(2);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame1->GetYaxis()->SetTitleOffset(1.4);\n",
"frame1->Draw();\n",
"if (leg1)\n",
" leg1->Draw();\n",
"\n",
"c->cd(3);\n",
"gPad->SetLeftMargin(0.15);\n",
"\n",
"TMultiGraph *mg = new TMultiGraph();\n",
"for (auto &g : graphs) {\n",
" mg->Add(g, \"PL\");\n",
" mg->GetYaxis()->SetTitleOffset(1.8);\n",
"}\n",
"\n",
"mg->Draw(\"APL\");\n",
"mg->GetXaxis()->SetTitle(\"Mean\");\n",
"mg->GetYaxis()->SetTitle(\"NLL\");\n",
"\n",
"gPad->BuildLegend();"
]
},
{
"cell_type": "markdown",
"id": "8937763e",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "1a6e2e9a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:10.978858Z",
"iopub.status.busy": "2026-05-19T20:34:10.978745Z",
"iopub.status.idle": "2026-05-19T20:34:11.193426Z",
"shell.execute_reply": "2026-05-19T20:34:11.192910Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%jsroot on\n",
"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
}