diff --git a/RELEASE.txt b/RELEASE.txt index f2e6ffb0e..89f0184cc 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -19,36 +19,10 @@ This document describes the differences between v7.0.1 and v7.0.0 1 Resolved Issues ================= - - Receiver - -------- - - - * HDF5 Compilation - Compilation issues from 7.0.0 fixed. - - - * Arping error - Cmdline: rx_arping - API: setRxArping/ getRxArping - Even if arping was successful, it gave an error. Fixed. - - - - Client - ------ - - - * Detector Server Version from previous Releases - Hostname command would hang with 7.0.0 client if the detector server - was from a previous release (eg. 6.1.2). In this case, the user cannot - get the detector server version. - - Fixed that the hostname command will throw an exception about - incompatible server with its version in the message. Now, the user can - get the version number without having to telnet or ssh to the detector. - With this info, one can then update to matching client for that server - and start the detector updation process. + - row and col for multi mod junngfrau single interface (gui) + - jungfrau multi mod sync mode (start, trigger, stop) + - set/get timing jungfrau does not give error when syc enabled + - switching between 1 and 2 interfaces did not set gui/client zmq port properly. Resulted in dummy streaming forever. 2 On-board Detector Server Compatibility @@ -56,7 +30,7 @@ This document describes the differences between v7.0.1 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 diff --git a/serverBin/jungfrauDetectorServerv7.0.0 b/serverBin/jungfrauDetectorServerv7.0.0 deleted file mode 120000 index c91c000b3..000000000 --- a/serverBin/jungfrauDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/jungfrauDetectorServerv7.0.2 b/serverBin/jungfrauDetectorServerv7.0.2 new file mode 120000 index 000000000..b0e1b3fe4 --- /dev/null +++ b/serverBin/jungfrauDetectorServerv7.0.2 @@ -0,0 +1 @@ +../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2 \ No newline at end of file diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0 b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2 similarity index 70% rename from slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0 rename to slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2 index f4e3b91f4..820c9cb9e 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0 and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2 differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 62ea6fe04..c34db22d4 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -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", diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 0692b0d09..32e7ab047 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -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 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) { diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 12bbb9a45..43b9e168b 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -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 positions) { - // handle Mythen3 synchronization - if (shm()->detType == defs::MYTHEN3 && size() > 1) { - std::vector master; - std::vector 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 positions, + std::vector &masters, + std::vector &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 masters; + std::vector 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 masters; + std::vector 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 masters; + std::vector 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) { @@ -1397,7 +1458,8 @@ std::vector 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 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 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) { diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index cb1394640..710ad00fe 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -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 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 positions, + std::vector &masters, + std::vector &slaves); + void printProgress(double progress); void startProcessingThread(bool receiver); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index c2b27c613..8249ef1e8 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -538,8 +538,15 @@ bool Module::getSynchronization() const { return sendToDetector(F_GET_SYNCHRONIZATION); } +bool Module::getSynchronizationFromStopServer() const { + return sendToDetectorStop(F_GET_SYNCHRONIZATION); +} + void Module::setSynchronization(const bool value) { sendToDetector(F_SET_SYNCHRONIZATION, static_cast(value), nullptr); + // to deal with virtual servers as well + // (get sync from stop server during blocking acquisition) + sendToDetectorStop(F_SET_SYNCHRONIZATION, static_cast(value), nullptr); } std::vector Module::getBadChannels() const { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 37cd00a08..a0e4fcc80 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -129,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 getBadChannels() const; void setBadChannels(std::vector list); diff --git a/slsSupportLib/include/sls/network_utils.h b/slsSupportLib/include/sls/network_utils.h index aeaed5aa9..e0e48c416 100644 --- a/slsSupportLib/include/sls/network_utils.h +++ b/slsSupportLib/include/sls/network_utils.h @@ -2,6 +2,7 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package #pragma once #include +#include #include #include diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index e392dc101..03f4d373f 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -5,9 +5,9 @@ #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 APIRECEIVER "7.0.0 0x230222" -#define APILIB "7.0.1 0x230323" +#define APIJUNGFRAU "7.0.2 0x230420" +#define APILIB "7.0.2 0x230421"