{ "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 }