Logo ROOT  
Reference Guide
RNTuple.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTuple.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-04
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_RNTuple
17#define ROOT7_RNTuple
18
20#include <ROOT/RNTupleModel.hxx>
22#include <ROOT/RNTupleUtil.hxx>
23#include <ROOT/RNTupleView.hxx>
24#include <ROOT/RPageStorage.hxx>
25#include <ROOT/RStringView.hxx>
26
27#include <iterator>
28#include <memory>
29#include <sstream>
30#include <utility>
31
32namespace ROOT {
33namespace Experimental {
34
35class REntry;
36class RNTupleModel;
37
38namespace Detail {
39class RPageSink;
40class RPageSource;
41}
42
43namespace Detail {
44
45// clang-format off
46/**
47\class ROOT::Experimental::RNTuple
48\ingroup NTuple
49\brief The RNTuple represents a live dataset, whose structure is defined by an RNTupleModel
50
51RNTuple connects the static information of the RNTupleModel to a source or sink on physical storage.
52Reading and writing requires use of the corresponding derived class RNTupleReader or RNTupleWriter.
53RNTuple writes only complete entries (rows of the data set). The entry itself is not kept within the
54RNTuple, which allows for multiple concurrent entries for the same RNTuple. Besides reading an entire entry,
55the RNTuple can expose views that read only specific fields.
56*/
57// clang-format on
58class RNTuple {
59protected:
60 std::unique_ptr<RNTupleModel> fModel;
61 /// The number of entries is constant for reading and reflects the sum of Fill() operations when writing
63
64 /// Only the derived RNTupleReader and RNTupleWriter can be instantiated
65 explicit RNTuple(std::unique_ptr<RNTupleModel> model);
66
67public:
68 RNTuple(const RNTuple&) = delete;
69 RNTuple& operator =(const RNTuple&) = delete;
70 ~RNTuple();
71
72 RNTupleModel* GetModel() { return fModel.get(); }
73}; // RNTuple
74
75} // namespace Detail
76
77
78/**
79 * Listing of the different options that can be returned by RNTupleReader::GetInfo()
80 */
81enum class ENTupleInfo {
82 kSummary, // The ntuple name, description, number of entries
83 kStorageDetails, // size on storage, page sizes, compression factor, etc.
84 kMetrics, // internals performance counters, requires that EnableMetrics() was called
85};
86
87
88// clang-format off
89/**
90\class ROOT::Experimental::RNTupleReader
91\ingroup NTuple
92\brief An RNTuple that is used to read data from storage
93
94An input ntuple provides data from storage as C++ objects. The ntuple model can be created from the data on storage
95or it can be imposed by the user. The latter case allows users to read into a specialized ntuple model that covers
96only a subset of the fields in the ntuple. The ntuple model is used when reading complete entries.
97Individual fields can be read as well by instantiating a tree view.
98*/
99// clang-format on
101private:
102 std::unique_ptr<Detail::RPageSource> fSource;
104
105 void ConnectModel();
106
107public:
108 // Browse through the entries
109 class RIterator : public std::iterator<std::forward_iterator_tag, NTupleSize_t> {
110 private:
113 public:
114 RIterator() = default;
115 explicit RIterator(NTupleSize_t index) : fIndex(index) {}
116 ~RIterator() = default;
117
118 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
119 iterator& operator++() /* prefix */ { ++fIndex; return *this; }
120 reference operator* () { return fIndex; }
121 pointer operator->() { return &fIndex; }
122 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
123 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
124 };
125
126
127 static std::unique_ptr<RNTupleReader> Open(std::unique_ptr<RNTupleModel> model,
128 std::string_view ntupleName,
129 std::string_view storage);
130 static std::unique_ptr<RNTupleReader> Open(std::string_view ntupleName, std::string_view storage);
131
132 /// The user imposes an ntuple model, which must be compatible with the model found in the data on storage
133 RNTupleReader(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Detail::RPageSource> source);
134 /// The model is generated from the ntuple metadata on storage
135 explicit RNTupleReader(std::unique_ptr<Detail::RPageSource> source);
136 std::unique_ptr<RNTupleReader> Clone() { return std::make_unique<RNTupleReader>(fSource->Clone()); }
138
140 const RNTupleDescriptor &GetDescriptor() const { return fSource->GetDescriptor(); }
141
142 /// Prints a detailed summary of the ntuple, including a list of fields.
143 void PrintInfo(const ENTupleInfo what = ENTupleInfo::kSummary, std::ostream &output = std::cout);
144
145 /// Analogous to Fill(), fills the default entry of the model. Returns false at the end of the ntuple.
146 /// On I/O errors, raises an expection.
147 void LoadEntry(NTupleSize_t index) { LoadEntry(index, fModel->GetDefaultEntry()); }
148 /// Fills a user provided entry after checking that the entry has been instantiated from the ntuple model
149 void LoadEntry(NTupleSize_t index, REntry* entry) {
150 for (auto& value : *entry) {
151 value.GetField()->Read(index, &value);
152 }
153 }
154
156
157 /// Provides access to an individual field that can contain either a scalar value or a collection, e.g.
158 /// GetView<double>("particles.pt") or GetView<std::vector<double>>("particle"). It can as well be the index
159 /// field of a collection itself, like GetView<NTupleSize_t>("particle")
160 template <typename T>
162 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName);
163 return RNTupleView<T>(fieldId, fSource.get());
164 }
166 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName);
167 return RNTupleViewCollection(fieldId, fSource.get());
168 }
169
170 RIterator begin() { return RIterator(0); }
172
174};
175
176// clang-format off
177/**
178\class ROOT::Experimental::RNTupleWriter
179\ingroup NTuple
180\brief An RNTuple that gets filled with entries (data) and writes them to storage
181
182An output ntuple can be filled with entries. The caller has to make sure that the data that gets filled into an ntuple
183is not modified for the time of the Fill() call. The fill call serializes the C++ object into the column format and
184writes data into the corresponding column page buffers. Writing of the buffers to storage is deferred and can be
185triggered by Flush() or by destructing the ntuple. On I/O errors, an exception is thrown.
186*/
187// clang-format on
189private:
190 static constexpr NTupleSize_t kDefaultClusterSizeEntries = 64000;
191 std::unique_ptr<Detail::RPageSink> fSink;
194
195public:
196 static std::unique_ptr<RNTupleWriter> Recreate(std::unique_ptr<RNTupleModel> model,
197 std::string_view ntupleName,
198 std::string_view storage,
199 const RNTupleWriteOptions &options = RNTupleWriteOptions());
200 RNTupleWriter(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Detail::RPageSink> sink);
201 RNTupleWriter(const RNTupleWriter&) = delete;
204
205 /// The simplest user interface if the default entry that comes with the ntuple model is used
206 void Fill() { Fill(fModel->GetDefaultEntry()); }
207 /// Multiple entries can have been instantiated from the tnuple model. This method will perform
208 /// a light check whether the entry comes from the ntuple's own model
209 void Fill(REntry *entry) {
210 for (auto& value : *entry) {
211 value.GetField()->Append(value);
212 }
213 fNEntries++;
214 if ((fNEntries % fClusterSizeEntries) == 0)
216 }
217 /// Ensure that the data from the so far seen Fill calls has been written to storage
218 void CommitCluster();
219};
220
221// clang-format off
222/**
223\class ROOT::Experimental::RCollectionNTuple
224\ingroup NTuple
225\brief A virtual ntuple for collections that can be used to some extent like a real ntuple
226*
227* This class is between a field and a ntuple. It carries the offset column for the collection and the default entry
228* taken from the collection model. It does not, however, have a tree model because the collection model has been merged
229* into the larger ntuple model.
230*/
231// clang-format on
233private:
235 std::unique_ptr<REntry> fDefaultEntry;
236public:
237 explicit RCollectionNTuple(std::unique_ptr<REntry> defaultEntry);
241
242 void Fill() { Fill(fDefaultEntry.get()); }
243 void Fill(REntry *entry) {
244 for (auto& treeValue : *entry) {
245 treeValue.GetField()->Append(treeValue);
246 }
247 fOffset++;
248 }
249
251};
252
253} // namespace Experimental
254} // namespace ROOT
255
256#endif
ROOT::R::TRInterface & r
Definition: Object.C:4
A collection of Counter objects with a name, a unit, and a description.
RNTuple & operator=(const RNTuple &)=delete
NTupleSize_t fNEntries
The number of entries is constant for reading and reflects the sum of Fill() operations when writing.
Definition: RNTuple.hxx:62
RNTuple(const RNTuple &)=delete
RNTuple(std::unique_ptr< RNTupleModel > model)
Only the derived RNTupleReader and RNTupleWriter can be instantiated.
Definition: RNTuple.cxx:34
std::unique_ptr< RNTupleModel > fModel
Definition: RNTuple.hxx:60
A virtual ntuple for collections that can be used to some extent like a real ntuple.
Definition: RNTuple.hxx:232
RCollectionNTuple(std::unique_ptr< REntry > defaultEntry)
Definition: RNTuple.cxx:200
RCollectionNTuple(const RCollectionNTuple &)=delete
std::unique_ptr< REntry > fDefaultEntry
Definition: RNTuple.hxx:235
RCollectionNTuple & operator=(const RCollectionNTuple &)=delete
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Definition: REntry.hxx:42
The on-storage meta-data of an ntuple.
Used to loop over indexes (entries or collections) between start and end.
Definition: RNTupleView.hxx:39
The RNTupleModel encapulates the schema of an ntuple.
bool operator!=(const iterator &rh) const
Definition: RNTuple.hxx:123
bool operator==(const iterator &rh) const
Definition: RNTuple.hxx:122
An RNTuple that is used to read data from storage.
Definition: RNTuple.hxx:100
static std::unique_ptr< RNTupleReader > Open(std::unique_ptr< RNTupleModel > model, std::string_view ntupleName, std::string_view storage)
Definition: RNTuple.cxx:89
std::unique_ptr< RNTupleReader > Clone()
Definition: RNTuple.hxx:136
Detail::RNTupleMetrics fMetrics
Definition: RNTuple.hxx:103
void LoadEntry(NTupleSize_t index, REntry *entry)
Fills a user provided entry after checking that the entry has been instantiated from the ntuple model...
Definition: RNTuple.hxx:149
const RNTupleDescriptor & GetDescriptor() const
Definition: RNTuple.hxx:140
RNTupleView< T > GetView(std::string_view fieldName)
Provides access to an individual field that can contain either a scalar value or a collection,...
Definition: RNTuple.hxx:161
NTupleSize_t GetNEntries() const
Definition: RNTuple.hxx:139
std::unique_ptr< Detail::RPageSource > fSource
Definition: RNTuple.hxx:102
RNTupleReader(std::unique_ptr< RNTupleModel > model, std::unique_ptr< Detail::RPageSource > source)
The user imposes an ntuple model, which must be compatible with the model found in the data on storag...
Definition: RNTuple.cxx:58
RNTupleViewCollection GetViewCollection(std::string_view fieldName)
Definition: RNTuple.hxx:165
void LoadEntry(NTupleSize_t index)
Analogous to Fill(), fills the default entry of the model.
Definition: RNTuple.hxx:147
void PrintInfo(const ENTupleInfo what=ENTupleInfo::kSummary, std::ostream &output=std::cout)
Prints a detailed summary of the ntuple, including a list of fields.
Definition: RNTuple.cxx:104
RNTupleGlobalRange GetViewRange()
Definition: RNTuple.hxx:155
A view for a collection, that can itself generate new ntuple views for its nested fields.
An RNTupleView provides read-only access to a single field of the ntuple.
Common user-tunable settings for storing ntuples.
An RNTuple that gets filled with entries (data) and writes them to storage.
Definition: RNTuple.hxx:188
void Fill(REntry *entry)
Multiple entries can have been instantiated from the tnuple model.
Definition: RNTuple.hxx:209
void CommitCluster()
Ensure that the data from the so far seen Fill calls has been written to storage.
Definition: RNTuple.cxx:185
RNTupleWriter(std::unique_ptr< RNTupleModel > model, std::unique_ptr< Detail::RPageSink > sink)
Definition: RNTuple.cxx:156
static constexpr NTupleSize_t kDefaultClusterSizeEntries
Definition: RNTuple.hxx:190
RNTupleWriter(const RNTupleWriter &)=delete
RNTupleWriter & operator=(const RNTupleWriter &)=delete
std::unique_ptr< Detail::RPageSink > fSink
Definition: RNTuple.hxx:191
void Fill()
The simplest user interface if the default entry that comes with the ntuple model is used.
Definition: RNTuple.hxx:206
static std::unique_ptr< RNTupleWriter > Recreate(std::unique_ptr< RNTupleModel > model, std::string_view ntupleName, std::string_view storage, const RNTupleWriteOptions &options=RNTupleWriteOptions())
Definition: RNTuple.cxx:175
basic_string_view< char > string_view
ENTupleInfo
Listing of the different options that can be returned by RNTupleReader::GetInfo()
Definition: RNTuple.hxx:81
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:43
constexpr NTupleSize_t kInvalidNTupleIndex
Definition: RNTupleUtil.hxx:44
VSD Structures.
Definition: StringConv.hxx:21
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:46
static void output(int code)
Definition: gifencode.c:226