diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index fc395eecb..9aa9bc821 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -732,13 +732,6 @@ class Detector(CppDetectorApi): res = self.getMeasuredSubFramePeriod() return element_if_equal([it.total_seconds() for it in res]) - @property - def storeinram(self): - return element_if_equal(self.getStoreInRamMode()) - - @storeinram.setter - def storeinram(self, value): - self.setStoreInRamMode(value) """ Jungfrau specific diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 97f555ffc..06ae7c435 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -318,6 +318,16 @@ void init_det(py::module &m) { (void (Detector::*)(defs::dacIndex, int, int, sls::Positions)) & Detector::setOnChipDAC, py::arg(), py::arg(), py::arg(), py::arg() = Positions{}) + .def("getExternalSignalFlags", + (Result(Detector::*)(int, sls::Positions) + const) & + Detector::getExternalSignalFlags, + py::arg(), py::arg() = Positions{}) + .def("setExternalSignalFlags", + (void (Detector::*)(int, defs::externalSignalFlag, + sls::Positions)) & + Detector::setExternalSignalFlags, + py::arg(), py::arg(), py::arg() = Positions{}) .def("acquire", (void (Detector::*)()) & Detector::acquire) .def("clearAcquiringFlag", (void (Detector::*)()) & Detector::clearAcquiringFlag) @@ -745,14 +755,6 @@ void init_det(py::module &m) { (void (Detector::*)(bool, sls::Positions)) & Detector::setOverFlowMode, py::arg(), py::arg() = Positions{}) - .def("getStoreInRamMode", - (Result(Detector::*)(sls::Positions) const) & - Detector::getStoreInRamMode, - py::arg() = Positions{}) - .def("setStoreInRamMode", - (void (Detector::*)(bool, sls::Positions)) & - Detector::setStoreInRamMode, - py::arg(), py::arg() = Positions{}) .def("getBottom", (Result(Detector::*)(sls::Positions) const) & Detector::getBottom, @@ -914,16 +916,6 @@ void init_det(py::module &m) { (Result(Detector::*)(sls::Positions) const) & Detector::getExptimeLeft, py::arg() = Positions{}) - .def("getExternalSignalFlags", - (Result(Detector::*)(int, sls::Positions) - const) & - Detector::getExternalSignalFlags, - py::arg(), py::arg() = Positions{}) - .def("setExternalSignalFlags", - (void (Detector::*)(int, defs::externalSignalFlag, - sls::Positions)) & - Detector::setExternalSignalFlags, - py::arg(), py::arg(), py::arg() = Positions{}) .def("getNumberOfBursts", (Result(Detector::*)(sls::Positions) const) & Detector::getNumberOfBursts, @@ -1396,7 +1388,8 @@ void init_det(py::module &m) { Detector::getLastClientIP, py::arg() = Positions{}) .def("executeCommand", - (void (Detector::*)(const std::string &, sls::Positions)) & + (Result(Detector::*)(const std::string &, + sls::Positions)) & Detector::executeCommand, py::arg(), py::arg() = Positions{}) .def("getNumberOfFramesFromStart", diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index c48992fae..f8eee20a6 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 075f965ad..1a78f829b 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index 30b357b6e..0b9edfe78 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -60,7 +60,6 @@ int eiger_iodelay = 0; int eiger_photonenergy = 0; int eiger_dynamicrange = 0; int eiger_parallelmode = 0; -int eiger_storeinmem = 0; int eiger_overflow32 = 0; int eiger_readoutspeed = 0; int eiger_triggermode = 0; @@ -687,8 +686,7 @@ void setupDetector() { setDynamicRange(DEFAULT_DYNAMIC_RANGE); eiger_photonenergy = DEFAULT_PHOTON_ENERGY; setParallelMode(DEFAULT_PARALLEL_MODE); - setOverFlowMode(DEFAULT_READOUT_STOREINRAM_MODE); - setStoreInRamMode(DEFAULT_READOUT_OVERFLOW32_MODE); + setOverFlowMode(DEFAULT_READOUT_OVERFLOW32_MODE); setClockDivider(RUN_CLK, DEFAULT_CLK_SPEED); // clk_devider,half speed setIODelay(DEFAULT_IO_DELAY); setTiming(DEFAULT_TIMING_MODE); @@ -805,14 +803,6 @@ int setOverFlowMode(int mode) { int getOverFlowMode() { return eiger_overflow32; } -void setStoreInRamMode(int mode) { - mode = (mode == 0 ? 0 : 1); - LOG(logINFO, ("Setting Store in Ram mode to %d\n", mode)); - eiger_storeinmem = mode; -} - -int getStoreInRamMode() { return eiger_storeinmem; } - /* parameters - timer */ int setStartingFrameNumber(uint64_t value) { @@ -1118,37 +1108,6 @@ int setModule(sls_detector_module myMod, char *mess) { return OK; } -int getModule(sls_detector_module *myMod) { - -#ifndef VIRTUAL - // trimbits - unsigned int *tt; - tt = Feb_Control_GetTrimbits(); - - // exclude gap pixels - int ip = 0, ich = 0; - for (int iy = 0; iy < 256; ++iy) { - for (int ichip = 0; ichip < 4; ++ichip) { - for (int ix = 0; ix < 256; ++iy) { - myMod->chanregs[ich++] = tt[ip++]; - } - if (ichip < 3) { - ip++; - ip++; - } - } - } -#endif - - // copy local module to myMod - if (detectorModules) { - if (copyModule(myMod, detectorModules) == FAIL) - return FAIL; - } else - return FAIL; - return OK; -} - enum detectorSettings setSettings(enum detectorSettings sett) { if (sett == UNINITIALIZED) { return thisSettings; @@ -2057,10 +2016,8 @@ int startStateMachine() { LOG(logINFO, ("Going to start acquisition\n")); Feb_Control_StartAcquisition(); - if (!eiger_storeinmem) { - LOG(logINFO, ("requesting images right after start\n")); - ret = startReadOut(); - } + LOG(logINFO, ("requesting images right after start\n")); + ret = startReadOut(); // wait for acquisition start if (ret == OK) { @@ -2382,16 +2339,6 @@ void readFrame(int *ret, char *mess) { } LOG(logINFOGREEN, ("Acquisition finished\n")); - if (eiger_storeinmem) { - LOG(logINFO, ("requesting images after storing in memory\n")); - if (startReadOut() == FAIL) { - strcpy(mess, "Could not execute read image requests\n"); - LOG(logERROR, (mess)); - *ret = (int)FAIL; - return; - } - } - // wait for detector to send int isTransmitting = 1; while (isTransmitting) { diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index a5921fe44..76268dedf 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -103,7 +103,6 @@ enum MASTERINDEX { MASTER_HARDWARE, OW_MASTER, OW_SLAVE }; #define DEFAULT_DYNAMIC_RANGE (16) #define DEFAULT_PARALLEL_MODE (1) -#define DEFAULT_READOUT_STOREINRAM_MODE (0) #define DEFAULT_READOUT_OVERFLOW32_MODE (0) #define DEFAULT_CLK_SPEED (FULL_SPEED) #define DEFAULT_IO_DELAY (650) diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index d1d9f25ca..fb2733aa8 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 8a84b58d1..38fff844f 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c index 407b54c46..10dbc7bb8 100644 --- a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c @@ -945,23 +945,6 @@ int setModule(sls_detector_module myMod, char *mess) { return OK; } -int getModule(sls_detector_module *myMod) { - for (int idac = 0; idac < NDAC; ++idac) { - if (dacValues[idac] >= 0) - *((myMod->dacs) + idac) = dacValues[idac]; - } - // check if all of them are not initialized - int initialized = 0; - for (int idac = 0; idac < NDAC; ++idac) { - if (dacValues[idac] >= 0) - initialized = 1; - } - if (initialized) { - return OK; - } - return FAIL; -} - enum detectorSettings setSettings(enum detectorSettings sett) { if (sett == UNINITIALIZED) return thisSettings; diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 164c95769..fbb775e64 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 ee4bd1e7d..f15523473 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -367,6 +367,9 @@ void initStopServer() { if (!isControlServer) { ComVirtual_setStop(virtual_stop); } + // temp threshold and reset event (read by stop server) + setThresholdTemperature(DEFAULT_TMP_THRSHLD); + setTemperatureEvent(0); #endif } @@ -745,23 +748,6 @@ int setModule(sls_detector_module myMod, char *mess) { return OK; } -int getModule(sls_detector_module *myMod) { - for (int idac = 0; idac < NDAC; ++idac) { - if (dacValues[idac] >= 0) - *((myMod->dacs) + idac) = dacValues[idac]; - } - // check if all of them are not initialized - int initialized = 0; - for (int idac = 0; idac < NDAC; ++idac) { - if (dacValues[idac] >= 0) - initialized = 1; - } - if (initialized) { - return OK; - } - return FAIL; -} - enum detectorSettings setSettings(enum detectorSettings sett) { if (sett == UNINITIALIZED) return thisSettings; diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index 12f8fd4f4..781d587ab 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 2d7534def..3d2c570c9 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index 87cffcb72..4f6687adf 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -600,16 +600,6 @@ int setModule(sls_detector_module myMod, char *mess) { return OK; } -int getModule(sls_detector_module *myMod) { - // copy local module to myMod - if (detectorModules) { - if (copyModule(myMod, detectorModules) == FAIL) - return FAIL; - } else - return FAIL; - return OK; -} - int setBit(int ibit, int patword) { return patword |= (1 << ibit); } int clearBit(int ibit, int patword) { return patword &= ~(1 << ibit); } diff --git a/slsDetectorServers/slsDetectorServer/include/communication_funcs.h b/slsDetectorServers/slsDetectorServer/include/communication_funcs.h index ad14b6dd2..e41283484 100644 --- a/slsDetectorServers/slsDetectorServer/include/communication_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/communication_funcs.h @@ -24,7 +24,6 @@ int receiveData(int file_des, void *buf, int length, intType itype); int sendDataOnly(int file_des, void *buf, int length); int receiveDataOnly(int file_des, void *buf, int length); -int sendModule(int file_des, sls_detector_module *myMod); int receiveModule(int file_des, sls_detector_module *myMod); /** diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index febe29d11..cfeec2b49 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -184,8 +184,6 @@ int setParallelMode(int mode); int getParallelMode(); int setOverFlowMode(int mode); int getOverFlowMode(); -void setStoreInRamMode(int mode); -int getStoreInRamMode(); #endif #ifdef CHIPTESTBOARDD int setReadoutMode(enum readoutMode mode); @@ -276,7 +274,6 @@ int64_t getMeasurementTime(); // parameters - module, settings #if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD)) && (!defined(GOTTHARD2D)) int setModule(sls_detector_module myMod, char *mess); -int getModule(sls_detector_module *myMod); #endif #ifdef MYTHEN3D int setTrimbits(int *trimbits); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 4513eb63c..b79faebd3 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -41,12 +41,10 @@ int get_adc(int); int write_register(int); int read_register(int); int set_module(int); -int get_module(int); int set_settings(int); int get_threshold_energy(int); int start_acquisition(int); int stop_acquisition(int); -int start_readout(int); int get_run_status(int); int start_and_read_all(int); int read_all(int); @@ -85,7 +83,6 @@ int get_measurement_time(int); int set_dynamic_range(int); int set_roi(int); int get_roi(int); -int exit_server(int); int lock_server(int); int get_last_client_ip(int); int set_port(int); @@ -181,8 +178,6 @@ int set_parallel_mode(int); int get_parallel_mode(int); int set_overflow_mode(int); int get_overflow_mode(int); -int set_storeinram(int); -int get_storeinram(int); int set_readout_mode(int); int get_readout_mode(int); int set_clock_frequency(int); diff --git a/slsDetectorServers/slsDetectorServer/src/communication_funcs.c b/slsDetectorServers/slsDetectorServer/src/communication_funcs.c index 5bb757591..8a5c4d103 100644 --- a/slsDetectorServers/slsDetectorServer/src/communication_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/communication_funcs.c @@ -404,68 +404,6 @@ int receiveDataOnly(int file_des, void *buf, int length) { return total_received; } -int sendModule(int file_des, sls_detector_module *myMod) { - int ts = 0, n = 0; - n = sendData(file_des, &(myMod->serialnumber), sizeof(myMod->serialnumber), - INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->nchan), sizeof(myMod->nchan), INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->nchip), sizeof(myMod->nchip), INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->ndac), sizeof(myMod->ndac), INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->reg), sizeof(myMod->reg), INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->iodelay), sizeof(myMod->iodelay), INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->tau), sizeof(myMod->tau), INT32); - if (!n) { - return -1; - } - ts += n; - n = sendData(file_des, &(myMod->eV), sizeof(myMod->eV), INT32); - if (!n) { - return -1; - } - ts += n; - // dacs - n = sendData(file_des, myMod->dacs, sizeof(int) * (myMod->ndac), INT32); - if (!n) { - return -1; - } - ts += n; - // channels -#if defined(EIGERD) || defined(MYTHEN3D) - n = sendData(file_des, myMod->chanregs, sizeof(int) * (myMod->nchan), - INT32); - if (!n) { - return -1; - } - ts += n; -#endif - LOG(logDEBUG1, ("module of size %d sent register %x\n", ts, myMod->reg)); - return ts; -} - int receiveModule(int file_des, sls_detector_module *myMod) { enum TLogLevel level = logDEBUG1; LOG(level, ("Receiving Module\n")); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 6f5f1963e..675c4fd77 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -155,15 +155,12 @@ void function_table() { flist[F_WRITE_REGISTER] = &write_register; flist[F_READ_REGISTER] = &read_register; flist[F_SET_MODULE] = &set_module; - flist[F_GET_MODULE] = &get_module; flist[F_SET_SETTINGS] = &set_settings; flist[F_GET_THRESHOLD_ENERGY] = &get_threshold_energy; flist[F_START_ACQUISITION] = &start_acquisition; flist[F_STOP_ACQUISITION] = &stop_acquisition; - flist[F_START_READOUT] = &start_readout; flist[F_GET_RUN_STATUS] = &get_run_status; flist[F_START_AND_READ_ALL] = &start_and_read_all; - flist[F_READ_ALL] = &read_all; flist[F_GET_NUM_FRAMES] = &get_num_frames; flist[F_SET_NUM_FRAMES] = &set_num_frames; flist[F_GET_NUM_TRIGGERS] = &get_num_triggers; @@ -201,7 +198,6 @@ void function_table() { flist[F_SET_DYNAMIC_RANGE] = &set_dynamic_range; flist[F_SET_ROI] = &set_roi; flist[F_GET_ROI] = &get_roi; - flist[F_EXIT_SERVER] = &exit_server; flist[F_LOCK_SERVER] = &lock_server; flist[F_GET_LAST_CLIENT_IP] = &get_last_client_ip; flist[F_SET_PORT] = &set_port; @@ -292,8 +288,6 @@ void function_table() { flist[F_GET_PARALLEL_MODE] = &get_parallel_mode; flist[F_SET_OVERFLOW_MODE] = &set_overflow_mode; flist[F_GET_OVERFLOW_MODE] = &get_overflow_mode; - flist[F_SET_STOREINRAM_MODE] = &set_storeinram; - flist[F_GET_STOREINRAM_MODE] = &get_storeinram; flist[F_SET_READOUT_MODE] = &set_readout_mode; flist[F_GET_READOUT_MODE] = &get_readout_mode; flist[F_SET_CLOCK_FREQUENCY] = &set_clock_frequency; @@ -1544,68 +1538,6 @@ int set_module(int file_des) { return Server_SendResult(file_des, INT32, NULL, 0); } -int get_module(int file_des) { - ret = OK; - memset(mess, 0, sizeof(mess)); - sls_detector_module module; - int *myDac = NULL; - int *myChan = NULL; - module.dacs = NULL; - module.chanregs = NULL; - - // allocate to send arguments - // allocate dacs - myDac = malloc(getNumberOfDACs() * sizeof(int)); - // error - if (getNumberOfDACs() > 0 && myDac == NULL) { - ret = FAIL; - sprintf(mess, "Could not allocate dacs\n"); - LOG(logERROR, (mess)); - } else - module.dacs = myDac; - -#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(GOTTHARD2D) - functionNotImplemented(); -#endif - -#if defined(EIGERD) || defined(MYTHEN3D) - // allocate chans - if (ret == OK) { - myChan = malloc(getTotalNumberOfChannels() * sizeof(int)); - if (getTotalNumberOfChannels() > 0 && myChan == NULL) { - ret = FAIL; - sprintf(mess, "Could not allocate chans\n"); - LOG(logERROR, (mess)); - } else - module.chanregs = myChan; - } -#endif - - // get module - if (ret == OK) { - module.nchip = getNumberOfChips(); - module.nchan = getTotalNumberOfChannels(); - module.ndac = getNumberOfDACs(); - - // only get - LOG(logDEBUG1, ("Getting module\n")); -#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(GOTTHARD2D) - getModule(&module); -#endif - LOG(logDEBUG1, ("Getting module. Settings:%d\n", module.reg)); - } - - Server_SendResult(file_des, INT32, NULL, 0); - - // send module, 0 is to receive partially (without trimbits etc) - if (ret != FAIL) { - ret = sendModule(file_des, &module); - } - free(myChan); - free(myDac); - return ret; -} - int set_settings(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -1808,27 +1740,6 @@ int stop_acquisition(int file_des) { return Server_SendResult(file_des, INT32, NULL, 0); } -int start_readout(int file_des) { - ret = OK; - memset(mess, 0, sizeof(mess)); - - LOG(logDEBUG1, ("Starting readout\n")); -#ifndef EIGERD - functionNotImplemented(); -#else - // only set - if (Server_VerifyLock() == OK) { - ret = startReadOut(); - if (ret == FAIL) { - sprintf(mess, "Could not start readout\n"); - LOG(logERROR, (mess)); - } - LOG(logDEBUG1, ("Starting readout ret: %d\n", ret)); - } -#endif - return Server_SendResult(file_des, INT32, NULL, 0); -} - int get_run_status(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -2793,14 +2704,6 @@ int get_roi(int file_des) { return ret; } -int exit_server(int file_des) { - LOG(logINFORED, ("Closing Server\n")); - ret = OK; - memset(mess, 0, sizeof(mess)); - Server_SendResult(file_des, INT32, NULL, 0); - return GOODBYE; -} - int lock_server(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -5327,11 +5230,11 @@ int get_dest_udp_port(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); int retval = -1; - LOG(logDEBUG1, ("Getting destination porstore in ram moden")); + LOG(logDEBUG1, ("Getting destination port")); // get only retval = udpDetails.dstport; - LOG(logDEBUG, ("udp destination port retstore in ram model: %u\n", retval)); + LOG(logDEBUG, ("udp destination port retval: %u\n", retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } @@ -5570,43 +5473,6 @@ int get_overflow_mode(int file_des) { return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } -int set_storeinram(int file_des) { - ret = OK; - memset(mess, 0, sizeof(mess)); - int arg = 0; - - if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) - return printSocketReadError(); - LOG(logINFO, ("Setting store in ram mode: %u\n", arg)); - -#ifndef EIGERD - functionNotImplemented(); -#else - // only set - if (Server_VerifyLock() == OK) { - setStoreInRamMode(arg); - } -#endif - return Server_SendResult(file_des, INT32, NULL, 0); -} - -int get_storeinram(int file_des) { - ret = OK; - memset(mess, 0, sizeof(mess)); - int retval = -1; - - LOG(logDEBUG1, ("Getting store in ram mode\n")); - -#ifndef EIGERD - functionNotImplemented(); -#else - // get only - retval = getStoreInRamMode(); - LOG(logDEBUG1, ("store in ram mode retval: %u\n", retval)); -#endif - return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); -} - int set_readout_mode(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -6916,7 +6782,7 @@ int get_receiver_parameters(int file_des) { n += sendData(file_des, &i32, sizeof(i32), INT32); if (n < 0) return printSocketReadError(); - // multisize + // numberOfDetector i32 = 0; n += sendData(file_des, &i32, sizeof(i32), INT32); if (n < 0) diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index c03e9638d..12cabdfba 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -43,7 +43,7 @@ class Detector { * ************************************************/ /* Free the shared memory of this detector and all modules - * belonging to it.*/ + * belonging to it */ void freeSharedMemory(); void loadConfig(const std::string &fname); @@ -327,6 +327,21 @@ class Detector { void setOnChipDAC(defs::dacIndex index, int chipIndex, int value, Positions pos = {}); + /** [Gotthard] signal index is 0 + * [Mythen3] signal index 0-3 for master input, 4-7 master output signals */ + Result + getExternalSignalFlags(int signalIndex, Positions pos = {}) const; + + /** [Gotthard] signal index is 0 + * Options: TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE + * [Mythen3] signal index 0 is master input trigger signal, 1-3 for master + * input gate signals, 4 is busy out signal, 5-7 is master output gate + * signals. + * Options: TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE (for + * master input trigger only), INVERSION_ON, INVERSION_OFF */ + void setExternalSignalFlags(int signalIndex, defs::externalSignalFlag value, + Positions pos = {}); + /************************************************** * * * Acquisition * @@ -750,12 +765,6 @@ class Detector { /** [Eiger] */ void setOverFlowMode(bool value, Positions pos = {}); - /** [Eiger] */ - Result getStoreInRamMode(Positions pos = {}) const; - - /** [Eiger] */ - void setStoreInRamMode(bool value, Positions pos = {}); - /** [Eiger] */ Result getBottom(Positions pos = {}) const; @@ -925,21 +934,6 @@ class Detector { /** [Gotthard] */ Result getExptimeLeft(Positions pos = {}) const; - /** [Gotthard] signal index is 0 - * [Mythen3] signal index 0-3 for master input, 4-7 master output signals */ - Result - getExternalSignalFlags(int signalIndex, Positions pos = {}) const; - - /** [Gotthard] signal index is 0 - * Options: TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE - * [Mythen3] signal index 0 is master input trigger signal, 1-3 for master - * input gate signals, 4 is busy out signal, 5-7 is master output gate - * signals. - * Options: TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE (for - * master input trigger only), INVERSION_ON, INVERSION_OFF */ - void setExternalSignalFlags(int signalIndex, defs::externalSignalFlag value, - Positions pos = {}); - /************************************************** * * * Gotthard2 Specific * @@ -1412,7 +1406,8 @@ class Detector { Result getLastClientIP(Positions pos = {}) const; /** Execute a command on the detector server console */ - void executeCommand(const std::string &value, Positions pos = {}); + Result executeCommand(const std::string &value, + Positions pos = {}); /** [Jungfrau][Mythen3][CTB][Moench] * [Gotthard2] only in continuous mode */ diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index b0d74eb32..bd5284b23 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -2545,8 +2545,8 @@ std::string CmdProxy::ExecuteCommand(int action) { if (args.size() != 1) { WrongNumberOfParameters(1); } - det->executeCommand(args[0], {det_id}); - os << "successful" << '\n'; + auto t = det->executeCommand(args[0], {det_id}); + os << OutString(t) << '\n'; } else { throw sls::RuntimeError("Unknown action"); } diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 0790f7b9b..caadfef47 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -766,7 +766,6 @@ class CmdProxy { {"settingspath", &CmdProxy::settingspath}, {"parallel", &CmdProxy::parallel}, {"overflow", &CmdProxy::overflow}, - {"storeinram", &CmdProxy::storeinram}, {"flippeddatax", &CmdProxy::flippeddatax}, {"trimen", &CmdProxy::TrimEnergies}, {"ratecorr", &CmdProxy::RateCorrection}, @@ -1776,10 +1775,6 @@ class CmdProxy { "[0, 1]\n\t[Eiger] Enable or disable show overflow flag in " "32 bit mode."); - INTEGER_COMMAND(storeinram, getStoreInRamMode, setStoreInRamMode, - StringTo, - "[0, 1]\n\t[Eiger] Enable or disable store in ram mode."); - INTEGER_COMMAND( flippeddatax, getBottom, setBottom, StringTo, "[0, 1]\n\t[Eiger] Top or Bottom Half of Eiger module. 1 is bottom, 0 " diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index ce698f575..002682f5f 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -376,25 +376,25 @@ void Detector::setClockDivider(int clkIndex, int value, Positions pos) { } Result Detector::getHighVoltage(Positions pos) const { - return pimpl->Parallel(&Module::setDAC, pos, -1, defs::HIGH_VOLTAGE, 0); + return pimpl->Parallel(&Module::getDAC, pos, defs::HIGH_VOLTAGE, false); } void Detector::setHighVoltage(int value, Positions pos) { - pimpl->Parallel(&Module::setDAC, pos, value, defs::HIGH_VOLTAGE, 0); + pimpl->Parallel(&Module::setDAC, pos, value, defs::HIGH_VOLTAGE, false); } Result Detector::getPowerChip(Positions pos) const { - return pimpl->Parallel(&Module::powerChip, pos, -1); + return pimpl->Parallel(&Module::getPowerChip, pos); } void Detector::setPowerChip(bool on, Positions pos) { if ((pos.empty() || pos[0] == -1) && on && pimpl->size() > 3) { for (int i = 0; i != pimpl->size(); ++i) { - pimpl->Parallel(&Module::powerChip, {i}, static_cast(on)); + pimpl->Parallel(&Module::setPowerChip, {i}, on); usleep(1000 * 1000); } } else { - pimpl->Parallel(&Module::powerChip, pos, static_cast(on)); + pimpl->Parallel(&Module::setPowerChip, pos, on); } } @@ -486,7 +486,7 @@ std::vector Detector::getDacList() const { Result Detector::getDAC(defs::dacIndex index, bool mV, Positions pos) const { - return pimpl->Parallel(&Module::setDAC, pos, -1, index, mV); + return pimpl->Parallel(&Module::getDAC, pos, index, mV); } void Detector::setDAC(defs::dacIndex index, int value, bool mV, Positions pos) { @@ -503,6 +503,17 @@ void Detector::setOnChipDAC(defs::dacIndex index, int chipIndex, int value, pimpl->Parallel(&Module::setOnChipDAC, pos, index, chipIndex, value); } +Result +Detector::getExternalSignalFlags(int signalIndex, Positions pos) const { + return pimpl->Parallel(&Module::getExternalSignalFlags, pos, signalIndex); +} + +void Detector::setExternalSignalFlags(int signalIndex, + defs::externalSignalFlag value, + Positions pos) { + pimpl->Parallel(&Module::setExternalSignalFlags, pos, signalIndex, value); +} + // Acquisition void Detector::acquire() { pimpl->acquire(); } @@ -690,12 +701,11 @@ Result Detector::printRxConfiguration(Positions pos) const { } Result Detector::getTenGiga(Positions pos) const { - return pimpl->Parallel(&Module::enableTenGigabitEthernet, pos, -1); + return pimpl->Parallel(&Module::getTenGiga, pos); } void Detector::setTenGiga(bool value, Positions pos) { - pimpl->Parallel(&Module::enableTenGigabitEthernet, pos, - static_cast(value)); + pimpl->Parallel(&Module::setTenGiga, pos, value); } Result Detector::getTenGigaFlowControl(Positions pos) const { @@ -780,7 +790,7 @@ void Detector::setRxPort(int port, int module_id) { } Result Detector::getRxFifoDepth(Positions pos) const { - return pimpl->Parallel(&Module::setReceiverFifoDepth, pos, -1); + return pimpl->Parallel(&Module::getReceiverFifoDepth, pos); } void Detector::setRxFifoDepth(int nframes, Positions pos) { @@ -827,11 +837,11 @@ Result Detector::getRxRealUDPSocketBufferSize(Positions pos) const { } Result Detector::getRxLock(Positions pos) { - return pimpl->Parallel(&Module::lockReceiver, pos, -1); + return pimpl->Parallel(&Module::getReceiverLock, pos); } void Detector::setRxLock(bool value, Positions pos) { - pimpl->Parallel(&Module::lockReceiver, pos, static_cast(value)); + pimpl->Parallel(&Module::setReceiverLock, pos, value); } Result Detector::getRxLastClientIP(Positions pos) const { @@ -928,7 +938,7 @@ void Detector::setRxZmqFrequency(int freq, Positions pos) { } Result Detector::getRxZmqTimer(Positions pos) const { - return pimpl->Parallel(&Module::setReceiverStreamingTimer, pos, -1); + return pimpl->Parallel(&Module::getReceiverStreamingTimer, pos); } void Detector::setRxZmqTimer(int time_in_ms, Positions pos) { @@ -1054,14 +1064,6 @@ void Detector::setOverFlowMode(bool value, Positions pos) { pimpl->Parallel(&Module::setOverFlowMode, pos, value); } -Result Detector::getStoreInRamMode(Positions pos) const { - return pimpl->Parallel(&Module::getStoreInRamMode, pos); -} - -void Detector::setStoreInRamMode(bool value, Positions pos) { - pimpl->Parallel(&Module::setStoreInRamMode, pos, value); -} - Result Detector::getBottom(Positions pos) const { return pimpl->Parallel(&Module::getFlippedDataX, pos); } @@ -1131,16 +1133,11 @@ void Detector::setRxPadDeactivatedMode(bool pad, Positions pos) { } Result Detector::getPartialReset(Positions pos) const { - auto res = pimpl->Parallel(&Module::setCounterBit, pos, -1); - Result t(res.size()); - for (unsigned int i = 0; i < res.size(); ++i) { - t[i] = !res[i]; - } - return t; + return pimpl->Parallel(&Module::getCounterBit, pos); } void Detector::setPartialReset(bool value, Positions pos) { - pimpl->Parallel(&Module::setCounterBit, pos, !value); + pimpl->Parallel(&Module::setCounterBit, pos, value); } void Detector::pulsePixel(int n, defs::xy pixel, Positions pos) { @@ -1170,41 +1167,35 @@ void Detector::setQuad(const bool enable) { // Jungfrau Specific Result Detector::getThresholdTemperature(Positions pos) const { - auto res = pimpl->Parallel(&Module::setThresholdTemperature, pos, -1); - for (auto &it : res) { - it /= 1000; - } - return res; + return pimpl->Parallel(&Module::getThresholdTemperature, pos); } void Detector::setThresholdTemperature(int temp, Positions pos) { - pimpl->Parallel(&Module::setThresholdTemperature, pos, temp * 1000); + pimpl->Parallel(&Module::setThresholdTemperature, pos, temp); } Result Detector::getTemperatureControl(Positions pos) const { - return pimpl->Parallel(&Module::setTemperatureControl, pos, -1); + return pimpl->Parallel(&Module::getTemperatureControl, pos); } void Detector::setTemperatureControl(bool enable, Positions pos) { - pimpl->Parallel(&Module::setTemperatureControl, pos, - static_cast(enable)); + pimpl->Parallel(&Module::setTemperatureControl, pos, enable); } Result Detector::getTemperatureEvent(Positions pos) const { - return pimpl->Parallel(&Module::setTemperatureEvent, pos, -1); + return pimpl->Parallel(&Module::getTemperatureEvent, pos); } void Detector::resetTemperatureEvent(Positions pos) { - pimpl->Parallel(&Module::setTemperatureEvent, pos, 0); + pimpl->Parallel(&Module::resetTemperatureEvent, pos); } Result Detector::getAutoCompDisable(Positions pos) const { - return pimpl->Parallel(&Module::setAutoComparatorDisableMode, pos, -1); + return pimpl->Parallel(&Module::getAutoComparatorDisableMode, pos); } void Detector::setAutoCompDisable(bool value, Positions pos) { - pimpl->Parallel(&Module::setAutoComparatorDisableMode, pos, - static_cast(value)); + pimpl->Parallel(&Module::setAutoComparatorDisableMode, pos, value); } Result Detector::getNumberOfAdditionalStorageCells(Positions pos) const { @@ -1216,7 +1207,7 @@ void Detector::setNumberOfAdditionalStorageCells(int value) { } Result Detector::getStorageCellStart(Positions pos) const { - return pimpl->Parallel(&Module::setStorageCellStart, pos, -1); + return pimpl->Parallel(&Module::getStorageCellStart, pos); } void Detector::setStorageCellStart(int cell, Positions pos) { @@ -1252,17 +1243,6 @@ Result Detector::getExptimeLeft(Positions pos) const { return pimpl->Parallel(&Module::getExptimeLeft, pos); } -Result -Detector::getExternalSignalFlags(int signalIndex, Positions pos) const { - return pimpl->Parallel(&Module::getExternalSignalFlags, pos, signalIndex); -} - -void Detector::setExternalSignalFlags(int signalIndex, - defs::externalSignalFlag value, - Positions pos) { - pimpl->Parallel(&Module::setExternalSignalFlags, pos, signalIndex, value); -} - // Gotthard2 Specific Result Detector::getNumberOfBursts(Positions pos) const { @@ -1440,7 +1420,7 @@ Result Detector::getVoltage(defs::dacIndex index, Positions pos) const { default: throw RuntimeError("Unknown Voltage Index"); } - return pimpl->Parallel(&Module::setDAC, pos, -1, index, 1); + return pimpl->Parallel(&Module::getDAC, pos, index, true); } void Detector::setVoltage(defs::dacIndex index, int value, Positions pos) { @@ -1456,7 +1436,7 @@ void Detector::setVoltage(defs::dacIndex index, int value, Positions pos) { default: throw RuntimeError("Unknown Voltage Index"); } - pimpl->Parallel(&Module::setDAC, pos, value, index, 1); + pimpl->Parallel(&Module::setDAC, pos, value, index, true); } Result Detector::getADCEnableMask(Positions pos) const { @@ -1581,11 +1561,11 @@ void Detector::setDigitalIODelay(uint64_t pinMask, int delay, Positions pos) { } Result Detector::getLEDEnable(Positions pos) const { - return pimpl->Parallel(&Module::setLEDEnable, pos, -1); + return pimpl->Parallel(&Module::getLEDEnable, pos); } void Detector::setLEDEnable(bool enable, Positions pos) { - pimpl->Parallel(&Module::setLEDEnable, pos, static_cast(enable)); + pimpl->Parallel(&Module::setLEDEnable, pos, enable); } // Pattern @@ -1597,7 +1577,7 @@ void Detector::savePattern(const std::string &fname) { throw RuntimeError("Could not create file to save pattern"); } // get pattern limits - auto r = pimpl->Parallel(&Module::setPatternLoopAddresses, {}, -1, -1, -1) + auto r = pimpl->Parallel(&Module::getPatternLoopAddresses, {}, -1) .tsquash("Inconsistent pattern limits"); CmdProxy proxy(this); @@ -1629,7 +1609,7 @@ void Detector::setPattern(const std::string &fname, Positions pos) { } Result Detector::getPatternIOControl(Positions pos) const { - return pimpl->Parallel(&Module::setPatternIOControl, pos, -1); + return pimpl->Parallel(&Module::getPatternIOControl, pos); } void Detector::setPatternIOControl(uint64_t word, Positions pos) { @@ -1637,7 +1617,7 @@ void Detector::setPatternIOControl(uint64_t word, Positions pos) { } Result Detector::getPatternClockControl(Positions pos) const { - return pimpl->Parallel(&Module::setPatternClockControl, pos, -1); + return pimpl->Parallel(&Module::getPatternClockControl, pos); } void Detector::setPatternClockControl(uint64_t word, Positions pos) { @@ -1645,7 +1625,7 @@ void Detector::setPatternClockControl(uint64_t word, Positions pos) { } Result Detector::getPatternWord(int addr, Positions pos) { - return pimpl->Parallel(&Module::setPatternWord, pos, addr, -1); + return pimpl->Parallel(&Module::getPatternWord, pos, addr); } void Detector::setPatternWord(int addr, uint64_t word, Positions pos) { @@ -1654,8 +1634,7 @@ void Detector::setPatternWord(int addr, uint64_t word, Positions pos) { Result> Detector::getPatternLoopAddresses(int level, Positions pos) const { - return pimpl->Parallel(&Module::setPatternLoopAddresses, pos, level, -1, - -1); + return pimpl->Parallel(&Module::getPatternLoopAddresses, pos, level); } void Detector::setPatternLoopAddresses(int level, int start, int stop, @@ -1664,7 +1643,7 @@ void Detector::setPatternLoopAddresses(int level, int start, int stop, } Result Detector::getPatternLoopCycles(int level, Positions pos) const { - return pimpl->Parallel(&Module::setPatternLoopCycles, pos, level, -1); + return pimpl->Parallel(&Module::getPatternLoopCycles, pos, level); } void Detector::setPatternLoopCycles(int level, int n, Positions pos) { @@ -1672,7 +1651,7 @@ void Detector::setPatternLoopCycles(int level, int n, Positions pos) { } Result Detector::getPatternWaitAddr(int level, Positions pos) const { - return pimpl->Parallel(&Module::setPatternWaitAddr, pos, level, -1); + return pimpl->Parallel(&Module::getPatternWaitAddr, pos, level); } void Detector::setPatternWaitAddr(int level, int addr, Positions pos) { @@ -1680,7 +1659,7 @@ void Detector::setPatternWaitAddr(int level, int addr, Positions pos) { } Result Detector::getPatternWaitTime(int level, Positions pos) const { - return pimpl->Parallel(&Module::setPatternWaitTime, pos, level, -1); + return pimpl->Parallel(&Module::getPatternWaitTime, pos, level); } void Detector::setPatternWaitTime(int level, uint64_t t, Positions pos) { @@ -1886,19 +1865,20 @@ void Detector::setStopPort(int value, Positions pos) { } Result Detector::getDetectorLock(Positions pos) const { - return pimpl->Parallel(&Module::lockServer, pos, -1); + return pimpl->Parallel(&Module::getLockDetector, pos); } void Detector::setDetectorLock(bool lock, Positions pos) { - pimpl->Parallel(&Module::lockServer, pos, static_cast(lock)); + pimpl->Parallel(&Module::setLockDetector, pos, lock); } Result Detector::getLastClientIP(Positions pos) const { return pimpl->Parallel(&Module::getLastClientIP, pos); } -void Detector::executeCommand(const std::string &value, Positions pos) { - pimpl->Parallel(&Module::execCommand, pos, value); +Result Detector::executeCommand(const std::string &value, + Positions pos) { + return pimpl->Parallel(&Module::execCommand, pos, value); } Result Detector::getNumberOfFramesFromStart(Positions pos) const { diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index b83b72f4e..97aa617ee 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -315,7 +315,7 @@ void DetectorImpl::updateDetectorSize() { << multi_shm()->numberOfChannels.y; for (auto &d : detectors) { - d->updateMultiSize(multi_shm()->numberOfDetector); + d->updateNumberOfDetector(multi_shm()->numberOfDetector); } } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 11e8ac25c..794232b1a 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -20,9 +20,11 @@ namespace sls { -// create shm -Module::Module(detectorType type, int multi_id, int det_id, bool verify) - : detId(det_id), shm(multi_id, det_id) { +// Configuration + +// creating new shm +Module::Module(detectorType type, int det_id, int module_id, bool verify) + : moduleId(module_id), shm(det_id, module_id) { // ensure shared memory was not created before if (shm.IsExisting()) { @@ -32,305 +34,32 @@ Module::Module(detectorType type, int multi_id, int det_id, bool verify) shm.RemoveSharedMemory(); } - initSharedMemory(type, multi_id, verify); + initSharedMemory(type, det_id, verify); } -// pick up from shm -Module::Module(int multi_id, int det_id, bool verify) - : detId(det_id), shm(multi_id, det_id) { +// opening existing shm +Module::Module(int det_id, int module_id, bool verify) + : moduleId(module_id), shm(det_id, module_id) { - // getDetectorType From shm will check if it was already existing - detectorType type = getDetectorTypeFromShm(multi_id, verify); - initSharedMemory(type, multi_id, verify); + // getDetectorType From shm will check if existing + detectorType type = getDetectorTypeFromShm(det_id, verify); + initSharedMemory(type, det_id, verify); } Module::~Module() = default; -bool Module::isFixedPatternSharedMemoryCompatible() { - return (shm()->shmversion >= SLS_SHMAPIVERSION); -} - -void Module::checkDetectorVersionCompatibility() { - int fnum = F_CHECK_VERSION; - int64_t arg = 0; - - // get api version number for detector server - switch (shm()->myDetectorType) { - case EIGER: - arg = APIEIGER; - break; - case JUNGFRAU: - arg = APIJUNGFRAU; - break; - case GOTTHARD: - arg = APIGOTTHARD; - break; - case CHIPTESTBOARD: - arg = APICTB; - break; - case MOENCH: - arg = APIMOENCH; - break; - case MYTHEN3: - arg = APIMYTHEN3; - break; - case GOTTHARD2: - arg = APIGOTTHARD2; - break; - default: - throw NotImplementedError( - "Check version compatibility is not implemented for this detector"); - } - LOG(logDEBUG1) << "Checking version compatibility with detector with value " - << std::hex << arg << std::dec; - - sendToDetector(fnum, arg, nullptr); - sendToDetectorStop(fnum, arg, nullptr); -} - -void Module::checkReceiverVersionCompatibility() { - // TODO! Verify that this works as intended when version don't match - int64_t arg = APIRECEIVER; - LOG(logDEBUG1) << "Checking version compatibility with receiver with value " - << std::hex << arg << std::dec; - sendToReceiver(F_RECEIVER_CHECK_VERSION, arg, nullptr); -} - -int64_t Module::getFirmwareVersion() { - return sendToDetector(F_GET_FIRMWARE_VERSION); -} - -int64_t Module::getDetectorServerVersion() { - return sendToDetector(F_GET_SERVER_VERSION); -} - -int64_t Module::getSerialNumber() { - return sendToDetector(F_GET_SERIAL_NUMBER); -} - -int64_t Module::getReceiverSoftwareVersion() const { - if (shm()->useReceiverFlag) { - return sendToReceiver(F_GET_RECEIVER_VERSION); - } - return -1; -} - -void Module::sendToDetector(int fnum, const void *args, size_t args_size, - void *retval, size_t retval_size) { - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - client.sendCommandThenRead(fnum, args, args_size, retval, retval_size); - client.close(); -} - -template -void Module::sendToDetector(int fnum, const Arg &args, Ret &retval) { - sendToDetector(fnum, &args, sizeof(args), &retval, sizeof(retval)); -} - -template -void Module::sendToDetector(int fnum, const Arg &args, std::nullptr_t) { - sendToDetector(fnum, &args, sizeof(args), nullptr, 0); -} - -template -void Module::sendToDetector(int fnum, std::nullptr_t, Ret &retval) { - sendToDetector(fnum, nullptr, 0, &retval, sizeof(retval)); -} - -void Module::sendToDetector(int fnum) { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << "]"; - sendToDetector(fnum, nullptr, 0, nullptr, 0); -} - -template Ret Module::sendToDetector(int fnum) { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << ", nullptr, 0, " << typeid(Ret).name() << ", " - << sizeof(Ret) << "]"; - Ret retval{}; - sendToDetector(fnum, nullptr, 0, &retval, sizeof(retval)); - LOG(logDEBUG1) << "Got back: " << ToString(retval); - return retval; -} - -template -Ret Module::sendToDetector(int fnum, const Arg &args) { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << ", " << args << ", " << sizeof(args) << ", " - << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; - Ret retval{}; - sendToDetector(fnum, &args, sizeof(args), &retval, sizeof(retval)); - LOG(logDEBUG1) << "Got back: " << ToString(retval); - return retval; -} - -void Module::sendToDetectorStop(int fnum, const void *args, size_t args_size, - void *retval, size_t retval_size) { - static_cast(*this).sendToDetectorStop(fnum, args, args_size, - retval, retval_size); -} - -void Module::sendToDetectorStop(int fnum, const void *args, size_t args_size, - void *retval, size_t retval_size) const { - auto stop = DetectorSocket(shm()->hostname, shm()->stopPort); - stop.sendCommandThenRead(fnum, args, args_size, retval, retval_size); - stop.close(); -} - -template -void Module::sendToDetectorStop(int fnum, const Arg &args, Ret &retval) { - sendToDetectorStop(fnum, &args, sizeof(args), &retval, sizeof(retval)); -} - -template -void Module::sendToDetectorStop(int fnum, const Arg &args, Ret &retval) const { - sendToDetectorStop(fnum, &args, sizeof(args), &retval, sizeof(retval)); -} - -template -void Module::sendToDetectorStop(int fnum, const Arg &args, std::nullptr_t) { - sendToDetectorStop(fnum, &args, sizeof(args), nullptr, 0); -} - -template -void Module::sendToDetectorStop(int fnum, const Arg &args, - std::nullptr_t) const { - sendToDetectorStop(fnum, &args, sizeof(args), nullptr, 0); -} - -template -void Module::sendToDetectorStop(int fnum, std::nullptr_t, Ret &retval) { - sendToDetectorStop(fnum, nullptr, 0, &retval, sizeof(retval)); -} - -template -void Module::sendToDetectorStop(int fnum, std::nullptr_t, Ret &retval) const { - sendToDetectorStop(fnum, nullptr, 0, &retval, sizeof(retval)); -} - -void Module::sendToDetectorStop(int fnum) { - LOG(logDEBUG1) << "Sending to detector stop: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << "]"; - sendToDetectorStop(fnum, nullptr, 0, nullptr, 0); -} - -void Module::sendToDetectorStop(int fnum) const { - sendToDetectorStop(fnum, nullptr, 0, nullptr, 0); -} - -void Module::sendToReceiver(int fnum, const void *args, size_t args_size, - void *retval, size_t retval_size) { - static_cast(*this).sendToReceiver(fnum, args, args_size, - retval, retval_size); -} - -void Module::sendToReceiver(int fnum, const void *args, size_t args_size, - void *retval, size_t retval_size) const { - if (!shm()->useReceiverFlag) { - std::ostringstream oss; - oss << "Set rx_hostname first to use receiver parameters, "; - oss << getFunctionNameFromEnum(static_cast(fnum)); - throw RuntimeError(oss.str()); - } - auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); - receiver.sendCommandThenRead(fnum, args, args_size, retval, retval_size); - receiver.close(); -} - -template -void Module::sendToReceiver(int fnum, const Arg &args, Ret &retval) { - sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); -} - -template -void Module::sendToReceiver(int fnum, const Arg &args, Ret &retval) const { - sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); -} - -template -void Module::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) { - sendToReceiver(fnum, &args, sizeof(args), nullptr, 0); -} - -template -void Module::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const { - sendToReceiver(fnum, &args, sizeof(args), nullptr, 0); -} - -template -void Module::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) { - sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); -} - -template -void Module::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const { - sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); -} - -template Ret Module::sendToReceiver(int fnum) { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << ", nullptr, 0, " << typeid(Ret).name() << ", " - << sizeof(Ret) << "]"; - Ret retval{}; - sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); - LOG(logDEBUG1) << "Got back: " << retval; - return retval; -} - -template Ret Module::sendToReceiver(int fnum) const { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << ", nullptr, 0, " << typeid(Ret).name() << ", " - << sizeof(Ret) << "]"; - Ret retval{}; - sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); - LOG(logDEBUG1) << "Got back: " << ToString(retval); - return retval; -} - -template -Ret Module::sendToReceiver(int fnum, const Arg &args) { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << ", " << args << ", " << sizeof(args) << ", " - << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; - Ret retval{}; - sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); - LOG(logDEBUG1) << "Got back: " << retval; - return retval; -} - -template -Ret Module::sendToReceiver(int fnum, const Arg &args) const { - LOG(logDEBUG1) << "Sending: [" - << getFunctionNameFromEnum(static_cast(fnum)) - << ", " << args << ", " << sizeof(args) << ", " - << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; - Ret retval{}; - sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); - LOG(logDEBUG1) << "Got back: " << retval; - return retval; -} - -// void Module::sendToReceiver(int fnum) { -// sendToReceiver(fnum, nullptr, 0, nullptr, 0); -// } - -// void Module::sendToReceiver(int fnum) const { -// sendToReceiver(fnum, nullptr, 0, nullptr, 0); -// } - void Module::freeSharedMemory() { if (shm.IsExisting()) { shm.RemoveSharedMemory(); } } +bool Module::isFixedPatternSharedMemoryCompatible() { + return (shm()->shmversion >= SLS_SHMAPIVERSION); +} + +std::string Module::getHostname() const { return shm()->hostname; } + void Module::setHostname(const std::string &hostname, const bool initialChecks) { sls::strcpy_safe(shm()->hostname, hostname.c_str()); @@ -351,149 +80,23 @@ void Module::setHostname(const std::string &hostname, } } -std::string Module::getHostname() const { return shm()->hostname; } - -void Module::initSharedMemory(detectorType type, int multi_id, bool verify) { - shm = SharedMemory(multi_id, detId); - if (!shm.IsExisting()) { - shm.CreateSharedMemory(); - initializeDetectorStructure(type); - } else { - shm.OpenSharedMemory(); - if (verify && shm()->shmversion != SLS_SHMVERSION) { - std::ostringstream ss; - ss << "Single shared memory (" << multi_id << "-" << detId - << ":) version mismatch (expected 0x" << std::hex - << SLS_SHMVERSION << " but got 0x" << shm()->shmversion << ")" - << std::dec << ". Clear Shared memory to continue."; - throw SharedMemoryError(ss.str()); - } - } +int64_t Module::getFirmwareVersion() { + return sendToDetector(F_GET_FIRMWARE_VERSION); } -void Module::initializeDetectorStructure(detectorType type) { - shm()->shmversion = SLS_SHMVERSION; - memset(shm()->hostname, 0, MAX_STR_LENGTH); - shm()->myDetectorType = type; - shm()->multiSize.x = 0; - shm()->multiSize.y = 0; - shm()->controlPort = DEFAULT_PORTNO; - shm()->stopPort = DEFAULT_PORTNO + 1; - sls::strcpy_safe(shm()->settingsDir, getenv("HOME")); - sls::strcpy_safe(shm()->rxHostname, "none"); - shm()->rxTCPPort = DEFAULT_PORTNO + 2; - shm()->useReceiverFlag = false; - shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO + - (detId * ((shm()->myDetectorType == EIGER) ? 2 : 1)); - shm()->zmqip = IpAddr{}; - shm()->numUDPInterfaces = 1; - shm()->stoppedFlag = false; - - // get the detector parameters based on type - detParameters parameters{type}; - shm()->nChan.x = parameters.nChanX; - shm()->nChan.y = parameters.nChanY; - shm()->nChip.x = parameters.nChipX; - shm()->nChip.y = parameters.nChipY; - shm()->nDacs = parameters.nDacs; +int64_t Module::getDetectorServerVersion() { + return sendToDetector(F_GET_SERVER_VERSION); } -int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) { - TLogLevel level = logDEBUG1; - LOG(level) << "Sending Module"; - int ts = 0; - int n = 0; - n = client.Send(&(myMod->serialnumber), sizeof(myMod->serialnumber)); - ts += n; - LOG(level) << "Serial number sent. " << n - << " bytes. serialno: " << myMod->serialnumber; - - n = client.Send(&(myMod->nchan), sizeof(myMod->nchan)); - ts += n; - LOG(level) << "nchan sent. " << n << " bytes. nchan: " << myMod->nchan; - - n = client.Send(&(myMod->nchip), sizeof(myMod->nchip)); - ts += n; - LOG(level) << "nchip sent. " << n << " bytes. nchip: " << myMod->nchip; - - n = client.Send(&(myMod->ndac), sizeof(myMod->ndac)); - ts += n; - LOG(level) << "ndac sent. " << n << " bytes. ndac: " << myMod->ndac; - - n = client.Send(&(myMod->reg), sizeof(myMod->reg)); - ts += n; - LOG(level) << "reg sent. " << n << " bytes. reg: " << myMod->reg; - - n = client.Send(&(myMod->iodelay), sizeof(myMod->iodelay)); - ts += n; - LOG(level) << "iodelay sent. " << n - << " bytes. iodelay: " << myMod->iodelay; - - n = client.Send(&(myMod->tau), sizeof(myMod->tau)); - ts += n; - LOG(level) << "tau sent. " << n << " bytes. tau: " << myMod->tau; - - n = client.Send(&(myMod->eV), sizeof(myMod->eV)); - ts += n; - LOG(level) << "ev sent. " << n << " bytes. ev: " << myMod->eV; - - n = client.Send(myMod->dacs, sizeof(int) * (myMod->ndac)); - ts += n; - LOG(level) << "dacs sent. " << n << " bytes"; - - if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) { - n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan)); - ts += n; - LOG(level) << "channels sent. " << n << " bytes"; - } - return ts; +int64_t Module::getSerialNumber() { + return sendToDetector(F_GET_SERIAL_NUMBER); } -int Module::receiveModule(sls_detector_module *myMod, - sls::ClientSocket &client) { - int ts = 0; - ts += client.Receive(&(myMod->serialnumber), sizeof(myMod->serialnumber)); - ts += client.Receive(&(myMod->nchan), sizeof(myMod->nchan)); - ts += client.Receive(&(myMod->nchip), sizeof(myMod->nchip)); - ts += client.Receive(&(myMod->ndac), sizeof(myMod->ndac)); - ts += client.Receive(&(myMod->reg), sizeof(myMod->reg)); - ts += client.Receive(&(myMod->iodelay), sizeof(myMod->iodelay)); - ts += client.Receive(&(myMod->tau), sizeof(myMod->tau)); - ts += client.Receive(&(myMod->eV), sizeof(myMod->eV)); - - ts += client.Receive(myMod->dacs, sizeof(int) * (myMod->ndac)); - LOG(logDEBUG1) << "received dacs of size " << ts; - if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) { - ts += client.Receive(myMod->chanregs, sizeof(int) * (myMod->nchan)); - LOG(logDEBUG1) << " nchan= " << myMod->nchan - << " nchip= " << myMod->nchip - << "received chans of size " << ts; +int64_t Module::getReceiverSoftwareVersion() const { + if (shm()->useReceiverFlag) { + return sendToReceiver(F_GET_RECEIVER_VERSION); } - LOG(logDEBUG1) << "received module of size " << ts << " register " - << myMod->reg; - return ts; -} - -slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int multi_id, - bool verify) { - if (!shm.IsExisting()) { - throw SharedMemoryError("Shared memory " + shm.GetName() + - "does not exist.\n Corrupted Multi Shared " - "memory. Please free shared memory."); - } - - shm.OpenSharedMemory(); - if (verify && shm()->shmversion != SLS_SHMVERSION) { - std::ostringstream ss; - ss << "Single shared memory (" << multi_id << "-" << detId - << ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION - << " but got 0x" << shm()->shmversion << ")" << std::dec - << ". Clear Shared memory to continue."; - shm.UnmapSharedMemory(); - throw SharedMemoryError(ss.str()); - } - auto type = shm()->myDetectorType; - return type; + return -1; } // static function @@ -518,11 +121,8 @@ slsDetectorDefs::detectorType Module::getDetectorType() const { void Module::updateNumberOfChannels() { if (shm()->myDetectorType == CHIPTESTBOARD || shm()->myDetectorType == MOENCH) { - LOG(logDEBUG1) << "Updating number of channels"; std::array retvals{}; sendToDetector(F_GET_NUM_CHANNELS, nullptr, retvals); - LOG(logDEBUG1) << "Number of channels retval: [" << retvals[0] << ", " - << retvals[1] << ']'; shm()->nChan.x = retvals[0]; shm()->nChan.y = retvals[1]; } @@ -535,182 +135,12 @@ slsDetectorDefs::xy Module::getNumberOfChannels() const { return coord; } -bool Module::getQuad() { return sendToDetector(F_GET_QUAD) != 0; } - -void Module::setQuad(const bool enable) { - int value = enable ? 1 : 0; - LOG(logDEBUG1) << "Setting Quad type to " << value; - sendToDetector(F_SET_QUAD, value, nullptr); - LOG(logDEBUG1) << "Setting Quad type to " << value << " in Receiver"; - if (shm()->useReceiverFlag) { - sendToReceiver(F_SET_RECEIVER_QUAD, value, nullptr); - } -} - -void Module::setReadNLines(const int value) { - LOG(logDEBUG1) << "Setting read n lines to " << value; - sendToDetector(F_SET_READ_N_LINES, value, nullptr); - LOG(logDEBUG1) << "Setting read n lines to " << value << " in Receiver"; - if (shm()->useReceiverFlag) { - sendToReceiver(F_SET_RECEIVER_READ_N_LINES, value, nullptr); - } -} - -int Module::getReadNLines() { return sendToDetector(F_GET_READ_N_LINES); } - -void Module::updateMultiSize(slsDetectorDefs::xy det) { - shm()->multiSize = det; - int args[2] = {shm()->multiSize.y, detId}; +void Module::updateNumberOfDetector(slsDetectorDefs::xy det) { + shm()->numberOfDetector = det; + int args[2] = {shm()->numberOfDetector.y, moduleId}; sendToDetector(F_SET_POSITION, args, nullptr); } -int Module::setControlPort(int port_number) { - int retval = -1; - LOG(logDEBUG1) << "Setting control port to " << port_number; - if (port_number >= 0 && port_number != shm()->controlPort) { - if (strlen(shm()->hostname) > 0) { - sendToDetector(F_SET_PORT, port_number, retval); - shm()->controlPort = retval; - LOG(logDEBUG1) << "Control port: " << retval; - } else { - shm()->controlPort = port_number; - } - } - return shm()->controlPort; -} - -int Module::setStopPort(int port_number) { - int retval = -1; - LOG(logDEBUG1) << "Setting stop port to " << port_number; - if (port_number >= 0 && port_number != shm()->stopPort) { - if (strlen(shm()->hostname) > 0) { - sendToDetectorStop(F_SET_PORT, port_number, retval); - shm()->stopPort = retval; - LOG(logDEBUG1) << "Stop port: " << retval; - } else { - shm()->stopPort = port_number; - } - } - return shm()->stopPort; -} - -int Module::setReceiverPort(int port_number) { - LOG(logDEBUG1) << "Setting reciever port to " << port_number; - if (port_number >= 0 && port_number != shm()->rxTCPPort) { - if (shm()->useReceiverFlag) { - int retval = -1; - sendToReceiver(F_SET_RECEIVER_PORT, port_number, retval); - shm()->rxTCPPort = retval; - LOG(logDEBUG1) << "Receiver port: " << retval; - - } else { - shm()->rxTCPPort = port_number; - } - } - return shm()->rxTCPPort; -} - -int Module::getReceiverPort() const { return shm()->rxTCPPort; } - -int Module::getControlPort() const { return shm()->controlPort; } - -int Module::getStopPort() const { return shm()->stopPort; } - -bool Module::lockServer(int lock) { - return sendToDetector(F_LOCK_SERVER, lock) != 0; -} - -sls::IpAddr Module::getLastClientIP() { - return sendToDetector(F_GET_LAST_CLIENT_IP); -} - -void Module::exitServer() { sendToDetector(F_EXIT_SERVER); } - -void Module::execCommand(const std::string &cmd) { - char arg[MAX_STR_LENGTH]{}; - char retval[MAX_STR_LENGTH]{}; - sls::strcpy_safe(arg, cmd.c_str()); - LOG(logDEBUG1) << "Sending command to detector " << arg; - sendToDetector(F_EXEC_COMMAND, arg, retval); - if (strlen(retval) != 0U) { - LOG(logINFO) << "Detector " << detId << " returned:\n" << retval; - } -} - -std::vector Module::getConfigFileCommands() { - std::vector base{"hostname", "port", "stopport", - "settingsdir", "fpath", "lock", - "zmqport", "rx_zmqport", "zmqip", - "rx_zmqip", "rx_tcpport"}; - - switch (shm()->myDetectorType) { - case GOTTHARD: - base.emplace_back("detectormac"); - base.emplace_back("detectorip"); - base.emplace_back("rx_udpport"); - base.emplace_back("rx_udpip"); - base.emplace_back("rx_udpmac"); - base.emplace_back("extsig"); - break; - case EIGER: - base.emplace_back("detectormac"); - base.emplace_back("detectorip"); - base.emplace_back("rx_udpport"); - base.emplace_back("rx_udpport2"); - base.emplace_back("rx_udpip"); - base.emplace_back("rx_udpmac"); - base.emplace_back("trimen"); - base.emplace_back("iodelay"); - base.emplace_back("tengiga"); - break; - case JUNGFRAU: - base.emplace_back("detectormac"); - base.emplace_back("detectormac2"); - base.emplace_back("detectorip"); - base.emplace_back("detectorip2"); - base.emplace_back("rx_udpport"); - base.emplace_back("rx_udpport2"); - base.emplace_back("rx_udpip"); - base.emplace_back("rx_udpip2"); - base.emplace_back("rx_udpmac"); - base.emplace_back("rx_udpmac2"); - base.emplace_back("powerchip"); - break; - case CHIPTESTBOARD: - base.emplace_back("detectormac"); - base.emplace_back("detectorip"); - base.emplace_back("rx_udpport"); - base.emplace_back("rx_udpip"); - base.emplace_back("rx_udpmac"); - break; - case MOENCH: - base.emplace_back("detectormac"); - base.emplace_back("detectorip"); - base.emplace_back("rx_udpport"); - base.emplace_back("rx_udpip"); - base.emplace_back("rx_udpmac"); - break; - default: - throw RuntimeError( - "Write configuration file called with unknown detector: " + - std::to_string(shm()->myDetectorType)); - } - - base.emplace_back("vhighvoltage"); - base.emplace_back("rx_hostname"); - base.emplace_back("r_readfreq"); - base.emplace_back("rx_udpsocksize"); - base.emplace_back("rx_realudpsocksize"); - - std::vector commands; - for (const auto &cmd : base) { - std::ostringstream os; - os << detId << ':' << cmd; - commands.emplace_back(os.str()); - } - return commands; -} - slsDetectorDefs::detectorSettings Module::getSettings() { auto r = sendToDetector(F_SET_SETTINGS, -1); return static_cast(r); @@ -721,142 +151,7 @@ void Module::setSettings(detectorSettings isettings) { throw RuntimeError( "Cannot set settings for Eiger. Use threshold energy."); } - int arg = static_cast(isettings); - int retval = -1; - LOG(logDEBUG1) << "Setting settings to " << arg; - sendToDetector(F_SET_SETTINGS, arg, retval); -} - -int Module::getThresholdEnergy() { - // moench - get threshold energy from processor (due to different clients, - // diff shm) - if (shm()->myDetectorType == MOENCH) { - // get json from rxr, parse for threshold and update shm - getAdditionalJsonHeader(); - std::string result = getAdditionalJsonParameter("threshold"); - // convert to integer - try { - return std::stoi(result); - } - // not found or cannot scan integer - catch (...) { - return -1; - } - } - return sendToDetector(F_GET_THRESHOLD_ENERGY); -} - -void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, int tb) { - // check as there is client processing - if (shm()->myDetectorType == EIGER) { - setThresholdEnergyAndSettings(e_eV, isettings, tb); - } - - // moench - send threshold energy to processor - else if (shm()->myDetectorType == MOENCH) { - setAdditionalJsonParameter("threshold", std::to_string(e_eV)); - } - - else { - throw RuntimeError( - "Set threshold energy not implemented for this detector"); - } -} - -void Module::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, - int tb) { - - // if settings provided, use that, else use the shared memory variable - detectorSettings is = - ((isettings != GET_SETTINGS) ? isettings : getSettings()); - - // verify e_eV exists in trimEneregies[] - if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) || - (e_eV > shm()->trimEnergies.back())) { - throw RuntimeError("This energy " + std::to_string(e_eV) + - " not defined for this module!"); - } - - bool interpolate = - std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(), - [e_eV](const int &e) { return e != e_eV; }); - - sls_detector_module myMod{shm()->myDetectorType}; - - if (!interpolate) { - std::string settingsfname = getTrimbitFilename(is, e_eV); - LOG(logDEBUG1) << "Settings File is " << settingsfname; - myMod = readSettingsFile(settingsfname, tb); - } else { - // find the trim values - int trim1 = -1, trim2 = -1; - for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) { - if (e_eV < shm()->trimEnergies[i]) { - trim2 = shm()->trimEnergies[i]; - trim1 = shm()->trimEnergies[i - 1]; - break; - } - } - std::string settingsfname1 = getTrimbitFilename(is, trim1); - std::string settingsfname2 = getTrimbitFilename(is, trim2); - LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and " - << settingsfname2; - auto myMod1 = readSettingsFile(settingsfname1, tb); - auto myMod2 = readSettingsFile(settingsfname2, tb); - if (myMod1.iodelay != myMod2.iodelay) { - throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not " - "match between files"); - } - myMod = interpolateTrim(&myMod1, &myMod2, e_eV, trim1, trim2, tb); - myMod.iodelay = myMod1.iodelay; - myMod.tau = - linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau); - } - - myMod.reg = is; - myMod.eV = e_eV; - setModule(myMod, tb); - if (getSettings() != is) { - throw RuntimeError("setThresholdEnergyAndSettings: Could not set " - "settings in detector"); - } -} - -std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) { - std::string ssettings; - switch (s) { - case STANDARD: - ssettings = "/standard"; - break; - case HIGHGAIN: - ssettings = "/highgain"; - break; - case LOWGAIN: - ssettings = "/lowgain"; - break; - case VERYHIGHGAIN: - ssettings = "/veryhighgain"; - break; - case VERYLOWGAIN: - ssettings = "/verylowgain"; - break; - default: - std::ostringstream ss; - ss << "Unknown settings " << ToString(s) << " for this detector!"; - throw RuntimeError(ss.str()); - } - std::ostringstream ostfn; - ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV" - << "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec - << getSerialNumber() << std::setbase(10); - return ostfn.str(); -} - -std::string Module::getSettingsDir() { return std::string(shm()->settingsDir); } - -std::string Module::setSettingsDir(const std::string &dir) { - sls::strcpy_safe(shm()->settingsDir, dir.c_str()); - return shm()->settingsDir; + sendToDetector(F_SET_SETTINGS, static_cast(isettings)); } void Module::loadSettingsFile(const std::string &fname) { @@ -872,35 +167,213 @@ void Module::loadSettingsFile(const std::string &fname) { ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec << getSerialNumber(); } + } else { + throw RuntimeError("not implemented for this detector"); } fn = ostfn.str(); auto myMod = readSettingsFile(fn); setModule(myMod); } -void Module::saveSettingsFile(const std::string &fname) { - std::string fn = fname; - std::ostringstream ostfn; - ostfn << fname; - - // find specific file if it has detid in file name (.snxxx) - if (shm()->myDetectorType == EIGER) { - ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec - << getSerialNumber(); - } - fn = ostfn.str(); - sls_detector_module myMod = getModule(); - writeSettingsFile(fn, myMod); +int Module::getAllTrimbits() { + return sendToDetector(F_SET_ALL_TRIMBITS, -1); } -slsDetectorDefs::runStatus Module::getRunStatus() const { - runStatus retval = ERROR; - LOG(logDEBUG1) << "Getting status"; - sendToDetectorStop(F_GET_RUN_STATUS, nullptr, retval); - LOG(logDEBUG1) << "Detector status: " << ToString(retval); +void Module::setAllTrimbits(int val) { + sendToDetector(F_SET_ALL_TRIMBITS, val); +} + +int64_t Module::getNumberOfFrames() { + return sendToDetector(F_GET_NUM_FRAMES); +} + +void Module::setNumberOfFrames(int64_t value) { + sendToDetector(F_SET_NUM_FRAMES, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr); + } +} + +int64_t Module::getNumberOfTriggers() { + return sendToDetector(F_GET_NUM_TRIGGERS); +} + +void Module::setNumberOfTriggers(int64_t value) { + sendToDetector(F_SET_NUM_TRIGGERS, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr); + } +} + +int64_t Module::getExptime(int gateIndex) { + return sendToDetector(F_GET_EXPTIME, gateIndex); +} + +void Module::setExptime(int gateIndex, int64_t value) { + int64_t prevVal = value; + if (shm()->myDetectorType == EIGER) { + prevVal = getExptime(-1); + } + int64_t args[]{static_cast(gateIndex), value}; + sendToDetector(F_SET_EXPTIME, args, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_EXPTIME, args, nullptr); + } + if (prevVal != value) { + updateRateCorrection(); + } +} + +int64_t Module::getPeriod() { return sendToDetector(F_GET_PERIOD); } + +void Module::setPeriod(int64_t value) { + sendToDetector(F_SET_PERIOD, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_PERIOD, value, nullptr); + } +} + +int64_t Module::getDelayAfterTrigger() { + return sendToDetector(F_GET_DELAY_AFTER_TRIGGER); +} + +void Module::setDelayAfterTrigger(int64_t value) { + sendToDetector(F_SET_DELAY_AFTER_TRIGGER, value, nullptr); +} + +int64_t Module::getNumberOfFramesLeft() const { + int64_t retval = -1; + sendToDetectorStop(F_GET_FRAMES_LEFT, nullptr, retval); return retval; } +int64_t Module::getNumberOfTriggersLeft() const { + int64_t retval = -1; + sendToDetectorStop(F_GET_TRIGGERS_LEFT, nullptr, retval); + return retval; +} + +int64_t Module::getDelayAfterTriggerLeft() const { + int64_t retval = -1; + sendToDetectorStop(F_GET_DELAY_AFTER_TRIGGER_LEFT, nullptr, retval); + return retval; +} + +int64_t Module::getPeriodLeft() const { + int64_t retval = -1; + sendToDetectorStop(F_GET_PERIOD_LEFT, nullptr, retval); + return retval; +} + +slsDetectorDefs::timingMode Module::getTimingMode() { + return sendToDetector(F_SET_TIMING_MODE, -1); +} + +void Module::setTimingMode(timingMode value) { + timingMode retval = GET_TIMING_MODE; + sendToDetector(F_SET_TIMING_MODE, static_cast(value), retval); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_TIMING_MODE, value, nullptr); + } +} + +int Module::getClockDivider(int clkIndex) { + return sendToDetector(F_GET_CLOCK_DIVIDER, clkIndex); +} + +void Module::setClockDivider(int clkIndex, int value) { + int args[]{clkIndex, value}; + sendToDetector(F_SET_CLOCK_DIVIDER, args, nullptr); +} + +int Module::getClockPhase(int clkIndex, bool inDegrees) { + int args[]{clkIndex, static_cast(inDegrees)}; + return sendToDetector(F_GET_CLOCK_PHASE, args); +} + +void Module::setClockPhase(int clkIndex, int value, bool inDegrees) { + int args[]{clkIndex, value, static_cast(inDegrees)}; + sendToDetector(F_SET_CLOCK_PHASE, args, nullptr); +} + +int Module::getMaxClockPhaseShift(int clkIndex) { + return sendToDetector(F_GET_MAX_CLOCK_PHASE_SHIFT, clkIndex); +} + +int Module::getClockFrequency(int clkIndex) { + return sendToDetector(F_GET_CLOCK_FREQUENCY, clkIndex); +} + +void Module::setClockFrequency(int clkIndex, int value) { + int args[]{clkIndex, value}; + sendToDetector(F_SET_CLOCK_FREQUENCY, args, nullptr); +} + +int Module::getDAC(dacIndex index, bool mV) { + int args[]{static_cast(index), static_cast(mV), -1}; + return sendToDetector(F_SET_DAC, args); +} + +void Module::setDAC(int val, dacIndex index, bool mV) { + int args[]{static_cast(index), static_cast(mV), val}; + sendToDetector(F_SET_DAC, args); +} + +bool Module::getPowerChip() { + int arg = -1; + return sendToDetector(F_POWER_CHIP, arg); +} + +void Module::setPowerChip(bool on) { + sendToDetector(F_POWER_CHIP, static_cast(on)); +} + +int Module::getImageTestMode() { + return sendToDetector(F_GET_IMAGE_TEST_MODE); +} + +void Module::setImageTestMode(const int value) { + sendToDetector(F_SET_IMAGE_TEST_MODE, value, nullptr); +} + +int Module::getADC(dacIndex index) { + return sendToDetector(F_GET_ADC, static_cast(index)); +} + +int Module::getOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex) { + int args[]{static_cast(index), chipIndex}; + return sendToDetector(F_GET_ON_CHIP_DAC, args); +} + +void Module::setOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex, + int value) { + int args[]{static_cast(index), chipIndex, value}; + sendToDetector(F_SET_ON_CHIP_DAC, args, nullptr); +} + +slsDetectorDefs::externalSignalFlag +Module::getExternalSignalFlags(int signalIndex) { + return sendToDetector( + F_GET_EXTERNAL_SIGNAL_FLAG, signalIndex); +} + +void Module::setExternalSignalFlags(int signalIndex, externalSignalFlag type) { + int args[]{signalIndex, static_cast(type)}; + sendToDetector(F_SET_EXTERNAL_SIGNAL_FLAG, args, nullptr); +} + +// Acquisition + +void Module::startReceiver() { + shm()->stoppedFlag = false; + sendToReceiver(F_START_RECEIVER, nullptr, nullptr); +} + +void Module::stopReceiver() { + int arg = static_cast(shm()->stoppedFlag); + sendToReceiver(F_STOP_RECEIVER, arg, nullptr); +} + void Module::prepareAcquisition() { sendToDetector(F_PREPARE_ACQUISITION); } void Module::startAcquisition() { @@ -917,502 +390,310 @@ void Module::stopAcquisition() { s = getRunStatus(); r = getReceiverStatus(); } - LOG(logDEBUG1) << "Stopping Acquisition"; sendToDetectorStop(F_STOP_ACQUISITION); shm()->stoppedFlag = true; - LOG(logDEBUG1) << "Stopping Acquisition successful"; // if rxr streaming and acquisition finished, restream dummy stop packet if (zmqstreaming && (s == IDLE) && (r == IDLE)) { restreamStopFromReceiver(); } } -void Module::sendSoftwareTrigger() { sendToDetectorStop(F_SOFTWARE_TRIGGER); } - void Module::startAndReadAll() { shm()->stoppedFlag = false; sendToDetector(F_START_AND_READ_ALL); } -void Module::startReadOut() { sendToDetector(F_START_READOUT); } +slsDetectorDefs::runStatus Module::getRunStatus() const { + return sendToDetectorStop(F_GET_RUN_STATUS); +} -void Module::readAll() { sendToDetector(F_READ_ALL); } +slsDetectorDefs::runStatus Module::getReceiverStatus() const { + return sendToReceiver(F_GET_RECEIVER_STATUS); +} -void Module::setStartingFrameNumber(uint64_t value) { - LOG(logDEBUG1) << "Setting starting frame number to " << value; - sendToDetector(F_SET_STARTING_FRAME_NUMBER, value, nullptr); +int Module::getReceiverProgress() const { + return sendToReceiver(F_GET_RECEIVER_PROGRESS); +} + +int64_t Module::getFramesCaughtByReceiver() const { + return sendToReceiver(F_GET_RECEIVER_FRAMES_CAUGHT); +} + +std::vector Module::getNumMissingPackets() const { + // TODO!(Erik) Refactor + LOG(logDEBUG1) << "Getting num missing packets"; + if (shm()->useReceiverFlag) { + int fnum = F_GET_NUM_MISSING_PACKETS; + int ret = FAIL; + auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + client.Send(&fnum, sizeof(fnum)); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + char mess[MAX_STR_LENGTH]{}; + client.Receive(mess, MAX_STR_LENGTH); + throw RuntimeError("Receiver " + std::to_string(moduleId) + + " returned error: " + std::string(mess)); + } else { + int nports = -1; + client.Receive(&nports, sizeof(nports)); + uint64_t mp[nports]; + memset(mp, 0, sizeof(mp)); + client.Receive(mp, sizeof(mp)); + std::vector retval(mp, mp + nports); + LOG(logDEBUG1) << "Missing packets of Receiver" << moduleId << ": " + << sls::ToString(retval); + return retval; + } + } + throw RuntimeError("No receiver to get missing packets."); } uint64_t Module::getStartingFrameNumber() { return sendToDetector(F_GET_STARTING_FRAME_NUMBER); } -int64_t Module::getNumberOfFrames() { - return sendToDetector(F_GET_NUM_FRAMES); +void Module::setStartingFrameNumber(uint64_t value) { + sendToDetector(F_SET_STARTING_FRAME_NUMBER, value, nullptr); } -void Module::setNumberOfFrames(int64_t value) { - LOG(logDEBUG1) << "Setting number of frames to " << value; - sendToDetector(F_SET_NUM_FRAMES, value, nullptr); +void Module::sendSoftwareTrigger() { sendToDetectorStop(F_SOFTWARE_TRIGGER); } + +// Network Configuration (Detector<->Receiver) + +int Module::getNumberofUDPInterfacesFromShm() { + return shm()->numUDPInterfaces; +} + +int Module::getNumberofUDPInterfaces() { + shm()->numUDPInterfaces = sendToDetector(F_GET_NUM_INTERFACES); + return shm()->numUDPInterfaces; +} + +void Module::setNumberofUDPInterfaces(int n) { + sendToDetector(F_SET_NUM_INTERFACES, n, nullptr); + shm()->numUDPInterfaces = n; if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of frames to Receiver: " << value; - sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr); + sendToReceiver(F_SET_RECEIVER_NUM_INTERFACES, n, nullptr); } } -int64_t Module::getNumberOfTriggers() { - return sendToDetector(F_GET_NUM_TRIGGERS); +int Module::getSelectedUDPInterface() { + return sendToDetector(F_GET_INTERFACE_SEL); } -void Module::setNumberOfTriggers(int64_t value) { - LOG(logDEBUG1) << "Setting number of triggers to " << value; - sendToDetector(F_SET_NUM_TRIGGERS, value, nullptr); +void Module::selectUDPInterface(int n) { + sendToDetector(F_SET_INTERFACE_SEL, n, nullptr); +} + +sls::IpAddr Module::getSourceUDPIP() { + return sendToDetector(F_GET_SOURCE_UDP_IP); +} + +void Module::setSourceUDPIP(const IpAddr ip) { + if (ip == 0) { + throw RuntimeError("Invalid source udp ip address"); + } + sendToDetector(F_SET_SOURCE_UDP_IP, ip, nullptr); +} + +sls::IpAddr Module::getSourceUDPIP2() { + return sendToDetector(F_GET_SOURCE_UDP_IP2); +} + +void Module::setSourceUDPIP2(const IpAddr ip) { + if (ip == 0) { + throw RuntimeError("Invalid source udp ip address2"); + } + sendToDetector(F_SET_SOURCE_UDP_IP2, ip, nullptr); +} + +sls::MacAddr Module::getSourceUDPMAC() { + return sendToDetector(F_GET_SOURCE_UDP_MAC); +} + +void Module::setSourceUDPMAC(const sls::MacAddr mac) { + if (mac == 0) { + throw RuntimeError("Invalid source udp mac address"); + } + sendToDetector(F_SET_SOURCE_UDP_MAC, mac, nullptr); +} + +sls::MacAddr Module::getSourceUDPMAC2() { + return sendToDetector(F_GET_SOURCE_UDP_MAC2); +} + +void Module::setSourceUDPMAC2(const sls::MacAddr mac) { + if (mac == 0) { + throw RuntimeError("Invalid source udp mac address2"); + } + sendToDetector(F_SET_SOURCE_UDP_MAC2, mac, nullptr); +} + +sls::IpAddr Module::getDestinationUDPIP() { + return sendToDetector(F_GET_DEST_UDP_IP); +} + +void Module::setDestinationUDPIP(const IpAddr ip) { + if (ip == 0) { + throw RuntimeError("Invalid destination udp ip address"); + } + sendToDetector(F_SET_DEST_UDP_IP, ip, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of triggers to Receiver: " << value; - sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr); + sls::MacAddr retval(0LU); + sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval); + LOG(logINFO) << "Setting destination udp mac of detector " << moduleId + << " to " << retval; + sendToDetector(F_SET_DEST_UDP_MAC, retval, nullptr); } } -int64_t Module::getNumberOfBursts() { - return sendToDetector(F_GET_NUM_BURSTS); +sls::IpAddr Module::getDestinationUDPIP2() { + return sendToDetector(F_GET_DEST_UDP_IP2); } -void Module::setNumberOfBursts(int64_t value) { - LOG(logDEBUG1) << "Setting number of bursts to " << value; - sendToDetector(F_SET_NUM_BURSTS, value, nullptr); +void Module::setDestinationUDPIP2(const IpAddr ip) { + LOG(logDEBUG1) << "Setting destination udp ip2 to " << ip; + if (ip == 0) { + throw RuntimeError("Invalid destination udp ip address2"); + } + + sendToDetector(F_SET_DEST_UDP_IP2, ip, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of bursts to Receiver: " << value; - sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr); + sls::MacAddr retval(0LU); + sendToReceiver(F_SET_RECEIVER_UDP_IP2, ip, retval); + LOG(logINFO) << "Setting destination udp mac2 of detector " << moduleId + << " to " << retval; + sendToDetector(F_SET_DEST_UDP_MAC2, retval, nullptr); } } -int Module::getNumberOfAdditionalStorageCells() { - return sendToDetector(F_GET_NUM_ADDITIONAL_STORAGE_CELLS); +sls::MacAddr Module::getDestinationUDPMAC() { + return sendToDetector(F_GET_DEST_UDP_MAC); } -void Module::setNumberOfAdditionalStorageCells(int value) { - LOG(logDEBUG1) << "Setting number of storage cells to " << value; - sendToDetector(F_SET_NUM_ADDITIONAL_STORAGE_CELLS, value, nullptr); +void Module::setDestinationUDPMAC(const MacAddr mac) { + if (mac == 0) { + throw RuntimeError("Invalid destination udp mac address"); + } + sendToDetector(F_SET_DEST_UDP_MAC, mac, nullptr); } -int Module::getNumberOfAnalogSamples() { - return sendToDetector(F_GET_NUM_ANALOG_SAMPLES); +sls::MacAddr Module::getDestinationUDPMAC2() { + return sendToDetector(F_GET_DEST_UDP_MAC2); } -void Module::setNumberOfAnalogSamples(int value) { - LOG(logDEBUG1) << "Setting number of analog samples to " << value; - sendToDetector(F_SET_NUM_ANALOG_SAMPLES, value, nullptr); - // update #nchan, as it depends on #samples, adcmask - updateNumberOfChannels(); +void Module::setDestinationUDPMAC2(const MacAddr mac) { + if (mac == 0) { + throw RuntimeError("Invalid desinaion udp mac address2"); + } + sendToDetector(F_SET_DEST_UDP_MAC2, mac, nullptr); +} + +int Module::getDestinationUDPPort() { + return sendToDetector(F_GET_DEST_UDP_PORT); +} + +void Module::setDestinationUDPPort(const int port) { + sendToDetector(F_SET_DEST_UDP_PORT, port, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of analog samples to Receiver: " - << value; - sendToReceiver(F_RECEIVER_SET_NUM_ANALOG_SAMPLES, value, nullptr); + sendToReceiver(F_SET_RECEIVER_UDP_PORT, port, nullptr); } } -int Module::getNumberOfDigitalSamples() { - return sendToDetector(F_GET_NUM_DIGITAL_SAMPLES); +int Module::getDestinationUDPPort2() { + return sendToDetector(F_GET_DEST_UDP_PORT2); } -void Module::setNumberOfDigitalSamples(int value) { - LOG(logDEBUG1) << "Setting number of digital samples to " << value; - sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr); - // update #nchan, as it depends on #samples, adcmask - updateNumberOfChannels(); +void Module::setDestinationUDPPort2(const int port) { + sendToDetector(F_SET_DEST_UDP_PORT2, port, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " - << value; - sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr); + sendToReceiver(F_SET_RECEIVER_UDP_PORT2, port, nullptr); } } -int Module::getNumberOfGates() { return sendToDetector(F_GET_NUM_GATES); } +std::string Module::printReceiverConfiguration() { + std::ostringstream os; + os << "\n\nDetector " << moduleId << "\nReceiver Hostname:\t" + << getReceiverHostname(); -void Module::setNumberOfGates(int value) { - LOG(logDEBUG1) << "Setting number of gates to " << value; - sendToDetector(F_SET_NUM_GATES, value, nullptr); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of gates to Receiver: " << value; - sendToReceiver(F_SET_RECEIVER_NUM_GATES, value, nullptr); - } -} - -int64_t Module::getExptime(int gateIndex) { - return sendToDetector(F_GET_EXPTIME, gateIndex); -} - -void Module::setExptime(int gateIndex, int64_t value) { - int64_t prevVal = value; - if (shm()->myDetectorType == EIGER) { - prevVal = getExptime(-1); - } - LOG(logDEBUG1) << "Setting exptime to " << value - << "ns (gateindex: " << gateIndex << ")"; - int64_t args[]{static_cast(gateIndex), value}; - sendToDetector(F_SET_EXPTIME, args, nullptr); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending exptime to Receiver: " << value; - sendToReceiver(F_RECEIVER_SET_EXPTIME, args, nullptr); - } - if (prevVal != value) { - updateRateCorrection(); - } -} - -std::array Module::getExptimeForAllGates() { - static_assert(sizeof(time::ns) == 8, "ns needs to be 64bit"); - return sendToDetector>(F_GET_EXPTIME_ALL_GATES); -} - -int64_t Module::getGateDelay(int gateIndex) { - return sendToDetector(F_GET_GATE_DELAY, gateIndex); -} - -void Module::setGateDelay(int gateIndex, int64_t value) { - LOG(logDEBUG1) << "Setting gate delay to " << value - << "ns (gateindex: " << gateIndex << ")"; - int64_t args[]{static_cast(gateIndex), value}; - sendToDetector(F_SET_GATE_DELAY, args, nullptr); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending gate delay to Receiver: " << value; - sendToReceiver(F_SET_RECEIVER_GATE_DELAY, args, nullptr); - } -} - -std::array Module::getGateDelayForAllGates() { - static_assert(sizeof(time::ns) == 8, "ns needs to be 64bit"); - return sendToDetector>(F_GET_GATE_DELAY_ALL_GATES); -} - -int64_t Module::getPeriod() { return sendToDetector(F_GET_PERIOD); } - -void Module::setPeriod(int64_t value) { - LOG(logDEBUG1) << "Setting period to " << value << "ns"; - sendToDetector(F_SET_PERIOD, value, nullptr); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending period to Receiver: " << value; - sendToReceiver(F_RECEIVER_SET_PERIOD, value, nullptr); - } -} - -int64_t Module::getDelayAfterTrigger() { - return sendToDetector(F_GET_DELAY_AFTER_TRIGGER); -} - -void Module::setDelayAfterTrigger(int64_t value) { - LOG(logDEBUG1) << "Setting delay after trigger to " << value << "ns"; - sendToDetector(F_SET_DELAY_AFTER_TRIGGER, value, nullptr); -} - -int64_t Module::getBurstPeriod() { - return sendToDetector(F_GET_BURST_PERIOD); -} - -void Module::setBurstPeriod(int64_t value) { - LOG(logDEBUG1) << "Setting burst period to " << value << "ns"; - sendToDetector(F_SET_BURST_PERIOD, value, nullptr); -} - -int64_t Module::getSubExptime() { - return sendToDetector(F_GET_SUB_EXPTIME); -} - -void Module::setSubExptime(int64_t value) { - int64_t prevVal = value; - if (shm()->myDetectorType == EIGER) { - prevVal = getSubExptime(); - } - LOG(logDEBUG1) << "Setting sub exptime to " << value << "ns"; - sendToDetector(F_SET_SUB_EXPTIME, value, nullptr); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending sub exptime to Receiver: " << value; - sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr); - } - if (prevVal != value) { - updateRateCorrection(); - } -} - -int64_t Module::getSubDeadTime() { - return sendToDetector(F_GET_SUB_DEADTIME); -} - -void Module::setSubDeadTime(int64_t value) { - LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns"; - sendToDetector(F_SET_SUB_DEADTIME, value, nullptr); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending sub deadtime to Receiver: " << value; - sendToReceiver(F_RECEIVER_SET_SUB_DEADTIME, value, nullptr); - } -} - -int64_t Module::getStorageCellDelay() { - return sendToDetector(F_GET_STORAGE_CELL_DELAY); -} - -void Module::setStorageCellDelay(int64_t value) { - LOG(logDEBUG1) << "Setting storage cell delay to " << value << "ns"; - sendToDetector(F_SET_STORAGE_CELL_DELAY, value, nullptr); -} - -int64_t Module::getNumberOfFramesLeft() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_FRAMES_LEFT, nullptr, retval); - LOG(logDEBUG1) << "number of frames left :" << retval; - return retval; -} - -int64_t Module::getNumberOfTriggersLeft() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_TRIGGERS_LEFT, nullptr, retval); - LOG(logDEBUG1) << "number of triggers left :" << retval; - return retval; -} - -int64_t Module::getDelayAfterTriggerLeft() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_DELAY_AFTER_TRIGGER_LEFT, nullptr, retval); - LOG(logDEBUG1) << "delay after trigger left :" << retval << "ns"; - return retval; -} - -int64_t Module::getExptimeLeft() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_EXPTIME_LEFT, nullptr, retval); - LOG(logDEBUG1) << "exptime left :" << retval << "ns"; - return retval; -} - -int64_t Module::getPeriodLeft() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_PERIOD_LEFT, nullptr, retval); - LOG(logDEBUG1) << "period left :" << retval << "ns"; - return retval; -} - -int64_t Module::getMeasuredPeriod() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_MEASURED_PERIOD, nullptr, retval); - LOG(logDEBUG1) << "measured period :" << retval << "ns"; - return retval; -} - -int64_t Module::getMeasuredSubFramePeriod() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_MEASURED_SUBPERIOD, nullptr, retval); - LOG(logDEBUG1) << "exptime :" << retval << "ns"; - return retval; -} - -int64_t Module::getNumberOfFramesFromStart() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_FRAMES_FROM_START, nullptr, retval); - LOG(logDEBUG1) << "number of frames from start :" << retval; - return retval; -} - -int64_t Module::getActualTime() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_ACTUAL_TIME, nullptr, retval); - LOG(logDEBUG1) << "actual time :" << retval << "ns"; - return retval; -} - -int64_t Module::getMeasurementTime() const { - int64_t retval = -1; - sendToDetectorStop(F_GET_MEASUREMENT_TIME, nullptr, retval); - LOG(logDEBUG1) << "measurement time :" << retval << "ns"; - return retval; -} - -slsDetectorDefs::timingMode Module::getTimingMode() { - return sendToDetector(F_SET_TIMING_MODE, -1); -} - -void Module::setTimingMode(timingMode value) { - timingMode retval = GET_TIMING_MODE; - LOG(logDEBUG1) << "Setting timing mode to " << value; - sendToDetector(F_SET_TIMING_MODE, static_cast(value), retval); - if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending timing mode to Receiver: " << value; - sendToReceiver(F_SET_RECEIVER_TIMING_MODE, value, nullptr); - } -} - -int Module::getDynamicRange() { - return sendToDetector(F_SET_DYNAMIC_RANGE, -1); -} - -void Module::setDynamicRange(int n) { - int prev_val = n; - if (shm()->myDetectorType == EIGER) { - prev_val = getDynamicRange(); + if (shm()->myDetectorType == JUNGFRAU) { + os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfaces() + << "\nSelected Interface:\t" << getSelectedUDPInterface(); } + os << "\nDetector UDP IP:\t" << getSourceUDPIP() << "\nDetector UDP MAC:\t" + << getSourceUDPMAC() << "\nReceiver UDP IP:\t" << getDestinationUDPIP() + << "\nReceiver UDP MAC:\t" << getDestinationUDPMAC(); + + if (shm()->myDetectorType == JUNGFRAU) { + os << "\nDetector UDP IP2:\t" << getSourceUDPIP2() + << "\nDetector UDP MAC2:\t" << getSourceUDPMAC2() + << "\nReceiver UDP IP2:\t" << getDestinationUDPIP2() + << "\nReceiver UDP MAC2:\t" << getDestinationUDPMAC2(); + } + os << "\nReceiver UDP Port:\t" << getDestinationUDPPort(); + if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) { + os << "\nReceiver UDP Port2:\t" << getDestinationUDPPort2(); + } + os << "\n"; + return os.str(); +} + +bool Module::getTenGiga() { + int arg = -1; + return static_cast(sendToDetector(F_ENABLE_TEN_GIGA, arg)); +} + +void Module::setTenGiga(bool value) { + int arg = static_cast(value); int retval = -1; - LOG(logDEBUG1) << "Setting dynamic range to " << n; - sendToDetector(F_SET_DYNAMIC_RANGE, n, retval); - LOG(logDEBUG1) << "Dynamic Range: " << retval; - - if (shm()->useReceiverFlag) { - int arg = retval; - retval = -1; - LOG(logDEBUG1) << "Sending dynamic range to receiver: " << arg; - sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, arg, retval); - LOG(logDEBUG1) << "Receiver Dynamic range: " << retval; - } - - // changes in dr - if (n != prev_val) { - // update speed for usability - if (n == 32) { - LOG(logINFO) << "Setting Clock to Quarter Speed to cope with " - "Dynamic Range of 32"; - setClockDivider(RUN_CLOCK, 2); - } else if (prev_val == 32) { - LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range of " - << n; - setClockDivider(RUN_CLOCK, 0); - } - updateRateCorrection(); + sendToDetector(F_ENABLE_TEN_GIGA, arg, retval); + sendToDetectorStop(F_ENABLE_TEN_GIGA, arg); + arg = retval; + if (shm()->useReceiverFlag && arg != -1) { + sendToReceiver(F_ENABLE_RECEIVER_TEN_GIGA, arg); } } -int Module::setDAC(int val, dacIndex index, int mV) { - int args[]{static_cast(index), mV, val}; - int retval = -1; - LOG(logDEBUG1) << "Setting DAC " << index << " to " << val - << (mV != 0 ? "mV" : "dac units"); - sendToDetector(F_SET_DAC, args, retval); - LOG(logDEBUG1) << "Dac index " << index << ": " << retval - << (mV != 0 ? "mV" : "dac units"); - return retval; +bool Module::getTenGigaFlowControl() { + return sendToDetector(F_GET_TEN_GIGA_FLOW_CONTROL); } -int Module::getOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex) { - int args[]{static_cast(index), chipIndex}; - int retval = -1; - sendToDetector(F_GET_ON_CHIP_DAC, args, retval); - LOG(logDEBUG1) << "On chip DAC " << index << " (chip index:" << chipIndex - << "): " << retval; - return retval; -} - -void Module::setOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex, - int value) { - int args[]{static_cast(index), chipIndex, value}; - LOG(logDEBUG1) << "Setting On chip DAC " << index - << " (chip index:" << chipIndex << ") to " << value; - sendToDetector(F_SET_ON_CHIP_DAC, args, nullptr); -} - -int Module::getADC(dacIndex index) { - return sendToDetector(F_GET_ADC, static_cast(index)); -} - -slsDetectorDefs::externalSignalFlag -Module::getExternalSignalFlags(int signalIndex) { - return sendToDetector( - F_GET_EXTERNAL_SIGNAL_FLAG, signalIndex); -} - -void Module::setExternalSignalFlags(int signalIndex, externalSignalFlag type) { - LOG(logDEBUG1) << "Setting signal flag (" << signalIndex << ") to " << type; - int args[]{signalIndex, static_cast(type)}; - sendToDetector(F_SET_EXTERNAL_SIGNAL_FLAG, args, nullptr); -} - -void Module::setParallelMode(const bool enable) { - LOG(logDEBUG1) << "Setting parallel mode to " << enable; - sendToDetector(F_SET_PARALLEL_MODE, static_cast(enable), nullptr); -} - -bool Module::getParallelMode() { - auto r = sendToDetector(F_GET_PARALLEL_MODE); - return static_cast(r); -} - -void Module::setOverFlowMode(const bool enable) { +void Module::setTenGigaFlowControl(bool enable) { int arg = static_cast(enable); - LOG(logDEBUG1) << "Setting overflow mode to " << arg; - sendToDetector(F_SET_OVERFLOW_MODE, arg, nullptr); + sendToDetector(F_SET_TEN_GIGA_FLOW_CONTROL, arg, nullptr); } -bool Module::getOverFlowMode() { - auto r = sendToDetector(F_GET_OVERFLOW_MODE); - return static_cast(r); +int Module::getTransmissionDelayFrame() { + return sendToDetector(F_GET_TRANSMISSION_DELAY_FRAME); } -void Module::setStoreInRamMode(const bool enable) { - int arg = static_cast(enable); - LOG(logDEBUG1) << "Setting store in ram mode to " << arg; - sendToDetector(F_SET_STOREINRAM_MODE, arg, nullptr); +void Module::setTransmissionDelayFrame(int value) { + sendToDetector(F_SET_TRANSMISSION_DELAY_FRAME, value, nullptr); } -bool Module::getStoreInRamMode() { - auto r = sendToDetector(F_GET_STOREINRAM_MODE); - return static_cast(r); +int Module::getTransmissionDelayLeft() { + return sendToDetector(F_GET_TRANSMISSION_DELAY_LEFT); } -void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) { - auto arg = static_cast(mode); - LOG(logDEBUG1) << "Setting readout mode to " << arg; - sendToDetector(F_SET_READOUT_MODE, arg, nullptr); - // update #nchan, as it depends on #samples, adcmask, - if (shm()->myDetectorType == CHIPTESTBOARD) { - updateNumberOfChannels(); - } - if (shm()->useReceiverFlag) { - sendToReceiver(F_RECEIVER_SET_READOUT_MODE, mode, nullptr); - } +void Module::setTransmissionDelayLeft(int value) { + sendToDetector(F_SET_TRANSMISSION_DELAY_LEFT, value, nullptr); } -slsDetectorDefs::readoutMode Module::getReadoutMode() { - auto r = sendToDetector(F_GET_READOUT_MODE); - return static_cast(r); +int Module::getTransmissionDelayRight() { + return sendToDetector(F_GET_TRANSMISSION_DELAY_RIGHT); } -void Module::setInterruptSubframe(const bool enable) { - int arg = static_cast(enable); - LOG(logDEBUG1) << "Setting Interrupt subframe to " << arg; - sendToDetector(F_SET_INTERRUPT_SUBFRAME, arg, nullptr); +void Module::setTransmissionDelayRight(int value) { + sendToDetector(F_SET_TRANSMISSION_DELAY_RIGHT, value, nullptr); } -bool Module::getInterruptSubframe() { - auto r = sendToDetector(F_GET_INTERRUPT_SUBFRAME); - return static_cast(r); -} +// Receiver Config -uint32_t Module::writeRegister(uint32_t addr, uint32_t val) { - uint32_t args[]{addr, val}; - uint32_t retval = -1; - sendToDetectorStop(F_WRITE_REGISTER, args, retval); - return retval; -} +bool Module::getUseReceiverFlag() const { return shm()->useReceiverFlag; } -uint32_t Module::readRegister(uint32_t addr) { - uint32_t retval = -1; - sendToDetectorStop(F_READ_REGISTER, addr, retval); - return retval; -} - -uint32_t Module::setBit(uint32_t addr, int n) { - if (n < 0 || n > 31) { - throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); - } else { - uint32_t val = readRegister(addr); - return writeRegister(addr, val | 1 << n); - } -} - -uint32_t Module::clearBit(uint32_t addr, int n) { - if (n < 0 || n > 31) { - throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); - } else { - uint32_t val = readRegister(addr); - return writeRegister(addr, val & ~(1 << n)); - } +std::string Module::getReceiverHostname() const { + return std::string(shm()->rxHostname); } void Module::setReceiverHostname(const std::string &receiverIP) { @@ -1447,69 +728,25 @@ void Module::setReceiverHostname(const std::string &receiverIP) { // populate from shared memory retval.detType = shm()->myDetectorType; - retval.multiSize.x = shm()->multiSize.x; - retval.multiSize.y = shm()->multiSize.y; - retval.detId = detId; + retval.numberOfDetector.x = shm()->numberOfDetector.x; + retval.numberOfDetector.y = shm()->numberOfDetector.y; + retval.moduleId = moduleId; memset(retval.hostname, 0, sizeof(retval.hostname)); strcpy_safe(retval.hostname, shm()->hostname); - LOG(logDEBUG1) << "detType:" << retval.detType << std::endl - << "multiSize.x:" << retval.multiSize.x << std::endl - << "multiSize.y:" << retval.multiSize.y << std::endl - << "detId:" << retval.detId << std::endl - << "hostname:" << retval.hostname << std::endl - << "udpInterfaces:" << retval.udpInterfaces << std::endl - << "udp_dstport:" << retval.udp_dstport << std::endl - << "udp_dstip:" << sls::IpAddr(retval.udp_dstip) << std::endl - << "udp_dstmac:" << sls::MacAddr(retval.udp_dstmac) - << std::endl - << "udp_dstport2:" << retval.udp_dstport2 << std::endl - << "udp_dstip2:" << sls::IpAddr(retval.udp_dstip2) - << std::endl - << "udp_dstmac2:" << sls::MacAddr(retval.udp_dstmac2) - << std::endl - << "frames:" << retval.frames << std::endl - << "triggers:" << retval.triggers << std::endl - << "bursts:" << retval.bursts << std::endl - << "analogSamples:" << retval.analogSamples << std::endl - << "digitalSamples:" << retval.digitalSamples << std::endl - << "expTimeNs:" << retval.expTimeNs << std::endl - << "periodNs:" << retval.periodNs << std::endl - << "subExpTimeNs:" << retval.subExpTimeNs << std::endl - << "subDeadTimeNs:" << retval.subDeadTimeNs << std::endl - << "activate:" << retval.activate << std::endl - << "quad:" << retval.quad << std::endl - << "dynamicRange:" << retval.dynamicRange << std::endl - << "timMode:" << retval.timMode << std::endl - << "tenGiga:" << retval.tenGiga << std::endl - << "roMode:" << retval.roMode << std::endl - << "adcMask:" << retval.adcMask << std::endl - << "adc10gMask:" << retval.adc10gMask << std::endl - << "roi.xmin:" << retval.roi.xmin << std::endl - << "roi.xmax:" << retval.roi.xmax << std::endl - << "countermask:" << retval.countermask << std::endl - << "burstType:" << retval.burstType << std::endl - << "exptime1:" << retval.expTime1Ns << std::endl - << "exptime2:" << retval.expTime2Ns << std::endl - << "exptime3:" << retval.expTime3Ns << std::endl - << "gateDelay1:" << retval.gateDelay1Ns << std::endl - << "gateDelay2:" << retval.gateDelay2Ns << std::endl - << "gateDelay3:" << retval.gateDelay3Ns << std::endl - << "gates:" << retval.gates << std::endl; - sls::MacAddr retvals[2]; sendToReceiver(F_SETUP_RECEIVER, retval, retvals); // update detectors with dest mac if (retval.udp_dstmac == 0 && retvals[0] != 0) { LOG(logINFO) << "Setting destination udp mac of " "detector " - << detId << " to " << retvals[0]; + << moduleId << " to " << retvals[0]; sendToDetector(F_SET_DEST_UDP_MAC, retvals[0], nullptr); } if (retval.udp_dstmac2 == 0 && retvals[1] != 0) { LOG(logINFO) << "Setting destination udp mac2 of " "detector " - << detId << " to " << retvals[1]; + << moduleId << " to " << retvals[1]; sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr); } @@ -1527,197 +764,215 @@ void Module::setReceiverHostname(const std::string &receiverIP) { updateReceiverStreamingIP(); } -std::string Module::getReceiverHostname() const { - return std::string(shm()->rxHostname); -} +int Module::getReceiverPort() const { return shm()->rxTCPPort; } -void Module::setSourceUDPMAC(const sls::MacAddr mac) { - LOG(logDEBUG1) << "Setting source udp mac to " << mac; - if (mac == 0) { - throw RuntimeError("Invalid source udp mac address"); +int Module::setReceiverPort(int port_number) { + if (port_number >= 0 && port_number != shm()->rxTCPPort) { + if (shm()->useReceiverFlag) { + int retval = -1; + sendToReceiver(F_SET_RECEIVER_PORT, port_number, retval); + shm()->rxTCPPort = retval; + } else { + shm()->rxTCPPort = port_number; + } } - sendToDetector(F_SET_SOURCE_UDP_MAC, mac, nullptr); + return shm()->rxTCPPort; } -sls::MacAddr Module::getSourceUDPMAC() { - return sendToDetector(F_GET_SOURCE_UDP_MAC); +int Module::getReceiverFifoDepth() { + int arg = -1; + return sendToReceiver(F_SET_RECEIVER_FIFO_DEPTH, arg); } -void Module::setSourceUDPMAC2(const sls::MacAddr mac) { - LOG(logDEBUG1) << "Setting source udp mac2 to " << mac; - if (mac == 0) { - throw RuntimeError("Invalid source udp mac address2"); +void Module::setReceiverFifoDepth(int n_frames) { + sendToReceiver(F_SET_RECEIVER_FIFO_DEPTH, n_frames); +} + +bool Module::getReceiverSilentMode() { + return sendToReceiver(F_GET_RECEIVER_SILENT_MODE); +} + +void Module::setReceiverSilentMode(bool enable) { + sendToReceiver(F_SET_RECEIVER_SILENT_MODE, static_cast(enable), + nullptr); +} + +slsDetectorDefs::frameDiscardPolicy Module::getReceiverFramesDiscardPolicy() { + return static_cast( + sendToReceiver(F_GET_RECEIVER_DISCARD_POLICY)); +} + +void Module::setReceiverFramesDiscardPolicy(frameDiscardPolicy f) { + sendToReceiver(F_SET_RECEIVER_DISCARD_POLICY, static_cast(f), nullptr); +} + +bool Module::getPartialFramesPadding() { + return sendToReceiver(F_GET_RECEIVER_PADDING); +} + +void Module::setPartialFramesPadding(bool padding) { + sendToReceiver(F_SET_RECEIVER_PADDING, static_cast(padding), nullptr); +} + +int64_t Module::getReceiverUDPSocketBufferSize() const { + int64_t arg = -1; + return sendToReceiver(F_RECEIVER_UDP_SOCK_BUF_SIZE, arg); +} + +int64_t Module::getReceiverRealUDPSocketBufferSize() const { + return sendToReceiver(F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE); +} + +void Module::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize) { + sendToReceiver(F_RECEIVER_UDP_SOCK_BUF_SIZE, udpsockbufsize); +} + +bool Module::getReceiverLock() { + int arg = -1; + return static_cast(sendToReceiver(F_LOCK_RECEIVER, arg)); +} + +void Module::setReceiverLock(bool lock) { + sendToReceiver(F_LOCK_RECEIVER, static_cast(lock)); +} + +sls::IpAddr Module::getReceiverLastClientIP() const { + return sendToReceiver(F_GET_LAST_RECEIVER_CLIENT_IP); +} + +std::array Module::getReceiverThreadIds() const { + return sendToReceiver>( + F_GET_RECEIVER_THREAD_IDS); +} + +// File + +slsDetectorDefs::fileFormat Module::getFileFormat() { + return static_cast( + sendToReceiver(F_GET_RECEIVER_FILE_FORMAT)); +} + +void Module::setFileFormat(fileFormat f) { + sendToReceiver(F_SET_RECEIVER_FILE_FORMAT, static_cast(f), nullptr); +} + +std::string Module::getFilePath() { + char ret[MAX_STR_LENGTH]{}; + sendToReceiver(F_GET_RECEIVER_FILE_PATH, nullptr, ret); + return ret; +} + +void Module::setFilePath(const std::string &path) { + if (path.empty()) { + throw RuntimeError("Cannot set empty file path"); } - sendToDetector(F_SET_SOURCE_UDP_MAC2, mac, nullptr); + char args[MAX_STR_LENGTH]{}; + sls::strcpy_safe(args, path.c_str()); + sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr); } -sls::MacAddr Module::getSourceUDPMAC2() { - return sendToDetector(F_GET_SOURCE_UDP_MAC2); +std::string Module::getFileName() { + char retvals[MAX_STR_LENGTH]{}; + sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, retvals); + return std::string(retvals); } -void Module::setSourceUDPIP(const IpAddr ip) { - LOG(logDEBUG1) << "Setting source udp ip to " << ip; - if (ip == 0) { - throw RuntimeError("Invalid source udp ip address"); +void Module::setFileName(const std::string &fname) { + if (fname.empty()) { + throw RuntimeError("Cannot set empty file name prefix"); } - sendToDetector(F_SET_SOURCE_UDP_IP, ip, nullptr); + char args[MAX_STR_LENGTH]{}; + sls::strcpy_safe(args, fname.c_str()); + sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr); } -sls::IpAddr Module::getSourceUDPIP() { - return sendToDetector(F_GET_SOURCE_UDP_IP); +int64_t Module::getFileIndex() { + return sendToReceiver(F_GET_RECEIVER_FILE_INDEX); } -void Module::setSourceUDPIP2(const IpAddr ip) { - LOG(logDEBUG1) << "Setting source udp ip2 to " << ip; - if (ip == 0) { - throw RuntimeError("Invalid source udp ip address2"); +void Module::setFileIndex(int64_t file_index) { + sendToReceiver(F_SET_RECEIVER_FILE_INDEX, file_index, nullptr); +} + +void Module::incrementFileIndex() { + sendToReceiver(F_INCREMENT_FILE_INDEX, nullptr, nullptr); +} + +bool Module::getFileWrite() { + return sendToReceiver(F_GET_RECEIVER_FILE_WRITE); +} + +void Module::setFileWrite(bool value) { + sendToReceiver(F_SET_RECEIVER_FILE_WRITE, static_cast(value), nullptr); +} + +bool Module::getMasterFileWrite() { + return sendToReceiver(F_GET_RECEIVER_MASTER_FILE_WRITE); +} + +void Module::setMasterFileWrite(bool value) { + sendToReceiver(F_SET_RECEIVER_MASTER_FILE_WRITE, static_cast(value), + nullptr); +} + +bool Module::getFileOverWrite() { + return sendToReceiver(F_GET_RECEIVER_OVERWRITE); +} + +void Module::setFileOverWrite(bool value) { + sendToReceiver(F_SET_RECEIVER_OVERWRITE, static_cast(value), nullptr); +} + +int Module::getFramesPerFile() { + return sendToReceiver(F_GET_RECEIVER_FRAMES_PER_FILE); +} + +void Module::setFramesPerFile(int n_frames) { + sendToReceiver(F_SET_RECEIVER_FRAMES_PER_FILE, n_frames, nullptr); +} + +// ZMQ Streaming Parameters (Receiver<->Client) + +bool Module::getReceiverStreaming() { + return sendToReceiver(F_GET_RECEIVER_STREAMING); +} + +void Module::setReceiverStreaming(bool enable) { + sendToReceiver(F_SET_RECEIVER_STREAMING, static_cast(enable), nullptr); +} + +int Module::getReceiverStreamingFrequency() { + return sendToReceiver(F_GET_RECEIVER_STREAMING_FREQUENCY); +} + +void Module::setReceiverStreamingFrequency(int freq) { + if (freq < 0) { + throw RuntimeError("Invalid streaming frequency " + + std::to_string(freq)); } - sendToDetector(F_SET_SOURCE_UDP_IP2, ip, nullptr); + sendToReceiver(F_SET_RECEIVER_STREAMING_FREQUENCY, freq, nullptr); } -sls::IpAddr Module::getSourceUDPIP2() { - return sendToDetector(F_GET_SOURCE_UDP_IP2); +int Module::getReceiverStreamingTimer() { + int arg = -1; + return sendToReceiver(F_RECEIVER_STREAMING_TIMER, arg); } -void Module::setDestinationUDPIP(const IpAddr ip) { - LOG(logDEBUG1) << "Setting destination udp ip to " << ip; - if (ip == 0) { - throw RuntimeError("Invalid destination udp ip address"); - } - sendToDetector(F_SET_DEST_UDP_IP, ip, nullptr); - if (shm()->useReceiverFlag) { - sls::MacAddr retval(0LU); - sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval); - LOG(logINFO) << "Setting destination udp mac of detector " << detId - << " to " << retval; - sendToDetector(F_SET_DEST_UDP_MAC, retval, nullptr); - } -} - -sls::IpAddr Module::getDestinationUDPIP() { - return sendToDetector(F_GET_DEST_UDP_IP); -} - -void Module::setDestinationUDPIP2(const IpAddr ip) { - LOG(logDEBUG1) << "Setting destination udp ip2 to " << ip; - if (ip == 0) { - throw RuntimeError("Invalid destination udp ip address2"); - } - - sendToDetector(F_SET_DEST_UDP_IP2, ip, nullptr); - if (shm()->useReceiverFlag) { - sls::MacAddr retval(0LU); - sendToReceiver(F_SET_RECEIVER_UDP_IP2, ip, retval); - LOG(logINFO) << "Setting destination udp mac2 of detector " << detId - << " to " << retval; - sendToDetector(F_SET_DEST_UDP_MAC2, retval, nullptr); - } -} - -sls::IpAddr Module::getDestinationUDPIP2() { - return sendToDetector(F_GET_DEST_UDP_IP2); -} - -void Module::setDestinationUDPMAC(const MacAddr mac) { - LOG(logDEBUG1) << "Setting destination udp mac to " << mac; - if (mac == 0) { - throw RuntimeError("Invalid destination udp mac address"); - } - sendToDetector(F_SET_DEST_UDP_MAC, mac, nullptr); -} - -sls::MacAddr Module::getDestinationUDPMAC() { - return sendToDetector(F_GET_DEST_UDP_MAC); -} - -void Module::setDestinationUDPMAC2(const MacAddr mac) { - LOG(logDEBUG1) << "Setting destination udp mac2 to " << mac; - if (mac == 0) { - throw RuntimeError("Invalid desinaion udp mac address2"); - } - sendToDetector(F_SET_DEST_UDP_MAC2, mac, nullptr); -} - -sls::MacAddr Module::getDestinationUDPMAC2() { - return sendToDetector(F_GET_DEST_UDP_MAC2); -} - -void Module::setDestinationUDPPort(const int port) { - LOG(logDEBUG1) << "Setting destination udp port to " << port; - sendToDetector(F_SET_DEST_UDP_PORT, port, nullptr); - if (shm()->useReceiverFlag) { - sendToReceiver(F_SET_RECEIVER_UDP_PORT, port, nullptr); - } -} - -int Module::getDestinationUDPPort() { - return sendToDetector(F_GET_DEST_UDP_PORT); -} - -void Module::setDestinationUDPPort2(const int port) { - LOG(logDEBUG1) << "Setting destination udp port2 to " << port; - sendToDetector(F_SET_DEST_UDP_PORT2, port, nullptr); - if (shm()->useReceiverFlag) { - sendToReceiver(F_SET_RECEIVER_UDP_PORT2, port, nullptr); - } -} - -int Module::getDestinationUDPPort2() { - return sendToDetector(F_GET_DEST_UDP_PORT2); -} - -void Module::setNumberofUDPInterfaces(int n) { - LOG(logDEBUG1) << "Setting number of udp interfaces to " << n; - sendToDetector(F_SET_NUM_INTERFACES, n, nullptr); - shm()->numUDPInterfaces = n; - if (shm()->useReceiverFlag) { - sendToReceiver(F_SET_RECEIVER_NUM_INTERFACES, n, nullptr); - } -} - -int Module::getNumberofUDPInterfacesFromShm() { - return shm()->numUDPInterfaces; -} - -int Module::getNumberofUDPInterfaces() { - int retval = -1; - LOG(logDEBUG1) << "Getting number of udp interfaces"; - sendToDetector(F_GET_NUM_INTERFACES, nullptr, retval); - LOG(logDEBUG1) << "Number of udp interfaces: " << retval; - shm()->numUDPInterfaces = retval; - return shm()->numUDPInterfaces; -} - -void Module::selectUDPInterface(int n) { - LOG(logDEBUG1) << "Setting selected udp interface to " << n; - sendToDetector(F_SET_INTERFACE_SEL, n, nullptr); -} - -int Module::getSelectedUDPInterface() { - return sendToDetector(F_GET_INTERFACE_SEL); -} - -void Module::setClientStreamingPort(int port) { shm()->zmqport = port; } - -int Module::getClientStreamingPort() { return shm()->zmqport; } - -void Module::setReceiverStreamingPort(int port) { - sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr); +void Module::setReceiverStreamingTimer(int time_in_ms) { + sendToReceiver(F_RECEIVER_STREAMING_TIMER, time_in_ms); } int Module::getReceiverStreamingPort() { return sendToReceiver(F_GET_RECEIVER_STREAMING_PORT); } -void Module::setClientStreamingIP(const sls::IpAddr ip) { - LOG(logDEBUG1) << "Setting client zmq ip to " << ip; - if (ip == 0) { - throw RuntimeError("Invalid client zmq ip address"); - } - shm()->zmqip = ip; +void Module::setReceiverStreamingPort(int port) { + sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr); } -sls::IpAddr Module::getClientStreamingIP() { return shm()->zmqip; } +sls::IpAddr Module::getReceiverStreamingIP() { + return sendToReceiver(F_GET_RECEIVER_STREAMING_SRC_IP); +} void Module::setReceiverStreamingIP(const sls::IpAddr ip) { if (ip == 0) { @@ -1730,204 +985,401 @@ void Module::setReceiverStreamingIP(const sls::IpAddr ip) { sendToReceiver(F_SET_RECEIVER_STREAMING_SRC_IP, ip, nullptr); } -sls::IpAddr Module::getReceiverStreamingIP() { - return sendToReceiver(F_GET_RECEIVER_STREAMING_SRC_IP); -} +int Module::getClientStreamingPort() { return shm()->zmqport; } -void Module::updateReceiverStreamingIP() { - auto ip = getReceiverStreamingIP(); +void Module::setClientStreamingPort(int port) { shm()->zmqport = port; } + +sls::IpAddr Module::getClientStreamingIP() { return shm()->zmqip; } + +void Module::setClientStreamingIP(const sls::IpAddr ip) { if (ip == 0) { - // Hostname could be ip try to decode otherwise look up the hostname - ip = sls::IpAddr{shm()->rxHostname}; - if (ip == 0) { - ip = HostnameToIp(shm()->rxHostname); + throw RuntimeError("Invalid client zmq ip address"); + } + shm()->zmqip = ip; +} + +// Eiger Specific + +int Module::getDynamicRange() { + return sendToDetector(F_SET_DYNAMIC_RANGE, -1); +} + +void Module::setDynamicRange(int n) { + int prev_val = n; + if (shm()->myDetectorType == EIGER) { + prev_val = getDynamicRange(); + } + + auto retval = sendToDetector(F_SET_DYNAMIC_RANGE, n); + if (shm()->useReceiverFlag) { + int arg = retval; + sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, arg); + } + + // changes in dr + if (n != prev_val) { + // update speed for usability + if (n == 32) { + LOG(logINFO) << "Setting Clock to Quarter Speed to cope with " + "Dynamic Range of 32"; + setClockDivider(RUN_CLOCK, 2); + } else if (prev_val == 32) { + LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range of " + << n; + setClockDivider(RUN_CLOCK, 0); } - LOG(logINFO) << "Setting default receiver " << detId - << " streaming zmq ip to " << ip; + updateRateCorrection(); } - setReceiverStreamingIP(ip); } -bool Module::getTenGigaFlowControl() { - return sendToDetector(F_GET_TEN_GIGA_FLOW_CONTROL); +int64_t Module::getSubExptime() { + return sendToDetector(F_GET_SUB_EXPTIME); } -void Module::setTenGigaFlowControl(bool enable) { - int arg = static_cast(enable); - LOG(logDEBUG1) << "Setting ten giga flow control to " << arg; - sendToDetector(F_SET_TEN_GIGA_FLOW_CONTROL, arg, nullptr); -} - -int Module::getTransmissionDelayFrame() { - return sendToDetector(F_GET_TRANSMISSION_DELAY_FRAME); -} - -void Module::setTransmissionDelayFrame(int value) { - LOG(logDEBUG1) << "Setting transmission delay frame to " << value; - sendToDetector(F_SET_TRANSMISSION_DELAY_FRAME, value, nullptr); -} - -int Module::getTransmissionDelayLeft() { - return sendToDetector(F_GET_TRANSMISSION_DELAY_LEFT); -} - -void Module::setTransmissionDelayLeft(int value) { - LOG(logDEBUG1) << "Setting transmission delay left to " << value; - sendToDetector(F_SET_TRANSMISSION_DELAY_LEFT, value, nullptr); -} - -int Module::getTransmissionDelayRight() { - return sendToDetector(F_GET_TRANSMISSION_DELAY_RIGHT); -} - -void Module::setTransmissionDelayRight(int value) { - LOG(logDEBUG1) << "Setting transmission delay right to " << value; - sendToDetector(F_SET_TRANSMISSION_DELAY_RIGHT, value, nullptr); -} - -void Module::setAdditionalJsonHeader( - const std::map &jsonHeader) { - if (!shm()->useReceiverFlag) { - throw RuntimeError("Set rx_hostname first to use receiver parameters " - "(zmq json header)"); +void Module::setSubExptime(int64_t value) { + int64_t prevVal = value; + if (shm()->myDetectorType == EIGER) { + prevVal = getSubExptime(); } - for (auto &it : jsonHeader) { - if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH || - it.second.length() > SHORT_STR_LENGTH) { - throw RuntimeError( - it.first + " or " + it.second + - " pair has invalid size. " - "Key cannot be empty. Both can have max 20 characters"); + sendToDetector(F_SET_SUB_EXPTIME, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr); + } + if (prevVal != value) { + updateRateCorrection(); + } +} + +int64_t Module::getSubDeadTime() { + return sendToDetector(F_GET_SUB_DEADTIME); +} + +void Module::setSubDeadTime(int64_t value) { + sendToDetector(F_SET_SUB_DEADTIME, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_SUB_DEADTIME, value, nullptr); + } +} + +int Module::getThresholdEnergy() { + // moench - get threshold energy from json header + if (shm()->myDetectorType == MOENCH) { + getAdditionalJsonHeader(); + std::string result = getAdditionalJsonParameter("threshold"); + // convert to integer + try { + return std::stoi(result); + } + // not found or cannot scan integer + catch (...) { + return -1; } } - const int size = jsonHeader.size(); - int fnum = F_SET_ADDITIONAL_JSON_HEADER; - int ret = FAIL; - LOG(logDEBUG) << "Sending to receiver additional json header " - << ToString(jsonHeader); - auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); - client.Send(&fnum, sizeof(fnum)); - client.Send(&size, sizeof(size)); - if (size > 0) { - char args[size * 2][SHORT_STR_LENGTH]; - memset(args, 0, sizeof(args)); - int iarg = 0; - for (auto &it : jsonHeader) { - sls::strcpy_safe(args[iarg], it.first.c_str()); - sls::strcpy_safe(args[iarg + 1], it.second.c_str()); - iarg += 2; - } - client.Send(args, sizeof(args)); - } - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - char mess[MAX_STR_LENGTH]{}; - client.Receive(mess, MAX_STR_LENGTH); - throw RuntimeError("Receiver " + std::to_string(detId) + - " returned error: " + std::string(mess)); - } + return sendToDetector(F_GET_THRESHOLD_ENERGY); } -std::map Module::getAdditionalJsonHeader() { - if (!shm()->useReceiverFlag) { - throw RuntimeError("Set rx_hostname first to use receiver parameters " - "(zmq json header)"); +void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, + bool trimbits) { + // check as there is client processing + if (shm()->myDetectorType == EIGER) { + setThresholdEnergyAndSettings(e_eV, isettings, trimbits); } - int fnum = F_GET_ADDITIONAL_JSON_HEADER; - int ret = FAIL; - int size = 0; - auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); - client.Send(&fnum, sizeof(fnum)); - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - char mess[MAX_STR_LENGTH]{}; - client.Receive(mess, MAX_STR_LENGTH); - throw RuntimeError("Receiver " + std::to_string(detId) + - " returned error: " + std::string(mess)); + // moench - send threshold energy to processor + else if (shm()->myDetectorType == MOENCH) { + setAdditionalJsonParameter("threshold", std::to_string(e_eV)); } else { - client.Receive(&size, sizeof(size)); - std::map retval; - if (size > 0) { - char retvals[size * 2][SHORT_STR_LENGTH]; - memset(retvals, 0, sizeof(retvals)); - client.Receive(retvals, sizeof(retvals)); - for (int i = 0; i < size; ++i) { - retval[retvals[2 * i]] = retvals[2 * i + 1]; - } - } - LOG(logDEBUG) << "Getting additional json header " << ToString(retval); - return retval; - } -} - -void Module::setAdditionalJsonParameter(const std::string &key, - const std::string &value) { - if (key.empty() || key.length() > SHORT_STR_LENGTH || - value.length() > SHORT_STR_LENGTH) { throw RuntimeError( - key + " or " + value + - " pair has invalid size. " - "Key cannot be empty. Both can have max 2 characters"); + "Set threshold energy not implemented for this detector"); } - char args[2][SHORT_STR_LENGTH]{}; - sls::strcpy_safe(args[0], key.c_str()); - sls::strcpy_safe(args[1], value.c_str()); - sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr); } -std::string Module::getAdditionalJsonParameter(const std::string &key) { - char arg[SHORT_STR_LENGTH]{}; - sls::strcpy_safe(arg, key.c_str()); - char retval[SHORT_STR_LENGTH]{}; - sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval); +std::string Module::getSettingsDir() { return std::string(shm()->settingsDir); } + +std::string Module::setSettingsDir(const std::string &dir) { + sls::strcpy_safe(shm()->settingsDir, dir.c_str()); + return shm()->settingsDir; +} + +bool Module::getParallelMode() { + auto r = sendToDetector(F_GET_PARALLEL_MODE); + return static_cast(r); +} + +void Module::setParallelMode(const bool enable) { + sendToDetector(F_SET_PARALLEL_MODE, static_cast(enable), nullptr); +} + +bool Module::getOverFlowMode() { + auto r = sendToDetector(F_GET_OVERFLOW_MODE); + return static_cast(r); +} + +void Module::setOverFlowMode(const bool enable) { + int arg = static_cast(enable); + sendToDetector(F_SET_OVERFLOW_MODE, arg, nullptr); +} + +bool Module::getFlippedDataX() { + return sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, -1); +} + +void Module::setFlippedDataX(bool value) { + sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, static_cast(value)); +} + +std::vector Module::getTrimEn() { + if (shm()->myDetectorType != EIGER) { + throw RuntimeError("getTrimEn not implemented for this detector."); + } + return std::vector(shm()->trimEnergies.begin(), + shm()->trimEnergies.end()); +} + +int Module::setTrimEn(const std::vector &energies) { + if (shm()->myDetectorType != EIGER) { + throw RuntimeError("setTrimEn not implemented for this detector."); + } + if (energies.size() > MAX_TRIMEN) { + std::ostringstream os; + os << "Size of trim energies: " << energies.size() + << " exceeds what can be stored in shared memory: " << MAX_TRIMEN + << "\n"; + throw RuntimeError(os.str()); + } + shm()->trimEnergies = energies; + return shm()->trimEnergies.size(); +} + +int64_t Module::getRateCorrection() { + return sendToDetector(F_GET_RATE_CORRECT); +} + +void Module::setDefaultRateCorrection() { + int64_t arg = -1; + sendToDetector(F_SET_RATE_CORRECT, arg, nullptr); +} + +void Module::setRateCorrection(int64_t t) { + sendToDetector(F_SET_RATE_CORRECT, t, nullptr); +} + +int Module::getReadNLines() { return sendToDetector(F_GET_READ_N_LINES); } + +void Module::setReadNLines(const int value) { + sendToDetector(F_SET_READ_N_LINES, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_READ_N_LINES, value, nullptr); + } +} + +bool Module::getInterruptSubframe() { + auto r = sendToDetector(F_GET_INTERRUPT_SUBFRAME); + return static_cast(r); +} + +void Module::setInterruptSubframe(const bool enable) { + int arg = static_cast(enable); + sendToDetector(F_SET_INTERRUPT_SUBFRAME, arg, nullptr); +} + +int64_t Module::getMeasuredPeriod() const { + return sendToDetectorStop(F_GET_MEASURED_PERIOD); +} + +int64_t Module::getMeasuredSubFramePeriod() const { + return sendToDetectorStop(F_GET_MEASURED_SUBPERIOD); +} + +bool Module::getActivate() { + int arg = -1; + auto retval = sendToDetector(F_ACTIVATE, arg); + auto retval2 = sendToDetectorStop(F_ACTIVATE, arg); + if (retval != retval2) { + std::ostringstream oss; + oss << "Inconsistent activate state. Control Server: " << retval + << ". Stop Server: " << retval2; + throw RuntimeError(oss.str()); + } return retval; } -int64_t Module::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize) { - return sendToReceiver(F_RECEIVER_UDP_SOCK_BUF_SIZE, - udpsockbufsize); +void Module::setActivate(const bool enable) { + int arg = static_cast(enable); + auto retval = sendToDetector(F_ACTIVATE, arg); + sendToDetectorStop(F_ACTIVATE, arg); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_ACTIVATE, retval, nullptr); + } } -int64_t Module::getReceiverUDPSocketBufferSize() { - return setReceiverUDPSocketBufferSize(); +bool Module::getDeactivatedRxrPaddingMode() { + return sendToReceiver(F_GET_RECEIVER_DEACTIVATED_PADDING); } -int64_t Module::getReceiverRealUDPSocketBufferSize() const { - return sendToReceiver(F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE); +void Module::setDeactivatedRxrPaddingMode(bool padding) { + sendToReceiver(F_SET_RECEIVER_DEACTIVATED_PADDING, + static_cast(padding), nullptr); } -void Module::executeFirmwareTest() { - LOG(logDEBUG1) << "Executing firmware test"; - sendToDetector(F_SET_FIRMWARE_TEST); +bool Module::getCounterBit() { + int arg = -1; + return (!static_cast(sendToDetector(F_SET_COUNTER_BIT, arg))); } -void Module::executeBusTest() { - LOG(logDEBUG1) << "Executing bus test"; - sendToDetector(F_SET_BUS_TEST); +void Module::setCounterBit(bool cb) { + sendToDetector(F_SET_COUNTER_BIT, static_cast(!cb)); } -int Module::getImageTestMode() { - return sendToDetector(F_GET_IMAGE_TEST_MODE); +void Module::pulsePixel(int n, int x, int y) { + int args[]{n, x, y}; + sendToDetector(F_PULSE_PIXEL, args, nullptr); } -void Module::setImageTestMode(const int value) { - LOG(logDEBUG1) << "Sending image test mode " << value; - sendToDetector(F_SET_IMAGE_TEST_MODE, value, nullptr); +void Module::pulsePixelNMove(int n, int x, int y) { + int args[]{n, x, y}; + sendToDetector(F_PULSE_PIXEL_AND_MOVE, args, nullptr); +} + +void Module::pulseChip(int n_pulses) { + sendToDetector(F_PULSE_CHIP, n_pulses, nullptr); +} + +bool Module::getQuad() { return sendToDetector(F_GET_QUAD) != 0; } + +void Module::setQuad(const bool enable) { + int value = enable ? 1 : 0; + sendToDetector(F_SET_QUAD, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_QUAD, value, nullptr); + } +} + +// Jungfrau Specific + +int Module::getThresholdTemperature() { + int arg = -1; + auto retval = sendToDetectorStop(F_THRESHOLD_TEMP, arg); + if (retval != 0) { + retval /= 1000; + } + return retval; +} + +void Module::setThresholdTemperature(int val) { + if (val <= 0) { + throw RuntimeError("Invalid threshold temperature " + + std::to_string(val)); + } + val *= 1000; + sendToDetectorStop(F_THRESHOLD_TEMP, val); +} + +bool Module::getTemperatureControl() { + int arg = -1; + return static_cast(sendToDetectorStop(F_TEMP_CONTROL, arg)); +} + +void Module::setTemperatureControl(bool val) { + sendToDetectorStop(F_TEMP_CONTROL, static_cast(val)); +} + +int Module::getTemperatureEvent() { + int arg = -1; + return sendToDetectorStop(F_TEMP_EVENT, arg); +} + +void Module::resetTemperatureEvent() { + int arg = 0; + sendToDetectorStop(F_TEMP_EVENT, arg); +} + +bool Module::getAutoComparatorDisableMode() { + int arg = -1; + return static_cast(sendToDetector(F_AUTO_COMP_DISABLE, arg)); +} + +void Module::setAutoComparatorDisableMode(bool val) { + sendToDetector(F_AUTO_COMP_DISABLE, static_cast(val)); +} + +int Module::getNumberOfAdditionalStorageCells() { + return sendToDetector(F_GET_NUM_ADDITIONAL_STORAGE_CELLS); +} + +void Module::setNumberOfAdditionalStorageCells(int value) { + sendToDetector(F_SET_NUM_ADDITIONAL_STORAGE_CELLS, value, nullptr); +} + +int Module::getStorageCellStart() { + int arg = -1; + return sendToDetector(F_STORAGE_CELL_START, arg); +} + +void Module::setStorageCellStart(int pos) { + sendToDetector(F_STORAGE_CELL_START, pos); +} + +int64_t Module::getStorageCellDelay() { + return sendToDetector(F_GET_STORAGE_CELL_DELAY); +} + +void Module::setStorageCellDelay(int64_t value) { + sendToDetector(F_SET_STORAGE_CELL_DELAY, value, nullptr); +} + +// Gotthard Specific + +slsDetectorDefs::ROI Module::getROI() { + return sendToDetector(F_GET_ROI); +} + +void Module::setROI(slsDetectorDefs::ROI arg) { + if (arg.xmin < 0 || arg.xmax >= getNumberOfChannels().x) { + arg.xmin = -1; + arg.xmax = -1; + } + sendToDetector(F_SET_ROI, arg, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_ROI, arg, nullptr); + } +} + +void Module::clearROI() { setROI(slsDetectorDefs::ROI{}); } + +int64_t Module::getExptimeLeft() const { + return sendToDetectorStop(F_GET_EXPTIME_LEFT); +} + +// Gotthard2 Specific + +int64_t Module::getNumberOfBursts() { + return sendToDetector(F_GET_NUM_BURSTS); +} + +void Module::setNumberOfBursts(int64_t value) { + sendToDetector(F_SET_NUM_BURSTS, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr); + } +} + +int64_t Module::getBurstPeriod() { + return sendToDetector(F_GET_BURST_PERIOD); +} + +void Module::setBurstPeriod(int64_t value) { + sendToDetector(F_SET_BURST_PERIOD, value, nullptr); } std::array Module::getInjectChannel() { std::array retvals{}; sendToDetector(F_GET_INJECT_CHANNEL, nullptr, retvals); - LOG(logDEBUG1) << "Inject Channel: [offset: " << retvals[0] - << ", increment: " << retvals[1] << ']'; return retvals; } void Module::setInjectChannel(const int offsetChannel, const int incrementChannel) { int args[]{offsetChannel, incrementChannel}; - LOG(logDEBUG1) << "Setting inject channels [offset: " << offsetChannel - << ", increment: " << incrementChannel << ']'; sendToDetector(F_SET_INJECT_CHANNEL, args, nullptr); } @@ -1941,7 +1393,7 @@ std::vector Module::getVetoPhoton(const int chipIndex) { if (ret == FAIL) { char mess[MAX_STR_LENGTH]{}; client.Receive(mess, MAX_STR_LENGTH); - throw RuntimeError("Detector " + std::to_string(detId) + + throw RuntimeError("Detector " + std::to_string(moduleId) + " returned error: " + std::string(mess)); } else { int nch = -1; @@ -2054,15 +1506,13 @@ void Module::setVetoPhoton(const int chipIndex, const int numPhotons, if (ret == FAIL) { char mess[MAX_STR_LENGTH]{}; client.Receive(mess, MAX_STR_LENGTH); - throw RuntimeError("Detector " + std::to_string(detId) + + throw RuntimeError("Detector " + std::to_string(moduleId) + " returned error: " + std::string(mess)); } } void Module::setVetoReference(const int gainIndex, const int value) { int args[]{gainIndex, value}; - LOG(logDEBUG1) << "Setting veto reference [gainIndex: " << gainIndex - << ", value: 0x" << std::hex << value << std::dec << ']'; sendToDetector(F_SET_VETO_REFERENCE, args, nullptr); } @@ -2073,10 +1523,8 @@ slsDetectorDefs::burstMode Module::getBurstMode() { void Module::setBurstMode(slsDetectorDefs::burstMode value) { int arg = static_cast(value); - LOG(logDEBUG1) << "Setting burst mode to " << arg; sendToDetector(F_SET_BURST_MODE, arg, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending burst mode to Receiver: " << value; sendToReceiver(F_SET_RECEIVER_BURST_MODE, value, nullptr); } } @@ -2104,39 +1552,83 @@ void Module::setVeto(bool enable) { sendToDetector(F_SET_VETO, static_cast(enable), nullptr); } -int Module::setCounterBit(int cb) { - return sendToDetector(F_SET_COUNTER_BIT, cb); +// Mythen3 Specific + +uint32_t Module::getCounterMask() { + return sendToDetector(F_GET_COUNTER_MASK); } -void Module::clearROI() { - LOG(logDEBUG1) << "Clearing ROI"; - setROI(slsDetectorDefs::ROI{}); -} - -void Module::setROI(slsDetectorDefs::ROI arg) { - if (arg.xmin < 0 || arg.xmax >= getNumberOfChannels().x) { - arg.xmin = -1; - arg.xmax = -1; - } - LOG(logDEBUG) << "Sending ROI to detector [" << arg.xmin << ", " << arg.xmax - << "]"; - sendToDetector(F_SET_ROI, arg, nullptr); +void Module::setCounterMask(uint32_t countermask) { + LOG(logDEBUG1) << "Setting Counter mask to " << countermask; + sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending ROI to receiver"; - sendToReceiver(F_RECEIVER_SET_ROI, arg, nullptr); + int ncounters = __builtin_popcount(countermask); + LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters; + sendToReceiver(F_RECEIVER_SET_NUM_COUNTERS, ncounters, nullptr); } } -slsDetectorDefs::ROI Module::getROI() { - return sendToDetector(F_GET_ROI); +int Module::getNumberOfGates() { return sendToDetector(F_GET_NUM_GATES); } + +void Module::setNumberOfGates(int value) { + sendToDetector(F_SET_NUM_GATES, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_NUM_GATES, value, nullptr); + } +} + +std::array Module::getExptimeForAllGates() { + static_assert(sizeof(time::ns) == 8, "ns needs to be 64bit"); + return sendToDetector>(F_GET_EXPTIME_ALL_GATES); +} + +int64_t Module::getGateDelay(int gateIndex) { + return sendToDetector(F_GET_GATE_DELAY, gateIndex); +} + +void Module::setGateDelay(int gateIndex, int64_t value) { + int64_t args[]{static_cast(gateIndex), value}; + sendToDetector(F_SET_GATE_DELAY, args, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_GATE_DELAY, args, nullptr); + } +} + +std::array Module::getGateDelayForAllGates() { + static_assert(sizeof(time::ns) == 8, "ns needs to be 64bit"); + return sendToDetector>(F_GET_GATE_DELAY_ALL_GATES); +} + +// CTB / Moench Specific + +int Module::getNumberOfAnalogSamples() { + return sendToDetector(F_GET_NUM_ANALOG_SAMPLES); +} + +void Module::setNumberOfAnalogSamples(int value) { + sendToDetector(F_SET_NUM_ANALOG_SAMPLES, value, nullptr); + // update #nchan, as it depends on #samples, adcmask + updateNumberOfChannels(); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_NUM_ANALOG_SAMPLES, value, nullptr); + } +} + +int Module::getPipeline(int clkIndex) { + return sendToDetector(F_GET_PIPELINE, clkIndex); +} + +void Module::setPipeline(int clkIndex, int value) { + int args[]{clkIndex, value}; + sendToDetector(F_SET_PIPELINE, args, nullptr); +} + +uint32_t Module::getADCEnableMask() { + return sendToDetector(F_GET_ADC_ENABLE_MASK); } void Module::setADCEnableMask(uint32_t mask) { - uint32_t arg = mask; - LOG(logDEBUG1) << "Setting ADC Enable mask to 0x" << std::hex << arg - << std::dec; - sendToDetector(F_SET_ADC_ENABLE_MASK, &arg, sizeof(arg), nullptr, 0); - + sendToDetector(F_SET_ADC_ENABLE_MASK, mask, nullptr); // update #nchan, as it depends on #samples, adcmask, updateNumberOfChannels(); @@ -2145,24 +1637,16 @@ void Module::setADCEnableMask(uint32_t mask) { setAdditionalJsonParameter("adcmask_1g", std::to_string(mask)); if (shm()->useReceiverFlag) { - int fnum = F_RECEIVER_SET_ADC_MASK; - int retval = -1; - LOG(logDEBUG1) << "Setting ADC Enable mask to 0x" << std::hex << mask - << std::dec << " in receiver"; - sendToReceiver(fnum, mask, retval); + sendToReceiver(F_RECEIVER_SET_ADC_MASK, mask); } } -uint32_t Module::getADCEnableMask() { - return sendToDetector(F_GET_ADC_ENABLE_MASK); +uint32_t Module::getTenGigaADCEnableMask() { + return sendToDetector(F_GET_ADC_ENABLE_MASK_10G); } void Module::setTenGigaADCEnableMask(uint32_t mask) { - uint32_t arg = mask; - LOG(logDEBUG1) << "Setting 10Gb ADC Enable mask to 0x" << std::hex << arg - << std::dec; - sendToDetector(F_SET_ADC_ENABLE_MASK_10G, &arg, sizeof(arg), nullptr, 0); - + sendToDetector(F_SET_ADC_ENABLE_MASK_10G, mask, nullptr); // update #nchan, as it depends on #samples, adcmask, updateNumberOfChannels(); @@ -2171,38 +1655,52 @@ void Module::setTenGigaADCEnableMask(uint32_t mask) { setAdditionalJsonParameter("adcmask_10g", std::to_string(mask)); if (shm()->useReceiverFlag) { - int fnum = F_RECEIVER_SET_ADC_MASK_10G; - int retval = -1; - LOG(logDEBUG1) << "Setting 10Gb ADC Enable mask to 0x" << std::hex - << mask << std::dec << " in receiver"; - sendToReceiver(fnum, mask, retval); + sendToReceiver(F_RECEIVER_SET_ADC_MASK_10G, mask); } } -uint32_t Module::getTenGigaADCEnableMask() { - return sendToDetector(F_GET_ADC_ENABLE_MASK_10G); +// CTB Specific + +int Module::getNumberOfDigitalSamples() { + return sendToDetector(F_GET_NUM_DIGITAL_SAMPLES); } -void Module::setADCInvert(uint32_t value) { - LOG(logDEBUG1) << "Setting ADC Invert to 0x" << std::hex << value - << std::dec; - sendToDetector(F_SET_ADC_INVERT, value, nullptr); +void Module::setNumberOfDigitalSamples(int value) { + LOG(logDEBUG1) << "Setting number of digital samples to " << value; + sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr); + // update #nchan, as it depends on #samples, adcmask + updateNumberOfChannels(); + if (shm()->useReceiverFlag) { + LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " + << value; + sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr); + } } -uint32_t Module::getADCInvert() { - return sendToDetector(F_GET_ADC_INVERT); +slsDetectorDefs::readoutMode Module::getReadoutMode() { + auto r = sendToDetector(F_GET_READOUT_MODE); + return static_cast(r); } -int Module::setExternalSamplingSource(int value) { - return sendToDetector(F_EXTERNAL_SAMPLING_SOURCE, value); +void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) { + auto arg = static_cast(mode); + LOG(logDEBUG1) << "Setting readout mode to " << arg; + sendToDetector(F_SET_READOUT_MODE, arg, nullptr); + // update #nchan, as it depends on #samples, adcmask, + if (shm()->myDetectorType == CHIPTESTBOARD) { + updateNumberOfChannels(); + } + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_READOUT_MODE, mode, nullptr); + } } int Module::getExternalSamplingSource() { return setExternalSamplingSource(-1); } -void Module::setExternalSampling(bool value) { - sendToDetector(F_EXTERNAL_SAMPLING, static_cast(value)); +int Module::setExternalSamplingSource(int value) { + return sendToDetector(F_EXTERNAL_SAMPLING_SOURCE, value); } bool Module::getExternalSampling() { @@ -2210,6 +1708,15 @@ bool Module::getExternalSampling() { return sendToDetector(F_EXTERNAL_SAMPLING, arg); } +void Module::setExternalSampling(bool value) { + sendToDetector(F_EXTERNAL_SAMPLING, static_cast(value)); +} + +std::vector Module::getReceiverDbitList() const { + return sendToReceiver>( + F_GET_RECEIVER_DBIT_LIST); +} + void Module::setReceiverDbitList(const std::vector &list) { LOG(logDEBUG1) << "Setting Receiver Dbit List"; if (list.size() > 64) { @@ -2225,631 +1732,29 @@ void Module::setReceiverDbitList(const std::vector &list) { sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr); } -std::vector Module::getReceiverDbitList() const { - return sendToReceiver>( - F_GET_RECEIVER_DBIT_LIST); +int Module::getReceiverDbitOffset() { + return sendToReceiver(F_GET_RECEIVER_DBIT_OFFSET); } void Module::setReceiverDbitOffset(int value) { sendToReceiver(F_SET_RECEIVER_DBIT_OFFSET, value, nullptr); } -int Module::getReceiverDbitOffset() { - return sendToReceiver(F_GET_RECEIVER_DBIT_OFFSET); +void Module::setDigitalIODelay(uint64_t pinMask, int delay) { + uint64_t args[]{pinMask, static_cast(delay)}; + sendToDetector(F_DIGITAL_IO_DELAY, args, nullptr); } -void Module::writeAdcRegister(uint32_t addr, uint32_t val) { - uint32_t args[]{addr, val}; - LOG(logDEBUG1) << "Writing to ADC register 0x" << std::hex << addr - << "data: 0x" << std::hex << val << std::dec; - sendToDetector(F_WRITE_ADC_REG, args, nullptr); -} - -bool Module::getActivate() { - int retval = -1, retval2 = -1; +bool Module::getLEDEnable() { int arg = -1; - sendToDetector(F_ACTIVATE, arg, retval); - sendToDetectorStop(F_ACTIVATE, arg, retval2); - if (retval != retval2) { - std::ostringstream oss; - oss << "Inconsistent activate state. Control Server: " << retval - << ". Stop Server: " << retval2; - throw RuntimeError(oss.str()); - } - return retval; + return static_cast(sendToDetector(F_LED, arg)); } -void Module::setActivate(const bool enable) { - int retval = -1; - int arg = static_cast(enable); - LOG(logDEBUG1) << "Setting activate flag to " << enable; - sendToDetector(F_ACTIVATE, arg, retval); - sendToDetectorStop(F_ACTIVATE, arg, retval); - if (shm()->useReceiverFlag) { - sendToReceiver(F_RECEIVER_ACTIVATE, retval, nullptr); - } +void Module::setLEDEnable(bool enable) { + sendToDetector(F_LED, static_cast(enable)); } -bool Module::getDeactivatedRxrPaddingMode() { - return sendToReceiver(F_GET_RECEIVER_DEACTIVATED_PADDING); -} - -void Module::setDeactivatedRxrPaddingMode(bool padding) { - sendToReceiver(F_SET_RECEIVER_DEACTIVATED_PADDING, - static_cast(padding), nullptr); -} - -bool Module::getFlippedDataX() { - return sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, -1); -} - -void Module::setFlippedDataX(bool value) { - sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, static_cast(value)); -} - -int Module::getAllTrimbits() { - return sendToDetector(F_SET_ALL_TRIMBITS, -1); -} - -void Module::setAllTrimbits(int val) { - sendToDetector(F_SET_ALL_TRIMBITS, val); -} - -int Module::setTrimEn(const std::vector &energies) { - if (shm()->myDetectorType != EIGER) { - throw RuntimeError("setTrimEn not implemented for this detector."); - } - if (energies.size() > MAX_TRIMEN) { - std::ostringstream os; - os << "Size of trim energies: " << energies.size() - << " exceeds what can be stored in shared memory: " << MAX_TRIMEN - << "\n"; - throw RuntimeError(os.str()); - } - shm()->trimEnergies = energies; - return shm()->trimEnergies.size(); -} - -std::vector Module::getTrimEn() { - if (shm()->myDetectorType != EIGER) { - throw RuntimeError("getTrimEn not implemented for this detector."); - } - return std::vector(shm()->trimEnergies.begin(), - shm()->trimEnergies.end()); -} - -void Module::pulsePixel(int n, int x, int y) { - int args[]{n, x, y}; - LOG(logDEBUG1) << "Pulsing pixel " << n << " number of times at (" << x - << "," << y << ")"; - sendToDetector(F_PULSE_PIXEL, args, nullptr); -} - -void Module::pulsePixelNMove(int n, int x, int y) { - int args[]{n, x, y}; - LOG(logDEBUG1) << "Pulsing pixel " << n - << " number of times and move by delta (" << x << "," << y - << ")"; - sendToDetector(F_PULSE_PIXEL_AND_MOVE, args, nullptr); -} - -void Module::pulseChip(int n_pulses) { - LOG(logDEBUG1) << "Pulsing chip " << n_pulses << " number of times"; - sendToDetector(F_PULSE_CHIP, n_pulses, nullptr); -} - -int Module::setThresholdTemperature(int val) { - int retval = -1; - LOG(logDEBUG1) << "Setting threshold temperature to " << val; - sendToDetectorStop(F_THRESHOLD_TEMP, val, retval); - LOG(logDEBUG1) << "Threshold temperature: " << retval; - return retval; -} - -int Module::setTemperatureControl(int val) { - int retval = -1; - LOG(logDEBUG1) << "Setting temperature control to " << val; - sendToDetectorStop(F_TEMP_CONTROL, val, retval); - LOG(logDEBUG1) << "Temperature control: " << retval; - return retval; -} - -int Module::setTemperatureEvent(int val) { - int retval = -1; - LOG(logDEBUG1) << "Setting temperature event to " << val; - sendToDetectorStop(F_TEMP_EVENT, val, retval); - LOG(logDEBUG1) << "Temperature event: " << retval; - return retval; -} - -int Module::setStorageCellStart(int pos) { - return sendToDetector(F_STORAGE_CELL_START, pos); -} - -void Module::programFPGA(std::vector buffer) { - switch (shm()->myDetectorType) { - case JUNGFRAU: - case CHIPTESTBOARD: - case MOENCH: - programFPGAviaBlackfin(buffer); - break; - case MYTHEN3: - case GOTTHARD2: - programFPGAviaNios(buffer); - break; - default: - throw RuntimeError("Program FPGA is not implemented for this detector"); - } -} - -void Module::programFPGAviaBlackfin(std::vector buffer) { - uint64_t filesize = buffer.size(); - - // send program from memory to detector - int fnum = F_PROGRAM_FPGA; - int ret = FAIL; - char mess[MAX_STR_LENGTH] = {0}; - LOG(logINFO) << "Sending programming binary (from pof) to detector " - << detId << " (" << shm()->hostname << ")"; - - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - client.Send(&fnum, sizeof(fnum)); - client.Send(&filesize, sizeof(filesize)); - client.Receive(&ret, sizeof(ret)); - // error in detector at opening file pointer to flash - if (ret == FAIL) { - client.Receive(mess, sizeof(mess)); - std::ostringstream os; - os << "Detector " << detId << " (" << shm()->hostname << ")" - << " returned error: " << mess; - throw RuntimeError(os.str()); - } - - // erasing flash - LOG(logINFO) << "Erasing Flash for detector " << detId << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); - std::cout << std::flush; - // erasing takes 65 seconds, printing here (otherwise need threads - // in server-unnecessary) - const int ERASE_TIME = 65; - int count = ERASE_TIME + 1; - while (count > 0) { - usleep(1 * 1000 * 1000); - --count; - printf( - "%d%%\r", - static_cast( - (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); - std::cout << std::flush; - } - printf("\n"); - LOG(logINFO) << "Writing to Flash to detector " << detId << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); - std::cout << std::flush; - - // sending program in parts of 2mb each - uint64_t unitprogramsize = 0; - int currentPointer = 0; - uint64_t totalsize = filesize; - while (filesize > 0) { - unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb - if (unitprogramsize > filesize) { // less than 2mb - unitprogramsize = filesize; - } - LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize - << "\t filesize:" << filesize; - - client.Send(&buffer[currentPointer], unitprogramsize); - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - printf("\n"); - client.Receive(mess, sizeof(mess)); - std::ostringstream os; - os << "Detector " << detId << " (" << shm()->hostname << ")" - << " returned error: " << mess; - throw RuntimeError(os.str()); - } - filesize -= unitprogramsize; - currentPointer += unitprogramsize; - - // print progress - printf( - "%d%%\r", - static_cast( - (static_cast(totalsize - filesize) / totalsize) * 100)); - std::cout << std::flush; - } - printf("\n"); - LOG(logINFO) << "FPGA programmed successfully"; - rebootController(); -} - -void Module::programFPGAviaNios(std::vector buffer) { - uint64_t filesize = buffer.size(); - int fnum = F_PROGRAM_FPGA; - int ret = FAIL; - char mess[MAX_STR_LENGTH] = {0}; - LOG(logINFO) << "Sending programming binary (from rbf) to detector " - << detId << " (" << shm()->hostname << ")"; - - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - client.Send(&fnum, sizeof(fnum)); - // filesize - client.Send(&filesize, sizeof(filesize)); - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - client.Receive(mess, sizeof(mess)); - std::ostringstream os; - os << "Detector " << detId << " (" << shm()->hostname << ")" - << " returned error: " << mess; - throw RuntimeError(os.str()); - } - // program - client.Send(&buffer[0], filesize); - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - client.Receive(mess, sizeof(mess)); - std::ostringstream os; - os << "Detector " << detId << " (" << shm()->hostname << ")" - << " returned error: " << mess; - throw RuntimeError(os.str()); - } - LOG(logINFO) << "FPGA programmed successfully"; - rebootController(); -} - -void Module::resetFPGA() { return sendToDetector(F_RESET_FPGA); } - -void Module::copyDetectorServer(const std::string &fname, - const std::string &hostname) { - char args[2][MAX_STR_LENGTH]{}; - sls::strcpy_safe(args[0], fname.c_str()); - sls::strcpy_safe(args[1], hostname.c_str()); - LOG(logINFO) << "Sending detector server " << args[0] << " from host " - << args[1]; - sendToDetector(F_COPY_DET_SERVER, args, nullptr); -} - -void Module::rebootController() { - LOG(logDEBUG1) << "Rebooting Controller"; - sendToDetector(F_REBOOT_CONTROLLER, nullptr, nullptr); - LOG(logINFO) << "Controller rebooted successfully!"; -} - -int Module::powerChip(int ival) { - return sendToDetector(F_POWER_CHIP, ival); -} - -int Module::setAutoComparatorDisableMode(int ival) { - return sendToDetector(F_AUTO_COMP_DISABLE, ival); -} - -void Module::setModule(sls_detector_module &module, int tb) { - int fnum = F_SET_MODULE; - int ret = FAIL; - LOG(logDEBUG1) << "Setting module with tb:" << tb; - // to exclude trimbits - if (tb == 0) { - module.nchan = 0; - module.nchip = 0; - } - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - client.Send(&fnum, sizeof(fnum)); - sendModule(&module, client); - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - char mess[MAX_STR_LENGTH] = {0}; - client.Receive(mess, sizeof(mess)); - throw RuntimeError("Detector " + std::to_string(detId) + - " returned error: " + mess); - } -} - -sls_detector_module Module::getModule() { - int fnum = F_GET_MODULE; - LOG(logDEBUG1) << "Getting module"; - sls_detector_module myMod{shm()->myDetectorType}; - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); - receiveModule(&myMod, client); - return myMod; -} - -void Module::setDefaultRateCorrection() { - LOG(logDEBUG1) << "Setting Default Rate Correction"; - int64_t arg = -1; - sendToDetector(F_SET_RATE_CORRECT, arg, nullptr); -} - -void Module::setRateCorrection(int64_t t) { - LOG(logDEBUG1) << "Setting Rate Correction to " << t; - sendToDetector(F_SET_RATE_CORRECT, t, nullptr); -} - -int64_t Module::getRateCorrection() { - return sendToDetector(F_GET_RATE_CORRECT); -} - -void Module::updateRateCorrection() { - sendToDetector(F_UPDATE_RATE_CORRECTION); -} - -std::string Module::printReceiverConfiguration() { - std::ostringstream os; - os << "\n\nDetector " << detId << "\nReceiver Hostname:\t" - << getReceiverHostname(); - - if (shm()->myDetectorType == JUNGFRAU) { - os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfaces() - << "\nSelected Interface:\t" << getSelectedUDPInterface(); - } - - os << "\nDetector UDP IP:\t" << getSourceUDPIP() << "\nDetector UDP MAC:\t" - << getSourceUDPMAC() << "\nReceiver UDP IP:\t" << getDestinationUDPIP() - << "\nReceiver UDP MAC:\t" << getDestinationUDPMAC(); - - if (shm()->myDetectorType == JUNGFRAU) { - os << "\nDetector UDP IP2:\t" << getSourceUDPIP2() - << "\nDetector UDP MAC2:\t" << getSourceUDPMAC2() - << "\nReceiver UDP IP2:\t" << getDestinationUDPIP2() - << "\nReceiver UDP MAC2:\t" << getDestinationUDPMAC2(); - } - os << "\nReceiver UDP Port:\t" << getDestinationUDPPort(); - if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) { - os << "\nReceiver UDP Port2:\t" << getDestinationUDPPort2(); - } - os << "\n"; - return os.str(); -} - -bool Module::getUseReceiverFlag() const { return shm()->useReceiverFlag; } - -int Module::lockReceiver(int lock) { - return sendToReceiver(F_LOCK_RECEIVER, lock); -} - -sls::IpAddr Module::getReceiverLastClientIP() const { - return sendToReceiver(F_GET_LAST_RECEIVER_CLIENT_IP); -} - -std::array Module::getReceiverThreadIds() const { - return sendToReceiver>( - F_GET_RECEIVER_THREAD_IDS); -} - -void Module::exitReceiver() { - LOG(logDEBUG1) << "Sending exit command to receiver server"; - sendToReceiver(F_EXIT_RECEIVER, nullptr, nullptr); -} - -std::string Module::getFilePath() { - char ret[MAX_STR_LENGTH]{}; - sendToReceiver(F_GET_RECEIVER_FILE_PATH, nullptr, ret); - return ret; -} - -void Module::setFilePath(const std::string &path) { - if (path.empty()) { - throw RuntimeError("Cannot set empty file path"); - } - char args[MAX_STR_LENGTH]{}; - sls::strcpy_safe(args, path.c_str()); - sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr); -} - -std::string Module::getFileName() { - char retvals[MAX_STR_LENGTH]{}; - sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, retvals); - return std::string(retvals); -} - -void Module::setFileName(const std::string &fname) { - if (fname.empty()) { - throw RuntimeError("Cannot set empty file name prefix"); - } - char args[MAX_STR_LENGTH]{}; - sls::strcpy_safe(args, fname.c_str()); - sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr); -} - -int64_t Module::getFileIndex() { - return sendToReceiver(F_GET_RECEIVER_FILE_INDEX); -} - -void Module::setFileIndex(int64_t file_index) { - sendToReceiver(F_SET_RECEIVER_FILE_INDEX, file_index, nullptr); -} - -void Module::incrementFileIndex() { - sendToReceiver(F_INCREMENT_FILE_INDEX, nullptr, nullptr); -} - -slsDetectorDefs::fileFormat Module::getFileFormat() { - return static_cast( - sendToReceiver(F_GET_RECEIVER_FILE_FORMAT)); -} - -void Module::setFileFormat(fileFormat f) { - sendToReceiver(F_SET_RECEIVER_FILE_FORMAT, static_cast(f), nullptr); -} - -int Module::getFramesPerFile() { - return sendToReceiver(F_GET_RECEIVER_FRAMES_PER_FILE); -} - -void Module::setFramesPerFile(int n_frames) { - sendToReceiver(F_SET_RECEIVER_FRAMES_PER_FILE, n_frames, nullptr); -} - -slsDetectorDefs::frameDiscardPolicy Module::getReceiverFramesDiscardPolicy() { - return static_cast( - sendToReceiver(F_GET_RECEIVER_DISCARD_POLICY)); -} - -void Module::setReceiverFramesDiscardPolicy(frameDiscardPolicy f) { - sendToReceiver(F_SET_RECEIVER_DISCARD_POLICY, static_cast(f), nullptr); -} - -bool Module::getPartialFramesPadding() { - return sendToReceiver(F_GET_RECEIVER_PADDING); -} - -void Module::setPartialFramesPadding(bool padding) { - sendToReceiver(F_SET_RECEIVER_PADDING, static_cast(padding), nullptr); -} - -void Module::startReceiver() { - LOG(logDEBUG1) << "Starting Receiver"; - shm()->stoppedFlag = false; - sendToReceiver(F_START_RECEIVER, nullptr, nullptr); -} - -void Module::stopReceiver() { - LOG(logDEBUG1) << "Stopping Receiver"; - int arg = static_cast(shm()->stoppedFlag); - sendToReceiver(F_STOP_RECEIVER, arg, nullptr); -} - -slsDetectorDefs::runStatus Module::getReceiverStatus() const { - return sendToReceiver(F_GET_RECEIVER_STATUS); -} - -int64_t Module::getFramesCaughtByReceiver() const { - return sendToReceiver(F_GET_RECEIVER_FRAMES_CAUGHT); -} - -std::vector Module::getNumMissingPackets() const { - // TODO!(Erik) Refactor - LOG(logDEBUG1) << "Getting num missing packets"; - if (shm()->useReceiverFlag) { - int fnum = F_GET_NUM_MISSING_PACKETS; - int ret = FAIL; - auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); - client.Send(&fnum, sizeof(fnum)); - client.Receive(&ret, sizeof(ret)); - if (ret == FAIL) { - char mess[MAX_STR_LENGTH]{}; - client.Receive(mess, MAX_STR_LENGTH); - throw RuntimeError("Receiver " + std::to_string(detId) + - " returned error: " + std::string(mess)); - } else { - int nports = -1; - client.Receive(&nports, sizeof(nports)); - uint64_t mp[nports]; - memset(mp, 0, sizeof(mp)); - client.Receive(mp, sizeof(mp)); - std::vector retval(mp, mp + nports); - LOG(logDEBUG1) << "Missing packets of Receiver" << detId << ": " - << sls::ToString(retval); - return retval; - } - } - throw RuntimeError("No receiver to get missing packets."); -} - -uint64_t Module::getReceiverCurrentFrameIndex() const { - return sendToReceiver(F_GET_RECEIVER_FRAME_INDEX); -} - -int Module::getReceiverProgress() const { - return sendToReceiver(F_GET_RECEIVER_PROGRESS); -} - -void Module::setFileWrite(bool value) { - sendToReceiver(F_SET_RECEIVER_FILE_WRITE, static_cast(value), nullptr); -} - -bool Module::getFileWrite() { - return sendToReceiver(F_GET_RECEIVER_FILE_WRITE); -} - -void Module::setMasterFileWrite(bool value) { - sendToReceiver(F_SET_RECEIVER_MASTER_FILE_WRITE, static_cast(value), - nullptr); -} - -bool Module::getMasterFileWrite() { - return sendToReceiver(F_GET_RECEIVER_MASTER_FILE_WRITE); -} - -void Module::setFileOverWrite(bool value) { - sendToReceiver(F_SET_RECEIVER_OVERWRITE, static_cast(value), nullptr); -} - -bool Module::getFileOverWrite() { - return sendToReceiver(F_GET_RECEIVER_OVERWRITE); -} - -int Module::getReceiverStreamingFrequency() { - return sendToReceiver(F_GET_RECEIVER_STREAMING_FREQUENCY); -} - -void Module::setReceiverStreamingFrequency(int freq) { - if (freq < 0) { - throw RuntimeError("Invalid streaming frequency " + - std::to_string(freq)); - } - sendToReceiver(F_SET_RECEIVER_STREAMING_FREQUENCY, freq, nullptr); -} - -int Module::setReceiverStreamingTimer(int time_in_ms) { - return sendToReceiver(F_RECEIVER_STREAMING_TIMER, time_in_ms); -} - -bool Module::getReceiverStreaming() { - return sendToReceiver(F_GET_RECEIVER_STREAMING); -} - -void Module::setReceiverStreaming(bool enable) { - sendToReceiver(F_SET_RECEIVER_STREAMING, static_cast(enable), nullptr); -} - -bool Module::enableTenGigabitEthernet(int value) { - int retval = -1; - LOG(logDEBUG1) << "Enabling / Disabling 10Gbe: " << value; - sendToDetector(F_ENABLE_TEN_GIGA, value, retval); - if (value != -1) { - int stopRetval = -1; - sendToDetectorStop(F_ENABLE_TEN_GIGA, value, stopRetval); - } - LOG(logDEBUG1) << "10Gbe: " << retval; - value = retval; - if (shm()->useReceiverFlag && value != -1) { - int retval = -1; - LOG(logDEBUG1) << "Sending 10Gbe enable to receiver: " << value; - sendToReceiver(F_ENABLE_RECEIVER_TEN_GIGA, value, retval); - LOG(logDEBUG1) << "Receiver 10Gbe enable: " << retval; - } - return static_cast(retval); -} - -int Module::setReceiverFifoDepth(int n_frames) { - int retval = -1; - LOG(logDEBUG1) << "Sending Receiver Fifo Depth: " << n_frames; - if (shm()->useReceiverFlag) { - sendToReceiver(F_SET_RECEIVER_FIFO_DEPTH, n_frames, retval); - LOG(logDEBUG1) << "Receiver Fifo Depth: " << retval; - } - return retval; -} - -bool Module::getReceiverSilentMode() { - return sendToReceiver(F_GET_RECEIVER_SILENT_MODE); -} - -void Module::setReceiverSilentMode(bool enable) { - sendToReceiver(F_SET_RECEIVER_SILENT_MODE, static_cast(enable), - nullptr); -} - -void Module::restreamStopFromReceiver() { - LOG(logDEBUG1) << "Restream stop dummy from Receiver via zmq"; - if (shm()->useReceiverFlag) { - sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER, nullptr, nullptr); - } -} +// Pattern void Module::setPattern(const std::string &fname) { uint64_t word; @@ -2867,161 +1772,912 @@ void Module::setPattern(const std::string &fname) { } } -uint64_t Module::setPatternIOControl(uint64_t word) { - LOG(logDEBUG1) << "Setting Pattern IO Control, word: 0x" << std::hex << word - << std::dec; - return sendToDetector(F_SET_PATTERN_IO_CONTROL, word); +uint64_t Module::getPatternIOControl() { + int64_t arg = -1; + return sendToDetector(F_SET_PATTERN_IO_CONTROL, arg); } -uint64_t Module::setPatternClockControl(uint64_t word) { - LOG(logDEBUG1) << "Setting Pattern Clock Control, word: 0x" << std::hex - << word << std::dec; - return sendToDetector(F_SET_PATTERN_CLOCK_CONTROL, word); +void Module::setPatternIOControl(uint64_t word) { + sendToDetector(F_SET_PATTERN_IO_CONTROL, word); } -uint64_t Module::setPatternWord(int addr, uint64_t word) { - uint64_t args[]{static_cast(addr), word}; +uint64_t Module::getPatternClockControl() { + int64_t arg = -1; + return sendToDetector(F_SET_PATTERN_CLOCK_CONTROL, arg); +} - LOG(logDEBUG1) << "Setting Pattern word, addr: 0x" << std::hex << addr - << ", word: 0x" << word << std::dec; +void Module::setPatternClockControl(uint64_t word) { + sendToDetector(F_SET_PATTERN_CLOCK_CONTROL, word); +} + +uint64_t Module::getPatternWord(int addr) { + uint64_t args[]{static_cast(addr), static_cast(-1)}; return sendToDetector(F_SET_PATTERN_WORD, args); } -std::array Module::setPatternLoopAddresses(int level, int start, - int stop) { - int args[]{level, start, stop}; +void Module::setPatternWord(int addr, uint64_t word) { + uint64_t args[]{static_cast(addr), word}; + sendToDetector(F_SET_PATTERN_WORD, args); +} + +std::array Module::getPatternLoopAddresses(int level) { + int args[]{level, -1, -1}; std::array retvals{}; - LOG(logDEBUG1) << "Setting Pat Loop Addresses, level: " << level - << ", start: " << start << ", stop: " << stop; sendToDetector(F_SET_PATTERN_LOOP_ADDRESSES, args, retvals); - LOG(logDEBUG1) << "Set Pat Loop Addresses: " << retvals[0] << ", " - << retvals[1]; return retvals; } -int Module::setPatternLoopCycles(int level, int n) { - int args[]{level, n}; - LOG(logDEBUG1) << "Setting Pat Loop cycles, level: " << level - << ",nloops: " << n; +void Module::setPatternLoopAddresses(int level, int start, int stop) { + int args[]{level, start, stop}; + std::array retvals{}; + sendToDetector(F_SET_PATTERN_LOOP_ADDRESSES, args, retvals); +} + +int Module::getPatternLoopCycles(int level) { + int args[]{level, -1}; return sendToDetector(F_SET_PATTERN_LOOP_CYCLES, args); } -int Module::setPatternWaitAddr(int level, int addr) { - int args[]{level, addr}; - LOG(logDEBUG1) << "Setting Pat Wait Addr, level: " << level << ", addr: 0x" - << std::hex << addr << std::dec; +void Module::setPatternLoopCycles(int level, int n) { + int args[]{level, n}; + sendToDetector(F_SET_PATTERN_LOOP_CYCLES, args); +} + +int Module::getPatternWaitAddr(int level) { + int args[]{level, -1}; return sendToDetector(F_SET_PATTERN_WAIT_ADDR, args); } -uint64_t Module::setPatternWaitTime(int level, uint64_t t) { - uint64_t args[]{static_cast(level), t}; +void Module::setPatternWaitAddr(int level, int addr) { + int args[]{level, addr}; + sendToDetector(F_SET_PATTERN_WAIT_ADDR, args); +} + +uint64_t Module::getPatternWaitTime(int level) { + uint64_t args[]{static_cast(level), static_cast(-1)}; return sendToDetector(F_SET_PATTERN_WAIT_TIME, args); } -void Module::setPatternMask(uint64_t mask) { - LOG(logDEBUG1) << "Setting Pattern Mask " << std::hex << mask << std::dec; - sendToDetector(F_SET_PATTERN_MASK, mask, nullptr); +void Module::setPatternWaitTime(int level, uint64_t t) { + uint64_t args[]{static_cast(level), t}; + sendToDetector(F_SET_PATTERN_WAIT_TIME, args); } uint64_t Module::getPatternMask() { return sendToDetector(F_GET_PATTERN_MASK); } -void Module::setPatternBitMask(uint64_t mask) { - LOG(logDEBUG1) << "Setting Pattern Bit Mask " << std::hex << mask - << std::dec; - sendToDetector(F_SET_PATTERN_BIT_MASK, mask, nullptr); - LOG(logDEBUG1) << "Pattern Bit Mask successful"; +void Module::setPatternMask(uint64_t mask) { + sendToDetector(F_SET_PATTERN_MASK, mask, nullptr); } uint64_t Module::getPatternBitMask() { return sendToDetector(F_GET_PATTERN_BIT_MASK); } +void Module::setPatternBitMask(uint64_t mask) { + sendToDetector(F_SET_PATTERN_BIT_MASK, mask, nullptr); +} + void Module::startPattern() { sendToDetector(F_START_PATTERN); } -int Module::setLEDEnable(int enable) { - return sendToDetector(F_LED, enable); -} +// Moench -void Module::setDigitalIODelay(uint64_t pinMask, int delay) { - uint64_t args[]{pinMask, static_cast(delay)}; - LOG(logDEBUG1) << "Sending Digital IO Delay, pin mask: " << std::hex - << args[0] << ", delay: " << std::dec << args[1] << " ps"; - sendToDetector(F_DIGITAL_IO_DELAY, args, nullptr); - LOG(logDEBUG1) << "Digital IO Delay successful"; -} - -int Module::getClockFrequency(int clkIndex) { - return sendToDetector(F_GET_CLOCK_FREQUENCY, clkIndex); -} - -void Module::setClockFrequency(int clkIndex, int value) { - int args[]{clkIndex, value}; - LOG(logDEBUG1) << "Setting Clock " << clkIndex << " frequency to " << value; - sendToDetector(F_SET_CLOCK_FREQUENCY, args, nullptr); -} - -int Module::getClockPhase(int clkIndex, bool inDegrees) { - int args[]{clkIndex, static_cast(inDegrees)}; - int retval = -1; - LOG(logDEBUG1) << "Getting Clock " << clkIndex << " phase " - << (inDegrees ? "in degrees" : ""); - sendToDetector(F_GET_CLOCK_PHASE, args, retval); - LOG(logDEBUG1) << "Clock " << clkIndex << " frequency: " << retval - << (inDegrees ? "degrees" : ""); - return retval; -} - -void Module::setClockPhase(int clkIndex, int value, bool inDegrees) { - int args[]{clkIndex, value, static_cast(inDegrees)}; - LOG(logDEBUG1) << "Setting Clock " << clkIndex << " phase to " << value - << (inDegrees ? "degrees" : ""); - sendToDetector(F_SET_CLOCK_PHASE, args, nullptr); -} - -int Module::getMaxClockPhaseShift(int clkIndex) { - return sendToDetector(F_GET_MAX_CLOCK_PHASE_SHIFT, clkIndex); -} - -int Module::getClockDivider(int clkIndex) { - return sendToDetector(F_GET_CLOCK_DIVIDER, clkIndex); -} - -void Module::setClockDivider(int clkIndex, int value) { - int args[]{clkIndex, value}; - LOG(logDEBUG1) << "Setting Clock " << clkIndex << " divider to " << value; - sendToDetector(F_SET_CLOCK_DIVIDER, args, nullptr); -} - -int Module::getPipeline(int clkIndex) { - return sendToDetector(F_GET_PIPELINE, clkIndex); -} - -void Module::setPipeline(int clkIndex, int value) { - int args[]{clkIndex, value}; - LOG(logDEBUG1) << "Setting Clock " << clkIndex << " pipeline to " << value; - sendToDetector(F_SET_PIPELINE, args, nullptr); -} - -void Module::setCounterMask(uint32_t countermask) { - LOG(logDEBUG1) << "Setting Counter mask to " << countermask; - sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr); - if (shm()->useReceiverFlag) { - int ncounters = __builtin_popcount(countermask); - LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters; - sendToReceiver(F_RECEIVER_SET_NUM_COUNTERS, ncounters, nullptr); +std::map Module::getAdditionalJsonHeader() { + if (!shm()->useReceiverFlag) { + throw RuntimeError("Set rx_hostname first to use receiver parameters " + "(zmq json header)"); + } + int fnum = F_GET_ADDITIONAL_JSON_HEADER; + int ret = FAIL; + int size = 0; + auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + client.Send(&fnum, sizeof(fnum)); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + char mess[MAX_STR_LENGTH]{}; + client.Receive(mess, MAX_STR_LENGTH); + throw RuntimeError("Receiver " + std::to_string(moduleId) + + " returned error: " + std::string(mess)); + } else { + client.Receive(&size, sizeof(size)); + std::map retval; + if (size > 0) { + char retvals[size * 2][SHORT_STR_LENGTH]; + memset(retvals, 0, sizeof(retvals)); + client.Receive(retvals, sizeof(retvals)); + for (int i = 0; i < size; ++i) { + retval[retvals[2 * i]] = retvals[2 * i + 1]; + } + } + LOG(logDEBUG) << "Getting additional json header " << ToString(retval); + return retval; } } -uint32_t Module::getCounterMask() { - return sendToDetector(F_GET_COUNTER_MASK); +void Module::setAdditionalJsonHeader( + const std::map &jsonHeader) { + if (!shm()->useReceiverFlag) { + throw RuntimeError("Set rx_hostname first to use receiver parameters " + "(zmq json header)"); + } + for (auto &it : jsonHeader) { + if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH || + it.second.length() > SHORT_STR_LENGTH) { + throw RuntimeError( + it.first + " or " + it.second + + " pair has invalid size. " + "Key cannot be empty. Both can have max 20 characters"); + } + } + const int size = jsonHeader.size(); + int fnum = F_SET_ADDITIONAL_JSON_HEADER; + int ret = FAIL; + LOG(logDEBUG) << "Sending to receiver additional json header " + << ToString(jsonHeader); + auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + client.Send(&fnum, sizeof(fnum)); + client.Send(&size, sizeof(size)); + if (size > 0) { + char args[size * 2][SHORT_STR_LENGTH]; + memset(args, 0, sizeof(args)); + int iarg = 0; + for (auto &it : jsonHeader) { + sls::strcpy_safe(args[iarg], it.first.c_str()); + sls::strcpy_safe(args[iarg + 1], it.second.c_str()); + iarg += 2; + } + client.Send(args, sizeof(args)); + } + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + char mess[MAX_STR_LENGTH]{}; + client.Receive(mess, MAX_STR_LENGTH); + throw RuntimeError("Receiver " + std::to_string(moduleId) + + " returned error: " + std::string(mess)); + } +} + +std::string Module::getAdditionalJsonParameter(const std::string &key) { + char arg[SHORT_STR_LENGTH]{}; + sls::strcpy_safe(arg, key.c_str()); + char retval[SHORT_STR_LENGTH]{}; + sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval); + return retval; +} + +void Module::setAdditionalJsonParameter(const std::string &key, + const std::string &value) { + if (key.empty() || key.length() > SHORT_STR_LENGTH || + value.length() > SHORT_STR_LENGTH) { + throw RuntimeError( + key + " or " + value + + " pair has invalid size. " + "Key cannot be empty. Both can have max 2 characters"); + } + char args[2][SHORT_STR_LENGTH]{}; + sls::strcpy_safe(args[0], key.c_str()); + sls::strcpy_safe(args[1], value.c_str()); + sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr); +} + +// Advanced + +void Module::programFPGA(std::vector buffer) { + switch (shm()->myDetectorType) { + case JUNGFRAU: + case CHIPTESTBOARD: + case MOENCH: + programFPGAviaBlackfin(buffer); + break; + case MYTHEN3: + case GOTTHARD2: + programFPGAviaNios(buffer); + break; + default: + throw RuntimeError("Program FPGA is not implemented for this detector"); + } +} + +void Module::resetFPGA() { return sendToDetector(F_RESET_FPGA); } + +void Module::copyDetectorServer(const std::string &fname, + const std::string &hostname) { + char args[2][MAX_STR_LENGTH]{}; + sls::strcpy_safe(args[0], fname.c_str()); + sls::strcpy_safe(args[1], hostname.c_str()); + LOG(logINFO) << "Sending detector server " << args[0] << " from host " + << args[1]; + sendToDetector(F_COPY_DET_SERVER, args, nullptr); +} + +void Module::rebootController() { + sendToDetector(F_REBOOT_CONTROLLER, nullptr, nullptr); + LOG(logINFO) << "Controller rebooted successfully!"; +} + +uint32_t Module::readRegister(uint32_t addr) { + return sendToDetectorStop(F_READ_REGISTER, addr); +} + +uint32_t Module::writeRegister(uint32_t addr, uint32_t val) { + uint32_t args[]{addr, val}; + return sendToDetectorStop(F_WRITE_REGISTER, args); +} + +uint32_t Module::setBit(uint32_t addr, int n) { + if (n < 0 || n > 31) { + throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); + } else { + uint32_t val = readRegister(addr); + return writeRegister(addr, val | 1 << n); + } +} + +uint32_t Module::clearBit(uint32_t addr, int n) { + if (n < 0 || n > 31) { + throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); + } else { + uint32_t val = readRegister(addr); + return writeRegister(addr, val & ~(1 << n)); + } +} + +void Module::executeFirmwareTest() { sendToDetector(F_SET_FIRMWARE_TEST); } + +void Module::executeBusTest() { sendToDetector(F_SET_BUS_TEST); } + +void Module::writeAdcRegister(uint32_t addr, uint32_t val) { + uint32_t args[]{addr, val}; + sendToDetector(F_WRITE_ADC_REG, args, nullptr); +} + +uint32_t Module::getADCInvert() { + return sendToDetector(F_GET_ADC_INVERT); +} + +void Module::setADCInvert(uint32_t value) { + sendToDetector(F_SET_ADC_INVERT, value, nullptr); +} + +// Insignificant + +int Module::getControlPort() const { return shm()->controlPort; } + +int Module::setControlPort(int port_number) { + if (port_number >= 0 && port_number != shm()->controlPort) { + if (strlen(shm()->hostname) > 0) { + shm()->controlPort = sendToDetector(F_SET_PORT, port_number); + } else { + shm()->controlPort = port_number; + } + } + return shm()->controlPort; +} + +int Module::getStopPort() const { return shm()->stopPort; } + +int Module::setStopPort(int port_number) { + if (port_number >= 0 && port_number != shm()->stopPort) { + if (strlen(shm()->hostname) > 0) { + shm()->stopPort = sendToDetectorStop(F_SET_PORT, port_number); + } else { + shm()->stopPort = port_number; + } + } + return shm()->stopPort; +} + +bool Module::getLockDetector() { + int arg = -1; + return static_cast(sendToDetector(F_LOCK_SERVER, arg)); +} + +void Module::setLockDetector(bool lock) { + sendToDetector(F_LOCK_SERVER, static_cast(lock)); +} + +sls::IpAddr Module::getLastClientIP() { + return sendToDetector(F_GET_LAST_CLIENT_IP); +} + +std::string Module::execCommand(const std::string &cmd) { + char arg[MAX_STR_LENGTH]{}; + char retval[MAX_STR_LENGTH]{}; + sls::strcpy_safe(arg, cmd.c_str()); + sendToDetector(F_EXEC_COMMAND, arg, retval); + return std::string(retval); +} + +int64_t Module::getNumberOfFramesFromStart() const { + return sendToDetectorStop(F_GET_FRAMES_FROM_START); +} + +int64_t Module::getActualTime() const { + return sendToDetectorStop(F_GET_ACTUAL_TIME); +} + +int64_t Module::getMeasurementTime() const { + return sendToDetectorStop(F_GET_MEASUREMENT_TIME); +} + +uint64_t Module::getReceiverCurrentFrameIndex() const { + return sendToReceiver(F_GET_RECEIVER_FRAME_INDEX); +} + +// private + +void Module::sendToDetector(int fnum, const void *args, size_t args_size, + void *retval, size_t retval_size) { + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.sendCommandThenRead(fnum, args, args_size, retval, retval_size); + client.close(); +} + +template +void Module::sendToDetector(int fnum, const Arg &args, Ret &retval) { + LOG(logDEBUG1) << "Sending: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + sendToDetector(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +template +void Module::sendToDetector(int fnum, const Arg &args, std::nullptr_t) { + LOG(logDEBUG1) << "Sending: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << typeid(Arg).name() << ", " << sizeof(Arg) + << ", nullptr, 0 ]"; + sendToDetector(fnum, &args, sizeof(args), nullptr, 0); +} + +template +void Module::sendToDetector(int fnum, std::nullptr_t, Ret &retval) { + LOG(logDEBUG1) << "Sending: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + sendToDetector(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +void Module::sendToDetector(int fnum) { + LOG(logDEBUG1) << "Sending: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << "]"; + sendToDetector(fnum, nullptr, 0, nullptr, 0); +} + +template Ret Module::sendToDetector(int fnum) { + LOG(logDEBUG1) << "Sending: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + Ret retval{}; + sendToDetector(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); + return retval; +} + +template +Ret Module::sendToDetector(int fnum, const Arg &args) { + LOG(logDEBUG1) << "Sending: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + Ret retval{}; + sendToDetector(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); + return retval; +} + +void Module::sendToDetectorStop(int fnum, const void *args, size_t args_size, + void *retval, size_t retval_size) { + static_cast(*this).sendToDetectorStop(fnum, args, args_size, + retval, retval_size); +} + +void Module::sendToDetectorStop(int fnum, const void *args, size_t args_size, + void *retval, size_t retval_size) const { + auto stop = DetectorSocket(shm()->hostname, shm()->stopPort); + stop.sendCommandThenRead(fnum, args, args_size, retval, retval_size); + stop.close(); +} + +template +void Module::sendToDetectorStop(int fnum, const Arg &args, Ret &retval) { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + sendToDetectorStop(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +template +void Module::sendToDetectorStop(int fnum, const Arg &args, Ret &retval) const { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + sendToDetectorStop(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +template +void Module::sendToDetectorStop(int fnum, const Arg &args, std::nullptr_t) { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << typeid(Arg).name() << ", " << sizeof(Arg) + << ", nullptr, 0 ]"; + sendToDetectorStop(fnum, &args, sizeof(args), nullptr, 0); +} + +template +void Module::sendToDetectorStop(int fnum, const Arg &args, + std::nullptr_t) const { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << typeid(Arg).name() << ", " << sizeof(Arg) + << ", nullptr, 0 ]"; + sendToDetectorStop(fnum, &args, sizeof(args), nullptr, 0); +} + +template +void Module::sendToDetectorStop(int fnum, std::nullptr_t, Ret &retval) { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + sendToDetectorStop(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; +} + +template +void Module::sendToDetectorStop(int fnum, std::nullptr_t, Ret &retval) const { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + sendToDetectorStop(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; +} + +void Module::sendToDetectorStop(int fnum) { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, nullptr, 0]"; + sendToDetectorStop(fnum, nullptr, 0, nullptr, 0); +} + +void Module::sendToDetectorStop(int fnum) const { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, nullptr, 0]"; + sendToDetectorStop(fnum, nullptr, 0, nullptr, 0); +} + +template Ret Module::sendToDetectorStop(int fnum) { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + Ret retval{}; + sendToDetectorStop(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; + return retval; +} + +template Ret Module::sendToDetectorStop(int fnum) const { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + Ret retval{}; + sendToDetectorStop(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; + return retval; +} + +template +Ret Module::sendToDetectorStop(int fnum, const Arg &args) { + LOG(logDEBUG1) << "Sending to Stop: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + Ret retval{}; + sendToDetectorStop(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); + return retval; +} + +void Module::sendToReceiver(int fnum, const void *args, size_t args_size, + void *retval, size_t retval_size) { + static_cast(*this).sendToReceiver(fnum, args, args_size, + retval, retval_size); +} + +void Module::sendToReceiver(int fnum, const void *args, size_t args_size, + void *retval, size_t retval_size) const { + if (!shm()->useReceiverFlag) { + std::ostringstream oss; + oss << "Set rx_hostname first to use receiver parameters, "; + oss << getFunctionNameFromEnum(static_cast(fnum)); + throw RuntimeError(oss.str()); + } + auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + receiver.sendCommandThenRead(fnum, args, args_size, retval, retval_size); + receiver.close(); +} + +template +void Module::sendToReceiver(int fnum, const Arg &args, Ret &retval) { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; +} + +template +void Module::sendToReceiver(int fnum, const Arg &args, Ret &retval) const { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +template +void Module::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << typeid(Arg).name() << ", " << sizeof(Arg) + << ", nullptr, 0 ]"; + sendToReceiver(fnum, &args, sizeof(args), nullptr, 0); +} + +template +void Module::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << typeid(Arg).name() << ", " << sizeof(Arg) + << ", nullptr, 0 ]"; + sendToReceiver(fnum, &args, sizeof(args), nullptr, 0); +} + +template +void Module::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +template +void Module::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); +} + +template Ret Module::sendToReceiver(int fnum) { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + Ret retval{}; + sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; + return retval; +} + +template Ret Module::sendToReceiver(int fnum) const { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", nullptr, 0, " << typeid(Ret).name() << ", " + << sizeof(Ret) << "]"; + Ret retval{}; + sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << ToString(retval); + return retval; +} + +template +Ret Module::sendToReceiver(int fnum, const Arg &args) { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + Ret retval{}; + sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; + return retval; +} + +template +Ret Module::sendToReceiver(int fnum, const Arg &args) const { + LOG(logDEBUG1) << "Sending to Receiver: [" + << getFunctionNameFromEnum(static_cast(fnum)) + << ", " << args << ", " << sizeof(args) << ", " + << typeid(Ret).name() << ", " << sizeof(Ret) << "]"; + Ret retval{}; + sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval)); + LOG(logDEBUG1) << "Got back: " << retval; + return retval; +} + +slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id, + bool verify) { + if (!shm.IsExisting()) { + throw SharedMemoryError("Shared memory " + shm.GetName() + + "does not exist.\n Corrupted Multi Shared " + "memory. Please free shared memory."); + } + + shm.OpenSharedMemory(); + if (verify && shm()->shmversion != SLS_SHMVERSION) { + std::ostringstream ss; + ss << "Single shared memory (" << det_id << "-" << moduleId + << ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION + << " but got 0x" << shm()->shmversion << ")" << std::dec + << ". Clear Shared memory to continue."; + shm.UnmapSharedMemory(); + throw SharedMemoryError(ss.str()); + } + auto type = shm()->myDetectorType; + return type; +} + +void Module::initSharedMemory(detectorType type, int det_id, bool verify) { + shm = SharedMemory(det_id, moduleId); + if (!shm.IsExisting()) { + shm.CreateSharedMemory(); + initializeDetectorStructure(type); + } else { + shm.OpenSharedMemory(); + if (verify && shm()->shmversion != SLS_SHMVERSION) { + std::ostringstream ss; + ss << "Single shared memory (" << det_id << "-" << moduleId + << ":) version mismatch (expected 0x" << std::hex + << SLS_SHMVERSION << " but got 0x" << shm()->shmversion << ")" + << std::dec << ". Clear Shared memory to continue."; + throw SharedMemoryError(ss.str()); + } + } +} + +void Module::initializeDetectorStructure(detectorType type) { + shm()->shmversion = SLS_SHMVERSION; + memset(shm()->hostname, 0, MAX_STR_LENGTH); + shm()->myDetectorType = type; + shm()->numberOfDetector.x = 0; + shm()->numberOfDetector.y = 0; + shm()->controlPort = DEFAULT_PORTNO; + shm()->stopPort = DEFAULT_PORTNO + 1; + sls::strcpy_safe(shm()->settingsDir, getenv("HOME")); + sls::strcpy_safe(shm()->rxHostname, "none"); + shm()->rxTCPPort = DEFAULT_PORTNO + 2; + shm()->useReceiverFlag = false; + shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO + + (moduleId * ((shm()->myDetectorType == EIGER) ? 2 : 1)); + shm()->zmqip = IpAddr{}; + shm()->numUDPInterfaces = 1; + shm()->stoppedFlag = false; + + // get the detector parameters based on type + detParameters parameters{type}; + shm()->nChan.x = parameters.nChanX; + shm()->nChan.y = parameters.nChanY; + shm()->nChip.x = parameters.nChipX; + shm()->nChip.y = parameters.nChipY; + shm()->nDacs = parameters.nDacs; +} + +void Module::checkDetectorVersionCompatibility() { + int64_t arg = 0; + switch (shm()->myDetectorType) { + case EIGER: + arg = APIEIGER; + break; + case JUNGFRAU: + arg = APIJUNGFRAU; + break; + case GOTTHARD: + arg = APIGOTTHARD; + break; + case CHIPTESTBOARD: + arg = APICTB; + break; + case MOENCH: + arg = APIMOENCH; + break; + case MYTHEN3: + arg = APIMYTHEN3; + break; + case GOTTHARD2: + arg = APIGOTTHARD2; + break; + default: + throw NotImplementedError( + "Check version compatibility is not implemented for this detector"); + } + sendToDetector(F_CHECK_VERSION, arg, nullptr); + sendToDetectorStop(F_CHECK_VERSION, arg, nullptr); +} + +void Module::checkReceiverVersionCompatibility() { + // TODO! Verify that this works as intended when version don't match + int64_t arg = APIRECEIVER; + sendToReceiver(F_RECEIVER_CHECK_VERSION, arg, nullptr); +} + +void Module::restreamStopFromReceiver() { + sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER, nullptr, nullptr); +} + +int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) { + TLogLevel level = logDEBUG1; + LOG(level) << "Sending Module"; + int ts = 0; + int n = 0; + n = client.Send(&(myMod->serialnumber), sizeof(myMod->serialnumber)); + ts += n; + LOG(level) << "Serial number sent. " << n + << " bytes. serialno: " << myMod->serialnumber; + + n = client.Send(&(myMod->nchan), sizeof(myMod->nchan)); + ts += n; + LOG(level) << "nchan sent. " << n << " bytes. nchan: " << myMod->nchan; + + n = client.Send(&(myMod->nchip), sizeof(myMod->nchip)); + ts += n; + LOG(level) << "nchip sent. " << n << " bytes. nchip: " << myMod->nchip; + + n = client.Send(&(myMod->ndac), sizeof(myMod->ndac)); + ts += n; + LOG(level) << "ndac sent. " << n << " bytes. ndac: " << myMod->ndac; + + n = client.Send(&(myMod->reg), sizeof(myMod->reg)); + ts += n; + LOG(level) << "reg sent. " << n << " bytes. reg: " << myMod->reg; + + n = client.Send(&(myMod->iodelay), sizeof(myMod->iodelay)); + ts += n; + LOG(level) << "iodelay sent. " << n + << " bytes. iodelay: " << myMod->iodelay; + + n = client.Send(&(myMod->tau), sizeof(myMod->tau)); + ts += n; + LOG(level) << "tau sent. " << n << " bytes. tau: " << myMod->tau; + + n = client.Send(&(myMod->eV), sizeof(myMod->eV)); + ts += n; + LOG(level) << "ev sent. " << n << " bytes. ev: " << myMod->eV; + + n = client.Send(myMod->dacs, sizeof(int) * (myMod->ndac)); + ts += n; + LOG(level) << "dacs sent. " << n << " bytes"; + + if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) { + n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan)); + ts += n; + LOG(level) << "channels sent. " << n << " bytes"; + } + return ts; +} + +void Module::setModule(sls_detector_module &module, bool trimbits) { + int fnum = F_SET_MODULE; + int ret = FAIL; + LOG(logDEBUG1) << "Setting module with trimbits:" << trimbits; + // to exclude trimbits + if (!trimbits) { + module.nchan = 0; + module.nchip = 0; + } + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + sendModule(&module, client); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + char mess[MAX_STR_LENGTH] = {0}; + client.Receive(mess, sizeof(mess)); + throw RuntimeError("Detector " + std::to_string(moduleId) + + " returned error: " + mess); + } +} + +void Module::updateReceiverStreamingIP() { + auto ip = getReceiverStreamingIP(); + if (ip == 0) { + // Hostname could be ip try to decode otherwise look up the hostname + ip = sls::IpAddr{shm()->rxHostname}; + if (ip == 0) { + ip = HostnameToIp(shm()->rxHostname); + } + LOG(logINFO) << "Setting default receiver " << moduleId + << " streaming zmq ip to " << ip; + } + setReceiverStreamingIP(ip); +} + +void Module::updateRateCorrection() { + sendToDetector(F_UPDATE_RATE_CORRECTION); +} + +void Module::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, + bool trimbits) { + + // if settings provided, use that, else use the shared memory variable + detectorSettings is = + ((isettings != GET_SETTINGS) ? isettings : getSettings()); + + // verify e_eV exists in trimEneregies[] + if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) || + (e_eV > shm()->trimEnergies.back())) { + throw RuntimeError("This energy " + std::to_string(e_eV) + + " not defined for this module!"); + } + + bool interpolate = + std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(), + [e_eV](const int &e) { return e != e_eV; }); + + sls_detector_module myMod{shm()->myDetectorType}; + + if (!interpolate) { + std::string settingsfname = getTrimbitFilename(is, e_eV); + LOG(logDEBUG1) << "Settings File is " << settingsfname; + myMod = readSettingsFile(settingsfname, trimbits); + } else { + // find the trim values + int trim1 = -1, trim2 = -1; + for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) { + if (e_eV < shm()->trimEnergies[i]) { + trim2 = shm()->trimEnergies[i]; + trim1 = shm()->trimEnergies[i - 1]; + break; + } + } + std::string settingsfname1 = getTrimbitFilename(is, trim1); + std::string settingsfname2 = getTrimbitFilename(is, trim2); + LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and " + << settingsfname2; + auto myMod1 = readSettingsFile(settingsfname1, trimbits); + auto myMod2 = readSettingsFile(settingsfname2, trimbits); + if (myMod1.iodelay != myMod2.iodelay) { + throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not " + "match between files"); + } + myMod = interpolateTrim(&myMod1, &myMod2, e_eV, trim1, trim2, trimbits); + myMod.iodelay = myMod1.iodelay; + myMod.tau = + linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau); + } + + myMod.reg = is; + myMod.eV = e_eV; + setModule(myMod, trimbits); + if (getSettings() != is) { + throw RuntimeError("setThresholdEnergyAndSettings: Could not set " + "settings in detector"); + } } sls_detector_module Module::interpolateTrim(sls_detector_module *a, sls_detector_module *b, const int energy, const int e1, - const int e2, int tb) { + const int e2, bool trimbits) { // only implemented for eiger currently (in terms of which dacs) if (shm()->myDetectorType != EIGER) { @@ -3079,7 +2735,7 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a, b->dacs[dacs_to_interpolate[i]]); } // Interpolate all trimbits - if (tb != 0) { + if (trimbits) { for (int i = 0; i < myMod.nchan; ++i) { myMod.chanregs[i] = linearInterpolation( energy, e1, e2, a->chanregs[i], b->chanregs[i]); @@ -3088,7 +2744,38 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a, return myMod; } -sls_detector_module Module::readSettingsFile(const std::string &fname, int tb) { +std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) { + std::string ssettings; + switch (s) { + case STANDARD: + ssettings = "/standard"; + break; + case HIGHGAIN: + ssettings = "/highgain"; + break; + case LOWGAIN: + ssettings = "/lowgain"; + break; + case VERYHIGHGAIN: + ssettings = "/veryhighgain"; + break; + case VERYLOWGAIN: + ssettings = "/verylowgain"; + break; + default: + std::ostringstream ss; + ss << "Unknown settings " << ToString(s) << " for this detector!"; + throw RuntimeError(ss.str()); + } + std::ostringstream ostfn; + ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV" + << "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec + << getSerialNumber() << std::setbase(10); + return ostfn.str(); +} + +sls_detector_module Module::readSettingsFile(const std::string &fname, + bool trimbits) { LOG(logDEBUG1) << "Read settings file " << fname; sls_detector_module myMod(shm()->myDetectorType); // open file @@ -3109,7 +2796,7 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, int tb) { infile.read(reinterpret_cast(&myMod.iodelay), sizeof(myMod.iodelay)); infile.read(reinterpret_cast(&myMod.tau), sizeof(myMod.tau)); - if (tb != 0) { + if (trimbits) { infile.read(reinterpret_cast(myMod.chanregs), sizeof(int) * (myMod.nchan)); } @@ -3142,98 +2829,129 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, int tb) { } } - // gotthard, jungfrau else { - auto names = getSettingsFileDacNames(); - size_t idac = 0; - std::string str; - while (infile.good()) { - getline(infile, str); - if (str.empty()) { - break; - } - LOG(logDEBUG1) << str; - std::string sargname; - int ival = 0; - std::istringstream ssstr(str); - ssstr >> sargname >> ival; - bool found = false; - for (size_t i = 0; i < names.size(); ++i) { - if (sargname == names[i]) { - myMod.dacs[i] = ival; - found = true; - LOG(logDEBUG1) << names[i] << "(" << i << "): " << ival; - ++idac; - } - } - if (!found) { - throw RuntimeError("readSettingsFile: Unknown dac: " + - sargname); - } - } - // not all read - if (idac != names.size()) { - throw RuntimeError("Could read only " + std::to_string(idac) + - " dacs. Expected " + - std::to_string(names.size()) + " dacs"); - } + throw RuntimeError("Not implemented for this detector"); } LOG(logINFO) << "Settings file loaded: " << fname.c_str(); return myMod; } -void Module::writeSettingsFile(const std::string &fname, - sls_detector_module &mod) { - LOG(logDEBUG1) << "Write settings file " << fname; +void Module::programFPGAviaBlackfin(std::vector buffer) { + uint64_t filesize = buffer.size(); - std::ofstream outfile; - if (shm()->myDetectorType == EIGER) { - outfile.open(fname.c_str(), std::ofstream::binary); - } else { - outfile.open(fname.c_str(), std::ios_base::out); - } - if (!outfile.is_open()) { - throw RuntimeError("Could not open settings file for writing: " + - fname); - } - if (shm()->myDetectorType == EIGER) { - for (int i = 0; i < mod.ndac; ++i) { - LOG(logINFO) << "dac " << i << ":" << mod.dacs[i]; - } - LOG(logINFO) << "iodelay: " << mod.iodelay; - LOG(logINFO) << "tau: " << mod.tau; + // send program from memory to detector + int fnum = F_PROGRAM_FPGA; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = {0}; + LOG(logINFO) << "Sending programming binary (from pof) to detector " + << moduleId << " (" << shm()->hostname << ")"; - outfile.write(reinterpret_cast(mod.dacs), - sizeof(int) * (mod.ndac)); - outfile.write(reinterpret_cast(&mod.iodelay), - sizeof(mod.iodelay)); - outfile.write(reinterpret_cast(&mod.tau), sizeof(mod.tau)); - outfile.write(reinterpret_cast(mod.chanregs), - sizeof(int) * (mod.nchan)); + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + client.Send(&filesize, sizeof(filesize)); + client.Receive(&ret, sizeof(ret)); + // error in detector at opening file pointer to flash + if (ret == FAIL) { + client.Receive(mess, sizeof(mess)); + std::ostringstream os; + os << "Detector " << moduleId << " (" << shm()->hostname << ")" + << " returned error: " << mess; + throw RuntimeError(os.str()); } - // gotthard, jungfrau - else { - auto names = getSettingsFileDacNames(); - for (int i = 0; i < mod.ndac; ++i) { - LOG(logDEBUG1) << "dac " << i << ": " << mod.dacs[i]; - outfile << names[i] << " " << mod.dacs[i] << std::endl; + + // erasing flash + LOG(logINFO) << "Erasing Flash for detector " << moduleId << " (" + << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + // erasing takes 65 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 65; + int count = ERASE_TIME + 1; + while (count > 0) { + usleep(1 * 1000 * 1000); + --count; + printf( + "%d%%\r", + static_cast( + (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); + std::cout << std::flush; + } + printf("\n"); + LOG(logINFO) << "Writing to Flash to detector " << moduleId << " (" + << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + + // sending program in parts of 2mb each + uint64_t unitprogramsize = 0; + int currentPointer = 0; + uint64_t totalsize = filesize; + while (filesize > 0) { + unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb + if (unitprogramsize > filesize) { // less than 2mb + unitprogramsize = filesize; } + LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize + << "\t filesize:" << filesize; + + client.Send(&buffer[currentPointer], unitprogramsize); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + printf("\n"); + client.Receive(mess, sizeof(mess)); + std::ostringstream os; + os << "Detector " << moduleId << " (" << shm()->hostname << ")" + << " returned error: " << mess; + throw RuntimeError(os.str()); + } + filesize -= unitprogramsize; + currentPointer += unitprogramsize; + + // print progress + printf( + "%d%%\r", + static_cast( + (static_cast(totalsize - filesize) / totalsize) * 100)); + std::cout << std::flush; } + printf("\n"); + LOG(logINFO) << "FPGA programmed successfully"; + rebootController(); } -std::vector Module::getSettingsFileDacNames() { - switch (shm()->myDetectorType) { - case GOTTHARD: - return {"Vref", "VcascN", "VcascP", "Vout", - "Vcasc", "Vin", "Vref_comp", "Vib_test"}; - case JUNGFRAU: - return {"VDAC0", "VDAC1", "VDAC2", "VDAC3", "VDAC4", "VDAC5", - "VDAC6", "VDAC7", "VDAC8", "VDAC9", "VDAC10", "VDAC11", - "VDAC12", "VDAC13", "VDAC14", "VDAC15"}; - default: - throw RuntimeError( - "Unknown detector type - unknown format for settings file"); +void Module::programFPGAviaNios(std::vector buffer) { + uint64_t filesize = buffer.size(); + int fnum = F_PROGRAM_FPGA; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = {0}; + LOG(logINFO) << "Sending programming binary (from rbf) to detector " + << moduleId << " (" << shm()->hostname << ")"; + + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + // filesize + client.Send(&filesize, sizeof(filesize)); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + client.Receive(mess, sizeof(mess)); + std::ostringstream os; + os << "Detector " << moduleId << " (" << shm()->hostname << ")" + << " returned error: " << mess; + throw RuntimeError(os.str()); } + // program + client.Send(&buffer[0], filesize); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + client.Receive(mess, sizeof(mess)); + std::ostringstream os; + os << "Detector " << moduleId << " (" << shm()->hostname << ")" + << " returned error: " << mess; + throw RuntimeError(os.str()); + } + LOG(logINFO) << "FPGA programmed successfully"; + rebootController(); } } // namespace sls \ No newline at end of file diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 255ec15c1..96e744d37 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -26,1296 +26,223 @@ struct sharedSlsDetector { /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ - /** shared memory version */ int shmversion; - - /** is the hostname (or IP address) of the detector. needs to be set - * before starting the communication */ char hostname[MAX_STR_LENGTH]; - - /** detector type \ see :: detectorType*/ slsDetectorDefs::detectorType myDetectorType; /** END OF FIXED PATTERN -----------------------------------------------*/ - /** Number of detectors in multi list in x dir and y dir */ - slsDetectorDefs::xy multiSize; - - /** is the port used for control functions */ + slsDetectorDefs::xy numberOfDetector; int controlPort; - - /** is the port used to stop the acquisition */ int stopPort; - - /** path of the trimbits/settings files */ char settingsDir[MAX_STR_LENGTH]; - /** list of the energies at which the detector has been trimmed */ sls::StaticVector trimEnergies; - - /** number of channels per chip in one direction */ + /** number of channels per chip */ slsDetectorDefs::xy nChan; - - /** number of chips per module in one direction */ slsDetectorDefs::xy nChip; - - /** number of dacs per module*/ int nDacs; - - /** ip address/hostname of the receiver for client control via TCP */ char rxHostname[MAX_STR_LENGTH]; - - /** is the TCP port used to communicate between client and the receiver */ int rxTCPPort; - - /** is set if the receiver hostname given and is connected, - * unset if socket connection is not possible */ + /** if rxHostname and rxTCPPort can be connected to */ bool useReceiverFlag; - - /** tcp port from gui/different process to receiver (only data) */ + /** Listening tcp port from gui (only data) */ int zmqport; - - /** zmq tcp src ip address in client (only data) **/ + /** Listening tcp ip address from gui (only data) **/ sls::IpAddr zmqip; - - /** num udp interfaces */ int numUDPInterfaces; - - /** stopped flag to inform rxr */ + /** to inform rxr when stopping rxr */ bool stoppedFlag; }; class Module : public virtual slsDetectorDefs { public: - /** - * Constructor called when creating new shared memory - * @param type detector type - * @param multi_id multi detector shared memory id - * @param id sls detector id (position in detectors list) - * @param verify true to verify if shared memory version matches existing - * one - */ - explicit Module(detectorType type, int multi_id = 0, int det_id = 0, + /************************************************** + * * + * Configuration * + * * + * ************************************************/ + + /** creating new shared memory + @param verify if shared memory version matches existing one */ + explicit Module(detectorType type, int det_id = 0, int module_id = 0, bool verify = true); - /** - * Constructor called when opening existing shared memory - * @param multi_id multi detector shared memory id - * @param id sls detector id (position in detectors list) - * @param verify true to verify if shared memory version matches existing - * one - */ - explicit Module(int multi_id = 0, int det_id = 0, bool verify = true); + /** opening existing shared memory + @param verify if shared memory version matches existing one */ + explicit Module(int det_id = 0, int module_id = 0, bool verify = true); - /** - * Destructor - */ virtual ~Module(); - /** - * Returns false if it cannot get fixed pattern from an old version of shm - * (hostname, type), else true - */ - bool isFixedPatternSharedMemoryCompatible(); - - /** - * Check version compatibility with receiver software - */ - void checkReceiverVersionCompatibility(); - - /** - * Check version compatibility with detector software - */ - void checkDetectorVersionCompatibility(); - - int64_t getFirmwareVersion(); - - int64_t getDetectorServerVersion(); - - int64_t getSerialNumber(); - - /** - * Get Receiver Software version - */ - int64_t getReceiverSoftwareVersion() const; - - /** - * Free shared memory and delete shared memory structure - * occupied by the sharedSlsDetector structure - * Is only safe to call if one deletes the Module object afterward - * and frees multi shared memory/updates - * thisMultiDetector->numberOfDetectors - */ + /** Frees shared memory and deletes shared memory structure + Safe to call only if detector shm also deleted or its numberOfDetectors is + updated */ void freeSharedMemory(); - - /** - * Sets the hostname, if online flag is set connects to update the detector - * @param name hostname - * @param initialChecks enable or disable initial compatibility checks - * and other server start up checks. Enabled by default. Disable only - * for advanced users! - */ - void setHostname(const std::string &hostname, const bool initialChecks); - - /** - * Gets the hostname of detector - * @returns hostname - */ + bool isFixedPatternSharedMemoryCompatible(); std::string getHostname() const; - /** - * Get detector type by connecting to the detector - * @returns detector tpe or GENERIC if failed - */ + /** @param initialChecks enable or disable initial compatibility checks and + other server start up checks. Enabled by default. Disable only for advanced + users! */ + void setHostname(const std::string &hostname, const bool initialChecks); + + int64_t getFirmwareVersion(); + int64_t getDetectorServerVersion(); + int64_t getSerialNumber(); + int64_t getReceiverSoftwareVersion() const; static detectorType getTypeFromDetector(const std::string &hostname, int cport = DEFAULT_PORTNO); - /** - * Get Detector type from shared memory variable - * @returns detector type from shared memory variable - */ + /** Get Detector type from shared memory */ detectorType getDetectorType() const; - - /** - * Update total number of channels (chiptestboard or moench) - * from the detector server - */ void updateNumberOfChannels(); - slsDetectorDefs::xy getNumberOfChannels() const; - - /** - * Get Quad Type (Only for Eiger Quad detector hardware) - * @returns quad type - */ - bool getQuad(); - - /** - * Set Quad Type (Only for Eiger Quad detector hardware) - * @param enable true if quad type set, else false - */ - void setQuad(const bool enable); - - /** - * Set number of rows to read out (Only for Eiger) - * @param value number of lines - */ - void setReadNLines(const int value); - - /** - * Get number of rows to read out (Only for Eiger) - * @returns number of lines - */ - int getReadNLines(); - - /** - * Set Detector offset in shared memory in dimension d - * @param det detector size - */ - void updateMultiSize(slsDetectorDefs::xy det); - - int setControlPort(int port_number); - - /** - * Returns the detector TCP control port \sa sharedSlsDetector - * @returns the detector TCP control port - */ - int getControlPort() const; - - int setStopPort(int port_number); - - /** - * Returns the detector TCP stop port \sa sharedSlsDetector - * @returns the detector TCP stop port - */ - int getStopPort() const; - - int setReceiverPort(int port_number); - - /** - * Returns the receiver TCP port \sa sharedSlsDetector - * @returns the receiver TCP port - */ - int getReceiverPort() const; - - /** - * Lock server for this client IP - * @param p 0 to unlock, 1 to lock (-1 gets) - * @returns true for locked or false for unlocked - */ - bool lockServer(int lock = -1); - - /** - * Get last client IP saved on detector server - * @returns last client IP saved on detector server - */ - sls::IpAddr getLastClientIP(); - - /** - * Exit detector server - */ - void exitServer(); - - /** - * Executes a system command on the detector server - * e.g. mount an nfs disk, reboot and returns answer etc. - * @param cmd command to be executed - */ - void execCommand(const std::string &cmd); - - /** - * Get detector specific commands to write into config file - * @returns vector of strings with commands - */ - std::vector getConfigFileCommands(); - + void updateNumberOfDetector(slsDetectorDefs::xy det); detectorSettings getSettings(); - - /** [Jungfrau] Options:DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, - * FORCESWITCHG1, FORCESWITCHG2 [Gotthard] Options: DYNAMICGAIN, HIGHGAIN, - * LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN [Gotthard2] Options: DYNAMICGAIN, - * FIXGAIN1, FIXGAIN2 [Moench] Options: G1_HIGHGAIN, G1_LOWGAIN, - * G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN, G2_LOWCAP_HIGHGAIN, - * G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN - */ void setSettings(detectorSettings isettings); - - /** - * Get threshold energy (Mythen and Eiger) - * @returns current threshold value in ev (-1 failed) - */ - int getThresholdEnergy(); - - /** - * Set threshold energy (Mythen and Eiger) - * For Eiger, calls setThresholdEneryAndSettings - * @param e_eV threshold in eV - * @param isettings ev. change settings - * @param tb 1 to include trimbits, 0 to exclude - */ - void setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS, - int tb = 1); - - /** - * Set threshold energy and settings (Eiger only) - * @param e_eV threshold in eV - * @param isettings ev. change settings - * @param tb 1 to include trimbits, 0 to exclude - */ - void setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, - int tb = 1); - - /** - * Returns the detector trimbit/settings directory \sa sharedSlsDetector - * @returns the trimbit/settings directory - */ - std::string getSettingsDir(); - - /** - * Sets the detector trimbit/settings directory \sa sharedSlsDetector - * @param s trimbits/settings directory - * @returns the trimbit/settings directory - */ - std::string setSettingsDir(const std::string &dir); - void loadSettingsFile(const std::string &fname); - - /** - * Saves the modules settings/trimbits to a specific file - * file name extension is automatically generated. - * @param fname specific settings/trimbits file - */ - void saveSettingsFile(const std::string &fname); - - /** - * Get run status of the detector - * @returns the status of the detector - */ - runStatus getRunStatus() const; - - /** - * Prepares detector for acquisition (Eiger) - */ - void prepareAcquisition(); - - /** - * Start detector acquisition (Non blocking) - */ - void startAcquisition(); - - /** - * Stop detector acquisition - */ - void stopAcquisition(); - - /** - * Give an internal software trigger to the detector (Eiger only) - */ - void sendSoftwareTrigger(); - - /** - * Start detector acquisition and read all data (Blocking until end of - * acquisition) - */ - void startAndReadAll(); - - /** - * Start readout (without exposure or interrupting exposure) (Eiger store in - * ram) - */ - void startReadOut(); - - /** - * Requests and receives all data from the detector (Eiger store in ram) - */ - void readAll(); - - /** - * Configures in detector the destination for UDP packets - */ - void configureMAC(); - - /** - * Set starting frame number for the next acquisition - * @param val starting frame number - */ - void setStartingFrameNumber(uint64_t value); - - /** - * Get starting frame number for the next acquisition - * @returns starting frame number - */ - uint64_t getStartingFrameNumber(); - - int64_t getNumberOfFrames(); - - void setNumberOfFrames(int64_t value); - - int64_t getNumberOfTriggers(); - - void setNumberOfTriggers(int64_t value); - - /** [Gotthard2] only in burst mode and in auto timing mode */ - int64_t getNumberOfBursts(); - - /** [Gotthard2] only in burst mode and in auto timing mode */ - void setNumberOfBursts(int64_t value); - - /** [Jungfrau] Advanced */ - int getNumberOfAdditionalStorageCells(); - - /** [Jungfrau] Advanced */ - void setNumberOfAdditionalStorageCells(int value); - - /** [CTB][Moench] */ - int getNumberOfAnalogSamples(); - - /** [CTB][Moench] */ - void setNumberOfAnalogSamples(int value); - - /** [CTB] */ - int getNumberOfDigitalSamples(); - - /** [CTB] */ - void setNumberOfDigitalSamples(int value); - - /** [Mythen3] */ - int getNumberOfGates(); - - /** [Mythen3] */ - void setNumberOfGates(int value); - - /** [Mythen3] gatIndex: 0-2, [Others]: -1 always */ - int64_t getExptime(int gateIndex); - - /** [Mythen3] gatIndex: -1 for all, 0-2, [Others]: -1 always */ - void setExptime(int gateIndex, int64_t value); - - /** [Mythen3] for all gates */ - std::array getExptimeForAllGates(); - - /** [Mythen3] gatIndex: 0-2 */ - int64_t getGateDelay(int gateIndex); - - /** [Mythen3] gatIndex: -1 for all, 0-2 */ - void setGateDelay(int gateIndex, int64_t value); - - /** [Mythen3] for all gates */ - std::array getGateDelayForAllGates(); - - int64_t getPeriod(); - - void setPeriod(int64_t value); - - /** [Gotthard][Jungfrau][CTB][Moench][Mythen3][Gotthard2] */ - int64_t getDelayAfterTrigger(); - - /** [Gotthard][Jungfrau][CTB][Moench][Mythen3][Gotthard2] */ - void setDelayAfterTrigger(int64_t value); - - /** [Gotthard2] only in burst mode and in auto timing mode */ - int64_t getBurstPeriod(); - - /** [Gotthard2] only in burst mode and in auto timing mode */ - void setBurstPeriod(int64_t value); - - /** [Eiger] in 32 bit mode */ - int64_t getSubExptime(); - - /** [Eiger] in 32 bit mode */ - void setSubExptime(int64_t value); - - /** [Eiger] in 32 bit mode */ - int64_t getSubDeadTime(); - - /** [Eiger] in 32 bit mode */ - void setSubDeadTime(int64_t value); - - /** [Jungfrau] Advanced*/ - int64_t getStorageCellDelay(); - - /** [Jungfrau] Advanced - * Options: (0-1638375 ns (resolution of 25ns) */ - void setStorageCellDelay(int64_t value); - - /** [Gotthard][Jungfrau][CTB][Moench][Mythen3] - * [Gotthard2] only in continuous mode */ - int64_t getNumberOfFramesLeft() const; - - /** [Gotthard][Jungfrau][CTB][Moench][Mythen3] - * [Gotthard2] only in continuous mode */ - int64_t getNumberOfTriggersLeft() const; - - /** [Gotthard][Jungfrau][CTB][Moench] - * [Gotthard2] only in continuous mode */ - int64_t getDelayAfterTriggerLeft() const; - - /** [Gotthard] */ - int64_t getExptimeLeft() const; - - /** [Gotthard][Jungfrau][CTB][Moench][Mythen3][Gotthard2] */ - int64_t getPeriodLeft() const; - - /** [Eiger] minimum two frames */ - int64_t getMeasuredPeriod() const; - - /** [Eiger] */ - int64_t getMeasuredSubFramePeriod() const; - - /** [Jungfrau][CTB][Moench][Mythen3] - * [Gotthard2] only in continuous mode */ - int64_t getNumberOfFramesFromStart() const; - - /** [Jungfrau][CTB][Moench][Mythen3] Get time from detector start - * [Gotthard2] only in continuous mode */ - int64_t getActualTime() const; - - /** [Jungfrau][CTB][Moench][Mythen3] Get timestamp at a frame start - * [Gotthard2] only in continuous mode */ - int64_t getMeasurementTime() const; - - timingMode getTimingMode(); - void setTimingMode(timingMode value); - - int getDynamicRange(); - /** - * Set/get dynamic range - * (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to - * 1) - */ - void setDynamicRange(int n); - - /** - * Set/get dacs value - * @param val value (in V) - * @param index DAC index - * @param mV 0 in dac units or 1 in mV - * @returns current DAC value - */ - int setDAC(int val, dacIndex index, int mV); - - /* [Gotthard2] */ - int getOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex); - - /* [Gotthard2] */ - void setOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex, - int value); - - /** - * Get adc value - * @param index adc(DAC) index - * @returns current adc value (temperature for eiger and jungfrau in - * millidegrees) - */ - int getADC(dacIndex index); - - externalSignalFlag getExternalSignalFlags(int signalIndex); - void setExternalSignalFlags(int signalIndex, externalSignalFlag type); - - /** - * Set Parallel readout mode (Only for Eiger) - * @param enable true if parallel, else false for non parallel - */ - void setParallelMode(const bool enable); - - /** - * Get parallel mode (Only for Eiger) - * @returns parallel mode - */ - bool getParallelMode(); - - /** - * Set overflow readout mode in 32 bit mode (Only for Eiger) - * @param enable true if overflow, else false - */ - void setOverFlowMode(const bool enable); - - /** - * Get overflow mode in 32 bit mode (Only for Eiger) - * @returns overflow mode - */ - bool getOverFlowMode(); - - /** - * Set store in ram readout mode (Only for Eiger) - * @param enable true if store in ram, else false - */ - void setStoreInRamMode(const bool enable); - - /** - * Get store in ram mode (Only for Eiger) - * @returns store in ram mode - */ - bool getStoreInRamMode(); - - /** - * [Ctb] - * @param mode readout mode Options: ANALOG_ONLY, DIGITAL_ONLY, - * ANALOG_AND_DIGITAL - */ - void setReadoutMode(const readoutMode mode); - - /** - * [Ctb] - * @returns readout mode - */ - readoutMode getReadoutMode(); - - /** - * Set Interrupt last sub frame (Only for Eiger) - * @param enable true if interrupt last subframe set, else false - */ - void setInterruptSubframe(const bool enable); - - /** - * Get Interrupt last sub frame (Only for Eiger) - * @returns true if interrupt last subframe set, else false - */ - bool getInterruptSubframe(); - - /** - * Write in a register. For Advanced users - * @param addr address of register - * @param val value to write into register - * @returns value read after writing - */ - uint32_t writeRegister(uint32_t addr, uint32_t val); - - /** - * Read from a register. For Advanced users - * @param addr address of register - * @returns value read from register - */ - uint32_t readRegister(uint32_t addr); - - /** - * Set bit in a register. For Advanced users - * @param addr address of register - * @param n nth bit - * @returns value read from register - */ - uint32_t setBit(uint32_t addr, int n); - - /** - * Clear bit in a register. For Advanced users - * @param addr address of register - * @param n nth bit - * @returns value read from register - */ - uint32_t clearBit(uint32_t addr, int n); - - /** - * Validates and sets the receiver. - * Also updates the receiver with all the shared memory parameters - * significant for the receiver Also configures the detector to the receiver - * as UDP destination - * @param receiver receiver hostname or IP address - */ - void setReceiverHostname(const std::string &receiver); - - void test(); - /** - * Returns the receiver IP address\sa sharedSlsDetector - * @returns the receiver IP address - */ - std::string getReceiverHostname() const; - - /** - * Validates the format of the detector MAC address and sets it - * @param mac detector MAC address - */ - void setSourceUDPMAC(const sls::MacAddr mac); - - /** - * Returns the detector MAC address - * @returns the detector MAC address - */ - sls::MacAddr getSourceUDPMAC(); - - /** - * Validates the format of the detector MAC address (bottom half) and sets - * it (Jungfrau only) - * @param mac detector MAC address (bottom half) - */ - void setSourceUDPMAC2(const sls::MacAddr mac); - - /** - * Returns the detector MAC address (bottom half) Jungfrau only - * @returns the detector MAC address (bottom half) - */ - sls::MacAddr getSourceUDPMAC2(); - - /** - * Validates the format of the detector IP address and sets it - * @param ip detector IP address - */ - void setSourceUDPIP(const sls::IpAddr ip); - - /** - * Returns the detector IP address - * @returns the detector IP address - */ - sls::IpAddr getSourceUDPIP(); - - /** - * Validates the format of the detector IP address (bottom half) and sets it - * (Jungfrau only) - * @param ip detector IP address (bottom half) - */ - void setSourceUDPIP2(const sls::IpAddr ip); - - /** - * Returns the detector IP address (bottom half) Jungfrau only - * @returns the detector IP address (bottom half) - */ - sls::IpAddr getSourceUDPIP2(); - - /** - * Validates the format of the receiver UDP IP address and sets it - * If slsReceiver used, Gets receiver udp mac address and sends it to the - * detector - * @param ip receiver UDP IP address - */ - void setDestinationUDPIP(const sls::IpAddr ip); - - /** - * Returns the receiver UDP IP address - * If slsReceiver used, Gets receiver udp mac address and sends it to the - * detector - * @returns the receiver UDP IP address - */ - sls::IpAddr getDestinationUDPIP(); - - /** - * Validates the format of the receiver UDP IP address (bottom half) and - * sets it(Jungfrau only) - * If slsReceiver used, Gets receiver udp mac address2 and sends it to the - * detector - * @param ip receiver UDP IP address (bottom half) - */ - void setDestinationUDPIP2(const sls::IpAddr ip); - - /** - * Returns the receiver UDP IP address (bottom half) Jungfrau only - * If slsReceiver used, Gets receiver udp mac address2 and sends it to the - * detector - * @returns the receiver UDP IP address (bottom half) - */ - sls::IpAddr getDestinationUDPIP2(); - - /** - * Validates the format of the receiver UDP MAC address and sets it - * @param mac receiver UDP MAC address - */ - void setDestinationUDPMAC(const sls::MacAddr mac); - - /** - * Returns the receiver UDP MAC address - * @returns the receiver UDP MAC address - */ - sls::MacAddr getDestinationUDPMAC(); - - /** - * Validates the format of the receiver UDP MAC address (bottom half) and - * sets it (Jungfrau only) - * @param mac receiver UDP MAC address (bottom half) - */ - void setDestinationUDPMAC2(const sls::MacAddr mac); - - /** - * Returns the receiver UDP MAC address (bottom half) Jungfrau only - * @returns the receiver UDP MAC address (bottom half) - */ - sls::MacAddr getDestinationUDPMAC2(); - - /** - * Sets the receiver UDP port\sa sharedSlsDetector - * @param udpport receiver UDP port - */ - void setDestinationUDPPort(int udpport); - - /** - * Returns the receiver UDP port\sa sharedSlsDetector - * @returns the receiver UDP port - */ - int getDestinationUDPPort(); - - /** - * Sets the receiver UDP port 2\sa sharedSlsDetector (Eiger and Jungfrau - * only) - * @param udpport receiver UDP port 2 - */ - void setDestinationUDPPort2(int udpport); - - /** - * Returns the receiver UDP port 2 of same interface\sa sharedSlsDetector - * (Eiger and Jungfrau only) - * @returns the receiver UDP port 2 of same interface - */ - int getDestinationUDPPort2(); - - /** [Jungfrau][Gotthard2] */ - void setNumberofUDPInterfaces(int n); - - /** Returns the number of udp interfaces from shared memory */ - int getNumberofUDPInterfacesFromShm(); - - /** - * Returns the number of UDP interfaces to stream data from detector - * (Jungfrau only) - * @returns the number of interfaces - */ - int getNumberofUDPInterfaces(); - - /** - * Selects the UDP interfaces to stream data from detector. Effective only - * when number of interfaces is 1. (Jungfrau only) - * @param n selected interface. Options 1 or 2. - * @returns the interface selected - */ - void selectUDPInterface(int n); - - /** - * Returns the UDP interfaces to stream data from detector. Effective only - * when number of interfaces is 1. (Jungfrau only) - * @returns the interface selected - */ - int getSelectedUDPInterface(); - - /** - * Sets the client zmq port\sa sharedSlsDetector - * @param port client zmq port - */ - void setClientStreamingPort(int port); - - /** - * Returns the client zmq port \sa sharedSlsDetector - * @returns the client zmq port - */ - int getClientStreamingPort(); - - /** - * Sets the receiver zmq port\sa sharedSlsDetector - * @param port receiver zmq port - */ - void setReceiverStreamingPort(int port); - - /** - * Returns the receiver zmq port \sa sharedSlsDetector - * @returns the receiver zmq port - */ - int getReceiverStreamingPort(); - - /** - * Sets the client zmq ip\sa sharedSlsDetector - * @param ip client zmq ip - */ - void setClientStreamingIP(const sls::IpAddr ip); - - /** - * Returns the client zmq ip \sa sharedSlsDetector - * @returns the client zmq ip - */ - sls::IpAddr getClientStreamingIP(); - - /** - * Sets the receiver zmq ip\sa sharedSlsDetector - * @param ip receiver zmq ip - */ - void setReceiverStreamingIP(const sls::IpAddr ip); - - /** - * Returns the receiver zmq ip \sa sharedSlsDetector - * @returns the receiver zmq ip - */ - sls::IpAddr getReceiverStreamingIP(); - - /** update receiver stremaing ip from shm to receiver - * if empty, use rx_hostname ip - */ - void updateReceiverStreamingIP(); - - /** [Eiger, Jungfrau] */ - bool getTenGigaFlowControl(); - - /** [Eiger, Jungfrau] */ - void setTenGigaFlowControl(bool enable); - - /** [Eiger, Jungfrau] */ - int getTransmissionDelayFrame(); - - /** - * [Jungfrau]: Sets the transmission delay of the first UDP packet being - * streamed out of the module. Options: 0 - 31, each value represenets 1 ms - * [Eiger]: Sets the transmission delay of entire frame streamed out for - * both left and right UDP ports. Options: //TODO possible values - */ - void setTransmissionDelayFrame(int value); - - /** [Eiger] */ - int getTransmissionDelayLeft(); - - /** - * [Eiger] - * Sets the transmission delay of first packet streamed out of the left UDP - * port - */ - void setTransmissionDelayLeft(int value); - - /** [Eiger] */ - int getTransmissionDelayRight(); - - /** - * [Eiger] - * Sets the transmission delay of first packet streamed ut of the right UDP - * port - */ - void setTransmissionDelayRight(int value); - - /** empty vector deletes entire additional json header */ - void setAdditionalJsonHeader( - const std::map &jsonHeader); - std::map getAdditionalJsonHeader(); - - /** - * Sets the value for the additional json header parameter key if found, - * else append it. If value empty, then deletes parameter */ - void setAdditionalJsonParameter(const std::string &key, - const std::string &value); - std::string getAdditionalJsonParameter(const std::string &key); - - /** - * Sets the receiver UDP socket buffer size - * @param udpsockbufsize additional json header - * @returns receiver udp socket buffer size - */ - int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1); - - /** - * Returns the receiver UDP socket buffer size\sa sharedSlsDetector - * @returns the receiver UDP socket buffer size - */ - int64_t getReceiverUDPSocketBufferSize(); - - /** - * Returns the receiver real UDP socket buffer size\sa sharedSlsDetector - * @returns the receiver real UDP socket buffer size - */ - int64_t getReceiverRealUDPSocketBufferSize() const; - - /** [Gotthard][Jungfrau][CTB][Moench] */ - void executeFirmwareTest(); - - /** [Gotthard][Jungfrau][CTB][Moench] */ - void executeBusTest(); - - /** [Gotthard][Eiger virtual] */ - int getImageTestMode(); - - /** [Gotthard] If 1, adds channel intensity with precalculated values. - * Default is 0 - * [Eiger virtual] If 1, pixels are saturated. If 0, increasing intensity - * Only for virtual servers */ - void setImageTestMode(const int value); - - /** [Gotthard2] */ - std::array getInjectChannel(); - - /** [Gotthard2] - * @param offsetChannel starting channel to be injected - * @param incrementChannel determines succeeding channels to be injected */ - void setInjectChannel(const int offsetChannel, const int incrementChannel); - - /** [Gotthard2] asic input */ - std::vector getVetoPhoton(const int chipIndex); - - /** [Gotthard2] energy in keV */ - void setVetoPhoton(const int chipIndex, const int numPhotons, - const int energy, const std::string &fname); - - void setVetoReference(const int gainIndex, const int value); - - /** [Gotthard2] */ - burstMode getBurstMode(); - - /** [Gotthard2] BURST_OFF, BURST_INTERNAL (default), BURST_EXTERNAL */ - void setBurstMode(burstMode value); - - /** [Gotthard2] */ - bool getCurrentSource(); - - /** default disabled */ - void setCurrentSource(bool value); - - /** [Gotthard2] */ - slsDetectorDefs::timingSourceType getTimingSource(); - - /** [Gotthard2] Options: TIMING_INTERNAL, TIMING_EXTERNAL */ - void setTimingSource(slsDetectorDefs::timingSourceType value); - - /** [Gotthard2] */ - bool getVeto(); - - /** default disabled */ - void setVeto(bool enable); - - /** - * Set/get counter bit in detector (Gotthard) - * @param i is -1 to get, 0 to reset and any other value to set the counter - * bit - * @returns the counter bit in detector - */ - int setCounterBit(int cb = -1); - - /** - * Clear ROI (Gotthard) - */ - void clearROI(); - - /** - * Set ROI (Gotthard) - * Also calls configuremac - * @param arg roi - */ - void setROI(slsDetectorDefs::ROI arg); - - /** - * Get ROI (Gotthard) - * Update receiver if different from shm - * @returns roi - */ - slsDetectorDefs::ROI getROI(); - - /** - * Set ADC Enable Mask (CTB, Moench) - * @param mask ADC Enable mask - */ - void setADCEnableMask(uint32_t mask); - - /** - * Get ADC Enable Mask (CTB, Moench) - * @returns ADC Enable mask - */ - uint32_t getADCEnableMask(); - - /** - * Set 10Gb ADC Enable Mask (CTB, Moench) - * @param mask ADC Enable mask - */ - void setTenGigaADCEnableMask(uint32_t mask); - - /** - * Get 10Gb ADC Enable Mask (CTB, Moench) - * @returns ADC Enable mask - */ - uint32_t getTenGigaADCEnableMask(); - - /** - * Set ADC invert register (CTB, Moench, Jungfrau) - * @param value ADC invert value - * @param detPos -1 for all detectors in list or specific detector position - */ - void setADCInvert(uint32_t value); - - /** - * Get ADC invert register (CTB, Moench, Jungfrau) - * @param detPos -1 for all detectors in list or specific detector position - * @returns ADC invert value - */ - uint32_t getADCInvert(); - - /** - * Set external sampling source (CTB only) - * @param value external sampling source (Option: 0-63) - * @param detPos -1 for all detectors in list or specific detector position - * @returns external sampling source - */ - int setExternalSamplingSource(int value); - - /** - * Get external sampling source (CTB only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns external sampling source - */ - int getExternalSamplingSource(); - - void setExternalSampling(bool value); - - bool getExternalSampling(); - - /** digital data bits enable (CTB only) */ - void setReceiverDbitList(const std::vector &list); - std::vector getReceiverDbitList() const; - - /** Set digital data offset in bytes (CTB only) */ - void setReceiverDbitOffset(int value); - int getReceiverDbitOffset(); - - /** - * Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert - * users - * @param addr address of adc register - * @param val value - */ - void writeAdcRegister(uint32_t addr, uint32_t val); - - bool getActivate(); - void setActivate(const bool enable); - - bool getDeactivatedRxrPaddingMode(); - - /** - * Set deactivated Receiver padding mode (Eiger only) - */ - void setDeactivatedRxrPaddingMode(bool padding); - - /** - * Returns the enable if data will be flipped across x axis (Eiger) - * @returns if flipped across x axis - */ - bool getFlippedDataX(); - - /** - * Sets the enable which determines if - * data will be flipped across x axis (Eiger) - * @param value 0 or 1 to reset/set - */ - void setFlippedDataX(bool value); - int getAllTrimbits(); void setAllTrimbits(int val); - /** - * Sets the number of trim energies and their value (Eiger) - * \sa sharedSlsDetector - * @param nen number of energies - * @param vector os trimmed energies - * @returns number of trim energies - */ - int setTrimEn(const std::vector &energies = {}); + /************************************************** + * * + * Acquisition Parameters * + * * + * ************************************************/ + int64_t getNumberOfFrames(); + void setNumberOfFrames(int64_t value); + int64_t getNumberOfTriggers(); + void setNumberOfTriggers(int64_t value); + /** [Mythen3] gatIndex: 0-2, [Others]: -1 always */ + int64_t getExptime(int gateIndex); + /** [Mythen3] gatIndex: -1 for all, 0-2, [Others]: -1 always */ + void setExptime(int gateIndex, int64_t value); + int64_t getPeriod(); + void setPeriod(int64_t value); + int64_t getDelayAfterTrigger(); + void setDelayAfterTrigger(int64_t value); + int64_t getNumberOfFramesLeft() const; + int64_t getNumberOfTriggersLeft() const; + int64_t getDelayAfterTriggerLeft() const; + int64_t getPeriodLeft() const; + timingMode getTimingMode(); + void setTimingMode(timingMode value); + int getClockDivider(int clkIndex); + void setClockDivider(int clkIndex, int value); + int getClockPhase(int clkIndex, bool inDegrees); + void setClockPhase(int clkIndex, int value, bool inDegrees); + int getMaxClockPhaseShift(int clkIndex); + int getClockFrequency(int clkIndex); + void setClockFrequency(int clkIndex, int value); + int getDAC(dacIndex index, bool mV); + void setDAC(int val, dacIndex index, bool mV); + bool getPowerChip(); + void setPowerChip(bool on); + int getImageTestMode(); + void setImageTestMode(const int value); + /* temperature in millidegrees */ + int getADC(dacIndex index); + int getOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex); + void setOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex, + int value); + externalSignalFlag getExternalSignalFlags(int signalIndex); + void setExternalSignalFlags(int signalIndex, externalSignalFlag type); - /** - * Returns a vector with the trimmed energies (Eiger) - * \sa sharedSlsDetector - * @returns vector with the trimmed energies - */ - std::vector getTrimEn(); + /************************************************** + * * + * Acquisition * + * * + * ************************************************/ + void startReceiver(); + void stopReceiver(); + void prepareAcquisition(); + void startAcquisition(); + void stopAcquisition(); + void startAndReadAll(); + runStatus getRunStatus() const; + runStatus getReceiverStatus() const; + int getReceiverProgress() const; + int64_t getFramesCaughtByReceiver() const; + std::vector getNumMissingPackets() const; + uint64_t getStartingFrameNumber(); + void setStartingFrameNumber(uint64_t value); + void sendSoftwareTrigger(); - /** - * Pulse Pixel (Eiger) - * @param n is number of times to pulse - * @param x is x coordinate - * @param y is y coordinate - */ - void pulsePixel(int n = 0, int x = 0, int y = 0); - - /** - * Pulse Pixel and move by a relative value (Eiger) - * @param n is number of times to pulse - * @param x is relative x value - * @param y is relative y value - */ - void pulsePixelNMove(int n = 0, int x = 0, int y = 0); - - /** - * Pulse Chip (Eiger) - * @param n is number of times to pulse - */ - void pulseChip(int n_pulses = 0); - - /** - * Set/gets threshold temperature (Jungfrau) - * @param val value in millidegrees, -1 gets - * @returns threshold temperature in millidegrees - */ - int setThresholdTemperature(int val = -1); - - /** - * Enables/disables temperature control (Jungfrau) - * @param val value, -1 gets - * @returns temperature control enable - */ - int setTemperatureControl(int val = -1); - - /** - * Resets/ gets over-temperature event (Jungfrau) - * @param val value, -1 gets - * @returns over-temperature event - */ - int setTemperatureEvent(int val = -1); - - /** - * Set storage cell that stores first acquisition of the series (Jungfrau) - * @param value storage cell index. Value can be 0 to 15. (-1 gets) - * @returns the storage cell that stores the first acquisition of the series - */ - int setStorageCellStart(int pos = -1); - - /** - * [Jungfau][Ctb] Programs FPGA with raw file from pof file - * [Mythen3][Gotthard2] Programs FPGA with raw file from rbf file - * @param buffer programming file in memory - */ - void programFPGA(std::vector buffer); - - /** [Jungfau][Ctb] */ - void programFPGAviaBlackfin(std::vector buffer); - - /** [Mythen3][Gotthard2] */ - void programFPGAviaNios(std::vector buffer); - /** - * Resets FPGA (Jungfrau) - */ - void resetFPGA(); - - /** - * Copies detector server from tftp and changes respawn server (Not Eiger) - * @param fname name of detector server binary - * @param hostname name of pc to tftp from - */ - void copyDetectorServer(const std::string &fname, - const std::string &hostname); - - /** - * [Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2] - * Reboot detector controller (blackfin/ powerpc) - */ - void rebootController(); - - /** - * Power on/off Chip (Jungfrau) - * @param ival on is 1, off is 0, -1 to get - * @returns OK or FAIL - */ - int powerChip(int ival = -1); - - /** - * Automatic comparator disable (Jungfrau) - * @param ival on is 1, off is 0, -1 to get - * @returns OK or FAIL - */ - int setAutoComparatorDisableMode(int ival = -1); - - /** - * Get trimbit filename with path for settings and energy - * - */ - std::string getTrimbitFilename(detectorSettings settings, int e_eV); - - /** - * Configure Module (Eiger) - * Called for loading trimbits and settings settings to the detector - * @param module module to be set - must contain correct module number and - * also channel and chip registers - * @param tb 1 to include trimbits, 0 to exclude (used for eiger) - * \sa ::sls_detector_module - */ - void setModule(sls_detector_module &module, int tb = 1); - - /** - * Get module structure from detector (all detectors) - * @returns pointer to module structure (which has been created and must - * then be deleted) - */ - sls_detector_module getModule(); - - /** - * Set Default Rate correction from trimbit file(Eiger) - */ - void setDefaultRateCorrection(); - - /** - * Set Rate correction (Eiger) - * @param t dead time in ns - if 0 disable correction, - * if >0 set dead time to t, cannot be < 0 - * for current settings - */ - void setRateCorrection(int64_t t = 0); - - /** - * Get rate correction (Eiger) - * @returns 0 if rate correction disabled, > 0 otherwise - */ - int64_t getRateCorrection(); - - /** - * Update rate correction according to dynamic range (Eiger) - * If rate correction enabled and dr is 8 or 16, it will throw - * Otherwise update ratecorrection if enabled - */ - void updateRateCorrection(); - - /** - * Prints receiver configuration - * @returns receiver configuration - */ + /************************************************** + * * + * Network Configuration (Detector<->Receiver) * + * * + * ************************************************/ + int getNumberofUDPInterfacesFromShm(); + int getNumberofUDPInterfaces(); + void setNumberofUDPInterfaces(int n); + int getSelectedUDPInterface(); + void selectUDPInterface(int n); + sls::IpAddr getSourceUDPIP(); + void setSourceUDPIP(const sls::IpAddr ip); + sls::IpAddr getSourceUDPIP2(); + void setSourceUDPIP2(const sls::IpAddr ip); + sls::MacAddr getSourceUDPMAC(); + void setSourceUDPMAC(const sls::MacAddr mac); + sls::MacAddr getSourceUDPMAC2(); + void setSourceUDPMAC2(const sls::MacAddr mac); + sls::IpAddr getDestinationUDPIP(); + void setDestinationUDPIP(const sls::IpAddr ip); + sls::IpAddr getDestinationUDPIP2(); + void setDestinationUDPIP2(const sls::IpAddr ip); + sls::MacAddr getDestinationUDPMAC(); + void setDestinationUDPMAC(const sls::MacAddr mac); + sls::MacAddr getDestinationUDPMAC2(); + void setDestinationUDPMAC2(const sls::MacAddr mac); + int getDestinationUDPPort(); + void setDestinationUDPPort(int udpport); + int getDestinationUDPPort2(); + void setDestinationUDPPort2(int udpport); std::string printReceiverConfiguration(); + bool getTenGiga(); + void setTenGiga(bool value); + bool getTenGigaFlowControl(); + void setTenGigaFlowControl(bool enable); + int getTransmissionDelayFrame(); + void setTransmissionDelayFrame(int value); + int getTransmissionDelayLeft(); + void setTransmissionDelayLeft(int value); + int getTransmissionDelayRight(); + void setTransmissionDelayRight(int value); - /** - * Gets the use receiver flag from shared memory - */ + /************************************************** + * * + * Receiver Config * + * * + * ************************************************/ bool getUseReceiverFlag() const; - - /** - * Locks/Unlocks the connection to the receiver - * @param lock sets (1), usets (0), gets (-1) the lock - * @returns lock status of the receiver - */ - int lockReceiver(int lock = -1); - - /** - * Returns the IP of the last client connecting to the receiver - * @returns the IP of the last client connecting to the receiver - */ + std::string getReceiverHostname() const; + void setReceiverHostname(const std::string &receiver); + int getReceiverPort() const; + int setReceiverPort(int port_number); + int getReceiverFifoDepth(); + void setReceiverFifoDepth(int n_frames); + bool getReceiverSilentMode(); + void setReceiverSilentMode(bool enable); + frameDiscardPolicy getReceiverFramesDiscardPolicy(); + void setReceiverFramesDiscardPolicy(frameDiscardPolicy f); + bool getPartialFramesPadding(); + void setPartialFramesPadding(bool padding); + int64_t getReceiverUDPSocketBufferSize() const; + int64_t getReceiverRealUDPSocketBufferSize() const; + void setReceiverUDPSocketBufferSize(int64_t udpsockbufsize); + bool getReceiverLock(); + void setReceiverLock(bool lock); sls::IpAddr getReceiverLastClientIP() const; - std::array getReceiverThreadIds() const; - /** - * Exits the receiver TCP server - */ - void exitReceiver(); - + /************************************************** + * * + * File * + * * + * ************************************************/ + fileFormat getFileFormat(); + void setFileFormat(fileFormat f); std::string getFilePath(); void setFilePath(const std::string &path); std::string getFileName(); @@ -1323,243 +250,260 @@ class Module : public virtual slsDetectorDefs { int64_t getFileIndex(); void setFileIndex(int64_t file_index); void incrementFileIndex(); - fileFormat getFileFormat(); - void setFileFormat(fileFormat f); + bool getFileWrite(); + void setFileWrite(bool value); + bool getMasterFileWrite(); + void setMasterFileWrite(bool value); + bool getFileOverWrite(); + void setFileOverWrite(bool value); int getFramesPerFile(); /** 0 will set frames per file to unlimited */ void setFramesPerFile(int n_frames); - frameDiscardPolicy getReceiverFramesDiscardPolicy(); - void setReceiverFramesDiscardPolicy(frameDiscardPolicy f); - bool getPartialFramesPadding(); - void setPartialFramesPadding(bool padding); - - /** - * Receiver starts listening to packets - */ - void startReceiver(); - - /** - * Stops the listening mode of receiver - */ - void stopReceiver(); - - /** - * Gets the status of the listening mode of receiver - * @returns status - */ - runStatus getReceiverStatus() const; - - /** - * Gets the number of frames caught by receiver - * @returns number of frames caught by receiver - */ - int64_t getFramesCaughtByReceiver() const; - - /** Gets number of missing packets */ - std::vector getNumMissingPackets() const; - - /** - * Gets the current frame index of receiver - * @returns current frame index of receiver - */ - uint64_t getReceiverCurrentFrameIndex() const; - int getReceiverProgress() const; - - void setFileWrite(bool value); - bool getFileWrite(); - void setMasterFileWrite(bool value); - bool getMasterFileWrite(); - void setFileOverWrite(bool value); - bool getFileOverWrite(); - - int getReceiverStreamingFrequency(); - - /** - * (previously setReadReceiverFrequency) - * Sets the receiver streaming frequency - * @param freq nth frame streamed out, if 0, streamed out at a timer of 200 - * ms - * @param detPos -1 for all detectors in list or specific detector position - */ - void setReceiverStreamingFrequency(int freq); - - /** - * (previously setReceiverReadTimer) - * Sets the receiver streaming timer - * If receiver streaming frequency is 0, then this timer between each - * data stream is set. Default is 200 ms. - * @param time_in_ms timer between frames - * @returns receiver streaming timer in ms - */ - int setReceiverStreamingTimer(int time_in_ms = 200); + /************************************************** + * * + * ZMQ Streaming Parameters (Receiver<->Client)* + * * + * ************************************************/ bool getReceiverStreaming(); - void setReceiverStreaming(bool enable); + int getReceiverStreamingFrequency(); + /** Option: nth frame streamed out, if 0, streamed out at a timer of 200 */ + void setReceiverStreamingFrequency(int freq); + int getReceiverStreamingTimer(); + void setReceiverStreamingTimer(int time_in_ms = 200); + int getReceiverStreamingPort(); + void setReceiverStreamingPort(int port); + sls::IpAddr getReceiverStreamingIP(); + void setReceiverStreamingIP(const sls::IpAddr ip); + int getClientStreamingPort(); + void setClientStreamingPort(int port); + sls::IpAddr getClientStreamingIP(); + void setClientStreamingIP(const sls::IpAddr ip); - /** - * Enable/disable or 10Gbe - * @param i is -1 to get, 0 to disable and 1 to enable - * @returns if 10Gbe is enabled - */ - bool enableTenGigabitEthernet(int value = -1); + /************************************************** + * * + * Eiger Specific * + * * + * ************************************************/ + int getDynamicRange(); + void setDynamicRange(int n); + int64_t getSubExptime(); + void setSubExptime(int64_t value); + int64_t getSubDeadTime(); + void setSubDeadTime(int64_t value); + int getThresholdEnergy(); + void setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS, + bool trimbits = true); + std::string getSettingsDir(); + std::string setSettingsDir(const std::string &dir); + bool getParallelMode(); + void setParallelMode(const bool enable); + bool getOverFlowMode(); + void setOverFlowMode(const bool enable); + bool getFlippedDataX(); + void setFlippedDataX(bool value); + std::vector getTrimEn(); + int setTrimEn(const std::vector &energies = {}); + int64_t getRateCorrection(); + void setDefaultRateCorrection(); + void setRateCorrection(int64_t t = 0); + int getReadNLines(); + void setReadNLines(const int value); + bool getInterruptSubframe(); + void setInterruptSubframe(const bool enable); + int64_t getMeasuredPeriod() const; + int64_t getMeasuredSubFramePeriod() const; + bool getActivate(); + void setActivate(const bool enable); + bool getDeactivatedRxrPaddingMode(); + void setDeactivatedRxrPaddingMode(bool padding); + bool getCounterBit(); + void setCounterBit(bool cb); + void pulsePixel(int n = 0, int x = 0, int y = 0); + void pulsePixelNMove(int n = 0, int x = 0, int y = 0); + void pulseChip(int n_pulses = 0); + bool getQuad(); + void setQuad(const bool enable); - /** - * Set/get receiver fifo depth - * @param i is -1 to get, any other value to set the fifo deph - * @returns the receiver fifo depth - */ - int setReceiverFifoDepth(int n_frames = -1); + /************************************************** + * * + * Jungfrau Specific * + * * + * ************************************************/ + int getThresholdTemperature(); + void setThresholdTemperature(int val); + bool getTemperatureControl(); + void setTemperatureControl(bool val); + int getTemperatureEvent(); + void resetTemperatureEvent(); + bool getAutoComparatorDisableMode(); + void setAutoComparatorDisableMode(bool val); + int getNumberOfAdditionalStorageCells(); + void setNumberOfAdditionalStorageCells(int value); + int getStorageCellStart(); + void setStorageCellStart(int pos); + int64_t getStorageCellDelay(); + void setStorageCellDelay(int64_t value); - bool getReceiverSilentMode(); - void setReceiverSilentMode(bool enable); + /************************************************** + * * + * Gotthard Specific * + * * + * ************************************************/ + slsDetectorDefs::ROI getROI(); + void setROI(slsDetectorDefs::ROI arg); + void clearROI(); + int64_t getExptimeLeft() const; - /** - * If data streaming in receiver is enabled, - * restream the stop dummy packet from receiver - * Used usually for Moench, - * in case it is lost in network due to high data rate - */ - void restreamStopFromReceiver(); + /************************************************** + * * + * Gotthard2 Specific * + * * + * ************************************************/ + int64_t getNumberOfBursts(); + void setNumberOfBursts(int64_t value); + int64_t getBurstPeriod(); + void setBurstPeriod(int64_t value); + std::array getInjectChannel(); + void setInjectChannel(const int offsetChannel, const int incrementChannel); + std::vector getVetoPhoton(const int chipIndex); + void setVetoPhoton(const int chipIndex, const int numPhotons, + const int energy, const std::string &fname); + void setVetoReference(const int gainIndex, const int value); + burstMode getBurstMode(); + void setBurstMode(burstMode value); + bool getCurrentSource(); + void setCurrentSource(bool value); + slsDetectorDefs::timingSourceType getTimingSource(); + void setTimingSource(slsDetectorDefs::timingSourceType value); + bool getVeto(); + void setVeto(bool enable); - /** - * Opens pattern file and sends pattern to CTB - * @param fname pattern file to open - */ + /************************************************** + * * + * Mythen3 Specific * + * * + * ************************************************/ + uint32_t getCounterMask(); + void setCounterMask(uint32_t countermask); + int getNumberOfGates(); + void setNumberOfGates(int value); + std::array getExptimeForAllGates(); + int64_t getGateDelay(int gateIndex); + void setGateDelay(int gateIndex, int64_t value); + std::array getGateDelayForAllGates(); + + /************************************************** + * * + * CTB / Moench Specific * + * * + * ************************************************/ + int getNumberOfAnalogSamples(); + void setNumberOfAnalogSamples(int value); + int getPipeline(int clkIndex); + void setPipeline(int clkIndex, int value); + uint32_t getADCEnableMask(); + void setADCEnableMask(uint32_t mask); + uint32_t getTenGigaADCEnableMask(); + void setTenGigaADCEnableMask(uint32_t mask); + + /************************************************** + * * + * CTB Specific * + * * + * ************************************************/ + int getNumberOfDigitalSamples(); + void setNumberOfDigitalSamples(int value); + readoutMode getReadoutMode(); + void setReadoutMode(const readoutMode mode); + int getExternalSamplingSource(); + int setExternalSamplingSource(int value); + bool getExternalSampling(); + void setExternalSampling(bool value); + std::vector getReceiverDbitList() const; + void setReceiverDbitList(const std::vector &list); + int getReceiverDbitOffset(); + void setReceiverDbitOffset(int value); + void setDigitalIODelay(uint64_t pinMask, int delay); + bool getLEDEnable(); + void setLEDEnable(bool enable); + + /************************************************** + * * + * Pattern * + * * + * ************************************************/ void setPattern(const std::string &fname); - - /** - * Sets pattern IO control (CTB/ Moench) - * @param word 64bit word to be written, -1 gets - * @returns actual value - */ - uint64_t setPatternIOControl(uint64_t word = -1); - - /** - * Sets pattern clock control (CTB/ Moench) - * @param word 64bit word to be written, -1 gets - * @returns actual value - */ - uint64_t setPatternClockControl(uint64_t word = -1); - - /** - * Writes a pattern word (CTB/ Moench/ Mythen3) - * @param addr address of the word - * @param word 64bit word to be written, -1 reads the addr (same as - * executing the pattern for ctb) - * @returns actual value - */ - uint64_t setPatternWord(int addr, uint64_t word); - - /** - * Sets the pattern or loop limits (CTB/ Moench/ Mythen3) - * @param level -1 complete pattern, 0,1,2, loop level - * @param start start address for level 0-2, -1 gets - * @param stop stop address for level 0-2, -1 gets - * @returns array of start addr and stop addr - */ - std::array setPatternLoopAddresses(int level = -1, int start = -1, - int stop = -1); - - /** - * Sets the pattern or loop limits (CTB/ Moench/ Mythen3) - * @param level -1 complete pattern, 0,1,2, loop level - * @param n number of loops for level 0-2, -1 gets - * @returns number of loops - */ - int setPatternLoopCycles(int level = -1, int n = -1); - - /** - * Sets the wait address (CTB/ Moench/ Mythen3) - * @param level 0,1,2, wait level - * @param addr wait address, -1 gets - * @returns actual value - */ - int setPatternWaitAddr(int level, int addr = -1); - - /** - * Sets the wait time (CTB/ Moench/ Mythen3) - * @param level 0,1,2, wait level - * @param t wait time, -1 gets - * @returns actual value - */ - uint64_t setPatternWaitTime(int level, uint64_t t = -1); - - /** - * Sets the mask applied to every pattern (CTB/ Moench/ Mythen3) - * @param mask mask to be applied - */ - void setPatternMask(uint64_t mask); - - /** - * Gets the mask applied to every pattern (CTB/ Moench/ Mythen3) - * @returns mask set - */ + uint64_t getPatternIOControl(); + void setPatternIOControl(uint64_t word); + uint64_t getPatternClockControl(); + void setPatternClockControl(uint64_t word); + uint64_t getPatternWord(int addr); + void setPatternWord(int addr, uint64_t word); + std::array getPatternLoopAddresses(int level); + void setPatternLoopAddresses(int level, int start, int stop); + int getPatternLoopCycles(int level); + void setPatternLoopCycles(int level, int n); + int getPatternWaitAddr(int level); + void setPatternWaitAddr(int level, int addr); + uint64_t getPatternWaitTime(int level); + void setPatternWaitTime(int level, uint64_t t); uint64_t getPatternMask(); - - /** - * Selects the bits that the mask will be applied to for every pattern (CTB/ - * Moench/ Mythen3) - * @param mask mask to select bits - */ - void setPatternBitMask(uint64_t mask); - - /** - * Gets the bits that the mask will be applied to for every pattern (CTB/ - * Moench/ Mythen3) - * @returns mask of bits selected - */ + void setPatternMask(uint64_t mask); uint64_t getPatternBitMask(); - - /** [Mythen3] */ + void setPatternBitMask(uint64_t mask); void startPattern(); - /** - * Set LED Enable (Moench, CTB only) - * @param enable 1 to switch on, 0 to switch off, -1 gets - * @returns LED enable - */ - int setLEDEnable(int enable = -1); + /************************************************** + * * + * Moench * + * * + * ************************************************/ + std::map getAdditionalJsonHeader(); + void setAdditionalJsonHeader( + const std::map &jsonHeader); + std::string getAdditionalJsonParameter(const std::string &key); + void setAdditionalJsonParameter(const std::string &key, + const std::string &value); - /** - * Set Digital IO Delay (Moench, CTB only) - * @param digital IO mask to select the pins - * @param delay delay in ps(1 bit=25ps, max of 775 ps) - */ - void setDigitalIODelay(uint64_t pinMask, int delay); + /************************************************** + * * + * Advanced * + * * + * ************************************************/ + void programFPGA(std::vector buffer); + void resetFPGA(); + void copyDetectorServer(const std::string &fname, + const std::string &hostname); + void rebootController(); + uint32_t readRegister(uint32_t addr); + uint32_t writeRegister(uint32_t addr, uint32_t val); + uint32_t setBit(uint32_t addr, int n); + uint32_t clearBit(uint32_t addr, int n); + void executeFirmwareTest(); + void executeBusTest(); + void writeAdcRegister(uint32_t addr, uint32_t val); + uint32_t getADCInvert(); + void setADCInvert(uint32_t value); - /** [Mythen3][Gotthard2] */ - int getClockFrequency(int clkIndex); - - /** [Mythen3][Gotthard2] */ - void setClockFrequency(int clkIndex, int value); - - /** [Mythen3][Gotthard2] */ - int getClockPhase(int clkIndex, bool inDegrees); - - /** [Mythen3][Gotthard2] */ - void setClockPhase(int clkIndex, int value, bool inDegrees); - - /** [Mythen3][Gotthard2] */ - int getMaxClockPhaseShift(int clkIndex); - - /** [Mythen3][Gotthard2] */ - int getClockDivider(int clkIndex); - - /** [Mythen3][Gotthard2] */ - void setClockDivider(int clkIndex, int value); - - /** [Ctb][Moench] */ - int getPipeline(int clkIndex); - - /** [Ctb][Moench] */ - void setPipeline(int clkIndex, int value); - - /** [Mythen3] */ - void setCounterMask(uint32_t countermask); - - /** [Mythen3] */ - uint32_t getCounterMask(); + /************************************************** + * * + * Insignificant * + * * + * ************************************************/ + int getControlPort() const; + int setControlPort(int port_number); + int getStopPort() const; + int setStopPort(int port_number); + bool getLockDetector(); + void setLockDetector(bool lock); + sls::IpAddr getLastClientIP(); + std::string execCommand(const std::string &cmd); + int64_t getNumberOfFramesFromStart() const; + int64_t getActualTime() const; + int64_t getMeasurementTime() const; + uint64_t getReceiverCurrentFrameIndex() const; private: /** @@ -1586,14 +530,7 @@ class Module : public virtual slsDetectorDefs { template Ret sendToDetector(int fnum, const Arg &args); - /** - * Send function parameters to detector (stop server) - * @param fnum function enum - * @param args argument pointer - * @param args_size size of argument - * @param retval return pointers - * @param retval_size size of return value - */ + /** Send function parameters to detector (stop server) */ void sendToDetectorStop(int fnum, const void *args, size_t args_size, void *retval, size_t retval_size); @@ -1622,14 +559,14 @@ class Module : public virtual slsDetectorDefs { void sendToDetectorStop(int fnum) const; - /** - * Send function parameters to receiver - * @param fnum function enum - * @param args argument pointer - * @param args_size size of argument - * @param retval return pointers - * @param retval_size size of return value - */ + template Ret sendToDetectorStop(int fnum); + + template Ret sendToDetectorStop(int fnum) const; + + template + Ret sendToDetectorStop(int fnum, const Arg &args); + + /** Send function parameters to receiver */ void sendToReceiver(int fnum, const void *args, size_t args_size, void *retval, size_t retval_size); @@ -1664,55 +601,30 @@ class Module : public virtual slsDetectorDefs { template Ret sendToReceiver(int fnum, const Arg &args) const; - /** - * Get Detector Type from Shared Memory (opening shm without verifying size) - * @param multi_id multi detector Id - * @param verify true to verify if shm size matches existing one - * @returns detector type - */ - detectorType getDetectorTypeFromShm(int multi_id, bool verify = true); + /** Get Detector Type from Shared Memory + @param verify if shm size matches existing one */ + detectorType getDetectorTypeFromShm(int det_id, bool verify = true); - /** - * Initialize shared memory - * @param created true if shared memory must be created, else false to open - * @param type type of detector - * @param multi_id multi detector Id - * @param verify true to verify if shm size matches existing one - * @returns true if the shared memory was created now - */ - void initSharedMemory(detectorType type, int multi_id, bool verify = true); + /** Initialize shared memory + @param verify if shm size matches existing one */ + void initSharedMemory(detectorType type, int det_id, bool verify = true); - /** - * Initialize detector structure to defaults - * Called when new shared memory is created - * @param type type of detector - */ + /** Initialize detector structure to defaults, + Called when new shared memory is created */ void initializeDetectorStructure(detectorType type); - /** - * Send a sls_detector_module structure over socket - * @param myMod module structure to send - * @returns number of bytes sent to the detector - */ + void checkDetectorVersionCompatibility(); + void checkReceiverVersionCompatibility(); + void restreamStopFromReceiver(); + void setModule(sls_detector_module &module, bool trimbits = true); int sendModule(sls_detector_module *myMod, sls::ClientSocket &client); + void updateReceiverStreamingIP(); - /** - * Receive a sls_detector_module structure over socket - * @param myMod module structure to receive - * @returns number of bytes received from the detector - */ - int receiveModule(sls_detector_module *myMod, sls::ClientSocket &client); - - /** - * Get MAC from the receiver using udpip and - * set up UDP connection in detector - */ - void setUDPConnection(); - - /* - * Template function to do linear interpolation between two points (Eiger - * only) - */ + void updateRateCorrection(); + void setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, + bool trimbits = true); + /** Template function to do linear interpolation between two points (Eiger + only) */ template V linearInterpolation(const E x, const E x1, const E x2, const V y1, const V y2) { @@ -1736,36 +648,15 @@ class Module : public virtual slsDetectorDefs { sls_detector_module interpolateTrim(sls_detector_module *a, sls_detector_module *b, const int energy, const int e1, - const int e2, int tb = 1); + const int e2, bool trimbits = true); - /** - * reads a trim/settings file - * @param fname name of the file to be read - * @param myMod pointer to the module structure which has to be set.
- * If it is NULL a new module structure will be created - * @param tb 1 to include trimbits, 0 to exclude (used for eiger) - * @returns the pointer to myMod or NULL if reading the file failed - */ + std::string getTrimbitFilename(detectorSettings settings, int e_eV); + sls_detector_module readSettingsFile(const std::string &fname, + bool trimbits = true); + void programFPGAviaBlackfin(std::vector buffer); + void programFPGAviaNios(std::vector buffer); - sls_detector_module readSettingsFile(const std::string &fname, int tb = 1); - - /** - * writes a trim/settings file - * @param fname name of the file to be written - * @param mod module structure which has to be written to file - */ - void writeSettingsFile(const std::string &fname, sls_detector_module &mod); - - /** - * Get Names of dacs in settings file - * @returns vector dac names expected in settings file - */ - std::vector getSettingsFileDacNames(); - - /** Module Id or position in the detectors list */ - const int detId; - - /** Shared Memory object */ + const int moduleId; mutable sls::SharedMemory shm{0, 0}; }; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp index f9975b2f5..e41bea6b4 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp @@ -523,27 +523,6 @@ TEST_CASE("overflow", "[.cmd][.new]") { } } -TEST_CASE("storeinram", "[.cmd][.new]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::EIGER) { - auto previous = det.getStoreInRamMode(); - std::ostringstream oss1, oss2, oss3; - proxy.Call("storeinram", {"1"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "storeinram 1\n"); - proxy.Call("storeinram", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "storeinram 1\n"); - proxy.Call("storeinram", {"0"}, -1, PUT, oss3); - REQUIRE(oss3.str() == "storeinram 0\n"); - for (int i = 0; i != det.size(); ++i) { - det.setStoreInRamMode(previous[i], {i}); - } - } else { - REQUIRE_THROWS(proxy.Call("storeinram", {}, -1, GET)); - } -} - TEST_CASE("flippeddatax", "[.cmd][.new]") { Detector det; CmdProxy proxy(&det); diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index ef9dbfc52..65ce7e4c3 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -109,7 +109,6 @@ void ClientInterface::startTCPServer() { // clang-format off int ClientInterface::functionTable(){ flist[F_EXEC_RECEIVER_COMMAND] = &ClientInterface::exec_command; - flist[F_EXIT_RECEIVER] = &ClientInterface::exit_server; flist[F_LOCK_RECEIVER] = &ClientInterface::lock_receiver; flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip; flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port; @@ -291,12 +290,6 @@ int ClientInterface::exec_command(Interface &socket) { return socket.sendResult(retval); } -int ClientInterface::exit_server(Interface &socket) { - LOG(logINFO) << "Closing server"; - socket.Send(OK); - return GOODBYE; -} - int ClientInterface::lock_receiver(Interface &socket) { auto lock = socket.Receive(); LOG(logDEBUG1) << "Locking Server to " << lock; @@ -338,47 +331,7 @@ int ClientInterface::get_version(Interface &socket) { int ClientInterface::setup_receiver(Interface &socket) { auto arg = socket.Receive(); - LOG(logDEBUG) << "detType:" << arg.detType << std::endl - << "multiSize.x:" << arg.multiSize.x << std::endl - << "multiSize.y:" << arg.multiSize.y << std::endl - << "detId:" << arg.detId << std::endl - << "hostname:" << arg.hostname << std::endl - << "udpInterfaces:" << arg.udpInterfaces << std::endl - << "udp_dstport:" << arg.udp_dstport << std::endl - << "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl - << "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl - << "udp_dstport2:" << arg.udp_dstport2 << std::endl - << "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl - << "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) - << std::endl - << "frames:" << arg.frames << std::endl - << "triggers:" << arg.triggers << std::endl - << "bursts:" << arg.bursts << std::endl - << "analogSamples:" << arg.analogSamples << std::endl - << "digitalSamples:" << arg.digitalSamples << std::endl - << "expTimeNs:" << arg.expTimeNs << std::endl - << "periodNs:" << arg.periodNs << std::endl - << "subExpTimeNs:" << arg.subExpTimeNs << std::endl - << "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl - << "activate:" << arg.activate << std::endl - << "quad:" << arg.quad << std::endl - << "dynamicRange:" << arg.dynamicRange << std::endl - << "timMode:" << arg.timMode << std::endl - << "tenGiga:" << arg.tenGiga << std::endl - << "roMode:" << arg.roMode << std::endl - << "adcMask:" << arg.adcMask << std::endl - << "adc10gMask:" << arg.adc10gMask << std::endl - << "roi.xmin:" << arg.roi.xmin << std::endl - << "roi.xmax:" << arg.roi.xmax << std::endl - << "countermask:" << arg.countermask << std::endl - << "burstType:" << arg.burstType << std::endl - << "exptime1:" << arg.expTime1Ns << std::endl - << "exptime2:" << arg.expTime2Ns << std::endl - << "exptime3:" << arg.expTime3Ns << std::endl - << "gateDelay1:" << arg.gateDelay1Ns << std::endl - << "gateDelay2:" << arg.gateDelay2Ns << std::endl - << "gateDelay3:" << arg.gateDelay3Ns << std::endl - << "gates:" << arg.gates << std::endl; + LOG(logDEBUG) << sls::ToString(arg); // if object exists, verify unlocked and idle, else only verify lock // (connecting first time) @@ -389,10 +342,10 @@ int ClientInterface::setup_receiver(Interface &socket) { // basic setup setDetectorType(arg.detType); { - int msize[2] = {arg.multiSize.x, arg.multiSize.y}; - impl()->setMultiDetectorSize(msize); + int msize[2] = {arg.numberOfDetector.x, arg.numberOfDetector.y}; + impl()->setDetectorSize(msize); } - impl()->setDetectorPositionId(arg.detId); + impl()->setModulePositionId(arg.moduleId); impl()->setDetectorHostname(arg.hostname); // udp setup diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index c34e2cc50..3b0212d37 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -61,7 +61,6 @@ class ClientInterface : private virtual slsDetectorDefs { void verifyIdle(sls::ServerInterface &socket); int exec_command(sls::ServerInterface &socket); - int exit_server(sls::ServerInterface &socket); int lock_receiver(sls::ServerInterface &socket); int get_last_client_ip(sls::ServerInterface &socket); int set_port(sls::ServerInterface &socket); diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 31e7304ca..621bdbcc4 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -55,7 +55,7 @@ void Implementation::InitializeMembers() { myDetectorType = GENERIC; for (int i = 0; i < MAX_DIMENSIONS; ++i) numDet[i] = 0; - detID = 0; + modulePos = 0; detHostname = ""; silentMode = false; fifoDepth = 0; @@ -315,12 +315,12 @@ void Implementation::setDetectorType(const detectorType d) { LOG(logDEBUG) << " Detector type set to " << sls::ToString(d); } -int *Implementation::getMultiDetectorSize() const { +int *Implementation::getDetectorSize() const { LOG(logDEBUG3) << __SHORT_AT__ << " called"; return (int *)numDet; } -void Implementation::setMultiDetectorSize(const int *size) { +void Implementation::setDetectorSize(const int *size) { LOG(logDEBUG3) << __SHORT_AT__ << " called"; std::string log_message = "Detector Size (ports): ("; for (int i = 0; i < MAX_DIMENSIONS; ++i) { @@ -350,31 +350,32 @@ void Implementation::setMultiDetectorSize(const int *size) { LOG(logINFO) << log_message; } -int Implementation::getDetectorPositionId() const { +int Implementation::getModulePositionId() const { LOG(logDEBUG3) << __SHORT_AT__ << " called"; - return detID; + return modulePos; } -void Implementation::setDetectorPositionId(const int id) { +void Implementation::setModulePositionId(const int id) { LOG(logDEBUG3) << __SHORT_AT__ << " called"; - detID = id; - LOG(logINFO) << "Detector Position Id:" << detID; + modulePos = id; + LOG(logINFO) << "Module Position Id:" << modulePos; // update zmq port streamingPort = - DEFAULT_ZMQ_RX_PORTNO + (detID * (myDetectorType == EIGER ? 2 : 1)); + DEFAULT_ZMQ_RX_PORTNO + (modulePos * (myDetectorType == EIGER ? 2 : 1)); for (unsigned int i = 0; i < dataProcessor.size(); ++i) { dataProcessor[i]->SetupFileWriter( fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, - &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads, + &filePath, &fileIndex, &overwriteEnable, &modulePos, &numThreads, &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData); } assert(numDet[1] != 0); for (unsigned int i = 0; i < listener.size(); ++i) { uint16_t row = 0, col = 0; - row = (detID % numDet[1]) * ((numUDPInterfaces == 2) ? 2 : 1); // row - col = (detID / numDet[1]) * ((myDetectorType == EIGER) ? 2 : 1) + + row = + (modulePos % numDet[1]) * ((numUDPInterfaces == 2) ? 2 : 1); // row + col = (modulePos / numDet[1]) * ((myDetectorType == EIGER) ? 2 : 1) + i; // col for horiz. udp ports listener[i]->SetHardCodedPosition(row, col); } @@ -555,9 +556,9 @@ void Implementation::setFileWriteEnable(const bool b) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) { dataProcessor[i]->SetupFileWriter( fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, - &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads, - &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], - generalData); + &filePath, &fileIndex, &overwriteEnable, &modulePos, + &numThreads, &numberOfTotalFrames, &dynamicRange, + &udpPortNum[i], generalData); } } @@ -1062,9 +1063,9 @@ void Implementation::setNumberofUDPInterfaces(const int n) { SetThreadPriorities(); // update (from 1 to 2 interface) & also for printout - setMultiDetectorSize(numDet); + setDetectorSize(numDet); // update row and column in dataprocessor - setDetectorPositionId(detID); + setModulePositionId(modulePos); // update call backs if (rawDataReadyCallBack) { diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 5f6e94374..403ceb412 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -28,10 +28,10 @@ class Implementation : private virtual slsDetectorDefs { * ************************************************/ void setDetectorType(const detectorType d); - int *getMultiDetectorSize() const; - void setMultiDetectorSize(const int *size); - int getDetectorPositionId() const; - void setDetectorPositionId(const int id); + int *getDetectorSize() const; + void setDetectorSize(const int *size); + int getModulePositionId() const; + void setModulePositionId(const int id); std::string getDetectorHostname() const; void setDetectorHostname(const std::string &c); bool getSilentMode() const; @@ -265,7 +265,7 @@ class Implementation : private virtual slsDetectorDefs { int numThreads; detectorType myDetectorType; int numDet[MAX_DIMENSIONS]; - int detID; + int modulePos; std::string detHostname; bool silentMode; uint32_t fifoDepth; diff --git a/slsSupportLib/include/ToString.h b/slsSupportLib/include/ToString.h index 7d7517e85..ff2db057f 100644 --- a/slsSupportLib/include/ToString.h +++ b/slsSupportLib/include/ToString.h @@ -41,6 +41,9 @@ std::string ToString(const defs::timingSourceType s); std::string ToString(const slsDetectorDefs::ROI &roi); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi); +std::string ToString(const slsDetectorDefs::rxParameters &r); +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::rxParameters &r); const std::string &ToString(const std::string &s); /** Convert std::chrono::duration with specified output unit */ diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 52ce82470..373f0707f 100644 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -445,8 +445,8 @@ typedef struct { */ struct rxParameters { detectorType detType{GENERIC}; - xy multiSize; - int detId{0}; + xy numberOfDetector; + int moduleId{0}; char hostname[MAX_STR_LENGTH]; int udpInterfaces{1}; int udp_dstport{0}; diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index aad684fc1..a0fd9137d 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -26,15 +26,12 @@ enum detFuncs { F_WRITE_REGISTER, F_READ_REGISTER, F_SET_MODULE, - F_GET_MODULE, F_SET_SETTINGS, F_GET_THRESHOLD_ENERGY, F_START_ACQUISITION, F_STOP_ACQUISITION, - F_START_READOUT, F_GET_RUN_STATUS, F_START_AND_READ_ALL, - F_READ_ALL, F_GET_NUM_FRAMES, F_SET_NUM_FRAMES, F_GET_NUM_TRIGGERS, @@ -70,7 +67,6 @@ enum detFuncs { F_SET_DYNAMIC_RANGE, F_SET_ROI, F_GET_ROI, - F_EXIT_SERVER, F_LOCK_SERVER, F_GET_LAST_CLIENT_IP, F_SET_PORT, @@ -161,8 +157,6 @@ enum detFuncs { F_GET_PARALLEL_MODE, F_SET_OVERFLOW_MODE, F_GET_OVERFLOW_MODE, - F_SET_STOREINRAM_MODE, - F_GET_STOREINRAM_MODE, F_SET_READOUT_MODE, F_GET_READOUT_MODE, F_SET_CLOCK_FREQUENCY, @@ -213,7 +207,6 @@ enum detFuncs { (detector server should not compile anyway) */ F_EXEC_RECEIVER_COMMAND, - F_EXIT_RECEIVER, F_LOCK_RECEIVER, F_GET_LAST_RECEIVER_CLIENT_IP, F_SET_RECEIVER_PORT, @@ -332,15 +325,12 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_WRITE_REGISTER: return "F_WRITE_REGISTER"; case F_READ_REGISTER: return "F_READ_REGISTER"; case F_SET_MODULE: return "F_SET_MODULE"; - case F_GET_MODULE: return "F_GET_MODULE"; case F_SET_SETTINGS: return "F_SET_SETTINGS"; case F_GET_THRESHOLD_ENERGY: return "F_GET_THRESHOLD_ENERGY"; case F_START_ACQUISITION: return "F_START_ACQUISITION"; case F_STOP_ACQUISITION: return "F_STOP_ACQUISITION"; - case F_START_READOUT: return "F_START_READOUT"; case F_GET_RUN_STATUS: return "F_GET_RUN_STATUS"; case F_START_AND_READ_ALL: return "F_START_AND_READ_ALL"; - case F_READ_ALL: return "F_READ_ALL"; case F_GET_NUM_FRAMES: return "F_GET_NUM_FRAMES"; case F_SET_NUM_FRAMES: return "F_SET_NUM_FRAMES"; case F_GET_NUM_TRIGGERS: return "F_GET_NUM_TRIGGERS"; @@ -376,7 +366,6 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_DYNAMIC_RANGE: return "F_SET_DYNAMIC_RANGE"; case F_SET_ROI: return "F_SET_ROI"; case F_GET_ROI: return "F_GET_ROI"; - case F_EXIT_SERVER: return "F_EXIT_SERVER"; case F_LOCK_SERVER: return "F_LOCK_SERVER"; case F_GET_LAST_CLIENT_IP: return "F_GET_LAST_CLIENT_IP"; case F_SET_PORT: return "F_SET_PORT"; @@ -467,8 +456,6 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_PARALLEL_MODE: return "F_GET_PARALLEL_MODE"; case F_SET_OVERFLOW_MODE: return "F_SET_OVERFLOW_MODE"; case F_GET_OVERFLOW_MODE: return "F_GET_OVERFLOW_MODE"; - case F_SET_STOREINRAM_MODE: return "F_SET_STOREINRAM_MODE"; - case F_GET_STOREINRAM_MODE: return "F_GET_STOREINRAM_MODE"; case F_SET_READOUT_MODE: return "F_SET_READOUT_MODE"; case F_GET_READOUT_MODE: return "F_GET_READOUT_MODE"; case F_SET_CLOCK_FREQUENCY: return "F_SET_CLOCK_FREQUENCY"; @@ -518,7 +505,6 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND"; - case F_EXIT_RECEIVER: return "F_EXIT_RECEIVER"; case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER"; case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP"; case F_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT"; diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 33529de4d..c958bc317 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -3,10 +3,10 @@ #define APILIB 0x200409 #define APIRECEIVER 0x200409 #define APIGUI 0x200409 -#define APICTB 0x200610 -#define APIGOTTHARD 0x200610 -#define APIJUNGFRAU 0x200610 -#define APIMOENCH 0x200610 -#define APIGOTTHARD2 0x200610 -#define APIMYTHEN3 0x200616 -#define APIEIGER 0x200617 +#define APIEIGER 0x200618 +#define APICTB 0x200618 +#define APIGOTTHARD 0x200618 +#define APIGOTTHARD2 0x200618 +#define APIJUNGFRAU 0x200618 +#define APIMYTHEN3 0x200618 +#define APIMOENCH 0x200615 diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 8b33f553d..e57727957 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -1,4 +1,5 @@ #include "ToString.h" +#include "network_utils.h" namespace sls { @@ -12,6 +13,57 @@ std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi) { return os << ToString(roi); } +std::string ToString(const slsDetectorDefs::rxParameters &r) { + std::ostringstream oss; + oss << '[' << "detType:" << r.detType << std::endl + << "numberOfDetector.x:" << r.numberOfDetector.x << std::endl + << "numberOfDetector.y:" << r.numberOfDetector.y << std::endl + << "moduleId:" << r.moduleId << std::endl + << "hostname:" << r.hostname << std::endl + << "udpInterfaces:" << r.udpInterfaces << std::endl + << "udp_dstport:" << r.udp_dstport << std::endl + << "udp_dstip:" << sls::IpAddr(r.udp_dstip) << std::endl + << "udp_dstmac:" << sls::MacAddr(r.udp_dstmac) << std::endl + << "udp_dstport2:" << r.udp_dstport2 << std::endl + << "udp_dstip2:" << sls::IpAddr(r.udp_dstip2) << std::endl + << "udp_dstmac2:" << sls::MacAddr(r.udp_dstmac2) << std::endl + << "frames:" << r.frames << std::endl + << "triggers:" << r.triggers << std::endl + << "bursts:" << r.bursts << std::endl + << "analogSamples:" << r.analogSamples << std::endl + << "digitalSamples:" << r.digitalSamples << std::endl + << "expTimeNs:" << r.expTimeNs << std::endl + << "periodNs:" << r.periodNs << std::endl + << "subExpTimeNs:" << r.subExpTimeNs << std::endl + << "subDeadTimeNs:" << r.subDeadTimeNs << std::endl + << "activate:" << r.activate << std::endl + << "quad:" << r.quad << std::endl + << "dynamicRange:" << r.dynamicRange << std::endl + << "timMode:" << r.timMode << std::endl + << "tenGiga:" << r.tenGiga << std::endl + << "roMode:" << r.roMode << std::endl + << "adcMask:" << r.adcMask << std::endl + << "adc10gMask:" << r.adc10gMask << std::endl + << "roi.xmin:" << r.roi.xmin << std::endl + << "roi.xmax:" << r.roi.xmax << std::endl + << "countermask:" << r.countermask << std::endl + << "burstType:" << r.burstType << std::endl + << "exptime1:" << r.expTime1Ns << std::endl + << "exptime2:" << r.expTime2Ns << std::endl + << "exptime3:" << r.expTime3Ns << std::endl + << "gateDelay1:" << r.gateDelay1Ns << std::endl + << "gateDelay2:" << r.gateDelay2Ns << std::endl + << "gateDelay3:" << r.gateDelay3Ns << std::endl + << "gates:" << r.gates << std::endl + << ']'; + return oss.str(); +} + +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::rxParameters &r) { + return os << ToString(r); +} + std::string ToString(const defs::runStatus s) { switch (s) { case defs::ERROR: