{
"cells": [
{
"cell_type": "markdown",
"id": "602e7369",
"metadata": {},
"source": [
"# mt_readNtuplesFillHistosAndFit\n",
"Read n-tuples in distinct workers, fill histograms, merge them and fit.\n",
"Knowing that other facilities like TProcessExecutor might be more adequate for\n",
"this operation, this tutorial complements mc101, reading and merging.\n",
"We convey another message with this tutorial: the synergy of ROOT and\n",
"STL algorithms is possible.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Danilo Piparo \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:17 PM."
]
},
{
"cell_type": "markdown",
"id": "73699101",
"metadata": {},
"source": [
"No nuisance for batch execution"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "91f1e628",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:29.317846Z",
"iopub.status.busy": "2026-05-19T20:17:29.317733Z",
"iopub.status.idle": "2026-05-19T20:17:29.639617Z",
"shell.execute_reply": "2026-05-19T20:17:29.638888Z"
}
},
"outputs": [],
"source": [
"gROOT->SetBatch();"
]
},
{
"cell_type": "markdown",
"id": "e5942378",
"metadata": {},
"source": [
"Perform the operation sequentially ---------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "387ec8b6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:29.641719Z",
"iopub.status.busy": "2026-05-19T20:17:29.641576Z",
"iopub.status.idle": "2026-05-19T20:17:31.047494Z",
"shell.execute_reply": "2026-05-19T20:17:31.046871Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"****************************************\n",
"Minimizer is Minuit2 / Migrad\n",
"Chi2 = 137.398\n",
"NDf = 125\n",
"Edm = 5.54575e-10\n",
"NCalls = 56\n",
"Constant = 498685 +/- 136.728 \n",
"Mean = -1.6863e-05 +/- 0.00022373 \n",
"Sigma = 0.99998 +/- 0.000158815 \t (limited)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Info in : created default TCanvas with name c1\n"
]
}
],
"source": [
"TChain inputChain(\"multiCore\");\n",
"inputChain.Add(\"mt101_multiCore_*.root\");\n",
"TH1F outHisto(\"outHisto\", \"Random Numbers\", 128, -4, 4);\n",
"inputChain.Draw(\"r >> outHisto\");\n",
"outHisto.Fit(\"gaus\");"
]
},
{
"cell_type": "markdown",
"id": "cc66d3bc",
"metadata": {},
"source": [
"We now go MT! ------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "c7218207",
"metadata": {},
"source": [
"The first, fundamental operation to be performed in order to make ROOT\n",
"thread-aware."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "bc1627e4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:31.049069Z",
"iopub.status.busy": "2026-05-19T20:17:31.048950Z",
"iopub.status.idle": "2026-05-19T20:17:31.254359Z",
"shell.execute_reply": "2026-05-19T20:17:31.253488Z"
}
},
"outputs": [],
"source": [
"ROOT::EnableThreadSafety();"
]
},
{
"cell_type": "markdown",
"id": "5a834a1b",
"metadata": {},
"source": [
"We adapt our parallelisation to the number of input files"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "78144ef6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:31.255970Z",
"iopub.status.busy": "2026-05-19T20:17:31.255849Z",
"iopub.status.idle": "2026-05-19T20:17:31.461143Z",
"shell.execute_reply": "2026-05-19T20:17:31.460440Z"
}
},
"outputs": [],
"source": [
"const auto nFiles = inputChain.GetListOfFiles()->GetEntries();"
]
},
{
"cell_type": "markdown",
"id": "c637c191",
"metadata": {},
"source": [
"We define the histograms we'll fill"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "6b88d9a4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:31.463013Z",
"iopub.status.busy": "2026-05-19T20:17:31.462895Z",
"iopub.status.idle": "2026-05-19T20:17:31.665204Z",
"shell.execute_reply": "2026-05-19T20:17:31.664527Z"
}
},
"outputs": [],
"source": [
"std::vector histograms;\n",
"auto workerIDs = ROOT::TSeqI(nFiles);\n",
"histograms.reserve(nFiles);\n",
"for (auto workerID : workerIDs) {\n",
" histograms.emplace_back(TH1F(Form(\"outHisto_%u\", workerID), \"Random Numbers\", 128, -4, 4));\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "4d565ecb",
"metadata": {},
"source": [
"We define our work item"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "d219355c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:31.667310Z",
"iopub.status.busy": "2026-05-19T20:17:31.667190Z",
"iopub.status.idle": "2026-05-19T20:17:31.872800Z",
"shell.execute_reply": "2026-05-19T20:17:31.872172Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_158:2:20: error: 'histograms' cannot be captured because it does not have automatic storage duration\n",
" auto workItem = [&histograms](UInt_t workerID) {\n",
" ^\n",
"input_line_157:2:20: note: 'histograms' declared here\n",
" std::vector histograms;\n",
" ^\n"
]
}
],
"source": [
"auto workItem = [&histograms](UInt_t workerID) {\n",
" TFile f(Form(\"mt101_multiCore_%u.root\", workerID));\n",
" auto ntuple = f.Get(\"multiCore\");\n",
" auto &histo = histograms.at(workerID);\n",
" for (auto index : ROOT::TSeqL(ntuple->GetEntriesFast())) {\n",
" ntuple->GetEntry(index);\n",
" histo.Fill(ntuple->GetArgs()[0]);\n",
" }\n",
"};\n",
"\n",
"TH1F sumHistogram(\"SumHisto\", \"Random Numbers\", 128, -4, 4);"
]
},
{
"cell_type": "markdown",
"id": "c034f9d9",
"metadata": {},
"source": [
"Create the collection which will hold the threads, our \"pool\""
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "b109c0bd",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:31.874264Z",
"iopub.status.busy": "2026-05-19T20:17:31.874148Z",
"iopub.status.idle": "2026-05-19T20:17:32.080990Z",
"shell.execute_reply": "2026-05-19T20:17:32.080371Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:79:7: warning: inline function 'ROOT::TSeq::TSeq' is not defined [-Wundefined-inline]\n",
" TSeq(T theEnd): fBegin(), fEnd(theEnd), fStep(1) {\n",
" ^\n",
"input_line_158: note: used here\n",
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:172:16: warning: inline function 'ROOT::TSeq::begin' is not defined [-Wundefined-inline]\n",
" iterator begin() const {\n",
" ^\n",
"input_line_158: note: used here\n",
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:175:16: warning: inline function 'ROOT::TSeq::end' is not defined [-Wundefined-inline]\n",
" iterator end() const {\n",
" ^\n",
"input_line_158: note: used here\n",
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:109:15: warning: inline function 'ROOT::TSeq::iterator::operator!=' is not defined [-Wundefined-inline]\n",
" bool operator!=(const iterator &other) const {\n",
" ^\n",
"input_line_158: note: used here\n",
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:125:20: warning: inline function 'ROOT::TSeq::iterator::operator++' is not defined [-Wundefined-inline]\n",
" iterator &operator++() {\n",
" ^\n",
"input_line_158: note: used here\n",
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:101:12: warning: inline function 'ROOT::TSeq::iterator::operator*' is not defined [-Wundefined-inline]\n",
" T operator*() const {\n",
" ^\n",
"input_line_158: note: used here\n",
"In module 'Core':\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:69:12: warning: inline function 'ROOT::TSeq::checkIntegralType' is not defined [-Wundefined-inline]\n",
" void checkIntegralType() {\n",
" ^\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:80:10: note: used here\n",
" checkIntegralType();\n",
" ^\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:100:10: warning: inline function 'ROOT::TSeq::iterator::iterator' is not defined [-Wundefined-inline]\n",
" iterator(T start, T step): fCounter(start), fStep(step) {}\n",
" ^\n",
"/github/home/ROOT-CI/build/include/ROOT/TSeq.hxx:173:17: note: used here\n",
" return iterator(fBegin, fStep);\n",
" ^\n"
]
}
],
"source": [
"std::vector workers;"
]
},
{
"cell_type": "markdown",
"id": "e8ade4f5",
"metadata": {},
"source": [
"Spawn workers\n",
"Fill the \"pool\" with workers"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "983cce71",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:32.082501Z",
"iopub.status.busy": "2026-05-19T20:17:32.082378Z",
"iopub.status.idle": "2026-05-19T20:17:32.285238Z",
"shell.execute_reply": "2026-05-19T20:17:32.284615Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_161:2:63: error: use of undeclared identifier 'workItem'\n",
" (((*(std::vector*)0x7feeac5d1000)).emplace_back(workItem, ((*(int*)0x7feec2ffc260))))\n",
" ^\n",
"Error in : Error evaluating expression (((*(std::vector*)0x7feeac5d1000)).emplace_back(workItem, ((*(int*)0x7feec2ffc260))))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"for (auto workerID : workerIDs) {\n",
" workers.emplace_back(workItem, workerID);\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "1dd1cbe5",
"metadata": {},
"source": [
"Now join them"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "35e9a689",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:32.286877Z",
"iopub.status.busy": "2026-05-19T20:17:32.286756Z",
"iopub.status.idle": "2026-05-19T20:17:32.492045Z",
"shell.execute_reply": "2026-05-19T20:17:32.491264Z"
}
},
"outputs": [],
"source": [
"for (auto &&worker : workers)\n",
" worker.join();"
]
},
{
"cell_type": "markdown",
"id": "4ddc4d7d",
"metadata": {},
"source": [
"And reduce with a simple lambda"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "92125d02",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:32.494051Z",
"iopub.status.busy": "2026-05-19T20:17:32.493929Z",
"iopub.status.idle": "2026-05-19T20:17:32.699595Z",
"shell.execute_reply": "2026-05-19T20:17:32.698973Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_163:3:17: error: use of undeclared identifier 'sumHistogram'\n",
" [&sumHistogram](const TH1F &h) { sumHistogram.Add(&h); });\n",
" ^\n",
"input_line_163:3:48: error: use of undeclared identifier 'sumHistogram'\n",
" [&sumHistogram](const TH1F &h) { sumHistogram.Add(&h); });\n",
" ^\n",
"input_line_163:5:1: error: use of undeclared identifier 'sumHistogram'\n",
"sumHistogram.Fit(\"gaus\", 0);\n",
"^\n"
]
}
],
"source": [
"std::for_each(std::begin(histograms), std::end(histograms),\n",
" [&sumHistogram](const TH1F &h) { sumHistogram.Add(&h); });\n",
"\n",
"sumHistogram.Fit(\"gaus\", 0);\n",
"\n",
"return 0;"
]
},
{
"cell_type": "markdown",
"id": "f69e6600",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "0f55b79d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:17:32.701068Z",
"iopub.status.busy": "2026-05-19T20:17:32.700947Z",
"iopub.status.idle": "2026-05-19T20:17:33.006557Z",
"shell.execute_reply": "2026-05-19T20:17:33.005822Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"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
}