{ "cells": [ { "cell_type": "markdown", "id": "4d1218d6", "metadata": {}, "source": [ "# rf504_simwstool\n", "Organisation and simultaneous fits: using RooSimWSTool to construct a simultaneous pdf\n", "that is built of variations of an input pdf\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:32 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "20ffcd34", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:15.147175Z", "iopub.status.busy": "2026-05-19T20:32:15.147065Z", "iopub.status.idle": "2026-05-19T20:32:15.161655Z", "shell.execute_reply": "2026-05-19T20:32:15.161102Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \"RooRealVar.h\"\n", "#include \"RooCategory.h\"\n", "#include \"RooDataSet.h\"\n", "#include \"RooGaussian.h\"\n", "#include \"RooPolynomial.h\"\n", "#include \"RooSimultaneous.h\"\n", "#include \"RooAddPdf.h\"\n", "#include \"RooWorkspace.h\"\n", "#include \"RooSimWSTool.h\"\n", "#include \"RooPlot.h\"\n", "#include \"TCanvas.h\"\n", "#include \"TAxis.h\"\n", "#include \"TFile.h\"\n", "#include \"TH1.h\"\n", "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "73060383", "metadata": {}, "source": [ "Create master pdf\n", "---------------------------------" ] }, { "cell_type": "markdown", "id": "6f5432a1", "metadata": {}, "source": [ "Construct gauss(x,m,s)" ] }, { "cell_type": "code", "execution_count": 2, "id": "f6029f11", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:15.163417Z", "iopub.status.busy": "2026-05-19T20:32:15.163289Z", "iopub.status.idle": "2026-05-19T20:32:15.527567Z", "shell.execute_reply": "2026-05-19T20:32:15.526937Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#0] WARNING:InputArguments -- The parameter 's' with range [-10, 10] of the RooGaussian 'g' exceeds the safe range of (0, inf). Advise to limit its range.\n" ] } ], "source": [ "RooRealVar x(\"x\", \"x\", -10, 10);\n", "RooRealVar m(\"m\", \"m\", 0, -10, 10);\n", "RooRealVar s(\"s\", \"s\", 1, -10, 10);\n", "RooGaussian gauss(\"g\", \"g\", x, m, s);" ] }, { "cell_type": "markdown", "id": "3fb21359", "metadata": {}, "source": [ "Construct poly(x,p0)" ] }, { "cell_type": "code", "execution_count": 3, "id": "342dea81", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:15.529258Z", "iopub.status.busy": "2026-05-19T20:32:15.529135Z", "iopub.status.idle": "2026-05-19T20:32:15.737511Z", "shell.execute_reply": "2026-05-19T20:32:15.736876Z" } }, "outputs": [], "source": [ "RooRealVar p0(\"p0\", \"p0\", 0.01, 0., 1.);\n", "RooPolynomial poly(\"p\", \"p\", x, p0);" ] }, { "cell_type": "markdown", "id": "6a6ccf7f", "metadata": {}, "source": [ "Construct model = f*gauss(x) + (1-f)*poly(x)" ] }, { "cell_type": "code", "execution_count": 4, "id": "0ca2e037", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:15.739192Z", "iopub.status.busy": "2026-05-19T20:32:15.739079Z", "iopub.status.idle": "2026-05-19T20:32:15.947384Z", "shell.execute_reply": "2026-05-19T20:32:15.946829Z" } }, "outputs": [], "source": [ "RooRealVar f(\"f\", \"f\", 0.5, 0., 1.);\n", "RooAddPdf model(\"model\", \"model\", RooArgSet(gauss, poly), f);" ] }, { "cell_type": "markdown", "id": "83d5ffad", "metadata": {}, "source": [ "Create category observables for splitting\n", "----------------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "55990236", "metadata": {}, "source": [ "Define two categories that can be used for splitting" ] }, { "cell_type": "code", "execution_count": 5, "id": "dc6cc58b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:15.949154Z", "iopub.status.busy": "2026-05-19T20:32:15.949034Z", "iopub.status.idle": "2026-05-19T20:32:16.154420Z", "shell.execute_reply": "2026-05-19T20:32:16.153931Z" } }, "outputs": [], "source": [ "RooCategory c(\"c\", \"c\");\n", "c.defineType(\"run1\");\n", "c.defineType(\"run2\");\n", "\n", "RooCategory d(\"d\", \"d\");\n", "d.defineType(\"foo\");\n", "d.defineType(\"bar\");" ] }, { "cell_type": "markdown", "id": "2af7e0b9", "metadata": {}, "source": [ "Setup SimWSTool\n", "-----------------------------" ] }, { "cell_type": "markdown", "id": "0d367fee", "metadata": {}, "source": [ "Import ingredients in a workspace" ] }, { "cell_type": "code", "execution_count": 6, "id": "96e1b267", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:16.156459Z", "iopub.status.busy": "2026-05-19T20:32:16.156334Z", "iopub.status.idle": "2026-05-19T20:32:16.365767Z", "shell.execute_reply": "2026-05-19T20:32:16.365354Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooGaussian::g\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::x\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::m\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::s\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::f\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooPolynomial::p\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::p0\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooCategory::c\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooCategory::d\n" ] } ], "source": [ "RooWorkspace w(\"w\", \"w\");\n", "w.import(RooArgSet(model, c, d));" ] }, { "cell_type": "markdown", "id": "30d62865", "metadata": {}, "source": [ "Make Sim builder tool" ] }, { "cell_type": "code", "execution_count": 7, "id": "cb4ecc12", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:16.367201Z", "iopub.status.busy": "2026-05-19T20:32:16.367085Z", "iopub.status.idle": "2026-05-19T20:32:16.575186Z", "shell.execute_reply": "2026-05-19T20:32:16.574650Z" } }, "outputs": [], "source": [ "RooSimWSTool sct(w);" ] }, { "cell_type": "markdown", "id": "db08c946", "metadata": {}, "source": [ "Build a simultaneous model with one split\n", "---------------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "6000f36e", "metadata": {}, "source": [ "Construct a simultaneous pdf with the following form\n", "\n", "model_run1(x) = f*gauss_run1(x,m_run1,s) + (1-f)*poly\n", "model_run2(x) = f*gauss_run2(x,m_run2,s) + (1-f)*poly\n", "simpdf(x,c) = model_run1(x) if c==\"run1\"\n", "= model_run2(x) if c==\"run2\"\n", "\n", "Returned pdf is owned by the workspace" ] }, { "cell_type": "code", "execution_count": 8, "id": "f9df1ba3", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:16.576921Z", "iopub.status.busy": "2026-05-19T20:32:16.576794Z", "iopub.status.idle": "2026-05-19T20:32:16.783390Z", "shell.execute_reply": "2026-05-19T20:32:16.782932Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Splitrule for p.d.f model with state list \n", " parameter m is split with constraint in categories (c)\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: list of prototype pdfs (model)\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: list of splitting categories (c)\n", "[#1] INFO:ObjectHandling -- RooSimPdfBuilder::executeBuild: processing prototype pdf model\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: configured customizers for all prototype pdfs\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: Customizing prototype pdf model for mode run1\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: Customizing prototype pdf model for mode run2\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooSimultaneous::model_sim\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model_run1\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooGaussian::g_run1\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::m_run1\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model_run2\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooGaussian::g_run2\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::m_run2\n" ] } ], "source": [ "RooSimultaneous *model_sim = sct.build(\"model_sim\", \"model\", SplitParam(\"m\", \"c\"));" ] }, { "cell_type": "markdown", "id": "d8fa7f9a", "metadata": {}, "source": [ "Print tree structure of model" ] }, { "cell_type": "code", "execution_count": 9, "id": "35ab91d9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:16.785010Z", "iopub.status.busy": "2026-05-19T20:32:16.784881Z", "iopub.status.idle": "2026-05-19T20:32:16.991732Z", "shell.execute_reply": "2026-05-19T20:32:16.991276Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0x7f7571757ab0 RooSimultaneous::model_sim = 1 [Auto,Dirty] \n", " 0x7f75714f4260/V- RooCategory::c = run2(idx = 1)\n", "\n", " 0x7f7571737e20/V- RooAddPdf::model_run1 = 1/1 [Auto,Clean] \n", " 0x7f757173c7d0/V- RooGaussian::g_run1 = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75717634f0/V- RooRealVar::m_run1 = 0\n", " 0x7f757176e800/V- RooRealVar::s = 1\n", " 0x7f757176f5b0/V- RooRealVar::f = 0.5\n", " 0x7f75715b9af0/V- RooPolynomial::p = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75717250b0/V- RooRealVar::p0 = 0.01\n", " 0x7f75717671d0/V- RooAddPdf::model_run2 = 1/1 [Auto,Clean] \n", " 0x7f75715cf380/V- RooGaussian::g_run2 = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75715d1a60/V- RooRealVar::m_run2 = 0\n", " 0x7f757176e800/V- RooRealVar::s = 1\n", " 0x7f757176f5b0/V- RooRealVar::f = 0.5\n", " 0x7f75715b9af0/V- RooPolynomial::p = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75717250b0/V- RooRealVar::p0 = 0.01\n" ] } ], "source": [ "model_sim->Print(\"t\");" ] }, { "cell_type": "markdown", "id": "449bcc4b", "metadata": {}, "source": [ "Adjust model_sim parameters in workspace" ] }, { "cell_type": "code", "execution_count": 10, "id": "6183ed7f", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:16.993178Z", "iopub.status.busy": "2026-05-19T20:32:16.993061Z", "iopub.status.idle": "2026-05-19T20:32:17.198801Z", "shell.execute_reply": "2026-05-19T20:32:17.198087Z" } }, "outputs": [], "source": [ "w.var(\"m_run1\")->setVal(-3);\n", "w.var(\"m_run2\")->setVal(+3);" ] }, { "cell_type": "markdown", "id": "41ddaa54", "metadata": {}, "source": [ "Print contents of workspace" ] }, { "cell_type": "code", "execution_count": 11, "id": "52f55145", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:17.200516Z", "iopub.status.busy": "2026-05-19T20:32:17.200398Z", "iopub.status.idle": "2026-05-19T20:32:17.407534Z", "shell.execute_reply": "2026-05-19T20:32:17.406652Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RooWorkspace(w) w contents\n", "\n", "variables\n", "---------\n", "(c,d,f,m,m_run1,m_run2,p0,s,x)\n", "\n", "p.d.f.s\n", "-------\n", "RooGaussian::g[ x=x mean=m sigma=s ] = 1\n", "RooGaussian::g_run1[ x=x mean=m_run1 sigma=s ] = 0.011109\n", "RooGaussian::g_run2[ x=x mean=m_run2 sigma=s ] = 0.011109\n", "RooAddPdf::model[ f * g + [%] * p ] = 1/1\n", "RooAddPdf::model_run1[ f * g_run1 + [%] * p ] = 0.505554/1\n", "RooAddPdf::model_run2[ f * g_run2 + [%] * p ] = 0.505554/1\n", "RooSimultaneous::model_sim[ indexCat=c run1=model_run1 run2=model_run2 ] = 0.505554\n", "RooPolynomial::p[ x=x coefList=(p0) ] = 1\n", "\n" ] } ], "source": [ "w.Print(\"v\");" ] }, { "cell_type": "markdown", "id": "ce913908", "metadata": {}, "source": [ "Build a simultaneous model with product split\n", "-----------------------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "20f5c4f5", "metadata": {}, "source": [ "Build another simultaneous pdf using a composite split in states c X d" ] }, { "cell_type": "code", "execution_count": 12, "id": "f81b6f0a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:17.409185Z", "iopub.status.busy": "2026-05-19T20:32:17.409057Z", "iopub.status.idle": "2026-05-19T20:32:17.616932Z", "shell.execute_reply": "2026-05-19T20:32:17.616516Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Splitrule for p.d.f model with state list \n", " parameter p0 is split with constraint in categories (c,d)\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: list of prototype pdfs (model)\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: list of splitting categories (c,d)\n", "[#1] INFO:ObjectHandling -- RooSimPdfBuilder::executeBuild: processing prototype pdf model\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooMultiCategory::c,d\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: configured customizers for all prototype pdfs\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: Customizing prototype pdf model for mode {run1;bar}\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: Customizing prototype pdf model for mode {run1;foo}\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: Customizing prototype pdf model for mode {run2;bar}\n", "[#1] INFO:ObjectHandling -- RooSimWSTool::executeBuild: Customizing prototype pdf model for mode {run2;foo}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooSimultaneous::model_sim2\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooSuperCategory::model_sim2_index\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooMultiCategory::model_sim2_index_internalMultiCat\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model_{run1;bar}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooPolynomial::p_{run1;bar}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::p0_{run1;bar}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model_{run1;foo}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooPolynomial::p_{run1;foo}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::p0_{run1;foo}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model_{run2;bar}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooPolynomial::p_{run2;bar}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::p0_{run2;bar}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model_{run2;foo}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooPolynomial::p_{run2;foo}\n", "[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::p0_{run2;foo}\n" ] } ], "source": [ "RooSimultaneous *model_sim2 = sct.build(\"model_sim2\", \"model\", SplitParam(\"p0\", \"c,d\"));" ] }, { "cell_type": "markdown", "id": "693ef235", "metadata": {}, "source": [ "Print tree structure of this model" ] }, { "cell_type": "code", "execution_count": 13, "id": "8d2d2856", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:17.618726Z", "iopub.status.busy": "2026-05-19T20:32:17.618579Z", "iopub.status.idle": "2026-05-19T20:32:17.826570Z", "shell.execute_reply": "2026-05-19T20:32:17.825920Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0x7f75717cb150 RooSimultaneous::model_sim2 = 1 [Auto,Dirty] \n", " 0x7f7571553b30/V- RooSuperCategory::model_sim2_index = {run2;foo}(idx = 1)\n", " [Auto,Clean] \n", " 0x7f75714c75f0/VS RooMultiCategory::model_sim2_index_internalMultiCat = {run2;foo}(idx = 1)\n", " [Auto,Clean] \n", " 0x7f75714f4260/VS RooCategory::c = run2(idx = 1)\n", "\n", " 0x7f7571412b90/VS RooCategory::d = foo(idx = 0)\n", "\n", " 0x7f75714c7a20/V- RooAddPdf::model_{run1;bar} = 1/1 [Auto,Clean] \n", " 0x7f75716d8b10/V- RooGaussian::g = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f757154df20/V- RooRealVar::m = 0\n", " 0x7f757176e800/V- RooRealVar::s = 1\n", " 0x7f757176f5b0/V- RooRealVar::f = 0.5\n", " 0x7f75717d0e30/V- RooPolynomial::p_{run1;bar} = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75717d33c0/V- RooRealVar::p0_{run1;bar} = 0.01\n", " 0x7f75717d3a40/V- RooAddPdf::model_{run1;foo} = 1/1 [Auto,Clean] \n", " 0x7f75716d8b10/V- RooGaussian::g = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f757154df20/V- RooRealVar::m = 0\n", " 0x7f757176e800/V- RooRealVar::s = 1\n", " 0x7f757176f5b0/V- RooRealVar::f = 0.5\n", " 0x7f75717d8630/V- RooPolynomial::p_{run1;foo} = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75717f3b70/V- RooRealVar::p0_{run1;foo} = 0.01\n", " 0x7f75717f41f0/V- RooAddPdf::model_{run2;bar} = 1/1 [Auto,Clean] \n", " 0x7f75716d8b10/V- RooGaussian::g = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f757154df20/V- RooRealVar::m = 0\n", " 0x7f757176e800/V- RooRealVar::s = 1\n", " 0x7f757176f5b0/V- RooRealVar::f = 0.5\n", " 0x7f75717f8e00/V- RooPolynomial::p_{run2;bar} = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f75717fb330/V- RooRealVar::p0_{run2;bar} = 0.01\n", " 0x7f75717fb9b0/V- RooAddPdf::model_{run2;foo} = 1/1 [Auto,Clean] \n", " 0x7f75716d8b10/V- RooGaussian::g = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f757154df20/V- RooRealVar::m = 0\n", " 0x7f757176e800/V- RooRealVar::s = 1\n", " 0x7f757176f5b0/V- RooRealVar::f = 0.5\n", " 0x7f757181d4a0/V- RooPolynomial::p_{run2;foo} = 1 [Auto,Dirty] \n", " 0x7f757176dcc0/V- RooRealVar::x = 0\n", " 0x7f757181f6c0/V- RooRealVar::p0_{run2;foo} = 0.01\n" ] } ], "source": [ "model_sim2->Print(\"t\");" ] } ], "metadata": { "kernelspec": { "display_name": "ROOT C++", "language": "c++", "name": "root" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".C", "mimetype": " text/x-c++src", "name": "c++" } }, "nbformat": 4, "nbformat_minor": 5 }