Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RBatchSink.cxx
Go to the documentation of this file.
1// Author: Silia Taider, CERN 08/2026
2
3/*************************************************************************
4 * Copyright (C) 1995-2026, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
12
13#include <algorithm>
14#include <stdexcept>
15#include <string>
16
18#include "ROOT/RNTupleModel.hxx"
20#include "TFile.h"
21#include "TTree.h"
22
24
26{
27 if (batch.GetCols() != fRowWidth)
28 throw std::runtime_error("RBatchSink::FillBatch: batch has " + std::to_string(batch.GetCols()) +
29 " columns, expected " + std::to_string(fRowWidth));
30
31 const float *data = batch.GetData();
32 for (std::size_t row = 0; row < batch.GetRows(); row++)
33 FillRow(data + row * fRowWidth);
34}
35
36RTTreeBatchSink::RTTreeBatchSink(std::string_view dataset_name, std::string_view filename,
37 std::vector<RColumnLayout> layout)
38 : RBatchSink(std::move(layout)), fFile(TFile::Open(std::string(filename).c_str(), "RECREATE"))
39{
40 fTree = new TTree(std::string(dataset_name).c_str(), std::string(dataset_name).c_str());
41 fTree->SetDirectory(fFile.get()); // fFile owns the TTree
42
43 fRow.resize(fRowWidth);
44 fVectorBuffers.resize(
45 std::count_if(fLayout.begin(), fLayout.end(), [](const RColumnLayout &col) { return col.fIsVector; }));
46
47 std::size_t vecIdx = 0;
48 for (const auto &col : fLayout) {
49 if (col.fIsVector) {
50 fVectorBuffers[vecIdx].resize(col.fWidth);
51 fTree->Branch(col.fName.c_str(), &fVectorBuffers[vecIdx]);
52 vecIdx++;
53 } else {
54 fTree->Branch(col.fName.c_str(), fRow.data() + col.fOffset, (col.fName + "/F").c_str());
55 }
56 }
57}
58
60
61void RTTreeBatchSink::FillRow(const float *row)
62{
63 std::copy_n(row, fRowWidth, fRow.begin());
64
65 std::size_t vecIdx = 0;
66 for (const auto &col : fLayout) {
67 if (col.fIsVector)
68 std::copy_n(row + col.fOffset, col.fWidth, fVectorBuffers[vecIdx++].begin());
69 }
70
71 fTree->Fill();
72}
73
75{
76 fFile->Write();
77}
78
79RNTupleBatchSink::RNTupleBatchSink(std::string_view dataset_name, std::string_view filename,
80 std::vector<RColumnLayout> layout)
81 : RBatchSink(std::move(layout))
82{
83 auto model = ROOT::RNTupleModel::Create();
84 fDestinations.reserve(fLayout.size());
85
86 for (const auto &col : fLayout) {
87 if (col.fIsVector) {
88 auto field = model->MakeField<std::vector<float>>(col.fName);
89 field->resize(col.fWidth);
90 fDestinations.push_back(field->data());
91 fVectorFields.push_back(std::move(field));
92 } else {
93 auto field = model->MakeField<float>(col.fName);
94 fDestinations.push_back(field.get());
95 fScalarFields.push_back(std::move(field));
96 }
97 }
98
99 fWriter = ROOT::RNTupleWriter::Recreate(std::move(model), std::string(dataset_name), std::string(filename));
100}
101
103
104void RNTupleBatchSink::FillRow(const float *row)
105{
106 for (std::size_t i = 0; i < fLayout.size(); i++)
107 std::copy_n(row + fLayout[i].fOffset, fLayout[i].fWidth, fDestinations[i]);
108 fWriter->Fill();
109}
110
112{
113 fWriter->CommitDataset();
114}
115
116std::unique_ptr<RBatchSink> CreateBatchSink(std::string_view dataset_name, std::string_view filename,
117 std::vector<RColumnLayout> layout, std::string_view format)
118{
119 if (format == "ttree")
120 return std::make_unique<RTTreeBatchSink>(dataset_name, filename, std::move(layout));
121 if (format == "rntuple")
122 return std::make_unique<RNTupleBatchSink>(dataset_name, filename, std::move(layout));
123
124 throw std::runtime_error("CreateBatchSink: unrecognised output format \"" + std::string(format) +
125 "\", expected \"ttree\" or \"rntuple\"");
126}
127
128} // namespace ROOT::Experimental::Internal::ML
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
Writes RFlat2DMatrix batches to disk letting RDataLoaderEngine::Save() stay agnostic to the output fo...
std::vector< RColumnLayout > fLayout
void FillBatch(const RFlat2DMatrix &batch)
Write every row of batch.
virtual void FillRow(const float *row)=0
Copy one row of fRowWidth floats into the writer's buffers and write the entry.
std::vector< std::shared_ptr< std::vector< float > > > fVectorFields
void FillRow(const float *row) override
Copy one row of fRowWidth floats into the writer's buffers and write the entry.
void Commit() override
Flush everything to disk once after the last batch.
std::unique_ptr< ROOT::RNTupleWriter > fWriter
RNTupleBatchSink(std::string_view dataset_name, std::string_view filename, std::vector< RColumnLayout > layout)
std::vector< std::shared_ptr< float > > fScalarFields
void Commit() override
Flush everything to disk once after the last batch.
RTTreeBatchSink(std::string_view dataset_name, std::string_view filename, std::vector< RColumnLayout > layout)
void FillRow(const float *row) override
Copy one row of fRowWidth floats into the writer's buffers and write the entry.
std::vector< std::vector< float > > fVectorBuffers
static std::unique_ptr< RNTupleModel > Create()
static std::unique_ptr< RNTupleWriter > Recreate(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, std::string_view storage, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter backed by storage, overwriting it if one with the same URI exists.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
A TTree represents a columnar dataset.
Definition TTree.h:89
virtual Int_t Fill()
Fill all branches.
Definition TTree.cxx:4674
virtual void SetDirectory(TDirectory *dir)
Change the tree's directory.
Definition TTree.cxx:9363
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
Definition TTree.h:405
std::unique_ptr< RBatchSink > CreateBatchSink(std::string_view dataset_name, std::string_view filename, std::vector< RColumnLayout > layout, std::string_view format)
Create the sink matching format.
Where one of the loader's columns lives inside a batch-tensor row and how it's shaped.
Wrapper around ROOT::RVec<float> representing a 2D matrix.