mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-05-16 06:35:36 +02:00
0837de2a5a
* round CTB clocks to next closest possible value, added freq measurement * added time for firmware to measrue actual value after frequency change * add check for backwards compatibility * change CTB and XCTB clock values to MHz, TODO: units and validation errors * changed runclk command to use units and float, TODO: dbit, adcclk, why is everything called StringTo ? * do the same for dbit and adcclk * added tolerance to exptime, fixed test * update default values in server defs * added virtual check in Altera_PLL, update testcases * change python and pyctbgui to accept and return floating point MHz * update help and comments * Dev/ctb clocks fix (#1434) * introduced new type Hz, typetraits, String conversions, command generation (not yet generated) * incorrect unit typo * cmd generation and compiles * default to MHz, removed space between units for consistency with timers, min and max checks for clks * in python, but need to change the default to Hz again for clean code and intuition * allow ints, doubles, implicit conversions * dont allow raw ints, doubles and implicit conversions * fixed tests * added operators for Hz in python * fix test for min clk for xilinx ctb * fix test * fix python tests * fixed xilinx period and default clks * test fix * removed the 3 clock cycle check for ctb and implemented properly the max adc clk frq for altera ctb * removing 3 clock cycle code from xilinx as well * formatting * loadpattern before 3 clk cycles code * actualtime and measurement time to be implemented in 100ns already in fw * fix tests * pyzmq dependency forthe tests * fixed pyctbgui for freq * insert tolerance check again * also added tolerance check for patwaittime * formatting * minor: rounding test * removed Rep redundant in ToString for freq * intro frequency unit enums, removed unnecessary template behavior for ToString with freq unit, switching from parsing string unit argument to the enum argument for ToString, adding parsing string to unit at CLI boundary * minor, and binaries * minor, default clk vals are 0 but set up at detector setup * get frequency only for that unit * tolerance process * missed in previous commit * some more changes to exptime and validations * ctb is probably done * periodleft and delayleft * fixed xilinx freq conv as well * fixed m3 bug, binaries * xilinx: setup also done in stop server so that the clk is not 0 * missed a test marker * binaries in * review fixes, simpler validation of timers in ctb and xilinx ctb * typo fix * format * fix tests --------- Co-authored-by: Martin Mueller <martin.mueller@psi.ch> Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
168 lines
6.0 KiB
C++
168 lines
6.0 KiB
C++
// SPDX-License-Identifier: LGPL-3.0-or-other
|
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
#pragma once
|
|
|
|
/**
|
|
* \file Result.h
|
|
* Result is a thin wrapper around std::vector and used for returning values
|
|
* from the detector. Since every module could have a different value, we need
|
|
* to return a vector instead of just a single value.
|
|
*
|
|
* Easy conversions to single values are provided using the squash and tsquash
|
|
* method.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "sls/ToString.h"
|
|
#include "sls/TypeTraits.h"
|
|
#include "sls/container_utils.h"
|
|
|
|
namespace sls {
|
|
|
|
/**
|
|
* @tparam T type to store in the result
|
|
* @tparam Allocator for the underlying vector, default
|
|
*/
|
|
template <class T, class Allocator = std::allocator<T>> class Result {
|
|
/** wrapped vector */
|
|
std::vector<T, Allocator> vec;
|
|
|
|
public:
|
|
Result() = default;
|
|
Result(std::initializer_list<T> list) : vec(list){};
|
|
|
|
/** Custom constructor from integer type to Result<ns> or Result<bool> */
|
|
template <typename V, typename = typename std::enable_if<
|
|
std::is_integral<V>::value &&
|
|
(std::is_same<T, time::ns>::value ||
|
|
std::is_same<T, defs::Hz>::value ||
|
|
std::is_same<T, bool>::value)>::type>
|
|
Result(const Result<V> &from) {
|
|
vec.reserve(from.size());
|
|
for (const auto &item : from)
|
|
vec.push_back(T(item));
|
|
}
|
|
|
|
/** Custom constructor from integer type to Result<ns> or Result<bool> */
|
|
template <typename V, typename = typename std::enable_if<
|
|
std::is_integral<V>::value &&
|
|
(std::is_same<T, time::ns>::value ||
|
|
std::is_same<T, defs::Hz>::value ||
|
|
std::is_same<T, bool>::value)>::type>
|
|
Result(Result<V> &from) {
|
|
vec.reserve(from.size());
|
|
for (const auto &item : from)
|
|
vec.push_back(T(item));
|
|
}
|
|
|
|
/** Custom constructor from integer type to Result<ns> or Result<bool> */
|
|
template <typename V, typename = typename std::enable_if<
|
|
std::is_integral<V>::value &&
|
|
(std::is_same<T, time::ns>::value ||
|
|
std::is_same<T, defs::Hz>::value ||
|
|
std::is_same<T, bool>::value)>::type>
|
|
Result(Result<V> &&from) {
|
|
vec.reserve(from.size());
|
|
for (const auto &item : from)
|
|
vec.push_back(T(item));
|
|
}
|
|
|
|
/**
|
|
* Forward arguments to the constructor of std::vector
|
|
* @tparam Args template paramter pack to forward
|
|
*/
|
|
template <typename... Args>
|
|
Result(Args &&...args) : vec(std::forward<Args>(args)...) {}
|
|
|
|
using value_type = typename std::vector<T>::value_type;
|
|
using iterator = typename std::vector<T>::iterator;
|
|
using const_iterator = typename std::vector<T>::const_iterator;
|
|
using size_type = typename std::vector<T>::size_type;
|
|
using reference = typename std::vector<T>::reference;
|
|
using const_reference = typename std::vector<T>::const_reference;
|
|
|
|
auto begin() noexcept -> decltype(vec.begin()) { return vec.begin(); }
|
|
auto begin() const noexcept -> decltype(vec.begin()) { return vec.begin(); }
|
|
auto cbegin() const noexcept -> decltype(vec.cbegin()) {
|
|
return vec.cbegin();
|
|
}
|
|
auto end() noexcept -> decltype(vec.end()) { return vec.end(); }
|
|
auto end() const noexcept -> decltype(vec.end()) { return vec.end(); }
|
|
auto cend() const noexcept -> decltype(vec.cend()) { return vec.cend(); }
|
|
auto size() const noexcept -> decltype(vec.size()) { return vec.size(); }
|
|
auto empty() const noexcept -> decltype(vec.empty()) { return vec.empty(); }
|
|
auto front() -> decltype(vec.front()) { return vec.front(); }
|
|
auto front() const -> decltype(vec.front()) { return vec.front(); }
|
|
void reserve(size_type new_cap) { vec.reserve(new_cap); }
|
|
|
|
template <typename V>
|
|
auto push_back(V value) -> decltype(vec.push_back(value)) {
|
|
vec.push_back(std::forward<V>(value));
|
|
}
|
|
|
|
auto operator[](size_type pos) -> decltype(vec[pos]) { return vec[pos]; }
|
|
const_reference operator[](size_type pos) const { return vec[pos]; }
|
|
|
|
/**
|
|
* If all elements are equal it returns the front value
|
|
* otherwise a default constructed T
|
|
*/
|
|
T squash() const { return Squash(vec); }
|
|
|
|
/**
|
|
* If all elements are equal it returns the front value
|
|
* otherwise throws an exception with custom message provided
|
|
*/
|
|
T tsquash(const std::string &error_msg) {
|
|
if (equal())
|
|
return vec.front();
|
|
else
|
|
throw RuntimeError(error_msg);
|
|
}
|
|
/**
|
|
* If all elements are equal return the front value, otherwise
|
|
* return the supplied default value
|
|
*/
|
|
T squash(const T &default_value) const {
|
|
return Squash(vec, default_value);
|
|
}
|
|
|
|
/** 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 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> */
|
|
operator std::vector<T>() { return vec; }
|
|
};
|
|
|
|
/**
|
|
* operator << overload to print Result, uses ToString for the conversion
|
|
* @tparam T type stored in the Result
|
|
*/
|
|
template <typename T>
|
|
std::ostream &operator<<(std::ostream &os, const Result<T> &res) {
|
|
return os << ToString(res);
|
|
}
|
|
|
|
} // namespace sls
|