{
"cells": [
{
"cell_type": "markdown",
"id": "e0587129",
"metadata": {},
"source": [
"# StandardHistFactoryPlotsWithCategories\n",
"StandardHistFactoryPlotsWithCategories\n",
"\n",
" This is a standard demo that can be used with any ROOT file\n",
" prepared in the standard way. You specify:\n",
" - name for input ROOT file\n",
" - name of workspace inside ROOT file that holds model and data\n",
" - name of ModelConfig that specifies details for calculator tools\n",
" - name of dataset\n",
"\n",
" With default parameters the macro will attempt to run the\n",
" standard hist2workspace example and read the ROOT file\n",
" that it produces.\n",
"\n",
" The macro will scan through all the categories in a simPdf find the corresponding\n",
" observable. For each category, it will loop through each of the nuisance parameters\n",
" and plot\n",
" - the data\n",
" - the nominal model (blue)\n",
" - the +Nsigma (red)\n",
" - the -Nsigma (green)\n",
"\n",
" You can specify how many sigma to vary by changing nSigmaToVary.\n",
" You can also change the signal rate by changing muVal.\n",
"\n",
" The script produces a lot plots, you can merge them by doing:\n",
"```cpp\n",
" gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=merged.pdf `ls *pdf`\n",
"```\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Kyle Cranmer \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:36 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e1292efb",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:19.250308Z",
"iopub.status.busy": "2026-05-19T20:36:19.250191Z",
"iopub.status.idle": "2026-05-19T20:36:19.266978Z",
"shell.execute_reply": "2026-05-19T20:36:19.266495Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"TFile.h\"\n",
"#include \"TROOT.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TList.h\"\n",
"#include \"TMath.h\"\n",
"#include \"TSystem.h\"\n",
"#include \"RooWorkspace.h\"\n",
"#include \"RooAbsData.h\"\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooPlot.h\"\n",
"#include \"RooSimultaneous.h\"\n",
"#include \"RooCategory.h\"\n",
"\n",
"#include \"RooStats/ModelConfig.h\"\n",
"#include \"RooStats/ProfileInspector.h\"\n",
"\n",
"using namespace RooFit;\n",
"using namespace RooStats;\n",
"using std::cout, std::endl;"
]
},
{
"cell_type": "markdown",
"id": "617f60cb",
"metadata": {},
"source": [
" Arguments are defined. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "5f069442",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:19.268425Z",
"iopub.status.busy": "2026-05-19T20:36:19.268307Z",
"iopub.status.idle": "2026-05-19T20:36:19.599075Z",
"shell.execute_reply": "2026-05-19T20:36:19.598515Z"
}
},
"outputs": [],
"source": [
"const char *infile = \"\";\n",
"const char *workspaceName = \"combined\";\n",
"const char *modelConfigName = \"ModelConfig\";\n",
"const char *dataName = \"obsData\";"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "cdbffdad",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:19.601657Z",
"iopub.status.busy": "2026-05-19T20:36:19.601520Z",
"iopub.status.idle": "2026-05-19T20:36:19.812612Z",
"shell.execute_reply": "2026-05-19T20:36:19.811138Z"
}
},
"outputs": [],
"source": [
"double nSigmaToVary = 5.;\n",
"double muVal = 0;\n",
"bool doFit = false;"
]
},
{
"cell_type": "markdown",
"id": "971e3d62",
"metadata": {},
"source": [
"-------------------------------------------------------\n",
"First part is just to access a user-defined file\n",
"or create the standard example file if it doesn't exist"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "280d3137",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:19.818042Z",
"iopub.status.busy": "2026-05-19T20:36:19.817913Z",
"iopub.status.idle": "2026-05-19T20:36:20.026612Z",
"shell.execute_reply": "2026-05-19T20:36:20.026219Z"
}
},
"outputs": [],
"source": [
"const char *filename = \"\";\n",
"if (!strcmp(infile, \"\")) {\n",
" filename = \"results/example_combined_GaussExample_model.root\";\n",
" bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code\n",
" // if file does not exists generate with histfactory\n",
" if (!fileExist) {\n",
" // Normally this would be run on the command line\n",
" cout << \"will run standard hist2workspace example\" << endl;\n",
" gROOT->ProcessLine(\".! prepareHistFactory .\");\n",
" gROOT->ProcessLine(\".! hist2workspace config/example.xml\");\n",
" cout << \"\\n\\n---------------------\" << endl;\n",
" cout << \"Done creating example input\" << endl;\n",
" cout << \"---------------------\\n\\n\" << endl;\n",
" }\n",
"\n",
"} else\n",
" filename = infile;"
]
},
{
"cell_type": "markdown",
"id": "6b127cd7",
"metadata": {},
"source": [
"Try to open the file"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1d07dedb",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:20.042828Z",
"iopub.status.busy": "2026-05-19T20:36:20.042684Z",
"iopub.status.idle": "2026-05-19T20:36:20.251324Z",
"shell.execute_reply": "2026-05-19T20:36:20.250749Z"
}
},
"outputs": [],
"source": [
"TFile *file = TFile::Open(filename);"
]
},
{
"cell_type": "markdown",
"id": "9194fd31",
"metadata": {},
"source": [
"if input file was specified but not found, quit"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "50b835a6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:20.263381Z",
"iopub.status.busy": "2026-05-19T20:36:20.263255Z",
"iopub.status.idle": "2026-05-19T20:36:20.465014Z",
"shell.execute_reply": "2026-05-19T20:36:20.464645Z"
}
},
"outputs": [],
"source": [
"if (!file) {\n",
" cout << \"StandardRooStatsDemoMacro: Input file \" << filename << \" is not found\" << endl;\n",
" return;\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "bab1578e",
"metadata": {},
"source": [
"-------------------------------------------------------\n",
"Tutorial starts here\n",
"-------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "60b424cc",
"metadata": {},
"source": [
"get the workspace out of the file"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "3a7cb937",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:20.472659Z",
"iopub.status.busy": "2026-05-19T20:36:20.472500Z",
"iopub.status.idle": "2026-05-19T20:36:20.827835Z",
"shell.execute_reply": "2026-05-19T20:36:20.827155Z"
}
},
"outputs": [],
"source": [
"RooWorkspace *w = (RooWorkspace *)file->Get(workspaceName);\n",
"if (!w) {\n",
" cout << \"workspace not found\" << endl;\n",
" return;\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "fe9333d8",
"metadata": {},
"source": [
"get the modelConfig out of the file"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "89d47f30",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:20.829625Z",
"iopub.status.busy": "2026-05-19T20:36:20.829491Z",
"iopub.status.idle": "2026-05-19T20:36:21.038792Z",
"shell.execute_reply": "2026-05-19T20:36:21.038144Z"
}
},
"outputs": [],
"source": [
"ModelConfig *mc = (ModelConfig *)w->obj(modelConfigName);"
]
},
{
"cell_type": "markdown",
"id": "98176684",
"metadata": {},
"source": [
"get the modelConfig out of the file"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "e5da4e19",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:21.040911Z",
"iopub.status.busy": "2026-05-19T20:36:21.040791Z",
"iopub.status.idle": "2026-05-19T20:36:21.250449Z",
"shell.execute_reply": "2026-05-19T20:36:21.250122Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_77:2:2: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n",
" RooAbsData *data = w->data(dataName);\n",
" ^\n"
]
}
],
"source": [
"RooAbsData *data = w->data(dataName);"
]
},
{
"cell_type": "markdown",
"id": "0fd0b898",
"metadata": {},
"source": [
"make sure ingredients are found"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "297d8644",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:21.251831Z",
"iopub.status.busy": "2026-05-19T20:36:21.251705Z",
"iopub.status.idle": "2026-05-19T20:36:21.467098Z",
"shell.execute_reply": "2026-05-19T20:36:21.465702Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_78:2:7: error: reference to 'data' is ambiguous\n",
" if (!data || !mc) {\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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": [
"if (!data || !mc) {\n",
" w->Print();\n",
" cout << \"data or ModelConfig was not found\" << endl;\n",
" return;\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "a6ad8768",
"metadata": {},
"source": [
"-------------------------------------------------------\n",
"now use the profile inspector"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "fef257ed",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:21.468702Z",
"iopub.status.busy": "2026-05-19T20:36:21.468568Z",
"iopub.status.idle": "2026-05-19T20:36:21.678448Z",
"shell.execute_reply": "2026-05-19T20:36:21.677414Z"
}
},
"outputs": [],
"source": [
"RooRealVar *obs = (RooRealVar *)mc->GetObservables()->first();\n",
"std::vector frameList;\n",
"\n",
"RooRealVar *firstPOI = dynamic_cast(mc->GetParametersOfInterest()->first());\n",
"\n",
"firstPOI->setVal(muVal);"
]
},
{
"cell_type": "markdown",
"id": "c69e602c",
"metadata": {},
"source": [
"firstPOI->setConstant();"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "bb12d6d7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:21.680033Z",
"iopub.status.busy": "2026-05-19T20:36:21.679910Z",
"iopub.status.idle": "2026-05-19T20:36:21.895755Z",
"shell.execute_reply": "2026-05-19T20:36:21.894932Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_80:3:25: error: reference to 'data' is ambiguous\n",
" mc->GetPdf()->fitTo(*data);\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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": [
"if (doFit) {\n",
" mc->GetPdf()->fitTo(*data);\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "c159239f",
"metadata": {},
"source": [
"-------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "e8d96853",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:21.897355Z",
"iopub.status.busy": "2026-05-19T20:36:21.897238Z",
"iopub.status.idle": "2026-05-19T20:36:22.105039Z",
"shell.execute_reply": "2026-05-19T20:36:22.104278Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_81:23:4: error: reference to 'data' is ambiguous\n",
" data->plotOn(frame, MarkerSize(1),\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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",
"input_line_81:28:7: error: reference to 'data' is ambiguous\n",
" data->sumEntries(Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str()));\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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",
"input_line_81:32:66: error: reference to 'data' is ambiguous\n",
" cout << \"expected events = \" << mc->GetPdf()->expectedEvents(*data->get()) << endl;\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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",
"input_line_81:42:7: error: reference to 'data' is ambiguous\n",
" data->plotOn(frame, MarkerSize(1));\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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",
"input_line_81:83:10: error: reference to 'data' is ambiguous\n",
" data->plotOn(frame, MarkerSize(1),\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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",
"input_line_81:88:13: error: reference to 'data' is ambiguous\n",
" data->sumEntries(Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str()));\n",
" ^\n",
"input_line_77:2:14: note: candidate found by name lookup is 'data'\n",
" RooAbsData *data = w->data(dataName);\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": [
"mc->GetNuisanceParameters()->Print(\"v\");\n",
"int nPlotsMax = 1000;\n",
"cout << \" check expectedData by category\" << endl;\n",
"RooDataSet *simData = NULL;\n",
"RooSimultaneous *simPdf = NULL;\n",
"if (strcmp(mc->GetPdf()->ClassName(), \"RooSimultaneous\") == 0) {\n",
" cout << \"Is a simultaneous PDF\" << endl;\n",
" simPdf = (RooSimultaneous *)(mc->GetPdf());\n",
"} else {\n",
" cout << \"Is not a simultaneous PDF\" << endl;\n",
"}\n",
"\n",
"if (doFit) {\n",
" RooCategory *channelCat = (RooCategory *)(&simPdf->indexCat());\n",
" auto const& catName = channelCat->begin()->first;\n",
" RooAbsPdf *pdftmp = ((RooSimultaneous *)mc->GetPdf())->getPdf(catName.c_str());\n",
" std::unique_ptr obstmp{pdftmp->getObservables(*mc->GetObservables())};\n",
" obs = ((RooRealVar *)obstmp->first());\n",
" RooPlot *frame = obs->frame();\n",
" cout << Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str()) << endl;\n",
" cout << catName << \" \" << channelCat->getLabel() << endl;\n",
" data->plotOn(frame, MarkerSize(1),\n",
" Cut(Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str())),\n",
" DataError(RooAbsData::None));\n",
"\n",
" Double_t normCount =\n",
" data->sumEntries(Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str()));\n",
"\n",
" pdftmp->plotOn(frame, LineWidth(2.), Normalization(normCount, RooAbsReal::NumEvent));\n",
" frame->Draw();\n",
" cout << \"expected events = \" << mc->GetPdf()->expectedEvents(*data->get()) << endl;\n",
" return;\n",
"}\n",
"\n",
"int nPlots = 0;\n",
"if (!simPdf) {\n",
"\n",
" for (auto *var : static_range_cast(*mc->GetNuisanceParameters())) {\n",
" RooPlot *frame = obs->frame();\n",
" frame->SetYTitle(var->GetName());\n",
" data->plotOn(frame, MarkerSize(1));\n",
" const double value = var->getVal();\n",
" mc->GetPdf()->plotOn(frame, LineWidth(1.));\n",
" var->setVal(value + var->getError());\n",
" mc->GetPdf()->plotOn(frame, LineColor(kRed), LineStyle(kDashed), LineWidth(1));\n",
" var->setVal(value - var->getError());\n",
" mc->GetPdf()->plotOn(frame, LineColor(kGreen), LineStyle(kDashed), LineWidth(1));\n",
" frameList.push_back(frame);\n",
" var->setVal(value);\n",
" }\n",
"\n",
"} else {\n",
" RooCategory *channelCat = (RooCategory *)(&simPdf->indexCat());\n",
" for (auto const& tt : *channelCat) {\n",
"\n",
" if (nPlots == nPlotsMax) {\n",
" break;\n",
" }\n",
"\n",
" auto const& catName = tt.first;\n",
"\n",
" cout << \"on type \" << catName << \" \" << endl;\n",
" // Get pdf associated with state from simpdf\n",
" RooAbsPdf *pdftmp = simPdf->getPdf(catName.c_str());\n",
"\n",
" // Generate observables defined by the pdf associated with this state\n",
" std::unique_ptr obstmp{pdftmp->getObservables(*mc->GetObservables())};\n",
" // obstmp->Print();\n",
"\n",
" obs = ((RooRealVar *)obstmp->first());\n",
"\n",
" for (auto *var : static_range_cast(*mc->GetNuisanceParameters())) {\n",
" if (nPlots == nPlotsMax) break;\n",
"\n",
" TCanvas *c2 = new TCanvas(\"c2\");\n",
" RooPlot *frame = obs->frame();\n",
" frame->SetName(Form(\"frame%d\", nPlots));\n",
" frame->SetYTitle(var->GetName());\n",
"\n",
" cout << Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str()) << endl;\n",
" cout << catName << \" \" << channelCat->getLabel() << endl;\n",
" data->plotOn(frame, MarkerSize(1),\n",
" Cut(Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str())),\n",
" DataError(RooAbsData::None));\n",
"\n",
" Double_t normCount =\n",
" data->sumEntries(Form(\"%s==%s::%s\", channelCat->GetName(), channelCat->GetName(), catName.c_str()));\n",
"\n",
" // remember the nominal value\n",
" const double value = var->getVal();\n",
"\n",
" // w->allVars().Print(\"v\");\n",
" // mc->GetNuisanceParameters()->Print(\"v\");\n",
" // pdftmp->plotOn(frame,LineWidth(2.));\n",
" // mc->GetPdf()->plotOn(frame,LineWidth(2.),Slice(*channelCat,catName.c_str()),ProjWData(*data));\n",
" // pdftmp->plotOn(frame,LineWidth(2.),Slice(*channelCat,catName.c_str()),ProjWData(*data));\n",
" normCount = pdftmp->expectedEvents(*obs);\n",
" pdftmp->plotOn(frame, LineWidth(2.), Normalization(normCount, RooAbsReal::NumEvent)); // nominal\n",
"\n",
" var->setVal(value + nSigmaToVary * var->getError());\n",
" // pdftmp->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2));\n",
" // mc->GetPdf()->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2.),Slice(*channelCat,catName.c_str()),ProjWData(*data));\n",
" // pdftmp->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2.),Slice(*channelCat,catName.c_str()),ProjWData(*data));\n",
" normCount = pdftmp->expectedEvents(*obs);\n",
" pdftmp->plotOn(frame, LineWidth(2.), LineColor(kRed), LineStyle(kDashed),\n",
" Normalization(normCount, RooAbsReal::NumEvent)); // +n sigma\n",
"\n",
" var->setVal(value - nSigmaToVary * var->getError());\n",
" // pdftmp->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2));\n",
" // mc->GetPdf()->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2),Slice(*channelCat,catName.c_str()),ProjWData(*data));\n",
" // pdftmp->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2),Slice(*channelCat,catName.c_str()),ProjWData(*data));\n",
" normCount = pdftmp->expectedEvents(*obs);\n",
" pdftmp->plotOn(frame, LineWidth(2.), LineColor(kGreen), LineStyle(kDashed),\n",
" Normalization(normCount, RooAbsReal::NumEvent)); // -n sigma\n",
"\n",
" // set them back to normal\n",
" var->setVal(value);\n",
"\n",
" frameList.push_back(frame);\n",
"\n",
" // quit making plots\n",
" ++nPlots;\n",
"\n",
" frame->Draw();\n",
" c2->SaveAs(Form(\"%s_%s_%s.pdf\", catName.c_str(), obs->GetName(), var->GetName()));\n",
" delete c2;\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "ce9a472d",
"metadata": {},
"source": [
"-------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "4bc8acd7",
"metadata": {},
"source": [
"now make plots"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "5142ad03",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:22.106572Z",
"iopub.status.busy": "2026-05-19T20:36:22.106459Z",
"iopub.status.idle": "2026-05-19T20:36:22.309115Z",
"shell.execute_reply": "2026-05-19T20:36:22.308102Z"
}
},
"outputs": [],
"source": [
"TCanvas *c1 = new TCanvas(\"c1\", \"ProfileInspectorDemo\", 800, 200);\n",
"int nFrames = frameList.size();\n",
"if (nFrames > 4) {\n",
" int nx = (int)sqrt(nFrames);\n",
" int ny = TMath::CeilNint(nFrames / nx);\n",
" nx = TMath::CeilNint(sqrt(nFrames));\n",
" c1->Divide(ny, nx);\n",
"} else\n",
" c1->Divide(nFrames);\n",
"for (int i = 0; i < nFrames; ++i) {\n",
" c1->cd(i + 1);\n",
" frameList[i]->Draw();\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "50e04555",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "11430c1f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:36:22.310695Z",
"iopub.status.busy": "2026-05-19T20:36:22.310551Z",
"iopub.status.idle": "2026-05-19T20:36:22.543808Z",
"shell.execute_reply": "2026-05-19T20:36:22.542860Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"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
}