28 if (
const std::string *storagePath = std::get_if<std::string>(&
fStorage))
31 auto dir = std::get<TDirectory *>(
fStorage);
36std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
39 return std::unique_ptr<RNTupleSingleProcessor>(
new RNTupleSingleProcessor(std::move(ntuple), processorName));
42std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
48 std::vector<std::unique_ptr<RNTupleProcessor>> innerProcessors;
49 innerProcessors.reserve(ntuples.size());
51 for (
auto &ntuple : ntuples) {
52 innerProcessors.emplace_back(
Create(std::move(ntuple)));
55 return CreateChain(std::move(innerProcessors), processorName);
58std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
60 std::string_view processorName)
62 if (innerProcessors.empty())
65 return std::unique_ptr<RNTupleChainProcessor>(
new RNTupleChainProcessor(std::move(innerProcessors), processorName));
68std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
70 const std::vector<std::string> &joinFields,
71 std::string_view processorName)
73 if (joinFields.size() > 4) {
77 if (std::unordered_set(joinFields.begin(), joinFields.end()).size() < joinFields.size()) {
81 std::unique_ptr<RNTupleProcessor> primaryProcessor =
Create(primaryNTuple, processorName);
83 std::unique_ptr<RNTupleProcessor> auxProcessor =
Create(auxNTuple);
85 return CreateJoin(std::move(primaryProcessor), std::move(auxProcessor), joinFields, processorName);
88std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
90 std::unique_ptr<RNTupleProcessor> auxProcessor,
91 const std::vector<std::string> &joinFields,
92 std::string_view processorName)
94 if (joinFields.size() > 4) {
98 if (std::unordered_set(joinFields.begin(), joinFields.end()).size() < joinFields.size()) {
102 return std::unique_ptr<RNTupleJoinProcessor>(
103 new RNTupleJoinProcessor(std::move(primaryProcessor), std::move(auxProcessor), joinFields, processorName));
109 std::string_view processorName)
113 fProcessorName = fNTupleSpec.fNTupleName;
118 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
125 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
140 auto desc =
fPageSource->GetSharedDescriptorGuard();
141 auto fieldZeroId = desc->GetFieldZeroId();
151 auto fieldIdx =
fEntry->FindFieldIndex(fieldName);
154 std::string onDiskFieldName = std::string(fieldName);
156 onDiskFieldName = onDiskFieldName.substr(provenance.
Get().size() + 1);
158 auto &field =
fProtoModel->GetMutableField(onDiskFieldName);
159 fieldIdx =
fEntry->AddField(fieldName, field, valuePtr, provenance);
162 return R__FAIL(
"cannot register field with name \"" + std::string(fieldName) +
163 "\" because it is not present in the on-disk information of the RNTuple(s) this "
164 "processor is created from");
177 fEntry->ReadValue(fieldIdx, entryNumber);
186 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
198 auto desc =
fPageSource->GetSharedDescriptorGuard();
200 auto fieldZeroId = desc->GetFieldZeroId();
201 fieldZero.SetOnDiskId(fieldZeroId);
204 for (
const auto &fieldIdx : fieldIdxs) {
205 const auto &entryField =
fEntry->GetField(fieldIdx);
208 auto onDiskId = desc->FindFieldId(entryField.GetQualifiedFieldName(), fieldZeroId);
211 fEntry->SetFieldValidity(fieldIdx,
false);
215 auto &modelField =
fProtoModel->GetMutableField(entryField.GetQualifiedFieldName());
218 fEntry->UpdateField(fieldIdx, modelField);
222 modelField.SetOnDiskId(onDiskId);
226 fEntry->SetFieldValidity(fieldIdx,
true);
240 static constexpr int width = 32;
242 std::string ntupleNameTrunc =
fNTupleSpec.fNTupleName.substr(0, width - 4);
243 if (ntupleNameTrunc.size() <
fNTupleSpec.fNTupleName.size())
244 ntupleNameTrunc =
fNTupleSpec.fNTupleName.substr(0, width - 6) +
"..";
246 output <<
"+" << std::setfill(
'-') << std::setw(width - 1) <<
"+\n";
247 output << std::setfill(
' ') <<
"| " << ntupleNameTrunc << std::setw(width - 2 - ntupleNameTrunc.size()) <<
" |\n";
249 if (
const std::string *storage = std::get_if<std::string>(&
fNTupleSpec.fStorage)) {
250 std::string storageTrunc = storage->substr(0, width - 5);
251 if (storageTrunc.size() < storage->size())
252 storageTrunc = storage->substr(0, width - 8) +
"...";
254 output << std::setfill(
' ') <<
"| " << storageTrunc << std::setw(width - 2 - storageTrunc.size()) <<
" |\n";
256 output <<
"| " << std::setw(width - 2) <<
" |\n";
259 output <<
"+" << std::setfill(
'-') << std::setw(width - 1) <<
"+\n";
265 std::vector<std::unique_ptr<RNTupleProcessor>> processors, std::string_view processorName)
270 fProcessorName = fInnerProcessors[0]->GetProcessorName();
277 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
283 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
309 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
321 innerProc->Initialize(
fEntry);
336 std::size_t currProcessorNumber = 0;
371 innerProc->Initialize(
nullptr);
372 innerProc->AddEntriesToJoinTable(joinTable, entryOffset);
373 entryOffset += innerProc->GetNEntries();
380 innerProc->PrintStructure(output);
392 throw RException(
R__FAIL(
"RAuxiliaryProcessorField fields must only be used for reading"));
405 std::unique_ptr<RNTupleProcessor> auxProcessor,
406 const std::vector<std::string> &joinFields,
407 std::string_view processorName)
414 fProcessorName = fPrimaryProcessor->GetProcessorName();
419 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
425 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
437 primaryModel.GetFieldNames().end()) {
440 "\" is already present as a field in the primary processor; rename the auxiliary "
441 "processor to avoid conflicts"));
449 throw RException(
R__FAIL(
"could not find join field \"" + joinField +
"\" in auxiliary processor \"" +
457 throw RException(
R__FAIL(
"could not find join field \"" + joinField +
"\" in primary processor \"" +
467 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
473 for (
const auto &fieldIdx : fieldIdxs) {
474 auto fieldProvenance =
fEntry->GetFieldProvenance(fieldIdx);
475 if (fieldProvenance.Contains(auxProvenance))
486 std::unique_ptr<RNTupleModel> auxModel)
494 std::vector<std::unique_ptr<ROOT::RFieldBase>> auxFields;
495 auxFields.reserve(auxModel->GetFieldNames().size());
497 for (
const auto &fieldName : auxModel->GetFieldNames()) {
498 auxFields.emplace_back(auxModel->GetConstField(fieldName).Clone(fieldName));
501 auto auxParentField = std::make_unique<Internal::RAuxiliaryProcessorField>(
fAuxiliaryProcessor->GetProcessorName(),
502 std::move(auxFields));
503 const auto &subFields = auxParentField->GetConstSubfields();
506 for (
const auto &field : subFields) {
507 fProtoModel->RegisterSubfield(field->GetQualifiedFieldName());
509 if (field->GetTypeName() ==
"RAuxiliaryProcessorField") {
510 for (
const auto &auxSubfield : field->GetConstSubfields()) {
511 fProtoModel->RegisterSubfield(auxSubfield->GetQualifiedFieldName());
522 if (auxProvenance.IsPresentInFieldName(fieldName)) {
528 auto fieldIdx =
fPrimaryProcessor->AddFieldToEntry(fieldName, valuePtr, provenance);
538 fEntry->SetFieldValidity(fieldIdx, isValid);
546 fEntry->SetFieldValidity(fieldIdx,
false);
567 std::vector<void *> valPtrs;
570 auto ptr =
fEntry->GetPtr<
void>(fieldIdx);
571 valPtrs.push_back(ptr.get());
576 const auto entryIdx =
fJoinTable->GetEntryIndex(valPtrs);
583 fEntry->ReadValue(fieldIdx, entryIdx);
605 std::ostringstream primaryStructureStr;
607 const auto primaryStructure =
ROOT::Split(primaryStructureStr.str(),
"\n",
true);
608 const auto primaryStructureWidth = primaryStructure.front().size();
610 std::ostringstream auxStructureStr;
612 const auto auxStructure =
ROOT::Split(auxStructureStr.str(),
"\n",
true);
614 const auto maxLength = std::max(primaryStructure.size(), auxStructure.size());
615 for (
unsigned i = 0; i < maxLength; i++) {
616 if (i < primaryStructure.size())
617 output << primaryStructure[i];
619 output << std::setw(primaryStructureWidth) <<
"";
621 if (i < auxStructure.size())
622 output <<
" " << auxStructure[i];
#define R__FORWARD_RESULT(res)
Short-hand to return an RResult<T> value from a subroutine to the calling stack frame.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
RAuxiliaryProcessorField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > itemFields)
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
Builds a join table on one or several fields of an RNTuple so it can be joined onto other RNTuples.
static std::unique_ptr< RNTupleJoinTable > Create(const std::vector< std::string > &joinFieldNames)
Create an RNTupleJoinTable from an existing RNTuple.
RNTupleJoinTable & Add(ROOT::Internal::RPageSource &pageSource, PartitionKey_t partitionKey=kDefaultPartitionKey, ROOT::NTupleSize_t entryOffset=0)
Add an entry mapping to the join table.
static constexpr PartitionKey_t kDefaultPartitionKey
std::string Get() const
Get the full processor provenance, in the form of "x.y.z".
bool IsPresentInFieldName(std::string_view fieldName) const
Check whether the provided field name contains this provenance.
RNTupleProcessorProvenance Evolve(const std::string &processorName) const
Add a new processor to the provenance.
void PrintStructureImpl(std::ostream &output) const final
Processor-specific implementation for printing its structure, called by PrintStructure().
void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset=0) final
Add the entry mappings for this processor to the provided join table.
void ConnectInnerProcessor(std::size_t processorNumber)
Update the entry to reflect any missing fields in the current inner processor.
Internal::RNTupleProcessorProvenance fProvenance
ROOT::NTupleSize_t GetNEntries() final
Get the total number of entries in this processor.
void Initialize(std::shared_ptr< Internal::RNTupleProcessorEntry > entry=nullptr) final
Initialize the processor, by setting fProtoModel and creating an (initially empty) fEntry,...
friend class RNTupleProcessor
std::vector< ROOT::NTupleSize_t > fInnerNEntries
void Connect(const std::unordered_set< Internal::RNTupleProcessorEntry::FieldIndex_t > &fieldIdxs, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance(), bool updateFields=false) final
Connect the provided fields indices in the entry to their on-disk fields.
ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber) final
Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in th...
ROOT::RResult< Internal::RNTupleProcessorEntry::FieldIndex_t > AddFieldToEntry(std::string_view fieldName, void *valuePtr=nullptr, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance()) final
Add a field to the entry.
std::vector< std::unique_ptr< RNTupleProcessor > > fInnerProcessors
std::set< Internal::RNTupleProcessorEntry::FieldIndex_t > fJoinFieldIdxs
std::unordered_set< Internal::RNTupleProcessorEntry::FieldIndex_t > fAuxiliaryFieldIdxs
void PrintStructureImpl(std::ostream &output) const final
Processor-specific implementation for printing its structure, called by PrintStructure().
ROOT::RResult< Internal::RNTupleProcessorEntry::FieldIndex_t > AddFieldToEntry(std::string_view fieldName, void *valuePtr=nullptr, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance()) final
Add a field to the entry.
void SetProtoModel(std::unique_ptr< ROOT::RNTupleModel > primaryModel, std::unique_ptr< ROOT::RNTupleModel > auxModel)
Set the processor's proto model by combining the primary and auxiliary models.
ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber) final
Load the entry identified by the provided entry number of the primary processor.
void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset=0) final
Add the entry mappings for this processor to the provided join table.
ROOT::NTupleSize_t GetNEntries() final
Get the total number of entries in this processor.
void SetAuxiliaryFieldValidity(bool validity)
Set the validity for all fields in the auxiliary processor at once.
void Connect(const std::unordered_set< Internal::RNTupleProcessorEntry::FieldIndex_t > &fieldIdxs, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance(), bool updateFields=false) final
Connect the provided fields indices in the entry to their on-disk fields.
std::vector< std::string > fJoinFieldNames
friend class RNTupleProcessor
std::unique_ptr< RNTupleProcessor > fPrimaryProcessor
void Initialize(std::shared_ptr< Internal::RNTupleProcessorEntry > entry=nullptr) final
Initialize the processor, by setting fProtoModel and creating an (initially empty) fEntry,...
std::unique_ptr< Internal::RNTupleJoinTable > fJoinTable
std::unique_ptr< RNTupleProcessor > fAuxiliaryProcessor
Specification of the name and location of an RNTuple, used for creating a new RNTupleProcessor.
std::variant< std::string, TDirectory * > fStorage
std::unique_ptr< ROOT::Internal::RPageSource > CreatePageSource() const
static std::unique_ptr< RNTupleProcessor > CreateJoin(RNTupleOpenSpec primaryNTuple, RNTupleOpenSpec auxNTuple, const std::vector< std::string > &joinFields, std::string_view processorName="")
Create an RNTupleProcessor for a join (i.e., a horizontal combination) of RNTuples.
std::size_t fCurrentProcessorNumber
ROOT::NTupleSize_t fNEntries
Total number of entries.
friend class RNTupleJoinProcessor
static std::unique_ptr< RNTupleProcessor > CreateChain(std::vector< RNTupleOpenSpec > ntuples, std::string_view processorName="")
Create an RNTupleProcessor for a chain (i.e., a vertical combination) of RNTuples.
std::shared_ptr< Internal::RNTupleProcessorEntry > fEntry
ROOT::NTupleSize_t fNEntriesProcessed
std::unordered_set< Internal::RNTupleProcessorEntry::FieldIndex_t > fFieldIdxs
std::string fProcessorName
bool IsInitialized() const
Check if the processor already has been initialized.
ROOT::NTupleSize_t fCurrentEntryNumber
friend class RNTupleChainProcessor
friend class RNTupleSingleProcessor
std::unique_ptr< ROOT::RNTupleModel > fProtoModel
static std::unique_ptr< RNTupleProcessor > Create(RNTupleOpenSpec ntuple, std::string_view processorName="")
Create an RNTupleProcessor for a single RNTuple.
void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset=0) final
Add the entry mappings for this processor to the provided join table.
ROOT::RResult< Internal::RNTupleProcessorEntry::FieldIndex_t > AddFieldToEntry(std::string_view fieldName, void *valuePtr=nullptr, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance()) final
Add a field to the entry.
void Connect(const std::unordered_set< Internal::RNTupleProcessorEntry::FieldIndex_t > &fieldIdxs, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance(), bool updateFields=false) final
Connect the provided fields indices in the entry to their on-disk fields.
void Initialize(std::shared_ptr< Internal::RNTupleProcessorEntry > entry=nullptr) final
Initialize the processor, by setting fProtoModel and creating an (initially empty) fEntry,...
void PrintStructureImpl(std::ostream &output) const final
Processor-specific implementation for printing its structure, called by PrintStructure().
RNTupleOpenSpec fNTupleSpec
std::unique_ptr< ROOT::Internal::RPageSource > fPageSource
friend class RNTupleProcessor
bool CanReadFieldFromDisk(std::string_view fieldName) final
Check if a field exists on-disk and can be read by the processor.
ROOT::NTupleSize_t LoadEntry(ROOT::NTupleSize_t entryNumber) final
Load the entry identified by the provided (global) entry number (i.e., considering all RNTuples in th...
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).
Base class for all ROOT issued exceptions.
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponding to the field type ...
Representation of an RNTuple data set in a ROOT file.
The field for an untyped record.
RRecordField(std::string_view name, const RRecordField &source)
void AttachItemFields(ContainerT &&itemFields)
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
void SetAllowFieldSubstitutions(RFieldZero &fieldZero, bool val)
ROOT::RFieldZero & GetFieldZeroOfModel(RNTupleModel &model)
void CallConnectPageSourceOnField(RFieldBase &, ROOT::Internal::RPageSource &)
constexpr NTupleSize_t kInvalidNTupleIndex
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId
Modifiers passed to CreateModel().
void SetCreateBare(bool v)