{ "cells": [ { "cell_type": "markdown", "id": "c36a6ac7", "metadata": {}, "source": [ "# rf501_simultaneouspdf\n", "Organisation and simultaneous fits: using simultaneous pdfs to describe simultaneous\n", "fits to multiple datasets\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": "27a1e2d0", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:06.187044Z", "iopub.status.busy": "2026-05-19T20:32:06.186934Z", "iopub.status.idle": "2026-05-19T20:32:06.202677Z", "shell.execute_reply": "2026-05-19T20:32:06.201766Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \"RooRealVar.h\"\n", "#include \"RooDataSet.h\"\n", "#include \"RooGaussian.h\"\n", "#include \"RooChebychev.h\"\n", "#include \"RooAddPdf.h\"\n", "#include \"RooSimultaneous.h\"\n", "#include \"RooCategory.h\"\n", "#include \"TCanvas.h\"\n", "#include \"TAxis.h\"\n", "#include \"RooPlot.h\"\n", "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "a3467bf0", "metadata": {}, "source": [ "Create model for physics sample\n", "-------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "fa0c1a46", "metadata": {}, "source": [ "Create observables" ] }, { "cell_type": "code", "execution_count": 2, "id": "83d3008b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:06.205058Z", "iopub.status.busy": "2026-05-19T20:32:06.204945Z", "iopub.status.idle": "2026-05-19T20:32:06.519261Z", "shell.execute_reply": "2026-05-19T20:32:06.518492Z" } }, "outputs": [], "source": [ "RooRealVar x(\"x\", \"x\", -8, 8);" ] }, { "cell_type": "markdown", "id": "4b48aaac", "metadata": {}, "source": [ "Construct signal pdf" ] }, { "cell_type": "code", "execution_count": 3, "id": "575bc259", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:06.520992Z", "iopub.status.busy": "2026-05-19T20:32:06.520873Z", "iopub.status.idle": "2026-05-19T20:32:06.729051Z", "shell.execute_reply": "2026-05-19T20:32:06.728397Z" } }, "outputs": [], "source": [ "RooRealVar mean(\"mean\", \"mean\", 0, -8, 8);\n", "RooRealVar sigma(\"sigma\", \"sigma\", 0.3, 0.1, 10);\n", "RooGaussian gx(\"gx\", \"gx\", x, mean, sigma);" ] }, { "cell_type": "markdown", "id": "8fb95904", "metadata": {}, "source": [ "Construct background pdf" ] }, { "cell_type": "code", "execution_count": 4, "id": "800404a8", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:06.731179Z", "iopub.status.busy": "2026-05-19T20:32:06.731050Z", "iopub.status.idle": "2026-05-19T20:32:06.939307Z", "shell.execute_reply": "2026-05-19T20:32:06.938591Z" } }, "outputs": [], "source": [ "RooRealVar a0(\"a0\", \"a0\", -0.1, -1, 1);\n", "RooRealVar a1(\"a1\", \"a1\", 0.004, -1, 1);\n", "RooChebychev px(\"px\", \"px\", x, RooArgSet(a0, a1));" ] }, { "cell_type": "markdown", "id": "e9f52908", "metadata": {}, "source": [ "Construct composite pdf" ] }, { "cell_type": "code", "execution_count": 5, "id": "a28d5e5d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:06.940874Z", "iopub.status.busy": "2026-05-19T20:32:06.940741Z", "iopub.status.idle": "2026-05-19T20:32:07.149298Z", "shell.execute_reply": "2026-05-19T20:32:07.148521Z" } }, "outputs": [], "source": [ "RooRealVar f(\"f\", \"f\", 0.2, 0., 1.);\n", "RooAddPdf model(\"model\", \"model\", RooArgList(gx, px), f);" ] }, { "cell_type": "markdown", "id": "3ce6f0a7", "metadata": {}, "source": [ "Create model for control sample\n", "--------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "d9a01158", "metadata": {}, "source": [ "Construct signal pdf.\n", "NOTE that sigma is shared with the signal sample model" ] }, { "cell_type": "code", "execution_count": 6, "id": "65f0d8fa", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:07.150818Z", "iopub.status.busy": "2026-05-19T20:32:07.150674Z", "iopub.status.idle": "2026-05-19T20:32:07.359063Z", "shell.execute_reply": "2026-05-19T20:32:07.358556Z" } }, "outputs": [], "source": [ "RooRealVar mean_ctl(\"mean_ctl\", \"mean_ctl\", -3, -8, 8);\n", "RooGaussian gx_ctl(\"gx_ctl\", \"gx_ctl\", x, mean_ctl, sigma);" ] }, { "cell_type": "markdown", "id": "92bdd7b8", "metadata": {}, "source": [ "Construct the background pdf" ] }, { "cell_type": "code", "execution_count": 7, "id": "b8ad72b7", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:07.361348Z", "iopub.status.busy": "2026-05-19T20:32:07.361226Z", "iopub.status.idle": "2026-05-19T20:32:07.569321Z", "shell.execute_reply": "2026-05-19T20:32:07.568769Z" } }, "outputs": [], "source": [ "RooRealVar a0_ctl(\"a0_ctl\", \"a0_ctl\", -0.1, -1, 1);\n", "RooRealVar a1_ctl(\"a1_ctl\", \"a1_ctl\", 0.5, -0.1, 1);\n", "RooChebychev px_ctl(\"px_ctl\", \"px_ctl\", x, RooArgSet(a0_ctl, a1_ctl));" ] }, { "cell_type": "markdown", "id": "2f8521e2", "metadata": {}, "source": [ "Construct the composite model" ] }, { "cell_type": "code", "execution_count": 8, "id": "27e0a578", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:07.571018Z", "iopub.status.busy": "2026-05-19T20:32:07.570900Z", "iopub.status.idle": "2026-05-19T20:32:07.778925Z", "shell.execute_reply": "2026-05-19T20:32:07.778433Z" } }, "outputs": [], "source": [ "RooRealVar f_ctl(\"f_ctl\", \"f_ctl\", 0.5, 0., 1.);\n", "RooAddPdf model_ctl(\"model_ctl\", \"model_ctl\", RooArgList(gx_ctl, px_ctl), f_ctl);" ] }, { "cell_type": "markdown", "id": "24102611", "metadata": {}, "source": [ "Generate events for both samples\n", "---------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "29f6ceee", "metadata": {}, "source": [ "Generate 1000 events in x and y from model" ] }, { "cell_type": "code", "execution_count": 9, "id": "0265d3e2", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:07.780985Z", "iopub.status.busy": "2026-05-19T20:32:07.780851Z", "iopub.status.idle": "2026-05-19T20:32:07.989517Z", "shell.execute_reply": "2026-05-19T20:32:07.989047Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_56:2:2: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n", " std::unique_ptr data{model.generate({x}, 1000)};\n", " ^\n" ] } ], "source": [ "std::unique_ptr data{model.generate({x}, 1000)};\n", "std::unique_ptr data_ctl{model_ctl.generate({x}, 2000)};" ] }, { "cell_type": "markdown", "id": "140cdfd3", "metadata": {}, "source": [ "Create index category and join samples\n", "---------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "8c58d60f", "metadata": {}, "source": [ "Define category to distinguish physics and control samples events" ] }, { "cell_type": "code", "execution_count": 10, "id": "5824ee13", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:07.991059Z", "iopub.status.busy": "2026-05-19T20:32:07.990933Z", "iopub.status.idle": "2026-05-19T20:32:08.196361Z", "shell.execute_reply": "2026-05-19T20:32:08.196035Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_57:2:2: warning: 'sample' shadows a declaration with the same name in the 'std' namespace; use '::sample' to reference this declaration\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n" ] } ], "source": [ "RooCategory sample(\"sample\", \"sample\");\n", "sample.defineType(\"physics\");\n", "sample.defineType(\"control\");" ] }, { "cell_type": "markdown", "id": "ae84db2c", "metadata": {}, "source": [ "Construct combined dataset in (x,sample)" ] }, { "cell_type": "code", "execution_count": 11, "id": "35095113", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:08.197935Z", "iopub.status.busy": "2026-05-19T20:32:08.197809Z", "iopub.status.idle": "2026-05-19T20:32:08.407207Z", "shell.execute_reply": "2026-05-19T20:32:08.406730Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_58:2:60: error: reference to 'sample' is ambiguous\n", " RooDataSet combData(\"combData\", \"combined data\", x, Index(sample),\n", " ^\n", "input_line_57:2:14: note: candidate found by name lookup is 'sample'\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_algo.h:5826:5: note: candidate found by name lookup is 'std::sample'\n", " sample(_PopulationIterator __first, _PopulationIterator __last,\n", " ^\n", "input_line_58:3:41: error: reference to 'data' is ambiguous\n", " Import({{\"physics\", data.get()}, {\"control\", data_ctl.get()}}));\n", " ^\n", "input_line_56:2:30: note: candidate found by name lookup is 'data'\n", " std::unique_ptr data{model.generate({x}, 1000)};\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n", " data(initializer_list<_Tp> __il) noexcept\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\n", " data(_Container& __cont) noexcept(noexcept(__cont.data()))\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:323:5: note: candidate found by name lookup is 'std::data'\n", " data(const _Container& __cont) noexcept(noexcept(__cont.data()))\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:334:5: note: candidate found by name lookup is 'std::data'\n", " data(_Tp (&__array)[_Nm]) noexcept\n", " ^\n" ] } ], "source": [ "RooDataSet combData(\"combData\", \"combined data\", x, Index(sample),\n", " Import({{\"physics\", data.get()}, {\"control\", data_ctl.get()}}));" ] }, { "cell_type": "markdown", "id": "56fe023f", "metadata": {}, "source": [ "Construct a simultaneous pdf in (x,sample)\n", "-----------------------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "54939eb0", "metadata": {}, "source": [ "Construct a simultaneous pdf using category sample as index:\n", "associate model with the physics state and model_ctl with the control state" ] }, { "cell_type": "code", "execution_count": 12, "id": "fac152f0", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:08.408485Z", "iopub.status.busy": "2026-05-19T20:32:08.408370Z", "iopub.status.idle": "2026-05-19T20:32:08.617119Z", "shell.execute_reply": "2026-05-19T20:32:08.616560Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_59:2:103: error: reference to 'sample' is ambiguous\n", " RooSimultaneous simPdf(\"simPdf\", \"simultaneous pdf\", {{\"physics\", &model}, {\"control\", &model_ctl}}, sample);\n", " ^\n", "input_line_57:2:14: note: candidate found by name lookup is 'sample'\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_algo.h:5826:5: note: candidate found by name lookup is 'std::sample'\n", " sample(_PopulationIterator __first, _PopulationIterator __last,\n", " ^\n" ] } ], "source": [ "RooSimultaneous simPdf(\"simPdf\", \"simultaneous pdf\", {{\"physics\", &model}, {\"control\", &model_ctl}}, sample);" ] }, { "cell_type": "markdown", "id": "e3ed0bef", "metadata": {}, "source": [ "Perform a simultaneous fit\n", "---------------------------------------------------" ] }, { "cell_type": "markdown", "id": "80c566e4", "metadata": {}, "source": [ "Perform simultaneous fit of model to data and model_ctl to data_ctl" ] }, { "cell_type": "code", "execution_count": 13, "id": "738e830c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:08.618391Z", "iopub.status.busy": "2026-05-19T20:32:08.618269Z", "iopub.status.idle": "2026-05-19T20:32:08.826983Z", "shell.execute_reply": "2026-05-19T20:32:08.826427Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_60:2:65: error: cannot initialize an array element of type 'void *' with an rvalue of type 'RooCmdArg (*)(bool)'\n", " std::unique_ptr fitResult{simPdf.fitTo(combData, Save(), PrintLevel(-1))};\n", " ^~~~\n", "input_line_60:2:73: error: cannot initialize an array element of type 'void *' with an rvalue of type 'RooCmdArg (*)(Int_t)' (aka 'RooCmdArg (*)(int)')\n", " std::unique_ptr fitResult{simPdf.fitTo(combData, Save(), PrintLevel(-1))};\n", " ^~~~~~~~~~\n" ] } ], "source": [ "std::unique_ptr fitResult{simPdf.fitTo(combData, Save(), PrintLevel(-1))};\n", "fitResult->Print();" ] }, { "cell_type": "markdown", "id": "a2301b64", "metadata": {}, "source": [ "Plot model slices on data slices\n", "----------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "e818ac07", "metadata": {}, "source": [ "Make a frame for the physics sample" ] }, { "cell_type": "code", "execution_count": 14, "id": "80820a18", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:08.828284Z", "iopub.status.busy": "2026-05-19T20:32:08.828164Z", "iopub.status.idle": "2026-05-19T20:32:09.033580Z", "shell.execute_reply": "2026-05-19T20:32:09.032967Z" } }, "outputs": [], "source": [ "RooPlot *frame1 = x.frame(Title(\"Physics sample\"));" ] }, { "cell_type": "markdown", "id": "d0130b73", "metadata": {}, "source": [ "Plot all data tagged as physics sample" ] }, { "cell_type": "code", "execution_count": 15, "id": "69cf9565", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:09.035152Z", "iopub.status.busy": "2026-05-19T20:32:09.035027Z", "iopub.status.idle": "2026-05-19T20:32:09.243587Z", "shell.execute_reply": "2026-05-19T20:32:09.243145Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_62:2:58: error: cannot initialize an array element of type 'void *' with an rvalue of type 'RooCmdArg (*)(const char *)'\n", " std::unique_ptr slicedData1{combData.reduce(Cut(\"sample==sample::physics\"))};\n", " ^~~\n" ] } ], "source": [ "std::unique_ptr slicedData1{combData.reduce(Cut(\"sample==sample::physics\"))};\n", "slicedData1->plotOn(frame1);" ] }, { "cell_type": "markdown", "id": "fda7413a", "metadata": {}, "source": [ "Plot \"physics\" slice of simultaneous pdf." ] }, { "cell_type": "code", "execution_count": 16, "id": "f961bea9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:09.244991Z", "iopub.status.busy": "2026-05-19T20:32:09.244883Z", "iopub.status.idle": "2026-05-19T20:32:09.454054Z", "shell.execute_reply": "2026-05-19T20:32:09.453394Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_63:3:70: error: cannot take the address of an rvalue of type 'ELineStyle'\n", "simPdf.getPdf(\"physics\")->plotOn(frame1, Components(\"px\"), LineStyle(kDashed));\n", " ^~~~~~~\n", "Error while creating dynamic expression for:\n", " simPdf.getPdf(\"physics\")->plotOn(frame1, Components(\"px\"), LineStyle(kDashed))\n" ] } ], "source": [ "simPdf.getPdf(\"physics\")->plotOn(frame1);\n", "simPdf.getPdf(\"physics\")->plotOn(frame1, Components(\"px\"), LineStyle(kDashed));" ] }, { "cell_type": "markdown", "id": "1a3b41bf", "metadata": {}, "source": [ "The same plot for the control sample slice. We do this with a different\n", "approach, using the data slice for the projection. This approach is more\n", "general, because you can plot sums of slices by using logical or in the\n", "Cut() command.\n", "NBL You _must_ project the sample index category with data using ProjWData\n", "as a RooSimultaneous makes no prediction on the shape in the index category\n", "and can thus not be integrated.\n", "In other words: Since the PDF doesn't know the number of events in the different\n", "category states, it doesn't know how much of each component it has to project out.\n", "This information is read from the data." ] }, { "cell_type": "code", "execution_count": 17, "id": "7af6fc26", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:09.455629Z", "iopub.status.busy": "2026-05-19T20:32:09.455446Z", "iopub.status.idle": "2026-05-19T20:32:09.667729Z", "shell.execute_reply": "2026-05-19T20:32:09.666996Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_64:5:33: error: reference to 'sample' is ambiguous\n", "simPdf.plotOn(frame2, ProjWData(sample, *slicedData2));\n", " ^\n", "input_line_57:2:14: note: candidate found by name lookup is 'sample'\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_algo.h:5826:5: note: candidate found by name lookup is 'std::sample'\n", " sample(_PopulationIterator __first, _PopulationIterator __last,\n", " ^\n", "input_line_64:6:1: error: use of undeclared identifier 'simPdf'\n", "simPdf.plotOn(frame2, Components(\"px_ctl\"), ProjWData(sample, *slicedData2), LineStyle(kDashed));\n", "^\n", "input_line_64:6:55: error: reference to 'sample' is ambiguous\n", "simPdf.plotOn(frame2, Components(\"px_ctl\"), ProjWData(sample, *slicedData2), LineStyle(kDashed));\n", " ^\n", "input_line_57:2:14: note: candidate found by name lookup is 'sample'\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_algo.h:5826:5: note: candidate found by name lookup is 'std::sample'\n", " sample(_PopulationIterator __first, _PopulationIterator __last,\n", " ^\n", "input_line_64:3:57: error: cannot initialize an array element of type 'void *' with an rvalue of type 'RooCmdArg (*)(const char *)'\n", "std::unique_ptr slicedData2{combData.reduce(Cut(\"sample==sample::control\"))};\n", " ^~~\n" ] } ], "source": [ "RooPlot *frame2 = x.frame(Bins(30), Title(\"Control sample\"));\n", "std::unique_ptr slicedData2{combData.reduce(Cut(\"sample==sample::control\"))};\n", "slicedData2->plotOn(frame2);\n", "simPdf.plotOn(frame2, ProjWData(sample, *slicedData2));\n", "simPdf.plotOn(frame2, Components(\"px_ctl\"), ProjWData(sample, *slicedData2), LineStyle(kDashed));" ] }, { "cell_type": "markdown", "id": "359029c0", "metadata": {}, "source": [ "The same plot for all the phase space. Here, we can just use the original\n", "combined dataset." ] }, { "cell_type": "code", "execution_count": 18, "id": "f0e67add", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:09.669299Z", "iopub.status.busy": "2026-05-19T20:32:09.669125Z", "iopub.status.idle": "2026-05-19T20:32:09.880803Z", "shell.execute_reply": "2026-05-19T20:32:09.880469Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_65:4:33: error: reference to 'sample' is ambiguous\n", "simPdf.plotOn(frame3, ProjWData(sample, combData));\n", " ^\n", "input_line_57:2:14: note: candidate found by name lookup is 'sample'\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_algo.h:5826:5: note: candidate found by name lookup is 'std::sample'\n", " sample(_PopulationIterator __first, _PopulationIterator __last,\n", " ^\n", "input_line_65:4:41: error: use of undeclared identifier 'combData'\n", "simPdf.plotOn(frame3, ProjWData(sample, combData));\n", " ^\n", "input_line_65:5:1: error: use of undeclared identifier 'simPdf'\n", "simPdf.plotOn(frame3, Components(\"px,px_ctl\"), ProjWData(sample, combData),\n", "^\n", "input_line_65:5:58: error: reference to 'sample' is ambiguous\n", "simPdf.plotOn(frame3, Components(\"px,px_ctl\"), ProjWData(sample, combData),\n", " ^\n", "input_line_57:2:14: note: candidate found by name lookup is 'sample'\n", " RooCategory sample(\"sample\", \"sample\");\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/stl_algo.h:5826:5: note: candidate found by name lookup is 'std::sample'\n", " sample(_PopulationIterator __first, _PopulationIterator __last,\n", " ^\n", "input_line_65:5:66: error: use of undeclared identifier 'combData'\n", "simPdf.plotOn(frame3, Components(\"px,px_ctl\"), ProjWData(sample, combData),\n", " ^\n", "input_line_65:17:10: error: use of undeclared identifier 'frame2'\n", "draw(2, *frame2);\n", " ^\n" ] } ], "source": [ "RooPlot *frame3 = x.frame(Title(\"Both samples\"));\n", "combData.plotOn(frame3);\n", "simPdf.plotOn(frame3, ProjWData(sample, combData));\n", "simPdf.plotOn(frame3, Components(\"px,px_ctl\"), ProjWData(sample, combData),\n", " LineStyle(kDashed));\n", "\n", "TCanvas *c = new TCanvas(\"rf501_simultaneouspdf\", \"rf403_simultaneouspdf\", 1200, 400);\n", "c->Divide(3);\n", "auto draw = [&](int i, RooPlot & frame) {\n", " c->cd(i);\n", " gPad->SetLeftMargin(0.15);\n", " frame.GetYaxis()->SetTitleOffset(1.4);\n", " frame.Draw();\n", "};\n", "draw(1, *frame1);\n", "draw(2, *frame2);\n", "draw(3, *frame3);" ] }, { "cell_type": "markdown", "id": "20905e60", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 19, "id": "e4685c7a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:32:09.882952Z", "iopub.status.busy": "2026-05-19T20:32:09.882833Z", "iopub.status.idle": "2026-05-19T20:32:10.113176Z", "shell.execute_reply": "2026-05-19T20:32:10.112532Z" } }, "outputs": [], "source": [ "%jsroot on\n", "gROOT->GetListOfCanvases()->Draw()" ] } ], "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 }