mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-05-01 05:52:22 +02:00
5ec5d46c48
Build and Deploy on local RHEL9 / build (push) Successful in 2m12s
Build on RHEL9 docker image / build (push) Successful in 3m33s
Build on RHEL8 docker image / build (push) Successful in 4m54s
Build and Deploy on local RHEL8 / build (push) Successful in 4m54s
Run Simulator Tests on local RHEL9 / build (push) Successful in 14m41s
Run Simulator Tests on local RHEL8 / build (push) Successful in 17m10s
* not allowing power names for dac names to prevent duplicate names * wip * v_abcd commands should be removed to prevent unintentional usage and throw with a suggestion command for dac and power * binary in * dacs with power dac names should work and do not take in dac units to avoid ambiguity, test with 0 value for power dacs should fail, to do: implement power commands * wip: power in client, tests, and fixed server interfaces and ctb implementation, not tested * wip. client and xilinx todo * wip: ctb power works, tests left * fixed some tests * added vchip check * python cmds still left. wip * fixed xilinx. python left * wip * wip. xilinx * fixed powerchip for ctb * power all returns all * configtransceiver is removed * wip python * wip * wip * wip * wip * wip * wip * wip xilinx * wip * wip * wip * pybindings * fix getdacindex and getdacname for normal detectors to throw if random index that doesnt fit to the detector * wip * fixed tests * fixes for python api * wip * python: moved powerlist to Ctb * fixed tests to work for powelist in Ctb * moved signallist, adclist, slowadc, slowadclist to Ctb * throw approperiate error when no modules added for powers * added dac test * fix dac default names and test for dacs * ctb dacs, yet to do othe rdacs * dacs should work now even in tests * run all tests * DetectorPowers->NamedPowers in ctb * comments * removed unnecessary test code * removed hard coded dac names in python NamedDacs and NamedPowers * minor * minor * fixed error messages * changed power to be able to set DAC directly, using enable and disable methods with enabled to get
362 lines
12 KiB
C++
362 lines
12 KiB
C++
// SPDX-License-Identifier: LGPL-3.0-or-other
|
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
#pragma once
|
|
|
|
/**
|
|
* \file ToString.h
|
|
*
|
|
* Conversion from various types to std::string
|
|
*
|
|
*/
|
|
|
|
#include "sls/TimeHelper.h"
|
|
#include "sls/TypeTraits.h"
|
|
#include "sls/bit_utils.h"
|
|
#include "sls/sls_detector_defs.h"
|
|
#include "sls/sls_detector_exceptions.h"
|
|
#include "sls/string_utils.h"
|
|
#include <array>
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
#include <map>
|
|
#include <sstream>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
namespace sls {
|
|
|
|
using defs = slsDetectorDefs;
|
|
std::string ToString(const defs::runStatus s);
|
|
std::string ToString(const defs::detectorType s);
|
|
std::string ToString(const defs::detectorSettings s);
|
|
std::string ToString(const defs::speedLevel s);
|
|
std::string ToString(const defs::timingMode s);
|
|
std::string ToString(const defs::frameDiscardPolicy s);
|
|
std::string ToString(const defs::fileFormat s);
|
|
std::string ToString(const defs::externalSignalFlag s);
|
|
std::string ToString(const defs::readoutMode s);
|
|
std::string ToString(const defs::dacIndex s);
|
|
std::string ToString(const std::vector<defs::dacIndex> &vec);
|
|
std::string ToString(const defs::powerIndex s);
|
|
std::string ToString(const std::vector<defs::powerIndex> &vec);
|
|
std::string ToString(const defs::burstMode s);
|
|
std::string ToString(const defs::timingSourceType s);
|
|
std::string ToString(const defs::M3_GainCaps s);
|
|
std::string ToString(const defs::portPosition s);
|
|
std::string ToString(const defs::streamingInterface s);
|
|
std::string ToString(const defs::vetoAlgorithm s);
|
|
std::string ToString(const defs::gainMode s);
|
|
std::string ToString(const defs::polarity s);
|
|
std::string ToString(const defs::timingInfoDecoder s);
|
|
std::string ToString(const defs::collectionMode s);
|
|
|
|
std::string ToString(bool value);
|
|
std::string ToString(bool value, defs::boolFormat format);
|
|
|
|
std::string ToString(const slsDetectorDefs::xy &coord);
|
|
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
|
|
std::string ToString(const slsDetectorDefs::ROI &roi);
|
|
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi);
|
|
std::string ToString(const slsDetectorDefs::rxParameters &r);
|
|
std::ostream &operator<<(std::ostream &os,
|
|
const slsDetectorDefs::rxParameters &r);
|
|
std::string ToString(const slsDetectorDefs::scanParameters &r);
|
|
std::ostream &operator<<(std::ostream &os,
|
|
const slsDetectorDefs::scanParameters &r);
|
|
std::string ToString(const slsDetectorDefs::currentSrcParameters &r);
|
|
std::ostream &operator<<(std::ostream &os,
|
|
const slsDetectorDefs::currentSrcParameters &r);
|
|
std::string ToString(const slsDetectorDefs::pedestalParameters &r);
|
|
std::ostream &operator<<(std::ostream &os,
|
|
const slsDetectorDefs::pedestalParameters &r);
|
|
|
|
const std::string &ToString(const std::string &s);
|
|
|
|
/** Convert std::chrono::duration with specified output unit */
|
|
template <typename T, typename Rep = double>
|
|
typename std::enable_if<is_duration<T>::value, std::string>::type
|
|
ToString(T t, const std::string &unit) {
|
|
using std::chrono::duration;
|
|
using std::chrono::duration_cast;
|
|
std::ostringstream os;
|
|
if (unit == "ns")
|
|
os << duration_cast<duration<Rep, std::nano>>(t).count() << unit;
|
|
else if (unit == "us")
|
|
os << duration_cast<duration<Rep, std::micro>>(t).count() << unit;
|
|
else if (unit == "ms")
|
|
os << duration_cast<duration<Rep, std::milli>>(t).count() << unit;
|
|
else if (unit == "s")
|
|
os << duration_cast<duration<Rep>>(t).count() << unit;
|
|
else
|
|
throw std::runtime_error("Unknown unit: " + unit);
|
|
return os.str();
|
|
}
|
|
|
|
/** Convert std::chrono::duration automatically selecting the unit */
|
|
template <typename From>
|
|
typename std::enable_if<is_duration<From>::value, std::string>::type
|
|
ToString(From t) {
|
|
auto tns = std::chrono::duration_cast<std::chrono::nanoseconds>(t);
|
|
if (time::abs(tns) < std::chrono::microseconds(1)) {
|
|
return ToString(tns, "ns");
|
|
} else if (time::abs(tns) < std::chrono::milliseconds(1)) {
|
|
return ToString(tns, "us");
|
|
} else if (time::abs(tns) < std::chrono::milliseconds(99)) {
|
|
return ToString(tns, "ms");
|
|
} else {
|
|
return ToString(tns, "s");
|
|
}
|
|
}
|
|
|
|
/** Conversion of floating point values, removes trailing zeros*/
|
|
template <typename T>
|
|
typename std::enable_if<std::is_floating_point<T>::value, std::string>::type
|
|
ToString(const T &value) {
|
|
auto s = std::to_string(value);
|
|
s.erase(s.find_last_not_of('0') + 1u, std::string::npos);
|
|
s.erase(s.find_last_not_of('.') + 1u, std::string::npos);
|
|
return s;
|
|
}
|
|
|
|
/** Conversion of integer types, do not remove trailing zeros */
|
|
template <typename T>
|
|
typename std::enable_if<std::is_integral<T>::value, std::string>::type
|
|
ToString(const T &value) {
|
|
return std::to_string(value);
|
|
}
|
|
|
|
/** Conversion of integer types, do not remove trailing zeros */
|
|
template <typename T>
|
|
typename std::enable_if<std::is_integral<T>::value, std::string>::type
|
|
ToStringHex(const T &value) {
|
|
std::ostringstream os;
|
|
os << "0x" << std::hex << value << std::dec;
|
|
return os.str();
|
|
}
|
|
|
|
/** Conversion of integer types, do not remove trailing zeros */
|
|
template <typename T>
|
|
typename std::enable_if<std::is_integral<T>::value, std::string>::type
|
|
ToStringHex(const T &value, int width) {
|
|
std::ostringstream os;
|
|
os << "0x" << std::hex << std::setfill('0') << std::setw(width) << value
|
|
<< std::dec;
|
|
return os.str();
|
|
}
|
|
|
|
/**
|
|
* hex
|
|
* For a container loop over all elements and call ToString on the element
|
|
* Container<std::string> is excluded
|
|
*/
|
|
template <typename T>
|
|
typename std::enable_if<
|
|
is_container<T>::value &&
|
|
!std::is_same<typename T::value_type, std::string>::value,
|
|
std::string>::type
|
|
ToStringHex(const T &container) {
|
|
std::ostringstream os;
|
|
os << '[';
|
|
if (!container.empty()) {
|
|
auto it = container.cbegin();
|
|
os << ToStringHex(*it++);
|
|
while (it != container.cend())
|
|
os << ", " << ToStringHex(*it++);
|
|
}
|
|
os << ']';
|
|
return os.str();
|
|
}
|
|
|
|
template <typename T>
|
|
typename std::enable_if<
|
|
is_container<T>::value &&
|
|
!std::is_same<typename T::value_type, std::string>::value,
|
|
std::string>::type
|
|
ToStringHex(const T &container, int width) {
|
|
std::ostringstream os;
|
|
os << '[';
|
|
if (!container.empty()) {
|
|
auto it = container.cbegin();
|
|
os << ToStringHex(*it++, width);
|
|
while (it != container.cend())
|
|
os << ", " << ToStringHex(*it++, width);
|
|
}
|
|
os << ']';
|
|
return os.str();
|
|
}
|
|
|
|
template <typename KeyType, typename ValueType>
|
|
std::string ToString(const std::map<KeyType, ValueType> &m) {
|
|
std::ostringstream os;
|
|
os << '{';
|
|
if (!m.empty()) {
|
|
auto it = m.cbegin();
|
|
os << ToString(it->first) << ": " << ToString(it->second);
|
|
it++;
|
|
while (it != m.cend()) {
|
|
os << ", " << ToString(it->first) << ": " << ToString(it->second);
|
|
it++;
|
|
}
|
|
}
|
|
os << '}';
|
|
return os.str();
|
|
}
|
|
|
|
/**
|
|
* Print a c style array
|
|
*/
|
|
template <typename T, size_t size> std::string ToString(const T (&arr)[size]) {
|
|
std::ostringstream os;
|
|
os << '[';
|
|
if (size) {
|
|
size_t i = 0;
|
|
os << ToString(arr[i++]);
|
|
for (; i < size; ++i)
|
|
os << ", " << ToString(arr[i]);
|
|
}
|
|
os << ']';
|
|
return os.str();
|
|
}
|
|
|
|
/**
|
|
* For a container loop over all elements and call ToString on the element
|
|
* Container<std::string> is excluded
|
|
*/
|
|
template <typename T>
|
|
typename std::enable_if<
|
|
is_container<T>::value &&
|
|
!std::is_same<typename T::value_type, std::string>::value,
|
|
std::string>::type
|
|
ToString(const T &container) {
|
|
std::ostringstream os;
|
|
os << '[';
|
|
if (!container.empty()) {
|
|
auto it = container.cbegin();
|
|
os << ToString(*it++);
|
|
while (it != container.cend())
|
|
os << ", " << ToString(*it++);
|
|
}
|
|
os << ']';
|
|
return os.str();
|
|
}
|
|
|
|
/**
|
|
* Special case when container holds a string, don't call ToString again but
|
|
* print directly to stream
|
|
*/
|
|
|
|
template <typename T>
|
|
typename std::enable_if<
|
|
is_container<T>::value &&
|
|
std::is_same<typename T::value_type, std::string>::value,
|
|
std::string>::type
|
|
ToString(const T &vec) {
|
|
std::ostringstream os;
|
|
os << '[';
|
|
if (!vec.empty()) {
|
|
auto it = vec.begin();
|
|
os << *it++;
|
|
while (it != vec.end())
|
|
os << ", " << *it++;
|
|
}
|
|
os << ']';
|
|
return os.str();
|
|
}
|
|
|
|
/** Container and specified unit, call ToString(value, unit) */
|
|
template <typename T>
|
|
typename std::enable_if<is_container<T>::value, std::string>::type
|
|
ToString(const T &container, const std::string &unit) {
|
|
std::ostringstream os;
|
|
os << '[';
|
|
if (!container.empty()) {
|
|
auto it = container.cbegin();
|
|
os << ToString(*it++, unit);
|
|
while (it != container.cend())
|
|
os << ", " << ToString(*it++, unit);
|
|
}
|
|
os << ']';
|
|
return os.str();
|
|
}
|
|
|
|
template <typename T>
|
|
T StringTo(const std::string &t, const std::string &unit) {
|
|
double tval{0};
|
|
try {
|
|
tval = std::stod(t);
|
|
} catch (const std::invalid_argument &e) {
|
|
throw RuntimeError("Could not convert string to time");
|
|
}
|
|
|
|
using std::chrono::duration;
|
|
using std::chrono::duration_cast;
|
|
if (unit == "ns") {
|
|
return duration_cast<T>(duration<double, std::nano>(tval));
|
|
} else if (unit == "us") {
|
|
return duration_cast<T>(duration<double, std::micro>(tval));
|
|
} else if (unit == "ms") {
|
|
return duration_cast<T>(duration<double, std::milli>(tval));
|
|
} else if (unit == "s" || unit.empty()) {
|
|
return duration_cast<T>(std::chrono::duration<double>(tval));
|
|
} else {
|
|
throw RuntimeError(
|
|
"Invalid unit in conversion from string to std::chrono::duration");
|
|
}
|
|
}
|
|
|
|
template <typename T> T StringTo(const std::string &t) {
|
|
std::string tmp{t};
|
|
auto unit = RemoveUnit(tmp);
|
|
return StringTo<T>(tmp, unit);
|
|
}
|
|
|
|
template <> defs::detectorType StringTo(const std::string &s);
|
|
template <> defs::detectorSettings StringTo(const std::string &s);
|
|
template <> defs::speedLevel StringTo(const std::string &s);
|
|
template <> defs::timingMode StringTo(const std::string &s);
|
|
template <> defs::frameDiscardPolicy StringTo(const std::string &s);
|
|
template <> defs::fileFormat StringTo(const std::string &s);
|
|
template <> defs::externalSignalFlag StringTo(const std::string &s);
|
|
template <> defs::readoutMode StringTo(const std::string &s);
|
|
template <> defs::dacIndex StringTo(const std::string &s);
|
|
template <> defs::powerIndex StringTo(const std::string &s);
|
|
template <> defs::burstMode StringTo(const std::string &s);
|
|
template <> defs::timingSourceType StringTo(const std::string &s);
|
|
template <> defs::M3_GainCaps StringTo(const std::string &s);
|
|
template <> defs::portPosition StringTo(const std::string &s);
|
|
template <> defs::streamingInterface StringTo(const std::string &s);
|
|
template <> defs::vetoAlgorithm StringTo(const std::string &s);
|
|
template <> defs::gainMode StringTo(const std::string &s);
|
|
template <> defs::polarity StringTo(const std::string &s);
|
|
template <> defs::timingInfoDecoder StringTo(const std::string &s);
|
|
template <> defs::collectionMode StringTo(const std::string &s);
|
|
template <> RegisterAddress StringTo(const std::string &s);
|
|
template <> RegisterValue StringTo(const std::string &s);
|
|
|
|
template <> uint8_t StringTo(const std::string &s);
|
|
template <> uint16_t StringTo(const std::string &s);
|
|
template <> uint32_t StringTo(const std::string &s);
|
|
template <> uint64_t StringTo(const std::string &s);
|
|
template <> int StringTo(const std::string &s);
|
|
template <> bool StringTo(const std::string &s);
|
|
bool StringTo(const std::string &s, defs::boolFormat format);
|
|
template <> int64_t StringTo(const std::string &s);
|
|
|
|
/** For types with a .str() method use this for conversion */
|
|
template <typename T>
|
|
typename std::enable_if<has_str<T>::value, std::string>::type
|
|
ToString(const T &obj) {
|
|
return obj.str();
|
|
}
|
|
|
|
template <typename T>
|
|
std::vector<T> StringTo(const std::vector<std::string> &strings) {
|
|
std::vector<T> result;
|
|
result.reserve(strings.size());
|
|
for (const auto &s : strings)
|
|
result.push_back(StringTo<T>(s));
|
|
return result;
|
|
}
|
|
|
|
} // namespace sls
|