29 if (
const std::string *storagePath = std::get_if<std::string>(&
fStorage))
32 auto dir = std::get<TDirectory *>(
fStorage);
37std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
40 return std::unique_ptr<RNTupleSingleProcessor>(
new RNTupleSingleProcessor(std::move(ntuple), processorName));
43std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
49 std::vector<std::unique_ptr<RNTupleProcessor>> innerProcessors;
50 innerProcessors.reserve(ntuples.size());
52 for (
auto &ntuple : ntuples) {
53 innerProcessors.emplace_back(
Create(std::move(ntuple)));
56 return CreateChain(std::move(innerProcessors), processorName);
59std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
61 std::string_view processorName)
63 if (innerProcessors.empty())
66 return std::unique_ptr<RNTupleChainProcessor>(
new RNTupleChainProcessor(std::move(innerProcessors), processorName));
69std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
71 const std::vector<std::string> &joinFields,
72 std::string_view processorName)
74 if (joinFields.size() > 4) {
78 if (std::unordered_set(joinFields.begin(), joinFields.end()).size() < joinFields.size()) {
82 std::unique_ptr<RNTupleProcessor> primaryProcessor =
Create(primaryNTuple, processorName);
84 std::unique_ptr<RNTupleProcessor> auxProcessor =
Create(auxNTuple);
86 return CreateJoin(std::move(primaryProcessor), std::move(auxProcessor), joinFields, processorName);
89std::unique_ptr<ROOT::Experimental::RNTupleProcessor>
91 std::unique_ptr<RNTupleProcessor> auxProcessor,
92 const std::vector<std::string> &joinFields,
93 std::string_view processorName)
95 if (joinFields.size() > 4) {
99 if (std::unordered_set(joinFields.begin(), joinFields.end()).size() < joinFields.size()) {
103 return std::unique_ptr<RNTupleJoinProcessor>(
104 new RNTupleJoinProcessor(std::move(primaryProcessor), std::move(auxProcessor), joinFields, processorName));
110 std::string_view processorName)
114 fProcessorName = fNTupleSpec.fNTupleName;
119 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
126 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
139 auto desc =
fPageSource->GetSharedDescriptorGuard();
140 auto fieldZeroId = desc->GetFieldZeroId();
146std::unique_ptr<ROOT::RFieldBase>
148 const std::string &typeName)
152 std::string onDiskFieldName = qualifiedFieldName;
155 if (onDiskFieldName.find(
"_join.") == 0) {
156 onDiskFieldName = onDiskFieldName.substr(6);
159 const auto &desc =
fPageSource->GetSharedDescriptorGuard().GetRef();
163 const auto onDiskFieldId = desc.FindFieldId(onDiskFieldName);
169 std::unique_ptr<ROOT::RFieldBase> field;
170 if (typeName.empty()) {
171 const auto &fieldDesc = desc.GetFieldDescriptor(onDiskFieldId);
172 field = fieldDesc.CreateField(desc);
175 std::string subfieldName = onDiskFieldName;
176 auto posDot = onDiskFieldName.find_last_of(
'.');
177 if (posDot != std::string::npos)
178 subfieldName = onDiskFieldName.substr(posDot + 1);
183 field->SetOnDiskId(onDiskFieldId);
184 fieldZero.
Attach(std::move(field));
194 auto fieldIdx =
fEntry->FindFieldIndex(fieldName, typeName);
197 std::string qualifiedFieldName = fieldName;
199 qualifiedFieldName = qualifiedFieldName.substr(provenance.
Get().size() + 1);
205 throw RException(
R__FAIL(
"cannot register field with name \"" + qualifiedFieldName +
206 "\" because it is not present in the on-disk information of the RNTuple(s) this "
207 "processor is created from"));
210 fieldIdx =
fEntry->AddField(qualifiedFieldName, std::move(field), valuePtr, provenance);
222 fEntry->ReadValue(fieldIdx, entryNumber);
231 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
240 const auto &currField =
fEntry->GetValue(fieldIdx).GetField();
243 fEntry->UpdateField(fieldIdx, std::move(newField));
257 static constexpr int width = 32;
260 if (ntupleNameTrunc.size() <
fNTupleSpec.fNTupleName.size())
263 output <<
"+" << std::setfill(
'-') << std::setw(
width - 1) <<
"+\n";
264 output << std::setfill(
' ') <<
"| " << ntupleNameTrunc << std::setw(
width - 2 - ntupleNameTrunc.size()) <<
" |\n";
266 if (
const std::string *storage = std::get_if<std::string>(&
fNTupleSpec.fStorage)) {
267 std::string storageTrunc = storage->substr(0,
width - 5);
268 if (storageTrunc.size() < storage->size())
269 storageTrunc = storage->substr(0,
width - 8) +
"...";
271 output << std::setfill(
' ') <<
"| " << storageTrunc << std::setw(
width - 2 - storageTrunc.size()) <<
" |\n";
273 output <<
"| " << std::setw(
width - 2) <<
" |\n";
276 output <<
"+" << std::setfill(
'-') << std::setw(
width - 1) <<
"+\n";
282 std::vector<std::unique_ptr<RNTupleProcessor>> processors, std::string_view processorName)
287 fProcessorName = fInnerProcessors[0]->GetProcessorName();
294 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
300 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
325 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
337 innerProc->Initialize(
fEntry);
352 std::size_t currProcessorNumber = 0;
387 innerProc->Initialize(
nullptr);
388 innerProc->AddEntriesToJoinTable(joinTable, entryOffset);
389 entryOffset += innerProc->GetNEntries();
396 innerProc->PrintStructure(output);
408 throw RException(
R__FAIL(
"RAuxiliaryProcessorField fields must only be used for reading"));
421 std::unique_ptr<RNTupleProcessor> auxProcessor,
422 const std::vector<std::string> &joinFields,
423 std::string_view processorName)
430 fProcessorName = fPrimaryProcessor->GetProcessorName();
435 std::shared_ptr<ROOT::Experimental::Internal::RNTupleProcessorEntry> entry)
441 fEntry = std::make_shared<Internal::RNTupleProcessorEntry>();
451 throw RException(
R__FAIL(
"could not find join field \"" + joinField +
"\" in primary processor \"" +
455 throw RException(
R__FAIL(
"could not find join field \"" + joinField +
"\" in auxiliary processor \"" +
471 const std::unordered_set<ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t> &fieldIdxs,
477 for (
const auto &fieldIdx : fieldIdxs) {
478 const auto &fieldProvenance =
fEntry->GetFieldProvenance(fieldIdx);
479 if (fieldProvenance.Contains(auxProvenance))
495 if (auxProvenance.IsPresentInFieldName(fieldName)) {
501 "\" is present in the primary RNTupleProcessor \"" +
503 "\", but may also refer to a field in the auxiliary RNTupleProcessor named \"" +
505 "\". To avoid this ambiguity, rename the auxiliary RNTupleProcessor."));
508 auto fieldIdx =
fAuxiliaryProcessor->AddFieldToEntry(fieldName, typeName, valuePtr, auxProvenance);
513 auto fieldIdx =
fPrimaryProcessor->AddFieldToEntry(fieldName, typeName, valuePtr, provenance);
523 fEntry->SetFieldValidity(fieldIdx, isValid);
531 fEntry->SetFieldValidity(fieldIdx,
false);
552 std::vector<void *> valPtrs;
555 auto ptr =
fEntry->GetValue(fieldIdx).GetPtr<
void>();
556 valPtrs.push_back(ptr.get());
561 const auto entryIdx =
fJoinTable->GetEntryIndex(valPtrs);
568 fEntry->ReadValue(fieldIdx, entryIdx);
590 std::ostringstream primaryStructureStr;
592 const auto primaryStructure =
ROOT::Split(primaryStructureStr.str(),
"\n",
true);
593 const auto primaryStructureWidth = primaryStructure.front().size();
595 std::ostringstream auxStructureStr;
597 const auto auxStructure =
ROOT::Split(auxStructureStr.str(),
"\n",
true);
599 const auto maxLength = std::max(primaryStructure.size(), auxStructure.size());
600 for (
unsigned i = 0; i < maxLength; i++) {
601 if (i < primaryStructure.size())
602 output << primaryStructure[i];
604 output << std::setw(primaryStructureWidth) <<
"";
606 if (i < auxStructure.size())
607 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...
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::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.
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponding to the field type ...
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.
The field for an untyped record.
RRecordField(std::string_view name, const RRecordField &source)
void AttachItemFields(ContainerT &&itemFields)
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