Skip to content

Commit cdba96f

Browse files
committed
Add test for projection of nested fields
Closes #28
1 parent d65fffd commit cdba96f

File tree

4 files changed

+160
-0
lines changed

4 files changed

+160
-0
lines changed

projections/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
* [`cardinality`](cardinality): `ROOT::RNTupleCardinality`
44
* [`collection`](collection): of collection fields
55
* [`leaf`](leaf): of leaf fields
6+
* [`nested`](nested): projection of nested fields

projections/nested/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Projections of Nested Fields
2+
3+
## Fields
4+
5+
* `VectorPair` of type `std::vector<std::pair<std::int32_t, float>>`
6+
* `VectorInt` and `VectorFloat` projected fields of types `std::vector<std::int32_t>` and `std::vector<float>`
7+
8+
## Entries
9+
10+
1. Ascending values
11+
2. Empty collection

projections/nested/read.C

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <ROOT/REntry.hxx>
2+
#include <ROOT/RNTupleReader.hxx>
3+
#include <ROOT/RVec.hxx>
4+
5+
using ROOT::Experimental::REntry;
6+
using ROOT::Experimental::RNTupleReader;
7+
8+
#include <cstdint>
9+
#include <fstream>
10+
#include <ostream>
11+
#include <string>
12+
#include <string_view>
13+
#include <utility>
14+
#include <vector>
15+
16+
template <typename T> static void PrintValue(const T &value, std::ostream &os);
17+
18+
template <> void PrintValue(const std::int32_t &value, std::ostream &os) {
19+
os << value;
20+
}
21+
22+
template <> void PrintValue(const float &value, std::ostream &os) {
23+
os << "\"" << value << "\"";
24+
}
25+
26+
template <>
27+
void PrintValue(const std::pair<std::int32_t, float> &value, std::ostream &os) {
28+
os << "[\n";
29+
os << " ";
30+
PrintValue(value.first, os);
31+
os << ",\n";
32+
os << " ";
33+
PrintValue(value.second, os);
34+
os << "\n";
35+
os << " ]";
36+
}
37+
38+
template <typename T>
39+
static void PrintVectorValue(const REntry &entry, std::string_view name,
40+
std::ostream &os, bool last = false) {
41+
auto &value = *entry.GetPtr<std::vector<T>>(name);
42+
os << " \"" << name << "\": [";
43+
bool first = true;
44+
for (auto element : value) {
45+
if (first) {
46+
first = false;
47+
} else {
48+
os << ",";
49+
}
50+
os << "\n ";
51+
PrintValue(element, os);
52+
}
53+
if (!value.empty()) {
54+
os << "\n ";
55+
}
56+
os << "]";
57+
if (!last) {
58+
os << ",";
59+
}
60+
os << "\n";
61+
}
62+
63+
void read(std::string_view input = "projections.nested.root",
64+
std::string_view output = "projections.nested.json") {
65+
std::ofstream os(std::string{output});
66+
// Print floating-point numbers as hexadecimal literals.
67+
os << std::hexfloat;
68+
os << "[\n";
69+
70+
auto reader = RNTupleReader::Open("ntpl", input);
71+
auto &entry = reader->GetModel().GetDefaultEntry();
72+
bool first = true;
73+
for (auto index : *reader) {
74+
reader->LoadEntry(index);
75+
76+
if (first) {
77+
first = false;
78+
} else {
79+
os << ",\n";
80+
}
81+
os << " {\n";
82+
83+
PrintVectorValue<std::pair<std::int32_t, float>>(entry, "VectorPair", os);
84+
PrintVectorValue<std::int32_t>(entry, "VectorInt", os);
85+
PrintVectorValue<float>(entry, "VectorFloat", os, /*last=*/true);
86+
87+
os << " }";
88+
// Newline is intentionally missing, may need to print a comma before the
89+
// next entry.
90+
}
91+
os << "\n";
92+
os << "]\n";
93+
}

projections/nested/write.C

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <ROOT/RField.hxx>
2+
#include <ROOT/RNTupleModel.hxx>
3+
#include <ROOT/RNTupleWriteOptions.hxx>
4+
#include <ROOT/RNTupleWriter.hxx>
5+
#include <ROOT/RVec.hxx>
6+
7+
using ROOT::Experimental::RField;
8+
using ROOT::Experimental::RNTupleModel;
9+
using ROOT::Experimental::RNTupleWriteOptions;
10+
using ROOT::Experimental::RNTupleWriter;
11+
12+
#include <cstdint>
13+
#include <memory>
14+
#include <string>
15+
#include <string_view>
16+
#include <utility>
17+
#include <vector>
18+
19+
template <typename T>
20+
static void AddProjectedField(RNTupleModel &model, std::string_view name,
21+
std::string_view source) {
22+
auto field = std::make_unique<RField<std::vector<T>>>(name);
23+
model.AddProjectedField(std::move(field),
24+
[&name, &source](const std::string &fieldName) {
25+
if (fieldName == name) {
26+
return std::string("VectorPair");
27+
} else {
28+
return "VectorPair._0." + std::string(source);
29+
}
30+
});
31+
}
32+
33+
void write(std::string_view filename = "projections.nested.root") {
34+
auto model = RNTupleModel::Create();
35+
36+
auto VectorPair =
37+
model->MakeField<std::vector<std::pair<std::int32_t, float>>>(
38+
"VectorPair");
39+
AddProjectedField<std::int32_t>(*model, "VectorInt", "_0");
40+
AddProjectedField<float>(*model, "VectorFloat", "_1");
41+
42+
RNTupleWriteOptions options;
43+
options.SetCompression(0);
44+
auto writer =
45+
RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options);
46+
47+
// First entry: ascending values
48+
VectorPair->emplace_back(1, 2.0);
49+
VectorPair->emplace_back(3, 4.0);
50+
writer->Fill();
51+
52+
// Second entry: empty collection
53+
VectorPair->clear();
54+
writer->Fill();
55+
}

0 commit comments

Comments
 (0)