Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleWriter.cxx
Go to the documentation of this file.
1/// \file RNTupleReader.cxx
2/// \ingroup NTuple
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2024-02-20
5
6/*************************************************************************
7 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
15
16#include <ROOT/RLogger.hxx>
20#include <ROOT/RNTupleModel.hxx>
21#include <ROOT/RNTupleUtils.hxx>
23#include <ROOT/RPageSinkBuf.hxx>
24#include <ROOT/RPageStorage.hxx>
26
27#include <TFile.h>
28#include <TROOT.h>
29
30#include <utility>
31
32ROOT::RNTupleWriter::RNTupleWriter(std::unique_ptr<ROOT::RNTupleModel> model,
33 std::unique_ptr<ROOT::Internal::RPageSink> sink)
34 : fFillContext(std::move(model), std::move(sink)), fMetrics("RNTupleWriter")
35{
36#ifdef R__USE_IMT
37 if (IsImplicitMTEnabled() &&
38 fFillContext.fSink->GetWriteOptions().GetUseImplicitMT() != ROOT::RNTupleWriteOptions::EImplicitMT::kOff) {
39 fFillContext.fZipTasks = std::make_unique<ROOT::Experimental::Internal::RNTupleImtTaskScheduler>();
40 fFillContext.fSink->SetTaskScheduler(fFillContext.fZipTasks.get());
41 }
42#endif
43 // Observe directly the sink's metrics to avoid an additional prefix from the fill context.
45}
46
48{
49 try {
50 CommitDataset();
51 } catch (const RException &err) {
52 R__LOG_ERROR(ROOT::Internal::NTupleLog()) << "failure committing ntuple: " << err.GetError().GetReport();
53 }
54}
55
56std::unique_ptr<ROOT::RNTupleWriter> ROOT::RNTupleWriter::Create(std::unique_ptr<ROOT::RNTupleModel> model,
57 std::unique_ptr<Internal::RPageSink> sink,
58 const ROOT::RNTupleWriteOptions &options)
59{
60 if (model->GetRegisteredSubfieldNames().size() > 0) {
61 throw RException(R__FAIL("cannot create an RNTupleWriter from a model with registered subfields"));
62 }
63 for (const auto &field : model->GetConstFieldZero()) {
65 throw RException(
66 R__FAIL("creating a RNTupleWriter from a model containing emulated fields is currently unsupported."));
67 }
68 if (options.GetUseBufferedWrite()) {
69 sink = std::make_unique<Internal::RPageSinkBuf>(std::move(sink));
70 }
71 return std::unique_ptr<RNTupleWriter>(new RNTupleWriter(std::move(model), std::move(sink)));
72}
73
74std::unique_ptr<ROOT::RNTupleWriter>
75ROOT::RNTupleWriter::Recreate(std::unique_ptr<ROOT::RNTupleModel> model, std::string_view ntupleName,
76 std::string_view storage, const ROOT::RNTupleWriteOptions &options)
77{
79 return Create(std::move(model), std::move(sink), options);
80}
81
82std::unique_ptr<ROOT::RNTupleWriter>
83ROOT::RNTupleWriter::Recreate(std::initializer_list<std::pair<std::string_view, std::string_view>> fields,
84 std::string_view ntupleName, std::string_view storage,
85 const ROOT::RNTupleWriteOptions &options)
86{
88 auto model = ROOT::RNTupleModel::Create();
89 for (const auto &fieldDesc : fields) {
90 std::string typeName(fieldDesc.first);
91 std::string fieldName(fieldDesc.second);
93 model->AddField(field.Unwrap());
94 }
95 return Create(std::move(model), std::move(sink), options);
96}
97
98std::unique_ptr<ROOT::RNTupleWriter>
99ROOT::RNTupleWriter::Append(std::unique_ptr<ROOT::RNTupleModel> model, std::string_view ntupleName,
101{
102 auto file = fileOrDirectory.GetFile();
103 if (!file) {
104 throw RException(R__FAIL("RNTupleWriter only supports writing to a ROOT file. Cannot write into a directory "
105 "that is not backed by a file"));
106 }
107 if (!file->IsBinary()) {
108 throw RException(R__FAIL("RNTupleWriter only supports writing to a ROOT file. Cannot write into " +
109 std::string(file->GetName())));
110 }
111
112 auto sink = std::make_unique<Internal::RPageSinkFile>(ntupleName, fileOrDirectory, options);
113 return Create(std::move(model), std::move(sink), options);
114}
115
117{
118 if (GetNEntries() == fLastCommittedClusterGroup)
119 return;
120 fFillContext.fSink->CommitClusterGroup();
121 fLastCommittedClusterGroup = GetNEntries();
122}
123
125{
126 if (fFillContext.fModel->IsExpired()) {
127 throw RException(R__FAIL("invalid attempt to update expired model"));
128 }
129 return *fFillContext.fModel;
130}
131
133{
134 if (fFillContext.GetModel().IsExpired())
135 return;
136
137 CommitCluster(true /* commitClusterGroup */);
138 fFillContext.fSink->CommitDataset();
139 fFillContext.fModel->Expire();
140}
141
142std::unique_ptr<ROOT::RNTupleWriter>
143ROOT::Internal::CreateRNTupleWriter(std::unique_ptr<ROOT::RNTupleModel> model,
144 std::unique_ptr<ROOT::Internal::RPageSink> sink)
145{
146 return std::unique_ptr<ROOT::RNTupleWriter>(new ROOT::RNTupleWriter(std::move(model), std::move(sink)));
147}
#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:300
#define R__LOG_ERROR(...)
Definition RLogger.hxx:357
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void ObserveMetrics(RNTupleMetrics &observee)
std::unique_ptr< ROOT::Internal::RPageSink > fSink
std::unique_ptr< ROOT::Internal::RPageStorage::RTaskScheduler > fZipTasks
The page sink's parallel page compression scheduler if IMT is on.
static std::unique_ptr< RPageSink > Create(std::string_view ntupleName, std::string_view location, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Guess the concrete derived page source from the location.
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
const RError & GetError() const
Definition RError.hxx:84
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName, const ROOT::RCreateFieldOptions &options, const ROOT::RNTupleDescriptor *desc, ROOT::DescriptorId_t fieldId)
Factory method to resurrect a field from the stored on-disk type information.
@ kTraitEmulatedField
This field is a user defined type that was missing dictionaries and was reconstructed from the on-dis...
The RNTupleModel encapulates the schema of an RNTuple.
static std::unique_ptr< RNTupleModel > Create()
Common user-tunable settings for storing RNTuples.
An RNTuple that gets filled with entries (data) and writes them to storage.
static std::unique_ptr< RNTupleWriter > Create(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink, const ROOT::RNTupleWriteOptions &options)
Create a writer, potentially wrapping the sink in a RPageSinkBuf.
static std::unique_ptr< RNTupleWriter > Recreate(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, std::string_view storage, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter backed by storage, overwriting it if one with the same URI exists.
Experimental::Detail::RNTupleMetrics fMetrics
ROOT::RNTupleModel & GetUpdatableModel()
static std::unique_ptr< RNTupleWriter > Append(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, TDirectory &fileOrDirectory, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter that writes into an existing TFile or TDirectory, without overwriting its co...
RNTupleWriter(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink)
void CommitDataset()
Closes the underlying file (page sink) and expires the model.
Experimental::RNTupleFillContext fFillContext
Describe directory structure in memory.
Definition TDirectory.h:45
ROOT::RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
std::unique_ptr< RNTupleWriter > CreateRNTupleWriter(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink)
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:600