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 <type_traits>
26#include <utility>
27#include <unordered_map>
28
29namespace ROOT {
30namespace Experimental {
31
32
33// clang-format off
34/**
35\class ROOT::Experimental::RNTupleGlobalRange
36\ingroup NTuple
37\brief Used to loop over indexes (entries or collections) between start and end
38*/
39// clang-format on
41private:
44public:
45 class RIterator {
46 private:
48 public:
50 using iterator_category = std::forward_iterator_tag;
55
56 RIterator() = default;
58 ~RIterator() = default;
59
60 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
61 iterator& operator++() /* prefix */ { ++fIndex; return *this; }
63 pointer operator->() { return &fIndex; }
64 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
65 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
66 };
67
70 RIterator end() { return RIterator(fEnd); }
71};
72
73
74// clang-format off
75/**
76\class ROOT::Experimental::RNTupleClusterRange
77\ingroup NTuple
78\brief Used to loop over entries of collections in a single cluster
79*/
80// clang-format on
82private:
86public:
87 class RIterator {
88 private:
90 public:
92 using iterator_category = std::forward_iterator_tag;
97
98 RIterator() = default;
99 explicit RIterator(const RClusterIndex &index) : fIndex(index) {}
100 ~RIterator() = default;
101
102 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
103 iterator& operator++() /* prefix */ { fIndex++; return *this; }
105 pointer operator->() { return &fIndex; }
106 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
107 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
108 };
109
111 : fClusterId(clusterId), fStart(start), fEnd(end) {}
114};
115
116
117namespace Internal {
118
119template <class FieldT>
121public:
122 using RSuccess = char;
123 struct RFailure { char x[2]; };
124
125 template<class C, typename ... ArgsT>
126 using MapOverloadT = decltype(std::declval<C>().Map(std::declval<ArgsT>() ...)) (C::*)(ArgsT ...);
127
128 template <class C> static RSuccess Test(MapOverloadT<C, NTupleSize_t>);
129 template <class C> static RFailure Test(...);
130
131public:
132 static constexpr bool value = sizeof(Test<FieldT>(0)) == sizeof(RSuccess);
133};
134
135} // namespace Internal
136
137
138// clang-format off
139/**
140\class ROOT::Experimental::RNTupleView
141\ingroup NTuple
142\brief An RNTupleView provides read-only access to a single field of the ntuple
143
144The view owns a field and its underlying columns in order to fill an ntuple value object with data. Data can be
145accessed by index. For top-level fields, the index refers to the entry number. Fields that are part of
146nested collections have global index numbers that are derived from their parent indexes.
147
148Fields of simple types with a Map() method will use that and thus expose zero-copy access.
149*/
150// clang-format on
151template <typename T>
154
156
157private:
158 /// fFieldId has fParent always set to null; views access nested fields without looking at the parent
160 /// Used as a Read() destination for fields that are not mappable
162
163public:
165 : fField(pageSource->GetSharedDescriptorGuard()->GetFieldDescriptor(fieldId).GetFieldName()),
166 fValue(fField.GenerateValue())
167 {
168 fField.SetOnDiskId(fieldId);
169 fField.ConnectPageSource(*pageSource);
170 for (auto &f : fField) {
171 auto subFieldId =
172 pageSource->GetSharedDescriptorGuard()->FindFieldId(f.GetName(), f.GetParent()->GetOnDiskId());
173 f.SetOnDiskId(subFieldId);
174 f.ConnectPageSource(*pageSource);
175 }
176 }
177
178 RNTupleView(const RNTupleView& other) = delete;
179 RNTupleView(RNTupleView&& other) = default;
180 RNTupleView& operator=(const RNTupleView& other) = delete;
181 RNTupleView& operator=(RNTupleView&& other) = default;
182 ~RNTupleView() { fField.DestroyValue(fValue); }
183
184 RNTupleGlobalRange GetFieldRange() const { return RNTupleGlobalRange(0, fField.GetNElements()); }
185
186 template <typename C = T>
188 operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
189
190 template <typename C = T>
193 fField.Read(globalIndex, &fValue);
194 return *fValue.Get<T>();
195 }
196
197 template <typename C = T>
199 operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
200
201 template <typename C = T>
203 operator()(const RClusterIndex &clusterIndex) {
204 fField.Read(clusterIndex, &fValue);
205 return *fValue.Get<T>();
206 }
207
208 template <typename C = T>
210 MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
211 return fField.MapV(globalIndex, nItems);
212 }
213
214 template <typename C = T>
216 MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
217 return fField.MapV(clusterIndex, nItems);
218 }
219};
220
221
222// clang-format off
223/**
224\class ROOT::Experimental::RNTupleViewCollection
225\ingroup NTuple
226\brief A view for a collection, that can itself generate new ntuple views for its nested fields.
227*/
228// clang-format on
229class RNTupleViewCollection : public RNTupleView<ClusterSize_t> {
230 friend class RNTupleReader;
231
232private:
235
237 : RNTupleView<ClusterSize_t>(fieldId, source)
238 , fSource(source)
239 , fCollectionFieldId(fieldId)
240 {}
241
242public:
248
251 RClusterIndex collectionStart;
252 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
253 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
254 collectionStart.GetIndex() + size);
255 }
258 RClusterIndex collectionStart;
259 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
260 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
261 collectionStart.GetIndex() + size);
262 }
263
264 /// Raises an exception if there is no field with the given name.
265 template <typename T>
267 auto fieldId = fSource->GetSharedDescriptorGuard()->FindFieldId(fieldName, fCollectionFieldId);
268 if (fieldId == kInvalidDescriptorId) {
269 throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '" +
271 }
272 return RNTupleView<T>(fieldId, fSource);
273 }
274 /// Raises an exception if there is no field with the given name.
276 auto fieldId = fSource->GetSharedDescriptorGuard()->FindFieldId(fieldName, fCollectionFieldId);
277 if (fieldId == kInvalidDescriptorId) {
278 throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '" +
280 }
281 return RNTupleViewCollection(fieldId, fSource);
282 }
283
286 RClusterIndex collectionStart;
287 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
288 return size;
289 }
292 RClusterIndex collectionStart;
293 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
294 return size;
295 }
296};
297
298} // namespace Experimental
299} // namespace ROOT
300
301#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:291
#define f(i)
Definition: RSha256.hxx:104
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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 r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
decltype(std::declval< C >().Map(std::declval< ArgsT >() ...))(C::*)(ArgsT ...) MapOverloadT
static RSuccess Test(MapOverloadT< C, NTupleSize_t >)
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:87
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
Base class for all ROOT issued exceptions.
Definition: RError.hxx:114
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Special help for offset fields.
Definition: RField.hxx:686
Classes with dictionaries that can be inspected by TClass.
Definition: RField.hxx:537
Used to loop over entries of collections in a single cluster.
Definition: RNTupleView.hxx:81
const ClusterSize_t::ValueType fStart
Definition: RNTupleView.hxx:84
RNTupleClusterRange(DescriptorId_t clusterId, ClusterSize_t::ValueType start, ClusterSize_t::ValueType end)
const ClusterSize_t::ValueType fEnd
Definition: RNTupleView.hxx:85
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:64
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:65
Used to loop over indexes (entries or collections) between start and end.
Definition: RNTupleView.hxx:40
RNTupleGlobalRange(NTupleSize_t start, NTupleSize_t end)
Definition: RNTupleView.hxx:68
An RNTuple that is used to read data from storage.
Definition: RNTuple.hxx:110
A view for a collection, that can itself generate new ntuple views for its nested fields.
RNTupleClusterRange GetCollectionRange(const RClusterIndex &clusterIndex)
RNTupleViewCollection GetViewCollection(std::string_view fieldName)
Raises an exception if there is no field with the given name.
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)
Raises an exception if there is no field with the given name.
RNTupleClusterRange GetCollectionRange(NTupleSize_t globalIndex)
RNTupleViewCollection(const RNTupleViewCollection &other)=delete
An RNTupleView provides read-only access to a single field of the ntuple.
Detail::RFieldValue fValue
Used as a Read() destination for fields that are not mappable.
RNTupleView & operator=(RNTupleView &&other)=default
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
std::enable_if_t<!Internal::IsMappable< FieldT >::value, const C & > operator()(const RClusterIndex &clusterIndex)
RNTupleView & operator=(const RNTupleView &other)=delete
RNTupleView(RNTupleView &&other)=default
RNTupleView(const RNTupleView &other)=delete
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(const RClusterIndex &clusterIndex)
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C * > MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
std::enable_if_t<!Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
FieldT fField
fFieldId has fParent always set to null; views access nested fields without looking at the parent
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C * > MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems)
RNTupleGlobalRange GetFieldRange() const
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:47
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:83
constexpr NTupleSize_t kInvalidNTupleIndex
Definition: RNTupleUtil.hxx:48
constexpr DescriptorId_t kInvalidDescriptorId
Definition: RNTupleUtil.hxx:84
static double C[]
double T(double x)
Definition: ChebyshevPol.h:34
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:50