From ff60b8c379c1821a4312ac5f7a01e64e7042b0b7 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Fri, 13 Oct 2023 15:25:19 +0200 Subject: [PATCH] 8.0.0.rc: jf sync: stopping master gives idle (#823) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * jf sync mode master could return idle when stopped and so not all modules return the same value and must check for 'stopped or idle', Also must throw if any of the module gives an error * added contains_only to sls::Result (#827) * added variadic template for checking if a result contains only specified values * fix for gcc4.8 * renamed to Result::contains_only * stop on only the positions --------- Co-authored-by: Erik Fröjdh --- slsDetectorSoftware/include/sls/Result.h | 20 ++++++++++++++++ slsDetectorSoftware/src/Detector.cpp | 28 +++++++++++++++-------- slsDetectorSoftware/tests/test-Result.cpp | 20 ++++++++++++++++ slsSupportLib/include/sls/TypeTraits.h | 10 ++++++++ 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/slsDetectorSoftware/include/sls/Result.h b/slsDetectorSoftware/include/sls/Result.h index 2578ad2ba..73e5fc332 100644 --- a/slsDetectorSoftware/include/sls/Result.h +++ b/slsDetectorSoftware/include/sls/Result.h @@ -16,6 +16,7 @@ #include #include "sls/ToString.h" +#include "sls/TypeTraits.h" #include "sls/container_utils.h" namespace sls { @@ -128,6 +129,25 @@ template > class Result { /** Test whether all elements of the result are equal */ bool equal() const noexcept { return allEqual(vec); } + /** Test whether any element of the result are equal to a value */ + bool any(const T &value) const noexcept { return anyEqualTo(vec, value); } + + template > + typename std::enable_if::value, bool>::type + contains_only(const V &a, const Args &...args) const noexcept { + auto values = {a, args...}; + for (const auto &element : vec) { + int found = 0; + for (const auto &value : values) { + if (value == element) + found++; + } + if (!found) + return false; + } + return true; + } + /** Convert Result to std::vector */ operator std::vector() { return vec; } }; diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 344bde73c..4124110d3 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -18,6 +18,7 @@ #include #include +#include #include namespace sls { @@ -873,18 +874,25 @@ void Detector::startDetectorReadout() { void Detector::stopDetector(Positions pos) { - // stop and check status X times int retries{0}; - // avoid default construction of runStatus::IDLE on squash - auto status = getDetectorStatus().squash(defs::runStatus::RUNNING); - while (status != defs::runStatus::IDLE && - status != defs::runStatus::STOPPED) { - if (status == defs::runStatus::ERROR) { - throw RuntimeError( - "Could not stop detector. Returned error status."); + auto status = getDetectorStatus(pos); + + // jf sync fix: status [stopped or idle] = [stopped] + // sync issue: (master idle sometimes, slaves stopped) + + // eiger fix: stop multiple times from multi client till all modules stopped + // issue: asynchronous start and stop scripts with a module being started + // (stop before) and waiting for the other to be done. So a module that was + // idle before stopping will return running (after async start script) when + // getting status after, which will then be stopped again. + + while (!status.contains_only(defs::runStatus::IDLE, defs::runStatus::STOPPED)){ + if (status.any(defs::runStatus::ERROR)) { + throw RuntimeError("Could not stop detector. At least one module " + "returned error status."); } pimpl->stopDetector(pos); - status = getDetectorStatus().squash(defs::runStatus::RUNNING); + status = getDetectorStatus(pos); ++retries; if (retries == 10) @@ -903,7 +911,7 @@ void Detector::stopDetector(Positions pos) { for (auto it : res) { maxVal = std::max(maxVal, it); } - setNextFrameNumber(maxVal + 1); + setNextFrameNumber(maxVal + 1, pos); } } break; default: diff --git a/slsDetectorSoftware/tests/test-Result.cpp b/slsDetectorSoftware/tests/test-Result.cpp index 6763a43d0..30a735f28 100644 --- a/slsDetectorSoftware/tests/test-Result.cpp +++ b/slsDetectorSoftware/tests/test-Result.cpp @@ -196,4 +196,24 @@ TEST_CASE("String conversions") { "[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]"); } +TEST_CASE("Any element is equal"){ + Result r{1,2,3,4,5}; + REQUIRE(r.any(3)); + REQUIRE_FALSE(r.any(9)); +} + +TEST_CASE("Result contains only the specified elements"){ + Result r{1,1,1}; + REQUIRE(r.contains_only(1)); + REQUIRE(r.contains_only(1,1)); +} + +TEST_CASE("Only with multiple values"){ + Result r{1,1,2,1,2,1,1}; + REQUIRE_FALSE(r.contains_only(1)); + REQUIRE_FALSE(r.contains_only(2)); + REQUIRE(r.contains_only(1,2)); + REQUIRE(r.contains_only(2,1)); +} + } // namespace sls diff --git a/slsSupportLib/include/sls/TypeTraits.h b/slsSupportLib/include/sls/TypeTraits.h index cbbeb7bea..80bee0b44 100644 --- a/slsSupportLib/include/sls/TypeTraits.h +++ b/slsSupportLib/include/sls/TypeTraits.h @@ -103,4 +103,14 @@ template struct is_vector : public std::false_type {}; template struct is_vector> : public std::true_type {}; + + +template struct Conjunction : std::true_type {}; +template struct Conjunction : B1 {}; +template +struct Conjunction + : std::conditional, B1>::type {}; + +template +using AllSame = typename std::enable_if...>::value>::type; } // namespace sls \ No newline at end of file