Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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/RError.hxx>
20#include <ROOT/RField.hxx>
21#include <ROOT/RNTupleRange.hxx>
22#include <ROOT/RNTupleUtil.hxx>
23#include <string_view>
24
25#include <iterator>
26#include <memory>
27#include <type_traits>
28#include <utility>
29#include <unordered_map>
30
31namespace ROOT {
32namespace Experimental {
33
34namespace Internal {
35
36/// Helper to get the iteration space of the given field that needs to be connected to the given page source.
37/// The indexes are given by the number of elements of the principal column of the field or, if none exists,
38/// by the number of elements of the first principal column found in the subfields searched by BFS.
39/// If the field hierarchy is empty on columns, the returned field range is invalid (start and end set to
40/// kInvalidNTupleIndex). An attempt to use such a field range in RNTupleViewBase::GetFieldRange will throw.
42
43} // namespace Internal
44
45// clang-format off
46/**
47\class ROOT::Experimental::RNTupleViewBase
48\ingroup NTuple
49\brief An RNTupleView provides read-only access to a single field of the ntuple
50
51\tparam T The type of the object that will be read by the view; can be void if unknown at compile time.
52
53The view owns a field and its underlying columns in order to fill an RField::RValue object with data. Data can be
54accessed by index. For top-level fields, the index refers to the entry number. Fields that are part of
55nested collections have global index numbers that are derived from their parent indexes.
56
57View can only be created by a reader or by a collection view.
58*/
59// clang-format on
60template <typename T>
62protected:
63 std::unique_ptr<ROOT::RFieldBase> fField;
66
67 static std::unique_ptr<ROOT::RFieldBase> CreateField(ROOT::DescriptorId_t fieldId, Internal::RPageSource &pageSource)
68 {
69 std::unique_ptr<ROOT::RFieldBase> field;
70 {
71 const auto &desc = pageSource.GetSharedDescriptorGuard().GetRef();
72 const auto &fieldDesc = desc.GetFieldDescriptor(fieldId);
73 if constexpr (std::is_void_v<T>) {
74 field = fieldDesc.CreateField(desc);
75 } else {
76 field = std::make_unique<ROOT::RField<T>>(fieldDesc.GetFieldName());
77 }
78 }
79 field->SetOnDiskId(fieldId);
81 return field;
82 }
83
84 RNTupleViewBase(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range)
85 : fField(std::move(field)), fFieldRange(range), fValue(fField->CreateValue())
86 {
87 }
88
89 RNTupleViewBase(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range, std::shared_ptr<T> objPtr)
90 : fField(std::move(field)), fFieldRange(range), fValue(fField->BindValue(objPtr))
91 {
92 }
93
94 RNTupleViewBase(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range, T *rawPtr)
95 : fField(std::move(field)),
97 fValue(fField->BindValue(ROOT::Internal::MakeAliasedSharedPtr(rawPtr)))
98 {
99 }
100
101public:
106 ~RNTupleViewBase() = default;
107
108 const ROOT::RFieldBase &GetField() const { return *fField; }
109 ROOT::RFieldBase::RBulk CreateBulk() { return fField->CreateBulk(); }
110
111 const ROOT::RFieldBase::RValue &GetValue() const { return fValue; }
113 {
114 if (!fFieldRange.IsValid()) {
115 throw RException(R__FAIL("field iteration over empty fields is unsupported: " + fField->GetFieldName()));
116 }
117 return fFieldRange;
118 }
119
120 void Bind(std::shared_ptr<T> objPtr) { fValue.Bind(objPtr); }
123};
124
125// clang-format off
126/**
127\class ROOT::Experimental::RNTupleView
128\ingroup NTuple
129\brief An RNTupleView for a known type. See RNTupleViewBase.
130*/
131// clang-format on
132template <typename T>
133class RNTupleView : public RNTupleViewBase<T> {
134 friend class RNTupleReader;
136
137protected:
138 RNTupleView(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range)
139 : RNTupleViewBase<T>(std::move(field), range)
140 {
141 }
142
143 RNTupleView(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range, std::shared_ptr<T> objPtr)
145 {
146 }
147
148 RNTupleView(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range, T *rawPtr)
150 {
151 }
152
153public:
154 RNTupleView(const RNTupleView &other) = delete;
158 ~RNTupleView() = default;
159
165
171};
172
173// clang-format off
174/**
175\class ROOT::Experimental::RNTupleView
176\ingroup NTuple
177\brief An RNTupleView that can be used when the type is unknown at compile time. See RNTupleViewBase.
178*/
179// clang-format on
180template <>
181class RNTupleView<void> final : public RNTupleViewBase<void> {
182 friend class RNTupleReader;
184
185protected:
186 RNTupleView(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range)
187 : RNTupleViewBase<void>(std::move(field), range)
188 {
189 }
190
191 RNTupleView(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range, std::shared_ptr<void> objPtr)
192 : RNTupleViewBase<void>(std::move(field), range, objPtr)
193 {
194 }
195
196 RNTupleView(std::unique_ptr<ROOT::RFieldBase> field, ROOT::RNTupleGlobalRange range, void *rawPtr)
197 : RNTupleViewBase<void>(std::move(field), range, rawPtr)
198 {
199 }
200
201public:
202 RNTupleView(const RNTupleView &other) = delete;
206 ~RNTupleView() = default;
207
210};
211
212// clang-format off
213/**
214\class ROOT::Experimental::RNTupleDirectAccessView
215\ingroup NTuple
216\brief A view variant that provides direct access to the I/O buffers. Only works for mappable fields.
217*/
218// clang-format on
219template <typename T>
221 friend class RNTupleReader;
223
224protected:
227
229 {
230 const auto &desc = pageSource.GetSharedDescriptorGuard().GetRef();
231 const auto &fieldDesc = desc.GetFieldDescriptor(fieldId);
232 if (fieldDesc.GetTypeName() != ROOT::RField<T>::TypeName()) {
233 throw RException(R__FAIL("type mismatch for field " + fieldDesc.GetFieldName() + ": " +
234 fieldDesc.GetTypeName() + " vs. " + ROOT::RField<T>::TypeName()));
235 }
236 ROOT::RField<T> field(fieldDesc.GetFieldName());
237 field.SetOnDiskId(fieldId);
239 return field;
240 }
241
246
247public:
253
254 const ROOT::RFieldBase &GetField() const { return fField; }
256
259};
260
261// clang-format off
262/**
263\class ROOT::Experimental::RNTupleCollectionView
264\ingroup NTuple
265\brief A view for a collection, that can itself generate new ntuple views for its nested fields.
266*/
267// clang-format on
269 friend class RNTupleReader;
270
271private:
275
282
284 {
285 std::string fieldName;
286 {
287 const auto &desc = source->GetSharedDescriptorGuard().GetRef();
288 const auto &fieldDesc = desc.GetFieldDescriptor(fieldId);
289 if (fieldDesc.GetStructure() != ROOT::ENTupleStructure::kCollection) {
290 throw RException(
291 R__FAIL("invalid attemt to create collection view on non-collection field " + fieldDesc.GetFieldName()));
292 }
293 fieldName = fieldDesc.GetFieldName();
294 }
296 }
297
299 {
301 auto fieldId = descGuard->FindFieldId(fieldName, fField.GetOnDiskId());
303 throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in collection '" +
304 descGuard->GetQualifiedFieldName(fField.GetOnDiskId()) + "'"));
305 }
306 return fieldId;
307 }
308
309public:
315
324
333
334 /// Raises an exception if there is no field with the given name.
335 template <typename T>
342
343 /// Raises an exception if there is no field with the given name.
344 template <typename T>
351
352 /// Raises an exception if there is no field with the given name.
357
359 {
361 return fValue.GetRef<std::uint64_t>();
362 }
363
365 {
367 return fValue.GetRef<std::uint64_t>();
368 }
369};
370
371} // namespace Experimental
372} // namespace ROOT
373
374#endif
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:299
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
A view for a collection, that can itself generate new ntuple views for its nested fields.
static RNTupleCollectionView Create(ROOT::DescriptorId_t fieldId, Internal::RPageSource *source)
RNTupleCollectionView & operator=(RNTupleCollectionView &&other)=default
RNTupleCollectionView(RNTupleCollectionView &&other)=default
RNTupleCollectionView GetCollectionView(std::string_view fieldName)
Raises an exception if there is no field with the given name.
RNTupleCollectionView & operator=(const RNTupleCollectionView &other)=delete
RNTupleView< T > GetView(std::string_view fieldName)
Raises an exception if there is no field with the given name.
ROOT::RNTupleLocalRange GetCollectionRange(ROOT::NTupleSize_t globalIndex)
std::uint64_t operator()(RNTupleLocalIndex localIndex)
ROOT::RNTupleLocalRange GetCollectionRange(RNTupleLocalIndex localIndex)
ROOT::RField< RNTupleCardinality< std::uint64_t > > fField
RNTupleDirectAccessView< T > GetDirectAccessView(std::string_view fieldName)
Raises an exception if there is no field with the given name.
RNTupleCollectionView(ROOT::DescriptorId_t fieldId, const std::string &fieldName, Internal::RPageSource *source)
RNTupleCollectionView(const RNTupleCollectionView &other)=delete
ROOT::DescriptorId_t GetFieldId(std::string_view fieldName)
std::uint64_t operator()(ROOT::NTupleSize_t globalIndex)
A view variant that provides direct access to the I/O buffers.
RNTupleDirectAccessView & operator=(const RNTupleDirectAccessView &other)=delete
ROOT::RNTupleGlobalRange GetFieldRange() const
const T & operator()(RNTupleLocalIndex localIndex)
const ROOT::RFieldBase & GetField() const
static ROOT::RField< T > CreateField(ROOT::DescriptorId_t fieldId, Internal::RPageSource &pageSource)
const T & operator()(ROOT::NTupleSize_t globalIndex)
RNTupleDirectAccessView(const RNTupleDirectAccessView &other)=delete
RNTupleDirectAccessView(RNTupleDirectAccessView &&other)=default
RNTupleDirectAccessView & operator=(RNTupleDirectAccessView &&other)=default
RNTupleDirectAccessView(ROOT::RField< T > field, ROOT::RNTupleGlobalRange range)
An RNTuple that is used to read data from storage.
An RNTupleView provides read-only access to a single field of the ntuple.
RNTupleViewBase(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range, std::shared_ptr< T > objPtr)
RNTupleViewBase(const RNTupleViewBase &other)=delete
RNTupleViewBase & operator=(const RNTupleViewBase &other)=delete
const ROOT::RFieldBase & GetField() const
RNTupleViewBase(RNTupleViewBase &&other)=default
ROOT::RNTupleGlobalRange fFieldRange
std::unique_ptr< ROOT::RFieldBase > fField
ROOT::RNTupleGlobalRange GetFieldRange() const
void Bind(std::shared_ptr< T > objPtr)
RNTupleViewBase & operator=(RNTupleViewBase &&other)=default
ROOT::RFieldBase::RBulk CreateBulk()
const ROOT::RFieldBase::RValue & GetValue() const
static std::unique_ptr< ROOT::RFieldBase > CreateField(ROOT::DescriptorId_t fieldId, Internal::RPageSource &pageSource)
RNTupleViewBase(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range, T *rawPtr)
RNTupleViewBase(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range)
ROOT::RFieldBase::RValue fValue
RNTupleView(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range)
RNTupleView(RNTupleView &&other)=default
RNTupleView(const RNTupleView &other)=delete
RNTupleView & operator=(RNTupleView &&other)=default
void operator()(RNTupleLocalIndex localIndex)
RNTupleView(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range, void *rawPtr)
RNTupleView(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range, std::shared_ptr< void > objPtr)
RNTupleView & operator=(const RNTupleView &other)=delete
void operator()(ROOT::NTupleSize_t globalIndex)
An RNTupleView for a known type.
RNTupleView & operator=(RNTupleView &&other)=default
const T & operator()(ROOT::NTupleSize_t globalIndex)
RNTupleView & operator=(const RNTupleView &other)=delete
RNTupleView(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range, std::shared_ptr< T > objPtr)
RNTupleView(RNTupleView &&other)=default
RNTupleView(const RNTupleView &other)=delete
RNTupleView(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range, T *rawPtr)
const T & operator()(RNTupleLocalIndex localIndex)
RNTupleView(std::unique_ptr< ROOT::RFieldBase > field, ROOT::RNTupleGlobalRange range)
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
Similar to RValue but manages an array of consecutive values.
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
void Read(ROOT::NTupleSize_t globalIndex)
void EmplaceNew()
Replace the current object pointer by a pointer to a new object constructed by the field.
void Bind(std::shared_ptr< void > objPtr)
void BindRawPtr(void *rawPtr)
const T & GetRef() const
A field translates read and write calls from/to underlying columns to/from tree values.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:291
Used to loop over indexes (entries or collections) between start and end.
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Used to loop over entries of collections in a single cluster.
ROOT::RNTupleGlobalRange GetFieldRange(const ROOT::RFieldBase &field, const RPageSource &pageSource)
Helper to get the iteration space of the given field that needs to be connected to the given page sou...
auto MakeAliasedSharedPtr(T *rawPtr)
void CallConnectPageSourceOnField(RFieldBase &, ROOT::Experimental::Internal::RPageSource &)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId