diff --git a/tree/dataframe/inc/ROOT/RNTupleProcessorDS.hxx b/tree/dataframe/inc/ROOT/RNTupleProcessorDS.hxx index 85f4935958fe1..aa102989cc494 100644 --- a/tree/dataframe/inc/ROOT/RNTupleProcessorDS.hxx +++ b/tree/dataframe/inc/ROOT/RNTupleProcessorDS.hxx @@ -58,10 +58,10 @@ class RNTupleProcessorDS final : public ROOT::RDF::RDataSource { std::string fFieldName; std::string fTypeName; std::size_t fNRepetitions; - RNTupleProcessorEntry::FieldIndex_t fEntryFieldIdx; + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fEntryFieldIdx; // Enable `std::vector::emplace_back` for this type RFieldInfo(ROOT::DescriptorId_t onDiskId, std::string_view fieldName, std::string_view typeName, - std::size_t nRepetitions, Internal::RNTupleProcessorEntry::FieldIndex_t entryFieldIdx) + std::size_t nRepetitions, ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t entryFieldIdx) : fOnDiskId(onDiskId), fFieldName(fieldName), fTypeName(typeName), @@ -97,11 +97,11 @@ class RNTupleProcessorDS final : public ROOT::RDF::RDataSource { /// be added as `ROOT::VecOps::RVec` (e.g., `std::set will be added as a `std::set`, but `Jet.[pt|eta] will be /// added as `ROOT::VecOps::RVec). void AddField(const ROOT::RFieldBase &field, std::string_view colName, - Internal::RNTupleProcessorProvenance procProvenance, std::deque &fieldInfos, + ROOT::Internal::RNTupleProcessorProvenance procProvenance, std::deque &fieldInfos, bool convertToRVec = true); public: - RNTupleProcessorDS(std::unique_ptr processor); + RNTupleProcessorDS(std::unique_ptr processor); RNTupleProcessorDS(const RNTupleProcessorDS &) = delete; RNTupleProcessorDS &operator=(const RNTupleProcessorDS &) = delete; RNTupleProcessorDS(RNTupleProcessorDS &&) = delete; @@ -137,7 +137,7 @@ protected: } // namespace ROOT::Experimental::Internal::RDF namespace ROOT::Experimental::RDF { -RDataFrame FromRNTupleProcessor(std::unique_ptr processor); +RDataFrame FromRNTupleProcessor(std::unique_ptr processor); } // namespace ROOT::Experimental::RDF #endif // ROOT_RNTupleProcessorDS diff --git a/tree/dataframe/src/RNTupleProcessorDS.cxx b/tree/dataframe/src/RNTupleProcessorDS.cxx index 9ae3d75ae5962..2b3f37b2e83e4 100644 --- a/tree/dataframe/src/RNTupleProcessorDS.cxx +++ b/tree/dataframe/src/RNTupleProcessorDS.cxx @@ -29,11 +29,11 @@ namespace ROOT::Experimental::Internal::RDF { /// Every RDF column is represented by exactly one RNTuple field class RNTupleProcessorColumnReader : public ROOT::Detail::RDF::RColumnReaderBase { - RNTupleProcessorOptionalPtr fValuePtr; ///< Container for the value of the column + RNTupleProcessorValuePtr fValuePtr; ///< Container for the value of the column Long64_t fLastLoadedEntry = ROOT::kInvalidNTupleIndex; public: - RNTupleProcessorColumnReader(RNTupleProcessorOptionalPtr &valuePtr) : fValuePtr(std::move(valuePtr)) {} + RNTupleProcessorColumnReader(RNTupleProcessorValuePtr &valuePtr) : fValuePtr(std::move(valuePtr)) {} ~RNTupleProcessorColumnReader() override = default; void *GetImpl(Long64_t entry) final @@ -49,7 +49,7 @@ RNTupleProcessorDS::~RNTupleProcessorDS() = default; // TODO: see if common parts of this and RNTupleDS::AddField can be factored out. void RNTupleProcessorDS::AddField(const ROOT::RFieldBase &field, std::string_view colName, - Internal::RNTupleProcessorProvenance procProvenance, + ROOT::Internal::RNTupleProcessorProvenance procProvenance, std::deque &fieldInfos, bool convertToRVec) { // As an example for the mapping of RNTuple fields to RDF columns, let's consider an RNTuple @@ -215,13 +215,13 @@ void RNTupleProcessorDS::AddField(const ROOT::RFieldBase &field, std::string_vie fColumnNames.emplace_back(canonicalName); fColumnTypes.emplace_back(valueField->GetTypeName()); - RNTupleProcessorEntry::FieldIndex_t fieldIdx; + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fieldIdx; if (auto optFieldIdx = fProcessor->GetEntry().FindFieldIndex(canonicalName); optFieldIdx && fProcessor->GetEntry().GetField(*optFieldIdx).GetTypeName() == field.GetTypeName()) { fieldIdx = *optFieldIdx; } else { fieldIdx = fProcessor->AddFieldToEntry(std::move(valueField), canonicalName, nullptr, - Internal::RNTupleProcessorProvenance()); + ROOT::Internal::RNTupleProcessorProvenance()); } if (cardinalityField) { @@ -231,7 +231,7 @@ void RNTupleProcessorDS::AddField(const ROOT::RFieldBase &field, std::string_vie fColumnNames.emplace_back(cardinalityFieldName); fColumnTypes.emplace_back(cardinalityField->GetTypeName()); auto cardinalityFieldIdx = fProcessor->AddFieldToEntry(std::move(cardinalityField), cardinalityFieldName, nullptr, - Internal::RNTupleProcessorProvenance()); + ROOT::Internal::RNTupleProcessorProvenance()); if (!fieldInfos.empty()) { const auto &fieldInfo = fieldInfos.back(); fieldIdx = fieldInfo.fEntryFieldIdx; @@ -244,11 +244,11 @@ void RNTupleProcessorDS::AddField(const ROOT::RFieldBase &field, std::string_vie } } -RNTupleProcessorDS::RNTupleProcessorDS(std::unique_ptr processor) +RNTupleProcessorDS::RNTupleProcessorDS(std::unique_ptr processor) : fProcessor(std::move(processor)) { // Do not add the subfields now, this is handled by AddField. - fProcessor->AddAllFieldsToEntry(Internal::RNTupleProcessorProvenance(), /*includeSubfields=*/false); + fProcessor->AddAllFieldsToEntry(ROOT::Internal::RNTupleProcessorProvenance(), /*includeSubfields=*/false); const auto &entry = fProcessor->GetEntry(); for (auto fieldIdx : entry.GetFieldIndices()) { const auto &field = entry.GetValue(fieldIdx).GetField(); @@ -337,7 +337,7 @@ RNTupleProcessorDS::GetColumnReaders(unsigned int /* slot */, std::string_view n newField->SetOnDiskId(field.GetOnDiskId()); try { - fProcessor->AddFieldToEntry(std::move(newField), strName, nullptr, Internal::RNTupleProcessorProvenance()); + fProcessor->AddFieldToEntry(std::move(newField), strName, nullptr, ROOT::Internal::RNTupleProcessorProvenance()); } catch (const ROOT::RException &) { std::string msg = "RNTupleProcessorDS: invalid type \"" + requestedType + "\" for column \"" + strName + "\" with on-disk type \"" + field.GetTypeName() + "\""; @@ -391,7 +391,7 @@ bool RNTupleProcessorDS::HasColumn(std::string_view colName) const void RNTupleProcessorDS::Initialize() { fCurrentRanges.clear(); - fProcessor->Connect(fProcessor->GetEntry().GetFieldIndices(), Internal::RNTupleProcessorProvenance(), + fProcessor->Connect(fProcessor->GetEntry().GetFieldIndices(), ROOT::Internal::RNTupleProcessorProvenance(), /*updateFields=*/false); } @@ -441,8 +441,7 @@ ROOT::RDF::RSampleInfo RNTupleProcessorDS::CreateSampleInfo( } } // namespace ROOT::Experimental::Internal::RDF -ROOT::RDataFrame -ROOT::Experimental::RDF::FromRNTupleProcessor(std::unique_ptr processor) +ROOT::RDataFrame ROOT::Experimental::RDF::FromRNTupleProcessor(std::unique_ptr processor) { return ROOT::RDataFrame( std::make_unique(std::move(processor))); diff --git a/tree/dataframe/test/datasource_ntuple_processor.cxx b/tree/dataframe/test/datasource_ntuple_processor.cxx index d88765ae26620..5cc4632e689c9 100644 --- a/tree/dataframe/test/datasource_ntuple_processor.cxx +++ b/tree/dataframe/test/datasource_ntuple_processor.cxx @@ -20,9 +20,9 @@ using ROOT::TestSupport::FileRaii; using ROOT::RNTupleModel; +using ROOT::RNTupleProcessor; using ROOT::RNTupleWriter; using ROOT::Experimental::CreateRNTupleJoinProcessor; -using ROOT::Experimental::RNTupleProcessor; using ROOT::Experimental::Internal::RDF::RNTupleProcessorDS; /* @@ -235,8 +235,8 @@ static void ChainTest(const std::string &name, const std::string &fname) // Causes "Too many open files" errors on Windows // TODO(fdegeus) Investigate root cause + fix #if !defined(_MSC_VER) || defined(R__ENABLE_BROKEN_WIN_TESTS) - std::vector openSpecs(1000, {name, fname}); - auto proc1000 = RNTupleProcessor::CreateChain(openSpecs); + std::vector inputSpecs(1000, {name, fname}); + auto proc1000 = RNTupleProcessor::CreateChain(inputSpecs); auto df1000 = ROOT::Experimental::RDF::FromRNTupleProcessor(std::move(proc1000)); EXPECT_DOUBLE_EQ(42000.0, df1000.Sum("pt").GetValue()); #endif diff --git a/tree/ntuple/inc/ROOT/RNTupleProcessor.hxx b/tree/ntuple/inc/ROOT/RNTupleProcessor.hxx index d3fbaae230475..dafdee8c6e227 100644 --- a/tree/ntuple/inc/ROOT/RNTupleProcessor.hxx +++ b/tree/ntuple/inc/ROOT/RNTupleProcessor.hxx @@ -30,47 +30,24 @@ #include namespace ROOT { -namespace Experimental { class RNTupleProcessor; -namespace Internal { -struct RNTupleProcessorEntryLoader; // for unit tests -const RNTupleProcessorEntry * -LoadFullRNTupleProcessorEntry(ROOT::Experimental::RNTupleProcessor &processor, bool includeSubfields); // for unit tests +namespace Experimental { +class RNTupleJoinProcessor; +namespace Internal { namespace RDF { class RNTupleProcessorColumnReader; class RNTupleProcessorDS; } // namespace RDF } // namespace Internal +} // namespace Experimental -// clang-format off -/** -\class ROOT::Experimental::RNTupleOpenSpec -\ingroup NTuple -\brief Specification of the name and location of an RNTuple, used for creating a new RNTupleProcessor. - -An RNTupleOpenSpec can be created by providing either a string with a path to the ROOT file or a pointer to the -TDirectory (or any of its subclasses) that contains the RNTuple. - -Note that the RNTupleOpenSpec is *write-only*, to prevent usability issues with Python. -*/ -// clang-format on -class RNTupleOpenSpec { - friend class RNTupleProcessor; - friend class RNTupleSingleProcessor; - friend class RNTupleJoinProcessor; - -private: - std::string fNTupleName; - std::variant fStorage; - -public: - RNTupleOpenSpec(std::string_view n, TDirectory *s) : fNTupleName(n), fStorage(s) {} - RNTupleOpenSpec(std::string_view n, const std::string &s) : fNTupleName(n), fStorage(s) {} - - std::unique_ptr CreatePageSource() const; -}; +namespace Internal { +struct RNTupleProcessorEntryLoader; // for unit tests +const RNTupleProcessorEntry * +LoadFullRNTupleProcessorEntry(ROOT::RNTupleProcessor &processor, bool includeSubfields); // for unit tests +} // namespace Internal class RNTupleProcessorOptions { private: @@ -79,29 +56,38 @@ private: std::string fProcessorName = ""; public: + ///////////////////////////////////////////////////////////////////////////// + /// \brief Get the processor's name. const std::string &GetProcessorName() const { return fProcessorName; } + ///////////////////////////////////////////////////////////////////////////// + /// \brief Set the processor's name. + /// + /// \param[in] name Name to assign to the processor. + /// + /// By default, the processor name is the name of the underlying RNTuple for RNTupleSingleProcessor, the name of the + /// first processor for RNTupleChainProcessor, or the name of the primary RNTuple for RNTupleJoinProcessor. void SetProcessorName(std::string_view name) { fProcessorName = name; } }; // clang-format off /** -\class ROOT::Experimental::RNTupleProcessorOptionalPtr +\class ROOT::RNTupleProcessorValuePtr \ingroup NTuple -\brief The RNTupleProcessorOptionalPtr provides access to values from fields present in an RNTupleProcessor, with support +\brief The RNTupleProcessorValuePtr provides access to values from fields present in an RNTupleProcessor, with support and checks for missing values. */ // clang-format on template -class RNTupleProcessorOptionalPtr { +class RNTupleProcessorValuePtr { friend class RNTupleProcessor; private: - Internal::RNTupleProcessorEntry *fProcessorEntry; - Internal::RNTupleProcessorEntry::FieldIndex_t fFieldIndex; + ROOT::Internal::RNTupleProcessorEntry *fProcessorEntry; + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fFieldIndex; - RNTupleProcessorOptionalPtr(Internal::RNTupleProcessorEntry *processorEntry, - Internal::RNTupleProcessorEntry::FieldIndex_t fieldIdx) + RNTupleProcessorValuePtr(ROOT::Internal::RNTupleProcessorEntry *processorEntry, + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fieldIdx) : fProcessorEntry(processorEntry), fFieldIndex(fieldIdx) { } @@ -120,7 +106,7 @@ private: /// \warning Use this function with care! Values may not always be valid for every entry during processing, for /// example when a field is not present in one of the chained processors or when during a join operation, no matching /// entry in the auxiliary processor can be found. Reading `valuePtr` as-is therefore comes with the risk of reading - /// invalid data. After binding a pointer to an `RNTupleProcessorOptionalPtr`, we *strongly* recommend only accessing + /// invalid data. After binding a pointer to an `RNTupleProcessorValuePtr`, we *strongly* recommend only accessing /// its data through this interface, to ensure that only valid data can be read. void BindRawPtr(T *valuePtr) { fProcessorEntry->BindRawPtr(fFieldIndex, valuePtr); } @@ -151,7 +137,7 @@ public: /// \warning Use this function with care! Values may not always be valid for every entry during processing, for /// example when a field is not present in one of the chained processors or when during a join operation, no matching /// entry in the auxiliary processor can be found. Reading `valuePtr` as-is therefore comes with the risk of reading - /// invalid data. After binding a pointer to an `RNTupleProcessorOptionalPtr`, we *strongly* recommend only accessing + /// invalid data. After binding a pointer to an `RNTupleProcessorValuePtr`, we *strongly* recommend only accessing /// its data through this interface, to ensure that only valid data can be read. void Bind(std::shared_ptr valuePtr) { fProcessorEntry->Bind(fFieldIndex, std::move(valuePtr)); } @@ -181,7 +167,7 @@ public: "\" because it has no value for the current entry")); } - friend bool operator==(const RNTupleProcessorOptionalPtr &lhs, const RNTupleProcessorOptionalPtr &rhs) + friend bool operator==(const RNTupleProcessorValuePtr &lhs, const RNTupleProcessorValuePtr &rhs) { return lhs.fProcessorEntry == rhs.fProcessorEntry && lhs.fFieldIndex == rhs.fFieldIndex; } @@ -189,21 +175,21 @@ public: // clang-format off /** -\class ROOT::Experimental::RNTupleProcessorOptionalPtr +\class ROOT::RNTupleProcessorValuePtr \ingroup NTuple -\brief Specialization of RNTupleProcessorOptionalPtr for `void`-type pointers. +\brief Specialization of RNTupleProcessorValuePtr for `void`-type pointers. */ // clang-format on template <> -class RNTupleProcessorOptionalPtr { +class RNTupleProcessorValuePtr { friend class RNTupleProcessor; private: - Internal::RNTupleProcessorEntry *fProcessorEntry; - Internal::RNTupleProcessorEntry::FieldIndex_t fFieldIndex; + ROOT::Internal::RNTupleProcessorEntry *fProcessorEntry; + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fFieldIndex; - RNTupleProcessorOptionalPtr(Internal::RNTupleProcessorEntry *processorEntry, - Internal::RNTupleProcessorEntry::FieldIndex_t fieldIdx) + RNTupleProcessorValuePtr(ROOT::Internal::RNTupleProcessorEntry *processorEntry, + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t fieldIdx) : fProcessorEntry(processorEntry), fFieldIndex(fieldIdx) { } @@ -222,7 +208,7 @@ private: /// \warning Use this function with care! Values may not always be valid for every entry during processing, for /// example when a field is not present in one of the chained processors or when during a join operation, no matching /// entry in the auxiliary processor can be found. Reading `valuePtr` as-is therefore comes with the risk of reading - /// invalid data. After binding a pointer to an `RNTupleProcessorOptionalPtr`, we *strongly* recommend only accessing + /// invalid data. After binding a pointer to an `RNTupleProcessorValuePtr`, we *strongly* recommend only accessing /// its data through this interface, to ensure that only valid data can be read. void BindRawPtr(void *valuePtr) { fProcessorEntry->BindRawPtr(fFieldIndex, valuePtr); } @@ -253,57 +239,19 @@ public: /// \warning Use this function with care! Values may not always be valid for every entry during processing, for /// example when a field is not present in one of the chained processors or when during a join operation, no matching /// entry in the auxiliary processor can be found. Reading `valuePtr` as-is therefore comes with the risk of reading - /// invalid data. After binding a pointer to an `RNTupleProcessorOptionalPtr`, we *strongly* recommend only accessing + /// invalid data. After binding a pointer to an `RNTupleProcessorValuePtr`, we *strongly* recommend only accessing /// its data through this interface, to ensure that only valid data can be read. void Bind(std::shared_ptr valuePtr) { fProcessorEntry->Bind(fFieldIndex, std::move(valuePtr)); } - friend bool operator==(const RNTupleProcessorOptionalPtr &lhs, const RNTupleProcessorOptionalPtr &rhs) + friend bool operator==(const RNTupleProcessorValuePtr &lhs, const RNTupleProcessorValuePtr &rhs) { return lhs.fProcessorEntry == rhs.fProcessorEntry && lhs.fFieldIndex == rhs.fFieldIndex; } }; -///////////////////////////////////////////////////////////////////////////// -/// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples. -/// -/// \param[in] primaryNTuple The name and location of the primary RNTuple. Its entries are processed in sequential -/// order. -/// \param[in] auxNTuple The name and location of the RNTuple to join the primary RNTuple with. The order in which -/// its entries are processed is determined by the primary RNTuple and doesn't necessarily have to be sequential. -/// \param[in] joinFields The names of the fields on which to join, in case the specified RNTuples are unaligned. -/// The join is made based on the combined join field values, and therefore each field has to be present in each -/// specified RNTuple. If an empty list is provided, it is assumed that the specified ntuple are fully aligned. -/// \param[in] opts Options for the processor. -/// -/// \return A pointer to the newly created RNTupleProcessor. -// TODO(fdegeus) Move back to RNTupleProcessor::CreateJoin once RNTupleProcessor moves out of Experimental. -std::unique_ptr -CreateRNTupleJoinProcessor(RNTupleOpenSpec primaryNTuple, RNTupleOpenSpec auxNTuple, - const std::vector &joinFields, - const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); - -///////////////////////////////////////////////////////////////////////////// -/// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples. -/// -/// \param[in] primaryProcessor The primary processor. Its entries are processed in sequential order. -/// \param[in] auxProcessor The processor to join the primary processor with. The order in which its entries are -/// processed is determined by the primary processor and doesn't necessarily have to be sequential. -/// \param[in] joinFields The names of the fields on which to join, in case the specified processors are unaligned. -/// The join is made based on the combined join field values, and therefore each field has to be present in each -/// specified processors. If an empty list is provided, it is assumed that the specified processors are fully -/// aligned. -/// \param[in] opts Options for the processor. -/// -/// \return A pointer to the newly created RNTupleProcessor. -// TODO(fdegeus) Move back to RNTupleProcessor::CreateJoin once RNTupleProcessor moves out of Experimental. -std::unique_ptr -CreateRNTupleJoinProcessor(std::unique_ptr primaryProcessor, - std::unique_ptr auxProcessor, const std::vector &joinFields, - const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); - // clang-format off /** -\class ROOT::Experimental::RNTupleProcessor +\class ROOT::RNTupleProcessor \ingroup NTuple \brief Interface for iterating over entries of vertically ("chained") and/or horizontally ("joined") combined RNTuples. @@ -311,11 +259,9 @@ Example usage (see ntpl012_processor_chain.C and ntpl015_processor_join.C for bi ~~~{.cpp} #include -using ROOT::Experimental::RNTupleProcessor; -using ROOT::Experimental::RNTupleOpenSpec; -std::vector ntuples = {{"ntuple1", "ntuple1.root"}, {"ntuple2", "ntuple2.root"}}; -auto processor = RNTupleProcessor::CreateChain(ntuples); +std::vector ntuples = {{"ntuple1", "ntuple1.root"}, {"ntuple2", "ntuple2.root"}}; +auto processor = ROOT::RNTupleProcessor::CreateChain(ntuples); auto pt = processor->RequestField("pt"); @@ -326,7 +272,7 @@ for (const auto &idx : *processor) { ~~~ An RNTupleProcessor is created either: -1. By providing one or more RNTupleOpenSpecs, each of which contains the name and storage location of a single RNTuple; +1. By providing one or more RNTupleInputSpecs, each of which contains the name and storage location of a single RNTuple; 2. By providing a previously created RNTupleProcessor. The RNTupleProcessor provides an iterator which gives access to the index of the current *global* entry of the @@ -334,19 +280,19 @@ processor, i.e. taking into account previously processed RNTuples. Because the schemas of each RNTuple that are part of an RNTupleProcessor may not necessarily be identical, or because it can occur that entries are only partially complete in a join-based processor, field values may be marked as -"invalid", at which point their data should not be read. This is handled by the RNTupleProcessorOptionalPtr +"invalid", at which point their data should not be read. This is handled by the RNTupleProcessorValuePtr that is returned by RequestField(). */ // clang-format on class RNTupleProcessor { - friend struct ROOT::Experimental::Internal::RNTupleProcessorEntryLoader; // for unit tests - friend const Internal::RNTupleProcessorEntry * - ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(RNTupleProcessor &processor, - bool includeSubfields); // For unit tests + friend struct ROOT::Internal::RNTupleProcessorEntryLoader; // for unit tests + friend const ROOT::Internal::RNTupleProcessorEntry * + ROOT::Internal::LoadFullRNTupleProcessorEntry(RNTupleProcessor &processor, + bool includeSubfields); // For unit tests friend class RNTupleSingleProcessor; friend class RNTupleChainProcessor; - friend class RNTupleJoinProcessor; - friend class Internal::RDF::RNTupleProcessorDS; + friend class Experimental::RNTupleJoinProcessor; + friend class Experimental::Internal::RDF::RNTupleProcessorDS; protected: ///////////////////////////////////////////////////////////////////////////// @@ -354,7 +300,7 @@ protected: class REntryMapping { friend class RNTupleSingleProcessor; friend class RNTupleChainProcessor; - friend class RNTupleJoinProcessor; + friend class Experimental::RNTupleJoinProcessor; private: ROOT::NTupleSize_t fEntryNumber = ROOT::kInvalidNTupleIndex; @@ -432,7 +378,7 @@ protected: RNTupleProcessorOptions fOptions; - std::shared_ptr fEntry = nullptr; + std::shared_ptr fEntry = nullptr; std::unordered_set fFieldIdxs; /// Total number of entries. Only to be used internally by the processor, not meant to be exposed in the public @@ -443,7 +389,7 @@ protected: ///////////////////////////////////////////////////////////////////////////// /// \brief Initialize the processor by creating an (initially empty) `fEntry`, or setting an existing one. - virtual void Initialize(std::shared_ptr entry) = 0; + virtual void Initialize(std::shared_ptr entry) = 0; ///////////////////////////////////////////////////////////////////////////// /// \brief Check if the processor already has been initialized. @@ -484,11 +430,11 @@ protected: ///////////////////////////////////////////////////////////////////////////// /// \brief Get a reference to the processor's internal entry. - Internal::RNTupleProcessorEntry &GetEntry() { return *fEntry; } + ROOT::Internal::RNTupleProcessorEntry &GetEntry() { return *fEntry; } ///////////////////////////////////////////////////////////////////////////// /// \brief Get a reference to the processor's internal entry. - const Internal::RNTupleProcessorEntry &GetEntry() const { return *fEntry; } + const ROOT::Internal::RNTupleProcessorEntry &GetEntry() const { return *fEntry; } ///////////////////////////////////////////////////////////////////////////// /// \brief Get the total number of entries in this processor @@ -550,7 +496,8 @@ protected: /// \param[in] joinTable the join table to map the entries to. /// \param[in] entryOffset In case the entry mapping is added from a chain, the offset of the entry indexes to use /// with respect to the processor's position in the chain. - virtual void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) = 0; + virtual void + AddEntriesToJoinTable(Experimental::Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) = 0; ///////////////////////////////////////////////////////////////////////////// /// \brief Processor-specific implementation for printing its structure, called by PrintStructure(). @@ -590,15 +537,15 @@ public: /// \param[in] valuePtr Pointer to bind to the field's value in the entry. If this is a `nullptr`, a pointer will be /// created. /// - /// \return An RNTupleProcessorOptionalPtr of type `T`, which provides access to the field's value. + /// \return An RNTupleProcessorValuePtr of type `T`, which provides access to the field's value. /// /// \warning Provide a `valuePtr` with care! Values may not always be valid for every entry during processing, for /// example when a field is not present in one of the chained processors or when during a join operation, no matching /// entry in the auxiliary processor can be found. Reading `valuePtr` as-is therefore comes with the risk of reading /// invalid data. After passing a pointer to `RequestField`, we *strongly* recommend only accessing its data through - /// the interface of the returned `RNTupleProcessorOptionalPtr`, to ensure that only valid data can be read. + /// the interface of the returned `RNTupleProcessorValuePtr`, to ensure that only valid data can be read. template - RNTupleProcessorOptionalPtr RequestField(const std::string &fieldName, void *valuePtr = nullptr) + RNTupleProcessorValuePtr RequestField(const std::string &fieldName, void *valuePtr = nullptr) { Initialize(fEntry); std::string typeName{}; @@ -615,13 +562,13 @@ public: throw RException(R__FAIL("attempted to request a field with user-provided value pointer to field \"" + fieldName + "\", which already exists in the entry. To change the underlying value pointer, " - "use RNTupleProcessorOptionalPtr::Bind instead.")); + "use RNTupleProcessorValuePtr::Bind instead.")); } - return RNTupleProcessorOptionalPtr(fEntry.get(), *fieldIdx); + return RNTupleProcessorValuePtr(fEntry.get(), *fieldIdx); } auto fieldIdx = AddFieldToEntry(fieldName, typeName, valuePtr, Internal::RNTupleProcessorProvenance()); - return RNTupleProcessorOptionalPtr(fEntry.get(), fieldIdx); + return RNTupleProcessorValuePtr(fEntry.get(), fieldIdx); } ///////////////////////////////////////////////////////////////////////////// @@ -632,19 +579,19 @@ public: /// \param[in] valuePtr Pointer to bind to the field's value in the entry. If this is a `nullptr`, a pointer will be /// created. /// - /// \return An void-type RNTupleProcessorOptionalPtr, which provides access to the field's value. + /// \return An void-type RNTupleProcessorValuePtr, which provides access to the field's value. /// /// \warning Provide a `valuePtr` with care! Values may not always be valid for every entry during processing, for /// example when a field is not present in one of the chained processors or when during a join operation, no matching /// entry in the auxiliary processor can be found. Reading `valuePtr` as-is therefore comes with the risk of reading /// invalid data. After passing a pointer to `RequestField`, we *strongly* recommend only accessing its data through - /// the interface of the returned `RNTupleProcessorOptionalPtr`, to ensure that only valid data can be read. - RNTupleProcessorOptionalPtr + /// the interface of the returned `RNTupleProcessorValuePtr`, to ensure that only valid data can be read. + RNTupleProcessorValuePtr RequestField(const std::string &fieldName, const std::string &typeName, void *valuePtr = nullptr) { Initialize(fEntry); auto fieldIdx = AddFieldToEntry(fieldName, typeName, valuePtr, Internal::RNTupleProcessorProvenance()); - return RNTupleProcessorOptionalPtr(fEntry.get(), fieldIdx); + return RNTupleProcessorValuePtr(fEntry.get(), fieldIdx); } ///////////////////////////////////////////////////////////////////////////// @@ -675,7 +622,7 @@ public: // clang-format off /** - \class ROOT::Experimental::RNTupleProcessor::RIterator + \class ROOT::RNTupleProcessor::RIterator \ingroup NTuple \brief Iterator over the entries of an RNTuple, or vertical concatenation thereof. */ @@ -739,7 +686,7 @@ public: /// /// \return A pointer to the newly created RNTupleProcessor. static std::unique_ptr - Create(RNTupleOpenSpec ntuple, const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); + Create(RNTupleInputSpec ntuple, const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); ///////////////////////////////////////////////////////////////////////////// /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of RNTuples. @@ -749,7 +696,7 @@ public: /// /// \return A pointer to the newly created RNTupleProcessor. static std::unique_ptr - CreateChain(std::vector ntuples, const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); + CreateChain(std::vector ntuples, const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); ///////////////////////////////////////////////////////////////////////////// /// \brief Create an RNTupleProcessor for a *chain* (i.e., a vertical combination) of other RNTupleProcessors. @@ -765,7 +712,7 @@ public: // clang-format off /** -\class ROOT::Experimental::RNTupleSingleProcessor +\class ROOT::RNTupleSingleProcessor \ingroup NTuple \brief Processor specialization for processing a single RNTuple. */ @@ -774,7 +721,7 @@ class RNTupleSingleProcessor : public RNTupleProcessor { friend class RNTupleProcessor; private: - RNTupleOpenSpec fNTupleSpec; + RNTupleInputSpec fNTupleSpec; std::unique_ptr fPageSource; ///////////////////////////////////////////////////////////////////////////// @@ -802,7 +749,7 @@ private: /// \brief Initialize the processor by creating an (initially empty) `fEntry`, or setting an existing one. /// /// At this point, the page source for the underlying RNTuple of the processor will be created and opened. - void Initialize(std::shared_ptr entry = nullptr) final; + void Initialize(std::shared_ptr entry = nullptr) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Connect the provided fields indices in the entry to their on-disk fields. @@ -817,13 +764,13 @@ private: ///////////////////////////////////////////////////////////////////////////// /// \brief Set the local entry mapping (for nested processors), according to a global entry number. /// - /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryMapping + /// \sa ROOT::RNTupleProcessor::SetEntryMapping void SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, REntryMapping &mapping) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Load the entry identified by the entry mapping. /// - /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntryImpl + /// \sa ROOT::RNTupleProcessor::LoadEntryImpl void LoadEntryImpl(const REntryMapping &mapping) final; ///////////////////////////////////////////////////////////////////////////// @@ -866,13 +813,14 @@ private: ///////////////////////////////////////////////////////////////////////////// /// \brief Add the entry mappings for this processor to the provided join table. /// - /// \sa ROOT::Experimental::RNTupleProcessor::AddEntriesToJoinTable - void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final; + /// \sa ROOT::RNTupleProcessor::AddEntriesToJoinTable + void + AddEntriesToJoinTable(Experimental::Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Processor-specific implementation for printing its structure, called by PrintStructure(). /// - /// \sa ROOT::Experimental::RNTupleProcessor::PrintStructureImpl + /// \sa ROOT::RNTupleProcessor::PrintStructureImpl void PrintStructureImpl(std::ostream &output) const final; ///////////////////////////////////////////////////////////////////////////// @@ -880,7 +828,7 @@ private: /// /// \param[in] ntuple The source specification (name and storage location) for the RNTuple to process. /// \param[in] opts Options for the processor. - RNTupleSingleProcessor(RNTupleOpenSpec ntuple, const RNTupleProcessorOptions &opts); + RNTupleSingleProcessor(RNTupleInputSpec ntuple, const RNTupleProcessorOptions &opts); public: RNTupleSingleProcessor(const RNTupleSingleProcessor &) = delete; @@ -897,7 +845,7 @@ public: // clang-format off /** -\class ROOT::Experimental::RNTupleChainProcessor +\class ROOT::RNTupleChainProcessor \ingroup NTuple \brief Processor specialization for vertically combined (*chained*) RNTupleProcessors. */ @@ -916,7 +864,7 @@ private: ///////////////////////////////////////////////////////////////////////////// /// \brief Initialize the processor by creating an (initially empty) `fEntry`, or setting an existing one. - void Initialize(std::shared_ptr entry = nullptr) final; + void Initialize(std::shared_ptr entry = nullptr) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Connect the provided fields indices in the entry to their on-disk fields. @@ -937,13 +885,13 @@ private: ///////////////////////////////////////////////////////////////////////////// /// \brief Set the local entry mapping (for nested processors), according to a global entry number. /// - /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryMapping + /// \sa ROOT::RNTupleProcessor::SetEntryMapping void SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, REntryMapping &mapping) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Load the entry identified by the entry mapping. /// - /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntryImpl + /// \sa ROOT::RNTupleProcessor::LoadEntryImpl void LoadEntryImpl(const REntryMapping &mapping) final; ///////////////////////////////////////////////////////////////////////////// @@ -986,13 +934,14 @@ private: ///////////////////////////////////////////////////////////////////////////// /// \brief Add the entry mappings for this processor to the provided join table. /// - /// \sa ROOT::Experimental::RNTupleProcessor::AddEntriesToJoinTable - void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final; + /// \sa ROOT::RNTupleProcessor::AddEntriesToJoinTable + void + AddEntriesToJoinTable(Experimental::Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Processor-specific implementation for printing its structure, called by PrintStructure(). /// - /// \sa ROOT::Experimental::RNTupleProcessor::PrintStructureImpl + /// \sa ROOT::RNTupleProcessor::PrintStructureImpl void PrintStructureImpl(std::ostream &output) const final; ///////////////////////////////////////////////////////////////////////////// @@ -1013,6 +962,45 @@ public: ~RNTupleChainProcessor() override = default; }; +namespace Experimental { +///////////////////////////////////////////////////////////////////////////// +/// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples. +/// +/// \param[in] primaryNTuple The name and location of the primary RNTuple. Its entries are processed in sequential +/// order. +/// \param[in] auxNTuple The name and location of the RNTuple to join the primary RNTuple with. The order in which +/// its entries are processed is determined by the primary RNTuple and doesn't necessarily have to be sequential. +/// \param[in] joinFields The names of the fields on which to join, in case the specified RNTuples are unaligned. +/// The join is made based on the combined join field values, and therefore each field has to be present in each +/// specified RNTuple. If an empty list is provided, it is assumed that the specified ntuple are fully aligned. +/// \param[in] opts Options for the processor. +/// +/// \return A pointer to the newly created RNTupleProcessor. +// TODO(fdegeus) Move back to RNTupleProcessor::CreateJoin once RNTupleProcessor moves out of Experimental. +std::unique_ptr +CreateRNTupleJoinProcessor(RNTupleInputSpec primaryNTuple, RNTupleInputSpec auxNTuple, + const std::vector &joinFields, + const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); + +///////////////////////////////////////////////////////////////////////////// +/// \brief Create an RNTupleProcessor for a *join* (i.e., a horizontal combination) of RNTuples. +/// +/// \param[in] primaryProcessor The primary processor. Its entries are processed in sequential order. +/// \param[in] auxProcessor The processor to join the primary processor with. The order in which its entries are +/// processed is determined by the primary processor and doesn't necessarily have to be sequential. +/// \param[in] joinFields The names of the fields on which to join, in case the specified processors are unaligned. +/// The join is made based on the combined join field values, and therefore each field has to be present in each +/// specified processors. If an empty list is provided, it is assumed that the specified processors are fully +/// aligned. +/// \param[in] opts Options for the processor. +/// +/// \return A pointer to the newly created RNTupleProcessor. +// TODO(fdegeus) Move back to RNTupleProcessor::CreateJoin once RNTupleProcessor moves out of Experimental. +std::unique_ptr +CreateRNTupleJoinProcessor(std::unique_ptr primaryProcessor, + std::unique_ptr auxProcessor, const std::vector &joinFields, + const RNTupleProcessorOptions &opts = RNTupleProcessorOptions()); + // clang-format off /** \class ROOT::Experimental::RNTupleJoinProcessor @@ -1020,7 +1008,7 @@ public: \brief Processor specialization for horizontally combined (*joined*) RNTupleProcessors. */ // clang-format on -class RNTupleJoinProcessor : public RNTupleProcessor { +class RNTupleJoinProcessor : public ROOT::RNTupleProcessor { friend class RNTupleProcessor; friend std::unique_ptr CreateRNTupleJoinProcessor(std::unique_ptr primaryProcessor, @@ -1032,23 +1020,24 @@ private: std::unique_ptr fAuxiliaryProcessor; std::vector fJoinFieldNames; - std::set fJoinFieldIdxs; + std::set fJoinFieldIdxs; std::unique_ptr fJoinTable; bool fJoinTableIsBuilt = false; - std::unordered_set fAuxiliaryFieldIdxs; + std::unordered_set fAuxiliaryFieldIdxs; /// \brief Initialize the processor by creating an (initially empty) `fEntry`, or setting an existing one. - void Initialize(std::shared_ptr entry = nullptr) final; + void Initialize(std::shared_ptr entry = nullptr) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Connect the provided fields indices in the entry to their on-disk fields. /// /// \sa RNTupleProcessor::Connect() - void Connect(const std::unordered_set &fieldIdxs, - const Internal::RNTupleProcessorProvenance &provenance = Internal::RNTupleProcessorProvenance(), - bool updateFields = false) final; + void + Connect(const std::unordered_set &fieldIdxs, + const ROOT::Internal::RNTupleProcessorProvenance &provenance = ROOT::Internal::RNTupleProcessorProvenance(), + bool updateFields = false) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Disconnect the processor from associated physical storage. @@ -1057,13 +1046,13 @@ private: ///////////////////////////////////////////////////////////////////////////// /// \brief Set the local entry mapping (for nested processors), according to a global entry number. /// - /// \sa ROOT::Experimental::RNTupleProcessor::SetEntryMapping + /// \sa ROOT::RNTupleProcessor::SetEntryMapping void SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, REntryMapping &mapping) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Load the entry identified by the entry mapping. /// - /// \sa ROOT::Experimental::RNTupleProcessor::LoadEntryImpl + /// \sa ROOT::RNTupleProcessor::LoadEntryImpl void LoadEntryImpl(const REntryMapping &mapping) final; ///////////////////////////////////////////////////////////////////////////// @@ -1093,34 +1082,35 @@ private: /// \brief Add a field to the entry. /// /// \sa RNTupleProcessor::AddFieldToEntry() - Internal::RNTupleProcessorEntry::FieldIndex_t AddFieldToEntry( - const std::string &fieldName, const std::string &typeName, void *valuePtr = nullptr, - const Internal::RNTupleProcessorProvenance &provenance = Internal::RNTupleProcessorProvenance()) final; + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t + AddFieldToEntry(const std::string &fieldName, const std::string &typeName, void *valuePtr = nullptr, + const ROOT::Internal::RNTupleProcessorProvenance &provenance = + ROOT::Internal::RNTupleProcessorProvenance()) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Add a field to the entry. /// /// \sa RNTupleProcessor::AddFieldToEntry() - Internal::RNTupleProcessorEntry::FieldIndex_t + ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t AddFieldToEntry(std::unique_ptr field, const std::string &fieldName, void *valuePtr, - const Internal::RNTupleProcessorProvenance &provenance) final; + const ROOT::Internal::RNTupleProcessorProvenance &provenance) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Add all known fields (from on-disk information) to the entry. /// /// \sa RNTupleProcessor::AddAllFieldsToEntry() - void AddAllFieldsToEntry(const Internal::RNTupleProcessorProvenance &provenance, bool includeSubfields) final; + void AddAllFieldsToEntry(const ROOT::Internal::RNTupleProcessorProvenance &provenance, bool includeSubfields) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Add the entry mappings for this processor to the provided join table. /// - /// \sa ROOT::Experimental::RNTupleProcessor::AddEntriesToJoinTable + /// \sa ROOT::RNTupleProcessor::AddEntriesToJoinTable void AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset = 0) final; ///////////////////////////////////////////////////////////////////////////// /// \brief Processor-specific implementation for printing its structure, called by PrintStructure(). /// - /// \sa ROOT::Experimental::RNTupleProcessor::PrintStructureImpl + /// \sa ROOT::RNTupleProcessor::PrintStructureImpl void PrintStructureImpl(std::ostream &output) const final; ///////////////////////////////////////////////////////////////////////////// @@ -1143,7 +1133,6 @@ public: RNTupleJoinProcessor operator=(RNTupleJoinProcessor &&) = delete; ~RNTupleJoinProcessor() override = default; }; - } // namespace Experimental } // namespace ROOT diff --git a/tree/ntuple/inc/ROOT/RNTupleProcessorEntry.hxx b/tree/ntuple/inc/ROOT/RNTupleProcessorEntry.hxx index afd994fd397e4..50b5df3870910 100644 --- a/tree/ntuple/inc/ROOT/RNTupleProcessorEntry.hxx +++ b/tree/ntuple/inc/ROOT/RNTupleProcessorEntry.hxx @@ -1,8 +1,6 @@ /// \file ROOT/RNTupleProcessor.hxx /// \author Florine de Geus /// \date 2025-06-25 -/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback -/// is welcome! /************************************************************************* * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. * @@ -24,10 +22,9 @@ #include namespace ROOT { -namespace Experimental { namespace Internal { /** -\class ROOT::Experimental::RNTupleProcessorProvenance +\class ROOT::RNTupleProcessorProvenance \ingroup NTuple \brief Identifies how a processor is composed. @@ -84,7 +81,7 @@ public: // clang-format off /** -\class ROOT::Experimental::Internal::RNTupleProcessorEntry +\class ROOT::Internal::RNTupleProcessorEntry \ingroup NTuple \brief Collection of values in an RNTupleProcessor, analogous to REntry, with checks and support for missing values. */ @@ -290,7 +287,6 @@ public: std::unordered_set GetFieldIndices() const; }; } // namespace Internal -} // namespace Experimental } // namespace ROOT #endif // ROOT_RNTupleProcessorEntry diff --git a/tree/ntuple/inc/ROOT/RNTupleTypes.hxx b/tree/ntuple/inc/ROOT/RNTupleTypes.hxx index eff797ba7ce86..4defc13b7883f 100644 --- a/tree/ntuple/inc/ROOT/RNTupleTypes.hxx +++ b/tree/ntuple/inc/ROOT/RNTupleTypes.hxx @@ -20,6 +20,9 @@ #include #include #include +#include + +class TDirectory; // For RNTupleInputSpec namespace ROOT { @@ -319,6 +322,41 @@ public: void SetPosition(RNTupleLocatorMulti position); }; +namespace Internal { +class RPageSource; // For RNTupleInputSpec +} + +// clang-format off + /** + \class ROOT::Experimental::RNTupleInputSpec + \ingroup NTuple + \brief Specification of the name and location of an RNTuple, used for creating a new RNTupleProcessor. + + An RNTupleInputSpec can be created by providing either a string with a path to the ROOT file or a pointer to the + TDirectory (or any of its subclasses) that contains the RNTuple. + + Note that the RNTupleInputSpec is *write-only*, to prevent usability issues with Python. + */ +// clang-format on +class RNTupleInputSpec { + friend class RNTupleProcessor; + friend class RNTupleSingleProcessor; + +public: + using Storage_t = std::variant; + +private: + std::string fNTupleName; + Storage_t fStorage; + +public: + RNTupleInputSpec(std::string_view n, TDirectory *s) : fNTupleName(n), fStorage(s) {} + RNTupleInputSpec(std::string_view n, const std::string &s) : fNTupleName(n), fStorage(s) {} + + const std::string &GetNTupleName() const { return fNTupleName; } + const Storage_t &GetStorage() const { return fStorage; } +}; + namespace Internal { struct RNTupleLink { diff --git a/tree/ntuple/src/RNTupleProcessor.cxx b/tree/ntuple/src/RNTupleProcessor.cxx index 795d87b604151..52c886ddccc1d 100644 --- a/tree/ntuple/src/RNTupleProcessor.cxx +++ b/tree/ntuple/src/RNTupleProcessor.cxx @@ -23,8 +23,8 @@ #include -const ROOT::Experimental::Internal::RNTupleProcessorEntry * -ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(RNTupleProcessor &processor, bool includeSubfields) +const ROOT::Internal::RNTupleProcessorEntry * +ROOT::Internal::LoadFullRNTupleProcessorEntry(ROOT::RNTupleProcessor &processor, bool includeSubfields) { processor.AddAllFieldsToEntry(RNTupleProcessorProvenance(), includeSubfields); return processor.fEntry.get(); @@ -32,25 +32,14 @@ ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(RNTupleProcessor &pr //------------------------------------------------------------------------------ -std::unique_ptr ROOT::Experimental::RNTupleOpenSpec::CreatePageSource() const -{ - if (const std::string *storagePath = std::get_if(&fStorage)) - return ROOT::Internal::RPageSource::Create(fNTupleName, *storagePath); - - auto dir = std::get(fStorage); - auto ntuple = std::unique_ptr(dir->Get(fNTupleName.c_str())); - return ROOT::Internal::RPageSourceFile::CreateFromAnchor(*ntuple); -} - -std::unique_ptr -ROOT::Experimental::RNTupleProcessor::Create(RNTupleOpenSpec ntuple, const RNTupleProcessorOptions &options) +std::unique_ptr +ROOT::RNTupleProcessor::Create(RNTupleInputSpec ntuple, const RNTupleProcessorOptions &options) { return std::unique_ptr(new RNTupleSingleProcessor(std::move(ntuple), options)); } -std::unique_ptr -ROOT::Experimental::RNTupleProcessor::CreateChain(std::vector ntuples, - const RNTupleProcessorOptions &options) +std::unique_ptr +ROOT::RNTupleProcessor::CreateChain(std::vector ntuples, const RNTupleProcessorOptions &options) { if (ntuples.empty()) throw RException(R__FAIL("at least one RNTuple must be provided")); @@ -65,9 +54,9 @@ ROOT::Experimental::RNTupleProcessor::CreateChain(std::vector n return CreateChain(std::move(innerProcessors), options); } -std::unique_ptr -ROOT::Experimental::RNTupleProcessor::CreateChain(std::vector> innerProcessors, - const RNTupleProcessorOptions &options) +std::unique_ptr +ROOT::RNTupleProcessor::CreateChain(std::vector> innerProcessors, + const RNTupleProcessorOptions &options) { if (innerProcessors.empty()) throw RException(R__FAIL("at least one inner processor must be provided")); @@ -75,8 +64,8 @@ ROOT::Experimental::RNTupleProcessor::CreateChain(std::vector(new RNTupleChainProcessor(std::move(innerProcessors), options)); } -std::unique_ptr -ROOT::Experimental::CreateRNTupleJoinProcessor(RNTupleOpenSpec primaryNTuple, RNTupleOpenSpec auxNTuple, +std::unique_ptr +ROOT::Experimental::CreateRNTupleJoinProcessor(RNTupleInputSpec primaryNTuple, RNTupleInputSpec auxNTuple, const std::vector &joinFields, const RNTupleProcessorOptions &options) { @@ -95,7 +84,7 @@ ROOT::Experimental::CreateRNTupleJoinProcessor(RNTupleOpenSpec primaryNTuple, RN return CreateRNTupleJoinProcessor(std::move(primaryProcessor), std::move(auxProcessor), joinFields, options); } -std::unique_ptr +std::unique_ptr ROOT::Experimental::CreateRNTupleJoinProcessor(std::unique_ptr primaryProcessor, std::unique_ptr auxProcessor, const std::vector &joinFields, @@ -115,8 +104,7 @@ ROOT::Experimental::CreateRNTupleJoinProcessor(std::unique_ptr //------------------------------------------------------------------------------ -ROOT::Experimental::RNTupleSingleProcessor::RNTupleSingleProcessor(RNTupleOpenSpec ntuple, - const RNTupleProcessorOptions &options) +ROOT::RNTupleSingleProcessor::RNTupleSingleProcessor(RNTupleInputSpec ntuple, const RNTupleProcessorOptions &options) : RNTupleProcessor(options), fNTupleSpec(std::move(ntuple)) { if (fOptions.GetProcessorName().empty()) { @@ -124,8 +112,19 @@ ROOT::Experimental::RNTupleSingleProcessor::RNTupleSingleProcessor(RNTupleOpenSp } } -void ROOT::Experimental::RNTupleSingleProcessor::Initialize( - std::shared_ptr entry) +namespace { +std::unique_ptr CreatePageSource(const ROOT::RNTupleInputSpec &inputSpec) +{ + if (const std::string *storagePath = std::get_if(&inputSpec.GetStorage())) + return ROOT::Internal::RPageSource::Create(inputSpec.GetNTupleName(), *storagePath); + + auto dir = std::get(inputSpec.GetStorage()); + auto ntuple = std::unique_ptr(dir->Get(inputSpec.GetNTupleName().c_str())); + return ROOT::Internal::RPageSourceFile::CreateFromAnchor(*ntuple); +} +} // anonymous namespace + +void ROOT::RNTupleSingleProcessor::Initialize(std::shared_ptr entry) { // The processor has already been initialized. if (IsInitialized() && fPageSource) @@ -136,13 +135,13 @@ void ROOT::Experimental::RNTupleSingleProcessor::Initialize( else fEntry = std::move(entry); - fPageSource = fNTupleSpec.CreatePageSource(); + fPageSource = CreatePageSource(fNTupleSpec); fPageSource->Attach(); fNEntries = fPageSource->GetNEntries(); } -bool ROOT::Experimental::RNTupleSingleProcessor::CanReadFieldFromDisk(std::string_view fieldName) +bool ROOT::RNTupleSingleProcessor::CanReadFieldFromDisk(std::string_view fieldName) { Initialize(); auto desc = fPageSource->GetSharedDescriptorGuard(); @@ -153,8 +152,7 @@ bool ROOT::Experimental::RNTupleSingleProcessor::CanReadFieldFromDisk(std::strin } std::unique_ptr -ROOT::Experimental::RNTupleSingleProcessor::CreateAndConnectField(const std::string &qualifiedFieldName, - const std::string &typeName) +ROOT::RNTupleSingleProcessor::CreateAndConnectField(const std::string &qualifiedFieldName, const std::string &typeName) { assert(fPageSource); @@ -189,8 +187,7 @@ ROOT::Experimental::RNTupleSingleProcessor::CreateAndConnectField(const std::str return ConnectField(std::move(field)); } -std::unique_ptr -ROOT::Experimental::RNTupleSingleProcessor::ConnectField(std::unique_ptr field) +std::unique_ptr ROOT::RNTupleSingleProcessor::ConnectField(std::unique_ptr field) { ROOT::RFieldZero fieldZero; ROOT::Internal::SetAllowFieldSubstitutions(fieldZero, true); @@ -199,10 +196,9 @@ ROOT::Experimental::RNTupleSingleProcessor::ConnectField(std::unique_ptrFindFieldIndex(canonicalFieldName, typeName); if (!fieldIdx) { @@ -226,10 +222,10 @@ ROOT::Experimental::RNTupleSingleProcessor::AddFieldToEntry(const std::string &c return *fieldIdx; } -ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t -ROOT::Experimental::RNTupleSingleProcessor::AddFieldToEntry(std::unique_ptr field, - const std::string &canonicalFieldName, void *valuePtr, - const Internal::RNTupleProcessorProvenance &provenance) +ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t +ROOT::RNTupleSingleProcessor::AddFieldToEntry(std::unique_ptr field, + const std::string &canonicalFieldName, void *valuePtr, + const Internal::RNTupleProcessorProvenance &provenance) { auto fieldIdx = fEntry->FindFieldIndex(canonicalFieldName, field->GetTypeName()); if (!fieldIdx) { @@ -253,8 +249,8 @@ ROOT::Experimental::RNTupleSingleProcessor::AddFieldToEntry(std::unique_ptrGetSharedDescriptorGuard(); @@ -283,8 +279,7 @@ void ROOT::Experimental::RNTupleSingleProcessor::AddAllFieldsToEntry( } } -void ROOT::Experimental::RNTupleSingleProcessor::SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, - REntryMapping &mapping) +void ROOT::RNTupleSingleProcessor::SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, REntryMapping &mapping) { if (globalEntryNumber >= fNEntries || !fEntry) mapping.SetEntryNumber(kInvalidNTupleIndex); @@ -292,7 +287,7 @@ void ROOT::Experimental::RNTupleSingleProcessor::SetEntryMapping(ROOT::NTupleSiz mapping.SetEntryNumber(globalEntryNumber); } -void ROOT::Experimental::RNTupleSingleProcessor::LoadEntryImpl(const REntryMapping &mapping) +void ROOT::RNTupleSingleProcessor::LoadEntryImpl(const REntryMapping &mapping) { assert(mapping.GetEntryNumber() != kInvalidNTupleIndex); @@ -323,8 +318,8 @@ void SetOnDiskId(ROOT::RFieldBase &field, ROOT::DescriptorId_t onDiskId, const R } } // anonymous namespace -void ROOT::Experimental::RNTupleSingleProcessor::Connect( - const std::unordered_set &fieldIdxs, +void ROOT::RNTupleSingleProcessor::Connect( + const std::unordered_set &fieldIdxs, const Internal::RNTupleProcessorProvenance & /* provenance */, bool updateFields) { Initialize(fEntry); @@ -368,7 +363,7 @@ void ROOT::Experimental::RNTupleSingleProcessor::Connect( } } -void ROOT::Experimental::RNTupleSingleProcessor::Disconnect() +void ROOT::RNTupleSingleProcessor::Disconnect() { if (fPageSource) { fEntry->ResetFields(fFieldIdxs); @@ -376,14 +371,14 @@ void ROOT::Experimental::RNTupleSingleProcessor::Disconnect() } } -void ROOT::Experimental::RNTupleSingleProcessor::AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, - ROOT::NTupleSize_t entryOffset) +void ROOT::RNTupleSingleProcessor::AddEntriesToJoinTable(Experimental::Internal::RNTupleJoinTable &joinTable, + ROOT::NTupleSize_t entryOffset) { Connect(fFieldIdxs); - joinTable.Add(*fPageSource, Internal::RNTupleJoinTable::kDefaultPartitionKey, entryOffset); + joinTable.Add(*fPageSource, Experimental::Internal::RNTupleJoinTable::kDefaultPartitionKey, entryOffset); } -void ROOT::Experimental::RNTupleSingleProcessor::PrintStructureImpl(std::ostream &output) const +void ROOT::RNTupleSingleProcessor::PrintStructureImpl(std::ostream &output) const { static constexpr int width = 32; @@ -409,8 +404,8 @@ void ROOT::Experimental::RNTupleSingleProcessor::PrintStructureImpl(std::ostream //------------------------------------------------------------------------------ -ROOT::Experimental::RNTupleChainProcessor::RNTupleChainProcessor( - std::vector> processors, const RNTupleProcessorOptions &options) +ROOT::RNTupleChainProcessor::RNTupleChainProcessor(std::vector> processors, + const RNTupleProcessorOptions &options) : RNTupleProcessor(options), fInnerProcessors(std::move(processors)) { if (fOptions.GetProcessorName().empty()) { @@ -421,8 +416,7 @@ ROOT::Experimental::RNTupleChainProcessor::RNTupleChainProcessor( fInnerNEntries.assign(fInnerProcessors.size(), kInvalidNTupleIndex); } -void ROOT::Experimental::RNTupleChainProcessor::Initialize( - std::shared_ptr entry) +void ROOT::RNTupleChainProcessor::Initialize(std::shared_ptr entry) { if (IsInitialized()) return; @@ -435,7 +429,7 @@ void ROOT::Experimental::RNTupleChainProcessor::Initialize( fInnerProcessors[0]->Initialize(fEntry); } -ROOT::NTupleSize_t ROOT::Experimental::RNTupleChainProcessor::GetNEntries() +ROOT::NTupleSize_t ROOT::RNTupleChainProcessor::GetNEntries() { if (fNEntries == kInvalidNTupleIndex) { fNEntries = 0; @@ -453,8 +447,8 @@ ROOT::NTupleSize_t ROOT::Experimental::RNTupleChainProcessor::GetNEntries() return fNEntries; } -void ROOT::Experimental::RNTupleChainProcessor::Connect( - const std::unordered_set &fieldIdxs, +void ROOT::RNTupleChainProcessor::Connect( + const std::unordered_set &fieldIdxs, const Internal::RNTupleProcessorProvenance &provenance, bool /* updateFields */) { Initialize(); @@ -463,14 +457,14 @@ void ROOT::Experimental::RNTupleChainProcessor::Connect( ConnectInnerProcessor(fCurrentProcessorNumber); } -void ROOT::Experimental::RNTupleChainProcessor::Disconnect() +void ROOT::RNTupleChainProcessor::Disconnect() { for (const auto &innerProc : fInnerProcessors) { innerProc->Disconnect(); } } -void ROOT::Experimental::RNTupleChainProcessor::ConnectInnerProcessor(std::size_t processorNumber) +void ROOT::RNTupleChainProcessor::ConnectInnerProcessor(std::size_t processorNumber) { if (fCurrentProcessorNumber != processorNumber) { fInnerProcessors[fCurrentProcessorNumber]->Disconnect(); @@ -482,31 +476,28 @@ void ROOT::Experimental::RNTupleChainProcessor::ConnectInnerProcessor(std::size_ innerProc->Connect(fFieldIdxs, fProvenance, /*updateFields=*/true); } -ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t -ROOT::Experimental::RNTupleChainProcessor::AddFieldToEntry(const std::string &fieldName, const std::string &typeName, - void *valuePtr, - const Internal::RNTupleProcessorProvenance &provenance) +ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t +ROOT::RNTupleChainProcessor::AddFieldToEntry(const std::string &fieldName, const std::string &typeName, void *valuePtr, + const Internal::RNTupleProcessorProvenance &provenance) { return fInnerProcessors[fCurrentProcessorNumber]->AddFieldToEntry(fieldName, typeName, valuePtr, provenance); } -ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t -ROOT::Experimental::RNTupleChainProcessor::AddFieldToEntry(std::unique_ptr field, - const std::string &fieldName, void *valuePtr, - const Internal::RNTupleProcessorProvenance &provenance) +ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t +ROOT::RNTupleChainProcessor::AddFieldToEntry(std::unique_ptr field, const std::string &fieldName, + void *valuePtr, const Internal::RNTupleProcessorProvenance &provenance) { return fInnerProcessors[fCurrentProcessorNumber]->AddFieldToEntry(std::move(field), fieldName, valuePtr, provenance); } -void ROOT::Experimental::RNTupleChainProcessor::AddAllFieldsToEntry( - const Internal::RNTupleProcessorProvenance &provenance, bool includeSubfields) +void ROOT::RNTupleChainProcessor::AddAllFieldsToEntry(const Internal::RNTupleProcessorProvenance &provenance, + bool includeSubfields) { Initialize(); fInnerProcessors[0]->AddAllFieldsToEntry(provenance, includeSubfields); } -void ROOT::Experimental::RNTupleChainProcessor::SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, - REntryMapping &mapping) +void ROOT::RNTupleChainProcessor::SetEntryMapping(ROOT::NTupleSize_t globalEntryNumber, REntryMapping &mapping) { std::size_t currProcessorIdx = mapping.GetInnerProcessorIdx(); @@ -558,7 +549,7 @@ void ROOT::Experimental::RNTupleChainProcessor::SetEntryMapping(ROOT::NTupleSize mapping.SetInnerProcessorIdx(currProcessorIdx); } -void ROOT::Experimental::RNTupleChainProcessor::LoadEntryImpl(const REntryMapping &mapping) +void ROOT::RNTupleChainProcessor::LoadEntryImpl(const REntryMapping &mapping) { assert(mapping.GetEntryNumber() != kInvalidNTupleIndex); @@ -569,8 +560,8 @@ void ROOT::Experimental::RNTupleChainProcessor::LoadEntryImpl(const REntryMappin fNEntriesProcessed++; } -void ROOT::Experimental::RNTupleChainProcessor::AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, - ROOT::NTupleSize_t entryOffset) +void ROOT::RNTupleChainProcessor::AddEntriesToJoinTable(Experimental::Internal::RNTupleJoinTable &joinTable, + ROOT::NTupleSize_t entryOffset) { for (unsigned i = 0; i < fInnerProcessors.size(); ++i) { const auto &innerProc = fInnerProcessors[i]; @@ -581,7 +572,7 @@ void ROOT::Experimental::RNTupleChainProcessor::AddEntriesToJoinTable(Internal:: } } -void ROOT::Experimental::RNTupleChainProcessor::PrintStructureImpl(std::ostream &output) const +void ROOT::RNTupleChainProcessor::PrintStructureImpl(std::ostream &output) const { for (const auto &innerProc : fInnerProcessors) { innerProc->PrintStructure(output); @@ -604,14 +595,13 @@ ROOT::Experimental::RNTupleJoinProcessor::RNTupleJoinProcessor(std::unique_ptr entry) +void ROOT::Experimental::RNTupleJoinProcessor::Initialize(std::shared_ptr entry) { if (IsInitialized()) return; if (!entry) - fEntry = std::make_shared(); + fEntry = std::make_shared(); else fEntry = std::move(entry); @@ -631,18 +621,19 @@ void ROOT::Experimental::RNTupleJoinProcessor::Initialize( // We prepend the name of the primary processor in this case to prevent reading from the wrong join field in // composed join operations. - auto fieldIdx = AddFieldToEntry(fOptions.GetProcessorName() + ".R_rntproc_join_" + joinField, "std::uint64_t", - nullptr, Internal::RNTupleProcessorProvenance(fOptions.GetProcessorName())); + auto fieldIdx = + AddFieldToEntry(fOptions.GetProcessorName() + ".R_rntproc_join_" + joinField, "std::uint64_t", nullptr, + ROOT::Internal::RNTupleProcessorProvenance(fOptions.GetProcessorName())); fJoinFieldIdxs.insert(fieldIdx); } - fJoinTable = Internal::RNTupleJoinTable::Create(fJoinFieldNames); + fJoinTable = Experimental::Internal::RNTupleJoinTable::Create(fJoinFieldNames); } } void ROOT::Experimental::RNTupleJoinProcessor::Connect( - const std::unordered_set &fieldIdxs, - const Internal::RNTupleProcessorProvenance &provenance, bool updateFields) + const std::unordered_set &fieldIdxs, + const ROOT::Internal::RNTupleProcessorProvenance &provenance, bool updateFields) { Initialize(); @@ -665,10 +656,10 @@ void ROOT::Experimental::RNTupleJoinProcessor::Disconnect() fAuxiliaryProcessor->Disconnect(); } -ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t +ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t ROOT::Experimental::RNTupleJoinProcessor::AddFieldToEntry(const std::string &fieldName, const std::string &typeName, void *valuePtr, - const Internal::RNTupleProcessorProvenance &provenance) + const ROOT::Internal::RNTupleProcessorProvenance &provenance) { auto auxProvenance = provenance.Evolve(fAuxiliaryProcessor->fOptions.GetProcessorName()); if (auxProvenance.IsPresentInFieldName(fieldName)) { @@ -696,10 +687,10 @@ ROOT::Experimental::RNTupleJoinProcessor::AddFieldToEntry(const std::string &fie } } -ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t +ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t ROOT::Experimental::RNTupleJoinProcessor::AddFieldToEntry(std::unique_ptr field, const std::string &fieldName, void *valuePtr, - const Internal::RNTupleProcessorProvenance &provenance) + const ROOT::Internal::RNTupleProcessorProvenance &provenance) { auto auxProvenance = provenance.Evolve(fAuxiliaryProcessor->GetOptions().GetProcessorName()); if (auxProvenance.IsPresentInFieldName(fieldName)) { @@ -727,7 +718,7 @@ ROOT::Experimental::RNTupleJoinProcessor::AddFieldToEntry(std::unique_ptrAddAllFieldsToEntry(provenance, includeSubfields); @@ -810,8 +801,8 @@ ROOT::NTupleSize_t ROOT::Experimental::RNTupleJoinProcessor::GetNEntries() return fNEntries; } -void ROOT::Experimental::RNTupleJoinProcessor::AddEntriesToJoinTable(Internal::RNTupleJoinTable &joinTable, - ROOT::NTupleSize_t entryOffset) +void ROOT::Experimental::RNTupleJoinProcessor::AddEntriesToJoinTable( + Experimental::Internal::RNTupleJoinTable &joinTable, ROOT::NTupleSize_t entryOffset) { fPrimaryProcessor->AddEntriesToJoinTable(joinTable, entryOffset); } diff --git a/tree/ntuple/src/RNTupleProcessorEntry.cxx b/tree/ntuple/src/RNTupleProcessorEntry.cxx index 355e8cef185d9..0a510231a8dd4 100644 --- a/tree/ntuple/src/RNTupleProcessorEntry.cxx +++ b/tree/ntuple/src/RNTupleProcessorEntry.cxx @@ -15,7 +15,7 @@ #include -const std::string &ROOT::Experimental::Internal::RNTupleProcessorEntry::FindFieldName(FieldIndex_t fieldIdx) const +const std::string &ROOT::Internal::RNTupleProcessorEntry::FindFieldName(FieldIndex_t fieldIdx) const { assert(fieldIdx < fProcessorValues.size()); @@ -30,9 +30,9 @@ const std::string &ROOT::Experimental::Internal::RNTupleProcessorEntry::FindFiel return empty; } -std::optional -ROOT::Experimental::Internal::RNTupleProcessorEntry::FindFieldIndex(std::string_view canonicalFieldName, - std::string_view typeName) const +std::optional +ROOT::Internal::RNTupleProcessorEntry::FindFieldIndex(std::string_view canonicalFieldName, + std::string_view typeName) const { auto it = fFieldName2Index.find(std::string(canonicalFieldName)); if (it == fFieldName2Index.end()) { @@ -51,10 +51,10 @@ ROOT::Experimental::Internal::RNTupleProcessorEntry::FindFieldIndex(std::string_ return std::nullopt; } -ROOT::Experimental::Internal::RNTupleProcessorEntry::FieldIndex_t -ROOT::Experimental::Internal::RNTupleProcessorEntry::AddField(const std::string &qualifiedFieldName, - std::unique_ptr field, void *valuePtr, - const RNTupleProcessorProvenance &provenance) +ROOT::Internal::RNTupleProcessorEntry::FieldIndex_t +ROOT::Internal::RNTupleProcessorEntry::AddField(const std::string &qualifiedFieldName, + std::unique_ptr field, void *valuePtr, + const RNTupleProcessorProvenance &provenance) { auto fieldNameWithProcessorPrefix = qualifiedFieldName; if (const auto &processorPrefix = provenance.Get(); !processorPrefix.empty()) @@ -76,14 +76,13 @@ ROOT::Experimental::Internal::RNTupleProcessorEntry::AddField(const std::string return fieldIdx; } -const ROOT::RFieldBase &ROOT::Experimental::Internal::RNTupleProcessorEntry::GetField(FieldIndex_t fieldIdx) const +const ROOT::RFieldBase &ROOT::Internal::RNTupleProcessorEntry::GetField(FieldIndex_t fieldIdx) const { assert(fieldIdx < fProcessorValues.size()); return *fProcessorValues[fieldIdx].fField; } -void ROOT::Experimental::Internal::RNTupleProcessorEntry::UpdateField(FieldIndex_t fieldIdx, - std::unique_ptr field) +void ROOT::Internal::RNTupleProcessorEntry::UpdateField(FieldIndex_t fieldIdx, std::unique_ptr field) { assert(fieldIdx < fProcessorValues.size()); @@ -101,19 +100,19 @@ void ROOT::Experimental::Internal::RNTupleProcessorEntry::UpdateField(FieldIndex } } -void ROOT::Experimental::Internal::RNTupleProcessorEntry::BindRawPtr(FieldIndex_t fieldIdx, void *valuePtr) +void ROOT::Internal::RNTupleProcessorEntry::BindRawPtr(FieldIndex_t fieldIdx, void *valuePtr) { assert(fieldIdx < fProcessorValues.size()); fProcessorValues[fieldIdx].fValue.BindRawPtr(valuePtr); } -void ROOT::Experimental::Internal::RNTupleProcessorEntry::Bind(FieldIndex_t fieldIdx, std::shared_ptr valuePtr) +void ROOT::Internal::RNTupleProcessorEntry::Bind(FieldIndex_t fieldIdx, std::shared_ptr valuePtr) { assert(fieldIdx < fProcessorValues.size()); fProcessorValues[fieldIdx].fValue.Bind(std::move(valuePtr)); } -void ROOT::Experimental::Internal::RNTupleProcessorEntry::ReadValue(FieldIndex_t fieldIdx, ROOT::NTupleSize_t entryIdx) +void ROOT::Internal::RNTupleProcessorEntry::ReadValue(FieldIndex_t fieldIdx, ROOT::NTupleSize_t entryIdx) { assert(fieldIdx < fProcessorValues.size()); @@ -122,8 +121,8 @@ void ROOT::Experimental::Internal::RNTupleProcessorEntry::ReadValue(FieldIndex_t } } -std::unordered_set -ROOT::Experimental::Internal::RNTupleProcessorEntry::GetFieldIndices() const +std::unordered_set +ROOT::Internal::RNTupleProcessorEntry::GetFieldIndices() const { // Field indices are sequentially assigned, and the entry (currently) offers no way to remove fields, so we can just // generate and return a set {0, ..., |fProcessorValues| - 1}. diff --git a/tree/ntuple/test/ntuple_processor.cxx b/tree/ntuple/test/ntuple_processor.cxx index 55c7e0853d810..65e0778521dee 100644 --- a/tree/ntuple/test/ntuple_processor.cxx +++ b/tree/ntuple/test/ntuple_processor.cxx @@ -337,7 +337,7 @@ TEST_F(RNTupleProcessorTest, RequestExistingField) err.what(), testing::HasSubstr( "attempted to request a field with user-provided value pointer to field \"x\", which already exists in the " - "entry. To change the underlying value pointer, use RNTupleProcessorOptionalPtr::Bind instead.")); + "entry. To change the underlying value pointer, use RNTupleProcessorValuePtr::Bind instead.")); } } @@ -387,7 +387,7 @@ TEST_F(RNTupleProcessorTest, Subfields) TEST_F(RNTupleProcessorTest, AddAllFields) { auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); auto fieldIdxs = entry->GetFieldIndices(); EXPECT_EQ(fieldIdxs.size(), 4); @@ -396,7 +396,7 @@ TEST_F(RNTupleProcessorTest, AddAllFields) TEST_F(RNTupleProcessorTest, AddAllFieldsAndSubfields) { auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); auto fieldIdxs = entry->GetFieldIndices(); EXPECT_EQ(fieldIdxs.size(), 13); @@ -918,7 +918,7 @@ TEST_F(RNTupleProcessorTest, AddAllFieldsComposed) auto proc = CreateRNTupleJoinProcessor(std::move(primaryProc), std::move(auxProc), {}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); auto fieldIdxs = entry->GetFieldIndices(); // 11 fields instead of 10, because the join field is also included. @@ -939,7 +939,7 @@ TEST_F(RNTupleProcessorTest, AddAllFieldsAndSubfieldsComposed) auto proc = CreateRNTupleJoinProcessor(std::move(primaryProc), std::move(auxProc), {}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); auto fieldIdxs = entry->GetFieldIndices(); // 36 fields instead of 25, because the join field is also included. @@ -1117,11 +1117,11 @@ class GH16805ProcessorTest : public testing::Test { TEST_F(GH16805ProcessorTest, JoinReading) { - std::vector stepOneSpecs{{"stepone", fStepOneFile}}; + std::vector stepOneSpecs{{"stepone", fStepOneFile}}; - std::vector stepZeroSpecs{{"stepzero", fStepZeroFiles[0]}, {"stepzero", fStepZeroFiles[1]}}; + std::vector stepZeroSpecs{{"stepzero", fStepZeroFiles[0]}, {"stepzero", fStepZeroFiles[1]}}; - std::vector joinSpecs{ + std::vector joinSpecs{ {"topLevelJoin", fJoinFiles[0]}, {"topLevelJoin", fJoinFiles[1]}, {"topLevelJoin", fJoinFiles[2]}}; auto stepOneProc = RNTupleProcessor::CreateChain(stepOneSpecs); @@ -1238,7 +1238,7 @@ class GH20033ProcessorTest : public testing::TestWithParam specs{{std::string(ntupleName), std::string(fileName)}}; + std::vector specs{{std::string(ntupleName), std::string(fileName)}}; return RNTupleProcessor::CreateChain(specs); } @@ -1247,7 +1247,7 @@ class GH20033ProcessorTest : public testing::TestWithParam CreateJoinedProcessor() { - std::vector stepZeroSpecs{{"stepzero", fStepZeroFiles[0]}, {"stepzero", fStepZeroFiles[1]}}; + std::vector stepZeroSpecs{{"stepzero", fStepZeroFiles[0]}, {"stepzero", fStepZeroFiles[1]}}; auto stepZeroProc = RNTupleProcessor::CreateChain(stepZeroSpecs); diff --git a/tree/ntuple/test/ntuple_processor_chain.cxx b/tree/ntuple/test/ntuple_processor_chain.cxx index 8219816457359..2c9525aad9ece 100644 --- a/tree/ntuple/test/ntuple_processor_chain.cxx +++ b/tree/ntuple/test/ntuple_processor_chain.cxx @@ -74,7 +74,7 @@ class RNTupleChainProcessorTest : public testing::Test { TEST(RNTupleChainProcessor, EmptySpec) { try { - auto proc = RNTupleProcessor::CreateChain(std::vector{}); + auto proc = RNTupleProcessor::CreateChain(std::vector{}); FAIL() << "creating a processor without at least one RNTuple should throw"; } catch (const ROOT::RException &err) { EXPECT_THAT(err.what(), testing::HasSubstr("at least one RNTuple must be provided")); @@ -148,7 +148,7 @@ TEST_F(RNTupleChainProcessorTest, AddAllFields) { auto proc = RNTupleProcessor::CreateChain( {{fNTupleName, fFileNames[0]}, {fNTupleName, fFileNames[2]}, {fNTupleName, fFileNames[1]}}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); auto fieldIdxs = entry->GetFieldIndices(); EXPECT_EQ(fieldIdxs.size(), 2); @@ -158,7 +158,7 @@ TEST_F(RNTupleChainProcessorTest, AddAllFieldsAndSubfields) { auto proc = RNTupleProcessor::CreateChain( {{fNTupleName, fFileNames[0]}, {fNTupleName, fFileNames[2]}, {fNTupleName, fFileNames[1]}}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); auto fieldIdxs = entry->GetFieldIndices(); EXPECT_EQ(fieldIdxs.size(), 3); @@ -174,7 +174,7 @@ TEST_F(RNTupleChainProcessorTest, EmptyNTuples) auto ntuple = RNTupleWriter::Recreate(std::move(model), fNTupleName, fileGuard.GetPath()); } - std::vector ntuples = {{fNTupleName, fileGuard.GetPath()}, {fNTupleName, fFileNames[0]}}; + std::vector ntuples = {{fNTupleName, fileGuard.GetPath()}, {fNTupleName, fFileNames[0]}}; // Empty ntuples are skipped (as long as their model complies) auto proc = RNTupleProcessor::CreateChain({{fNTupleName, fileGuard.GetPath()}, @@ -191,7 +191,7 @@ TEST_F(RNTupleChainProcessorTest, EmptyNTuples) EXPECT_EQ(10, proc->GetNEntriesProcessed()); } -namespace ROOT::Experimental::Internal { +namespace ROOT::Internal { struct RNTupleProcessorEntryLoader { static ROOT::RResult LoadEntry(RNTupleProcessor &processor, ROOT::NTupleSize_t entryNumber) { @@ -204,11 +204,11 @@ struct RNTupleProcessorEntryLoader { return RResult::Success(); } }; -} // namespace ROOT::Experimental::Internal +} // namespace ROOT::Internal TEST_F(RNTupleChainProcessorTest, LoadRandomEntry) { - using ROOT::Experimental::Internal::RNTupleProcessorEntryLoader; + using ROOT::Internal::RNTupleProcessorEntryLoader; auto proc = RNTupleProcessor::CreateChain({{fNTupleName, fFileNames[0]}, {fNTupleName, fFileNames[1]}}); @@ -285,7 +285,7 @@ TEST_F(RNTupleChainProcessorTest, OpenFileLimit) { // Assuming the open file limit is 1024, this should exceed that. Only one RNTuple page source at the should be // attached, so this should not be an issue. - std::vector chain(2000, {fNTupleName, fFileNames[0]}); + std::vector chain(2000, {fNTupleName, fFileNames[0]}); auto proc = RNTupleProcessor::CreateChain(std::move(chain)); auto x = proc->RequestField("x"); diff --git a/tree/ntuple/test/ntuple_processor_join.cxx b/tree/ntuple/test/ntuple_processor_join.cxx index 7e7de819f79b9..b65ea920519b3 100644 --- a/tree/ntuple/test/ntuple_processor_join.cxx +++ b/tree/ntuple/test/ntuple_processor_join.cxx @@ -170,7 +170,7 @@ TEST(RNTupleJoinProcessor, NameConflict) TEST_F(RNTupleJoinProcessorTest, AddAllFields) { auto proc = CreateRNTupleJoinProcessor({fNTupleNames[1], fFileNames[1]}, {fNTupleNames[2], fFileNames[2]}, {}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/false); auto fieldIdxs = entry->GetFieldIndices(); EXPECT_EQ(fieldIdxs.size(), 5); @@ -179,7 +179,7 @@ TEST_F(RNTupleJoinProcessorTest, AddAllFields) TEST_F(RNTupleJoinProcessorTest, AddAllFieldsAndSubfields) { auto proc = CreateRNTupleJoinProcessor({fNTupleNames[1], fFileNames[1]}, {fNTupleNames[2], fFileNames[2]}, {}); - auto entry = ROOT::Experimental::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); + auto entry = ROOT::Internal::LoadFullRNTupleProcessorEntry(*proc, /*includeSubfields=*/true); auto fieldIdxs = entry->GetFieldIndices(); EXPECT_EQ(fieldIdxs.size(), 6); diff --git a/tree/ntuple/test/ntuple_test.hxx b/tree/ntuple/test/ntuple_test.hxx index 1a12aa84bdd0a..6328362aa0a7f 100644 --- a/tree/ntuple/test/ntuple_test.hxx +++ b/tree/ntuple/test/ntuple_test.hxx @@ -94,11 +94,11 @@ using RNTupleMerger = ROOT::Experimental::Internal::RNTupleMerger; using RNTupleMergeOptions = ROOT::Experimental::Internal::RNTupleMergeOptions; using ENTupleMergingMode = ROOT::Experimental::Internal::ENTupleMergingMode; using RNTupleModel = ROOT::RNTupleModel; -using RNTupleOpenSpec = ROOT::Experimental::RNTupleOpenSpec; +using RNTupleInputSpec = ROOT::RNTupleInputSpec; using RNTuplePlainCounter = ROOT::Experimental::Detail::RNTuplePlainCounter; using RNTuplePlainTimer = ROOT::Experimental::Detail::RNTuplePlainTimer; -using RNTupleProcessor = ROOT::Experimental::RNTupleProcessor; -using RNTupleProcessorOptions = ROOT::Experimental::RNTupleProcessorOptions; +using RNTupleProcessor = ROOT::RNTupleProcessor; +using RNTupleProcessorOptions = ROOT::RNTupleProcessorOptions; using RNTupleSerializer = ROOT::Internal::RNTupleSerializer; using RPage = ROOT::Internal::RPage; using RPageAllocatorHeap = ROOT::Internal::RPageAllocatorHeap; diff --git a/tutorials/io/ntuple/ntpl012_processor_chain.C b/tutorials/io/ntuple/ntpl012_processor_chain.C index f9eee0812f35c..9f846e2f7d920 100644 --- a/tutorials/io/ntuple/ntpl012_processor_chain.C +++ b/tutorials/io/ntuple/ntpl012_processor_chain.C @@ -20,10 +20,6 @@ #include #include -// Import classes from the `Experimental` namespace for the time being. -using ROOT::Experimental::RNTupleOpenSpec; -using ROOT::Experimental::RNTupleProcessor; - // Number of events to generate for each ntuple. constexpr int kNEvents = 10000; @@ -58,16 +54,15 @@ void Write(std::string_view ntupleName, std::string_view fileName) } } -void Read(const std::vector &ntuples) +void Read(const std::vector &ntuples) { auto c = new TCanvas("c", "RNTupleProcessor Example", 200, 10, 700, 500); TH1F hPx("h", "This is the px distribution", 100, -4, 4); hPx.SetFillColor(48); - // The chain-based processor can be created by passing a list of RNTupleOpenSpecs, describing the name and location + // The chain-based processor can be created by passing a list of RNTupleInputSpecs, describing the name and location // of each ntuple in the chain. - auto processor = RNTupleProcessor::CreateChain(ntuples); - int prevProcessorNumber{-1}; + auto processor = ROOT::RNTupleProcessor::CreateChain(ntuples); // Access to the processor's fields is done by first requesting them through RNTupleProcessor::RequestField(). The // returned value can be used to read the current entry's value for that particular field. @@ -96,7 +91,7 @@ void ntpl012_processor_chain() // The ntuples to generate and subsequently process. The model of the first ntuple will be used to construct the // entry used by the processor. - std::vector ntuples = { + std::vector ntuples = { {"ntuple1", "ntuple1.root"}, {"ntuple2", "ntuple2.root"}, {"ntuple3", "ntuple3.root"}}; Read(ntuples); diff --git a/tutorials/io/ntuple/ntpl015_processor_join.C b/tutorials/io/ntuple/ntpl015_processor_join.C index 7164aa25b7a6a..070b6590f733e 100644 --- a/tutorials/io/ntuple/ntpl015_processor_join.C +++ b/tutorials/io/ntuple/ntpl015_processor_join.C @@ -22,7 +22,6 @@ // Import classes from the `Experimental` namespace for the time being. using ROOT::Experimental::CreateRNTupleJoinProcessor; -using ROOT::Experimental::RNTupleOpenSpec; const std::string kPrimaryNTupleName = "mainNTuple"; const std::string kMainNTuplePath = "main_ntuple.root";