{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0d1c8546",
   "metadata": {},
   "source": [
    "# rf515_hfJSON\n",
    "Code HistFactory Models in JSON.\n",
    "\n",
    "With the HS3 standard, it is possible to code RooFit-Models of any kind as JSON files.\n",
    "In this tutorial, you can see how to code up a (simple) HistFactory-based model in JSON and import it into a RooWorkspace.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "**Author:** Carsten Burgard  \n",
    "<i><small>This notebook tutorial was automatically generated with <a href= \"https://github.com/root-project/root/blob/master/documentation/doxygen/converttonotebook.py\">ROOTBOOK-izer</a> from the macro found in the ROOT repository  on Tuesday, May 19, 2026 at 08:32 PM.</small></i>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cdc538f9",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:54.613529Z",
     "iopub.status.busy": "2026-05-19T20:32:54.613406Z",
     "iopub.status.idle": "2026-05-19T20:32:55.595833Z",
     "shell.execute_reply": "2026-05-19T20:32:55.595134Z"
    }
   },
   "outputs": [],
   "source": [
    "import ROOT"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4643e65d",
   "metadata": {},
   "source": [
    "start by creating an empty workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a921b025",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:55.597646Z",
     "iopub.status.busy": "2026-05-19T20:32:55.597499Z",
     "iopub.status.idle": "2026-05-19T20:32:55.732435Z",
     "shell.execute_reply": "2026-05-19T20:32:55.732019Z"
    }
   },
   "outputs": [],
   "source": [
    "ws = ROOT.RooWorkspace(\"workspace\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdf29c85",
   "metadata": {},
   "source": [
    "the RooJSONFactoryWSTool is responsible for importing and exporting things to and from your workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "813b9379",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:55.734577Z",
     "iopub.status.busy": "2026-05-19T20:32:55.734456Z",
     "iopub.status.idle": "2026-05-19T20:32:55.869021Z",
     "shell.execute_reply": "2026-05-19T20:32:55.868332Z"
    }
   },
   "outputs": [],
   "source": [
    "tool = ROOT.RooJSONFactoryWSTool(ws)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "980a4816",
   "metadata": {},
   "source": [
    "use it to import the information from your JSON file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4b07a502",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:55.870642Z",
     "iopub.status.busy": "2026-05-19T20:32:55.870500Z",
     "iopub.status.idle": "2026-05-19T20:32:56.004816Z",
     "shell.execute_reply": "2026-05-19T20:32:56.004231Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#2] INFO:HistFactory -- Creating constraint for: gamma_stat_channel1_bin_0. Type of constraint: 1\n",
      "[#2] INFO:HistFactory -- Creating constraint for: gamma_stat_channel1_bin_1. Type of constraint: 1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooPoisson::gamma_stat_channel1_bin_0_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_gamma_stat_channel1_bin_0\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooProduct::gamma_stat_channel1_bin_0_poisMean\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) using existing copy of RooRealVar::gamma_stat_channel1_bin_0 for import of RooPoisson::gamma_stat_channel1_bin_0_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooConstVar::gamma_stat_channel1_bin_0_tau\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooPoisson::gamma_stat_channel1_bin_1_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_gamma_stat_channel1_bin_1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooProduct::gamma_stat_channel1_bin_1_poisMean\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) using existing copy of RooRealVar::gamma_stat_channel1_bin_1 for import of RooPoisson::gamma_stat_channel1_bin_1_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooConstVar::gamma_stat_channel1_bin_1_tau\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset model_channel1_signal_dataHist\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset model_channel1_background1_dataHist\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset model_channel1_background2_dataHist\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset observed\n",
      "\n",
      "RooWorkspace(workspace) workspace contents\n",
      "\n",
      "variables\n",
      "---------\n",
      "(alpha_syst1,alpha_syst2,alpha_syst3,channelCat,gamma_stat_channel1_bin_0,gamma_stat_channel1_bin_1,mu,nom_alpha_syst1,nom_alpha_syst2,nom_alpha_syst3,nom_gamma_stat_channel1_bin_0,nom_gamma_stat_channel1_bin_1,obs_x_channel1)\n",
      "\n",
      "p.d.f.s\n",
      "-------\n",
      "RooGaussian::alpha_syst1Constraint[ x=alpha_syst1 mean=nom_alpha_syst1 sigma=1 ] = 1\n",
      "RooGaussian::alpha_syst2Constraint[ x=alpha_syst2 mean=nom_alpha_syst2 sigma=1 ] = 1\n",
      "RooGaussian::alpha_syst3Constraint[ x=alpha_syst3 mean=nom_alpha_syst3 sigma=1 ] = 1\n",
      "RooRealSumPdf::channel1_model[ model_channel1_signal_scaleFactors * model_channel1_signal_shapes + model_channel1_background1_scaleFactors * model_channel1_background1_shapes + model_channel1_background2_scaleFactors * model_channel1_background2_shapes ] = 220\n",
      "RooPoisson::gamma_stat_channel1_bin_0_constraint[ x=nom_gamma_stat_channel1_bin_0 mean=gamma_stat_channel1_bin_0_poisMean ] = 0.019943\n",
      "RooPoisson::gamma_stat_channel1_bin_1_constraint[ x=nom_gamma_stat_channel1_bin_1 mean=gamma_stat_channel1_bin_1_poisMean ] = 0.039861\n",
      "RooSimultaneous::main[ indexCat=channelCat channel1=model_channel1 ] = 0.174888\n",
      "RooProdPdf::model_channel1[ gamma_stat_channel1_bin_0_constraint * gamma_stat_channel1_bin_1_constraint * alpha_syst1Constraint * alpha_syst2Constraint * alpha_syst3Constraint * channel1_model(obs_x_channel1) ] = 0.174888\n",
      "\n",
      "functions\n",
      "--------\n",
      "RooStats::HistFactory::FlexibleInterpVar::background1_channel1_epsilon[ paramList=(alpha_syst2) ] = 1\n",
      "RooStats::HistFactory::FlexibleInterpVar::background2_channel1_epsilon[ paramList=(alpha_syst3) ] = 1\n",
      "RooProduct::gamma_stat_channel1_bin_0_poisMean[ gamma_stat_channel1_bin_0 * gamma_stat_channel1_bin_0_tau ] = 400\n",
      "RooProduct::gamma_stat_channel1_bin_1_poisMean[ gamma_stat_channel1_bin_1 * gamma_stat_channel1_bin_1_tau ] = 100\n",
      "RooHistFunc::hist_model_channel1_background1[ depList=(obs_x_channel1) ] = 0\n",
      "RooHistFunc::hist_model_channel1_background2[ depList=(obs_x_channel1) ] = 100\n",
      "RooHistFunc::hist_model_channel1_signal[ depList=(obs_x_channel1) ] = 10\n",
      "ParamHistFunc::mc_stat_channel1[ ] = 1\n",
      "RooBinWidthFunction::model_channel1_background1_binWidth[ HistFuncForBinWidth=hist_model_channel1_background1 ] = 2\n",
      "RooProduct::model_channel1_background1_scaleFactors[ background1_channel1_epsilon ] = 1\n",
      "RooProduct::model_channel1_background1_shapes[ model_channel1_background1_binWidth * mc_stat_channel1 * hist_model_channel1_background1 ] = 0\n",
      "RooBinWidthFunction::model_channel1_background2_binWidth[ HistFuncForBinWidth=hist_model_channel1_background2 ] = 2\n",
      "RooProduct::model_channel1_background2_scaleFactors[ background2_channel1_epsilon ] = 1\n",
      "RooProduct::model_channel1_background2_shapes[ model_channel1_background2_binWidth * mc_stat_channel1 * hist_model_channel1_background2 ] = 200\n",
      "RooBinWidthFunction::model_channel1_signal_binWidth[ HistFuncForBinWidth=hist_model_channel1_signal ] = 2\n",
      "RooProduct::model_channel1_signal_scaleFactors[ mu * signal_channel1_epsilon ] = 1\n",
      "RooProduct::model_channel1_signal_shapes[ model_channel1_signal_binWidth * hist_model_channel1_signal ] = 20\n",
      "RooStats::HistFactory::FlexibleInterpVar::signal_channel1_epsilon[ paramList=(alpha_syst1) ] = 1\n",
      "\n",
      "datasets\n",
      "--------\n",
      "RooDataSet::observed(channelCat,obs_x_channel1)\n",
      "\n",
      "embedded datasets (in pdfs and functions)\n",
      "-----------------------------------------\n",
      "RooDataHist::model_channel1_signal_dataHist(obs_x_channel1)\n",
      "RooDataHist::model_channel1_background1_dataHist(obs_x_channel1)\n",
      "RooDataHist::model_channel1_background2_dataHist(obs_x_channel1)\n",
      "\n",
      "named sets\n",
      "----------\n",
      "ModelConfig_GlobalObservables:()\n",
      "ModelConfig_NuisParams:()\n",
      "ModelConfig_Observables:(obs_x_channel1)\n",
      "ModelConfig_POI:(mu)\n",
      "\n",
      "generic objects\n",
      "---------------\n",
      "RooStats::ModelConfig::ModelConfig\n",
      "\n"
     ]
    }
   ],
   "source": [
    "tool.importJSON(ROOT.gROOT.GetTutorialDir().Data() + \"/roofit/roofit/rf515_hfJSON.json\")\n",
    "ws.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecbc521b",
   "metadata": {},
   "source": [
    "now, you can easily use your workspace to run your fit (as you usually would)\n",
    "the model config is named after your pdf, i.e. <the pdf name>_modelConfig"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9108dffa",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.006918Z",
     "iopub.status.busy": "2026-05-19T20:32:56.006792Z",
     "iopub.status.idle": "2026-05-19T20:32:56.153679Z",
     "shell.execute_reply": "2026-05-19T20:32:56.152899Z"
    }
   },
   "outputs": [],
   "source": [
    "model = ws[\"ModelConfig\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e93a3c0",
   "metadata": {},
   "source": [
    "for resetting the parameters after the fit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e64536d1",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.155366Z",
     "iopub.status.busy": "2026-05-19T20:32:56.155241Z",
     "iopub.status.idle": "2026-05-19T20:32:56.310478Z",
     "shell.execute_reply": "2026-05-19T20:32:56.309779Z"
    }
   },
   "outputs": [],
   "source": [
    "params = model.GetPdf().getParameters(ws[\"observed\"])\n",
    "ROOT.SetOwnership(params, True)\n",
    "params_initial = params.snapshot()\n",
    "ROOT.SetOwnership(params_initial, True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a11bf2e5",
   "metadata": {},
   "source": [
    "we are fitting a clone of the model now,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "73da046b",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.312119Z",
     "iopub.status.busy": "2026-05-19T20:32:56.311996Z",
     "iopub.status.idle": "2026-05-19T20:32:56.515554Z",
     "shell.execute_reply": "2026-05-19T20:32:56.514968Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:Minimization -- p.d.f. provides expected number of events, including extended term in likelihood.\n",
      "[#1] INFO:Minimization --  Including the following constraint terms in minimization: (gamma_stat_channel1_bin_0_constraint,gamma_stat_channel1_bin_1_constraint,alpha_syst1Constraint,alpha_syst2Constraint,alpha_syst3Constraint)\n",
      "[#1] INFO:Minimization -- The following global observables have been defined and their values are taken from the model: ()\n",
      "[#1] INFO:Fitting -- RooAbsPdf::fitTo(main) fixing normalization set for coefficient determination to observables in data\n",
      "[#1] INFO:Fitting -- using generic CPU library compiled with no vectorizations\n",
      "[#1] INFO:Fitting -- Creation of NLL object took 1.48943 ms\n",
      "[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_main_observed) Summation contains a RooNLLVar, using its error level\n",
      "[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(_channel1_model_channel1_signal_shapes_Int[_channel1_obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(_channel1_model_channel1_background1_shapes_Int[_channel1_obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(_channel1_model_channel1_background2_shapes_Int[_channel1_obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_channel1_signal_shapes_Int[obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_channel1_background1_shapes_Int[obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_channel1_background2_shapes_Int[obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "  RooFitResult: minimized FCN value: -1035.62, estimated distance to minimum: 0.000225981\n",
      "                covariance matrix quality: Full, accurate covariance matrix\n",
      "                Status : MINIMIZE=0 HESSE=0 \n",
      "\n",
      "    Floating Parameter    FinalValue +/-  Error   \n",
      "  --------------------  --------------------------\n",
      "           alpha_syst1   -4.9434e-03 +/-  9.93e-01\n",
      "           alpha_syst2   -9.4922e-03 +/-  9.82e-01\n",
      "           alpha_syst3    1.5278e-02 +/-  9.48e-01\n",
      "  gamma_stat_channel1_bin_0    9.9956e-01 +/-  4.93e-02\n",
      "  gamma_stat_channel1_bin_1    1.0051e+00 +/-  8.02e-02\n",
      "                    mu    1.1095e+00 +/-  6.04e-01\n",
      "\n"
     ]
    }
   ],
   "source": [
    "result = model.fitTo(ws[\"observed\"], ROOT.RooFit.Save(), ROOT.RooFit.PrintLevel(-1))\n",
    "ROOT.SetOwnership(result, True)\n",
    "result.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e67fb0bf",
   "metadata": {},
   "source": [
    "reset parameters, such that we are not double-fitting the model in the\n",
    "closure check."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "17796fc8",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.517433Z",
     "iopub.status.busy": "2026-05-19T20:32:56.517220Z",
     "iopub.status.idle": "2026-05-19T20:32:56.624086Z",
     "shell.execute_reply": "2026-05-19T20:32:56.623647Z"
    }
   },
   "outputs": [],
   "source": [
    "params.assign(params_initial)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ceb3473",
   "metadata": {},
   "source": [
    "in the end, you can again write to json\n",
    "the result will be not completely identical to the JSON file you used as an input, but it will work just the same"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "76cfc2d0",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.632532Z",
     "iopub.status.busy": "2026-05-19T20:32:56.632403Z",
     "iopub.status.idle": "2026-05-19T20:32:56.743251Z",
     "shell.execute_reply": "2026-05-19T20:32:56.742834Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tool.exportJSON(\"myWorkspace.json\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48b8cb84",
   "metadata": {},
   "source": [
    "You can again import it if you want and check for closure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "29439c51",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.745432Z",
     "iopub.status.busy": "2026-05-19T20:32:56.745305Z",
     "iopub.status.idle": "2026-05-19T20:32:56.885023Z",
     "shell.execute_reply": "2026-05-19T20:32:56.884268Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::alpha_syst1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::alpha_syst2\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::alpha_syst3\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::gamma_stat_channel1_bin_0\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::gamma_stat_channel1_bin_1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::mu\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_alpha_syst1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_alpha_syst2\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_alpha_syst3\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::obs_x_channel1\n",
      "[#1] INFO:Eval -- RooRealVar::setRange(mu) new range named 'main_observed_parameters_of_interest' created with bounds [-3,5]\n",
      "[#2] INFO:HistFactory -- Creating constraint for: gamma_stat_channel1_bin_0. Type of constraint: 1\n",
      "[#2] INFO:HistFactory -- Creating constraint for: gamma_stat_channel1_bin_1. Type of constraint: 1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooPoisson::gamma_stat_channel1_bin_0_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_gamma_stat_channel1_bin_0\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooProduct::gamma_stat_channel1_bin_0_poisMean\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) using existing copy of RooRealVar::gamma_stat_channel1_bin_0 for import of RooPoisson::gamma_stat_channel1_bin_0_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooConstVar::gamma_stat_channel1_bin_0_tau\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooPoisson::gamma_stat_channel1_bin_1_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooRealVar::nom_gamma_stat_channel1_bin_1\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooProduct::gamma_stat_channel1_bin_1_poisMean\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) using existing copy of RooRealVar::gamma_stat_channel1_bin_1 for import of RooPoisson::gamma_stat_channel1_bin_1_constraint\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing RooConstVar::gamma_stat_channel1_bin_1_tau\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset model_channel1_background1_dataHist\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset model_channel1_background2_dataHist\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset model_channel1_signal_dataHist\n",
      "[#1] INFO:ObjectHandling -- RooWorkspace::import(workspace) importing dataset observed\n",
      "\n",
      "RooWorkspace(workspace) workspace contents\n",
      "\n",
      "variables\n",
      "---------\n",
      "(alpha_syst1,alpha_syst2,alpha_syst3,channelCat,gamma_stat_channel1_bin_0,gamma_stat_channel1_bin_1,mu,nom_alpha_syst1,nom_alpha_syst2,nom_alpha_syst3,nom_gamma_stat_channel1_bin_0,nom_gamma_stat_channel1_bin_1,obs_x_channel1)\n",
      "\n",
      "p.d.f.s\n",
      "-------\n",
      "RooGaussian::alpha_syst1Constraint[ x=alpha_syst1 mean=nom_alpha_syst1 sigma=1 ] = 1\n",
      "RooGaussian::alpha_syst2Constraint[ x=alpha_syst2 mean=nom_alpha_syst2 sigma=1 ] = 1\n",
      "RooGaussian::alpha_syst3Constraint[ x=alpha_syst3 mean=nom_alpha_syst3 sigma=1 ] = 1\n",
      "RooRealSumPdf::channel1_model[ model_channel1_background1_scaleFactors * model_channel1_background1_shapes + model_channel1_background2_scaleFactors * model_channel1_background2_shapes + model_channel1_signal_scaleFactors * model_channel1_signal_shapes ] = 220\n",
      "RooPoisson::gamma_stat_channel1_bin_0_constraint[ x=nom_gamma_stat_channel1_bin_0 mean=gamma_stat_channel1_bin_0_poisMean ] = 0.019943\n",
      "RooPoisson::gamma_stat_channel1_bin_1_constraint[ x=nom_gamma_stat_channel1_bin_1 mean=gamma_stat_channel1_bin_1_poisMean ] = 0.039861\n",
      "RooSimultaneous::main[ indexCat=channelCat channel1=model_channel1 ] = 0.174888\n",
      "RooProdPdf::model_channel1[ gamma_stat_channel1_bin_0_constraint * gamma_stat_channel1_bin_1_constraint * alpha_syst2Constraint * alpha_syst3Constraint * alpha_syst1Constraint * channel1_model(obs_x_channel1) ] = 0.174888\n",
      "\n",
      "functions\n",
      "--------\n",
      "RooStats::HistFactory::FlexibleInterpVar::background1_channel1_epsilon[ paramList=(alpha_syst2) ] = 1\n",
      "RooStats::HistFactory::FlexibleInterpVar::background2_channel1_epsilon[ paramList=(alpha_syst3) ] = 1\n",
      "RooProduct::gamma_stat_channel1_bin_0_poisMean[ gamma_stat_channel1_bin_0 * gamma_stat_channel1_bin_0_tau ] = 400\n",
      "RooProduct::gamma_stat_channel1_bin_1_poisMean[ gamma_stat_channel1_bin_1 * gamma_stat_channel1_bin_1_tau ] = 100\n",
      "RooHistFunc::hist_model_channel1_background1[ depList=(obs_x_channel1) ] = 0\n",
      "RooHistFunc::hist_model_channel1_background2[ depList=(obs_x_channel1) ] = 100\n",
      "RooHistFunc::hist_model_channel1_signal[ depList=(obs_x_channel1) ] = 10\n",
      "ParamHistFunc::mc_stat_channel1[ ] = 1\n",
      "RooBinWidthFunction::model_channel1_background1_binWidth[ HistFuncForBinWidth=hist_model_channel1_background1 ] = 2\n",
      "RooProduct::model_channel1_background1_scaleFactors[ background1_channel1_epsilon ] = 1\n",
      "RooProduct::model_channel1_background1_shapes[ model_channel1_background1_binWidth * mc_stat_channel1 * hist_model_channel1_background1 ] = 0\n",
      "RooBinWidthFunction::model_channel1_background2_binWidth[ HistFuncForBinWidth=hist_model_channel1_background2 ] = 2\n",
      "RooProduct::model_channel1_background2_scaleFactors[ background2_channel1_epsilon ] = 1\n",
      "RooProduct::model_channel1_background2_shapes[ model_channel1_background2_binWidth * mc_stat_channel1 * hist_model_channel1_background2 ] = 200\n",
      "RooBinWidthFunction::model_channel1_signal_binWidth[ HistFuncForBinWidth=hist_model_channel1_signal ] = 2\n",
      "RooProduct::model_channel1_signal_scaleFactors[ mu * signal_channel1_epsilon ] = 1\n",
      "RooProduct::model_channel1_signal_shapes[ model_channel1_signal_binWidth * hist_model_channel1_signal ] = 20\n",
      "RooStats::HistFactory::FlexibleInterpVar::signal_channel1_epsilon[ paramList=(alpha_syst1) ] = 1\n",
      "\n",
      "datasets\n",
      "--------\n",
      "RooDataSet::observed(channelCat,obs_x_channel1)\n",
      "\n",
      "embedded datasets (in pdfs and functions)\n",
      "-----------------------------------------\n",
      "RooDataHist::model_channel1_background1_dataHist(obs_x_channel1)\n",
      "RooDataHist::model_channel1_background2_dataHist(obs_x_channel1)\n",
      "RooDataHist::model_channel1_signal_dataHist(obs_x_channel1)\n",
      "\n",
      "parameter snapshots\n",
      "-------------------\n",
      "default_values = (alpha_syst1=0 +/- 1,alpha_syst2=0 +/- 1,alpha_syst3=0 +/- 1,gamma_stat_channel1_bin_0=1 +/- 0.05,gamma_stat_channel1_bin_1=1 +/- 0.1,mu=1,nom_alpha_syst1=0[C],nom_alpha_syst2=0[C],nom_alpha_syst3=0[C])\n",
      "\n",
      "named sets\n",
      "----------\n",
      "ModelConfig_GlobalObservables:()\n",
      "ModelConfig_NuisParams:()\n",
      "ModelConfig_Observables:(obs_x_channel1)\n",
      "ModelConfig_POI:(mu)\n",
      "\n",
      "generic objects\n",
      "---------------\n",
      "RooStats::ModelConfig::ModelConfig\n",
      "\n",
      "[#1] INFO:Minimization -- p.d.f. provides expected number of events, including extended term in likelihood.\n",
      "[#1] INFO:Minimization --  Including the following constraint terms in minimization: (gamma_stat_channel1_bin_0_constraint,gamma_stat_channel1_bin_1_constraint,alpha_syst2Constraint,alpha_syst3Constraint,alpha_syst1Constraint)\n",
      "[#1] INFO:Minimization -- The following global observables have been defined and their values are taken from the model: ()\n",
      "[#1] INFO:Fitting -- RooAbsPdf::fitTo(main) fixing normalization set for coefficient determination to observables in data\n",
      "[#1] INFO:Fitting -- Creation of NLL object took 783.983 μs\n",
      "[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_main_observed) Summation contains a RooNLLVar, using its error level\n",
      "[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(_channel1_model_channel1_background1_shapes_Int[_channel1_obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(_channel1_model_channel1_background2_shapes_Int[_channel1_obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(_channel1_model_channel1_signal_shapes_Int[_channel1_obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_channel1_background1_shapes_Int[obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_channel1_background2_shapes_Int[obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n",
      "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_channel1_signal_shapes_Int[obs_x_channel1]) using numeric integrator RooBinIntegrator to calculate Int(_channel1_obs_x_channel1)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "  RooFitResult: minimized FCN value: -1035.62, estimated distance to minimum: 0.000225981\n",
      "                covariance matrix quality: Full, accurate covariance matrix\n",
      "                Status : MINIMIZE=0 HESSE=0 \n",
      "\n",
      "    Floating Parameter    FinalValue +/-  Error   \n",
      "  --------------------  --------------------------\n",
      "           alpha_syst1   -4.9434e-03 +/-  9.93e-01\n",
      "           alpha_syst2   -9.4922e-03 +/-  9.82e-01\n",
      "           alpha_syst3    1.5278e-02 +/-  9.48e-01\n",
      "  gamma_stat_channel1_bin_0    9.9956e-01 +/-  4.93e-02\n",
      "  gamma_stat_channel1_bin_1    1.0051e+00 +/-  8.02e-02\n",
      "                    mu    1.1095e+00 +/-  6.04e-01\n",
      "\n"
     ]
    }
   ],
   "source": [
    "ws_2 = ROOT.RooWorkspace(\"workspace\")\n",
    "tool_2 = ROOT.RooJSONFactoryWSTool(ws_2)\n",
    "tool_2.importJSON(\"myWorkspace.json\")\n",
    "ws_2.Print()\n",
    "model_2 = ws_2[\"ModelConfig\"]\n",
    "result = model_2.fitTo(ws_2[\"observed\"], ROOT.RooFit.Save(), ROOT.RooFit.PrintLevel(-1))\n",
    "ROOT.SetOwnership(result, True)\n",
    "result.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "952d1d77",
   "metadata": {},
   "source": [
    "Draw all canvases "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ceaa23df",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:32:56.886875Z",
     "iopub.status.busy": "2026-05-19T20:32:56.886747Z",
     "iopub.status.idle": "2026-05-19T20:32:56.994280Z",
     "shell.execute_reply": "2026-05-19T20:32:56.993453Z"
    }
   },
   "outputs": [],
   "source": [
    "from ROOT import gROOT \n",
    "gROOT.GetListOfCanvases().Draw()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
