mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-11 04:17:15 +02:00
merge from 7.0.0
This commit is contained in:
@ -225,6 +225,17 @@ class Detector {
|
||||
*/
|
||||
void setBadChannels(const std::string &fname, Positions pos = {});
|
||||
|
||||
/** [Gotthard2][Mythen3] */
|
||||
Result<std::vector<int>> getBadChannels(Positions pos = {}) const;
|
||||
|
||||
/** [Gotthard2][Mythen3] Empty list resets bad channel list */
|
||||
void setBadChannels(const std::vector<int> list, Positions pos = {});
|
||||
|
||||
/** [Gotthard2][Mythen3] Size of list should match number of modules. Each
|
||||
* value is at module level and can start at 0. Empty vector resets bad
|
||||
* channel list. */
|
||||
void setBadChannels(const std::vector<std::vector<int>> list);
|
||||
|
||||
Result<bool> isVirtualDetectorServer(Positions pos = {}) const;
|
||||
///@}
|
||||
|
||||
@ -937,9 +948,10 @@ class Detector {
|
||||
/** Client IP Address that last communicated with the receiver */
|
||||
Result<IpAddr> getRxLastClientIP(Positions pos = {}) const;
|
||||
|
||||
/** Get thread ids from the receiver in order of [parent, tcp, listener 0,
|
||||
* processor 0, streamer 0, listener 1, processor 1, streamer 1, arping]. If
|
||||
* no streamer yet or there is no second interface, it gives 0 in its place.
|
||||
/** Get kernel thread ids from the receiver in order of [parent, tcp,
|
||||
* listener 0, processor 0, streamer 0, listener 1, processor 1, streamer 1,
|
||||
* arping]. If no streamer yet or there is no second interface, it gives 0
|
||||
* in its place.
|
||||
*/
|
||||
Result<std::array<pid_t, NUM_RX_THREAD_IDS>>
|
||||
getRxThreadIds(Positions pos = {}) const;
|
||||
@ -1469,8 +1481,9 @@ class Detector {
|
||||
Result<int> getADCConfiguration(const int chipIndex, const int adcIndex,
|
||||
Positions pos = {}) const;
|
||||
|
||||
/** [Gotthard2] configures one chip at a time for specific adc, chipIndex
|
||||
* and adcIndex is -1 for all */
|
||||
/** [Gotthard2] configures one chip at a time for specific adc, chipIndex.
|
||||
* -1 for all. Setting specific chip index not implemented in hardware yet
|
||||
*/
|
||||
void setADCConfiguration(const int chipIndex, const int adcIndex,
|
||||
const int value, Positions pos = {});
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/file_utils.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
@ -278,7 +279,12 @@ std::string CmdProxy::Versions(int action) {
|
||||
auto t = det->getFirmwareVersion(std::vector<int>{det_id});
|
||||
os << "\nType : " << OutString(det->getDetectorType())
|
||||
<< "\nRelease : " << det->getPackageVersion() << std::hex
|
||||
<< "\nClient : " << det->getClientVersion();
|
||||
<< "\nClient : " << det->getClientVersion()
|
||||
<< "\nServer : "
|
||||
<< OutString(det->getDetectorServerVersion(std::vector<int>{det_id}))
|
||||
<< "\nKernel : "
|
||||
<< OutString(det->getKernelVersion({std::vector<int>{det_id}}));
|
||||
|
||||
if (eiger) {
|
||||
os << "\nFirmware (Beb) : "
|
||||
<< OutString(det->getFirmwareVersion(std::vector<int>{det_id}));
|
||||
@ -291,16 +297,11 @@ std::string CmdProxy::Versions(int action) {
|
||||
} else {
|
||||
os << "\nFirmware : "
|
||||
<< OutStringHex(
|
||||
det->getFirmwareVersion(std::vector<int>{det_id}));
|
||||
}
|
||||
os << "\nServer : "
|
||||
<< OutString(
|
||||
det->getDetectorServerVersion(std::vector<int>{det_id}));
|
||||
if (!eiger)
|
||||
os << "\nHardware : "
|
||||
det->getFirmwareVersion(std::vector<int>{det_id}))
|
||||
<< "\nHardware : "
|
||||
<< OutString(det->getHardwareVersion(std::vector<int>{det_id}));
|
||||
os << "\nKernel : "
|
||||
<< OutString(det->getKernelVersion({std::vector<int>{det_id}}));
|
||||
}
|
||||
|
||||
if (det->getUseReceiverFlag().squash(true)) {
|
||||
os << "\nReceiver : "
|
||||
<< OutString(det->getReceiverVersion(std::vector<int>{det_id}));
|
||||
@ -557,9 +558,9 @@ std::string CmdProxy::BadChannels(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[fname]\n\t[Gotthard2][Mythen3] Sets the bad channels (from "
|
||||
"file of bad channel numbers) to be masked out."
|
||||
"\n\t[Mythen3] Also does trimming"
|
||||
os << "[fname|none|0]\n\t[Gotthard2][Mythen3] Sets the bad channels "
|
||||
"(from file of bad channel numbers) to be masked out. None or 0 "
|
||||
"unsets all the badchannels.\n\t[Mythen3] Also does trimming"
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
@ -568,10 +569,25 @@ std::string CmdProxy::BadChannels(int action) {
|
||||
det->getBadChannels(args[0], std::vector<int>{det_id});
|
||||
os << "successfully retrieved" << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
bool parse = false;
|
||||
if (args.size() == 0) {
|
||||
WrongNumberOfParameters(1);
|
||||
} else if (args.size() == 1) {
|
||||
if (args[0] == "none" || args[0] == "0") {
|
||||
det->setBadChannels(std::vector<int>{},
|
||||
std::vector<int>{det_id});
|
||||
} else if (args[0].find(".") != std::string::npos) {
|
||||
det->setBadChannels(args[0], std::vector<int>{det_id});
|
||||
} else {
|
||||
parse = true;
|
||||
}
|
||||
}
|
||||
// parse multi args or single one with range or single value
|
||||
if (parse || args.size() > 1) {
|
||||
// get channels
|
||||
auto list = getChannelsFromStringList(args);
|
||||
det->setBadChannels(list, std::vector<int>{det_id});
|
||||
}
|
||||
det->setBadChannels(args[0], std::vector<int>{det_id});
|
||||
os << "successfully loaded" << '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
@ -1481,7 +1497,7 @@ std::string CmdProxy::Trigger(int action) {
|
||||
|
||||
/* Network Configuration (Detector<->Receiver) */
|
||||
|
||||
IpAddr CmdProxy::getIpFromAuto() {
|
||||
IpAddr CmdProxy::getDstIpFromAuto() {
|
||||
std::string rxHostname =
|
||||
det->getRxHostname(std::vector<int>{det_id}).squash("none");
|
||||
// Hostname could be ip try to decode otherwise look up the hostname
|
||||
@ -1492,6 +1508,21 @@ IpAddr CmdProxy::getIpFromAuto() {
|
||||
return val;
|
||||
}
|
||||
|
||||
IpAddr CmdProxy::getSrcIpFromAuto() {
|
||||
if (det->getDetectorType().squash() == defs::GOTTHARD) {
|
||||
throw RuntimeError(
|
||||
"Cannot use 'auto' for udp_srcip for GotthardI Detector.");
|
||||
}
|
||||
std::string hostname =
|
||||
det->getHostname(std::vector<int>{det_id}).squash("none");
|
||||
// Hostname could be ip try to decode otherwise look up the hostname
|
||||
auto val = IpAddr{hostname};
|
||||
if (val == 0) {
|
||||
val = HostnameToIp(hostname.c_str());
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
UdpDestination CmdProxy::getUdpEntry() {
|
||||
UdpDestination udpDestination{};
|
||||
udpDestination.entry = rx_id;
|
||||
@ -1502,7 +1533,7 @@ UdpDestination CmdProxy::getUdpEntry() {
|
||||
std::string value = it.substr(pos + 1);
|
||||
if (key == "ip") {
|
||||
if (value == "auto") {
|
||||
auto val = getIpFromAuto();
|
||||
auto val = getDstIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_dstip of detector " << det_id
|
||||
<< " to " << val;
|
||||
udpDestination.ip = val;
|
||||
@ -1511,7 +1542,7 @@ UdpDestination CmdProxy::getUdpEntry() {
|
||||
}
|
||||
} else if (key == "ip2") {
|
||||
if (value == "auto") {
|
||||
auto val = getIpFromAuto();
|
||||
auto val = getDstIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id
|
||||
<< " to " << val;
|
||||
udpDestination.ip2 = val;
|
||||
@ -1586,8 +1617,9 @@ std::string CmdProxy::UDPSourceIP(int action) {
|
||||
os << "[x.x.x.x] or auto\n\tIp address of the detector (source) udp "
|
||||
"interface. Must be same subnet as destination udp "
|
||||
"ip.\n\t[Eiger] Set only for 10G. For 1G, detector will replace "
|
||||
"with its own DHCP IP address. If 'auto' used, then ip is set to "
|
||||
"ip of rx_hostname."
|
||||
"with its own DHCP IP address. \n\tOne can also set this to "
|
||||
"'auto' for 1 GbE data and virtual detectors. It will set to IP "
|
||||
"of detector. Not available for GotthardI"
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
auto t = det->getSourceUDPIP(std::vector<int>{det_id});
|
||||
@ -1601,7 +1633,7 @@ std::string CmdProxy::UDPSourceIP(int action) {
|
||||
}
|
||||
IpAddr val;
|
||||
if (args[0] == "auto") {
|
||||
val = getIpFromAuto();
|
||||
val = getSrcIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_srcip of detector " << det_id << " to "
|
||||
<< val;
|
||||
} else {
|
||||
@ -1624,8 +1656,9 @@ std::string CmdProxy::UDPSourceIP2(int action) {
|
||||
"of the "
|
||||
"detector (source) udp interface 2. Must be same subnet as "
|
||||
"destination udp ip2.\n\t [Jungfrau][Moench] top half or inner "
|
||||
"interface\n\t [Gotthard2] veto debugging. If 'auto' used, then "
|
||||
"ip is set to ip of rx_hostname."
|
||||
"interface\n\t [Gotthard2] veto debugging. \n\tOne can also set "
|
||||
"this to 'auto' for 1 GbE data and virtual detectors. It will "
|
||||
"set to IP of detector."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
auto t = det->getSourceUDPIP2(std::vector<int>{det_id});
|
||||
@ -1639,7 +1672,7 @@ std::string CmdProxy::UDPSourceIP2(int action) {
|
||||
}
|
||||
IpAddr val;
|
||||
if (args[0] == "auto") {
|
||||
val = getIpFromAuto();
|
||||
val = getSrcIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_srcip2 of detector " << det_id
|
||||
<< " to " << val;
|
||||
} else {
|
||||
@ -1673,7 +1706,7 @@ std::string CmdProxy::UDPDestinationIP(int action) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
if (args[0] == "auto") {
|
||||
auto val = getIpFromAuto();
|
||||
auto val = getDstIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_dstip of detector " << det_id << " to "
|
||||
<< val;
|
||||
det->setDestinationUDPIP(val, std::vector<int>{det_id});
|
||||
@ -1710,7 +1743,7 @@ std::string CmdProxy::UDPDestinationIP2(int action) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
if (args[0] == "auto") {
|
||||
auto val = getIpFromAuto();
|
||||
auto val = getDstIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id
|
||||
<< " to " << val;
|
||||
det->setDestinationUDPIP2(val, std::vector<int>{det_id});
|
||||
@ -2381,7 +2414,7 @@ std::string CmdProxy::ConfigureADC(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[chip index 0-10, -1 for all] [adc index 0-31, -1 for all] [12 "
|
||||
os << "[chip index 0-9, -1 for all] [adc index 0-31, -1 for all] [7 "
|
||||
"bit configuration value in hex]\n\t[Gotthard2] Sets "
|
||||
"configuration for specific chip and adc, but configures 1 chip "
|
||||
"(all adcs for that chip) at a time."
|
||||
@ -2860,6 +2893,8 @@ std::string CmdProxy::PatternLoopAddresses(int action) {
|
||||
if (cmd != "patlimits") {
|
||||
GetLevelAndUpdateArgIndex(action, "patloop", level, iArg, nGetArgs,
|
||||
nPutArgs);
|
||||
if (cmd != "patloop0" && cmd != "patloop1" && cmd != "patloop2")
|
||||
os << level << ' ';
|
||||
}
|
||||
if (action == defs::GET_ACTION) {
|
||||
auto t =
|
||||
@ -2899,6 +2934,8 @@ std::string CmdProxy::PatternLoopCycles(int action) {
|
||||
int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1;
|
||||
GetLevelAndUpdateArgIndex(action, "patnloop", level, iArg, nGetArgs,
|
||||
nPutArgs);
|
||||
if (cmd != "patnloop0" && cmd != "patnloop1" && cmd != "patnloop2")
|
||||
os << level << ' ';
|
||||
if (action == defs::GET_ACTION) {
|
||||
auto t = det->getPatternLoopCycles(level, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
@ -2933,6 +2970,8 @@ std::string CmdProxy::PatternWaitAddress(int action) {
|
||||
int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1;
|
||||
GetLevelAndUpdateArgIndex(action, "patwait", level, iArg, nGetArgs,
|
||||
nPutArgs);
|
||||
if (cmd != "patwait0" && cmd != "patwait1" && cmd != "patwait2")
|
||||
os << level << ' ';
|
||||
if (action == defs::GET_ACTION) {
|
||||
auto t = det->getPatternWaitAddr(level, std::vector<int>{det_id});
|
||||
os << OutStringHex(t, 4) << '\n';
|
||||
@ -2966,6 +3005,9 @@ std::string CmdProxy::PatternWaitTime(int action) {
|
||||
int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1;
|
||||
GetLevelAndUpdateArgIndex(action, "patwaittime", level, iArg, nGetArgs,
|
||||
nPutArgs);
|
||||
if (cmd != "patwaittime0" && cmd != "patwaittime1" &&
|
||||
cmd != "patwaittime2")
|
||||
os << level << ' ';
|
||||
if (action == defs::GET_ACTION) {
|
||||
auto t = det->getPatternWaitTime(level, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
|
@ -1155,7 +1155,8 @@ class CmdProxy {
|
||||
std::string Scan(int action);
|
||||
std::string Trigger(int action);
|
||||
/* Network Configuration (Detector<->Receiver) */
|
||||
IpAddr getIpFromAuto();
|
||||
IpAddr getDstIpFromAuto();
|
||||
IpAddr getSrcIpFromAuto();
|
||||
UdpDestination getUdpEntry();
|
||||
std::string UDPDestinationList(int action);
|
||||
std::string UDPSourceIP(int action);
|
||||
@ -1782,11 +1783,12 @@ class CmdProxy {
|
||||
rx_lastclient, getRxLastClientIP,
|
||||
"\n\tClient IP Address that last communicated with the receiver.");
|
||||
|
||||
GET_COMMAND(rx_threads, getRxThreadIds,
|
||||
"\n\tGet thread ids from the receiver in order of [parent, "
|
||||
"tcp, listener 0, processor 0, streamer 0, listener 1, "
|
||||
"processor 1, streamer 1, arping]. If no streamer yet or there "
|
||||
"is no second interface, it gives 0 in its place.");
|
||||
GET_COMMAND(
|
||||
rx_threads, getRxThreadIds,
|
||||
"\n\tGet kernel thread ids from the receiver in order of [parent, "
|
||||
"tcp, listener 0, processor 0, streamer 0, listener 1, "
|
||||
"processor 1, streamer 1, arping]. If no streamer yet or there "
|
||||
"is no second interface, it gives 0 in its place.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(rx_arping, getRxArping, setRxArping, StringTo<int>,
|
||||
"[0, 1]\n\tStarts a thread in slsReceiver to arping "
|
||||
|
@ -351,6 +351,29 @@ void Detector::setBadChannels(const std::string &fname, Positions pos) {
|
||||
pimpl->setBadChannels(fname, pos);
|
||||
}
|
||||
|
||||
Result<std::vector<int>> Detector::getBadChannels(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getBadChannels, pos);
|
||||
}
|
||||
|
||||
void Detector::setBadChannels(const std::vector<std::vector<int>> list) {
|
||||
|
||||
if (list.size() != static_cast<size_t>(size())) {
|
||||
std::stringstream ss;
|
||||
ss << "Number of bad channel sets (" << list.size()
|
||||
<< ") needs to match the number of modules (" << size() << ")";
|
||||
throw RuntimeError(ss.str());
|
||||
}
|
||||
|
||||
for (int idet = 0; idet < size(); ++idet) {
|
||||
// TODO! Call in parallel since loading trimbits is slow?
|
||||
pimpl->Parallel(&Module::setBadChannels, {idet}, list[idet]);
|
||||
}
|
||||
}
|
||||
|
||||
void Detector::setBadChannels(const std::vector<int> list, Positions pos) {
|
||||
pimpl->setBadChannels(list, pos);
|
||||
}
|
||||
|
||||
Result<bool> Detector::isVirtualDetectorServer(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::isVirtualDetectorServer, pos);
|
||||
}
|
||||
|
@ -253,14 +253,15 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
|
||||
}
|
||||
|
||||
void DetectorImpl::setHostname(const std::vector<std::string> &name) {
|
||||
// this check is there only to allow the previous detsizechan command
|
||||
if (shm()->totalNumberOfModules != 0) {
|
||||
// do not free always to allow the previous detsize/ initialchecks command
|
||||
if (shm.exists() && shm()->totalNumberOfModules != 0) {
|
||||
LOG(logWARNING) << "There are already module(s) in shared memory."
|
||||
"Freeing Shared memory now.";
|
||||
bool initialChecks = shm()->initialChecks;
|
||||
freeSharedMemory();
|
||||
}
|
||||
// could be called after freeing shm from API
|
||||
if (!shm.exists()) {
|
||||
setupDetector();
|
||||
shm()->initialChecks = initialChecks;
|
||||
}
|
||||
for (const auto &hostname : name) {
|
||||
addModule(hostname);
|
||||
@ -342,28 +343,32 @@ void DetectorImpl::updateDetectorSize() {
|
||||
"updating detector size. ");
|
||||
}
|
||||
|
||||
int maxx = shm()->numberOfChannels.x;
|
||||
int maxy = shm()->numberOfChannels.y;
|
||||
int nModx = 0, nMody = 0;
|
||||
// 1d, add modules along x axis
|
||||
if (modSize.y == 1) {
|
||||
if (maxx == 0) {
|
||||
maxx = modSize.x * size();
|
||||
int detSizeX = shm()->numberOfChannels.x;
|
||||
int maxChanX = modSize.x * size();
|
||||
// user given detsizex used only within max value
|
||||
if (detSizeX > 1 && detSizeX <= maxChanX) {
|
||||
maxChanX = detSizeX;
|
||||
}
|
||||
nModx = maxx / modSize.x;
|
||||
nModx = maxChanX / modSize.x;
|
||||
nMody = size() / nModx;
|
||||
if ((maxx % modSize.x) > 0) {
|
||||
if ((maxChanX % modSize.x) > 0) {
|
||||
++nMody;
|
||||
}
|
||||
}
|
||||
// 2d, add modules along y axis (due to eiger top/bottom)
|
||||
else {
|
||||
if (maxy == 0) {
|
||||
maxy = modSize.y * size();
|
||||
int detSizeY = shm()->numberOfChannels.y;
|
||||
int maxChanY = modSize.y * size();
|
||||
// user given detsizey used only within max value
|
||||
if (detSizeY > 1 && detSizeY <= maxChanY) {
|
||||
maxChanY = detSizeY;
|
||||
}
|
||||
nMody = maxy / modSize.y;
|
||||
nMody = maxChanY / modSize.y;
|
||||
nModx = size() / nMody;
|
||||
if ((maxy % modSize.y) > 0) {
|
||||
if ((maxChanY % modSize.y) > 0) {
|
||||
++nModx;
|
||||
}
|
||||
}
|
||||
@ -518,19 +523,18 @@ void DetectorImpl::setTransmissionDelay(int step) {
|
||||
f.get();
|
||||
}
|
||||
|
||||
int DetectorImpl::destroyReceivingDataSockets() {
|
||||
void DetectorImpl::destroyReceivingDataSockets() {
|
||||
LOG(logINFO) << "Going to destroy data sockets";
|
||||
// close socket
|
||||
zmqSocket.clear();
|
||||
|
||||
client_downstream = false;
|
||||
LOG(logINFO) << "Destroyed Receiving Data Socket(s)";
|
||||
return OK;
|
||||
}
|
||||
|
||||
int DetectorImpl::createReceivingDataSockets() {
|
||||
void DetectorImpl::createReceivingDataSockets() {
|
||||
if (client_downstream) {
|
||||
return OK;
|
||||
return;
|
||||
}
|
||||
LOG(logINFO) << "Going to create data sockets";
|
||||
|
||||
@ -557,24 +561,22 @@ int DetectorImpl::createReceivingDataSockets() {
|
||||
int hwm = shm()->zmqHwm;
|
||||
if (hwm >= 0) {
|
||||
zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm);
|
||||
if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) {
|
||||
throw ZmqSocketError("Could not set zmq rcv hwm to " +
|
||||
std::to_string(hwm));
|
||||
}
|
||||
// need not reconnect. cannot be connected (detector idle)
|
||||
}
|
||||
LOG(logINFO) << "Zmq Client[" << iSocket << "] at "
|
||||
<< zmqSocket.back()->GetZmqServerAddress() << "[hwm: "
|
||||
<< zmqSocket.back()->GetReceiveHighWaterMark() << "]";
|
||||
} catch (...) {
|
||||
LOG(logERROR) << "Could not create Zmq socket on port " << portnum;
|
||||
} catch (std::exception &e) {
|
||||
destroyReceivingDataSockets();
|
||||
return FAIL;
|
||||
std::ostringstream oss;
|
||||
oss << "Could not create zmq sub socket on port " << portnum;
|
||||
oss << " [" << e.what() << ']';
|
||||
throw RuntimeError(oss.str());
|
||||
}
|
||||
}
|
||||
|
||||
client_downstream = true;
|
||||
LOG(logINFO) << "Receiving Data Socket(s) created";
|
||||
return OK;
|
||||
}
|
||||
|
||||
void DetectorImpl::readFrameFromReceiver() {
|
||||
@ -1114,9 +1116,7 @@ void DetectorImpl::setDataStreamingToClient(bool enable) {
|
||||
destroyReceivingDataSockets();
|
||||
// create data threads
|
||||
} else {
|
||||
if (createReceivingDataSockets() == FAIL) {
|
||||
throw RuntimeError("Could not create data threads in client.");
|
||||
}
|
||||
createReceivingDataSockets();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1149,11 +1149,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
|
||||
if (limit >= 0) {
|
||||
for (auto &it : zmqSocket) {
|
||||
it->SetReceiveHighWaterMark(limit);
|
||||
if (it->GetReceiveHighWaterMark() != limit) {
|
||||
shm()->zmqHwm = -1;
|
||||
throw ZmqSocketError("Could not set zmq rcv hwm to " +
|
||||
std::to_string(limit));
|
||||
}
|
||||
// need not reconnect. cannot be connected (detector idle)
|
||||
}
|
||||
LOG(logINFO) << "Setting Client Zmq socket rcv hwm to " << limit;
|
||||
}
|
||||
@ -1231,8 +1227,7 @@ int DetectorImpl::acquire() {
|
||||
// let the progress thread (no callback) know acquisition is done
|
||||
if (dataReady == nullptr) {
|
||||
setJoinThreadFlag(true);
|
||||
}
|
||||
if (receiver) {
|
||||
} else if (receiver) {
|
||||
while (numZmqRunning != 0) {
|
||||
Parallel(&Module::restreamStopFromReceiver, {});
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
@ -1322,6 +1317,7 @@ void DetectorImpl::processData(bool receiver) {
|
||||
}
|
||||
// only update progress
|
||||
else {
|
||||
LOG(logINFO) << "Type 'q' and hit enter to stop acquisition";
|
||||
double progress = 0;
|
||||
printProgress(progress);
|
||||
|
||||
@ -1778,6 +1774,10 @@ void DetectorImpl::setBadChannels(const std::string &fname, Positions pos) {
|
||||
if (list.empty()) {
|
||||
throw RuntimeError("Bad channel file is empty.");
|
||||
}
|
||||
setBadChannels(list, pos);
|
||||
}
|
||||
|
||||
void DetectorImpl::setBadChannels(const std::vector<int> list, Positions pos) {
|
||||
|
||||
// update to multi values if multi modules
|
||||
if (isAllPositions(pos)) {
|
||||
@ -1794,20 +1794,24 @@ void DetectorImpl::setBadChannels(const std::string &fname, Positions pos) {
|
||||
" out of bounds.");
|
||||
}
|
||||
int ch = badchannel % nchan;
|
||||
int imod = badchannel / nchan;
|
||||
if (imod >= (int)modules.size()) {
|
||||
size_t imod = badchannel / nchan;
|
||||
if (imod >= modules.size()) {
|
||||
throw RuntimeError("Invalid bad channel list. " +
|
||||
std::to_string(badchannel) +
|
||||
" out of bounds.");
|
||||
}
|
||||
|
||||
if ((int)badchannels.size() != imod + 1) {
|
||||
if (badchannels.size() != imod + 1) {
|
||||
badchannels.push_back(std::vector<int>{});
|
||||
}
|
||||
badchannels[imod].push_back(ch);
|
||||
}
|
||||
for (int imod = 0; imod != (int)modules.size(); ++imod) {
|
||||
Parallel(&Module::setBadChannels, {imod}, badchannels[imod]);
|
||||
for (size_t imod = 0; imod != modules.size(); ++imod) {
|
||||
// add empty vector if no bad channels in this module
|
||||
if (badchannels.size() != imod + 1) {
|
||||
badchannels.push_back(std::vector<int>{});
|
||||
}
|
||||
Parallel(&Module::setBadChannels, {static_cast<int>(imod)},
|
||||
badchannels[imod]);
|
||||
}
|
||||
|
||||
} else if (pos.size() != 1) {
|
||||
|
@ -306,6 +306,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
|
||||
void getBadChannels(const std::string &fname, Positions pos) const;
|
||||
void setBadChannels(const std::string &fname, Positions pos);
|
||||
void setBadChannels(const std::vector<int> list, Positions pos);
|
||||
|
||||
std::vector<std::string> getCtbDacNames() const;
|
||||
std::string getCtbDacName(defs::dacIndex i) const;
|
||||
@ -348,8 +349,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
|
||||
void updateDetectorSize();
|
||||
|
||||
int destroyReceivingDataSockets();
|
||||
int createReceivingDataSockets();
|
||||
void destroyReceivingDataSockets();
|
||||
void createReceivingDataSockets();
|
||||
|
||||
/**
|
||||
* Reads frames from receiver through a constant socket
|
||||
|
@ -76,7 +76,7 @@ void Module::setHostname(const std::string &hostname,
|
||||
initialDetectorServerChecks();
|
||||
checkDetectorVersionCompatibility();
|
||||
LOG(logINFO) << "Module Version Compatibility - Success";
|
||||
} catch (const DetectorError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
if (!initialChecks) {
|
||||
LOG(logWARNING) << "Bypassing Initial Checks at your own risk!";
|
||||
} else {
|
||||
@ -876,26 +876,25 @@ void Module::startReadout() {
|
||||
}
|
||||
|
||||
void Module::stopAcquisition() {
|
||||
// get status before stopping acquisition
|
||||
runStatus s = ERROR, r = ERROR;
|
||||
bool zmqstreaming = false;
|
||||
|
||||
// get det status before stopping acq
|
||||
runStatus detStatus = ERROR;
|
||||
try {
|
||||
if (shm()->useReceiverFlag && getReceiverStreaming()) {
|
||||
zmqstreaming = true;
|
||||
s = getRunStatus();
|
||||
r = getReceiverStatus();
|
||||
}
|
||||
detStatus = getRunStatus();
|
||||
} catch (...) {
|
||||
// if receiver crashed, stop detector in any case
|
||||
zmqstreaming = false;
|
||||
}
|
||||
|
||||
sendToDetectorStop(F_STOP_ACQUISITION);
|
||||
shm()->stoppedFlag = true;
|
||||
|
||||
// if rxr streaming and acquisition finished, restream dummy stop packet
|
||||
if (zmqstreaming && (s == IDLE) && (r == IDLE)) {
|
||||
restreamStopFromReceiver();
|
||||
// restream dummy header, if rxr streaming and det idle before stop
|
||||
try {
|
||||
if (shm()->useReceiverFlag && getReceiverStreaming()) {
|
||||
if (detStatus == IDLE && getReceiverStatus() == IDLE) {
|
||||
restreamStopFromReceiver();
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,15 @@
|
||||
|
||||
namespace sls {
|
||||
|
||||
Pattern::Pattern() = default;
|
||||
Pattern::Pattern() {
|
||||
// initialize pattern addresses
|
||||
for (int i = 0; i != MAX_PATTERN_LEVELS; ++i) {
|
||||
pat->startloop[i] = MAX_PATTERN_LENGTH - 1;
|
||||
pat->stoploop[i] = MAX_PATTERN_LENGTH - 1;
|
||||
pat->wait[i] = MAX_PATTERN_LENGTH - 1;
|
||||
}
|
||||
}
|
||||
|
||||
Pattern::~Pattern() { delete pat; }
|
||||
|
||||
Pattern::Pattern(const Pattern &other) {
|
||||
|
@ -33,7 +33,7 @@ namespace sls {
|
||||
template <typename T> class SharedMemory {
|
||||
static constexpr int NAME_MAX_LENGTH = 255;
|
||||
std::string name;
|
||||
T *shared_struct{};
|
||||
T *shared_struct{nullptr};
|
||||
|
||||
public:
|
||||
// moduleid of -1 creates a detector only shared memory
|
||||
@ -64,8 +64,18 @@ template <typename T> class SharedMemory {
|
||||
unmapSharedMemory();
|
||||
}
|
||||
|
||||
T *operator()() { return shared_struct; }
|
||||
const T *operator()() const { return shared_struct; }
|
||||
T *operator()() {
|
||||
if (shared_struct)
|
||||
return shared_struct;
|
||||
throw SharedMemoryError(getNoShmAccessMessage());
|
||||
}
|
||||
|
||||
const T *operator()() const {
|
||||
if (shared_struct)
|
||||
return shared_struct;
|
||||
throw SharedMemoryError(getNoShmAccessMessage());
|
||||
}
|
||||
|
||||
std::string getName() const { return name; }
|
||||
|
||||
bool exists() {
|
||||
@ -204,6 +214,11 @@ template <typename T> class SharedMemory {
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
const char *getNoShmAccessMessage() const {
|
||||
return ("No shared memory to access. Create it first with "
|
||||
"hostname or config command.");
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
|
@ -702,11 +702,11 @@ TEST_CASE("confadc", "[.cmd]") {
|
||||
}
|
||||
}
|
||||
|
||||
REQUIRE_THROWS(proxy.Call("confadc", {"11", "2", "0x3ff"}, -1,
|
||||
REQUIRE_THROWS(proxy.Call("confadc", {"11", "2", "0x7f"}, -1,
|
||||
PUT)); // invalid chip index
|
||||
REQUIRE_THROWS(proxy.Call("confadc", {"-1", "10", "0x3ff"}, -1,
|
||||
REQUIRE_THROWS(proxy.Call("confadc", {"-1", "32", "0x7f"}, -1,
|
||||
PUT)); // invalid adc index
|
||||
REQUIRE_THROWS(proxy.Call("confadc", {"-1", "10", "0x1fff"}, -1,
|
||||
REQUIRE_THROWS(proxy.Call("confadc", {"-1", "10", "0x80"}, -1,
|
||||
PUT)); // invalid value
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@ -718,10 +718,11 @@ TEST_CASE("confadc", "[.cmd]") {
|
||||
proxy.Call("confadc", {"2", "3"}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "confadc 0x11\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i != ndet; ++i) {
|
||||
for (int j = 0; j != nchip; ++j) {
|
||||
for (int k = 0; k != nadc; ++k) {
|
||||
det.setADCConfiguration(j, k, prev_val[i][j][k], {i});
|
||||
det.setADCConfiguration(-1, k, prev_val[i][j][k], {i});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,12 +181,14 @@ TEST_CASE("patloop", "[.cmd]") {
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patloop", {sLoop, "0x20", "0x5c"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "patloop [0x0020, 0x005c]\n");
|
||||
REQUIRE(oss.str() ==
|
||||
"patloop " + sLoop + " [0x0020, 0x005c]\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patloop", {sLoop}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "patloop [0x0020, 0x005c]\n");
|
||||
REQUIRE(oss.str() ==
|
||||
"patloop " + sLoop + " [0x0020, 0x005c]\n");
|
||||
}
|
||||
for (int iDet = 0; iDet != det.size(); ++iDet) {
|
||||
det.setPatternLoopAddresses(iLoop, prev_val[iDet][0],
|
||||
@ -227,12 +229,12 @@ TEST_CASE("patnloop", "[.cmd]") {
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patnloop", {sLoop, "5"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "patnloop 5\n");
|
||||
REQUIRE(oss.str() == "patnloop " + sLoop + " 5\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patnloop", {sLoop}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "patnloop 5\n");
|
||||
REQUIRE(oss.str() == "patnloop " + sLoop + " 5\n");
|
||||
}
|
||||
for (int iDet = 0; iDet != det.size(); ++iDet) {
|
||||
det.setPatternLoopCycles(iLoop, prev_val[iDet], {iDet});
|
||||
@ -272,12 +274,12 @@ TEST_CASE("patwait", "[.cmd]") {
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patwait", {sLoop, "0x5c"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "patwait 0x005c\n");
|
||||
REQUIRE(oss.str() == "patwait " + sLoop + " 0x005c\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patwait", {sLoop}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "patwait 0x005c\n");
|
||||
REQUIRE(oss.str() == "patwait " + sLoop + " 0x005c\n");
|
||||
}
|
||||
for (int iDet = 0; iDet != det.size(); ++iDet) {
|
||||
det.setPatternWaitAddr(iLoop, prev_val[iDet], {iDet});
|
||||
@ -317,12 +319,12 @@ TEST_CASE("patwaittime", "[.cmd]") {
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patwaittime", {sLoop, "8589936640"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "patwaittime 8589936640\n");
|
||||
REQUIRE(oss.str() == "patwaittime " + sLoop + " 8589936640\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("patwaittime", {sLoop}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "patwaittime 8589936640\n");
|
||||
REQUIRE(oss.str() == "patwaittime " + sLoop + " 8589936640\n");
|
||||
}
|
||||
for (int iDet = 0; iDet != det.size(); ++iDet) {
|
||||
det.setPatternWaitTime(iLoop, prev_val[iDet], {iDet});
|
||||
|
@ -145,7 +145,8 @@ TEST_CASE("rx_missingpackets", "[.cmd][.rx]") {
|
||||
REQUIRE(oss.str() != "rx_missingpackets [0, 0]\n");
|
||||
}
|
||||
}
|
||||
{
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type != defs::CHIPTESTBOARD && det_type != defs::MOENCH) {
|
||||
// 0 missing packets (takes into account that acquisition is stopped)
|
||||
det.startReceiver();
|
||||
det.startDetector();
|
||||
|
@ -517,8 +517,19 @@ TEST_CASE("gappixels", "[.cmd]") {
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH ||
|
||||
det_type == defs::EIGER) {
|
||||
// test eiger(quad or full module only)
|
||||
bool gapPixelTest = false;
|
||||
if (det_type == defs:: || det_type == defs::MOENCH)
|
||||
gapPixelTest = true;
|
||||
else if (det_type == defs::EIGER) {
|
||||
bool quad = det.getQuad().squash(false);
|
||||
bool fullModule = (det.getModuleGeometry().y % 2 == 0);
|
||||
if (quad || fullModule) {
|
||||
gapPixelTest = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (gapPixelTest) {
|
||||
auto prev_val = det.getGapPixelsinCallback();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@ -637,6 +648,8 @@ TEST_CASE("badchannels", "[.cmd]") {
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::GOTTHARD2 || det_type == defs::MYTHEN3) {
|
||||
auto prev = det.getBadChannels();
|
||||
|
||||
REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET));
|
||||
|
||||
std::string fname_put =
|
||||
@ -649,6 +662,51 @@ TEST_CASE("badchannels", "[.cmd]") {
|
||||
std::vector<int> expected = {0, 12, 15, 40, 41, 42, 43, 44, 1279};
|
||||
REQUIRE(list == expected);
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {"none"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
REQUIRE(list.empty());
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_put}, 0, PUT));
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {"0"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
REQUIRE(list.empty());
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {"12"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
expected = {12};
|
||||
REQUIRE(list == expected);
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call(
|
||||
"badchannels", {"0", "12,", "15", "43", "40:45", "1279"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
expected = {0, 12, 15, 40, 41, 42, 43, 44, 1279};
|
||||
REQUIRE(list == expected);
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {"40:45"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
expected = {40, 41, 42, 43, 44};
|
||||
REQUIRE(list == expected);
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {"5,6,7"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
expected = {5, 6, 7};
|
||||
REQUIRE(list == expected);
|
||||
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {"1:5,6,7"}, 0, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
|
||||
list = getChannelsFromFile(fname_get);
|
||||
expected = {1, 2, 3, 4, 6, 7};
|
||||
REQUIRE(list == expected);
|
||||
|
||||
det.setBadChannels(prev);
|
||||
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET));
|
||||
}
|
||||
@ -1216,7 +1274,7 @@ TEST_CASE("clkphase", "[.cmd]") {
|
||||
}
|
||||
std::string s_deg_val = "15";
|
||||
if (det_type == defs::MYTHEN3) {
|
||||
s_deg_val = "15";
|
||||
s_deg_val = "14";
|
||||
} else if (det_type == defs::GOTTHARD2) {
|
||||
s_deg_val = "23";
|
||||
}
|
||||
|
@ -101,7 +101,8 @@ TEST_CASE("Move SharedMemory", "[detector]") {
|
||||
shm2 = std::move(shm); // shm is now a moved from object!
|
||||
|
||||
CHECK(shm2()->x == 9);
|
||||
CHECK(shm() == nullptr);
|
||||
REQUIRE_THROWS(
|
||||
shm()); // trying to access should throw instead of returning a nullptr
|
||||
CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") +
|
||||
std::to_string(shm_id));
|
||||
shm2.removeSharedMemory();
|
||||
|
Reference in New Issue
Block a user