mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-13 21:37:13 +02:00
Compare commits
56 Commits
2020.04.08
...
con3
Author | SHA1 | Date | |
---|---|---|---|
c4c2866905 | |||
b90f9b046f | |||
d66df844e5 | |||
4f712fcd70 | |||
bb32b2f653 | |||
085cbbf0d6 | |||
45a770cf38 | |||
990008c9d9 | |||
5339e16101 | |||
c976c63fb5 | |||
9ee2d389fb | |||
8d0146949c | |||
6de68eacc2 | |||
94103a05b1 | |||
1185f1ea17 | |||
d3f420ffd4 | |||
6b5511c9e5 | |||
d8aa1ab08e | |||
b4c31327d6 | |||
c408f9807a | |||
c1ae67ac46 | |||
9df128fced | |||
e39ec65d19 | |||
601be462af | |||
68f76e5356 | |||
8afa11ed33 | |||
bc389f4825 | |||
095ced153c | |||
1d31695cc1 | |||
df63a6dffe | |||
cfa9049ed3 | |||
a1a5a20845 | |||
9a208caca8 | |||
78fb8080ce | |||
cd45f9d45b | |||
c725a05ef8 | |||
d536ad2b5b | |||
815b6a37aa | |||
655a410d43 | |||
97ba81d923 | |||
3d00eed0f0 | |||
2921cbfac8 | |||
a7f5300455 | |||
2f33a1a479 | |||
39fa5e0185 | |||
ba4985ed4d | |||
f811c065d1 | |||
3a1d87728c | |||
0652ff6b5a | |||
373e177274 | |||
6dd6685e7d | |||
38c31fdada | |||
b3fe0e79bc | |||
215e4a56fd | |||
71a68c2022 | |||
55f8497eac |
@ -320,7 +320,7 @@ public:
|
||||
// int nnx, nny, ns;
|
||||
int nn=dets[0]->getImageSize(nnx, nny,ns, nsy);
|
||||
if (image) {
|
||||
delete image;
|
||||
delete [] image;
|
||||
image=NULL;
|
||||
}
|
||||
image=new int[nn];
|
||||
|
@ -429,7 +429,7 @@ int *getClusters(char *data, int *ph=NULL) {
|
||||
max=*v;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Binary file not shown.
@ -898,7 +898,7 @@ int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int
|
||||
|
||||
|
||||
|
||||
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) {
|
||||
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits, int top) {
|
||||
LOG(logINFO, ("Setting Trimbits\n"));
|
||||
|
||||
//for (int iy=10000;iy<20020;++iy)//263681
|
||||
@ -963,7 +963,7 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) {
|
||||
int i;
|
||||
for(i=0;i<8;i++) { // column loop i
|
||||
|
||||
if (Module_TopAddressIsValid(&modules[1])) {
|
||||
if (top==1) {
|
||||
trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low
|
||||
trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper
|
||||
trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low
|
||||
@ -1572,12 +1572,12 @@ int Feb_Control_StopAcquisition() {
|
||||
|
||||
|
||||
|
||||
int Feb_Control_SaveAllTrimbitsTo(int value) {
|
||||
int Feb_Control_SaveAllTrimbitsTo(int value, int top) {
|
||||
unsigned int chanregs[Feb_Control_trimbit_size];
|
||||
int i;
|
||||
for(i=0;i<Feb_Control_trimbit_size;i++)
|
||||
chanregs[i] = value;
|
||||
return Feb_Control_SetTrimbits(0,chanregs);
|
||||
return Feb_Control_SetTrimbits(0,chanregs, top);
|
||||
}
|
||||
|
||||
|
||||
|
@ -93,9 +93,9 @@ int Feb_Control_SetDAC(char* s, int value, int is_a_voltage_mv);
|
||||
int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv);
|
||||
int Feb_Control_GetDACName(unsigned int dac_num,char* s);
|
||||
|
||||
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits);
|
||||
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits, int top);
|
||||
unsigned int* Feb_Control_GetTrimbits();
|
||||
int Feb_Control_SaveAllTrimbitsTo(int value);
|
||||
int Feb_Control_SaveAllTrimbitsTo(int value, int top);
|
||||
int Feb_Control_Reset();
|
||||
int Feb_Control_PrepareForAcquisition();
|
||||
|
||||
|
Binary file not shown.
@ -759,7 +759,7 @@ int64_t getSubExpTime() {
|
||||
#endif
|
||||
}
|
||||
|
||||
int setDeadTime(int64_t val) {
|
||||
int setSubDeadTime(int64_t val) {
|
||||
LOG(logINFO, ("Setting subdeadtime %lld ns\n", (long long int)val));
|
||||
#ifndef VIRTUAL
|
||||
// get subexptime
|
||||
@ -781,7 +781,7 @@ int setDeadTime(int64_t val) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getDeadTime() {
|
||||
int64_t getSubDeadTime() {
|
||||
#ifndef VIRTUAL
|
||||
// get subexptime
|
||||
int64_t subexptime = Feb_Control_GetSubFrameExposureTime();
|
||||
@ -890,7 +890,7 @@ int setModule(sls_detector_module myMod, char* mess) {
|
||||
}
|
||||
|
||||
//set trimbits
|
||||
if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(), tt)) {
|
||||
if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(), tt,top)) {
|
||||
sprintf(mess, "Could not set module. Could not set trimbits\n");
|
||||
LOG(logERROR, (mess));
|
||||
setSettings(UNDEFINED);
|
||||
@ -1671,7 +1671,7 @@ void setExternalGating(int enable[]) {
|
||||
|
||||
int setAllTrimbits(int val) {
|
||||
#ifndef VIRTUAL
|
||||
if (!Feb_Control_SaveAllTrimbitsTo(val)) {
|
||||
if (!Feb_Control_SaveAllTrimbitsTo(val,top)) {
|
||||
LOG(logERROR, ("Could not set all trimbits\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -52,12 +52,11 @@ int Server_VerifyLock();
|
||||
* Server sends result to client (also set ret to force_update if different clients)
|
||||
* @param fileDes file descriptor for the socket
|
||||
* @param itype 32 or 64 or others to determine to swap data from big endian to little endian
|
||||
* @param update 1 if one must update if different clients, else 0
|
||||
* @param retval pointer to result
|
||||
* @param retvalSize size of result
|
||||
* @returns result of operation
|
||||
*/
|
||||
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize);
|
||||
int Server_SendResult(int fileDes, intType itype, void* retval, int retvalSize);
|
||||
|
||||
/**
|
||||
* Convert mac address from integer to char array
|
||||
|
@ -206,8 +206,8 @@ int64_t getBurstPeriod();
|
||||
#ifdef EIGERD
|
||||
int setSubExpTime(int64_t val);
|
||||
int64_t getSubExpTime();
|
||||
int setDeadTime(int64_t val);
|
||||
int64_t getDeadTime();
|
||||
int setSubDeadTime(int64_t val);
|
||||
int64_t getSubDeadTime();
|
||||
int64_t getMeasuredPeriod();
|
||||
int64_t getMeasuredSubPeriod();
|
||||
#endif
|
||||
|
@ -216,4 +216,5 @@ int get_timing_source(int);
|
||||
int set_timing_source(int);
|
||||
int get_num_channels(int);
|
||||
int update_rate_correction(int);
|
||||
int get_receiver_parameters(int);
|
||||
|
||||
|
@ -577,7 +577,7 @@ int Server_VerifyLock() {
|
||||
}
|
||||
|
||||
|
||||
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) {
|
||||
int Server_SendResult(int fileDes, intType itype, void* retval, int retvalSize) {
|
||||
|
||||
// send success of operation
|
||||
int ret1 = ret;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@ set(SOURCES
|
||||
src/slsDetectorUsers.cpp
|
||||
src/Module.cpp
|
||||
src/Detector.cpp
|
||||
src/Receiver.cpp
|
||||
src/CmdProxy.cpp
|
||||
src/CmdParser.cpp
|
||||
)
|
||||
|
@ -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 = {});
|
||||
|
||||
/** cannot be for multiple detectors as port is unique */
|
||||
void setRxHostname(const int udpInterface, const std::string &hostname,
|
||||
const int port, int module_id);
|
||||
|
||||
/** multiple rx hostnames (same as setRxHostname) */
|
||||
void setRxHostname(const std::vector<std::string> &name);
|
||||
|
||||
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
|
@ -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) {
|
||||
os << "running, idle]\n\tReceiver listener status."
|
||||
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) {
|
||||
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"
|
||||
"Used for TCP control communication between client and receiver "
|
||||
"to configure receiver. Also updates receiver with detector parameters."
|
||||
<< '\n';
|
||||
if (cmd == "rx_hostname") {
|
||||
os << "[hostname or ip address]\n\t"
|
||||
"[hostname or ip address]:[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.\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");
|
||||
}
|
||||
if (det_id != -1) {
|
||||
throw sls::RuntimeError("Cannot add multiple receivers at module level");
|
||||
}
|
||||
det->setRxHostname(args);
|
||||
os << ToString(args) << '\n';
|
||||
if (args[0].find('+') != std::string::npos) {
|
||||
throw sls::RuntimeError("Cannot concatenate receiver hostnames");
|
||||
}
|
||||
std::pair<std::string, int> res = parseHostnameAndPort(args[0]);
|
||||
// removing receivers
|
||||
if (res.first == "none") {
|
||||
det->removeReceivers(udpInterface);
|
||||
os << "removed" << '\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 */
|
||||
|
@ -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,8 +1434,11 @@ 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).");
|
||||
|
157
slsDetectorSoftware/src/Container3.h
Normal file
157
slsDetectorSoftware/src/Container3.h
Normal 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
|
@ -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) {
|
||||
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]);
|
||||
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) {
|
||||
for (int idet = 0; idet < size(); ++idet) {
|
||||
pimpl->Parallel1(&Receiver::setTCPPort, {idet}, {},
|
||||
port++);
|
||||
}
|
||||
} else {
|
||||
pimpl->Parallel1(&Receiver::setTCPPort, {module_id}, {}, port);
|
||||
}
|
||||
} else {
|
||||
pimpl->Parallel(&Module::setReceiverPort, {module_id}, port);
|
||||
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
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Container3.h"
|
||||
#include "Result.h"
|
||||
#include "SharedMemory.h"
|
||||
#include "logger.h"
|
||||
@ -15,22 +15,23 @@ 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>
|
||||
#include <numeric>
|
||||
|
||||
namespace sls{
|
||||
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,27 +69,29 @@ 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,
|
||||
bool update = true);
|
||||
explicit DetectorImpl(int detector_id = 0, bool verify = true,
|
||||
bool update = true);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~DetectorImpl();
|
||||
|
||||
|
||||
|
||||
template <class CT> struct NonDeduced { using type = CT; };
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel(RT (sls::Module::*somefunc)(CT...),
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -115,8 +118,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -143,8 +146,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -168,8 +171,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -188,21 +191,101 @@ 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);
|
||||
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 */
|
||||
void freeSharedMemory();
|
||||
/** Free all modules from current multi Id shared memory and delete members
|
||||
*/
|
||||
void freeSharedMemory();
|
||||
|
||||
/** Get user details of shared memory */
|
||||
std::string getUserDetails();
|
||||
std::string getUserDetails();
|
||||
|
||||
bool getInitialChecks() const;
|
||||
|
||||
@ -217,19 +300,32 @@ 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);
|
||||
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;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfDetectors() const;
|
||||
slsDetectorDefs::xy getNumberOfDetectors() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
|
||||
/** Must be set before setting hostname
|
||||
* Sets maximum number of channels of all sls detectors */
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
|
||||
/** [Eiger][Jungfrau] */
|
||||
bool getGapPixelsinCallback() const;
|
||||
@ -272,7 +368,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* index, loops for measurements, calls required call backs.
|
||||
* @returns OK or FAIL depending on if it already started
|
||||
*/
|
||||
int acquire();
|
||||
int acquire();
|
||||
|
||||
/**
|
||||
* Combines data from all readouts and gives it to the gui
|
||||
@ -284,7 +380,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* Convert raw file
|
||||
* [Jungfrau][Ctb] from pof file
|
||||
* [Mythen3][Gotthard2] from rbf file
|
||||
* @param fname name of pof/rbf file
|
||||
* @param fname name of pof/rbf file
|
||||
* @param fpgasrc pointer in memory to read programming file to
|
||||
* @returns file size
|
||||
*/
|
||||
@ -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();
|
||||
|
||||
@ -351,8 +447,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* @param nPixelsy number of pixels in Y axis (updated)
|
||||
* @returns total data bytes for updated image
|
||||
*/
|
||||
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||
int &nPixelsx, int &nPixelsy);
|
||||
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||
int &nPixelsx, int &nPixelsy);
|
||||
|
||||
void printProgress(double progress);
|
||||
|
||||
@ -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};
|
||||
|
||||
@ -418,4 +523,4 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
void *pCallbackArg{nullptr};
|
||||
};
|
||||
|
||||
}//namespace sls
|
||||
} // namespace sls
|
59
slsDetectorSoftware/src/MaskGenerator.h
Normal file
59
slsDetectorSoftware/src/MaskGenerator.h
Normal 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
@ -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,11 +103,13 @@ 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
|
||||
@ -176,13 +158,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
detectorType getDetectorType() const;
|
||||
|
||||
/**
|
||||
* Gets detector type from detector and set it in receiver
|
||||
* @param type the detector type
|
||||
* @returns detector type in receiver
|
||||
*/
|
||||
int setDetectorType(detectorType type = GET_DETECTOR_TYPE);
|
||||
|
||||
/**
|
||||
* Update total number of channels (chiptestboard or moench)
|
||||
* from the detector server
|
||||
@ -220,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;
|
||||
@ -233,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)
|
||||
@ -313,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
|
||||
*/
|
||||
@ -641,22 +608,9 @@ 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
|
||||
* @returns the receiver IP address from shared memory
|
||||
*/
|
||||
std::string setReceiverHostname(const std::string &receiver);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param mac detector MAC address
|
||||
@ -721,13 +675,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
sls::IpAddr getDestinationUDPIP();
|
||||
|
||||
/**
|
||||
* Gets destination udp ip from detector,
|
||||
* if 0, it converts rx_hostname to ip and
|
||||
* updates both detector and receiver
|
||||
*/
|
||||
void updateRxDestinationUDPIP();
|
||||
|
||||
/**
|
||||
* Validates the format of the receiver UDP IP address (bottom half) and
|
||||
* sets it(Jungfrau only)
|
||||
@ -743,13 +690,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
sls::IpAddr getDestinationUDPIP2();
|
||||
|
||||
/**
|
||||
* Gets destination udp ip2 from detector,
|
||||
* if 0, it converts rx_hostname to ip and
|
||||
* updates both detector and receiver
|
||||
*/
|
||||
void updateRxDestinationUDPIP2();
|
||||
|
||||
/**
|
||||
* Validates the format of the receiver UDP MAC address and sets it
|
||||
* @param mac receiver UDP MAC address
|
||||
@ -776,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
|
||||
*/
|
||||
@ -834,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
|
||||
@ -924,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();
|
||||
|
||||
@ -1030,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();
|
||||
|
||||
/**
|
||||
@ -1098,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
|
||||
@ -1114,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)
|
||||
@ -1150,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
|
||||
@ -1159,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();
|
||||
@ -1308,169 +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);
|
||||
|
||||
/**
|
||||
* Send the multi detector size to the detector
|
||||
* @param detx number of detectors in x dir
|
||||
* @param dety number of detectors in y dir
|
||||
*/
|
||||
void sendMultiDetectorSize();
|
||||
|
||||
/**
|
||||
* Send the detector pos id to the receiver
|
||||
* for various file naming conventions for multi detectors in receiver
|
||||
*/
|
||||
void setDetectorId();
|
||||
|
||||
/**
|
||||
* Send the detector host name to the receiver
|
||||
* for various handshaking required with the detector
|
||||
*/
|
||||
void setDetectorHostname();
|
||||
|
||||
|
||||
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
|
||||
@ -1606,9 +1260,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
/** [Mythen3] */
|
||||
void setCounterMask(uint32_t countermask);
|
||||
|
||||
/** [Mythen3] */
|
||||
void sendNumberofCounterstoReceiver(uint32_t countermask);
|
||||
|
||||
/** [Mythen3] */
|
||||
uint32_t getCounterMask();
|
||||
|
||||
@ -1674,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
|
||||
@ -1817,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
|
85
slsDetectorSoftware/src/Parallel.h
Normal file
85
slsDetectorSoftware/src/Parallel.h
Normal 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
|
883
slsDetectorSoftware/src/Receiver.cpp
Executable file
883
slsDetectorSoftware/src/Receiver.cpp
Executable 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
|
251
slsDetectorSoftware/src/Receiver.h
Executable file
251
slsDetectorSoftware/src/Receiver.h
Executable 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
|
@ -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;
|
||||
|
@ -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>")
|
@ -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;
|
||||
|
330
slsDetectorSoftware/tests/test-Container3.cpp
Normal file
330
slsDetectorSoftware/tests/test-Container3.cpp
Normal 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);
|
||||
|
||||
|
||||
}
|
99
slsDetectorSoftware/tests/test-MaskGenerator.cpp
Normal file
99
slsDetectorSoftware/tests/test-MaskGenerator.cpp
Normal 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);
|
||||
|
||||
}
|
10
slsDetectorSoftware/tests/test-Receiver.cpp
Normal file
10
slsDetectorSoftware/tests/test-Receiver.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "catch.hpp"
|
||||
#include "Container3.h"
|
||||
#include "Receiver.h"
|
||||
|
||||
using sls::Receiver;
|
||||
|
||||
// TEST_CASE("Receiver can be default constructed"){
|
||||
|
||||
|
||||
// }
|
File diff suppressed because it is too large
Load Diff
@ -10,8 +10,18 @@ class ServerInterface;
|
||||
#include <future>
|
||||
|
||||
class ClientInterface : private virtual slsDetectorDefs {
|
||||
private:
|
||||
enum numberMode { DEC, HEX };
|
||||
detectorType myDetectorType;
|
||||
int portNumber{0};
|
||||
sls::ServerSocket server;
|
||||
std::unique_ptr<Implementation> receiver;
|
||||
std::unique_ptr<std::thread> tcpThread;
|
||||
int ret{OK};
|
||||
int fnum{-1};
|
||||
int lockedByClient{0};
|
||||
|
||||
std::atomic<bool> killTcpThread{false};
|
||||
|
||||
|
||||
public:
|
||||
virtual ~ClientInterface();
|
||||
@ -49,15 +59,15 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
void verifyLock();
|
||||
void verifyIdle(sls::ServerInterface &socket);
|
||||
|
||||
|
||||
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);
|
||||
int set_detector_type(sls::ServerInterface &socket);
|
||||
int set_detector_hostname(sls::ServerInterface &socket);
|
||||
int setup_receiver(sls::ServerInterface &socket);
|
||||
void setDetectorType(detectorType arg);
|
||||
int set_roi(sls::ServerInterface &socket);
|
||||
int set_num_frames(sls::ServerInterface &socket);
|
||||
int set_num_triggers(sls::ServerInterface &socket);
|
||||
@ -95,15 +105,16 @@ 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_detector_posid(sls::ServerInterface &socket);
|
||||
int set_multi_detector_size(sls::ServerInterface &socket);
|
||||
int set_streaming_port(sls::ServerInterface &socket);
|
||||
int get_streaming_port(sls::ServerInterface &socket);
|
||||
int set_streaming_source_ip(sls::ServerInterface &socket);
|
||||
@ -114,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);
|
||||
@ -132,10 +144,9 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int get_dbit_offset(sls::ServerInterface &socket);
|
||||
int set_quad_type(sls::ServerInterface &socket);
|
||||
int set_read_n_lines(sls::ServerInterface &socket);
|
||||
sls::MacAddr setUdpIp(sls::IpAddr arg);
|
||||
int set_udp_ip(sls::ServerInterface &socket);
|
||||
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);
|
||||
@ -144,7 +155,6 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int get_additional_json_parameter(sls::ServerInterface &socket);
|
||||
int get_progress(sls::ServerInterface &socket);
|
||||
|
||||
|
||||
Implementation *impl() {
|
||||
if (receiver != nullptr) {
|
||||
return receiver.get();
|
||||
@ -154,19 +164,9 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
}
|
||||
}
|
||||
|
||||
detectorType myDetectorType;
|
||||
std::unique_ptr<Implementation> receiver{nullptr};
|
||||
int (ClientInterface::*flist[NUM_REC_FUNCTIONS])(
|
||||
sls::ServerInterface &socket);
|
||||
int ret{OK};
|
||||
int fnum{-1};
|
||||
int lockedByClient{0};
|
||||
int portNumber{0};
|
||||
std::atomic<bool> killTcpThread{false};
|
||||
std::unique_ptr<std::thread> tcpThread;
|
||||
|
||||
|
||||
|
||||
|
||||
//***callback parameters***
|
||||
|
||||
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t,
|
||||
@ -179,6 +179,6 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
void *) = nullptr;
|
||||
void *pRawDataReady{nullptr};
|
||||
|
||||
protected:
|
||||
std::unique_ptr<sls::ServerSocket> server{nullptr};
|
||||
|
||||
|
||||
};
|
||||
|
@ -29,13 +29,9 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
uint32_t* freq, uint32_t* timer,
|
||||
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
|
||||
std::vector <int> * cdl, int* cdo, int* cad) :
|
||||
|
||||
ThreadObject(ind, TypeName),
|
||||
runningFlag(false),
|
||||
generalData(nullptr),
|
||||
fifo(f),
|
||||
myDetectorType(dtype),
|
||||
file(nullptr),
|
||||
dataStreamEnable(dsEnable),
|
||||
fileFormatType(ftype),
|
||||
fileWriteEnable(fwenable),
|
||||
@ -43,7 +39,6 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
dynamicRange(dr),
|
||||
streamingFrequency(freq),
|
||||
streamingTimerInMs(timer),
|
||||
currentFreqCount(0),
|
||||
activated(act),
|
||||
deactivatedPaddingEnable(depaden),
|
||||
silentMode(sm),
|
||||
@ -51,14 +46,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
framePadding(fp),
|
||||
ctbDbitList(cdl),
|
||||
ctbDbitOffset(cdo),
|
||||
ctbAnalogDataBytes(cad),
|
||||
startedFlag(false),
|
||||
firstIndex(0),
|
||||
numFramesCaught(0),
|
||||
currentFrameIndex(0),
|
||||
rawDataReadyCallBack(nullptr),
|
||||
rawDataModifyReadyCallBack(nullptr),
|
||||
pRawDataReady(nullptr)
|
||||
ctbAnalogDataBytes(cad)
|
||||
{
|
||||
LOG(logDEBUG) << "DataProcessor " << ind << " created";
|
||||
memset((void*)&timerBegin, 0, sizeof(timespec));
|
||||
@ -71,10 +59,6 @@ DataProcessor::~DataProcessor() {
|
||||
|
||||
/** getters */
|
||||
|
||||
bool DataProcessor::IsRunning() {
|
||||
return runningFlag;
|
||||
}
|
||||
|
||||
bool DataProcessor::GetStartedFlag(){
|
||||
return startedFlag;
|
||||
}
|
||||
@ -91,24 +75,12 @@ uint64_t DataProcessor::GetProcessedIndex() {
|
||||
return currentFrameIndex - firstIndex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** setters */
|
||||
void DataProcessor::StartRunning() {
|
||||
runningFlag = true;
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::StopRunning() {
|
||||
runningFlag = false;
|
||||
}
|
||||
|
||||
void DataProcessor::SetFifo(Fifo* f) {
|
||||
fifo = f;
|
||||
}
|
||||
|
||||
void DataProcessor::ResetParametersforNewAcquisition(){
|
||||
runningFlag = false;
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
numFramesCaught = 0;
|
||||
firstIndex = 0;
|
||||
|
@ -59,11 +59,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
|
||||
//*** getters ***
|
||||
/**
|
||||
* Returns if the thread is currently running
|
||||
* @returns true if thread is running, else false
|
||||
*/
|
||||
bool IsRunning() override;
|
||||
|
||||
/**
|
||||
* Get acquisition started flag
|
||||
@ -89,17 +84,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
uint64_t GetProcessedIndex();
|
||||
|
||||
//*** setters ***
|
||||
/**
|
||||
* Set bit in RunningMask to allow thread to run
|
||||
*/
|
||||
void StartRunning();
|
||||
|
||||
/**
|
||||
* Reset bit in RunningMask to prevent thread from running
|
||||
*/
|
||||
void StopRunning();
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
@ -254,11 +238,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
|
||||
/** Object running status */
|
||||
std::atomic<bool> runningFlag;
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
const GeneralData* generalData;
|
||||
const GeneralData* generalData{nullptr};
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo* fifo;
|
||||
@ -269,7 +250,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
detectorType myDetectorType;
|
||||
|
||||
/** File writer implemented as binary or hdf5 File */
|
||||
File* file;
|
||||
File* file{nullptr};
|
||||
|
||||
/** Data Stream Enable */
|
||||
bool* dataStreamEnable;
|
||||
@ -293,7 +274,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
uint32_t* streamingTimerInMs;
|
||||
|
||||
/** Current frequency count */
|
||||
uint32_t currentFreqCount;
|
||||
uint32_t currentFreqCount{0};
|
||||
|
||||
/** timer beginning stamp for random streaming */
|
||||
struct timespec timerBegin;
|
||||
@ -324,21 +305,18 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
//acquisition start
|
||||
/** Aquisition Started flag */
|
||||
bool startedFlag;
|
||||
std::atomic<bool> startedFlag{false};
|
||||
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex;
|
||||
std::atomic<uint64_t> firstIndex{0};
|
||||
|
||||
|
||||
//for statistics
|
||||
/** Number of complete frames caught */
|
||||
uint64_t numFramesCaught;
|
||||
uint64_t numFramesCaught{0};
|
||||
|
||||
/** Frame Number of latest processed frame number */
|
||||
uint64_t currentFrameIndex;
|
||||
|
||||
|
||||
|
||||
std::atomic<uint64_t> currentFrameIndex{0};
|
||||
|
||||
//call back
|
||||
/**
|
||||
@ -349,7 +327,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* dataSize in bytes is the size of the data in bytes.
|
||||
*/
|
||||
void (*rawDataReadyCallBack)(char*,
|
||||
char*, uint32_t, void*);
|
||||
char*, uint32_t, void*) = nullptr;
|
||||
|
||||
/**
|
||||
* Call back for raw data (modified)
|
||||
@ -359,9 +337,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value).
|
||||
*/
|
||||
void (*rawDataModifyReadyCallBack)(char*,
|
||||
char*, uint32_t &, void*);
|
||||
char*, uint32_t &, void*) = nullptr;
|
||||
|
||||
void *pRawDataReady;
|
||||
void *pRawDataReady{nullptr};
|
||||
|
||||
|
||||
|
||||
|
@ -17,25 +17,18 @@ 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),
|
||||
runningFlag(0),
|
||||
generalData(nullptr),
|
||||
fifo(f),
|
||||
zmqSocket(nullptr),
|
||||
dynamicRange(dr),
|
||||
roi(r),
|
||||
adcConfigured(-1),
|
||||
fileIndex(fi),
|
||||
flippedDataX(fd),
|
||||
startedFlag(false),
|
||||
firstIndex(0),
|
||||
completeBuffer(nullptr),
|
||||
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";
|
||||
}
|
||||
@ -46,29 +39,12 @@ DataStreamer::~DataStreamer() {
|
||||
delete [] completeBuffer;
|
||||
}
|
||||
|
||||
/** getters */
|
||||
|
||||
bool DataStreamer::IsRunning() {
|
||||
return runningFlag;
|
||||
}
|
||||
|
||||
|
||||
/** setters */
|
||||
void DataStreamer::StartRunning() {
|
||||
runningFlag = true;
|
||||
}
|
||||
|
||||
|
||||
void DataStreamer::StopRunning() {
|
||||
runningFlag = false;
|
||||
}
|
||||
|
||||
void DataStreamer::SetFifo(Fifo* f) {
|
||||
fifo = f;
|
||||
}
|
||||
|
||||
void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){
|
||||
runningFlag = false;
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
firstIndex = 0;
|
||||
|
||||
@ -98,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) {
|
||||
@ -235,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;
|
||||
|
@ -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
|
||||
@ -42,25 +42,6 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
~DataStreamer();
|
||||
|
||||
//*** getters ***
|
||||
/**
|
||||
* Returns if the thread is currently running
|
||||
* @returns true if thread is running, else false
|
||||
*/
|
||||
bool IsRunning();
|
||||
|
||||
|
||||
//*** setters ***
|
||||
/**
|
||||
* Set bit in RunningMask to allow thread to run
|
||||
*/
|
||||
void StartRunning();
|
||||
|
||||
/**
|
||||
* Reset bit in RunningMask to prevent thread from running
|
||||
*/
|
||||
void StopRunning();
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
@ -79,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
|
||||
@ -158,19 +139,14 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
|
||||
/** Object running status */
|
||||
bool runningFlag;
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
const GeneralData* generalData;
|
||||
const GeneralData* generalData{nullptr};
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo* fifo;
|
||||
|
||||
|
||||
|
||||
/** ZMQ Socket - Receiver to Client */
|
||||
ZmqSocket* zmqSocket;
|
||||
ZmqSocket* zmqSocket{nullptr};
|
||||
|
||||
/** Pointer to dynamic range */
|
||||
uint32_t* dynamicRange;
|
||||
@ -179,7 +155,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
ROI* roi;
|
||||
|
||||
/** adc Configured */
|
||||
int adcConfigured;
|
||||
int adcConfigured{-1};
|
||||
|
||||
/** Pointer to file index */
|
||||
uint64_t* fileIndex;
|
||||
@ -191,19 +167,19 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
std::map<std::string, std::string> additionJsonHeader;
|
||||
|
||||
/** Aquisition Started flag */
|
||||
bool startedFlag;
|
||||
bool startedFlag{nullptr};
|
||||
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex;
|
||||
uint64_t firstIndex{0};
|
||||
|
||||
/* File name to stream */
|
||||
std::string fileNametoStream;
|
||||
|
||||
/** Complete buffer used for roi, eg. shortGotthard */
|
||||
char* completeBuffer;
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
};
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "container_utils.h" // For sls::make_unique<>
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include "UdpRxSocket.h"
|
||||
#include "network_utils.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
@ -25,12 +26,9 @@ Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>*
|
||||
int64_t* us, int64_t* as, uint32_t* fpf,
|
||||
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm) :
|
||||
ThreadObject(ind, TypeName),
|
||||
runningFlag(0),
|
||||
generalData(nullptr),
|
||||
fifo(f),
|
||||
myDetectorType(dtype),
|
||||
status(s),
|
||||
udpSocket(nullptr),
|
||||
udpPortNumber(portno),
|
||||
eth(e),
|
||||
numImages(nf),
|
||||
@ -41,45 +39,22 @@ Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>*
|
||||
frameDiscardMode(fdp),
|
||||
activated(act),
|
||||
deactivatedPaddingEnable(depaden),
|
||||
silentMode(sm),
|
||||
row(0),
|
||||
column(0),
|
||||
startedFlag(false),
|
||||
firstIndex(0),
|
||||
numPacketsCaught(0),
|
||||
lastCaughtFrameIndex(0),
|
||||
currentFrameIndex(0),
|
||||
carryOverFlag(0),
|
||||
udpSocketAlive(0),
|
||||
numPacketsStatistic(0),
|
||||
numFramesStatistic(0),
|
||||
oddStartingPacket(true)
|
||||
silentMode(sm)
|
||||
{
|
||||
LOG(logDEBUG) << "Listener " << ind << " created";
|
||||
}
|
||||
|
||||
Listener::~Listener() = default;
|
||||
|
||||
Listener::~Listener() {
|
||||
if (udpSocket){
|
||||
sem_post(&semaphore_socket);
|
||||
sem_destroy(&semaphore_socket);
|
||||
}
|
||||
}
|
||||
|
||||
/** getters */
|
||||
bool Listener::IsRunning() {
|
||||
return runningFlag;
|
||||
}
|
||||
|
||||
uint64_t Listener::GetPacketsCaught() {
|
||||
uint64_t Listener::GetPacketsCaught() const {
|
||||
return numPacketsCaught;
|
||||
}
|
||||
|
||||
uint64_t Listener::GetLastFrameIndexCaught() {
|
||||
uint64_t Listener::GetLastFrameIndexCaught() const {
|
||||
return lastCaughtFrameIndex;
|
||||
}
|
||||
|
||||
uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) {
|
||||
uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const {
|
||||
if (!stoppedFlag) {
|
||||
return (numPackets - numPacketsCaught);
|
||||
}
|
||||
@ -89,24 +64,12 @@ uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) {
|
||||
return (lastCaughtFrameIndex - firstIndex + 1) * generalData->packetsPerFrame - numPacketsCaught;
|
||||
}
|
||||
|
||||
/** setters */
|
||||
void Listener::StartRunning() {
|
||||
runningFlag = true;
|
||||
}
|
||||
|
||||
|
||||
void Listener::StopRunning() {
|
||||
runningFlag = false;
|
||||
}
|
||||
|
||||
|
||||
void Listener::SetFifo(Fifo* f) {
|
||||
fifo = f;
|
||||
}
|
||||
|
||||
|
||||
void Listener::ResetParametersforNewAcquisition() {
|
||||
runningFlag = false;
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
numPacketsCaught = 0;
|
||||
firstIndex = 0;
|
||||
@ -149,7 +112,7 @@ void Listener::SetGeneralData(GeneralData* g) {
|
||||
}
|
||||
|
||||
|
||||
void Listener::CreateUDPSockets() {
|
||||
void Listener::CreateUDPSocket() {
|
||||
if (!(*activated)) {
|
||||
return;
|
||||
}
|
||||
@ -174,10 +137,9 @@ void Listener::CreateUDPSockets() {
|
||||
}
|
||||
|
||||
udpSocketAlive = true;
|
||||
sem_init(&semaphore_socket,1,0);
|
||||
|
||||
// doubled due to kernel bookkeeping (could also be less due to permissions)
|
||||
*actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize();
|
||||
*actualUDPSocketBufferSize = udpSocket->getBufferSize();
|
||||
}
|
||||
|
||||
|
||||
@ -185,14 +147,8 @@ void Listener::CreateUDPSockets() {
|
||||
void Listener::ShutDownUDPSocket() {
|
||||
if(udpSocket){
|
||||
udpSocketAlive = false;
|
||||
udpSocket->ShutDownSocket();
|
||||
udpSocket->Shutdown();
|
||||
LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber;
|
||||
fflush(stdout);
|
||||
// wait only if the threads have started as it is the threads that
|
||||
//give a post to semaphore(at stopListening)
|
||||
if (runningFlag)
|
||||
sem_wait(&semaphore_socket);
|
||||
sem_destroy(&semaphore_socket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +176,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
|
||||
*udpSocketBufferSize);
|
||||
|
||||
// doubled due to kernel bookkeeping (could also be less due to permissions)
|
||||
*actualUDPSocketBufferSize = g.getActualUDPSocketBufferSize();
|
||||
*actualUDPSocketBufferSize = g.getBufferSize();
|
||||
if (*actualUDPSocketBufferSize == -1) {
|
||||
*udpSocketBufferSize = temp;
|
||||
} else {
|
||||
@ -300,10 +256,8 @@ void Listener::StopListening(char* buf) {
|
||||
(*((uint32_t*)buf)) = DUMMY_PACKET_VALUE;
|
||||
fifo->PushAddress(buf);
|
||||
StopRunning();
|
||||
|
||||
sem_post(&semaphore_socket);
|
||||
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught;
|
||||
LOG(logDEBUG1) << index << ": Listening Completed";
|
||||
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught;
|
||||
LOG(logDEBUG1) << index << ": Listening Completed";
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,13 +12,10 @@
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "ThreadObject.h"
|
||||
#include "UdpRxSocket.h"
|
||||
|
||||
class GeneralData;
|
||||
class Fifo;
|
||||
namespace sls{
|
||||
class UdpRxSocket;
|
||||
}
|
||||
|
||||
|
||||
class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
@ -53,40 +50,20 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
~Listener();
|
||||
|
||||
|
||||
//*** getters ***
|
||||
/**
|
||||
* Returns if the thread is currently running
|
||||
* @returns true if thread is running, else false
|
||||
*/
|
||||
bool IsRunning() override;
|
||||
|
||||
/**
|
||||
* Get Packets caught
|
||||
* @return Packets caught
|
||||
*/
|
||||
uint64_t GetPacketsCaught();
|
||||
uint64_t GetPacketsCaught() const;
|
||||
|
||||
/**
|
||||
* Get Last Frame index caught
|
||||
* @return last frame index caught
|
||||
*/
|
||||
uint64_t GetLastFrameIndexCaught();
|
||||
uint64_t GetLastFrameIndexCaught() const;
|
||||
|
||||
/** Get number of missing packets */
|
||||
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets);
|
||||
|
||||
|
||||
//*** setters ***
|
||||
/**
|
||||
* Set bit in RunningMask to allow thread to run
|
||||
*/
|
||||
void StartRunning();
|
||||
|
||||
/**
|
||||
* Reset bit in RunningMask to prevent thread from running
|
||||
*/
|
||||
void StopRunning();
|
||||
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const;
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
@ -106,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
|
||||
@ -140,7 +117,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
void RecordFirstIndex(uint64_t fnum);
|
||||
|
||||
/**
|
||||
* Thread Exeution for Listener Class
|
||||
* Thread Execution for Listener Class
|
||||
* Pop free addresses, listen to udp socket,
|
||||
* write to memory & push the address into fifo
|
||||
*/
|
||||
@ -168,16 +145,11 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
void PrintFifoStatistics();
|
||||
|
||||
|
||||
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
|
||||
/** Object running status */
|
||||
std::atomic<bool> runningFlag;
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
GeneralData* generalData;
|
||||
GeneralData* generalData{nullptr};
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo* fifo;
|
||||
@ -190,7 +162,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
std::atomic<runStatus>* status;
|
||||
|
||||
/** UDP Socket - Detector to Receiver */
|
||||
std::unique_ptr<sls::UdpRxSocket> udpSocket;
|
||||
std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
|
||||
|
||||
/** UDP Port Number */
|
||||
uint32_t* udpPortNumber;
|
||||
@ -228,36 +200,34 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** row hardcoded as 1D or 2d,
|
||||
* if detector does not send them yet or
|
||||
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
|
||||
uint16_t row;
|
||||
uint16_t row{0};
|
||||
|
||||
/** column hardcoded as 2D,
|
||||
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
|
||||
uint16_t column;
|
||||
|
||||
uint16_t column{0};
|
||||
|
||||
// acquisition start
|
||||
/** Aquisition Started flag */
|
||||
std::atomic<bool> startedFlag;
|
||||
std::atomic<bool> startedFlag{false};
|
||||
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex;
|
||||
uint64_t firstIndex{0};
|
||||
|
||||
// for acquisition summary
|
||||
/** Number of complete Packets caught */
|
||||
std::atomic<uint64_t> numPacketsCaught;
|
||||
std::atomic<uint64_t> numPacketsCaught{0};
|
||||
|
||||
/** Last Frame Index caught from udp network */
|
||||
std::atomic<uint64_t> lastCaughtFrameIndex;
|
||||
|
||||
std::atomic<uint64_t> lastCaughtFrameIndex{0};
|
||||
|
||||
// parameters to acquire image
|
||||
/** Current Frame Index, default value is 0
|
||||
* ( always check startedFlag for validity first)
|
||||
*/
|
||||
uint64_t currentFrameIndex;
|
||||
uint64_t currentFrameIndex{0};
|
||||
|
||||
/** True if there is a packet carry over from previous Image */
|
||||
bool carryOverFlag;
|
||||
bool carryOverFlag{false};
|
||||
|
||||
/** Carry over packet buffer */
|
||||
std::unique_ptr<char []> carryOverPacket;
|
||||
@ -266,22 +236,19 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
std::unique_ptr<char []> listeningPacket;
|
||||
|
||||
/** if the udp socket is connected */
|
||||
std::atomic<bool> udpSocketAlive;
|
||||
std::atomic<bool> udpSocketAlive{false};
|
||||
|
||||
/** Semaphore to synchonize deleting udp socket */
|
||||
sem_t semaphore_socket;
|
||||
|
||||
// for print progress during acqusition
|
||||
// for print progress during acquisition
|
||||
/** number of packets for statistic */
|
||||
uint32_t numPacketsStatistic;
|
||||
uint32_t numPacketsStatistic{0};
|
||||
|
||||
/** number of images for statistic */
|
||||
uint32_t numFramesStatistic;
|
||||
uint32_t numFramesStatistic{0};
|
||||
|
||||
/**
|
||||
* starting packet number is odd or evern, accordingly increment frame number
|
||||
* starting packet number is odd or even, accordingly increment frame number
|
||||
* to get first packet number as 0
|
||||
* (pecific to gotthard, can vary between modules, hence defined here) */
|
||||
bool oddStartingPacket;
|
||||
bool oddStartingPacket{true};
|
||||
};
|
||||
|
||||
|
@ -42,17 +42,14 @@ int main(int argc, char *argv[]) {
|
||||
LOG(logERROR) << "Could not set handler function for SIGPIPE";
|
||||
}
|
||||
|
||||
std::unique_ptr<Receiver> receiver = nullptr;
|
||||
try {
|
||||
receiver = sls::make_unique<Receiver>(argc, argv);
|
||||
Receiver r(argc, argv);
|
||||
LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]";
|
||||
sem_wait(&semaphore);
|
||||
sem_destroy(&semaphore);
|
||||
} catch (...) {
|
||||
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
|
||||
throw;
|
||||
//pass
|
||||
}
|
||||
|
||||
LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]";
|
||||
sem_wait(&semaphore);
|
||||
sem_destroy(&semaphore);
|
||||
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
|
||||
LOG(logINFO) << "Exiting Receiver";
|
||||
return 0;
|
||||
|
@ -3,56 +3,51 @@
|
||||
* @short creates/destroys a thread
|
||||
***********************************************/
|
||||
|
||||
|
||||
|
||||
#include "ThreadObject.h"
|
||||
#include "container_utils.h"
|
||||
#include <iostream>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
|
||||
ThreadObject::ThreadObject(int threadIndex, std::string threadType)
|
||||
: index(threadIndex), type(threadType) {
|
||||
LOG(logDEBUG) << type << " thread created: " << index;
|
||||
|
||||
sem_init(&semaphore,1,0);
|
||||
|
||||
try {
|
||||
threadObject = sls::make_unique<std::thread>(&ThreadObject::RunningThread, this);
|
||||
threadObject = std::thread(&ThreadObject::RunningThread, this);
|
||||
} catch (...) {
|
||||
throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ThreadObject::~ThreadObject() {
|
||||
killThread = true;
|
||||
sem_post(&semaphore);
|
||||
|
||||
threadObject->join();
|
||||
|
||||
threadObject.join();
|
||||
sem_destroy(&semaphore);
|
||||
}
|
||||
|
||||
bool ThreadObject::IsRunning() const{
|
||||
return runningFlag;
|
||||
}
|
||||
|
||||
void ThreadObject::StartRunning() {
|
||||
runningFlag = true;
|
||||
}
|
||||
|
||||
void ThreadObject::StopRunning() {
|
||||
runningFlag = false;
|
||||
}
|
||||
|
||||
void ThreadObject::RunningThread() {
|
||||
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
|
||||
LOG(logDEBUG) << type << " thread " << index << " created successfully.";
|
||||
|
||||
while(true) {
|
||||
while(!killThread) {
|
||||
while(IsRunning()) {
|
||||
ThreadExecution();
|
||||
}
|
||||
//wait till the next acquisition
|
||||
sem_wait(&semaphore);
|
||||
if(killThread) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(logDEBUG) << type << " thread with index " << index << " destroyed successfully.";
|
||||
LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
|
||||
}
|
||||
|
||||
@ -61,11 +56,10 @@ void ThreadObject::Continue() {
|
||||
sem_post(&semaphore);
|
||||
}
|
||||
|
||||
|
||||
void ThreadObject::SetThreadPriority(int priority) {
|
||||
struct sched_param param;
|
||||
param.sched_priority = priority;
|
||||
if (pthread_setschedparam(threadObject->native_handle(), SCHED_FIFO, ¶m) == EPERM) {
|
||||
if (pthread_setschedparam(threadObject.native_handle(), SCHED_FIFO, ¶m) == EPERM) {
|
||||
if (index == 0) {
|
||||
LOG(logWARNING) << "Could not prioritize " << type << " thread. "
|
||||
"(No Root Privileges?)";
|
||||
|
@ -7,41 +7,40 @@
|
||||
*@short creates/destroys a thread
|
||||
*/
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <semaphore.h>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
|
||||
class ThreadObject : private virtual slsDetectorDefs {
|
||||
|
||||
public:
|
||||
ThreadObject(int threadIndex, std::string threadType);
|
||||
virtual ~ThreadObject();
|
||||
virtual bool IsRunning() = 0;
|
||||
void Continue();
|
||||
void SetThreadPriority(int priority);
|
||||
protected:
|
||||
const int index{0};
|
||||
|
||||
protected:
|
||||
virtual void ThreadExecution() = 0;
|
||||
private:
|
||||
std::atomic<bool> killThread{false};
|
||||
std::atomic<bool> runningFlag{false};
|
||||
std::thread threadObject;
|
||||
sem_t semaphore;
|
||||
const std::string type;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Thread called: An infinite while loop in which,
|
||||
* semaphore starts executing its contents as long RunningMask is satisfied
|
||||
* Then it exits the thread on its own if killThread is true
|
||||
*/
|
||||
void RunningThread();
|
||||
public:
|
||||
ThreadObject(int threadIndex, std::string threadType);
|
||||
virtual ~ThreadObject();
|
||||
bool IsRunning() const;
|
||||
void StartRunning();
|
||||
void StopRunning();
|
||||
void Continue();
|
||||
void SetThreadPriority(int priority);
|
||||
|
||||
|
||||
protected:
|
||||
int index{0};
|
||||
std::string type;
|
||||
std::atomic<bool> killThread{false};
|
||||
std::unique_ptr<std::thread> threadObject;
|
||||
sem_t semaphore;
|
||||
private:
|
||||
virtual void ThreadExecution() = 0;
|
||||
/**
|
||||
* Thread called: An infinite while loop in which,
|
||||
* semaphore starts executing its contents as long RunningMask is satisfied
|
||||
* Then it exits the thread on its own if killThread is true
|
||||
*/
|
||||
void RunningThread();
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@ set(SOURCES
|
||||
src/ToString.cpp
|
||||
src/network_utils.cpp
|
||||
src/ZmqSocket.cpp
|
||||
src/UdpRxSocket.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
|
@ -21,7 +21,7 @@ class DataSocket {
|
||||
//No copy since the class manage the underlying socket
|
||||
DataSocket(const DataSocket &) = delete;
|
||||
DataSocket &operator=(DataSocket const &) = delete;
|
||||
int getSocketId() const { return socketId_; }
|
||||
int getSocketId() const { return sockfd_; }
|
||||
|
||||
|
||||
int Send(const void *buffer, size_t size);
|
||||
@ -51,9 +51,10 @@ class DataSocket {
|
||||
int setReceiveTimeout(int us);
|
||||
void close();
|
||||
void shutDownSocket();
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
int socketId_ = -1;
|
||||
int sockfd_ = -1;
|
||||
};
|
||||
|
||||
}; // namespace sls
|
||||
|
@ -1,141 +1,30 @@
|
||||
|
||||
#pragma once
|
||||
/*
|
||||
UdpRxSocket provies socket control to receive
|
||||
data on a udp socket.
|
||||
|
||||
It provides a drop in replacement for
|
||||
genericSocket. But please be careful since
|
||||
this might be deprecated in the future
|
||||
|
||||
UDP socket class to receive data. The intended use is in the
|
||||
receiver listener loop. Should be used RAII style...
|
||||
*/
|
||||
|
||||
#include "network_utils.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include <cstdint>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/types.h> //ssize_t
|
||||
namespace sls {
|
||||
|
||||
class UdpRxSocket {
|
||||
const ssize_t packet_size;
|
||||
char *buff;
|
||||
int fd = -1;
|
||||
const ssize_t packet_size_;
|
||||
int sockfd_{-1};
|
||||
|
||||
public:
|
||||
UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr,
|
||||
ssize_t buffer_size = 0)
|
||||
: packet_size(packet_size) {
|
||||
/* hostname = nullptr -> wildcard */
|
||||
size_t kernel_buffer_size = 0);
|
||||
~UdpRxSocket();
|
||||
bool ReceivePacket(char *dst) noexcept;
|
||||
size_t getBufferSize() const;
|
||||
void setBufferSize(ssize_t size);
|
||||
ssize_t getPacketSize() const noexcept;
|
||||
void Shutdown();
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
|
||||
struct addrinfo *res = 0;
|
||||
|
||||
const std::string portname = std::to_string(port);
|
||||
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
|
||||
throw RuntimeError("Failed at getaddrinfo with " +
|
||||
std::string(hostname));
|
||||
}
|
||||
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (fd == -1) {
|
||||
throw RuntimeError("Failed to create UDP RX socket");
|
||||
}
|
||||
if (bind(fd, res->ai_addr, res->ai_addrlen) == -1) {
|
||||
throw RuntimeError("Failed to bind UDP RX socket");
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
// If we get a specified buffer size that is larger than the set one
|
||||
// we set it. Otherwise we leave it there since it could have been
|
||||
// set by the rx_udpsocksize command
|
||||
if (buffer_size) {
|
||||
auto current = getBufferSize() / 2;
|
||||
if (current < buffer_size) {
|
||||
setBufferSize(buffer_size);
|
||||
if (getBufferSize() / 2 < buffer_size) {
|
||||
LOG(logWARNING)
|
||||
<< "Could not set buffer size. Got: "
|
||||
<< getBufferSize() / 2 << " instead of " << buffer_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Allocate at the end to avoid memory leak if we throw
|
||||
buff = new char[packet_size];
|
||||
}
|
||||
|
||||
~UdpRxSocket() {
|
||||
delete[] buff;
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
const char *LastPacket() const noexcept { return buff; }
|
||||
ssize_t getPacketSize() const noexcept { return packet_size; }
|
||||
|
||||
bool ReceivePacket() noexcept { return ReceivePacket(buff); }
|
||||
|
||||
bool ReceivePacket(char *dst, int flags = 0) noexcept {
|
||||
auto bytes_received =
|
||||
recvfrom(fd, dst, packet_size, flags, nullptr, nullptr);
|
||||
return bytes_received == packet_size;
|
||||
}
|
||||
|
||||
bool PeekPacket() noexcept{
|
||||
return ReceivePacket(buff, MSG_PEEK);
|
||||
}
|
||||
|
||||
// Only for backwards compatibility this function will be removed during
|
||||
// refactoring of the receiver
|
||||
ssize_t ReceiveDataOnly(char *dst) {
|
||||
auto r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr);
|
||||
constexpr ssize_t eiger_header_packet =
|
||||
40; // only detector that has this
|
||||
if (r == eiger_header_packet) {
|
||||
LOG(logWARNING) << "Got header pkg";
|
||||
r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t getBufferSize() const {
|
||||
uint64_t ret_size = 0;
|
||||
socklen_t optlen = sizeof(uint64_t);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1)
|
||||
return -1;
|
||||
else
|
||||
return ret_size;
|
||||
}
|
||||
|
||||
// Only for backwards compatibility will be removed
|
||||
ssize_t getActualUDPSocketBufferSize() const { return getBufferSize(); }
|
||||
|
||||
// Only for backwards compatibility will be removed
|
||||
void ShutDownSocket() { Shutdown(); }
|
||||
|
||||
void setBufferSize(ssize_t size) {
|
||||
socklen_t optlen = sizeof(size);
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, optlen)) {
|
||||
throw RuntimeError("Could not set socket buffer size");
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
shutdown(fd, SHUT_RDWR);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
// Only for backwards compatibility, this drops the EIGER small pkt, may be
|
||||
// removed
|
||||
ssize_t ReceiveDataOnly(char *dst) noexcept;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
@ -175,7 +176,7 @@ class slsDetectorDefs {
|
||||
struct ROI {
|
||||
int xmin{-1}; /**< is the roi xmin (in channel number) */
|
||||
int xmax{-1}; /**< is the roi xmax (in channel number)*/
|
||||
};
|
||||
}__attribute__((packed));
|
||||
#else
|
||||
typedef struct {
|
||||
int xmin; /**< is the roi xmin (in channel number) */
|
||||
@ -203,7 +204,7 @@ class slsDetectorDefs {
|
||||
int y{0};
|
||||
xy() = default;
|
||||
xy(int x, int y):x(x),y(y){};
|
||||
};
|
||||
}__attribute__((packed));
|
||||
#endif
|
||||
|
||||
|
||||
@ -460,6 +461,46 @@ class slsDetectorDefs {
|
||||
TIMING_EXTERNAL
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* structure to udpate receiver
|
||||
*/
|
||||
struct rxParameters {
|
||||
detectorType detType{GENERIC};
|
||||
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};
|
||||
uint64_t udp_dstmac{0LU};
|
||||
int udp_dstport2{0};
|
||||
uint32_t udp_dstip2{0U};
|
||||
uint64_t udp_dstmac2{0LU};
|
||||
int64_t frames{0};
|
||||
int64_t triggers{0};
|
||||
int64_t bursts{0};
|
||||
int analogSamples{0};
|
||||
int digitalSamples{0};
|
||||
int64_t expTimeNs{0};
|
||||
int64_t periodNs{0};
|
||||
int64_t subExpTimeNs{0};
|
||||
int64_t subDeadTimeNs{0};
|
||||
int activate{0};
|
||||
int quad{0};
|
||||
int dynamicRange{16};
|
||||
timingMode timMode{AUTO_TIMING};
|
||||
int tenGiga{0};
|
||||
readoutMode roMode{ANALOG_ONLY};
|
||||
uint32_t adcMask{0};
|
||||
uint32_t adc10gMask{0};
|
||||
ROI roi;
|
||||
uint32_t countermask{0};
|
||||
burstMode burstType{BURST_OFF};
|
||||
}__attribute__((packed));
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
protected:
|
||||
|
@ -197,18 +197,18 @@ enum detFuncs{
|
||||
F_SET_TIMING_SOURCE,
|
||||
F_GET_NUM_CHANNELS,
|
||||
F_UPDATE_RATE_CORRECTION,
|
||||
F_GET_RECEIVER_PARAMETERS,
|
||||
|
||||
NUM_DET_FUNCTIONS,
|
||||
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */
|
||||
|
||||
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,
|
||||
F_GET_RECEIVER_TYPE,
|
||||
F_SEND_RECEIVER_DETHOSTNAME,
|
||||
F_RECEIVER_SET_ROI,
|
||||
F_RECEIVER_SET_NUM_FRAMES,
|
||||
F_SET_RECEIVER_NUM_TRIGGERS,
|
||||
@ -245,15 +245,16 @@ 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_SEND_RECEIVER_DETPOSID,
|
||||
F_SEND_RECEIVER_MULTIDETSIZE,
|
||||
F_SET_RECEIVER_STREAMING_PORT,
|
||||
F_GET_RECEIVER_STREAMING_PORT,
|
||||
F_SET_RECEIVER_STREAMING_SRC_IP,
|
||||
@ -263,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,
|
||||
@ -283,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,
|
||||
@ -293,6 +293,7 @@ enum detFuncs{
|
||||
F_SET_ADDITIONAL_JSON_PARAMETER,
|
||||
F_GET_ADDITIONAL_JSON_PARAMETER,
|
||||
F_GET_RECEIVER_PROGRESS,
|
||||
F_SETUP_RECEIVER,
|
||||
|
||||
NUM_REC_FUNCTIONS
|
||||
};
|
||||
@ -487,18 +488,19 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE";
|
||||
case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS";
|
||||
case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION";
|
||||
case F_GET_RECEIVER_PARAMETERS: return "F_GET_RECEIVER_PARAMETERS";
|
||||
|
||||
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
||||
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
||||
|
||||
case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND";
|
||||
case F_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";
|
||||
case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE";
|
||||
case F_SEND_RECEIVER_DETHOSTNAME: return "F_SEND_RECEIVER_DETHOSTNAME";
|
||||
case F_SETUP_RECEIVER: return "F_SETUP_RECEIVER";
|
||||
case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI";
|
||||
case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES";
|
||||
case F_SET_RECEIVER_NUM_TRIGGERS: return "F_SET_RECEIVER_NUM_TRIGGERS";
|
||||
@ -535,15 +537,16 @@ 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_SEND_RECEIVER_DETPOSID: return "F_SEND_RECEIVER_DETPOSID";
|
||||
case F_SEND_RECEIVER_MULTIDETSIZE: return "F_SEND_RECEIVER_MULTIDETSIZE";
|
||||
case F_SET_RECEIVER_STREAMING_PORT: return "F_SET_RECEIVER_STREAMING_PORT";
|
||||
case F_GET_RECEIVER_STREAMING_PORT: return "F_GET_RECEIVER_STREAMING_PORT";
|
||||
case F_SET_RECEIVER_STREAMING_SRC_IP: return "F_SET_RECEIVER_STREAMING_SRC_IP";
|
||||
@ -553,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";
|
||||
@ -573,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";
|
||||
|
@ -1,12 +1,12 @@
|
||||
/** API versions */
|
||||
#define GITBRANCH "removeshm"
|
||||
#define APILIB 0x200402
|
||||
#define APIRECEIVER 0x200402
|
||||
#define APIGUI 0x200331
|
||||
#define APICTB 0x200407
|
||||
#define APIGOTTHARD 0x200407
|
||||
#define APIGOTTHARD2 0x200407
|
||||
#define APIJUNGFRAU 0x200407
|
||||
#define APIMYTHEN3 0x200407
|
||||
#define APIMOENCH 0x200407
|
||||
#define APIEIGER 0x200408
|
||||
#define GITBRANCH "setrxhostname"
|
||||
#define APILIB 0x200409
|
||||
#define APIRECEIVER 0x200409
|
||||
#define APIGUI 0x200409
|
||||
#define APIEIGER 0x200409
|
||||
#define APICTB 0x200409
|
||||
#define APIGOTTHARD 0x200409
|
||||
#define APIGOTTHARD2 0x200409
|
||||
#define APIJUNGFRAU 0x200409
|
||||
#define APIMYTHEN3 0x200409
|
||||
#define APIMOENCH 0x200409
|
||||
|
@ -15,13 +15,13 @@
|
||||
|
||||
namespace sls {
|
||||
|
||||
DataSocket::DataSocket(int socketId) : socketId_(socketId) {
|
||||
DataSocket::DataSocket(int socketId) : sockfd_(socketId) {
|
||||
int value = 1;
|
||||
setsockopt(socketId_, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
|
||||
setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
|
||||
}
|
||||
|
||||
DataSocket::~DataSocket() {
|
||||
if (socketId_ <= 0) {
|
||||
if (sockfd_ <= 0) {
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
@ -32,7 +32,7 @@ DataSocket::~DataSocket() {
|
||||
}
|
||||
|
||||
void DataSocket::swap(DataSocket &other) noexcept {
|
||||
std::swap(socketId_, other.socketId_);
|
||||
std::swap(sockfd_, other.sockfd_);
|
||||
}
|
||||
|
||||
DataSocket::DataSocket(DataSocket &&move) noexcept { move.swap(*this); }
|
||||
@ -121,19 +121,23 @@ int DataSocket::setTimeOut(int t_seconds) {
|
||||
}
|
||||
|
||||
void DataSocket::close() {
|
||||
if (socketId_ > 0) {
|
||||
if (::close(socketId_)) {
|
||||
if (sockfd_ > 0) {
|
||||
if (::close(sockfd_)) {
|
||||
throw SocketError("could not close socket");
|
||||
}
|
||||
socketId_ = -1;
|
||||
sockfd_ = -1;
|
||||
} else {
|
||||
throw std::runtime_error("Socket ERROR: close called on bad socket\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DataSocket::shutDownSocket() {
|
||||
shutdown(getSocketId(), SHUT_RDWR);
|
||||
::shutdown(getSocketId(), SHUT_RDWR);
|
||||
close();
|
||||
}
|
||||
|
||||
void DataSocket::shutdown(){
|
||||
::shutdown(sockfd_, SHUT_RDWR);
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
96
slsSupportLib/src/UdpRxSocket.cpp
Normal file
96
slsSupportLib/src/UdpRxSocket.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
#include "UdpRxSocket.h"
|
||||
#include "network_utils.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include <cstdint>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace sls {
|
||||
|
||||
UdpRxSocket::UdpRxSocket(int port, ssize_t packet_size, const char *hostname,
|
||||
size_t kernel_buffer_size)
|
||||
: packet_size_(packet_size) {
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
|
||||
struct addrinfo *res = 0;
|
||||
|
||||
const std::string portname = std::to_string(port);
|
||||
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
|
||||
throw RuntimeError("Failed at getaddrinfo with " +
|
||||
std::string(hostname));
|
||||
}
|
||||
sockfd_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (sockfd_ == -1) {
|
||||
throw RuntimeError("Failed to create UDP RX socket");
|
||||
}
|
||||
if (bind(sockfd_, res->ai_addr, res->ai_addrlen) == -1) {
|
||||
throw RuntimeError("Failed to bind UDP RX socket");
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
// If we get a specified buffer size that is larger than the set one
|
||||
// we set it. Otherwise we leave it there since it could have been
|
||||
// set by the rx_udpsocksize command
|
||||
if (kernel_buffer_size) {
|
||||
auto current = getBufferSize() / 2;
|
||||
if (current < kernel_buffer_size) {
|
||||
setBufferSize(kernel_buffer_size);
|
||||
if (getBufferSize() / 2 < kernel_buffer_size) {
|
||||
LOG(logWARNING)
|
||||
<< "Could not set buffer size. Got: " << getBufferSize() / 2
|
||||
<< " instead of " << kernel_buffer_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UdpRxSocket::~UdpRxSocket() { Shutdown(); }
|
||||
ssize_t UdpRxSocket::getPacketSize() const noexcept { return packet_size_; }
|
||||
|
||||
bool UdpRxSocket::ReceivePacket(char *dst) noexcept{
|
||||
auto bytes_received =
|
||||
recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
|
||||
return bytes_received == packet_size_;
|
||||
}
|
||||
|
||||
ssize_t UdpRxSocket::ReceiveDataOnly(char *dst) noexcept {
|
||||
auto r = recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
|
||||
constexpr ssize_t eiger_header_packet =
|
||||
40; // only detector that has this
|
||||
if (r == eiger_header_packet) {
|
||||
LOG(logWARNING) << "Got header pkg";
|
||||
r = recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
size_t UdpRxSocket::getBufferSize() const {
|
||||
size_t ret = 0;
|
||||
socklen_t optlen = sizeof(ret);
|
||||
if (getsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &ret, &optlen) == -1)
|
||||
throw RuntimeError("Could not get socket buffer size");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UdpRxSocket::setBufferSize(ssize_t size) {
|
||||
if (setsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)))
|
||||
throw RuntimeError("Could not set socket buffer size");
|
||||
}
|
||||
|
||||
void UdpRxSocket::Shutdown() {
|
||||
shutdown(sockfd_, SHUT_RDWR);
|
||||
if (sockfd_ >= 0) {
|
||||
close(sockfd_);
|
||||
sockfd_ = -1;
|
||||
}
|
||||
}
|
||||
} // namespace sls
|
@ -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();
|
||||
|
@ -109,7 +109,7 @@ TEST_CASE("run status"){
|
||||
using defs = slsDetectorDefs;
|
||||
REQUIRE(ToString(defs::runStatus::ERROR) == "error");
|
||||
REQUIRE(ToString(defs::runStatus::WAITING) == "waiting");
|
||||
REQUIRE(ToString(defs::runStatus::TRANSMITTING) == "data"); //??
|
||||
REQUIRE(ToString(defs::runStatus::TRANSMITTING) == "transmitting");
|
||||
REQUIRE(ToString(defs::runStatus::RUN_FINISHED) == "finished");
|
||||
REQUIRE(ToString(defs::runStatus::STOPPED) == "stopped");
|
||||
REQUIRE(ToString(defs::runStatus::IDLE) == "idle");
|
||||
|
@ -4,6 +4,14 @@
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
constexpr int default_port = 50001;
|
||||
|
||||
@ -29,46 +37,49 @@ int open_socket(int port) {
|
||||
throw sls::RuntimeError("Failed to create UDP RX socket");
|
||||
}
|
||||
|
||||
if (connect(fd, res->ai_addr, res->ai_addrlen)){
|
||||
if (connect(fd, res->ai_addr, res->ai_addrlen)) {
|
||||
throw sls::RuntimeError("Failed to connect socket");
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return fd;
|
||||
}
|
||||
|
||||
TEST_CASE("Receive data on localhost") {
|
||||
TEST_CASE("Get packet size returns the packet size we set in the constructor"){
|
||||
constexpr int port = 50001;
|
||||
constexpr ssize_t packet_size = 8000;
|
||||
sls::UdpRxSocket s{port, packet_size};
|
||||
CHECK(s.getPacketSize() == packet_size);
|
||||
}
|
||||
|
||||
TEST_CASE("Receive data from a vector") {
|
||||
constexpr int port = 50001;
|
||||
std::vector<int> data_to_send{4, 5, 3, 2, 5, 7, 2, 3};
|
||||
std::vector<int> data_received(data_to_send.size());
|
||||
ssize_t packet_size =
|
||||
sizeof(decltype(data_to_send)::value_type) * data_to_send.size();
|
||||
|
||||
sls::UdpRxSocket udpsock{port, packet_size};
|
||||
|
||||
|
||||
int fd = open_socket(port);
|
||||
auto n = write(fd, data_to_send.data(), packet_size);
|
||||
CHECK(n == packet_size);
|
||||
CHECK(udpsock.ReceivePacket());
|
||||
|
||||
CHECK(udpsock.ReceivePacket((char*)data_received.data()));
|
||||
close(fd);
|
||||
// Copy data from buffer and compare values
|
||||
std::vector<int> data_received(data_to_send.size());
|
||||
memcpy(data_received.data(), udpsock.LastPacket(), udpsock.getPacketSize());
|
||||
CHECK(data_received.size() == data_to_send.size()); // sanity check
|
||||
for (size_t i = 0; i != data_to_send.size(); ++i) {
|
||||
CHECK(data_to_send[i] == data_received[i]);
|
||||
}
|
||||
CHECK(data_to_send == data_received);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Shutdown socket without hanging when waiting for data") {
|
||||
constexpr int port = 50001;
|
||||
constexpr ssize_t packet_size = 8000;
|
||||
sls::UdpRxSocket s{port, packet_size};
|
||||
char buff[packet_size];
|
||||
|
||||
// Start a thread and wait for package
|
||||
// if the socket is left open we would block
|
||||
std::future<bool> ret =
|
||||
std::async(static_cast<bool (sls::UdpRxSocket::*)()>(
|
||||
&sls::UdpRxSocket::ReceivePacket),
|
||||
&s);
|
||||
std::async(&sls::UdpRxSocket::ReceivePacket, &s, (char *)&buff);
|
||||
|
||||
s.Shutdown();
|
||||
auto r = ret.get();
|
||||
@ -76,60 +87,23 @@ TEST_CASE("Shutdown socket without hanging when waiting for data") {
|
||||
CHECK(r == false); // since we didn't get the packet
|
||||
}
|
||||
|
||||
TEST_CASE("Too small packet"){
|
||||
TEST_CASE("Too small packet") {
|
||||
constexpr int port = 50001;
|
||||
sls::UdpRxSocket s(port, 2*sizeof(uint32_t));
|
||||
sls::UdpRxSocket s(port, 2 * sizeof(uint32_t));
|
||||
auto fd = open_socket(port);
|
||||
uint32_t val = 10;
|
||||
write(fd, &val, sizeof(val));
|
||||
CHECK(s.ReceivePacket() == false);
|
||||
uint32_t buff[2];
|
||||
CHECK(s.ReceivePacket((char *)&buff) == false);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Receive an int to internal buffer"){
|
||||
TEST_CASE("Receive an int to an external buffer") {
|
||||
int to_send = 5;
|
||||
int received = -1;
|
||||
auto fd = open_socket(default_port);
|
||||
sls::UdpRxSocket s(default_port, sizeof(int));
|
||||
write(fd, &to_send, sizeof(to_send));
|
||||
CHECK(s.ReceivePacket());
|
||||
memcpy(&received, s.LastPacket(), sizeof(int));
|
||||
CHECK(s.ReceivePacket(reinterpret_cast<char *>(&received)));
|
||||
CHECK(received == to_send);
|
||||
}
|
||||
|
||||
TEST_CASE("Receive an int to an external buffer"){
|
||||
int to_send = 5;
|
||||
int received = -1;
|
||||
auto fd = open_socket(default_port);
|
||||
sls::UdpRxSocket s(default_port, sizeof(int));
|
||||
write(fd, &to_send, sizeof(to_send));
|
||||
CHECK(s.ReceivePacket(reinterpret_cast<char*>(&received)));
|
||||
CHECK(received == to_send);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("PEEK data"){
|
||||
int to_send = 5;
|
||||
int to_send2 = 12;
|
||||
int received = -1;
|
||||
auto fd = open_socket(default_port);
|
||||
sls::UdpRxSocket s(default_port, sizeof(int));
|
||||
write(fd, &to_send, sizeof(to_send));
|
||||
write(fd, &to_send2, sizeof(to_send));
|
||||
CHECK(s.PeekPacket());
|
||||
memcpy(&received, s.LastPacket(), sizeof(int));
|
||||
CHECK(received == to_send);
|
||||
|
||||
CHECK(s.PeekPacket());
|
||||
memcpy(&received, s.LastPacket(), sizeof(int));
|
||||
CHECK(received == to_send);
|
||||
|
||||
CHECK(s.ReceivePacket());
|
||||
memcpy(&received, s.LastPacket(), sizeof(int));
|
||||
CHECK(received == to_send);
|
||||
|
||||
CHECK(s.ReceivePacket());
|
||||
memcpy(&received, s.LastPacket(), sizeof(int));
|
||||
CHECK(received == to_send2);
|
||||
}
|
||||
|
Reference in New Issue
Block a user