diff --git a/RELEASE.txt b/RELEASE.txt index 92ddf7f4b..7eff077d3 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -55,6 +55,8 @@ This document describes the differences between v7.0.0 and v6.x.x - 10g eiger nextframenumber get fixed. - stop, able to set nextframenumber to a consistent (max + 1) for all modules if different (eiger/ctb/jungfrau/moench) - ctb: can set names for all the dacs +- fpga/kernel programming, checks if drive is a special file and not a normal file +- gotthard 25 um image reconstructed in gui and virtual hdf5 (firmware updated for slave to reverse channels) 2. Resolved Issues ================== diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 0bb25e64e..2323a0e1d 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1544,9 +1544,10 @@ void init_det(py::module &m) { Detector::setAdditionalJsonParameter, py::arg(), py::arg(), py::arg() = Positions{}) .def("programFPGA", - (void (Detector::*)(const std::string &, sls::Positions)) & + (void (Detector::*)(const std::string &, const bool, + sls::Positions)) & Detector::programFPGA, - py::arg(), py::arg() = Positions{}) + py::arg(), py::arg(), py::arg() = Positions{}) .def("resetFPGA", (void (Detector::*)(sls::Positions)) & Detector::resetFPGA, py::arg() = Positions{}) diff --git a/slsDetectorCalibration/singlePhotonDetector.h b/slsDetectorCalibration/singlePhotonDetector.h index 083e25f7b..96d239c97 100644 --- a/slsDetectorCalibration/singlePhotonDetector.h +++ b/slsDetectorCalibration/singlePhotonDetector.h @@ -429,23 +429,28 @@ class singlePhotonDetector : public analogDetector { for (ic = -(clusterSize / 2); ic < (clusterSize / 2) + 1; ic++) { - if ((iy + ir) >= iy && (iy + ir) < ny && - (ix + ic) >= ix && (ix + ic) < nx) { + if ((iy + ir) >= 0 && (iy + ir) < ny && + (ix + ic) >= 0 && (ix + ic) < nx) { + + + if ((iy + ir) >= iy && (ix + ic) >= ix ) { val[(iy + ir) * nx + ix + ic] = subtractPedestal(data, ix + ic, iy + ir, cm); - v = &(val[(iy + ir) * nx + ix + ic]); - tot += *v; - if (ir <= 0 && ic <= 0) - bl += *v; - if (ir <= 0 && ic >= 0) - br += *v; - if (ir >= 0 && ic <= 0) - tl += *v; - if (ir >= 0 && ic >= 0) - tr += *v; - if (*v > max) { - max = *v; - } + + } + v = &(val[(iy + ir) * nx + ix + ic]); + tot += *v; + if (ir <= 0 && ic <= 0) + bl += *v; + if (ir <= 0 && ic >= 0) + br += *v; + if (ir >= 0 && ic <= 0) + tl += *v; + if (ir >= 0 && ic >= 0) + tr += *v; + if (*v > max) //{ + max = *v; + //} } } } @@ -513,12 +518,19 @@ class singlePhotonDetector : public analogDetector { for (ic = -(clusterSize / 2); ic < (clusterSize / 2) + 1; ic++) { if ((iy + ir) >= 0 && (iy + ir) < ny && - (ix + ic) >= 0 && (ix + ic) < nx) - (clusters + nph) + (ix + ic) >= 0 && (ix + ic) < nx) { + (clusters + nph) ->set_data(val[(iy + ir) * nx + ix + ic], ic, ir); + if (val[(iy + ir) * nx + ix + ic]>max) + good=0; + } } } + if (good==0) { + (clusters + nph)->print(); + cout << max << " " << val[iy * nx + ix] << endl; + } good = 1; if (eMin > 0 && tot < eMin) good = 0; diff --git a/slsDetectorCalibration/single_photon_hit.h b/slsDetectorCalibration/single_photon_hit.h index 919f6af4b..0317e6e4d 100644 --- a/slsDetectorCalibration/single_photon_hit.h +++ b/slsDetectorCalibration/single_photon_hit.h @@ -216,14 +216,18 @@ class single_photon_hit { // int ix, iy; + printf("***************\n"); + printf("** %d %d **\n",x,y); for (int iy = 0; iy < dy; iy++) { for (int ix = 0; ix < dx; ix++) { printf("%d \t", data[ix + iy * dx]); } printf("\n"); } + printf("***************\n"); } + /** assign the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) \param v value to be diff --git a/slsDetectorGui/include/qDrawPlot.h b/slsDetectorGui/include/qDrawPlot.h index df96214bf..2c8739040 100644 --- a/slsDetectorGui/include/qDrawPlot.h +++ b/slsDetectorGui/include/qDrawPlot.h @@ -91,8 +91,10 @@ class qDrawPlot : public QWidget, private Ui::PlotObject { void Update2dPlot(); void Update1dXYRange(); void Update2dXYRange(); + void rearrangeGotthard25data(double *data); static const int NUM_PEDESTAL_FRAMES = 20; + static const int NUM_GOTTHARD25_CHANS = 1280; sls::Detector *det; slsDetectorDefs::detectorType detType; @@ -164,4 +166,5 @@ class qDrawPlot : public QWidget, private Ui::PlotObject { uint32_t pixelMask{0}; uint32_t gainMask{0}; int gainOffset{0}; + bool gotthard25; }; diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index a95c9efcd..5101c11dd 100644 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -80,6 +80,10 @@ void qDrawPlot::SetupWidgetWindow() { fileSaveName = "Image"; } + gotthard25 = ((detType == slsDetectorDefs::GOTTHARD2 || + detType == slsDetectorDefs::GOTTHARD) && + det->size() == 2); + SetupPlots(); SetDataCallBack(true); det->registerAcquisitionFinishedCallback(&(GetAcquisitionFinishedCallBack), @@ -807,6 +811,11 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex, isGainDataExtracted = false; } + // gotthard25um rearranging + if (gotthard25) { + rearrangeGotthard25data(rawData); + } + // title and frame index titles plotTitle = plotTitlePrefix + QString(data->fileName.c_str()).section('/', -1); @@ -1145,6 +1154,18 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size, } } +void qDrawPlot::rearrangeGotthard25data(double *data) { + const int nChans = NUM_GOTTHARD25_CHANS; + double temp[nChans * 2] = {0.0}; + for (int i = 0; i != nChans; ++i) { + // master module + temp[i * 2] = data[i]; + // slave module + temp[i * 2 + 1] = data[nChans + i]; + } + memcpy(data, temp, nChans * 2 * sizeof(double)); +} + void qDrawPlot::UpdatePlot() { std::lock_guard lock(mPlots); LOG(logDEBUG) << "Update Plot"; diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 3e3a18e9e..b85880659 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index e0544455f..de82c02ef 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index 40935898f..ad2379ae3 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index 09af215a0..43d71d90b 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index bccdf98d0..d4200dfea 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index 391942c4e..43cdabacb 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 4f5714204..dadb7a648 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h b/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h index 0c644f27b..5c8cbec53 100644 --- a/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h +++ b/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h @@ -26,10 +26,12 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd, uint64_t fsize); int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, char *functionType, char *clientChecksum, - ssize_t fsize); + ssize_t fsize, int forceDeleteNormalFile); int getDrive(char *mess, enum PROGRAM_INDEX index); /** Notify fpga not to touch flash, open src and flash drive to write */ -int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd); +int openFileForFlash(char *mess, enum PROGRAM_INDEX index, FILE **flashfd, FILE **srcfd, + int forceDeleteNormalFile); +int checkNormalFile(char *mess, enum PROGRAM_INDEX index, int forceDeleteNormalFile); int eraseFlash(char *mess); /* write from tmp file to flash */ int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index e68720305..385b45ae7 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -285,7 +285,8 @@ int update_detector_server(int); int receive_program(int file_des, enum PROGRAM_INDEX index); void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, - char *checksum, char *serverName); + char *checksum, char *serverName, + int forceDeleteNormalFile); void receive_program_default(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, char *checksum, char *serverName); diff --git a/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c b/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c index 5ad37fd43..0d5d6d840 100644 --- a/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c +++ b/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c @@ -7,6 +7,7 @@ #include "slsDetectorServer_defs.h" #include +#include #include #include // usleep @@ -38,6 +39,9 @@ #define CMD_GET_AMD_FLASH "dmesg | grep Amd" +#define CMD_CREATE_DEVICE_FILE_PART1 "mknod" +#define CMD_CREATE_DEVICE_FILE_PART2 "c 90 6" + #define FLASH_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB // clang-format on @@ -274,7 +278,8 @@ int allowUpdate(char *mess, char *functionType) { getKernelVersion(retvals); snprintf(mess, MAX_STR_LENGTH, "Could not update %s. Kernel version %s is too old to " - "update the Amd flash/ root directory. Most likely, blackfin needs rescue or replacement. Please contact us.\n", + "update the Amd flash/ root directory. Most likely, blackfin " + "needs rescue or replacement. Please contact us.\n", functionType, retvals); LOG(logERROR, (mess)); return FAIL; @@ -319,7 +324,7 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd, int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, char *functionType, char *clientChecksum, - ssize_t fsize) { + ssize_t fsize, int forceDeleteNormalFile) { memset(messageType, 0, sizeof(messageType)); strcpy(messageType, functionType); @@ -330,7 +335,8 @@ int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, FILE *flashfd = NULL; FILE *srcfd = NULL; - if (openFileForFlash(mess, &flashfd, &srcfd) == FAIL) { + if (openFileForFlash(mess, index, &flashfd, &srcfd, forceDeleteNormalFile) == + FAIL) { return FAIL; } @@ -434,7 +440,8 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) { return OK; } -int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) { +int openFileForFlash(char *mess, enum PROGRAM_INDEX index, FILE **flashfd, FILE **srcfd, + int forceDeleteNormalFile) { // open src file *srcfd = fopen(TEMP_PROG_FILE_NAME, "r"); if (*srcfd == NULL) { @@ -447,6 +454,11 @@ int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) { } LOG(logDEBUG1, ("Temp file ready for reading\n")); + if (checkNormalFile(mess, index, forceDeleteNormalFile) == FAIL) { + fclose(*srcfd); + return FAIL; + } + // open flash drive for writing *flashfd = fopen(flashDriveName, "w"); if (*flashfd == NULL) { @@ -462,6 +474,95 @@ int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) { return OK; } +int checkNormalFile(char *mess, enum PROGRAM_INDEX index, int forceDeleteNormalFile) { +#ifndef VIRTUAL + // check if its a normal file or special file + struct stat buf; + if (stat(flashDriveName, &buf) == -1) { + sprintf(mess, + "Could not %s. Unable to find the flash drive %s\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + // zero = normal file (not char special drive file) + if (!S_ISCHR(buf.st_mode)) { + // kernel memory is not permanent + if (index != PROGRAM_FPGA) { + sprintf(mess, + "Could not %s. The flash drive found is a normal file. " + "Reboot board using 'rebootcontroller' command to load " + "proper device tree\n", + messageType); + LOG(logERROR, (mess)); + return FAIL; + } + + // user does not allow to fix it (default) + if (forceDeleteNormalFile == 0) { + sprintf(mess, + "Could not %s. The flash drive %s found for fpga programming is a normal file. To " + "fix this (by deleting this file, creating the flash drive and proceeding with " + "programming), re-run the programming command 'programfpga' with parameter " + "'--force-delete-normal-file'\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + + // fpga memory stays after a reboot, user allowed to fix it + LOG(logWARNING, ("Flash drive invalidated (normal file). Fixing it...\n")); + + // user allows to fix it, so force delete normal file + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + + if (snprintf(cmd, MAX_STR_LENGTH, "rm %s", flashDriveName) >= + MAX_STR_LENGTH) { + sprintf(mess, + "Could not update %s. Command to delete normal file %s is " + "too long\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { + snprintf( + mess, MAX_STR_LENGTH, + "Could not update %s. (could not delete normal file %s: %s)\n", + messageType, flashDriveName, retvals); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tDeleted Normal File (%s)\n", flashDriveName)); + + // create special drive + if (snprintf(cmd, MAX_STR_LENGTH, "%s %s %s", + CMD_CREATE_DEVICE_FILE_PART1, flashDriveName, + CMD_CREATE_DEVICE_FILE_PART2) >= MAX_STR_LENGTH) { + sprintf(mess, + "Could not update %s. Command to create special file %s is " + "too long\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { + snprintf( + mess, MAX_STR_LENGTH, + "Could not update %s. (could not create special file %s: %s)\n", + messageType, flashDriveName, retvals); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tSpecial File created (%s)\n", flashDriveName)); + } else { + LOG(logINFO, ("\tValidated flash drive (not a normal file)\n")); + } +#endif + return OK; +} + int eraseFlash(char *mess) { LOG(logINFO, ("\tErasing Flash...\n")); diff --git a/slsDetectorServers/slsDetectorServer/src/programViaNios.c b/slsDetectorServers/slsDetectorServer/src/programViaNios.c index c81598650..fef00ace5 100644 --- a/slsDetectorServers/slsDetectorServer/src/programViaNios.c +++ b/slsDetectorServers/slsDetectorServer/src/programViaNios.c @@ -8,6 +8,7 @@ #include #include // usleep +#include /* global variables */ @@ -146,6 +147,30 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) { } int openFileForFlash(char *mess, FILE **flashfd) { +#ifndef VIRTUAL + // check if its a normal file or special file + struct stat buf; + if (stat(flashDriveName, &buf) == -1) { + sprintf(mess, + "Could not %s. Unable to find the flash drive %s\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + // zero = normal file (not char drive special file) + if (!S_ISCHR(buf.st_mode)) { + // memory is not permanent + sprintf(mess, + "Could not %s. The flash drive found is a normal file. " + "Reboot board using 'rebootcontroller' command to load " + "proper device tree\n", + messageType); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tValidated flash drive (not a normal file)\n")); +#endif + *flashfd = fopen(flashDriveName, "w"); if (*flashfd == NULL) { sprintf(mess, diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 796dd4f3f..fc32272ea 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4003,7 +4003,8 @@ int check_version(int file_des) { usleep(3 * 1000 * 1000); if (!isInitCheckDone()) { ret = FAIL; - strcpy(mess, "Server Initialization still not done done in server. Unexpected.\n"); + strcpy(mess, "Server Initialization still not done done in server. " + "Unexpected.\n"); LOG(logERROR, (mess)); } } @@ -9443,6 +9444,15 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) { LOG(logINFO, ("\tServer Name: %s\n", serverName)); } +#if !defined(GOTTHARD2D) && !defined(MYTHEN3D) && !defined(EIGERD) + int forceDeleteNormalFile = 0; + if (receiveData(file_des, &forceDeleteNormalFile, + sizeof(forceDeleteNormalFile), INT32) < 0) + return printSocketReadError(); + LOG(logINFO, + ("\tForce Delete Normal File flag? %s\n", (forceDeleteNormalFile ? "Y" : "N"))); +#endif + // in same folder as current process (will also work for virtual then // with write permissions) { @@ -9467,7 +9477,7 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) { checksum, serverName); #else receive_program_via_blackfin(file_des, index, functionType, - filesize, checksum, serverName); + filesize, checksum, serverName, forceDeleteNormalFile); #endif } @@ -9483,7 +9493,7 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) { void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, - char *checksum, char *serverName) { + char *checksum, char *serverName, int forceDeleteNormalFile) { #if !defined(JUNGFRAUD) && !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && \ !defined(GOTTHARDD) @@ -9582,7 +9592,7 @@ void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index, case PROGRAM_FPGA: case PROGRAM_KERNEL: ret = eraseAndWriteToFlash(mess, index, functionType, checksum, - totalsize); + totalsize, forceDeleteNormalFile); break; case PROGRAM_SERVER: ret = moveBinaryFile(mess, serverName, TEMP_PROG_FILE_NAME, @@ -9785,20 +9795,24 @@ int set_top(int file_des) { if (Server_VerifyLock() == OK) { if (arg != 0 && arg != 1) { ret = FAIL; - sprintf(mess, "Could not set top mode. Invalid value: %d. Must be 0 or 1\n", arg); + sprintf( + mess, + "Could not set top mode. Invalid value: %d. Must be 0 or 1\n", + arg); LOG(logERROR, (mess)); } else { ret = setTop(arg == 1 ? OW_TOP : OW_BOTTOM); if (ret == FAIL) { - sprintf(mess, "Could not set %s\n", (arg == 1 ? "Top" : "Bottom")); + sprintf(mess, "Could not set %s\n", + (arg == 1 ? "Top" : "Bottom")); LOG(logERROR, (mess)); - } else { + } else { int retval = -1; ret = isTop(&retval); if (ret == FAIL) { strcpy(mess, "Could not get Top mode\n"); LOG(logERROR, (mess)); - } else { + } else { LOG(logDEBUG1, ("retval top: %d\n", retval)); validate(&ret, mess, arg, retval, "set top mode", DEC); } diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index b935b5a04..68ccbd2a9 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1755,10 +1755,13 @@ class Detector { /** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] * Advanced user Function! * Program firmware from command line, after which detector controller is - * rebooted. [Jungfrau][CTB][Moench] fname is a pof file (full path) \n - * [Mythen3][Gotthard2] fname is an rbf file (full path) + * rebooted. forceDeleteNormalFile is true, if normal file found + * in device tree, it must be deleted, a new device drive created and + * programming continued.[Jungfrau][CTB][Moench] fname is a pof file (full + * path) \n [Mythen3][Gotthard2] fname is an rbf file (full path) */ - void programFPGA(const std::string &fname, Positions pos = {}); + void programFPGA(const std::string &fname, const bool forceDeleteNormalFile, + Positions pos = {}); /** [Jungfrau][CTB][Moench] Advanced user Function! */ void resetFPGA(Positions pos = {}); diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index b75e1fe2d..6b84e770d 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -2876,19 +2876,31 @@ std::string CmdProxy::ProgramFpga(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[fname.pof | fname.rbf (full path)]\n\t[Jungfrau][Ctb][Moench] " - "Programs FPGA from pof file (full path). Then, detector " - "controller is rebooted \n\t[Mythen3][Gotthard2] Programs FPGA " - "from rbf file (full path). Then, detector controller is " - "rebooted." + os << "[fname.pof | fname.rbf (full " + "path)][(opitonal)--force-delete-normal-file]\n\t[Jungfrau][Ctb][" + "Moench] Programs FPGA from pof file (full path). Then, detector " + "controller is rebooted. \n\t\tUse --force-delete-normal-file " + "argument, if normal file found in device tree, it must be " + "deleted, a new device drive created and programming " + "continued.\n\t[Mythen3][Gotthard2] Programs FPGA from rbf file " + "(full path). Then, detector controller is rebooted." << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get"); } else if (action == defs::PUT_ACTION) { - if (args.size() != 1) { + bool forceDeteleNormalFile = false; + if (args.size() == 2) { + if (args[1] != "--force-delete-normal-file") { + throw sls::RuntimeError( + "Could not scan second argument. Did you " + "mean --force-delete-normal-file?"); + } + forceDeteleNormalFile = true; + } else if (args.size() != 1) { WrongNumberOfParameters(1); } - det->programFPGA(args[0], std::vector{det_id}); + det->programFPGA(args[0], forceDeteleNormalFile, + std::vector{det_id}); os << "successful\n"; } else { throw sls::RuntimeError("Unknown action"); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 150263f5f..74447566d 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -883,7 +883,7 @@ Result Detector::getScanErrorMessage(Positions pos) const { Result Detector::getNumberofUDPInterfaces(Positions pos) const { // also called by vetostream (for gotthard2) - return pimpl->getNumberofUDPInterfaces(pos); + return pimpl->Parallel(&Module::getNumberofUDPInterfacesFromShm, pos); } void Detector::setNumberofUDPInterfaces(int n, Positions pos) { @@ -1751,7 +1751,7 @@ Result Detector::getVetoStream(Positions pos) const { // 3gbe auto r3 = pimpl->Parallel(&Module::getVetoStream, pos); // 10gbe (debugging interface) opens 2nd udp interface in receiver - auto r10 = pimpl->getNumberofUDPInterfaces(pos); + auto r10 = getNumberofUDPInterfaces(pos); Result res(r3.size()); for (unsigned int i = 0; i < res.size(); ++i) { @@ -1773,7 +1773,7 @@ void Detector::setVetoStream(defs::streamingInterface interface, pimpl->Parallel(&Module::setVetoStream, pos, LOW_LATENCY_LINK); // 10gbe (debugging interface) opens 2nd udp interface in receiver - int old_numinterfaces = pimpl->getNumberofUDPInterfaces(pos).tsquash( + int old_numinterfaces = getNumberofUDPInterfaces(pos).tsquash( "retrieved inconsistent number of udp interfaces"); int numinterfaces = (((interface & defs::streamingInterface::ETHERNET_10GB) == @@ -2230,10 +2230,11 @@ void Detector::setAdditionalJsonParameter(const std::string &key, // Advanced -void Detector::programFPGA(const std::string &fname, Positions pos) { +void Detector::programFPGA(const std::string &fname, + const bool forceDeleteNormalFile, Positions pos) { LOG(logINFO) << "Updating Firmware..."; std::vector buffer = pimpl->readProgrammingFile(fname); - pimpl->Parallel(&Module::programFPGA, pos, buffer); + pimpl->Parallel(&Module::programFPGA, pos, buffer, forceDeleteNormalFile); rebootController(pos); } @@ -2278,7 +2279,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname, LOG(logINFO) << "Updating Firmware and Detector Server (with tftp)..."; LOG(logINFO) << "Updating Detector Server (via tftp)..."; pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname); - programFPGA(fname, pos); + programFPGA(fname, false, pos); } void Detector::updateFirmwareAndServer(const std::string &sname, @@ -2289,7 +2290,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname, std::vector buffer = readBinaryFile(sname, "Update Detector Server"); std::string filename = sls::getFileNameFromFilePath(sname); pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename); - programFPGA(fname, pos); + programFPGA(fname, false, pos); } Result Detector::getUpdateMode(Positions pos) const { @@ -2399,7 +2400,7 @@ Result Detector::getMeasurementTime(Positions pos) const { std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); } std::vector Detector::getPortNumbers(int start_port) { - int num_sockets_per_detector = pimpl->getNumberofUDPInterfaces({}).tsquash( + int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash( "Number of UDP Interfaces is not consistent among modules"); std::vector res; res.reserve(size()); diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index aa169fdb2..7e8aa1719 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -32,7 +32,8 @@ namespace sls { DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update) - : detectorIndex(detector_index), shm(detector_index, -1),ctb_shm(detector_index, -1, CtbConfig::shm_tag()) { + : detectorIndex(detector_index), shm(detector_index, -1), + ctb_shm(detector_index, -1, CtbConfig::shm_tag()) { setupDetector(verify, update); } @@ -44,7 +45,7 @@ void DetectorImpl::setupDetector(bool verify, bool update) { if (update) { updateUserdetails(); } - + if (ctb_shm.IsExisting()) ctb_shm.OpenSharedMemory(); } @@ -94,7 +95,7 @@ void DetectorImpl::freeSharedMemory() { shm.RemoveSharedMemory(); client_downstream = false; - if(ctb_shm.IsExisting()) + if (ctb_shm.IsExisting()) ctb_shm.RemoveSharedMemory(); } @@ -155,7 +156,7 @@ void DetectorImpl::initSharedMemory(bool verify) { } } - // std::cout << + // std::cout << } void DetectorImpl::initializeDetectorStructure() { @@ -258,20 +259,11 @@ void DetectorImpl::setHostname(const std::vector &name) { } updateDetectorSize(); - // update zmq port (especially for eiger) - int numInterfaces = modules[0]->getNumberofUDPInterfaces(); - if (numInterfaces == 2) { - for (size_t i = 0; i < modules.size(); ++i) { - modules[i]->setClientStreamingPort(DEFAULT_ZMQ_CL_PORTNO + - i * numInterfaces); - } - } + // Here we know the detector type and can add ctb shared memory + // if needed, CTB dac names are only on detector level - //Here we know the detector type and can add ctb shared memory - //if needed, CTB dac names are only on detector level - - if (shm()->detType == defs::CHIPTESTBOARD){ - if(ctb_shm.IsExisting()) + if (shm()->detType == defs::CHIPTESTBOARD) { + if (ctb_shm.IsExisting()) ctb_shm.OpenSharedMemory(); else ctb_shm.CreateSharedMemory(); @@ -303,6 +295,13 @@ void DetectorImpl::addModule(const std::string &hostname) { // get type by connecting detectorType type = Module::getTypeFromDetector(host, port); + + // gotthard cannot have more than 2 modules (50um=1, 25um=2 + if ((type == GOTTHARD || type == GOTTHARD2) && modules.size() > 2) { + freeSharedMemory(); + throw sls::RuntimeError("Gotthard cannot have more than 2 modules"); + } + auto pos = modules.size(); modules.emplace_back( sls::make_unique(type, detectorIndex, pos, false)); @@ -310,11 +309,20 @@ void DetectorImpl::addModule(const std::string &hostname) { modules[pos]->setControlPort(port); modules[pos]->setStopPort(port + 1); modules[pos]->setHostname(host, shm()->initialChecks); + // module type updated by now shm()->detType = Parallel(&Module::getDetectorType, {}) .tsquash("Inconsistent detector types."); // for moench and ctb modules[pos]->updateNumberOfChannels(); + + // for eiger, jungfrau, gotthard2 + modules[pos]->updateNumberofUDPInterfaces(); + + // update zmq port in case numudpinterfaces changed + int numInterfaces = modules[pos]->getNumberofUDPInterfacesFromShm(); + modules[pos]->setClientStreamingPort(DEFAULT_ZMQ_CL_PORTNO + + pos * numInterfaces); } void DetectorImpl::updateDetectorSize() { @@ -1383,10 +1391,6 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { return buffer; } -sls::Result DetectorImpl::getNumberofUDPInterfaces(Positions pos) const { - return Parallel(&Module::getNumberofUDPInterfaces, pos); -} - sls::Result DetectorImpl::getDefaultDac(defs::dacIndex index, defs::detectorSettings sett, Positions pos) { @@ -1398,16 +1402,15 @@ void DetectorImpl::setDefaultDac(defs::dacIndex index, int defaultValue, Parallel(&Module::setDefaultDac, pos, index, defaultValue, sett); } - std::vector DetectorImpl::getCtbDacNames() const { return ctb_shm()->getDacNames(); } -void DetectorImpl::setCtbDacNames(const std::vector& names){ +void DetectorImpl::setCtbDacNames(const std::vector &names) { ctb_shm()->setDacNames(names); } -std::string DetectorImpl::getCtbDacName(defs::dacIndex i) const{ +std::string DetectorImpl::getCtbDacName(defs::dacIndex i) const { return ctb_shm()->getDacName(static_cast(i)); } diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index d30743da2..92d364556 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -293,7 +293,6 @@ class DetectorImpl : public virtual slsDetectorDefs { */ std::vector readProgrammingFile(const std::string &fname); - sls::Result getNumberofUDPInterfaces(Positions pos) const; void setNumberofUDPInterfaces(int n, Positions pos); sls::Result getDefaultDac(defs::dacIndex index, defs::detectorSettings sett, diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 49cff9b83..5555ec71f 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -976,9 +976,8 @@ int Module::getNumberofUDPInterfacesFromShm() const { return shm()->numUDPInterfaces; } -int Module::getNumberofUDPInterfaces() const { +void Module::updateNumberofUDPInterfaces() { shm()->numUDPInterfaces = sendToDetector(F_GET_NUM_INTERFACES); - return shm()->numUDPInterfaces; } void Module::setNumberofUDPInterfaces(int n) { @@ -1186,7 +1185,7 @@ std::string Module::printReceiverConfiguration() { << getReceiverHostname(); if (shm()->detType == JUNGFRAU) { - os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfaces() + os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfacesFromShm() << "\nSelected Interface:\t" << getSelectedUDPInterface(); } @@ -2591,12 +2590,14 @@ void Module::setAdditionalJsonParameter(const std::string &key, } // Advanced -void Module::programFPGA(std::vector buffer) { +void Module::programFPGA(std::vector buffer, + const bool forceDeleteNormalFile) { switch (shm()->detType) { case JUNGFRAU: case CHIPTESTBOARD: case MOENCH: - sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware"); + sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware", "", + forceDeleteNormalFile); break; case MYTHEN3: case GOTTHARD2: @@ -3219,10 +3220,10 @@ void Module::initializeModuleStructure(detectorType type) { sls::strcpy_safe(shm()->rxHostname, "none"); shm()->rxTCPPort = DEFAULT_PORTNO + 2; shm()->useReceiverFlag = false; + shm()->numUDPInterfaces = 1; shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO + moduleIndex * shm()->numUDPInterfaces; shm()->zmqip = IpAddr{}; - shm()->numUDPInterfaces = 1; shm()->stoppedFlag = false; // get the Module parameters based on type @@ -3583,7 +3584,8 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, void Module::sendProgram(bool blackfin, std::vector buffer, const int functionEnum, const std::string &functionType, - const std::string serverName) { + const std::string serverName, + const bool forceDeleteNormalFile) { LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname << "): Sending " << functionType; @@ -3607,6 +3609,11 @@ void Module::sendProgram(bool blackfin, std::vector buffer, client.Send(sname); } + // send forceDeleteNormalFile flag + if (blackfin) { + client.Send(static_cast(forceDeleteNormalFile)); + } + // validate memory allocation etc in detector if (client.Receive() == FAIL) { std::ostringstream os; diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 0529773cd..fe5c5f5b3 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -219,7 +219,7 @@ class Module : public virtual slsDetectorDefs { * * * ************************************************/ int getNumberofUDPInterfacesFromShm() const; - int getNumberofUDPInterfaces() const; + void updateNumberofUDPInterfaces(); void setNumberofUDPInterfaces(int n); int getSelectedUDPInterface() const; void selectUDPInterface(int n); @@ -545,7 +545,8 @@ class Module : public virtual slsDetectorDefs { * Advanced * * * * ************************************************/ - void programFPGA(std::vector buffer); + void programFPGA(std::vector buffer, + const bool forceDeleteNormalFile); void resetFPGA(); void copyDetectorServer(const std::string &fname, const std::string &hostname); @@ -760,7 +761,8 @@ class Module : public virtual slsDetectorDefs { bool trimbits = true); void sendProgram(bool blackfin, std::vector buffer, const int functionEnum, const std::string &functionType, - const std::string serverName = ""); + const std::string serverName = "", + const bool forceDeleteNormalFile = false); void simulatingActivityinDetector(const std::string &functionType, const int timeRequired); diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index e4426aafb..a22abdfc1 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -200,7 +200,10 @@ void DataProcessor::CreateVirtualFile( if (virtualFile_) { delete virtualFile_; } - virtualFile_ = new HDF5VirtualFile(hdf5Lib); + bool gotthard25um = + ((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) && + (numModX * numModY) == 2); + virtualFile_ = new HDF5VirtualFile(hdf5Lib, gotthard25um); // maxframesperfile = 0 for infinite files uint32_t framesPerFile = @@ -214,7 +217,7 @@ void DataProcessor::CreateVirtualFile( filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode, modulePos, numUnitsPerReadout, framesPerFile, numImages, generalData_->nPixelsX, generalData_->nPixelsY, dynamicRange, - numImagesProcessed, numModX, numModY, dataFile_->GetPDataType(), + numFramesCaught_, numModX, numModY, dataFile_->GetPDataType(), dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes()); } diff --git a/slsReceiverSoftware/src/HDF5VirtualFile.cpp b/slsReceiverSoftware/src/HDF5VirtualFile.cpp index 71ef51099..015ad0ae3 100644 --- a/slsReceiverSoftware/src/HDF5VirtualFile.cpp +++ b/slsReceiverSoftware/src/HDF5VirtualFile.cpp @@ -5,8 +5,8 @@ #include -HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5Lib) - : File(HDF5), hdf5Lib_(hdf5Lib) {} +HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5Lib, bool g25) + : File(HDF5), hdf5Lib_(hdf5Lib), gotthard25um(g25) {} HDF5VirtualFile::~HDF5VirtualFile() { CloseFile(); } @@ -73,12 +73,10 @@ void HDF5VirtualFile::CreateVirtualFile( "version", PredType::NATIVE_DOUBLE, dataspace_attr); attribute.write(PredType::NATIVE_DOUBLE, &dValue); - // virtual data dataspace + // virtual dataspace hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy, numModZ * nDimz}; DataSpace vdsDataSpace(3, vdsDims, nullptr); - - // virtual parameter dataspace hsize_t vdsDimsPara[2] = {numImagesCaught, (unsigned int)numModY * numModZ}; DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); @@ -91,37 +89,54 @@ void HDF5VirtualFile::CreateVirtualFile( // property list for parameters (datatype) std::vector plistPara(paraSize); - // hyperslab - int numMajorHyperslab = numImagesCaught / maxFramesPerFile; + // hyperslab (files) + int numFiles = numImagesCaught / maxFramesPerFile; if (numImagesCaught % maxFramesPerFile) - ++numMajorHyperslab; + ++numFiles; uint64_t framesSaved = 0; - // loop through files - for (int hyperSlab = 0; hyperSlab < numMajorHyperslab; ++hyperSlab) { + for (int iFile = 0; iFile < numFiles; ++iFile) { uint64_t nDimx = ((numImagesCaught - framesSaved) > maxFramesPerFile) ? maxFramesPerFile : (numImagesCaught - framesSaved); - hsize_t start[3] = {framesSaved, 0, 0}; - hsize_t count[3] = {nDimx, nDimy, nDimz}; - hsize_t startPara[2] = {framesSaved, 0}; - hsize_t countPara[2] = {nDimx, 1}; - // loop through readouts - for (unsigned int i = 0; i < numModY * numModZ; ++i) { - // setect data hyperslabs - vdsDataSpace.selectHyperslab(H5S_SELECT_SET, count, start); + hsize_t startLocation[3] = {framesSaved, 0, 0}; + hsize_t strideBetweenBlocks[3] = {1, 1, 1}; + hsize_t numBlocks[3] = {nDimx, nDimy, nDimz}; + hsize_t blockSize[3] = {1, 1, 1}; - // select parameter hyperslabs - vdsDataSpacePara.selectHyperslab(H5S_SELECT_SET, countPara, - startPara); + hsize_t startLocationPara[2] = {framesSaved, 0}; + hsize_t strideBetweenBlocksPara[3] = {1, 1}; + hsize_t numBlocksPara[2] = {1, 1}; + hsize_t blockSizePara[3] = {nDimx, 1}; + + // interleaving for g2 + if (gotthard25um) { + strideBetweenBlocks[2] = 2; + } + + for (unsigned int iReadout = 0; iReadout < numModY * numModZ; + ++iReadout) { + + // interleaving for g2 (startLocation is 0 and 1) + if (gotthard25um) { + startLocation[2] = iReadout; + } + + vdsDataSpace.selectHyperslab(H5S_SELECT_SET, numBlocks, + startLocation, strideBetweenBlocks, + blockSize); + + vdsDataSpacePara.selectHyperslab( + H5S_SELECT_SET, numBlocksPara, startLocationPara, + strideBetweenBlocksPara, blockSizePara); // source file name std::ostringstream os; os << filePath << "/" << fileNamePrefix << "_d" - << (modulePos * numUnitsPerReadout + i) << "_f" << hyperSlab - << '_' << fileIndex << ".h5"; + << (modulePos * numUnitsPerReadout + iReadout) << "_f" + << iFile << '_' << fileIndex << ".h5"; std::string srcFileName = os.str(); LOG(logDEBUG1) << srcFileName; @@ -138,25 +153,20 @@ void HDF5VirtualFile::CreateVirtualFile( std::ostringstream osfn; osfn << "/data"; if (numImages > 1) - osfn << "_f" << std::setfill('0') << std::setw(12) - << hyperSlab; + osfn << "_f" << std::setfill('0') << std::setw(12) << iFile; std::string srcDatasetName = osfn.str(); - // source data dataspace + // source dataspace hsize_t srcDims[3] = {nDimx, nDimy, nDimz}; hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz}; DataSpace srcDataSpace(3, srcDims, srcDimsMax); - - // source parameter dataspace hsize_t srcDimsPara[1] = {nDimx}; hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED}; DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); - // mapping of data property list + // mapping of property list plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), srcDatasetName.c_str(), srcDataSpace); - - // mapping of parameter property list for (unsigned int p = 0; p < paraSize; ++p) { plistPara[p].setVirtual( vdsDataSpacePara, relative_srcFileName.c_str(), @@ -165,21 +175,23 @@ void HDF5VirtualFile::CreateVirtualFile( // H5Sclose(srcDataspace); // H5Sclose(srcDataspace_para); - start[2] += nDimz; - if (start[2] >= (numModZ * nDimz)) { - start[2] = 0; - start[1] += nDimy; + + if (!gotthard25um) { + startLocation[2] += nDimz; + if (startLocation[2] >= (numModZ * nDimz)) { + startLocation[2] = 0; + startLocation[1] += nDimy; + } } - startPara[1]++; + startLocationPara[1]++; } framesSaved += nDimx; } - // data dataset + // datasets dataSetName_ = "data"; DataSet vdsDataSet(fd_->createDataSet(dataSetName_.c_str(), dataType, vdsDataSpace, plist)); - // parameter dataset for (unsigned int p = 0; p < paraSize; ++p) { DataSet vdsDataSetPara(fd_->createDataSet( parameterNames[p].c_str(), parameterDataTypes[p], @@ -196,4 +208,4 @@ void HDF5VirtualFile::CreateVirtualFile( if (!silentMode) { LOG(logINFO) << "Virtual File: " << fileName_; } -} \ No newline at end of file +} diff --git a/slsReceiverSoftware/src/HDF5VirtualFile.h b/slsReceiverSoftware/src/HDF5VirtualFile.h index a479bce2d..89b1c0b60 100644 --- a/slsReceiverSoftware/src/HDF5VirtualFile.h +++ b/slsReceiverSoftware/src/HDF5VirtualFile.h @@ -9,7 +9,7 @@ class HDF5VirtualFile : private virtual slsDetectorDefs, public File { public: - HDF5VirtualFile(std::mutex *hdf5Lib); + HDF5VirtualFile(std::mutex *hdf5Lib, bool g25); ~HDF5VirtualFile(); std::array GetFileAndDatasetName() const override; @@ -30,4 +30,5 @@ class HDF5VirtualFile : private virtual slsDetectorDefs, public File { H5File *fd_{nullptr}; std::string fileName_; std::string dataSetName_; + bool gotthard25um; }; \ No newline at end of file diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 04645699b..71b44521d 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -6,10 +6,10 @@ #define APIRECEIVER 0x211124 #define APIGUI 0x211124 -#define APICTB 0x220318 -#define APIGOTTHARD 0x220318 -#define APIGOTTHARD2 0x220318 -#define APIJUNGFRAU 0x220318 -#define APIMYTHEN3 0x220318 -#define APIMOENCH 0x220318 -#define APIEIGER 0x220318 +#define APIEIGER 0x220324 +#define APICTB 0x220328 +#define APIGOTTHARD 0x220328 +#define APIGOTTHARD2 0x220328 +#define APIJUNGFRAU 0x220328 +#define APIMYTHEN3 0x220328 +#define APIMOENCH 0x220328