mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-13 21:37:13 +02:00
Compare commits
17 Commits
moench8.0.
...
7.0.2
Author | SHA1 | Date | |
---|---|---|---|
f761046bfc | |||
1a859b83db | |||
70bfc875a6 | |||
c0755308a4 | |||
ab5509e10c | |||
004cb26646 | |||
a4f47a5945 | |||
312f3f473d | |||
5871086cd6 | |||
6a0fe823b3 | |||
5912aae53e | |||
8833ccf5cc | |||
77c558a7be | |||
378fc301b8 | |||
87d6e16090 | |||
2ef021041c | |||
574127b5ac |
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(slsDetectorPackage)
|
||||
set(PROJECT_VERSION 7.0.0)
|
||||
set(PROJECT_VERSION 7.0.2)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||
|
||||
|
983
RELEASE.txt
983
RELEASE.txt
File diff suppressed because it is too large
Load Diff
@ -140,14 +140,21 @@ ZMQ: Json Header Format
|
||||
"quad": unsigned int,
|
||||
"addJsonHeader": {
|
||||
string : string
|
||||
}
|
||||
},
|
||||
"rx_roi": [
|
||||
unsigned int,
|
||||
unsigned int,
|
||||
unsigned int,
|
||||
unsigned int
|
||||
]
|
||||
}
|
||||
|
||||
+--------------+----------------------------------------------+
|
||||
| Field | Description |
|
||||
+--------------+----------------------------------------------+
|
||||
| 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] |
|
||||
+--------------+----------------------------------------------+
|
||||
@ -222,7 +229,10 @@ ZMQ: Json Header Format
|
||||
| addJsonHeader| Optional custom parameters that is required |
|
||||
| | 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
|
||||
--------------------------
|
||||
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0
|
1
serverBin/jungfrauDetectorServerv7.0.2
Symbolic link
1
serverBin/jungfrauDetectorServerv7.0.2
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2
|
@ -132,7 +132,7 @@ void qTabSettings::SetupWidgetWindow() {
|
||||
}
|
||||
|
||||
void qTabSettings::SetExportMode(bool exportMode) {
|
||||
if (comboGainMode->isVisible()) {
|
||||
if (comboGainMode->isEnabled()) {
|
||||
ShowFixG0(exportMode);
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
BIN
slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2
Executable file
BIN
slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2
Executable file
Binary file not shown.
@ -1388,14 +1388,18 @@ int setMaster(enum MASTERINDEX m) {
|
||||
char *master_names[] = {MASTER_NAMES};
|
||||
LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m],
|
||||
(isControlServer ? "control" : "stop")));
|
||||
|
||||
int prevSync = getSynchronization();
|
||||
setSynchronization(0);
|
||||
int retval = -1;
|
||||
int retMaster = OK;
|
||||
switch (m) {
|
||||
case OW_MASTER:
|
||||
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK);
|
||||
isMaster(&retval);
|
||||
if (retval != 1) {
|
||||
LOG(logERROR, ("Could not set master\n"));
|
||||
return FAIL;
|
||||
retMaster = FAIL;
|
||||
}
|
||||
break;
|
||||
case OW_SLAVE:
|
||||
@ -1403,15 +1407,16 @@ int setMaster(enum MASTERINDEX m) {
|
||||
isMaster(&retval);
|
||||
if (retval != 0) {
|
||||
LOG(logERROR, ("Could not set slave\n"));
|
||||
return FAIL;
|
||||
retMaster = FAIL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(logERROR, ("Cannot reset to hardware settings from client. Restart "
|
||||
"detector server.\n"));
|
||||
return FAIL;
|
||||
retMaster = FAIL;
|
||||
}
|
||||
return OK;
|
||||
setSynchronization(prevSync);
|
||||
return retMaster;
|
||||
}
|
||||
|
||||
int isMaster(int *retval) {
|
||||
@ -1449,7 +1454,7 @@ void setTiming(enum timingMode arg) {
|
||||
}
|
||||
|
||||
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 AUTO_TIMING;
|
||||
}
|
||||
@ -1736,40 +1741,40 @@ int setDetectorPosition(int pos[]) {
|
||||
detPos[2] = outerPos[X];
|
||||
detPos[3] = outerPos[Y];
|
||||
|
||||
// row
|
||||
// row [Y]
|
||||
// outer
|
||||
uint32_t addr = COORD_ROW_REG;
|
||||
bus_w(addr,
|
||||
(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) !=
|
||||
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])
|
||||
ret = FAIL;
|
||||
// inner
|
||||
bus_w(addr,
|
||||
(bus_r(addr) & ~COORD_COL_INNER_MSK) |
|
||||
((innerPos[Y] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK));
|
||||
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) !=
|
||||
(bus_r(addr) & ~COORD_ROW_INNER_MSK) |
|
||||
((innerPos[Y] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
|
||||
if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
|
||||
innerPos[Y])
|
||||
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 (getNumberofUDPInterfaces() == 1) {
|
||||
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#define MIN_REQRD_VRSN_T_RD_API 0x171220
|
||||
#define REQRD_FRMWRE_VRSN_BOARD2 0x221104 // 1.0 pcb (version = 010)
|
||||
#define REQRD_FRMWRE_VRSN 0x221103 // 2.0 pcb (version = 011)
|
||||
#define REQRD_FRMWRE_VRSN_BOARD2 0x230516 // 1.0 pcb (version = 010)
|
||||
#define REQRD_FRMWRE_VRSN 0x230515 // 2.0 pcb (version = 011)
|
||||
|
||||
#define NUM_HARDWARE_VERSIONS (2)
|
||||
#define HARDWARE_VERSION_NUMBERS \
|
||||
|
@ -855,7 +855,7 @@ void Detector::stopDetector(Positions pos) {
|
||||
throw RuntimeError(
|
||||
"Could not stop detector. Returned error status.");
|
||||
}
|
||||
pimpl->Parallel(&Module::stopAcquisition, pos);
|
||||
pimpl->stopDetector(pos);
|
||||
status = getDetectorStatus().squash(defs::runStatus::RUNNING);
|
||||
++retries;
|
||||
|
||||
@ -914,7 +914,7 @@ void Detector::setNextFrameNumber(uint64_t value, 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 {
|
||||
@ -951,18 +951,23 @@ 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();
|
||||
int clientStartingPort = getClientZmqPort({0}).squash(0);
|
||||
bool useReceiver = getUseReceiverFlag().squash(false);
|
||||
bool previouslyReceiverStreaming = false;
|
||||
int startingPort = 0;
|
||||
int rxStartingPort = 0;
|
||||
if (useReceiver) {
|
||||
previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true);
|
||||
startingPort = getRxZmqPort({0}).squash(0);
|
||||
rxStartingPort = getRxZmqPort({0}).squash(0);
|
||||
}
|
||||
pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n);
|
||||
// ensure receiver zmq socket ports are multiplied by 2 (2 interfaces)
|
||||
if (getUseReceiverFlag().squash(false) && size()) {
|
||||
setRxZmqPort(startingPort, -1);
|
||||
setClientZmqPort(clientStartingPort, -1);
|
||||
if (getUseReceiverFlag().squash(false)) {
|
||||
setRxZmqPort(rxStartingPort, -1);
|
||||
}
|
||||
// redo the zmq sockets if enabled
|
||||
if (previouslyClientStreaming) {
|
||||
|
@ -769,7 +769,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
int nDetActualPixelsY = nDetPixelsY;
|
||||
|
||||
if (gapPixels) {
|
||||
int n = InsertGapPixels(multiframe.get(), multigappixels,
|
||||
int n = insertGapPixels(multiframe.get(), multigappixels,
|
||||
quadEnable, dynamicRange,
|
||||
nDetActualPixelsX, nDetActualPixelsY);
|
||||
callbackImage = multigappixels;
|
||||
@ -808,7 +808,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
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) {
|
||||
|
||||
LOG(logDEBUG) << "Insert Gap pixels:"
|
||||
@ -1256,43 +1256,104 @@ int DetectorImpl::acquire() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
|
||||
// handle Mythen3 synchronization
|
||||
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
|
||||
std::vector<int> master;
|
||||
std::vector<int> slaves;
|
||||
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])
|
||||
master.push_back(i);
|
||||
else
|
||||
slaves.push_back(i);
|
||||
bool DetectorImpl::handleSynchronization(Positions pos) {
|
||||
bool handleSync = false;
|
||||
// multi module m3 or multi module sync enabled jungfrau
|
||||
if (size() > 1) {
|
||||
switch (shm()->detType) {
|
||||
case defs::MYTHEN3:
|
||||
case defs::GOTTHARD2:
|
||||
case defs::GOTTHARD:
|
||||
handleSync = true;
|
||||
break;
|
||||
case defs::JUNGFRAU:
|
||||
if (Parallel(&Module::getSynchronizationFromStopServer, pos)
|
||||
.tsquash("Inconsistent synchronization among modules")) {
|
||||
handleSync = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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()) {
|
||||
Parallel(&Module::startAcquisition, slaves);
|
||||
}
|
||||
if (!master.empty()) {
|
||||
if (blocking) {
|
||||
Parallel(&Module::startAndReadAll, master);
|
||||
} else {
|
||||
Parallel(&Module::startAcquisition, master);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (blocking) {
|
||||
Parallel(&Module::startAndReadAll, positions);
|
||||
} else {
|
||||
Parallel(&Module::startAcquisition, positions);
|
||||
if (!masters.empty()) {
|
||||
Parallel((blocking ? &Module::startAndReadAll
|
||||
: &Module::startAcquisition),
|
||||
masters);
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
@ -1324,7 +1385,7 @@ void DetectorImpl::processData(bool receiver) {
|
||||
if (fgetc(stdin) == 'q') {
|
||||
LOG(logINFO)
|
||||
<< "Caught the command to stop acquisition";
|
||||
Parallel(&Module::stopAcquisition, {});
|
||||
stopDetector({});
|
||||
}
|
||||
}
|
||||
// get and print progress
|
||||
@ -1397,7 +1458,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
default:
|
||||
throw RuntimeError(
|
||||
"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.";
|
||||
@ -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
|
||||
if (dst == -1) {
|
||||
fclose(src);
|
||||
throw RuntimeError(
|
||||
std::string(
|
||||
"Could not create destination file in /tmp for programming: ") +
|
||||
destfname);
|
||||
throw RuntimeError(std::string("Could not create destination file "
|
||||
"in /tmp for programming: ") +
|
||||
destfname);
|
||||
}
|
||||
|
||||
// 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
|
||||
if (isPof && dstFilePos < pofFooterOfst) {
|
||||
throw RuntimeError(
|
||||
"Could not convert programming file. EOF before end of flash");
|
||||
throw RuntimeError("Could not convert programming file. EOF "
|
||||
"before end of flash");
|
||||
}
|
||||
}
|
||||
if (fclose(src) != 0) {
|
||||
|
@ -278,7 +278,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
int acquire();
|
||||
|
||||
/** 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
|
||||
@ -368,9 +374,14 @@ 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 insertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||
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 startProcessingThread(bool receiver);
|
||||
|
@ -73,8 +73,8 @@ void Module::setHostname(const std::string &hostname,
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.close();
|
||||
try {
|
||||
initialDetectorServerChecks();
|
||||
checkDetectorVersionCompatibility();
|
||||
initialDetectorServerChecks();
|
||||
LOG(logINFO) << "Module Version Compatibility - Success";
|
||||
} catch (const RuntimeError &e) {
|
||||
if (!initialChecks) {
|
||||
@ -93,9 +93,28 @@ int64_t Module::getFirmwareVersion() const {
|
||||
}
|
||||
|
||||
std::string Module::getControlServerLongVersion() const {
|
||||
char retval[MAX_STR_LENGTH]{};
|
||||
sendToDetector(F_GET_SERVER_VERSION, nullptr, retval);
|
||||
return retval;
|
||||
try {
|
||||
char retval[MAX_STR_LENGTH]{};
|
||||
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 {
|
||||
@ -519,8 +538,15 @@ bool Module::getSynchronization() const {
|
||||
return sendToDetector<int>(F_GET_SYNCHRONIZATION);
|
||||
}
|
||||
|
||||
bool Module::getSynchronizationFromStopServer() const {
|
||||
return sendToDetectorStop<int>(F_GET_SYNCHRONIZATION);
|
||||
}
|
||||
|
||||
void Module::setSynchronization(const bool value) {
|
||||
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 {
|
||||
|
@ -92,6 +92,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
int64_t getFirmwareVersion() const;
|
||||
std::string getControlServerLongVersion() const;
|
||||
std::string getStopServerLongVersion() const;
|
||||
void throwDeprecatedServerVersion() const;
|
||||
std::string getDetectorServerVersion() const;
|
||||
std::string getHardwareVersion() const;
|
||||
std::string getKernelVersion() const;
|
||||
@ -128,6 +129,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
bool isMaster() const;
|
||||
void setMaster(const bool master);
|
||||
bool getSynchronization() const;
|
||||
bool getSynchronizationFromStopServer() const;
|
||||
void setSynchronization(const bool value);
|
||||
std::vector<int> getBadChannels() const;
|
||||
void setBadChannels(std::vector<int> list);
|
||||
|
@ -523,6 +523,28 @@ TEST_CASE("sync", "[.cmd]") {
|
||||
proxy.Call("sync", {"1"}, -1, PUT, oss);
|
||||
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;
|
||||
proxy.Call("sync", {}, -1, GET, oss);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -16,6 +17,8 @@ namespace sls {
|
||||
#define gettid() syscall(SYS_gettid)
|
||||
#endif
|
||||
|
||||
void func(int signum) { wait(NULL); }
|
||||
|
||||
Arping::Arping() {}
|
||||
|
||||
Arping::~Arping() {
|
||||
@ -44,10 +47,11 @@ pid_t Arping::GetProcessId() const { return childPid; }
|
||||
bool Arping::IsRunning() const { return runningFlag; }
|
||||
|
||||
void Arping::StartProcess() {
|
||||
TestCommands();
|
||||
|
||||
// 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
|
||||
// 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
|
||||
if (commands[0].empty()) {
|
||||
throw RuntimeError(
|
||||
@ -116,7 +120,8 @@ std::string Arping::ExecuteCommands() {
|
||||
FILE *sysFile = popen(cmd.c_str(), "r");
|
||||
if (sysFile == NULL) {
|
||||
std::ostringstream os;
|
||||
os << "Could not Arping [" << cmd << " ] : Popen fail";
|
||||
os << "Could not Arping (" << cmd << " ) : Popen fail ("
|
||||
<< strerror(errno) << ')';
|
||||
return os.str();
|
||||
}
|
||||
|
||||
@ -128,7 +133,7 @@ std::string Arping::ExecuteCommands() {
|
||||
// check exit status of command
|
||||
if (pclose(sysFile)) {
|
||||
std::ostringstream os;
|
||||
os << "Could not arping[" << cmd << "] : " << output;
|
||||
os << "Could not arping (" << cmd << ") : " << strerror(errno);
|
||||
return os.str();
|
||||
} else {
|
||||
LOG(logDEBUG) << output;
|
||||
|
@ -28,7 +28,7 @@ class Arping {
|
||||
void StopProcess();
|
||||
|
||||
private:
|
||||
void TestCommands();
|
||||
void TestForErrors();
|
||||
std::string ExecuteCommands();
|
||||
void ProcessExecution();
|
||||
|
||||
|
@ -56,6 +56,8 @@ void DataStreamer::SetAdditionalJsonHeader(
|
||||
isAdditionalJsonUpdated = true;
|
||||
}
|
||||
|
||||
void DataStreamer::SetReceiverROI(ROI roi) { receiverRoi = roi; }
|
||||
|
||||
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
@ -249,6 +251,7 @@ int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size,
|
||||
isAdditionalJsonUpdated = false;
|
||||
}
|
||||
zHeader.addJsonHeader = localAdditionalJsonHeader;
|
||||
zHeader.rx_roi = receiverRoi.getIntArray();
|
||||
|
||||
return zmqSocket->SendHeader(index, zHeader);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
void SetNumberofTotalFrames(uint64_t value);
|
||||
void
|
||||
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
|
||||
void SetReceiverROI(ROI roi);
|
||||
|
||||
void ResetParametersforNewAcquisition(const std::string &fname);
|
||||
/**
|
||||
@ -92,6 +93,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
uint64_t fileIndex{0};
|
||||
bool flipRows{false};
|
||||
std::map<std::string, std::string> additionalJsonHeader;
|
||||
ROI receiverRoi{};
|
||||
|
||||
/** Used by streamer thread to update local copy (reduce number of locks
|
||||
* during streaming) */
|
||||
|
@ -14,14 +14,14 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
|
||||
"frame number",
|
||||
"exp length or sub exposure time",
|
||||
"packets caught",
|
||||
"bunch id",
|
||||
"detector specific 1",
|
||||
"timestamp",
|
||||
"mod id",
|
||||
"row",
|
||||
"column",
|
||||
"reserved",
|
||||
"debug",
|
||||
"round robin number",
|
||||
"detector specific 2",
|
||||
"detector specific 3",
|
||||
"detector specific 4",
|
||||
"detector type",
|
||||
"detector header version",
|
||||
"packets caught bit mask",
|
||||
@ -317,7 +317,7 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
|
||||
dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2],
|
||||
memspace, *dataSpacePara);
|
||||
i = 3;
|
||||
dataSetPara[3]->write(&header.bunchId, parameterDataTypes[3], memspace,
|
||||
dataSetPara[3]->write(&header.detSpec1, parameterDataTypes[3], memspace,
|
||||
*dataSpacePara);
|
||||
i = 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,
|
||||
*dataSpacePara);
|
||||
i = 8;
|
||||
dataSetPara[8]->write(&header.reserved, parameterDataTypes[8], memspace,
|
||||
dataSetPara[8]->write(&header.detSpec2, parameterDataTypes[8], memspace,
|
||||
*dataSpacePara);
|
||||
i = 9;
|
||||
dataSetPara[9]->write(&header.debug, parameterDataTypes[9], memspace,
|
||||
dataSetPara[9]->write(&header.detSpec3, parameterDataTypes[9], memspace,
|
||||
*dataSpacePara);
|
||||
i = 10;
|
||||
dataSetPara[10]->write(&header.roundRNumber, parameterDataTypes[10],
|
||||
dataSetPara[10]->write(&header.detSpec4, parameterDataTypes[10],
|
||||
memspace, *dataSpacePara);
|
||||
i = 11;
|
||||
dataSetPara[11]->write(&header.detType, parameterDataTypes[11],
|
||||
|
@ -216,6 +216,8 @@ void Implementation::SetupDataStreamer(int i) {
|
||||
dataStreamer[i]->SetNumberofPorts(numPorts);
|
||||
dataStreamer[i]->SetQuadEnable(quadEnable);
|
||||
dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames);
|
||||
dataStreamer[i]->SetReceiverROI(
|
||||
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
|
||||
}
|
||||
|
||||
slsDetectorDefs::xy Implementation::getDetectorSize() const {
|
||||
@ -231,6 +233,11 @@ const slsDetectorDefs::xy Implementation::GetPortGeometry() const {
|
||||
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) {
|
||||
xy portGeometry = GetPortGeometry();
|
||||
|
||||
@ -458,6 +465,10 @@ void Implementation::setReceiverROI(const slsDetectorDefs::ROI arg) {
|
||||
listener[i]->SetNoRoi(portRois[i].noRoi());
|
||||
for (size_t i = 0; i != dataProcessor.size(); ++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);
|
||||
if (generalData->numUDPInterfaces == 2 &&
|
||||
generalData->detType != slsDetectorDefs::GOTTHARD2) {
|
||||
|
@ -282,6 +282,7 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void SetupFifoStructure();
|
||||
|
||||
const xy GetPortGeometry() const;
|
||||
const ROI GetMaxROIPerPort() const;
|
||||
void ResetParametersforNewAcquisition();
|
||||
void CreateUDPSockets();
|
||||
void SetupWriter();
|
||||
|
@ -19,8 +19,8 @@ namespace sls {
|
||||
// files
|
||||
|
||||
// versions
|
||||
#define HDF5_WRITER_VERSION (6.5) // 1 decimal places
|
||||
#define BINARY_WRITER_VERSION (7.1) // 1 decimal places
|
||||
#define HDF5_WRITER_VERSION (6.6) // 1 decimal places
|
||||
#define BINARY_WRITER_VERSION (7.2) // 1 decimal places
|
||||
|
||||
#define MAX_FRAMES_PER_FILE 20000
|
||||
#define SHORT_MAX_FRAMES_PER_FILE 100000
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
@ -83,6 +84,8 @@ struct zmqHeader {
|
||||
bool completeImage{false};
|
||||
/** additional json header */
|
||||
std::map<std::string, std::string> addJsonHeader;
|
||||
/** (xmin, xmax, ymin, ymax) roi only in files written */
|
||||
std::array<int, 4> rx_roi{};
|
||||
};
|
||||
|
||||
class ZmqSocket {
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
#define MAX_UDP_DESTINATION 32
|
||||
|
||||
#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)
|
||||
#define UDP_PACKET_DATA_BYTES (1344)
|
||||
|
@ -1,13 +1,13 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
/** API versions */
|
||||
#define RELEASE "7.0.0"
|
||||
#define RELEASE "7.0.2"
|
||||
#define APICTB "7.0.0 0x230222"
|
||||
#define APIGOTTHARD "7.0.0 0x230222"
|
||||
#define APIGOTTHARD2 "7.0.0 0x230222"
|
||||
#define APIJUNGFRAU "7.0.0 0x230222"
|
||||
#define APIMYTHEN3 "7.0.0 0x230222"
|
||||
#define APIMOENCH "7.0.0 0x230222"
|
||||
#define APIEIGER "7.0.0 0x230222"
|
||||
#define APILIB "7.0.0 0x230223"
|
||||
#define APIRECEIVER "7.0.0 0x230222"
|
||||
#define APIJUNGFRAU "7.0.2 0x230710"
|
||||
#define APILIB "7.0.2 0x230712"
|
||||
#define APIRECEIVER "7.0.2 0x230712"
|
||||
|
@ -254,6 +254,8 @@ int ZmqSocket::SendHeader(int index, zmqHeader header) {
|
||||
}
|
||||
oss << " } ";
|
||||
}
|
||||
oss << ", \"rx_roi\":[" << header.rx_roi[0] << ", " << header.rx_roi[1]
|
||||
<< ", " << header.rx_roi[2] << ", " << header.rx_roi[3] << "]";
|
||||
oss << "}\n";
|
||||
std::string message = oss.str();
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user