Compare commits

...

17 Commits

Author SHA1 Message Date
f761046bfc updated docs and versions 2023-07-12 16:50:13 +02:00
1a859b83db formatting 2023-07-12 16:06:31 +02:00
70bfc875a6 updating release notes 2023-07-11 17:02:27 +02:00
c0755308a4 updating release notes 2023-07-11 17:01:14 +02:00
ab5509e10c updating release notes 2023-07-11 17:00:42 +02:00
004cb26646 updated firmware versions for 7.0.2 2023-07-10 12:21:19 +02:00
a4f47a5945 synced master status running when setting to slave (#747)
* jf: unsync before setting master/slave and then sync (if it was set) to overcome master going into running state when making it a slave and synced

* add tests for this condition

* updated release notes, updated min fw version requirement for v1.0 boards
2023-05-25 11:04:05 +02:00
312f3f473d fix that only master starts second and not all (for start acq), typo with pos and masters list (#743) 2023-05-11 10:20:17 +02:00
5871086cd6 formatting 2023-05-08 17:04:04 +02:00
6a0fe823b3 enable fix g0 when in expert mode (when gain mode enabled and not just visible) (#736) 2023-05-08 14:20:21 +02:00
5912aae53e Rx roi zmq (#726)
adding rx_roi also in the zmq header for external guis to put the "yellow box".. sending full roi instead of -1, and sending for each zmq port. "(multiple yellow boxes)".
2023-05-08 12:23:05 +02:00
8833ccf5cc 7.0.2.rc (#721)
* row and column for jungfrau mixed up

* multi module jungfrau sync must do slaves first then master for start acquisition and send software trigger, and master first and then slaves for stopacquisition

* non blocking to slaves first and only then blocking/nonblocking to the master for sending software trigger(jungfrau multi mod sync)

* fixed get/set timing jungfrau when sync enabled, getsync during blocking acquire (for trigger or stop) will get stuck as it should ask the stop server

* switching between 1 and 2 interfaces did not set gui/client zmq port properly. Resulted in dummy streaming forever. fixed

* formatting, refactoring: const & for positions, multi mod M3 stop first master first

* adding missing cstdint for gcc 13

* Refactoring handle sync out, handling synchronization also for softwaretrigger for m3, for start/sync/stop for g2/g1

---------

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
2023-05-08 12:11:19 +02:00
77c558a7be formatting 2023-03-24 12:54:55 +01:00
378fc301b8 updating client version, release version and project_version in CMakeLists.txt 2023-03-23 15:43:17 +01:00
87d6e16090 7.0.1 fix det server version (#702)
* check server version before initial checks, catch old server version exception, get old server version as 64 bit and print it along with exception
2023-03-23 15:37:01 +01:00
2ef021041c rx_arping sigchld (#701)
* rx_arping pclose gave -1 due to sigchld being ignored, fixed with sig handler doing a wait
2023-03-23 13:58:40 +01:00
574127b5ac fix hdf5 compilation using det spec fields in header (#700)
* fix hdf5 compilation using det spec fields in header
2023-03-23 12:30:38 +01:00
29 changed files with 347 additions and 1029 deletions

View File

@ -2,7 +2,7 @@
# Copyright (C) 2021 Contributors to the SLS Detector Package # Copyright (C) 2021 Contributors to the SLS Detector Package
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.12)
project(slsDetectorPackage) project(slsDetectorPackage)
set(PROJECT_VERSION 7.0.0) set(PROJECT_VERSION 7.0.2)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")

File diff suppressed because it is too large Load Diff

View File

@ -140,14 +140,21 @@ ZMQ: Json Header Format
"quad": unsigned int, "quad": unsigned int,
"addJsonHeader": { "addJsonHeader": {
string : string string : string
} },
"rx_roi": [
unsigned int,
unsigned int,
unsigned int,
unsigned int
]
} }
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| Field | Description | | Field | Description |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| jsonversion | Version of the json header. | | jsonversion | Version of the json header. |
| | Value at 4 for v6.x.x and v7.x.x | | | Value at 4 for v6.x.x - v7.0.1 |
| | Value at 5 for v7.0.2 |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| bitmode | Bits per pixel [4|8|16|32] | | bitmode | Bits per pixel [4|8|16|32] |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
@ -222,7 +229,10 @@ ZMQ: Json Header Format
| addJsonHeader| Optional custom parameters that is required | | addJsonHeader| Optional custom parameters that is required |
| | for processing code. | | | for processing code. |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| rx_roi | ROI in the receiver per port (xmin, xmax, |
| | ymin, ymax). For external guis to know |
| | what is saved |
+--------------+----------------------------------------------+
SLS Receiver Header Format SLS Receiver Header Format
-------------------------- --------------------------

View File

@ -1 +0,0 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2

View File

@ -132,7 +132,7 @@ void qTabSettings::SetupWidgetWindow() {
} }
void qTabSettings::SetExportMode(bool exportMode) { void qTabSettings::SetExportMode(bool exportMode) {
if (comboGainMode->isVisible()) { if (comboGainMode->isEnabled()) {
ShowFixG0(exportMode); ShowFixG0(exportMode);
} }
} }

View File

@ -1388,14 +1388,18 @@ int setMaster(enum MASTERINDEX m) {
char *master_names[] = {MASTER_NAMES}; char *master_names[] = {MASTER_NAMES};
LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m], LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m],
(isControlServer ? "control" : "stop"))); (isControlServer ? "control" : "stop")));
int prevSync = getSynchronization();
setSynchronization(0);
int retval = -1; int retval = -1;
int retMaster = OK;
switch (m) { switch (m) {
case OW_MASTER: case OW_MASTER:
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK); bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK);
isMaster(&retval); isMaster(&retval);
if (retval != 1) { if (retval != 1) {
LOG(logERROR, ("Could not set master\n")); LOG(logERROR, ("Could not set master\n"));
return FAIL; retMaster = FAIL;
} }
break; break;
case OW_SLAVE: case OW_SLAVE:
@ -1403,15 +1407,16 @@ int setMaster(enum MASTERINDEX m) {
isMaster(&retval); isMaster(&retval);
if (retval != 0) { if (retval != 0) {
LOG(logERROR, ("Could not set slave\n")); LOG(logERROR, ("Could not set slave\n"));
return FAIL; retMaster = FAIL;
} }
break; break;
default: default:
LOG(logERROR, ("Cannot reset to hardware settings from client. Restart " LOG(logERROR, ("Cannot reset to hardware settings from client. Restart "
"detector server.\n")); "detector server.\n"));
return FAIL; retMaster = FAIL;
} }
return OK; setSynchronization(prevSync);
return retMaster;
} }
int isMaster(int *retval) { int isMaster(int *retval) {
@ -1449,7 +1454,7 @@ void setTiming(enum timingMode arg) {
} }
enum timingMode getTiming() { enum timingMode getTiming() {
if (bus_r(EXT_SIGNAL_REG) == EXT_SIGNAL_MSK) if ((bus_r(EXT_SIGNAL_REG) & EXT_SIGNAL_MSK) >> EXT_SIGNAL_OFST)
return TRIGGER_EXPOSURE; return TRIGGER_EXPOSURE;
return AUTO_TIMING; return AUTO_TIMING;
} }
@ -1736,40 +1741,40 @@ int setDetectorPosition(int pos[]) {
detPos[2] = outerPos[X]; detPos[2] = outerPos[X];
detPos[3] = outerPos[Y]; detPos[3] = outerPos[Y];
// row // row [Y]
// outer // outer
uint32_t addr = COORD_ROW_REG; uint32_t addr = COORD_ROW_REG;
bus_w(addr, bus_w(addr,
(bus_r(addr) & ~COORD_ROW_OUTER_MSK) | (bus_r(addr) & ~COORD_ROW_OUTER_MSK) |
((outerPos[X] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK)); ((outerPos[Y] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK));
if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) != if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) !=
outerPos[X])
ret = FAIL;
// inner
bus_w(addr,
(bus_r(addr) & ~COORD_ROW_INNER_MSK) |
((innerPos[X] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
innerPos[X])
ret = FAIL;
// col
// outer
addr = COORD_COL_REG;
bus_w(addr,
(bus_r(addr) & ~COORD_COL_OUTER_MSK) |
((outerPos[Y] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK));
if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) !=
outerPos[Y]) outerPos[Y])
ret = FAIL; ret = FAIL;
// inner // inner
bus_w(addr, bus_w(addr,
(bus_r(addr) & ~COORD_COL_INNER_MSK) | (bus_r(addr) & ~COORD_ROW_INNER_MSK) |
((innerPos[Y] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK)); ((innerPos[Y] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) != if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
innerPos[Y]) innerPos[Y])
ret = FAIL; ret = FAIL;
// col [X]
// outer
addr = COORD_COL_REG;
bus_w(addr,
(bus_r(addr) & ~COORD_COL_OUTER_MSK) |
((outerPos[X] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK));
if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) !=
outerPos[X])
ret = FAIL;
// inner
bus_w(addr,
(bus_r(addr) & ~COORD_COL_INNER_MSK) |
((innerPos[X] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK));
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) !=
innerPos[X])
ret = FAIL;
if (ret == OK) { if (ret == OK) {
if (getNumberofUDPInterfaces() == 1) { if (getNumberofUDPInterfaces() == 1) {
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n", LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",

View File

@ -5,8 +5,8 @@
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#define MIN_REQRD_VRSN_T_RD_API 0x171220 #define MIN_REQRD_VRSN_T_RD_API 0x171220
#define REQRD_FRMWRE_VRSN_BOARD2 0x221104 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN_BOARD2 0x230516 // 1.0 pcb (version = 010)
#define REQRD_FRMWRE_VRSN 0x221103 // 2.0 pcb (version = 011) #define REQRD_FRMWRE_VRSN 0x230515 // 2.0 pcb (version = 011)
#define NUM_HARDWARE_VERSIONS (2) #define NUM_HARDWARE_VERSIONS (2)
#define HARDWARE_VERSION_NUMBERS \ #define HARDWARE_VERSION_NUMBERS \

View File

@ -855,7 +855,7 @@ void Detector::stopDetector(Positions pos) {
throw RuntimeError( throw RuntimeError(
"Could not stop detector. Returned error status."); "Could not stop detector. Returned error status.");
} }
pimpl->Parallel(&Module::stopAcquisition, pos); pimpl->stopDetector(pos);
status = getDetectorStatus().squash(defs::runStatus::RUNNING); status = getDetectorStatus().squash(defs::runStatus::RUNNING);
++retries; ++retries;
@ -914,7 +914,7 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) {
} }
void Detector::sendSoftwareTrigger(const bool block, Positions pos) { void Detector::sendSoftwareTrigger(const bool block, Positions pos) {
pimpl->Parallel(&Module::sendSoftwareTrigger, pos, block); pimpl->sendSoftwareTrigger(block, pos);
} }
Result<defs::scanParameters> Detector::getScan(Positions pos) const { Result<defs::scanParameters> Detector::getScan(Positions pos) const {
@ -951,18 +951,23 @@ void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
} }
void Detector::setNumberofUDPInterfaces_(int n, Positions pos) { void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
if (!size()) {
throw RuntimeError("No modules added.");
}
bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
int clientStartingPort = getClientZmqPort({0}).squash(0);
bool useReceiver = getUseReceiverFlag().squash(false); bool useReceiver = getUseReceiverFlag().squash(false);
bool previouslyReceiverStreaming = false; bool previouslyReceiverStreaming = false;
int startingPort = 0; int rxStartingPort = 0;
if (useReceiver) { if (useReceiver) {
previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true); previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true);
startingPort = getRxZmqPort({0}).squash(0); rxStartingPort = getRxZmqPort({0}).squash(0);
} }
pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n); pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n);
// ensure receiver zmq socket ports are multiplied by 2 (2 interfaces) // ensure receiver zmq socket ports are multiplied by 2 (2 interfaces)
if (getUseReceiverFlag().squash(false) && size()) { setClientZmqPort(clientStartingPort, -1);
setRxZmqPort(startingPort, -1); if (getUseReceiverFlag().squash(false)) {
setRxZmqPort(rxStartingPort, -1);
} }
// redo the zmq sockets if enabled // redo the zmq sockets if enabled
if (previouslyClientStreaming) { if (previouslyClientStreaming) {

View File

@ -769,7 +769,7 @@ void DetectorImpl::readFrameFromReceiver() {
int nDetActualPixelsY = nDetPixelsY; int nDetActualPixelsY = nDetPixelsY;
if (gapPixels) { if (gapPixels) {
int n = InsertGapPixels(multiframe.get(), multigappixels, int n = insertGapPixels(multiframe.get(), multigappixels,
quadEnable, dynamicRange, quadEnable, dynamicRange,
nDetActualPixelsX, nDetActualPixelsY); nDetActualPixelsX, nDetActualPixelsY);
callbackImage = multigappixels; callbackImage = multigappixels;
@ -808,7 +808,7 @@ void DetectorImpl::readFrameFromReceiver() {
delete[] multigappixels; delete[] multigappixels;
} }
int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int DetectorImpl::insertGapPixels(char *image, char *&gpImage, bool quadEnable,
int dr, int &nPixelsx, int &nPixelsy) { int dr, int &nPixelsx, int &nPixelsy) {
LOG(logDEBUG) << "Insert Gap pixels:" LOG(logDEBUG) << "Insert Gap pixels:"
@ -1256,43 +1256,104 @@ int DetectorImpl::acquire() {
return OK; return OK;
} }
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) { bool DetectorImpl::handleSynchronization(Positions pos) {
// handle Mythen3 synchronization bool handleSync = false;
if (shm()->detType == defs::MYTHEN3 && size() > 1) { // multi module m3 or multi module sync enabled jungfrau
std::vector<int> master; if (size() > 1) {
std::vector<int> slaves; switch (shm()->detType) {
if (positions.empty() || case defs::MYTHEN3:
(positions.size() == 1 && positions[0] == -1)) { case defs::GOTTHARD2:
positions.resize(modules.size()); case defs::GOTTHARD:
std::iota(begin(positions), end(positions), 0); handleSync = true;
} break;
// could be all slaves in positions case defs::JUNGFRAU:
slaves.reserve(positions.size()); if (Parallel(&Module::getSynchronizationFromStopServer, pos)
auto is_master = Parallel(&Module::isMaster, positions); .tsquash("Inconsistent synchronization among modules")) {
for (size_t i : positions) { handleSync = true;
if (is_master[i]) }
master.push_back(i); break;
else default:
slaves.push_back(i); break;
} }
}
return handleSync;
}
void DetectorImpl::getMasterSlaveList(std::vector<int> positions,
std::vector<int> &masters,
std::vector<int> &slaves) {
// expand positions list
if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
// could be all slaves in positions
slaves.reserve(positions.size());
auto is_master = Parallel(&Module::isMaster, positions);
for (size_t i : positions) {
if (is_master[i])
masters.push_back(i);
else
slaves.push_back(i);
}
}
void DetectorImpl::startAcquisition(const bool blocking, Positions pos) {
// slaves first
if (handleSynchronization(pos)) {
std::vector<int> masters;
std::vector<int> slaves;
getMasterSlaveList(pos, masters, slaves);
if (!slaves.empty()) { if (!slaves.empty()) {
Parallel(&Module::startAcquisition, slaves); Parallel(&Module::startAcquisition, slaves);
} }
if (!master.empty()) { if (!masters.empty()) {
if (blocking) { Parallel((blocking ? &Module::startAndReadAll
Parallel(&Module::startAndReadAll, master); : &Module::startAcquisition),
} else { masters);
Parallel(&Module::startAcquisition, master);
}
}
} else {
if (blocking) {
Parallel(&Module::startAndReadAll, positions);
} else {
Parallel(&Module::startAcquisition, positions);
} }
} }
// all in parallel
else {
Parallel(
(blocking ? &Module::startAndReadAll : &Module::startAcquisition),
pos);
}
}
void DetectorImpl::sendSoftwareTrigger(const bool block, Positions pos) {
// slaves first
if (handleSynchronization(pos)) {
std::vector<int> masters;
std::vector<int> slaves;
getMasterSlaveList(pos, masters, slaves);
if (!slaves.empty())
Parallel(&Module::sendSoftwareTrigger, slaves, false);
if (!masters.empty())
Parallel(&Module::sendSoftwareTrigger, masters, block);
}
// all in parallel
else {
Parallel(&Module::sendSoftwareTrigger, pos, block);
}
}
void DetectorImpl::stopDetector(Positions pos) {
// masters first
if (handleSynchronization(pos)) {
std::vector<int> masters;
std::vector<int> slaves;
getMasterSlaveList(pos, masters, slaves);
if (!masters.empty())
Parallel(&Module::stopAcquisition, masters);
if (!slaves.empty())
Parallel(&Module::stopAcquisition, slaves);
}
// all in parallel
else {
Parallel(&Module::stopAcquisition, pos);
}
} }
void DetectorImpl::printProgress(double progress) { void DetectorImpl::printProgress(double progress) {
@ -1324,7 +1385,7 @@ void DetectorImpl::processData(bool receiver) {
if (fgetc(stdin) == 'q') { if (fgetc(stdin) == 'q') {
LOG(logINFO) LOG(logINFO)
<< "Caught the command to stop acquisition"; << "Caught the command to stop acquisition";
Parallel(&Module::stopAcquisition, {}); stopDetector({});
} }
} }
// get and print progress // get and print progress
@ -1397,7 +1458,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
default: default:
throw RuntimeError( throw RuntimeError(
"Unknown detector type. Did the 'hostname' command execute " "Unknown detector type. Did the 'hostname' command execute "
"successfully? Or use update mode in the detector server side."); "successfully? Or use update mode in the detector server "
"side.");
} }
LOG(logINFO) << "This can take awhile. Please be patient."; LOG(logINFO) << "This can take awhile. Please be patient.";
@ -1425,10 +1487,9 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
int dst = mkstemp(destfname); // create temporary file and open it in r/w int dst = mkstemp(destfname); // create temporary file and open it in r/w
if (dst == -1) { if (dst == -1) {
fclose(src); fclose(src);
throw RuntimeError( throw RuntimeError(std::string("Could not create destination file "
std::string( "in /tmp for programming: ") +
"Could not create destination file in /tmp for programming: ") + destfname);
destfname);
} }
// convert src to dst rawbin // convert src to dst rawbin
@ -1480,8 +1541,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
} }
// validate pof: read less than footer offset // validate pof: read less than footer offset
if (isPof && dstFilePos < pofFooterOfst) { if (isPof && dstFilePos < pofFooterOfst) {
throw RuntimeError( throw RuntimeError("Could not convert programming file. EOF "
"Could not convert programming file. EOF before end of flash"); "before end of flash");
} }
} }
if (fclose(src) != 0) { if (fclose(src) != 0) {

View File

@ -278,7 +278,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
int acquire(); int acquire();
/** also takes care of master and slave for multi module mythen */ /** also takes care of master and slave for multi module mythen */
void startAcquisition(bool blocking, std::vector<int> positions); void startAcquisition(const bool blocking, Positions pos);
/** also takes care of master and slave for multi module mythen */
void sendSoftwareTrigger(const bool block, Positions pos);
/** also takes care of master and slave for multi module mythen */
void stopDetector(Positions pos);
/** /**
* Combines data from all readouts and gives it to the gui * Combines data from all readouts and gives it to the gui
@ -368,9 +374,14 @@ class DetectorImpl : public virtual slsDetectorDefs {
* @param nPixelsy number of pixels in Y axis (updated) * @param nPixelsy number of pixels in Y axis (updated)
* @returns total data bytes for updated image * @returns total data bytes for updated image
*/ */
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, int insertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
int &nPixelsx, int &nPixelsy); int &nPixelsx, int &nPixelsy);
bool handleSynchronization(Positions pos);
void getMasterSlaveList(std::vector<int> positions,
std::vector<int> &masters,
std::vector<int> &slaves);
void printProgress(double progress); void printProgress(double progress);
void startProcessingThread(bool receiver); void startProcessingThread(bool receiver);

View File

@ -73,8 +73,8 @@ void Module::setHostname(const std::string &hostname,
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.close(); client.close();
try { try {
initialDetectorServerChecks();
checkDetectorVersionCompatibility(); checkDetectorVersionCompatibility();
initialDetectorServerChecks();
LOG(logINFO) << "Module Version Compatibility - Success"; LOG(logINFO) << "Module Version Compatibility - Success";
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
if (!initialChecks) { if (!initialChecks) {
@ -93,9 +93,28 @@ int64_t Module::getFirmwareVersion() const {
} }
std::string Module::getControlServerLongVersion() const { std::string Module::getControlServerLongVersion() const {
char retval[MAX_STR_LENGTH]{}; try {
sendToDetector(F_GET_SERVER_VERSION, nullptr, retval); char retval[MAX_STR_LENGTH]{};
return retval; sendToDetector(F_GET_SERVER_VERSION, nullptr, retval);
return retval;
}
// throw with old server version (sends 8 bytes)
catch (RuntimeError &e) {
std::string emsg = std::string(e.what());
if (emsg.find(F_GET_SERVER_VERSION) && emsg.find("8 bytes")) {
throwDeprecatedServerVersion();
}
throw;
}
}
void Module::throwDeprecatedServerVersion() const {
uint64_t res = sendToDetectorStop<int64_t>(F_GET_SERVER_VERSION);
std::cout << std::endl;
std::ostringstream os;
os << "Detector Server (Control) version (0x" << std::hex << res
<< ") is incompatible with this client. Please update detector server!";
throw RuntimeError(os.str());
} }
std::string Module::getStopServerLongVersion() const { std::string Module::getStopServerLongVersion() const {
@ -519,8 +538,15 @@ bool Module::getSynchronization() const {
return sendToDetector<int>(F_GET_SYNCHRONIZATION); return sendToDetector<int>(F_GET_SYNCHRONIZATION);
} }
bool Module::getSynchronizationFromStopServer() const {
return sendToDetectorStop<int>(F_GET_SYNCHRONIZATION);
}
void Module::setSynchronization(const bool value) { void Module::setSynchronization(const bool value) {
sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr); sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
// to deal with virtual servers as well
// (get sync from stop server during blocking acquisition)
sendToDetectorStop(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
} }
std::vector<int> Module::getBadChannels() const { std::vector<int> Module::getBadChannels() const {

View File

@ -92,6 +92,7 @@ class Module : public virtual slsDetectorDefs {
int64_t getFirmwareVersion() const; int64_t getFirmwareVersion() const;
std::string getControlServerLongVersion() const; std::string getControlServerLongVersion() const;
std::string getStopServerLongVersion() const; std::string getStopServerLongVersion() const;
void throwDeprecatedServerVersion() const;
std::string getDetectorServerVersion() const; std::string getDetectorServerVersion() const;
std::string getHardwareVersion() const; std::string getHardwareVersion() const;
std::string getKernelVersion() const; std::string getKernelVersion() const;
@ -128,6 +129,7 @@ class Module : public virtual slsDetectorDefs {
bool isMaster() const; bool isMaster() const;
void setMaster(const bool master); void setMaster(const bool master);
bool getSynchronization() const; bool getSynchronization() const;
bool getSynchronizationFromStopServer() const;
void setSynchronization(const bool value); void setSynchronization(const bool value);
std::vector<int> getBadChannels() const; std::vector<int> getBadChannels() const;
void setBadChannels(std::vector<int> list); void setBadChannels(std::vector<int> list);

View File

@ -523,6 +523,28 @@ TEST_CASE("sync", "[.cmd]") {
proxy.Call("sync", {"1"}, -1, PUT, oss); proxy.Call("sync", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "sync 1\n"); REQUIRE(oss.str() == "sync 1\n");
} }
// setting to master or slave when synced
{
// get previous master
int prevMaster = 0;
auto previous = det.getMaster();
for (int i = 0; i != det.size(); ++i) {
if (previous[i] == 1) {
prevMaster = i;
break;
}
}
proxy.Call("master", {"1"}, 0, PUT);
proxy.Call("master", {"0"}, 0, PUT);
std::ostringstream oss;
proxy.Call("status", {}, -1, GET, oss);
REQUIRE(oss.str() != "status running\n");
// set all to slaves, and then master
for (int i = 0; i != det.size(); ++i) {
det.setMaster(0, {i});
}
det.setMaster(1, prevMaster);
}
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("sync", {}, -1, GET, oss); proxy.Call("sync", {}, -1, GET, oss);

View File

@ -5,6 +5,7 @@
#include <chrono> #include <chrono>
#include <signal.h> #include <signal.h>
#include <sys/wait.h>
#include <thread> #include <thread>
#include <unistd.h> #include <unistd.h>
@ -16,6 +17,8 @@ namespace sls {
#define gettid() syscall(SYS_gettid) #define gettid() syscall(SYS_gettid)
#endif #endif
void func(int signum) { wait(NULL); }
Arping::Arping() {} Arping::Arping() {}
Arping::~Arping() { Arping::~Arping() {
@ -44,10 +47,11 @@ pid_t Arping::GetProcessId() const { return childPid; }
bool Arping::IsRunning() const { return runningFlag; } bool Arping::IsRunning() const { return runningFlag; }
void Arping::StartProcess() { void Arping::StartProcess() {
TestCommands();
// to prevent zombies from child processes being killed // to prevent zombies from child processes being killed
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, func);
// test once to throw exception if arping failed
TestForErrors();
// Needs to be a fork and udp socket deleted after Listening threads // Needs to be a fork and udp socket deleted after Listening threads
// done running to prevent udp socket cannot bind because of popen // done running to prevent udp socket cannot bind because of popen
@ -90,7 +94,7 @@ void Arping::ProcessExecution() {
} }
} }
void Arping::TestCommands() { void Arping::TestForErrors() {
// atleast one interface must be set up // atleast one interface must be set up
if (commands[0].empty()) { if (commands[0].empty()) {
throw RuntimeError( throw RuntimeError(
@ -116,7 +120,8 @@ std::string Arping::ExecuteCommands() {
FILE *sysFile = popen(cmd.c_str(), "r"); FILE *sysFile = popen(cmd.c_str(), "r");
if (sysFile == NULL) { if (sysFile == NULL) {
std::ostringstream os; std::ostringstream os;
os << "Could not Arping [" << cmd << " ] : Popen fail"; os << "Could not Arping (" << cmd << " ) : Popen fail ("
<< strerror(errno) << ')';
return os.str(); return os.str();
} }
@ -128,7 +133,7 @@ std::string Arping::ExecuteCommands() {
// check exit status of command // check exit status of command
if (pclose(sysFile)) { if (pclose(sysFile)) {
std::ostringstream os; std::ostringstream os;
os << "Could not arping[" << cmd << "] : " << output; os << "Could not arping (" << cmd << ") : " << strerror(errno);
return os.str(); return os.str();
} else { } else {
LOG(logDEBUG) << output; LOG(logDEBUG) << output;

View File

@ -28,7 +28,7 @@ class Arping {
void StopProcess(); void StopProcess();
private: private:
void TestCommands(); void TestForErrors();
std::string ExecuteCommands(); std::string ExecuteCommands();
void ProcessExecution(); void ProcessExecution();

View File

@ -56,6 +56,8 @@ void DataStreamer::SetAdditionalJsonHeader(
isAdditionalJsonUpdated = true; isAdditionalJsonUpdated = true;
} }
void DataStreamer::SetReceiverROI(ROI roi) { receiverRoi = roi; }
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) { void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
StopRunning(); StopRunning();
startedFlag = false; startedFlag = false;
@ -249,6 +251,7 @@ int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size,
isAdditionalJsonUpdated = false; isAdditionalJsonUpdated = false;
} }
zHeader.addJsonHeader = localAdditionalJsonHeader; zHeader.addJsonHeader = localAdditionalJsonHeader;
zHeader.rx_roi = receiverRoi.getIntArray();
return zmqSocket->SendHeader(index, zHeader); return zmqSocket->SendHeader(index, zHeader);
} }

View File

@ -38,6 +38,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
void SetNumberofTotalFrames(uint64_t value); void SetNumberofTotalFrames(uint64_t value);
void void
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json); SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
void SetReceiverROI(ROI roi);
void ResetParametersforNewAcquisition(const std::string &fname); void ResetParametersforNewAcquisition(const std::string &fname);
/** /**
@ -92,6 +93,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
uint64_t fileIndex{0}; uint64_t fileIndex{0};
bool flipRows{false}; bool flipRows{false};
std::map<std::string, std::string> additionalJsonHeader; std::map<std::string, std::string> additionalJsonHeader;
ROI receiverRoi{};
/** Used by streamer thread to update local copy (reduce number of locks /** Used by streamer thread to update local copy (reduce number of locks
* during streaming) */ * during streaming) */

View File

@ -14,14 +14,14 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
"frame number", "frame number",
"exp length or sub exposure time", "exp length or sub exposure time",
"packets caught", "packets caught",
"bunch id", "detector specific 1",
"timestamp", "timestamp",
"mod id", "mod id",
"row", "row",
"column", "column",
"reserved", "detector specific 2",
"debug", "detector specific 3",
"round robin number", "detector specific 4",
"detector type", "detector type",
"detector header version", "detector header version",
"packets caught bit mask", "packets caught bit mask",
@ -317,7 +317,7 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2], dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2],
memspace, *dataSpacePara); memspace, *dataSpacePara);
i = 3; i = 3;
dataSetPara[3]->write(&header.bunchId, parameterDataTypes[3], memspace, dataSetPara[3]->write(&header.detSpec1, parameterDataTypes[3], memspace,
*dataSpacePara); *dataSpacePara);
i = 4; i = 4;
dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4], dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4],
@ -332,13 +332,13 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace, dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace,
*dataSpacePara); *dataSpacePara);
i = 8; i = 8;
dataSetPara[8]->write(&header.reserved, parameterDataTypes[8], memspace, dataSetPara[8]->write(&header.detSpec2, parameterDataTypes[8], memspace,
*dataSpacePara); *dataSpacePara);
i = 9; i = 9;
dataSetPara[9]->write(&header.debug, parameterDataTypes[9], memspace, dataSetPara[9]->write(&header.detSpec3, parameterDataTypes[9], memspace,
*dataSpacePara); *dataSpacePara);
i = 10; i = 10;
dataSetPara[10]->write(&header.roundRNumber, parameterDataTypes[10], dataSetPara[10]->write(&header.detSpec4, parameterDataTypes[10],
memspace, *dataSpacePara); memspace, *dataSpacePara);
i = 11; i = 11;
dataSetPara[11]->write(&header.detType, parameterDataTypes[11], dataSetPara[11]->write(&header.detType, parameterDataTypes[11],

View File

@ -216,6 +216,8 @@ void Implementation::SetupDataStreamer(int i) {
dataStreamer[i]->SetNumberofPorts(numPorts); dataStreamer[i]->SetNumberofPorts(numPorts);
dataStreamer[i]->SetQuadEnable(quadEnable); dataStreamer[i]->SetQuadEnable(quadEnable);
dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames); dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames);
dataStreamer[i]->SetReceiverROI(
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
} }
slsDetectorDefs::xy Implementation::getDetectorSize() const { slsDetectorDefs::xy Implementation::getDetectorSize() const {
@ -231,6 +233,11 @@ const slsDetectorDefs::xy Implementation::GetPortGeometry() const {
return portGeometry; return portGeometry;
} }
const slsDetectorDefs::ROI Implementation::GetMaxROIPerPort() const {
return slsDetectorDefs::ROI{0, (int)generalData->nPixelsX - 1, 0,
(int)generalData->nPixelsY - 1};
}
void Implementation::setDetectorSize(const slsDetectorDefs::xy size) { void Implementation::setDetectorSize(const slsDetectorDefs::xy size) {
xy portGeometry = GetPortGeometry(); xy portGeometry = GetPortGeometry();
@ -458,6 +465,10 @@ void Implementation::setReceiverROI(const slsDetectorDefs::ROI arg) {
listener[i]->SetNoRoi(portRois[i].noRoi()); listener[i]->SetNoRoi(portRois[i].noRoi());
for (size_t i = 0; i != dataProcessor.size(); ++i) for (size_t i = 0; i != dataProcessor.size(); ++i)
dataProcessor[i]->SetReceiverROI(portRois[i]); dataProcessor[i]->SetReceiverROI(portRois[i]);
for (size_t i = 0; i != dataStreamer.size(); ++i) {
dataStreamer[i]->SetReceiverROI(
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
}
LOG(logINFO) << "receiver roi: " << ToString(receiverRoi); LOG(logINFO) << "receiver roi: " << ToString(receiverRoi);
if (generalData->numUDPInterfaces == 2 && if (generalData->numUDPInterfaces == 2 &&
generalData->detType != slsDetectorDefs::GOTTHARD2) { generalData->detType != slsDetectorDefs::GOTTHARD2) {

View File

@ -282,6 +282,7 @@ class Implementation : private virtual slsDetectorDefs {
void SetupFifoStructure(); void SetupFifoStructure();
const xy GetPortGeometry() const; const xy GetPortGeometry() const;
const ROI GetMaxROIPerPort() const;
void ResetParametersforNewAcquisition(); void ResetParametersforNewAcquisition();
void CreateUDPSockets(); void CreateUDPSockets();
void SetupWriter(); void SetupWriter();

View File

@ -19,8 +19,8 @@ namespace sls {
// files // files
// versions // versions
#define HDF5_WRITER_VERSION (6.5) // 1 decimal places #define HDF5_WRITER_VERSION (6.6) // 1 decimal places
#define BINARY_WRITER_VERSION (7.1) // 1 decimal places #define BINARY_WRITER_VERSION (7.2) // 1 decimal places
#define MAX_FRAMES_PER_FILE 20000 #define MAX_FRAMES_PER_FILE 20000
#define SHORT_MAX_FRAMES_PER_FILE 100000 #define SHORT_MAX_FRAMES_PER_FILE 100000

View File

@ -12,6 +12,7 @@
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_exceptions.h"
#include <array>
#include <map> #include <map>
#include <memory> #include <memory>
@ -83,6 +84,8 @@ struct zmqHeader {
bool completeImage{false}; bool completeImage{false};
/** additional json header */ /** additional json header */
std::map<std::string, std::string> addJsonHeader; std::map<std::string, std::string> addJsonHeader;
/** (xmin, xmax, ymin, ymax) roi only in files written */
std::array<int, 4> rx_roi{};
}; };
class ZmqSocket { class ZmqSocket {

View File

@ -2,6 +2,7 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once #pragma once
#include <array> #include <array>
#include <cstdint>
#include <iostream> #include <iostream>
#include <string> #include <string>

View File

@ -46,7 +46,7 @@
#define MAX_UDP_DESTINATION 32 #define MAX_UDP_DESTINATION 32
#define SLS_DETECTOR_HEADER_VERSION 0x2 #define SLS_DETECTOR_HEADER_VERSION 0x2
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4 #define SLS_DETECTOR_JSON_HEADER_VERSION 0x5
// ctb/ moench 1g udp (read from fifo) // ctb/ moench 1g udp (read from fifo)
#define UDP_PACKET_DATA_BYTES (1344) #define UDP_PACKET_DATA_BYTES (1344)

View File

@ -1,13 +1,13 @@
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
/** API versions */ /** API versions */
#define RELEASE "7.0.0" #define RELEASE "7.0.2"
#define APICTB "7.0.0 0x230222" #define APICTB "7.0.0 0x230222"
#define APIGOTTHARD "7.0.0 0x230222" #define APIGOTTHARD "7.0.0 0x230222"
#define APIGOTTHARD2 "7.0.0 0x230222" #define APIGOTTHARD2 "7.0.0 0x230222"
#define APIJUNGFRAU "7.0.0 0x230222"
#define APIMYTHEN3 "7.0.0 0x230222" #define APIMYTHEN3 "7.0.0 0x230222"
#define APIMOENCH "7.0.0 0x230222" #define APIMOENCH "7.0.0 0x230222"
#define APIEIGER "7.0.0 0x230222" #define APIEIGER "7.0.0 0x230222"
#define APILIB "7.0.0 0x230223" #define APIJUNGFRAU "7.0.2 0x230710"
#define APIRECEIVER "7.0.0 0x230222" #define APILIB "7.0.2 0x230712"
#define APIRECEIVER "7.0.2 0x230712"

View File

@ -254,6 +254,8 @@ int ZmqSocket::SendHeader(int index, zmqHeader header) {
} }
oss << " } "; oss << " } ";
} }
oss << ", \"rx_roi\":[" << header.rx_roi[0] << ", " << header.rx_roi[1]
<< ", " << header.rx_roi[2] << ", " << header.rx_roi[3] << "]";
oss << "}\n"; oss << "}\n";
std::string message = oss.str(); std::string message = oss.str();
int length = message.length(); int length = message.length();
@ -375,6 +377,11 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
} }
} }
const Value &a = document["rx_roi"].GetArray();
for (SizeType i = 0; i != a.Size(); ++i) {
zHeader.rx_roi[i] = a[i].GetInt();
}
return 1; return 1;
} }