Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleWriter.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleWriter.hxx
2/// \ingroup NTuple
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2024-02-20
5
6/*************************************************************************
7 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#ifndef ROOT_RNTupleWriter
15#define ROOT_RNTupleWriter
16
17#include <ROOT/RConfig.hxx> // for R__unlikely
18#include <ROOT/REntry.hxx>
19#include <ROOT/RError.hxx>
23#include <ROOT/RNTupleModel.hxx>
24#include <ROOT/RNTupleTypes.hxx>
25#include <ROOT/RPageStorage.hxx>
27
28#include <cstddef>
29#include <cstdint>
30#include <memory>
31#include <string_view>
32#include <utility>
33
34class TDirectory;
35
36namespace ROOT {
37
38class RNTupleWriteOptions;
39
40namespace Internal {
41// Non-public factory method for an RNTuple writer that uses an already constructed page sink
42std::unique_ptr<RNTupleWriter>
43CreateRNTupleWriter(std::unique_ptr<ROOT::RNTupleModel> model, std::unique_ptr<Internal::RPageSink> sink);
44} // namespace Internal
45
46// clang-format off
47/**
48\class ROOT::RNTupleWriter
49\ingroup NTuple
50\brief An RNTuple that gets filled with entries (data) and writes them to storage
51
52RNTupleWriter is an interface for writing RNTuples to storage. It can be instantiated using the static functions
53Append() and Recreate(), providing an RNTupleModel that defines the schema of the data to be written.
54
55An RNTuple can be thought of as a table, whose columns are defined by its schema (i.e. by its associated RNTupleModel,
56whose Fields map to 0 or more columns).
57Writing into an RNTuple happens by filling *entries* into the RNTupleWriter, which make up the rows of the table.
58The simplest way to do so is by:
59
60- retrieving a (shared) pointer to each Field's value;
61- writing a value into each pointer;
62- calling `writer->Fill()` to commit the entry with all the current pointer values.
63
64~~~ {.cpp}
65#include <ROOT/RNTupleWriter.hxx>
66
67/// 1. Create the model.
68auto model = ROOT::RNTupleModel::Create();
69// Define the schema by adding Fields to the model.
70// MakeField returns a shared_ptr to the value to be written (in this case, a shared_ptr<int>)
71auto pFoo = model->MakeField<int>("foo");
72
73/// 2. Create writer from the model.
74auto writer = ROOT::RNTupleReader::Recreate(std::move(model), "myNTuple", "some/file.root");
75
76/// 3. Write into it.
77for (int i = 0; i < 10; ++i) {
78 // Assign the value you want to each RNTuple Field (in this case there is only one Field "foo").
79 *pFoo = i;
80
81 // Fill() writes the entire entry to the RNTuple.
82 // After calling Fill() you can safely write another value into `pFoo` knowing that the previous one was
83 // already saved.
84 writer->Fill();
85}
86
87// On destruction, the writer will flush the written data to disk.
88~~~
89
90The caller has to make sure that the data that gets filled into an RNTuple is not modified for the time of the
91Fill() call. The Fill call serializes the C++ object into the column format and
92writes data into the corresponding column page buffers.
93
94The actual writing of the buffers to storage is deferred and can be triggered by FlushCluster() or by
95destructing the writer.
96
97On I/O errors, a ROOT::RException is thrown.
98
99*/
100// clang-format on
103 friend std::unique_ptr<RNTupleWriter>
104 Internal::CreateRNTupleWriter(std::unique_ptr<ROOT::RNTupleModel>, std::unique_ptr<Internal::RPageSink>);
105
106private:
109
111
112 RNTupleWriter(std::unique_ptr<ROOT::RNTupleModel> model, std::unique_ptr<Internal::RPageSink> sink);
113
116
117 // Helper function that is called from CommitCluster() when necessary
118 void CommitClusterGroup();
119
120 /// Create a writer, potentially wrapping the sink in a RPageSinkBuf.
121 static std::unique_ptr<RNTupleWriter> Create(std::unique_ptr<ROOT::RNTupleModel> model,
122 std::unique_ptr<Internal::RPageSink> sink,
123 const ROOT::RNTupleWriteOptions &options);
124
125public:
126 /// Creates an RNTupleWriter backed by `storage`, overwriting it if one with the same URI exists.
127 /// The format of the backing storage is determined by `storage`: in the simplest case it will be a local file, but
128 /// a different backend may be selected via the URI prefix.
129 ///
130 /// The RNTupleWriter will create an RNTuple with the schema determined by `model` (which must not be null) and
131 /// with name `ntupleName`. This same name can later be used to read back the RNTuple via RNTupleReader.
132 ///
133 /// \param model The RNTupleModel describing the schema of the RNTuple written by this writer
134 /// \param ntupleName The name of the RNTuple to be written
135 /// \param storage The URI where the RNTuple will be stored (usually just a file name or path)
136 /// \param options May be passed to customize the behavior of the RNTupleWriter (see also RNTupleWriteOptions).
137 ///
138 /// Throws a ROOT::RException if the model is null.
139 static std::unique_ptr<RNTupleWriter>
140 Recreate(std::unique_ptr<ROOT::RNTupleModel> model, std::string_view ntupleName, std::string_view storage,
142
143 /// Convenience function allowing to call Recreate() with an inline-defined model.
144 static std::unique_ptr<RNTupleWriter>
145 Recreate(std::initializer_list<std::pair<std::string_view, std::string_view>> fields, std::string_view ntupleName,
146 std::string_view storage, const ROOT::RNTupleWriteOptions &options = ROOT::RNTupleWriteOptions());
147
148 /// Creates an RNTupleWriter that writes into an existing TFile or TDirectory, without overwriting its content.
149 /// `fileOrDirectory` may be an empty TFile.
150 /// \see Recreate()
151 static std::unique_ptr<RNTupleWriter> Append(std::unique_ptr<ROOT::RNTupleModel> model, std::string_view ntupleName,
154 RNTupleWriter(const RNTupleWriter &) = delete;
157
158 /// The simplest user interface if the default entry that comes with the ntuple model is used.
159 /// \return The number of uncompressed bytes written.
160 std::size_t Fill() { return fFillContext.Fill(fFillContext.fModel->GetDefaultEntry()); }
161 /// Multiple entries can have been instantiated from the ntuple model. This method will check the entry's model ID
162 /// to ensure it comes from the writer's own model or throw an exception otherwise.
163 /// \return The number of uncompressed bytes written.
164 std::size_t Fill(ROOT::REntry &entry) { return fFillContext.Fill(entry); }
165 /// Fill an entry into this ntuple, but don't commit the cluster. The calling code must pass an RNTupleFillStatus
166 /// and check RNTupleFillStatus::ShouldFlushCluster.
168
169 /// Fill an RRawPtrWriteEntry into this ntuple. This method will check the entry's model ID to ensure it comes from
170 /// the writer's own model or throw an exception otherwise.
171 /// \return The number of uncompressed bytes written.
173 /// Fill an RRawPtrWriteEntry into this ntuple, but don't commit the cluster. The calling code must pass an
174 /// RNTupleFillStatus and check RNTupleFillStatus::ShouldFlushCluster.
179
180 /// Flush column data, preparing for CommitCluster or to reduce memory usage. This will trigger compression of pages,
181 /// but not actually write to storage (unless buffered writing is turned off).
183 /// Flush so far filled entries to storage
185 /// Ensure that the data from the so far seen Fill calls has been written to storage
192 /// Closes the underlying file (page sink) and expires the model. Automatically called on destruct.
193 /// Once the dataset is committed, calls to Fill(), [Commit|Flush]Cluster(), FlushColumns(), CreateEntry(),
194 /// and model updating fail.
195 void CommitDataset();
196
197 std::unique_ptr<ROOT::REntry> CreateEntry() const { return fFillContext.CreateEntry(); }
198 std::unique_ptr<Experimental::Detail::RRawPtrWriteEntry> CreateRawPtrWriteEntry() const
199 {
201 }
202
203 /// Return the entry number that was last flushed in a cluster.
205 /// Return the entry number that was last committed in a cluster.
207 /// Return the entry number that was last committed in a cluster group.
209 /// Return the number of entries filled so far.
211
214
215 const ROOT::RNTupleModel &GetModel() const { return *fFillContext.fModel; }
216
217 /// Get a RNTupleModel::RUpdater that provides limited support for incremental updates to the underlying
218 /// model, e.g. addition of new fields.
219 ///
220 /// Note that a Model may not be extended with Streamer fields.
221 ///
222 /// **Example: add a new field after the model has been used to construct a `RNTupleWriter` object**
223 /// ~~~ {.cpp}
224 /// #include <ROOT/RNTuple.hxx>
225 ///
226 /// auto model = ROOT::RNTupleModel::Create();
227 /// auto fldFloat = model->MakeField<float>("fldFloat");
228 /// auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), "myNTuple", "some/file.root");
229 /// auto updater = writer->CreateModelUpdater();
230 /// updater->BeginUpdate();
231 /// updater->AddField(std::make_unique<RField<float>>("pt"));
232 /// updater->CommitUpdate();
233 ///
234 /// // ...
235 /// ~~~
236 std::unique_ptr<ROOT::RNTupleModel::RUpdater> CreateModelUpdater()
237 {
238 return std::make_unique<ROOT::RNTupleModel::RUpdater>(*this);
239 }
240}; // class RNTupleWriter
241
242} // namespace ROOT
243
244#endif // ROOT_RNTupleWriter
A collection of Counter objects with a name, a unit, and a description.
A container of const raw pointers, corresponding to a row in the data set.
A context for filling entries (data) into clusters of an RNTuple.
ROOT::NTupleSize_t GetNEntries() const
Return the number of entries filled so far.
std::unique_ptr< ROOT::Internal::RPageSink > fSink
void FillNoFlush(ROOT::REntry &entry, ROOT::RNTupleFillStatus &status)
Fill an entry into this context, but don't commit the cluster.
std::unique_ptr< ROOT::RNTupleModel > fModel
Needs to be destructed before fSink.
void FlushCluster()
Flush so far filled entries to storage.
std::size_t Fill(ROOT::REntry &entry)
Fill an entry into this context.
ROOT::NTupleSize_t GetLastFlushed() const
Return the entry number that was last flushed in a cluster.
void FlushColumns()
Flush column data, preparing for CommitCluster or to reduce memory usage.
std::unique_ptr< ROOT::REntry > CreateEntry() const
std::unique_ptr< Detail::RRawPtrWriteEntry > CreateRawPtrWriteEntry() const
Abstract interface to write data into an ntuple.
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:54
A status object after filling an entry.
A model is usually immutable after passing it to an RNTupleWriter.
The RNTupleModel encapulates the schema of an RNTuple.
Common user-tunable settings for storing RNTuples.
An RNTuple that gets filled with entries (data) and writes them to storage.
std::unique_ptr< ROOT::REntry > CreateEntry() const
static std::unique_ptr< RNTupleWriter > Create(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink, const ROOT::RNTupleWriteOptions &options)
Create a writer, potentially wrapping the sink in a RPageSinkBuf.
std::size_t Fill(Experimental::Detail::RRawPtrWriteEntry &entry)
Fill an RRawPtrWriteEntry into this ntuple.
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.
RNTupleWriter(const RNTupleWriter &)=delete
Experimental::Detail::RNTupleMetrics fMetrics
const Experimental::Detail::RNTupleMetrics & GetMetrics() const
ROOT::RNTupleModel & GetUpdatableModel()
Internal::RPageSink & GetSink()
void FillNoFlush(Experimental::Detail::RRawPtrWriteEntry &entry, RNTupleFillStatus &status)
Fill an RRawPtrWriteEntry into this ntuple, but don't commit the cluster.
static std::unique_ptr< RNTupleWriter > Append(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, TDirectory &fileOrDirectory, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter that writes into an existing TFile or TDirectory, without overwriting its co...
std::size_t Fill(ROOT::REntry &entry)
Multiple entries can have been instantiated from the ntuple model.
void FillNoFlush(ROOT::REntry &entry, RNTupleFillStatus &status)
Fill an entry into this ntuple, but don't commit the cluster.
RNTupleWriter(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink)
ROOT::NTupleSize_t GetLastCommitted() const
Return the entry number that was last committed in a cluster.
ROOT::NTupleSize_t GetLastCommittedClusterGroup() const
Return the entry number that was last committed in a cluster group.
void CommitDataset()
Closes the underlying file (page sink) and expires the model.
const ROOT::RNTupleModel & GetModel() const
ROOT::NTupleSize_t fLastCommittedClusterGroup
void FlushColumns()
Flush column data, preparing for CommitCluster or to reduce memory usage.
RNTupleWriter & operator=(const RNTupleWriter &)=delete
ROOT::NTupleSize_t GetLastFlushed() const
Return the entry number that was last flushed in a cluster.
std::unique_ptr< Experimental::Detail::RRawPtrWriteEntry > CreateRawPtrWriteEntry() const
std::unique_ptr< ROOT::RNTupleModel::RUpdater > CreateModelUpdater()
Get a RNTupleModel::RUpdater that provides limited support for incremental updates to the underlying ...
void FlushCluster()
Flush so far filled entries to storage.
ROOT::NTupleSize_t GetNEntries() const
Return the number of entries filled so far.
void CommitCluster(bool commitClusterGroup=false)
Ensure that the data from the so far seen Fill calls has been written to storage.
Experimental::RNTupleFillContext fFillContext
std::size_t Fill()
The simplest user interface if the default entry that comes with the ntuple model is used.
Describe directory structure in memory.
Definition TDirectory.h:45
std::unique_ptr< RNTupleWriter > CreateRNTupleWriter(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink)
Namespace for new ROOT classes and functions.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.