merge fix #721 PR (sync 7.0.2.rc) to developer (#739)

* merge fix from #721 PR (sync) 7.0.2.rc -> developer
* 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>

* fixed row and col for moench 2 interfaces

* fix moench getTiming and also allow moench to handle sync

---------

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
This commit is contained in:
maliakal_d 2023-05-08 15:58:19 +02:00 committed by GitHub
parent 14ec4cf1da
commit e757e25fa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 183 additions and 103 deletions

View File

@ -39,7 +39,7 @@ This document describes the differences between v7.x.x and v7.0.0
Eiger 7.0.0
Jungfrau 7.0.0
Jungfrau 7.0.2
Mythen3 7.0.0
Gotthard2 7.0.0
Gotthard 7.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv7.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv7.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv7.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv7.0.0

View File

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

View File

@ -1 +0,0 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv7.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv7.0.0

View File

@ -1449,7 +1449,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 +1736,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

@ -1345,7 +1345,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;
}
@ -1632,40 +1632,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

@ -857,7 +857,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;
@ -916,7 +916,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 {
@ -954,18 +954,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

@ -755,7 +755,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;
@ -794,7 +794,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:"
@ -1242,43 +1242,105 @@ 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:
case defs::MOENCH:
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),
pos);
}
}
// 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) {
@ -1383,7 +1445,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.";
@ -1411,10 +1474,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
@ -1466,8 +1528,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
@ -379,9 +385,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

@ -544,8 +544,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

@ -130,6 +130,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

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

View File

@ -5,9 +5,9 @@
#define APICTB "developer 0x230224"
#define APIGOTTHARD "developer 0x230224"
#define APIGOTTHARD2 "developer 0x230224"
#define APIJUNGFRAU "developer 0x230224"
#define APIMYTHEN3 "developer 0x230224"
#define APIMOENCH "developer 0x230224"
#define APILIB "developer 0x230224"
#define APIRECEIVER "developer 0x230224"
#define APIEIGER "developer 0x230224"
#define APIJUNGFRAU "developer 0x230508"
#define APIMOENCH "developer 0x230508"