{
"cells": [
{
"cell_type": "markdown",
"id": "80301795",
"metadata": {},
"source": [
"# ntpl012_processor_chain\n",
"Demonstrate the RNTupleProcessor for vertical compositions (chains) of RNTuples\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** The ROOT Team \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:15 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "cba18dda",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:15:20.193226Z",
"iopub.status.busy": "2026-05-19T20:15:20.193117Z",
"iopub.status.idle": "2026-05-19T20:15:20.201287Z",
"shell.execute_reply": "2026-05-19T20:15:20.200582Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \n",
"#include \n",
"#include \n",
"\n",
"#include \n",
"#include \n",
"#include \n",
"\n",
"using ROOT::Experimental::RNTupleOpenSpec;\n",
"using ROOT::Experimental::RNTupleProcessor;\n",
"\n",
"constexpr int kNEvents = 10000;"
]
},
{
"cell_type": "markdown",
"id": "7b3515a2",
"metadata": {},
"source": [
" NOTE: The RNTupleProcessor and related classes are experimental at this point.\n",
"Functionality and interface are still subject to changes.\n",
"Import classes from the `Experimental` namespace for the time being.\n",
"Number of events to generate for each ntuple.\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7cdf5264",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:15:20.202523Z",
"iopub.status.busy": "2026-05-19T20:15:20.202404Z",
"iopub.status.idle": "2026-05-19T20:15:20.466717Z",
"shell.execute_reply": "2026-05-19T20:15:20.466053Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void Write(std::string_view ntupleName, std::string_view fileName)\n",
"{\n",
" auto model = ROOT::RNTupleModel::Create();\n",
"\n",
" auto fldVpx = model->MakeField>(\"vpx\");\n",
" auto fldVpy = model->MakeField>(\"vpy\");\n",
" auto fldVpz = model->MakeField>(\"vpz\");\n",
" auto fldN = model->MakeField(\"vn\");\n",
"\n",
" auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), ntupleName, fileName);\n",
"\n",
" for (int i = 0; i < kNEvents; ++i) {\n",
" fldVpx->clear();\n",
" fldVpy->clear();\n",
" fldVpz->clear();\n",
"\n",
" *fldN = gRandom->Integer(15);\n",
" for (int j = 0; j < *fldN; ++j) {\n",
" float px, py, pz;\n",
" gRandom->Rannor(px, py);\n",
" pz = px * px + py * py;\n",
"\n",
" fldVpx->emplace_back(px);\n",
" fldVpy->emplace_back(py);\n",
" fldVpz->emplace_back(pz);\n",
" }\n",
"\n",
" writer->Fill();\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "547287c0",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "eb0d7daa",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:15:20.468214Z",
"iopub.status.busy": "2026-05-19T20:15:20.468089Z",
"iopub.status.idle": "2026-05-19T20:15:20.563277Z",
"shell.execute_reply": "2026-05-19T20:15:20.562647Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void Read(const std::vector &ntuples)\n",
"{\n",
" auto c = new TCanvas(\"c\", \"RNTupleProcessor Example\", 200, 10, 700, 500);\n",
" TH1F hPx(\"h\", \"This is the px distribution\", 100, -4, 4);\n",
" hPx.SetFillColor(48);\n",
"\n",
" // The chain-based processor can be created by passing a list of RNTupleOpenSpecs, describing the name and location\n",
" // of each ntuple in the chain.\n",
" auto processor = RNTupleProcessor::CreateChain(ntuples);\n",
" int prevProcessorNumber{-1};\n",
"\n",
" // Access to the processor's fields is done by first requesting them through RNTupleProcessor::RequestField(). The\n",
" // returned value can be used to read the current entry's value for that particular field.\n",
" auto px = processor->RequestField>(\"vpx\");\n",
"\n",
" // The iterator value is the index of the current entry being processed.\n",
" for (auto idx : *processor) {\n",
" // The RNTupleProcessor provides some additional bookkeeping information, such as the current processor number.\n",
" if (static_cast(processor->GetCurrentProcessorNumber()) > prevProcessorNumber) {\n",
" prevProcessorNumber = processor->GetCurrentProcessorNumber();\n",
" std::cout << \"Processing `ntuple\" << prevProcessorNumber + 1 << \"` (\" << idx + 1\n",
" << \" total entries processed so far)\" << std::endl;\n",
" }\n",
"\n",
" // We use the value returned from requesting the field to read its data for the current entry.\n",
" for (auto x : *px) {\n",
" hPx.Fill(x);\n",
" }\n",
" }\n",
"\n",
" std::cout << \"Processed a total of \" << processor->GetNEntriesProcessed() << \" entries\" << std::endl;\n",
"\n",
" hPx.DrawCopy();\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3c4d65e6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:15:20.564771Z",
"iopub.status.busy": "2026-05-19T20:15:20.564638Z",
"iopub.status.idle": "2026-05-19T20:15:21.293769Z",
"shell.execute_reply": "2026-05-19T20:15:21.293078Z"
}
},
"outputs": [],
"source": [
"Write(\"ntuple1\", \"ntuple1.root\");\n",
"Write(\"ntuple2\", \"ntuple2.root\");\n",
"Write(\"ntuple3\", \"ntuple3.root\");"
]
},
{
"cell_type": "markdown",
"id": "d5d015b9",
"metadata": {},
"source": [
"The ntuples to generate and subsequently process. The model of the first ntuple will be used to construct the\n",
"entry used by the processor."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1721f740",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:15:21.303403Z",
"iopub.status.busy": "2026-05-19T20:15:21.303268Z",
"iopub.status.idle": "2026-05-19T20:15:28.104929Z",
"shell.execute_reply": "2026-05-19T20:15:28.104353Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Processing `ntuple1` (1 total entries processed so far)\n",
"Processing `ntuple2` (10001 total entries processed so far)\n",
"Processing `ntuple3` (20001 total entries processed so far)\n",
"Processed a total of 30000 entries\n"
]
}
],
"source": [
"std::vector ntuples = {\n",
" {\"ntuple1\", \"ntuple1.root\"}, {\"ntuple2\", \"ntuple2.root\"}, {\"ntuple3\", \"ntuple3.root\"}};\n",
"\n",
"Read(ntuples);"
]
},
{
"cell_type": "markdown",
"id": "b4042561",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a35e8fc7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:15:28.106654Z",
"iopub.status.busy": "2026-05-19T20:15:28.106515Z",
"iopub.status.idle": "2026-05-19T20:15:28.311380Z",
"shell.execute_reply": "2026-05-19T20:15:28.310715Z"
}
},
"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
}