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;
61 // Enable `std::vector::emplace_back` for this type
62 RFieldInfo(ROOT::DescriptorId_t fieldId, std::string_view fieldName, std::string_view typeName,
63 std::size_t nRepetitions)
64 : fFieldId(fieldId), fFieldName(fieldName), fTypeName(typeName), fNRepetitions(nRepetitions)
65 {
66 }
67 };
68
69 /////////////////////////////////////////////////////////////////////////////
70 /// \brief Provides the RDF column "colName" given the field.
71 ///
72 /// \param[in] field Field to add.
73 /// \param[in] colName RDF column name corresponding to the field.
74 /// \param[in] procProvenance Processor provenance of the field to add.
75 /// \param[in] fieldInfos Additional information about the field's outer collections.
76 /// \param[in] convertToRVec Whether to add collections (`std::vector` or `std::array`) as ROOT::VecOps::RVec
77 /// (enabled by default).
78 ///
79 /// For records and collections, AddField recurses into the subfields. For instance, if the provided field refers to
80 /// an `std::vector<Jet>`, with
81 /// ~~~{.cpp}
82 /// struct Jet {
83 /// float pt;
84 /// float eta;
85 /// };
86 /// ~~~
87 /// AddField will recurse into `Jet.pt` and `Jet.eta` and provide the two inner fields as `ROOT::VecOps::RVec<float>`
88 /// each.
89 ///
90 /// When `convertToRVec` is true, the field's corresponding column is added as a `ROOT::VecOps::RVec`. Otherwise, the
91 /// collection field's on-disk type is used. Note, however, that inner record members of such collections will still
92 /// be added as `ROOT::VecOps::RVec` (e.g., `std::set<Jet> will be added as a `std::set`, but `Jet.[pt|eta] will be
93 /// added as `ROOT::VecOps::RVec<float>).
94 void AddField(const ROOT::RFieldBase &field, std::string_view colName,
95 Internal::RNTupleProcessorProvenance procProvenance, std::deque<RFieldInfo> &fieldInfos,
96 bool convertToRVec = true);
97
98public:
99 RNTupleProcessorDS(std::unique_ptr<ROOT::Experimental::RNTupleProcessor> processor);
105
106 void SetNSlots(unsigned int nSlots) final;
107 // FIXME(fdegeus) get correct number of files (needs to be added in RNTupleProcessor)
108 std::size_t GetNFiles() const final { return 1; }
109 const std::vector<std::string> &GetColumnNames() const final { return fColumnNames; }
110 bool HasColumn(std::string_view colName) const final;
111 std::string GetTypeName(std::string_view colName) const final;
112 std::vector<std::pair<ULong64_t, ULong64_t>> GetEntryRanges() final;
113 std::string GetLabel() final { return "RNTupleProcessorDS"; }
114
115 void Initialize() final;
116 void InitSlot(unsigned int slot, ULong64_t firstEntry) final;
117 void FinalizeSlot(unsigned int slot) final;
118 void Finalize() final;
119
120 std::unique_ptr<ROOT::Detail::RDF::RColumnReaderBase>
121 GetColumnReaders(unsigned int slot, std::string_view name, const std::type_info &) final;
122
123 ROOT::RDF::RSampleInfo
124 CreateSampleInfo(unsigned int,
125 const std::unordered_map<std::string, ROOT::RDF::Experimental::RSample *> &) const final;
126
127 bool SetEntry(unsigned int, ULong64_t) final;
128
129protected:
130 Record_t GetColumnReadersImpl(std::string_view name, const std::type_info &) final;
131};
132} // namespace ROOT::Experimental::Internal::RDF
133
134namespace ROOT::Experimental::RDF {
135RDataFrame FromRNTupleProcessor(std::unique_ptr<ROOT::Experimental::RNTupleProcessor> processor);
136} // namespace ROOT::Experimental::RDF
137
138#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
RNTupleProcessorDS(std::unique_ptr< ROOT::Experimental::RNTupleProcessor > processor)
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
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.
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
void AddField(const ROOT::RFieldBase &field, std::string_view colName, Internal::RNTupleProcessorProvenance procProvenance, std::deque< RFieldInfo > &fieldInfos, bool convertToRVec=true)
Provides the RDF column "colName" given the field.
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.
Maps a processor's global (outer) entry index to its inner ones.
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.
RDataFrame FromRNTupleProcessor(std::unique_ptr< ROOT::Experimental::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 fieldId, std::string_view fieldName, std::string_view typeName, std::size_t nRepetitions)