Compare commits

...

31 Commits

Author SHA1 Message Date
c4c2866905 WIP 2020-04-27 17:21:22 +02:00
b90f9b046f getHostname 2020-04-27 17:03:52 +02:00
d66df844e5 added parallel and container3 2020-04-27 15:20:13 +02:00
4f712fcd70 WIP 2020-04-24 15:28:41 +02:00
bb32b2f653 rxr done WIP 2020-04-24 15:13:37 +02:00
085cbbf0d6 WIP, separated rxr from module 2020-04-23 16:09:40 +02:00
45a770cf38 WIP 2020-04-23 15:16:14 +02:00
990008c9d9 WIP 2020-04-23 12:20:04 +02:00
5339e16101 port sequences and client zmq implementation needs revisit, WIP 2020-04-22 17:55:02 +02:00
c976c63fb5 WIP udp 2020-04-22 14:05:20 +02:00
9ee2d389fb WIP 2020-04-22 13:43:10 +02:00
8d0146949c WIP 2020-04-22 12:54:55 +02:00
6de68eacc2 WIP 2020-04-21 18:48:04 +02:00
94103a05b1 parallel3 fix, software version check 2020-04-21 18:27:52 +02:00
1185f1ea17 WIP, a in shm name 2020-04-21 18:02:27 +02:00
d3f420ffd4 WIP, indexstring 2020-04-21 17:14:09 +02:00
6b5511c9e5 WIP, moved bool primaryinterface to an int interface_id 2020-04-21 14:34:48 +02:00
d8aa1ab08e json para and header added 2020-04-21 14:10:07 +02:00
b4c31327d6 WIP, temp fix 2020-04-21 12:35:08 +02:00
c408f9807a Merge branch 'developer' into separateRxr 2020-04-21 11:30:23 +02:00
9df128fced WIP, cant compile squash for rxParameters 2020-04-20 18:35:30 +02:00
e39ec65d19 Merge branch 'developer' into separateRxr 2020-04-20 18:33:37 +02:00
601be462af WIP, rxhostname 2020-04-20 18:33:14 +02:00
1d31695cc1 WIP 2020-04-17 12:15:16 +02:00
df63a6dffe rx_statusL unknown, but others good WIP 2020-04-17 12:09:23 +02:00
cfa9049ed3 WIP: none to remove receivers 2020-04-17 10:34:10 +02:00
9a208caca8 WIP: first connect to rxr 2020-04-16 18:20:04 +02:00
78fb8080ce WIP: some bug fixes and reducing redundant code 2020-04-16 18:07:11 +02:00
cd45f9d45b WIP, parallel 2020-04-16 16:18:50 +02:00
d536ad2b5b WIP, rxr constr done 2020-04-16 13:58:59 +02:00
2921cbfac8 WIP 2020-04-14 12:44:43 +02:00
34 changed files with 3778 additions and 2835 deletions

View File

@ -6846,14 +6846,11 @@ int get_receiver_parameters(int file_des) {
n += sendData(file_des,&i32,sizeof(i32),INT32);
if (n < 0) return printSocketReadError();
// multisize
i32 = 0;
n += sendData(file_des,&i32,sizeof(i32),INT32);
if (n < 0) return printSocketReadError();
i32 = 0;
n += sendData(file_des,&i32,sizeof(i32),INT32);
if (n < 0) return printSocketReadError();
// detId
i32 = 0;
n += sendData(file_des,&i32,sizeof(i32),INT32);
if (n < 0) return printSocketReadError();
// hostname
@ -6863,6 +6860,12 @@ int get_receiver_parameters(int file_des) {
n += sendData(file_des, hostname, MAX_STR_LENGTH, OTHER);
if (n < 0) return printSocketReadError();
}
// interface id
n += sendData(file_des,&i32,sizeof(i32),INT32);
if (n < 0) return printSocketReadError();
// zmq ip
n += sendData(file_des,&i32,sizeof(i32),INT32);
if (n < 0) return printSocketReadError();
// end of shared memory variables in struct

View File

@ -3,6 +3,7 @@ set(SOURCES
src/slsDetectorUsers.cpp
src/Module.cpp
src/Detector.cpp
src/Receiver.cpp
src/CmdProxy.cpp
src/CmdParser.cpp
)

View File

@ -19,7 +19,7 @@ class IpAddr;
//Free function to avoid dependence on class
//and avoid the option to free another objects
//shm by mistake
void freeSharedMemory(int multiId, int detPos = -1);
void freeSharedMemory(int detectorId, int moduleId = -1);
/**
@ -57,6 +57,8 @@ class Detector {
/* Frees shared memory, adds detectors to the list
* and updates local detector cache */
void setHostname(const std::vector<std::string> &hostname);
void setHostname(const std::vector<std::string> &hostname,
const std::vector<int> &port);
/** connects to n servers at local host starting at specific control port */
void setVirtualDetectorServers(int numServers, int startingPort);
@ -344,11 +346,15 @@ class Detector {
Result<defs::runStatus> getDetectorStatus(Positions pos = {}) const;
Result<defs::runStatus> getReceiverStatus(Positions pos = {}) const;
Result<defs::runStatus> getReceiverStatus() const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
Result<defs::runStatus> getReceiverStatus(const int udpInterface,
Positions pos = {}) const;
Result<int64_t> getFramesCaught(Positions pos = {}) const;
Result<uint64_t> getFramesCaught(Positions pos = {}) const;
Result<std::vector<uint64_t>> getNumMissingPackets(Positions pos = {}) const;
Result<uint64_t> getNumMissingPackets(Positions pos = {}) const;
/** [Eiger][Jungfrau] */
Result<uint64_t> getStartingFrameNumber(Positions pos = {}) const;
@ -503,28 +509,40 @@ class Detector {
* *
* ************************************************/
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
void removeReceivers(const int udpInterface);
/** true when slsReceiver is used */
Result<bool> getUseReceiverFlag(Positions pos = {}) const;
Result<std::string> getRxHostname(Positions pos = {}) const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau]
*/
Result<std::string> getRxHostname(const int udpInterface, Positions pos = {}) const;
/**
* Validates and sets the receiver.
* Updates local receiver cache parameters
* Configures the detector to the receiver as UDP destination
* @param receiver receiver hostname or IP address, can include tcp port eg. hostname:port
* interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau]
*/
void setRxHostname(const std::string &receiver, Positions pos = {});
void setRxHostname(const int udpInterface, const std::string &hostname,
Positions pos = {});
/** multiple rx hostnames (same as setRxHostname) */
void setRxHostname(const std::vector<std::string> &name);
/** cannot be for multiple detectors as port is unique */
void setRxHostname(const int udpInterface, const std::string &hostname,
const int port, int module_id);
Result<int> getRxPort(Positions pos = {}) const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
Result<int> getRxPort(const int udpInterface, Positions pos = {}) const;
/** Receiver TCP port (for client communication with Receiver)
* module_id is -1 for all detectors, ports for each module is calculated
* (increments) */
void setRxPort(int port, int module_id = -1);
* (increments)
* interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
void setRxPort(const int udpInterface, const int port, int module_id = -1);
Result<int> getRxFifoDepth(Positions pos = {}) const;
@ -1352,8 +1370,6 @@ class Detector {
Result<uint64_t> getRxCurrentFrameIndex(Positions pos = {}) const;
private:
std::vector<int> getPortNumbers(int start_port);
};
} // namespace sls

View File

@ -115,13 +115,29 @@ std::string CmdProxy::ListCommands(int action) {
}
/* configuration */
std::pair<std::string, int>
CmdProxy::parseHostnameAndPort(std::string name) {
std::string host = name;
std::string hostname;
int port = 0;
auto res = sls::split(host, ':');
if (res.size() > 1) {
hostname = res[0];
port = StringTo<int>(res[1]);
} else {
hostname = host;
}
return std::make_pair(hostname, port);
}
std::string CmdProxy::Hostname(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "\n\tFrees shared memory and sets hostname (or IP address) of "
"all modules concatenated by +."
"all modules concatenated by +.\n\t"
"[hostname or ip address]:[tcp port] Use this for virtual servers\n\t"
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
@ -136,17 +152,35 @@ std::string CmdProxy::Hostname(int action) {
if (det_id != -1) {
throw sls::RuntimeError("Cannot execute this at module level");
}
std::vector<std::string> arguments;
// only args[0], but many hostames concatenated with +
if (args[0].find('+') != std::string::npos) {
auto t = sls::split(args[0], '+');
det->setHostname(t);
os << ToString(t) << '\n';
if (args.size() > 1) {
throw sls::RuntimeError("Cannot have concatenated hostnames and"
"multiple arguments");
}
arguments = sls::split(args[0], '+');
}
// either hostnames separated by space, or single hostname
else {
det->setHostname(args);
os << ToString(args) << '\n';
arguments.assign(args.begin(), args.end());
}
// separate hostname and port
std::vector<std::string> hostnames;
std::vector<int> ports;
for (size_t i = 0; i < arguments.size(); ++i) {
std::pair<std::string, int> res = parseHostnameAndPort(arguments[i]);
hostnames.push_back(res.first);
if (res.second == 0) {
ports.push_back(DEFAULT_PORTNO);
} else {
ports.push_back(res.second);
}
}
det->setHostname(hostnames, ports);
auto t = det->getHostname({det_id});
os << OutString(t) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
@ -787,16 +821,29 @@ std::vector<std::string> CmdProxy::DacCommands() {
/* acquisition */
std::string CmdProxy::ReceiverStatus(int action) {
int udpInterface = 1;
if (cmd == "rx_status") {
udpInterface = 1;
} else if (cmd == "rx_status2") {
udpInterface = 2;
} else {
throw sls::RuntimeError("Unknown command, use list to list all commands");
}
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
if (cmd == "rx_status") {
os << "running, idle]\n\tReceiver listener status."
<< '\n';
} else {
os << "running, idle]\n\tReceiver listener status for second udp port."
<< '\n';
}
} else if (action == defs::GET_ACTION) {
if (args.size() != 0) {
WrongNumberOfParameters(0);
}
auto t = det->getReceiverStatus({det_id});
auto t = det->getReceiverStatus(udpInterface, {det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
throw sls::RuntimeError("Cannot put. Did you mean to use command 'rx_start' or 'rx_stop'?");
@ -905,61 +952,76 @@ std::string CmdProxy::UDPDestinationIP2(int action) {
}
/* Receiver Config */
std::string CmdProxy::ReceiveHostname(int action) {
std::string CmdProxy::ReceiverHostname(int action) {
int udpInterface = 1;
if (cmd == "rx_hostname") {
udpInterface = 1;
} else if (cmd == "rx_hostname2") {
udpInterface = 2;
} else {
throw sls::RuntimeError("Unknown command, use list to list all commands");
}
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
if (cmd == "rx_hostname") {
os << "[hostname or ip address]\n\t"
"[hostname or ip address]:[tcp port]\n\t"
"[hostname1]:[tcp_port1]+[hostname2]:[tcp_port2]+\n\t"
"Receiver hostname or IP. If port included, then the receiver tcp port.\n\t"
"Receiver hostname or IP. Port is the receiver tcp port (optional).\n\t"
"Use 'none' to remove receivers\n\t"
"Used for TCP control communication between client and receiver "
"to configure receiver. Also updates receiver with detector parameters."
"to configure receiver. Also updates receiver with detector parameters.\n\t"
"TCP port must be unique, if included.\n\t"
"If port not included and not set earlier, then it takes default port 1954"
" and calculates from there. \n\t"
"[Eiger][Jungfrau] For the 2nd udp interface, use rx_hostname2."
<< '\n';
} else {
os << "[hostname or ip address]\n\t"
"[hostname or ip address]:[tcp port]\n\t"
"[Eiger][Jungfrau] Receiver hostname or IP for the second udp port. "
"Port is the receiver tcp port (optional).\n\t"
"Use 'none' to remove receivers\n\t"
"Refer rx_hostname help for details"
<< '\n';
}
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getRxHostname({det_id});
auto t = det->getRxHostname(udpInterface, {det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() < 1) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
// multiple arguments
if (args.size() > 1) {
// multiple in mulitple
if (args[0].find('+') != std::string::npos) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
throw sls::RuntimeError("Cannot concatenate receiver hostnames");
}
if (det_id != -1) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
std::pair<std::string, int> res = parseHostnameAndPort(args[0]);
// removing receivers
if (res.first == "none") {
det->removeReceivers(udpInterface);
os << "removed" << '\n';
}
det->setRxHostname(args);
os << ToString(args) << '\n';
}
// single argument
// adding receivers
else {
// multiple receivers concatenated with +
if (args[0].find('+') != std::string::npos) {
if (det_id != -1) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
}
auto t = sls::split(args[0], '+');
det->setRxHostname(t);
os << ToString(t) << '\n';
}
// single receiver
else {
det->setRxHostname(args[0], {det_id});
os << ToString(args) << '\n';
std::string hostname = res.first;
int port = res.second;
if (port == 0) {
det->setRxHostname(udpInterface, hostname, {det_id});
} else {
det->setRxHostname(udpInterface, hostname, port, det_id);
}
auto t = det->getRxHostname(udpInterface, {det_id});
os << OutString(t) << '\n';
}
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */

View File

@ -719,8 +719,10 @@ class CmdProxy {
{"txndelay_right", &CmdProxy::txndelay_right},
/* Receiver Config */
{"rx_hostname", &CmdProxy::ReceiveHostname},
{"rx_hostname", &CmdProxy::ReceiverHostname},
{"rx_hostname2", &CmdProxy::ReceiverHostname},
{"rx_tcpport", &CmdProxy::rx_tcpport},
{"rx_tcpport2", &CmdProxy::rx_tcpport2},
{"rx_fifodepth", &CmdProxy::rx_fifodepth},
{"rx_silent", &CmdProxy::rx_silent},
{"rx_discardpolicy", &CmdProxy::rx_discardpolicy},
@ -911,6 +913,7 @@ class CmdProxy {
/* configuration */
std::string free(int action);
// std::string config2(int action);
std::pair<std::string, int> parseHostnameAndPort(std::string name);
std::string Hostname(int action);
std::string VirtualServer(int action);
std::string FirmwareVersion(int action);
@ -940,7 +943,7 @@ class CmdProxy {
std::string UDPDestinationIP(int action);
std::string UDPDestinationIP2(int action);
/* Receiver Config */
std::string ReceiveHostname(int action);
std::string ReceiverHostname(int action);
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */
@ -1431,9 +1434,12 @@ class CmdProxy {
/* Receiver Config */
INTEGER_COMMAND(rx_tcpport, getRxPort, setRxPort, StringTo<int>,
INTEGER_IND_COMMAND(rx_tcpport, getRxPort, setRxPort, StringTo<int>, 1,
"[port]\n\tTCP port for client-receiver communication. Default is 1954. Must be different if multiple receivers on same pc. Must be first command to set a receiver parameter. Multi command will automatically increment for individual modules.");
INTEGER_IND_COMMAND(rx_tcpport2, getRxPort, setRxPort, StringTo<int>, 2,
"[port]\n\t[Eiger][Jungfrau] TCP port for client-receiver communication for 2nd udp port. For details, refer rx_tcpport.");
INTEGER_COMMAND(rx_fifodepth, getRxFifoDepth, setRxFifoDepth, StringTo<int>,
"[n_frames]\n\tSet the number of frames in the receiver fifo (buffer between listener and writer threads).");

View File

@ -0,0 +1,157 @@
#pragma once
#include <array>
#include <cstddef>
#include <iostream>
#include <numeric>
namespace sls{
template <typename T> class Container3 {
std::array<size_t, 3> shape_{0, 0, 0};
T *data_{nullptr};
public:
Container3(){};
Container3(std::array<size_t, 3> shape)
: Container3(shape[0], shape[1], shape[2]) {}
Container3(std::array<size_t, 3> shape, T value)
: Container3(shape[0], shape[1], shape[2], value) {}
Container3(size_t x, size_t y, size_t z)
: shape_{x, y, z}, data_(new T[size()]{}) {}
Container3(size_t x, size_t y, size_t z, const T &value)
: shape_{x, y, z}, data_(new T[size()]) {
std::fill_n(data_, size(), value);
}
// Copy constructor
Container3(const Container3 &other) {
shape_ = other.shape_;
data_ = new T[size()];
std::copy(other.data_, other.data_ + size(), data_);
}
// Move constructor
Container3(Container3 &&other) {
shape_ = other.shape_;
other.shape_ = {0, 0, 0};
data_ = other.data_;
other.data_ = nullptr;
}
// Copy assignment
Container3 &operator=(const Container3 &other) {
if (this != &other) {
Container3<T> tmp(other);
std::swap(shape_, tmp.shape_);
std::swap(data_, tmp.data_);
}
return *this;
}
// Move assignment
Container3 &operator=(Container3 &&other) {
if (this != &other) {
shape_ = other.shape_;
other.shape_ = {0, 0, 0};
delete[] data_;
data_ = other.data_;
other.data_ = nullptr;
}
return *this;
}
~Container3() { delete[] data_; }
size_t size() const noexcept {
return std::accumulate(std::begin(shape_), std::end(shape_), 1,
std::multiplies<size_t>());
}
size_t size(size_t i) const noexcept { return shape_[i]; }
std::array<size_t, 3> shape() const noexcept { return shape_; }
T *data() noexcept { return data_; }
const T *data() const noexcept { return data_; }
bool is_valid_index(size_t x, size_t y, size_t z) const noexcept {
return x < shape_[0] && y < shape_[1] && z < shape_[2];
}
// Will truncate if other is larger in any dimension
// In the future move object out of other, rename function
void copy_data(const Container3 &other) {
for (size_t i = 0; i < std::min(size(0), other.size(0)); ++i) {
for (size_t j = 0; j < std::min(size(1), other.size(1)); ++j) {
for (size_t k = 0; k < std::min(size(2), other.size(2)); ++k) {
(*this)(i, j, k) = other(i, j, k);
}
}
}
}
void move_data(Container3 &other) {
for (size_t i = 0; i < std::min(size(0), other.size(0)); ++i) {
for (size_t j = 0; j < std::min(size(1), other.size(1)); ++j) {
for (size_t k = 0; k < std::min(size(2), other.size(2)); ++k) {
(*this)(i, j, k) = std::move(other(i, j, k));
}
}
}
}
void resize(size_t x, size_t y, size_t z) {
Container3<T> tmp(x, y, z);
tmp.move_data(*this);
*this = std::move(tmp);
}
T &operator()(size_t x, size_t y, size_t z) noexcept {
return data_[element_offset(x, y, z)];
}
const T &operator()(size_t x, size_t y, size_t z) const noexcept {
return data_[element_offset(x, y, z)];
}
// throws on out of bounds access
const T &at(size_t x, size_t y, size_t z) const {
if (!is_valid_index(x, y, z))
throw std::runtime_error("Index error");
return data_[element_offset(x, y, z)];
}
T &at(size_t x, size_t y, size_t z) {
return const_cast<T &>(
static_cast<const Container3 &>(*this).at(x, y, z));
}
T &operator[](size_t i) { return data_[i]; }
const T &operator[](size_t i) const { return data_[i]; }
T *begin() { return data_; }
T *end() { return data_ + size(); }
void clear(){
*this = Container3<T>();
}
// reference to position, grow if needed, prefer resize and .at()
T &at_can_grow(size_t x, size_t y, size_t z) {
if (!is_valid_index(x, y, z)) {
resize(std::max(x + 1, size(0)), std::max(y + 1, size(1)),
std::max(z + 1, size(2)));
}
return data_[element_offset(x, y, z)];
}
private:
size_t element_offset(size_t x, size_t y, size_t z) const noexcept {
return x * shape_[1] * shape_[2] + y * shape_[2] + z;
}
};
} // namespace sls

View File

@ -6,36 +6,65 @@
#include "logger.h"
#include "DetectorImpl.h"
#include "Module.h"
#include "Receiver.h"
#include "sls_detector_defs.h"
#include "versionAPI.h"
#include "Parallel.h"
#include "MaskGenerator.h"
#include <fstream>
namespace sls {
void freeSharedMemory(int multiId, int detPos) {
void freeSharedMemory(int detectorId, int moduleId) {
// single
if (detPos >= 0) {
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
if (temp_shm.IsExisting()) {
temp_shm.RemoveSharedMemory();
if (moduleId >= 0) {
SharedMemory<sharedModule> moduleShm(detectorId, moduleId);
int numReceivers = 0, numReceivers2 = 0;
if (moduleShm.IsExisting()) {
moduleShm.OpenSharedMemory();
if (Module::hasSharedMemoryReceiverList(moduleShm()->shmversion)) {
numReceivers = moduleShm()->numberOfReceivers;
numReceivers2 = moduleShm()->numberOfReceivers2;
}
moduleShm.RemoveSharedMemory();
}
for (int iReceiver = 0; iReceiver < numReceivers + numReceivers2; ++iReceiver) {
SharedMemory<sharedModule> receiverShm(detectorId, moduleId, iReceiver);
if (receiverShm.IsExisting()) {
receiverShm.RemoveSharedMemory();
}
}
return;
}
// multi - get number of detectors from shm
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
SharedMemory<sharedDetector> detectorShm(detectorId, -1);
int numDetectors = 0;
if (multiShm.IsExisting()) {
multiShm.OpenSharedMemory();
numDetectors = multiShm()->numberOfDetectors;
multiShm.RemoveSharedMemory();
if (detectorShm.IsExisting()) {
detectorShm.OpenSharedMemory();
numDetectors = detectorShm()->numberOfModules;
detectorShm.RemoveSharedMemory();
}
for (int i = 0; i < numDetectors; ++i) {
SharedMemory<sharedSlsDetector> shm(multiId, i);
shm.RemoveSharedMemory();
for (int iModule = 0; iModule < numDetectors; ++iModule) {
SharedMemory<sharedModule> moduleShm(detectorId, iModule);
int numReceivers = 0, numReceivers2 = 0;
if (moduleShm.IsExisting()) {
moduleShm.OpenSharedMemory();
if (Module::hasSharedMemoryReceiverList(moduleShm()->shmversion)) {
numReceivers = moduleShm()->numberOfReceivers;
numReceivers2 = moduleShm()->numberOfReceivers2;
}
moduleShm.RemoveSharedMemory();
}
for (int iReceiver = 0; iReceiver < numReceivers + numReceivers2; ++iReceiver) {
SharedMemory<sharedModule> receiverShm(detectorId, iModule, iReceiver);
if (receiverShm.IsExisting()) {
receiverShm.RemoveSharedMemory();
}
}
}
}
@ -91,11 +120,16 @@ void Detector::setHostname(const std::vector<std::string> &hostname) {
pimpl->setHostname(hostname);
}
void Detector::setHostname(const std::vector<std::string> &hostname,
const std::vector<int> &port) {
pimpl->setHostname(hostname, port);
}
void Detector::setVirtualDetectorServers(int numServers, int startingPort) {
pimpl->setVirtualDetectorServers(numServers, startingPort);
}
int Detector::getShmId() const { return pimpl->getMultiId(); }
int Detector::getShmId() const { return pimpl->getDetectorId(); }
std::string Detector::getPackageVersion() const {
return GITBRANCH;
@ -118,7 +152,7 @@ Result<int64_t> Detector::getSerialNumber(Positions pos) const {
}
Result<int64_t> Detector::getReceiverVersion(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverSoftwareVersion, pos);
return pimpl->Parallel3(&Receiver::getSoftwareVersion); //FIXME
}
Result<defs::detectorType> Detector::getDetectorType(Positions pos) const {
@ -183,6 +217,7 @@ Result<int64_t> Detector::getNumberOfFrames(Positions pos) const {
void Detector::setNumberOfFrames(int64_t value) {
pimpl->Parallel(&Module::setNumberOfFrames, {}, value);
pimpl->Parallel3(&Receiver::setNumberOfFrames, value); //FIXME
}
Result<int64_t> Detector::getNumberOfTriggers(Positions pos) const {
@ -191,6 +226,7 @@ Result<int64_t> Detector::getNumberOfTriggers(Positions pos) const {
void Detector::setNumberOfTriggers(int64_t value) {
pimpl->Parallel(&Module::setNumberOfTriggers, {}, value);
pimpl->Parallel3(&Receiver::setNumberOfTriggers, value);
}
Result<ns> Detector::getExptime(Positions pos) const {
@ -198,7 +234,18 @@ Result<ns> Detector::getExptime(Positions pos) const {
}
void Detector::setExptime(ns t, Positions pos) {
bool change = false;
if (getDetectorType().squash() == defs::EIGER) {
ns prevVal = getExptime(pos).squash();
if (getExptime(pos).squash() != t) {
change = true;
}
}
pimpl->Parallel(&Module::setExptime, pos, t.count());
pimpl->Parallel3(&Receiver::setExptime, t.count());
if (change) {
pimpl->Parallel(&Module::updateRateCorrection, pos);
}
}
Result<ns> Detector::getPeriod(Positions pos) const {
@ -207,6 +254,7 @@ Result<ns> Detector::getPeriod(Positions pos) const {
void Detector::setPeriod(ns t, Positions pos) {
pimpl->Parallel(&Module::setPeriod, pos, t.count());
pimpl->Parallel3(&Receiver::setPeriod, t.count());
}
Result<ns> Detector::getDelayAfterTrigger(Positions pos) const {
@ -239,6 +287,7 @@ Result<defs::timingMode> Detector::getTimingMode(Positions pos) const {
void Detector::setTimingMode(defs::timingMode value, Positions pos) {
pimpl->Parallel(&Module::setTimingMode, pos, value);
pimpl->Parallel3(&Receiver::setTimingMode, value);
}
Result<defs::speedLevel> Detector::getSpeed(Positions pos) const {
@ -431,11 +480,11 @@ void Detector::acquire() { pimpl->acquire(); }
void Detector::clearAcquiringFlag() { pimpl->setAcquiringFlag(0); }
void Detector::startReceiver() {
pimpl->Parallel(&Module::startReceiver, {});
pimpl->Parallel3(&Receiver::start);
}
void Detector::stopReceiver() {
pimpl->Parallel(&Module::stopReceiver, {});
pimpl->Parallel3(&Receiver::stop);
}
void Detector::startDetector() {
@ -446,23 +495,57 @@ void Detector::startDetector() {
}
void Detector::stopDetector() {
// get status before stopping acquisition
defs::runStatus s = defs::ERROR, r = defs::ERROR;
bool restreamStop = false;
if (pimpl->isReceiverInitialized(1) && getRxZmqDataStream().squash(true)) {
s = getDetectorStatus().squash(defs::ERROR);
r = getReceiverStatus().squash(defs::ERROR);
// if rxr streaming and acquisition finished, restream dummy stop packet
if (s == defs::IDLE && r == defs::IDLE) {
restreamStop = true;
}
}
pimpl->Parallel(&Module::stopAcquisition, {});
if (pimpl->isReceiverInitialized(1)) {
pimpl->Parallel1(&Receiver::setStoppedFlag, {}, {});
if (restreamStop) {
pimpl->Parallel1(&Receiver::restreamStop, {}, {});
}
} else if (pimpl->isReceiverInitialized(2)) {
pimpl->Parallel2(&Receiver::setStoppedFlag, {}, {});
if (restreamStop) {
pimpl->Parallel2(&Receiver::restreamStop, {}, {});
}
}
}
Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {
return pimpl->Parallel(&Module::getRunStatus, pos);
}
Result<defs::runStatus> Detector::getReceiverStatus(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStatus, pos);
Result<defs::runStatus> Detector::getReceiverStatus() const {
return pimpl->Parallel3(&Receiver::getStatus);
}
Result<int64_t> Detector::getFramesCaught(Positions pos) const {
return pimpl->Parallel(&Module::getFramesCaughtByReceiver, pos);
Result<defs::runStatus> Detector::getReceiverStatus(const int udpInterface, Positions pos) const {
switch (udpInterface) {
case 1:
return pimpl->Parallel1(&Receiver::getStatus, pos, {});
case 2:
return pimpl->Parallel2(&Receiver::getStatus, pos, {});
default:
throw RuntimeError("Invalid udp interface number " +
std::to_string(udpInterface));
}
}
Result<std::vector<uint64_t>> Detector::getNumMissingPackets(Positions pos) const {
return pimpl->Parallel(&Module::getNumMissingPackets, pos);
Result<uint64_t> Detector::getFramesCaught(Positions pos) const {
return pimpl->Parallel3(&Receiver::getFramesCaught);
}
Result<uint64_t> Detector::getNumMissingPackets(Positions pos) const {
return pimpl->Parallel3(&Receiver::getNumMissingPackets);
}
Result<uint64_t> Detector::getStartingFrameNumber(Positions pos) const {
@ -553,6 +636,8 @@ Result<IpAddr> Detector::getDestinationUDPIP(Positions pos) const {
void Detector::setDestinationUDPIP(const IpAddr ip, Positions pos) {
pimpl->Parallel(&Module::setDestinationUDPIP, pos, ip);
auto mac = pimpl->Parallel1(&Receiver::setUDPIP, pos, {}, ip).squash();
setDestinationUDPMAC(mac, pos);
}
Result<IpAddr> Detector::getDestinationUDPIP2(Positions pos) const {
@ -561,6 +646,8 @@ Result<IpAddr> Detector::getDestinationUDPIP2(Positions pos) const {
void Detector::setDestinationUDPIP2(const IpAddr ip, Positions pos) {
pimpl->Parallel(&Module::setDestinationUDPIP2, pos, ip);
auto mac = pimpl->Parallel2(&Receiver::setUDPIP, pos, {}, ip).squash();
setDestinationUDPMAC2(mac, pos);
}
Result<MacAddr> Detector::getDestinationUDPMAC(Positions pos) const {
@ -585,13 +672,14 @@ Result<int> Detector::getDestinationUDPPort(Positions pos) const {
void Detector::setDestinationUDPPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setDestinationUDPPort, {idet},
port_list[idet]);
for (int iModule = 0; iModule < size(); ++iModule) {
pimpl->Parallel(&Module::setDestinationUDPPort, {iModule}, port);
pimpl->Parallel1(&Receiver::setUDPPort, {iModule}, {}, port);
++port;
}
} else {
pimpl->Parallel(&Module::setDestinationUDPPort, {module_id}, port);
pimpl->Parallel1(&Receiver::setUDPPort, {module_id}, {}, port);
}
}
@ -601,28 +689,28 @@ Result<int> Detector::getDestinationUDPPort2(Positions pos) const {
void Detector::setDestinationUDPPort2(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setDestinationUDPPort2, {idet},
port_list[idet]);
for (int iModule = 0; iModule < size(); ++iModule) {
pimpl->Parallel(&Module::setDestinationUDPPort2, {iModule}, port++);
pimpl->Parallel2(&Receiver::setUDPPort, {iModule}, {}, port);
++port;
}
} else {
pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id},
port);
pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id}, port);
pimpl->Parallel2(&Receiver::setUDPPort, {module_id}, {}, port);
}
}
Result<std::string> Detector::printRxConfiguration(Positions pos) const {
return pimpl->Parallel(&Module::printReceiverConfiguration, pos);
return pimpl->Parallel(&Module::printUDPConfiguration, pos);
}
Result<bool> Detector::getTenGiga(Positions pos) const {
return pimpl->Parallel(&Module::enableTenGigabitEthernet, pos, -1);
return pimpl->Parallel(&Module::getTenGiga, pos);
}
void Detector::setTenGiga(bool value, Positions pos) {
pimpl->Parallel(&Module::enableTenGigabitEthernet, pos,
static_cast<int>(value));
pimpl->Parallel(&Module::setTenGiga, pos, value);
pimpl->Parallel3(&Receiver::setTenGiga, value);
}
Result<bool> Detector::getTenGigaFlowControl(Positions pos) const {
@ -659,230 +747,235 @@ void Detector::setTransmissionDelayRight(int value, Positions pos) {
// Receiver
void Detector::removeReceivers(const int udpInterface) {
pimpl->removeReceivers(udpInterface);
}
Result<bool> Detector::getUseReceiverFlag(Positions pos) const {
return pimpl->Parallel(&Module::getUseReceiverFlag, pos);
return (pimpl->isReceiverInitialized(1) || pimpl->isReceiverInitialized(2));
}
Result<std::string> Detector::getRxHostname(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverHostname, pos);
Result<std::string> Detector::getRxHostname(const int udpInterface, Positions pos) const {
return pimpl->getRxHostname(pos, udpInterface);
}
void Detector::setRxHostname(const std::string &receiver, Positions pos) {
pimpl->Parallel(&Module::setReceiverHostname, pos, receiver);
void Detector::setRxHostname(const int udpInterface, const std::string &hostname, Positions pos) {
pimpl->configureReceiver(udpInterface, pos, hostname);
}
void Detector::setRxHostname(const std::vector<std::string> &name) {
// set all to same rx_hostname
if (name.size() == 1) {
pimpl->Parallel(&Module::setReceiverHostname, {}, name[0]);
} else {
if ((int)name.size() != size()) {
throw RuntimeError("Receiver hostnames size " +
std::to_string(name.size()) + " does not match detector size " +
std::to_string(size()));
}
// set each rx_hostname
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet]);
}
void Detector::setRxHostname(const int udpInterface, const std::string &hostname, const int port,
int module_id) {
if (module_id == -1 && size() > 1) {
throw sls::RuntimeError("Cannot set same rx_tcpport and rx_hostname for multiple receivers");
}
pimpl->configureReceiver(udpInterface, module_id, hostname, port);
}
Result<int> Detector::getRxPort(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverPort, pos);
Result<int> Detector::getRxPort(const int udpInterface, Positions pos) const {
return pimpl->getRxPort(pos, udpInterface);
}
void Detector::setRxPort(int port, int module_id) {
void Detector::setRxPort(const int udpInterface, int port, int module_id) {
if (!pimpl->isReceiverInitialized(udpInterface)) {
pimpl->initReceiver(udpInterface);
}
// return pimpl->setRxPort();
if (udpInterface == 1) {
if (module_id == -1) {
std::vector<int> port_list(size());
for (auto &it : port_list) {
it = port++;
}
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverPort, {idet},
port_list[idet]);
pimpl->Parallel1(&Receiver::setTCPPort, {idet}, {},
port++);
}
} else {
pimpl->Parallel(&Module::setReceiverPort, {module_id}, port);
pimpl->Parallel1(&Receiver::setTCPPort, {module_id}, {}, port);
}
} else {
if (module_id == -1) {
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel2(&Receiver::setTCPPort, {idet}, {},
port++);
}
} else {
pimpl->Parallel2(&Receiver::setTCPPort, {module_id}, {}, port);
}
}
}
Result<int> Detector::getRxFifoDepth(Positions pos) const {
return pimpl->Parallel(&Module::setReceiverFifoDepth, pos, -1);
return pimpl->Parallel3(&Receiver::getFifoDepth);
}
void Detector::setRxFifoDepth(int nframes, Positions pos) {
pimpl->Parallel(&Module::setReceiverFifoDepth, pos, nframes);
pimpl->Parallel3(&Receiver::setFifoDepth, nframes);
}
Result<bool> Detector::getRxSilentMode(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverSilentMode, pos);
return pimpl->Parallel3(&Receiver::getSilentMode);
}
void Detector::setRxSilentMode(bool value, Positions pos) {
pimpl->Parallel(&Module::setReceiverSilentMode, pos, value);
pimpl->Parallel3(&Receiver::setSilentMode, value);
}
Result<defs::frameDiscardPolicy>
Detector::getRxFrameDiscardPolicy(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverFramesDiscardPolicy, pos);
return pimpl->Parallel3(&Receiver::getFramesDiscardPolicy);
}
void Detector::setRxFrameDiscardPolicy(defs::frameDiscardPolicy f,
Positions pos) {
pimpl->Parallel(&Module::setReceiverFramesDiscardPolicy, pos, f);
pimpl->Parallel3(&Receiver::setFramesDiscardPolicy, f);
}
Result<bool> Detector::getPartialFramesPadding(Positions pos) const {
return pimpl->Parallel(&Module::getPartialFramesPadding, pos);
return pimpl->Parallel3(&Receiver::getPartialFramesPadding);
}
void Detector::setPartialFramesPadding(bool value, Positions pos) {
pimpl->Parallel(&Module::setPartialFramesPadding, pos, value);
pimpl->Parallel3(&Receiver::setPartialFramesPadding, value);
}
Result<int64_t> Detector::getRxUDPSocketBufferSize(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverUDPSocketBufferSize, pos);
return pimpl->Parallel3(&Receiver::getUDPSocketBufferSize);
}
void Detector::setRxUDPSocketBufferSize(int64_t udpsockbufsize, Positions pos) {
pimpl->Parallel(&Module::setReceiverUDPSocketBufferSize, pos,
pimpl->Parallel3(&Receiver::setUDPSocketBufferSize,
udpsockbufsize);
}
Result<int64_t> Detector::getRxRealUDPSocketBufferSize(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverRealUDPSocketBufferSize,
pos);
return pimpl->Parallel3(&Receiver::getRealUDPSocketBufferSize);
}
Result<bool> Detector::getRxLock(Positions pos) {
return pimpl->Parallel(&Module::lockReceiver, pos, -1);
return pimpl->Parallel3(&Receiver::getLock);
}
void Detector::setRxLock(bool value, Positions pos) {
pimpl->Parallel(&Module::lockReceiver, pos, static_cast<int>(value));
pimpl->Parallel3(&Receiver::setLock, value);
}
Result<sls::IpAddr> Detector::getRxLastClientIP(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverLastClientIP, pos);
return pimpl->Parallel3(&Receiver::getLastClientIP);
}
// File
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {
return pimpl->Parallel(&Module::getFileFormat, pos);
return pimpl->Parallel3(&Receiver::getFileFormat);
}
void Detector::setFileFormat(defs::fileFormat f, Positions pos) {
pimpl->Parallel(&Module::setFileFormat, pos, f);
pimpl->Parallel3(&Receiver::setFileFormat, f);
}
Result<std::string> Detector::getFilePath(Positions pos) const {
return pimpl->Parallel(&Module::getFilePath, pos);
return pimpl->Parallel3(&Receiver::getFilePath);
}
void Detector::setFilePath(const std::string &fpath, Positions pos) {
pimpl->Parallel(&Module::setFilePath, pos, fpath);
pimpl->Parallel3(&Receiver::setFilePath, fpath);
}
Result<std::string> Detector::getFileNamePrefix(Positions pos) const {
return pimpl->Parallel(&Module::getFileName, pos);
return pimpl->Parallel3(&Receiver::getFileName);
}
void Detector::setFileNamePrefix(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::setFileName, pos, fname);
pimpl->Parallel3(&Receiver::setFileName, fname);
}
Result<int64_t> Detector::getAcquisitionIndex(Positions pos) const {
return pimpl->Parallel(&Module::getFileIndex, pos);
return pimpl->Parallel3(&Receiver::getFileIndex);
}
void Detector::setAcquisitionIndex(int64_t i, Positions pos) {
pimpl->Parallel(&Module::setFileIndex, pos, i);
pimpl->Parallel3(&Receiver::setFileIndex, i);
}
Result<bool> Detector::getFileWrite(Positions pos) const {
return pimpl->Parallel(&Module::getFileWrite, pos);
return pimpl->Parallel3(&Receiver::getFileWrite);
}
void Detector::setFileWrite(bool value, Positions pos) {
pimpl->Parallel(&Module::setFileWrite, pos, value);
pimpl->Parallel3(&Receiver::setFileWrite, value);
}
void Detector::setMasterFileWrite(bool value, Positions pos) {
pimpl->Parallel(&Module::setMasterFileWrite, pos, value);
pimpl->Parallel3(&Receiver::setMasterFileWrite, value);
}
Result<bool> Detector::getMasterFileWrite(Positions pos) const {
return pimpl->Parallel(&Module::getMasterFileWrite, pos);
return pimpl->Parallel3(&Receiver::getMasterFileWrite);
}
Result<bool> Detector::getFileOverWrite(Positions pos) const {
return pimpl->Parallel(&Module::getFileOverWrite, pos);
return pimpl->Parallel3(&Receiver::getFileOverWrite);
}
void Detector::setFileOverWrite(bool value, Positions pos) {
pimpl->Parallel(&Module::setFileOverWrite, pos, value);
pimpl->Parallel3(&Receiver::setFileOverWrite, value);
}
Result<int> Detector::getFramesPerFile(Positions pos) const {
return pimpl->Parallel(&Module::getFramesPerFile, pos);
return pimpl->Parallel3(&Receiver::getFramesPerFile);
}
void Detector::setFramesPerFile(int n, Positions pos) {
pimpl->Parallel(&Module::setFramesPerFile, pos, n);
pimpl->Parallel3(&Receiver::setFramesPerFile, n);
}
// Zmq Streaming (Receiver<->Client)
Result<bool> Detector::getRxZmqDataStream(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreaming, pos);
return pimpl->Parallel3(&Receiver::getZmq);
}
void Detector::setRxZmqDataStream(bool value, Positions pos) {
pimpl->Parallel(&Module::setReceiverStreaming, pos, value);
pimpl->Parallel3(&Receiver::setZmq, value);
}
Result<int> Detector::getRxZmqFrequency(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingFrequency, pos);
return pimpl->Parallel3(&Receiver::getZmqFrequency);
}
void Detector::setRxZmqFrequency(int freq, Positions pos) {
pimpl->Parallel(&Module::setReceiverStreamingFrequency, pos, freq);
pimpl->Parallel3(&Receiver::setZmqFrequency, freq);
}
Result<int> Detector::getRxZmqTimer(Positions pos) const {
return pimpl->Parallel(&Module::setReceiverStreamingTimer, pos, -1);
return pimpl->Parallel3(&Receiver::getZmqTimer);
}
void Detector::setRxZmqTimer(int time_in_ms, Positions pos) {
pimpl->Parallel(&Module::setReceiverStreamingTimer, pos, time_in_ms);
pimpl->Parallel3(&Receiver::setZmqTimer, time_in_ms);
}
Result<int> Detector::getRxZmqPort(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingPort, pos);
return pimpl->Parallel1(&Receiver::getZmqPort, pos, {});
}
void Detector::setRxZmqPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverStreamingPort, {idet},
port_list[idet]);
pimpl->Parallel1(&Receiver::setZmqPort, {idet},
{}, port++);
}
} else {
pimpl->Parallel(&Module::setReceiverStreamingPort, {module_id},
port);
pimpl->Parallel1(&Receiver::setZmqPort, {module_id},
{}, port++);
}
}
Result<IpAddr> Detector::getRxZmqIP(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingIP, pos);
return pimpl->Parallel3(&Receiver::getZmqIP);
}
void Detector::setRxZmqIP(const IpAddr ip, Positions pos) {
bool previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(false);
pimpl->Parallel(&Module::setReceiverStreamingIP, pos, ip);
pimpl->Parallel3(&Receiver::setZmqIP, ip);
if (previouslyReceiverStreaming) {
setRxZmqDataStream(false, pos);
setRxZmqDataStream(true, pos);
@ -890,29 +983,28 @@ void Detector::setRxZmqIP(const IpAddr ip, Positions pos) {
}
Result<int> Detector::getClientZmqPort(Positions pos) const {
return pimpl->Parallel(&Module::getClientStreamingPort, pos);
return pimpl->Parallel1(&Receiver::getClientZmqPort, pos, {});
}
void Detector::setClientZmqPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setClientStreamingPort, {idet},
port_list[idet]);
pimpl->Parallel1(&Receiver::setClientZmqPort, {idet},
{}, port++);
}
} else {
pimpl->Parallel(&Module::setClientStreamingPort, {module_id},
port);
pimpl->Parallel1(&Receiver::setClientZmqPort, {module_id},
{}, port);// FIXME: Needs a clientzmqport2
}
}
Result<IpAddr> Detector::getClientZmqIp(Positions pos) const {
return pimpl->Parallel(&Module::getClientStreamingIP, pos);
return pimpl->Parallel3(&Receiver::getClientZmqIP);
}
void Detector::setClientZmqIp(const IpAddr ip, Positions pos) {
int previouslyClientStreaming = pimpl->enableDataStreamingToClient(-1);
pimpl->Parallel(&Module::setClientStreamingIP, pos, ip);
pimpl->Parallel3(&Receiver::setClientZmqIP, ip);
if (previouslyClientStreaming != 0) {
pimpl->enableDataStreamingToClient(0);
pimpl->enableDataStreamingToClient(1);
@ -926,7 +1018,29 @@ Result<int> Detector::getDynamicRange(Positions pos) const {
}
void Detector::setDynamicRange(int value) {
bool change = false;
int prevVal = value;
if (getDetectorType().squash() == defs::EIGER) {
prevVal = getDynamicRange().squash();
if (prevVal != value) {
change = true;
}
}
pimpl->Parallel(&Module::setDynamicRange, {}, value);
pimpl->Parallel3(&Receiver::setDynamicRange, value);
if (change) {
// update speed for usability
if (value == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
"Dynamic Range of 32";
setSpeed(defs::QUARTER_SPEED);
} else if (prevVal == 32) {
LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range "
"of " << value;
setSpeed(defs::FULL_SPEED);
}
pimpl->Parallel(&Module::updateRateCorrection, {});
}
}
Result<ns> Detector::getSubExptime(Positions pos) const {
@ -934,7 +1048,18 @@ Result<ns> Detector::getSubExptime(Positions pos) const {
}
void Detector::setSubExptime(ns t, Positions pos) {
bool change = false;
if (getDetectorType().squash() == defs::EIGER) {
ns prevVal = getSubExptime(pos).squash();
if (prevVal != t) {
change = true;
}
}
pimpl->Parallel(&Module::setSubExptime, pos, t.count());
pimpl->Parallel3(&Receiver::setSubExptime, t.count());
if (change) {
pimpl->Parallel(&Module::updateRateCorrection, pos);
}
}
Result<ns> Detector::getSubDeadTime(Positions pos) const {
@ -943,15 +1068,34 @@ Result<ns> Detector::getSubDeadTime(Positions pos) const {
void Detector::setSubDeadTime(ns value, Positions pos) {
pimpl->Parallel(&Module::setSubDeadTime, pos, value.count());
pimpl->Parallel3(&Receiver::setSubDeadTime, value.count());
}
Result<int> Detector::getThresholdEnergy(Positions pos) const {
if (getDetectorType().squash() == defs::MOENCH) {
auto res = getAdditionalJsonParameter("threshold", pos);
Result<int> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
intResult[i] = stoi(res[i]);
}
} catch (...) {
throw RuntimeError(
"Cannot find or convert threshold string to integer");
}
return intResult;
}
return pimpl->Parallel(&Module::getThresholdEnergy, pos);
}
void Detector::setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
if (getDetectorType().squash() == defs::MOENCH) {
setAdditionalJsonParameter("threshold",
std::to_string(threshold_ev), pos);
}
pimpl->Parallel(&Module::setThresholdEnergy, pos, threshold_ev,
settings, static_cast<int>(trimbits));
}
@ -993,11 +1137,11 @@ void Detector::setStoreInRamMode(bool value, Positions pos) {
}
Result<bool> Detector::getBottom(Positions pos) const {
return pimpl->Parallel(&Module::getFlippedDataX, pos);
return pimpl->Parallel3(&Receiver::getFlippedDataX);
}
void Detector::setBottom(bool value, Positions pos) {
pimpl->Parallel(&Module::setFlippedDataX, pos, value);
pimpl->Parallel3(&Receiver::setFlippedDataX, value);
}
Result<int> Detector::getAllTrimbits(Positions pos) const {
@ -1034,6 +1178,7 @@ Result<int> Detector::getPartialReadout(Positions pos) const {
void Detector::setPartialReadout(const int lines, Positions pos) {
pimpl->Parallel(&Module::setReadNLines, pos, lines);
pimpl->Parallel3(&Receiver::setReadNLines, lines);
}
Result<bool> Detector::getInterruptSubframe(Positions pos) const {
@ -1053,19 +1198,20 @@ Result<ns> Detector::getMeasuredSubFramePeriod(Positions pos) const {
}
Result<bool> Detector::getActive(Positions pos) const {
return pimpl->Parallel(&Module::activate, pos, -1);
return pimpl->Parallel(&Module::getActivate, pos);
}
void Detector::setActive(bool active, Positions pos) {
pimpl->Parallel(&Module::activate, pos, static_cast<int>(active));
pimpl->Parallel(&Module::setActivate, pos, active);
pimpl->Parallel3(&Receiver::setActivate, active);
}
Result<bool> Detector::getRxPadDeactivatedMode(Positions pos) const {
return pimpl->Parallel(&Module::getDeactivatedRxrPaddingMode, pos);
return pimpl->Parallel3(&Receiver::getDeactivatedPaddingMode);
}
void Detector::setRxPadDeactivatedMode(bool pad, Positions pos) {
pimpl->Parallel(&Module::setDeactivatedRxrPaddingMode, pos, pad);
pimpl->Parallel3(&Receiver::setDeactivatedPaddingMode, pad);
}
Result<bool> Detector::getPartialReset(Positions pos) const {
@ -1103,6 +1249,7 @@ void Detector::setQuad(const bool enable) {
"Eiger Quad Half module.");
}
pimpl->Parallel(&Module::setQuad, {}, enable);
pimpl->Parallel3(&Receiver::setQuad, enable); //FIXME
}
// Jungfrau Specific
@ -1180,11 +1327,16 @@ void Detector::setROI(defs::ROI value, int module_id) {
if (module_id < 0 && size() > 1) {
throw RuntimeError("Cannot set ROI for all modules simultaneously");
}
if (value.xmin < 0 || value.xmax >= getModuleSize({module_id})[0].x) {
throw RuntimeError("roi arguments out of range");
}
pimpl->Parallel(&Module::setROI, {module_id}, value);
pimpl->Parallel3(&Receiver::setROI, value);
}
void Detector::clearROI(Positions pos) {
pimpl->Parallel(&Module::clearROI, pos);
pimpl->Parallel3(&Receiver::clearROI);
}
Result<ns> Detector::getExptimeLeft(Positions pos) const {
@ -1210,6 +1362,7 @@ Result<int64_t> Detector::getNumberOfBursts(Positions pos) const {
void Detector::setNumberOfBursts(int64_t value) {
pimpl->Parallel(&Module::setNumberOfBursts, {}, value);
pimpl->Parallel3(&Receiver::setNumberOfBursts, value);
}
Result<ns> Detector::getBurstPeriod(Positions pos) const {
@ -1246,6 +1399,7 @@ Result<defs::burstMode> Detector::getBurstMode(Positions pos) {
void Detector::setBurstMode(defs::burstMode value, Positions pos) {
pimpl->Parallel(&Module::setBurstMode, pos, value);
pimpl->Parallel3(&Receiver::setBurstMode, value);
}
Result<bool> Detector::getCurrentSource(Positions pos) const {
@ -1272,6 +1426,7 @@ Result<uint32_t> Detector::getCounterMask(Positions pos) const {
void Detector::setCounterMask(uint32_t countermask, Positions pos) {
pimpl->Parallel(&Module::setCounterMask, pos, countermask);
pimpl->Parallel3(&Receiver::setCounterMask, countermask);
}
// CTB/ Moench Specific
@ -1282,6 +1437,7 @@ Result<int> Detector::getNumberOfAnalogSamples(Positions pos) const {
void Detector::setNumberOfAnalogSamples(int value, Positions pos) {
pimpl->Parallel(&Module::setNumberOfAnalogSamples, pos, value);
pimpl->Parallel3(&Receiver::setNumberOfAnalogSamples, value);
}
@ -1359,7 +1515,11 @@ Result<uint32_t> Detector::getADCEnableMask(Positions pos) const {
}
void Detector::setADCEnableMask(uint32_t mask, Positions pos) {
if (getDetectorType().squash() == defs::MOENCH) {
setAdditionalJsonParameter("adcmask_1g", std::to_string(mask), pos);
}
pimpl->Parallel(&Module::setADCEnableMask, pos, mask);
pimpl->Parallel3(&Receiver::setADCEnableMask, mask);
}
Result<uint32_t> Detector::getTenGigaADCEnableMask(Positions pos) const {
@ -1367,7 +1527,11 @@ Result<uint32_t> Detector::getTenGigaADCEnableMask(Positions pos) const {
}
void Detector::setTenGigaADCEnableMask(uint32_t mask, Positions pos) {
if (getDetectorType().squash() == defs::MOENCH) {
setAdditionalJsonParameter("adcmask_10g", std::to_string(mask), pos);
}
pimpl->Parallel(&Module::setTenGigaADCEnableMask, pos, mask);
pimpl->Parallel3(&Receiver::setTenGigaADCEnableMask, mask);
}
// CTB Specific
@ -1379,6 +1543,7 @@ Result<int> Detector::getNumberOfDigitalSamples(Positions pos) const {
void Detector::setNumberOfDigitalSamples(int value, Positions pos) {
pimpl->Parallel(&Module::setNumberOfDigitalSamples, pos, value);
pimpl->Parallel3(&Receiver::setNumberOfDigitalSamples, value);
}
Result<defs::readoutMode> Detector::getReadoutMode(Positions pos) const {
@ -1387,6 +1552,7 @@ Result<defs::readoutMode> Detector::getReadoutMode(Positions pos) const {
void Detector::setReadoutMode(defs::readoutMode value, Positions pos) {
pimpl->Parallel(&Module::setReadoutMode, pos, value);
pimpl->Parallel3(&Receiver::setReadoutMode, value);
}
Result<int> Detector::getDBITClock(Positions pos) const {
@ -1458,19 +1624,19 @@ void Detector::setExternalSampling(bool value, Positions pos) {
}
Result<std::vector<int>> Detector::getRxDbitList(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverDbitList, pos);
return pimpl->Parallel3(&Receiver::getDbitList);
}
void Detector::setRxDbitList(const std::vector<int>& list, Positions pos) {
pimpl->Parallel(&Module::setReceiverDbitList, pos, list);
pimpl->Parallel3(&Receiver::setDbitList, list);
}
Result<int> Detector::getRxDbitOffset(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverDbitOffset, pos);
return pimpl->Parallel3(&Receiver::getDbitOffset);
}
void Detector::setRxDbitOffset(int value, Positions pos) {
pimpl->Parallel(&Module::setReceiverDbitOffset, pos, value);
pimpl->Parallel3(&Receiver::setDbitOffset, value);
}
void Detector::setDigitalIODelay(uint64_t pinMask, int delay, Positions pos) {
@ -1612,28 +1778,27 @@ void Detector::setPatternBitMask(uint64_t mask, Positions pos) {
// Moench
Result<std::map<std::string, std::string>> Detector::getAdditionalJsonHeader(Positions pos) const {
return pimpl->Parallel(&Module::getAdditionalJsonHeader, pos);
return pimpl->Parallel3(&Receiver::getAdditionalJsonHeader);
}
void Detector::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader,
Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonHeader);
pimpl->Parallel3(&Receiver::setAdditionalJsonHeader, jsonHeader);
}
Result<std::string> Detector::getAdditionalJsonParameter(const std::string &key,
Positions pos) const {
return pimpl->Parallel(&Module::getAdditionalJsonParameter, pos, key);
return pimpl->Parallel3(&Receiver::getAdditionalJsonParameter, key);
}
void Detector::setAdditionalJsonParameter(const std::string &key, const std::string &value,
Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, key, value);
pimpl->Parallel3(&Receiver::setAdditionalJsonParameter, key, value);
}
Result<int> Detector::getDetectorMinMaxEnergyThreshold(const bool isEmax,
Positions pos) const {
auto res = pimpl->Parallel(&Module::getAdditionalJsonParameter, pos,
isEmax ? "emax" : "emin");
auto res = getAdditionalJsonParameter(isEmax ? "emax" : "emin", pos);
Result<int> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
@ -1649,13 +1814,12 @@ Result<int> Detector::getDetectorMinMaxEnergyThreshold(const bool isEmax,
void Detector::setDetectorMinMaxEnergyThreshold(const bool isEmax,
const int value,
Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos,
isEmax ? "emax" : "emin", std::to_string(value));
setAdditionalJsonParameter(isEmax ? "emax" : "emin",
std::to_string(value), pos);
}
Result<defs::frameModeType> Detector::getFrameMode(Positions pos) const {
auto res = pimpl->Parallel(&Module::getAdditionalJsonParameter, pos,
"frameMode");
auto res = getAdditionalJsonParameter("frameMode", pos);
Result<defs::frameModeType> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
@ -1670,13 +1834,11 @@ Result<defs::frameModeType> Detector::getFrameMode(Positions pos) const {
}
void Detector::setFrameMode(defs::frameModeType value, Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, "frameMode",
sls::ToString(value));
setAdditionalJsonParameter("frameMode", sls::ToString(value), pos);
}
Result<defs::detectorModeType> Detector::getDetectorMode(Positions pos) const {
auto res = pimpl->Parallel(&Module::getAdditionalJsonParameter, pos,
"detectorMode");
auto res = getAdditionalJsonParameter("detectorMode", pos);
Result<defs::detectorModeType> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
@ -1691,8 +1853,7 @@ Result<defs::detectorModeType> Detector::getDetectorMode(Positions pos) const {
}
void Detector::setDetectorMode(defs::detectorModeType value, Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos,
"detectorMode", sls::ToString(value));
setAdditionalJsonParameter("detectorMode", sls::ToString(value), pos);
}
// Advanced
@ -1818,29 +1979,7 @@ Result<ns> Detector::getMeasurementTime(Positions pos) const {
std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); }
Result<uint64_t> Detector::getRxCurrentFrameIndex(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverCurrentFrameIndex, pos);
}
std::vector<int> Detector::getPortNumbers(int start_port) {
int num_sockets_per_detector = 1;
switch (getDetectorType().squash()) {
case defs::EIGER:
num_sockets_per_detector *= 2;
break;
case defs::JUNGFRAU:
if (getNumberofUDPInterfaces().squash() == 2) {
num_sockets_per_detector *= 2;
}
break;
default:
break;
}
std::vector<int> res;
res.reserve(size());
for (int idet = 0; idet < size(); ++idet) {
res.push_back(start_port + (idet * num_sockets_per_detector));
}
return res;
return pimpl->Parallel3(&Receiver::getCurrentFrameIndex);
}
} // namespace sls

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#pragma once
#include "Container3.h"
#include "Result.h"
#include "SharedMemory.h"
#include "logger.h"
@ -15,8 +15,8 @@ class detectorData;
#include <thread>
#include <vector>
#define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x200319
#define DETECTOR_SHMAPIVERSION 0x190809
#define DETECTOR_SHMVERSION 0x200319
#define SHORT_STRING_LENGTH 50
#include <future>
@ -25,12 +25,13 @@ class detectorData;
namespace sls {
class Module;
class Receiver;
/**
* @short structure allocated in shared memory to store detector settings
* for IPC and cache
*/
struct sharedMultiSlsDetector {
struct sharedDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
* ------*/
@ -47,7 +48,7 @@ struct sharedMultiSlsDetector {
/** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH];
int numberOfDetectors;
int numberOfModules;
slsDetectorDefs::detectorType multiDetectorType;
/** END OF FIXED PATTERN
@ -68,12 +69,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
public:
/**
* Constructor
* @param id multi detector id
* @param detector_id multi detector id
* @param verify true to verify if shared memory version matches existing
* one
* @param update true to update last user pid, date etc
*/
explicit DetectorImpl(int multi_id = 0, bool verify = true,
explicit DetectorImpl(int detector_id = 0, bool verify = true,
bool update = true);
/**
@ -81,6 +82,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/
virtual ~DetectorImpl();
template <class CT> struct NonDeduced { using type = CT; };
template <typename RT, typename... CT>
sls::Result<RT> Parallel(RT (sls::Module::*somefunc)(CT...),
@ -188,17 +191,97 @@ class DetectorImpl : public virtual slsDetectorDefs {
}
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
return {};
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
return {};
}
template <typename... CT>
void Parallel1(void (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {}
template <typename... CT>
void Parallel1(void (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {}
template <typename RT, typename... CT>
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
return {};
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
return {};
}
template <typename... CT>
void Parallel2(void (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {}
template <typename... CT>
void Parallel2(void (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {}
// for all , but dont complain if receiver2 doesnt exist
template <typename RT, typename... CT>
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
return {};
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
return {};
}
template <typename... CT>
void Parallel3(void (sls::Receiver::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {}
template <typename... CT>
void Parallel3(void (sls::Receiver::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {}
/** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag);
/** return multi detector shared memory ID */
int getMultiId() const;
/** return detector shared memory ID */
int getDetectorId() const;
/** Free specific shared memory from the command line without creating object */
static void freeSharedMemory(int multiId, int detPos = -1);
/** Free specific shared memory from the command line without creating
* object */
static void freeSharedMemory(int detectorId, int moduleId = -1);
/** Free all modules from current multi Id shared memory and delete members */
/** Free all modules from current multi Id shared memory and delete members
*/
void freeSharedMemory();
/** Get user details of shared memory */
@ -217,8 +300,21 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/
void setVirtualDetectorServers(const int numdet, const int port);
/** Sets the hostname of all sls detectors in shared memory and updates local cache */
void setHostname(const std::vector<std::string> &name);
void setHostname(const std::vector<std::string> &name,
const std::vector<int> &port);
Result<std::string> getRxHostname(Positions pos, int udpInterface);
Result<int> getRxPort(Positions pos, int udpInterface);
int getNumberofReceiversPerModule() const;
void initReceiver(const int udpInterface);
bool isReceiverInitialized(const int udpInterface);
void removeReceivers(const int udpInterface);
void configureReceiver(const int udpInterface, Positions pos,
const std::string &hostname);
void configureReceiver(const int udpInterface, int module_id,
const std::string &hostname, const int port);
/** Gets the total number of detectors */
int size() const;
@ -298,7 +394,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
* one
* @param update true to update last user pid, date etc
*/
void setupMultiDetector(bool verify = true, bool update = true);
void setupDetector(bool verify = true, bool update = true);
/**
* Creates shm and initializes shm structure OR
@ -324,7 +420,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** Execute command in terminal and return result */
std::string exec(const char *cmd);
void addSlsDetector(const std::string &hostname);
void addModule(const std::string &hostname, const int port);
void updateDetectorSize();
@ -377,14 +473,23 @@ class DetectorImpl : public virtual slsDetectorDefs {
int kbhit();
/** Multi detector Id */
const int multiId{0};
const int detectorId{0};
/** Shared Memory object */
sls::SharedMemory<sharedMultiSlsDetector> multi_shm{0, -1};
sls::SharedMemory<sharedDetector> detector_shm{0, -1};
/** pointers to the Module structures */
std::vector<std::unique_ptr<sls::Module>> detectors;
/** pointers to the Receiver structures, each row for a module */
// std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers;
/** for the second udp port [Eiger][Jungfrau] */
std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers2;
sls::Container3<std::unique_ptr<sls::Receiver>> receivers;
// sls::Container3<Receiver> receivers;
/** data streaming (down stream) enabled in client (zmq sckets created) */
bool client_downstream{false};

View File

@ -0,0 +1,59 @@
#pragma once
#include "Container3.h"
#include <initializer_list>
#include <vector>
namespace sls{
class MaskGenerator {
enum class OperationMode { ALL, ROW, SINGLE };
OperationMode mode_{OperationMode::ALL};
std::vector<int> idx0; // hack
size_t x_{0};
size_t y_{0};
size_t z_{0};
public:
MaskGenerator(){};
explicit MaskGenerator(size_t i) : mode_(OperationMode::SINGLE), x_(i) {}
MaskGenerator(size_t i, size_t j)
: mode_(OperationMode::SINGLE), x_(i), y_(j) {}
MaskGenerator(size_t i, size_t j, size_t k)
: mode_(OperationMode::SINGLE), x_(i), y_(j), z_(k) {}
explicit MaskGenerator(const std::vector<int> vec)
: mode_(OperationMode::ROW), idx0(vec) {}
explicit MaskGenerator(const std::vector<int> vec, size_t y)
: mode_(OperationMode::ROW), idx0(vec), y_(y) {}
template <typename T> Container3<bool> mask(const Container3<T>& cont) {
return mask(cont.shape());
}
Container3<bool> mask(std::array<size_t, 3> shape) {
Container3<bool> m(shape);
if (idx0.size()== 1 && idx0[0] == -1){
idx0.resize(m.size(0));
std::iota(begin(idx0), end(idx0), 0);
}
switch (mode_) {
case OperationMode::ALL:
for (auto &item : m)
item = true;
break;
case OperationMode::ROW:
for (auto i : idx0) {
m(i, 0, 0) = true;
}
break;
case OperationMode::SINGLE:
m(x_, y_, z_) = true;
break;
}
return m;
}
Container3<bool> mask() { return {}; }
};
} // namespace sls

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,9 @@
class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726
#define SLS_SHMVERSION 0x200402
#define MODULE_SHMRXVERSION 0x200415
#define MODULE_SHMAPIVERSION 0x190726
#define MODULE_SHMVERSION 0x200423
namespace sls{
@ -22,7 +23,7 @@ namespace sls{
* @short structure allocated in shared memory to store detector settings for
* IPC and cache
*/
struct sharedSlsDetector {
struct sharedModule {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
@ -36,10 +37,13 @@ struct sharedSlsDetector {
/** detector type \ see :: detectorType*/
slsDetectorDefs::detectorType myDetectorType;
int numberOfReceivers;
int numberOfReceivers2;
/** END OF FIXED PATTERN -----------------------------------------------*/
/** Number of detectors in multi list in x dir and y dir */
slsDetectorDefs::xy multiSize;
slsDetectorDefs::xy detectorSize;
/** is the port used for control functions */
int controlPort;
@ -62,27 +66,8 @@ struct sharedSlsDetector {
/** number of dacs per module*/
int nDacs;
/** ip address/hostname of the receiver for client control via TCP */
char rxHostname[MAX_STR_LENGTH];
/** is the TCP port used to communicate between client and the receiver */
int rxTCPPort;
/** is set if the receiver hostname given and is connected,
* unset if socket connection is not possible */
bool useReceiverFlag;
/** tcp port from gui/different process to receiver (only data) */
int zmqport;
/** zmq tcp src ip address in client (only data) **/
sls::IpAddr zmqip;
/** num udp interfaces */
int numUDPInterfaces;
/** stopped flag to inform rxr */
bool stoppedFlag;
};
class Module : public virtual slsDetectorDefs {
@ -90,22 +75,22 @@ class Module : public virtual slsDetectorDefs {
/**
* Constructor called when creating new shared memory
* @param type detector type
* @param multi_id multi detector shared memory id
* @param id sls detector id (position in detectors list)
* @param detector_id multi detector shared memory id
* @param module_id module id (position in detectors list)
* @param verify true to verify if shared memory version matches existing
* one
*/
explicit Module(detectorType type, int multi_id = 0, int det_id = 0,
explicit Module(detectorType type, int detector_id = 0, int module_id = 0,
bool verify = true);
/**
* Constructor called when opening existing shared memory
* @param multi_id multi detector shared memory id
* @param id sls detector id (position in detectors list)
* @param detector_id multi detector shared memory id
* @param module_id module id (position in detectors list)
* @param verify true to verify if shared memory version matches existing
* one
*/
explicit Module(int multi_id = 0, int det_id = 0, bool verify = true);
explicit Module(int detector_id = 0, int module_id = 0, bool verify = true);
/**
* Destructor
@ -118,10 +103,12 @@ class Module : public virtual slsDetectorDefs {
*/
bool isFixedPatternSharedMemoryCompatible();
/**
* Check version compatibility with receiver software
*/
void checkReceiverVersionCompatibility();
static bool hasSharedMemoryReceiverList(int version);
int getNumberOfReceivers() const;
void setNumberOfReceivers(const int num);
int getNumberOfReceivers2() const;
void setNumberOfReceivers2(const int num);
/**
* Check version compatibility with detector software
@ -134,14 +121,9 @@ class Module : public virtual slsDetectorDefs {
int64_t getSerialNumber();
/**
* Get Receiver Software version
*/
int64_t getReceiverSoftwareVersion() const;
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedSlsDetector structure
* occupied by the sharedModule structure
* Is only safe to call if one deletes the Module object afterward
* and frees multi shared memory/updates
* thisMultiDetector->numberOfDetectors
@ -213,12 +195,12 @@ class Module : public virtual slsDetectorDefs {
* Set Detector offset in shared memory in dimension d
* @param det detector size
*/
void updateMultiSize(slsDetectorDefs::xy det);
void updateDetectorSize(slsDetectorDefs::xy det);
int setControlPort(int port_number);
/**
* Returns the detector TCP control port \sa sharedSlsDetector
* Returns the detector TCP control port
* @returns the detector TCP control port
*/
int getControlPort() const;
@ -226,19 +208,11 @@ class Module : public virtual slsDetectorDefs {
int setStopPort(int port_number);
/**
* Returns the detector TCP stop port \sa sharedSlsDetector
* Returns the detector TCP stop port
* @returns the detector TCP stop port
*/
int getStopPort() const;
int setReceiverPort(int port_number);
/**
* Returns the receiver TCP port \sa sharedSlsDetector
* @returns the receiver TCP port
*/
int getReceiverPort() const;
/**
* Lock server for this client IP
* @param p 0 to unlock, 1 to lock (-1 gets)
@ -306,13 +280,13 @@ class Module : public virtual slsDetectorDefs {
int tb = 1);
/**
* Returns the detector trimbit/settings directory \sa sharedSlsDetector
* Returns the detector trimbit/settings directory
* @returns the trimbit/settings directory
*/
std::string getSettingsDir();
/**
* Sets the detector trimbit/settings directory \sa sharedSlsDetector
* Sets the detector trimbit/settings directory
* @param s trimbits/settings directory
* @returns the trimbit/settings directory
*/
@ -634,21 +608,8 @@ class Module : public virtual slsDetectorDefs {
*/
uint32_t clearBit(uint32_t addr, int n);
/**
* Validates and sets the receiver.
* Also updates the receiver with all the shared memory parameters
* significant for the receiver Also configures the detector to the receiver
* as UDP destination
* @param receiver receiver hostname or IP address
*/
void setReceiverHostname(const std::string &receiver);
void test();
/**
* Returns the receiver IP address\sa sharedSlsDetector
* @returns the receiver IP address
*/
std::string getReceiverHostname() const;
/** gets receiver parameters from detector and shared memory */
rxParameters getReceiverParameters();
/**
* Validates the format of the detector MAC address and sets it
@ -755,26 +716,26 @@ class Module : public virtual slsDetectorDefs {
sls::MacAddr getDestinationUDPMAC2();
/**
* Sets the receiver UDP port\sa sharedSlsDetector
* Sets the receiver UDP port
* @param udpport receiver UDP port
*/
void setDestinationUDPPort(int udpport);
/**
* Returns the receiver UDP port\sa sharedSlsDetector
* Returns the receiver UDP port
* @returns the receiver UDP port
*/
int getDestinationUDPPort();
/**
* Sets the receiver UDP port 2\sa sharedSlsDetector (Eiger and Jungfrau
* Sets the receiver UDP port 2 (Eiger and Jungfrau
* only)
* @param udpport receiver UDP port 2
*/
void setDestinationUDPPort2(int udpport);
/**
* Returns the receiver UDP port 2 of same interface\sa sharedSlsDetector
* Returns the receiver UDP port 2 of same interface
* (Eiger and Jungfrau only)
* @returns the receiver UDP port 2 of same interface
*/
@ -813,53 +774,7 @@ class Module : public virtual slsDetectorDefs {
*/
int getSelectedUDPInterface();
/**
* Sets the client zmq port\sa sharedSlsDetector
* @param port client zmq port
*/
void setClientStreamingPort(int port);
/**
* Returns the client zmq port \sa sharedSlsDetector
* @returns the client zmq port
*/
int getClientStreamingPort();
/**
* Sets the receiver zmq port\sa sharedSlsDetector
* @param port receiver zmq port
*/
void setReceiverStreamingPort(int port);
/**
* Returns the receiver zmq port \sa sharedSlsDetector
* @returns the receiver zmq port
*/
int getReceiverStreamingPort();
/**
* Sets the client zmq ip\sa sharedSlsDetector
* @param ip client zmq ip
*/
void setClientStreamingIP(const sls::IpAddr ip);
/**
* Returns the client zmq ip \sa sharedSlsDetector
* @returns the client zmq ip
*/
sls::IpAddr getClientStreamingIP();
/**
* Sets the receiver zmq ip\sa sharedSlsDetector
* @param ip receiver zmq ip
*/
void setReceiverStreamingIP(const sls::IpAddr ip);
/**
* Returns the receiver zmq ip \sa sharedSlsDetector
* @returns the receiver zmq ip
*/
sls::IpAddr getReceiverStreamingIP();
std::string printUDPConfiguration();
/** update receiver stremaing ip from shm to receiver
* if empty, use rx_hostname ip
@ -903,35 +818,6 @@ class Module : public virtual slsDetectorDefs {
*/
void setTransmissionDelayRight(int value);
/** empty vector deletes entire additional json header */
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
std::map<std::string, std::string> getAdditionalJsonHeader();
/**
* Sets the value for the additional json header parameter key if found, else
* append it. If value empty, then deletes parameter */
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
std::string getAdditionalJsonParameter(const std::string &key);
/**
* Sets the receiver UDP socket buffer size
* @param udpsockbufsize additional json header
* @returns receiver udp socket buffer size
*/
int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1);
/**
* Returns the receiver UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver UDP socket buffer size
*/
int64_t getReceiverUDPSocketBufferSize();
/**
* Returns the receiver real UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver real UDP socket buffer size
*/
int64_t getReceiverRealUDPSocketBufferSize() const;
/** [Gotthard][Jungfrau][CTB][Moench] */
void executeFirmwareTest();
@ -1009,28 +895,10 @@ class Module : public virtual slsDetectorDefs {
*/
slsDetectorDefs::ROI getROI();
/**
* Set ADC Enable Mask (CTB, Moench)
* @param mask ADC Enable mask
*/
void setADCEnableMask(uint32_t mask);
/**
* Get ADC Enable Mask (CTB, Moench)
* @returns ADC Enable mask
*/
uint32_t getADCEnableMask();
/**
* Set 10Gb ADC Enable Mask (CTB, Moench)
* @param mask ADC Enable mask
*/
void setTenGigaADCEnableMask(uint32_t mask);
/**
* Get 10Gb ADC Enable Mask (CTB, Moench)
* @returns ADC Enable mask
*/
uint32_t getTenGigaADCEnableMask();
/**
@ -1077,14 +945,6 @@ class Module : public virtual slsDetectorDefs {
*/
int getExternalSampling();
/** digital data bits enable (CTB only) */
void setReceiverDbitList(const std::vector<int>& list);
std::vector<int> getReceiverDbitList() const;
/** Set digital data offset in bytes (CTB only) */
void setReceiverDbitOffset(int value);
int getReceiverDbitOffset();
/**
* Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert
* users
@ -1093,32 +953,10 @@ class Module : public virtual slsDetectorDefs {
*/
void writeAdcRegister(uint32_t addr, uint32_t val);
/**
* Activates/Deactivates the detector (Eiger only)
* @param enable active (1) or inactive (0), -1 gets
* @returns 0 (inactive) or 1 (active)for activate mode
*/
int activate(int const enable = -1);
bool getDeactivatedRxrPaddingMode();
/**
* Set deactivated Receiver padding mode (Eiger only)
*/
void setDeactivatedRxrPaddingMode(bool padding);
/**
* Returns the enable if data will be flipped across x axis (Eiger)
* @returns if flipped across x axis
*/
bool getFlippedDataX();
/**
* Sets the enable which determines if
* data will be flipped across x axis (Eiger)
* @param value 0 or 1 to reset/set
*/
void setFlippedDataX(bool value);
/** [Eiger] */
bool getActivate();
/** [Eiger] */
void setActivate(const bool enable);
/**
* Sets all the trimbits to a particular value (Eiger)
@ -1129,7 +967,6 @@ class Module : public virtual slsDetectorDefs {
/**
* Sets the number of trim energies and their value (Eiger)
* \sa sharedSlsDetector
* @param nen number of energies
* @param vector os trimmed energies
* @returns number of trim energies
@ -1138,7 +975,6 @@ class Module : public virtual slsDetectorDefs {
/**
* Returns a vector with the trimmed energies (Eiger)
* \sa sharedSlsDetector
* @returns vector with the trimmed energies
*/
std::vector<int> getTrimEn();
@ -1287,149 +1123,8 @@ class Module : public virtual slsDetectorDefs {
*/
void updateRateCorrection();
/**
* Prints receiver configuration
* @returns receiver configuration
*/
std::string printReceiverConfiguration();
/**
* Gets the use receiver flag from shared memory
*/
bool getUseReceiverFlag() const;
/**
* Locks/Unlocks the connection to the receiver
* @param lock sets (1), usets (0), gets (-1) the lock
* @returns lock status of the receiver
*/
int lockReceiver(int lock = -1);
/**
* Returns the IP of the last client connecting to the receiver
* @returns the IP of the last client connecting to the receiver
*/
sls::IpAddr getReceiverLastClientIP() const;
/**
* Exits the receiver TCP server
*/
void exitReceiver();
/**
* Executes a system command on the receiver server
* e.g. mount an nfs disk, reboot and returns answer etc.
* @param cmd command to be executed
*/
void execReceiverCommand(const std::string &cmd);
std::string getFilePath();
void setFilePath(const std::string &path);
std::string getFileName();
void setFileName(const std::string &fname);
int64_t getFileIndex();
void setFileIndex(int64_t file_index);
void incrementFileIndex();
fileFormat getFileFormat() ;
void setFileFormat(fileFormat f);
int getFramesPerFile();
/** 0 will set frames per file to unlimited */
void setFramesPerFile(int n_frames);
frameDiscardPolicy getReceiverFramesDiscardPolicy();
void setReceiverFramesDiscardPolicy(frameDiscardPolicy f);
bool getPartialFramesPadding();
void setPartialFramesPadding(bool padding);
/**
* Receiver starts listening to packets
*/
void startReceiver();
/**
* Stops the listening mode of receiver
*/
void stopReceiver();
/**
* Gets the status of the listening mode of receiver
* @returns status
*/
runStatus getReceiverStatus() const;
/**
* Gets the number of frames caught by receiver
* @returns number of frames caught by receiver
*/
int64_t getFramesCaughtByReceiver() const;
/** Gets number of missing packets */
std::vector<uint64_t> getNumMissingPackets() const;
/**
* Gets the current frame index of receiver
* @returns current frame index of receiver
*/
uint64_t getReceiverCurrentFrameIndex() const;
int getReceiverProgress() const;
void setFileWrite(bool value);
bool getFileWrite();
void setMasterFileWrite(bool value);
bool getMasterFileWrite();
void setFileOverWrite(bool value);
bool getFileOverWrite();
int getReceiverStreamingFrequency();
/**
* (previously setReadReceiverFrequency)
* Sets the receiver streaming frequency
* @param freq nth frame streamed out, if 0, streamed out at a timer of 200
* ms
* @param detPos -1 for all detectors in list or specific detector position
*/
void setReceiverStreamingFrequency(int freq);
/**
* (previously setReceiverReadTimer)
* Sets the receiver streaming timer
* If receiver streaming frequency is 0, then this timer between each
* data stream is set. Default is 200 ms.
* @param time_in_ms timer between frames
* @returns receiver streaming timer in ms
*/
int setReceiverStreamingTimer(int time_in_ms = 200);
bool getReceiverStreaming();
void setReceiverStreaming(bool enable);
/**
* Enable/disable or 10Gbe
* @param i is -1 to get, 0 to disable and 1 to enable
* @returns if 10Gbe is enabled
*/
bool enableTenGigabitEthernet(int value = -1);
/**
* Set/get receiver fifo depth
* @param i is -1 to get, any other value to set the fifo deph
* @returns the receiver fifo depth
*/
int setReceiverFifoDepth(int n_frames = -1);
bool getReceiverSilentMode();
void setReceiverSilentMode(bool enable);
/**
* If data streaming in receiver is enabled,
* restream the stop dummy packet from receiver
* Used usually for Moench,
* in case it is lost in network due to high data rate
*/
void restreamStopFromReceiver();
bool getTenGiga();
void setTenGiga(bool value);
/**
* Opens pattern file and sends pattern to CTB
@ -1630,67 +1325,23 @@ class Module : public virtual slsDetectorDefs {
void sendToDetectorStop(int fnum) const;
/**
* Send function parameters to receiver
* @param fnum function enum
* @param args argument pointer
* @param args_size size of argument
* @param retval return pointers
* @param retval_size size of return value
*/
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
template <typename Ret>
Ret sendToReceiver(int fnum);
template <typename Ret>
Ret sendToReceiver(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const;
/**
* Get Detector Type from Shared Memory (opening shm without verifying size)
* @param multi_id multi detector Id
* @param detector_id multi detector Id
* @param verify true to verify if shm size matches existing one
* @returns detector type
*/
detectorType getDetectorTypeFromShm(int multi_id, bool verify = true);
detectorType getDetectorTypeFromShm(int detector_id, bool verify = true);
/**
* Initialize shared memory
* @param created true if shared memory must be created, else false to open
* @param type type of detector
* @param multi_id multi detector Id
* @param detector_id multi detector Id
* @param verify true to verify if shm size matches existing one
* @returns true if the shared memory was created now
*/
void initSharedMemory(detectorType type, int multi_id, bool verify = true);
void initSharedMemory(detectorType type, int detector_id, bool verify = true);
/**
* Initialize detector structure to defaults
@ -1773,10 +1424,10 @@ class Module : public virtual slsDetectorDefs {
std::vector<std::string> getSettingsFileDacNames();
/** Module Id or position in the detectors list */
const int detId;
const int moduleId;
/** Shared Memory object */
mutable sls::SharedMemory<sharedSlsDetector> shm{0, 0};
mutable sls::SharedMemory<sharedModule> shm{0, 0};
};
}// sls

View File

@ -0,0 +1,85 @@
#pragma once
#include "Container3.h"
#include "Result.h"
#include <future>
#include <vector>
/*
Can't use std::forward<CT>(Args)...) in parallel call since it would
end up moving temporary objects into the first called function
leaving the other ones with moved from args.
*/
namespace experimental {
using sls::Container3;
template <class CT> struct NonDeduced { using type = CT; };
template <typename RT, typename Class, typename... CT>
sls::Result<RT> Parallel(RT (Class::*func)(CT...) const,
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<RT>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, objects[i].get(), Args...));
}
sls::Result<RT> result;
for (auto &f : futures) {
result.push_back(f.get());
}
return result;
}
template <typename RT, typename Class, typename... CT>
sls::Result<RT> Parallel(RT (Class::*func)(CT...),
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<RT>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, &objects[i], Args...));
}
sls::Result<RT> result;
for (auto &f : futures) {
result.push_back(f.get());
}
return result;
}
template <typename Class, typename... CT>
void Parallel(void (Class::*func)(CT...) const,
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<void>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, &objects[i], Args...));
}
for (auto &f : futures) {
f.get();
}
}
template <typename Class, typename... CT>
void Parallel(void (Class::*func)(CT...),
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<void>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, &objects[i], Args...));
}
for (auto &f : futures)
f.get();
}
} // namespace experimental

View File

@ -0,0 +1,883 @@
#include "Receiver.h"
#include "ClientSocket.h"
#include "FixedCapacityContainer.h"
#include "string_utils.h"
#include "versionAPI.h"
#include "ToString.h"
namespace sls {
// create shm
Receiver::Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, int tcp_port, std::string hostname,
int zmq_port) :
receiverId(receiver_id), interfaceId(interface_id), moduleId(module_id),
shm(detector_id, module_id, interface_id, receiver_id) {
createIndexString();
// ensure shared memory was not created before
if (shm.IsExisting()) {
LOG(logWARNING) << "This shared memory should have been deleted "
"before! " << shm.GetName() << ". Freeing it again";
shm.RemoveSharedMemory();
}
shm = SharedMemory<sharedReceiver>(detector_id, module_id, interface_id,
receiver_id);
shm.CreateSharedMemory();
// initalize receiver structure
shm()->shmversion = RECEIVER_SHMVERSION;
memset(shm()->hostname, 0, MAX_STR_LENGTH);
shm()->tcpPort = DEFAULT_RX_PORTNO + receiver_id;
shm()-> stoppedFlag = false;
shm()->zmqPort = DEFAULT_ZMQ_RX_PORTNO + receiver_id;
shm()->zmqIp = IpAddr{};
// copy port, hostname if given
if (tcp_port != 0) {
setTCPPort(tcp_port);
}
if (zmq_port != 0) {
shm()->zmqPort = zmq_port;
}
if (!hostname.empty()) {
setHostname(hostname);
}
}
// open shm
Receiver::Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, bool verify) :
receiverId(receiver_id), interfaceId(interface_id), moduleId(module_id),
shm(detector_id, module_id, interface_id, receiver_id) {
createIndexString();
shm.OpenSharedMemory();
if (verify && shm()->shmversion != RECEIVER_SHMVERSION) {
std::ostringstream ss;
ss << "Receiver shared memory (" << detector_id << "-" << indexString
<< ":" << receiverId << ") version mismatch (expected 0x" << std::hex
<< RECEIVER_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< std::dec << ". Clear Shared memory to continue.";
throw SharedMemoryError(ss.str());
}
}
Receiver::~Receiver() = default;
void Receiver::createIndexString() {
std::ostringstream oss;
oss << '(' << moduleId << (char)(interfaceId + 97) << "." << receiverId << ')';
indexString = oss.str();
}
/** Configuration */
void Receiver::freeSharedMemory() {
if (shm.IsExisting()) {
shm.RemoveSharedMemory();
}
}
std::string Receiver::getHostname() const {
return shm()->hostname;
}
void Receiver::setHostname(const std::string &hostname) {
if (hostname.empty()) {
throw RuntimeError("Invalid receiver hostname. Cannot be empty.");
}
sls::strcpy_safe(shm()->hostname, hostname.c_str());
checkVersionCompatibility();
}
int Receiver::getTCPPort() const {
return shm()->tcpPort;
}
void Receiver::setTCPPort(const int port) {
LOG(logDEBUG1) << "Setting reciever port to " << port;
if (port >= 0 && port != shm()->tcpPort) {
if (strlen(shm()->hostname) != 0) {
int retval = -1;
sendToReceiver(F_SET_RECEIVER_PORT, port, retval);
shm()->tcpPort = retval;
LOG(logDEBUG1) << "Receiver port: " << retval;
} else {
shm()->tcpPort = port;
}
}
}
void Receiver::checkVersionCompatibility() {
int64_t arg = APIRECEIVER;
LOG(logDEBUG1)
<< "Checking version compatibility with receiver with value "
<< std::hex << arg << std::dec;
sendToReceiver(F_RECEIVER_CHECK_VERSION, arg, nullptr);
}
sls::MacAddr Receiver::configure(slsDetectorDefs::rxParameters arg) {
// hostname
memset(arg.hostname, 0, sizeof(arg.hostname));
strcpy_safe(arg.hostname, shm()->hostname);
// interface id
arg.interfaceId = interfaceId;
// zmqip
{
sls::IpAddr ip;
// Hostname could be ip try to decode otherwise look up the hostname
ip = sls::IpAddr{shm()->hostname};
if (ip == 0) {
ip = HostnameToIp(shm()->hostname);
}
LOG(logINFO) << "Setting default receiver " << indexString
<< " streaming zmq ip to " << ip;
// if client zmqip is empty, update it
if (shm()->zmqIp == 0) {
shm()->zmqIp = ip;
}
memcpy(&arg.zmq_ip, &ip, sizeof(ip));
}
if (arg.detType == EIGER) {
arg.udpInterfaces = 2;
}
LOG(logDEBUG1)
<< "detType:" << arg.detType << std::endl
<< "detectorSize.x:" << arg.detectorSize.x << std::endl
<< "detectorSize.y:" << arg.detectorSize.y << std::endl
<< "moduleId:" << arg.moduleId << std::endl
<< "hostname:" << arg.hostname << std::endl
<< "interfaceId: " << arg.interfaceId << std::endl
<< "zmq ip:" << arg.zmq_ip << std::endl
<< "udpInterfaces:" << arg.udpInterfaces << std::endl
<< "udp_dstport:" << arg.udp_dstport << std::endl
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
<< "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
<< "udp_dstport2:" << arg.udp_dstport2 << std::endl
<< "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl
<< "frames:" << arg.frames << std::endl
<< "triggers:" << arg.triggers << std::endl
<< "bursts:" << arg.bursts << std::endl
<< "analogSamples:" << arg.analogSamples << std::endl
<< "digitalSamples:" << arg.digitalSamples << std::endl
<< "expTimeNs:" << arg.expTimeNs << std::endl
<< "periodNs:" << arg.periodNs << std::endl
<< "subExpTimeNs:" << arg.subExpTimeNs << std::endl
<< "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl
<< "activate:" << arg.activate << std::endl
<< "quad:" << arg.quad << std::endl
<< "dynamicRange:" << arg.dynamicRange << std::endl
<< "timMode:" << arg.timMode << std::endl
<< "tenGiga:" << arg.tenGiga << std::endl
<< "roMode:" << arg.roMode << std::endl
<< "adcMask:" << arg.adcMask << std::endl
<< "adc10gMask:" << arg.adc10gMask << std::endl
<< "roi.xmin:" << arg.roi.xmin << std::endl
<< "roi.xmax:" << arg.roi.xmax << std::endl
<< "countermask:" << arg.countermask << std::endl
<< "burstType:" << arg.burstType << std::endl;
sls::MacAddr mac;
{
sls::MacAddr retval;
sendToReceiver(F_SETUP_RECEIVER, arg, retval);
// detector does not have customized udp mac
if (arg.udp_dstmac == 0) {
mac = retval;
}
}
if (arg.detType == MOENCH) {
setAdditionalJsonParameter("adcmask_1g", std::to_string(arg.adcMask));
setAdditionalJsonParameter("adcmask_10g", std::to_string(arg.adc10gMask));
}
LOG(logINFOBLUE) << "reciever " << indexString << " configured!";
return mac;
}
std::string Receiver::printConfiguration() {
std::ostringstream oss;
oss << std::endl << std::endl
<< "Receiver " << indexString << std::endl
<< "Hostname : " << shm()->hostname << std::endl
<< "Tcp port : " << shm()->tcpPort << std::endl;
/*
os << "\nReceiver UDP IP:\t"
<< getDestinationUDPIP() << "\nReceiver UDP MAC:\t" << getDestinationUDPMAC();
if (shm()->myDetectorType == JUNGFRAU) {
os << "\nDetector UDP IP2:\t" << getSourceUDPIP2()
<< "\nDetector UDP MAC2:\t" << getSourceUDPMAC2()
<< "\nReceiver UDP IP2:\t" << getDestinationUDPIP2()
<< "\nReceiver UDP MAC2:\t" << getDestinationUDPMAC2();
}
os << "\nReceiver UDP Port:\t" << getDestinationUDPPort();
if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) {
os << "\nReceiver UDP Port2:\t" << getDestinationUDPPort2();
}
*/
oss << "\n";
return oss.str();
}
int64_t Receiver::getSoftwareVersion() const {
LOG(logDEBUG1) << "Getting receiver software version";
return sendToReceiver<int64_t>(F_GET_RECEIVER_VERSION);
}
/** Acquisition */
void Receiver::start() {
LOG(logDEBUG1) << "Starting Receiver";
shm()->stoppedFlag = false;
sendToReceiver(F_START_RECEIVER, nullptr, nullptr);
}
void Receiver::stop() {
LOG(logDEBUG1) << "Stopping Receiver";
int arg = static_cast<int>(shm()->stoppedFlag);
sendToReceiver(F_STOP_RECEIVER, arg, nullptr);
}
slsDetectorDefs::runStatus Receiver::getStatus() const {
runStatus retval = ERROR;
LOG(logDEBUG1) << "Getting Receiver Status";
sendToReceiver(F_GET_RECEIVER_STATUS, nullptr, retval);
LOG(logDEBUG1) << "Receiver Status: " << ToString(retval);
return retval;
}
int Receiver::getProgress() const {
int retval = -1;
sendToReceiver(F_GET_RECEIVER_PROGRESS, nullptr, retval);
LOG(logDEBUG1) << "Current Progress of Receiver: " << retval;
return retval;
}
void Receiver::setStoppedFlag() {
shm()->stoppedFlag = true;
}
void Receiver::restreamStop() {
LOG(logDEBUG1) << "Restream stop dummy from Receiver via zmq";
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER, nullptr, nullptr);
}
uint64_t Receiver::getFramesCaught() const {
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAMES_CAUGHT);
}
uint64_t Receiver::getNumMissingPackets() const {
return sendToReceiver<uint64_t>(F_GET_NUM_MISSING_PACKETS);
}
uint64_t Receiver::getCurrentFrameIndex() const {
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAME_INDEX);
}
/** Network Configuration (Detector<->Receiver) */
sls::MacAddr Receiver::setUDPIP(const IpAddr ip) {
LOG(logDEBUG1) << "Setting udp ip to receier: " << ip;
if (ip == 0) {
throw RuntimeError("Invalid destination udp ip address");
}
sls::MacAddr retval(0LU);
sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval);
return retval;
}
void Receiver::setUDPPort(const int port) {
LOG(logDEBUG1) << "Setting udp port to receiver: " << port;
sendToReceiver(F_SET_RECEIVER_UDP_PORT, port, nullptr);
}
int64_t Receiver::getUDPSocketBufferSize() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_UDP_SOCK_BUF_SIZE);
}
void Receiver::setUDPSocketBufferSize(int64_t value) {
LOG(logDEBUG1) << "Sending UDP Socket Buffer size to receiver: "
<< value;
sendToReceiver(F_SET_RECEIVER_UDP_SOCK_BUF_SIZE, value, nullptr);
}
int64_t Receiver::getRealUDPSocketBufferSize() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE);
}
/** ZMQ Streaming Parameters (Receiver<->Client) */
bool Receiver::getZmq() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING);
}
void Receiver::setZmq(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_SET_RECEIVER_STREAMING, arg, nullptr);
}
int Receiver::getZmqFrequency() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_FREQUENCY);
}
void Receiver::setZmqFrequency(const int freq) {
if (freq < 0) {
throw RuntimeError("Invalid streaming frequency " + std::to_string(freq));
}
sendToReceiver(F_SET_RECEIVER_STREAMING_FREQUENCY, freq, nullptr);
}
int Receiver::getZmqTimer() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_TIMER);
}
void Receiver::setZmqTimer(const int time_in_ms) {
sendToReceiver(F_SET_RECEIVER_STREAMING_TIMER, time_in_ms, nullptr);
}
int Receiver::getZmqPort() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_PORT);
}
void Receiver::setZmqPort(int port) {
sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr);
}
sls::IpAddr Receiver::getZmqIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_RECEIVER_STREAMING_SRC_IP);
}
void Receiver::setZmqIP(const sls::IpAddr ip) {
if (ip == 0) {
throw RuntimeError("Invalid receiver zmq ip address");
}
// if client zmqip is empty, update it
if (shm()->zmqIp == 0) {
shm()->zmqIp = ip;
}
sendToReceiver(F_SET_RECEIVER_STREAMING_SRC_IP, ip, nullptr);
}
int Receiver::getClientZmqPort() const {
return shm()->zmqPort;
}
void Receiver::setClientZmqPort(const int port) {
shm()->zmqPort = port;
}
sls::IpAddr Receiver::getClientZmqIP() const {
return shm()->zmqIp;
}
void Receiver::setClientZmqIP(const sls::IpAddr ip) {
LOG(logDEBUG1) << "Setting client zmq ip to " << ip;
if (ip == 0) {
throw RuntimeError("Invalid client zmq ip address");
}
shm()->zmqIp = ip;
}
/** Receiver Parameters */
bool Receiver::getLock() const {
return sendToReceiver<int>(F_GET_LOCK_RECEIVER);
}
void Receiver::setLock(const bool lock) {
LOG(logDEBUG1) << "Setting receiver server lock to " << lock;
sendToReceiver(F_SET_LOCK_RECEIVER, lock, nullptr);
}
sls::IpAddr Receiver::getLastClientIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_LAST_RECEIVER_CLIENT_IP);
}
void Receiver::exitServer() {
LOG(logDEBUG1) << "Sending exit command to receiver server";
sendToReceiver(F_EXIT_RECEIVER, nullptr, nullptr);
}
bool Receiver::getDeactivatedPaddingMode() const {
return sendToReceiver<int>(F_GET_RECEIVER_DEACTIVATED_PADDING);
}
void Receiver::setDeactivatedPaddingMode(const bool padding) {
int arg = static_cast<int>(padding);
sendToReceiver(F_SET_RECEIVER_DEACTIVATED_PADDING, arg, nullptr);
}
bool Receiver::getFlippedDataX() const {
int arg = -1;
return sendToReceiver<int>(F_GET_FLIPPED_DATA_RECEIVER, arg);
}
void Receiver::setFlippedDataX(const bool value) {
int arg = static_cast<int>(value);
LOG(logDEBUG1) << "Setting flipped data across x axis with value: "
<< value;
sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, arg, nullptr);
}
slsDetectorDefs::frameDiscardPolicy Receiver::getFramesDiscardPolicy() const {
return static_cast<frameDiscardPolicy>(
sendToReceiver<int>(F_GET_RECEIVER_DISCARD_POLICY));
}
void Receiver::setFramesDiscardPolicy(const frameDiscardPolicy f) {
int arg = static_cast<int>(f);
sendToReceiver(F_SET_RECEIVER_DISCARD_POLICY, arg, nullptr);
}
bool Receiver::getPartialFramesPadding() const {
return sendToReceiver<int>(F_GET_RECEIVER_PADDING);
}
void Receiver::setPartialFramesPadding(const bool padding) {
int arg = static_cast<int>(padding);
sendToReceiver(F_SET_RECEIVER_PADDING, arg, nullptr);
}
int Receiver::getFifoDepth() const {
return sendToReceiver<int>(F_GET_RECEIVER_FIFO_DEPTH);
}
void Receiver::setFifoDepth(const int value) {
sendToReceiver(F_SET_RECEIVER_FIFO_DEPTH, value, nullptr);
}
bool Receiver::getSilentMode() const {
return sendToReceiver<int>(F_GET_RECEIVER_SILENT_MODE);
}
void Receiver::setSilentMode(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_SET_RECEIVER_SILENT_MODE, arg, nullptr);
}
/** File */
std::string Receiver::getFilePath() const {
char retvals[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_PATH, nullptr, retvals);
return std::string(retvals);
}
void Receiver::setFilePath(const std::string &path) {
if (path.empty()) {
throw RuntimeError("Cannot set empty file path");
}
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, path.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr);
}
std::string Receiver::getFileName() const {
char retvals[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, retvals);
return std::string(retvals);
}
void Receiver::setFileName(const std::string &fname) {
if (fname.empty()) {
throw RuntimeError("Cannot set empty file name prefix");
}
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, fname.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr);
}
int64_t Receiver::getFileIndex() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_FILE_INDEX);
}
void Receiver::setFileIndex(const int64_t file_index) {
sendToReceiver(F_SET_RECEIVER_FILE_INDEX, file_index, nullptr);
}
void Receiver::incrementFileIndex() {
sendToReceiver(F_INCREMENT_FILE_INDEX, nullptr, nullptr);
}
slsDetectorDefs::fileFormat Receiver::getFileFormat() const {
return static_cast<fileFormat>(
sendToReceiver<int>(F_GET_RECEIVER_FILE_FORMAT));
}
void Receiver::setFileFormat(const fileFormat f) {
int arg = static_cast<int>(f);
sendToReceiver(F_SET_RECEIVER_FILE_FORMAT, arg, nullptr);
}
int Receiver::getFramesPerFile() const {
return sendToReceiver<int>(F_GET_RECEIVER_FRAMES_PER_FILE);
}
void Receiver::setFramesPerFile(const int n_frames) {
sendToReceiver(F_SET_RECEIVER_FRAMES_PER_FILE, n_frames, nullptr);
}
bool Receiver::getFileWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_FILE_WRITE);
}
void Receiver::setFileWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_FILE_WRITE, arg, nullptr);
}
bool Receiver::getMasterFileWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_MASTER_FILE_WRITE);
}
void Receiver::setMasterFileWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_MASTER_FILE_WRITE, arg, nullptr);
}
bool Receiver::getFileOverWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_OVERWRITE);
}
void Receiver::setFileOverWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_OVERWRITE, arg, nullptr);
}
/** Detector Parameters */
void Receiver::setNumberOfFrames(const int64_t value) {
LOG(logDEBUG1) << "Sending number of frames to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr);
}
void Receiver::setNumberOfTriggers(const int64_t value) {
LOG(logDEBUG1) << "Sending number of triggers to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr);
}
void Receiver::setNumberOfBursts(const int64_t value) {
LOG(logDEBUG1) << "Sending number of bursts to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr);
}
void Receiver::setNumberOfAnalogSamples(const int value) {
LOG(logDEBUG1) << "Sending number of analog samples to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_ANALOG_SAMPLES, value, nullptr);
}
void Receiver::setNumberOfDigitalSamples(const int value) {
LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
}
void Receiver::setExptime(const int64_t value) {
LOG(logDEBUG1) << "Sending exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr);
}
void Receiver::setPeriod(const int64_t value) {
LOG(logDEBUG1) << "Sending period to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_PERIOD, value, nullptr);
}
void Receiver::setSubExptime(const int64_t value) {
LOG(logDEBUG1) << "Sending sub exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr);
}
void Receiver::setSubDeadTime(const int64_t value) {
LOG(logDEBUG1) << "Sending sub deadtime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_DEADTIME, value, nullptr);
}
void Receiver::setTimingMode(const timingMode value) {
LOG(logDEBUG1) << "Sending timing mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_TIMING_MODE, value, nullptr);
}
void Receiver::setDynamicRange(const int n) {
int retval = -1;
LOG(logDEBUG1) << "Sending dynamic range to receiver: " << n;
sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, n, retval);
}
void Receiver::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
sendToReceiver(F_RECEIVER_SET_READOUT_MODE, mode, nullptr);
}
void Receiver::setQuad(const bool enable) {
int value = enable ? 1 : 0;
LOG(logDEBUG1) << "Setting Quad type to " << value << " in Receiver";
sendToReceiver(F_SET_RECEIVER_QUAD, value, nullptr);
}
void Receiver::setReadNLines(const int value) {
LOG(logDEBUG1) << "Setting read n lines to " << value
<< " in Receiver";
sendToReceiver(F_SET_RECEIVER_READ_N_LINES, value, nullptr);
}
void Receiver::setADCEnableMask(const uint32_t mask) {
sendToReceiver(F_RECEIVER_SET_ADC_MASK, mask, nullptr);
}
void Receiver::setTenGigaADCEnableMask(const uint32_t mask) {
sendToReceiver(F_RECEIVER_SET_ADC_MASK_10G, mask, nullptr);
}
void Receiver::setBurstMode(const slsDetectorDefs::burstMode value) {
LOG(logDEBUG1) << "Sending burst mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_BURST_MODE, value, nullptr);
}
void Receiver::setROI(const slsDetectorDefs::ROI arg) {
std::array<int, 2> args{arg.xmin, arg.xmax};
LOG(logDEBUG1) << "Sending ROI to receiver";
sendToReceiver(F_RECEIVER_SET_ROI, args, nullptr);
}
void Receiver::clearROI() {
LOG(logDEBUG1) << "Clearing ROI";
slsDetectorDefs::ROI arg;
arg.xmin = -1;
arg.xmax = -1;
setROI(arg);
}
std::vector<int> Receiver::getDbitList() const {
sls::FixedCapacityContainer<int, MAX_RX_DBIT> retval;
sendToReceiver(F_GET_RECEIVER_DBIT_LIST, nullptr, retval);
return retval;
}
void Receiver::setDbitList(const std::vector<int>& list) {
LOG(logDEBUG1) << "Setting Receiver Dbit List";
if (list.size() > 64) {
throw sls::RuntimeError("Dbit list size cannot be greater than 64\n");
}
for (auto &it : list) {
if (it < 0 || it > 63) {
throw sls::RuntimeError(
"Dbit list value must be between 0 and 63\n");
}
}
sls::FixedCapacityContainer<int, MAX_RX_DBIT> arg = list;
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);
}
int Receiver::getDbitOffset() const {
return sendToReceiver<int>(F_GET_RECEIVER_DBIT_OFFSET);
}
void Receiver::setDbitOffset(const int value) {
sendToReceiver(F_SET_RECEIVER_DBIT_OFFSET, value, nullptr);
}
void Receiver::setActivate(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_RECEIVER_ACTIVATE, arg, nullptr);
}
void Receiver::setTenGiga(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_ENABLE_RECEIVER_TEN_GIGA, arg, nullptr);
}
void Receiver::setCounterMask(const uint32_t mask) {
int ncounters = __builtin_popcount(mask);
LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters;
sendToReceiver(F_RECEIVER_SET_NUM_COUNTERS, ncounters, nullptr);
}
/** Json */
std::map<std::string, std::string> Receiver::getAdditionalJsonHeader() const {
int fnum = F_GET_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
int size = 0;
auto client = ReceiverSocket(shm()->hostname, shm()->tcpPort);
client.Send(&fnum, sizeof(fnum));
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess));
} else {
client.Receive(&size, sizeof(size));
std::map<std::string, std::string> retval;
if (size > 0) {
char retvals[size * 2][SHORT_STR_LENGTH];
memset(retvals, 0, sizeof(retvals));
client.Receive(retvals, sizeof(retvals));
for (int i = 0; i < size; ++i) {
retval[retvals[2 * i]] = retvals[2 * i + 1];
}
}
LOG(logDEBUG) << "Getting additional json header " << ToString(retval);
return retval;
}
}
void Receiver::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader) {
for (auto &it : jsonHeader) {
if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH ||
it.second.length() > SHORT_STR_LENGTH ) {
throw RuntimeError(it.first + " or " + it.second + " pair has invalid size. "
"Key cannot be empty. Both can have max 20 characters");
}
}
const int size = jsonHeader.size();
int fnum = F_SET_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
LOG(logDEBUG) << "Sending to receiver additional json header " << ToString(jsonHeader);
auto client = ReceiverSocket(shm()->hostname, shm()->tcpPort);
client.Send(&fnum, sizeof(fnum));
client.Send(&size, sizeof(size));
if (size > 0) {
char args[size * 2][SHORT_STR_LENGTH];
memset(args, 0, sizeof(args));
int iarg = 0;
for (auto &it : jsonHeader) {
sls::strcpy_safe(args[iarg], it.first.c_str());
sls::strcpy_safe(args[iarg + 1], it.second.c_str());
iarg += 2;
}
client.Send(args, sizeof(args));
}
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess));
}
}
std::string Receiver::getAdditionalJsonParameter(const std::string &key) const {
char arg[SHORT_STR_LENGTH]{};
sls::strcpy_safe(arg, key.c_str());
char retval[SHORT_STR_LENGTH]{};
sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval);
return retval;
}
void Receiver::setAdditionalJsonParameter(const std::string &key, const std::string &value) {
if (key.empty() || key.length() > SHORT_STR_LENGTH ||
value.length() > SHORT_STR_LENGTH ) {
throw RuntimeError(key + " or " + value + " pair has invalid size. "
"Key cannot be empty. Both can have max 2 characters");
}
char args[2][SHORT_STR_LENGTH]{};
sls::strcpy_safe(args[0], key.c_str());
sls::strcpy_safe(args[1], value.c_str());
sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr);
}
void Receiver::sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) {
static_cast<const Receiver &>(*this).sendToReceiver(
fnum, args, args_size, retval, retval_size);
}
void Receiver::sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const {
if (strlen(shm()->hostname) == 0) {
throw RuntimeError("Reciver not added");
}
auto receiver = ReceiverSocket(shm()->hostname, shm()->tcpPort);
receiver.sendCommandThenRead(fnum, args, args_size, retval, retval_size);
receiver.close();
}
template <typename Arg, typename Ret>
void Receiver::sendToReceiver(int fnum, const Arg &args, Ret &retval) {
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
}
template <typename Arg, typename Ret>
void Receiver::sendToReceiver(int fnum, const Arg &args, Ret &retval) const {
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
}
template <typename Arg>
void Receiver::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) {
sendToReceiver(fnum, &args, sizeof(args), nullptr, 0);
}
template <typename Arg>
void Receiver::sendToReceiver(int fnum, const Arg &args,
std::nullptr_t) const {
sendToReceiver(fnum, &args, sizeof(args), nullptr, 0);
}
template <typename Ret>
void Receiver::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) {
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
}
template <typename Ret>
void Receiver::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const {
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
}
template <typename Ret>
Ret Receiver::sendToReceiver(int fnum){
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret>
Ret Receiver::sendToReceiver(int fnum) const{
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret, typename Arg>
Ret Receiver::sendToReceiver(int fnum, const Arg &args){
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name()
<< ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret, typename Arg>
Ret Receiver::sendToReceiver(int fnum, const Arg &args) const{
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name()
<< ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
} // namespace sls

View File

@ -0,0 +1,251 @@
#pragma once
#include "SharedMemory.h"
#include "logger.h"
#include "network_utils.h"
#include "sls_detector_defs.h"
#include <map>
#define RECEIVER_SHMVERSION 0x200421
namespace sls {
struct sharedReceiver {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
int shmversion;
char hostname[MAX_STR_LENGTH];
int tcpPort;
/** END OF FIXED PATTERN -----------------------------------------------*/
int stoppedFlag;
int zmqPort;
sls::IpAddr zmqIp;
};
class Receiver : public virtual slsDetectorDefs {
const int receiverId{0};
const int interfaceId{0};
const int moduleId{0};
std::string indexString;
mutable sls::SharedMemory<sharedReceiver> shm{0, 0, 0, 0};
public:
static size_t getNumReceivers();
// create shm
explicit Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, int tcp_port = 0,
std::string hostname = "", int zmq_port = 0);
// open shm
explicit Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, bool verify);
virtual ~Receiver();
void createIndexString();
/**************************************************
* *
* Configuration *
* *
* ************************************************/
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedReceiver structure
* Is only safe to call if one deletes the Receiver object afterward
* and frees multi shared memory/updates
* thisMultiDetector->numberOfReceivers
*/
void freeSharedMemory();
std::string getHostname() const;
void setHostname(const std::string &hostname);
sls::MacAddr configure(slsDetectorDefs::rxParameters arg);
int getTCPPort() const;
void setTCPPort(const int port);
std::string printConfiguration();
int64_t getSoftwareVersion() const;
/**************************************************
* *
* Acquisition *
* *
* ************************************************/
void start();
void stop();
slsDetectorDefs::runStatus getStatus() const;
int getProgress() const;
void setStoppedFlag();
void restreamStop();
uint64_t getFramesCaught() const;
uint64_t getNumMissingPackets() const;
uint64_t getCurrentFrameIndex() const;
/**************************************************
* *
* Network Configuration (Detector<->Receiver) *
* *
* ************************************************/
sls::MacAddr setUDPIP(const sls::IpAddr ip);
void setUDPPort(const int udpport);
int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(int64_t value);
int64_t getRealUDPSocketBufferSize() const;
/**************************************************
* *
* ZMQ Streaming Parameters (Receiver<->Client)*
* *
* ************************************************/
bool getZmq() const;
void setZmq(const bool enable);
int getZmqFrequency() const;
/** Freq = 0 for a timer, else frequency */
void setZmqFrequency(const int freq);
int getZmqTimer() const;
void setZmqTimer(const int time_in_ms = 200);
int getZmqPort() const;
void setZmqPort(int port);
sls::IpAddr getZmqIP() const;
void setZmqIP(const sls::IpAddr ip);
int getClientZmqPort() const;
void setClientZmqPort(const int port);
sls::IpAddr getClientZmqIP() const;
void setClientZmqIP(const sls::IpAddr ip);
/**************************************************
* *
* Receiver Parameters *
* *
* ************************************************/
bool getLock() const;
void setLock(const bool lock);
sls::IpAddr getLastClientIP() const;
void exitServer();
bool getDeactivatedPaddingMode() const;
void setDeactivatedPaddingMode(const bool padding);
bool getFlippedDataX() const;
void setFlippedDataX(const bool value);
frameDiscardPolicy getFramesDiscardPolicy() const;
void setFramesDiscardPolicy(const frameDiscardPolicy f);
bool getPartialFramesPadding() const;
void setPartialFramesPadding(const bool padding);
int getFifoDepth() const;
void setFifoDepth(const int value);
bool getSilentMode() const;
void setSilentMode(const bool value);
/**************************************************
* *
* File *
* *
* ************************************************/
std::string getFilePath() const;
void setFilePath(const std::string &path);
std::string getFileName() const;
void setFileName(const std::string &fname);
int64_t getFileIndex() const;
void setFileIndex(const int64_t file_index);
void incrementFileIndex();
fileFormat getFileFormat() const;
void setFileFormat(const fileFormat f);
int getFramesPerFile() const;
/** 0 will set frames per file to unlimited */
void setFramesPerFile(const int n_frames);
bool getFileWrite() const;
void setFileWrite(const bool value);
bool getMasterFileWrite() const;
void setMasterFileWrite(const bool value);
bool getFileOverWrite() const;
void setFileOverWrite(const bool value);
/**************************************************
* *
* Detector Parameters *
* *
* ************************************************/
void setNumberOfFrames(const int64_t value);
void setNumberOfTriggers(const int64_t value);
void setNumberOfBursts(const int64_t value);
void setNumberOfAnalogSamples(const int value);
void setNumberOfDigitalSamples(const int value);
void setExptime(const int64_t value);
void setPeriod(const int64_t value);
void setSubExptime(const int64_t value);
void setSubDeadTime(const int64_t value);
void setTimingMode(const timingMode value);
void setDynamicRange(const int n);
void setReadoutMode(const readoutMode mode);
void setQuad(const bool enable);
void setReadNLines(const int value);
void setADCEnableMask(const uint32_t mask);
void setTenGigaADCEnableMask(const uint32_t mask);
void setBurstMode(const burstMode value);
void setROI(const slsDetectorDefs::ROI arg);
void clearROI();
std::vector<int> getDbitList() const;
/** digital data bits enable (CTB only) */
void setDbitList(const std::vector<int> &list);
int getDbitOffset() const;
/** Set digital data offset in bytes (CTB only) */
void setDbitOffset(const int value);
void setActivate(const bool enable);
void setTenGiga(const bool enable);
void setCounterMask(const uint32_t mask);
/**************************************************
* *
* Json *
* *
* ************************************************/
std::map<std::string, std::string> getAdditionalJsonHeader() const;
/** empty vector deletes entire additional json header */
void setAdditionalJsonHeader(
const std::map<std::string, std::string> &jsonHeader);
std::string getAdditionalJsonParameter(const std::string &key) const;
/** Sets the value for the additional json header parameter key if found,
else append it. If value empty, then deletes parameter */
void setAdditionalJsonParameter(const std::string &key,
const std::string &value);
private:
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
template <typename Ret> Ret sendToReceiver(int fnum);
template <typename Ret> Ret sendToReceiver(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const;
void checkVersionCompatibility();
};
} // namespace sls

View File

@ -23,7 +23,8 @@
#include <unistd.h>
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_"
#define SHM_MODULE_PREFIX "_module_"
#define SHM_RECEIVER_PREFIX "_receiver_"
#define SHM_ENV_NAME "SLSDETNAME"
#include <iostream>
@ -39,10 +40,12 @@ class SharedMemory {
* Constructor
* creates the single/multi detector shared memory name
* @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory
* @param moduleId module detectr id, -1 if a multi detector shared memory
* @param interfaceId 0 for primary interface, 1 for secondary
* @param receiverId receiver id, -1 if not a rxr shm, else round robin entry
*/
SharedMemory(int multiId, int slsId) {
name = ConstructSharedMemoryName(multiId, slsId);
SharedMemory(int multiId, int moduleId, int interfaceId = 0, int receiverId = -1) {
name = ConstructSharedMemoryName(multiId, moduleId, interfaceId, receiverId);
}
/**
@ -184,7 +187,8 @@ class SharedMemory {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
std::string msg = "Free Shared Memory " + name + " Failed: " + strerror(errno);
std::string msg = "Free Shared Memory " + name + " Failed: " +
strerror(errno);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
@ -215,10 +219,13 @@ class SharedMemory {
* Create Shared memory name
* throws exception if name created is longer than required 255(manpages)
* @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory
* @param moduleId module detector id, -1 if a multi detector shared memory
* @param interfaceId 0 for primary interface, 1 for secondary
* @param receiverId receiver id, -1 if not a rxr shm, else round robin entry
* @returns shared memory name
*/
std::string ConstructSharedMemoryName(int multiId, int slsId) {
std::string ConstructSharedMemoryName(int multiId, int moduleId,
int interfaceId = 0, int receiverId = -1) {
// using environment path
std::string sEnvPath = "";
@ -229,14 +236,22 @@ class SharedMemory {
}
std::stringstream ss;
if (slsId < 0)
if (moduleId < 0 && receiverId < 0)
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
else if (receiverId < 0)
ss << SHM_MULTI_PREFIX << multiId <<
SHM_MODULE_PREFIX << moduleId << sEnvPath;
else
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath;
ss << SHM_MULTI_PREFIX << multiId <<
SHM_MODULE_PREFIX << moduleId <<
SHM_RECEIVER_PREFIX << (char)(interfaceId + 97) << '_' << receiverId << sEnvPath;
std::string temp = ss.str();
if (temp.length() > NAME_MAX_LENGTH) {
std::string msg = "Shared memory initialization failed. " + temp + " has " + std::to_string(temp.length()) + " characters. \n" + "Maximum is " + std::to_string(NAME_MAX_LENGTH) + ". Change the environment variable " + SHM_ENV_NAME;
std::string msg = "Shared memory initialization failed. " +
temp + " has " + std::to_string(temp.length()) + " characters. \n" +
"Maximum is " + std::to_string(NAME_MAX_LENGTH) +
". Change the environment variable " + SHM_ENV_NAME;
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
@ -250,9 +265,11 @@ class SharedMemory {
*/
T *MapSharedMemory() {
void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
std::string msg = "Mapping shared memory " + name + " failed: " + strerror(errno);
std::string msg = "Mapping shared memory " + name + " failed: " +
strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
@ -271,7 +288,8 @@ class SharedMemory {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
std::string msg = "Could not verify existing shared memory " + name + " size match " + "(could not fstat): " + strerror(errno);
std::string msg = "Could not verify existing shared memory " +
name + " size match " + "(could not fstat): " + strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
@ -280,7 +298,9 @@ class SharedMemory {
//size does not match
auto sz = static_cast<size_t>(sb.st_size);
if (sz != expectedSize) {
std::string msg = "Existing shared memory " + name + " size does not match" + "Expected " + std::to_string(expectedSize) + ", found " + std::to_string(sz);
std::string msg = "Existing shared memory " + name +
" size does not match" + "Expected " +
std::to_string(expectedSize) + ", found " + std::to_string(sz);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
return 1;

View File

@ -13,6 +13,9 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-global.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Container3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-MaskGenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Receiver.cpp
)
target_include_directories(tests PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../src>")

View File

@ -144,10 +144,10 @@ TEST_CASE("rx_printconfig", "[.cmd][.rx][.new]") {
/* Receiver Config */
TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getRxHostname();
// TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
// Detector det;
// CmdProxy proxy(&det);
// auto prev_val = det.getRxHostname();
// Cannot set rx_hostname (will reset parameters in rxr and no shm variables to update)
// {
@ -168,37 +168,37 @@ TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
// for (int i = 0; i != det.size(); ++i) {
// det.setRxHostname(prev_val[i], {i});
// }
{
std::ostringstream oss;
proxy.Call("rx_hostname", {}, 0, GET, oss);
REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
}
}
// {
// std::ostringstream oss;
// proxy.Call("rx_hostname", {}, 0, GET, oss);
// REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
// }
// }
TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getRxPort();
// TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") {
// Detector det;
// CmdProxy proxy(&det);
// auto prev_val = det.getRxPort();
int port = 3500;
proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
proxy.Call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
}
REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT));
port = 5754;
proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
proxy.Call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
}
for (int i = 0; i != det.size(); ++i) {
det.setRxPort(prev_val[i], i);
}
}
// int port = 3500;
// proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
// for (int i = 0; i != det.size(); ++i) {
// std::ostringstream oss;
// proxy.Call("rx_tcpport", {}, i, GET, oss);
// REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
// }
// REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT));
// port = 5754;
// proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
// for (int i = 0; i != det.size(); ++i) {
// std::ostringstream oss;
// proxy.Call("rx_tcpport", {}, i, GET, oss);
// REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
// }
// for (int i = 0; i != det.size(); ++i) {
// det.setRxPort(prev_val[i], i);
// }
// }
TEST_CASE("rx_fifodepth", "[.cmd][.rx][.new]") {
Detector det;

View File

@ -0,0 +1,330 @@
#include "catch.hpp"
#include "Container3.h"
using sls::Container3;
TEST_CASE("Default construction gives container of size 0") {
Container3<int> c;
CHECK(c.size() == 0);
CHECK(c.size(0) == 0);
CHECK(c.size(1) == 0);
CHECK(c.size(2) == 0);
}
TEST_CASE("Construct container with size") {
Container3<int> c(3, 4, 5);
CHECK(c.size() == 3 * 4 * 5);
CHECK(c.size(0) == 3);
CHECK(c.size(1) == 4);
CHECK(c.size(2) == 5);
}
TEST_CASE("Constructor with default value") {
constexpr int val = 7;
Container3<int> c({1, 1, 5}, val);
for (size_t i = 0; i < c.size(); ++i) {
CHECK(c[i] == val);
}
}
TEST_CASE("Container3 can be iterated with range for") {
constexpr int val = 7;
Container3<int> c({1, 1, 5}, val);
for (const auto& item : c) {
CHECK(item == val);
}
}
TEST_CASE(
"() gives access to an element for both const and non const objects") {
Container3<int> c{1, 1, 1};
CHECK(c(0, 0, 0) == 0);
const Container3<int> c2{1, 1, 1};
CHECK(c2(0, 0, 0) == 0);
}
TEST_CASE("() can be used to modify object") {
Container3<int> c{1, 1, 1};
c(0, 0, 0) = 7;
CHECK(c(0, 0, 0) == 7);
}
TEST_CASE("at() can be used to modify object") {
Container3<int> c{1, 1, 1};
c.at(0, 0, 0) = 7;
CHECK(c(0, 0, 0) == 7);
}
TEST_CASE("at throws outsize range for both const and non const objects") {
Container3<int> c{1, 1, 1};
const Container3<double> c2{1, 1, 1};
CHECK_THROWS(c.at(5, 5, 5));
CHECK_THROWS(c2.at(5, 5, 5));
}
TEST_CASE("Set values") {
Container3<int> c(2, 3, 4);
size_t count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
}
TEST_CASE("Check if index is valid") {
Container3<int> c(2, 3, 4);
CHECK(c.is_valid_index(1,1,1));
CHECK(c.is_valid_index(1,2,3));
CHECK(c.is_valid_index(1,2,3));
CHECK_FALSE(c.is_valid_index(1,7,1));
CHECK_FALSE(c.is_valid_index(1,1,4));
CHECK_FALSE(c.is_valid_index(3,1,1));
}
TEST_CASE("Copy data from one container to another") {
Container3<int> c(2, 1, 2);
for (size_t i = 0; i < c.size(); ++i) {
c[i] = i;
}
Container3<int> c2(3, 3, 3);
c2.copy_data(c);
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
CHECK(c2(i, j, k) == c(i, j, k));
}
}
}
}
TEST_CASE("Copy assignment copies values") {
Container3<int> c(2, 3, 4);
size_t count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
Container3<int> c2;
c2 = c;
count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c2(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
}
TEST_CASE("Copy constructor copies values") {
Container3<int> c(18, 23, 4);
size_t count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
Container3<int> c2 = c;
count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c2(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
}
TEST_CASE("Copy assignment create disjoint objects") {
Container3<int> c(2, 3, 4);
Container3<int> c2;
c2 = c;
c2(1, 1, 1) = 72;
CHECK(c2(1, 1, 1) == 72);
CHECK(c(1, 1, 1) != 72);
}
TEST_CASE("Move constructor") {
Container3<int> c(2, 3, 4);
// explicit move only for testing
Container3<int> c2(std::move(c));
// Moved from object is in an ok state
CHECK(c.data() == nullptr);
for (size_t i = 0; i < 3; ++i) {
CHECK(c.size(i) == 0);
}
// new object has the correct size and owns some data
CHECK(c2.data() != nullptr);
CHECK(c2.size(0) == 2);
CHECK(c2.size(1) == 3);
CHECK(c2.size(2) == 4);
}
TEST_CASE("Move assignment ") {
Container3<int> c(2, 3, 4);
Container3<int> c2(5, 5, 5);
c2 = std::move(c);
// Moved from object is in an ok state
CHECK(c.data() == nullptr);
for (size_t i = 0; i < 3; ++i) {
CHECK(c.size(i) == 0);
}
// new object has the correct size and owns some data
CHECK(c2.data() != nullptr);
CHECK(c2.size(0) == 2);
CHECK(c2.size(1) == 3);
CHECK(c2.size(2) == 4);
}
TEST_CASE("Resize to a larger size") {
Container3<int> c(2, 3, 4);
// Assign values
auto shape = c.shape();
CHECK(shape == std::array<size_t, 3>{2,3,4});
size_t count = 0;
for (size_t i = 0; i < shape[0]; ++i) {
for (size_t j = 0; j < shape[1]; ++j) {
for (size_t k = 0; k < shape[2]; ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
++count;
}
}
}
c.resize(3, 4, 5);
CHECK(c.shape() == std::array<size_t, 3>{3,4,5});
// Values should remain the same in the old region
count = 0;
for (size_t i = 0; i < shape[0]; ++i) {
for (size_t j = 0; j < shape[1]; ++j) {
for (size_t k = 0; k < shape[2]; ++k) {
CHECK(c(i, j, k) == count);
++count;
}
}
}
// Default constructed values outsize
CHECK(c(2, 2, 2) == 0);
CHECK(c(2, 3, 2) == 0);
}
TEST_CASE("Inserting values outside range with a empty receiver") {
Container3<int> c;
c.at_can_grow(0, 0, 0) = 5;
CHECK(c(0, 0, 0) == 5);
CHECK(c.size() == 1);
CHECK(c.size(0) == 1);
CHECK(c.size(1) == 1);
CHECK(c.size(2) == 1);
c.at_can_grow(0, 0, 1) = 6;
CHECK(c.size() == 2);
CHECK(c.size(0) == 1);
CHECK(c.size(1) == 1);
CHECK(c.size(2) == 2);
}
TEST_CASE("Inserting a value outside of the current size") {
Container3<int> c{1, 2, 3};
for (size_t i = 0; i < c.size(); ++i) {
c[i] = i;
}
Container3<int> copy;
copy = c;
c.at_can_grow(2, 2, 2) = 7;
CHECK(c.size(0) == 3);
CHECK(c.size(1) == 3);
CHECK(c.size(2) == 3);
for (size_t i = 0; i < copy.size(0); ++i) {
for (size_t j = 0; j < copy.size(0); ++j) {
for (size_t k = 0; k < copy.size(0); ++k) {
CHECK(copy(i, j, k) == c(i, j, k));
}
}
}
}
TEST_CASE("Clear sets size to zero and clears memory"){
Container3<int> c(5,5,5);
CHECK(c.shape() == std::array<size_t, 3>{5,5,5});
c.clear();
CHECK(c.shape() == std::array<size_t, 3>{0,0,0});
CHECK(c.size() == 0);
}
TEST_CASE("Put unique pointer in Container3"){
Container3<std::unique_ptr<int>> c(3,1,1);
c(0,0,0) = std::unique_ptr<int>(new int);
CHECK(c(0,0,0) != nullptr);
CHECK(c(1,0,0) == nullptr);
CHECK(c(2,0,0) == nullptr);
*c(0,0,0) = 5;
CHECK(*c(0,0,0) == 5);
}
TEST_CASE("Resize with unique ptr"){
Container3<std::unique_ptr<int>> c(2,1,1);
c(1,0,0) = std::unique_ptr<int>(new int);
*c(1,0,0) = 7;
c.resize(3,1,1);
CHECK(c.size() == 3);
CHECK(*c(1,0,0) == 7);
}

View File

@ -0,0 +1,99 @@
#include "catch.hpp"
#include "MaskGenerator.h"
using sls::MaskGenerator;
using sls::Container3;
TEST_CASE("Default construction gives an mask of size 0") {
auto m = MaskGenerator().mask();
CHECK(m.shape() == std::array<size_t, 3>{0, 0, 0});
CHECK(m.size() == 0);
}
TEST_CASE("Default behaviour with shape is all true and same shape") {
Container3<int> c{1, 2, 3};
auto m = MaskGenerator().mask(c.shape());
CHECK(m.shape() == std::array<size_t, 3>{1, 2, 3});
for (auto &i : m)
CHECK(i == true);
}
TEST_CASE("With std::vector we give back the first index and 0, 0") {
Container3<int> rec{14, 1, 3};
auto m = MaskGenerator(std::vector<int>{0, 3, 5}).mask(rec.shape());
CHECK(m.shape() == std::array<size_t, 3>{14, 1, 3});
CHECK(m(0, 0, 0) == true);
CHECK(m(3, 0, 0) == true);
CHECK(m(5, 0, 0) == true);
std::vector<int> positions(rec.size(0));
std::iota(begin(positions), end(positions), 0);
positions.erase(std::remove(positions.begin(), positions.end(), 0),
positions.end());
positions.erase(std::remove(positions.begin(), positions.end(), 3),
positions.end());
positions.erase(std::remove(positions.begin(), positions.end(), 5),
positions.end());
for (auto i : positions) {
for (size_t j = 0; j < rec.size(1); ++j) {
for (size_t k = 0; k < rec.size(2); ++k) {
REQUIRE(m(i, j, k) == false);
}
}
}
}
TEST_CASE("With single number we get that detector x,0,0") {
Container3<int> rec{2, 2, 1};
auto m = MaskGenerator(1).mask(rec);
CHECK(m(1, 0, 0) == true);
CHECK(m(1, 1, 0) == false);
CHECK(m(0, 1, 0) == false);
CHECK(m(0, 0, 0) == false);
}
TEST_CASE("With two numbers we get x,y,0") {
Container3<int> rec{2, 2, 1};
auto m = MaskGenerator(1, 1).mask(rec);
CHECK(m(1, 1, 0) == true);
CHECK(m(1, 0, 0) == false);
CHECK(m(0, 1, 0) == false);
CHECK(m(0, 0, 0) == false);
}
TEST_CASE("With three numbers we get x,y,z") {
Container3<int> rec{9, 7, 5};
auto m = MaskGenerator(3, 4, 1).mask(rec);
REQUIRE(m.shape() == rec.shape());
REQUIRE(m(3, 4, 1) == true);
for (size_t i = 0; i < rec.size(0); ++i) {
for (size_t j = 0; j < rec.size(1); ++j) {
for (size_t k = 0; k < rec.size(2); ++k) {
if (!(i == 3 && j == 4 && k == 1)) {
REQUIRE(m(i, j, k) == false);
}
}
}
}
}
TEST_CASE("Passing in -1 as the only element in the vector gives all rows"){
Container3<int> r{3,3,3};
std::vector<int> vec{-1};
auto m = MaskGenerator(vec, 0).mask(r);
REQUIRE(m.shape() == std::array<size_t, 3>{3,3,3});
CHECK(m(0,0,0) == true);
CHECK(m(1,0,0) == true);
CHECK(m(2,0,0) == true);
CHECK(m(0,1,0) == false);
CHECK(m(0,2,0) == false);
CHECK(m(0,0,1) == false);
}

View File

@ -0,0 +1,10 @@
#include "catch.hpp"
#include "Container3.h"
#include "Receiver.h"
using sls::Receiver;
// TEST_CASE("Receiver can be default constructed"){
// }

View File

@ -95,7 +95,7 @@ void ClientInterface::startTCPServer() {
}
if (receiver) {
receiver->shutDownUDPSockets();
receiver->shutDownUDPSocket();
}
LOG(logINFOBLUE) << "Exiting [ TCP server Tid: " << syscall(SYS_gettid) << "]";
}
@ -104,7 +104,8 @@ void ClientInterface::startTCPServer() {
int ClientInterface::functionTable(){
flist[F_EXEC_RECEIVER_COMMAND] = &ClientInterface::exec_command;
flist[F_EXIT_RECEIVER] = &ClientInterface::exit_server;
flist[F_LOCK_RECEIVER] = &ClientInterface::lock_receiver;
flist[F_SET_LOCK_RECEIVER] = &ClientInterface::set_lock_server;
flist[F_GET_LOCK_RECEIVER] = &ClientInterface::get_lock_server;
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port;
flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version;
@ -145,11 +146,14 @@ int ClientInterface::functionTable(){
flist[F_GET_RECEIVER_OVERWRITE] = &ClientInterface::get_overwrite;
flist[F_ENABLE_RECEIVER_TEN_GIGA] = &ClientInterface::enable_tengiga;
flist[F_SET_RECEIVER_FIFO_DEPTH] = &ClientInterface::set_fifo_depth;
flist[F_GET_RECEIVER_FIFO_DEPTH] = &ClientInterface::get_fifo_depth;
flist[F_RECEIVER_ACTIVATE] = &ClientInterface::set_activate;
flist[F_SET_RECEIVER_STREAMING] = &ClientInterface::set_streaming;
flist[F_GET_RECEIVER_STREAMING] = &ClientInterface::get_streaming;
flist[F_RECEIVER_STREAMING_TIMER] = &ClientInterface::set_streaming_timer;
flist[F_SET_RECEIVER_STREAMING_TIMER] = &ClientInterface::set_streaming_timer;
flist[F_GET_RECEIVER_STREAMING_TIMER] = &ClientInterface::get_streaming_timer;
flist[F_SET_FLIPPED_DATA_RECEIVER] = &ClientInterface::set_flipped_data;
flist[F_GET_FLIPPED_DATA_RECEIVER] = &ClientInterface::get_flipped_data;
flist[F_SET_RECEIVER_FILE_FORMAT] = &ClientInterface::set_file_format;
flist[F_GET_RECEIVER_FILE_FORMAT] = &ClientInterface::get_file_format;
flist[F_SET_RECEIVER_STREAMING_PORT] = &ClientInterface::set_streaming_port;
@ -161,8 +165,9 @@ int ClientInterface::functionTable(){
flist[F_RESTREAM_STOP_FROM_RECEIVER] = &ClientInterface::restream_stop;
flist[F_SET_ADDITIONAL_JSON_HEADER] = &ClientInterface::set_additional_json_header;
flist[F_GET_ADDITIONAL_JSON_HEADER] = &ClientInterface::get_additional_json_header;
flist[F_RECEIVER_UDP_SOCK_BUF_SIZE] = &ClientInterface::set_udp_socket_buffer_size;
flist[F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE]= &ClientInterface::get_real_udp_socket_buffer_size;
flist[F_SET_RECEIVER_UDP_SOCK_BUF_SIZE] = &ClientInterface::set_udp_socket_buffer_size;
flist[F_GET_RECEIVER_UDP_SOCK_BUF_SIZE] = &ClientInterface::get_udp_socket_buffer_size;
flist[F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE]= &ClientInterface::get_real_udp_socket_buffer_size;
flist[F_SET_RECEIVER_FRAMES_PER_FILE] = &ClientInterface::set_frames_per_file;
flist[F_GET_RECEIVER_FRAMES_PER_FILE] = &ClientInterface::get_frames_per_file;
flist[F_RECEIVER_CHECK_VERSION] = &ClientInterface::check_version_compatibility;
@ -181,9 +186,7 @@ int ClientInterface::functionTable(){
flist[F_SET_RECEIVER_QUAD] = &ClientInterface::set_quad_type;
flist[F_SET_RECEIVER_READ_N_LINES] = &ClientInterface::set_read_n_lines;
flist[F_SET_RECEIVER_UDP_IP] = &ClientInterface::set_udp_ip;
flist[F_SET_RECEIVER_UDP_IP2] = &ClientInterface::set_udp_ip2;
flist[F_SET_RECEIVER_UDP_PORT] = &ClientInterface::set_udp_port;
flist[F_SET_RECEIVER_UDP_PORT2] = &ClientInterface::set_udp_port2;
flist[F_SET_RECEIVER_NUM_INTERFACES] = &ClientInterface::set_num_interfaces;
flist[F_RECEIVER_SET_ADC_MASK_10G] = &ClientInterface::set_adc_mask_10g;
flist[F_RECEIVER_SET_NUM_COUNTERS] = &ClientInterface::set_num_counters;
@ -288,7 +291,7 @@ int ClientInterface::exit_server(Interface &socket) {
return GOODBYE;
}
int ClientInterface::lock_receiver(Interface &socket) {
int ClientInterface::set_lock_server(Interface &socket) {
auto lock = socket.Receive<int>();
LOG(logDEBUG1) << "Locking Server to " << lock;
if (lock >= 0) {
@ -300,6 +303,11 @@ int ClientInterface::lock_receiver(Interface &socket) {
throw RuntimeError("Receiver locked\n");
}
}
socket.Send(OK);
return OK;
}
int ClientInterface::get_lock_server(Interface &socket) {
return socket.sendResult(lockedByClient);
}
@ -330,10 +338,12 @@ int ClientInterface::setup_receiver(Interface &socket) {
auto arg = socket.Receive<rxParameters>();
LOG(logDEBUG1)
<< "detType:" << arg.detType << std::endl
<< "multiSize.x:" << arg.multiSize.x << std::endl
<< "multiSize.y:" << arg.multiSize.y << std::endl
<< "detId:" << arg.detId << std::endl
<< "detectorSize.x:" << arg.detectorSize.x << std::endl
<< "detectorSize.y:" << arg.detectorSize.y << std::endl
<< "moduleId:" << arg.moduleId << std::endl
<< "hostname:" << arg.hostname << std::endl
<< "interfaceId: " << arg.interfaceId << std::endl
<< "zmq ip:" << arg.zmq_ip << std::endl
<< "udpInterfaces:" << arg.udpInterfaces << std::endl
<< "udp_dstport:" << arg.udp_dstport << std::endl
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
@ -373,30 +383,32 @@ int ClientInterface::setup_receiver(Interface &socket) {
// basic setup
setDetectorType(arg.detType);
{
int msize[2] = {arg.multiSize.x, arg.multiSize.y};
impl()->setMultiDetectorSize(msize);
int msize[2] = {arg.detectorSize.x, arg.detectorSize.y};
impl()->setDetectorSize(msize);
}
impl()->setDetectorPositionId(arg.detId);
impl()->setDetectorPositionId(arg.moduleId);
impl()->setDetectorHostname(arg.hostname);
// udp setup
sls::MacAddr retvals[2];
impl()->setInterfaceId(arg.interfaceId);
sls::MacAddr retval;
if (arg.interfaceId == 0) {
if (arg.udp_dstmac == 0 && arg.udp_dstip != 0) {
retvals[0] = setUdpIp(sls::IpAddr(arg.udp_dstip));
}
if (arg.udp_dstmac2 == 0 && arg.udp_dstip2 != 0) {
retvals[1] = setUdpIp2(sls::IpAddr(arg.udp_dstip2));
retval = setUdpIp(sls::IpAddr(arg.udp_dstip));
}
impl()->setUDPPortNumber(arg.udp_dstport);
impl()->setUDPPortNumber2(arg.udp_dstport2);
if (myDetectorType == JUNGFRAU) {
} else {
if (arg.udp_dstmac2 == 0 && arg.udp_dstip2 != 0) {
retval = setUdpIp(sls::IpAddr(arg.udp_dstip2));
}
impl()->setUDPPortNumber(arg.udp_dstport2);
}
try {
impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
} catch(const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg.udpInterfaces));
}
}
impl()->setUDPSocketBufferSize(0);
// acquisition parameters
@ -490,8 +502,14 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == GOTTHARD) {
impl()->setBurstMode(arg.burstType);
}
return socket.sendResult(retvals);
{
sls::IpAddr ip(arg.zmq_ip);
if (ip == 0) {
throw RuntimeError("Invalid zmq ip: " + ip.str());
}
impl()->setStreamingSourceIP(ip);
}
return socket.sendResult(retval);
}
void ClientInterface::setDetectorType(detectorType arg) {
@ -514,6 +532,7 @@ void ClientInterface::setDetectorType(detectorType arg) {
receiver = sls::make_unique<Implementation>(arg);
myDetectorType = arg;
} catch (...) {
receiver.reset();
throw RuntimeError("Could not set detector type");
}
@ -547,7 +566,8 @@ int ClientInterface::set_roi(Interface &socket) {
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set ROI");
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_frames(Interface &socket) {
@ -561,7 +581,8 @@ int ClientInterface::set_num_frames(Interface &socket) {
impl()->setNumberOfFrames(value);
int64_t retval = impl()->getNumberOfFrames();
validate(value, retval, "set number of frames", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_triggers(Interface &socket) {
@ -575,7 +596,8 @@ int ClientInterface::set_num_triggers(Interface &socket) {
impl()->setNumberOfTriggers(value);
int64_t retval = impl()->getNumberOfTriggers();
validate(value, retval, "set number of triggers", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_bursts(Interface &socket) {
@ -589,7 +611,8 @@ int ClientInterface::set_num_bursts(Interface &socket) {
impl()->setNumberOfBursts(value);
int64_t retval = impl()->getNumberOfBursts();
validate(value, retval, "set number of bursts", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_add_storage_cells(Interface &socket) {
@ -603,7 +626,8 @@ int ClientInterface::set_num_add_storage_cells(Interface &socket) {
impl()->setNumberOfAdditionalStorageCells(value);
int retval = impl()->getNumberOfAdditionalStorageCells();
validate(value, retval, "set number of additional storage cells", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_timing_mode(Interface &socket) {
@ -617,7 +641,8 @@ int ClientInterface::set_timing_mode(Interface &socket) {
impl()->setTimingMode(static_cast<timingMode>(value));
int retval = impl()->getTimingMode();
validate(value, retval, "set timing mode", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_burst_mode(Interface &socket) {
@ -631,7 +656,8 @@ int ClientInterface::set_burst_mode(Interface &socket) {
impl()->setBurstMode(static_cast<burstMode>(value));
int retval = impl()->getBurstMode();
validate(value, retval, "set burst mode", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_analog_samples(Interface &socket) {
@ -645,7 +671,8 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " + std::to_string(value) + " due to fifo structure memory allocation.");
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_digital_samples(Interface &socket) {
@ -659,21 +686,24 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to " + std::to_string(value) + " due to fifo structure memory allocation.");
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_exptime(Interface &socket) {
auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting exptime to " << value << "ns";
impl()->setAcquisitionTime(value);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_period(Interface &socket) {
auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting period to " << value << "ns";
impl()->setAcquisitionPeriod(value);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_subexptime(Interface &socket) {
@ -682,7 +712,8 @@ int ClientInterface::set_subexptime(Interface &socket) {
uint64_t subdeadtime = impl()->getSubPeriod() - impl()->getSubExpTime();
impl()->setSubExpTime(value);
impl()->setSubPeriod(impl()->getSubExpTime() + subdeadtime);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_subdeadtime(Interface &socket) {
@ -690,7 +721,8 @@ int ClientInterface::set_subdeadtime(Interface &socket) {
LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns";
impl()->setSubPeriod(value + impl()->getSubExpTime());
LOG(logDEBUG1) << "Setting sub period to " << impl()->getSubPeriod() << "ns";
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_dynamic_range(Interface &socket) {
@ -745,7 +777,8 @@ int ClientInterface::set_streaming_frequency(Interface &socket) {
int retval = impl()->getStreamingFrequency();
validate(index, retval, "set streaming frequency", DEC);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_streaming_frequency(Interface &socket) {
@ -765,7 +798,8 @@ int ClientInterface::start_receiver(Interface &socket) {
LOG(logDEBUG1) << "Starting Receiver";
impl()->startReceiver();
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::stop_receiver(Interface &socket) {
@ -780,7 +814,8 @@ int ClientInterface::stop_receiver(Interface &socket) {
throw RuntimeError("Could not stop receiver. It as it is: " +
sls::ToString(s));
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_file_dir(Interface &socket) {
@ -803,7 +838,8 @@ int ClientInterface::set_file_dir(Interface &socket) {
else
LOG(logDEBUG1) << "file path:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_file_dir(Interface &socket) {
@ -827,7 +863,8 @@ int ClientInterface::set_file_name(Interface &socket) {
std::string s = impl()->getFileName();
sls::strcpy_safe(retval, s.c_str());
LOG(logDEBUG1) << "file name:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_file_name(Interface &socket) {
@ -851,7 +888,8 @@ int ClientInterface::set_file_index(Interface &socket) {
int64_t retval = impl()->getFileIndex();
validate(index, retval, "set file index", DEC);
LOG(logDEBUG1) << "file index:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_file_index(Interface &socket) {
@ -867,19 +905,13 @@ int ClientInterface::get_frame_index(Interface &socket) {
}
int ClientInterface::get_missing_packets(Interface &socket) {
std::vector<uint64_t> m = impl()->getNumMissingPackets();
LOG(logDEBUG1) << "missing packets:" << sls::ToString(m);
int retvalsize = m.size();
uint64_t retval[retvalsize];
std::copy(std::begin(m), std::end(m), retval);
socket.Send(OK);
socket.Send(&retvalsize, sizeof(retvalsize));
socket.Send(retval, sizeof(retval));
return OK;
uint64_t retval = impl()->getNumMissingPackets();
LOG(logDEBUG1) << "missing packets:" << retval;
return socket.sendResult(retval);
}
int ClientInterface::get_frames_caught(Interface &socket) {
int64_t retval = impl()->getFramesCaught();
uint64_t retval = impl()->getFramesCaught();
LOG(logDEBUG1) << "frames caught:" << retval;
return socket.sendResult(retval);
}
@ -896,7 +928,8 @@ int ClientInterface::set_file_write(Interface &socket) {
int retval = impl()->getFileWriteEnable();
validate(enable, retval, "set file write enable", DEC);
LOG(logDEBUG1) << "file write enable:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_file_write(Interface &socket) {
@ -918,7 +951,8 @@ int ClientInterface::set_master_file_write(Interface &socket) {
int retval = impl()->getMasterFileWriteEnable();
validate(enable, retval, "set master file write enable", DEC);
LOG(logDEBUG1) << "master file write enable:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_master_file_write(Interface &socket) {
@ -940,7 +974,8 @@ int ClientInterface::set_overwrite(Interface &socket) {
int retval = impl()->getOverwriteEnable();
validate(index, retval, "set file overwrite enable", DEC);
LOG(logDEBUG1) << "file overwrite enable:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_overwrite(Interface &socket) {
@ -967,7 +1002,8 @@ int ClientInterface::enable_tengiga(Interface &socket) {
int retval = impl()->getTenGigaEnable();
validate(val, retval, "set 10GbE", DEC);
LOG(logDEBUG1) << "10Gbe:" << retval;
return socket.sendResult(retval);
socket.Send(OK);
return OK;
}
int ClientInterface::set_fifo_depth(Interface &socket) {
@ -984,6 +1020,14 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
int retval = impl()->getFifoDepth();
validate(value, retval, std::string("set fifo depth"), DEC);
LOG(logDEBUG1) << "fifo depth:" << retval;
socket.Send(OK);
return OK;
}
int ClientInterface::get_fifo_depth(Interface &socket) {
int retval = impl()->getFifoDepth();
LOG(logDEBUG1) << "fifo depth:" << retval;
return socket.sendResult(retval);
}
@ -1020,7 +1064,8 @@ int ClientInterface::set_streaming(Interface &socket) {
auto retval = static_cast<int>(impl()->getDataStreamEnable());
validate(index, retval, "set data stream enable", DEC);
LOG(logDEBUG1) << "data streaming enable:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_streaming(Interface &socket) {
@ -1039,9 +1084,17 @@ int ClientInterface::set_streaming_timer(Interface &socket) {
int retval = impl()->getStreamingTimer();
validate(index, retval, "set data stream timer", DEC);
LOG(logDEBUG1) << "Streaming timer:" << retval;
socket.Send(OK);
return OK;
}
int ClientInterface::get_streaming_timer(Interface &socket) {
int retval = impl()->getStreamingTimer();
LOG(logDEBUG1) << "Streaming timer:" << retval;
return socket.sendResult(retval);
}
int ClientInterface::set_flipped_data(Interface &socket) {
auto arg = socket.Receive<int>();
@ -1056,6 +1109,13 @@ int ClientInterface::set_flipped_data(Interface &socket) {
int retval = impl()->getFlippedDataX();
validate(arg, retval, std::string("set flipped data"), DEC);
LOG(logDEBUG1) << "Flipped Data:" << retval;
socket.Send(OK);
return OK;
}
int ClientInterface::get_flipped_data(Interface &socket) {
int retval = impl()->getFlippedDataX();
LOG(logDEBUG1) << "Flipped Data:" << retval;
return socket.sendResult(retval);
}
@ -1073,7 +1133,8 @@ int ClientInterface::set_file_format(Interface &socket) {
auto retval = impl()->getFileFormat();
validate(f, retval, "set file format", DEC);
LOG(logDEBUG1) << "File Format: " << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_file_format(Interface &socket) {
@ -1094,7 +1155,8 @@ int ClientInterface::set_streaming_port(Interface &socket) {
int retval = impl()->getStreamingPort();
validate(port, retval, "set streaming port", DEC);
LOG(logDEBUG1) << "streaming port:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_streaming_port(Interface &socket) {
@ -1121,7 +1183,8 @@ int ClientInterface::set_streaming_source_ip(Interface &socket) {
<< ", but read " << retval << '\n';
throw RuntimeError(os.str());
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_streaming_source_ip(Interface &socket) {
@ -1143,7 +1206,8 @@ int ClientInterface::set_silent_mode(Interface &socket) {
auto retval = static_cast<int>(impl()->getSilentMode());
validate(value, retval, "set silent mode", DEC);
LOG(logDEBUG1) << "silent mode:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_silent_mode(Interface &socket) {
@ -1161,7 +1225,8 @@ int ClientInterface::restream_stop(Interface &socket) {
LOG(logDEBUG1) << "Restreaming stop";
impl()->restreamStop();
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_additional_json_header(Interface &socket) {
@ -1178,7 +1243,8 @@ int ClientInterface::set_additional_json_header(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json);
impl()->setAdditionalJsonHeader(json);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_additional_json_header(Interface &socket) {
@ -1213,6 +1279,13 @@ int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
"set udp socket buffer size (No CAP_NET_ADMIN privileges?)",
DEC);
LOG(logDEBUG1) << "UDP Socket Buffer Size:" << retval;
socket.Send(OK);
return OK;
}
int ClientInterface::get_udp_socket_buffer_size(Interface &socket) {
int64_t retval = impl()->getUDPSocketBufferSize();
LOG(logDEBUG1) << "UDP Socket Buffer Size:" << retval;
return socket.sendResult(retval);
}
@ -1236,7 +1309,8 @@ int ClientInterface::set_frames_per_file(Interface &socket) {
auto retval = static_cast<int>(impl()->getFramesPerFile());
validate(index, retval, "set frames per file", DEC);
LOG(logDEBUG1) << "frames per file:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_frames_per_file(Interface &socket) {
@ -1270,7 +1344,8 @@ int ClientInterface::check_version_compatibility(Interface &socket) {
} else {
LOG(logINFO) << "Compatibility with Client: Successful";
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_discard_policy(Interface &socket) {
@ -1284,7 +1359,8 @@ int ClientInterface::set_discard_policy(Interface &socket) {
int retval = impl()->getFrameDiscardPolicy();
validate(index, retval, "set discard policy", DEC);
LOG(logDEBUG1) << "frame discard policy:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_discard_policy(Interface &socket) {
@ -1305,7 +1381,8 @@ int ClientInterface::set_padding_enable(Interface &socket) {
auto retval = static_cast<int>(impl()->getFramePaddingEnable());
validate(index, retval, "set frame padding enable", DEC);
LOG(logDEBUG1) << "Frame Padding Enable:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_padding_enable(Interface &socket) {
@ -1331,7 +1408,8 @@ int ClientInterface::set_deactivated_padding_enable(
auto retval = static_cast<int>(impl()->getDeactivatedPadding());
validate(enable, retval, "set deactivated padding enable", DEC);
LOG(logDEBUG1) << "Deactivated Padding Enable: " << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_deactivated_padding_enable(
@ -1382,7 +1460,8 @@ int ClientInterface::set_adc_mask(Interface &socket) {
throw RuntimeError(os.str());
}
LOG(logDEBUG1) << "1Gb ADC enable mask retval: " << retval;
return socket.sendResult(retval);
socket.Send(OK);
return OK;
}
int ClientInterface::set_dbit_list(Interface &socket) {
@ -1397,7 +1476,8 @@ int ClientInterface::set_dbit_list(Interface &socket) {
LOG(logDEBUG1) << "\n";
verifyIdle(socket);
impl()->setDbitList(args);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_dbit_list(Interface &socket) {
@ -1424,7 +1504,8 @@ int ClientInterface::set_dbit_offset(Interface &socket) {
int retval = impl()->getDbitOffset();
validate(arg, retval, "set dbit offset", DEC);
LOG(logDEBUG1) << "Dbit offset retval: " << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_dbit_offset(Interface &socket) {
@ -1449,7 +1530,8 @@ int ClientInterface::set_quad_type(Interface &socket) {
int retval = impl()->getQuad() ? 1 : 0;
validate(quadEnable, retval, "set quad", DEC);
LOG(logDEBUG1) << "quad retval:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_read_n_lines(Interface &socket) {
@ -1462,7 +1544,8 @@ int ClientInterface::set_read_n_lines(Interface &socket) {
int retval = impl()->getReadNLines();
validate(arg, retval, "set read n lines", DEC);
LOG(logDEBUG1) << "read n lines retval:" << retval;
return socket.Send(OK);
socket.Send(OK);
return OK;
}
sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
@ -1476,9 +1559,7 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
LOG(logERROR) << "Failed to get udp ethernet interface from IP " << arg << ". Got " << eth;
}
impl()->setEthernetInterface(eth);
if (myDetectorType == EIGER) {
impl()->setEthernetInterface2(eth);
}
// get mac address
auto retval = sls::InterfaceNameToMac(eth);
if (retval == 0) {
@ -1496,55 +1577,13 @@ int ClientInterface::set_udp_ip(Interface &socket) {
return socket.sendResult(retval);
}
sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
// getting eth
std::string eth = sls::IpToInterfaceName(arg.str());
if (eth == "none") {
throw RuntimeError("Failed to get udp ethernet interface2 from IP " + arg.str());
}
if (eth.find('.') != std::string::npos) {
eth = "";
LOG(logERROR) << "Failed to get udp ethernet interface2 from IP " << arg << ". Got " << eth;
}
impl()->setEthernetInterface2(eth);
// get mac address
auto retval = sls::InterfaceNameToMac(eth);
if (retval == 0) {
throw RuntimeError("Failed to get udp mac adddress2 to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n");
}
return retval;
}
int ClientInterface::set_udp_ip2(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>();
verifyIdle(socket);
if (myDetectorType != JUNGFRAU) {
throw RuntimeError("UDP Destination IP2 not implemented for this detector");
}
LOG(logINFO) << "Received UDP IP2: " << arg;
auto retval = setUdpIp2(arg);
LOG(logINFO) << "Receiver MAC Address2: " << retval;
return socket.sendResult(retval);
}
int ClientInterface::set_udp_port(Interface &socket) {
auto arg = socket.Receive<int>();
verifyIdle(socket);
LOG(logDEBUG1) << "Setting UDP Port:" << arg;
impl()->setUDPPortNumber(arg);
return socket.Send(OK);
}
int ClientInterface::set_udp_port2(Interface &socket) {
auto arg = socket.Receive<int>();
verifyIdle(socket);
if (myDetectorType != JUNGFRAU && myDetectorType != EIGER) {
throw RuntimeError("UDP Destination Port2 not implemented for this detector");
}
LOG(logDEBUG1) << "Setting UDP Port:" << arg;
impl()->setUDPPortNumber2(arg);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_interfaces(Interface &socket) {
@ -1560,7 +1599,8 @@ int ClientInterface::set_num_interfaces(Interface &socket) {
} catch(const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " + std::to_string(arg));
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::set_adc_mask_10g(Interface &socket) {
@ -1580,7 +1620,8 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
throw RuntimeError(os.str());
}
LOG(logDEBUG1) << "10Gb ADC enable mask retval: " << retval;
return socket.sendResult(retval);
socket.Send(OK);
return OK;
}
int ClientInterface::set_num_counters(Interface &socket) {
@ -1588,7 +1629,8 @@ int ClientInterface::set_num_counters(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting counters: " << arg;
impl()->setNumberofCounters(arg);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::increment_file_index(Interface &socket) {
@ -1597,7 +1639,8 @@ int ClientInterface::increment_file_index(Interface &socket) {
LOG(logDEBUG1) << "Incrementing file index";
impl()->setFileIndex(impl()->getFileIndex() + 1);
}
return socket.Send(OK);
socket.Send(OK);
return OK;
}
@ -1607,7 +1650,8 @@ int ClientInterface::set_additional_json_parameter(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting additional json parameter (" << args[0] << "): " << args[1];
impl()->setAdditionalJsonParameter(args[0], args[1]);
return socket.Send(OK);
socket.Send(OK);
return OK;
}
int ClientInterface::get_additional_json_parameter(Interface &socket) {

View File

@ -61,7 +61,8 @@ class ClientInterface : private virtual slsDetectorDefs {
int exec_command(sls::ServerInterface &socket);
int exit_server(sls::ServerInterface &socket);
int lock_receiver(sls::ServerInterface &socket);
int set_lock_server(sls::ServerInterface &socket);
int get_lock_server(sls::ServerInterface &socket);
int get_last_client_ip(sls::ServerInterface &socket);
int set_port(sls::ServerInterface &socket);
int get_version(sls::ServerInterface &socket);
@ -104,11 +105,14 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_overwrite(sls::ServerInterface &socket);
int enable_tengiga(sls::ServerInterface &socket);
int set_fifo_depth(sls::ServerInterface &socket);
int get_fifo_depth(sls::ServerInterface &socket);
int set_activate(sls::ServerInterface &socket);
int set_streaming(sls::ServerInterface &socket);
int get_streaming(sls::ServerInterface &socket);
int set_streaming_timer(sls::ServerInterface &socket);
int get_streaming_timer(sls::ServerInterface &socket);
int set_flipped_data(sls::ServerInterface &socket);
int get_flipped_data(sls::ServerInterface &socket);
int set_file_format(sls::ServerInterface &socket);
int get_file_format(sls::ServerInterface &socket);
int set_streaming_port(sls::ServerInterface &socket);
@ -121,6 +125,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_additional_json_header(sls::ServerInterface &socket);
int get_additional_json_header(sls::ServerInterface &socket);
int set_udp_socket_buffer_size(sls::ServerInterface &socket);
int get_udp_socket_buffer_size(sls::ServerInterface &socket);
int get_real_udp_socket_buffer_size(sls::ServerInterface &socket);
int set_frames_per_file(sls::ServerInterface &socket);
int get_frames_per_file(sls::ServerInterface &socket);
@ -141,10 +146,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_read_n_lines(sls::ServerInterface &socket);
sls::MacAddr setUdpIp(sls::IpAddr arg);
int set_udp_ip(sls::ServerInterface &socket);
sls::MacAddr setUdpIp2(sls::IpAddr arg);
int set_udp_ip2(sls::ServerInterface &socket);
int set_udp_port(sls::ServerInterface &socket);
int set_udp_port2(sls::ServerInterface &socket);
int set_num_interfaces(sls::ServerInterface &socket);
int set_adc_mask_10g(sls::ServerInterface &socket);
int set_num_counters(sls::ServerInterface &socket);

View File

@ -17,7 +17,7 @@ const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot) :
uint64_t* fi, int fd, int* nr, bool* qe, uint64_t* tot) :
ThreadObject(ind, TypeName),
fifo(f),
dynamicRange(dr),
@ -27,8 +27,8 @@ DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
quadEnable(qe),
totalNumFrames(tot)
{
numDet[0] = nd[0];
numDet[1] = nd[1];
numRx[0] = nr[0];
numRx[1] = nr[1];
LOG(logDEBUG) << "DataStreamer " << ind << " created";
}
@ -74,9 +74,9 @@ void DataStreamer::SetGeneralData(GeneralData* g) {
generalData->Print();
}
void DataStreamer::SetNumberofDetectors(int* nd) {
numDet[0] = nd[0];
numDet[1] = nd[1];
void DataStreamer::SetReceiverShape(int* nr) {
numRx[0] = nr[0];
numRx[1] = nr[1];
}
void DataStreamer::SetFlippedDataX(int fd) {
@ -211,8 +211,8 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.dynamicRange = *dynamicRange;
zHeader.fileIndex = *fileIndex;
zHeader.ndetx = numDet[0];
zHeader.ndety = numDet[1];
zHeader.nSocketX = numRx[0];
zHeader.nSocketY = numRx[1];
zHeader.npixelsx = nx;
zHeader.npixelsy = ny;
zHeader.imageSize = size;

View File

@ -29,12 +29,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param r roi
* @param fi pointer to file index
* @param fd flipped data enable for x dimension
* @param nd pointer to number of detectors in each dimension
* @param nd pointer to number of receivers in each dimension
* @param qe pointer to quad Enable
* @param tot pointer to total number of frames
*/
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot);
uint64_t* fi, int fd, int* nr, bool* qe, uint64_t* tot);
/**
* Destructor
@ -60,10 +60,10 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
void SetGeneralData(GeneralData* g);
/**
* Set number of detectors
* @param number of detectors in both dimensions
* Set receiver shape
* @param number of receivers in both dimensions
*/
void SetNumberofDetectors(int* nd);
void SetReceiverShape(int* nr);
/**
* Set Flipped data enable across x dimension
@ -178,8 +178,8 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** Complete buffer used for roi, eg. shortGotthard */
char* completeBuffer{nullptr};
/** Number of Detectors in X and Y dimension */
int numDet[2];
/** Number of Recievers in X and Y dimension */
int numRx[2];
/** Quad Enable */
bool* quadEnable;

View File

@ -64,9 +64,6 @@ public:
/** Default Fifo depth */
uint32_t defaultFifoDepth;
/** Threads per receiver */
uint32_t threadsPerReceiver;
/** Size of a header packet */
uint32_t headerPacketSize;
@ -105,7 +102,6 @@ public:
maxFramesPerFile(0),
fifoBufferHeaderSize(0),
defaultFifoDepth(0),
threadsPerReceiver(1),
headerPacketSize(0),
nPixelsXComplete(0),
nPixelsYComplete(0),
@ -233,7 +229,6 @@ public:
LOG(level) << "Max Frames Per File: " << maxFramesPerFile;
LOG(level) << "Fifo Buffer Header Size: " << fifoBufferHeaderSize;
LOG(level) << "Default Fifo Depth: " << defaultFifoDepth;
LOG(level) << "Threads Per Receiver: " << threadsPerReceiver;
LOG(level) << "Header Packet Size: " << headerPacketSize;
LOG(level) << "Complete Pixels X: " << nPixelsXComplete;
LOG(level) << "Complete Pixels Y: " << nPixelsYComplete;
@ -415,7 +410,6 @@ class EigerData : public GeneralData {
maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 1000;
threadsPerReceiver = 2;
headerPacketSize = 40;
standardheader = true;
};
@ -479,7 +473,6 @@ class JungfrauData : public GeneralData {
nPixelsY = 256;
packetsPerFrame = 64;
imageSize = dataSize * packetsPerFrame;
threadsPerReceiver = 2;
defaultUdpSocketBufferSize = (500 * 1024 * 1024);
}
@ -488,7 +481,6 @@ class JungfrauData : public GeneralData {
nPixelsY = 512;
packetsPerFrame = 128;
imageSize = dataSize * packetsPerFrame;
threadsPerReceiver = 1;
defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
}
}

View File

@ -38,23 +38,22 @@ void Implementation::DeleteMembers() {
}
additionalJsonHeader.clear();
listener.clear();
dataProcessor.clear();
dataStreamer.clear();
fifo.clear();
eth.clear();
udpPortNum.clear();
ctbDbitList.clear();
listener.reset();
dataProcessor.reset();
dataStreamer.reset();
fifo.reset();
}
void Implementation::InitializeMembers() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
// config parameters
numThreads = 1;
myDetectorType = GENERIC;
for (int i = 0; i < MAX_DIMENSIONS; ++i)
for (int i = 0; i < MAX_DIMENSIONS; ++i) {
numDet[i] = 0;
numRx[i] = 0;
}
detID = 0;
detHostname = "";
silentMode = false;
@ -77,13 +76,10 @@ void Implementation::InitializeMembers() {
stoppedFlag = false;
// network configuration (UDP)
interfaceId = 0;
numUDPInterfaces = 1;
eth.resize(MAX_NUMBER_OF_LISTENING_THREADS);
udpPortNum.resize(MAX_NUMBER_OF_LISTENING_THREADS);
for (int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i) {
eth[i] = "";
udpPortNum[i] = DEFAULT_UDP_PORTNO + i;
}
eth = "";
udpPortNum = DEFAULT_UDP_PORTNO;
udpSocketBufferSize = 0;
actualUDPSocketBufferSize = 0;
@ -168,44 +164,36 @@ void Implementation::SetLocalNetworkParameters() {
void Implementation::SetThreadPriorities() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
for (const auto &it : listener) {
it->SetThreadPriority(LISTENER_PRIORITY);
}
listener->SetThreadPriority(LISTENER_PRIORITY);
}
void Implementation::SetupFifoStructure() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
fifo.clear();
for (int i = 0; i < numThreads; ++i) {
// create fifo structure
try {
fifo.push_back(sls::make_unique<Fifo>(
i,
fifo = sls::make_unique<Fifo>( 0,
(generalData->imageSize) + (generalData->fifoBufferHeaderSize),
fifoDepth));
fifoDepth);
} catch (...) {
fifo.clear();
fifoDepth = 0;
throw sls::RuntimeError("Could not allocate memory for fifo structure " +
std::to_string(i) + ". FifoDepth is now 0.");
throw sls::RuntimeError("Could not allocate memory for fifo structure "
". FifoDepth is now 0.");
}
// set the listener & dataprocessor threads to point to the right fifo
if (listener.size())
listener[i]->SetFifo(fifo[i].get());
if (dataProcessor.size())
dataProcessor[i]->SetFifo(fifo[i].get());
if (dataStreamer.size())
dataStreamer[i]->SetFifo(fifo[i].get());
}
if (listener)
listener->SetFifo(fifo.get());
if (dataProcessor)
dataProcessor->SetFifo(fifo.get());
if (dataStreamEnable)
dataStreamer->SetFifo(fifo.get());
LOG(logINFO) << "Memory Allocated Per Fifo: "
LOG(logINFO) << "Memory Allocated: "
<< (double)(((size_t)(generalData->imageSize) +
(size_t)(generalData->fifoBufferHeaderSize)) *
(size_t)fifoDepth) / (double)(1024 * 1024)
<< " MB";
LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed";
LOG(logINFO) << " Fifo structure(s) reconstructed";
}
@ -260,7 +248,6 @@ void Implementation::setDetectorType(const detectorType d) {
default:
break;
}
numThreads = generalData->threadsPerReceiver;
fifoDepth = generalData->defaultFifoDepth;
udpSocketBufferSize = generalData->defaultUdpSocketBufferSize;
framesPerFile = generalData->maxFramesPerFile;
@ -268,36 +255,29 @@ void Implementation::setDetectorType(const detectorType d) {
SetLocalNetworkParameters();
SetupFifoStructure();
// create threads
for (int i = 0; i < numThreads; ++i) {
try {
auto fifo_ptr = fifo[i].get();
listener.push_back(sls::make_unique<Listener>(
i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], &eth[i],
auto fifo_ptr = fifo.get();
listener = sls::make_unique<Listener>(
0, myDetectorType, fifo_ptr, &status, &udpPortNum, &eth,
&numberOfTotalFrames, &dynamicRange, &udpSocketBufferSize,
&actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode,
&activated, &deactivatedPaddingEnable, &silentMode));
dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
&activated, &deactivatedPaddingEnable, &silentMode);
dataProcessor = sls::make_unique<DataProcessor>(
0, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
&masterFileWriteEnable, &dataStreamEnable,
&dynamicRange, &streamingFrequency, &streamingTimerInMs,
&framePadding, &activated, &deactivatedPaddingEnable,
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
&ctbAnalogDataBytes));
&ctbAnalogDataBytes);
} catch (...) {
listener.clear();
dataProcessor.clear();
throw sls::RuntimeError("Could not create listener/dataprocessor threads (index:" + std::to_string(i) + ")");
}
listener.reset();
dataProcessor.reset();
throw sls::RuntimeError("Could not create listener/dataprocessor threads");
}
// set up writer and callbacks
for (const auto &it : listener)
it->SetGeneralData(generalData);
for (const auto &it : dataProcessor)
it->SetGeneralData(generalData);
listener->SetGeneralData(generalData);
dataProcessor->SetGeneralData(generalData);
SetThreadPriorities();
LOG(logDEBUG) << " Detector type set to " << sls::ToString(d);
@ -308,35 +288,41 @@ int *Implementation::getMultiDetectorSize() const {
return (int *)numDet;
}
void Implementation::setMultiDetectorSize(const int *size) {
void Implementation::setDetectorSize(const int *size) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
std::string log_message = "Detector Size (ports): (";
for (int i = 0; i < MAX_DIMENSIONS; ++i) {
// x dir (colums) each udp port
if (myDetectorType == EIGER && i == X)
numDet[i] = size[i] * 2;
// y dir (rows) each udp port
else if (numUDPInterfaces == 2 && i == Y)
numDet[i] = size[i] * 2;
else
numDet[i] = size[i];
log_message += std::to_string(numDet[i]);
if (i < MAX_DIMENSIONS - 1)
log_message += ", ";
}
log_message += ")";
numDet[X] = size[X];
numDet[Y] = size[Y];
numRx[X] = numDet[X];
numRx[Y] = numDet[Y];
int nd[2] = {numDet[0], numDet[1]};
// calculating receivers shape
switch (myDetectorType) {
case EIGER:
if (quadEnable) {
nd[0] = 1;
nd[1] = 2;
numRx[X] = 1;
numRx[Y] = 2;
} else {
numRx[X] = numDet[X] * 2;
}
for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(nd);
break;
case JUNGFRAU:
if (numUDPInterfaces == 2) {
numRx[Y] = numDet[X] * 2;
} else {
numRx[Y] = numDet[X];
}
break;
default:
break;
}
if (dataStreamEnable)
dataStreamer->SetReceiverShape(numRx);
setDetectorPositionId(detID);
LOG(logINFO) << "Receiver Shape: (" << numRx[X] << ", "
<< numRx[Y] << ")";
}
LOG(logINFO) << log_message;
}
int Implementation::getDetectorPositionId() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
@ -352,20 +338,19 @@ void Implementation::setDetectorPositionId(const int id) {
streamingPort = DEFAULT_ZMQ_RX_PORTNO +
(detID * (myDetectorType == EIGER ? 2 : 1));
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath,
&fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfTotalFrames,
&dynamicRange, &udpPortNum[i], generalData);
}
assert(numDet[1] != 0);
for (unsigned int i = 0; i < listener.size(); ++i) {
dataProcessor->SetupFileWriter(
fileWriteEnable, (int *)numRx, &framesPerFile, &fileName, &filePath,
&fileIndex, &overwriteEnable, &detID, &numUDPInterfaces, &numberOfTotalFrames,
&dynamicRange, &udpPortNum, generalData);
assert(numRx[1] != 0);
uint16_t row = 0, col = 0;
row = (detID % numDet[1]) * ((numUDPInterfaces == 2) ? 2 : 1); // row
col = (detID / numDet[1]) * ((myDetectorType == EIGER) ? 2 : 1) +
i; // col for horiz. udp ports
listener[i]->SetHardCodedPosition(row, col);
}
row = (detID % numRx[1]) * ((myDetectorType == JUNGFRAU &&
numUDPInterfaces == 2) ? 2 : 1); // row
col = (detID / numRx[1]) * ((myDetectorType == EIGER) ? 2 : 1) +
interfaceId; // col for horiz. udp ports
listener->SetHardCodedPosition(row, col);
}
std::string Implementation::getDetectorHostname() const {
@ -458,8 +443,7 @@ void Implementation::setFileFormat(const fileFormat f) {
break;
}
for (const auto &it : dataProcessor)
it->SetFileFormat(f);
dataProcessor->SetFileFormat(f);
LOG(logINFO) << "File Format: " << sls::ToString(fileFormatType);
}
@ -512,12 +496,10 @@ bool Implementation::getFileWriteEnable() const {
void Implementation::setFileWriteEnable(const bool b) {
if (fileWriteEnable != b) {
fileWriteEnable = b;
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
&filePath, &fileIndex, &overwriteEnable, &detID, &numThreads,
&numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData);
}
dataProcessor->SetupFileWriter(
fileWriteEnable, (int *)numRx, &framesPerFile, &fileName,
&filePath, &fileIndex, &overwriteEnable, &detID, &numUDPInterfaces,
&numberOfTotalFrames, &dynamicRange, &udpPortNum, generalData);
}
LOG(logINFO) << "File Write Enable: " << (fileWriteEnable ? "enabled" : "disabled");
@ -571,58 +553,32 @@ slsDetectorDefs::runStatus Implementation::getStatus() const {
}
uint64_t Implementation::getFramesCaught() const {
uint64_t min = -1;
uint32_t flagsum = 0;
for (const auto &it : dataProcessor) {
flagsum += it->GetStartedFlag();
uint64_t curr = it->GetNumFramesCaught();
min = curr < min ? curr : min;
}
// no data processed
if (flagsum != dataProcessor.size())
if (!dataProcessor->GetStartedFlag()) {
return 0;
return min;
}
return dataProcessor->GetNumFramesCaught();
}
uint64_t Implementation::getAcquisitionIndex() const {
uint64_t min = -1;
uint32_t flagsum = 0;
for (const auto &it : dataProcessor) {
flagsum += it->GetStartedFlag();
uint64_t curr = it->GetCurrentFrameIndex();
min = curr < min ? curr : min;
}
// no data processed
if (flagsum != dataProcessor.size())
if (!dataProcessor->GetStartedFlag()) {
return 0;
return min;
}
return dataProcessor->GetCurrentFrameIndex();
}
int Implementation::getProgress() const {
// get minimum of processed frame indices
uint64_t currentFrameIndex = -1;
uint32_t flagsum = 0;
for (const auto &it : dataProcessor) {
flagsum += it->GetStartedFlag();
uint64_t curr = it->GetProcessedIndex();
currentFrameIndex = curr < currentFrameIndex ? curr : currentFrameIndex;
uint64_t currentFrameIndex = 0;
// data processed
if (dataProcessor->GetStartedFlag()) {
currentFrameIndex = dataProcessor->GetProcessedIndex();
}
// no data processed
if (flagsum != dataProcessor.size()) {
currentFrameIndex = -1;
return (100.00 * ((double)(currentFrameIndex) / (double)numberOfTotalFrames));
}
return (100.00 * ((double)(currentFrameIndex + 1) / (double)numberOfTotalFrames));
}
std::vector<uint64_t> Implementation::getNumMissingPackets() const {
std::vector<uint64_t> mp(numThreads);
for (int i = 0; i < numThreads; i++) {
uint64_t Implementation::getNumMissingPackets() const {
uint64_t mp = 0;
int np = generalData->packetsPerFrame;
uint64_t totnp = np;
// partial readout
@ -630,8 +586,7 @@ std::vector<uint64_t> Implementation::getNumMissingPackets() const {
totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT);
}
totnp *= numberOfTotalFrames;
mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp);
}
mp = listener->GetNumMissingPacket(stoppedFlag, totnp);
return mp;
}
@ -642,7 +597,7 @@ void Implementation::startReceiver() {
ResetParametersforNewAcquisition();
// listener
CreateUDPSockets();
CreateUDPSocket();
// callbacks
if (startAcquisitionCallBack) {
@ -688,69 +643,54 @@ void Implementation::stopReceiver() {
bool running = true;
while (running) {
running = false;
for (const auto &it : listener)
if (it->IsRunning())
if (listener->IsRunning())
running = true;
for (const auto &it : dataProcessor)
if (it->IsRunning())
if (dataProcessor->IsRunning())
running = true;
usleep(5000);
}
// create virtual file
if (fileWriteEnable && fileFormatType == HDF5) {
uint64_t maxIndexCaught = 0;
bool anycaught = false;
for (const auto &it : dataProcessor) {
maxIndexCaught =
std::max(maxIndexCaught, it->GetProcessedIndex());
if (it->GetStartedFlag())
anycaught = true;
}
if (fileWriteEnable && fileFormatType == HDF5 && interfaceId == 0) {
// to create virtual file & set files/acquisition to 0 (only hdf5 at the
// moment)
dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught);
dataProcessor->EndofAcquisition(
dataProcessor->GetStartedFlag(),
dataProcessor->GetProcessedIndex());
}
// wait for the processes (dataStreamer) to be done
if (dataStreamEnable) {
running = true;
while (running) {
running = false;
for (const auto &it : dataStreamer)
if (it->IsRunning())
running = true;
running = dataStreamer->IsRunning();
usleep(5000);
}
}
status = RUN_FINISHED;
LOG(logINFO) << "Status: " << sls::ToString(status);
{ // statistics
std::vector<uint64_t> mp = getNumMissingPackets();
uint64_t tot = 0;
for (int i = 0; i < numThreads; i++) {
int nf = dataProcessor[i]->GetNumFramesCaught();
tot += nf;
uint64_t mp = getNumMissingPackets();
uint64_t tot = dataProcessor->GetNumFramesCaught();
TLogLevel lev =
(((int64_t)mp[i]) > 0) ? logINFORED : logINFOGREEN;
(((int64_t)mp) > 0) ? logINFORED : logINFOGREEN;
LOG(lev) <<
// udp port number could be the second if selected interface is
// 2 for jungfrau
"Summary of Port " << udpPortNum[i]
<< "\n\tMissing Packets\t\t: " << mp[i]
<< "\n\tComplete Frames\t\t: " << nf
"Summary of Port " << udpPortNum
<< "\n\tMissing Packets\t\t: " << mp
<< "\n\tComplete Frames\t\t: " << tot
<< "\n\tLast Frame Caught\t: "
<< listener[i]->GetLastFrameIndexCaught();
}
<< listener->GetLastFrameIndexCaught();
if (!activated) {
LOG(logINFORED) << "Deactivated Receiver";
}
// callback
if (acquisitionFinishedCallBack)
acquisitionFinishedCallBack((tot / numThreads),
pAcquisitionFinished);
acquisitionFinishedCallBack(tot, pAcquisitionFinished);
}
// change status
@ -764,14 +704,12 @@ void Implementation::startReadout() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (status == RUNNING) {
// wait for incoming delayed packets
int totalPacketsReceived = 0;
int totalPacketsReceived = listener->GetPacketsCaught();
int previousValue = -1;
for (const auto &it : listener)
totalPacketsReceived += it->GetPacketsCaught();
// wait for all packets
const int numPacketsToReceive =
numberOfTotalFrames * generalData->packetsPerFrame * listener.size();
numberOfTotalFrames * generalData->packetsPerFrame;
if (totalPacketsReceived != numPacketsToReceive) {
while (totalPacketsReceived != previousValue) {
LOG(logDEBUG3)
@ -780,9 +718,7 @@ void Implementation::startReadout() {
<< " totalPacketsReceived: " << totalPacketsReceived;
usleep(5 * 1000); /* TODO! Need to find optimal time **/
previousValue = totalPacketsReceived;
totalPacketsReceived = 0;
for (const auto &it : listener)
totalPacketsReceived += it->GetPacketsCaught();
totalPacketsReceived = listener->GetPacketsCaught();
LOG(logDEBUG3) << "\tupdated: totalPacketsReceived:"
<< totalPacketsReceived;
@ -791,68 +727,58 @@ void Implementation::startReadout() {
status = TRANSMITTING;
LOG(logINFO) << "Status: Transmitting";
}
// shut down udp sockets to make listeners push dummy (end) packets for
// shut down udp socket to make listeners push dummy (end) packets for
// processors
shutDownUDPSockets();
shutDownUDPSocket();
}
void Implementation::shutDownUDPSockets() {
void Implementation::shutDownUDPSocket() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
for (const auto &it : listener)
it->ShutDownUDPSocket();
listener->ShutDownUDPSocket();
}
void Implementation::closeFiles() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
uint64_t maxIndexCaught = 0;
bool anycaught = false;
for (const auto &it : dataProcessor) {
it->CloseFiles();
maxIndexCaught =
std::max(maxIndexCaught, it->GetProcessedIndex());
if (it->GetStartedFlag())
anycaught = true;
}
dataProcessor->CloseFiles();
// to create virtual file & set files/acquisition to 0 (only hdf5 at the
// moment)
dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught);
if (interfaceId == 0) {
dataProcessor->EndofAcquisition(
dataProcessor->GetStartedFlag(),
dataProcessor->GetProcessedIndex());
}
}
void Implementation::restreamStop() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
for (const auto &it : dataStreamer) {
it->RestreamStop();
}
if (dataStreamEnable) {
dataStreamer->RestreamStop();
LOG(logINFO) << "Restreaming Dummy Header via ZMQ successful";
}
}
void Implementation::ResetParametersforNewAcquisition() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
for (const auto &it : listener)
it->ResetParametersforNewAcquisition();
for (const auto &it : dataProcessor)
it->ResetParametersforNewAcquisition();
listener->ResetParametersforNewAcquisition();
dataProcessor->ResetParametersforNewAcquisition();
if (dataStreamEnable) {
std::ostringstream os;
os << filePath << '/' << fileName;
std::string fnametostream = os.str();
for (const auto &it : dataStreamer)
it->ResetParametersforNewAcquisition(fnametostream);
dataStreamer->ResetParametersforNewAcquisition(fnametostream);
}
}
void Implementation::CreateUDPSockets() {
void Implementation::CreateUDPSocket() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
try{
for (unsigned int i = 0; i < listener.size(); ++i) {
listener[i]->CreateUDPSockets();
}
listener->CreateUDPSocket();
} catch(const sls::RuntimeError &e) {
shutDownUDPSockets();
throw sls::RuntimeError("Could not create UDP Socket(s).");
shutDownUDPSocket();
throw sls::RuntimeError("Could not create UDP Socket.");
}
LOG(logDEBUG) << "UDP socket(s) created successfully.";
@ -886,11 +812,9 @@ void Implementation::SetupWriter() {
}
try {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->CreateNewFile(attr);
}
dataProcessor->CreateNewFile(attr);
} catch(const sls::RuntimeError &e) {
shutDownUDPSockets();
shutDownUDPSocket();
closeFiles();
throw sls::RuntimeError("Could not create file.");
}
@ -900,17 +824,13 @@ void Implementation::StartRunning() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
// set running mask and post semaphore to start the inner loop in execution
// thread
for (const auto &it : listener) {
it->StartRunning();
it->Continue();
}
for (const auto &it : dataProcessor) {
it->StartRunning();
it->Continue();
}
for (const auto &it : dataStreamer) {
it->StartRunning();
it->Continue();
listener->StartRunning();
listener->Continue();
dataProcessor->StartRunning();
dataProcessor->Continue();
if (dataStreamEnable) {
dataStreamer->StartRunning();
dataStreamer->Continue();
}
}
@ -930,100 +850,12 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
if (numUDPInterfaces != n) {
// reduce number of detectors in y dir (rows) if it had 2 interfaces
// before
if (numUDPInterfaces == 2)
numDet[Y] /= 2;
numUDPInterfaces = n;
// clear all threads and fifos
listener.clear();
dataProcessor.clear();
dataStreamer.clear();
fifo.clear();
// set local variables
generalData->SetNumberofInterfaces(n);
numThreads = generalData->threadsPerReceiver;
udpSocketBufferSize = generalData->defaultUdpSocketBufferSize;
// fifo
SetupFifoStructure();
// create threads
for (int i = 0; i < numThreads; ++i) {
// listener and dataprocessor threads
try {
auto fifo_ptr = fifo[i].get();
listener.push_back(sls::make_unique<Listener>(
i, myDetectorType, fifo_ptr, &status, &udpPortNum[i],
&eth[i], &numberOfTotalFrames, &dynamicRange,
&udpSocketBufferSize, &actualUDPSocketBufferSize,
&framesPerFile, &frameDiscardMode, &activated,
&deactivatedPaddingEnable, &silentMode));
listener[i]->SetGeneralData(generalData);
dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType,
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
&dynamicRange, &streamingFrequency,
&streamingTimerInMs, &framePadding, &activated,
&deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList,
&ctbDbitOffset, &ctbAnalogDataBytes));
dataProcessor[i]->SetGeneralData(generalData);
} catch (...) {
listener.clear();
dataProcessor.clear();
throw sls::RuntimeError("Could not create listener/dataprocessor threads (index:" + std::to_string(i) + ")");
}
// streamer threads
if (dataStreamEnable) {
try {
int fd = flippedDataX;
int nd[2] = {numDet[0], numDet[1]};
if (quadEnable) {
fd = i;
nd[0] = 1;
nd[1] = 2;
}
dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
fd, (int*)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
} catch (...) {
if (dataStreamEnable) {
dataStreamer.clear();
dataStreamEnable = false;
}
throw sls::RuntimeError("Could not create datastreamer threads (index:" + std::to_string(i) + ")");
}
}
}
SetThreadPriorities();
// update (from 1 to 2 interface) & also for printout
setMultiDetectorSize(numDet);
// update row and column in dataprocessor
setDetectorPositionId(detID);
// update call backs
if (rawDataReadyCallBack) {
for (const auto &it : dataProcessor)
it->registerCallBackRawDataReady(rawDataReadyCallBack,
pRawDataReady);
}
if (rawDataModifyReadyCallBack) {
for (const auto &it : dataProcessor)
it->registerCallBackRawDataModifyReady(
rawDataModifyReadyCallBack, pRawDataReady);
}
setDetectorSize(numDet);
// test socket buffer size with current set up
setUDPSocketBufferSize(0);
}
@ -1031,52 +863,40 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
LOG(logINFO) << "Number of Interfaces: " << numUDPInterfaces;
}
int Implementation::getInterfaceId() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return interfaceId;
}
void Implementation::setInterfaceId(const int i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
interfaceId = i;
LOG(logINFO) << "Interface Id: " << interfaceId;
}
std::string Implementation::getEthernetInterface() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return eth[0];
return eth;
}
void Implementation::setEthernetInterface(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
eth[0] = c;
LOG(logINFO) << "Ethernet Interface: " << eth[0];
}
std::string Implementation::getEthernetInterface2() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return eth[1];
}
void Implementation::setEthernetInterface2(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
eth[1] = c;
LOG(logINFO) << "Ethernet Interface 2: " << eth[1];
eth = c;
LOG(logINFO) << "Ethernet Interface: " << eth;
}
uint32_t Implementation::getUDPPortNumber() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return udpPortNum[0];
return udpPortNum;
}
void Implementation::setUDPPortNumber(const uint32_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
udpPortNum[0] = i;
LOG(logINFO) << "UDP Port Number[0]: " << udpPortNum[0];
}
uint32_t Implementation::getUDPPortNumber2() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return udpPortNum[1];
}
void Implementation::setUDPPortNumber2(const uint32_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
udpPortNum[1] = i;
LOG(logINFO) << "UDP Port Number[1]: " << udpPortNum[1];
udpPortNum = i;
LOG(logINFO) << "UDP Port Number[0]: " << udpPortNum;
}
int64_t Implementation::getUDPSocketBufferSize() const {
@ -1086,15 +906,7 @@ int64_t Implementation::getUDPSocketBufferSize() const {
void Implementation::setUDPSocketBufferSize(const int64_t s) {
int64_t size = (s == 0) ? udpSocketBufferSize : s;
size_t listSize = listener.size();
if (myDetectorType == JUNGFRAU && (int)listSize != numUDPInterfaces) {
throw sls::RuntimeError("Number of Interfaces " + std::to_string(numUDPInterfaces) + " do not match listener size " + std::to_string(listSize));
}
for (unsigned int i = 0; i < listSize; ++i) {
listener[i]->CreateDummySocketForUDPSocketBufferSize(size);
}
listener->CreateDummySocketForUDPSocketBufferSize(size);
}
int64_t Implementation::getActualUDPSocketBufferSize() const {
@ -1119,31 +931,26 @@ void Implementation::setDataStreamEnable(const bool enable) {
dataStreamEnable = enable;
// data sockets have to be created again as the client ones are
dataStreamer.clear();
dataStreamer.reset();
if (enable) {
for (int i = 0; i < numThreads; ++i) {
try {
int fd = flippedDataX;
int nd[2] = {numDet[0], numDet[1]};
if (quadEnable) {
fd = i;
nd[0] = 1;
nd[1] = 2;
fd = interfaceId;
}
dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
fd, (int*)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
dataStreamer = sls::make_unique<DataStreamer>(
0, fifo.get(), &dynamicRange, &roi, &fileIndex,
fd, (int*)numRx, &quadEnable, &numberOfTotalFrames);
dataStreamer->SetGeneralData(generalData);
dataStreamer->CreateZmqSockets(
&numUDPInterfaces, streamingPort, streamingSrcIP);
dataStreamer->SetAdditionalJsonHeader(additionalJsonHeader);
} catch (...) {
dataStreamer.clear();
dataStreamer.reset();
dataStreamEnable = false;
throw sls::RuntimeError("Could not set data stream enable.");
}
}
SetThreadPriorities();
}
}
@ -1204,8 +1011,8 @@ std::map<std::string, std::string> Implementation::getAdditionalJsonHeader() con
void Implementation::setAdditionalJsonHeader(const std::map<std::string, std::string> &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
additionalJsonHeader = c;
for (const auto &it : dataStreamer) {
it->SetAdditionalJsonHeader(c);
if (dataStreamEnable) {
dataStreamer->SetAdditionalJsonHeader(c);
}
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader);
}
@ -1240,8 +1047,8 @@ void Implementation::setAdditionalJsonParameter(const std::string &key, const st
additionalJsonHeader[key] = value;
LOG(logINFO) << "Adding additional json parameter (" << key << ") to " << value;
}
for (const auto &it : dataStreamer) {
it->SetAdditionalJsonHeader(additionalJsonHeader);
if (dataStreamEnable) {
dataStreamer->SetAdditionalJsonHeader(additionalJsonHeader);
}
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader);
}
@ -1409,8 +1216,7 @@ void Implementation::setNumberofAnalogSamples(const uint32_t i) {
numberOfAnalogSamples, numberOfDigitalSamples,
tengigaEnable, readoutType);
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
LOG(logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples;
@ -1432,8 +1238,7 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
numberOfAnalogSamples, numberOfDigitalSamples,
tengigaEnable, readoutType);
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
LOG(logINFO) << "Number of Digital Samples: "
@ -1454,8 +1259,7 @@ void Implementation::setNumberofCounters(const int i) {
if (myDetectorType == MYTHEN3) {
generalData->SetNumberofCounters(i, dynamicRange);
// to update npixelsx, npixelsy in file writer
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
}
@ -1475,8 +1279,7 @@ void Implementation::setDynamicRange(const uint32_t i) {
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
generalData->SetDynamicRange(i, tengigaEnable);
// to update npixelsx, npixelsy in file writer
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
fifoDepth = generalData->defaultFifoDepth;
SetupFifoStructure();
}
@ -1497,8 +1300,7 @@ void Implementation::setROI(slsDetectorDefs::ROI arg) {
// only for gotthard
generalData->SetROI(arg);
framesPerFile = generalData->maxFramesPerFile;
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
@ -1547,15 +1349,11 @@ void Implementation::setFlippedDataX(int enable) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
flippedDataX = (enable == 0) ? 0 : 1;
if (dataStreamEnable) {
if (!quadEnable) {
for (const auto &it : dataStreamer) {
it->SetFlippedDataX(flippedDataX);
}
}
else {
if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlippedDataX(0);
dataStreamer[1]->SetFlippedDataX(1);
dataStreamer->SetFlippedDataX(flippedDataX);
} else {
dataStreamer->SetFlippedDataX(interfaceId);
}
}
@ -1571,19 +1369,14 @@ void Implementation::setQuad(const bool b) {
if (quadEnable != b) {
quadEnable = b;
if (dataStreamEnable) {
if (!quadEnable) {
for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(numDet);
it->SetFlippedDataX(flippedDataX);
}
dataStreamer->SetReceiverShape(numRx);
dataStreamer->SetFlippedDataX(flippedDataX);
} else {
int size[2] = {1, 2};
for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(size);
}
if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlippedDataX(0);
dataStreamer[1]->SetFlippedDataX(1);
dataStreamer->SetReceiverShape(size);
dataStreamer->SetFlippedDataX(interfaceId);
}
}
}
@ -1640,8 +1433,7 @@ void Implementation::setReadoutMode(const readoutMode f) {
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples,
tengigaEnable, readoutType);
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
@ -1664,8 +1456,7 @@ void Implementation::setADCEnableMask(uint32_t mask) {
numberOfAnalogSamples, numberOfDigitalSamples,
tengigaEnable, readoutType);
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
@ -1689,8 +1480,7 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) {
numberOfAnalogSamples, numberOfDigitalSamples,
tengigaEnable, readoutType);
for (const auto &it : dataProcessor)
it->SetPixelDimension();
dataProcessor->SetPixelDimension();
SetupFifoStructure();
}
@ -1742,16 +1532,14 @@ void Implementation::registerCallBackRawDataReady(
void (*func)(char *, char *, uint32_t, void *), void *arg) {
rawDataReadyCallBack = func;
pRawDataReady = arg;
for (const auto &it : dataProcessor)
it->registerCallBackRawDataReady(rawDataReadyCallBack, pRawDataReady);
dataProcessor->registerCallBackRawDataReady(rawDataReadyCallBack, pRawDataReady);
}
void Implementation::registerCallBackRawDataModifyReady(
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
rawDataModifyReadyCallBack = func;
pRawDataReady = arg;
for (const auto &it : dataProcessor)
it->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
dataProcessor->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
pRawDataReady);
}

View File

@ -29,7 +29,7 @@ class Implementation : private virtual slsDetectorDefs {
void setDetectorType(const detectorType d);
int *getMultiDetectorSize() const;
void setMultiDetectorSize(const int *size);
void setDetectorSize(const int *size);
int getDetectorPositionId() const;
void setDetectorPositionId(const int id);
std::string getDetectorHostname() const;
@ -76,12 +76,12 @@ class Implementation : private virtual slsDetectorDefs {
uint64_t getFramesCaught() const;
uint64_t getAcquisitionIndex() const;
int getProgress() const;
std::vector<uint64_t> getNumMissingPackets() const;
uint64_t getNumMissingPackets() const;
void startReceiver();
void setStoppedFlag(bool stopped);
void stopReceiver();
void startReadout();
void shutDownUDPSockets();
void shutDownUDPSocket();
void closeFiles();
void restreamStop();
@ -91,19 +91,15 @@ class Implementation : private virtual slsDetectorDefs {
* Network Configuration (UDP) *
* *
* ************************************************/
int getInterfaceId() const;
void setInterfaceId(const int value);
int getNumberofUDPInterfaces() const;
/* [Jungfrau] */
void setNumberofUDPInterfaces(const int n);
std::string getEthernetInterface() const;
void setEthernetInterface(const std::string &c);
std::string getEthernetInterface2() const;
/* [Jungfrau] */
void setEthernetInterface2(const std::string &c);
uint32_t getUDPPortNumber() const;
void setUDPPortNumber(const uint32_t i);
uint32_t getUDPPortNumber2() const;
/* [Eiger][Jungfrau] */
void setUDPPortNumber2(const uint32_t i);
int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(const int64_t s);
int64_t getActualUDPSocketBufferSize() const;
@ -226,7 +222,7 @@ class Implementation : private virtual slsDetectorDefs {
void SetupFifoStructure();
void ResetParametersforNewAcquisition();
void CreateUDPSockets();
void CreateUDPSocket();
void SetupWriter();
void StartRunning();
@ -238,9 +234,9 @@ class Implementation : private virtual slsDetectorDefs {
* ************************************************/
// config parameters
int numThreads;
detectorType myDetectorType;
int numDet[MAX_DIMENSIONS];
int numRx[MAX_DIMENSIONS];
int detID;
std::string detHostname;
bool silentMode;
@ -263,9 +259,10 @@ class Implementation : private virtual slsDetectorDefs {
bool stoppedFlag;
// network configuration (UDP)
int interfaceId;
int numUDPInterfaces;
std::vector <std::string> eth;
std::vector <uint32_t> udpPortNum;
std::string eth;
uint32_t udpPortNum;
int64_t udpSocketBufferSize;
int64_t actualUDPSocketBufferSize;
@ -318,8 +315,8 @@ class Implementation : private virtual slsDetectorDefs {
// class objects
GeneralData *generalData;
std::vector<std::unique_ptr<Listener>> listener;
std::vector<std::unique_ptr<DataProcessor>> dataProcessor;
std::vector<std::unique_ptr<DataStreamer>> dataStreamer;
std::vector<std::unique_ptr<Fifo>> fifo;
std::unique_ptr<Listener> listener;
std::unique_ptr<DataProcessor> dataProcessor;
std::unique_ptr<DataStreamer> dataStreamer;
std::unique_ptr<Fifo> fifo;
};

View File

@ -112,7 +112,7 @@ void Listener::SetGeneralData(GeneralData* g) {
}
void Listener::CreateUDPSockets() {
void Listener::CreateUDPSocket() {
if (!(*activated)) {
return;
}

View File

@ -83,9 +83,9 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void SetGeneralData(GeneralData* g);
/**
* Creates UDP Sockets
* Creates UDP Socket
*/
void CreateUDPSockets();
void CreateUDPSocket();
/**
* Shuts down and deletes UDP Sockets

View File

@ -26,10 +26,10 @@ struct zmqHeader {
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 sockets in x axis */
uint32_t nSocketX{0};
/** number of sockets in y axis */
uint32_t nSocketY{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 */

View File

@ -32,6 +32,7 @@
/** default ports */
#define DEFAULT_PORTNO 1952
#define DEFAULT_RX_PORTNO 1954
#define DEFAULT_UDP_PORTNO 50001
#define DEFAULT_ZMQ_CL_PORTNO 30001
#define DEFAULT_ZMQ_RX_PORTNO 30001
@ -466,9 +467,11 @@ class slsDetectorDefs {
*/
struct rxParameters {
detectorType detType{GENERIC};
xy multiSize;
int detId{0};
xy detectorSize;
int moduleId{0};
char hostname[MAX_STR_LENGTH];
int interfaceId{0};
uint32_t zmq_ip{0U};
int udpInterfaces{1};
int udp_dstport{0};
uint32_t udp_dstip{0U};

View File

@ -204,7 +204,8 @@ enum detFuncs{
F_EXEC_RECEIVER_COMMAND,
F_EXIT_RECEIVER,
F_LOCK_RECEIVER,
F_SET_LOCK_RECEIVER,
F_GET_LOCK_RECEIVER,
F_GET_LAST_RECEIVER_CLIENT_IP,
F_SET_RECEIVER_PORT,
F_GET_RECEIVER_VERSION,
@ -244,11 +245,14 @@ enum detFuncs{
F_GET_RECEIVER_OVERWRITE,
F_ENABLE_RECEIVER_TEN_GIGA,
F_SET_RECEIVER_FIFO_DEPTH,
F_GET_RECEIVER_FIFO_DEPTH,
F_RECEIVER_ACTIVATE,
F_SET_RECEIVER_STREAMING,
F_GET_RECEIVER_STREAMING,
F_RECEIVER_STREAMING_TIMER,
F_SET_RECEIVER_STREAMING_TIMER,
F_GET_RECEIVER_STREAMING_TIMER,
F_SET_FLIPPED_DATA_RECEIVER,
F_GET_FLIPPED_DATA_RECEIVER,
F_SET_RECEIVER_FILE_FORMAT,
F_GET_RECEIVER_FILE_FORMAT,
F_SET_RECEIVER_STREAMING_PORT,
@ -260,8 +264,9 @@ enum detFuncs{
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_UDP_SOCK_BUF_SIZE,
F_GET_RECEIVER_UDP_SOCK_BUF_SIZE,
F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE,
F_SET_RECEIVER_FRAMES_PER_FILE,
F_GET_RECEIVER_FRAMES_PER_FILE,
F_RECEIVER_CHECK_VERSION,
@ -280,9 +285,7 @@ enum detFuncs{
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_NUM_COUNTERS,
@ -492,7 +495,8 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND";
case F_EXIT_RECEIVER: return "F_EXIT_RECEIVER";
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER";
case F_SET_LOCK_RECEIVER: return "F_SET_LOCK_RECEIVER";
case F_GET_LOCK_RECEIVER: return "F_GET_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";
@ -533,11 +537,14 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
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_GET_RECEIVER_FIFO_DEPTH: return "F_GET_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_RECEIVER_STREAMING_TIMER: return "F_SET_RECEIVER_STREAMING_TIMER";
case F_GET_RECEIVER_STREAMING_TIMER: return "F_GET_RECEIVER_STREAMING_TIMER";
case F_SET_FLIPPED_DATA_RECEIVER: return "F_SET_FLIPPED_DATA_RECEIVER";
case F_GET_FLIPPED_DATA_RECEIVER: return "F_GET_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";
@ -549,8 +556,9 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
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_UDP_SOCK_BUF_SIZE: return "F_SET_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_GET_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_GET_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_GET_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";
@ -569,9 +577,7 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
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_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS";

View File

@ -187,8 +187,8 @@ int ZmqSocket::SendHeader(
header.jsonversion,
header.dynamicRange,
header.fileIndex,
header.ndetx,
header.ndety,
header.nSocketX,
header.nSocketY,
header.npixelsx,
header.npixelsy,
header.imageSize,
@ -319,8 +319,8 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
zHeader.data = ((document["data"].GetUint()) == 0) ? false : true;
zHeader.dynamicRange = document["bitmode"].GetUint();
zHeader.fileIndex = document["fileIndex"].GetUint64();
zHeader.ndetx = document["detshape"][0].GetUint();
zHeader.ndety = document["detshape"][1].GetUint();
zHeader.nSocketX = document["detshape"][0].GetUint();
zHeader.nSocketY = document["detshape"][1].GetUint();
zHeader.npixelsx = document["shape"][0].GetUint();
zHeader.npixelsy = document["shape"][1].GetUint();
zHeader.imageSize = document["size"].GetUint();