diff --git a/RELEASE.md b/RELEASE.md index aa51f62c..ab7cee36 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -40,9 +40,11 @@ - ``RawMasterFile::geometry()`` is deprecetad and returns full detector geometry information including module geometry. Use ``RawMasterFile::module_layout()`` to get num_modules in x an y - ``RawMasterFile::rois()`` always returns a list of rois (no optional). Per default it returns a list of one ROI element spawing the entire detector +- ``TimingMode::Auto`` changed to ``TimingMode::AUTO_TIMING``, ``TimingMode::Trigger`` changed to ``TimingMode::TRIGGER_EXPOSURE`` ### Bugfixes: - Fixed broken reading of old (pre reordering) Moench03 +- Supports reading all timing modes supported in slsDetectorPackage (auto, trigger, gating, burst_trigger, trigger_gating) ## 2026.7.2 diff --git a/include/aare/defs.hpp b/include/aare/defs.hpp index 19abb032..b0701912 100644 --- a/include/aare/defs.hpp +++ b/include/aare/defs.hpp @@ -309,7 +309,14 @@ enum class UDPPortPosition : uint8_t { BOTTOM = 3 }; -enum class TimingMode { Auto, Trigger }; +enum class TimingMode : uint8_t { + AUTO_TIMING = 0, + TRIGGER_EXPOSURE = 1, + GATED = 2, + BURST_TRIGGER = 3, + TRIGGER_GATED = 4 +}; + enum class FrameDiscardPolicy { NoDiscard, Discard, DiscardPartial }; using DataTypeVariants = std::variant; diff --git a/python/src/bind_Defs.hpp b/python/src/bind_Defs.hpp index 1165e5b3..c6886def 100644 --- a/python/src/bind_Defs.hpp +++ b/python/src/bind_Defs.hpp @@ -72,4 +72,11 @@ void define_defs_bindings(py::module &m) { .value("RIGHT", UDPPortPosition::RIGHT) .value("TOP", UDPPortPosition::TOP) .value("BOTTOM", UDPPortPosition::BOTTOM); + + py::enum_(m, "TimingMode") + .value("AUTO_TIMING", TimingMode::AUTO_TIMING) + .value("TRIGGER_EXPOSURE", TimingMode::TRIGGER_EXPOSURE) + .value("GATED", TimingMode::GATED) + .value("BURST_TRIGGER", TimingMode::BURST_TRIGGER) + .value("TRIGGER_GATED", TimingMode::TRIGGER_GATED); } diff --git a/src/RawMasterFile.test.cpp b/src/RawMasterFile.test.cpp index 41857a7f..bd244844 100644 --- a/src/RawMasterFile.test.cpp +++ b/src/RawMasterFile.test.cpp @@ -80,7 +80,7 @@ TEST_CASE("Parse a master file in .json format", "[.with-data]") { // "Detector Type": "Jungfrau", REQUIRE(f.detector_type() == DetectorType::Jungfrau); // "Timing Mode": "auto", - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); // "Geometry": { // "x": 1, @@ -179,7 +179,7 @@ TEST_CASE("Parse a master file in .raw format", "[.with-data]") { // Detector Type : ChipTestBoard REQUIRE(f.detector_type() == DetectorType::ChipTestBoard); // Timing Mode : auto - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); // Detector Layout : [1, 1] REQUIRE(f.detector_layout().col == 1); REQUIRE(f.detector_layout().row == 1); @@ -245,7 +245,7 @@ TEST_CASE("Parse a master file in new .json format", "[.with-data]") { REQUIRE(f.detector_type() == DetectorType::Mythen3); // Timing Mode : auto - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); // Detector Layout : [2, 1] REQUIRE(f.detector_layout().col == 2); REQUIRE(f.detector_layout().row == 1); @@ -278,7 +278,7 @@ TEST_CASE("Read eiger master file", "[.with-data]") { // "Detector Type": "Eiger", REQUIRE(f.detector_type() == DetectorType::Eiger); // "Timing Mode": "auto", - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); // "Geometry": { // "x": 2, // "y": 2 @@ -398,7 +398,7 @@ TEST_CASE("Parse EIGER 7.2 master from string stream") { REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::Eiger); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout().col == 2); REQUIRE(f.detector_layout().row == 2); @@ -475,7 +475,7 @@ TEST_CASE("Parse JUNGFRAU 7.2 master from string stream") { REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::Jungfrau); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout().col == 1); REQUIRE(f.detector_layout().row == 2); REQUIRE(f.n_modules() == 2); @@ -558,7 +558,7 @@ TEST_CASE( REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::ChipTestBoard); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{1, 1}); REQUIRE(f.image_size_in_bytes() == 192000); REQUIRE(f.pixels_x() == 32); @@ -636,7 +636,7 @@ TEST_CASE( REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::ChipTestBoard); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{1, 1}); REQUIRE(f.image_size_in_bytes() == 16000); REQUIRE(f.pixels_x() == 64); @@ -708,7 +708,7 @@ TEST_CASE("Parse Moench 7.2 master (SW 7.0.3) from string stream") { REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::Moench03_old); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{1, 1}); REQUIRE(f.image_size_in_bytes() == 320000); REQUIRE(f.pixels_x() == 400); @@ -779,7 +779,7 @@ TEST_CASE("Parse Moench 7.2 master (SW 8.0.0) from string stream") { REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::Moench03); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{1, 1}); REQUIRE(f.image_size_in_bytes() == 320000); REQUIRE(f.pixels_x() == 400); @@ -861,7 +861,7 @@ TEST_CASE("Parse CTB 7.2 master (SW 8.0.0) from string stream") { REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::ChipTestBoard); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{1, 1}); REQUIRE(f.image_size_in_bytes() == 192000); REQUIRE(f.pixels_x() == 32); @@ -942,7 +942,7 @@ TEST_CASE( REQUIRE(f.version() == "7.2"); REQUIRE(f.detector_type() == DetectorType::ChipTestBoard); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{1, 1}); REQUIRE(f.image_size_in_bytes() == 16000); REQUIRE(f.pixels_x() == 64); @@ -1009,7 +1009,7 @@ TEST_CASE("Parse a CTB file from stream") { REQUIRE(f.version() == "8.0"); REQUIRE(f.detector_type() == DetectorType::ChipTestBoard); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout().col == 1); REQUIRE(f.detector_layout().row == 1); REQUIRE(f.image_size_in_bytes() == 18432); @@ -1099,7 +1099,7 @@ TEST_CASE("Parse v8.0 MYTHEN3 from stream") { REQUIRE(f.version() == "8.0"); REQUIRE(f.detector_type() == DetectorType::Mythen3); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout().col == 2); REQUIRE(f.detector_layout().row == 1); REQUIRE(f.image_size_in_bytes() == 5120); @@ -1184,7 +1184,7 @@ TEST_CASE("Parse a v7.1 Mythen3 from stream") { REQUIRE(f.version() == "7.1"); REQUIRE(f.detector_type() == DetectorType::Mythen3); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout().col == 1); REQUIRE(f.detector_layout().row == 1); REQUIRE(f.image_size_in_bytes() == 15360); @@ -1266,7 +1266,7 @@ TEST_CASE("Parse old Moench03 from stream") { REQUIRE(f.version() == "7.1"); REQUIRE(f.detector_type() == DetectorType::Moench03_old); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout().col == 1); REQUIRE(f.detector_layout().row == 1); REQUIRE(f.image_size_in_bytes() == 320000); @@ -1352,7 +1352,7 @@ TEST_CASE("Parse Eiger json v8.1 all ports active") { REQUIRE(f.version() == "8.1"); REQUIRE(f.detector_type() == DetectorType::Eiger); - REQUIRE(f.timing_mode() == TimingMode::Auto); + REQUIRE(f.timing_mode() == TimingMode::AUTO_TIMING); REQUIRE(f.detector_layout() == xy{2, 2}); REQUIRE(f.n_modules() == 4); REQUIRE(f.image_size_in_bytes() == 262144); diff --git a/src/to_string.cpp b/src/to_string.cpp index bac7873b..e8265324 100644 --- a/src/to_string.cpp +++ b/src/to_string.cpp @@ -35,9 +35,15 @@ template <> DetectorType string_to(const std::string &arg) { template <> TimingMode string_to(const std::string &arg) { if (arg == "auto") - return TimingMode::Auto; + return TimingMode::AUTO_TIMING; if (arg == "trigger") - return TimingMode::Trigger; + return TimingMode::TRIGGER_EXPOSURE; + if (arg == "gating") + return TimingMode::GATED; + if (arg == "burst_trigger") + return TimingMode::BURST_TRIGGER; + if (arg == "trigger_gating") + return TimingMode::TRIGGER_GATED; throw std::runtime_error("Could not decode timing mode from: \"" + arg + "\""); } diff --git a/src/to_string.test.cpp b/src/to_string.test.cpp index 2385700a..4acd7813 100644 --- a/src/to_string.test.cpp +++ b/src/to_string.test.cpp @@ -36,9 +36,10 @@ TEST_CASE("DetectorType string to enum") { } TEST_CASE("TimingMode string to enum") { - REQUIRE(string_to("auto") == aare::TimingMode::Auto); + REQUIRE(string_to("auto") == + aare::TimingMode::AUTO_TIMING); REQUIRE(string_to("trigger") == - aare::TimingMode::Trigger); + aare::TimingMode::TRIGGER_EXPOSURE); REQUIRE_THROWS(string_to("invalid_mode")); }