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
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")

File diff suppressed because it is too large Load Diff

View File

@ -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
--------------------------

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) {
if (comboGainMode->isVisible()) {
if (comboGainMode->isEnabled()) {
ShowFixG0(exportMode);
}
}

View File

@ -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",

View File

@ -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 \

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

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

View File

@ -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);
}

View File

@ -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) */

View File

@ -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],

View File

@ -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) {

View File

@ -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();

View File

@ -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

View File

@ -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 {

View File

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

View File

@ -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)

View File

@ -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"

View File

@ -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;
}