Moving headers into include/sls (#212)

This commit is contained in:
Erik Fröjdh
2020-11-02 16:05:28 +01:00
committed by GitHub
parent a57bbc084c
commit a15d8dd30a
199 changed files with 417 additions and 413 deletions

View File

@ -0,0 +1,47 @@
#pragma once
#include "sls/DataSocket.h"
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
namespace sls {
class ClientSocket : public DataSocket {
public:
ClientSocket(std::string stype, const std::string &hostname,
uint16_t port_number);
ClientSocket(std::string stype, struct sockaddr_in addr);
int sendCommandThenRead(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
std::string readErrorMessage();
private:
void readReply(int &ret, void *retval, size_t retval_size);
struct sockaddr_in serverAddr {};
std::string socketType;
};
class ReceiverSocket : public ClientSocket {
public:
ReceiverSocket(const std::string &hostname, uint16_t port_number)
: ClientSocket("Receiver", hostname, port_number){};
ReceiverSocket(struct sockaddr_in addr) : ClientSocket("Receiver", addr){};
};
class DetectorSocket : public ClientSocket {
public:
DetectorSocket(const std::string &hostname, uint16_t port_number)
: ClientSocket("Detector", hostname, port_number){};
DetectorSocket(struct sockaddr_in addr) : ClientSocket("Detector", addr){};
};
class GuiSocket : public ClientSocket {
public:
GuiSocket(const std::string &hostname, uint16_t port_number)
: ClientSocket("Gui", hostname, port_number){};
GuiSocket(struct sockaddr_in addr) : ClientSocket("Gui", addr){};
};
}; // namespace sls

View File

@ -0,0 +1,87 @@
#pragma once
#include "sls/TypeTraits.h"
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <netdb.h>
#include <numeric>
#include <string>
#include <vector>
namespace sls {
/* Base class for TCP socket, this is used to send data between detector, client
and receiver. Specific protocols inherit from this class.*/
class DataSocket {
public:
DataSocket(int socketId);
DataSocket(DataSocket &&move) noexcept;
virtual ~DataSocket();
DataSocket &operator=(DataSocket &&move) noexcept;
void swap(DataSocket &other) noexcept;
// No copy since the class manage the underlying socket
DataSocket(const DataSocket &) = delete;
DataSocket &operator=(DataSocket const &) = delete;
int getSocketId() const { return sockfd_; }
int Send(const void *buffer, size_t size);
// Send everything that is not a vector or string by using address and
// sizeof
// TODO! We probably should restrict this even more to avoid bugs when
// we send object instead of data
template <typename T>
typename std::enable_if<
!is_vector<typename std::remove_reference<T>::type>::value &&
!std::is_same<typename std::remove_reference<T>::type,
std::string>::value,
int>::type
Send(T &&data) {
return Send(&data, sizeof(data));
}
template <typename T> int Send(const std::vector<T> &vec) {
return Send(vec.data(), sizeof(T) * vec.size());
}
int Send(const std::string &s);
// Variadic template to send all arguments
template <class... Args> int SendAll(Args &&... args) {
auto l = std::initializer_list<int>{Send(args)...};
auto sum = std::accumulate(begin(l), end(l), 0);
return sum;
}
int Receive(void *buffer, size_t size);
template <typename T> int Receive(T &arg) {
return Receive(&arg, sizeof(arg));
}
template <typename T> int Receive(std::vector<T> &buff) {
return Receive(buff.data(), sizeof(T) * buff.size());
}
template <typename T> T Receive() {
T arg;
Receive(&arg, sizeof(arg));
return arg;
}
std::string Receive(size_t length);
int read(void *buffer, size_t size);
int write(void *buffer, size_t size);
int setTimeOut(int t_seconds);
int setReceiveTimeout(int us);
void close();
void shutDownSocket();
void shutdown();
private:
int sockfd_ = -1;
};
}; // namespace sls

View File

@ -0,0 +1,31 @@
#pragma once
#include "sls/DataSocket.h"
namespace sls {
class ServerInterface;
}
#include "sls/ServerSocket.h"
#include "sls/sls_detector_defs.h"
namespace sls {
class ServerInterface : public DataSocket {
using defs = slsDetectorDefs;
public:
ServerInterface(int socketId) : DataSocket(socketId) {}
int sendResult(int ret, void *retval, int retvalSize, char *mess = nullptr);
template <typename T> int sendResult(int ret, T &retval) {
return sendResult(ret, &retval, sizeof(retval, nullptr));
}
template <typename T> int sendResult(T &&retval) {
Send(defs::OK);
Send(retval);
return defs::OK;
}
};
} // namespace sls

View File

@ -0,0 +1,33 @@
#pragma once
#include "sls/DataSocket.h"
#include "sls/ServerInterface.h"
#include "sls/network_utils.h"
#include <cstdint>
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
namespace sls {
class ServerSocket : public DataSocket {
public:
ServerSocket(int port);
ServerInterface accept();
IpAddr getLastClient() const noexcept { return lastClient; }
IpAddr getThisClient() const noexcept { return thisClient; }
IpAddr getLockedBy() const noexcept { return lockedBy; }
bool differentClients() const noexcept { return lastClient != thisClient; }
void setLockedBy(IpAddr addr) { lockedBy = addr; }
void setLastClient(IpAddr addr) { lastClient = addr; }
int getPort() const noexcept { return serverPort; }
private:
IpAddr thisClient;
IpAddr lastClient;
IpAddr lockedBy;
int serverPort;
};
}; // namespace sls

View File

@ -0,0 +1,192 @@
#pragma once
#include "sls/ToString.h"
#include "sls/TypeTraits.h"
#include <array>
#include <cassert>
#include <iostream>
#include <stdexcept>
#include <vector>
namespace sls {
template <typename T, size_t Capacity> class StaticVector {
public:
using size_type = typename std::array<T, Capacity>::size_type;
using value_type = typename std::array<T, Capacity>::value_type;
using iterator = typename std::array<T, Capacity>::iterator;
using const_iterator = typename std::array<T, Capacity>::const_iterator;
private:
size_type current_size{};
std::array<T, Capacity> data_;
public:
StaticVector() = default;
explicit StaticVector(std::initializer_list<T> l) : current_size(l.size()) {
size_check(l.size());
std::copy(l.begin(), l.end(), data_.begin());
}
/** Copy construct from another container */
template <typename V,
typename = typename std::enable_if<
is_container<V>::value &&
std::is_same<T, typename V::value_type>::value>::type>
StaticVector(const V &v) : current_size(v.size()) {
size_check(v.size());
std::copy(v.begin(), v.end(), data_.begin());
}
/** copy assignment from another container */
template <typename V>
typename std::enable_if<is_container<V>::value, StaticVector &>::type
operator=(const V &other) {
size_check(other.size());
std::copy(other.begin(), other.end(), data_.begin());
current_size = other.size();
return *this;
}
operator std::vector<T>() { return std::vector<T>(begin(), end()); }
T &operator[](size_t i) { return data_[i]; }
const T &operator[](size_t i) const { return data_[i]; }
constexpr size_type size() const noexcept { return current_size; }
bool empty() const noexcept { return current_size == 0; }
constexpr size_t capacity() const noexcept { return Capacity; }
void push_back(const T &value) {
if (current_size == Capacity) {
throw std::runtime_error("Container is full");
} else {
data_[current_size] = value;
++current_size;
}
}
void resize(size_t new_size) {
if (new_size > Capacity) {
throw std::runtime_error("Cannot resize beyond capacity");
} else {
current_size = new_size;
}
}
void erase(T *ptr) {
if (ptr >= begin() && ptr < end()) {
current_size = static_cast<size_t>(ptr - begin());
} else {
throw std::runtime_error("tried to erase with a ptr outside obj");
}
}
template <typename Container>
bool is_equal(const Container &c) const noexcept {
if (current_size != c.size()) {
return false;
} else {
for (size_t i = 0; i != current_size; ++i) {
if (data_[i] != c[i]) {
return false;
}
}
}
return true;
}
T &front() noexcept { return data_.front(); }
T &back() noexcept { return data_[current_size - 1]; }
constexpr const T &front() const noexcept { return data_.front(); }
constexpr const T &back() const noexcept { return data_[current_size - 1]; }
// iterators
iterator begin() noexcept { return data_.begin(); }
// auto begin() noexcept -> decltype(data_.begin()) { return data_.begin();
// }
const_iterator begin() const noexcept { return data_.begin(); }
iterator end() noexcept { return &data_[current_size]; }
const_iterator end() const noexcept { return &data_[current_size]; }
const_iterator cbegin() const noexcept { return data_.cbegin(); }
const_iterator cend() const noexcept { return &data_[current_size]; }
void size_check(size_type s) const {
if (s > Capacity) {
throw std::runtime_error(
"Capacity needs to be same size or larger than vector");
}
}
} __attribute__((packed));
template <typename T, size_t CapacityLhs, typename V, size_t CapacityRhs>
bool operator==(const StaticVector<T, CapacityLhs> &lhs,
const StaticVector<V, CapacityRhs> &rhs) {
return lhs.is_equal(rhs);
}
template <typename T, size_t CapacityLhs, typename V, size_t CapacityRhs>
bool operator!=(const StaticVector<T, CapacityLhs> &lhs,
const StaticVector<V, CapacityRhs> &rhs) {
return !(lhs.is_equal(rhs));
}
// Compare with array
template <typename T, size_t CapacityLhs, typename V, size_t Size>
bool operator==(const StaticVector<T, CapacityLhs> &lhs,
const std::array<V, Size> &rhs) {
return lhs.is_equal(rhs);
}
template <typename T, size_t Size, typename V, size_t CapacityRhs>
bool operator==(const std::array<T, Size> &lhs,
const StaticVector<V, CapacityRhs> &rhs) {
return rhs.is_equal(lhs);
}
template <typename T, size_t CapacityLhs, typename V, size_t Size>
bool operator!=(const StaticVector<T, CapacityLhs> &lhs,
const std::array<V, Size> &rhs) {
return !lhs.is_equal(rhs);
}
template <typename T, size_t Size, typename V, size_t CapacityRhs>
bool operator!=(const std::array<T, Size> &lhs,
const StaticVector<V, CapacityRhs> &rhs) {
return !rhs.is_equal(lhs);
}
// Compare with vector
template <typename T, size_t CapacityLhs, typename V>
bool operator==(const StaticVector<T, CapacityLhs> &lhs,
const std::vector<V> &rhs) {
return lhs.is_equal(rhs);
}
template <typename T, typename V, size_t CapacityRhs>
bool operator==(const std::vector<T> &lhs,
const StaticVector<V, CapacityRhs> &rhs) {
return rhs.is_equal(lhs);
}
template <typename T, size_t CapacityLhs, typename V>
bool operator!=(const StaticVector<T, CapacityLhs> &lhs,
const std::vector<V> &rhs) {
return !lhs.is_equal(rhs);
}
template <typename T, typename V, size_t CapacityRhs>
bool operator!=(const std::vector<T> &lhs,
const StaticVector<V, CapacityRhs> &rhs) {
return !rhs.is_equal(lhs);
}
template <typename T, size_t Capacity>
std::ostream &operator<<(std::ostream &os,
const sls::StaticVector<T, Capacity> &c) {
return os << ToString(c);
}
} // namespace sls

View File

@ -0,0 +1,22 @@
#pragma once
#include <chrono>
#include "sls/TypeTraits.h"
namespace sls {
namespace time {
using ns = std::chrono::nanoseconds;
using us = std::chrono::microseconds;
using ms = std::chrono::milliseconds;
using s = std::chrono::seconds;
// Absolute value of std::chrono::duration
template <class Rep, class Period>
constexpr std::chrono::duration<Rep, Period>
abs(std::chrono::duration<Rep, Period> d) {
return d >= d.zero() ? d : -d;
}
static_assert(sizeof(ns) == 8, "ns needs to be 64bit");
} // namespace time
} // namespace sls

View File

@ -0,0 +1,35 @@
#ifndef TIMER_H
#define TIMER_H
#include <chrono>
#include <iostream>
#include <string>
namespace sls {
class Timer {
using clock = std::chrono::high_resolution_clock;
using time_point = std::chrono::time_point<clock>;
public:
Timer(std::string name = "0") : t0(clock::now()), name_(name) {}
double elapsed_ms() {
return std::chrono::duration<double, std::milli>(clock::now() - t0)
.count();
}
double elapsed_s() {
return std::chrono::duration<double>(clock::now() - t0).count();
}
void print_elapsed() {
std::cout << "Timer \"" << name_ << "\": Elapsed time " << elapsed_ms()
<< " ms\n";
}
void restart() { t0 = clock::now(); }
private:
time_point t0;
std::string name_;
};
}; // namespace sls
#endif // TIMER_H

View File

@ -0,0 +1,310 @@
#pragma once
/**
* \file ToString.h
*
* Conversion from various types to std::string
*
*/
#include "sls/TimeHelper.h"
#include "sls/TypeTraits.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::burstMode s);
std::string ToString(const defs::timingSourceType s);
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::patternParameters &r);
std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::patternParameters &r);
std::string ToString(const slsDetectorDefs::scanParameters &r);
std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::scanParameters &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();
}
/**
* 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 sls::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 sls::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::burstMode StringTo(const std::string &s);
template <> defs::timingSourceType 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);
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

View File

@ -0,0 +1,104 @@
#pragma once
#include <type_traits>
#include <vector>
namespace sls {
/**
* Type trait to check if a template parameter is a std::chrono::duration
*/
template <typename T, typename _ = void>
struct is_duration : std::false_type {};
template <typename... Ts> struct is_duration_helper {};
template <typename T>
struct is_duration<T,
typename std::conditional<
false,
is_duration_helper<typename T::rep, typename T::period,
decltype(std::declval<T>().min()),
decltype(std::declval<T>().max()),
decltype(std::declval<T>().zero())>,
void>::type> : public std::true_type {};
/**
* Has str method
*/
template <typename T, typename _ = void> struct has_str : std::false_type {};
template <typename... Ts> struct has_str_helper {};
template <typename T>
struct has_str<T, typename std::conditional<
false, has_str_helper<decltype(std::declval<T>().str())>,
void>::type> : public std::true_type {};
/**
* Has emplace_back method
*/
template <typename T, typename _ = void>
struct has_emplace_back : std::false_type {};
template <typename... Ts> struct has_emplace_back_helper {};
template <typename T>
struct has_emplace_back<
T, typename std::conditional<
false,
has_emplace_back_helper<decltype(std::declval<T>().emplace_back())>,
void>::type> : public std::true_type {};
/**
* Type trait to evaluate if template parameter is
* complying with a standard container
*/
template <typename T, typename _ = void>
struct is_container : std::false_type {};
template <typename... Ts> struct is_container_helper {};
template <typename T>
struct is_container<
T, typename std::conditional<
false,
is_container_helper<
typename std::remove_reference<T>::type::value_type,
typename std::remove_reference<T>::type::size_type,
typename std::remove_reference<T>::type::iterator,
typename std::remove_reference<T>::type::const_iterator,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end()),
decltype(std::declval<T>().cbegin()),
decltype(std::declval<T>().cend()),
decltype(std::declval<T>().empty())>,
void>::type> : public std::true_type {};
/**
* Type trait to evaluate if template parameter is
* complying with a standard container
*/
template <typename T, typename _ = void>
struct is_light_container : std::false_type {};
template <typename... Ts> struct is_light_container_helper {};
template <typename T>
struct is_light_container<
T, typename std::conditional<
false,
is_container_helper<typename T::value_type, typename T::size_type,
typename T::iterator, typename T::const_iterator,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>,
void>::type> : public std::true_type {};
template <typename T> struct is_vector : public std::false_type {};
template <typename T>
struct is_vector<std::vector<T>> : public std::true_type {};
} // namespace sls

View File

@ -0,0 +1,30 @@
#pragma once
/*
UDP socket class to receive data. The intended use is in the
receiver listener loop. Should be used RAII style...
*/
#include <sys/types.h> //ssize_t
namespace sls {
class UdpRxSocket {
const ssize_t packet_size_;
int sockfd_{-1};
public:
UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr,
int kernel_buffer_size = 0);
~UdpRxSocket();
bool ReceivePacket(char *dst) noexcept;
int getBufferSize() const;
void setBufferSize(int size);
ssize_t getPacketSize() const noexcept;
void Shutdown();
// Only for backwards compatibility, this drops the EIGER small pkt, may be
// removed
ssize_t ReceiveDataOnly(char *dst) noexcept;
};
} // namespace sls

View File

@ -0,0 +1,224 @@
#pragma once
/************************************************
* @file zmqSocket.h
* @short functions to open/close zmq sockets
***********************************************/
/**
*@short functions to open/close zmq sockets
*/
#include "sls/sls_detector_exceptions.h"
#include <rapidjson/document.h> //json header in zmq stream
#define MAX_STR_LENGTH 1000
// #define ZMQ_DETAIL
#define ROIVERBOSITY
class zmq_msg_t;
#include "sls/container_utils.h"
#include <map>
#include <memory>
/** zmq header structure */
struct zmqHeader {
/** true if incoming data, false if end of acquisition */
bool data{true};
uint32_t jsonversion{0};
uint32_t dynamicRange{0};
uint64_t fileIndex{0};
/** number of detectors in x axis */
uint32_t ndetx{0};
/** number of detectors in y axis */
uint32_t ndety{0};
/** number of pixels/channels in x axis for this zmq socket */
uint32_t npixelsx{0};
/** number of pixels/channels in y axis for this zmq socket */
uint32_t npixelsy{0};
/** number of bytes for an image in this socket */
uint32_t imageSize{0};
/** frame number from detector */
uint64_t acqIndex{0};
/** frame index (starting at 0 for each acquisition) */
uint64_t frameIndex{0};
/** progress in percentage */
double progress{0};
/** file name prefix */
std::string fname;
/** header from detector */
uint64_t frameNumber{0};
uint32_t expLength{0};
uint32_t packetNumber{0};
uint64_t bunchId{0};
uint64_t timestamp{0};
uint16_t modId{0};
uint16_t row{0};
uint16_t column{0};
uint16_t reserved{0};
uint32_t debug{0};
uint16_t roundRNumber{0};
uint8_t detType{0};
uint8_t version{0};
/** if image should be flipped across x axis */
int flippedDataX{0};
/** quad type (eiger hardware specific) */
uint32_t quad{0};
/** true if complete image, else missing packets */
bool completeImage{false};
/** additional json header */
std::map<std::string, std::string> addJsonHeader;
};
class ZmqSocket {
public:
// Socket Options for optimization
// ZMQ_LINGER default is already -1 means no messages discarded. use this
// options if optimizing required ZMQ_SNDHWM default is 0 means no limit.
// use this to optimize if optimizing required eg. int value = -1; if
// (zmq_setsockopt(socketDescriptor, ZMQ_LINGER, &value,sizeof(value))) {
// Close();
/**
* Constructor for a client
* Creates socket, context and connects to server
* @param hostname_or_ip hostname or ip of server
* @param portnumber port number
*/
ZmqSocket(const char *const hostname_or_ip, const uint32_t portnumber);
/**
* Constructor for a server
* Creates socket, context and connects to server
* @param portnumber port number
* @param ethip is the ip of the ethernet interface to stream zmq from
*/
ZmqSocket(const uint32_t portnumber, const char *ethip);
/** Returns high water mark for outbound messages */
int GetSendHighWaterMark();
/** Sets high water mark for outbound messages. Default 1000 (zmqlib) */
void SetSendHighWaterMark(int limit);
/** Returns high water mark for inbound messages */
int GetReceiveHighWaterMark();
/** Sets high water mark for inbound messages. Default 1000 (zmqlib) */
void SetReceiveHighWaterMark(int limit);
/**
* Returns Port Number
* @returns Port Number
*/
uint32_t GetPortNumber() { return portno; }
/**
* Returns Server Address
* @returns Server Address
*/
std::string GetZmqServerAddress() { return sockfd.serverAddress; }
/**
* Connect client socket to server socket
* @returns 1 for fail, 0 for success
*/
int Connect();
/**
* Unbinds the Socket
*/
void Disconnect() { sockfd.Disconnect(); }
/**
* Send Message Header
* @param index self index for debugging
* @param header zmq header (from json)
* @returns 0 if error, else 1
*/
int SendHeader(int index, zmqHeader header);
/**
* Send Message Body
* @param buf message
* @param length length of message
* @returns 0 if error, else 1
*/
int SendData(char *buf, int length);
/**
* Receive Header
* @param index self index for debugging
* @param zHeader filled out zmqHeader structure (parsed from json header)
* @param version version that has to match, -1 to not care
* @returns 0 if error or end of acquisition, else 1 (call
* CloseHeaderMessage after parsing header)
*/
int ReceiveHeader(const int index, zmqHeader &zHeader, uint32_t version);
/**
* Receive Data
* @param index self index for debugging
* @param buf buffer to copy image data to
* @param size size of image
* @returns length of data received
*/
int ReceiveData(const int index, char *buf, const int size);
/**
* Print error
*/
void PrintError();
private:
/**
* Receive Message
* @param index self index for debugging
* @param message message
* @returns length of message, -1 if error
*/
int ReceiveMessage(const int index, zmq_msg_t &message);
/**
* Parse Header
* @param index self index for debugging
* @param length length of message
* @param buff message
* @param zHeader filled out zmqHeader structure (parsed from json header)
* @param version version that has to match, -1 to not care
* @returns true if successful else false
*/
int ParseHeader(const int index, int length, char *buff, zmqHeader &zHeader,
uint32_t version);
/**
* Class to close socket descriptors automatically
* upon encountering exceptions in the ZmqSocket constructor
*/
class mySocketDescriptors {
public:
/** Constructor */
mySocketDescriptors(bool server);
/** Destructor */
~mySocketDescriptors();
/** Unbinds the Socket */
void Disconnect();
/** Close Socket and destroy Context */
void Close();
/** true if server, else false */
const bool server;
/** Server Address */
std::string serverAddress;
/** Context Descriptor */
void *contextDescriptor;
/** Socket Descriptor */
void *socketDescriptor;
};
/** Port Number */
uint32_t portno;
/** Socket descriptor */
mySocketDescriptors sockfd;
std::unique_ptr<char[]> header_buffer =
sls::make_unique<char[]>(MAX_STR_LENGTH);
};

View File

@ -0,0 +1,65 @@
#define RED "\x1b[31m"
#define GREEN "\x1b[32m"
#define YELLOW "\x1b[33m"
#define BLUE "\x1b[34m"
#define MAGENTA "\x1b[35m"
#define CYAN "\x1b[36m"
#define GRAY "\x1b[37m"
#define DARKGRAY "\x1b[30m"
#define BG_BLACK "\x1b[48;5;232m"
#define BG_RED "\x1b[41m"
#define BG_GREEN "\x1b[42m"
#define BG_YELLOW "\x1b[43m"
#define BG_BLUE "\x1b[44m"
#define BG_MAGENTA "\x1b[45m"
#define BG_CYAN "\x1b[46m"
#define RESET "\x1b[0m"
#define BOLD "\x1b[1m"
// on background black
#define bprintf(code, format, ...) \
printf(code BG_BLACK format RESET, ##__VA_ARGS__)
// normal printout
#define cprintf(code, format, ...) printf(code format RESET, ##__VA_ARGS__)
/*
Code examples
example 1 (a snippet):
#ifdef MARTIN
cprintf(BLUE, "LL Write - Len: %2d - If: %X - Data: ",buffer_len,
ll->ll_fifo_base); for (i=0; i < buffer_len/4; i++) cprintf(BLUE, "%.8X
",*(((unsigned *) buffer)+i)); printf("\n"); #endif
#ifdef MARTIN
cprintf(CYAN, "LL Read - If: %X - Data: ",ll->ll_fifo_base);
#endif
example 2:
int main()
{
int i=1;
printf("Normal %i\n", i);
cprintf(RED, "Red\n");
cprintf(GREEN, "Green\n");
cprintf(YELLOW, "Yellow\n");
cprintf(BLUE, "Blue\n");
cprintf(MAGENTA, "Mangenta %i\n", i);
cprintf(CYAN, "Cyan %i\n", i);
cprintf(BOLD, "White %i\n", i);
cprintf(RED BOLD, "Red %i\n", i);
cprintf(GREEN BOLD, "Green\n");
cprintf(YELLOW BOLD, "Yellow\n");
cprintf(BLUE BOLD, "Blue\n");
cprintf(MAGENTA BOLD, "Mangenta %i\n", i);
cprintf(CYAN BOLD, "Cyan %i\n", i);
}
*/

View File

@ -0,0 +1,19 @@
#pragma once
#include <bitset>
#include <vector>
namespace sls {
template <typename T> std::vector<int> getSetBits(T val) {
constexpr size_t bitsPerByte = 8;
constexpr size_t numBits = sizeof(T) * bitsPerByte;
std::bitset<numBits> bs(val);
std::vector<int> set_bits;
set_bits.reserve(bs.count());
for (size_t i = 0; i < bs.size(); ++i) {
if (bs[i]) {
set_bits.push_back(static_cast<int>(i));
}
}
return set_bits;
}
} // namespace sls

View File

@ -0,0 +1,151 @@
#ifndef CONTAINER_UTILS_H
#define CONTAINER_UTILS_H
#include <algorithm>
#include <memory>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include "sls/TypeTraits.h"
namespace sls {
// C++11 make_unique implementation for exception safety
// already available as std::make_unique in C++14
template <typename T, typename... Args>
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(Args &&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
template <typename T>
typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(std::size_t n) {
typedef typename std::remove_extent<T>::type RT;
return std::unique_ptr<T>(new RT[n]);
}
/** Compare elements in a Container to see if they are all equal */
template <typename Container> bool allEqual(const Container &c) {
if (!c.empty() &&
std::all_of(begin(c), end(c),
[c](const typename Container::value_type &element) {
return element == c.front();
}))
return true;
return false;
}
/**
* Compare elements but with specified tolerance, useful
* for floating point values.
*/
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
allEqualWithTol(const std::vector<T> &container, const T tol) {
if (container.empty())
return false;
const auto &first = container[0];
return std::all_of(container.cbegin(), container.cend(),
[first, tol](const T &element) {
return (std::abs(element - first) < tol);
});
}
template <typename T>
bool allEqualTo(const std::vector<T> &container, const T value) {
if (container.empty())
return false;
return std::all_of(container.cbegin(), container.cend(),
[value](const T &element) { return element == value; });
}
template <typename T>
bool allEqualToWithTol(const std::vector<T> &container, const T value,
const T tol) {
if (container.empty())
return false;
return std::all_of(container.cbegin(), container.cend(),
[value, tol](const T &element) {
return (std::abs(element - value) < tol);
});
}
template <typename T>
bool anyEqualTo(const std::vector<T> &container, const T value) {
return std::any_of(container.cbegin(), container.cend(),
[value](const T &element) { return element == value; });
}
template <typename T>
bool anyEqualToWithTol(const std::vector<T> &container, const T value,
const T tol) {
return std::any_of(container.cbegin(), container.cend(),
[value, tol](const T &element) {
return (std::abs(element - value) < tol);
});
}
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
sum(const std::vector<T> &container) {
return std::accumulate(container.cbegin(), container.cend(), T{0});
}
template <typename T> T minusOneIfDifferent(const std::vector<T> &container) {
if (allEqual(container))
return container.front();
return static_cast<T>(-1);
}
inline int minusOneIfDifferent(const std::vector<bool> &container) {
if (allEqual(container))
return static_cast<int>(container.front());
return -1;
}
template <typename T>
std::vector<T>
minusOneIfDifferent(const std::vector<std::vector<T>> &container) {
if (allEqual(container))
return container.front();
return std::vector<T>{-1};
}
template <typename T, size_t size>
std::array<T, size>
minusOneIfDifferent(const std::vector<std::array<T, size>> &container) {
if (allEqual(container))
return container.front();
std::array<T, size> arr;
arr.fill(static_cast<T>(-1));
return arr;
}
/**
* Return the first value if all values are equal
* otherwise return default_value. If no default
* value is supplied it will be default constructed
*/
template <typename Container>
typename Container::value_type
Squash(const Container &c, typename Container::value_type default_value = {}) {
if (!c.empty() &&
std::all_of(begin(c), end(c),
[c](const typename Container::value_type &element) {
return element == c.front();
}))
return c.front();
return default_value;
}
} // namespace sls
#endif // CONTAINER_UTILS_H

View File

@ -0,0 +1,50 @@
#pragma once
#include "sls/sls_detector_defs.h"
#include <cstdio>
#include <fstream>
#include <string>
/** (used by multi and sls)
* reads a short int raw data file
* @param infile input file stream
* @param data array of data values
* @param nch number of channels
* @param offset start channel value
* @returns OK or FAIL if it could not read the file or data=NULL
*/
int readDataFile(std::ifstream &infile, short int *data, int nch,
int offset = 0);
/** (used by multi and sls)
* reads a short int rawdata file
* @param fname name of the file to be read
* @param data array of data value
* @param nch number of channels
* @returns OK or FAIL if it could not read the file or data=NULL
*/
int readDataFile(std::string fname, short int *data, int nch);
/** (used by multi and sls)
* writes a short int raw data file
* @param outfile output file stream
* @param nch number of channels
* @param data array of data values
* @param offset start channel number
* @returns OK or FAIL if it could not write the file or data=NULL
*/
int writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset = 0);
/** (used by multi and sls)
* writes a short int raw data file
* @param fname of the file to be written
* @param nch number of channels
* @param data array of data values
* @returns OK or FAIL if it could not write the file or data=NULL
*/
int writeDataFile(std::string fname, int nch, short int *data);
// mkdir -p path implemented by recursive calls
void mkdir_p(const std::string &path, std::string dir = "");

View File

@ -0,0 +1,106 @@
#pragma once
/*Utility to log to console*/
#include "sls/ansi.h" //Colors
#include <iostream>
#include <sstream>
#include <sys/time.h>
enum TLogLevel {
logERROR,
logWARNING,
logINFOBLUE,
logINFOGREEN,
logINFORED,
logINFO,
logDEBUG,
logDEBUG1,
logDEBUG2,
logDEBUG3,
logDEBUG4,
logDEBUG5
};
// Compiler should optimize away anything below this value
#ifndef LOG_MAX_REPORTING_LEVEL
#define LOG_MAX_REPORTING_LEVEL logINFO
#endif
#define __AT__ \
std::string(__FILE__) + std::string("::") + std::string(__func__) + \
std::string("(): ")
#define __SHORT_FORM_OF_FILE__ \
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#define __SHORT_AT__ \
std::string(__SHORT_FORM_OF_FILE__) + std::string("::") + \
std::string(__func__) + std::string("(): ")
namespace sls {
class Logger {
std::ostringstream os;
TLogLevel level = LOG_MAX_REPORTING_LEVEL;
public:
Logger() = default;
explicit Logger(TLogLevel level) : level(level){};
~Logger() {
// output in the destructor to allow for << syntax
os << RESET << '\n';
std::clog << os.str() << std::flush; // Single write
}
static TLogLevel &ReportingLevel() { // singelton eeh
static TLogLevel reportingLevel = logINFO;
return reportingLevel;
}
// Danger this buffer need as many elements as TLogLevel
static const char *Color(TLogLevel level) noexcept {
static const char *const colors[] = {
RED BOLD, YELLOW BOLD, BLUE, GREEN, RED, RESET,
RESET, RESET, RESET, RESET, RESET, RESET};
return colors[level];
}
// Danger this buffer need as many elements as TLogLevel
static std::string ToString(TLogLevel level) {
static const char *const buffer[] = {
"ERROR", "WARNING", "INFO", "INFO", "INFO", "INFO",
"DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
return buffer[level];
}
std::ostringstream &Get() {
os << Color(level) << "- " << Timestamp() << " " << ToString(level)
<< ": ";
return os;
}
static std::string Timestamp() {
constexpr size_t buffer_len = 12;
char buffer[buffer_len];
time_t t;
::time(&t);
tm r;
strftime(buffer, buffer_len, "%X", localtime_r(&t, &r));
buffer[buffer_len - 1] = '\0';
struct timeval tv;
gettimeofday(&tv, nullptr);
constexpr size_t result_len = 100;
char result[result_len];
snprintf(result, result_len, "%s.%03ld", buffer,
(long)tv.tv_usec / 1000);
result[result_len - 1] = '\0';
return result;
}
};
#define LOG(level) \
if (level > LOG_MAX_REPORTING_LEVEL) \
; \
else if (level > sls::Logger::ReportingLevel()) \
; \
else \
sls::Logger(level).Get()
} // namespace sls

View File

@ -0,0 +1,69 @@
#pragma once
#include <array>
#include <iostream>
#include <string>
namespace sls {
class IpAddr {
private:
uint32_t addr_{0};
public:
constexpr IpAddr() noexcept = default;
explicit constexpr IpAddr(uint32_t address) noexcept : addr_{address} {}
explicit IpAddr(const std::string &address);
explicit IpAddr(const char *address);
std::string str() const;
std::string hex() const;
std::array<char, 16u> arr() const;
constexpr bool operator==(const IpAddr &other) const noexcept {
return addr_ == other.addr_;
}
constexpr bool operator!=(const IpAddr &other) const noexcept {
return addr_ != other.addr_;
}
constexpr bool operator==(const uint32_t other) const noexcept {
return addr_ == other;
}
constexpr bool operator!=(const uint32_t other) const noexcept {
return addr_ != other;
}
constexpr uint32_t uint32() const noexcept { return addr_; }
};
class MacAddr {
private:
uint64_t addr_{0};
std::string to_hex(const char delimiter = 0) const;
public:
constexpr MacAddr() noexcept = default;
explicit constexpr MacAddr(uint64_t mac) noexcept : addr_{mac} {}
explicit MacAddr(std::string mac);
explicit MacAddr(const char *address);
std::string str() const;
std::string hex() const;
constexpr bool operator==(const MacAddr &other) const noexcept {
return addr_ == other.addr_;
}
constexpr bool operator!=(const MacAddr &other) const noexcept {
return addr_ != other.addr_;
}
constexpr bool operator==(const uint64_t other) const noexcept {
return addr_ == other;
}
constexpr bool operator!=(const uint64_t other) const noexcept {
return addr_ != other;
}
constexpr uint64_t uint64() const noexcept { return addr_; }
};
IpAddr HostnameToIp(const char *hostname);
std::string IpToInterfaceName(const std::string &ip);
MacAddr InterfaceNameToMac(const std::string &inf);
IpAddr InterfaceNameToIp(const std::string &ifn);
std::ostream &operator<<(std::ostream &out, const IpAddr &addr);
std::ostream &operator<<(std::ostream &out, const MacAddr &addr);
} // namespace sls

View File

@ -0,0 +1,645 @@
#pragma once
/************************************************
* @file sls_detector_defs.h
* @short contains all the constants, enum definitions and enum-string
*conversions
***********************************************/
/**
*@short contains all the constants, enum definitions and enum-string
*conversions
*/
#ifdef __CINT__
#define MYROOT
#define __cplusplus
#endif
#ifdef __cplusplus
// C++ includes
#include "sls/sls_detector_exceptions.h"
#include <algorithm>
#include <bitset>
#include <chrono>
#include <cstdint>
#include <string>
#else
// C includes
#include <stdint.h>
#endif
#define BIT32_MASK 0xFFFFFFFF
#define MAX_RX_DBIT 64
/** default ports */
#define DEFAULT_PORTNO 1952
#define DEFAULT_UDP_PORTNO 50001
#define DEFAULT_ZMQ_CL_PORTNO 30001
#define DEFAULT_ZMQ_RX_PORTNO 30001
#define SLS_DETECTOR_HEADER_VERSION 0x2
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4
// ctb/ moench 1g udp (read from fifo)
#define UDP_PACKET_DATA_BYTES (1344)
/** maximum rois */
#define MAX_ROIS 100
/** maximum trim en */
#define MAX_TRIMEN 100
/** maximum unit size of program sent to detector */
#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024)
#define GET_FLAG -1
#define DEFAULT_DET_MAC "00:aa:bb:cc:dd:ee"
#define DEFAULT_DET_IP "129.129.202.45"
#define DEFAULT_DET_MAC2 "00:aa:bb:cc:dd:ff"
#define DEFAULT_DET_IP2 "129.129.202.46"
/** default maximum string length */
#define MAX_STR_LENGTH 1000
#define SHORT_STR_LENGTH 20
#define MAX_PATTERN_LENGTH 0x2000
#define DEFAULT_STREAMING_TIMER_IN_MS 500
#define NUM_RX_THREAD_IDS 8
#ifdef __cplusplus
class slsDetectorDefs {
public:
#endif
/** Type of the detector */
enum detectorType {
GENERIC,
EIGER,
GOTTHARD,
JUNGFRAU,
CHIPTESTBOARD,
MOENCH,
MYTHEN3,
GOTTHARD2,
};
/** return values */
enum { OK, FAIL };
/** staus mask */
enum runStatus {
IDLE,
ERROR,
WAITING,
RUN_FINISHED,
TRANSMITTING,
RUNNING,
STOPPED
};
/**
@short structure for a Detector Packet or Image Header
@li frameNumber is the frame number
@li expLength is the subframe number (32 bit eiger) or real time
exposure time in 100ns (others)
@li packetNumber is the packet number
@li bunchId is the bunch id from beamline
@li timestamp is the time stamp with 10 MHz clock
@li modId is the unique module id (unique even for left, right, top,
bottom)
@li row is the row index in the complete detector system
@li column is the column index in the complete detector system
@li reserved is reserved
@li debug is for debugging purposes
@li roundRNumber is the round robin set number
@li detType is the detector type see :: detectorType
@li version is the version number of this structure format
*/
typedef struct {
uint64_t frameNumber;
uint32_t expLength;
uint32_t packetNumber;
uint64_t bunchId;
uint64_t timestamp;
uint16_t modId;
uint16_t row;
uint16_t column;
uint16_t reserved;
uint32_t debug;
uint16_t roundRNumber;
uint8_t detType;
uint8_t version;
} sls_detector_header;
#ifdef __cplusplus
// For sending and receiving data
static_assert(sizeof(detectorType) == sizeof(int),
"enum and int differ in size");
#define MAX_NUM_PACKETS 512
using sls_bitset = std::bitset<MAX_NUM_PACKETS>;
using bitset_storage = uint8_t[MAX_NUM_PACKETS / 8];
struct sls_receiver_header {
sls_detector_header detHeader; /**< is the detector header */
sls_bitset packetsMask; /**< is the packets caught bit mask */
};
#endif
enum frameDiscardPolicy {
NO_DISCARD,
DISCARD_EMPTY_FRAMES,
DISCARD_PARTIAL_FRAMES,
NUM_DISCARD_POLICIES
};
enum fileFormat { BINARY, HDF5, NUM_FILE_FORMATS };
/**
@short structure for a region of interest
xmin,xmax,ymin,ymax define the limits of the region
*/
#ifdef __cplusplus
struct ROI {
int xmin{-1};
int xmax{-1};
ROI() = default;
ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){};
} __attribute__((packed));
#else
typedef struct {
int xmin;
int xmax;
} ROI;
#endif
/**
type of action performed (for text client)
*/
enum { GET_ACTION, PUT_ACTION, READOUT_ACTION, HELP_ACTION };
/**
dimension indexes
*/
enum dimension { X, Y };
#ifdef __cplusplus
struct xy {
int x{0};
int y{0};
xy() = default;
xy(int x, int y) : x(x), y(y){};
} __attribute__((packed));
#endif
/**
use of the external signals
*/
enum externalSignalFlag {
TRIGGER_IN_RISING_EDGE,
TRIGGER_IN_FALLING_EDGE,
INVERSION_ON,
INVERSION_OFF
};
/**
communication mode using external signals
*/
enum timingMode {
AUTO_TIMING,
TRIGGER_EXPOSURE,
GATED,
BURST_TRIGGER,
TRIGGER_GATED,
NUM_TIMING_MODES
};
/**
detector dacs indexes
*/
enum dacIndex {
DAC_0,
DAC_1,
DAC_2,
DAC_3,
DAC_4,
DAC_5,
DAC_6,
DAC_7,
DAC_8,
DAC_9,
DAC_10,
DAC_11,
DAC_12,
DAC_13,
DAC_14,
DAC_15,
DAC_16,
DAC_17,
VSVP,
VTRIM,
VRPREAMP,
VRSHAPER,
VSVN,
VTGSTV,
VCMP_LL,
VCMP_LR,
VCAL,
VCMP_RL,
RXB_RB,
RXB_LB,
VCMP_RR,
VCP,
VCN,
VISHAPER,
VTHRESHOLD,
IO_DELAY,
VREF_DS,
VCASCN_PB,
VCASCP_PB,
VOUT_CM,
VCASC_OUT,
VIN_CM,
VREF_COMP,
IB_TESTC,
VB_COMP,
VDD_PROT,
VIN_COM,
VREF_PRECH,
VB_PIXBUF,
VB_DS,
VREF_H_ADC,
VB_COMP_FE,
VB_COMP_ADC,
VCOM_CDS,
VREF_RSTORE,
VB_OPA_1ST,
VREF_COMP_FE,
VCOM_ADC1,
VREF_L_ADC,
VREF_CDS,
VB_CS,
VB_OPA_FD,
VCOM_ADC2,
VCASSH,
VTH2,
VRSHAPER_N,
VIPRE_OUT,
VTH3,
VTH1,
VICIN,
VCAS,
VCAL_N,
VIPRE,
VCAL_P,
VDCSH,
VBP_COLBUF,
VB_SDA,
VCASC_SFP,
VIPRE_CDS,
IBIAS_SFP,
ADC_VPP,
HIGH_VOLTAGE,
TEMPERATURE_ADC,
TEMPERATURE_FPGA,
TEMPERATURE_FPGAEXT,
TEMPERATURE_10GE,
TEMPERATURE_DCDC,
TEMPERATURE_SODL,
TEMPERATURE_SODR,
TEMPERATURE_FPGA2,
TEMPERATURE_FPGA3,
TRIMBIT_SCAN,
V_POWER_A = 100,
V_POWER_B = 101,
V_POWER_C = 102,
V_POWER_D = 103,
V_POWER_IO = 104,
V_POWER_CHIP = 105,
I_POWER_A = 106,
I_POWER_B = 107,
I_POWER_C = 108,
I_POWER_D = 109,
I_POWER_IO = 110,
V_LIMIT = 111,
SLOW_ADC0 = 1000,
SLOW_ADC1,
SLOW_ADC2,
SLOW_ADC3,
SLOW_ADC4,
SLOW_ADC5,
SLOW_ADC6,
SLOW_ADC7,
SLOW_ADC_TEMP
};
/**
detector settings indexes
*/
enum detectorSettings {
STANDARD,
FAST,
HIGHGAIN,
DYNAMICGAIN,
LOWGAIN,
MEDIUMGAIN,
VERYHIGHGAIN,
DYNAMICHG0,
FIXGAIN1,
FIXGAIN2,
FORCESWITCHG1,
FORCESWITCHG2,
VERYLOWGAIN,
G1_HIGHGAIN,
G1_LOWGAIN,
G2_HIGHCAP_HIGHGAIN,
G2_HIGHCAP_LOWGAIN,
G2_LOWCAP_HIGHGAIN,
G2_LOWCAP_LOWGAIN,
G4_HIGHGAIN,
G4_LOWGAIN,
UNDEFINED = 200,
UNINITIALIZED
};
#define TRIMBITMASK 0x3f
enum clockIndex { ADC_CLOCK, DBIT_CLOCK, RUN_CLOCK, SYNC_CLOCK };
/**
* read out mode (ctb, moench)
*/
enum readoutMode { ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL };
/** chip speed */
enum speedLevel { FULL_SPEED, HALF_SPEED, QUARTER_SPEED };
/** hierarchy in multi-detector structure, if any */
enum masterFlags { NO_MASTER, IS_MASTER, IS_SLAVE };
/**
* burst mode for gotthard2
*/
enum burstMode {
BURST_INTERNAL,
BURST_EXTERNAL,
CONTINUOUS_INTERNAL,
CONTINUOUS_EXTERNAL,
NUM_BURST_MODES
};
/**
* timing source for gotthard2
*/
enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL };
#ifdef __cplusplus
/** scan structure */
struct scanParameters {
int enable;
dacIndex dacInd;
int startOffset;
int stopOffset;
int stepSize;
int64_t dacSettleTime_ns;
/** disable scan */
scanParameters()
: enable(0), dacInd(DAC_0), startOffset(0), stopOffset(0),
stepSize(0), dacSettleTime_ns{0} {}
/** enable scan */
scanParameters(
dacIndex dac, int start, int stop, int step,
std::chrono::nanoseconds t = std::chrono::milliseconds{1})
: enable(1), dacInd(dac), startOffset(start), stopOffset(stop),
stepSize(step) {
dacSettleTime_ns = t.count();
}
bool operator==(const scanParameters &other) const {
return ((enable == other.enable) && (dacInd == other.dacInd) &&
(startOffset == other.startOffset) &&
(stopOffset == other.stopOffset) &&
(stepSize == other.stepSize) &&
(dacSettleTime_ns == other.dacSettleTime_ns));
}
} __attribute__((packed));
/**
* structure to udpate receiver
*/
struct rxParameters {
detectorType detType{GENERIC};
xy numberOfDetector;
int moduleId{0};
char hostname[MAX_STR_LENGTH];
int udpInterfaces{1};
int udp_dstport{0};
uint32_t udp_dstip{0U};
uint64_t udp_dstmac{0LU};
int udp_dstport2{0};
uint32_t udp_dstip2{0U};
uint64_t udp_dstmac2{0LU};
int64_t frames{0};
int64_t triggers{0};
int64_t bursts{0};
int additionalStorageCells{0};
int analogSamples{0};
int digitalSamples{0};
int64_t expTimeNs{0};
int64_t periodNs{0};
int64_t subExpTimeNs{0};
int64_t subDeadTimeNs{0};
int activate{0};
int quad{0};
int numLinesReadout{0};
int thresholdEnergyeV{0};
int dynamicRange{16};
timingMode timMode{AUTO_TIMING};
int tenGiga{0};
readoutMode roMode{ANALOG_ONLY};
uint32_t adcMask{0};
uint32_t adc10gMask{0};
ROI roi;
uint32_t countermask{0};
burstMode burstType{BURST_INTERNAL};
int64_t expTime1Ns{0};
int64_t expTime2Ns{0};
int64_t expTime3Ns{0};
int64_t gateDelay1Ns{0};
int64_t gateDelay2Ns{0};
int64_t gateDelay3Ns{0};
int gates{0};
scanParameters scanParams{};
} __attribute__((packed));
/** pattern structure */
struct patternParameters {
uint64_t word[MAX_PATTERN_LENGTH]{};
uint64_t patioctrl{0};
uint32_t patlimits[2]{};
uint32_t patloop[6]{};
uint32_t patnloop[3]{};
uint32_t patwait[3]{};
uint64_t patwaittime[3]{};
} __attribute__((packed));
#endif
#ifdef __cplusplus
protected:
#endif
// #ifndef MYROOT
// #include "sls/sls_detector_funcs.h"
// #endif
#ifdef __cplusplus
};
#endif
;
#ifdef __cplusplus
struct detParameters {
int nChanX{0};
int nChanY{0};
int nChipX{0};
int nChipY{0};
int nDacs{0};
detParameters() = default;
explicit detParameters(slsDetectorDefs::detectorType type) {
switch (type) {
case slsDetectorDefs::detectorType::GOTTHARD:
nChanX = 128;
nChanY = 1;
nChipX = 10;
nChipY = 1;
nDacs = 8;
break;
case slsDetectorDefs::detectorType::JUNGFRAU:
nChanX = 256;
nChanY = 256;
nChipX = 4;
nChipY = 2;
nDacs = 8;
break;
case slsDetectorDefs::detectorType::CHIPTESTBOARD:
nChanX = 36;
nChanY = 1;
nChipX = 1;
nChipY = 1;
nDacs = 24;
break;
case slsDetectorDefs::detectorType::MOENCH:
nChanX = 32;
nChanY = 1;
nChipX = 1;
nChipY = 1;
nDacs = 8;
break;
case slsDetectorDefs::detectorType::EIGER:
nChanX = 256;
nChanY = 256;
nChipX = 4;
nChipY = 1;
nDacs = 16;
break;
case slsDetectorDefs::detectorType::MYTHEN3:
nChanX = 128 * 3;
nChanY = 1;
nChipX = 10;
nChipY = 1;
nDacs = 16;
break;
case slsDetectorDefs::detectorType::GOTTHARD2:
nChanX = 128;
nChanY = 1;
nChipX = 10;
nChipY = 1;
nDacs = 14;
break;
default:
throw sls::RuntimeError("Unknown detector type! " +
std::to_string(type));
}
}
};
#endif
/**
@short structure for a detector module
*/
#ifdef __cplusplus
struct sls_detector_module {
#else
typedef struct {
#endif
int serialnumber; /**< is the module serial number */
int nchan; /**< is the number of channels on the module*/
int nchip; /**< is the number of chips on the module */
int ndac; /**< is the number of dacs on the module */
int reg; /**< is the module register settings (gain level) */
int iodelay; /**< iodelay */
int tau; /**< tau */
int eV; /**< threshold energy */
int *dacs; /**< is the pointer to the array of the dac values (in V) */
int *chanregs; /**< is the pointer to the array of the channel registers */
#ifdef __cplusplus
sls_detector_module()
: serialnumber(0), nchan(0), nchip(0), ndac(0), reg(-1), iodelay(0),
tau(0), eV(-1), dacs(nullptr), chanregs(nullptr) {}
explicit sls_detector_module(slsDetectorDefs::detectorType type)
: sls_detector_module() {
detParameters parameters{type};
int nch = parameters.nChanX * parameters.nChanY;
int nc = parameters.nChipX * parameters.nChipY;
ndac = parameters.nDacs;
nchip = nc;
nchan = nch * nc;
dacs = new int[ndac];
chanregs = new int[nchan];
}
sls_detector_module(const sls_detector_module &other)
: dacs(nullptr), chanregs(nullptr) {
*this = other;
}
sls_detector_module &operator=(const sls_detector_module &other) {
delete[] dacs;
delete[] chanregs;
serialnumber = other.serialnumber;
nchan = other.nchan;
nchip = other.nchip;
ndac = other.ndac;
reg = other.reg;
iodelay = other.iodelay;
tau = other.tau;
eV = other.eV;
dacs = new int[ndac];
std::copy(other.dacs, other.dacs + ndac, dacs);
chanregs = new int[nchan];
std::copy(other.chanregs, other.chanregs + nchan, chanregs);
return *this;
}
~sls_detector_module() {
delete[] dacs;
delete[] chanregs;
}
};
#else
} sls_detector_module;
#endif
#ifdef __cplusplus
// TODO! discuss this
#include <vector> //hmm... but currently no way around
namespace sls {
using Positions = const std::vector<int> &;
using defs = slsDetectorDefs;
} // namespace sls
#endif

View File

@ -0,0 +1,48 @@
#pragma once
#include <stdexcept>
namespace sls {
struct RuntimeError : public std::runtime_error {
public:
RuntimeError();
RuntimeError(const std::string &msg);
RuntimeError(const char *msg);
};
struct SharedMemoryError : public RuntimeError {
public:
SharedMemoryError(const std::string &msg);
};
struct SocketError : public RuntimeError {
public:
SocketError(const std::string &msg);
};
struct ZmqSocketError : public RuntimeError {
public:
ZmqSocketError(const std::string &msg);
};
struct NotImplementedError : public RuntimeError {
public:
NotImplementedError(const std::string &msg);
};
struct DetectorError : public RuntimeError {
public:
DetectorError(const std::string &msg);
};
struct ReceiverError : public RuntimeError {
public:
ReceiverError(const std::string &msg);
};
struct GuiError : public RuntimeError {
public:
GuiError(const std::string &msg);
};
} // namespace sls

View File

@ -0,0 +1,647 @@
#pragma once
/************************************************
* @file sls_detector_funcs.h
* @short functions indices to call on server (detector/receiver)
***********************************************/
/**
*@short functions indices to call on server (detector/receiver)
*/
enum detFuncs {
F_EXEC_COMMAND = 0,
F_GET_DETECTOR_TYPE,
F_GET_EXTERNAL_SIGNAL_FLAG,
F_SET_EXTERNAL_SIGNAL_FLAG,
F_SET_TIMING_MODE,
F_GET_FIRMWARE_VERSION,
F_GET_SERVER_VERSION,
F_GET_SERIAL_NUMBER,
F_SET_FIRMWARE_TEST,
F_SET_BUS_TEST,
F_SET_IMAGE_TEST_MODE,
F_GET_IMAGE_TEST_MODE,
F_SET_DAC,
F_GET_ADC,
F_WRITE_REGISTER,
F_READ_REGISTER,
F_SET_MODULE,
F_SET_SETTINGS,
F_GET_THRESHOLD_ENERGY,
F_START_ACQUISITION,
F_STOP_ACQUISITION,
F_GET_RUN_STATUS,
F_START_AND_READ_ALL,
F_GET_NUM_FRAMES,
F_SET_NUM_FRAMES,
F_GET_NUM_TRIGGERS,
F_SET_NUM_TRIGGERS,
F_GET_NUM_ADDITIONAL_STORAGE_CELLS,
F_SET_NUM_ADDITIONAL_STORAGE_CELLS,
F_GET_NUM_ANALOG_SAMPLES,
F_SET_NUM_ANALOG_SAMPLES,
F_GET_NUM_DIGITAL_SAMPLES,
F_SET_NUM_DIGITAL_SAMPLES,
F_GET_EXPTIME,
F_SET_EXPTIME,
F_GET_PERIOD,
F_SET_PERIOD,
F_GET_DELAY_AFTER_TRIGGER,
F_SET_DELAY_AFTER_TRIGGER,
F_GET_SUB_EXPTIME,
F_SET_SUB_EXPTIME,
F_GET_SUB_DEADTIME,
F_SET_SUB_DEADTIME,
F_GET_STORAGE_CELL_DELAY,
F_SET_STORAGE_CELL_DELAY,
F_GET_FRAMES_LEFT,
F_GET_TRIGGERS_LEFT,
F_GET_EXPTIME_LEFT,
F_GET_PERIOD_LEFT,
F_GET_DELAY_AFTER_TRIGGER_LEFT,
F_GET_MEASURED_PERIOD,
F_GET_MEASURED_SUBPERIOD,
F_GET_FRAMES_FROM_START,
F_GET_ACTUAL_TIME,
F_GET_MEASUREMENT_TIME,
F_SET_DYNAMIC_RANGE,
F_SET_ROI,
F_GET_ROI,
F_LOCK_SERVER,
F_GET_LAST_CLIENT_IP,
F_SET_PORT,
F_ENABLE_TEN_GIGA,
F_SET_ALL_TRIMBITS,
F_SET_PATTERN_IO_CONTROL,
F_SET_PATTERN_WORD,
F_SET_PATTERN_LOOP_ADDRESSES,
F_SET_PATTERN_LOOP_CYCLES,
F_SET_PATTERN_WAIT_ADDR,
F_SET_PATTERN_WAIT_TIME,
F_SET_PATTERN_MASK,
F_GET_PATTERN_MASK,
F_SET_PATTERN_BIT_MASK,
F_GET_PATTERN_BIT_MASK,
F_WRITE_ADC_REG,
F_SET_COUNTER_BIT,
F_PULSE_PIXEL,
F_PULSE_PIXEL_AND_MOVE,
F_PULSE_CHIP,
F_SET_RATE_CORRECT,
F_GET_RATE_CORRECT,
F_SET_TEN_GIGA_FLOW_CONTROL,
F_GET_TEN_GIGA_FLOW_CONTROL,
F_SET_TRANSMISSION_DELAY_FRAME,
F_GET_TRANSMISSION_DELAY_FRAME,
F_SET_TRANSMISSION_DELAY_LEFT,
F_GET_TRANSMISSION_DELAY_LEFT,
F_SET_TRANSMISSION_DELAY_RIGHT,
F_GET_TRANSMISSION_DELAY_RIGHT,
F_PROGRAM_FPGA,
F_RESET_FPGA,
F_POWER_CHIP,
F_ACTIVATE,
F_THRESHOLD_TEMP,
F_TEMP_CONTROL,
F_TEMP_EVENT,
F_AUTO_COMP_DISABLE,
F_STORAGE_CELL_START,
F_CHECK_VERSION,
F_SOFTWARE_TRIGGER,
F_LED,
F_DIGITAL_IO_DELAY,
F_COPY_DET_SERVER,
F_REBOOT_CONTROLLER,
F_SET_ADC_ENABLE_MASK,
F_GET_ADC_ENABLE_MASK,
F_SET_ADC_INVERT,
F_GET_ADC_INVERT,
F_EXTERNAL_SAMPLING_SOURCE,
F_EXTERNAL_SAMPLING,
F_SET_STARTING_FRAME_NUMBER,
F_GET_STARTING_FRAME_NUMBER,
F_SET_QUAD,
F_GET_QUAD,
F_SET_INTERRUPT_SUBFRAME,
F_GET_INTERRUPT_SUBFRAME,
F_SET_READ_N_LINES,
F_GET_READ_N_LINES,
F_SET_POSITION,
F_SET_SOURCE_UDP_MAC,
F_GET_SOURCE_UDP_MAC,
F_SET_SOURCE_UDP_MAC2,
F_GET_SOURCE_UDP_MAC2,
F_SET_SOURCE_UDP_IP,
F_GET_SOURCE_UDP_IP,
F_SET_SOURCE_UDP_IP2,
F_GET_SOURCE_UDP_IP2,
F_SET_DEST_UDP_MAC,
F_GET_DEST_UDP_MAC,
F_SET_DEST_UDP_MAC2,
F_GET_DEST_UDP_MAC2,
F_SET_DEST_UDP_IP,
F_GET_DEST_UDP_IP,
F_SET_DEST_UDP_IP2,
F_GET_DEST_UDP_IP2,
F_SET_DEST_UDP_PORT,
F_GET_DEST_UDP_PORT,
F_SET_DEST_UDP_PORT2,
F_GET_DEST_UDP_PORT2,
F_SET_NUM_INTERFACES,
F_GET_NUM_INTERFACES,
F_SET_INTERFACE_SEL,
F_GET_INTERFACE_SEL,
F_SET_PARALLEL_MODE,
F_GET_PARALLEL_MODE,
F_SET_OVERFLOW_MODE,
F_GET_OVERFLOW_MODE,
F_SET_READOUT_MODE,
F_GET_READOUT_MODE,
F_SET_CLOCK_FREQUENCY,
F_GET_CLOCK_FREQUENCY,
F_SET_CLOCK_PHASE,
F_GET_CLOCK_PHASE,
F_GET_MAX_CLOCK_PHASE_SHIFT,
F_SET_CLOCK_DIVIDER,
F_GET_CLOCK_DIVIDER,
F_SET_PIPELINE,
F_GET_PIPELINE,
F_SET_ON_CHIP_DAC,
F_GET_ON_CHIP_DAC,
F_SET_INJECT_CHANNEL,
F_GET_INJECT_CHANNEL,
F_SET_VETO_PHOTON,
F_GET_VETO_PHOTON,
F_SET_VETO_REFERENCE,
F_GET_BURST_MODE,
F_SET_BURST_MODE,
F_SET_ADC_ENABLE_MASK_10G,
F_GET_ADC_ENABLE_MASK_10G,
F_SET_COUNTER_MASK,
F_GET_COUNTER_MASK,
F_GET_NUM_BURSTS,
F_SET_NUM_BURSTS,
F_GET_BURST_PERIOD,
F_SET_BURST_PERIOD,
F_GET_CURRENT_SOURCE,
F_SET_CURRENT_SOURCE,
F_GET_TIMING_SOURCE,
F_SET_TIMING_SOURCE,
F_GET_NUM_CHANNELS,
F_UPDATE_RATE_CORRECTION,
F_GET_RECEIVER_PARAMETERS,
F_START_PATTERN,
F_SET_NUM_GATES,
F_GET_NUM_GATES,
F_SET_GATE_DELAY,
F_GET_GATE_DELAY,
F_GET_EXPTIME_ALL_GATES,
F_GET_GATE_DELAY_ALL_GATES,
F_GET_VETO,
F_SET_VETO,
F_SET_PATTERN,
F_GET_SCAN,
F_SET_SCAN,
F_GET_SCAN_ERROR_MESSAGE,
F_GET_CDS_GAIN,
F_SET_CDS_GAIN,
F_GET_FILTER,
F_SET_FILTER,
F_GET_ADC_CONFIGURATION,
F_SET_ADC_CONFIGURATION,
F_GET_BAD_CHANNELS,
F_SET_BAD_CHANNELS,
F_RECONFIGURE_UDP,
F_VALIDATE_UDP_CONFIG,
F_GET_BURSTS_LEFT,
F_START_READOUT,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
(detector server should not compile anyway) */
F_EXEC_RECEIVER_COMMAND,
F_LOCK_RECEIVER,
F_GET_LAST_RECEIVER_CLIENT_IP,
F_SET_RECEIVER_PORT,
F_GET_RECEIVER_VERSION,
F_RECEIVER_SET_ROI,
F_RECEIVER_SET_NUM_FRAMES,
F_SET_RECEIVER_NUM_TRIGGERS,
F_SET_RECEIVER_NUM_BURSTS,
F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS,
F_SET_RECEIVER_TIMING_MODE,
F_SET_RECEIVER_BURST_MODE,
F_RECEIVER_SET_NUM_ANALOG_SAMPLES,
F_RECEIVER_SET_NUM_DIGITAL_SAMPLES,
F_RECEIVER_SET_EXPTIME,
F_RECEIVER_SET_PERIOD,
F_RECEIVER_SET_SUB_EXPTIME,
F_RECEIVER_SET_SUB_DEADTIME,
F_SET_RECEIVER_DYNAMIC_RANGE,
F_SET_RECEIVER_STREAMING_FREQUENCY,
F_GET_RECEIVER_STREAMING_FREQUENCY,
F_GET_RECEIVER_STATUS,
F_START_RECEIVER,
F_STOP_RECEIVER,
F_SET_RECEIVER_FILE_PATH,
F_GET_RECEIVER_FILE_PATH,
F_SET_RECEIVER_FILE_NAME,
F_GET_RECEIVER_FILE_NAME,
F_SET_RECEIVER_FILE_INDEX,
F_GET_RECEIVER_FILE_INDEX,
F_GET_RECEIVER_FRAME_INDEX,
F_GET_RECEIVER_FRAMES_CAUGHT,
F_GET_NUM_MISSING_PACKETS,
F_SET_RECEIVER_FILE_WRITE,
F_GET_RECEIVER_FILE_WRITE,
F_SET_RECEIVER_MASTER_FILE_WRITE,
F_GET_RECEIVER_MASTER_FILE_WRITE,
F_SET_RECEIVER_OVERWRITE,
F_GET_RECEIVER_OVERWRITE,
F_ENABLE_RECEIVER_TEN_GIGA,
F_SET_RECEIVER_FIFO_DEPTH,
F_RECEIVER_ACTIVATE,
F_SET_RECEIVER_STREAMING,
F_GET_RECEIVER_STREAMING,
F_RECEIVER_STREAMING_TIMER,
F_SET_FLIPPED_DATA_RECEIVER,
F_SET_RECEIVER_FILE_FORMAT,
F_GET_RECEIVER_FILE_FORMAT,
F_SET_RECEIVER_STREAMING_PORT,
F_GET_RECEIVER_STREAMING_PORT,
F_SET_RECEIVER_STREAMING_SRC_IP,
F_GET_RECEIVER_STREAMING_SRC_IP,
F_SET_RECEIVER_SILENT_MODE,
F_GET_RECEIVER_SILENT_MODE,
F_RESTREAM_STOP_FROM_RECEIVER,
F_SET_ADDITIONAL_JSON_HEADER,
F_GET_ADDITIONAL_JSON_HEADER,
F_RECEIVER_UDP_SOCK_BUF_SIZE,
F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE,
F_SET_RECEIVER_FRAMES_PER_FILE,
F_GET_RECEIVER_FRAMES_PER_FILE,
F_RECEIVER_CHECK_VERSION,
F_SET_RECEIVER_DISCARD_POLICY,
F_GET_RECEIVER_DISCARD_POLICY,
F_SET_RECEIVER_PADDING,
F_GET_RECEIVER_PADDING,
F_SET_RECEIVER_DEACTIVATED_PADDING,
F_GET_RECEIVER_DEACTIVATED_PADDING,
F_RECEIVER_SET_READOUT_MODE,
F_RECEIVER_SET_ADC_MASK,
F_SET_RECEIVER_DBIT_LIST,
F_GET_RECEIVER_DBIT_LIST,
F_SET_RECEIVER_DBIT_OFFSET,
F_GET_RECEIVER_DBIT_OFFSET,
F_SET_RECEIVER_QUAD,
F_SET_RECEIVER_READ_N_LINES,
F_SET_RECEIVER_UDP_IP,
F_SET_RECEIVER_UDP_IP2,
F_SET_RECEIVER_UDP_PORT,
F_SET_RECEIVER_UDP_PORT2,
F_SET_RECEIVER_NUM_INTERFACES,
F_RECEIVER_SET_ADC_MASK_10G,
F_RECEIVER_SET_COUNTER_MASK,
F_INCREMENT_FILE_INDEX,
F_SET_ADDITIONAL_JSON_PARAMETER,
F_GET_ADDITIONAL_JSON_PARAMETER,
F_GET_RECEIVER_PROGRESS,
F_SETUP_RECEIVER,
F_SET_RECEIVER_NUM_GATES,
F_SET_RECEIVER_GATE_DELAY,
F_GET_RECEIVER_THREAD_IDS,
F_GET_RECEIVER_STREAMING_START_FNUM,
F_SET_RECEIVER_STREAMING_START_FNUM,
F_SET_RECEIVER_RATE_CORRECT,
F_SET_RECEIVER_SCAN,
F_RECEIVER_SET_THRESHOLD,
F_GET_RECEIVER_STREAMING_HWM,
F_SET_RECEIVER_STREAMING_HWM,
NUM_REC_FUNCTIONS
};
// clang-format off
#ifdef __cplusplus
inline const char* getFunctionNameFromEnum(enum detFuncs func) {
#else
const char* getFunctionNameFromEnum(enum detFuncs func) {
#endif
switch (func) {
case F_EXEC_COMMAND: return "F_EXEC_COMMAND";
case F_GET_DETECTOR_TYPE: return "F_GET_DETECTOR_TYPE";
case F_GET_EXTERNAL_SIGNAL_FLAG: return "F_GET_EXTERNAL_SIGNAL_FLAG";
case F_SET_EXTERNAL_SIGNAL_FLAG: return "F_SET_EXTERNAL_SIGNAL_FLAG";
case F_SET_TIMING_MODE: return "F_SET_TIMING_MODE";
case F_GET_FIRMWARE_VERSION: return "F_GET_FIRMWARE_VERSION";
case F_GET_SERVER_VERSION: return "F_GET_SERVER_VERSION";
case F_GET_SERIAL_NUMBER: return "F_GET_SERIAL_NUMBER";
case F_SET_FIRMWARE_TEST: return "F_SET_FIRMWARE_TEST";
case F_SET_BUS_TEST: return "F_SET_BUS_TEST";
case F_SET_IMAGE_TEST_MODE: return "F_SET_IMAGE_TEST_MODE";
case F_GET_IMAGE_TEST_MODE: return "F_GET_IMAGE_TEST_MODE";
case F_SET_DAC: return "F_SET_DAC";
case F_GET_ADC: return "F_GET_ADC";
case F_WRITE_REGISTER: return "F_WRITE_REGISTER";
case F_READ_REGISTER: return "F_READ_REGISTER";
case F_SET_MODULE: return "F_SET_MODULE";
case F_SET_SETTINGS: return "F_SET_SETTINGS";
case F_GET_THRESHOLD_ENERGY: return "F_GET_THRESHOLD_ENERGY";
case F_START_ACQUISITION: return "F_START_ACQUISITION";
case F_STOP_ACQUISITION: return "F_STOP_ACQUISITION";
case F_GET_RUN_STATUS: return "F_GET_RUN_STATUS";
case F_START_AND_READ_ALL: return "F_START_AND_READ_ALL";
case F_GET_NUM_FRAMES: return "F_GET_NUM_FRAMES";
case F_SET_NUM_FRAMES: return "F_SET_NUM_FRAMES";
case F_GET_NUM_TRIGGERS: return "F_GET_NUM_TRIGGERS";
case F_SET_NUM_TRIGGERS: return "F_SET_NUM_TRIGGERS";
case F_GET_NUM_ADDITIONAL_STORAGE_CELLS:return "F_GET_NUM_ADDITIONAL_STORAGE_CELLS";
case F_SET_NUM_ADDITIONAL_STORAGE_CELLS:return "F_SET_NUM_ADDITIONAL_STORAGE_CELLS";
case F_GET_NUM_ANALOG_SAMPLES: return "F_GET_NUM_ANALOG_SAMPLES";
case F_SET_NUM_ANALOG_SAMPLES: return "F_SET_NUM_ANALOG_SAMPLES";
case F_GET_NUM_DIGITAL_SAMPLES: return "F_GET_NUM_DIGITAL_SAMPLES";
case F_SET_NUM_DIGITAL_SAMPLES: return "F_SET_NUM_DIGITAL_SAMPLES";
case F_GET_EXPTIME: return "F_GET_EXPTIME";
case F_SET_EXPTIME: return "F_SET_EXPTIME";
case F_GET_PERIOD: return "F_GET_PERIOD";
case F_SET_PERIOD: return "F_SET_PERIOD";
case F_GET_DELAY_AFTER_TRIGGER: return "F_GET_DELAY_AFTER_TRIGGER";
case F_SET_DELAY_AFTER_TRIGGER: return "F_SET_DELAY_AFTER_TRIGGER";
case F_GET_SUB_EXPTIME: return "F_GET_SUB_EXPTIME";
case F_SET_SUB_EXPTIME: return "F_SET_SUB_EXPTIME";
case F_GET_SUB_DEADTIME: return "F_GET_SUB_DEADTIME";
case F_SET_SUB_DEADTIME: return "F_SET_SUB_DEADTIME";
case F_GET_STORAGE_CELL_DELAY: return "F_GET_STORAGE_CELL_DELAY";
case F_SET_STORAGE_CELL_DELAY: return "F_SET_STORAGE_CELL_DELAY";
case F_GET_FRAMES_LEFT: return "F_GET_FRAMES_LEFT";
case F_GET_TRIGGERS_LEFT: return "F_GET_TRIGGERS_LEFT";
case F_GET_EXPTIME_LEFT: return "F_GET_EXPTIME_LEFT";
case F_GET_PERIOD_LEFT: return "F_GET_PERIOD_LEFT";
case F_GET_DELAY_AFTER_TRIGGER_LEFT: return "F_GET_DELAY_AFTER_TRIGGER_LEFT";
case F_GET_MEASURED_PERIOD: return "F_GET_MEASURED_PERIOD";
case F_GET_MEASURED_SUBPERIOD: return "F_GET_MEASURED_SUBPERIOD";
case F_GET_FRAMES_FROM_START: return "F_GET_FRAMES_FROM_START";
case F_GET_ACTUAL_TIME: return "F_GET_ACTUAL_TIME";
case F_GET_MEASUREMENT_TIME: return "F_GET_MEASUREMENT_TIME";
case F_SET_DYNAMIC_RANGE: return "F_SET_DYNAMIC_RANGE";
case F_SET_ROI: return "F_SET_ROI";
case F_GET_ROI: return "F_GET_ROI";
case F_LOCK_SERVER: return "F_LOCK_SERVER";
case F_GET_LAST_CLIENT_IP: return "F_GET_LAST_CLIENT_IP";
case F_SET_PORT: return "F_SET_PORT";
case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA";
case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS";
case F_SET_PATTERN_IO_CONTROL: return "F_SET_PATTERN_IO_CONTROL";
case F_SET_PATTERN_WORD: return "F_SET_PATTERN_WORD";
case F_SET_PATTERN_LOOP_ADDRESSES: return "F_SET_PATTERN_LOOP_ADDRESSES";
case F_SET_PATTERN_LOOP_CYCLES: return "F_SET_PATTERN_LOOP_CYCLES";
case F_SET_PATTERN_WAIT_ADDR: return "F_SET_PATTERN_WAIT_ADDR";
case F_SET_PATTERN_WAIT_TIME: return "F_SET_PATTERN_WAIT_TIME";
case F_SET_PATTERN_MASK: return "F_SET_PATTERN_MASK";
case F_GET_PATTERN_MASK: return "F_GET_PATTERN_MASK";
case F_SET_PATTERN_BIT_MASK: return "F_SET_PATTERN_BIT_MASK";
case F_GET_PATTERN_BIT_MASK: return "F_GET_PATTERN_BIT_MASK";
case F_WRITE_ADC_REG: return "F_WRITE_ADC_REG";
case F_SET_COUNTER_BIT: return "F_SET_COUNTER_BIT";
case F_PULSE_PIXEL: return "F_PULSE_PIXEL";
case F_PULSE_PIXEL_AND_MOVE: return "F_PULSE_PIXEL_AND_MOVE";
case F_PULSE_CHIP: return "F_PULSE_CHIP";
case F_SET_RATE_CORRECT: return "F_SET_RATE_CORRECT";
case F_GET_RATE_CORRECT: return "F_GET_RATE_CORRECT";
case F_SET_TEN_GIGA_FLOW_CONTROL: return "F_SET_TEN_GIGA_FLOW_CONTROL";
case F_GET_TEN_GIGA_FLOW_CONTROL: return "F_GET_TEN_GIGA_FLOW_CONTROL";
case F_SET_TRANSMISSION_DELAY_FRAME: return "F_SET_TRANSMISSION_DELAY_FRAME";
case F_GET_TRANSMISSION_DELAY_FRAME: return "F_GET_TRANSMISSION_DELAY_FRAME";
case F_SET_TRANSMISSION_DELAY_LEFT: return "F_SET_TRANSMISSION_DELAY_LEFT";
case F_GET_TRANSMISSION_DELAY_LEFT: return "F_GET_TRANSMISSION_DELAY_LEFT";
case F_SET_TRANSMISSION_DELAY_RIGHT: return "F_SET_TRANSMISSION_DELAY_RIGHT";
case F_GET_TRANSMISSION_DELAY_RIGHT: return "F_GET_TRANSMISSION_DELAY_RIGHT";
case F_PROGRAM_FPGA: return "F_PROGRAM_FPGA";
case F_RESET_FPGA: return "F_RESET_FPGA";
case F_POWER_CHIP: return "F_POWER_CHIP";
case F_ACTIVATE: return "F_ACTIVATE";
case F_THRESHOLD_TEMP: return "F_THRESHOLD_TEMP";
case F_TEMP_CONTROL: return "F_TEMP_CONTROL";
case F_TEMP_EVENT: return "F_TEMP_EVENT";
case F_AUTO_COMP_DISABLE: return "F_AUTO_COMP_DISABLE";
case F_STORAGE_CELL_START: return "F_STORAGE_CELL_START";
case F_CHECK_VERSION: return "F_CHECK_VERSION";
case F_SOFTWARE_TRIGGER: return "F_SOFTWARE_TRIGGER";
case F_LED: return "F_LED";
case F_DIGITAL_IO_DELAY: return "F_DIGITAL_IO_DELAY";
case F_COPY_DET_SERVER: return "F_COPY_DET_SERVER";
case F_REBOOT_CONTROLLER: return "F_REBOOT_CONTROLLER";
case F_SET_ADC_ENABLE_MASK: return "F_SET_ADC_ENABLE_MASK";
case F_GET_ADC_ENABLE_MASK: return "F_GET_ADC_ENABLE_MASK";
case F_SET_ADC_INVERT: return "F_SET_ADC_INVERT";
case F_GET_ADC_INVERT: return "F_GET_ADC_INVERT";
case F_EXTERNAL_SAMPLING_SOURCE: return "F_EXTERNAL_SAMPLING_SOURCE";
case F_EXTERNAL_SAMPLING: return "F_EXTERNAL_SAMPLING";
case F_SET_STARTING_FRAME_NUMBER: return "F_SET_STARTING_FRAME_NUMBER";
case F_GET_STARTING_FRAME_NUMBER: return "F_GET_STARTING_FRAME_NUMBER";
case F_SET_QUAD: return "F_SET_QUAD";
case F_GET_QUAD: return "F_GET_QUAD";
case F_SET_INTERRUPT_SUBFRAME: return "F_SET_INTERRUPT_SUBFRAME";
case F_GET_INTERRUPT_SUBFRAME: return "F_GET_INTERRUPT_SUBFRAME";
case F_SET_READ_N_LINES: return "F_SET_READ_N_LINES";
case F_GET_READ_N_LINES: return "F_GET_READ_N_LINES";
case F_SET_POSITION: return "F_SET_POSITION";
case F_SET_SOURCE_UDP_MAC: return "F_SET_SOURCE_UDP_MAC";
case F_GET_SOURCE_UDP_MAC: return "F_GET_SOURCE_UDP_MAC";
case F_SET_SOURCE_UDP_MAC2: return "F_SET_SOURCE_UDP_MAC2";
case F_GET_SOURCE_UDP_MAC2: return "F_GET_SOURCE_UDP_MAC2";
case F_SET_SOURCE_UDP_IP: return "F_SET_SOURCE_UDP_IP";
case F_GET_SOURCE_UDP_IP: return "F_GET_SOURCE_UDP_IP";
case F_SET_SOURCE_UDP_IP2: return "F_SET_SOURCE_UDP_IP2";
case F_GET_SOURCE_UDP_IP2: return "F_GET_SOURCE_UDP_IP2";
case F_SET_DEST_UDP_MAC: return "F_SET_DEST_UDP_MAC";
case F_GET_DEST_UDP_MAC: return "F_GET_DEST_UDP_MAC";
case F_SET_DEST_UDP_MAC2: return "F_SET_DEST_UDP_MAC2";
case F_GET_DEST_UDP_MAC2: return "F_GET_DEST_UDP_MAC2";
case F_SET_DEST_UDP_IP: return "F_SET_DEST_UDP_IP";
case F_GET_DEST_UDP_IP: return "F_GET_DEST_UDP_IP";
case F_SET_DEST_UDP_IP2: return "F_SET_DEST_UDP_IP2";
case F_GET_DEST_UDP_IP2: return "F_GET_DEST_UDP_IP2";
case F_SET_DEST_UDP_PORT: return "F_SET_DEST_UDP_PORT";
case F_GET_DEST_UDP_PORT: return "F_GET_DEST_UDP_PORT";
case F_SET_DEST_UDP_PORT2: return "F_SET_DEST_UDP_PORT2";
case F_GET_DEST_UDP_PORT2: return "F_GET_DEST_UDP_PORT2";
case F_SET_NUM_INTERFACES: return "F_SET_NUM_INTERFACES";
case F_GET_NUM_INTERFACES: return "F_GET_NUM_INTERFACES";
case F_SET_INTERFACE_SEL: return "F_SET_INTERFACE_SEL";
case F_GET_INTERFACE_SEL: return "F_GET_INTERFACE_SEL";
case F_SET_PARALLEL_MODE: return "F_SET_PARALLEL_MODE";
case F_GET_PARALLEL_MODE: return "F_GET_PARALLEL_MODE";
case F_SET_OVERFLOW_MODE: return "F_SET_OVERFLOW_MODE";
case F_GET_OVERFLOW_MODE: return "F_GET_OVERFLOW_MODE";
case F_SET_READOUT_MODE: return "F_SET_READOUT_MODE";
case F_GET_READOUT_MODE: return "F_GET_READOUT_MODE";
case F_SET_CLOCK_FREQUENCY: return "F_SET_CLOCK_FREQUENCY";
case F_GET_CLOCK_FREQUENCY: return "F_GET_CLOCK_FREQUENCY";
case F_SET_CLOCK_PHASE: return "F_SET_CLOCK_PHASE";
case F_GET_CLOCK_PHASE: return "F_GET_CLOCK_PHASE";
case F_GET_MAX_CLOCK_PHASE_SHIFT: return "F_GET_MAX_CLOCK_PHASE_SHIFT";
case F_SET_CLOCK_DIVIDER: return "F_SET_CLOCK_DIVIDER";
case F_GET_CLOCK_DIVIDER: return "F_GET_CLOCK_DIVIDER";
case F_SET_PIPELINE: return "F_SET_PIPELINE";
case F_GET_PIPELINE: return "F_GET_PIPELINE";
case F_SET_ON_CHIP_DAC: return "F_SET_ON_CHIP_DAC";
case F_GET_ON_CHIP_DAC: return "F_GET_ON_CHIP_DAC";
case F_SET_INJECT_CHANNEL: return "F_SET_INJECT_CHANNEL";
case F_GET_INJECT_CHANNEL: return "F_GET_INJECT_CHANNEL";
case F_SET_VETO_PHOTON: return "F_SET_VETO_PHOTON";
case F_GET_VETO_PHOTON: return "F_GET_VETO_PHOTON";
case F_SET_VETO_REFERENCE: return "F_SET_VETO_REFERENCE";
case F_GET_BURST_MODE: return "F_GET_BURST_MODE";
case F_SET_BURST_MODE: return "F_SET_BURST_MODE";
case F_SET_ADC_ENABLE_MASK_10G: return "F_SET_ADC_ENABLE_MASK_10G";
case F_GET_ADC_ENABLE_MASK_10G: return "F_GET_ADC_ENABLE_MASK_10G";
case F_SET_COUNTER_MASK: return "F_SET_COUNTER_MASK";
case F_GET_COUNTER_MASK: return "F_GET_COUNTER_MASK";
case F_GET_NUM_BURSTS: return "F_GET_NUM_BURSTS";
case F_SET_NUM_BURSTS: return "F_SET_NUM_BURSTS";
case F_GET_BURST_PERIOD: return "F_GET_BURST_PERIOD";
case F_SET_BURST_PERIOD: return "F_SET_BURST_PERIOD";
case F_GET_CURRENT_SOURCE: return "F_GET_CURRENT_SOURCE";
case F_SET_CURRENT_SOURCE: return "F_SET_CURRENT_SOURCE";
case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE";
case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE";
case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS";
case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION";
case F_GET_RECEIVER_PARAMETERS: return "F_GET_RECEIVER_PARAMETERS";
case F_START_PATTERN: return "F_START_PATTERN";
case F_SET_NUM_GATES: return "F_SET_NUM_GATES";
case F_GET_NUM_GATES: return "F_GET_NUM_GATES";
case F_SET_GATE_DELAY: return "F_SET_GATE_DELAY";
case F_GET_GATE_DELAY: return "F_GET_GATE_DELAY";
case F_GET_EXPTIME_ALL_GATES: return "F_GET_EXPTIME_ALL_GATES";
case F_GET_GATE_DELAY_ALL_GATES: return "F_GET_GATE_DELAY_ALL_GATES";
case F_GET_VETO: return "F_GET_VETO";
case F_SET_VETO: return "F_SET_VETO";
case F_SET_PATTERN: return "F_SET_PATTERN";
case F_GET_SCAN: return "F_GET_SCAN";
case F_SET_SCAN: return "F_SET_SCAN";
case F_GET_SCAN_ERROR_MESSAGE: return "F_GET_SCAN_ERROR_MESSAGE";
case F_GET_CDS_GAIN: return "F_GET_CDS_GAIN";
case F_SET_CDS_GAIN: return "F_SET_CDS_GAIN";
case F_GET_FILTER: return "F_GET_FILTER";
case F_SET_FILTER: return "F_SET_FILTER";
case F_SET_ADC_CONFIGURATION: return "F_SET_ADC_CONFIGURATION";
case F_GET_ADC_CONFIGURATION: return "F_GET_ADC_CONFIGURATION";
case F_GET_BAD_CHANNELS: return "F_GET_BAD_CHANNELS";
case F_SET_BAD_CHANNELS: return "F_SET_BAD_CHANNELS";
case F_RECONFIGURE_UDP: return "F_RECONFIGURE_UDP";
case F_VALIDATE_UDP_CONFIG: return "F_VALIDATE_UDP_CONFIG";
case F_GET_BURSTS_LEFT: return "F_GET_BURSTS_LEFT";
case F_START_READOUT: return "F_START_READOUT";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND";
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER";
case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP";
case F_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT";
case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION";
case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI";
case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES";
case F_SET_RECEIVER_NUM_TRIGGERS: return "F_SET_RECEIVER_NUM_TRIGGERS";
case F_SET_RECEIVER_NUM_BURSTS: return "F_SET_RECEIVER_NUM_BURSTS";
case F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS: return "F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS";
case F_SET_RECEIVER_TIMING_MODE: return "F_SET_RECEIVER_TIMING_MODE";
case F_SET_RECEIVER_BURST_MODE: return "F_SET_RECEIVER_BURST_MODE";
case F_RECEIVER_SET_NUM_ANALOG_SAMPLES: return "F_RECEIVER_SET_NUM_ANALOG_SAMPLES";
case F_RECEIVER_SET_NUM_DIGITAL_SAMPLES:return "F_RECEIVER_SET_NUM_DIGITAL_SAMPLES";
case F_RECEIVER_SET_EXPTIME: return "F_RECEIVER_SET_EXPTIME";
case F_RECEIVER_SET_PERIOD: return "F_RECEIVER_SET_PERIOD";
case F_RECEIVER_SET_SUB_EXPTIME: return "F_RECEIVER_SET_SUB_EXPTIME";
case F_RECEIVER_SET_SUB_DEADTIME: return "F_RECEIVER_SET_SUB_DEADTIME";
case F_SET_RECEIVER_DYNAMIC_RANGE: return "F_SET_RECEIVER_DYNAMIC_RANGE";
case F_SET_RECEIVER_STREAMING_FREQUENCY: return "F_SET_RECEIVER_STREAMING_FREQUENCY";
case F_GET_RECEIVER_STREAMING_FREQUENCY: return "F_GET_RECEIVER_STREAMING_FREQUENCY";
case F_GET_RECEIVER_STATUS: return "F_GET_RECEIVER_STATUS";
case F_START_RECEIVER: return "F_START_RECEIVER";
case F_STOP_RECEIVER: return "F_STOP_RECEIVER";
case F_SET_RECEIVER_FILE_PATH: return "F_SET_RECEIVER_FILE_PATH";
case F_GET_RECEIVER_FILE_PATH: return "F_GET_RECEIVER_FILE_PATH";
case F_SET_RECEIVER_FILE_NAME: return "F_SET_RECEIVER_FILE_NAME";
case F_GET_RECEIVER_FILE_NAME: return "F_GET_RECEIVER_FILE_NAME";
case F_SET_RECEIVER_FILE_INDEX: return "F_SET_RECEIVER_FILE_INDEX";
case F_GET_RECEIVER_FILE_INDEX: return "F_GET_RECEIVER_FILE_INDEX";
case F_GET_RECEIVER_FRAME_INDEX: return "F_GET_RECEIVER_FRAME_INDEX";
case F_GET_RECEIVER_FRAMES_CAUGHT: return "F_GET_RECEIVER_FRAMES_CAUGHT";
case F_GET_NUM_MISSING_PACKETS: return "F_GET_NUM_MISSING_PACKETS";
case F_SET_RECEIVER_FILE_WRITE: return "F_SET_RECEIVER_FILE_WRITE";
case F_GET_RECEIVER_FILE_WRITE: return "F_GET_RECEIVER_FILE_WRITE";
case F_SET_RECEIVER_MASTER_FILE_WRITE: return "F_SET_RECEIVER_MASTER_FILE_WRITE";
case F_GET_RECEIVER_MASTER_FILE_WRITE: return "F_GET_RECEIVER_MASTER_FILE_WRITE";
case F_SET_RECEIVER_OVERWRITE: return "F_SET_RECEIVER_OVERWRITE";
case F_GET_RECEIVER_OVERWRITE: return "F_GET_RECEIVER_OVERWRITE";
case F_ENABLE_RECEIVER_TEN_GIGA: return "F_ENABLE_RECEIVER_TEN_GIGA";
case F_SET_RECEIVER_FIFO_DEPTH: return "F_SET_RECEIVER_FIFO_DEPTH";
case F_RECEIVER_ACTIVATE: return "F_RECEIVER_ACTIVATE";
case F_SET_RECEIVER_STREAMING: return "F_SET_RECEIVER_STREAMING";
case F_GET_RECEIVER_STREAMING: return "F_GET_RECEIVER_STREAMING";
case F_RECEIVER_STREAMING_TIMER: return "F_RECEIVER_STREAMING_TIMER";
case F_SET_FLIPPED_DATA_RECEIVER: return "F_SET_FLIPPED_DATA_RECEIVER";
case F_SET_RECEIVER_FILE_FORMAT: return "F_SET_RECEIVER_FILE_FORMAT";
case F_GET_RECEIVER_FILE_FORMAT: return "F_GET_RECEIVER_FILE_FORMAT";
case F_SET_RECEIVER_STREAMING_PORT: return "F_SET_RECEIVER_STREAMING_PORT";
case F_GET_RECEIVER_STREAMING_PORT: return "F_GET_RECEIVER_STREAMING_PORT";
case F_SET_RECEIVER_STREAMING_SRC_IP: return "F_SET_RECEIVER_STREAMING_SRC_IP";
case F_GET_RECEIVER_STREAMING_SRC_IP: return "F_GET_RECEIVER_STREAMING_SRC_IP";
case F_SET_RECEIVER_SILENT_MODE: return "F_SET_RECEIVER_SILENT_MODE";
case F_GET_RECEIVER_SILENT_MODE: return "F_GET_RECEIVER_SILENT_MODE";
case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER";
case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER";
case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_ADDITIONAL_JSON_HEADER";
case F_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE";
case F_SET_RECEIVER_FRAMES_PER_FILE: return "F_SET_RECEIVER_FRAMES_PER_FILE";
case F_GET_RECEIVER_FRAMES_PER_FILE: return "F_GET_RECEIVER_FRAMES_PER_FILE";
case F_RECEIVER_CHECK_VERSION: return "F_RECEIVER_CHECK_VERSION";
case F_SET_RECEIVER_DISCARD_POLICY: return "F_SET_RECEIVER_DISCARD_POLICY";
case F_GET_RECEIVER_DISCARD_POLICY: return "F_GET_RECEIVER_DISCARD_POLICY";
case F_SET_RECEIVER_PADDING: return "F_SET_RECEIVER_PADDING";
case F_GET_RECEIVER_PADDING: return "F_GET_RECEIVER_PADDING";
case F_SET_RECEIVER_DEACTIVATED_PADDING: return "F_SET_RECEIVER_DEACTIVATED_PADDING";
case F_GET_RECEIVER_DEACTIVATED_PADDING: return "F_GET_RECEIVER_DEACTIVATED_PADDING";
case F_RECEIVER_SET_READOUT_MODE: return "F_RECEIVER_SET_READOUT_MODE";
case F_RECEIVER_SET_ADC_MASK: return "F_RECEIVER_SET_ADC_MASK";
case F_SET_RECEIVER_DBIT_LIST: return "F_SET_RECEIVER_DBIT_LIST";
case F_GET_RECEIVER_DBIT_LIST: return "F_GET_RECEIVER_DBIT_LIST";
case F_SET_RECEIVER_DBIT_OFFSET: return "F_SET_RECEIVER_DBIT_OFFSET";
case F_GET_RECEIVER_DBIT_OFFSET: return "F_GET_RECEIVER_DBIT_OFFSET";
case F_SET_RECEIVER_QUAD: return "F_SET_RECEIVER_QUAD";
case F_SET_RECEIVER_READ_N_LINES: return "F_SET_RECEIVER_READ_N_LINES";
case F_SET_RECEIVER_UDP_IP: return "F_SET_RECEIVER_UDP_IP";
case F_SET_RECEIVER_UDP_IP2: return "F_SET_RECEIVER_UDP_IP2";
case F_SET_RECEIVER_UDP_PORT: return "F_SET_RECEIVER_UDP_PORT";
case F_SET_RECEIVER_UDP_PORT2: return "F_SET_RECEIVER_UDP_PORT2";
case F_SET_RECEIVER_NUM_INTERFACES: return "F_SET_RECEIVER_NUM_INTERFACES";
case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G";
case F_RECEIVER_SET_COUNTER_MASK: return "F_RECEIVER_SET_COUNTER_MASK";
case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX";
case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER";
case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER";
case F_GET_RECEIVER_PROGRESS: return "F_GET_RECEIVER_PROGRESS";
case F_SETUP_RECEIVER: return "F_SETUP_RECEIVER";
case F_SET_RECEIVER_NUM_GATES: return "F_SET_RECEIVER_NUM_GATES";
case F_SET_RECEIVER_GATE_DELAY: return "F_SET_RECEIVER_GATE_DELAY";
case F_GET_RECEIVER_THREAD_IDS: return "F_GET_RECEIVER_THREAD_IDS";
case F_GET_RECEIVER_STREAMING_START_FNUM: return "F_GET_RECEIVER_STREAMING_START_FNUM";
case F_SET_RECEIVER_STREAMING_START_FNUM: return "F_SET_RECEIVER_STREAMING_START_FNUM";
case F_SET_RECEIVER_RATE_CORRECT: return "F_SET_RECEIVER_RATE_CORRECT";
case F_SET_RECEIVER_SCAN: return "F_SET_RECEIVER_SCAN";
case F_RECEIVER_SET_THRESHOLD: return "F_RECEIVER_SET_THRESHOLD";
case F_GET_RECEIVER_STREAMING_HWM: return "F_GET_RECEIVER_STREAMING_HWM";
case F_SET_RECEIVER_STREAMING_HWM: return "F_SET_RECEIVER_STREAMING_HWM";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";
}
// clang-format on
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
namespace sls {
/* Implementation of a safe string copy function for setting fields in
for example the multi sls detector. It tries to copy the size of the
destination from the source, stopping on '\0'.
Warning this will truncate the source string and should be used with care.
Still this is better than strcpy and a buffer overflow...
*/
template <size_t array_size>
void strcpy_safe(char (&destination)[array_size], const char *source) {
assert(array_size > strlen(source));
strncpy(destination, source, array_size - 1);
destination[array_size - 1] = '\0';
}
template <size_t array_size>
void strcpy_safe(char (&destination)[array_size], const std::string &source) {
assert(array_size > source.size());
strncpy(destination, source.c_str(), array_size - 1);
destination[array_size - 1] = '\0';
}
/*
Removes all occurrences of the specified char from a c string
Templated on array size to ensure no access after buffer limits.
*/
template <size_t array_size> void removeChar(char (&str)[array_size], char ch) {
int count = 0;
for (int i = 0; str[i]; i++) {
if (str[i] != ch)
str[count++] = str[i];
if (i == array_size - 1)
break;
}
str[count] = '\0';
}
/*
Split a string using the specified delimeter and return a vector of strings.
TODO! Look into switching to absl or a string_view based implementation. Current
implementation should not be used in a performance critical place.
*/
std::vector<std::string> split(const std::string &strToSplit, char delimeter);
std::string RemoveUnit(std::string &str);
bool is_int(const std::string& s);
} // namespace sls

View File

@ -0,0 +1,12 @@
/** API versions */
#define GITBRANCH "developer"
#define APILIB 0x201008
#define APIRECEIVER 0x201008
#define APIGUI 0x201009
#define APIEIGER 0x201009
#define APICTB 0x201016
#define APIGOTTHARD 0x201016
#define APIJUNGFRAU 0x201016
#define APIMOENCH 0x201013
#define APIMYTHEN3 0x201027
#define APIGOTTHARD2 0x201027