Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleModel.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleModel.hxx
2/// \ingroup NTuple
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-04
5
6/*************************************************************************
7 * Copyright (C) 1995-2019, 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_RNTupleModel
15#define ROOT_RNTupleModel
16
17#include <ROOT/REntry.hxx>
18#include <ROOT/RError.hxx>
19#include <ROOT/RField.hxx>
20#include <ROOT/RFieldToken.hxx>
21#include <ROOT/RNTupleTypes.hxx>
22#include <string_view>
23
24#include <cstdint>
25#include <functional>
26#include <memory>
27#include <string>
28#include <unordered_map>
29#include <unordered_set>
30#include <utility>
31
32namespace ROOT {
33
34class RNTupleWriteOptions;
35class RNTupleModel;
36class RNTupleWriter;
37
38namespace Detail {
39class RRawPtrWriteEntry;
40} // namespace Detail
41
42namespace Internal {
43class RProjectedFields;
44
45ROOT::RFieldZero &GetFieldZeroOfModel(RNTupleModel &model);
46RProjectedFields &GetProjectedFieldsOfModel(RNTupleModel &model);
47const RProjectedFields &GetProjectedFieldsOfModel(const RNTupleModel &model);
48
49// clang-format off
50/**
51\class ROOT::Internal::RProjectedFields
52\ingroup NTuple
53\brief Container for the projected fields of an RNTupleModel
54
55Projected fields are fields whose columns are reused from existing fields. Projected fields are not attached
56to the model's zero field but form a separate hierarchy with their own zero field (which is stored in this class).
57Only the real source fields are written to: projected fields are stored as metadata
58(header) information only. Only top-level projected fields are supported because otherwise the layout of types
59could be altered in unexpected ways.
60This class owns the hierarchy of projected fields and keeps the mapping between them and their backing source fields.
61*/
62// clang-format on
64public:
65 /// The map keys are the projected target fields, the map values are the backing source fields
66 /// Note that sub fields are treated individually and indepently of their parent field
67 using FieldMap_t = std::unordered_map<const ROOT::RFieldBase *, const ROOT::RFieldBase *>;
68
69private:
70 explicit RProjectedFields(std::unique_ptr<ROOT::RFieldZero> fieldZero) : fFieldZero(std::move(fieldZero)) {}
71 /// The projected fields are attached to this zero field
72 std::unique_ptr<ROOT::RFieldZero> fFieldZero;
73 /// Maps the source fields from fModel to the target projected fields attached to fFieldZero
75 /// The model this set of projected fields belongs to
77
78 /// Asserts that the passed field is a valid target of the source field provided in the field map.
79 /// Checks the field without looking into sub fields.
81
82public:
83 explicit RProjectedFields(const RNTupleModel &model)
84 : fFieldZero(std::make_unique<ROOT::RFieldZero>()), fModel(&model)
85 {
86 }
91 ~RProjectedFields() = default;
92
93 /// Clones this container and all the projected fields it owns. `newModel` must be a clone of the model
94 /// that this RProjectedFields was constructed with.
95 std::unique_ptr<RProjectedFields> Clone(const RNTupleModel &newModel) const;
96
99 /// Adds a new projected field. The field map needs to provide valid source fields of fModel for 'field'
100 /// and each of its sub fields.
101 RResult<void> Add(std::unique_ptr<ROOT::RFieldBase> field, const FieldMap_t &fieldMap);
102 bool IsEmpty() const { return fFieldZero->begin() == fFieldZero->end(); }
103};
104
105} // namespace Internal
106
107// clang-format off
108/**
109\class ROOT::RNTupleModel
110\ingroup NTuple
111\brief The RNTupleModel encapulates the schema of an RNTuple.
112
113The RNTupleModel comprises a collection of hierarchically organized fields. From a model, "entries"
114can be extracted or created. For convenience, the RNTupleModel provides a default entry unless it is created as a "bare model".
115Models have a unique model identifier that facilitates checking whether entries are compatible with it
116(i.e.: have been extracted from that model).
117
118A model is subject to state transitions during its lifetime: it starts in a *building* state, in which fields can be
119added and modified. Once the schema is finalized, the model gets *frozen*. Only frozen models can create entries.
120From frozen, models move into an *expired* state. In this state, the model is only partially usable: it can be cloned
121and queried, but it can't be unfrozen anymore and no new entries can be created. This state is used for models
122that were used for writing and are no longer connected to a page sink.
123
124```
125(Model gets created)
126 |
127 | (passed to a Sink (detached from
128 ____v______ or explicitly __________ Sink after ___________
129| | frozen) | | writing) | |
130| Building |---------------->| Frozen |-------------->| Expired |
131|___________|<----------------|__________| |___________|
132 (explicitly
133 unfrozen)
134```
135
136*/
137// clang-format on
142
143public:
144 /// User-provided function that describes the mapping of existing source fields to projected fields in terms
145 /// of fully qualified field names. The mapping function is called with the qualified field names of the provided
146 /// field and the subfields. It should return the qualified field names used as a mapping source.
147 /// See AddProjectedFields() for more details.
148 using FieldMappingFunc_t = std::function<std::string(const std::string &)>;
149
150 class RUpdater;
151
152private:
153 /// The states a model can be in. Possible transitions are between kBuilding and kFrozen
154 /// and from kFrozen to kExpired.
155 /// See RNTupleModel for the state transition graph.
156 enum class EState {
157 kBuilding,
158 kFrozen,
160 };
161
162 /// Hierarchy of fields consisting of simple types and collections (sub trees)
163 std::unique_ptr<ROOT::RFieldZero> fFieldZero;
164 /// Contains field values corresponding to the created top-level fields, as well as registered subfields
165 std::unique_ptr<ROOT::REntry> fDefaultEntry;
166 /// Keeps track of which field names are taken, including projected field names.
167 std::unordered_set<std::string> fFieldNames;
168 /// Free text set by the user
169 std::string fDescription;
170 /// The set of projected top-level fields
171 std::unique_ptr<Internal::RProjectedFields> fProjectedFields;
172 /// Keeps track of which subfields have been registered to be included in entries belonging to this model.
173 std::unordered_set<std::string> fRegisteredSubfields;
174 /// Every model has a unique ID to distinguish it from other models. Entries are linked to models via the ID.
175 /// Cloned models get a new model ID. Expired models are cloned into frozen models.
176 std::uint64_t fModelId = 0;
177 /// Models have a separate schema ID to remember that the clone of a frozen model still has the same schema.
178 std::uint64_t fSchemaId = 0;
179 /// Changed by Freeze() / Unfreeze() and by the RUpdater.
181
182 /// Checks that user-provided field names are valid in the context of this RNTupleModel.
183 /// Throws an RException for invalid names, empty names (which is reserved for the zero field) and duplicate field
184 /// names.
185 void EnsureValidFieldName(std::string_view fieldName);
186
187 /// Throws an RException if fFrozen is true
188 void EnsureNotFrozen() const;
189
190 /// Throws an RException if fDefaultEntry is nullptr
191 void EnsureNotBare() const;
192
193 /// The field name can be a top-level field or a nested field. Returns nullptr if the field is not in the model.
194 ROOT::RFieldBase *FindField(std::string_view fieldName) const;
195
196 /// Add a subfield to the provided entry. If `initializeValue` is false, a nullptr will be bound to the entry value
197 /// (used in bare models).
198 void AddSubfield(std::string_view fieldName, ROOT::REntry &entry, bool initializeValue = true) const;
199
200 RNTupleModel(std::unique_ptr<ROOT::RFieldZero> fieldZero);
201
202public:
203 RNTupleModel(const RNTupleModel &) = delete;
207 ~RNTupleModel() = default;
208
209 std::unique_ptr<RNTupleModel> Clone() const;
210 static std::unique_ptr<RNTupleModel> Create();
211 static std::unique_ptr<RNTupleModel> Create(std::unique_ptr<ROOT::RFieldZero> fieldZero);
212 /// Creates a "bare model", i.e. an RNTupleModel with no default entry
213 static std::unique_ptr<RNTupleModel> CreateBare();
214 /// Creates a "bare model", i.e. an RNTupleModel with no default entry, with the given field zero.
215 static std::unique_ptr<RNTupleModel> CreateBare(std::unique_ptr<ROOT::RFieldZero> fieldZero);
216
217 /// Creates a new field given a `name` or `{name, description}` pair and a
218 /// corresponding, default-constructed value that is managed by a shared pointer.
219 ///
220 /// **Example: create some fields and fill an %RNTuple**
221 /// ~~~ {.cpp}
222 /// #include <ROOT/RNTupleModel.hxx>
223 /// #include <ROOT/RNTupleWriter.hxx>
224 /// using ROOT::RNTupleWriter;
225 ///
226 /// #include <vector>
227 ///
228 /// auto model = ROOT::RNTupleModel::Create();
229 /// auto pt = model->MakeField<float>("pt");
230 /// auto vec = model->MakeField<std::vector<int>>("vec");
231 ///
232 /// // The RNTuple is written to disk when the RNTupleWriter goes out of scope
233 /// {
234 /// auto writer = RNTupleWriter::Recreate(std::move(model), "myNTuple", "myFile.root");
235 /// for (int i = 0; i < 100; i++) {
236 /// *pt = static_cast<float>(i);
237 /// *vec = {i, i+1, i+2};
238 /// writer->Fill();
239 /// }
240 /// }
241 /// ~~~
242 ///
243 /// **Example: create a field with a description**
244 /// ~~~ {.cpp}
245 /// #include <ROOT/RNTupleModel.hxx>
246 ///
247 /// auto model = ROOT::RNTupleModel::Create();
248 /// auto hadronFlavour = model->MakeField<float>(
249 /// "hadronFlavour", "flavour from hadron ghost clustering"
250 /// );
251 /// ~~~
252 template <typename T>
253 std::shared_ptr<T> MakeField(std::string_view name, std::string_view description = "")
254 {
257 auto field = std::make_unique<ROOT::RField<T>>(name);
258 field->SetDescription(description);
259 std::shared_ptr<T> ptr;
260 if (fDefaultEntry)
261 ptr = fDefaultEntry->AddValue<T>(*field);
262 fFieldNames.insert(field->GetFieldName());
263 fFieldZero->Attach(std::move(field));
264 return ptr;
265 }
266
267 /// Adds a field whose type is not known at compile time. No shared pointer is returned in this case:
268 /// pointers should be retrieved or bound via REntry.
269 ///
270 /// Throws an RException if the field is null.
271 void AddField(std::unique_ptr<ROOT::RFieldBase> field);
272
273 /// Register a subfield so it can be accessed directly from entries belonging to the model. Because registering a
274 /// subfield does not fundamentally change the model, previously created entries will not be invalidated, nor
275 /// modified in any way; a registered subfield is merely an accessor added to the default entry (if present) and any
276 /// entries created afterwards. Note that previously created entries won't have this subfield added to them.
277 ///
278 /// Using models with registered subfields for writing is not allowed. Attempting to do so will result in an
279 /// exception.
280 ///
281 /// Throws an RException if the provided subfield could not be found in the model.
282 void RegisterSubfield(std::string_view qualifiedFieldName);
283
284 /// Adds a top-level field based on existing fields.
285 ///
286 /// The mapping function takes one argument, which is a string containing the name of the projected field. The return
287 /// value of the mapping function should be the name of the (existing) field onto which the projection is made.
288 /// **Example**
289 /// ~~~ {.cpp}
290 /// auto model = RNTupleModel::Create();
291 /// model->MakeField<float>("met");
292 /// auto metProjection = ROOT::RFieldBase::Create("missingE", "float").Unwrap();
293 /// model->AddProjectedField(std::move(metProjection), [](const std::string &) { return "met"; });
294 /// ~~~
295 ///
296 /// Adding projections for collection fields is also possible, as long as they follow the same schema structure. For
297 /// example, a projection of a collection of structs onto a collection of scalars is possible, but a projection of a
298 /// collection of a collection of scalars onto a collection of scalars is not.
299 ///
300 /// In the case of projections for nested fields, the mapping function must provide a mapping for every nesting
301 /// level.
302 /// **Example**
303 /// ~~~ {.cpp}
304 /// struct P { int x, y; };
305 ///
306 /// auto model = RNTupleModel::Create();
307 /// model->MakeField<std::vector<P>>("points");
308 /// auto pxProjection = ROOT::RFieldBase::Create("pxs", "std::vector<int>").Unwrap();
309 /// model->AddProjectedField(std::move(pxProjection), [](const std::string &fieldName) {
310 /// if (fieldName == "pxs")
311 /// return "points";
312 /// else
313 /// return "points._0.x";
314 /// });
315 /// ~~~
316 ///
317 /// Creating projections for fields containing `std::variant` or fixed-size arrays is unsupported.
318 RResult<void> AddProjectedField(std::unique_ptr<ROOT::RFieldBase> field, FieldMappingFunc_t mapping);
319
320 /// Transitions an RNTupleModel from the *building* state to the *frozen* state, disabling adding additional fields
321 /// and enabling creating entries from it. Freezing an already-frozen model is a no-op. Throws an RException if the
322 /// model is in the *expired* state. See RNTupleModel for more detailed explanation on the state transitions.
323 void Freeze();
324 /// Transitions an RNTupleModel from the *frozen* state back to the *building* state, invalidating all previously
325 /// created entries, re-enabling adding additional fields and disabling creating entries from it. Unfreezing a model
326 /// that is already in the *building* state is a no-op. Throws an RException if the model is in the *expired* state.
327 /// See RNTupleModel for a more detailed explanation on the state transitions.
328 void Unfreeze();
329 /// Transitions an RNTupleModel from the *frozen* state to the *expired* state, invalidating all previously created
330 /// entries, disabling creating new entries from it and disabling further state transitions. Expiring a model that is
331 /// already expired is a no-op. Throws an RException if the model is in the *building* state. See RNTupleModel for a
332 /// more detailed explanation on the state transitions.
333 void Expire();
334 /// \see Expire()
335 bool IsExpired() const { return fModelState == EState::kExpired; }
336 /// \see Freeze()
338 /// \see CreateBare()
339 bool IsBare() const { return !fDefaultEntry; }
340 std::uint64_t GetModelId() const { return fModelId; }
341 std::uint64_t GetSchemaId() const { return fSchemaId; }
342
343 /// Creates a new entry with default values for each field.
344 std::unique_ptr<REntry> CreateEntry() const;
345 /// Creates a "bare entry", i.e. a entry with all null values. The user needs to explicitly call BindValue() or
346 /// BindRawPtr() to set memory addresses before serializing / deserializing the entry.
347 std::unique_ptr<REntry> CreateBareEntry() const;
348 std::unique_ptr<Detail::RRawPtrWriteEntry> CreateRawPtrWriteEntry() const;
349 /// Creates a token to be used in REntry methods to address a field present in the entry
350 ROOT::RFieldToken GetToken(std::string_view fieldName) const;
351 /// Calls the given field's CreateBulk() method. Throws an RException if no field with the given name exists.
352 ROOT::RFieldBase::RBulkValues CreateBulk(std::string_view fieldName) const;
353
354 /// Retrieves the default entry of this model.
355 /// Throws an RException if this is a bare model (i.e. if it was created with CreateBare()).
357 /// \see GetDefaultEntry()
358 const REntry &GetDefaultEntry() const;
359
360 /// Retrieves the field zero of this model, i.e. the root of the field hierarchy.
361 /// This may be used to make adjustments on the field hierarchy before the model is frozen.
363 /// Retrieves the field zero of this model, i.e. the root of the field hierarchy.
365 /// Retrieves the field with fully-qualified name `fieldName`.
366 /// Dot-separated names are used to walk down the field hierarchy: e.g. `"parent.child"` should
367 /// be used to retrieve a field with name `"child"` whose parent is the top-level field with name `"parent"`.
368 /// Throws an RException if no field is found with the given name.
369 ROOT::RFieldBase &GetMutableField(std::string_view fieldName);
370 /// \see GetMutableField()
371 const ROOT::RFieldBase &GetConstField(std::string_view fieldName) const;
372
373 const std::string &GetDescription() const { return fDescription; }
374 void SetDescription(std::string_view description);
375
376 /// Get the names of the fields currently present in the model, including projected fields. Registered subfields
377 /// are not included, use GetRegisteredSubfieldnames() for this.
378 const std::unordered_set<std::string> &GetFieldNames() const { return fFieldNames; }
379 /// Get the (qualified) names of subfields that have been registered (via RegisterSubfield()) to be included in
380 /// entries from this model.
381 const std::unordered_set<std::string> &GetRegisteredSubfieldNames() const { return fRegisteredSubfields; }
382
383 /// Estimate the memory usage for this model during writing
384 ///
385 /// This will return an estimate in bytes for the internal page and compression buffers. The value should be
386 /// understood per sequential RNTupleWriter or per RNTupleFillContext created for an RNTupleParallelWriter
387 /// constructed with this model.
389};
390
391namespace Internal {
392
393// clang-format off
394/**
395\class ROOT::Internal::RNTupleModelChangeset
396\ingroup NTuple
397\brief The incremental changes to a `RNTupleModel`
398
399Represents a set of alterations to a `RNTupleModel` that happened after the model is used to initialize a `RPageSink`
400instance. This object can be used to communicate metadata updates to a `RPageSink`.
401You will not normally use this directly; see `RNTupleModel::RUpdater` instead.
402*/
403// clang-format on
406 /// Points to the fields in fModel that were added as part of an updater transaction
407 std::vector<ROOT::RFieldBase *> fAddedFields;
408 /// Points to the projected fields in fModel that were added as part of an updater transaction
409 std::vector<ROOT::RFieldBase *> fAddedProjectedFields;
410
412 bool IsEmpty() const { return fAddedFields.empty() && fAddedProjectedFields.empty(); }
413
414 void AddField(std::unique_ptr<ROOT::RFieldBase> field);
415
416 /// \see RNTupleModel::AddProjectedField()
418 AddProjectedField(std::unique_ptr<ROOT::RFieldBase> field, RNTupleModel::FieldMappingFunc_t mapping);
419};
420
421} // namespace Internal
422
423/// A model is usually immutable after passing it to an `RNTupleWriter`. However, for the rare
424/// cases that require changing the model after the fact, `RUpdater` provides limited support for
425/// incremental updates, e.g. addition of new fields.
426///
427/// See `RNTupleWriter::CreateModelUpdater()` for an example.
429private:
432 std::uint64_t fNewModelId = 0; ///< The model ID after committing
433
434public:
437 /// Begin a new set of alterations to the underlying model. As a side effect, all REntry
438 /// instances related to the model are invalidated.
439 void BeginUpdate();
440 /// Commit changes since the last call to `BeginUpdate()`. All the invalidated REntries remain
441 /// invalid. `CreateEntry()` or `CreateBareEntry()` can be used to create an REntry that
442 /// matches the new model. Upon completion, `BeginUpdate()` can be called again to begin a new set of changes.
443 void CommitUpdate();
444
445 template <typename T>
446 std::shared_ptr<T> MakeField(std::string_view name, std::string_view description = "")
447 {
450 auto it =
451 std::find_if(fieldZero->begin(), fieldZero->end(), [&](const auto &f) { return f.GetFieldName() == name; });
452 R__ASSERT(it != fieldZero->end());
453 fOpenChangeset.fAddedFields.emplace_back(&(*it));
454 return objPtr;
455 }
456
457 void AddField(std::unique_ptr<ROOT::RFieldBase> field);
458
459 /// \see RNTupleModel::AddProjectedField()
460 RResult<void> AddProjectedField(std::unique_ptr<ROOT::RFieldBase> field, FieldMappingFunc_t mapping);
461};
462
463} // namespace ROOT
464
465#endif
#define f(i)
Definition RSha256.hxx:104
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
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 target
char name[80]
Definition TGX11.cxx:110
Container for the projected fields of an RNTupleModel.
const ROOT::RFieldBase * GetSourceField(const ROOT::RFieldBase *target) const
const RNTupleModel * fModel
The model this set of projected fields belongs to.
std::unordered_map< const ROOT::RFieldBase *, const ROOT::RFieldBase * > FieldMap_t
The map keys are the projected target fields, the map values are the backing source fields Note that ...
RResult< void > Add(std::unique_ptr< ROOT::RFieldBase > field, const FieldMap_t &fieldMap)
Adds a new projected field.
RProjectedFields(RProjectedFields &&)=default
RProjectedFields(std::unique_ptr< ROOT::RFieldZero > fieldZero)
RProjectedFields(const RNTupleModel &model)
std::unique_ptr< RProjectedFields > Clone(const RNTupleModel &newModel) const
Clones this container and all the projected fields it owns.
RProjectedFields & operator=(const RProjectedFields &)=delete
FieldMap_t fFieldMap
Maps the source fields from fModel to the target projected fields attached to fFieldZero.
std::unique_ptr< ROOT::RFieldZero > fFieldZero
The projected fields are attached to this zero field.
RProjectedFields(const RProjectedFields &)=delete
RResult< void > EnsureValidMapping(const ROOT::RFieldBase *target, const FieldMap_t &fieldMap)
Asserts that the passed field is a valid target of the source field provided in the field map.
ROOT::RFieldZero & GetFieldZero()
RProjectedFields & operator=(RProjectedFields &&)=default
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:47
Points to an array of objects with RNTuple I/O support, used for bulk reading.
A field translates read and write calls from/to underlying columns to/from tree values.
A field token identifies a (sub)field in an entry.
The container field for an ntuple model, which itself has no physical representation.
Definition RField.hxx:59
A model is usually immutable after passing it to an RNTupleWriter.
ROOT::RNTupleWriter & fWriter
std::uint64_t fNewModelId
The model ID after committing.
void CommitUpdate()
Commit changes since the last call to BeginUpdate().
RResult< void > AddProjectedField(std::unique_ptr< ROOT::RFieldBase > field, FieldMappingFunc_t mapping)
RUpdater(ROOT::RNTupleWriter &writer)
Internal::RNTupleModelChangeset fOpenChangeset
void AddField(std::unique_ptr< ROOT::RFieldBase > field)
std::shared_ptr< T > MakeField(std::string_view name, std::string_view description="")
void BeginUpdate()
Begin a new set of alterations to the underlying model.
The RNTupleModel encapulates the schema of an RNTuple.
std::unique_ptr< REntry > CreateEntry() const
Creates a new entry with default values for each field.
RNTupleModel(std::unique_ptr< ROOT::RFieldZero > fieldZero)
void AddSubfield(std::string_view fieldName, ROOT::REntry &entry, bool initializeValue=true) const
Add a subfield to the provided entry.
std::unique_ptr< RNTupleModel > Clone() const
std::uint64_t fModelId
Every model has a unique ID to distinguish it from other models.
void EnsureValidFieldName(std::string_view fieldName)
Checks that user-provided field names are valid in the context of this RNTupleModel.
RNTupleModel & operator=(const RNTupleModel &)=delete
std::uint64_t GetModelId() const
ROOT::RFieldZero & GetMutableFieldZero()
Retrieves the field zero of this model, i.e.
const std::unordered_set< std::string > & GetFieldNames() const
Get the names of the fields currently present in the model, including projected fields.
std::unordered_set< std::string > fRegisteredSubfields
Keeps track of which subfields have been registered to be included in entries belonging to this model...
const ROOT::RFieldZero & GetConstFieldZero() const
Retrieves the field zero of this model, i.e. the root of the field hierarchy.
std::size_t EstimateWriteMemoryUsage(const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions()) const
Estimate the memory usage for this model during writing.
EState fModelState
Changed by Freeze() / Unfreeze() and by the RUpdater.
EState
The states a model can be in.
RNTupleModel(RNTupleModel &&)=delete
void Unfreeze()
Transitions an RNTupleModel from the frozen state back to the building state, invalidating all previo...
REntry & GetDefaultEntry()
Retrieves the default entry of this model.
ROOT::RFieldBase::RBulkValues CreateBulk(std::string_view fieldName) const
Calls the given field's CreateBulk() method. Throws an RException if no field with the given name exi...
void EnsureNotFrozen() const
Throws an RException if fFrozen is true.
void AddField(std::unique_ptr< ROOT::RFieldBase > field)
Adds a field whose type is not known at compile time.
static std::unique_ptr< RNTupleModel > Create()
std::string fDescription
Free text set by the user.
bool IsFrozen() const
void SetDescription(std::string_view description)
std::unique_ptr< Internal::RProjectedFields > fProjectedFields
The set of projected top-level fields.
RNTupleModel(const RNTupleModel &)=delete
const std::string & GetDescription() const
std::unique_ptr< Detail::RRawPtrWriteEntry > CreateRawPtrWriteEntry() const
RResult< void > AddProjectedField(std::unique_ptr< ROOT::RFieldBase > field, FieldMappingFunc_t mapping)
Adds a top-level field based on existing fields.
ROOT::RFieldToken GetToken(std::string_view fieldName) const
Creates a token to be used in REntry methods to address a field present in the entry.
std::unordered_set< std::string > fFieldNames
Keeps track of which field names are taken, including projected field names.
std::unique_ptr< ROOT::RFieldZero > fFieldZero
Hierarchy of fields consisting of simple types and collections (sub trees)
void EnsureNotBare() const
Throws an RException if fDefaultEntry is nullptr.
void RegisterSubfield(std::string_view qualifiedFieldName)
Register a subfield so it can be accessed directly from entries belonging to the model.
ROOT::RFieldBase * FindField(std::string_view fieldName) const
The field name can be a top-level field or a nested field. Returns nullptr if the field is not in the...
std::shared_ptr< T > MakeField(std::string_view name, std::string_view description="")
Creates a new field given a name or {name, description} pair and a corresponding, default-constructed...
std::unique_ptr< ROOT::REntry > fDefaultEntry
Contains field values corresponding to the created top-level fields, as well as registered subfields.
void Freeze()
Transitions an RNTupleModel from the building state to the frozen state, disabling adding additional ...
ROOT::RFieldBase & GetMutableField(std::string_view fieldName)
Retrieves the field with fully-qualified name fieldName.
const std::unordered_set< std::string > & GetRegisteredSubfieldNames() const
Get the (qualified) names of subfields that have been registered (via RegisterSubfield()) to be inclu...
std::uint64_t GetSchemaId() const
static std::unique_ptr< RNTupleModel > CreateBare()
Creates a "bare model", i.e. an RNTupleModel with no default entry.
std::function< std::string(const std::string &)> FieldMappingFunc_t
User-provided function that describes the mapping of existing source fields to projected fields in te...
~RNTupleModel()=default
void Expire()
Transitions an RNTupleModel from the frozen state to the expired state, invalidating all previously c...
bool IsExpired() const
std::uint64_t fSchemaId
Models have a separate schema ID to remember that the clone of a frozen model still has the same sche...
RNTupleModel & operator=(RNTupleModel &&)=delete
const ROOT::RFieldBase & GetConstField(std::string_view fieldName) const
std::unique_ptr< REntry > CreateBareEntry() const
Creates a "bare entry", i.e.
Common user-tunable settings for storing RNTuples.
An RNTuple that gets filled with entries (data) and writes them to storage.
const_iterator begin() const
const_iterator end() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Definition RError.hxx:198
ROOT::RFieldZero & GetFieldZeroOfModel(RNTupleModel &model)
RProjectedFields & GetProjectedFieldsOfModel(RNTupleModel &model)
The incremental changes to a RNTupleModel
std::vector< ROOT::RFieldBase * > fAddedProjectedFields
Points to the projected fields in fModel that were added as part of an updater transaction.
void AddField(std::unique_ptr< ROOT::RFieldBase > field)
std::vector< ROOT::RFieldBase * > fAddedFields
Points to the fields in fModel that were added as part of an updater transaction.
ROOT::RResult< void > AddProjectedField(std::unique_ptr< ROOT::RFieldBase > field, RNTupleModel::FieldMappingFunc_t mapping)