From 047cee5ead9a4b88e838b405626e4efdea8b76ca Mon Sep 17 00:00:00 2001 From: Jad Dayoub Date: Mon, 29 Jun 2026 14:46:42 +0200 Subject: [PATCH] Add test for attributes --- structure/attributes/README.md | 16 ++++++++ structure/attributes/read.C | 72 ++++++++++++++++++++++++++++++++++ structure/attributes/write.C | 43 ++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 structure/attributes/README.md create mode 100644 structure/attributes/read.C create mode 100644 structure/attributes/write.C diff --git a/structure/attributes/README.md b/structure/attributes/README.md new file mode 100644 index 0000000..9371963 --- /dev/null +++ b/structure/attributes/README.md @@ -0,0 +1,16 @@ +# Attributes + +## Fields + + * `Int{32}` + * `Attr` + +one regular and one attribute field. + +## Entries + +1. Attribute set name +2. Attribute set description +3. List of attribute entries with value and regular field range + +The values can be found in the reference file `structure.attributes.json`. diff --git a/structure/attributes/read.C b/structure/attributes/read.C new file mode 100644 index 0000000..81239ca --- /dev/null +++ b/structure/attributes/read.C @@ -0,0 +1,72 @@ +#include +#include + +#include + +void read(std::string_view input = "structure.attributes.root", + std::string_view output = "structure.attributes.json") { +#if ROOT_VERSION_CODE < ROOT_VERSION(6, 40, 0) + std::cout << "Skipped structure/attributes/read.C - ROOT version too old." + << std::endl; +#else + // same logic as is read_structure.hxx, with additional special part for + // attributes + std::unique_ptr reader; + try { + reader = ROOT::RNTupleReader::Open("ntpl", input); + } catch (const ROOT::RException &e) { + std::ofstream os(std::string{output}); + std::string msgWithoutStacktrace; + std::getline(std::istringstream(e.what()), msgWithoutStacktrace); + os << "{\n"; + os << " \"error\": \"" << msgWithoutStacktrace << "\"\n"; + os << "}\n"; + return; + } catch (const runtime_error &e) { + cout << "Skipped structure/attributes/read.C - " << e.what() << endl; + return; + } + + std::ofstream os(std::string{output}); + os << "[\n"; + auto Int32 = + reader->GetModel().GetDefaultEntry().GetPtr("Int32"); + bool first = true; + + auto attrSet = reader->OpenAttributeSet("Attributes"); + auto attr = attrSet->GetModel().GetDefaultEntry().GetPtr("attr"); + + os << " {\n"; + os << " \"Attribute set name\": \"" << attrSet->GetDescriptor().GetName() << "\"\n"; + os << " }, \n"; + os << " {\n"; + os << " \"Description\": \"" << attrSet->GetDescriptor().GetDescription() << "\"\n"; + os << " },\n"; + + // list of values for attr with its range + os << " {\n"; + os << " \"Attr\": " << "[\n"; + first = true; + for (auto attrIdx : attrSet->GetAttributes()) { + auto range = attrSet->LoadEntry(attrIdx); + os << " {\n"; + os << " \"Value\": " << *attr << ",\n"; + os << " \"Range\": [" << *range.GetFirst() << ", " << *range.GetLast() << "]\n"; + if (first) { + os << " },\n"; + first = false; + } else { + os << " }\n"; + } + std::cout << " attr = " << *attr << " (valid for range [" << *range.GetFirst() << ", " << *range.GetLast() << "])\n"; + } + os << " ]\n"; + os << " }"; + + if (!first) { + os << "\n"; + } + + os << "]\n"; +#endif +} diff --git a/structure/attributes/write.C b/structure/attributes/write.C new file mode 100644 index 0000000..4320e23 --- /dev/null +++ b/structure/attributes/write.C @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +#include +#include +#include + +void write(std::string_view filename = "structure.attributes.root") { +#if ROOT_VERSION_CODE < ROOT_VERSION(6, 40, 0) + std::cout << "Skipped structure/attributes/write.C - ROOT version too old." + << std::endl; +#else + auto model = ROOT::RNTupleModel::Create(); + auto Int32 = model->MakeField("Int32"); + + auto file = std::unique_ptr(TFile::Open(std::string(filename).c_str(), "RECREATE")); + auto writer = ROOT::RNTupleWriter::Append(std::move(model), "ntpl", *file); + + // definition of attribute set with attribute fields + auto attrModel = ROOT::RNTupleModel::Create(); + attrModel->SetDescription("Attribute set for testing"); + auto attr = attrModel->MakeField("attr"); + auto attrSet = writer->CreateAttributeSet(std::move(attrModel), "Attributes"); + + // first entry + auto attrRange = attrSet->BeginRange(); + *Int32 = 1; + writer->Fill(); + *attr = 1; + attrSet->CommitRange(std::move(attrRange)); + + // second and third entry + attrRange = attrSet->BeginRange(); + *attr = 2; + *Int32 = 2; + writer->Fill(); + *Int32 = 3; + writer->Fill(); + attrSet->CommitRange(std::move(attrRange)); +#endif +}