diff --git a/types/fundamental/README.md b/types/fundamental/README.md index 5da589c..68f0a02 100644 --- a/types/fundamental/README.md +++ b/types/fundamental/README.md @@ -4,10 +4,8 @@ * [`misc`](misc): `Bit`, `Byte`, `Char` * [`real`](real): `Real{16,32,64}`, `SplitReal{32,64}` * [`real32trunc`](real32trunc): `Real32Trunc` + * [`real32quant`](real32quant): `Real32Quant` __Covered under a different category:__ * `[Split]Index{32,64}`: with [`std::string`](../string) and [`std::vector`](../vector) * `Switch`: with [`std::variant`](../variant) - -__Missing:__ - * `Real32Quant` diff --git a/types/fundamental/real32quant/README.md b/types/fundamental/real32quant/README.md new file mode 100644 index 0000000..aa9bad9 --- /dev/null +++ b/types/fundamental/real32quant/README.md @@ -0,0 +1,21 @@ +# Real Column Types with variable width and value range + +## Fields + + * `FloatReal32Quant1` + * `FloatReal32Quant8` + * `FloatReal32Quant32` with value range `[-pi, pi]` (where `pi` is truncated to `float`) + * `DoubleReal32Quant8` + * `DoubleReal32Quant20` + * `DoubleReal32Quant32` with value range `[-100, 25]` + +with the corresponding field types, column type `Real32Quant`, with corresponding bit width +and a value range of `[-1, 1]` unless noted otherwise. + +## Entries + +1. Ascending values +2. All 1s in the mantissa +3. Middle values of the fields' value range +4. Min values of the fields' value range +5. Max values of the fields' value range diff --git a/types/fundamental/real32quant/read.C b/types/fundamental/real32quant/read.C new file mode 100644 index 0000000..1180ddf --- /dev/null +++ b/types/fundamental/real32quant/read.C @@ -0,0 +1,57 @@ +#include +#include + +using ROOT::Experimental::REntry; +using ROOT::Experimental::RNTupleReader; + +#include +#include +#include +#include +#include + +template +static void PrintRealValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + T value = *entry.GetPtr(name); + os << " \"" << name << "\": \"" << value << "\""; + if (!last) { + os << ","; + } + os << "\n"; +} + +void read(std::string_view input = "types.fundamental.real32quant.root", + std::string_view output = "types.fundamental.real32quant.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"; + + PrintRealValue(entry, "FloatReal32Quant1", os); + PrintRealValue(entry, "FloatReal32Quant8", os); + PrintRealValue(entry, "FloatReal32Quant32", os); + PrintRealValue(entry, "DoubleReal32Quant1", os); + PrintRealValue(entry, "DoubleReal32Quant20", os); + PrintRealValue(entry, "DoubleReal32Quant32", 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/types/fundamental/real32quant/write.C b/types/fundamental/real32quant/write.C new file mode 100644 index 0000000..395b734 --- /dev/null +++ b/types/fundamental/real32quant/write.C @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include + +using ROOT::Experimental::EColumnType; +using ROOT::Experimental::RField; +using ROOT::Experimental::RNTupleModel; +using ROOT::Experimental::RNTupleWriteOptions; +using ROOT::Experimental::RNTupleWriter; + +#include +#include +#include + +static constexpr double pi = 3.14159265358979323846; + +template +static std::shared_ptr MakeFieldReal32Quant(RNTupleModel &model, + std::string_view name, + int nBits, double min, double max) { + assert(nBits >= 1 && nBits <= 32); + assert(max > min); + auto field = std::make_unique>(name); + field->SetQuantized(min, max, nBits); + model.AddField(std::move(field)); + return model.GetDefaultEntry().GetPtr(name); +} + +void write(std::string_view filename = "types.fundamental.real32quant.root") { + auto model = RNTupleModel::Create(); + + auto FloatReal32Quant1 = + MakeFieldReal32Quant(*model, "FloatReal32Quant1", 1, -1, 1); + auto FloatReal32Quant8 = + MakeFieldReal32Quant(*model, "FloatReal32Quant8", 8, -1, 1); + auto FloatReal32Quant32 = + MakeFieldReal32Quant(*model, "FloatReal32Quant32", 32, -(float)pi, (float)pi); + auto DoubleReal32Quant1 = + MakeFieldReal32Quant(*model, "DoubleReal32Quant1", 1, -1, 1); + auto DoubleReal32Quant20 = + MakeFieldReal32Quant(*model, "DoubleReal32Quant20", 20, -1, 1); + auto DoubleReal32Quant32 = + MakeFieldReal32Quant(*model, "DoubleReal32Quant32", 32, -100, 25); + + RNTupleWriteOptions options; + options.SetCompression(0); + auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options); + + // First entry: ascending values + *FloatReal32Quant1 = -1.0f; + *FloatReal32Quant8 = -0.5f; + *FloatReal32Quant32 = 0.25f; + *DoubleReal32Quant1 = 0.5; + *DoubleReal32Quant20 = 1.0; + *DoubleReal32Quant32 = 2.0; + writer->Fill(); + + // Second entry: a value containing all 1s in the mantissa + static constexpr float ValueAllOnes = 2.3509885e-38f; + *FloatReal32Quant1 = ValueAllOnes; + *FloatReal32Quant8 = ValueAllOnes; + *FloatReal32Quant32 = ValueAllOnes; + *DoubleReal32Quant1 = ValueAllOnes; + *DoubleReal32Quant20 = ValueAllOnes; + *DoubleReal32Quant32 = ValueAllOnes; + writer->Fill(); + + // Third entry: middle values of the value range + *FloatReal32Quant1 = 0; + *FloatReal32Quant8 = 0; + *FloatReal32Quant32 = 0; + *DoubleReal32Quant1 = 0; + *DoubleReal32Quant20 = 0; + *DoubleReal32Quant32 = -37.5; + writer->Fill(); + + // Fourth entry: min values + *FloatReal32Quant1 = -1; + *FloatReal32Quant8 = -1; + *FloatReal32Quant32 = -pi; + *DoubleReal32Quant1 = -1; + *DoubleReal32Quant20 = -1; + *DoubleReal32Quant32 = -100; + writer->Fill(); + + // Fifth entry: max values + *FloatReal32Quant1 = 1; + *FloatReal32Quant8 = 1; + *FloatReal32Quant32 = pi; + *DoubleReal32Quant1 = 1; + *DoubleReal32Quant20 = 1; + *DoubleReal32Quant32 = 25; + writer->Fill(); +}