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
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 ROOT_RNTupleProcessor
17#define ROOT_RNTupleProcessor
18
19#include <ROOT/REntry.hxx>
20#include <ROOT/RError.hxx>
21#include <ROOT/RFieldToken.hxx>
24#include <ROOT/RNTupleModel.hxx>
25#include <ROOT/RNTupleTypes.hxx>
26#include <ROOT/RPageStorage.hxx>
27
28#include <memory>
29#include <string>
30#include <string_view>
31#include <vector>
32
33namespace ROOT {
34namespace Experimental {
35
36namespace Internal {
37struct RNTupleProcessorEntryLoader;
38} // namespace Internal
39
40// clang-format off
41/**
42\class ROOT::Experimental::RNTupleOpenSpec
43\ingroup NTuple
44\brief Specification of the name and location of an RNTuple, used for creating a new RNTupleProcessor.
45
46An RNTupleOpenSpec can be created by providing either a string with a path to the ROOT file or a pointer to the
47TDirectory (or any of its subclasses) that contains the RNTuple.
48
49Note that the RNTupleOpenSpec is *write-only*, to prevent usability issues with Python.
50*/
51// clang-format on
53 friend class RNTupleProcessor;
56
57private:
58 std::string fNTupleName;
59 std::variant<std::string, TDirectory *> fStorage;
60
61public:
62 RNTupleOpenSpec(std::string_view n, TDirectory *s) : fNTupleName(n), fStorage(s) {}
63 RNTupleOpenSpec(std::string_view n, const std::string &s) : fNTupleName(n), fStorage(s) {}
64
65 std::unique_ptr<ROOT::Internal::RPageSource> CreatePageSource() const;
66};
67
68// clang-format off
69/**
70\class ROOT::Experimental::RNTupleProcessor
71\ingroup NTuple
72\brief Interface for iterating over entries of RNTuples and vertically concatenated RNTuples (chains).
73
74Example usage (see ntpl012_processor.C for a full example):
75
76~~~{.cpp}
77#include <ROOT/RNTupleProcessor.hxx>
78using ROOT::Experimental::RNTupleProcessor;
79using ROOT::Experimental::RNTupleOpenSpec;
80
81std::vector<RNTupleOpenSpec> ntuples = {{"ntuple1", "ntuple1.root"}, {"ntuple2", "ntuple2.root"}};
82auto processor = RNTupleProcessor::CreateChain(ntuples);
83
84for (const auto &entry : processor) {
85 std::cout << "pt = " << *entry.GetPtr<float>("pt") << std::endl;
86}
87~~~
88
89An RNTupleProcessor is created by providing one or more RNTupleOpenSpecs, each of which contains the name and storage
90location of a single RNTuple. The RNTuples are processed in the order in which they were provided.
91
92The RNTupleProcessor constructor also (optionally) accepts an RNTupleModel, which determines which fields should be
93read. If no model is provided, a default model based on the descriptor of the first specified RNTuple will be used.
94If a field that was present in the first RNTuple is not found in a subsequent one, an error will be thrown.
95
96The RNTupleProcessor provides an iterator which gives access to the REntry containing the field data for the current
97entry. Additional bookkeeping information can be obtained through the RNTupleProcessor itself.
98*/
99// clang-format on
105
106protected:
107 std::string fProcessorName;
108 std::unique_ptr<ROOT::REntry> fEntry;
109 std::unique_ptr<ROOT::RNTupleModel> fModel;
110
111 /// Total number of entries. Only to be used internally by the processor, not meant to be exposed in the public
112 /// interface.
114
115 ROOT::NTupleSize_t fNEntriesProcessed = 0; //< Total number of entries processed so far
116 ROOT::NTupleSize_t fCurrentEntryNumber = 0; //< Current processor entry number
117 std::size_t fCurrentProcessorNumber = 0; //< Number of the currently open inner processor
118
119 /////////////////////////////////////////////////////////////////////////////
120 /// \brief Load the entry identified by the provided entry number.
121 ///
122 /// \param[in] entryNumber Entry number to load
123 ///
124 /// \return `entryNumber` if the entry was successfully loaded, `kInvalidNTupleIndex` otherwise.
126
127 /////////////////////////////////////////////////////////////////////////////
128 /// \brief Point the entry's field values of the processor to the pointers from the provided entry.
129 ///
130 /// \param[in] entry The entry whose field values to use.
131 virtual void SetEntryPointers(const ROOT::REntry &entry, std::string_view fieldNamePrefix = "") = 0;
132
133 /////////////////////////////////////////////////////////////////////////////
134 /// \brief Get the total number of entries in this processor
136
137 /////////////////////////////////////////////////////////////////////////////
138 /// \brief Add the entry mappings for this processor to the provided join table.
139 ///
140 /// \param[in] joinTable the join table to map the entries to.
141 /// \param[in] entryOffset In case the entry mapping is added from a chain, the offset of the entry indexes to use
142 /// with respect to the processor's position in the chain.
144
145 /////////////////////////////////////////////////////////////////////////////
146 /// \brief Processor-specific implementation for printing its structure, called by PrintStructure().
147 ///
148 /// \param[in,out] output Output stream to print to.
149 virtual void PrintStructureImpl(std::ostream &output) const = 0;
150
151 /////////////////////////////////////////////////////////////////////////////
152 /// \brief Create a new base RNTupleProcessor.
153 ///
154 /// \param[in] processorName Name of the processor. By default, this is the name of the underlying RNTuple for
155 /// RNTupleSingleProcessor, the name of the first processor for RNTupleChainProcessor, or the name of the primary
156 /// RNTuple for RNTupleJoinProcessor.
157 /// \param[in] model The RNTupleModel representing the entries returned by the processor.
158 ///
159 /// \note Before processing, a model *must* exist. However, this is handled downstream by the RNTupleProcessor's
160 /// factory functions (CreateSingle, CreateChain and CreateJoin) and constructors.
161 RNTupleProcessor(std::string_view processorName, std::unique_ptr<ROOT::RNTupleModel> model)
162 : fProcessorName(processorName), fModel(std::move(model))
163 {
164 }
165
166public:
171 virtual ~RNTupleProcessor() = default;
172
173 /////////////////////////////////////////////////////////////////////////////
174 /// \brief Get the total number of entries processed so far.
176
177 /////////////////////////////////////////////////////////////////////////////
178 /// \brief Get the entry number that is currently being processed.
180
181 /////////////////////////////////////////////////////////////////////////////
182 /// \brief Get the number of the inner processor currently being read.
183 ///
184 /// This method is only relevant for the RNTupleChainProcessor. For the other processors, 0 is always returned.
186
187 /////////////////////////////////////////////////////////////////////////////
188 /// \brief Get the name of the processor.
189 ///
190 /// Unless this name was explicitly specified during creation of the processor, this is the name of the underlying
191 /// RNTuple for RNTupleSingleProcessor, the name of the first processor for RNTupleChainProcessor, or the name of the
192 /// primary processor for RNTupleJoinProcessor.
193 const std::string &GetProcessorName() const { return fProcessorName; }
194
195 /////////////////////////////////////////////////////////////////////////////
196 /// \brief Get the model used by the processor.
197 const ROOT::RNTupleModel &GetModel() const { return *fModel; }
198
199 /////////////////////////////////////////////////////////////////////////////
200 /// \brief Get a reference to the entry used by the processor.
201 ///
202 /// \return A reference to the entry used by the processor.
203 const ROOT::REntry &GetEntry() const { return *fEntry; }
204
205 /////////////////////////////////////////////////////////////////////////////
206 /// \brief Print a graphical representation of the processor composition.
207 ///
208 /// \param[in,out] output Stream to print to (default is stdout).
209 ///
210 /// ### Example:
211 /// The structure of a processor representing a join between a single primary RNTuple and a chain of two auxiliary
212 /// RNTuples will be printed as follows:
213 /// ~~~
214 /// +-----------------------------+ +-----------------------------+
215 /// | ntuple | | ntuple_aux |
216 /// | ntuple.root | | ntuple_aux1.root |
217 /// +-----------------------------+ +-----------------------------+
218 /// +-----------------------------+
219 /// | ntuple_aux |
220 /// | ntuple_aux2.root |
221 /// +-----------------------------+
222 /// ~~~
223 void PrintStructure(std::ostream &output = std::cout) { PrintStructureImpl(output); }
224
225 // clang-format off
226 /**
227 \class ROOT::Experimental::RNTupleProcessor::RIterator
228 \ingroup NTuple
229 \brief Iterator over the entries of an RNTuple, or vertical concatenation thereof.
230 */
231 // clang-format on
232 class RIterator {
233 private:
236
237 public:
238 using iterator_category = std::forward_iterator_tag;
241 using difference_type = std::ptrdiff_t;
243 using reference = const ROOT::REntry &;
244
247 {
248 // This constructor is called with kInvalidNTupleIndex for RNTupleProcessor::end(). In that case, we already
249 // know there is nothing to load.
252 }
253 }
254
260
262 {
263 auto obj = *this;
264 ++(*this);
265 return obj;
266 }
267
269
270 friend bool operator!=(const iterator &lh, const iterator &rh)
271 {
272 return lh.fCurrentEntryNumber != rh.fCurrentEntryNumber;
273 }
274 friend bool operator==(const iterator &lh, const iterator &rh)
275 {
276 return lh.fCurrentEntryNumber == rh.fCurrentEntryNumber;
277 }
278 };
279
280 RIterator begin() { return RIterator(*this, 0); }
282
283 /////////////////////////////////////////////////////////////////////////////
284 /// \brief Create an RNTupleProcessor for a single RNTuple.
285 ///
286 /// \param[in] ntuple The name and storage location of the RNTuple to process.
287 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
288 /// one will be created based on the descriptor of the first ntuple specified.
289 /// \param[in] processorName The name to give to the processor. If empty, the name of the input RNTuple is used.
290 ///
291 /// \return A pointer to the newly created RNTupleProcessor.
292 static std::unique_ptr<RNTupleProcessor> Create(RNTupleOpenSpec ntuple,
293 std::unique_ptr<ROOT::RNTupleModel> model = nullptr,
294 std::string_view processorName = "");
295
296 /////////////////////////////////////////////////////////////////////////////
297 /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of RNTuples.
298 ///
299 /// \param[in] ntuples A list specifying the names and locations of the RNTuples to process.
300 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
301 /// one will be created based on the descriptor of the first RNTuple specified.
302 /// \param[in] processorName The name to give to the processor. If empty, the name of the first RNTuple is used.
303 ///
304 /// \return A pointer to the newly created RNTupleProcessor.
305 static std::unique_ptr<RNTupleProcessor> CreateChain(std::vector<RNTupleOpenSpec> ntuples,
306 std::unique_ptr<ROOT::RNTupleModel> model = nullptr,
307 std::string_view processorName = "");
308
309 /////////////////////////////////////////////////////////////////////////////
310 /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of other RNTupleProcessors.
311 ///
312 /// \param[in] innerProcessors A list with the processors to chain.
313 /// \param[in] model An RNTupleModel specifying which fields can be read by the processor. If no model is provided,
314 /// one will be created based on the model used by the first inner processor.
315 /// \param[in] processorName The name to give to the processor. If empty, the name of the first inner processor is
316 /// used.
317 ///
318 /// \return A pointer to the newly created RNTupleProcessor.
319 static std::unique_ptr<RNTupleProcessor> CreateChain(std::vector<std::unique_ptr<RNTupleProcessor>> innerProcessors,
320 std::unique_ptr<ROOT::RNTupleModel> model = nullptr,
321 std::string_view processorName = "");
322
323 /////////////////////////////////////////////////////////////////////////////
324 /// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples.
325 ///
326 /// \param[in] primaryNTuple The name and location of the primary RNTuple. Its entries are processed in sequential
327 /// order.
328 /// \param[in] auxNTuple The name and location of the RNTuple to join the primary RNTuple with. The order in which
329 /// its entries are processed is determined by the primary RNTuple and doesn't necessarily have to be sequential.
330 /// \param[in] joinFields The names of the fields on which to join, in case the specified RNTuples are unaligned.
331 /// The join is made based on the combined join field values, and therefore each field has to be present in each
332 /// specified RNTuple. If an empty list is provided, it is assumed that the specified ntuple are fully aligned.
333 /// \param[in] primaryModel An RNTupleModel specifying which fields from the primary RNTuple can be read by the
334 /// processor. If no model is provided, one will be created based on the descriptor of the primary RNTuple.
335 /// \param[in] auxModel An RNTupleModel specifying which fields from the auxiliary RNTuple can be read by the
336 /// processor. If no model is provided, one will be created based on the descriptor of the auxiliary RNTuple.
337 /// \param[in] processorName The name to give to the processor. If empty, the name of the primary RNTuple is used.
338 ///
339 /// \return A pointer to the newly created RNTupleProcessor.
340 static std::unique_ptr<RNTupleProcessor>
342 std::unique_ptr<ROOT::RNTupleModel> primaryModel = nullptr,
343 std::unique_ptr<ROOT::RNTupleModel> auxModel = nullptr, std::string_view processorName = "");
344
345 /////////////////////////////////////////////////////////////////////////////
346 /// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples.
347 ///
348 /// \param[in] primaryProcessor The primary processor. Its entries are processed in sequential order.
349 /// \param[in] auxProcessor The processor to join the primary processor with. The order in which its entries are
350 /// processed is determined by the primary processor and doesn't necessarily have to be sequential.
351 /// \param[in] joinFields The names of the fields on which to join, in case the specified processors are unaligned.
352 /// The join is made based on the combined join field values, and therefore each field has to be present in each
353 /// specified processors. If an empty list is provided, it is assumed that the specified processors are fully
354 /// aligned.
355 /// \param[in] primaryModel An RNTupleModel specifying which fields from the primary processor can be read by the
356 /// processor. If no model is provided, one will be created based on the descriptor of the primary processor.
357 /// \param[in] auxModel An RNTupleModel specifying which fields from the auxiliary processor can be read by the
358 /// processor. If no model is provided, one will be created based on the descriptor of the auxiliary processor.
359 /// \param[in] processorName The name to give to the processor. If empty, the name of the primary processor is used.
360 ///
361 /// \return A pointer to the newly created RNTupleProcessor.
362 static std::unique_ptr<RNTupleProcessor>
363 CreateJoin(std::unique_ptr<RNTupleProcessor> primaryProcessor, std::unique_ptr<RNTupleProcessor> auxProcessor,
364 const std::vector<std::string> &joinFields, std::unique_ptr<ROOT::RNTupleModel> primaryModel = nullptr,
365 std::unique_ptr<ROOT::RNTupleModel> auxModel = nullptr, std::string_view processorName = "");
366};
367
368// clang-format off
369/**
370\class ROOT::Experimental::RNTupleSingleProcessor
371\ingroup NTuple
372\brief Processor specialization for processing a single RNTuple.
373*/
374// clang-format on
376 friend class RNTupleProcessor;
377
378private:
380 std::unique_ptr<ROOT::Internal::RPageSource> fPageSource;
381
382 /////////////////////////////////////////////////////////////////////////////
383 /// \brief Connect the page source of the underlying RNTuple.
384 void Connect();
385
386 /////////////////////////////////////////////////////////////////////////////
387 /// \brief Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in this
388 /// processor).
389 ///
390 /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntry
392
393 /////////////////////////////////////////////////////////////////////////////
394 /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryPointers.
395 void SetEntryPointers(const ROOT::REntry &entry, std::string_view fieldNamePrefix) final;
396
397 /////////////////////////////////////////////////////////////////////////////
398 /// \brief Get the total number of entries in this processor.
400 {
401 Connect();
402 return fNEntries;
403 }
404
405 /////////////////////////////////////////////////////////////////////////////
406 /// \brief Add the entry mappings for this processor to the provided join table.
407 ///
408 /// \sa ROOT::Experimental::RNTupleProcessor::AddEntriesToJoinTable
410
411 /////////////////////////////////////////////////////////////////////////////
412 /// \brief Processor-specific implementation for printing its structure, called by PrintStructure().
413 ///
414 /// \sa ROOT::Experimental::RNTupleProcessor::PrintStructureImpl
415 void PrintStructureImpl(std::ostream &output) const final;
416
417 /////////////////////////////////////////////////////////////////////////////
418 /// \brief Construct a new RNTupleProcessor for processing a single RNTuple.
419 ///
420 /// \param[in] ntuple The source specification (name and storage location) for the RNTuple to process.
421 /// \param[in] model The model that specifies which fields should be read by the processor.
422 /// \param[in] processorName Name of the processor. Unless specified otherwise in RNTupleProcessor::Create, this is
423 /// the name of the underlying RNTuple.
425 std::string_view processorName);
426
427public:
432 ~RNTupleSingleProcessor() override { fModel.release(); };
433};
434
435// clang-format off
436/**
437\class ROOT::Experimental::RNTupleChainProcessor
438\ingroup NTuple
439\brief Processor specialization for vertically combined (*chained*) RNTupleProcessors.
440*/
441// clang-format on
443 friend class RNTupleProcessor;
444
445private:
446 std::vector<std::unique_ptr<RNTupleProcessor>> fInnerProcessors;
447 std::vector<ROOT::NTupleSize_t> fInnerNEntries;
448
449 /////////////////////////////////////////////////////////////////////////////
450 /// \brief Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in this
451 /// processor).
452 ///
453 /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntry
455
456 /////////////////////////////////////////////////////////////////////////////
457 /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryPointers.
458 void SetEntryPointers(const ROOT::REntry &, std::string_view fieldNamePrefix) final;
459
460 /////////////////////////////////////////////////////////////////////////////
461 /// \brief Get the total number of entries in this processor.
462 ///
463 /// \note This requires opening all underlying RNTuples being processed in the chain, and could become costly!
465
466 /////////////////////////////////////////////////////////////////////////////
467 /// \brief Add the entry mappings for this processor to the provided join table.
468 ///
469 /// \sa ROOT::Experimental::RNTupleProcessor::AddEntriesToJoinTable
470 void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final;
471
472 /////////////////////////////////////////////////////////////////////////////
473 /// \brief Processor-specific implementation for printing its structure, called by PrintStructure().
474 ///
475 /// \sa ROOT::Experimental::RNTupleProcessor::PrintStructureImpl
476 void PrintStructureImpl(std::ostream &output) const final;
477
478 /////////////////////////////////////////////////////////////////////////////
479 /// \brief Construct a new RNTupleChainProcessor.
480 ///
481 /// \param[in] ntuples The source specification (name and storage location) for each RNTuple to process.
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 /// \param[in] processorName Name of the processor. Unless specified otherwise in RNTupleProcessor::CreateChain, this
486 /// is the name of the first inner processor.
487 ///
488 /// RNTuples are processed in the order in which they are specified.
489 RNTupleChainProcessor(std::vector<std::unique_ptr<RNTupleProcessor>> processors,
490 std::unique_ptr<ROOT::RNTupleModel> model, std::string_view processorName);
491
492public:
498};
499
500// clang-format off
501/**
502\class ROOT::Experimental::RNTupleJoinProcessor
503\ingroup NTuple
504\brief Processor specialization for horizontally combined (*joined*) RNTupleProcessors.
505*/
506// clang-format on
508 friend class RNTupleProcessor;
509
510private:
511 std::unique_ptr<RNTupleProcessor> fPrimaryProcessor;
512 std::unique_ptr<RNTupleProcessor> fAuxiliaryProcessor;
513
514 /// Tokens representing the join fields present in the primary processor.
515 std::vector<ROOT::RFieldToken> fJoinFieldTokens;
516 std::unique_ptr<Internal::RNTupleJoinTable> fJoinTable;
517 bool fJoinTableIsBuilt = false;
518
519 /////////////////////////////////////////////////////////////////////////////
520 /// \brief Load the entry identified by the provided entry number of the primary processor.
521 ///
522 /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntry
524
525 /////////////////////////////////////////////////////////////////////////////
526 /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryPointers.
527 void SetEntryPointers(const ROOT::REntry &, std::string_view fieldNamePrefix) final;
528
529 /////////////////////////////////////////////////////////////////////////////
530 /// \brief Get the total number of entries in this processor.
532
533 /////////////////////////////////////////////////////////////////////////////
534 /// \brief Add the entry mappings for this processor to the provided join table.
535 ///
536 /// \sa ROOT::Experimental::RNTupleProcessor::AddEntriesToJoinTable
537 void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final;
538
539 /////////////////////////////////////////////////////////////////////////////
540 /// \brief Set fModel by combining the primary and auxiliary models.
541 ///
542 /// \param[in] primaryModel The model of the primary processor.
543 /// \param[in] auxModel Model of the auxiliary processors.
544 ///
545 /// To prevent field name clashes when one or more models have fields with duplicate names, fields from each
546 /// auxiliary model are stored as a anonymous record, and subsequently registered as subfields in the join model.
547 /// This way, they can be accessed from the processor's entry as `auxNTupleName.fieldName`.
548 void SetModel(std::unique_ptr<ROOT::RNTupleModel> primaryModel, std::unique_ptr<ROOT::RNTupleModel> auxModel);
549
550 /////////////////////////////////////////////////////////////////////////////
551 /// \brief Processor-specific implementation for printing its structure, called by PrintStructure().
552 ///
553 /// \sa ROOT::Experimental::RNTupleProcessor::PrintStructureImpl
554 void PrintStructureImpl(std::ostream &output) const final;
555
556 /////////////////////////////////////////////////////////////////////////////
557 /// \brief Construct a new RNTupleJoinProcessor.
558 /// \param[in] primaryProcessor The primary processor. Its entries are processed in sequential order.
559 /// \param[in] auxProcessor The processor to join the primary processor with. The order in which its entries are
560 /// processed is determined by the primary processor and doesn't necessarily have to be sequential.
561 /// \param[in] joinFields The names of the fields on which to join, in case the specified processors are unaligned.
562 /// The join is made based on the combined join field values, and therefore each field has to be present in each
563 /// specified processor. If an empty list is provided, it is assumed that the processors are fully aligned.
564 /// \param[in] primaryModel An RNTupleModel specifying which fields from the primary processor can be read by the
565 /// processor. If no model is provided, one will be created based on the descriptor of the primary processor.
566 /// \param[in] auxModel An RNTupleModel specifying which fields from the auxiliary processor can be read by the
567 /// processor. If no model is provided, one will be created based on the descriptor of the auxiliary processor.
568 /// \param[in] processorName Name of the processor. Unless specified otherwise in RNTupleProcessor::CreateJoin, this
569 /// is the name of the primary processor.
571 std::unique_ptr<RNTupleProcessor> auxProcessor, const std::vector<std::string> &joinFields,
572 std::unique_ptr<ROOT::RNTupleModel> primaryModel, std::unique_ptr<ROOT::RNTupleModel> auxModel,
573 std::string_view processorName);
574
575public:
581};
582
583} // namespace Experimental
584} // namespace ROOT
585
586#endif // ROOT_RNTupleProcessor
Builds a join table on one or several fields of an RNTuple so it can be joined onto other RNTuples.
Processor specialization for vertically combined (chained) RNTupleProcessors.
void SetEntryPointers(const ROOT::REntry &, std::string_view fieldNamePrefix) final
void PrintStructureImpl(std::ostream &output) const final
Processor-specific implementation for printing its structure, called by PrintStructure().
void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset=0) final
Add the entry mappings for this processor to the provided join table.
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) RNTupleProcessors.
std::unique_ptr< RNTupleProcessor > fPrimaryProcessor
std::unique_ptr< Internal::RNTupleJoinTable > fJoinTable
std::unique_ptr< RNTupleProcessor > fAuxiliaryProcessor
std::vector< ROOT::RFieldToken > fJoinFieldTokens
Tokens representing the join fields present in the primary processor.
Specification of the name and location of an RNTuple, used for creating a new RNTupleProcessor.
RNTupleOpenSpec(std::string_view n, const std::string &s)
std::variant< std::string, TDirectory * > fStorage
RNTupleOpenSpec(std::string_view n, TDirectory *s)
std::unique_ptr< ROOT::Internal::RPageSource > CreatePageSource() const
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.
static std::unique_ptr< RNTupleProcessor > CreateJoin(RNTupleOpenSpec primaryNTuple, RNTupleOpenSpec auxNTuple, const std::vector< std::string > &joinFields, std::unique_ptr< ROOT::RNTupleModel > primaryModel=nullptr, std::unique_ptr< ROOT::RNTupleModel > auxModel=nullptr, std::string_view processorName="")
Create an RNTupleProcessor for a join (i.e., a horizontal combination) of RNTuples.
std::unique_ptr< ROOT::REntry > fEntry
virtual ROOT::NTupleSize_t GetNEntries()=0
Get the total number of entries in this processor.
std::unique_ptr< ROOT::RNTupleModel > fModel
ROOT::NTupleSize_t fNEntries
Total number of entries.
friend struct ROOT::Experimental::Internal::RNTupleProcessorEntryLoader
RNTupleProcessor(RNTupleProcessor &&)=delete
virtual void PrintStructureImpl(std::ostream &output) const =0
Processor-specific implementation for printing its structure, called by PrintStructure().
virtual ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber)=0
Load the entry identified by the provided entry number.
const ROOT::RNTupleModel & GetModel() const
Get the model used by the processor.
ROOT::NTupleSize_t GetCurrentEntryNumber() const
Get the entry number that is currently being processed.
static std::unique_ptr< RNTupleProcessor > CreateChain(std::vector< RNTupleOpenSpec > ntuples, std::unique_ptr< ROOT::RNTupleModel > model=nullptr, std::string_view processorName="")
Create an RNTupleProcessor for a chain (i.e., a vertical combination) of RNTuples.
virtual void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset=0)=0
Add the entry mappings for this processor to the provided join table.
std::size_t GetCurrentProcessorNumber() const
Get the number of the inner processor currently being read.
virtual void SetEntryPointers(const ROOT::REntry &entry, std::string_view fieldNamePrefix="")=0
Point the entry's field values of the processor to the pointers from the provided entry.
RNTupleProcessor(std::string_view processorName, std::unique_ptr< ROOT::RNTupleModel > model)
Create a new base RNTupleProcessor.
void PrintStructure(std::ostream &output=std::cout)
Print a graphical representation of the processor composition.
ROOT::NTupleSize_t GetNEntriesProcessed() const
Get the total number of entries processed so far.
RNTupleProcessor(const RNTupleProcessor &)=delete
RNTupleProcessor & operator=(RNTupleProcessor &&)=delete
static std::unique_ptr< RNTupleProcessor > Create(RNTupleOpenSpec ntuple, std::unique_ptr< ROOT::RNTupleModel > model=nullptr, std::string_view processorName="")
Create an RNTupleProcessor for a single RNTuple.
const ROOT::REntry & GetEntry() const
Get a reference to the entry used by the processor.
RNTupleProcessor & operator=(const RNTupleProcessor &)=delete
Processor specialization for processing a single RNTuple.
void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset=0) final
Add the entry mappings for this processor to the provided join table.
void SetEntryPointers(const ROOT::REntry &entry, std::string_view fieldNamePrefix) final
void PrintStructureImpl(std::ostream &output) const final
Processor-specific implementation for printing its structure, called by PrintStructure().
std::unique_ptr< ROOT::Internal::RPageSource > fPageSource
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.
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:54
The RNTupleModel encapulates the schema of an RNTuple.
Describe directory structure in memory.
Definition TDirectory.h:45
const Int_t n
Definition legend1.C:16
Namespace for new ROOT classes and functions.
constexpr NTupleSize_t kInvalidNTupleIndex
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
static void output()