diff --git a/slsDetectorSoftware/tests/CMakeLists.txt b/slsDetectorSoftware/tests/CMakeLists.txt index f84c00c3d..681a6801d 100755 --- a/slsDetectorSoftware/tests/CMakeLists.txt +++ b/slsDetectorSoftware/tests/CMakeLists.txt @@ -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 diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-master-attributes.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-master-attributes.cpp index abdcbb6b5..5c16581a1 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-master-attributes.cpp +++ b/slsDetectorSoftware/tests/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 -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 -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{dataset}, name); - REQUIRE(retval == expected); -} -#endif - template void check_master_file(const std::optional &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(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(*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 &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(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 diff --git a/slsDetectorSoftware/tests/master_file/Context.h b/slsDetectorSoftware/tests/master_file/Context.h index e5fd13048..bbf37a31b 100644 --- a/slsDetectorSoftware/tests/master_file/Context.h +++ b/slsDetectorSoftware/tests/master_file/Context.h @@ -13,7 +13,7 @@ namespace sls::test::master_file { struct JsonContext { - rapidjson::Document doc; + const rapidjson::Document &doc; }; #ifdef HDF5C struct H5Context { diff --git a/slsDetectorSoftware/tests/master_file/Readers.cpp b/slsDetectorSoftware/tests/master_file/Readers.cpp deleted file mode 100644 index d9e14745c..000000000 --- a/slsDetectorSoftware/tests/master_file/Readers.cpp +++ /dev/null @@ -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 */ -/** std::vector */ -void read_from_json(const Document &doc, const std::string &name, - std::vector &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 &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 */ -void read_from_json(const Document &doc, const std::string &name, - std::array &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 &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 */ -void read_from_json(const Document &doc, const std::string &name, - std::array &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(sval); - } -} -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::array &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 strValues(dims[0]); - ds.read(strValues.data(), ds.getStrType()); - for (size_t i = 0; i < dims[0]; ++i) { - out[i] = StringTo(strValues[i]); - } -} -#endif - -/** std::map */ -void read_from_json(const Document &doc, const std::string &name, - std::map &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 &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 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 */ -void read_from_json(const Document &doc, const std::string &name, - std::vector &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 &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(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 diff --git a/slsDetectorSoftware/tests/master_file/Readers.h b/slsDetectorSoftware/tests/master_file/Readers.h index 84b160fb9..a9fbaa724 100644 --- a/slsDetectorSoftware/tests/master_file/Readers.h +++ b/slsDetectorSoftware/tests/master_file/Readers.h @@ -3,14 +3,10 @@ #pragma once #include "Context.h" - -#ifdef HDF5C -#include "H5Cpp.h" -#endif - -#include +#include "sls/sls_detector_defs.h" namespace sls::test::master_file { + template struct Reader; template @@ -18,4 +14,13 @@ T read(const Context &ctx, const std::string &name) { return Reader::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 diff --git a/slsDetectorSoftware/tests/master_file/ReadersH5.cpp b/slsDetectorSoftware/tests/master_file/ReadersH5.cpp deleted file mode 100644 index 647197b6b..000000000 --- a/slsDetectorSoftware/tests/master_file/ReadersH5.cpp +++ /dev/null @@ -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 { - - 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 \ No newline at end of file diff --git a/slsDetectorSoftware/tests/master_file/ReadersH5.h b/slsDetectorSoftware/tests/master_file/ReadersH5.h new file mode 100644 index 000000000..c7690d394 --- /dev/null +++ b/slsDetectorSoftware/tests/master_file/ReadersH5.h @@ -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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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> { + static std::vector 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 out{}; + out.resize(len); + ds.read(out.data(), type); + return out; + } +}; + +template <> struct Reader { + 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> { + static std::array 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 out{}; + ds.read(out.data(), H5::PredType::NATIVE_INT); + return out; + } +}; + +template <> struct Reader> { + static std::array 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 raw(len); + ds.read(raw.data(), ds.getStrType()); + + std::array out{}; + for (size_t i = 0; i != len; ++i) { + out[i] = StringTo(raw[i]); + } + return out; + } +}; + +template <> struct Reader> { + static std::vector read(const H5Context &ctx, + const std::string &name) { + auto ds = ctx.file.openDataSet(HDF5_GROUP + name); + auto len = get_1d_size(ds); + std::vector out{}; + out.resize(len); + ds.read(out.data(), H5::PredType::STD_I64LE); + return out; + } +}; + +template <> struct Reader> { + static std::map read(const H5Context &ctx, + const std::string &name) { + std::map 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 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 \ No newline at end of file diff --git a/slsDetectorSoftware/tests/master_file/ReadersJson.cpp b/slsDetectorSoftware/tests/master_file/ReadersJson.cpp deleted file mode 100644 index 5fb2c7584..000000000 --- a/slsDetectorSoftware/tests/master_file/ReadersJson.cpp +++ /dev/null @@ -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 { - static int read(const JsonContext &ctx, const std::string &name) { - return ctx.doc[name.c_str()].GetInt(); - } -}; - -template<> -struct Reader { - - static uint32_t read(const JsonContext& ctx, - const std::string& name) { - - return ctx.doc[name.c_str()].GetUint(); - - } -}; - -template<> -struct Reader { - - static uint64_t read(const JsonContext& ctx, - const std::string& name) { - - return ctx.doc[name.c_str()].GetUint64(); - } -}; - -template<> -struct Reader { - - static double read(const JsonContext& ctx, - const std::string& name) { - - return ctx.doc[name.c_str()].GetDouble(); - } -}; - -template<> -struct Reader { - - static std::string read(const JsonContext& ctx, - const std::string& name) { - - return ctx.doc[name.c_str()].GetString(); - } -}; - -} // namespace sls::test::master_file \ No newline at end of file diff --git a/slsDetectorSoftware/tests/master_file/ReadersJson.h b/slsDetectorSoftware/tests/master_file/ReadersJson.h new file mode 100644 index 000000000..924c04bd9 --- /dev/null +++ b/slsDetectorSoftware/tests/master_file/ReadersJson.h @@ -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 + +namespace sls::test::master_file { +using ns = std::chrono::nanoseconds; + +/* --scalar reads-- */ +template <> struct Reader { + static int read(const JsonContext &ctx, const std::string &name) { + return ctx.doc[name.c_str()].GetInt(); + } +}; + +template <> struct Reader { + static uint32_t read(const JsonContext &ctx, const std::string &name) { + return ctx.doc[name.c_str()].GetUint(); + } +}; + +template <> struct Reader { + static uint64_t read(const JsonContext &ctx, const std::string &name) { + return ctx.doc[name.c_str()].GetUint64(); + } +}; + +template <> struct Reader { + static double read(const JsonContext &ctx, const std::string &name) { + return ctx.doc[name.c_str()].GetDouble(); + } +}; + +template <> struct Reader { + static std::string read(const JsonContext &ctx, const std::string &name) { + return ctx.doc[name.c_str()].GetString(); + } +}; + +/** complex types */ +template <> struct Reader { + 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> { + static std::vector read(const JsonContext &ctx, + const std::string &name) { + std::vector 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 { + 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(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> { + static std::array 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 out{}; + for (size_t i = 0; i < 3; ++i) { + out[i] = arr[i].GetInt(); + } + return out; + } +}; + +template <> struct Reader> { + static std::array 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 out{}; + for (size_t i = 0; i < 3; ++i) { + std::string sval = arr[i].GetString(); + out[i] = StringTo(sval); + } + return out; + } +}; + +template <> struct Reader> { + static std::vector read(const JsonContext &ctx, + const std::string &name) { + std::vector out{}; + for (const auto &item : ctx.doc[name.c_str()].GetArray()) { + out.push_back(item.GetInt64()); + } + return out; + } +}; + +template <> struct Reader> { + static std::map read(const JsonContext &ctx, + const std::string &name) { + std::map 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 \ No newline at end of file