mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-20 02:40:03 +02:00
8.0.0.rc: jf sync: stopping master gives idle (#823)
* 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 <erik.frojdh@gmail.com>
This commit is contained in:
parent
bf26533fd8
commit
ff60b8c379
@ -16,6 +16,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "sls/ToString.h"
|
#include "sls/ToString.h"
|
||||||
|
#include "sls/TypeTraits.h"
|
||||||
#include "sls/container_utils.h"
|
#include "sls/container_utils.h"
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
@ -128,6 +129,25 @@ template <class T, class Allocator = std::allocator<T>> class Result {
|
|||||||
/** Test whether all elements of the result are equal */
|
/** Test whether all elements of the result are equal */
|
||||||
bool equal() const noexcept { return allEqual(vec); }
|
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 V, typename... Args, typename = AllSame<V, Args...>>
|
||||||
|
typename std::enable_if<std::is_same<V, T>::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<T> to std::vector<T> */
|
/** Convert Result<T> to std::vector<T> */
|
||||||
operator std::vector<T>() { return vec; }
|
operator std::vector<T>() { return vec; }
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
@ -873,18 +874,25 @@ void Detector::startDetectorReadout() {
|
|||||||
|
|
||||||
void Detector::stopDetector(Positions pos) {
|
void Detector::stopDetector(Positions pos) {
|
||||||
|
|
||||||
// stop and check status X times
|
|
||||||
int retries{0};
|
int retries{0};
|
||||||
// avoid default construction of runStatus::IDLE on squash
|
auto status = getDetectorStatus(pos);
|
||||||
auto status = getDetectorStatus().squash(defs::runStatus::RUNNING);
|
|
||||||
while (status != defs::runStatus::IDLE &&
|
// jf sync fix: status [stopped or idle] = [stopped]
|
||||||
status != defs::runStatus::STOPPED) {
|
// sync issue: (master idle sometimes, slaves stopped)
|
||||||
if (status == defs::runStatus::ERROR) {
|
|
||||||
throw RuntimeError(
|
// eiger fix: stop multiple times from multi client till all modules stopped
|
||||||
"Could not stop detector. Returned error status.");
|
// 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);
|
pimpl->stopDetector(pos);
|
||||||
status = getDetectorStatus().squash(defs::runStatus::RUNNING);
|
status = getDetectorStatus(pos);
|
||||||
++retries;
|
++retries;
|
||||||
|
|
||||||
if (retries == 10)
|
if (retries == 10)
|
||||||
@ -903,7 +911,7 @@ void Detector::stopDetector(Positions pos) {
|
|||||||
for (auto it : res) {
|
for (auto it : res) {
|
||||||
maxVal = std::max(maxVal, it);
|
maxVal = std::max(maxVal, it);
|
||||||
}
|
}
|
||||||
setNextFrameNumber(maxVal + 1);
|
setNextFrameNumber(maxVal + 1, pos);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
|
@ -196,4 +196,24 @@ TEST_CASE("String conversions") {
|
|||||||
"[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]");
|
"[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Any element is equal"){
|
||||||
|
Result<int> r{1,2,3,4,5};
|
||||||
|
REQUIRE(r.any(3));
|
||||||
|
REQUIRE_FALSE(r.any(9));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Result contains only the specified elements"){
|
||||||
|
Result<int> r{1,1,1};
|
||||||
|
REQUIRE(r.contains_only(1));
|
||||||
|
REQUIRE(r.contains_only(1,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Only with multiple values"){
|
||||||
|
Result<int> 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
|
} // namespace sls
|
||||||
|
@ -103,4 +103,14 @@ template <typename T> struct is_vector : public std::false_type {};
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_vector<std::vector<T>> : public std::true_type {};
|
struct is_vector<std::vector<T>> : public std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class...> struct Conjunction : std::true_type {};
|
||||||
|
template<class B1> struct Conjunction<B1> : B1 {};
|
||||||
|
template<class B1, class... Bn>
|
||||||
|
struct Conjunction<B1, Bn...>
|
||||||
|
: std::conditional<bool(B1::value), Conjunction<Bn...>, B1>::type {};
|
||||||
|
|
||||||
|
template<typename T, typename... Ts>
|
||||||
|
using AllSame = typename std::enable_if<Conjunction<std::is_same<T, Ts>...>::value>::type;
|
||||||
} // namespace sls
|
} // namespace sls
|
Loading…
x
Reference in New Issue
Block a user