{ "cells": [ { "cell_type": "markdown", "id": "b7a65822", "metadata": {}, "source": [ "# rf102_dataimport\n", "Basic functionality: importing data from ROOT TTrees and THx histograms.\n", "\n", "\n", "\n", "\n", "**Author:** Wouter Verkerke \n", "This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:28 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "c7c54195", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.184075Z", "iopub.status.busy": "2026-05-19T20:28:25.183956Z", "iopub.status.idle": "2026-05-19T20:28:25.196527Z", "shell.execute_reply": "2026-05-19T20:28:25.196066Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \"RooRealVar.h\"\n", "#include \"RooDataSet.h\"\n", "#include \"RooDataHist.h\"\n", "#include \"RooGaussian.h\"\n", "#include \"TCanvas.h\"\n", "#include \"RooPlot.h\"\n", "#include \"TTree.h\"\n", "#include \"TH1D.h\"\n", "#include \"TRandom.h\"\n", "\n", "TH1 *makeTH1(TRandom &trnd);\n", "TTree *makeTTree(TRandom &trnd);" ] }, { "cell_type": "markdown", "id": "04c16d23", "metadata": {}, "source": [ " Create ROOT TH1 filled with a Gaussian distribution\n", " " ] }, { "cell_type": "code", "execution_count": 2, "id": "8308e051", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.197907Z", "iopub.status.busy": "2026-05-19T20:28:25.197784Z", "iopub.status.idle": "2026-05-19T20:28:25.204880Z", "shell.execute_reply": "2026-05-19T20:28:25.204415Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "TH1 *makeTH1(TRandom &trnd)\n", "{\n", " TH1D *hh = new TH1D(\"hh\", \"hh\", 25, -10, 10);\n", " for (int i = 0; i < 100; i++) {\n", " hh->Fill(trnd.Gaus(0, 3));\n", " }\n", " return hh;\n", "}" ] }, { "cell_type": "markdown", "id": "b7ad67fd", "metadata": {}, "source": [ " Create ROOT TTree filled with a Gaussian distribution in x and a uniform distribution in y\n", " " ] }, { "cell_type": "code", "execution_count": 3, "id": "08ed9581", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.206087Z", "iopub.status.busy": "2026-05-19T20:28:25.205970Z", "iopub.status.idle": "2026-05-19T20:28:25.214536Z", "shell.execute_reply": "2026-05-19T20:28:25.214063Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "TTree *makeTTree(TRandom &trnd)\n", "{\n", " TTree *tree = new TTree(\"tree\", \"tree\");\n", " double *px = new double;\n", " double *py = new double;\n", " tree->Branch(\"x\", px, \"x/D\");\n", " tree->Branch(\"y\", py, \"y/D\");\n", " for (int i = 0; i < 100; i++) {\n", " *px = trnd.Gaus(0, 3);\n", " *py = trnd.Uniform() * 30 - 15;\n", " tree->Fill();\n", " }\n", " return tree;\n", "}" ] }, { "cell_type": "code", "execution_count": 4, "id": "8676a150", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.215739Z", "iopub.status.busy": "2026-05-19T20:28:25.215598Z", "iopub.status.idle": "2026-05-19T20:28:25.422555Z", "shell.execute_reply": "2026-05-19T20:28:25.421910Z" } }, "outputs": [], "source": [ "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "8f2e796d", "metadata": {}, "source": [ "---------------------------------------------------\n", "Importing ROOT histograms\n", "===================================================" ] }, { "cell_type": "code", "execution_count": 5, "id": "811d628b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.424113Z", "iopub.status.busy": "2026-05-19T20:28:25.423988Z", "iopub.status.idle": "2026-05-19T20:28:25.631271Z", "shell.execute_reply": "2026-05-19T20:28:25.630656Z" } }, "outputs": [], "source": [ "TRandom3 trnd{};" ] }, { "cell_type": "markdown", "id": "def1f7ae", "metadata": {}, "source": [ "Import TH1 into a RooDataHist\n", "---------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "bf538216", "metadata": {}, "source": [ "Create a ROOT TH1 histogram" ] }, { "cell_type": "code", "execution_count": 6, "id": "db9a1c82", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.633351Z", "iopub.status.busy": "2026-05-19T20:28:25.633231Z", "iopub.status.idle": "2026-05-19T20:28:25.840210Z", "shell.execute_reply": "2026-05-19T20:28:25.839672Z" } }, "outputs": [], "source": [ "TH1 *hh = makeTH1(trnd);" ] }, { "cell_type": "markdown", "id": "512021f5", "metadata": {}, "source": [ "Declare observable x" ] }, { "cell_type": "code", "execution_count": 7, "id": "f0e1df66", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:25.842214Z", "iopub.status.busy": "2026-05-19T20:28:25.842096Z", "iopub.status.idle": "2026-05-19T20:28:26.049187Z", "shell.execute_reply": "2026-05-19T20:28:26.048558Z" } }, "outputs": [], "source": [ "RooRealVar x(\"x\", \"x\", -10, 10);" ] }, { "cell_type": "markdown", "id": "9f7b13ca", "metadata": {}, "source": [ "Create a binned dataset that imports contents of TH1 and associates its contents to observable 'x'" ] }, { "cell_type": "code", "execution_count": 8, "id": "bfa94418", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:26.051202Z", "iopub.status.busy": "2026-05-19T20:28:26.051089Z", "iopub.status.idle": "2026-05-19T20:28:26.258194Z", "shell.execute_reply": "2026-05-19T20:28:26.257569Z" } }, "outputs": [], "source": [ "RooDataHist dh(\"dh\", \"dh\", x, Import(*hh));" ] }, { "cell_type": "markdown", "id": "963f638c", "metadata": {}, "source": [ "Plot and fit a RooDataHist\n", "---------------------------------------------------" ] }, { "cell_type": "markdown", "id": "fa045445", "metadata": {}, "source": [ "Make plot of binned dataset showing Poisson error bars (RooFit default)" ] }, { "cell_type": "code", "execution_count": 9, "id": "8c89caa9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:26.260266Z", "iopub.status.busy": "2026-05-19T20:28:26.260150Z", "iopub.status.idle": "2026-05-19T20:28:26.467256Z", "shell.execute_reply": "2026-05-19T20:28:26.466618Z" } }, "outputs": [], "source": [ "RooPlot *frame = x.frame(Title(\"Imported TH1 with Poisson error bars\"));\n", "dh.plotOn(frame);" ] }, { "cell_type": "markdown", "id": "e661e053", "metadata": {}, "source": [ "Fit a Gaussian pdf to the data" ] }, { "cell_type": "code", "execution_count": 10, "id": "f76079f9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:26.469251Z", "iopub.status.busy": "2026-05-19T20:28:26.469135Z", "iopub.status.idle": "2026-05-19T20:28:26.712777Z", "shell.execute_reply": "2026-05-19T20:28:26.711924Z" } }, "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 6.62908 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" ] } ], "source": [ "RooRealVar mean(\"mean\", \"mean\", 0, -10, 10);\n", "RooRealVar sigma(\"sigma\", \"sigma\", 3, 0.1, 10);\n", "RooGaussian gauss(\"gauss\", \"gauss\", x, mean, sigma);\n", "gauss.fitTo(dh, PrintLevel(-1));\n", "gauss.plotOn(frame);" ] }, { "cell_type": "markdown", "id": "50c9d25a", "metadata": {}, "source": [ "Plot and fit a RooDataHist with internal errors\n", "---------------------------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "907fabc1", "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": 11, "id": "39e19a96", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:26.714237Z", "iopub.status.busy": "2026-05-19T20:28:26.714111Z", "iopub.status.idle": "2026-05-19T20:28:26.921195Z", "shell.execute_reply": "2026-05-19T20:28:26.920537Z" } }, "outputs": [], "source": [ "RooPlot *frame2 = x.frame(Title(\"Imported TH1 with internal errors\"));\n", "dh.plotOn(frame2, DataError(RooAbsData::SumW2));\n", "gauss.plotOn(frame2);" ] }, { "cell_type": "markdown", "id": "bf0129e8", "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.C)" ] }, { "cell_type": "markdown", "id": "89c60956", "metadata": {}, "source": [ "-----------------------------------------\n", "Importing ROOT TTrees\n", "=========================================" ] }, { "cell_type": "markdown", "id": "bfa06c1f", "metadata": {}, "source": [ "Import TTree into a RooDataSet\n", "-----------------------------------------------------------" ] }, { "cell_type": "code", "execution_count": 12, "id": "bd537c11", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:26.923299Z", "iopub.status.busy": "2026-05-19T20:28:26.923182Z", "iopub.status.idle": "2026-05-19T20:28:27.130272Z", "shell.execute_reply": "2026-05-19T20:28:27.129651Z" } }, "outputs": [], "source": [ "TTree *tree = makeTTree(trnd);" ] }, { "cell_type": "markdown", "id": "90a752e2", "metadata": {}, "source": [ "Define 2nd observable y" ] }, { "cell_type": "code", "execution_count": 13, "id": "3a7240ea", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:27.131986Z", "iopub.status.busy": "2026-05-19T20:28:27.131872Z", "iopub.status.idle": "2026-05-19T20:28:27.338962Z", "shell.execute_reply": "2026-05-19T20:28:27.338328Z" } }, "outputs": [], "source": [ "RooRealVar y(\"y\", \"y\", -10, 10);" ] }, { "cell_type": "markdown", "id": "bd8d888a", "metadata": {}, "source": [ "Construct unbinned dataset importing tree branches x and y matching between branches and 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", "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 RooDataSet below will have less entries than the TTree\n", "'tree'" ] }, { "cell_type": "code", "execution_count": 14, "id": "9709165a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:27.340889Z", "iopub.status.busy": "2026-05-19T20:28:27.340775Z", "iopub.status.idle": "2026-05-19T20:28:27.548480Z", "shell.execute_reply": "2026-05-19T20:28:27.547879Z" } }, "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": [ "RooDataSet ds(\"ds\", \"ds\", RooArgSet(x, y), Import(*tree));" ] }, { "cell_type": "markdown", "id": "c15e8f90", "metadata": {}, "source": [ "Use ascii import/export for datasets\n", "------------------------------------------------------------------------------------" ] }, { "cell_type": "code", "execution_count": 15, "id": "2c2db6b5", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:27.550153Z", "iopub.status.busy": "2026-05-19T20:28:27.550040Z", "iopub.status.idle": "2026-05-19T20:28:27.752185Z", "shell.execute_reply": "2026-05-19T20:28:27.751643Z" } }, "outputs": [], "source": [ "{\n", " // Write data to output stream\n", " std::ofstream outstream(\"rf102_testData.txt\");\n", " // Optionally, adjust the stream here (e.g. std::setprecision)\n", " ds.write(outstream);\n", " outstream.close();\n", "}" ] }, { "cell_type": "markdown", "id": "6d148caa", "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": 16, "id": "0f2bd857", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:27.754415Z", "iopub.status.busy": "2026-05-19T20:28:27.754300Z", "iopub.status.idle": "2026-05-19T20:28:27.959590Z", "shell.execute_reply": "2026-05-19T20:28:27.959126Z" } }, "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 = 0.0174204 L(-10 - 10) \"x\"\n", " 2) y = 9.46654 L(-10 - 10) \"y\"\n", " 3) blindState = Normal(idx = 0)\n", " \"Blinding State\"\n", "\n", "Original data, line 20:\n", " 1) RooRealVar:: x = -0.79919\n", " 2) RooRealVar:: y = 0.0106407\n", "\n", "Read-back data, line 20:\n", " 1) RooRealVar:: x = -0.79919\n", " 2) RooRealVar:: y = 0.0106407\n", " 3) RooCategory:: blindState = Normal(idx = 0)\n", "\n" ] } ], "source": [ "std::cout << \"\\n-----------------------\\nReading data from ASCII\\n\";\n", "RooDataSet *dataReadBack =\n", " RooDataSet::read(\"rf102_testData.txt\",\n", " RooArgList(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", "dataReadBack->Print(\"V\");\n", "\n", "std::cout << \"\\nOriginal data, line 20:\\n\";\n", "ds.get(20)->Print(\"V\");\n", "\n", "std::cout << \"\\nRead-back data, line 20:\\n\";\n", "dataReadBack->get(20)->Print(\"V\");" ] }, { "cell_type": "markdown", "id": "2fa9c1ae", "metadata": {}, "source": [ "Plot datasets with multiple binning choices\n", "------------------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "ba76c0f4", "metadata": {}, "source": [ "Print number of events in dataset" ] }, { "cell_type": "code", "execution_count": 17, "id": "b823e342", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:27.961446Z", "iopub.status.busy": "2026-05-19T20:28:27.961328Z", "iopub.status.idle": "2026-05-19T20:28:28.175553Z", "shell.execute_reply": "2026-05-19T20:28:28.174986Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RooDataSet::ds[x,y] = 64 entries\n" ] } ], "source": [ "ds.Print();" ] }, { "cell_type": "markdown", "id": "490b4477", "metadata": {}, "source": [ "Print unbinned dataset with default frame binning (100 bins)" ] }, { "cell_type": "code", "execution_count": 18, "id": "36fc4a94", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:28.177252Z", "iopub.status.busy": "2026-05-19T20:28:28.177135Z", "iopub.status.idle": "2026-05-19T20:28:28.384039Z", "shell.execute_reply": "2026-05-19T20:28:28.383487Z" } }, "outputs": [], "source": [ "RooPlot *frame3 = y.frame(Title(\"Unbinned data shown in default frame binning\"));\n", "ds.plotOn(frame3);" ] }, { "cell_type": "markdown", "id": "c21047ec", "metadata": {}, "source": [ "Print unbinned dataset with custom binning choice (20 bins)" ] }, { "cell_type": "code", "execution_count": 19, "id": "ef3ca2be", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:28.386092Z", "iopub.status.busy": "2026-05-19T20:28:28.385977Z", "iopub.status.idle": "2026-05-19T20:28:28.593024Z", "shell.execute_reply": "2026-05-19T20:28:28.592369Z" } }, "outputs": [], "source": [ "RooPlot *frame4 = y.frame(Title(\"Unbinned data shown with custom binning\"));\n", "ds.plotOn(frame4, Binning(20));\n", "\n", "RooPlot *frame5 = y.frame(Title(\"Unbinned data read back from ASCII file\"));\n", "ds.plotOn(frame5, Binning(20));\n", "dataReadBack->plotOn(frame5, Binning(20), MarkerColor(kRed), MarkerStyle(5));" ] }, { "cell_type": "markdown", "id": "d315623f", "metadata": {}, "source": [ "Draw all frames on a canvas" ] }, { "cell_type": "code", "execution_count": 20, "id": "71e11cbe", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:28.595144Z", "iopub.status.busy": "2026-05-19T20:28:28.595028Z", "iopub.status.idle": "2026-05-19T20:28:28.802000Z", "shell.execute_reply": "2026-05-19T20:28:28.801433Z" } }, "outputs": [], "source": [ "TCanvas *c = new TCanvas(\"rf102_dataimport\", \"rf102_dataimport\", 1000, 800);\n", "c->Divide(3, 2);\n", "c->cd(1);\n", "gPad->SetLeftMargin(0.15);\n", "frame->GetYaxis()->SetTitleOffset(1.4);\n", "frame->Draw();\n", "c->cd(2);\n", "gPad->SetLeftMargin(0.15);\n", "frame2->GetYaxis()->SetTitleOffset(1.4);\n", "frame2->Draw();\n", "\n", "c->cd(4);\n", "gPad->SetLeftMargin(0.15);\n", "frame3->GetYaxis()->SetTitleOffset(1.4);\n", "frame3->Draw();\n", "c->cd(5);\n", "gPad->SetLeftMargin(0.15);\n", "frame4->GetYaxis()->SetTitleOffset(1.4);\n", "frame4->Draw();\n", "c->cd(6);\n", "gPad->SetLeftMargin(0.15);\n", "frame4->GetYaxis()->SetTitleOffset(1.4);\n", "frame5->Draw();" ] }, { "cell_type": "markdown", "id": "a9a6f40f", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 21, "id": "a319a17d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:28.804140Z", "iopub.status.busy": "2026-05-19T20:28:28.804025Z", "iopub.status.idle": "2026-05-19T20:28:29.029276Z", "shell.execute_reply": "2026-05-19T20:28:29.028702Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "