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>();
138 auto desc =
fPageSource->GetSharedDescriptorGuard();
139 auto fieldZeroId = desc->GetFieldZeroId();
145std::unique_ptr<ROOT::RFieldBase>
147 const std::string &typeName)
151 std::string onDiskFieldName = qualifiedFieldName;
154 if (onDiskFieldName.find(
"_join.") == 0) {
155 onDiskFieldName = onDiskFieldName.substr(6);
158 const auto &desc =
fPageSource->GetSharedDescriptorGuard().GetRef();
162 const auto onDiskFieldId = desc.FindFieldId(onDiskFieldName);
168 std::unique_ptr<ROOT::RFieldBase> field;
169 if (typeName.empty()) {
170 const auto &fieldDesc = desc.GetFieldDescriptor(onDiskFieldId);
171 field = fieldDesc.CreateField(desc);
174 std::string subfieldName = onDiskFieldName;
175 auto posDot = onDiskFieldName.find_last_of(
'.');
176 if (posDot != std::string::npos)
177 subfieldName = onDiskFieldName.substr(posDot + 1);
182 field->SetOnDiskId(onDiskFieldId);
183 fieldZero.
Attach(std::move(field));
193 auto fieldIdx =
fEntry->FindFieldIndex(fieldName, typeName);
196 std::string qualifiedFieldName = fieldName;
198 qualifiedFieldName = qualifiedFieldName.substr(provenance.
Get().size() + 1);
204 throw RException(
R__FAIL(
"cannot register field with name \"" + qualifiedFieldName +
205 "\" because it is not present in the on-disk information of the RNTuple(s) this "
206 "processor is created from"));
209 fieldIdx =
fEntry->AddField(qualifiedFieldName, std::move(field), valuePtr, provenance);
221 fEntry->ReadValue(fieldIdx, entryNumber);
230 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
239 const auto &currField =
fEntry->GetValue(fieldIdx).GetField();
242 fEntry->UpdateField(fieldIdx, std::move(newField));
256 static constexpr int width = 32;
259 if (ntupleNameTrunc.size() <
fNTupleSpec.fNTupleName.size())
262 output <<
"+" << std::setfill(
'-') << std::setw(
width - 1) <<
"+\n";
263 output << std::setfill(
' ') <<
"| " << ntupleNameTrunc << std::setw(
width - 2 - ntupleNameTrunc.size()) <<
" |\n";
265 if (
const std::string *storage = std::get_if<std::string>(&
fNTupleSpec.fStorage)) {
266 std::string storageTrunc = storage->substr(0,
width - 5);
267 if (storageTrunc.size() < storage->size())
268 storageTrunc = storage->substr(0,
width - 8) +
"...";
270 output << std::setfill(
' ') <<
"| " << storageTrunc << std::setw(
width - 2 - storageTrunc.size()) <<
" |\n";
272 output <<
"| " << std::setw(
width - 2) <<
" |\n";
275 output <<
"+" << std::setfill(
'-') << std::setw(
width - 1) <<
"+\n";
281 std::vector<std::unique_ptr<RNTupleProcessor>> processors, std::string_view processorName)
286 fProcessorName = fInnerProcessors[0]->GetProcessorName();
293 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
299 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
324 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
336 innerProc->Initialize(
fEntry);
360 for (
unsigned i = 0; i < currProcessorNumber; ++i) {
397 innerProc->Initialize(
nullptr);
398 innerProc->AddEntriesToJoinTable(joinTable, entryOffset);
399 entryOffset += innerProc->GetNEntries();
406 innerProc->PrintStructure(output);
413 std::unique_ptr<RNTupleProcessor> auxProcessor,
414 const std::vector<std::string> &joinFields,
415 std::string_view processorName)
422 fProcessorName = fPrimaryProcessor->GetProcessorName();
427 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
433 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
443 throw RException(
R__FAIL(
"could not find join field \"" + joinField +
"\" in primary processor \"" +
447 throw RException(
R__FAIL(
"could not find join field \"" + joinField +
"\" in auxiliary processor \"" +
463 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
469 for (
const auto &fieldIdx : fieldIdxs) {
470 const auto &fieldProvenance =
fEntry->GetFieldProvenance(fieldIdx);
471 if (fieldProvenance.Contains(auxProvenance))
487 if (auxProvenance.IsPresentInFieldName(fieldName)) {
493 "\" is present in the primary RNTupleProcessor \"" +
495 "\", but may also refer to a field in the auxiliary RNTupleProcessor named \"" +
497 "\". To avoid this ambiguity, rename the auxiliary RNTupleProcessor."));
500 auto fieldIdx =
fAuxiliaryProcessor->AddFieldToEntry(fieldName, typeName, valuePtr, auxProvenance);
505 auto fieldIdx =
fPrimaryProcessor->AddFieldToEntry(fieldName, typeName, valuePtr, provenance);
515 fEntry->SetFieldValidity(fieldIdx, isValid);
523 fEntry->SetFieldValidity(fieldIdx,
false);
544 std::vector<ROOT::Experimental::Internal::RNTupleJoinTable::JoinValue_t> values;
548 values.push_back(val);
553 const auto entryIdx =
fJoinTable->GetEntryIndex(values);
560 fEntry->ReadValue(fieldIdx, entryIdx);
582 std::ostringstream primaryStructureStr;
584 const auto primaryStructure =
ROOT::Split(primaryStructureStr.str(),
"\n",
true);
585 const auto primaryStructureWidth = primaryStructure.front().size();
587 std::ostringstream auxStructureStr;
589 const auto auxStructure =
ROOT::Split(auxStructureStr.str(),
"\n",
true);
591 const auto maxLength = std::max(primaryStructure.size(), auxStructure.size());
592 for (
unsigned i = 0; i < maxLength; i++) {
593 if (i < primaryStructure.size())
594 output << primaryStructure[i];
596 output << std::setw(primaryStructureWidth) <<
"";
598 if (i < auxStructure.size())
599 output <<
" " << auxStructure[i];
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
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.
std::uint64_t JoinValue_t
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::uint64_t FieldIndex_t
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::RNTupleProcessorEntry::FieldIndex_t AddFieldToEntry(const std::string &fieldName, const std::string &typeName, void *valuePtr=nullptr, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance()) final
Add a field to the entry.
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 creating an (initially empty) fEntry, or setting an existing one.
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...
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::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 creating an (initially empty) fEntry, or setting an existing one.
std::unique_ptr< Internal::RNTupleJoinTable > fJoinTable
std::unique_ptr< RNTupleProcessor > fAuxiliaryProcessor
Internal::RNTupleProcessorEntry::FieldIndex_t AddFieldToEntry(const std::string &fieldName, const std::string &typeName, void *valuePtr=nullptr, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance()) final
Add a field to the entry.
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
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.
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 creating an (initially empty) fEntry, or setting an existing one.
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...
Internal::RNTupleProcessorEntry::FieldIndex_t AddFieldToEntry(const std::string &fieldName, const std::string &typeName, void *valuePtr=nullptr, const Internal::RNTupleProcessorProvenance &provenance=Internal::RNTupleProcessorProvenance()) final
Add a field to the entry.
std::unique_ptr< ROOT::RFieldBase > CreateAndConnectField(const std::string &qualifiedFieldName, const std::string &typeName)
Create a new field and connect it to the processor's page source.
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.
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.
The container field for an ntuple model, which itself has no physical representation.
std::vector< std::unique_ptr< RFieldBase > > ReleaseSubfields()
Moves all subfields into the returned vector.
void Attach(std::unique_ptr< RFieldBase > child)
A public version of the Attach method that allows piece-wise construction of the zero field.
Representation of an RNTuple data set in a ROOT file.
void SetAllowFieldSubstitutions(RFieldZero &fieldZero, bool val)
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