Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleReader.cxx
Go to the documentation of this file.
1/// \file RNTupleReader.cxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2024-02-20
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
17
18#include <ROOT/RField.hxx>
21#include <ROOT/RNTuple.hxx>
22#include <ROOT/RNTupleModel.hxx>
24
25#include <TROOT.h>
26
28{
30 // We must not use the descriptor guard to prevent recursive locking in field.ConnectPageSource
31 ROOT::DescriptorId_t fieldZeroId = fSource->GetSharedDescriptorGuard()->GetFieldZeroId();
32 fieldZero.SetOnDiskId(fieldZeroId);
33 // Iterate only over fieldZero's direct subfields; their descendants are recursively handled in
34 // RFieldBase::ConnectPageSource
35 for (auto &field : fieldZero.GetMutableSubfields()) {
36 // If the model has been created from the descriptor, the on-disk IDs are already set.
37 // User-provided models instead need to find their corresponding IDs in the descriptor.
38 if (field->GetOnDiskId() == ROOT::kInvalidDescriptorId) {
39 field->SetOnDiskId(fSource->GetSharedDescriptorGuard()->FindFieldId(field->GetFieldName(), fieldZeroId));
40 }
42 }
43}
44
46{
47#ifdef R__USE_IMT
48 if (IsImplicitMTEnabled() &&
49 fSource->GetReadOptions().GetUseImplicitMT() == ROOT::RNTupleReadOptions::EImplicitMT::kDefault) {
50 fUnzipTasks = std::make_unique<Internal::RNTupleImtTaskScheduler>();
51 fSource->SetTaskScheduler(fUnzipTasks.get());
52 }
53#endif
54 fMetrics.ObserveMetrics(fSource->GetMetrics());
55 if (enableMetrics)
56 EnableMetrics();
57 fSource->Attach();
58}
59
60ROOT::Experimental::RNTupleReader::RNTupleReader(std::unique_ptr<ROOT::Experimental::RNTupleModel> model,
61 std::unique_ptr<ROOT::Experimental::Internal::RPageSource> source,
62 const ROOT::RNTupleReadOptions &options)
63 : fSource(std::move(source)), fModel(std::move(model)), fMetrics("RNTupleReader")
64{
65 // TODO(jblomer): properly support projected fields
67 if (!projectedFields.IsEmpty()) {
68 throw RException(R__FAIL("model has projected fields, which is incompatible with providing a read model"));
69 }
70 fModel->Freeze();
73}
74
75ROOT::Experimental::RNTupleReader::RNTupleReader(std::unique_ptr<ROOT::Experimental::Internal::RPageSource> source,
76 const ROOT::RNTupleReadOptions &options)
77 : fSource(std::move(source)), fModel(nullptr), fMetrics("RNTupleReader")
78{
80}
81
83
84std::unique_ptr<ROOT::Experimental::RNTupleReader>
85ROOT::Experimental::RNTupleReader::Open(std::unique_ptr<RNTupleModel> model, std::string_view ntupleName,
86 std::string_view storage, const ROOT::RNTupleReadOptions &options)
87{
88 return std::unique_ptr<RNTupleReader>(
89 new RNTupleReader(std::move(model), Internal::RPageSource::Create(ntupleName, storage, options), options));
90}
91
92std::unique_ptr<ROOT::Experimental::RNTupleReader>
94 const ROOT::RNTupleReadOptions &options)
95{
96 return std::unique_ptr<RNTupleReader>(
98}
99
100std::unique_ptr<ROOT::Experimental::RNTupleReader>
102{
103 return std::unique_ptr<RNTupleReader>(
105}
106
107std::unique_ptr<ROOT::Experimental::RNTupleReader>
108ROOT::Experimental::RNTupleReader::Open(std::unique_ptr<RNTupleModel> model, const ROOT::RNTuple &ntuple,
109 const ROOT::RNTupleReadOptions &options)
110{
111 return std::unique_ptr<RNTupleReader>(
112 new RNTupleReader(std::move(model), Internal::RPageSourceFile::CreateFromAnchor(ntuple, options), options));
113}
114
115std::unique_ptr<ROOT::Experimental::RNTupleReader>
117 std::string_view ntupleName, std::string_view storage,
118 const ROOT::RNTupleReadOptions &options)
119{
120 auto reader = std::unique_ptr<RNTupleReader>(
122 reader->fCreateModelOptions = createModelOpts;
123 return reader;
124}
125
126std::unique_ptr<ROOT::Experimental::RNTupleReader>
128 const ROOT::RNTuple &ntuple, const ROOT::RNTupleReadOptions &options)
129{
130 auto reader = std::unique_ptr<RNTupleReader>(
132 reader->fCreateModelOptions = createModelOpts;
133 return reader;
134}
135
137{
138 if (!fModel) {
139 fModel = fSource->GetSharedDescriptorGuard()->CreateModel(
140 fCreateModelOptions.value_or(RNTupleDescriptor::RCreateModelOptions{}));
141 ConnectModel(*fModel);
142 }
143 return *fModel;
144}
145
146std::unique_ptr<ROOT::Experimental::REntry> ROOT::Experimental::RNTupleReader::CreateEntry()
147{
148 return GetModel().CreateEntry();
149}
150
152{
153 // TODO(lesimon): In a later version, these variables may be defined by the user or the ideal width may be read out
154 // from the terminal.
155 char frameSymbol = '*';
156 int width = 80;
157 /*
158 if (width < 30) {
159 output << "The width is too small! Should be at least 30." << std::endl;
160 return;
161 }
162 */
163 switch (what) {
165 std::string name;
166 std::unique_ptr<RNTupleModel> fullModel;
167 {
168 auto descriptorGuard = fSource->GetSharedDescriptorGuard();
169 name = descriptorGuard->GetName();
171 opts.SetCreateBare(true);
172 // When printing the schema we always try to reconstruct the whole thing even when we are missing the
173 // dictionaries.
174 opts.SetEmulateUnknownTypes(true);
175 fullModel = descriptorGuard->CreateModel(opts);
176 }
177
178 for (int i = 0; i < (width / 2 + width % 2 - 4); ++i)
180 output << " NTUPLE ";
181 for (int i = 0; i < (width / 2 - 4); ++i)
183 output << "\n";
184 // FitString defined in RFieldVisitor.cxx
185 output << frameSymbol << " N-Tuple : " << RNTupleFormatter::FitString(name, width - 13) << frameSymbol
186 << "\n"; // prints line with name of ntuple
187 output << frameSymbol << " Entries : " << RNTupleFormatter::FitString(std::to_string(GetNEntries()), width - 13)
188 << frameSymbol << "\n"; // prints line with number of entries
189
190 // Traverses through all fields to gather information needed for printing.
192 // Traverses through all fields to do the actual printing.
194
195 // Note that we do not need to connect the model, we are only looking at its tree of fields
196 fullModel->GetConstFieldZero().AcceptVisitor(prepVisitor);
197
198 printVisitor.SetFrameSymbol(frameSymbol);
199 printVisitor.SetWidth(width);
200 printVisitor.SetDeepestLevel(prepVisitor.GetDeepestLevel());
201 printVisitor.SetNumFields(prepVisitor.GetNumFields());
202
203 for (int i = 0; i < width; ++i)
205 output << "\n";
206 fullModel->GetConstFieldZero().AcceptVisitor(printVisitor);
207 for (int i = 0; i < width; ++i)
209 output << std::endl;
210 break;
211 }
212 case ENTupleInfo::kStorageDetails: fSource->GetSharedDescriptorGuard()->PrintInfo(output); break;
213 case ENTupleInfo::kMetrics: fMetrics.Print(output); break;
214 default:
215 // Unhandled case, internal error
216 R__ASSERT(false);
217 }
218}
219
221{
222 if (!fDisplayReader)
223 fDisplayReader = Clone();
224 return fDisplayReader.get();
225}
226
228{
229 auto reader = GetDisplayReader();
230 const auto &entry = reader->GetModel().GetDefaultEntry();
231
232 reader->LoadEntry(index);
233 output << "{";
234 for (auto iValue = entry.begin(); iValue != entry.end();) {
235 output << std::endl;
236 RPrintValueVisitor visitor(*iValue, output, 1 /* level */);
237 iValue->GetField().AcceptVisitor(visitor);
238
239 if (++iValue == entry.end()) {
240 output << std::endl;
241 break;
242 } else {
243 output << ",";
244 }
245 }
246 output << "}" << std::endl;
247}
248
250{
251 auto descriptorGuard = fSource->GetSharedDescriptorGuard();
252 if (!fCachedDescriptor || fCachedDescriptor->GetGeneration() != descriptorGuard->GetGeneration())
253 fCachedDescriptor = descriptorGuard->Clone();
254 return *fCachedDescriptor;
255}
256
258{
259 auto fieldId = fSource->GetSharedDescriptorGuard()->FindFieldId(fieldName);
261 throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '" +
262 fSource->GetSharedDescriptorGuard()->GetName() + "'"));
263 }
264 return fieldId;
265}
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:299
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t width
char name[80]
Definition TGX11.cxx:110
static std::unique_ptr< RPageSourceFile > CreateFromAnchor(const RNTuple &anchor, const ROOT::RNTupleReadOptions &options=ROOT::RNTupleReadOptions())
Used from the RNTuple class to build a datasource if the anchor is already available.
static std::unique_ptr< RPageSource > Create(std::string_view ntupleName, std::string_view location, const ROOT::RNTupleReadOptions &options=ROOT::RNTupleReadOptions())
Guess the concrete derived page source from the file name (location)
The on-storage meta-data of an ntuple.
static std::string FitString(const std::string &str, int availableSpace)
The RNTupleModel encapulates the schema of an ntuple.
An RNTuple that is used to read data from storage.
ROOT::DescriptorId_t RetrieveFieldId(std::string_view fieldName) const
std::unique_ptr< REntry > CreateEntry()
const RNTupleDescriptor & GetDescriptor()
Returns a cached copy of the page source descriptor.
std::unique_ptr< Internal::RPageSource > fSource
static std::unique_ptr< RNTupleReader > Open(std::string_view ntupleName, std::string_view storage, const ROOT::RNTupleReadOptions &options=ROOT::RNTupleReadOptions())
Open an RNTuple for reading.
void InitPageSource(bool enableMetrics)
void PrintInfo(const ENTupleInfo what=ENTupleInfo::kSummary, std::ostream &output=std::cout) const
Prints a detailed summary of the ntuple, including a list of fields.
std::unique_ptr< RNTupleModel > fModel
Needs to be destructed before fSource.
void Show(ROOT::NTupleSize_t index, std::ostream &output=std::cout)
Shows the values of the i-th entry/row, starting with 0 for the first entry.
void ConnectModel(RNTupleModel &model)
RNTupleReader(std::unique_ptr< RNTupleModel > model, std::unique_ptr< Internal::RPageSource > source, const ROOT::RNTupleReadOptions &options)
Visitor used for a pre-processing run to collect information needed by another visitor class.
Contains settings for printing and prints a summary of an RField instance.
Renders a JSON value corresponding to the field.
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
Common user-tunable settings for reading ntuples.
Representation of an RNTuple data set in a ROOT file.
Definition RNTuple.hxx:69
const_iterator begin() const
const_iterator end() const
RProjectedFields & GetProjectedFieldsOfModel(RNTupleModel &model)
void CallConnectPageSourceOnField(RFieldBase &, RPageSource &)
RFieldZero & GetFieldZeroOfModel(RNTupleModel &model)
ENTupleInfo
Listing of the different options that can be printed by RNTupleReader::GetInfo()
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:570
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId
static const char * what
Definition stlLoader.cc:5
static void output()