{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7d18a38c",
   "metadata": {},
   "source": [
    "# rf401_importttreethx\n",
    "'DATA AND CATEGORIES' RooFit tutorial macro #401\n",
    "\n",
    "Overview of advanced option for importing data from ROOT ROOT.TTree and ROOT.THx histograms\n",
    "Basic import options are demonstrated in rf102_dataimport.py\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": "08cc5fef",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:30.012007Z",
     "iopub.status.busy": "2026-05-19T20:31:30.011865Z",
     "iopub.status.idle": "2026-05-19T20:31:31.058437Z",
     "shell.execute_reply": "2026-05-19T20:31:31.057809Z"
    }
   },
   "outputs": [],
   "source": [
    "import ROOT\n",
    "from array import array\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "def makeTH1(trnd, name, mean, sigma):\n",
    "    \"\"\"Create ROOT TH1 filled with a Gaussian distribution.\"\"\"\n",
    "\n",
    "    hh = ROOT.TH1D(name, name, 100, -10, 10)\n",
    "    hh.Fill(np.array([trnd.Gaus(mean, sigma) for _ in range(1000)]))\n",
    "    return hh\n",
    "\n",
    "\n",
    "def makeTTree(trnd):\n",
    "    \"\"\"Create ROOT ROOT.TTree filled with a Gaussian distribution in x and a uniform distribution in y.\"\"\"\n",
    "\n",
    "    tree = ROOT.TTree(\"tree\", \"tree\")\n",
    "    px = array(\"d\", [0])\n",
    "    py = array(\"d\", [0])\n",
    "    pz = array(\"d\", [0])\n",
    "    pi = array(\"i\", [0])\n",
    "    tree.Branch(\"x\", px, \"x/D\")\n",
    "    tree.Branch(\"y\", py, \"y/D\")\n",
    "    tree.Branch(\"z\", pz, \"z/D\")\n",
    "    tree.Branch(\"i\", pi, \"i/I\")\n",
    "    for i in range(100):\n",
    "        px[0] = trnd.Gaus(0, 3)\n",
    "        py[0] = trnd.Uniform() * 30 - 15\n",
    "        pz[0] = trnd.Gaus(0, 5)\n",
    "        pi[0] = i % 3\n",
    "        tree.Fill()\n",
    "\n",
    "    return tree\n",
    "\n",
    "trnd = ROOT.TRandom3()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3ce9f07",
   "metadata": {},
   "source": [
    "Import multiple TH1 into a RooDataHist\n",
    "----------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b24e477",
   "metadata": {},
   "source": [
    "Create thee ROOT ROOT.TH1 histograms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c4aebf57",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:31.060777Z",
     "iopub.status.busy": "2026-05-19T20:31:31.060564Z",
     "iopub.status.idle": "2026-05-19T20:31:31.198686Z",
     "shell.execute_reply": "2026-05-19T20:31:31.197933Z"
    }
   },
   "outputs": [],
   "source": [
    "hh_1 = makeTH1(trnd, \"hh1\", 0, 3)\n",
    "hh_2 = makeTH1(trnd, \"hh2\", -3, 1)\n",
    "hh_3 = makeTH1(trnd, \"hh3\", +3, 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d410a48",
   "metadata": {},
   "source": [
    "Declare observable x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b1d5a1aa",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:31.200807Z",
     "iopub.status.busy": "2026-05-19T20:31:31.200674Z",
     "iopub.status.idle": "2026-05-19T20:31:31.352252Z",
     "shell.execute_reply": "2026-05-19T20:31:31.351413Z"
    }
   },
   "outputs": [],
   "source": [
    "x = ROOT.RooRealVar(\"x\", \"x\", -10, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "816bb88f",
   "metadata": {},
   "source": [
    "Create category observable c that serves as index for the ROOT histograms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0193ca6a",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:31.354531Z",
     "iopub.status.busy": "2026-05-19T20:31:31.354389Z",
     "iopub.status.idle": "2026-05-19T20:31:31.472980Z",
     "shell.execute_reply": "2026-05-19T20:31:31.472520Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = ROOT.RooCategory(\"c\", \"c\")\n",
    "c.defineType(\"SampleA\")\n",
    "c.defineType(\"SampleB\")\n",
    "c.defineType(\"SampleC\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1928d63f",
   "metadata": {},
   "source": [
    "Create a binned dataset that imports contents of all ROOT.TH1 mapped by\n",
    "index category c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b7a99b9f",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:31.475200Z",
     "iopub.status.busy": "2026-05-19T20:31:31.475069Z",
     "iopub.status.idle": "2026-05-19T20:31:31.834709Z",
     "shell.execute_reply": "2026-05-19T20:31:31.833981Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RooDataHist::dh[c,x] = 300 bins (2964 weights)\n",
      "RooDataHist::dh[c,x] = 300 bins (2964 weights)\n"
     ]
    }
   ],
   "source": [
    "dh = ROOT.RooDataHist(\"dh\", \"dh\", [x], Index=c, Import={\"SampleA\": hh_1, \"SampleB\": hh_2, \"SampleC\": hh_3})\n",
    "dh.Print()\n",
    "\n",
    "dh2 = ROOT.RooDataHist(\"dh\", \"dh\", [x], Index=c, Import={\"SampleA\": hh_1, \"SampleB\": hh_2, \"SampleC\": hh_3})\n",
    "dh2.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3c949b4",
   "metadata": {},
   "source": [
    "Importing a ROOT TTree into a RooDataSet with cuts\n",
    "--------------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "3cee24ea",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:31.836862Z",
     "iopub.status.busy": "2026-05-19T20:31:31.836734Z",
     "iopub.status.idle": "2026-05-19T20:31:31.965282Z",
     "shell.execute_reply": "2026-05-19T20:31:31.964587Z"
    }
   },
   "outputs": [],
   "source": [
    "tree = makeTTree(trnd)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66e50900",
   "metadata": {},
   "source": [
    "Define observables y,z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "27e594dc",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:31.967516Z",
     "iopub.status.busy": "2026-05-19T20:31:31.967387Z",
     "iopub.status.idle": "2026-05-19T20:31:32.070957Z",
     "shell.execute_reply": "2026-05-19T20:31:32.070260Z"
    }
   },
   "outputs": [],
   "source": [
    "y = ROOT.RooRealVar(\"y\", \"y\", -10, 10)\n",
    "z = ROOT.RooRealVar(\"z\", \"z\", -10, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f29b741",
   "metadata": {},
   "source": [
    "Import only observables (y,z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "44fa133e",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.073065Z",
     "iopub.status.busy": "2026-05-19T20:31:32.072933Z",
     "iopub.status.idle": "2026-05-19T20:31:32.241533Z",
     "shell.execute_reply": "2026-05-19T20:31:32.240898Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #7 because y cannot accommodate the value 13.3845\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #8 because y cannot accommodate the value 11.1861\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #12 because y cannot accommodate the value 13.7009\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping event #14 because y cannot accommodate the value -10.6852\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds) Skipping ...\n",
      "[#0] WARNING:DataHandling -- RooTreeDataStore::loadValues(ds) Ignored 35 out-of-range events\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RooDataSet::ds[x,y] = 65 entries\n"
     ]
    }
   ],
   "source": [
    "ds = ROOT.RooDataSet(\"ds\", \"ds\", {x, y}, Import=tree)\n",
    "ds.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51e561c2",
   "metadata": {},
   "source": [
    "Import observables (x,y,z) but only event for which (y+z<0) is ROOT.True\n",
    "Import observables (x,y,z) but only event for which (y+z<0) is ROOT.True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "eec06632",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.243342Z",
     "iopub.status.busy": "2026-05-19T20:31:32.243213Z",
     "iopub.status.idle": "2026-05-19T20:31:32.366244Z",
     "shell.execute_reply": "2026-05-19T20:31:32.365536Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds2) Skipping event #7 because y cannot accommodate the value 13.3845\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds2) Skipping event #8 because y cannot accommodate the value 11.1861\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds2) Skipping event #12 because y cannot accommodate the value 13.7009\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds2) Skipping event #14 because y cannot accommodate the value -10.6852\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds2) Skipping ...\n",
      "[#0] WARNING:DataHandling -- RooTreeDataStore::loadValues(ds2) Ignored 36 out-of-range events\n",
      "RooDataSet::ds2[x,y,z] = 26 entries\n"
     ]
    }
   ],
   "source": [
    "ds2 = ROOT.RooDataSet(\"ds2\", \"ds2\", {x, y, z}, Import=tree, Cut=\"y+z<0\")\n",
    "ds2.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e841f6ba",
   "metadata": {},
   "source": [
    "Importing integer ROOT TTree branches\n",
    "---------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fca25ea",
   "metadata": {},
   "source": [
    "Import integer tree branch as ROOT.RooRealVar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3584dda6",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.367911Z",
     "iopub.status.busy": "2026-05-19T20:31:32.367783Z",
     "iopub.status.idle": "2026-05-19T20:31:32.472535Z",
     "shell.execute_reply": "2026-05-19T20:31:32.471950Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:DataHandling -- RooAbsReal::attachToTree(i) TTree Int_t branch i will be converted to double precision.\n",
      "RooDataSet::ds3[i,x] = 100 entries\n"
     ]
    }
   ],
   "source": [
    "i = ROOT.RooRealVar(\"i\", \"i\", 0, 5)\n",
    "ds3 = ROOT.RooDataSet(\"ds3\", \"ds3\", {i, x}, Import=tree)\n",
    "ds3.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e14a5744",
   "metadata": {},
   "source": [
    "Define category i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "adde5679",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.479470Z",
     "iopub.status.busy": "2026-05-19T20:31:32.479334Z",
     "iopub.status.idle": "2026-05-19T20:31:32.588643Z",
     "shell.execute_reply": "2026-05-19T20:31:32.587093Z"
    }
   },
   "outputs": [],
   "source": [
    "icat = ROOT.RooCategory(\"i\", \"i\", {\"State0\": 0, \"State1\": 1})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fcb45d1",
   "metadata": {},
   "source": [
    "Import integer tree branch as ROOT.RooCategory (only events with i==0 and i==1\n",
    "will be imported as those are the only defined states)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f2457d83",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.590188Z",
     "iopub.status.busy": "2026-05-19T20:31:32.590065Z",
     "iopub.status.idle": "2026-05-19T20:31:32.706398Z",
     "shell.execute_reply": "2026-05-19T20:31:32.705737Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds4) Skipping event #2 because i cannot accommodate the value 0\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds4) Skipping event #5 because i cannot accommodate the value 0\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds4) Skipping event #8 because i cannot accommodate the value 0\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds4) Skipping event #11 because i cannot accommodate the value 0\n",
      "[#1] INFO:DataHandling -- RooTreeDataStore::loadValues(ds4) Skipping ...\n",
      "[#0] WARNING:DataHandling -- RooTreeDataStore::loadValues(ds4) Ignored 33 out-of-range events\n",
      "RooDataSet::ds4[x,i] = 67 entries\n"
     ]
    }
   ],
   "source": [
    "ds4 = ROOT.RooDataSet(\"ds4\", \"ds4\", {icat, x}, Import=tree)\n",
    "ds4.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "113f1fda",
   "metadata": {},
   "source": [
    "Import multiple RooDataSets into a RooDataSet\n",
    "----------------------------------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbd7f706",
   "metadata": {},
   "source": [
    "Create three ROOT.RooDataSets in (y,z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "96395dea",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.708116Z",
     "iopub.status.busy": "2026-05-19T20:31:32.707990Z",
     "iopub.status.idle": "2026-05-19T20:31:32.837612Z",
     "shell.execute_reply": "2026-05-19T20:31:32.837062Z"
    }
   },
   "outputs": [],
   "source": [
    "dsA = ds2.reduce({x, y}, \"z<-5\")\n",
    "dsB = ds2.reduce({x, y}, \"abs(z)<5\")\n",
    "dsC = ds2.reduce({x, y}, \"z>5\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4abc7a02",
   "metadata": {},
   "source": [
    "Create a dataset that imports contents of all the above datasets mapped\n",
    "by index category c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f9c56882",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:32.839545Z",
     "iopub.status.busy": "2026-05-19T20:31:32.839419Z",
     "iopub.status.idle": "2026-05-19T20:31:33.012914Z",
     "shell.execute_reply": "2026-05-19T20:31:33.012289Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RooDataSet::dsABC[x,y,c] = 26 entries\n"
     ]
    }
   ],
   "source": [
    "dsABC = ROOT.RooDataSet(\"dsABC\", \"dsABC\", {x, y}, Index=c, Import={\"SampleA\": dsA, \"SampleB\": dsB, \"SampleC\": dsC})\n",
    "\n",
    "dsABC.Print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "673a031c",
   "metadata": {},
   "source": [
    "Draw all canvases "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9f3df776",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:31:33.014337Z",
     "iopub.status.busy": "2026-05-19T20:31:33.014209Z",
     "iopub.status.idle": "2026-05-19T20:31:33.121270Z",
     "shell.execute_reply": "2026-05-19T20:31:33.120720Z"
    }
   },
   "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
}
