46 static constexpr std::uint64_t gUpdateFrequencyBytes = 100 * 1000 * 1000;
47 std::uint64_t fNbytesNext = gUpdateFrequencyBytes;
50 ~RDefaultProgressCallback()
override {}
51 void Call(std::uint64_t nbytesWritten, std::uint64_t neventsWritten)
final
54 if (nbytesWritten < fNbytesNext)
56 std::cout <<
"Wrote " << nbytesWritten / 1000 / 1000 <<
"MB, " << neventsWritten <<
" entries\n";
57 fNbytesNext += gUpdateFrequencyBytes;
58 if (nbytesWritten > fNbytesNext) {
60 fNbytesNext = nbytesWritten + gUpdateFrequencyBytes;
64 void Finish(std::uint64_t nbytesWritten, std::uint64_t neventsWritten)
final
66 std::cout <<
"Done, wrote " << nbytesWritten / 1000 / 1000 <<
"MB, " << neventsWritten <<
" entries\n";
79std::unique_ptr<ROOT::Experimental::RNTupleImporter>
81 std::string_view destFileName)
83 auto importer = std::unique_ptr<RNTupleImporter>(
new RNTupleImporter());
84 importer->fNTupleName = treeName;
85 importer->fSourceFile = std::unique_ptr<TFile>(
TFile::Open(std::string(sourceFileName).c_str()));
86 if (!importer->fSourceFile || importer->fSourceFile->IsZombie()) {
87 throw RException(
R__FAIL(
"cannot open source file " + std::string(sourceFileName)));
90 importer->fSourceTree = importer->fSourceFile->Get<
TTree>(std::string(treeName).c_str());
91 if (!importer->fSourceTree) {
92 throw RException(
R__FAIL(
"cannot read TTree " + std::string(treeName) +
" from " + std::string(sourceFileName)));
96 importer->fSourceTree->SetImplicitMT(
false);
97 auto result = importer->InitDestination(destFileName);
105std::unique_ptr<ROOT::Experimental::RNTupleImporter>
108 auto importer = std::unique_ptr<RNTupleImporter>(
new RNTupleImporter());
115 importer->fNTupleName = sourceTree->
GetName();
118 importer->fSourceTree = sourceTree;
122 auto result = importer->InitDestination(destFileName);
144 std::cout <<
"Importing '" <<
f.fField->GetFieldName() <<
"' [" <<
f.fField->GetTypeName() <<
"]\n";
147 std::cout <<
"Importing (projected) '" <<
f->GetFieldName() <<
"' [" <<
f->GetTypeName() <<
"]\n";
170 const auto firstLeaf =
static_cast<TLeaf *
>(
b->GetListOfLeaves()->First());
173 const bool isLeafList =
b->GetNleaves() > 1;
174 const bool isCountLeaf = firstLeaf->IsRange();
176 if (isLeafList && isClass)
177 return R__FAIL(
"unsupported: classes in leaf list, branch " + std::string(
b->GetName()));
178 if (isLeafList && isCountLeaf)
179 return R__FAIL(
"unsupported: count leaf arrays in leaf list, branch " + std::string(
b->GetName()));
184 Int_t firstLeafCountval;
185 const bool isCString = !isLeafList && (firstLeaf->IsA() ==
TLeafC::Class()) &&
186 (!firstLeaf->GetLeafCounter(firstLeafCountval)) && (firstLeafCountval == 1);
195 c.fCountVal = std::make_unique<Int_t>();
202 std::size_t branchBufferSize = 0;
204 std::vector<std::unique_ptr<RFieldBase>> recordItems;
207 bool isLeafCountArray =
false;
210 return R__FAIL(
"unsupported: TObject branches, branch: " + std::string(
b->GetName()));
215 Int_t countval =
l->GetLenStatic();
216 auto *countleaf =
l->GetLeafCount();
217 const bool isFixedSizeArray = !isCString && (countleaf ==
nullptr) && (countval > 1);
218 isLeafCountArray = (countleaf !=
nullptr);
223 std::string fieldName =
b->GetName();
224 std::string fieldType =
l->GetTypeName();
230 fieldType =
"std::string";
233 fieldType =
b->GetClassName();
235 if (isFixedSizeArray)
236 fieldType =
"std::array<" + fieldType +
"," + std::to_string(countval) +
">";
240 std::replace(fieldName.begin(), fieldName.end(),
'.',
'_');
247 auto field = fieldOrError.Unwrap();
249 branchBufferSize =
l->GetMaximum();
250 f.fValue = std::make_unique<RFieldBase::RValue>(field->CreateValue());
251 f.fFieldBuffer =
f.fValue->GetPtr<
void>().get();
258 branchBufferSize =
sizeof(
void *) * countval;
259 }
else if (isLeafCountArray) {
262 branchBufferSize =
l->GetOffset() + field->GetValueSize();
265 f.fField = field.get();
268 recordItems.emplace_back(std::move(field));
269 }
else if (isLeafCountArray) {
270 const std::string countleafName = countleaf->
GetName();
273 R__ASSERT(
b->GetListOfLeaves()->GetEntries() == 1);
276 fModel->AddField(std::move(field));
280 if (!recordItems.empty()) {
281 auto recordField = std::make_unique<RRecordField>(
b->GetName(), std::move(recordItems));
285 fModel->AddField(std::move(recordField));
290 ib.
fBranchBuffer = std::make_unique<unsigned char[]>(branchBufferSize);
294 return R__FAIL(
"unable to load class " + std::string(
b->GetClassName()) +
" for branch " +
295 std::string(
b->GetName()));
297 auto ptrBuf =
reinterpret_cast<void **
>(ib.
fBranchBuffer.get());
304 if (!isLeafCountArray && !
fImportFields.back().fFieldBuffer) {
312 int iLeafCountCollection = 0;
316 auto countLeafName =
p.first;
319 c.fFieldName =
"_collection" + std::to_string(iLeafCountCollection);
320 auto recordField = std::make_unique<RRecordField>(
"_0", std::move(
c.fLeafFields));
321 c.fRecordField = recordField.get();
323 fModel->AddField(std::move(collectionField));
326 for (
const auto leaf :
c.fRecordField->GetSubFields()) {
327 const auto name = leaf->GetFieldName();
328 auto projectedField =
RFieldBase::Create(
name,
"ROOT::VecOps::RVec<" + leaf->GetTypeName() +
">").Unwrap();
329 fModel->AddProjectedField(std::move(projectedField), [&
name, &
c](
const std::string &fieldName) {
330 if (fieldName ==
name)
333 return c.fFieldName +
"._0." +
name;
339 std::replace(countLeafName.begin(), countLeafName.end(),
'.',
'_');
343 auto projectedField =
RFieldBase::Create(countLeafName,
"ROOT::RNTupleCardinality<std::uint32_t>").Unwrap();
344 fModel->AddProjectedField(std::move(projectedField), [&
c](
const std::string &) {
return c.fFieldName; });
346 iLeafCountCollection++;
350 for (
auto &field :
fModel->GetMutableFieldZero()) {
359 fEntry->BindRawPtr(
f.fField->GetFieldName(),
f.fFieldBuffer);
362 fEntry->BindRawPtr<
void>(
c.fFieldName, &
c.fFieldBuffer);
378 std::unique_ptr<Internal::RPageSink> sink =
380 sink->GetMetrics().Enable();
381 auto ctrZippedBytes = sink->GetMetrics().GetCounter(
"RPageSinkFile.szWritePayload");
384 sink = std::make_unique<Internal::RPageSinkBuf>(std::move(sink));
399 for (
decltype(nEntries) i = 0; i < nEntries; ++i) {
403 const auto sizeOfRecord =
c.fRecordField->GetValueSize();
404 c.fFieldBuffer.resize(sizeOfRecord * (*
c.fCountVal));
406 const auto nLeafs =
c.fRecordField->GetSubFields().size();
407 for (std::size_t
l = 0;
l < nLeafs; ++
l) {
408 const auto offset =
c.fRecordField->GetOffsets()[
l];
409 const auto sizeOfLeaf =
c.fRecordField->GetSubFields()[
l]->GetValueSize();
410 const auto idxImportBranch =
c.fLeafBranchIndexes[
l];
411 for (
Int_t j = 0; j < *
c.fCountVal; ++j) {
412 memcpy(
c.fFieldBuffer.data() + j * sizeOfRecord +
offset,
413 fImportBranches[idxImportBranch].fBranchBuffer.get() + (j * sizeOfLeaf), sizeOfLeaf);
424 ntplWriter->Fill(*
fEntry);
#define R__FORWARD_ERROR(res)
Short-hand to return an RResult<T> in an error state (i.e. after checking)
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
RFieldZero & GetFieldZero()
Base class for all ROOT issued exceptions.
std::vector< RFieldBase * > GetSubFields()
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias, bool continueOnError=false)
Factory method to resurrect a field from the stored on-disk type information.
Used to report every ~100 MB (compressed), and at the end about the status of the import.
virtual void Finish(std::uint64_t nbytesWritten, std::uint64_t neventsWritten)=0
virtual void Call(std::uint64_t nbytesWritten, std::uint64_t neventsWritten)=0
bool fConvertDotsInBranchNames
Whether or not dot characters in branch names should be converted to underscores.
std::unique_ptr< TFile > fDestFile
RNTupleWriteOptions fWriteOptions
std::int64_t fMaxEntries
The maximum number of entries to import. When this value is -1 (default), import all entries.
std::map< std::string, RImportLeafCountCollection > fLeafCountCollections
Maps the count leaf to the information about the corresponding untyped collection.
RNTupleImporter()=default
std::vector< RImportBranch > fImportBranches
static std::unique_ptr< RNTupleImporter > Create(std::string_view sourceFileName, std::string_view treeName, std::string_view destFileName)
Opens the input file for reading and the output file for writing (update).
std::unique_ptr< RProgressCallback > fProgressCallback
RResult< void > PrepareSchema()
Sets up the connection from TTree branches to RNTuple fields, including initialization of the memory ...
ROOT::Experimental::RResult< void > InitDestination(std::string_view destFileName)
void Import()
Import works in two steps:
std::unique_ptr< REntry > fEntry
std::string fDestFileName
bool fIsQuiet
No standard output, conversely if set to false, schema information and progress is printed.
std::vector< RImportField > fImportFields
FieldModifier_t fFieldModifier
std::unique_ptr< RNTupleModel > fModel
std::vector< std::unique_ptr< RImportTransformation > > fImportTransformations
The list of transformations to be performed for every entry.
static std::unique_ptr< RNTupleModel > CreateBare()
A bare model has no default entry.
bool GetUseBufferedWrite() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
static std::unique_ptr< RVectorField > CreateUntyped(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
TClass * IsA() const override
const char * GetName() const override
Returns name of object.
virtual const char * GetName() const
Returns name of object.
A TTree represents a columnar dataset.
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=nullptr)
Change branch address, dealing with clone trees properly.
virtual Long64_t GetEntries() const
virtual void SetImplicitMT(bool enabled)
virtual TObjArray * GetListOfBranches()
virtual TTree * GetTree() const
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
TClass * IsA() const override
RProjectedFields & GetProjectedFieldsOfModel(RNTupleModel &model)
std::unique_ptr< RNTupleWriter > CreateRNTupleWriter(std::unique_ptr< RNTupleModel > model, std::unique_ptr< Internal::RPageSink > sink)
std::string fBranchName
Top-level branch name from the input TTree.
std::unique_ptr< unsigned char[]> fBranchBuffer
The destination of SetBranchAddress() for fBranchName
void * fFieldBuffer
Usually points to the corresponding RImportBranch::fBranchBuffer but not always.
RFieldBase * fField
The field is kept during schema preparation and transferred to the fModel before the writing starts.
When the schema is set up and the import started, it needs to be reset before the next Import() call ...
Leaf count arrays require special treatment.
Int_t fMaxLength
Stores count leaf GetMaximum() to create large enough buffers for the array leafs.