{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4c5f0736",
   "metadata": {},
   "source": [
    "# rf102_dataimport\n",
    "'BASIC FUNCTIONALITY' RooFit tutorial macro #102\n",
    "Importing data from ROOT TTrees and THx histograms\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "**Author:**  Clemens Lange, Wouter Verkerke (C version)  \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:28 PM.</small></i>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8ee4bfdb",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:27.252506Z",
     "iopub.status.busy": "2026-05-19T20:28:27.252391Z",
     "iopub.status.idle": "2026-05-19T20:28:28.241995Z",
     "shell.execute_reply": "2026-05-19T20:28:28.241422Z"
    }
   },
   "outputs": [],
   "source": [
    "import ROOT\n",
    "from array import array\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "def makeTH1(trnd):\n",
    "\n",
    "    # Create ROOT ROOT.TH1 filled with a Gaussian distribution\n",
    "\n",
    "    hh = ROOT.TH1D(\"hh\", \"hh\", 25, -10, 10)\n",
    "    hh.Fill(np.array([trnd.Gaus(0, 3) for _ in range(100)]))\n",
    "    return hh\n",
    "\n",
    "\n",
    "def makeTTree(trnd):\n",
    "    # Create ROOT ROOT.TTree filled with a Gaussian distribution in x and a\n",
    "    # uniform distribution in y\n",
    "\n",
    "    tree = ROOT.TTree(\"tree\", \"tree\")\n",
    "    px = array(\"d\", [0])\n",
    "    py = array(\"d\", [0])\n",
    "    tree.Branch(\"x\", px, \"x/D\")\n",
    "    tree.Branch(\"y\", py, \"y/D\")\n",
    "    for i in range(100):\n",
    "        px[0] = trnd.Gaus(0, 3)\n",
    "        py[0] = trnd.Uniform() * 30 - 15\n",
    "        tree.Fill()\n",
    "    return tree\n",
    "\n",
    "trnd = ROOT.TRandom3()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9389280",
   "metadata": {},
   "source": [
    "##########################\n",
    "Importing ROOT histograms\n",
    "##########################\n",
    "Import ROOT TH1 into a RooDataHist\n",
    "---------------------------------------------------------\n",
    "Create a ROOT TH1 histogram"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8f78651a",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:28.243773Z",
     "iopub.status.busy": "2026-05-19T20:28:28.243547Z",
     "iopub.status.idle": "2026-05-19T20:28:28.378348Z",
     "shell.execute_reply": "2026-05-19T20:28:28.377818Z"
    }
   },
   "outputs": [],
   "source": [
    "hh = makeTH1(trnd)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33076d06",
   "metadata": {},
   "source": [
    "Declare observable x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "47709660",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:28.379988Z",
     "iopub.status.busy": "2026-05-19T20:28:28.379862Z",
     "iopub.status.idle": "2026-05-19T20:28:28.530961Z",
     "shell.execute_reply": "2026-05-19T20:28:28.530394Z"
    }
   },
   "outputs": [],
   "source": [
    "x = ROOT.RooRealVar(\"x\", \"x\", -10, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b8f9d5d",
   "metadata": {},
   "source": [
    "Create a binned dataset that imports contents of ROOT.TH1 and associates\n",
    "its contents to observable 'x'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a0214f2b",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:28.532549Z",
     "iopub.status.busy": "2026-05-19T20:28:28.532422Z",
     "iopub.status.idle": "2026-05-19T20:28:28.791425Z",
     "shell.execute_reply": "2026-05-19T20:28:28.790894Z"
    }
   },
   "outputs": [],
   "source": [
    "dh = ROOT.RooDataHist(\"dh\", \"dh\", [x], Import=hh)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04642fe2",
   "metadata": {},
   "source": [
    "Plot and fit a RooDataHist\n",
    "---------------------------------------------------\n",
    "Make plot of binned dataset showing Poisson error bars (RooFit default)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2348f258",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:28.793016Z",
     "iopub.status.busy": "2026-05-19T20:28:28.792891Z",
     "iopub.status.idle": "2026-05-19T20:28:28.940654Z",
     "shell.execute_reply": "2026-05-19T20:28:28.940154Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x5618b4a52ce0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame = x.frame(Title=\"Imported ROOT.TH1 with Poisson error bars\")\n",
    "dh.plotOn(frame)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b75c0c8",
   "metadata": {},
   "source": [
    "Fit a Gaussian p.d.f to the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "812bd93d",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:28.942592Z",
     "iopub.status.busy": "2026-05-19T20:28:28.942461Z",
     "iopub.status.idle": "2026-05-19T20:28:29.182991Z",
     "shell.execute_reply": "2026-05-19T20:28:29.182396Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:Fitting -- RooAbsPdf::fitTo(gauss_over_gauss_Int[x]) 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 7.02287 ms\n",
      "[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_gauss_over_gauss_Int[x]_dh) Summation contains a RooNLLVar, using its error level\n",
      "[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x5618b4a52ce0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean = ROOT.RooRealVar(\"mean\", \"mean\", 0, -10, 10)\n",
    "sigma = ROOT.RooRealVar(\"sigma\", \"sigma\", 3, 0.1, 10)\n",
    "gauss = ROOT.RooGaussian(\"gauss\", \"gauss\", x, mean, sigma)\n",
    "gauss.fitTo(dh, PrintLevel=-1)\n",
    "gauss.plotOn(frame)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b1d1750",
   "metadata": {},
   "source": [
    "Plot and fit a RooDataHist with internal errors\n",
    "---------------------------------------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7df070a7",
   "metadata": {},
   "source": [
    "If histogram has custom error (i.e. its contents is does not originate from a Poisson process\n",
    "but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead\n",
    "(same error bars as shown by ROOT)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1357223d",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.184769Z",
     "iopub.status.busy": "2026-05-19T20:28:29.184637Z",
     "iopub.status.idle": "2026-05-19T20:28:29.293911Z",
     "shell.execute_reply": "2026-05-19T20:28:29.293307Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x5618b4e53030>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame2 = x.frame(Title=\"Imported ROOT.TH1 with internal errors\")\n",
    "dh.plotOn(frame2, DataError=\"SumW2\")\n",
    "gauss.plotOn(frame2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6351282f",
   "metadata": {},
   "source": [
    "Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used\n",
    "in a maximum likelihood fit\n",
    "\n",
    "A (binned) ML fit will ALWAYS assume the Poisson error interpretation of data (the mathematical definition\n",
    "of likelihood does not take any external definition of errors). Data with non-unit weights can only be correctly\n",
    "fitted with a chi^2 fit (see rf602_chi2fit.py)\n",
    "\n",
    "Importing ROOT TTrees\n",
    "-----------------------------------------------------------\n",
    "Import ROOT TTree into a RooDataSet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "34d2646c",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.296022Z",
     "iopub.status.busy": "2026-05-19T20:28:29.295893Z",
     "iopub.status.idle": "2026-05-19T20:28:29.424959Z",
     "shell.execute_reply": "2026-05-19T20:28:29.424209Z"
    }
   },
   "outputs": [],
   "source": [
    "tree = makeTTree(trnd)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2aaa3027",
   "metadata": {},
   "source": [
    "Define 2nd observable y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1688314f",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.427084Z",
     "iopub.status.busy": "2026-05-19T20:28:29.426955Z",
     "iopub.status.idle": "2026-05-19T20:28:29.530595Z",
     "shell.execute_reply": "2026-05-19T20:28:29.529825Z"
    }
   },
   "outputs": [],
   "source": [
    "y = ROOT.RooRealVar(\"y\", \"y\", -10, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3a9e080",
   "metadata": {},
   "source": [
    "Construct unbinned dataset importing tree branches x and y matching between branches and ROOT.RooRealVars\n",
    "is done by name of the branch/RRV\n",
    "\n",
    "Note that ONLY entries for which x,y have values within their allowed ranges as defined in\n",
    "ROOT.RooRealVar x and y are imported. Since the y values in the import tree are in the range [-15,15]\n",
    "and RRV y defines a range [-10,10] this means that the ROOT.RooDataSet\n",
    "below will have less entries than the ROOT.TTree 'tree'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "fc028426",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.532292Z",
     "iopub.status.busy": "2026-05-19T20:28:29.532165Z",
     "iopub.status.idle": "2026-05-19T20:28:29.701433Z",
     "shell.execute_reply": "2026-05-19T20:28:29.700835Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #0 because y cannot accommodate the value 14.424\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #3 because y cannot accommodate the value -12.0022\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #5 because y cannot accommodate the value 13.8261\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #6 because y cannot accommodate the value -14.9925\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping ...\n",
      "[#0] WARNING:DataHandling -- RooTreeDataStore::loadValues(ds) Ignored 36 out-of-range events\n"
     ]
    }
   ],
   "source": [
    "ds = ROOT.RooDataSet(\"ds\", \"ds\", {x, y}, Import=tree)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "559f3322",
   "metadata": {},
   "source": [
    "Use ascii import/export for datasets\n",
    "------------------------------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ed675d2f",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.703567Z",
     "iopub.status.busy": "2026-05-19T20:28:29.703439Z",
     "iopub.status.idle": "2026-05-19T20:28:29.842233Z",
     "shell.execute_reply": "2026-05-19T20:28:29.841519Z"
    }
   },
   "outputs": [],
   "source": [
    "def write_dataset(ds, filename):\n",
    "    # Write data to output stream\n",
    "    outstream = ROOT.std.ofstream(filename)\n",
    "    # Optionally, adjust the stream here (e.g. std::setprecision)\n",
    "    ds.write(outstream)\n",
    "    outstream.close()\n",
    "\n",
    "\n",
    "write_dataset(ds, \"rf102_testData.txt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20e07e14",
   "metadata": {},
   "source": [
    "Read data from input stream. The variables of the dataset need to be supplied\n",
    "to the RooDataSet::read() function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7348d002",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.844262Z",
     "iopub.status.busy": "2026-05-19T20:28:29.844136Z",
     "iopub.status.idle": "2026-05-19T20:28:29.961202Z",
     "shell.execute_reply": "2026-05-19T20:28:29.960347Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-----------------------\n",
      "Reading data from ASCII\n",
      "[#1] INFO:DataHandling -- RooDataSet::read: reading file rf102_testData.txt\n",
      "[#1] INFO:DataHandling -- RooDataSet::read: read 64 events (ignored 0 out of range events)\n",
      "DataStore dataset (rf102_testData.txt)\n",
      "  Contains 64 entries\n",
      "  Observables: \n",
      "    1)           x = 9.46654  L(-10 - 10)  \"x\"\n",
      "    2)           y = 0.0174204  L(-10 - 10)  \"y\"\n",
      "    3)  blindState = Normal(idx = 0)\n",
      "  \"Blinding State\"\n",
      "\n",
      "Original data, line 20:\n",
      "\n",
      "Read-back data, line 20:\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  1) RooRealVar:: y = 0.0106407\n",
      "  2) RooRealVar:: x = -0.79919\n",
      "  1) RooRealVar::          x = 0.0106407\n",
      "  2) RooRealVar::          y = -0.79919\n",
      "  3) RooCategory:: blindState = Normal(idx = 0)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n-----------------------\\nReading data from ASCII\")\n",
    "dataReadBack = ROOT.RooDataSet.read(\n",
    "    \"rf102_testData.txt\",\n",
    "    [x, y],  # variables to be read. If the file has more fields, these are ignored.\n",
    "    \"D\",  # Prints if a RooFit message stream listens for debug messages. Use Q for quiet.\n",
    ")\n",
    "\n",
    "dataReadBack.Print(\"V\")\n",
    "\n",
    "print(\"\\nOriginal data, line 20:\")\n",
    "ds.get(20).Print(\"V\")\n",
    "\n",
    "print(\"\\nRead-back data, line 20:\")\n",
    "dataReadBack.get(20).Print(\"V\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14ecb6ff",
   "metadata": {},
   "source": [
    "Plot data set with multiple binning choices\n",
    "------------------------------------------------------------------------------------\n",
    "Print number of events in dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "7eaef6b9",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:29.963071Z",
     "iopub.status.busy": "2026-05-19T20:28:29.962903Z",
     "iopub.status.idle": "2026-05-19T20:28:30.067114Z",
     "shell.execute_reply": "2026-05-19T20:28:30.066420Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RooDataSet::ds[y,x] = 64 entries\n"
     ]
    }
   ],
   "source": [
    "ds.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f2a3bef",
   "metadata": {},
   "source": [
    "Print unbinned dataset with default frame binning (100 bins)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "29addcf8",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:30.072773Z",
     "iopub.status.busy": "2026-05-19T20:28:30.072640Z",
     "iopub.status.idle": "2026-05-19T20:28:30.177429Z",
     "shell.execute_reply": "2026-05-19T20:28:30.176656Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x5618b3b1bda0>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame3 = y.frame(Title=\"Unbinned data shown in default frame binning\")\n",
    "ds.plotOn(frame3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12e212af",
   "metadata": {},
   "source": [
    "Print unbinned dataset with custom binning choice (20 bins)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "cf4c35b6",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:30.179161Z",
     "iopub.status.busy": "2026-05-19T20:28:30.179023Z",
     "iopub.status.idle": "2026-05-19T20:28:30.302409Z",
     "shell.execute_reply": "2026-05-19T20:28:30.301702Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x5618b559f350>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame4 = y.frame(Title=\"Unbinned data shown with custom binning\")\n",
    "ds.plotOn(frame4, Binning=20)\n",
    "\n",
    "frame5 = y.frame(Title=\"Unbinned data read back from ASCII file\")\n",
    "ds.plotOn(frame5, Binning=20)\n",
    "dataReadBack.plotOn(frame5, Binning=20, MarkerColor=\"r\", MarkerStyle=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3bf4497",
   "metadata": {},
   "source": [
    "Draw all frames on a canvas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "44820598",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:30.304178Z",
     "iopub.status.busy": "2026-05-19T20:28:30.304041Z",
     "iopub.status.idle": "2026-05-19T20:28:30.572494Z",
     "shell.execute_reply": "2026-05-19T20:28:30.571802Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Info in <TCanvas::Print>: png file rf102_dataimport.png has been created\n"
     ]
    }
   ],
   "source": [
    "c = ROOT.TCanvas(\"rf102_dataimport\", \"rf102_dataimport\", 800, 800)\n",
    "c.Divide(3, 2)\n",
    "c.cd(1)\n",
    "ROOT.gPad.SetLeftMargin(0.15)\n",
    "frame.GetYaxis().SetTitleOffset(1.4)\n",
    "frame.Draw()\n",
    "c.cd(2)\n",
    "ROOT.gPad.SetLeftMargin(0.15)\n",
    "frame2.GetYaxis().SetTitleOffset(1.4)\n",
    "frame2.Draw()\n",
    "c.cd(4)\n",
    "ROOT.gPad.SetLeftMargin(0.15)\n",
    "frame3.GetYaxis().SetTitleOffset(1.4)\n",
    "frame3.Draw()\n",
    "c.cd(5)\n",
    "ROOT.gPad.SetLeftMargin(0.15)\n",
    "frame4.GetYaxis().SetTitleOffset(1.4)\n",
    "frame4.Draw()\n",
    "c.cd(6)\n",
    "ROOT.gPad.SetLeftMargin(0.15)\n",
    "frame4.GetYaxis().SetTitleOffset(1.4)\n",
    "frame5.Draw()\n",
    "\n",
    "c.SaveAs(\"rf102_dataimport.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a89cb32",
   "metadata": {},
   "source": [
    "Draw all canvases "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "17c0cc34",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:28:30.574704Z",
     "iopub.status.busy": "2026-05-19T20:28:30.574553Z",
     "iopub.status.idle": "2026-05-19T20:28:30.763215Z",
     "shell.execute_reply": "2026-05-19T20:28:30.762463Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "\n",
       "<div id=\"root_plot_1779222510753\" style=\"width: 800px; height: 800px; position: relative\">\n",
       "</div>\n",
       "\n",
       "</div>\n",
       "<script>\n",
       "   function process_root_plot_1779222510753() {\n",
       "      function execCode(Core) {\n",
       "         Core.settings.HandleKeys = false;\n",
       "         \n",
       "Core.unzipJSON(65579,'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').then(json => {\n",
       "   const obj = Core.parse(json);\n",
       "   Core.draw('root_plot_1779222510753', obj, '');\n",
       "});\n",
       "\n",
       "      }\n",
       "      const servers = ['/static/', 'https://root.cern/js/7.11.0/', 'https://jsroot.gsi.de/7.11.0/'],\n",
       "            path = 'build/jsroot';\n",
       "      if (typeof JSROOT !== 'undefined')\n",
       "         execCode(JSROOT);\n",
       "      else if (typeof requirejs !== 'undefined') {\n",
       "         servers.forEach((s,i) => { servers[i] = s + path; });\n",
       "         requirejs.config({ paths: { 'jsroot' : servers } })(['jsroot'],  execCode);\n",
       "      } else {\n",
       "         const config = document.getElementById('jupyter-config-data');\n",
       "         if (config)\n",
       "            servers[0] = (JSON.parse(config.innerHTML || '{}')?.baseUrl || '/') + 'static/';\n",
       "         else\n",
       "            servers.shift();\n",
       "         function loadJsroot() {\n",
       "            return !servers.length ? 0 : import(servers.shift() + path + '.js').catch(loadJsroot).then(() => execCode(JSROOT));\n",
       "         }\n",
       "         loadJsroot();\n",
       "      }\n",
       "   }\n",
       "   process_root_plot_1779222510753();\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "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
}
