diff --git a/structure/attributes/README.md b/structure/attributes/README.md new file mode 100644 index 0000000..aa46432 --- /dev/null +++ b/structure/attributes/README.md @@ -0,0 +1,14 @@ +# Attributes + +## Fields + + * `Int{32}` + +one regular and one attribute field. + +## Entries + +1. Simple values +2. Zero / empty values + +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..82fd2fd --- /dev/null +++ b/structure/attributes/read.C @@ -0,0 +1,127 @@ +#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; + // for (auto index : *reader) { + // reader->LoadEntry(index); + + // if (first) { + // first = false; + // } else { + // os << ",\n"; + // } + // os << " {\n"; + // os << " \"Int32\": " << *Int32 << "\n"; + // os << " }"; + // // Newline is intentionally missing, may need to print a comma before the + // // next entry. + // } + + // // read available attribute sets + // for (const auto &attrSetDesc : reader->GetDescriptor().GetAttrSetIterable()) { + // os << ",\n"; + // os << " {\n"; + // os << " \"Attribute set\": \"" << attrSetDesc.GetName() << "\"\n"; + // os << " }"; + // } + + // auto attrSet = reader->OpenAttributeSet("Attributes"); + // os << ",\n"; + // os << " {\n"; + // os << " \"Description\": \"" << attrSet->GetDescriptor().GetDescription() << "\"\n"; + // os << " }"; + + // auto attr = attrSet->GetModel().GetDefaultEntry().GetPtr("attr"); + + // for (auto idx : reader->GetEntryRange()) { + // std::cout << "Entry " << idx << " has the following attributes associated to it:\n"; + // for (auto attrIdx : attrSet->GetAttributes(idx)) { + // auto range = attrSet->LoadEntry(attrIdx); + // std::cout << " runNumber = " << *attr << " (valid for range [" << *range.GetFirst() << ", " + // << *range.GetLast() << "])\n"; + // } + // } + + auto attrSet = reader->OpenAttributeSet("Attributes"); + auto attr1 = attrSet->GetModel().GetDefaultEntry().GetPtr("attr1"); + auto attr2 = attrSet->GetModel().GetDefaultEntry().GetPtr("attr2"); + + std::cout << "\nOpened attribute set '" << attrSet->GetDescriptor().GetName() << "' with description: \"" + << attrSet->GetDescriptor().GetDescription() << "\"\n"; + + os << " {\n"; + os << " \"Attribute set name\": \"" << attrSet->GetDescriptor().GetName() << "\"\n"; + os << " }, \n"; + os << " {\n"; + os << " \"Description\": \"" << attrSet->GetDescriptor().GetDescription() << "\"\n"; + os << " },\n"; + + first = true; + for (auto mainIdx : reader->GetEntryRange()) { + reader->LoadEntry(mainIdx); + std::cout << "Entry " << mainIdx << " with value " << *Int32 << " has the following attributes associated to it:\n"; + + if (first) { + first = false; + } else { + os << ",\n"; + } + os << " {\n"; + os << " \"Int32\": " << *Int32 << "\n"; + os << " }"; + for (auto attrIdx : attrSet->GetAttributes(mainIdx)) { + auto range = attrSet->LoadEntry(attrIdx); + if (*attr1 > 0) { + os << ",\n {\n"; + os << " \"Attr1\": " << *attr1 << "\n"; + os << " }"; + } + if (*attr2 > 0) { + os << ",\n {\n"; + os << " \"Attr2\": " << *attr2 << "\n"; + os << " }"; + } + std::cout << " attr1 = " << *attr1 << " (valid for range [" << *range.GetFirst() << ", " + << *range.GetLast() << "])\n"; + std::cout << " attr2 = " << *attr2 << " (valid for range [" << *range.GetFirst() << ", " + << *range.GetLast() << "])\n"; + } + } + + 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..15992e7 --- /dev/null +++ b/structure/attributes/write.C @@ -0,0 +1,56 @@ +#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("Informationless description for attribute set"); + auto attr1 = attrModel->MakeField("attr1"); + auto attr2 = attrModel->MakeField("attr2"); + + // creation of attribute set + auto attrSet = writer->CreateAttributeSet(std::move(attrModel), "Attributes"); + auto attrRange = attrSet->BeginRange(); + *attr1 = 0; + *attr2 = 0; + + int num_entries = 3; + for (int i=0; iFill(); + + // attr1 attached to first entry, attr2 attached to second and third entry + if (i == 0) { + *attr1 = i+1; + attrSet->CommitRange(std::move(attrRange)); + attrRange = attrSet->BeginRange(); + *attr1 = 0; + } else { + *attr2 = i+1; + attrSet->CommitRange(std::move(attrRange)); + attrRange = attrSet->BeginRange(); + *attr2 = 0; + } + } + + if (attrRange) { + attrSet->CommitRange(std::move(attrRange)); + } +#endif +}