{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "735e9721",
   "metadata": {},
   "source": [
    "# rf402_datahandling\n",
    "Data and categories: tools for manipulation of (un)binned datasets\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:31 PM.</small></i>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "132f7ba9",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:33.035909Z",
     "iopub.status.busy": "2026-05-19T20:31:33.035790Z",
     "iopub.status.idle": "2026-05-19T20:31:33.992251Z",
     "shell.execute_reply": "2026-05-19T20:31:33.991568Z"
    }
   },
   "outputs": [],
   "source": [
    "import ROOT\n",
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15188d7b",
   "metadata": {},
   "source": [
    "WVE Add reduction by range"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60aa1d79",
   "metadata": {},
   "source": [
    "Binned (RooDataHist) and unbinned datasets (RooDataSet) share\n",
    "many properties and inherit from a common abstract base class\n",
    "(RooAbsData), provides an interface for all operations\n",
    "that can be performed regardless of the data format"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "30443c2c",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:33.994372Z",
     "iopub.status.busy": "2026-05-19T20:31:33.994238Z",
     "iopub.status.idle": "2026-05-19T20:31:34.164334Z",
     "shell.execute_reply": "2026-05-19T20:31:34.163765Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = ROOT.RooRealVar(\"x\", \"x\", -10, 10)\n",
    "y = ROOT.RooRealVar(\"y\", \"y\", 0, 40)\n",
    "c = ROOT.RooCategory(\"c\", \"c\")\n",
    "c.defineType(\"Plus\", +1)\n",
    "c.defineType(\"Minus\", -1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02906e5c",
   "metadata": {},
   "source": [
    "Basic operations on unbinned datasetss\n",
    "--------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ac644d2",
   "metadata": {},
   "source": [
    "ROOT.RooDataSet is an unbinned dataset (a collection of points in\n",
    "N-dimensional space)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ebaf92fa",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:34.166654Z",
     "iopub.status.busy": "2026-05-19T20:31:34.166510Z",
     "iopub.status.idle": "2026-05-19T20:31:34.360377Z",
     "shell.execute_reply": "2026-05-19T20:31:34.359716Z"
    }
   },
   "outputs": [],
   "source": [
    "d = ROOT.RooDataSet(\"d\", \"d\", {x, y, c})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0dc54a6c",
   "metadata": {},
   "source": [
    "Unlike ROOT.RooAbsArgs (ROOT.RooAbsPdf, ROOT.RooFormulaVar,....) datasets are not attached to\n",
    "the variables they are constructed from. Instead they are attached to an internal\n",
    "clone of the supplied set of arguments"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6b8209e",
   "metadata": {},
   "source": [
    "Fill d with dummy values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "1104a9fe",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:34.362552Z",
     "iopub.status.busy": "2026-05-19T20:31:34.362420Z",
     "iopub.status.idle": "2026-05-19T20:31:34.532873Z",
     "shell.execute_reply": "2026-05-19T20:31:34.532267Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RooRealVar::x = -10  L(-10 - 10) \n",
      " RooRealVar::y = 0  L(0 - 40) \n",
      " { {\"Minus\" , -1}, {\"Plus\" , 1} }\n",
      "<class cppyy.gbl.RooRealVar at 0x55682c6d6990>\n",
      "RooRealVar::x = -9.98  L(-10 - 10) \n",
      " RooRealVar::y = 1  L(0 - 40) \n",
      " { {\"Minus\" , -1}, {\"Plus\" , 1} }\n",
      "<class cppyy.gbl.RooRealVar at 0x55682c6d6990>\n",
      "RooRealVar::x = -9.96  L(-10 - 10) \n",
      " RooRealVar::y = 1.41421  L(0 - 40) \n",
      " { {\"Minus\" , -1}, {\"Plus\" , 1} }\n",
      "<class cppyy.gbl.RooRealVar at 0x55682c6d6990>\n",
      "\n",
      "DataStore d (d)\n",
      "  Contains 1000 entries\n",
      "  Observables: \n",
      "    1)  y = 31.607  L(0 - 40)  \"y\"\n",
      "    2)  x = 9.98  L(-10 - 10)  \"x\"\n",
      "    3)  c = Plus(idx = 1)\n",
      "  \"c\"\n"
     ]
    }
   ],
   "source": [
    "for i in range(1000):\n",
    "    x.setVal(i / 50 - 10)\n",
    "    y.setVal(math.sqrt(1.0 * i))\n",
    "    if i % 2:\n",
    "        c.setLabel(\"Plus\")\n",
    "    else:\n",
    "        c.setLabel(\"Minus\")\n",
    "\n",
    "    # We must explicitly refer to x,y, here to pass the values because\n",
    "    # d is not linked to them (as explained above)\n",
    "    if i < 3:\n",
    "        print(x, y, c)\n",
    "        print(type(x))\n",
    "    d.add({x, y, c})\n",
    "\n",
    "d.Print(\"v\")\n",
    "print(\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ab6a504",
   "metadata": {},
   "source": [
    "The get() function returns a pointer to the internal copy of the RooArgSet(x,y,c)\n",
    "supplied in the constructor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "41bcdd07",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:34.534683Z",
     "iopub.status.busy": "2026-05-19T20:31:34.534539Z",
     "iopub.status.idle": "2026-05-19T20:31:34.644542Z",
     "shell.execute_reply": "2026-05-19T20:31:34.644117Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  1) 0x556825620140 RooRealVar:: y = 31.607  L(0 - 40)  \"y\"\n",
      "  2) 0x55682c48e260 RooRealVar:: x = 9.98  L(-10 - 10)  \"x\"\n",
      "  3) 0x55682cbcecf0 RooCategory:: c = Plus(idx = 1)\n",
      "  \"c\"\n",
      "\n"
     ]
    }
   ],
   "source": [
    "row = d.get()\n",
    "row.Print(\"v\")\n",
    "print(\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba935212",
   "metadata": {},
   "source": [
    "Get with an argument loads a specific data point in row and returns\n",
    "a pointer to row argset. get() always returns the same pointer, unless\n",
    "an invalid row number is specified. In that case a null ptr is returned"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e538035b",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:34.663840Z",
     "iopub.status.busy": "2026-05-19T20:31:34.663687Z",
     "iopub.status.idle": "2026-05-19T20:31:34.772382Z",
     "shell.execute_reply": "2026-05-19T20:31:34.771817Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  1) 0x556825620140 RooRealVar:: y = 30  L(0 - 40)  \"y\"\n",
      "  2) 0x55682c48e260 RooRealVar:: x = 8  L(-10 - 10)  \"x\"\n",
      "  3) 0x55682cbcecf0 RooCategory:: c = Minus(idx = -1)\n",
      "  \"c\"\n"
     ]
    }
   ],
   "source": [
    "d.get(900).Print(\"v\")\n",
    "print(\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09a29f1f",
   "metadata": {},
   "source": [
    "Reducing, appending and merging\n",
    "-------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5eba4b29",
   "metadata": {},
   "source": [
    "The reduce() function returns a dataset which is a subset of the\n",
    "original"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6f66a2db",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:34.774135Z",
     "iopub.status.busy": "2026-05-19T20:31:34.774008Z",
     "iopub.status.idle": "2026-05-19T20:31:34.905780Z",
     "shell.execute_reply": "2026-05-19T20:31:34.905062Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " >> d1 has only columns x,c\n",
      "\n",
      " >> d2 has only column y\n",
      "\n",
      " >> d3 has only the points with y>5.17\n",
      "DataStore d (d)\n",
      "  Contains 1000 entries\n",
      "  Observables: \n",
      "    1)  c = Plus(idx = 1)\n",
      "  \"c\"\n",
      "    2)  x = 9.98  L(-10 - 10)  \"x\"\n",
      "DataStore d (d)\n",
      "  Contains 1000 entries\n",
      "  Observables: \n",
      "    1)  y = 31.607  L(0 - 40)  \"y\"\n",
      "\n",
      " >> d4 has only columns x, for data points with y>5.17\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataStore d (d)\n",
      "  Contains 973 entries\n",
      "  Observables: \n",
      "    1)  y = 31.607  L(0 - 40)  \"y\"\n",
      "    2)  x = 9.98  L(-10 - 10)  \"x\"\n",
      "    3)  c = Plus(idx = 1)\n",
      "  \"c\"\n",
      "DataStore d (d)\n",
      "  Contains 973 entries\n",
      "  Observables: \n",
      "    1)  c = Plus(idx = 1)\n",
      "  \"c\"\n",
      "    2)  x = 9.98  L(-10 - 10)  \"x\"\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n >> d1 has only columns x,c\")\n",
    "d1 = d.reduce({x, c})\n",
    "d1.Print(\"v\")\n",
    "\n",
    "print(\"\\n >> d2 has only column y\")\n",
    "d2 = d.reduce({y})\n",
    "d2.Print(\"v\")\n",
    "\n",
    "print(\"\\n >> d3 has only the points with y>5.17\")\n",
    "d3 = d.reduce(\"y>5.17\")\n",
    "d3.Print(\"v\")\n",
    "\n",
    "print(\"\\n >> d4 has only columns x, for data points with y>5.17\")\n",
    "d4 = d.reduce({x, c}, \"y>5.17\")\n",
    "d4.Print(\"v\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd90fc88",
   "metadata": {},
   "source": [
    "The merge() function adds two data set column-wise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e5c545c5",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:34.907365Z",
     "iopub.status.busy": "2026-05-19T20:31:34.907203Z",
     "iopub.status.idle": "2026-05-19T20:31:35.027118Z",
     "shell.execute_reply": "2026-05-19T20:31:35.026560Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " >> merge d2(y) with d1(x,c) to form d1(x,c,y)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataStore d (d)\n",
      "  Contains 1000 entries\n",
      "  Observables: \n",
      "    1)  c = Plus(idx = 1)\n",
      "  \"c\"\n",
      "    2)  x = 9.98  L(-10 - 10)  \"x\"\n",
      "    3)  y = 31.607  L(0 - 40)  \"y\"\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n >> merge d2(y) with d1(x,c) to form d1(x,c,y)\")\n",
    "d1.merge(d2)\n",
    "d1.Print(\"v\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c68e9d0",
   "metadata": {},
   "source": [
    "The append() function adds two datasets row-wise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ed299180",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.028877Z",
     "iopub.status.busy": "2026-05-19T20:31:35.028754Z",
     "iopub.status.idle": "2026-05-19T20:31:35.137531Z",
     "shell.execute_reply": "2026-05-19T20:31:35.136815Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " >> append data points of d3 to d1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataStore d (d)\n",
      "  Contains 1973 entries\n",
      "  Observables: \n",
      "    1)  c = Plus(idx = 1)\n",
      "  \"c\"\n",
      "    2)  x = 9.98  L(-10 - 10)  \"x\"\n",
      "    3)  y = 31.607  L(0 - 40)  \"y\"\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n >> append data points of d3 to d1\")\n",
    "d1.append(d3)\n",
    "d1.Print(\"v\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d56211f3",
   "metadata": {},
   "source": [
    "Operations on binned datasets\n",
    "---------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92c20f9e",
   "metadata": {},
   "source": [
    "A binned dataset can be constructed empty, an unbinned dataset, or\n",
    "from a ROOT native histogram (TH1,2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d28e4c43",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.139294Z",
     "iopub.status.busy": "2026-05-19T20:31:35.139165Z",
     "iopub.status.idle": "2026-05-19T20:31:35.242589Z",
     "shell.execute_reply": "2026-05-19T20:31:35.241855Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> construct dh (binned) from d(unbinned) but only take the x and y dimensions, \n",
      ">> the category 'c' will be projected in the filling process\n"
     ]
    }
   ],
   "source": [
    "print(\">> construct dh (binned) from d(unbinned) but only take the x and y dimensions, \")\n",
    "print(\">> the category 'c' will be projected in the filling process\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb9ddf92",
   "metadata": {},
   "source": [
    "The binning of real variables (like x,y) is done using their fit range\n",
    "'get/setRange()' and number of specified fit bins 'get/setBins()'.\n",
    "Category dimensions of binned datasets get one bin per defined category\n",
    "state"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5aef72b4",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.244586Z",
     "iopub.status.busy": "2026-05-19T20:31:35.244416Z",
     "iopub.status.idle": "2026-05-19T20:31:35.427177Z",
     "shell.execute_reply": "2026-05-19T20:31:35.426458Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataStore dh (binned version of d)\n",
      "  Contains 100 entries\n",
      "  Observables: \n",
      "    1)  y = 38  L(0 - 40) B(10)  \"y\"\n",
      "    2)  x = 9  L(-10 - 10) B(10)  \"x\"\n",
      "Binned Dataset dh (binned version of d)\n",
      "  Contains 100 bins with a total weight of 1000\n",
      "  Observables:     1)  y = 38  L(0 - 40) B(10)  \"y\"\n",
      "    2)  x = 9  L(-10 - 10) B(10)  \"x\"\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x55682d2de900>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.setBins(10)\n",
    "y.setBins(10)\n",
    "dh = ROOT.RooDataHist(\"dh\", \"binned version of d\", {x, y}, d)\n",
    "dh.Print(\"v\")\n",
    "\n",
    "yframe = y.frame(Bins=10, Title=\"Operations on binned datasets\")\n",
    "dh.plotOn(yframe)  # plot projection of 2D binned data on y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ade8133e",
   "metadata": {},
   "source": [
    "Examine the statistics of a binned dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7f62b4aa",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.428908Z",
     "iopub.status.busy": "2026-05-19T20:31:35.428786Z",
     "iopub.status.idle": "2026-05-19T20:31:35.557251Z",
     "shell.execute_reply": "2026-05-19T20:31:35.556642Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> number of bins in dh   :  100\n",
      ">> sum of weights in dh   :  1000.0\n"
     ]
    }
   ],
   "source": [
    "print(\">> number of bins in dh   : \", dh.numEntries())\n",
    "print(\">> sum of weights in dh   : \", dh.sum(False))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dffe8782",
   "metadata": {},
   "source": [
    "accounts for bin volume"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "cf9c93ec",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.559254Z",
     "iopub.status.busy": "2026-05-19T20:31:35.559131Z",
     "iopub.status.idle": "2026-05-19T20:31:35.662422Z",
     "shell.execute_reply": "2026-05-19T20:31:35.661838Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> integral over histogram:  8000.0\n"
     ]
    }
   ],
   "source": [
    "print(\">> integral over histogram: \", dh.sum(True))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6b43d93",
   "metadata": {},
   "source": [
    "Locate a bin from a set of coordinates and retrieve its properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a8a983f0",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.664224Z",
     "iopub.status.busy": "2026-05-19T20:31:35.664085Z",
     "iopub.status.idle": "2026-05-19T20:31:35.767247Z",
     "shell.execute_reply": "2026-05-19T20:31:35.766832Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> retrieving the properties of the bin enclosing coordinate (x,y) = (0.3,20.5) bin center:\n"
     ]
    }
   ],
   "source": [
    "x.setVal(0.3)\n",
    "y.setVal(20.5)\n",
    "print(\">> retrieving the properties of the bin enclosing coordinate (x,y) = (0.3,20.5) bin center:\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30a66396",
   "metadata": {},
   "source": [
    "load bin center coordinates in internal buffer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "cb2740e1",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.775042Z",
     "iopub.status.busy": "2026-05-19T20:31:35.774915Z",
     "iopub.status.idle": "2026-05-19T20:31:35.885454Z",
     "shell.execute_reply": "2026-05-19T20:31:35.884872Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " weight =  76.0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  1) 0x55682b1d37d0 RooRealVar:: y = 22  L(0 - 40) B(10)  \"y\"\n",
      "  2) 0x55682cff2660 RooRealVar:: x = 1  L(-10 - 10) B(10)  \"x\"\n"
     ]
    }
   ],
   "source": [
    "dh.get({x, y}).Print(\"v\")\n",
    "print(\" weight = \", dh.weight())  # return weight of last loaded coordinates"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16243af5",
   "metadata": {},
   "source": [
    "Reduce the 2-dimensional binned dataset to a 1-dimensional binned dataset\n",
    "\n",
    "All reduce() methods are interfaced in RooAbsData. All reduction techniques\n",
    "demonstrated on unbinned datasets can be applied to binned datasets as\n",
    "well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4794cefa",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:35.886959Z",
     "iopub.status.busy": "2026-05-19T20:31:35.886763Z",
     "iopub.status.idle": "2026-05-19T20:31:35.999623Z",
     "shell.execute_reply": "2026-05-19T20:31:35.998967Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> Creating 1-dimensional projection on y of dh for bins with x>0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataStore dh (binned version of d)\n",
      "  Contains 10 entries\n",
      "  Observables: \n",
      "    1)  y = 38  L(0 - 40) B(10)  \"y\"\n",
      "Binned Dataset dh (binned version of d)\n",
      "  Contains 10 bins with a total weight of 500\n",
      "  Observables:     1)  y = 38  L(0 - 40) B(10)  \"y\"\n"
     ]
    }
   ],
   "source": [
    "print(\">> Creating 1-dimensional projection on y of dh for bins with x>0\")\n",
    "dh2 = dh.reduce({y}, \"x>0\")\n",
    "dh2.Print(\"v\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "814d38f9",
   "metadata": {},
   "source": [
    "Add dh2 to yframe and redraw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "2468c9b2",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:36.000861Z",
     "iopub.status.busy": "2026-05-19T20:31:36.000745Z",
     "iopub.status.idle": "2026-05-19T20:31:36.117534Z",
     "shell.execute_reply": "2026-05-19T20:31:36.116850Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:Plotting -- RooPlot::updateFitRangeNorm: New event count of 500 will supersede previous event count of 1000 for normalization of PDF projections\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<cppyy.gbl.RooPlot object at 0x55682d2de900>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dh2.plotOn(yframe, LineColor=\"r\", MarkerColor=\"r\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "510609a6",
   "metadata": {},
   "source": [
    "Saving and loading from file\n",
    "-------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1a37d1f",
   "metadata": {},
   "source": [
    "Datasets can be persisted with ROOT I/O"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "8a612f11",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:36.119172Z",
     "iopub.status.busy": "2026-05-19T20:31:36.119052Z",
     "iopub.status.idle": "2026-05-19T20:31:36.360597Z",
     "shell.execute_reply": "2026-05-19T20:31:36.360179Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " >> Persisting d via ROOT I/O\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TFile**\t\trf402_datahandling.root\t\n",
      " TFile*\t\trf402_datahandling.root\t\n",
      "  KEY: RooDataSet\td;1\td\n",
      "  KEY: TProcessID\tProcessID0;1\tb974c63b-53c1-11f1-964b-0200590abeef\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n >> Persisting d via ROOT I/O\")\n",
    "f = ROOT.TFile(\"rf402_datahandling.root\", \"RECREATE\")\n",
    "d.Write()\n",
    "f.ls()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61a7f32f",
   "metadata": {},
   "source": [
    "To read back in future session:\n",
    "> ROOT.TFile f(\"rf402_datahandling.root\")\n",
    "> d = (ROOT.RooDataSet*) f.FindObject(\"d\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "575eca4e",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:36.390525Z",
     "iopub.status.busy": "2026-05-19T20:31:36.390331Z",
     "iopub.status.idle": "2026-05-19T20:31:36.609919Z",
     "shell.execute_reply": "2026-05-19T20:31:36.609523Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Info in <TCanvas::Print>: png file rf402_datahandling.png has been created\n"
     ]
    }
   ],
   "source": [
    "c = ROOT.TCanvas(\"rf402_datahandling\", \"rf402_datahandling\", 600, 600)\n",
    "ROOT.gPad.SetLeftMargin(0.15)\n",
    "yframe.GetYaxis().SetTitleOffset(1.4)\n",
    "yframe.Draw()\n",
    "\n",
    "c.SaveAs(\"rf402_datahandling.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30594642",
   "metadata": {},
   "source": [
    "Draw all canvases "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f03e5c61",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:36.626454Z",
     "iopub.status.busy": "2026-05-19T20:31:36.626284Z",
     "iopub.status.idle": "2026-05-19T20:31:36.814941Z",
     "shell.execute_reply": "2026-05-19T20:31:36.814365Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "\n",
       "<div id=\"root_plot_1779222696805\" style=\"width: 600px; height: 600px; position: relative\">\n",
       "</div>\n",
       "\n",
       "</div>\n",
       "<script>\n",
       "   function process_root_plot_1779222696805() {\n",
       "      function execCode(Core) {\n",
       "         Core.settings.HandleKeys = false;\n",
       "         \n",
       "Core.unzipJSON(22600,'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').then(json => {\n",
       "   const obj = Core.parse(json);\n",
       "   Core.draw('root_plot_1779222696805', 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_1779222696805();\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
}
