diff --git a/RELEASE.txt b/RELEASE.txt index 96a6a645d..d94a1897f 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -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 diff --git a/serverBin/ctbDetectorServerv7.0.0 b/serverBin/ctbDetectorServerv7.0.0 deleted file mode 120000 index bc7dc05d2..000000000 --- a/serverBin/ctbDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/eigerDetectorServerv7.0.0 b/serverBin/eigerDetectorServerv7.0.0 deleted file mode 120000 index 06272c8f6..000000000 --- a/serverBin/eigerDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/gotthard2DetectorServerv7.0.0 b/serverBin/gotthard2DetectorServerv7.0.0 deleted file mode 120000 index 6e601d619..000000000 --- a/serverBin/gotthard2DetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/gotthardDetectorServerv7.0.0 b/serverBin/gotthardDetectorServerv7.0.0 deleted file mode 120000 index d8d2d651e..000000000 --- a/serverBin/gotthardDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv7.0.0 \ No newline at end of file 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/moenchDetectorServerv7.0.0 b/serverBin/moenchDetectorServerv7.0.0 deleted file mode 120000 index ea12c878c..000000000 --- a/serverBin/moenchDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/mythen3DetectorServerv7.0.0 b/serverBin/mythen3DetectorServerv7.0.0 deleted file mode 120000 index f5fe23393..000000000 --- a/serverBin/mythen3DetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv7.0.0 \ No newline at end of file diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index ea5764e54..c0febc991 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 69c624742..9a0cfb408 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/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index b80fdb937..6b7eede39 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 50e38b3e0..cf55894d5 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -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", diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index bcea6581e..5c9d4750c 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -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 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) { diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 36d9b7a10..a2f155f22 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -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 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: + 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 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) { @@ -1383,7 +1445,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."; @@ -1411,10 +1474,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 @@ -1466,8 +1528,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 9dd8fcb80..53d2d9a63 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 @@ -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 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 cb47f4d7c..782aa624f 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -544,8 +544,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 0d2d0fb92..40233c720 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -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 getBadChannels() const; void setBadChannels(std::vector list); diff --git a/slsSupportLib/include/sls/network_utils.h b/slsSupportLib/include/sls/network_utils.h index 687236751..b4094e406 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 #include diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 5a1a5fee8..12ec4c98d 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -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"