Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleProcessorDS.hxx
Go to the documentation of this file.
1/// \file RNTupleProcessorDS.hxx
2/// \author Florine de Geus <florine.de.geus@cern.ch>
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \author Enrico Guiraud <enrico.guiraud@cern.ch>
5/// \date 2026-06-18
6/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
7/// is welcome!
8
9#ifndef ROOT_RNTupleProcessorDS
10#define ROOT_RNTupleProcessorDS
11
12#include <ROOT/RDataSource.hxx>
14#include <ROOT/RNTupleUtils.hxx>
16
17#include <memory>
18#include <string>
19#include <string_view>
20#include <vector>
21#include <unordered_map>
22
23namespace ROOT {
24class RDataFrame;
25} // namespace ROOT
26
27// clang-format off
28/**
29* \class ROOT::Experimental::RDF::RNTupleProcessorDS
30* \ingroup dataframe
31* \brief The RDataSource implementation for the RNTupleProcessor. It lets RDataFrame read combined (chained and joined) RNTuple data.
32*
33* An RDataFrame that reads combined (chained and joined) RNTuple data, through the RNTupleProcessor.
34* It can be constructed using FromRNTupleProcessor().
35*
36* For each column containing an array or a collection, a corresponding column `#colname` is available to access
37* `colname.size()` without reading and deserializing the collection values.
38*
39**/
40// clang-format on
43 // TODO: turn into vector of processors and entry mappings for MT
44 std::unique_ptr<RNTupleProcessor> fProcessor;
46
47 std::vector<std::string> fColumnNames;
48 std::vector<std::string> fColumnTypes;
49
50 std::vector<ROOT::Experimental::Internal::RDF::RNTupleProcessorColumnReader *> fColumnReaders;
51
52 std::vector<std::pair<ULong64_t, ULong64_t>> fCurrentRanges;
53
54 /////////////////////////////////////////////////////////////////////////////
55 /// \brief Holds useful information about fields added to the RNTupleProcessorDS
56 struct RFieldInfo {
58 std::string fFieldName;
59 std::string fTypeName;
60 std::size_t fNRepetitions;
62 // Enable `std::vector::emplace_back` for this type
63 RFieldInfo(ROOT::DescriptorId_t onDiskId, std::string_view fieldName, std::string_view typeName,
64 std::size_t nRepetitions, ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t entryFieldIdx)
65 : fOnDiskId(onDiskId),
66 fFieldName(fieldName),
67 fTypeName(typeName),
68 fNRepetitions(nRepetitions),
69 fEntryFieldIdx(entryFieldIdx)
70 {
71 }
72 };
73
74 /////////////////////////////////////////////////////////////////////////////
75 /// \brief Provides the RDF column "colName" given the field.
76 ///
77 /// \param[in] field Field to add.
78 /// \param[in] colName RDF column name corresponding to the field.
79 /// \param[in] procProvenance Processor provenance of the field to add.
80 /// \param[in] fieldInfos Additional information about the field's outer collections.
81 /// \param[in] convertToRVec Whether to add collections (`std::vector` or `std::array`) as ROOT::VecOps::RVec
82 /// (enabled by default).
83 ///
84 /// For records and collections, AddField recurses into the subfields. For instance, if the provided field refers to
85 /// an `std::vector<Jet>`, with
86 /// ~~~{.cpp}
87 /// struct Jet {
88 /// float pt;
89 /// float eta;
90 /// };
91 /// ~~~
92 /// AddField will recurse into `Jet.pt` and `Jet.eta` and provide the two inner fields as `ROOT::VecOps::RVec<float>`
93 /// each.
94 ///
95 /// When `convertToRVec` is true, the field's corresponding column is added as a `ROOT::VecOps::RVec`. Otherwise, the
96 /// collection field's on-disk type is used. Note, however, that inner record members of such collections will still
97 /// be added as `ROOT::VecOps::RVec` (e.g., `std::set<Jet> will be added as a `std::set`, but `Jet.[pt|eta] will be
98 /// added as `ROOT::VecOps::RVec<float>).
99 void AddField(const ROOT::RFieldBase &field, std::string_view colName,
100 ROOT::Internal::RNTupleProcessorProvenance procProvenance, std::deque<RFieldInfo> &fieldInfos,
101 bool convertToRVec = true);
102
103public:
104 RNTupleProcessorDS(std::unique_ptr<ROOT::RNTupleProcessor> processor);
110
111 void SetNSlots(unsigned int nSlots) final;
112 // FIXME(fdegeus) get correct number of files (needs to be added in RNTupleProcessor)
113 std::size_t GetNFiles() const final { return 1; }
114 const std::vector<std::string> &GetColumnNames() const final { return fColumnNames; }
115 bool HasColumn(std::string_view colName) const final;
116 std::string GetTypeName(std::string_view colName) const final;
117 std::vector<std::pair<ULong64_t, ULong64_t>> GetEntryRanges() final;
118 std::string GetLabel() final { return "RNTupleProcessorDS"; }
119
120 void Initialize() final;
121 void InitSlot(unsigned int slot, ULong64_t firstEntry) final;
122 void FinalizeSlot(unsigned int slot) final;
123 void Finalize() final;
124
125 std::unique_ptr<ROOT::Detail::RDF::RColumnReaderBase>
126 GetColumnReaders(unsigned int slot, std::string_view name, const std::type_info &) final;
127
128 ROOT::RDF::RSampleInfo
129 CreateSampleInfo(unsigned int,
130 const std::unordered_map<std::string, ROOT::RDF::Experimental::RSample *> &) const final;
131
132 bool SetEntry(unsigned int, ULong64_t) final;
133
134protected:
135 Record_t GetColumnReadersImpl(std::string_view name, const std::type_info &) final;
136};
137} // namespace ROOT::Experimental::Internal::RDF
138
139namespace ROOT::Experimental::RDF {
140RDataFrame FromRNTupleProcessor(std::unique_ptr<ROOT::RNTupleProcessor> processor);
141} // namespace ROOT::Experimental::RDF
142
143#endif // ROOT_RNTupleProcessorDS
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:85
char name[80]
Definition TGX11.cxx:142
std::string GetTypeName(std::string_view colName) const final
Type of a column as a string, e.g.
void Finalize() final
Convenience method called after concluding an event-loop.
bool HasColumn(std::string_view colName) const final
Checks if the dataset has a certain column.
std::vector< std::pair< ULong64_t, ULong64_t > > GetEntryRanges() final
Return ranges of entries to distribute to tasks.
void FinalizeSlot(unsigned int slot) final
Convenience method called at the end of the data processing associated to a slot.
Record_t GetColumnReadersImpl(std::string_view name, const std::type_info &) final
type-erased vector of pointers to pointers to column values - one per slot
RNTupleProcessorDS(const RNTupleProcessorDS &)=delete
RNTupleProcessorDS(std::unique_ptr< ROOT::RNTupleProcessor > processor)
void Initialize() final
Convenience method called before starting an event-loop.
std::vector< ROOT::Experimental::Internal::RDF::RNTupleProcessorColumnReader * > fColumnReaders
RNTupleProcessorDS & operator=(RNTupleProcessorDS &&)=delete
std::unique_ptr< ROOT::Detail::RDF::RColumnReaderBase > GetColumnReaders(unsigned int slot, std::string_view name, const std::type_info &) final
If the other GetColumnReaders overload returns an empty vector, this overload will be called instead.
std::vector< std::pair< ULong64_t, ULong64_t > > fCurrentRanges
void InitSlot(unsigned int slot, ULong64_t firstEntry) final
Convenience method called at the start of the data processing associated to a slot.
std::string GetLabel() final
Return a string representation of the datasource type.
void AddField(const ROOT::RFieldBase &field, std::string_view colName, ROOT::Internal::RNTupleProcessorProvenance procProvenance, std::deque< RFieldInfo > &fieldInfos, bool convertToRVec=true)
Provides the RDF column "colName" given the field.
bool SetEntry(unsigned int, ULong64_t) final
Advance the "cursors" returned by GetColumnReaders to the selected entry for a particular slot.
RNTupleProcessorDS & operator=(const RNTupleProcessorDS &)=delete
std::size_t GetNFiles() const final
Returns the number of files from which the dataset is constructed.
const std::vector< std::string > & GetColumnNames() const final
Returns a reference to the collection of the dataset's column names.
void SetNSlots(unsigned int nSlots) final
Inform RDataSource of the number of processing slots (i.e.
Pure virtual base class for all column reader types.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
friend ROOT::RDF::RSampleInfo ROOT::Internal::RDF::CreateSampleInfo(const ROOT::RDF::RDataSource &, unsigned int, const std::unordered_map< std::string, ROOT::RDF::Experimental::RSample * > &)
std::vector< void * > Record_t
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
A field translates read and write calls from/to underlying columns to/from tree values.
Maps a processor's global (outer) entry index to its inner ones.
RDataFrame FromRNTupleProcessor(std::unique_ptr< ROOT::RNTupleProcessor > processor)
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Holds useful information about fields added to the RNTupleProcessorDS.
RFieldInfo(ROOT::DescriptorId_t onDiskId, std::string_view fieldName, std::string_view typeName, std::size_t nRepetitions, ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t entryFieldIdx)
ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fEntryFieldIdx