Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion tree/ntuple/inc/ROOT/RNTupleProcessor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ 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, which provides access to the field's value.
/// \return An RNTupleProcessorOptionalPtr 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
Expand All @@ -396,6 +396,29 @@ public:
return RNTupleProcessorOptionalPtr<T>(fEntry.get(), fieldIdx);
}

/////////////////////////////////////////////////////////////////////////////
/// \brief Request access to a field for reading during processing.
///
/// \param[in] fieldName Name of the requested field.
/// \param[in] typeName Type of the requested field.
/// \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.
///
/// \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<void>
RequestField(const std::string &fieldName, const std::string &typeName, void *valuePtr = nullptr)
{
Initialize(fEntry);
auto fieldIdx = AddFieldToEntry(fieldName, typeName, valuePtr, Internal::RNTupleProcessorProvenance());
return RNTupleProcessorOptionalPtr<void>(fEntry.get(), fieldIdx);
}

/////////////////////////////////////////////////////////////////////////////
/// \brief Print a graphical representation of the processor composition.
///
Expand Down
32 changes: 32 additions & 0 deletions tree/ntuple/test/ntuple_processor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,38 @@ TEST_F(RNTupleProcessorTest, RequestFieldWithVoidPtr)
}
}

TEST_F(RNTupleProcessorTest, RequestFieldWithTypeString)
{
{
auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]});
EXPECT_NO_THROW(proc->RequestField("y", "std::vector<float >"));
}
{
auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]});
EXPECT_NO_THROW(proc->RequestField("y", "std::vector<Float_t>"));
}
{
auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]});
EXPECT_THROW(proc->RequestField("y", "std::vetor<float>"), ROOT::RException);
Comment thread
enirolf marked this conversation as resolved.
}

auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]});
auto x = proc->RequestField("x", "float");
auto yPtr = std::make_shared<std::vector<float>>();
auto y = proc->RequestField("y", "std::vector<float>", yPtr.get());
Comment thread
enirolf marked this conversation as resolved.

for (auto idx : *proc) {
EXPECT_EQ(idx, proc->GetCurrentEntryNumber());
EXPECT_EQ(idx + 1, proc->GetNEntriesProcessed());

EXPECT_FLOAT_EQ(static_cast<float>(idx), *std::static_pointer_cast<float>(x.GetPtr()));

std::vector<float> yExp{static_cast<float>(idx), static_cast<float>((idx) * 2)};
EXPECT_EQ(yExp, *std::static_pointer_cast<std::vector<float>>(y.GetPtr()));
}
EXPECT_EQ(5, proc->GetNEntriesProcessed());
}

TEST_F(RNTupleProcessorTest, AlternativeTypes)
{
auto proc = RNTupleProcessor::Create({fNTupleNames[0], fFileNames[0]});
Expand Down