Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleProcessor.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleProcessor.hxx
2/// \ingroup NTuple ROOT7
3/// \author Florine de Geus <florine.de.geus@cern.ch>
4/// \date 2024-03-26
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-2024, 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_RNTupleProcessor
17#define ROOT7_RNTupleProcessor
18
19#include <ROOT/REntry.hxx>
20#include <ROOT/RError.hxx>
23#include <ROOT/RNTupleModel.hxx>
24#include <ROOT/RNTupleUtil.hxx>
25#include <ROOT/RPageStorage.hxx>
26
27#include <memory>
28#include <string>
29#include <string_view>
30#include <vector>
31
32namespace ROOT {
33namespace Experimental {
34
35namespace Internal {
36struct RNTupleProcessorEntryLoader;
37} // namespace Internal
38
39/// Used to specify the underlying RNTuples in RNTupleProcessor
41 std::string fNTupleName;
42 std::string fStorage;
43
44 RNTupleOpenSpec(std::string_view n, std::string_view s) : fNTupleName(n), fStorage(s) {}
45};
46
47// clang-format off
48/**
49\class ROOT::Experimental::RNTupleProcessor
50\ingroup NTuple
51\brief Interface for iterating over entries of RNTuples and vertically concatenated RNTuples (chains).
52
53Example usage (see ntpl012_processor.C for a full example):
54
55~~~{.cpp}
56#include <ROOT/RNTupleProcessor.hxx>
57using ROOT::Experimental::RNTupleProcessor;
58using ROOT::Experimental::RNTupleOpenSpec;
59
60std::vector<RNTupleOpenSpec> ntuples = {{"ntuple1", "ntuple1.root"}, {"ntuple2", "ntuple2.root"}};
61auto processor = RNTupleProcessor::CreateChain(ntuples);
62
63for (const auto &entry : processor) {
64 std::cout << "pt = " << *entry.GetPtr<float>("pt") << std::endl;
65}
66~~~
67
68An RNTupleProcessor is created by providing one or more RNTupleOpenSpecs, each of which contains the name and storage
69location of a single RNTuple. The RNTuples are processed in the order in which they were provided.
70
71The RNTupleProcessor constructor also (optionally) accepts an RNTupleModel, which determines which fields should be
72read. If no model is provided, a default model based on the descriptor of the first specified RNTuple will be used.
73If a field that was present in the first RNTuple is not found in a subsequent one, an error will be thrown.
74
75The RNTupleProcessor provides an iterator which gives access to the REntry containing the field data for the current
76entry. Additional bookkeeping information can be obtained through the RNTupleProcessor itself.
77*/
78// clang-format on
84
85protected:
86 // clang-format off
87 /**
88 \class ROOT::Experimental::RNTupleProcessor::RFieldContext
89 \ingroup NTuple
90 \brief Manager for a field as part of the RNTupleProcessor.
91
92 An RFieldContext contains two fields: a proto-field which is not connected to any page source but serves as the
93 blueprint for this particular field, and a concrete field that is connected to the page source currently connected
94 to the RNTupleProcessor for reading. When a new page source is connected, the current concrete field gets reset. A
95 new concrete field that is connected to this new page source is subsequently created from the proto-field.
96 */
97 // clang-format on
99 friend class RNTupleProcessor;
103
104 private:
105 std::unique_ptr<RFieldBase> fProtoField;
106 std::unique_ptr<RFieldBase> fConcreteField;
108 // Which RNTuple the field belongs to, in case the field belongs to an auxiliary RNTuple, according to the order
109 // in which it was specified. For chained RNTuples, this value will always be 0.
110 std::size_t fNTupleIdx;
111
112 public:
113 RFieldContext(std::unique_ptr<RFieldBase> protoField, REntry::RFieldToken token, std::size_t ntupleIdx = 0)
115 {
116 }
117
118 const RFieldBase &GetProtoField() const { return *fProtoField; }
119 /// Concrete pages need to be reset explicitly before the page source they belong to is destroyed.
121 void SetConcreteField() { fConcreteField = fProtoField->Clone(fProtoField->GetFieldName()); }
122 bool IsAuxiliary() const { return fNTupleIdx > 0; }
123 };
124
125 std::string fProcessorName;
126 std::vector<RNTupleOpenSpec> fNTuples;
127 std::unique_ptr<REntry> fEntry;
128 std::unique_ptr<Internal::RPageSource> fPageSource;
129 /// Maps the (qualified) field name to its corresponding field context.
130 std::unordered_map<std::string, RFieldContext> fFieldContexts;
131
132 std::unique_ptr<RNTupleModel> fModel;
133
134 /// Total number of entries. Only to be used internally by the processor, not meant to be exposed in the public
135 /// interface.
137
138 ROOT::NTupleSize_t fNEntriesProcessed = 0; //< Total number of entries processed so far
139 ROOT::NTupleSize_t fCurrentEntryNumber = 0; //< Current processor entry number
140 std::size_t fCurrentProcessorNumber = 0; //< Number of the currently open inner processor
141
142 /////////////////////////////////////////////////////////////////////////////
143 /// \brief Create and connect a concrete field to the current page source, based on its proto field.
145
146 /////////////////////////////////////////////////////////////////////////////
147 /// \brief Load the entry identified by the provided entry number.
148 ///
149 /// \param[in] entryNumber Entry number to load
150 ///
151 /// \return `entryNumber` if the entry was successfully loaded, `kInvalidNTupleIndex` otherwise.
153
154 /////////////////////////////////////////////////////////////////////////////
155 /// \brief Point the entry's field values of the processor to the pointers from the provided entry.
156 ///
157 /// \param[in] entry The entry whose field values to use.
158 virtual void SetEntryPointers(const REntry &entry) = 0;
159
160 /////////////////////////////////////////////////////////////////////////////
161 /// \brief Get the total number of entries in this processor
163
164 /////////////////////////////////////////////////////////////////////////////
165 /// \brief Create a new base RNTupleProcessor.
166 ///
167 /// \param[in] processorName Name of the processor. By default, this is the name of the underlying RNTuple for
168 /// RNTupleSingleProcessor, the name of the first processor for RNTupleChainProcessor, or the name of the primary
169 /// RNTuple for RNTupleJoinProcessor.
170 /// \param[in] model The RNTupleModel representing the entries returned by the processor.
171 ///
172 /// \note Before processing, a model *must* exist. However, this is handled downstream by the RNTupleProcessor's
173 /// factory functions (CreateSingle, CreateChain and CreateJoin) and constructors.
174 RNTupleProcessor(std::string_view processorName, std::unique_ptr<RNTupleModel> model)
175 : fProcessorName(processorName), fModel(std::move(model))
176 {
177 }
178
179public:
184 virtual ~RNTupleProcessor() = default;
185
186 /////////////////////////////////////////////////////////////////////////////
187 /// \brief Get the total number of entries processed so far.
189
190 /////////////////////////////////////////////////////////////////////////////
191 /// \brief Get the entry number that is currently being processed.
193
194 /////////////////////////////////////////////////////////////////////////////
195 /// \brief Get the number of the inner processor currently being read.
196 ///
197 /// This method is only relevant for the RNTupleChainProcessor. For the other processors, 0 is always returned.
199
200 /////////////////////////////////////////////////////////////////////////////
201 /// \brief Get the name of the processor.
202 ///
203 /// Unless this name was explicitly specified during creation of the processor, this is the name of the underlying
204 /// RNTuple for RNTupleSingleProcessor, the name of the first processor for RNTupleChainProcessor, or the name of the
205 /// primary RNTuple for RNTupleJoinProcessor.
206 const std::string &GetProcessorName() const { return fProcessorName; }
207
208 /////////////////////////////////////////////////////////////////////////////
209 /// \brief Get the model used by the processor.
210 const RNTupleModel &GetModel() const { return *fModel; }
211
212 /////////////////////////////////////////////////////////////////////////////
213 /// \brief Get a reference to the entry used by the processor.
214 ///
215 /// \return A reference to the entry used by the processor.
216 const REntry &GetEntry() const { return *fEntry; }
217
218 // clang-format off
219 /**
220 \class ROOT::Experimental::RNTupleProcessor::RIterator
221 \ingroup NTuple
222 \brief Iterator over the entries of an RNTuple, or vertical concatenation thereof.
223 */
224 // clang-format on
225 class RIterator {
226 private:
229
230 public:
231 using iterator_category = std::forward_iterator_tag;
234 using difference_type = std::ptrdiff_t;
235 using pointer = REntry *;
236 using reference = const REntry &;
237
240 {
241 // This constructor is called with kInvalidNTupleIndex for RNTupleProcessor::end(). In that case, we already
242 // know there is nothing to load.
245 }
246 }
247
253
255 {
256 auto obj = *this;
257 ++(*this);
258 return obj;
259 }
260
262
263 friend bool operator!=(const iterator &lh, const iterator &rh)
264 {
265 return lh.fCurrentEntryNumber != rh.fCurrentEntryNumber;
266 }
267 friend bool operator==(const iterator &lh, const iterator &rh)
268 {
269 return lh.fCurrentEntryNumber == rh.fCurrentEntryNumber;
270 }
271 };
272
273 RIterator begin() { return RIterator(*this, 0); }
275
276 /////////////////////////////////////////////////////////////////////////////
277 /// \brief Create an RNTupleProcessor for a single RNTuple.
278 ///
279 /// \param[in] ntuple The name and storage location of the RNTuple to process.
280 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
281 /// one will be created based on the descriptor of the first ntuple specified.
282 ///
283 /// \return A pointer to the newly created RNTupleProcessor.
284 static std::unique_ptr<RNTupleProcessor>
285 Create(const RNTupleOpenSpec &ntuple, std::unique_ptr<RNTupleModel> model = nullptr);
286
287 /////////////////////////////////////////////////////////////////////////////
288 /// \brief Create an RNTupleProcessor for a single RNTuple.
289 ///
290 /// \param[in] ntuple The name and storage location of the RNTuple to process.
291 /// \param[in] processorName The name to give to the processor. Use
292 /// Create(const RNTupleOpenSpec &, std::unique_ptr<RNTupleModel>) to automatically use the name of the input RNTuple
293 /// instead.
294 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
295 /// one will be created based on the descriptor of the first ntuple specified.
296 ///
297 /// \return A pointer to the newly created RNTupleProcessor.
298 static std::unique_ptr<RNTupleProcessor>
299 Create(const RNTupleOpenSpec &ntuple, std::string_view processorName, std::unique_ptr<RNTupleModel> model = nullptr);
300
301 /////////////////////////////////////////////////////////////////////////////
302 /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of RNTuples.
303 ///
304 /// \param[in] ntuples A list specifying the names and locations of the RNTuples to process.
305 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
306 /// one will be created based on the descriptor of the first RNTuple specified.
307 ///
308 /// \return A pointer to the newly created RNTupleProcessor.
309 static std::unique_ptr<RNTupleProcessor>
310 CreateChain(const std::vector<RNTupleOpenSpec> &ntuples, std::unique_ptr<RNTupleModel> model = nullptr);
311
312 /////////////////////////////////////////////////////////////////////////////
313 /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of RNTuples.
314 ///
315 /// \param[in] ntuples A list specifying the names and locations of the RNTuples to process.
316 /// \param[in] processorName The name to give to the processor. Use
317 /// CreateChain(const RNTupleOpenSpec &, std::unique_ptr<RNTupleModel>) to automatically use the name of the first
318 /// input RNTuple instead.
319 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
320 /// one will be created based on the descriptor of the first RNTuple specified.
321 ///
322 /// \return A pointer to the newly created RNTupleProcessor.
323 static std::unique_ptr<RNTupleProcessor> CreateChain(const std::vector<RNTupleOpenSpec> &ntuples,
324 std::string_view processorName,
325 std::unique_ptr<RNTupleModel> model = nullptr);
326
327 /////////////////////////////////////////////////////////////////////////////
328 /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of other RNTupleProcessors.
329 ///
330 /// \param[in] innerProcessors A list with the processors to chain.
331 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
332 /// one will be created based on the model used by the first inner processor.
333 ///
334 /// \return A pointer to the newly created RNTupleProcessor.
335 static std::unique_ptr<RNTupleProcessor> CreateChain(std::vector<std::unique_ptr<RNTupleProcessor>> innerProcessors,
336 std::unique_ptr<RNTupleModel> model = nullptr);
337
338 /////////////////////////////////////////////////////////////////////////////
339 /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of other RNTupleProcessors.
340 ///
341 /// \param[in] innerProcessors A list with the processors to chain.
342 /// \param[in] processorName The name to give to the processor. Use
343 /// CreateChain(std::vector<std::unique_ptr<RNTupleProcessor>>, std::unique_ptr<RNTupleModel>) to automatically use
344 /// the name of the first inner processor instead.
345 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
346 /// one will be created based on the model used by the first inner processor.
347 ///
348 /// \return A pointer to the newly created RNTupleProcessor.
349 static std::unique_ptr<RNTupleProcessor> CreateChain(std::vector<std::unique_ptr<RNTupleProcessor>> innerProcessors,
350 std::string_view processorName,
351 std::unique_ptr<RNTupleModel> model = nullptr);
352
353 /////////////////////////////////////////////////////////////////////////////
354 /// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples.
355 ///
356 /// \param[in] primaryNTuple The name and location of the primary RNTuple. Its entries are processed in sequential
357 /// order.
358 /// \param[in] auxNTuples The names and locations of the RNTuples to join the primary RNTuple with. The order in
359 /// which their entries are processed are determined by the primary RNTuple and doesn't necessarily have to be
360 /// sequential.
361 /// \param[in] joinFields The names of the fields on which to join, in case the specified RNTuples are unaligned.
362 /// The join is made based on the combined join field values, and therefore each field has to be present in each
363 /// specified RNTuple. If an empty list is provided, it is assumed that the specified ntuple are fully aligned.
364 /// \param[in] models A list of models for the RNTuples. This list must either contain a model for the primary
365 /// RNTuple and each auxiliary RNTuple (following the specification order), or be empty. When the list is empty, the
366 /// default model (i.e. containing all fields) will be used for each RNTuple.
367 ///
368 /// \return A pointer to the newly created RNTupleProcessor.
369 static std::unique_ptr<RNTupleProcessor>
370 CreateJoin(const RNTupleOpenSpec &primaryNTuple, const std::vector<RNTupleOpenSpec> &auxNTuples,
371 const std::vector<std::string> &joinFields, std::vector<std::unique_ptr<RNTupleModel>> models = {});
372
373 /////////////////////////////////////////////////////////////////////////////
374 /// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples.
375 ///
376 /// \param[in] primaryNTuple The name and location of the primary RNTuple. Its entries are processed in sequential
377 /// order.
378 /// \param[in] auxNTuples The names and locations of the RNTuples to join the primary RNTuple with. The order in
379 /// which their entries are processed are determined by the primary RNTuple and doesn't necessarily have to be
380 /// sequential.
381 /// \param[in] joinFields The names of the fields on which to join, in case the specified RNTuples are unaligned.
382 /// The join is made based on the combined join field values, and therefore each field has to be present in each
383 /// specified RNTuple. If an empty list is provided, it is assumed that the specified RNTuple are fully aligned.
384 /// \param[in] processorName The name to give to the processor. Use
385 /// CreateJoin(const RNTupleOpenSpec &, const std::vector<RNTupleOpenSpec> &, const std::vector<std::string> &,
386 /// std::vector<std::unique_ptr<RNTupleModel>>) to automatically use the name of the input RNTuple instead.
387 /// \param[in] models A list of models for the RNTuples. This list must either contain a model for the primary
388 /// RNTuple and each auxiliary RNTuple (following the specification order), or be empty. When the list is empty, the
389 /// default model (i.e. containing all fields) will be used for each RNTuple.
390 ///
391 /// \return A pointer to the newly created RNTupleProcessor.
392 static std::unique_ptr<RNTupleProcessor>
393 CreateJoin(const RNTupleOpenSpec &primaryNTuple, const std::vector<RNTupleOpenSpec> &auxNTuples,
394 const std::vector<std::string> &joinFields, std::string_view processorName,
395 std::vector<std::unique_ptr<RNTupleModel>> models = {});
396};
397
398// clang-format off
399/**
400\class ROOT::Experimental::RNTupleSingleProcessor
401\ingroup NTuple
402\brief Processor specialization for processing a single RNTuple.
403*/
404// clang-format on
406 friend class RNTupleProcessor;
407
408private:
410
411 /////////////////////////////////////////////////////////////////////////////
412 /// \brief Connect the page source of the underlying RNTuple.
413 void Connect();
414
415 /////////////////////////////////////////////////////////////////////////////
416 /// \brief Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in this
417 /// processor).
418 ///
419 /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntry
421
422 /////////////////////////////////////////////////////////////////////////////
423 /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryPointers.
424 void SetEntryPointers(const REntry &entry) final;
425
426 /////////////////////////////////////////////////////////////////////////////
427 /// \brief Get the total number of entries in this processor.
429 {
430 Connect();
431 return fNEntries;
432 }
433
434 /////////////////////////////////////////////////////////////////////////////
435 /// \brief Construct a new RNTupleProcessor for processing a single RNTuple.
436 ///
437 /// \param[in] ntuple The source specification (name and storage location) for the RNTuple to process.
438 /// \param[in] processorName Name of the processor. Unless specified otherwise in RNTupleProcessor::Create, this is
439 /// the name of the underlying RNTuple.
440 /// \param[in] model The model that specifies which fields should be read by the processor.
442 std::unique_ptr<RNTupleModel> model);
443};
444
445// clang-format off
446/**
447\class ROOT::Experimental::RNTupleChainProcessor
448\ingroup NTuple
449\brief Processor specialization for vertically combined (*chained*) RNTupleProcessors.
450*/
451// clang-format on
453 friend class RNTupleProcessor;
454
455private:
456 std::vector<std::unique_ptr<RNTupleProcessor>> fInnerProcessors;
457 std::vector<ROOT::NTupleSize_t> fInnerNEntries;
458
459 /////////////////////////////////////////////////////////////////////////////
460 /// \brief Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in this
461 /// processor).
462 ///
463 /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntry
465
466 /////////////////////////////////////////////////////////////////////////////
467 /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryPointers.
468 void SetEntryPointers(const REntry &) final;
469
470 /////////////////////////////////////////////////////////////////////////////
471 /// \brief Get the total number of entries in this processor.
472 ///
473 /// \note This requires opening all underlying RNTuples being processed in the chain, and could become costly!
475
476 /////////////////////////////////////////////////////////////////////////////
477 /// \brief Construct a new RNTupleChainProcessor.
478 ///
479 /// \param[in] ntuples The source specification (name and storage location) for each RNTuple to process.
480 /// \param[in] processorName Name of the processor. Unless specified otherwise in RNTupleProcessor::CreateChain, this
481 /// is the name of the first inner processor.
482 /// \param[in] model The model that specifies which fields should be read by the processor. The pointer returned by
483 /// RNTupleModel::MakeField can be used to access a field's value during the processor iteration. When no model is
484 /// specified, it is created from the descriptor of the first RNTuple specified in `ntuples`.
485 ///
486 /// RNTuples are processed in the order in which they are specified.
487 RNTupleChainProcessor(std::vector<std::unique_ptr<RNTupleProcessor>> processors, std::string_view processorName,
488 std::unique_ptr<RNTupleModel> model);
489};
490
491// clang-format off
492/**
493\class ROOT::Experimental::RNTupleJoinProcessor
494\ingroup NTuple
495\brief Processor specialization for horizontally combined (*joined*) RNTuples.
496*/
497// clang-format on
499 friend class RNTupleProcessor;
500
501private:
502 std::vector<std::unique_ptr<Internal::RPageSource>> fAuxiliaryPageSources;
503 /// Tokens representing the join fields present in the main RNTuple
504 std::vector<REntry::RFieldToken> fJoinFieldTokens;
505 std::vector<std::unique_ptr<Internal::RNTupleJoinTable>> fJoinTables;
506
507 bool HasJoinTable() const { return fJoinTables.size() > 0; }
508
509 /////////////////////////////////////////////////////////////////////////////
510 /// \brief Load the entry identified by the provided entry number of the primary RNTuple.
511 ///
512 /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntry
514
515 /////////////////////////////////////////////////////////////////////////////
516 /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryPointers.
517 void SetEntryPointers(const REntry &) final;
518
519 /////////////////////////////////////////////////////////////////////////////
520 /// \brief Get the total number of entries in this processor.
522
523 /////////////////////////////////////////////////////////////////////////////
524 /// \brief Construct a new RNTupleJoinProcessor.
525 ///
526 /// \param[in] mainNTuple The source specification (name and storage location) of the primary RNTuple.
527 /// \param[in] auxNTUples The source specifications (name and storage location) of the auxiliary RNTuples.
528 /// \param[in] joinFields The names of the fields on which to join, in case the specified RNTuples are unaligned.
529 /// The join is made based on the combined join field values, and therefore each field has to be present in each
530 /// specified RNTuple. If an empty list is provided, it is assumed that the RNTuples are fully aligned.
531 /// \param[in] processorName Name of the processor. Unless specified otherwise in RNTupleProcessor::CreateJoin, this
532 /// is the name of the main RNTuple.
533 /// \param[in] models The models that specify which fields should be read by the processor, ordered according to
534 /// {mainNTuple, auxNTuple[0], ...}. The pointer returned by RNTupleModel::MakeField can be used to access a field's
535 /// value during the processor iteration. When an empty list is passed, the models are created from the descriptor of
536 /// each RNTuple specified in `mainNTuple` and `auxNTuple`.
537 RNTupleJoinProcessor(const RNTupleOpenSpec &mainNTuple, const std::vector<RNTupleOpenSpec> &auxNTuples,
538 const std::vector<std::string> &joinFields, std::string_view processorName,
539 std::vector<std::unique_ptr<RNTupleModel>> models = {});
540
541 /////////////////////////////////////////////////////////////////////////////
542 /// \brief Add an auxiliary RNTuple to the processor.
543 ///
544 /// \param[in] auxNTuple The source specification (name and storage location) of the auxiliary RNTuple.
545 /// \param[in] joinFields The names of the fields used in the join.
546 /// \param[in] model The model that specifies which fields should be read by the processor. The pointer returned by
547 /// RNTupleModel::MakeField can be used to access a field's value during the processor iteration. When no model is
548 /// specified, it is created from the RNTuple's descriptor.
549 void AddAuxiliary(const RNTupleOpenSpec &auxNTuple, const std::vector<std::string> &joinFields,
550 std::unique_ptr<RNTupleModel> model = nullptr);
551
552 /////////////////////////////////////////////////////////////////////////////
553 /// \brief Connect all fields, once the primary and all auxiliary RNTuples have been added.
554 void ConnectFields();
555
556 /////////////////////////////////////////////////////////////////////////////
557 /// \brief Populate fJoinFieldTokens with tokens for join fields belonging to the main RNTuple in the join model.
558 ///
559 /// \param[in] joinFields The names of the fields used in the join.
560 void SetJoinFieldTokens(const std::vector<std::string> &joinFields)
561 {
562 fJoinFieldTokens.reserve(joinFields.size());
563 for (const auto &fieldName : joinFields) {
564 fJoinFieldTokens.emplace_back(fEntry->GetToken(fieldName));
565 }
566 }
567
568public:
574 {
575 for (auto &[_, fieldContext] : fFieldContexts) {
576 fieldContext.ResetConcreteField();
577 }
578 }
579};
580
581} // namespace Experimental
582} // namespace ROOT
583
584#endif // ROOT7_RNTupleProcessor
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define _(A, B)
Definition cfortran.h:108
Abstract interface to read data from an ntuple.
The field token identifies a (sub)field in this entry.
Definition REntry.hxx:63
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Definition REntry.hxx:51
A field translates read and write calls from/to underlying columns to/from tree values.
Processor specialization for vertically combined (chained) RNTupleProcessors.
ROOT::NTupleSize_t GetNEntries() final
Get the total number of entries in this processor.
std::vector< ROOT::NTupleSize_t > fInnerNEntries
ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber) final
Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in th...
std::vector< std::unique_ptr< RNTupleProcessor > > fInnerProcessors
Processor specialization for horizontally combined (joined) RNTuples.
RNTupleJoinProcessor(const RNTupleJoinProcessor &)=delete
RNTupleJoinProcessor(RNTupleJoinProcessor &&)=delete
void SetJoinFieldTokens(const std::vector< std::string > &joinFields)
Populate fJoinFieldTokens with tokens for join fields belonging to the main RNTuple in the join model...
std::vector< std::unique_ptr< Internal::RPageSource > > fAuxiliaryPageSources
RNTupleJoinProcessor operator=(const RNTupleJoinProcessor &)=delete
ROOT::NTupleSize_t GetNEntries() final
Get the total number of entries in this processor.
RNTupleJoinProcessor operator=(RNTupleJoinProcessor &&)=delete
std::vector< REntry::RFieldToken > fJoinFieldTokens
Tokens representing the join fields present in the main RNTuple.
std::vector< std::unique_ptr< Internal::RNTupleJoinTable > > fJoinTables
The RNTupleModel encapulates the schema of an ntuple.
Manager for a field as part of the RNTupleProcessor.
RFieldContext(std::unique_ptr< RFieldBase > protoField, REntry::RFieldToken token, std::size_t ntupleIdx=0)
void ResetConcreteField()
Concrete pages need to be reset explicitly before the page source they belong to is destroyed.
Iterator over the entries of an RNTuple, or vertical concatenation thereof.
friend bool operator==(const iterator &lh, const iterator &rh)
friend bool operator!=(const iterator &lh, const iterator &rh)
RIterator(RNTupleProcessor &processor, ROOT::NTupleSize_t entryNumber)
Interface for iterating over entries of RNTuples and vertically concatenated RNTuples (chains).
const std::string & GetProcessorName() const
Get the name of the processor.
virtual ROOT::NTupleSize_t GetNEntries()=0
Get the total number of entries in this processor.
const RNTupleModel & GetModel() const
Get the model used by the processor.
const REntry & GetEntry() const
Get a reference to the entry used by the processor.
ROOT::NTupleSize_t fNEntries
Total number of entries.
friend struct ROOT::Experimental::Internal::RNTupleProcessorEntryLoader
static std::unique_ptr< RNTupleProcessor > Create(const RNTupleOpenSpec &ntuple, std::unique_ptr< RNTupleModel > model=nullptr)
Create an RNTupleProcessor for a single RNTuple.
RNTupleProcessor(RNTupleProcessor &&)=delete
virtual void SetEntryPointers(const REntry &entry)=0
Point the entry's field values of the processor to the pointers from the provided entry.
static std::unique_ptr< RNTupleProcessor > CreateChain(const std::vector< RNTupleOpenSpec > &ntuples, std::unique_ptr< RNTupleModel > model=nullptr)
Create an RNTupleProcessor for a chain (i.e., a vertical combination) of RNTuples.
virtual ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber)=0
Load the entry identified by the provided entry number.
std::unordered_map< std::string, RFieldContext > fFieldContexts
Maps the (qualified) field name to its corresponding field context.
ROOT::NTupleSize_t GetCurrentEntryNumber() const
Get the entry number that is currently being processed.
RNTupleProcessor(std::string_view processorName, std::unique_ptr< RNTupleModel > model)
Create a new base RNTupleProcessor.
std::unique_ptr< RNTupleModel > fModel
std::size_t GetCurrentProcessorNumber() const
Get the number of the inner processor currently being read.
ROOT::NTupleSize_t GetNEntriesProcessed() const
Get the total number of entries processed so far.
RNTupleProcessor(const RNTupleProcessor &)=delete
RNTupleProcessor & operator=(RNTupleProcessor &&)=delete
void ConnectField(RFieldContext &fieldContext, Internal::RPageSource &pageSource, REntry &entry)
Create and connect a concrete field to the current page source, based on its proto field.
std::unique_ptr< Internal::RPageSource > fPageSource
static std::unique_ptr< RNTupleProcessor > CreateJoin(const RNTupleOpenSpec &primaryNTuple, const std::vector< RNTupleOpenSpec > &auxNTuples, const std::vector< std::string > &joinFields, std::vector< std::unique_ptr< RNTupleModel > > models={})
Create an RNTupleProcessor for a join (i.e., a horizontal combination) of RNTuples.
std::vector< RNTupleOpenSpec > fNTuples
RNTupleProcessor & operator=(const RNTupleProcessor &)=delete
Processor specialization for processing a single RNTuple.
void Connect()
Connect the page source of the underlying RNTuple.
ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber) final
Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in th...
ROOT::NTupleSize_t GetNEntries() final
Get the total number of entries in this processor.
void SetEntryPointers(const REntry &entry) final
const Int_t n
Definition legend1.C:16
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
constexpr NTupleSize_t kInvalidNTupleIndex
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Used to specify the underlying RNTuples in RNTupleProcessor.
RNTupleOpenSpec(std::string_view n, std::string_view s)