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 
29 namespace ROOT {
30 namespace 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
41 private:
44 public:
45  class RIterator {
46  private:
48  public:
50  using iterator_category = std::forward_iterator_tag;
55 
56  RIterator() = default;
57  explicit RIterator(NTupleSize_t index) : fIndex(index) {}
58  ~RIterator() = default;
59 
60  iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
61  iterator& operator++() /* prefix */ { ++fIndex; return *this; }
62  reference operator* () { return fIndex; }
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
82 private:
86 public:
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 
117 namespace Internal {
118 
119 template <class FieldT>
120 class IsMappable {
121 public:
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 
131 public:
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 
144 The view owns a field and its underlying columns in order to fill an ntuple value object with data. Data can be
145 accessed by index. For top-level fields, the index refers to the entry number. Fields that are part of
146 nested collections have global index numbers that are derived from their parent indexes.
147 
148 Fields of simple types with a Map() method will use that and thus expose zero-copy access.
149 */
150 // clang-format on
151 template <typename T>
152 class RNTupleView {
153  friend class RNTupleReader;
154  friend class RNTupleViewCollection;
155 
156  using FieldT = RField<T>;
157 
158 private:
159  /// fFieldId has fParent always set to null; views access nested fields without looking at the parent
161  /// Used as a Read() destination for fields that are not mappable
163 
165  : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName()), fValue(fField.GenerateValue())
166  {
167  Detail::RFieldFuse::ConnectRecursively(fieldId, *pageSource, fField);
168  }
169 
170 public:
171  RNTupleView(const RNTupleView& other) = delete;
172  RNTupleView(RNTupleView&& other) = default;
173  RNTupleView& operator=(const RNTupleView& other) = delete;
174  RNTupleView& operator=(RNTupleView&& other) = default;
176 
178 
179  template <typename C = T>
180  typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
181  operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
182 
183  template <typename C = T>
184  typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
185  operator()(NTupleSize_t globalIndex) {
186  fField.Read(globalIndex, &fValue);
187  return *fValue.Get<T>();
188  }
189 
190  template <typename C = T>
191  typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
192  operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
193 
194  template <typename C = T>
195  typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
196  operator()(const RClusterIndex &clusterIndex) {
197  fField.Read(clusterIndex, &fValue);
198  return *fValue.Get<T>();
199  }
200 };
201 
202 
203 // clang-format off
204 /**
205 \class ROOT::Experimental::RNTupleViewCollection
206 \ingroup NTuple
207 \brief A view for a collection, that can itself generate new ntuple views for its nested fields.
208 */
209 // clang-format on
210 class RNTupleViewCollection : public RNTupleView<ClusterSize_t> {
211  friend class RNTupleReader;
212 
213 private:
216 
218  : RNTupleView<ClusterSize_t>(fieldId, source)
219  , fSource(source)
220  , fCollectionFieldId(fieldId)
221  {}
222 
223 public:
229 
231  ClusterSize_t size;
232  RClusterIndex collectionStart;
233  fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
234  return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
235  collectionStart.GetIndex() + size);
236  }
238  ClusterSize_t size;
239  RClusterIndex collectionStart;
240  fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
241  return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
242  collectionStart.GetIndex() + size);
243  }
244 
245  template <typename T>
247  auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
248  return RNTupleView<T>(fieldId, fSource);
249  }
251  auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
252  return RNTupleViewCollection(fieldId, fSource);
253  }
254 
256  ClusterSize_t size;
257  RClusterIndex collectionStart;
258  fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
259  return size;
260  }
261  ClusterSize_t operator()(const RClusterIndex &clusterIndex) {
262  ClusterSize_t size;
263  RClusterIndex collectionStart;
264  fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
265  return size;
266  }
267 };
268 
269 } // namespace Experimental
270 } // namespace ROOT
271 
272 #endif
ROOT::Experimental::Internal::IsMappable::Test
static RFailure Test(...)
ROOT::Experimental::RNTupleView::operator()
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(const RClusterIndex &clusterIndex)
Definition: RNTupleView.hxx:192
ROOT::Experimental::RNTupleClusterRange::RIterator::operator->
pointer operator->()
Definition: RNTupleView.hxx:105
ROOT::Experimental::RNTupleView::operator=
RNTupleView & operator=(const RNTupleView &other)=delete
ROOT::Experimental::Detail::RFieldValue::Get
T * Get() const
Definition: RFieldValue.hxx:79
ROOT::Experimental::RNTupleClusterRange::RNTupleClusterRange
RNTupleClusterRange(DescriptorId_t clusterId, ClusterSize_t::ValueType start, ClusterSize_t::ValueType end)
Definition: RNTupleView.hxx:110
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator!=
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:65
ROOT::Experimental::Detail::RFieldFuse::ConnectRecursively
static void ConnectRecursively(DescriptorId_t fieldId, RPageSource &pageSource, RFieldBase &field)
Connect the field columns and all sub field columns.
Definition: RField.cxx:127
ROOT::Experimental::RNTupleGlobalRange::RIterator
Definition: RNTupleView.hxx:45
ROOT::Experimental::RNTupleGlobalRange::RIterator::fIndex
NTupleSize_t fIndex
Definition: RNTupleView.hxx:47
ROOT::Experimental::RNTupleView< ClusterSize_t >::RNTupleViewCollection
friend class RNTupleViewCollection
Definition: RNTupleView.hxx:154
ROOT::Experimental::RNTupleClusterRange::begin
RIterator begin()
Definition: RNTupleView.hxx:112
ROOT::Experimental::RNTupleClusterRange::fStart
const ClusterSize_t::ValueType fStart
Definition: RNTupleView.hxx:84
ROOT::Experimental::RNTupleView::operator()
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:181
ROOT::Experimental::RNTupleViewCollection::~RNTupleViewCollection
~RNTupleViewCollection()=default
ROOT::Experimental::RNTupleViewCollection::GetViewCollection
RNTupleViewCollection GetViewCollection(std::string_view fieldName)
Definition: RNTupleView.hxx:250
ROOT::Experimental::RNTupleView::RNTupleView
RNTupleView(const RNTupleView &other)=delete
ROOT::Experimental::Detail::RFieldBase::GetNElements
NTupleSize_t GetNElements() const
Definition: RField.hxx:222
ROOT::Experimental::Internal::IsMappable::Test
static RSuccess Test(MapOverloadT< C, NTupleSize_t >)
ROOT::Experimental::DescriptorId_t
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:91
r
ROOT::R::TRInterface & r
Definition: Object.C:4
RField.hxx
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator++
iterator operator++(int)
Definition: RNTupleView.hxx:60
ROOT::Experimental::RNTupleViewCollection::GetCollectionRange
RNTupleClusterRange GetCollectionRange(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:230
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator==
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:64
ROOT::Experimental::NTupleSize_t
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:55
ROOT::Experimental::Detail::RPageSource
Abstract interface to read data from an ntuple.
Definition: RPageStorage.hxx:192
ROOT::Experimental::RClassField::DestroyValue
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:610
ROOT::Experimental::RNTupleViewCollection::operator()
ClusterSize_t operator()(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:255
ROOT::Experimental::RNTupleGlobalRange::RIterator::RIterator
RIterator(NTupleSize_t index)
Definition: RNTupleView.hxx:57
ROOT::Experimental::RNTupleView
An RNTupleView provides read-only access to a single field of the ntuple.
Definition: RNTupleView.hxx:152
ROOT::Experimental::Detail::RFieldValue
Definition: RFieldValue.hxx:41
ROOT::Experimental::RNTupleClusterRange::RIterator
Definition: RNTupleView.hxx:87
ROOT::Experimental::RNTupleViewCollection::operator=
RNTupleViewCollection & operator=(RNTupleViewCollection &&other)=default
ROOT::Experimental::RNTupleViewCollection::operator=
RNTupleViewCollection & operator=(const RNTupleViewCollection &other)=delete
ROOT::Experimental::RNTupleGlobalRange::fStart
const NTupleSize_t fStart
Definition: RNTupleView.hxx:42
ROOT::Experimental::RNTupleClusterRange
Used to loop over entries of collections in a single cluster.
Definition: RNTupleView.hxx:81
ROOT::Experimental::RClusterIndex::GetIndex
ClusterSize_t::ValueType GetIndex() const
Definition: RNTupleUtil.hxx:116
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator->
pointer operator->()
Definition: RNTupleView.hxx:63
ROOT::Experimental::RNTupleView::operator=
RNTupleView & operator=(RNTupleView &&other)=default
ROOT::Experimental::RNTupleViewCollection::RNTupleViewCollection
RNTupleViewCollection(const RNTupleViewCollection &other)=delete
ROOT::Experimental::RNTupleGlobalRange::RIterator::pointer
NTupleSize_t * pointer
Definition: RNTupleView.hxx:53
ROOT::Math::Cephes::C
static double C[]
Definition: SpecFuncCephes.cxx:187
ROOT::Experimental::RNTupleViewCollection::GetView
RNTupleView< T > GetView(std::string_view fieldName)
Definition: RNTupleView.hxx:246
ROOT::Experimental::RNTupleView::fField
FieldT fField
fFieldId has fParent always set to null; views access nested fields without looking at the parent
Definition: RNTupleView.hxx:160
ROOT::Experimental::RNTupleClusterRange::end
RIterator end()
Definition: RNTupleView.hxx:113
ROOT::Experimental::RClusterSize::ValueType
std::uint32_t ValueType
Definition: RNTupleUtil.hxx:59
ROOT::Experimental::Internal::IsMappable::value
static constexpr bool value
Definition: RNTupleView.hxx:132
ROOT::Experimental::RNTupleClusterRange::RIterator::~RIterator
~RIterator()=default
ROOT::Experimental::RNTupleClusterRange::fEnd
const ClusterSize_t::ValueType fEnd
Definition: RNTupleView.hxx:85
ROOT::Experimental::Internal::IsMappable::RSuccess
char RSuccess
Definition: RNTupleView.hxx:122
ROOT::Experimental::RNTupleGlobalRange::end
RIterator end()
Definition: RNTupleView.hxx:70
RStringView.hxx
ROOT::Experimental::kInvalidNTupleIndex
constexpr NTupleSize_t kInvalidNTupleIndex
Definition: RNTupleUtil.hxx:56
ROOT::Experimental::RClusterIndex::GetClusterId
DescriptorId_t GetClusterId() const
Definition: RNTupleUtil.hxx:115
ROOT::Experimental::RNTupleViewCollection
A view for a collection, that can itself generate new ntuple views for its nested fields.
Definition: RNTupleView.hxx:210
ROOT::Experimental::RNTupleDescriptor::FindFieldId
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
Definition: RNTupleDescriptor.cxx:668
ROOT::Experimental::Internal::IsMappable::MapOverloadT
decltype(std::declval< C >().Map(std::declval< ArgsT >() ...))(C::*)(ArgsT ...) MapOverloadT
Definition: RNTupleView.hxx:126
ROOT::Experimental::Detail::RPageSource::GetDescriptor
const RNTupleDescriptor & GetDescriptor() const
Definition: RPageStorage.hxx:222
ROOT::Experimental::RNTupleView::RNTupleView
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
Definition: RNTupleView.hxx:164
ROOT::Experimental::RNTupleGlobalRange::RIterator::difference_type
NTupleSize_t difference_type
Definition: RNTupleView.hxx:52
ROOT::Experimental::RNTupleClusterRange::RIterator::fIndex
RClusterIndex fIndex
Definition: RNTupleView.hxx:89
ROOT::Experimental::RNTupleClusterRange::RIterator::operator++
iterator & operator++()
Definition: RNTupleView.hxx:103
ROOT::Experimental::RNTupleView::GetFieldRange
RNTupleGlobalRange GetFieldRange() const
Definition: RNTupleView.hxx:177
RNTupleUtil.hxx
ROOT::Experimental::RNTupleClusterRange::RIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: RNTupleView.hxx:92
ROOT::Experimental::RNTupleGlobalRange::RIterator::RIterator
RIterator()=default
ROOT::Experimental::RNTupleGlobalRange
Used to loop over indexes (entries or collections) between start and end.
Definition: RNTupleView.hxx:40
ROOT::Experimental::RClusterIndex
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:95
ROOT::Experimental::RNTupleGlobalRange::fEnd
const NTupleSize_t fEnd
Definition: RNTupleView.hxx:43
ROOT::Experimental::RClusterSize
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:58
ROOT::Experimental::RNTupleClusterRange::RIterator::operator!=
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:107
ROOT::Experimental::RField< ClusterSize_t >
Template specializations for concrete C++ types.
Definition: RField.hxx:467
ROOT::Experimental::Internal::IsMappable::RFailure::x
char x[2]
Definition: RNTupleView.hxx:123
ROOT::Experimental::RNTupleClusterRange::RIterator::operator++
iterator operator++(int)
Definition: RNTupleView.hxx:102
ROOT::Experimental::RNTupleViewCollection::RNTupleViewCollection
RNTupleViewCollection(DescriptorId_t fieldId, Detail::RPageSource *source)
Definition: RNTupleView.hxx:217
ROOT::Experimental::RNTupleView::fValue
Detail::RFieldValue fValue
Used as a Read() destination for fields that are not mappable.
Definition: RNTupleView.hxx:162
ROOT::Experimental::RNTupleClusterRange::fClusterId
const DescriptorId_t fClusterId
Definition: RNTupleView.hxx:83
ROOT::Experimental::RNTupleView::operator()
std::enable_if_t<!Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:185
ROOT::Experimental::Internal::IsMappable::RFailure
Definition: RNTupleView.hxx:123
ROOT::Experimental::RNTupleView::operator()
std::enable_if_t<!Internal::IsMappable< FieldT >::value, const C & > operator()(const RClusterIndex &clusterIndex)
Definition: RNTupleView.hxx:196
ROOT::Experimental::RNTupleClusterRange::RIterator::RIterator
RIterator(const RClusterIndex &index)
Definition: RNTupleView.hxx:99
ROOT::Experimental::RNTupleView::RNTupleView
RNTupleView(RNTupleView &&other)=default
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator*
reference operator*()
Definition: RNTupleView.hxx:62
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator++
iterator & operator++()
Definition: RNTupleView.hxx:61
ROOT::Experimental::RNTupleViewCollection::RNTupleViewCollection
RNTupleViewCollection(RNTupleViewCollection &&other)=default
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::Experimental::RNTupleGlobalRange::RIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: RNTupleView.hxx:50
ROOT::Experimental::RNTupleViewCollection::operator()
ClusterSize_t operator()(const RClusterIndex &clusterIndex)
Definition: RNTupleView.hxx:261
ROOT::Experimental::RNTupleClusterRange::RIterator::RIterator
RIterator()=default
ROOT::Experimental::RField< ClusterSize_t >::GetCollectionInfo
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Special help for offset fields.
Definition: RField.hxx:504
ROOT::Experimental::RNTupleViewCollection::fSource
Detail::RPageSource * fSource
Definition: RNTupleView.hxx:214
ROOT::Experimental::RNTupleView::~RNTupleView
~RNTupleView()
Definition: RNTupleView.hxx:175
ROOT::Experimental::Detail::RFieldBase::Read
void Read(NTupleSize_t globalIndex, RFieldValue *value)
Populate a single value with data from the tree, which needs to be of the fitting type.
Definition: RField.hxx:194
ROOT::Experimental::RNTupleViewCollection::fCollectionFieldId
DescriptorId_t fCollectionFieldId
Definition: RNTupleView.hxx:215
ROOT::Experimental::RNTupleClusterRange::RIterator::operator==
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:106
ROOT::Experimental::RNTupleGlobalRange::RIterator::reference
NTupleSize_t & reference
Definition: RNTupleView.hxx:54
ROOT::Experimental::RNTupleViewCollection::GetCollectionRange
RNTupleClusterRange GetCollectionRange(const RClusterIndex &clusterIndex)
Definition: RNTupleView.hxx:237
ROOT::Experimental::Internal::IsMappable
Definition: RNTupleView.hxx:120
ROOT::VecOps::Map
auto Map(Args &&... args) -> decltype(ROOT::Detail::VecOps::MapFromTuple(std::forward_as_tuple(args...), std::make_index_sequence< sizeof...(args) - 1 >()))
Create new collection applying a callable to the elements of the input collection.
Definition: RVec.hxx:939
ROOT::Experimental::RNTupleGlobalRange::RIterator::~RIterator
~RIterator()=default
ROOT
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: EExecutionPolicy.hxx:4
ROOT::Experimental::RNTupleGlobalRange::RNTupleGlobalRange
RNTupleGlobalRange(NTupleSize_t start, NTupleSize_t end)
Definition: RNTupleView.hxx:68
ROOT::Experimental::RNTupleGlobalRange::RIterator::value_type
NTupleSize_t value_type
Definition: RNTupleView.hxx:51
ROOT::Experimental::RNTupleClusterRange::RIterator::operator*
reference operator*()
Definition: RNTupleView.hxx:104
ROOT::Experimental::RNTupleReader
An RNTuple that is used to read data from storage.
Definition: RNTuple.hxx:87
ROOT::Experimental::RField< T >
ROOT::Experimental::RNTupleGlobalRange::begin
RIterator begin()
Definition: RNTupleView.hxx:69