Logo ROOT  
Reference Guide
RNTupleView.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleView.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-05
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_RNTupleView
17#define ROOT7_RNTupleView
18
19#include <ROOT/RField.hxx>
20#include <ROOT/RNTupleUtil.hxx>
21#include <ROOT/RStringView.hxx>
22
23#include <iterator>
24#include <memory>
25#include <utility>
26#include <unordered_map>
27
28namespace ROOT {
29namespace Experimental {
30
31
32// clang-format off
33/**
34\class ROOT::Experimental::RNTupleGlobalRange
35\ingroup NTuple
36\brief Used to loop over indexes (entries or collections) between start and end
37*/
38// clang-format on
40private:
43public:
44 class RIterator : public std::iterator<std::forward_iterator_tag, NTupleSize_t> {
45 private:
48 public:
49 RIterator() = default;
50 explicit RIterator(NTupleSize_t index) : fIndex(index) {}
51 ~RIterator() = default;
52
53 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
54 iterator& operator++() /* prefix */ { ++fIndex; return *this; }
55 reference operator* () { return fIndex; }
56 pointer operator->() { return &fIndex; }
57 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
58 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
59 };
60
63 RIterator end() { return RIterator(fEnd); }
64};
65
66
67// clang-format off
68/**
69\class ROOT::Experimental::RNTupleClusterRange
70\ingroup NTuple
71\brief Used to loop over entries of collections in a single cluster
72*/
73// clang-format on
75private:
79public:
80 class RIterator : public std::iterator<std::forward_iterator_tag, RClusterIndex> {
81 private:
84 public:
85 RIterator() = default;
86 explicit RIterator(const RClusterIndex &index) : fIndex(index) {}
87 ~RIterator() = default;
88
89 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
90 iterator& operator++() /* prefix */ { fIndex++; return *this; }
91 reference operator* () { return fIndex; }
92 pointer operator->() { return &fIndex; }
93 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
94 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
95 };
96
98 : fClusterId(clusterId), fStart(start), fEnd(end) {}
101};
102
103
104// clang-format off
105/**
106\class ROOT::Experimental::RNTupleView
107\ingroup NTuple
108\brief An RNTupleView provides read-only access to a single field of the ntuple
109
110(NB(jblomer): The ntuple view is very close to TTreeReader. Do we simply want to teach TTreeReader to deal with
111RNTuple?)
112
113The view owns a field and its underlying columns in order to fill an ntuple value object with data. Data can be
114accessed by index. For top level fields, the index refers to the entry number. Fields that are part of
115nested collections have global index numbers that are derived from their parent indexes.
116
117The RNTupleView object is an iterable. That means, all field values in the tree can be sequentially read from begin()
118to end().
119
120For simple types, template specializations let the reading become a pure mapping into a page buffer.
121*/
122// clang-format on
123template <typename T>
125 friend class RNTupleReader;
127
128protected:
129 /**
130 * fFieldId has fParent always set to null; views access nested fields without looking at the parent
131 */
134
136 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName()), fValue(fField.GenerateValue())
137 {
138 Detail::RFieldFuse::Connect(fieldId, *pageSource, fField);
139 std::unordered_map<const Detail::RFieldBase *, DescriptorId_t> field2Id;
140 field2Id[&fField] = fieldId;
141 for (auto &f : fField) {
142 auto subFieldId = pageSource->GetDescriptor().FindFieldId(f.GetName(), field2Id[f.GetParent()]);
143 Detail::RFieldFuse::Connect(subFieldId, *pageSource, f);
144 field2Id[&f] = subFieldId;
145 }
146 }
147
148public:
149 RNTupleView(const RNTupleView& other) = delete;
150 RNTupleView(RNTupleView&& other) = default;
151 RNTupleView& operator=(const RNTupleView& other) = delete;
152 RNTupleView& operator=(RNTupleView&& other) = default;
153 ~RNTupleView() { fField.DestroyValue(fValue); }
154
155 const T& operator()(NTupleSize_t globalIndex) {
156 fField.Read(globalIndex, &fValue);
157 return *fValue.Get<T>();
158 }
159
160 const T& operator()(const RClusterIndex &clusterIndex) {
161 fField.Read(clusterIndex, &fValue);
162 return *fValue.Get<T>();
163 }
164};
165
166// Template specializations in order to directly map simple types into the page pool
167
168template <>
169class RNTupleView<float> {
170 friend class RNTupleReader;
172
173protected:
176 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName())
177 {
178 Detail::RFieldFuse::Connect(fieldId, *pageSource, fField);
179 }
180
181public:
182 RNTupleView(const RNTupleView& other) = delete;
183 RNTupleView(RNTupleView&& other) = default;
184 RNTupleView& operator=(const RNTupleView& other) = delete;
185 RNTupleView& operator=(RNTupleView&& other) = default;
186 ~RNTupleView() = default;
187
188 float operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
189 float operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
190};
191
192
193template <>
194class RNTupleView<double> {
195 friend class RNTupleReader;
197
198protected:
201 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName())
202 {
203 Detail::RFieldFuse::Connect(fieldId, *pageSource, fField);
204 }
205
206public:
207 RNTupleView(const RNTupleView& other) = delete;
208 RNTupleView(RNTupleView&& other) = default;
209 RNTupleView& operator=(const RNTupleView& other) = delete;
210 RNTupleView& operator=(RNTupleView&& other) = default;
211 ~RNTupleView() = default;
212
213 double operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
214 double operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
215};
216
217
218template <>
219class RNTupleView<std::int32_t> {
220 friend class RNTupleReader;
221 friend class RNTupleViewCollection;
222
223protected:
224 RField<std::int32_t> fField;
225 RNTupleView(DescriptorId_t fieldId, Detail::RPageSource* pageSource)
226 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName())
227 {
228 Detail::RFieldFuse::Connect(fieldId, *pageSource, fField);
229 }
230
231public:
232 RNTupleView(const RNTupleView& other) = delete;
233 RNTupleView(RNTupleView&& other) = default;
234 RNTupleView& operator=(const RNTupleView& other) = delete;
235 RNTupleView& operator=(RNTupleView&& other) = default;
236 ~RNTupleView() = default;
237
238 std::int32_t operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
239 std::int32_t operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
240};
241
242template <>
244 friend class RNTupleReader;
246
247protected:
250 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName())
251 {
252 Detail::RFieldFuse::Connect(fieldId, *pageSource, fField);
253 }
254
255public:
256 RNTupleView(const RNTupleView& other) = delete;
257 RNTupleView(RNTupleView&& other) = default;
258 RNTupleView& operator=(const RNTupleView& other) = delete;
259 RNTupleView& operator=(RNTupleView&& other) = default;
260 ~RNTupleView() = default;
261
262 ClusterSize_t operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
263 ClusterSize_t operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
264};
265
266
267// clang-format off
268/**
269\class ROOT::Experimental::RNTupleViewCollection
270\ingroup NTuple
271\brief A view for a collection, that can itself generate new ntuple views for its nested fields.
272*/
273// clang-format on
274class RNTupleViewCollection : public RNTupleView<ClusterSize_t> {
275 friend class RNTupleReader;
276
277private:
280
282 : RNTupleView<ClusterSize_t>(fieldId, source)
283 , fSource(source)
284 , fCollectionFieldId(fieldId)
285 {}
286
287public:
293
295 ClusterSize_t size;
296 RClusterIndex collectionStart;
297 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
298 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
299 collectionStart.GetIndex() + size);
300 }
302 ClusterSize_t size;
303 RClusterIndex collectionStart;
304 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
305 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
306 collectionStart.GetIndex() + size);
307 }
308
309 template <typename T>
311 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
312 return RNTupleView<T>(fieldId, fSource);
313 }
315 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
316 return RNTupleViewCollection(fieldId, fSource);
317 }
318
320 ClusterSize_t size;
321 RClusterIndex collectionStart;
322 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
323 return size;
324 }
326 ClusterSize_t size;
327 RClusterIndex collectionStart;
328 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
329 return size;
330 }
331};
332
333} // namespace Experimental
334} // namespace ROOT
335
336#endif
ROOT::R::TRInterface & r
Definition: Object.C:4
#define f(i)
Definition: RSha256.hxx:104
static void Connect(DescriptorId_t fieldId, RPageStorage &pageStorage, RFieldBase &field)
Definition: RField.cxx:76
Abstract interface to read data from an ntuple.
const RNTupleDescriptor & GetDescriptor() const
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:83
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
Template specializations for concrete C++ types.
Definition: RField.hxx:483
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Special help for offset fields.
Definition: RField.hxx:518
Classes with dictionaries that can be inspected by TClass.
Definition: RField.hxx:428
Used to loop over entries of collections in a single cluster.
Definition: RNTupleView.hxx:74
const ClusterSize_t::ValueType fStart
Definition: RNTupleView.hxx:77
RNTupleClusterRange(DescriptorId_t clusterId, ClusterSize_t::ValueType start, ClusterSize_t::ValueType end)
Definition: RNTupleView.hxx:97
const ClusterSize_t::ValueType fEnd
Definition: RNTupleView.hxx:78
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:57
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:58
Used to loop over indexes (entries or collections) between start and end.
Definition: RNTupleView.hxx:39
RNTupleGlobalRange(NTupleSize_t start, NTupleSize_t end)
Definition: RNTupleView.hxx:61
An RNTuple that is used to read data from storage.
Definition: RNTuple.hxx:100
A view for a collection, that can itself generate new ntuple views for its nested fields.
RNTupleViewCollection GetViewCollection(std::string_view fieldName)
RNTupleClusterRange GetViewRange(const RClusterIndex &clusterIndex)
RNTupleClusterRange GetViewRange(NTupleSize_t globalIndex)
RNTupleViewCollection(RNTupleViewCollection &&other)=default
RNTupleViewCollection & operator=(RNTupleViewCollection &&other)=default
RNTupleViewCollection & operator=(const RNTupleViewCollection &other)=delete
RNTupleViewCollection(DescriptorId_t fieldId, Detail::RPageSource *source)
ClusterSize_t operator()(const RClusterIndex &clusterIndex)
ClusterSize_t operator()(NTupleSize_t globalIndex)
RNTupleView< T > GetView(std::string_view fieldName)
RNTupleViewCollection(const RNTupleViewCollection &other)=delete
RNTupleView & operator=(const RNTupleView &other)=delete
ClusterSize_t operator()(const RClusterIndex &clusterIndex)
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
RNTupleView & operator=(RNTupleView &&other)=default
ClusterSize_t operator()(NTupleSize_t globalIndex)
RNTupleView(const RNTupleView &other)=delete
RNTupleView & operator=(const RNTupleView &other)=delete
RNTupleView(RNTupleView &&other)=default
RNTupleView & operator=(RNTupleView &&other)=default
RNTupleView(const RNTupleView &other)=delete
double operator()(const RClusterIndex &clusterIndex)
double operator()(NTupleSize_t globalIndex)
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
float operator()(const RClusterIndex &clusterIndex)
RNTupleView(const RNTupleView &other)=delete
RNTupleView(RNTupleView &&other)=default
RNTupleView & operator=(RNTupleView &&other)=default
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
float operator()(NTupleSize_t globalIndex)
RNTupleView & operator=(const RNTupleView &other)=delete
An RNTupleView provides read-only access to a single field of the ntuple.
RNTupleView & operator=(RNTupleView &&other)=default
RNTupleView & operator=(const RNTupleView &other)=delete
RNTupleView(RNTupleView &&other)=default
RField< T > fField
fFieldId has fParent always set to null; views access nested fields without looking at the parent
const T & operator()(const RClusterIndex &clusterIndex)
RNTupleView(const RNTupleView &other)=delete
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
const T & operator()(NTupleSize_t globalIndex)
basic_string_view< char > string_view
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:43
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:79
constexpr NTupleSize_t kInvalidNTupleIndex
Definition: RNTupleUtil.hxx:44
double T(double x)
Definition: ChebyshevPol.h:34
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