refactored, yet to take out checkers
Build on RHEL9 docker image / build (push) Successful in 4m51s
Build on RHEL8 docker image / build (push) Successful in 5m57s
Run Simulator Tests on local RHEL9 / build (push) Successful in 18m14s
Run Simulator Tests on local RHEL8 / build (push) Successful in 21m53s

This commit is contained in:
2026-05-19 17:10:03 +02:00
parent 6f65a6d486
commit eb2554cf3e
9 changed files with 382 additions and 393 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-global.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-acquire.cpp
${CMAKE_CURRENT_SOURCE_DIR}/master_file/Readers.cpp
# ${CMAKE_CURRENT_SOURCE_DIR}/master_file/Readers.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-master-attributes.cpp
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "master_file/Context.h"
#include "master_file/Readers.h"
#include "master_file/ReadersJson.h"
#ifdef HDF5C
#include "master_file/ReadersH5.h"
#endif
#include "Caller.h"
#include "MasterAttributes.h"
@@ -23,7 +26,6 @@
#ifdef HDF5C
#include "H5Cpp.h"
const std::string HDF5_GROUP = "/entry/instrument/detector/";
#endif
namespace sls {
@@ -41,40 +43,26 @@ inline bool operator==(sls::ns lhs, sls::ns rhs) {
return lhs.count() == rhs.count();
}
/** test parameter in file */
template <typename T>
void test_json_parameter(const Document &doc, const std::string &name,
const T &expected) {
REQUIRE(doc.HasMember(name.c_str()));
T retval{};
mf::read_from_json(doc, name, retval);
REQUIRE(retval == expected);
}
#ifdef HDF5C
template <typename T>
void test_h5_dataset(const std::string &name, const T &expected) {
REQUIRE(h5ctx.has_value());
auto dataset = h5ctx->file.openDataSet(HDF5_GROUP + name);
T retval{};
mf::read_from_h5_dataset(dataset, name, retval);
// auto retval = mf::read<mf::H5Doc, T>(mf::H5Doc{dataset}, name);
REQUIRE(retval == expected);
}
#endif
template <typename T>
void check_master_file(const std::optional<Document> &doc,
const std::string &name, const T &expected) {
if (doc.has_value()) {
if (doc) {
const auto &d = *doc;
test_json_parameter(d, name, expected);
REQUIRE(d.HasMember(name.c_str()));
mf::JsonContext ctx{d};
auto retval = mf::read<mf::JsonContext, T>(ctx, name);
REQUIRE(retval == expected);
} else {
#ifdef HDF5C
if (!h5ctx.has_value()) {
throw sls::RuntimeError("HDF5 file is not opened for testing " +
name);
}
test_h5_dataset(name, expected);
REQUIRE(h5ctx.has_value());
// require hdf5 has dataset with this name
// REQUIRE(h5ctx.)
auto retval = mf::read<mf::H5Context, T>(*h5ctx, name);
REQUIRE(retval == expected);
#else
throw sls::RuntimeError("Document is not available for testing " +
name);
@@ -86,12 +74,12 @@ void test_master_file_version(const Detector &det,
const std::optional<Document> &doc) {
// different values for json and hdf5
// hdf5 version in atttribute and not dataset
double retval{};
std::string name = MasterAttributes::N_VERSION.data();
if (doc.has_value()) {
const auto name = MasterAttributes::N_VERSION.data();
if (doc) {
const auto &d = *doc;
REQUIRE(d.HasMember(MasterAttributes::N_VERSION.data()));
mf::read_from_json(d, name, retval);
REQUIRE(d.HasMember(name));
mf::JsonContext ctx{d};
double retval = mf::read<mf::JsonContext, double>(ctx, name);
REQUIRE(retval == BINARY_WRITER_VERSION);
} else {
#ifdef HDF5C
@@ -101,6 +89,7 @@ void test_master_file_version(const Detector &det,
}
auto attr =
h5ctx->file.openAttribute(MasterAttributes::N_VERSION.data());
double retval{};
attr.read(attr.getDataType(), &retval);
REQUIRE(retval == HDF5_WRITER_VERSION);
#else
@@ -13,7 +13,7 @@
namespace sls::test::master_file {
struct JsonContext {
rapidjson::Document doc;
const rapidjson::Document &doc;
};
#ifdef HDF5C
struct H5Context {
@@ -1,272 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "Readers.h"
#include "sls/ToString.h"
namespace sls::test::master_file {
/* --scalar reads-- */
/** std::string */
void read_from_json(const Document &doc, const std::string &name,
std::string &out) {
out = doc[name.c_str()].GetString();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
std::string &out) {
ds.read(out, ds.getStrType());
}
#endif
/** int */
void read_from_json(const Document &doc, const std::string &name, int &out) {
out = doc[name.c_str()].GetInt();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
int &out) {
ds.read(&out, H5::PredType::NATIVE_INT);
}
#endif
/** uint32_t */
void read_from_json(const Document &doc, const std::string &name,
uint32_t &out) {
out = doc[name.c_str()].GetUint();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
uint32_t &out) {
ds.read(&out, H5::PredType::STD_U32LE);
}
#endif
/** uint64_t */
void read_from_json(const Document &doc, const std::string &name,
uint64_t &out) {
out = doc[name.c_str()].GetUint64();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
uint64_t &out) {
ds.read(&out, H5::PredType::STD_U64LE);
}
#endif
/** double */
void read_from_json(const Document &doc, const std::string &name, double &out) {
out = doc[name.c_str()].GetDouble();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
double &out) {
ds.read(&out, H5::PredType::NATIVE_DOUBLE);
}
#endif
/** vector<string> */
/** std::vector<int64_t> */
void read_from_json(const Document &doc, const std::string &name,
std::vector<int64_t> &out) {
for (const auto &item : doc[name.c_str()].GetArray()) {
out.push_back(item.GetInt64());
}
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
std::vector<int64_t> &out) {
H5::DataSpace dataspace = ds.getSpace();
hsize_t dims[1];
dataspace.getSimpleExtentDims(dims);
out.resize(dims[0]);
ds.read(out.data(), H5::PredType::STD_I64LE);
}
#endif
/* ---arrays/ maps--- */
/** std::array<int, 3UL> */
void read_from_json(const Document &doc, const std::string &name,
std::array<int, 3UL> &out) {
const auto &json_values = doc[name.c_str()].GetArray();
auto len = json_values.Size();
if (len != 3) {
throw sls::RuntimeError("JSON array " + name + " has " +
std::to_string(len) +
" elements instead of 3.");
}
int index = 0;
for (const auto &item : json_values) {
out[index++] = item.GetInt();
}
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
std::array<int, 3UL> &out) {
H5::DataSpace dataspace = ds.getSpace();
hsize_t dims[1];
dataspace.getSimpleExtentDims(dims);
auto len = dims[0];
if (len != 3) {
throw sls::RuntimeError("HDF5 dataset " + name + " has " +
std::to_string(len) +
" elements instead of 3.");
}
ds.read(out.data(), H5::PredType::NATIVE_INT);
}
#endif
/* std::array<ns, 3UL> */
void read_from_json(const Document &doc, const std::string &name,
std::array<ns, 3UL> &out) {
const auto &json_values = doc[name.c_str()].GetArray();
auto len = json_values.Size();
if (len != 3) {
throw sls::RuntimeError("JSON array " + name + " has " +
std::to_string(len) +
" elements instead of 3.");
}
int index = 0;
for (const auto &item : json_values) {
std::string sval = item.GetString();
out[index++] = StringTo<ns>(sval);
}
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
std::array<ns, 3UL> &out) {
H5::DataSpace dataspace = ds.getSpace();
hsize_t dims[1];
dataspace.getSimpleExtentDims(dims);
auto len = dims[0];
if (len != 3) {
throw sls::RuntimeError("HDF5 dataset " + name + " has " +
std::to_string(len) +
" elements instead of 3.");
}
std::vector<const char *> strValues(dims[0]);
ds.read(strValues.data(), ds.getStrType());
for (size_t i = 0; i < dims[0]; ++i) {
out[i] = StringTo<ns>(strValues[i]);
}
}
#endif
/** std::map<std::string, std::string> */
void read_from_json(const Document &doc, const std::string &name,
std::map<std::string, std::string> &out) {
for (const auto &m : doc[name.c_str()].GetObject()) {
out[m.name.GetString()] = m.value.GetString();
}
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
std::map<std::string, std::string> &out) {
H5::DataSpace dataspace = ds.getSpace();
hsize_t dims[1];
dataspace.getSimpleExtentDims(dims);
if (dims[0] == 0) {
return; // empty ds
}
auto strType = ds.getStrType();
H5::CompType mapType(sizeof(char *) * 2);
mapType.insertMember("key", 0, strType);
mapType.insertMember("value", sizeof(char *), strType);
struct KeyValue {
const char *key;
const char *value;
};
std::vector<KeyValue> kv_vector(dims[0]);
ds.read(kv_vector.data(), mapType);
for (const auto &kv : kv_vector) {
out[kv.key] = kv.value;
}
}
#endif
/** complex types */
/* std::vector<ROI> */
void read_from_json(const Document &doc, const std::string &name,
std::vector<defs::ROI> &out) {
for (const auto &item : doc[name.c_str()].GetArray()) {
defs::ROI r{};
r.xmin = item["xmin"].GetInt();
r.xmax = item["xmax"].GetInt();
r.ymin = item["ymin"].GetInt();
r.ymax = item["ymax"].GetInt();
out.push_back(r);
}
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
std::vector<defs::ROI> &out) {
H5::DataSpace space = ds.getSpace();
hsize_t dims[1];
space.getSimpleExtentDims(dims);
H5::CompType type(sizeof(defs::ROI));
type.insertMember("xmin", HOFFSET(defs::ROI, xmin),
H5::PredType::NATIVE_INT);
type.insertMember("xmax", HOFFSET(defs::ROI, xmax),
H5::PredType::NATIVE_INT);
type.insertMember("ymin", HOFFSET(defs::ROI, ymin),
H5::PredType::NATIVE_INT);
type.insertMember("ymax", HOFFSET(defs::ROI, ymax),
H5::PredType::NATIVE_INT);
out.resize(dims[0]);
ds.read(out.data(), type);
}
#endif
/** defs::xy */
void read_from_json(const Document &doc, const std::string &name,
defs::xy &out) {
out.x = doc[name.c_str()]["x"].GetInt();
out.y = doc[name.c_str()]["y"].GetInt();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
defs::xy &out) {
H5::CompType type(sizeof(defs::xy));
type.insertMember("x", HOFFSET(defs::xy, x), H5::PredType::NATIVE_INT);
type.insertMember("y", HOFFSET(defs::xy, y), H5::PredType::NATIVE_INT);
ds.read(&out, type);
}
#endif
/** defs::scanParameters */
void read_from_json(const Document &doc, const std::string &name,
defs::scanParameters &out) {
const auto &s = doc[name.c_str()].GetObject();
out.enable = s["enable"].GetInt();
out.dacInd = static_cast<defs::dacIndex>(s["dacInd"].GetInt());
out.startOffset = s["start offset"].GetInt();
out.stopOffset = s["stop offset"].GetInt();
out.stepSize = s["step size"].GetInt();
out.dacSettleTime_ns = s["dac settle time ns"].GetInt64();
}
#ifdef HDF5C
void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name,
defs::scanParameters &out) {
H5::CompType cType(sizeof(defs::scanParameters));
cType.insertMember("enable", HOFFSET(defs::scanParameters, enable),
H5::PredType::NATIVE_INT);
cType.insertMember("dacInd", HOFFSET(defs::scanParameters, dacInd),
H5::PredType::NATIVE_INT);
cType.insertMember("startOffset",
HOFFSET(defs::scanParameters, startOffset),
H5::PredType::NATIVE_INT);
cType.insertMember("stopOffset", HOFFSET(defs::scanParameters, stopOffset),
H5::PredType::NATIVE_INT);
cType.insertMember("stepSize", HOFFSET(defs::scanParameters, stepSize),
H5::PredType::NATIVE_INT);
cType.insertMember("dacSettleTime_ns",
HOFFSET(defs::scanParameters, dacSettleTime_ns),
H5::PredType::STD_I64LE);
ds.read(&out, cType);
}
#endif
} // namespace sls::test::master_file
@@ -3,14 +3,10 @@
#pragma once
#include "Context.h"
#ifdef HDF5C
#include "H5Cpp.h"
#endif
#include <rapidjson/document.h>
#include "sls/sls_detector_defs.h"
namespace sls::test::master_file {
template <typename Context, typename T> struct Reader;
template <typename Context, typename T>
@@ -18,4 +14,13 @@ T read(const Context &ctx, const std::string &name) {
return Reader<Context, T>::read(ctx, name);
}
inline void check_size(size_t actual, size_t expected, const std::string &name,
const std::string &doc) {
if (actual != expected) {
throw sls::RuntimeError(
doc + " array " + name + " has " + std::to_string(actual) +
" elements instead of " + std::to_string(expected));
}
}
} // namespace sls::test::master_file
@@ -1,25 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "Readers.h"
#ifdef HDF5C
namespace sls::test::master_file {
template <>
struct Reader<H5Context, int> {
static int read(const H5Context& ctx,
const std::string& name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
int out{};
ds.read(&out, H5::PredType::NATIVE_INT);
return out;
}
};
} // namespace sls::test::master_file
#endif
@@ -0,0 +1,211 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "Readers.h"
#include "sls/sls_detector_defs.h"
#ifdef HDF5C
#include "H5Cpp.h"
namespace sls::test::master_file {
using ns = std::chrono::nanoseconds;
const std::string HDF5_GROUP = "/entry/instrument/detector/";
/* --scalar reads-- */
template <> struct Reader<H5Context, int> {
static int read(const H5Context &ctx, const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
int out{};
ds.read(&out, H5::PredType::NATIVE_INT);
return out;
}
};
template <> struct Reader<H5Context, uint32_t> {
static uint32_t read(const H5Context &ctx, const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
uint32_t out{};
ds.read(&out, H5::PredType::STD_U32LE);
return out;
}
};
template <> struct Reader<H5Context, uint64_t> {
static uint64_t read(const H5Context &ctx, const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
uint64_t out{};
ds.read(&out, H5::PredType::STD_U64LE);
return out;
}
};
template <> struct Reader<H5Context, double> {
static double read(const H5Context &ctx, const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
double out{};
ds.read(&out, H5::PredType::NATIVE_DOUBLE);
return out;
}
};
template <> struct Reader<H5Context, std::string> {
static std::string read(const H5Context &ctx, const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
std::string out{};
ds.read(out, ds.getStrType());
return out;
}
};
/** complex types */
template <> struct Reader<H5Context, defs::xy> {
static defs::xy read(const H5Context &ctx, const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
// define type
H5::CompType type(sizeof(defs::xy));
type.insertMember("x", HOFFSET(defs::xy, x), H5::PredType::NATIVE_INT);
type.insertMember("y", HOFFSET(defs::xy, y), H5::PredType::NATIVE_INT);
// read
defs::xy out{};
ds.read(&out, type);
return out;
}
};
inline hsize_t get_1d_size(const H5::DataSet &ds) {
H5::DataSpace space = ds.getSpace();
hsize_t dims[1];
space.getSimpleExtentDims(dims);
return dims[0];
}
template <> struct Reader<H5Context, std::vector<defs::ROI>> {
static std::vector<defs::ROI> read(const H5Context &ctx,
const std::string &name) {
// define type
H5::CompType type(sizeof(defs::ROI));
type.insertMember("xmin", HOFFSET(defs::ROI, xmin),
H5::PredType::NATIVE_INT);
type.insertMember("xmax", HOFFSET(defs::ROI, xmax),
H5::PredType::NATIVE_INT);
type.insertMember("ymin", HOFFSET(defs::ROI, ymin),
H5::PredType::NATIVE_INT);
type.insertMember("ymax", HOFFSET(defs::ROI, ymax),
H5::PredType::NATIVE_INT);
// read
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
auto len = get_1d_size(ds);
std::vector<defs::ROI> out{};
out.resize(len);
ds.read(out.data(), type);
return out;
}
};
template <> struct Reader<H5Context, defs::scanParameters> {
static defs::scanParameters read(const H5Context &ctx,
const std::string &name) {
// define type
H5::CompType type(sizeof(defs::scanParameters));
type.insertMember("enable", HOFFSET(defs::scanParameters, enable),
H5::PredType::NATIVE_INT);
type.insertMember("dacInd", HOFFSET(defs::scanParameters, dacInd),
H5::PredType::NATIVE_INT);
type.insertMember("startOffset",
HOFFSET(defs::scanParameters, startOffset),
H5::PredType::NATIVE_INT);
type.insertMember("stopOffset",
HOFFSET(defs::scanParameters, stopOffset),
H5::PredType::NATIVE_INT);
type.insertMember("stepSize", HOFFSET(defs::scanParameters, stepSize),
H5::PredType::NATIVE_INT);
type.insertMember("dacSettleTime_ns",
HOFFSET(defs::scanParameters, dacSettleTime_ns),
H5::PredType::STD_I64LE);
// read
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
defs::scanParameters out{};
ds.read(&out, type);
return out;
}
};
/** arrays/vectors/maps */
template <> struct Reader<H5Context, std::array<int, 3UL>> {
static std::array<int, 3UL> read(const H5Context &ctx,
const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
auto len = get_1d_size(ds);
check_size(len, 3, name, "HDF5");
std::array<int, 3UL> out{};
ds.read(out.data(), H5::PredType::NATIVE_INT);
return out;
}
};
template <> struct Reader<H5Context, std::array<ns, 3UL>> {
static std::array<ns, 3UL> read(const H5Context &ctx,
const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
auto len = get_1d_size(ds);
check_size(len, 3, name, "HDF5");
// read int raw char buffer
std::vector<const char *> raw(len);
ds.read(raw.data(), ds.getStrType());
std::array<ns, 3UL> out{};
for (size_t i = 0; i != len; ++i) {
out[i] = StringTo<ns>(raw[i]);
}
return out;
}
};
template <> struct Reader<H5Context, std::vector<int64_t>> {
static std::vector<int64_t> read(const H5Context &ctx,
const std::string &name) {
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
auto len = get_1d_size(ds);
std::vector<int64_t> out{};
out.resize(len);
ds.read(out.data(), H5::PredType::STD_I64LE);
return out;
}
};
template <> struct Reader<H5Context, std::map<std::string, std::string>> {
static std::map<std::string, std::string> read(const H5Context &ctx,
const std::string &name) {
std::map<std::string, std::string> out{};
// dim
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
auto len = get_1d_size(ds);
// empty ds
if (len == 0) {
return out;
}
// define type
auto strType = ds.getStrType();
H5::CompType mapType(sizeof(char *) * 2);
mapType.insertMember("key", 0, strType);
mapType.insertMember("value", sizeof(char *), strType);
struct KeyValue {
const char *key;
const char *value;
};
// read
std::vector<KeyValue> kv_vector(len);
ds.read(kv_vector.data(), mapType);
for (const auto &kv : kv_vector) {
out[kv.key] = kv.value;
}
return out;
}
};
} // namespace sls::test::master_file
#endif
@@ -1,57 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "Readers.h"
namespace sls::test::master_file {
/* --scalar reads-- */
template <>
struct Reader<JsonContext, int> {
static int read(const JsonContext &ctx, const std::string &name) {
return ctx.doc[name.c_str()].GetInt();
}
};
template<>
struct Reader<JsonContext, uint32_t> {
static uint32_t read(const JsonContext& ctx,
const std::string& name) {
return ctx.doc[name.c_str()].GetUint();
}
};
template<>
struct Reader<JsonContext, uint64_t> {
static uint64_t read(const JsonContext& ctx,
const std::string& name) {
return ctx.doc[name.c_str()].GetUint64();
}
};
template<>
struct Reader<JsonContext, double> {
static double read(const JsonContext& ctx,
const std::string& name) {
return ctx.doc[name.c_str()].GetDouble();
}
};
template<>
struct Reader<JsonContext, std::string> {
static std::string read(const JsonContext& ctx,
const std::string& name) {
return ctx.doc[name.c_str()].GetString();
}
};
} // namespace sls::test::master_file
@@ -0,0 +1,138 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "Readers.h"
#include "sls/ToString.h"
#include "sls/sls_detector_defs.h"
#include <rapidjson/document.h>
namespace sls::test::master_file {
using ns = std::chrono::nanoseconds;
/* --scalar reads-- */
template <> struct Reader<JsonContext, int> {
static int read(const JsonContext &ctx, const std::string &name) {
return ctx.doc[name.c_str()].GetInt();
}
};
template <> struct Reader<JsonContext, uint32_t> {
static uint32_t read(const JsonContext &ctx, const std::string &name) {
return ctx.doc[name.c_str()].GetUint();
}
};
template <> struct Reader<JsonContext, uint64_t> {
static uint64_t read(const JsonContext &ctx, const std::string &name) {
return ctx.doc[name.c_str()].GetUint64();
}
};
template <> struct Reader<JsonContext, double> {
static double read(const JsonContext &ctx, const std::string &name) {
return ctx.doc[name.c_str()].GetDouble();
}
};
template <> struct Reader<JsonContext, std::string> {
static std::string read(const JsonContext &ctx, const std::string &name) {
return ctx.doc[name.c_str()].GetString();
}
};
/** complex types */
template <> struct Reader<JsonContext, defs::xy> {
static defs::xy read(const JsonContext &ctx, const std::string &name) {
defs::xy out{};
out.x = ctx.doc[name.c_str()]["x"].GetInt();
out.y = ctx.doc[name.c_str()]["y"].GetInt();
return out;
}
};
template <> struct Reader<JsonContext, std::vector<defs::ROI>> {
static std::vector<defs::ROI> read(const JsonContext &ctx,
const std::string &name) {
std::vector<defs::ROI> out{};
for (const auto &item : ctx.doc[name.c_str()].GetArray()) {
defs::ROI r{};
r.xmin = item["xmin"].GetInt();
r.xmax = item["xmax"].GetInt();
r.ymin = item["ymin"].GetInt();
r.ymax = item["ymax"].GetInt();
out.push_back(r);
}
return out;
}
};
template <> struct Reader<JsonContext, defs::scanParameters> {
static defs::scanParameters read(const JsonContext &ctx,
const std::string &name) {
defs::scanParameters out{};
const auto &s = ctx.doc[name.c_str()].GetObject();
out.enable = s["enable"].GetInt();
out.dacInd = static_cast<defs::dacIndex>(s["dacInd"].GetInt());
out.startOffset = s["start offset"].GetInt();
out.stopOffset = s["stop offset"].GetInt();
out.stepSize = s["step size"].GetInt();
out.dacSettleTime_ns = s["dac settle time ns"].GetInt64();
return out;
}
};
/** arrays/vectors/maps */
template <> struct Reader<JsonContext, std::array<int, 3UL>> {
static std::array<int, 3UL> read(const JsonContext &ctx,
const std::string &name) {
const auto &arr = ctx.doc[name.c_str()].GetArray();
check_size(arr.Size(), 3, name, "JSON");
std::array<int, 3UL> out{};
for (size_t i = 0; i < 3; ++i) {
out[i] = arr[i].GetInt();
}
return out;
}
};
template <> struct Reader<JsonContext, std::array<ns, 3UL>> {
static std::array<ns, 3UL> read(const JsonContext &ctx,
const std::string &name) {
const auto &arr = ctx.doc[name.c_str()].GetArray();
check_size(arr.Size(), 3, name, "JSON");
std::array<ns, 3UL> out{};
for (size_t i = 0; i < 3; ++i) {
std::string sval = arr[i].GetString();
out[i] = StringTo<ns>(sval);
}
return out;
}
};
template <> struct Reader<JsonContext, std::vector<int64_t>> {
static std::vector<int64_t> read(const JsonContext &ctx,
const std::string &name) {
std::vector<int64_t> out{};
for (const auto &item : ctx.doc[name.c_str()].GetArray()) {
out.push_back(item.GetInt64());
}
return out;
}
};
template <> struct Reader<JsonContext, std::map<std::string, std::string>> {
static std::map<std::string, std::string> read(const JsonContext &ctx,
const std::string &name) {
std::map<std::string, std::string> out{};
for (const auto &m : ctx.doc[name.c_str()].GetObject()) {
out[m.name.GetString()] = m.value.GetString();
}
return out;
}
};
} // namespace sls::test::master_file