From 2b0e08f34d35751e2fb5e64b37b0f89131a25032 Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Thu, 15 Jan 2026 13:57:50 +0100 Subject: [PATCH] Add tests for projections of leaf fields Closes #26 --- projections/README.md | 1 + projections/leaf/README.md | 10 +++++ projections/leaf/read.C | 85 ++++++++++++++++++++++++++++++++++++++ projections/leaf/write.C | 41 ++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 projections/leaf/README.md create mode 100644 projections/leaf/read.C create mode 100644 projections/leaf/write.C diff --git a/projections/README.md b/projections/README.md index b1003d7..172f4af 100644 --- a/projections/README.md +++ b/projections/README.md @@ -1,3 +1,4 @@ # Projections * [`cardinality`](cardinality): `ROOT::RNTupleCardinality` + * [`leaf`](leaf): of leaf fields diff --git a/projections/leaf/README.md b/projections/leaf/README.md new file mode 100644 index 0000000..b34a7d5 --- /dev/null +++ b/projections/leaf/README.md @@ -0,0 +1,10 @@ +# Projections of Leaf Fields + +## Fields + + * `Pair` of type `std::pair` + * `Int32` and `Float` projected fields of types `std::int32_t` and `float` + +## Entries + +1. Ascending values diff --git a/projections/leaf/read.C b/projections/leaf/read.C new file mode 100644 index 0000000..6abb391 --- /dev/null +++ b/projections/leaf/read.C @@ -0,0 +1,85 @@ +#include +#include +#include + +using ROOT::Experimental::REntry; +using ROOT::Experimental::RNTupleReader; + +#include +#include +#include +#include +#include +#include + +template static void PrintValue(const T &value, std::ostream &os); + +template <> void PrintValue(const std::int32_t &value, std::ostream &os) { + os << value; +} + +template <> void PrintValue(const float &value, std::ostream &os) { + os << "\"" << value << "\""; +} + +template +static void PrintPairValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = *entry.GetPtr>(name); + os << " \"" << name << "\": [\n"; + os << " "; + PrintValue(value.first, os); + os << ",\n"; + os << " "; + PrintValue(value.second, os); + os << "\n"; + os << " ]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +template +static void PrintValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + T value = *entry.GetPtr(name); + os << " \"" << name << "\": "; + PrintValue(value, os); + if (!last) { + os << ","; + } + os << "\n"; +} + +void read(std::string_view input = "projections.leaf.root", + std::string_view output = "projections.leaf.json") { + std::ofstream os(std::string{output}); + // Print floating-point numbers as hexadecimal literals. + os << std::hexfloat; + os << "[\n"; + + auto reader = RNTupleReader::Open("ntpl", input); + auto &entry = reader->GetModel().GetDefaultEntry(); + bool first = true; + for (auto index : *reader) { + reader->LoadEntry(index); + + if (first) { + first = false; + } else { + os << ",\n"; + } + os << " {\n"; + + PrintPairValue(entry, "Pair", os); + PrintValue(entry, "Int32", os); + PrintValue(entry, "Float", os, /*last=*/true); + + os << " }"; + // Newline is intentionally missing, may need to print a comma before the + // next entry. + } + os << "\n"; + os << "]\n"; +} diff --git a/projections/leaf/write.C b/projections/leaf/write.C new file mode 100644 index 0000000..905e4f2 --- /dev/null +++ b/projections/leaf/write.C @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +using ROOT::Experimental::RField; +using ROOT::Experimental::RNTupleModel; +using ROOT::Experimental::RNTupleWriteOptions; +using ROOT::Experimental::RNTupleWriter; + +#include +#include +#include +#include +#include + +template +static void AddProjectedField(RNTupleModel &model, std::string_view name, + std::string_view source) { + auto field = std::make_unique>(name); + model.AddProjectedField(std::move(field), [&source](const std::string &) { + return std::string{source}; + }); +} + +void write(std::string_view filename = "projections.leaf.root") { + auto model = RNTupleModel::Create(); + + auto Pair = model->MakeField>("Pair"); + AddProjectedField(*model, "Int32", "Pair._0"); + AddProjectedField(*model, "Float", "Pair._1"); + + RNTupleWriteOptions options; + options.SetCompression(0); + auto writer = + RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options); + + // First entry: ascending values + *Pair = {1, 2.0}; + writer->Fill(); +}