diff --git a/slsDetectorSoftware/tests/CMakeLists.txt b/slsDetectorSoftware/tests/CMakeLists.txt index 681a6801d..ff79d75db 100755 --- a/slsDetectorSoftware/tests/CMakeLists.txt +++ b/slsDetectorSoftware/tests/CMakeLists.txt @@ -19,7 +19,6 @@ 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}/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 5c16581a1..556dddb81 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-master-attributes.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-master-attributes.cpp @@ -5,6 +5,7 @@ #ifdef HDF5C #include "master_file/ReadersH5.h" #endif +#include "master_file/Checker.h" #include "Caller.h" #include "MasterAttributes.h" @@ -36,95 +37,59 @@ using namespace rapidjson; namespace mf = test::master_file; #ifdef HDF5C -std::optional h5ctx; + #endif inline bool operator==(sls::ns lhs, sls::ns rhs) { return lhs.count() == rhs.count(); } -template -void check_master_file(const std::optional &doc, - const std::string &name, const T &expected) { - if (doc) { - const auto &d = *doc; - 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); - } - 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); -#endif - } -} +// different values for json and hdf5 => need to specialize separately +template +void test_master_file_version(const Detector &det, CheckerT &checker); -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 - const auto name = MasterAttributes::N_VERSION.data(); - if (doc) { - const auto &d = *doc; - REQUIRE(d.HasMember(name)); - mf::JsonContext ctx{d}; - double retval = mf::read(ctx, name); - REQUIRE(retval == BINARY_WRITER_VERSION); - } else { -#ifdef HDF5C - if (!h5ctx.has_value()) { - throw sls::RuntimeError( - "HDF5 file is not opened for testing Version"); - } - auto attr = - h5ctx->file.openAttribute(MasterAttributes::N_VERSION.data()); - double retval{}; - attr.read(attr.getDataType(), &retval); - REQUIRE(retval == HDF5_WRITER_VERSION); -#else - throw sls::RuntimeError( - "Document is not available for testing Version"); -#endif - } +template <> +void test_master_file_version>( + const Detector &det, mf::Checker &checker) { + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_VERSION.data(), BINARY_WRITER_VERSION)); } +#ifdef HDF5C +template <> +void test_master_file_version>( + const Detector &det, mf::Checker &checker) { + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_VERSION.data(), HDF5_WRITER_VERSION, + mf::AccessType::Attribute)); +} +#endif -void test_master_file_type(const Detector &det, - const std::optional &doc) { +template +void test_master_file_type(const Detector &det, CheckerT &checker) { auto det_type = det.getDetectorType().tsquash("Inconsistent detector type"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DETECTOR_TYPE.data(), ToString(det_type))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DETECTOR_TYPE.data(), ToString(det_type))); } -void test_master_file_timing_mode(const Detector &det, - const std::optional &doc) { +template +void test_master_file_timing_mode(const Detector &det, CheckerT &checker) { auto timing_mode = det.getTimingMode().tsquash("Inconsistent timing mode"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_TIMING_MODE.data(), ToString(timing_mode))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_TIMING_MODE.data(), ToString(timing_mode))); } -void test_master_file_geometry(const Detector &det, - const std::optional &doc) { +template +void test_master_file_geometry(const Detector &det, CheckerT &checker) { auto modGeometry = det.getModuleGeometry(); auto portperModGeometry = det.getPortPerModuleGeometry(); auto geometry = defs::xy{modGeometry.x * portperModGeometry.x, modGeometry.y * portperModGeometry.y}; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_GEOMETRY.data(), geometry)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_GEOMETRY.data(), geometry)); } -void test_master_file_image_size(const Detector &det, - const std::optional &doc) { +template +void test_master_file_image_size(const Detector &det, CheckerT &checker) { auto det_type = det.getDetectorType().tsquash("Inconsistent detector types to test"); @@ -172,12 +137,12 @@ void test_master_file_image_size(const Detector &det, throw sls::RuntimeError("Unsupported detector type for this test"); } - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_IMAGE_SIZE.data(), image_size)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_IMAGE_SIZE.data(), image_size)); } -void test_master_file_det_size(const Detector &det, - const std::optional &doc) { +template +void test_master_file_det_size(const Detector &det, CheckerT &checker) { auto det_type = det.getDetectorType().tsquash("Inconsistent detector types to test"); @@ -200,49 +165,49 @@ void test_master_file_det_size(const Detector &det, portSize.y = 1; } - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_PIXELS.data(), portSize)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_PIXELS.data(), portSize)); } +template void test_master_file_max_frames_per_file(const Detector &det, - const std::optional &doc) { + CheckerT &checker) { auto max_frames_per_file = det.getFramesPerFile().tsquash("Inconsistent max frames per file"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_MAX_FRAMES_PER_FILE.data(), - max_frames_per_file)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_MAX_FRAMES_PER_FILE.data(), max_frames_per_file)); } +template void test_master_file_frame_discard_policy(const Detector &det, - const std::optional &doc) { + CheckerT &checker) { auto policy = det.getRxFrameDiscardPolicy().tsquash( "Inconsistent frame discard policy"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_FRAME_DISCARD_POLICY.data(), - ToString(policy))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_FRAME_DISCARD_POLICY.data(), ToString(policy))); } -void test_master_file_frame_padding(const Detector &det, - const std::optional &doc) { +template +void test_master_file_frame_padding(const Detector &det, CheckerT &checker) { auto padding = static_cast( det.getPartialFramesPadding().tsquash("Inconsistent frame padding")); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_FRAME_PADDING.data(), padding)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_FRAME_PADDING.data(), padding)); } -void test_master_file_scan_parameters(const Detector &det, - const std::optional &doc) { +template +void test_master_file_scan_parameters(const Detector &det, CheckerT &checker) { auto scan_params = det.getScan().tsquash("Inconsistent scan parameters"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_SCAN_PARAMETERS.data(), scan_params)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_SCAN_PARAMETERS.data(), scan_params)); } -void test_master_file_total_frames(const Detector &det, - const std::optional &doc) { +template +void test_master_file_total_frames(const Detector &det, CheckerT &checker) { uint64_t repeats = det.getNumberOfTriggers().tsquash("Inconsistent number of triggers"); uint64_t numFrames = @@ -284,12 +249,12 @@ void test_master_file_total_frames(const Detector &det, uint64_t total_frames = numFrames * repeats * (int64_t)(numAdditionalStorageCells + 1); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_TOTAL_FRAMES.data(), total_frames)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_TOTAL_FRAMES.data(), total_frames)); } -void test_master_file_rois(const Detector &det, - const std::optional &doc) { +template +void test_master_file_rois(const Detector &det, CheckerT &checker) { auto rois = det.getRxROI(); auto detsize = det.getDetectorSize(); auto det_type = @@ -315,189 +280,188 @@ void test_master_file_rois(const Detector &det, } } - REQUIRE_NOTHROW(check_master_file>( - doc, MasterAttributes::N_RECEIVER_ROIS.data(), rois)); + REQUIRE_NOTHROW(checker.template check>( + MasterAttributes::N_RECEIVER_ROIS.data(), rois)); } -void test_master_file_exptime(const Detector &det, - const std::optional &doc) { +template +void test_master_file_exptime(const Detector &det, CheckerT &checker) { auto exptime = det.getExptime().tsquash("Inconsistent exposure time"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_EXPOSURE_TIME.data(), ToString(exptime))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_EXPOSURE_TIME.data(), ToString(exptime))); } -void test_master_file_period(const Detector &det, - const std::optional &doc) { +template +void test_master_file_period(const Detector &det, CheckerT &checker) { auto period = det.getPeriod().tsquash("Inconsistent period"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_ACQUISITION_PERIOD.data(), ToString(period))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_ACQUISITION_PERIOD.data(), ToString(period))); } +template void test_master_file_num_udp_interfaces(const Detector &det, - const std::optional &doc) { + CheckerT &checker) { auto num_udp_interfaces = det.getNumberofUDPInterfaces().tsquash( "Inconsistent number of UDP interfaces"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_NUM_UDP_INTERFACES.data(), - num_udp_interfaces)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_NUM_UDP_INTERFACES.data(), num_udp_interfaces)); } -void test_master_file_read_n_rows(const Detector &det, - const std::optional &doc) { +template +void test_master_file_read_n_rows(const Detector &det, CheckerT &checker) { auto readnrows = det.getReadNRows().tsquash("Inconsistent number of rows"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_NUMBER_OF_ROWS.data(), readnrows)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_NUMBER_OF_ROWS.data(), readnrows)); } -void test_master_file_readout_speed(const Detector &det, - const std::optional &doc) { +template +void test_master_file_readout_speed(const Detector &det, CheckerT &checker) { auto readout_speed = det.getReadoutSpeed().tsquash("Inconsistent readout speed"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_READOUT_SPEED.data(), - ToString(readout_speed))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_READOUT_SPEED.data(), ToString(readout_speed))); } -void test_master_file_frames_in_file(const std::optional &doc, +template +void test_master_file_frames_in_file(CheckerT &checker, const int frames_in_file) { - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_FRAMES_IN_FILE.data(), frames_in_file)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_FRAMES_IN_FILE.data(), frames_in_file)); } -void test_master_file_json_header(const Detector &det, - const std::optional &doc) { +template +void test_master_file_json_header(const Detector &det, CheckerT &checker) { auto json_header = det.getAdditionalJsonHeader().tsquash("Inconsistent JSON header"); - REQUIRE_NOTHROW(check_master_file>( - doc, MasterAttributes::N_ADDITIONAL_JSON_HEADER.data(), json_header)); + REQUIRE_NOTHROW(checker.template check>( + MasterAttributes::N_ADDITIONAL_JSON_HEADER.data(), json_header)); } -void test_master_file_dynamic_range(const Detector &det, - const std::optional &doc) { +template +void test_master_file_dynamic_range(const Detector &det, CheckerT &checker) { auto dr = det.getDynamicRange().tsquash("Inconsistent dynamic range"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DYNAMIC_RANGE.data(), dr)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DYNAMIC_RANGE.data(), dr)); } -void test_master_file_ten_giga(const Detector &det, - const std::optional &doc) { +template +void test_master_file_ten_giga(const Detector &det, CheckerT &checker) { auto ten_giga = static_cast(det.getTenGiga().tsquash("Inconsistent ten giga")); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_TEN_GIGA.data(), ten_giga)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_TEN_GIGA.data(), ten_giga)); } -void test_master_file_threshold_energy(const Detector &det, - const std::optional &doc) { +template +void test_master_file_threshold_energy(const Detector &det, CheckerT &checker) { auto threshold = det.getThresholdEnergy().tsquash("Inconsistent threshold energy"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_THRESHOLD_ENERGY.data(), threshold)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_THRESHOLD_ENERGY.data(), threshold)); } -void test_master_file_sub_exptime(const Detector &det, - const std::optional &doc) { +template +void test_master_file_sub_exptime(const Detector &det, CheckerT &checker) { auto sub_exptime = det.getSubExptime().tsquash("Inconsistent sub exposure time"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_SUB_EXPOSURE_TIME.data(), - ToString(sub_exptime))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_SUB_EXPOSURE_TIME.data(), ToString(sub_exptime))); } -void test_master_file_sub_period(const Detector &det, - const std::optional &doc) { +template +void test_master_file_sub_period(const Detector &det, CheckerT &checker) { auto exptime = det.getSubExptime().tsquash("Inconsistent sub exptime"); auto deadtime = det.getSubDeadTime().tsquash("Inconsistent sub deadtime"); auto sub_period = exptime + deadtime; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_SUB_ACQUISITION_PERIOD.data(), + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_SUB_ACQUISITION_PERIOD.data(), ToString(sub_period))); } -void test_master_file_quad(const Detector &det, - const std::optional &doc) { +template +void test_master_file_quad(const Detector &det, CheckerT &checker) { auto quad = static_cast(det.getQuad().tsquash("Inconsistent quad")); REQUIRE_NOTHROW( - check_master_file(doc, MasterAttributes::N_QUAD.data(), quad)); + checker.template check(MasterAttributes::N_QUAD.data(), quad)); } -void test_master_file_rate_corrections(const Detector &det, - const std::optional &doc) { +template +void test_master_file_rate_corrections(const Detector &det, CheckerT &checker) { std::vector dead_times; for (auto item : det.getRateCorrection()) dead_times.push_back(item.count()); - REQUIRE_NOTHROW(check_master_file>( - doc, MasterAttributes::N_RATE_CORRECTIONS.data(), dead_times)); + REQUIRE_NOTHROW(checker.template check>( + MasterAttributes::N_RATE_CORRECTIONS.data(), dead_times)); } -void test_master_file_counter_mask(const Detector &det, - const std::optional &doc) { +template +void test_master_file_counter_mask(const Detector &det, CheckerT &checker) { auto counter_mask = static_cast( det.getCounterMask().tsquash("Inconsistent counter mask")); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_COUNTER_MASK.data(), counter_mask)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_COUNTER_MASK.data(), counter_mask)); } -void test_master_file_exptimes(const Detector &det, - const std::optional &doc) { +template +void test_master_file_exptimes(const Detector &det, CheckerT &checker) { auto exptimes = det.getExptimeForAllGates().tsquash("Inconsistent exposure times"); - REQUIRE_NOTHROW(check_master_file>( - doc, MasterAttributes::N_EXPOSURE_TIMES.data(), exptimes)); + REQUIRE_NOTHROW(checker.template check>( + MasterAttributes::N_EXPOSURE_TIMES.data(), exptimes)); } -void test_master_file_gate_delays(const Detector &det, - const std::optional &doc) { +template +void test_master_file_gate_delays(const Detector &det, CheckerT &checker) { auto gate_delays = det.getGateDelayForAllGates().tsquash("Inconsistent GateDelay"); - REQUIRE_NOTHROW(check_master_file>( - doc, MasterAttributes::N_GATE_DELAYS.data(), gate_delays)); + REQUIRE_NOTHROW(checker.template check>( + MasterAttributes::N_GATE_DELAYS.data(), gate_delays)); } -void test_master_file_gates(const Detector &det, - const std::optional &doc) { +template +void test_master_file_gates(const Detector &det, CheckerT &checker) { auto gates = det.getNumberOfGates().tsquash("Inconsistent number of gates"); REQUIRE_NOTHROW( - check_master_file(doc, MasterAttributes::N_GATES.data(), gates)); + checker.template check(MasterAttributes::N_GATES.data(), gates)); } +template void test_master_file_threadhold_energies(const Detector &det, - const std::optional &doc) { + CheckerT &checker) { auto threshold_energies = det.getAllThresholdEnergy().tsquash("Inconsistent threshold energies"); - REQUIRE_NOTHROW(check_master_file>( - doc, MasterAttributes::N_THRESHOLD_ENERGIES.data(), - threshold_energies)); + REQUIRE_NOTHROW(checker.template check>( + MasterAttributes::N_THRESHOLD_ENERGIES.data(), threshold_energies)); } -void test_master_file_burst_mode(const Detector &det, - const std::optional &doc) { +template +void test_master_file_burst_mode(const Detector &det, CheckerT &checker) { auto burst_mode = det.getBurstMode().tsquash("Inconsistent burst mode"); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_BURST_MODE.data(), ToString(burst_mode))); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_BURST_MODE.data(), ToString(burst_mode))); } -void test_master_file_adc_mask(const Detector &det, - const std::optional &doc) { +template +void test_master_file_adc_mask(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_ctb_config{}; auto adc_mask = test_ctb_config.adc_enable_10g; auto det_type = det.getDetectorType().squash(); @@ -507,239 +471,242 @@ void test_master_file_adc_mask(const Detector &det, adc_mask = test_ctb_config.adc_enable_1g; } - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_ADC_MASK.data(), adc_mask)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_ADC_MASK.data(), adc_mask)); } -void test_master_file_analog_flag(const Detector &det, - const std::optional &doc) { +template +void test_master_file_analog_flag(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto romode = test_info.readout_mode; auto analog = static_cast( (romode == defs::ANALOG_ONLY || romode == defs::ANALOG_AND_DIGITAL)); REQUIRE_NOTHROW( - check_master_file(doc, MasterAttributes::N_ANALOG.data(), analog)); + checker.template check(MasterAttributes::N_ANALOG.data(), analog)); } -void test_master_file_analog_samples(const Detector &det, - const std::optional &doc) { +template +void test_master_file_analog_samples(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto analog_samples = test_info.num_adc_samples; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_ANALOG_SAMPLES.data(), analog_samples)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_ANALOG_SAMPLES.data(), analog_samples)); } -void test_master_file_digital_flag(const Detector &det, - const std::optional &doc) { +template +void test_master_file_digital_flag(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto romode = test_info.readout_mode; auto digital = static_cast(romode == defs::DIGITAL_ONLY || romode == defs::ANALOG_AND_DIGITAL || romode == defs::DIGITAL_AND_TRANSCEIVER); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DIGITAL.data(), digital)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DIGITAL.data(), digital)); } -void test_master_file_digital_samples(const Detector &det, - const std::optional &doc) { +template +void test_master_file_digital_samples(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto digital_samples = test_info.num_dbit_samples; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DIGITAL_SAMPLES.data(), digital_samples)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DIGITAL_SAMPLES.data(), digital_samples)); } -void test_master_file_dbit_offset(const Detector &det, - const std::optional &doc) { +template +void test_master_file_dbit_offset(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto dbit_offset = test_info.dbit_offset; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DBIT_OFFSET.data(), dbit_offset)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DBIT_OFFSET.data(), dbit_offset)); } -void test_master_file_dbit_reorder(const Detector &det, - const std::optional &doc) { +template +void test_master_file_dbit_reorder(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto dbit_reorder = test_info.dbit_reorder; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DBIT_REORDER.data(), dbit_reorder)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DBIT_REORDER.data(), dbit_reorder)); } -void test_master_file_dbit_bitset(const Detector &det, - const std::optional &doc) { +template +void test_master_file_dbit_bitset(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; uint64_t dbit_bitset = 0; for (auto &i : test_info.dbit_list) { dbit_bitset |= (static_cast(1) << i); } - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_DBIT_BITSET.data(), dbit_bitset)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_DBIT_BITSET.data(), dbit_bitset)); } -void test_master_file_transceiver_mask(const Detector &det, - const std::optional &doc) { +template +void test_master_file_transceiver_mask(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto trans_mask = test_info.transceiver_mask; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_TRANSCEIVER_MASK.data(), trans_mask)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_TRANSCEIVER_MASK.data(), trans_mask)); } -void test_master_file_transceiver_flag(const Detector &det, - const std::optional &doc) { +template +void test_master_file_transceiver_flag(const Detector &det, CheckerT &checker) { testCtbAcquireInfo test_info{}; auto romode = test_info.readout_mode; auto trans = static_cast(romode == defs::DIGITAL_AND_TRANSCEIVER || romode == defs::TRANSCEIVER_ONLY); - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_TRANSCEIVER.data(), trans)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_TRANSCEIVER.data(), trans)); } +template void test_master_file_transceiver_samples(const Detector &det, - const std::optional &doc) { + CheckerT &checker) { testCtbAcquireInfo test_info{}; auto trans_samples = test_info.num_trans_samples; - REQUIRE_NOTHROW(check_master_file( - doc, MasterAttributes::N_TRANSCEIVER_SAMPLES.data(), trans_samples)); + REQUIRE_NOTHROW(checker.template check( + MasterAttributes::N_TRANSCEIVER_SAMPLES.data(), trans_samples)); } -void test_master_file_common_metadata(const Detector &det, - const std::optional &doc) { - test_master_file_version(det, doc); - test_master_file_type(det, doc); - test_master_file_timing_mode(det, doc); - test_master_file_geometry(det, doc); - test_master_file_image_size(det, doc); - test_master_file_det_size(det, doc); - test_master_file_max_frames_per_file(det, doc); - test_master_file_frame_discard_policy(det, doc); - test_master_file_frame_padding(det, doc); - test_master_file_scan_parameters(det, doc); - test_master_file_total_frames(det, doc); - test_master_file_json_header(det, doc); +template +void test_master_file_common_metadata(const Detector &det, CheckerT &checker) { + test_master_file_version(det, checker); + test_master_file_type(det, checker); + test_master_file_timing_mode(det, checker); + test_master_file_geometry(det, checker); + test_master_file_image_size(det, checker); + test_master_file_det_size(det, checker); + test_master_file_max_frames_per_file(det, checker); + test_master_file_frame_discard_policy(det, checker); + test_master_file_frame_padding(det, checker); + test_master_file_scan_parameters(det, checker); + test_master_file_total_frames(det, checker); + test_master_file_json_header(det, checker); // TODO: test frame header format? } +template void test_master_file_jungfrau_metadata(const Detector &det, - const std::optional &doc) { - REQUIRE_NOTHROW(test_master_file_common_metadata(det, doc)); + CheckerT &checker) { + REQUIRE_NOTHROW(test_master_file_common_metadata(det, checker)); // Jungfrau specific metadata - REQUIRE_NOTHROW(test_master_file_rois(det, doc)); - REQUIRE_NOTHROW(test_master_file_exptime(det, doc)); - REQUIRE_NOTHROW(test_master_file_period(det, doc)); - REQUIRE_NOTHROW(test_master_file_num_udp_interfaces(det, doc)); - REQUIRE_NOTHROW(test_master_file_read_n_rows(det, doc)); - REQUIRE_NOTHROW(test_master_file_readout_speed(det, doc)); + REQUIRE_NOTHROW(test_master_file_rois(det, checker)); + REQUIRE_NOTHROW(test_master_file_exptime(det, checker)); + REQUIRE_NOTHROW(test_master_file_period(det, checker)); + REQUIRE_NOTHROW(test_master_file_num_udp_interfaces(det, checker)); + REQUIRE_NOTHROW(test_master_file_read_n_rows(det, checker)); + REQUIRE_NOTHROW(test_master_file_readout_speed(det, checker)); } -void test_master_file_eiger_metadata(const Detector &det, - const std::optional &doc) { - REQUIRE_NOTHROW(test_master_file_common_metadata(det, doc)); +template +void test_master_file_eiger_metadata(const Detector &det, CheckerT &checker) { + REQUIRE_NOTHROW(test_master_file_common_metadata(det, checker)); // Eiger specific metadata - REQUIRE_NOTHROW(test_master_file_rois(det, doc)); - REQUIRE_NOTHROW(test_master_file_dynamic_range(det, doc)); - REQUIRE_NOTHROW(test_master_file_ten_giga(det, doc)); - REQUIRE_NOTHROW(test_master_file_exptime(det, doc)); - REQUIRE_NOTHROW(test_master_file_period(det, doc)); - REQUIRE_NOTHROW(test_master_file_threshold_energy(det, doc)); - REQUIRE_NOTHROW(test_master_file_sub_exptime(det, doc)); - REQUIRE_NOTHROW(test_master_file_sub_period(det, doc)); - REQUIRE_NOTHROW(test_master_file_quad(det, doc)); - REQUIRE_NOTHROW(test_master_file_read_n_rows(det, doc)); - REQUIRE_NOTHROW(test_master_file_rate_corrections(det, doc)); - REQUIRE_NOTHROW(test_master_file_readout_speed(det, doc)); + REQUIRE_NOTHROW(test_master_file_rois(det, checker)); + REQUIRE_NOTHROW(test_master_file_dynamic_range(det, checker)); + REQUIRE_NOTHROW(test_master_file_ten_giga(det, checker)); + REQUIRE_NOTHROW(test_master_file_exptime(det, checker)); + REQUIRE_NOTHROW(test_master_file_period(det, checker)); + REQUIRE_NOTHROW(test_master_file_threshold_energy(det, checker)); + REQUIRE_NOTHROW(test_master_file_sub_exptime(det, checker)); + REQUIRE_NOTHROW(test_master_file_sub_period(det, checker)); + REQUIRE_NOTHROW(test_master_file_quad(det, checker)); + REQUIRE_NOTHROW(test_master_file_read_n_rows(det, checker)); + REQUIRE_NOTHROW(test_master_file_rate_corrections(det, checker)); + REQUIRE_NOTHROW(test_master_file_readout_speed(det, checker)); } -void test_master_file_moench_metadata(const Detector &det, - const std::optional &doc) { - REQUIRE_NOTHROW(test_master_file_common_metadata(det, doc)); +template +void test_master_file_moench_metadata(const Detector &det, CheckerT &checker) { + REQUIRE_NOTHROW(test_master_file_common_metadata(det, checker)); // Moench specific metadata - REQUIRE_NOTHROW(test_master_file_rois(det, doc)); - REQUIRE_NOTHROW(test_master_file_exptime(det, doc)); - REQUIRE_NOTHROW(test_master_file_period(det, doc)); - REQUIRE_NOTHROW(test_master_file_num_udp_interfaces(det, doc)); - REQUIRE_NOTHROW(test_master_file_read_n_rows(det, doc)); - REQUIRE_NOTHROW(test_master_file_readout_speed(det, doc)); + REQUIRE_NOTHROW(test_master_file_rois(det, checker)); + REQUIRE_NOTHROW(test_master_file_exptime(det, checker)); + REQUIRE_NOTHROW(test_master_file_period(det, checker)); + REQUIRE_NOTHROW(test_master_file_num_udp_interfaces(det, checker)); + REQUIRE_NOTHROW(test_master_file_read_n_rows(det, checker)); + REQUIRE_NOTHROW(test_master_file_readout_speed(det, checker)); } -void test_master_file_mythen3_metadata(const Detector &det, - const std::optional &doc) { - REQUIRE_NOTHROW(test_master_file_common_metadata(det, doc)); +template +void test_master_file_mythen3_metadata(const Detector &det, CheckerT &checker) { + REQUIRE_NOTHROW(test_master_file_common_metadata(det, checker)); // Mythen3 specific metadata - REQUIRE_NOTHROW(test_master_file_rois(det, doc)); - REQUIRE_NOTHROW(test_master_file_dynamic_range(det, doc)); - REQUIRE_NOTHROW(test_master_file_ten_giga(det, doc)); - REQUIRE_NOTHROW(test_master_file_period(det, doc)); - REQUIRE_NOTHROW(test_master_file_counter_mask(det, doc)); - REQUIRE_NOTHROW(test_master_file_exptimes(det, doc)); - REQUIRE_NOTHROW(test_master_file_gate_delays(det, doc)); - REQUIRE_NOTHROW(test_master_file_gates(det, doc)); - REQUIRE_NOTHROW(test_master_file_threadhold_energies(det, doc)); - REQUIRE_NOTHROW(test_master_file_readout_speed(det, doc)); + REQUIRE_NOTHROW(test_master_file_rois(det, checker)); + REQUIRE_NOTHROW(test_master_file_dynamic_range(det, checker)); + REQUIRE_NOTHROW(test_master_file_ten_giga(det, checker)); + REQUIRE_NOTHROW(test_master_file_period(det, checker)); + REQUIRE_NOTHROW(test_master_file_counter_mask(det, checker)); + REQUIRE_NOTHROW(test_master_file_exptimes(det, checker)); + REQUIRE_NOTHROW(test_master_file_gate_delays(det, checker)); + REQUIRE_NOTHROW(test_master_file_gates(det, checker)); + REQUIRE_NOTHROW(test_master_file_threadhold_energies(det, checker)); + REQUIRE_NOTHROW(test_master_file_readout_speed(det, checker)); } +template void test_master_file_gotthard2_metadata(const Detector &det, - const std::optional &doc) { - REQUIRE_NOTHROW(test_master_file_common_metadata(det, doc)); + CheckerT &checker) { + REQUIRE_NOTHROW(test_master_file_common_metadata(det, checker)); // Gotthard2 specific metadata - REQUIRE_NOTHROW(test_master_file_exptime(det, doc)); - REQUIRE_NOTHROW(test_master_file_period(det, doc)); - REQUIRE_NOTHROW(test_master_file_burst_mode(det, doc)); - REQUIRE_NOTHROW(test_master_file_readout_speed(det, doc)); + REQUIRE_NOTHROW(test_master_file_exptime(det, checker)); + REQUIRE_NOTHROW(test_master_file_period(det, checker)); + REQUIRE_NOTHROW(test_master_file_burst_mode(det, checker)); + REQUIRE_NOTHROW(test_master_file_readout_speed(det, checker)); } -void test_master_file_ctb_metadata(const Detector &det, - const std::optional &doc) { +template +void test_master_file_ctb_metadata(const Detector &det, CheckerT &checker) { auto det_type = det.getDetectorType().squash(); - REQUIRE_NOTHROW(test_master_file_common_metadata(det, doc)); + REQUIRE_NOTHROW(test_master_file_common_metadata(det, checker)); // Ctb specific metadata - REQUIRE_NOTHROW(test_master_file_exptime(det, doc)); - REQUIRE_NOTHROW(test_master_file_period(det, doc)); + REQUIRE_NOTHROW(test_master_file_exptime(det, checker)); + REQUIRE_NOTHROW(test_master_file_period(det, checker)); if (det_type == defs::CHIPTESTBOARD) - REQUIRE_NOTHROW(test_master_file_ten_giga(det, doc)); - REQUIRE_NOTHROW(test_master_file_adc_mask(det, doc)); - REQUIRE_NOTHROW(test_master_file_analog_flag(det, doc)); - REQUIRE_NOTHROW(test_master_file_analog_samples(det, doc)); - REQUIRE_NOTHROW(test_master_file_digital_flag(det, doc)); - REQUIRE_NOTHROW(test_master_file_digital_samples(det, doc)); - REQUIRE_NOTHROW(test_master_file_dbit_offset(det, doc)); - REQUIRE_NOTHROW(test_master_file_dbit_reorder(det, doc)); - REQUIRE_NOTHROW(test_master_file_dbit_bitset(det, doc)); - REQUIRE_NOTHROW(test_master_file_transceiver_mask(det, doc)); - REQUIRE_NOTHROW(test_master_file_transceiver_flag(det, doc)); - REQUIRE_NOTHROW(test_master_file_transceiver_samples(det, doc)); + REQUIRE_NOTHROW(test_master_file_ten_giga(det, checker)); + REQUIRE_NOTHROW(test_master_file_adc_mask(det, checker)); + REQUIRE_NOTHROW(test_master_file_analog_flag(det, checker)); + REQUIRE_NOTHROW(test_master_file_analog_samples(det, checker)); + REQUIRE_NOTHROW(test_master_file_digital_flag(det, checker)); + REQUIRE_NOTHROW(test_master_file_digital_samples(det, checker)); + REQUIRE_NOTHROW(test_master_file_dbit_offset(det, checker)); + REQUIRE_NOTHROW(test_master_file_dbit_reorder(det, checker)); + REQUIRE_NOTHROW(test_master_file_dbit_bitset(det, checker)); + REQUIRE_NOTHROW(test_master_file_transceiver_mask(det, checker)); + REQUIRE_NOTHROW(test_master_file_transceiver_flag(det, checker)); + REQUIRE_NOTHROW(test_master_file_transceiver_samples(det, checker)); } -void test_master_file_metadata(const Detector &det, - const std::optional &doc) { +template +void test_master_file_metadata(const Detector &det, CheckerT &checker) { auto det_type = det.getDetectorType().tsquash("Inconsistent detector types"); switch (det_type) { case defs::JUNGFRAU: - test_master_file_jungfrau_metadata(det, doc); + test_master_file_jungfrau_metadata(det, checker); break; case defs::EIGER: - test_master_file_eiger_metadata(det, doc); + test_master_file_eiger_metadata(det, checker); break; case defs::MOENCH: - test_master_file_moench_metadata(det, doc); + test_master_file_moench_metadata(det, checker); break; case defs::MYTHEN3: - test_master_file_mythen3_metadata(det, doc); + test_master_file_mythen3_metadata(det, checker); break; case defs::GOTTHARD2: - test_master_file_gotthard2_metadata(det, doc); + test_master_file_gotthard2_metadata(det, checker); break; case defs::CHIPTESTBOARD: case defs::XILINX_CHIPTESTBOARD: - test_master_file_ctb_metadata(det, doc); + test_master_file_ctb_metadata(det, checker); break; default: break; @@ -770,18 +737,6 @@ Document parse_binary_master_attributes(std::string file_path) { return doc; } -// todo: to be moved to checkers if group exists. -/* -#ifdef HDF5C -void open_hdf5_file(const std::string &file_path) { - REQUIRE(std::filesystem::exists(file_path) == true); - h5File = std::make_optional(file_path, H5F_ACC_RDONLY); - REQUIRE(H5Lexists(h5File->getId(), HDF5_GROUP.c_str(), H5P_DEFAULT) == - true); -} -#endif -*/ - TEST_CASE("check_master_file_attributes", "[.detectorintegration][.disable_check_data_file]") { @@ -814,17 +769,19 @@ TEST_CASE("check_master_file_attributes", // binary std::string fname = master_file_prefix + ".json"; // /tmp/sls_test_master_0.json - auto doc = std::make_optional(parse_binary_master_attributes(fname)); - test_master_file_metadata(det, doc); - test_master_file_frames_in_file(doc, num_frames); + auto doc = parse_binary_master_attributes(fname); + + mf::Checker checker(mf::JsonContext{doc}); + test_master_file_metadata(det, checker); + test_master_file_frames_in_file(checker, num_frames); // hdf5 #ifdef HDF5C fname = master_file_prefix + ".h5"; // /tmp/sls_test_master_0.h5 try { - h5ctx.emplace(fname); - test_master_file_metadata(det, std::nullopt); - test_master_file_frames_in_file(std::nullopt, num_frames); + mf::Checker checker(mf::H5Context{fname}); + test_master_file_metadata(det, checker); + test_master_file_frames_in_file(checker, num_frames); } catch (H5::Exception &e) { LOG(logERROR) << "HDF5 error: " << e.getDetailMsg(); throw; diff --git a/slsDetectorSoftware/tests/master_file/Checker.h b/slsDetectorSoftware/tests/master_file/Checker.h new file mode 100644 index 000000000..1c718b7e5 --- /dev/null +++ b/slsDetectorSoftware/tests/master_file/Checker.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package +#pragma once + +#include "Readers.h" +#include "catch.hpp" + +namespace sls::test::master_file { + +template class Checker; + +/** JSON Specialization */ +template <> class Checker { + public: + explicit Checker(const JsonContext &ctx) : ctx_(ctx) {} + const JsonContext &context() const { return ctx_; } + + template + void check(const std::string &name, const T &expected, + AccessType = AccessType::Dataset) const { + REQUIRE(ctx_.doc.HasMember(name.c_str())); + auto retval = read(ctx_, name); + REQUIRE(retval == expected); + } + + private: + const JsonContext &ctx_; +}; + +/** HDF5 Specialization */ +#ifdef HDF5C + +template <> class Checker { + public: + explicit Checker(H5Context ctx) : ctx_(std::move(ctx)) {} + const H5Context &context() const { return ctx_; } + + template + void check(const std::string &name, const T &expected, + AccessType access = AccessType::Dataset) const { + auto retval = read(ctx_, name, access); + REQUIRE(retval == expected); + } + + private: + H5Context ctx_; +}; + +#endif + +} // namespace sls::test::master_file \ No newline at end of file diff --git a/slsDetectorSoftware/tests/master_file/Readers.h b/slsDetectorSoftware/tests/master_file/Readers.h index a9fbaa724..99675f54a 100644 --- a/slsDetectorSoftware/tests/master_file/Readers.h +++ b/slsDetectorSoftware/tests/master_file/Readers.h @@ -8,10 +8,14 @@ namespace sls::test::master_file { template struct Reader; +template struct AttributeReader; + +enum class AccessType { Dataset, Attribute }; template -T read(const Context &ctx, const std::string &name) { - return Reader::read(ctx, name); +T read(const Context &ctx, const std::string &name, + AccessType access = AccessType::Dataset) { + return Reader::read(ctx, name, access); } inline void check_size(size_t actual, size_t expected, const std::string &name, diff --git a/slsDetectorSoftware/tests/master_file/ReadersH5.h b/slsDetectorSoftware/tests/master_file/ReadersH5.h index c7690d394..fcd4fa9f7 100644 --- a/slsDetectorSoftware/tests/master_file/ReadersH5.h +++ b/slsDetectorSoftware/tests/master_file/ReadersH5.h @@ -4,6 +4,7 @@ #include "Readers.h" #include "sls/sls_detector_defs.h" +#include #ifdef HDF5C #include "H5Cpp.h" @@ -11,11 +12,31 @@ namespace sls::test::master_file { using ns = std::chrono::nanoseconds; -const std::string HDF5_GROUP = "/entry/instrument/detector/"; +static const std::string HDF5_GROUP = "/entry/instrument/detector/"; + +/* --safety checks-- */ +inline void require_dataset(const H5Context &ctx, const std::string &name) { + const std::string full_name = HDF5_GROUP + name; + if (H5Lexists(ctx.file.getId(), full_name.c_str(), H5P_DEFAULT) <= 0) { + throw sls::RuntimeError("Missing HDF5 dataset: " + full_name); + } +} + +inline void require_file_attribute(const H5Context &ctx, + const std::string &name) { + if (!H5Aexists_by_name(ctx.file.getId(), "/", name.c_str(), H5P_DEFAULT)) { + throw sls::RuntimeError("Missing HDF5 attribute: " + name); + } +} /* --scalar reads-- */ template <> struct Reader { - static int read(const H5Context &ctx, const std::string &name) { + static int read(const H5Context &ctx, const std::string &name, + AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("int attribute access not supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); int out{}; ds.read(&out, H5::PredType::NATIVE_INT); @@ -24,7 +45,13 @@ template <> struct Reader { }; template <> struct Reader { - static uint32_t read(const H5Context &ctx, const std::string &name) { + static uint32_t read(const H5Context &ctx, const std::string &name, + AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError( + "uint32_t attribute access not supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); uint32_t out{}; ds.read(&out, H5::PredType::STD_U32LE); @@ -33,25 +60,46 @@ template <> struct Reader { }; template <> struct Reader { - static uint64_t read(const H5Context &ctx, const std::string &name) { - auto ds = ctx.file.openDataSet(HDF5_GROUP + name); + static uint64_t read(const H5Context &ctx, const std::string &name, + AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError( + "'uint64_t' attribute access not supported for HDF5"); + } uint64_t out{}; + require_dataset(ctx, name); + auto ds = ctx.file.openDataSet(HDF5_GROUP + name); 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); + static double read(const H5Context &ctx, const std::string &name, + AccessType access) { double out{}; + if (access == AccessType::Attribute) { + require_file_attribute(ctx, name); + auto attr = ctx.file.openAttribute(name); + attr.read(attr.getDataType(), &out); + return out; + } + // dataset + require_dataset(ctx, name); + auto ds = ctx.file.openDataSet(HDF5_GROUP + name); ds.read(&out, H5::PredType::NATIVE_DOUBLE); return out; } }; template <> struct Reader { - static std::string read(const H5Context &ctx, const std::string &name) { + static std::string read(const H5Context &ctx, const std::string &name, + AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError( + "string attribute access not supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); std::string out{}; ds.read(out, ds.getStrType()); @@ -61,7 +109,13 @@ template <> struct Reader { /** complex types */ template <> struct Reader { - static defs::xy read(const H5Context &ctx, const std::string &name) { + static defs::xy read(const H5Context &ctx, const std::string &name, + AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError( + "'defs::xy' attribute access not supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); // define type H5::CompType type(sizeof(defs::xy)); @@ -82,8 +136,13 @@ inline hsize_t get_1d_size(const H5::DataSet &ds) { } template <> struct Reader> { - static std::vector read(const H5Context &ctx, - const std::string &name) { + static std::vector + read(const H5Context &ctx, const std::string &name, AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("'std::vector' attribute access not " + "supported for HDF5"); + } + require_dataset(ctx, name); // define type H5::CompType type(sizeof(defs::ROI)); type.insertMember("xmin", HOFFSET(defs::ROI, xmin), @@ -105,8 +164,13 @@ template <> struct Reader> { }; template <> struct Reader { - static defs::scanParameters read(const H5Context &ctx, - const std::string &name) { + static defs::scanParameters + read(const H5Context &ctx, const std::string &name, AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("'defs::scanParameters' attribute access not " + "supported for HDF5"); + } + require_dataset(ctx, name); // define type H5::CompType type(sizeof(defs::scanParameters)); type.insertMember("enable", HOFFSET(defs::scanParameters, enable), @@ -134,8 +198,13 @@ template <> struct Reader { /** arrays/vectors/maps */ template <> struct Reader> { - static std::array read(const H5Context &ctx, - const std::string &name) { + static std::array + read(const H5Context &ctx, const std::string &name, AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("'std::array' attribute access not " + "supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); auto len = get_1d_size(ds); check_size(len, 3, name, "HDF5"); @@ -146,8 +215,13 @@ template <> struct Reader> { }; template <> struct Reader> { - static std::array read(const H5Context &ctx, - const std::string &name) { + static std::array + read(const H5Context &ctx, const std::string &name, AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("'std::array' attribute access not " + "supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); auto len = get_1d_size(ds); check_size(len, 3, name, "HDF5"); @@ -165,8 +239,13 @@ template <> struct Reader> { }; template <> struct Reader> { - static std::vector read(const H5Context &ctx, - const std::string &name) { + static std::vector + read(const H5Context &ctx, const std::string &name, AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("'std::vector' attribute access not " + "supported for HDF5"); + } + require_dataset(ctx, name); auto ds = ctx.file.openDataSet(HDF5_GROUP + name); auto len = get_1d_size(ds); std::vector out{}; @@ -177,8 +256,13 @@ template <> struct Reader> { }; template <> struct Reader> { - static std::map read(const H5Context &ctx, - const std::string &name) { + static std::map + read(const H5Context &ctx, const std::string &name, AccessType access) { + if (access == AccessType::Attribute) { + throw RuntimeError("'std::map' attribute " + "access not supported for HDF5"); + } + require_dataset(ctx, name); std::map out{}; // dim auto ds = ctx.file.openDataSet(HDF5_GROUP + name); diff --git a/slsDetectorSoftware/tests/master_file/ReadersJson.h b/slsDetectorSoftware/tests/master_file/ReadersJson.h index 924c04bd9..013f8f0fd 100644 --- a/slsDetectorSoftware/tests/master_file/ReadersJson.h +++ b/slsDetectorSoftware/tests/master_file/ReadersJson.h @@ -3,6 +3,7 @@ #pragma once #include "Readers.h" + #include "sls/ToString.h" #include "sls/sls_detector_defs.h" @@ -13,38 +14,44 @@ using ns = std::chrono::nanoseconds; /* --scalar reads-- */ template <> struct Reader { - static int read(const JsonContext &ctx, const std::string &name) { + static int read(const JsonContext &ctx, const std::string &name, + AccessType access) { return ctx.doc[name.c_str()].GetInt(); } }; template <> struct Reader { - static uint32_t read(const JsonContext &ctx, const std::string &name) { + static uint32_t read(const JsonContext &ctx, const std::string &name, + AccessType access) { return ctx.doc[name.c_str()].GetUint(); } }; template <> struct Reader { - static uint64_t read(const JsonContext &ctx, const std::string &name) { + static uint64_t read(const JsonContext &ctx, const std::string &name, + AccessType access) { return ctx.doc[name.c_str()].GetUint64(); } }; template <> struct Reader { - static double read(const JsonContext &ctx, const std::string &name) { + static double read(const JsonContext &ctx, const std::string &name, + AccessType access) { return ctx.doc[name.c_str()].GetDouble(); } }; template <> struct Reader { - static std::string read(const JsonContext &ctx, const std::string &name) { + static std::string read(const JsonContext &ctx, const std::string &name, + AccessType access) { return ctx.doc[name.c_str()].GetString(); } }; /** complex types */ template <> struct Reader { - static defs::xy read(const JsonContext &ctx, const std::string &name) { + static defs::xy read(const JsonContext &ctx, const std::string &name, + AccessType access) { defs::xy out{}; out.x = ctx.doc[name.c_str()]["x"].GetInt(); out.y = ctx.doc[name.c_str()]["y"].GetInt(); @@ -53,8 +60,8 @@ template <> struct Reader { }; template <> struct Reader> { - static std::vector read(const JsonContext &ctx, - const std::string &name) { + static std::vector + read(const JsonContext &ctx, const std::string &name, AccessType access) { std::vector out{}; for (const auto &item : ctx.doc[name.c_str()].GetArray()) { defs::ROI r{}; @@ -69,8 +76,8 @@ template <> struct Reader> { }; template <> struct Reader { - static defs::scanParameters read(const JsonContext &ctx, - const std::string &name) { + static defs::scanParameters + read(const JsonContext &ctx, const std::string &name, AccessType access) { defs::scanParameters out{}; const auto &s = ctx.doc[name.c_str()].GetObject(); out.enable = s["enable"].GetInt(); @@ -85,8 +92,8 @@ template <> struct Reader { /** arrays/vectors/maps */ template <> struct Reader> { - static std::array read(const JsonContext &ctx, - const std::string &name) { + static std::array + read(const JsonContext &ctx, const std::string &name, AccessType access) { const auto &arr = ctx.doc[name.c_str()].GetArray(); check_size(arr.Size(), 3, name, "JSON"); @@ -99,8 +106,8 @@ template <> struct Reader> { }; template <> struct Reader> { - static std::array read(const JsonContext &ctx, - const std::string &name) { + static std::array + read(const JsonContext &ctx, const std::string &name, AccessType access) { const auto &arr = ctx.doc[name.c_str()].GetArray(); check_size(arr.Size(), 3, name, "JSON"); @@ -114,8 +121,8 @@ template <> struct Reader> { }; template <> struct Reader> { - static std::vector read(const JsonContext &ctx, - const std::string &name) { + static std::vector + read(const JsonContext &ctx, const std::string &name, AccessType access) { std::vector out{}; for (const auto &item : ctx.doc[name.c_str()].GetArray()) { out.push_back(item.GetInt64()); @@ -125,8 +132,8 @@ template <> struct Reader> { }; template <> struct Reader> { - static std::map read(const JsonContext &ctx, - const std::string &name) { + static std::map + read(const JsonContext &ctx, const std::string &name, AccessType access) { std::map out{}; for (const auto &m : ctx.doc[name.c_str()].GetObject()) { out[m.name.GetString()] = m.value.GetString(); diff --git a/slsDetectorSoftware/tests/master_file/Readers_bak.h b/slsDetectorSoftware/tests/master_file/Readers_bak.h deleted file mode 100644 index 864501068..000000000 --- a/slsDetectorSoftware/tests/master_file/Readers_bak.h +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#pragma once - -#include "Context.h" -#include "sls/sls_detector_defs.h" - -#ifdef HDF5C -#include "H5Cpp.h" -#endif - -#include - -namespace sls::test::master_file { - -using ns = std::chrono::nanoseconds; - -void read_from_json(const Document &doc, const std::string &name, - std::string &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::string &out); -#endif - -/** int */ -void read_from_json(const Document &doc, const std::string &name, int &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - int &out); -#endif - -/** uint32_t */ -void read_from_json(const Document &doc, const std::string &name, - uint32_t &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - uint32_t &out); -#endif - -/** uint64_t */ -void read_from_json(const Document &doc, const std::string &name, - uint64_t &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - uint64_t &out); -#endif - -/** double */ -void read_from_json(const Document &doc, const std::string &name, double &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - double &out); -#endif - -/* ---vector reads--- */ -/** int64_t */ -void read_from_json(const Document &doc, const std::string &name, - std::vector &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::vector &out); -#endif - -/* ---arrays/ maps--- */ -/** std::array */ -void read_from_json(const Document &doc, const std::string &name, - std::array &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::array &out); -#endif - -/** std::array */ -void read_from_json(const Document &doc, const std::string &name, - std::array &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::array &out); -#endif - -/** std::map */ -void read_from_json(const Document &doc, const std::string &name, - std::map &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::map &out); -#endif - -/* complex types */ -/* std::vector */ -void read_from_json(const Document &doc, const std::string &name, - std::vector &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - std::vector &out); -#endif - -/** defs::xy */ -void read_from_json(const Document &doc, const std::string &name, - defs::xy &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - defs::xy &out); -#endif - -/** defs::scanParameters */ -void read_from_json(const Document &doc, const std::string &name, - defs::scanParameters &out); -#ifdef HDF5C -void read_from_h5_dataset(const H5::DataSet &ds, const std::string &name, - defs::scanParameters &out); -#endif - -} // namespace sls::test::master_file