{ "cells": [ { "cell_type": "markdown", "id": "d95382f8", "metadata": {}, "source": [ "# ntpl002_vector\n", "Write and read STL vectors with RNTuple. Adapted from the hvector tree tutorial.\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:14 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "24ed0d42", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:14:46.495580Z", "iopub.status.busy": "2026-05-19T20:14:46.495460Z", "iopub.status.idle": "2026-05-19T20:14:46.503032Z", "shell.execute_reply": "2026-05-19T20:14:46.502624Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \n", "#include \n", "#include \n", "\n", "#include \n", "#include \n", "#include \n", "#include \n", "\n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "\n", "constexpr char const* kNTupleFileName = \"ntpl002_vector.root\";\n", "\n", "constexpr int kUpdateGuiFreq = 1000;\n", "\n", "constexpr int kNEvents = 25000;" ] }, { "cell_type": "markdown", "id": "82813114", "metadata": {}, "source": [ " Where to store the ntuple of this example\n", "Update the histogram GUI every so many fills\n", "Number of events to generate\n", "Generate kNEvents with vectors in kNTupleFileName\n", " " ] }, { "cell_type": "code", "execution_count": 2, "id": "11e075bd", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:14:46.504425Z", "iopub.status.busy": "2026-05-19T20:14:46.504308Z", "iopub.status.idle": "2026-05-19T20:14:46.746254Z", "shell.execute_reply": "2026-05-19T20:14:46.745740Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "void Write()\n", "{\n", " // We create a unique pointer to an empty data model\n", " auto model = ROOT::RNTupleModel::Create();\n", "\n", " // Creating fields of std::vector is the same as creating fields of simple types. As a result, we get\n", " // shared pointers of the given type\n", " std::shared_ptr> fldVpx = model->MakeField>(\"vpx\");\n", " auto fldVpy = model->MakeField>(\"vpy\");\n", " auto fldVpz = model->MakeField>(\"vpz\");\n", " auto fldVrand = model->MakeField>(\"vrand\");\n", "\n", " // We hand-over the data model to a newly created ntuple of name \"F\", stored in kNTupleFileName\n", " // In return, we get a unique pointer to an ntuple that we can fill\n", " auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), \"F\", kNTupleFileName);\n", "\n", " TH1F hpx(\"hpx\", \"This is the px distribution\", 100, -4, 4);\n", " hpx.SetFillColor(48);\n", "\n", " auto c1 = new TCanvas(\"c1\", \"Dynamic Filling Example\", 200, 10, 700, 500);\n", "\n", " gRandom->SetSeed();\n", " for (int i = 0; i < kNEvents; i++) {\n", " int npx = static_cast(gRandom->Rndm(1) * 15);\n", "\n", " fldVpx->clear();\n", " fldVpy->clear();\n", " fldVpz->clear();\n", " fldVrand->clear();\n", "\n", " // Set the field data for the current event\n", " for (int j = 0; j < npx; ++j) {\n", " float px, py, pz;\n", " gRandom->Rannor(px, py);\n", " pz = px*px + py*py;\n", " auto random = gRandom->Rndm(1);\n", "\n", " hpx.Fill(px);\n", "\n", " fldVpx->emplace_back(px);\n", " fldVpy->emplace_back(py);\n", " fldVpz->emplace_back(pz);\n", " fldVrand->emplace_back(random);\n", " }\n", "\n", " // Gui updates\n", " if (i && (i % kUpdateGuiFreq) == 0) {\n", " if (i == kUpdateGuiFreq) hpx.Draw();\n", " c1->Modified();\n", " c1->Update();\n", " if (gSystem->ProcessEvents())\n", " break;\n", " }\n", "\n", " writer->Fill();\n", " }\n", "\n", " hpx.DrawCopy();\n", "\n", " // The ntuple unique pointer goes out of scope here. On destruction, the ntuple flushes unwritten data to disk\n", " // and closes the attached ROOT file.\n", "}" ] }, { "cell_type": "markdown", "id": "6b0ceee6", "metadata": {}, "source": [ " For all of the events, histogram only one of the written vectors\n", " " ] }, { "cell_type": "code", "execution_count": 3, "id": "d09d8a2e", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:14:46.748055Z", "iopub.status.busy": "2026-05-19T20:14:46.747923Z", "iopub.status.idle": "2026-05-19T20:14:46.865786Z", "shell.execute_reply": "2026-05-19T20:14:46.865236Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "void Read()\n", "{\n", " // Get a unique pointer to an empty RNTuple model\n", " auto model = ROOT::RNTupleModel::Create();\n", "\n", " // We only define the fields that are needed for reading\n", " auto fldVpx = model->MakeField>(\"vpx\");\n", "\n", " // Create an ntuple without imposing a specific data model. We could generate the data model from the ntuple\n", " // but here we prefer the view because we only want to access a single field\n", " auto reader = ROOT::RNTupleReader::Open(std::move(model), \"F\", kNTupleFileName);\n", "\n", " // Quick overview of the ntuple's key meta-data\n", " reader->PrintInfo();\n", "\n", " std::cout << \"Entry number 42 in JSON format:\" << std::endl;\n", " reader->Show(41);\n", "\n", " TCanvas *c2 = new TCanvas(\"c2\", \"Dynamic Filling Example\", 200, 10, 700, 500);\n", " TH1F h(\"h\", \"This is the px distribution\", 100, -4, 4);\n", " h.SetFillColor(48);\n", "\n", " // Iterate through all the events using i as event number and as an index for accessing the view\n", " for (auto entryId : *reader) {\n", " reader->LoadEntry(entryId);\n", "\n", " for (auto px : *fldVpx) {\n", " h.Fill(px);\n", " }\n", "\n", " if (entryId && (entryId % kUpdateGuiFreq) == 0) {\n", " if (entryId == kUpdateGuiFreq) h.Draw();\n", " c2->Modified();\n", " c2->Update();\n", " if (gSystem->ProcessEvents())\n", " break;\n", " }\n", " }\n", "\n", " // Prevent the histogram from disappearing\n", " h.DrawCopy();\n", "}" ] }, { "cell_type": "code", "execution_count": 4, "id": "5541a914", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:14:46.867459Z", "iopub.status.busy": "2026-05-19T20:14:46.867331Z", "iopub.status.idle": "2026-05-19T20:14:47.818456Z", "shell.execute_reply": "2026-05-19T20:14:47.817986Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "RNTuple : F\n", "Entries : 25000\n", "\n", "Field 1 : vpx (std::vector)\n", " Field 1.1 : _0 (float)\n", "Field 2 : vpy (std::vector)\n", " Field 2.1 : _0 (float)\n", "Field 3 : vpz (std::vector)\n", " Field 3.1 : _0 (float)\n", "Field 4 : vrand (std::vector)\n", " Field 4.1 : _0 (float)\n", "Entry number 42 in JSON format:\n", "{\n", " \"vpx\": [0.322016, 0.921461, 1.7988, -0.147883, 0.771109, -0.145027, 1.20442, 1.5759, 0.389795],\n", " \"vpy\": [0.605749, -1.73995, 0.675207, 0.359542, -0.171996, -0.403973, 0.19456, 0.849203, -0.328285],\n", " \"vpz\": [0.470626, 3.87651, 3.69159, 0.15114, 0.624192, 0.184227, 1.48848, 3.20459, 0.259711],\n", " \"vrand\": [0.0677952, 0.691239, 0.106511, 0.719716, 0.963284, 0.14623, 0.739488, 0.575028, 0.716595]\n", "}\n" ] } ], "source": [ "Write();\n", "Read();" ] }, { "cell_type": "markdown", "id": "b4e3768e", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 5, "id": "5d3f6ad7", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:14:47.820096Z", "iopub.status.busy": "2026-05-19T20:14:47.819976Z", "iopub.status.idle": "2026-05-19T20:14:48.024692Z", "shell.execute_reply": "2026-05-19T20:14:48.024117Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "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 }