{ "cells": [ { "cell_type": "markdown", "id": "ec855427", "metadata": {}, "source": [ "# rf613_global_observables\n", "This tutorial explains the concept of global observables in RooFit, and\n", "showcases how their values can be stored either in the model or in the\n", "dataset.\n", "\n", "### Introduction\n", "\n", "Note: in this tutorial, we are multiplying the likelihood with an additional\n", "likelihood to constrain the parameters with auxiliary measurements. This is\n", "different from the `rf604_constraints` tutorial, where the likelihood is\n", "multiplied with a Bayesian prior to constrain the parameters.\n", "\n", "\n", "With RooFit, you usually optimize some model parameters `p` to maximize the\n", "likelihood `L` given the per-event or per-bin observations `x`:\n", "\n", "\n", "Often, the parameters are constrained with some prior likelihood `C`, which\n", "doesn't depend on the observables `x`:\n", "\n", "\n", "Usually, these constraint terms depend on some auxiliary measurements of\n", "other observables `g`. The constraint term is then the likelihood of the\n", "so-called global observables:\n", "\n", "\n", "For example, think of a model where the true luminosity `lumi` is a\n", "nuisance parameter that is constrained by an auxiliary measurement\n", "`lumi_obs` with uncertainty `lumi_obs_sigma`:\n", "\n", "\n", "As a Gaussian is symmetric under exchange of the observable and the mean\n", "parameter, you can also sometimes find this equivalent but less conventional\n", "formulation for Gaussian constraints:\n", "\n", "\n", "If you wanted to constrain a parameter that represents event counts, you\n", "would use a Poissonian constraint, e.g.:\n", "\n", "\n", "Unlike a Gaussian, a Poissonian is not symmetric under exchange of the\n", "observable and the parameter, so here you need to be more careful to follow\n", "the global observable prescription correctly.\n", "\n", "\n", "\n", "\n", "\n", "**Author:** Jonas Rembser \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:33 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "cfe1a54c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:42.936546Z", "iopub.status.busy": "2026-05-19T20:33:42.936409Z", "iopub.status.idle": "2026-05-19T20:33:43.259625Z", "shell.execute_reply": "2026-05-19T20:33:43.258958Z" } }, "outputs": [], "source": [ "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "0bb422e4", "metadata": {}, "source": [ "Silence info output for this tutorial" ] }, { "cell_type": "code", "execution_count": 2, "id": "e1a21255", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:43.261599Z", "iopub.status.busy": "2026-05-19T20:33:43.261479Z", "iopub.status.idle": "2026-05-19T20:33:43.470381Z", "shell.execute_reply": "2026-05-19T20:33:43.469662Z" } }, "outputs": [], "source": [ "RooMsgService::instance().getStream(1).removeTopic(Minimization);\n", "RooMsgService::instance().getStream(1).removeTopic(Fitting);" ] }, { "cell_type": "markdown", "id": "a7b4ead5", "metadata": {}, "source": [ "Setting up the model and creating toy dataset\n", "---------------------------------------------" ] }, { "cell_type": "markdown", "id": "b6ecab74", "metadata": {}, "source": [ "l'(x | mu, sigma) = l(x | mu, sigma) * Gauss(mu_obs | mu, 0.2)" ] }, { "cell_type": "markdown", "id": "fa6ae7ab", "metadata": {}, "source": [ "event observables" ] }, { "cell_type": "code", "execution_count": 3, "id": "b857e2d7", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:43.472353Z", "iopub.status.busy": "2026-05-19T20:33:43.472201Z", "iopub.status.idle": "2026-05-19T20:33:43.681299Z", "shell.execute_reply": "2026-05-19T20:33:43.680901Z" } }, "outputs": [], "source": [ "RooRealVar x(\"x\", \"x\", -10, 10);" ] }, { "cell_type": "markdown", "id": "48587d9c", "metadata": {}, "source": [ "parameters" ] }, { "cell_type": "code", "execution_count": 4, "id": "5655d386", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:43.683231Z", "iopub.status.busy": "2026-05-19T20:33:43.683110Z", "iopub.status.idle": "2026-05-19T20:33:43.898140Z", "shell.execute_reply": "2026-05-19T20:33:43.897475Z" } }, "outputs": [], "source": [ "RooRealVar mu(\"mu\", \"mu\", 0.0, -10, 10);\n", "RooRealVar sigma(\"sigma\", \"sigma\", 1.0, 0.1, 2.0);" ] }, { "cell_type": "markdown", "id": "f204edde", "metadata": {}, "source": [ "Gaussian model for event observables" ] }, { "cell_type": "code", "execution_count": 5, "id": "a1fc5f16", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:43.899857Z", "iopub.status.busy": "2026-05-19T20:33:43.899734Z", "iopub.status.idle": "2026-05-19T20:33:44.109059Z", "shell.execute_reply": "2026-05-19T20:33:44.107891Z" } }, "outputs": [], "source": [ "RooGaussian gauss(\"gauss\", \"gauss\", x, mu, sigma);" ] }, { "cell_type": "markdown", "id": "ce924f83", "metadata": {}, "source": [ "global observables (which are not parameters so they are constant)" ] }, { "cell_type": "code", "execution_count": 6, "id": "46d532d9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:44.110419Z", "iopub.status.busy": "2026-05-19T20:33:44.110303Z", "iopub.status.idle": "2026-05-19T20:33:44.319467Z", "shell.execute_reply": "2026-05-19T20:33:44.318292Z" } }, "outputs": [], "source": [ "RooRealVar mu_obs(\"mu_obs\", \"mu_obs\", 1.0, -10, 10);\n", "mu_obs.setConstant();" ] }, { "cell_type": "markdown", "id": "3de99da8", "metadata": {}, "source": [ "note: alternatively, one can create a constant with default limits using `RooRealVar(\"mu_obs\", \"mu_obs\", 1.0)`" ] }, { "cell_type": "markdown", "id": "73a469bd", "metadata": {}, "source": [ "constraint pdf" ] }, { "cell_type": "code", "execution_count": 7, "id": "eacc6d29", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:44.320877Z", "iopub.status.busy": "2026-05-19T20:33:44.320751Z", "iopub.status.idle": "2026-05-19T20:33:44.530162Z", "shell.execute_reply": "2026-05-19T20:33:44.529043Z" } }, "outputs": [], "source": [ "RooGaussian constraint(\"constraint\", \"constraint\", mu_obs, mu, 0.1);" ] }, { "cell_type": "markdown", "id": "adbaf741", "metadata": {}, "source": [ "full pdf including constraint pdf" ] }, { "cell_type": "code", "execution_count": 8, "id": "8a74c775", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:44.531483Z", "iopub.status.busy": "2026-05-19T20:33:44.531365Z", "iopub.status.idle": "2026-05-19T20:33:44.740621Z", "shell.execute_reply": "2026-05-19T20:33:44.739434Z" } }, "outputs": [], "source": [ "RooProdPdf model(\"model\", \"model\", {gauss, constraint});" ] }, { "cell_type": "markdown", "id": "e162610e", "metadata": {}, "source": [ "Generating toy data with randomized global observables\n", "------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "99cb08b6", "metadata": {}, "source": [ "For most toy-based statistical procedures, it is necessary to also\n", "randomize the global observable when generating toy datasets.\n", "\n", "To that end, let's generate a single event from the model and take the\n", "global observable value (the same is done in the RooStats:ToyMCSampler\n", "class):" ] }, { "cell_type": "code", "execution_count": 9, "id": "23e71fbc", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:44.742030Z", "iopub.status.busy": "2026-05-19T20:33:44.741907Z", "iopub.status.idle": "2026-05-19T20:33:44.951361Z", "shell.execute_reply": "2026-05-19T20:33:44.950173Z" } }, "outputs": [], "source": [ "std::unique_ptr dataGlob{model.generate({mu_obs}, 1)};" ] }, { "cell_type": "markdown", "id": "4ae20c2b", "metadata": {}, "source": [ "Next, we temporarily set the value of `mu_obs` to the randomized value for\n", "generating our toy dataset:" ] }, { "cell_type": "code", "execution_count": 10, "id": "0146f32e", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:44.952815Z", "iopub.status.busy": "2026-05-19T20:33:44.952697Z", "iopub.status.idle": "2026-05-19T20:33:45.161802Z", "shell.execute_reply": "2026-05-19T20:33:45.160658Z" } }, "outputs": [], "source": [ "double mu_obs_orig_val = mu_obs.getVal();\n", "\n", "RooArgSet{mu_obs}.assign(*dataGlob->get(0));" ] }, { "cell_type": "markdown", "id": "b9ee23db", "metadata": {}, "source": [ "Actually generate the toy dataset. We don't generate too many events,\n", "otherwise, the constraint will not have much weight in the fit and the\n", "result looks like it's unaffected by it." ] }, { "cell_type": "code", "execution_count": 11, "id": "a55745d4", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:45.163121Z", "iopub.status.busy": "2026-05-19T20:33:45.163004Z", "iopub.status.idle": "2026-05-19T20:33:45.392190Z", "shell.execute_reply": "2026-05-19T20:33:45.388365Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_58:2:2: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n", " std::unique_ptr data{model.generate({x}, 50)};\n", " ^\n" ] } ], "source": [ "std::unique_ptr data{model.generate({x}, 50)};" ] }, { "cell_type": "markdown", "id": "14e9f7ba", "metadata": {}, "source": [ "When fitting the toy dataset, it is important to set the global\n", "observables in the fit to the values that were used to generate the toy\n", "dataset. To facilitate the bookkeeping of global observable values, you\n", "can attach a snapshot with the current global observable values to the\n", "dataset like this (new feature introduced in ROOT 6.26):" ] }, { "cell_type": "code", "execution_count": 12, "id": "d7dc539a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:45.399975Z", "iopub.status.busy": "2026-05-19T20:33:45.399846Z", "iopub.status.idle": "2026-05-19T20:33:45.617869Z", "shell.execute_reply": "2026-05-19T20:33:45.617392Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_59:2:2: error: reference to 'data' is ambiguous\n", " data->setGlobalObservables({mu_obs});\n", " ^\n", "input_line_58:2:30: note: candidate found by name lookup is 'data'\n", " std::unique_ptr data{model.generate({x}, 50)};\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": [ "data->setGlobalObservables({mu_obs});" ] }, { "cell_type": "markdown", "id": "ed6d5986", "metadata": {}, "source": [ "reset original mu_obs value" ] }, { "cell_type": "code", "execution_count": 13, "id": "39ed36f3", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:45.619024Z", "iopub.status.busy": "2026-05-19T20:33:45.618914Z", "iopub.status.idle": "2026-05-19T20:33:45.827317Z", "shell.execute_reply": "2026-05-19T20:33:45.826782Z" } }, "outputs": [], "source": [ "mu_obs.setVal(mu_obs_orig_val);" ] }, { "cell_type": "markdown", "id": "61ff7c2d", "metadata": {}, "source": [ "Fitting a model with global observables\n", "---------------------------------------" ] }, { "cell_type": "markdown", "id": "6daef4bc", "metadata": {}, "source": [ "Create snapshot of original parameters to reset parameters after fitting" ] }, { "cell_type": "code", "execution_count": 14, "id": "2d7bb6dd", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:45.828807Z", "iopub.status.busy": "2026-05-19T20:33:45.828689Z", "iopub.status.idle": "2026-05-19T20:33:46.038040Z", "shell.execute_reply": "2026-05-19T20:33:46.037603Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_61:3:21: error: reference to 'data' is ambiguous\n", "model.getParameters(data->get(), modelParameters);\n", " ^\n", "input_line_58:2:30: note: candidate found by name lookup is 'data'\n", " std::unique_ptr data{model.generate({x}, 50)};\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": [ "RooArgSet modelParameters;\n", "model.getParameters(data->get(), modelParameters);\n", "RooArgSet origParameters;\n", "modelParameters.snapshot(origParameters);\n", "\n", "using FitRes = std::unique_ptr;" ] }, { "cell_type": "markdown", "id": "9d45f7f4", "metadata": {}, "source": [ "When you fit a model that includes global observables, you need to\n", "specify them in the call to RooAbsPdf::fitTo with the\n", "RooFit::GlobalObservables command argument. By default, the global\n", "observable values attached to the dataset will be prioritized over the\n", "values in the model, so the following fit correctly uses the randomized\n", "global observable values from the toy dataset:" ] }, { "cell_type": "code", "execution_count": 15, "id": "1891814e", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:46.039193Z", "iopub.status.busy": "2026-05-19T20:33:46.039085Z", "iopub.status.idle": "2026-05-19T20:33:46.249467Z", "shell.execute_reply": "2026-05-19T20:33:46.249023Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_62:4:1: error: unknown type name 'FitRes'\n", "FitRes res1{model.fitTo(*data, GlobalObservables(mu_obs), PrintLevel(-1), Save())};\n", "^\n", "input_line_62:4:26: error: reference to 'data' is ambiguous\n", "FitRes res1{model.fitTo(*data, GlobalObservables(mu_obs), PrintLevel(-1), Save())};\n", " ^\n", "input_line_58:2:30: note: candidate found by name lookup is 'data'\n", " std::unique_ptr data{model.generate({x}, 50)};\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", "input_line_62:6:1: error: use of undeclared identifier 'modelParameters'\n", "modelParameters.assign(origParameters);\n", "^\n", "input_line_62:6:24: error: use of undeclared identifier 'origParameters'\n", "modelParameters.assign(origParameters);\n", " ^\n" ] } ], "source": [ "std::cout << \"1. model.fitTo(*data, GlobalObservables(mu_obs))\\n\";\n", "std::cout << \"------------------------------------------------\\n\";\n", "FitRes res1{model.fitTo(*data, GlobalObservables(mu_obs), PrintLevel(-1), Save())};\n", "res1->Print();\n", "modelParameters.assign(origParameters);" ] }, { "cell_type": "markdown", "id": "d0b35dfc", "metadata": {}, "source": [ "In our example, the set of global observables is attached to the toy\n", "dataset. In this case, you can actually drop the GlobalObservables()\n", "command argument, because the global observables are automatically\n", "figured out from the data set (this fit result should be identical to the\n", "previous one)." ] }, { "cell_type": "code", "execution_count": 16, "id": "e26d070a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:46.250997Z", "iopub.status.busy": "2026-05-19T20:33:46.250868Z", "iopub.status.idle": "2026-05-19T20:33:46.460510Z", "shell.execute_reply": "2026-05-19T20:33:46.460090Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_63:4:1: error: unknown type name 'FitRes'\n", "FitRes res2{model.fitTo(*data, PrintLevel(-1), Save())};\n", "^\n", "input_line_63:4:26: error: reference to 'data' is ambiguous\n", "FitRes res2{model.fitTo(*data, PrintLevel(-1), Save())};\n", " ^\n", "input_line_58:2:30: note: candidate found by name lookup is 'data'\n", " std::unique_ptr data{model.generate({x}, 50)};\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", "input_line_63:6:1: error: use of undeclared identifier 'modelParameters'\n", "modelParameters.assign(origParameters);\n", "^\n", "input_line_63:6:24: error: use of undeclared identifier 'origParameters'\n", "modelParameters.assign(origParameters);\n", " ^\n" ] } ], "source": [ "std::cout << \"2. model.fitTo(*data)\\n\";\n", "std::cout << \"---------------------\\n\";\n", "FitRes res2{model.fitTo(*data, PrintLevel(-1), Save())};\n", "res2->Print();\n", "modelParameters.assign(origParameters);" ] }, { "cell_type": "markdown", "id": "e20f048f", "metadata": {}, "source": [ "If you want to explicitly ignore the global observables in the dataset,\n", "you can do that by specifying GlobalObservablesSource(\"model\"). Keep in\n", "mind that now it's also again your responsibility to define the set of\n", "global observables." ] }, { "cell_type": "code", "execution_count": 17, "id": "49bafd6b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:46.461724Z", "iopub.status.busy": "2026-05-19T20:33:46.461576Z", "iopub.status.idle": "2026-05-19T20:33:46.671440Z", "shell.execute_reply": "2026-05-19T20:33:46.671027Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_64:4:1: error: unknown type name 'FitRes'\n", "FitRes res3{model.fitTo(*data, GlobalObservables(mu_obs), GlobalObservablesSource(\"model\"), PrintLevel(-1), Save())};\n", "^\n", "input_line_64:4:26: error: reference to 'data' is ambiguous\n", "FitRes res3{model.fitTo(*data, GlobalObservables(mu_obs), GlobalObservablesSource(\"model\"), PrintLevel(-1), Save())};\n", " ^\n", "input_line_58:2:30: note: candidate found by name lookup is 'data'\n", " std::unique_ptr data{model.generate({x}, 50)};\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", "input_line_64:6:1: error: use of undeclared identifier 'modelParameters'\n", "modelParameters.assign(origParameters);\n", "^\n", "input_line_64:6:24: error: use of undeclared identifier 'origParameters'\n", "modelParameters.assign(origParameters);\n", " ^\n" ] } ], "source": [ "std::cout << \"3. model.fitTo(*data, GlobalObservables(mu_obs), GlobalObservablesSource(\\\"model\\\"))\\n\";\n", "std::cout << \"------------------------------------------------\\n\";\n", "FitRes res3{model.fitTo(*data, GlobalObservables(mu_obs), GlobalObservablesSource(\"model\"), PrintLevel(-1), Save())};\n", "res3->Print();\n", "modelParameters.assign(origParameters);" ] }, { "cell_type": "markdown", "id": "413a49b2", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 18, "id": "ee51c4ca", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:33:46.672596Z", "iopub.status.busy": "2026-05-19T20:33:46.672489Z", "iopub.status.idle": "2026-05-19T20:33:46.903653Z", "shell.execute_reply": "2026-05-19T20:33:46.903112Z" } }, "outputs": [], "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 }