diff --git a/CMakeLists.txt b/CMakeLists.txt index 31d67ae1e..917ea805d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,17 @@ option(SLS_BUILD_DOCS "docs" OFF) option(SLS_BUILD_EXAMPLES "examples" OFF) option(SLS_TUNE_LOCAL "tune to local machine" OFF) - +# Use ld.gold if it is available and isn't disabled explicitly +option(SLS_USE_LD_GOLD "Use GNU gold linker" ON) +if (SLS_USE_LD_GOLD) + execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) + if ("${LD_VERSION}" MATCHES "GNU gold") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold") + else () + message(WARNING "GNU gold linker isn't available, using the default system linker.") + endif () +endif () set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) diff --git a/cmk.sh b/cmk.sh index 898e6f96f..98e11a684 100755 --- a/cmk.sh +++ b/cmk.sh @@ -11,6 +11,7 @@ PYTHON=0 TESTS=0 SIMULATOR=0 CTBGUI=0 +MANUALS=0 CLEAN=0 @@ -19,7 +20,7 @@ CMAKE_PRE="" CMAKE_POST="" usage() { echo -e " -Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [-h] [-d ] [-j] +Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [m] [-h] [-d ] [-j] -[no option]: only make -c: Clean -b: Builds/Rebuilds CMake files normal mode @@ -34,6 +35,7 @@ Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [-h] [-d ] -j: Number of threads to compile through -e: Debug mode -i: Builds tests + -m: Manuals Rebuild when you switch to a new build and compile in parallel: ./cmk.sh -bj5 @@ -69,7 +71,7 @@ For rebuilding only certain sections " ; exit 1; } -while getopts ":bpchd:j:trgeisu" opt ; do +while getopts ":bpchd:j:trgeisum" opt ; do case $opt in b) echo "Building of CMake files Required" @@ -124,6 +126,10 @@ while getopts ":bpchd:j:trgeisu" opt ; do echo "Compiling Options: Simulator" SIMULATOR=1 ;; + m) + echo "Compiling Manuals" + MANUALS=1 + ;; u) echo "Compiling Options: Chip Test Gui" CTBGUI=1 @@ -198,6 +204,12 @@ if [ $SIMULATOR -eq 1 ]; then echo "Simulator Option enabled" fi +#Manuals +if [ $MANUALS -eq 1 ]; then + CMAKE_POST+=" -DSLS_BUILD_DOCS=ON " + echo "Manuals Option enabled" +fi + #Chip Test Gui if [ $CTBGUI -eq 1 ]; then CMAKE_POST+=" -DSLS_USE_CTBGUI=ON " @@ -251,6 +263,9 @@ else make fi +if [ $MANUALS -eq 1 ]; then + make docs +fi diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index a81df2b7f..a37acd1e3 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,71 +1,69 @@ -find_package(Doxygen) -find_package(Sphinx) +find_package(Doxygen REQUIRED) +find_package(Sphinx REQUIRED) -if (DOXYGEN_FOUND AND SPHINX_FOUND) - # message(${CMAKE_PROJECT_SORURCE_DIR}/slsDetectorSoftware/src) - # Utility to generate command line documentation - add_executable(gendoc src/gendoc.cpp) - # This is a bit hacky, but better than exposing stuff? - target_include_directories(gendoc PRIVATE ${PROJECT_SOURCE_DIR}/slsDetectorSoftware/src) - target_link_libraries(gendoc PRIVATE - slsDetectorShared - ) - set_target_properties(gendoc PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) - - - #Doxygen - set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) - set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) - configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) +# Utility to generate command line documentation +add_executable(gendoc src/gendoc.cpp) +# This is a bit hacky, but better than exposing stuff? +target_include_directories(gendoc PRIVATE ${PROJECT_SOURCE_DIR}/slsDetectorSoftware/src) +target_link_libraries(gendoc PRIVATE + slsDetectorShared +) +set_target_properties(gendoc PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) - #Sphinx - set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src) - set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}) - set(SPHINX_SOURCE_FILES - src/commandline.rst - src/container_utils.rst - src/consuming.rst - src/dependencies.rst - src/detector.rst - src/index.rst - src/installation.rst - src/pydetector.rst - src/pyenums.rst - src/pyexamples.rst - src/receiver.rst - src/result.rst - src/type_traits.rst - src/ToString.rst - src/examples.rst - - ) - foreach(filename ${SPHINX_SOURCE_FILES}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${filename} - "${SPHINX_BUILD}/${filename}") - endforeach(filename ${SPHINX_SOURCE_FILES}) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" - "${SPHINX_BUILD}/conf.py" - @ONLY) +#Doxygen +set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) +set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) +configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) + +#Sphinx +set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}) + +set(SPHINX_SOURCE_FILES + src/commandline.rst + src/container_utils.rst + src/consuming.rst + src/dependencies.rst + src/detector.rst + src/index.rst + src/installation.rst + src/pydetector.rst + src/pyenums.rst + src/pyexamples.rst + src/receiver.rst + src/result.rst + src/type_traits.rst + src/ToString.rst + src/examples.rst + +) + +foreach(filename ${SPHINX_SOURCE_FILES}) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${filename} + "${SPHINX_BUILD}/${filename}") +endforeach(filename ${SPHINX_SOURCE_FILES}) + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" + "${SPHINX_BUILD}/conf.py" + @ONLY) + +add_custom_target(docs + gendoc + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} + COMMAND ${SPHINX_EXECUTABLE} -a -b html + -Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml + -c "${SPHINX_BUILD}" + ${SPHINX_BUILD}/src + ${SPHINX_BUILD}/html + COMMENT "Generating documentation with Sphinx") - add_custom_target(docs - gendoc - COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} - COMMAND ${SPHINX_EXECUTABLE} -a -b html - -Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml - -c "${SPHINX_BUILD}" - ${SPHINX_BUILD}/src - ${SPHINX_BUILD}/html - COMMENT "Generating documentation with Sphinx") -else (DOXYGEN_FOUND AND SPHINX_FOUND) - message("Doxygen and Sphinx are needed to build documentation") -endif (DOXYGEN_FOUND AND SPHINX_FOUND) diff --git a/docs/src/installation.rst b/docs/src/installation.rst index 57f624dc7..868b7aef2 100644 --- a/docs/src/installation.rst +++ b/docs/src/installation.rst @@ -54,4 +54,16 @@ using this compiler conda create -n myenv gxx_linux-64 cmake zmq conda activate myenv cmake ../slsDetectorPackage -DCMAKE_PREFIX_PATH=$CONDA_PREFIX - make -j12 \ No newline at end of file + make -j12 + + +Build this documentation +------------------------------- + +The documentation for the slsDetectorPackage is build using a combination +of Doxygen, Sphinx and Breathe. The easiest way to install the dependencies +is to use conda + +.. code-block:: bash + + conda create -n myenv python sphinx sphinx_rtd_theme \ No newline at end of file diff --git a/python/scripts/list_tested_cmd.py b/python/scripts/list_tested_cmd.py old mode 100644 new mode 100755 diff --git a/python/src/detector.cpp b/python/src/detector.cpp index d14258e8b..09a69668d 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -99,6 +99,12 @@ void init_det(py::module &m) { void (*)(detectorData *, uint64_t, uint32_t, void *), void *)) & Detector::registerDataCallback, py::arg(), py::arg()) + .def("getGapPixelsinCallback", + (bool (Detector::*)()) & Detector::getGapPixelsinCallback) + .def("setGapPixelsinCallback", + (void (Detector::*)(const bool)) & + Detector::setGapPixelsinCallback, + py::arg()) .def("getNumberOfFrames", (Result(Detector::*)(sls::Positions)) & Detector::getNumberOfFrames, @@ -246,6 +252,10 @@ void init_det(py::module &m) { (Result(Detector::*)(sls::Positions)) & Detector::getHighVoltage, py::arg() = Positions{}) + .def("setHighVoltage", + (void (Detector::*)(int, sls::Positions)) & + Detector::setHighVoltage, + py::arg(), py::arg() = Positions{}) .def("getPowerChip", (Result(Detector::*)(sls::Positions)) & Detector::getPowerChip, @@ -254,9 +264,13 @@ void init_det(py::module &m) { (void (Detector::*)(bool, sls::Positions)) & Detector::setPowerChip, py::arg(), py::arg() = Positions{}) - .def("setHighVoltage", - (void (Detector::*)(int, sls::Positions)) & - Detector::setHighVoltage, + .def("getImageTestMode", + (Result(Detector::*)(sls::Positions)) & + Detector::getImageTestMode, + py::arg() = Positions{}) + .def("setImageTestMode", + (void (Detector::*)(const int, sls::Positions)) & + Detector::setImageTestMode, py::arg(), py::arg() = Positions{}) .def("getTemperature", (Result(Detector::*)(defs::dacIndex, sls::Positions)) & @@ -685,13 +699,6 @@ void init_det(py::module &m) { (void (Detector::*)(const std::string &, sls::Positions)) & Detector::loadTrimbits, py::arg(), py::arg() = Positions{}) - .def("getRxAddGapPixels", - (Result(Detector::*)(sls::Positions)) & - Detector::getRxAddGapPixels, - py::arg() = Positions{}) - .def("setRxAddGapPixels", - (void (Detector::*)(bool)) & Detector::setRxAddGapPixels, - py::arg()) .def("getParallelMode", (Result(Detector::*)(sls::Positions)) & Detector::getParallelMode, @@ -889,14 +896,6 @@ void init_det(py::module &m) { (void (Detector::*)(defs::externalSignalFlag, sls::Positions)) & Detector::setExternalSignalFlags, py::arg(), py::arg() = Positions{}) - .def("getImageTestMode", - (Result(Detector::*)(sls::Positions)) & - Detector::getImageTestMode, - py::arg() = Positions{}) - .def("setImageTestMode", - (void (Detector::*)(const int, sls::Positions)) & - Detector::setImageTestMode, - py::arg(), py::arg() = Positions{}) .def("getNumberOfBursts", (Result(Detector::*)(sls::Positions)) & Detector::getNumberOfBursts, @@ -1190,11 +1189,13 @@ void init_det(py::module &m) { Detector::setPatternBitMask, py::arg(), py::arg() = Positions{}) .def("getAdditionalJsonHeader", - (Result(Detector::*)(sls::Positions)) & + (Result>(Detector::*)( + sls::Positions)) & Detector::getAdditionalJsonHeader, py::arg() = Positions{}) .def("setAdditionalJsonHeader", - (void (Detector::*)(const std::string &, sls::Positions)) & + (void (Detector::*)(const std::map &, + sls::Positions)) & Detector::setAdditionalJsonHeader, py::arg(), py::arg() = Positions{}) .def("getAdditionalJsonParameter", diff --git a/slsDetectorGui/forms/form_cloneplot.ui b/slsDetectorGui/forms/form_cloneplot.ui index 0965e65f2..5184ce500 100644 --- a/slsDetectorGui/forms/form_cloneplot.ui +++ b/slsDetectorGui/forms/form_cloneplot.ui @@ -55,6 +55,149 @@ + + + + 0 + 0 + + + + + 40 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 0 + 150 + 110 + + + + + + + + + 0 + 150 + 110 + + + + + + + + + 139 + 142 + 142 + + + + + + + + Complete Image + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 139 + 142 + 142 + + + + + + + + Missing Packets + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 117 + 20 + + + + + @@ -241,7 +384,7 @@ 0 0 376 - 28 + 27 diff --git a/slsDetectorGui/forms/form_plot.ui b/slsDetectorGui/forms/form_plot.ui index 56247f700..d01b1dbdd 100644 --- a/slsDetectorGui/forms/form_plot.ui +++ b/slsDetectorGui/forms/form_plot.ui @@ -19,47 +19,8 @@ Form - - - 6 - - - 0 - - - - - - 0 - 0 - - - - - Sans Serif - 10 - - - - Sample Plot - - - Qt::AlignCenter - - - false - - - - 9 - - - 0 - - - - - + + @@ -86,73 +47,6 @@ 0 - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 40 - 16777215 - - - - Sum: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - - - - - - - 0 - 0 - - - - - - - - @@ -181,8 +75,8 @@ - - + + 0 @@ -194,6 +88,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -222,6 +129,32 @@ + + + + + 0 + 0 + + + + - + + + + + + + + 0 + 0 + + + + - + + + @@ -235,9 +168,213 @@ + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 40 + 16777215 + + + + Sum: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 419 + 20 + + + + + + + + + 0 + 0 + + + + + Sans Serif + 10 + + + + Sample Plot + + + Qt::AlignCenter + + + true + + + + 9 + + + 0 + + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 139 + 142 + 142 + + + + + + + + Missing Packets + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 0 + 150 + 110 + + + + + + + + + 0 + 150 + 110 + + + + + + + + + 139 + 142 + 142 + + + + + + + + Complete Image + + + Qt::AlignCenter + + + diff --git a/slsDetectorGui/include/qCloneWidget.h b/slsDetectorGui/include/qCloneWidget.h index f7f000fb6..831ac33e4 100644 --- a/slsDetectorGui/include/qCloneWidget.h +++ b/slsDetectorGui/include/qCloneWidget.h @@ -14,7 +14,7 @@ class qCloneWidget : public QMainWindow, private Ui::ClonePlotObject { qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2, SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title, QString filePath, QString fileName, int64_t aIndex, - bool displayStats, QString min, QString max, QString sum); + bool displayStats, QString min, QString max, QString sum, bool completeImage); ~qCloneWidget(); diff --git a/slsDetectorGui/include/qDrawPlot.h b/slsDetectorGui/include/qDrawPlot.h index 1699c574a..b600c4441 100644 --- a/slsDetectorGui/include/qDrawPlot.h +++ b/slsDetectorGui/include/qDrawPlot.h @@ -59,11 +59,9 @@ class qDrawPlot : public QWidget, private Ui::PlotObject { private slots: void SetSaveFileName(QString val); - void AcquireThread(); void UpdatePlot(); signals: - void StartAcquireSignal(); void AcquireFinishedSignal(); void AbortSignal(); void UpdateSignal(); @@ -74,6 +72,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject { void SetupPlots(); void GetStatistics(double &min, double &max, double &sum); void DetachHists(); + void AcquireThread(); static void GetAcquisitionFinishedCallBack(double currentProgress, int detectorStatus, void *this_pointer); @@ -114,6 +113,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject { QString zTitle2d{"Intensity"}; QString plotTitle{""}; QString indexTitle{""}; + bool completeImage{false}; bool xyRangeChanged{false}; double xyRange[4]{0, 0, 0, 0}; bool isXYRange[4]{false, false, false, false}; diff --git a/slsDetectorGui/src/qCloneWidget.cpp b/slsDetectorGui/src/qCloneWidget.cpp index 6789c3092..42b80439e 100644 --- a/slsDetectorGui/src/qCloneWidget.cpp +++ b/slsDetectorGui/src/qCloneWidget.cpp @@ -15,13 +15,20 @@ qCloneWidget::qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2, SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title, QString fPath, QString fName, int64_t aIndex, bool displayStats, QString min, QString max, - QString sum) + QString sum, bool completeImage) : QMainWindow(parent), plot1d(p1), plot2d(p2), gainplot1d(gp1), gainplot2d(gp), filePath(fPath), fileName(fName), acqIndex(aIndex) { setupUi(this); id = qCloneWidget::NumClones++; SetupWidgetWindow(title); DisplayStats(displayStats, min, max, sum); + lblCompleteImage->hide(); + lblInCompleteImage->hide(); + if (completeImage) { + lblCompleteImage->show(); + } else { + lblInCompleteImage->show(); + } } qCloneWidget::~qCloneWidget() { diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index 3e79ba211..518235523 100644 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -87,7 +87,6 @@ void qDrawPlot::SetupWidgetWindow() { void qDrawPlot::Initialization() { connect(this, SIGNAL(UpdateSignal()), this, SLOT(UpdatePlot())); - connect(this, SIGNAL(StartAcquireSignal()), this, SLOT(AcquireThread())); } void qDrawPlot::SetupPlots() { @@ -97,27 +96,13 @@ void qDrawPlot::SetupPlots() { slsDetectorDefs::xy res = det->getDetectorSize(); nPixelsX = res.x; nPixelsY = res.y; - switch (detType) { - case slsDetectorDefs::EIGER: - try { - if (det->getQuad().tsquash("Inconsistent values for quad type")) { - nPixelsX /= 2; - nPixelsY *= 2; - if (nPixelsX != nPixelsY) { - --nPixelsX; - } - } - } - CATCH_DISPLAY("Could not get quad.", "qDrawPlot::SetupPlots") - break; - default: - break; - } LOG(logINFO) << "nPixelsX:" << nPixelsX; LOG(logINFO) << "nPixelsY:" << nPixelsY; boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal)); widgetStatistics->hide(); + lblCompleteImage->hide(); + lblInCompleteImage->hide(); // setup 1d data @@ -586,7 +571,7 @@ void qDrawPlot::ClonePlot() { clonegainplot2D, boxPlot->title(), fileSavePath, fileSaveName, currentAcqIndex, displayStatistics, lblMinDisp->text(), lblMaxDisp->text(), - lblSumDisp->text()); + lblSumDisp->text(), completeImage); } void qDrawPlot::SavePlot() { @@ -671,7 +656,8 @@ void qDrawPlot::StartAcquisition() { xyRangeChanged = true; } - emit StartAcquireSignal(); + QtConcurrent::run(this, &qDrawPlot::AcquireThread); + LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot"; } @@ -756,6 +742,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex, << " \t dynamic range: " << data->dynamicRange << std::endl << " \t file index: " << data->fileIndex << std::endl + << " \t complete image: " << data->completeImage << std::endl << " ]"; progress = (int)data->progressIndex; @@ -776,6 +763,11 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex, delete[] data2d; data2d = new double[nPixelsY * nPixelsX]; std::fill(data2d, data2d + nPixelsX * nPixelsY, 0); + if (gainData) { + delete[] gainData; + gainData = new double[nPixelsY * nPixelsX]; + std::fill(gainData, gainData + nPixelsX * nPixelsY, 0); + } } // convert data to double @@ -798,6 +790,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex, if ((int)subFrameIndex != -1) { indexTitle = QString("%1 %2").arg(frameIndex, subFrameIndex); } + completeImage = data->completeImage; // reset pedestal if (resetPedestal) { @@ -1118,6 +1111,16 @@ void qDrawPlot::UpdatePlot() { LOG(logDEBUG) << "Update Plot"; boxPlot->setTitle(plotTitle); + + // notify of incomplete images + lblCompleteImage->hide(); + lblInCompleteImage->hide(); + if(completeImage) { + lblCompleteImage->show(); + } else { + lblInCompleteImage->show(); + } + if (is1d) { Update1dPlot(); } else { diff --git a/slsDetectorGui/src/qTabPlot.cpp b/slsDetectorGui/src/qTabPlot.cpp index a9802f4bf..216f3cfe3 100644 --- a/slsDetectorGui/src/qTabPlot.cpp +++ b/slsDetectorGui/src/qTabPlot.cpp @@ -64,6 +64,7 @@ void qTabPlot::SetupWidgetWindow() { chkGapPixels->setEnabled(true); break; case slsDetectorDefs::JUNGFRAU: + chkGapPixels->setEnabled(true); chkGainPlot->setEnabled(true); chkGainPlot->setChecked(true); plot->EnableGainPlot(true); @@ -312,8 +313,7 @@ void qTabPlot::GetGapPixels() { disconnect(chkGapPixels, SIGNAL(toggled(bool)), this, SLOT(SetGapPixels(bool))); try { - auto retval = det->getRxAddGapPixels().tsquash( - "Inconsistent gap pixels enabled for all detectors."); + auto retval = det->getGapPixelsinCallback(); chkGapPixels->setChecked(retval); } CATCH_DISPLAY("Could not get gap pixels enable.", "qTabPlot::GetGapPixels") @@ -324,7 +324,7 @@ void qTabPlot::GetGapPixels() { void qTabPlot::SetGapPixels(bool enable) { LOG(logINFO) << "Setting Gap Pixels Enable to " << enable; try { - det->setRxAddGapPixels(enable); + det->setGapPixelsinCallback(enable); } CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels", this, &qTabPlot::GetGapPixels) @@ -672,6 +672,8 @@ void qTabPlot::Refresh() { break; case slsDetectorDefs::JUNGFRAU: chkGainPlot->setEnabled(true); + chkGapPixels->setEnabled(true); + GetGapPixels(); break; case slsDetectorDefs::GOTTHARD2: chkGainPlot1D->setEnabled(true); diff --git a/slsDetectorServers/ctbDetectorServer/CMakeLists.txt b/slsDetectorServers/ctbDetectorServer/CMakeLists.txt index 7ffdf780c..0eeec6b6f 100644 --- a/slsDetectorServers/ctbDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/ctbDetectorServer/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable(ctbDetectorServer_virtual ../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/programFpgaBlackfin.c + ../slsDetectorServer/src/communication_virtual.c ) include_directories( @@ -33,6 +34,7 @@ target_compile_definitions(ctbDetectorServer_virtual target_link_libraries(ctbDetectorServer_virtual PUBLIC pthread rt slsProjectCWarnings + m ) set_target_properties(ctbDetectorServer_virtual PROPERTIES diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index e655906b9..fbf0f9ed7 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 8ca4963a9..4e87de588 100755 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -10,22 +10,33 @@ #include "MAX1932.h" // hv #include "INA226.h" // i2c #include "ALTERA_PLL.h" // pll +#ifdef VIRTUAL +#include "communication_virtual.h" +#endif #include #include // usleep +#include #ifdef VIRTUAL #include #include +#include //ceil #endif // Global variable from slsDetectorServer_funcs extern int debugflag; extern udpStruct udpDetails; +extern const enum detectorType myDetectorType; // Global variable from UDPPacketHeaderGenerator extern uint64_t udpFrameNumber; extern uint32_t udpPacketNumber; +// Global variable from communication_funcs.c +extern int isControlServer; +extern void getMacAddressinString(char* cmac, int size, uint64_t mac); +extern void getIpAddressinString(char* cip, uint32_t ip); + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -420,6 +431,12 @@ void initStopServer() { LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); exit(EXIT_FAILURE); } +#ifdef VIRTUAL + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } +#endif } @@ -462,7 +479,12 @@ void setupDetector() { digitalEnable = 0; naSamples = 1; ndSamples = 1; - +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif ALTERA_PLL_ResetPLLAndReconfiguration(); resetCore(); @@ -1379,12 +1401,6 @@ int getADC(enum ADCINDEX ind){ int setHighVoltage(int val){ -#ifdef VIRTUAL - if (val >= 0) - highvoltage = val; - return highvoltage; -#endif - // setting hv if (val >= 0) { LOG(logINFO, ("Setting High voltage: %d V\n", val)); @@ -1393,7 +1409,7 @@ int setHighVoltage(int val){ // switch to external high voltage bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK)); - MAX1932_Set(val); + MAX1932_Set(&val); // switch on internal high voltage, if set if (val > 0) @@ -1473,26 +1489,36 @@ void calcChecksum(udp_header* udp) { int configureMAC(){ - uint32_t sourceip = udpDetails.srcip; - uint32_t destip = udpDetails.dstip; - uint64_t sourcemac = udpDetails.srcmac; - uint64_t destmac = udpDetails.dstmac; - int sourceport = udpDetails.srcport; - int destport = udpDetails.dstport; -#ifdef VIRTUAL - return OK; -#endif + uint32_t srcip = udpDetails.srcip; + uint32_t dstip = udpDetails.dstip; + uint64_t srcmac = udpDetails.srcmac; + uint64_t dstmac = udpDetails.dstmac; + int srcport = udpDetails.srcport; + int dstport = udpDetails.dstport; + LOG(logINFOBLUE, ("Configuring MAC\n")); + char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); + + LOG(logINFO, ( + "\tSource IP : %s\n" + "\tSource MAC : %s\n" + "\tSource Port : %d\n" + "\tDest IP : %s\n" + "\tDest MAC : %s\n" + "\tDest Port : %d\n", + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport)); + // 1 giga udp if (!enableTenGigabitEthernet(-1)) { - LOG(logINFOBLUE, ("Configuring 1G MAC\n")); + LOG(logINFOBLUE, ("\t1G MAC\n")); if (updateDatabytesandAllocateRAM() == FAIL) return -1; - char cDestIp[MAX_STR_LENGTH]; - memset(cDestIp, 0, MAX_STR_LENGTH); - sprintf(cDestIp, "%d.%d.%d.%d", (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff); - LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, destport)); - if (setUDPDestinationDetails(0, cDestIp, destport) == FAIL) { + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { LOG(logERROR, ("could not set udp 1G destination IP and port\n")); return FAIL; } @@ -1500,31 +1526,7 @@ int configureMAC(){ } // 10 G - LOG(logINFOBLUE, ("Configuring 10G MAC\n")); - - LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (sourceip>>24)&0xff,(sourceip>>16)&0xff,(sourceip>>8)&0xff,(sourceip)&0xff, sourceip)); - LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((sourcemac>>40)&0xFF), - (unsigned int)((sourcemac>>32)&0xFF), - (unsigned int)((sourcemac>>24)&0xFF), - (unsigned int)((sourcemac>>16)&0xFF), - (unsigned int)((sourcemac>>8)&0xFF), - (unsigned int)((sourcemac>>0)&0xFF), - (long long unsigned int)sourcemac)); - LOG(logINFO, ("\tSource Port : %d \t\t\t(0x%08x)\n",sourceport, sourceport)); - - LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff, destip)); - LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((destmac>>40)&0xFF), - (unsigned int)((destmac>>32)&0xFF), - (unsigned int)((destmac>>24)&0xFF), - (unsigned int)((destmac>>16)&0xFF), - (unsigned int)((destmac>>8)&0xFF), - (unsigned int)((destmac>>0)&0xFF), - (long long unsigned int)destmac)); - LOG(logINFO, ("\tDest. Port : %d \t\t\t(0x%08x)\n",destport, destport)); + LOG(logINFOBLUE, ("\t10G MAC\n")); // start addr uint32_t addr = RXR_ENDPOINT_START_REG; @@ -1534,21 +1536,21 @@ int configureMAC(){ // mac addresses // msb (32) + lsb (16) - udp->udp_destmac_msb = ((destmac >> 16) & BIT32_MASK); - udp->udp_destmac_lsb = ((destmac >> 0) & BIT16_MASK); + udp->udp_destmac_msb = ((dstmac >> 16) & BIT32_MASK); + udp->udp_destmac_lsb = ((dstmac >> 0) & BIT16_MASK); // msb (16) + lsb (32) - udp->udp_srcmac_msb = ((sourcemac >> 32) & BIT16_MASK); - udp->udp_srcmac_lsb = ((sourcemac >> 0) & BIT32_MASK); + udp->udp_srcmac_msb = ((srcmac >> 32) & BIT16_MASK); + udp->udp_srcmac_lsb = ((srcmac >> 0) & BIT32_MASK); // ip addresses - udp->ip_srcip_msb = ((sourceip >> 16) & BIT16_MASK); - udp->ip_srcip_lsb = ((sourceip >> 0) & BIT16_MASK); - udp->ip_destip_msb = ((destip >> 16) & BIT16_MASK); - udp->ip_destip_lsb = ((destip >> 0) & BIT16_MASK); + udp->ip_srcip_msb = ((srcip >> 16) & BIT16_MASK); + udp->ip_srcip_lsb = ((srcip >> 0) & BIT16_MASK); + udp->ip_destip_msb = ((dstip >> 16) & BIT16_MASK); + udp->ip_destip_lsb = ((dstip >> 0) & BIT16_MASK); // source port - udp->udp_srcport = sourceport; - udp->udp_destport = destport; + udp->udp_srcport = srcport; + udp->udp_destport = dstport; // other defines udp->udp_ethertype = 0x800; @@ -1579,6 +1581,9 @@ int* getDetectorPosition() { } int enableTenGigabitEthernet(int val) { +#ifdef VIRTUAL + return 0; +#endif uint32_t addr = CONFIG_REG; // set @@ -2157,11 +2162,27 @@ uint64_t getPatternBitMask() { int startStateMachine(){ #ifdef VIRTUAL - virtual_status = 1; - virtual_stop = 0; + // create udp socket + if(createUDPSocket(0) != OK) { + return FAIL; + } + LOG(logINFOBLUE, ("Starting State Machine\n")); + virtual_status = 1; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { - virtual_status = 0; LOG(logERROR, ("Could not start Virtual acquisition thread\n")); + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFOGREEN, ("Virtual Acquisition started\n")); @@ -2195,42 +2216,93 @@ int startStateMachine(){ #ifdef VIRTUAL void* start_timer(void* arg) { - int64_t periodns = getPeriod(); + if (!isControlServer) { + return NULL; + } + + int64_t periodNs = getPeriod(); int numFrames = (getNumFrames() * getNumTriggers() ); - int64_t exp_ns = getExpTime(); + int64_t expUs = getExpTime() / 1000; - int frameNr = 0; - // loop over number of frames - for(frameNr=0; frameNr!= numFrames; ++frameNr ) { + int imageSize = dataBytes; + int dataSize = UDP_PACKET_DATA_BYTES; + int packetSize = sizeof(sls_detector_header) + dataSize; + int packetsPerFrame = ceil((double)imageSize / (double)dataSize); - //check if virtual_stop is high - if(virtual_stop == 1){ - break; - } - - // sleep for exposure time - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); - usleep(exp_ns / 1000); - clock_gettime(CLOCK_REALTIME, &end); - - // calculate time left in period - int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); - - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodns > time_ns) { - usleep((periodns - time_ns)/ 1000); - } - } - - // set register frames left + // Generate Data + char imageData[imageSize]; + memset(imageData, 0, imageSize); + { + int i = 0; + for (i = 0; i < imageSize; i += sizeof(uint16_t)) { + *((uint16_t*)(imageData + i)) = i; + } } - // set status to idle + // Send data + { + int frameNr = 0; + // loop over number of frames + for(frameNr = 0; frameNr != numFrames; ++frameNr ) { + + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + break; + } + + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); + + int srcOffset = 0; + // loop packet + { + int i = 0; + for(i = 0; i != packetsPerFrame; ++i) { + + char packetData[packetSize]; + memset(packetData, 0, packetSize); + // set header + sls_detector_header* header = (sls_detector_header*)(packetData); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameNr; + header->packetNumber = i; + header->modId = 0; + header->row = detPos[X]; + header->column = detPos[Y]; + + // fill data + memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, dataSize); + srcOffset += dataSize; + + sendUDPPacket(0, packetData, packetSize); + } + } + LOG(logINFO, ("Sent frame: %d\n", frameNr)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + + // sleep for (period - exptime) + if (frameNr < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); + } + } + } + } + + closeUDPSocket(0); + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } @@ -2239,7 +2311,18 @@ void* start_timer(void* arg) { int stopStateMachine(){ LOG(logINFORED, ("Stopping State Machine\n")); #ifdef VIRTUAL - virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #endif //stop state machine @@ -2258,7 +2341,10 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - if(virtual_status == 0){ + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if(virtual_status == 0) { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; }else{ @@ -2530,6 +2616,9 @@ int readFrameFromFifo() { uint32_t runBusy() { #ifdef VIRTUAL + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } return virtual_status; #endif uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK); diff --git a/slsDetectorServers/eigerDetectorServer/Beb.c b/slsDetectorServers/eigerDetectorServer/Beb.c index 3676057a7..da6dcac56 100755 --- a/slsDetectorServers/eigerDetectorServer/Beb.c +++ b/slsDetectorServers/eigerDetectorServer/Beb.c @@ -178,120 +178,100 @@ void Beb_GetModuleConfiguration(int* master, int* top, int* normal) { -void Beb_EndofDataSend(int tengiga) { +int Beb_IsTransmitting(int* retval, int tengiga, int waitForDelay) { //mapping new memory - u_int32_t* csp0base=0; - int l_framepktLsbcounter, l_framepktMsbcounter, l_txndelaycounter, l_framedelaycounter; - int r_framepktLsbcounter, r_framepktMsbcounter, r_txndelaycounter, r_framedelaycounter; - int l_framepktLsbcounter_new, l_framepktMsbcounter_new, l_txndelaycounter_new, l_framedelaycounter_new; - int r_framepktLsbcounter_new, r_framepktMsbcounter_new, r_txndelaycounter_new, r_framedelaycounter_new; - int addr_l_framepktLsbcounter, addr_l_framepktMsbcounter, addr_l_txndelaycounter, addr_l_framedelaycounter; - int addr_r_framepktLsbcounter, addr_r_framepktMsbcounter, addr_r_txndelaycounter, addr_r_framedelaycounter; - - switch(tengiga) { - case 0: - addr_l_framepktLsbcounter = ONE_GIGA_LEFT_INDEX_LSB_COUNTER; - addr_l_framepktMsbcounter = ONE_GIGA_LEFT_INDEX_MSB_COUNTER; - addr_l_txndelaycounter = ONE_GIGA_LEFT_TXN_DELAY_COUNTER; - addr_l_framedelaycounter = ONE_GIGA_LEFT_FRAME_DELAY_COUNTER; - addr_r_framepktLsbcounter = ONE_GIGA_RIGHT_INDEX_LSB_COUNTER; - addr_r_framepktMsbcounter = ONE_GIGA_RIGHT_INDEX_MSB_COUNTER; - addr_r_txndelaycounter = ONE_GIGA_RIGHT_TXN_DELAY_COUNTER; - addr_r_framedelaycounter = ONE_GIGA_RIGHT_FRAME_DELAY_COUNTER; - break; - case 1: - addr_l_framepktLsbcounter = TEN_GIGA_LEFT_INDEX_LSB_COUNTER; - addr_l_framepktMsbcounter = TEN_GIGA_LEFT_INDEX_MSB_COUNTER; + u_int32_t* csp0base = 0; + int addr_l_txndelaycounter = 0, addr_l_framedelaycounter = 0; + int addr_r_txndelaycounter = 0, addr_r_framedelaycounter = 0; + int addr_l_framepktLsbcounter = 0, addr_l_framepktMsbcounter = 0; + int addr_r_framepktLsbcounter = 0, addr_r_framepktMsbcounter = 0; + if (tengiga) { addr_l_txndelaycounter = TEN_GIGA_LEFT_TXN_DELAY_COUNTER; addr_l_framedelaycounter = TEN_GIGA_LEFT_FRAME_DELAY_COUNTER; - addr_r_framepktLsbcounter = TEN_GIGA_RIGHT_INDEX_LSB_COUNTER; - addr_r_framepktMsbcounter = TEN_GIGA_RIGHT_INDEX_MSB_COUNTER; addr_r_txndelaycounter = TEN_GIGA_RIGHT_TXN_DELAY_COUNTER; addr_r_framedelaycounter = TEN_GIGA_RIGHT_FRAME_DELAY_COUNTER; - break; + addr_l_framepktLsbcounter = TEN_GIGA_LEFT_INDEX_LSB_COUNTER; + addr_l_framepktMsbcounter = TEN_GIGA_LEFT_INDEX_MSB_COUNTER; + addr_r_framepktLsbcounter = TEN_GIGA_RIGHT_INDEX_LSB_COUNTER; + addr_r_framepktMsbcounter = TEN_GIGA_RIGHT_INDEX_MSB_COUNTER; + } else { + addr_l_txndelaycounter = ONE_GIGA_LEFT_TXN_DELAY_COUNTER; + addr_l_framedelaycounter = ONE_GIGA_LEFT_FRAME_DELAY_COUNTER; + addr_r_txndelaycounter = ONE_GIGA_RIGHT_TXN_DELAY_COUNTER; + addr_r_framedelaycounter = ONE_GIGA_RIGHT_FRAME_DELAY_COUNTER; + addr_l_framepktLsbcounter = ONE_GIGA_LEFT_INDEX_LSB_COUNTER; + addr_l_framepktMsbcounter = ONE_GIGA_LEFT_INDEX_MSB_COUNTER; + addr_r_framepktLsbcounter = ONE_GIGA_RIGHT_INDEX_LSB_COUNTER; + addr_r_framepktMsbcounter = ONE_GIGA_RIGHT_INDEX_MSB_COUNTER; } - //open file pointer int fd = Beb_open(&csp0base,XPAR_COUNTER_BASEADDR); - if (fd < 0) { - LOG(logERROR, ("Delay read counter fail\n")); - return; + if(fd < 0){ + cprintf(BG_RED,"Could not read Beb Delay read counter\n"); + return FAIL; } else { //read data first time - l_framepktLsbcounter = Beb_Read32(csp0base, addr_l_framepktLsbcounter); - l_framepktMsbcounter = Beb_Read32(csp0base, addr_l_framepktMsbcounter); - l_txndelaycounter = Beb_Read32(csp0base, addr_l_txndelaycounter); - l_framedelaycounter = Beb_Read32(csp0base, addr_l_framedelaycounter); - r_framepktLsbcounter = Beb_Read32(csp0base, addr_r_framepktLsbcounter); - r_framepktMsbcounter = Beb_Read32(csp0base, addr_r_framepktMsbcounter); - r_txndelaycounter = Beb_Read32(csp0base, addr_r_txndelaycounter); - r_framedelaycounter = Beb_Read32(csp0base, addr_r_framedelaycounter); - LOG(logDEBUG1, ("\nLeft\n" - "FramepacketLsbcounter: %d\n" - "FramepacketMsbcounter: %d\n" - "Txndelaycounter:%d\n" - "Framedelaycounter:%d\n" - "\nRight\n" - "FramepacketLsbcounter: %d\n" - "FramepacketMsbcounter: %d\n" - "Txndelaycounter:%d\n" - "Framedelaycounter:%d\n\n", - l_framepktLsbcounter,l_framepktMsbcounter,l_txndelaycounter,l_framedelaycounter, - r_framepktLsbcounter,r_framepktMsbcounter,r_txndelaycounter,r_framedelaycounter)); - - //keep comparing with previous values - int maxtimer; - while(1) { - maxtimer = MAX(MAX(l_txndelaycounter,l_framedelaycounter),MAX(r_txndelaycounter,r_framedelaycounter)); - maxtimer /= 100; - LOG(logDEBUG1, ("Will wait for %d us\n",maxtimer)); - usleep(maxtimer); - - //read new values - l_framepktLsbcounter_new = Beb_Read32(csp0base, addr_l_framepktLsbcounter); - l_framepktMsbcounter_new = Beb_Read32(csp0base, addr_l_framepktMsbcounter); - l_txndelaycounter_new = Beb_Read32(csp0base, addr_l_txndelaycounter); - l_framedelaycounter_new = Beb_Read32(csp0base, addr_l_framedelaycounter); - r_framepktLsbcounter_new = Beb_Read32(csp0base, addr_r_framepktLsbcounter); - r_framepktMsbcounter_new = Beb_Read32(csp0base, addr_r_framepktMsbcounter); - r_txndelaycounter_new = Beb_Read32(csp0base, addr_r_txndelaycounter); - r_framedelaycounter_new = Beb_Read32(csp0base, addr_r_framedelaycounter); - LOG(logDEBUG1, ("\nLeft\n" - "FramepacketLsbcounter: %d\n" - "FramepacketMsbcounter: %d\n" - "Txndelaycounter:%d\n" - "Framedelaycounter:%d\n" - "\nRight\n" - "FramepacketLsbcounter: %d\n" - "FramepacketMsbcounter: %d\n" - "Txndelaycounter:%d\n" - "Framedelaycounter:%d\n\n", - l_framepktLsbcounter_new,l_framepktMsbcounter_new,l_txndelaycounter_new,l_framedelaycounter_new, - r_framepktLsbcounter_new,r_framepktMsbcounter_new,r_txndelaycounter_new,r_framedelaycounter_new)); - - if ((l_framepktLsbcounter == l_framepktLsbcounter_new) && - (l_framepktMsbcounter == l_framepktMsbcounter_new) && - (r_framepktLsbcounter == r_framepktLsbcounter_new) && - (r_framepktMsbcounter == r_framepktMsbcounter_new)) - break; - - //update old values - l_framepktLsbcounter = l_framepktLsbcounter_new; - l_framepktMsbcounter = l_framepktMsbcounter_new; - l_txndelaycounter = l_txndelaycounter_new; - l_framedelaycounter = l_framedelaycounter_new; - r_framepktLsbcounter = r_framepktLsbcounter_new; - r_framepktMsbcounter = r_framepktMsbcounter_new; - r_txndelaycounter = r_txndelaycounter_new; - r_framedelaycounter = r_framedelaycounter_new; - + int l_txndelaycounter = Beb_Read32(csp0base, addr_l_txndelaycounter); + int l_framedelaycounter = Beb_Read32(csp0base, addr_l_framedelaycounter); + int r_txndelaycounter = Beb_Read32(csp0base, addr_r_txndelaycounter); + int r_framedelaycounter = Beb_Read32(csp0base, addr_r_framedelaycounter); + int l_framepktLsbcounter = Beb_Read32(csp0base, addr_l_framepktLsbcounter); + int l_framepktMsbcounter = Beb_Read32(csp0base, addr_l_framepktMsbcounter); + int r_framepktLsbcounter = Beb_Read32(csp0base, addr_r_framepktLsbcounter); + int r_framepktMsbcounter = Beb_Read32(csp0base, addr_r_framepktMsbcounter); +#ifdef VERBOSE + printf("\nFirst Read:\n" + "\tLeft [Txndelaycounter:%d, Framedelaycounter:%d]\n" + "\tRight [Txndelaycounter:%d, Framedelaycounter:%d]\n", + "\tLeft [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n" + "\tRight [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n", + l_txndelaycounter,l_framedelaycounter, r_txndelaycounter,r_framedelaycounter, + l_framepktLsbcounter, l_framepktMsbcounter, r_framepktLsbcounter, r_framepktMsbcounter); +#endif + // wait for max counter delay + if (waitForDelay) { + int maxtimer = (MAX(MAX(l_txndelaycounter,l_framedelaycounter),MAX(r_txndelaycounter,r_framedelaycounter))) / 100; // counter values in 10 ns + printf("Will wait for %d us\n", maxtimer); + usleep (maxtimer); + } + // wait for 1 ms + else { + printf("Will wait for 1 ms\n"); + usleep (1 * 1000); } - LOG(logINFO, ("Detector has sent all data\n")); + // read values again + int l_txndelaycounter2 = Beb_Read32(csp0base, addr_l_txndelaycounter); + int l_framedelaycounter2 = Beb_Read32(csp0base, addr_l_framedelaycounter); + int r_txndelaycounter2 = Beb_Read32(csp0base, addr_r_txndelaycounter); + int r_framedelaycounter2 = Beb_Read32(csp0base, addr_r_framedelaycounter); + int l_framepktLsbcounter2 = Beb_Read32(csp0base, addr_l_framepktLsbcounter); + int l_framepktMsbcounter2 = Beb_Read32(csp0base, addr_l_framepktMsbcounter); + int r_framepktLsbcounter2 = Beb_Read32(csp0base, addr_r_framepktLsbcounter); + int r_framepktMsbcounter2 = Beb_Read32(csp0base, addr_r_framepktMsbcounter); +#ifdef VERBOSE + printf("\nSecond Read:\n" + "\tLeft [Txndelaycounter:%d, Framedelaycounter:%d]\n" + "\tRight [Txndelaycounter:%d, Framedelaycounter:%d]\n", + "\tLeft [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n" + "\tRight [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n", + l_txndelaycounter2,l_framedelaycounter2, r_txndelaycounter2,r_framedelaycounter2, + l_framepktLsbcounter2, l_framepktMsbcounter2, r_framepktLsbcounter2, r_framepktMsbcounter2); +#endif + // any change in values, it is still transmitting + if (l_txndelaycounter != l_txndelaycounter2 || l_framedelaycounter != l_framedelaycounter2 || + r_txndelaycounter != r_txndelaycounter2 || r_framedelaycounter != r_framedelaycounter2 || + l_framepktLsbcounter != l_framepktLsbcounter2 || l_framepktMsbcounter != l_framepktMsbcounter2 || + r_framepktLsbcounter != r_framepktLsbcounter2 || r_framepktMsbcounter != r_framepktMsbcounter2) { + *retval = 1; + } else { + *retval = 0; + } //close file pointer Beb_close(fd,csp0base); } + return OK; } diff --git a/slsDetectorServers/eigerDetectorServer/Beb.h b/slsDetectorServers/eigerDetectorServer/Beb.h index e661873a2..594ff7f1a 100755 --- a/slsDetectorServers/eigerDetectorServer/Beb.h +++ b/slsDetectorServers/eigerDetectorServer/Beb.h @@ -34,7 +34,7 @@ unsigned int Beb_GetBebInfoIndex(unsigned int beb_numb); void Beb_GetModuleConfiguration(int* master, int* top, int* normal); -void Beb_EndofDataSend(int tengiga); +int Beb_IsTransmitting(int* retval, int tengiga, int waitForDelay); int Beb_SetMasterViaSoftware(); int Beb_SetSlaveViaSoftware(); diff --git a/slsDetectorServers/eigerDetectorServer/CMakeLists.txt b/slsDetectorServers/eigerDetectorServer/CMakeLists.txt index d27f38252..b068ef4c4 100644 --- a/slsDetectorServers/eigerDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/eigerDetectorServer/CMakeLists.txt @@ -5,6 +5,7 @@ set(src ../slsDetectorServer/src/communication_funcs.c ../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/common.c + ../slsDetectorServer/src/communication_virtual.c ) include_directories( @@ -22,7 +23,7 @@ target_include_directories(eigerDetectorServerMaster_virtual target_compile_definitions(eigerDetectorServerMaster_virtual PUBLIC EIGERD PCCOMPILE STOP_SERVER - PUBLIC VIRTUAL DVIRTUAL_9M + PUBLIC VIRTUAL #VIRTUAL_9M PUBLIC VIRTUAL_MASTER ) @@ -38,27 +39,60 @@ install(TARGETS eigerDetectorServerMaster_virtual RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) -add_executable(eigerDetectorServerSlave_virtual + + + + +add_executable(eigerDetectorServerSlaveTop_virtual ${src} ) -target_include_directories(eigerDetectorServerSlave_virtual +target_include_directories(eigerDetectorServerSlaveTop_virtual PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) -target_compile_definitions(eigerDetectorServerSlave_virtual +target_compile_definitions(eigerDetectorServerSlaveTop_virtual PUBLIC EIGERD PCCOMPILE STOP_SERVER - PUBLIC VIRTUAL DVIRTUAL_9M + PUBLIC VIRTUAL #VIRTUAL_9M + PUBLIC VIRTUAL_TOP ) -target_link_libraries(eigerDetectorServerSlave_virtual +target_link_libraries(eigerDetectorServerSlaveTop_virtual PUBLIC pthread rt ) -set_target_properties(eigerDetectorServerSlave_virtual PROPERTIES +set_target_properties(eigerDetectorServerSlaveTop_virtual PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) -install(TARGETS eigerDetectorServerSlave_virtual +install(TARGETS eigerDetectorServerSlaveTop_virtual + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + + + + +add_executable(eigerDetectorServerSlaveBottom_virtual + ${src} +) + +target_include_directories(eigerDetectorServerSlaveBottom_virtual + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_compile_definitions(eigerDetectorServerSlaveBottom_virtual + PUBLIC EIGERD PCCOMPILE STOP_SERVER + PUBLIC VIRTUAL #VIRTUAL_9M +) + +target_link_libraries(eigerDetectorServerSlaveBottom_virtual + PUBLIC pthread rt +) + +set_target_properties(eigerDetectorServerSlaveBottom_virtual PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + +install(TARGETS eigerDetectorServerSlaveBottom_virtual RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index 1d48a328f..01a1a81cf 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 c51deb81c..8b74cc2eb 100755 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -6,6 +6,8 @@ #ifndef VIRTUAL #include "FebControl.h" #include "Beb.h" +#else +#include "communication_virtual.h" #endif #include //to gethostname @@ -20,6 +22,7 @@ // Global variable from slsDetectorServer_funcs extern int debugflag; extern udpStruct udpDetails; +extern const enum detectorType myDetectorType; // Global variable from communication_funcs.c extern int isControlServer; @@ -66,9 +69,13 @@ int eiger_extgating = 0; int eiger_extgatingpolarity = 0; int eiger_nexposures = 1; int eiger_ntriggers = 1; +int eiger_tau_ns = 0; #ifdef VIRTUAL +pthread_t virtual_tid; +int virtual_status=0; +int virtual_stop = 0; //values for virtual server int64_t eiger_virtual_exptime = 0; int64_t eiger_virtual_subexptime = 0; @@ -82,12 +89,11 @@ int eiger_virtual_transmission_delay_left=0; int eiger_virtual_transmission_delay_right=0; int eiger_virtual_transmission_delay_frame=0; int eiger_virtual_transmission_flowcontrol_10g=0; -int eiger_virtual_status=0; int eiger_virtual_activate=1; -pthread_t eiger_virtual_tid; -int eiger_virtual_stop = 0; -uint64_t eiger_virtual_startingframenumber = 0; +uint64_t eiger_virtual_startingframenumber = 1; int eiger_virtual_detPos[2] = {0, 0}; +int eiger_virtual_test_mode = 0; +int eiger_virtual_quad_mode = 0; #endif @@ -179,8 +185,23 @@ void basictests() { LOG(logINFO, ("Compatibility - success\n")); } +#ifdef VIRTUAL +void setTestImageMode(int ival) { + if (ival >= 0) { + if (ival == 0) { + LOG(logINFO, ("Switching off Image Test Mode\n")); + eiger_virtual_test_mode = 0; + } else { + LOG(logINFO, ("Switching on Image Test Mode\n")); + eiger_virtual_test_mode = 1; + } + } +} - +int getTestImageMode() { + return eiger_virtual_test_mode; +} +#endif /* Ids */ @@ -306,7 +327,14 @@ void initControlServer() { getModuleConfiguration(); Feb_Interface_FebInterface(); Feb_Control_FebControl(); - Feb_Control_Init(master,top,normal, getDetectorNumber()); + // different addresses for top and bottom + if (getFirmwareVersion() < FIRMWARE_VERSION_SAME_TOP_BOT_ADDR) { + Feb_Control_Init(master,top,normal, getDetectorNumber()); + } + // same addresses for top and bottom + else { + Feb_Control_Init(master,1, normal, getDetectorNumber()); + } //master of 9M, check high voltage serial communication to blackfin if (master && !normal) { if (Feb_Control_OpenSerialCommunication()) @@ -334,12 +362,23 @@ void initControlServer() { void initStopServer() { #ifdef VIRTUAL getModuleConfiguration(); + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } return; #else getModuleConfiguration(); Feb_Interface_FebInterface(); Feb_Control_FebControl(); - Feb_Control_Init(master,top,normal,getDetectorNumber()); + // different addresses for top and bottom + if (getFirmwareVersion() < FIRMWARE_VERSION_SAME_TOP_BOT_ADDR) { + Feb_Control_Init(master,top,normal, getDetectorNumber()); + } + // same addresses for top and bottom + else { + Feb_Control_Init(master,1, normal, getDetectorNumber()); + } LOG(logDEBUG1, ("Stop server: FEB Initialization done\n")); // activate (if it gets ip) (later FW will deactivate at startup) // also needed for stop server for status @@ -361,7 +400,11 @@ void getModuleConfiguration() { top = 1; #else master = 0; +#ifdef VIRTUAL_TOP top = 1; +#else + top = 0; +#endif #endif #ifdef VIRTUAL_9M normal = 0; @@ -446,6 +489,12 @@ void setupDetector() { } } } +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif LOG(logINFOBLUE, ("Setting Default Parameters\n")); //setting default measurement parameters @@ -455,6 +504,7 @@ void setupDetector() { getSubExpTime(DEFAULT_SUBFRAME_DEADTIME); setPeriod(DEFAULT_PERIOD); setNumTriggers(DEFAULT_NUM_CYCLES); + eiger_dynamicrange = DEFAULT_DYNAMIC_RANGE; setDynamicRange(DEFAULT_DYNAMIC_RANGE); eiger_photonenergy = DEFAULT_PHOTON_ENERGY; setParallelMode(DEFAULT_PARALLEL_MODE); @@ -466,6 +516,7 @@ void setupDetector() { setStartingFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); setReadNLines(MAX_ROWS_PER_READOUT); //SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15); + eiger_tau_ns = DEFAULT_RATE_CORRECTION; setRateCorrection(DEFAULT_RATE_CORRECTION); int enable[2] = {DEFAULT_EXT_GATING_ENABLE, DEFAULT_EXT_GATING_POLARITY}; setExternalGating(enable);//disable external gating @@ -510,31 +561,27 @@ int readRegister(uint32_t offset, uint32_t* retval) { int setDynamicRange(int dr) { -#ifdef VIRTUAL - if (dr > 0) { - LOG(logINFO, ("Setting dynamic range: %d\n", dr)); - eiger_dynamicrange = dr; - } - return eiger_dynamicrange; -#else + // setting dr if (dr > 0) { LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr)); +#ifndef VIRTUAL if (Feb_Control_SetDynamicRange(dr)) { - - //EigerSetBitMode(dr); on_dst = 0; int i; for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested - if (Beb_SetUpTransferParameters(dr)) - eiger_dynamicrange = dr; - else LOG(logERROR, ("Could not set bit mode in the back end\n")); + if (!Beb_SetUpTransferParameters(dr)) { + LOG(logERROR, ("Could not set bit mode in the back end\n")); + return eiger_dynamicrange; + } } - } - //make sure back end and front end have the same bit mode - dr= Feb_Control_GetDynamicRange(); - - return dr; #endif + eiger_dynamicrange = dr; + } + // getting dr +#ifndef VIRTUAL + eiger_dynamicrange = Feb_Control_GetDynamicRange(); +#endif + return eiger_dynamicrange; } @@ -820,8 +867,9 @@ int setModule(sls_detector_module myMod, char* mess) { } } } - // trimbits + #ifndef VIRTUAL + // trimbits if (myMod.nchan == 0) { LOG(logINFO, ("Setting module without trimbits\n")); } else { @@ -850,6 +898,7 @@ int setModule(sls_detector_module myMod, char* mess) { return FAIL; } } +#endif //rate correction @@ -869,17 +918,24 @@ int setModule(sls_detector_module myMod, char* mess) { else { setDefaultSettingsTau_in_nsec(myMod.tau); if (getRateCorrectionEnable()) { - int64_t retvalTau = setRateCorrection(myMod.tau); - if (myMod.tau != retvalTau) { - sprintf(mess, "Cannot set module. Could not set rate correction\n"); + if (setRateCorrection(myMod.tau) == FAIL) { + sprintf(mess, "Cannot set module. Rate correction failed.\n"); LOG(logERROR, (mess)); setSettings(UNDEFINED); LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n")); - return FAIL; + return FAIL; + } else { + int64_t retvalTau = getCurrentTau(); + if (myMod.tau != retvalTau) { + sprintf(mess, "Cannot set module. Could not set rate correction\n"); + LOG(logERROR, (mess)); + setSettings(UNDEFINED); + LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n")); + return FAIL; + } } } } -#endif return OK; } @@ -1178,21 +1234,20 @@ enum timingMode getTiming() { /* configure mac */ int configureMAC() { - uint32_t sourceip = udpDetails.srcip; - uint32_t destip = udpDetails.dstip; - uint64_t sourcemac = udpDetails.srcmac; - uint64_t destmac = udpDetails.dstmac; - int src_port = udpDetails.srcport; - int destport = udpDetails.dstport; - int destport2 = udpDetails.dstport2; + uint32_t srcip = udpDetails.srcip; + uint32_t dstip = udpDetails.dstip; + uint64_t srcmac = udpDetails.srcmac; + uint64_t dstmac = udpDetails.dstmac; + int srcport = udpDetails.srcport; + int dstport = udpDetails.dstport; + int dstport2 = udpDetails.dstport2; - LOG(logINFO, ("Configuring MAC\n")); - + LOG(logINFOBLUE, ("Configuring MAC\n")); char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; - getMacAddressinString(src_mac, 50, sourcemac); - getMacAddressinString(dst_mac, 50, destmac); - getIpAddressinString(src_ip, sourceip); - getIpAddressinString(dst_ip, destip); + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); LOG(logINFO, ( "\tSource IP : %s\n" @@ -1202,19 +1257,15 @@ int configureMAC() { "\tDest MAC : %s\n" "\tDest Port : %d\n" "\tDest Port2 : %d\n", - src_ip, src_mac, src_port, - dst_ip, dst_mac, destport, destport2)); + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport, dstport2)); #ifdef VIRTUAL - char cDestIp[MAX_STR_LENGTH]; - memset(cDestIp, 0, MAX_STR_LENGTH); - sprintf(cDestIp, "%d.%d.%d.%d", (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff); - LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d, port2:%d)\n", cDestIp, destport, destport2)); - if (setUDPDestinationDetails(0, cDestIp, destport) == FAIL) { + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { LOG(logERROR, ("could not set udp destination IP and port\n")); return FAIL; } - if (setUDPDestinationDetails(1, cDestIp, destport2) == FAIL) { + if (setUDPDestinationDetails(1, dst_ip, dstport2) == FAIL) { LOG(logERROR, ("could not set udp destination IP and port2\n")); return FAIL; } @@ -1223,15 +1274,13 @@ int configureMAC() { int beb_num = detid; int header_number = 0; - int dst_port = destport; + int dst_port = dstport; if (!top) - dst_port = destport2; - - LOG(logINFO, ("\tDest Port : %d\n", dst_port)); + dst_port = dstport2; int i=0; /* for(i=0;i<32;i++) { modified for Aldo*/ - if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && + if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,srcport) && Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) { LOG(logDEBUG1, ("\tset up left ok\n")); } else { @@ -1240,13 +1289,12 @@ int configureMAC() { /*}*/ header_number = 32; - dst_port = destport2; + dst_port = dstport2; if (!top) - dst_port = destport; - LOG(logINFO, ("\tDest Port : %d\n",dst_port)); + dst_port = dstport; /*for(i=0;i<32;i++) {*//** modified for Aldo*/ - if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && + if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,srcport) && Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) { LOG(logDEBUG1, (" set up right ok\n")); } else { @@ -1291,13 +1339,15 @@ int setQuad(int value) { if (!Feb_Control_SetQuad(value)) { return FAIL; } +#else + eiger_virtual_quad_mode = value; #endif return OK; } int getQuad() { #ifdef VIRTUAL - return 0; + return eiger_virtual_quad_mode; #else return Beb_GetQuad(); #endif @@ -1433,12 +1483,59 @@ int pulseChip(int n) { return OK; } -int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1) +int updateRateCorrection(char* mess) { + int ret = OK; + // recalculates rate correction table, or switches off in wrong bit mode + if (eiger_tau_ns != 0) { + switch (eiger_dynamicrange) { + case 16: + case 32: + ret = setRateCorrection(eiger_tau_ns); + break; + default: + setRateCorrection(0); + strcpy(mess, "Rate correction Deactivated, must be in 32 or 16 bit mode"); + ret = FAIL; + break; + } + } + getCurrentTau(); // update eiger_tau_ns + return ret; +} + +int validateAndSetRateCorrection(int64_t tau_ns, char* mess) { + // switching on in wrong bit mode + if ((tau_ns != 0) && + (eiger_dynamicrange != 32) && (eiger_dynamicrange != 16)) { + strcpy(mess,"Rate correction Deactivated, must be in 32 or 16 bit mode\n"); + LOG(logERROR,(mess)); + return FAIL; + } + // default tau (-1, get proper value) + if (tau_ns < 0) { + tau_ns = getDefaultSettingsTau_in_nsec(); + if (tau_ns < 0) { + strcpy(mess,"Default settings file not loaded. No default tau yet\n"); + LOG(logERROR,(mess)); + return FAIL; + } + eiger_tau_ns = -1; + } + // user defined value (settings become undefined) + else if (tau_ns > 0) { + setSettings(UNDEFINED); + LOG(logERROR, ("Settings has been changed to undefined (tau changed)\n")); + eiger_tau_ns = tau_ns; + } + return setRateCorrection(tau_ns); +} + +int setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1) #ifdef VIRTUAL //deactivating rate correction if (custom_tau_in_nsec==0) { eiger_virtual_ratecorrection_variable = 0; - return 0; + return OK; } //when dynamic range changes, use old tau @@ -1468,22 +1565,21 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never //different setting, calculate table else { eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec; - double period_in_sec = (double)(eiger_virtual_subexptime*10)/(double)1e9; + eiger_virtual_ratetable_period_in_ns = eiger_virtual_subexptime*10; if (eiger_dynamicrange == 16) - period_in_sec = eiger_virtual_exptime; - eiger_virtual_ratetable_period_in_ns = period_in_sec*1e9; + eiger_virtual_ratetable_period_in_ns = eiger_virtual_exptime; } //activating rate correction eiger_virtual_ratecorrection_variable = 1; LOG(logINFO, ("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns)); - return eiger_virtual_ratetable_tau_in_ns; + return OK; #else //deactivating rate correction if (custom_tau_in_nsec==0) { Feb_Control_SetRateCorrectionVariable(0); - return 0; + return OK; } //when dynamic range changes, use old tau @@ -1517,7 +1613,7 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never if (ret<=0) { LOG(logERROR, ("Rate correction failed. Deactivating rate correction\n")); Feb_Control_SetRateCorrectionVariable(0); - return ret; + return FAIL; } } //activating rate correction @@ -1525,7 +1621,7 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never LOG(logINFO, ("Rate Correction Value set to %lld ns\n", (long long int)Feb_Control_Get_RateTable_Tau_in_nsec())); Feb_Control_PrintCorrectedValues(); - return Feb_Control_Get_RateTable_Tau_in_nsec(); + return OK; #endif } @@ -1543,18 +1639,22 @@ int getDefaultSettingsTau_in_nsec() { void setDefaultSettingsTau_in_nsec(int t) { default_tau_from_file = t; - LOG(logINFO, ("Default tau set to %d\n", default_tau_from_file)); + LOG(logINFOBLUE, ("Default tau set to %d\n", default_tau_from_file)); } int64_t getCurrentTau() { - if (!getRateCorrectionEnable()) + if (!getRateCorrectionEnable()) { + eiger_tau_ns = 0; return 0; - else + } + else { #ifndef VIRTUAL - return Feb_Control_Get_RateTable_Tau_in_nsec(); + eiger_tau_ns = Feb_Control_Get_RateTable_Tau_in_nsec(); #else - return eiger_virtual_ratetable_tau_in_ns; + eiger_tau_ns = eiger_virtual_ratetable_tau_in_ns; #endif + return eiger_tau_ns; + } } void setExternalGating(int enable[]) { @@ -1728,18 +1828,29 @@ int startStateMachine() { if(createUDPSocket(1) != OK) { return FAIL; } - LOG(logINFOBLUE, ("starting state machine\n")); - eiger_virtual_status = 1; - eiger_virtual_stop = 0; - if (pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { + LOG(logINFOBLUE, ("Starting State Machine\n")); + virtual_status = 1; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } + if (pthread_create(&virtual_tid, NULL, &start_timer, NULL)) { LOG(logERROR, ("Could not start Virtual acquisition thread\n")); - eiger_virtual_status = 0; + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFO ,("Virtual Acquisition started\n")); return OK; #else - + LOG(logINFOBLUE, ("Starting State Machine\n")); int ret = OK,prev_flag; //get the DAQ toggle bit prev_flag = Feb_Control_AcquisitionStartedBit(); @@ -1767,9 +1878,13 @@ int startStateMachine() { #ifdef VIRTUAL void* start_timer(void* arg) { - int64_t periodns = eiger_virtual_period; + if (!isControlServer) { + return NULL; + } + + int64_t periodNs = eiger_virtual_period; int numFrames = nimages_per_request; - int64_t exp_us = eiger_virtual_exptime / 1000; + int64_t expUs = eiger_virtual_exptime / 1000; int dr = eiger_dynamicrange; double bytesPerPixel = (double)dr/8.00; @@ -1779,100 +1894,160 @@ void* start_timer(void* arg) { int numPacketsPerFrame = (tgEnable ? 4 : 16) * dr; int npixelsx = 256 * 2 * bytesPerPixel; int databytes = 256 * 256 * 2 * bytesPerPixel; - LOG(logINFO, (" dr:%f\n bytesperpixel:%d\n tgenable:%d\n datasize:%d\n packetsize:%d\n numpackes:%d\n npixelsx:%d\n databytes:%d\n", - dr, bytesPerPixel, tgEnable, datasize, packetsize, numPacketsPerFrame, npixelsx, databytes)); + int row = eiger_virtual_detPos[0]; + int colLeft = top ? eiger_virtual_detPos[1] : eiger_virtual_detPos[1] + 1; + int colRight = top ? eiger_virtual_detPos[1] + 1 : eiger_virtual_detPos[1]; + int ntotpixels = 256 * 256 * 4; + LOG(logINFO, (" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n packetsize:%d\n numpackes:%d\n npixelsx:%d\n databytes:%d\n ntotpixels:%d\n", + dr, bytesPerPixel, tgEnable, datasize, packetsize, numPacketsPerFrame, npixelsx, databytes, ntotpixels)); - //TODO: Generate data - char imageData[databytes * 2]; - memset(imageData, 0, databytes * 2); - { - int i = 0; - for (i = 0; i < databytes * 2; i += sizeof(uint8_t)) { - *((uint8_t*)(imageData + i)) = i; - } - } - - //TODO: Send data - { - int frameNr = 1; - for(frameNr=1; frameNr <= numFrames; ++frameNr ) { - - //check if virtual_stop is high - if(eiger_virtual_stop == 1){ - break; + // Generate data + char imageData[databytes * 2]; + memset(imageData, 0, databytes * 2); + { + int i = 0; + switch (dr) { + case 4: + for (i = 0; i < ntotpixels/2; ++i) { + *((uint8_t*)(imageData + i)) = eiger_virtual_test_mode ? 0xEE : (uint8_t)(((2 * i & 0xF) << 4) | ((2 * i + 1) & 0xF)); } + break; + case 8: + for (i = 0; i < ntotpixels; ++i) { + *((uint8_t*)(imageData + i)) = eiger_virtual_test_mode ? 0xFE : (uint8_t)i; + } + break; + case 16: + for (i = 0; i < ntotpixels; ++i) { + *((uint16_t*)(imageData + i * sizeof(uint16_t))) = eiger_virtual_test_mode ? 0xFFE : (uint16_t)i; + } + break; + case 32: + for (i = 0; i < ntotpixels; ++i) { + *((uint32_t*)(imageData + i * sizeof(uint32_t))) = eiger_virtual_test_mode ? 0xFFFFFE : (uint32_t)i; + } + break; + default: + break; + } + } + + // Send data + { + uint64_t frameNr = 0; + getStartingFrameNumber(&frameNr); + // loop over number of frames + int iframes = 0; + for(iframes = 0; iframes != numFrames; ++iframes ) { - int srcOffset = 0; - int srcOffset2 = npixelsx; + usleep(eiger_virtual_transmission_delay_frame); + + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + setStartingFrameNumber(frameNr + iframes + 1); + break; + } + + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); + + int srcOffset = 0; + int srcOffset2 = npixelsx; - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); - usleep(exp_us); - char packetData[packetsize]; - memset(packetData, 0, packetsize); - char packetData2[packetsize]; - memset(packetData2, 0, packetsize); - - // loop packet - { - int i = 0; - for(i = 0; i != numPacketsPerFrame; ++i) { - int dstOffset = sizeof(sls_detector_header); - int dstOffset2 = sizeof(sls_detector_header); - // set header - sls_detector_header* header = (sls_detector_header*)(packetData); - header->frameNumber = frameNr; - header->packetNumber = i; - header = (sls_detector_header*)(packetData2); - header->frameNumber = frameNr; - header->packetNumber = i; + // loop packet + { + int i = 0; + for(i = 0; i != numPacketsPerFrame; ++i) { + // set header + char packetData[packetsize]; + memset(packetData, 0, packetsize); + sls_detector_header* header = (sls_detector_header*)(packetData); + header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameNr + iframes; + header->packetNumber = i; + header->row = row; + header->column = colLeft; - // fill data - { - int psize = 0; - for (psize = 0; psize < datasize; psize += npixelsx) { + char packetData2[packetsize]; + memset(packetData2, 0, packetsize); + header = (sls_detector_header*)(packetData2); + header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameNr + iframes; + header->packetNumber = i; + header->row = row; + header->column = colRight; + if (eiger_virtual_quad_mode) { + header->row = 1; // right is next row + header->column = 0; // right same first column + } - if (dr == 32 && tgEnable == 0) { - memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2); - memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx/2); + // fill data + int dstOffset = sizeof(sls_detector_header); + int dstOffset2 = sizeof(sls_detector_header); + { + int psize = 0; + for (psize = 0; psize < datasize; psize += npixelsx) { + + if (dr == 32 && tgEnable == 0) { + memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2); + memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx/2); + if (srcOffset % npixelsx == 0) { + srcOffset += npixelsx/2; + srcOffset2 += npixelsx/2; + } + // skip the other half (2 packets in 1 line for 32 bit) + else { srcOffset += npixelsx; - srcOffset2 += npixelsx; - dstOffset += npixelsx/2; - dstOffset2 += npixelsx/2; - } else { - memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx); - memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx); - srcOffset += 2 * npixelsx; - srcOffset2 += 2 * npixelsx; - dstOffset += npixelsx; - dstOffset2 += npixelsx; + srcOffset2 += npixelsx; } + dstOffset += npixelsx/2; + dstOffset2 += npixelsx/2; + } else { + memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx); + memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx); + srcOffset += 2 * npixelsx; + srcOffset2 += 2 * npixelsx; + dstOffset += npixelsx; + dstOffset2 += npixelsx; } } - - sendUDPPacket(0, packetData, packetsize); - sendUDPPacket(1, packetData2, packetsize); } + usleep(eiger_virtual_transmission_delay_left); + sendUDPPacket(0, packetData, packetsize); + usleep(eiger_virtual_transmission_delay_right); + sendUDPPacket(1, packetData2, packetsize); } - LOG(logINFO, ("Sent frame: %d\n", frameNr)); - clock_gettime(CLOCK_REALTIME, &end); - int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); + } + LOG(logINFO, ("Sent frame: %d\n", iframes)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodns > time_ns) { - usleep((periodns - time_ns)/ 1000); - } + // sleep for (period - exptime) + if (iframes < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); } } } + setStartingFrameNumber(frameNr + numFrames); + } + closeUDPSocket(0); closeUDPSocket(1); - eiger_virtual_status = 0; + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } @@ -1884,7 +2059,18 @@ void* start_timer(void* arg) { int stopStateMachine() { LOG(logINFORED, ("Going to stop acquisition\n")); #ifdef VIRTUAL - eiger_virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #else if ((Feb_Control_StopAcquisition() != STATUS_IDLE) || (!Beb_StopAcquisition()) ) { @@ -1944,7 +2130,10 @@ int startReadOut() { enum runStatus getRunStatus() { #ifdef VIRTUAL - if (eiger_virtual_status == 0) { + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if (virtual_status == 0) { LOG(logINFO, ("Status: IDLE\n")); return IDLE; } else { @@ -1954,19 +2143,23 @@ enum runStatus getRunStatus() { #else int i = Feb_Control_AcquisitionInProgress(); - switch (i) { - case STATUS_ERROR: + if (i == STATUS_ERROR) { LOG(logERROR, ("Status: ERROR reading status register\n")); return ERROR; - case STATUS_IDLE: + } else if (i == STATUS_IDLE) { + int isTransmitting = 0; + if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 0) == FAIL) { + return ERROR; + } + if (isTransmitting) { + printf("Status: TRANSMITTING\n"); + return TRANSMITTING; + } LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; - default: - LOG(logINFOBLUE, ("Status: RUNNING...\n")); - return RUNNING; } - - return IDLE; + LOG(logINFOBLUE, ("Status: RUNNING...\n")); + return RUNNING; #endif } @@ -1975,7 +2168,7 @@ enum runStatus getRunStatus() { void readFrame(int *ret, char *mess) { #ifdef VIRTUAL // wait for status to be done - while(eiger_virtual_status == 1){ + while(virtual_status == 1){ usleep(500); } LOG(logINFOGREEN, ("acquisition successfully finished\n")); @@ -2000,7 +2193,18 @@ void readFrame(int *ret, char *mess) { } //wait for detector to send - Beb_EndofDataSend(send_to_ten_gig); + int isTransmitting = 1; + while (isTransmitting) { + if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) { + strcpy(mess,"Could not read delay counters\n"); + *ret = (int)FAIL; + return; + } + if (isTransmitting) { + printf("Transmitting...\n"); + } + } + printf("Detector has sent all data\n"); LOG(logINFOGREEN, ("Acquisition successfully finished\n")); #endif } diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index a885456ee..b0d1143a2 100755 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -3,6 +3,7 @@ #define REQUIRED_FIRMWARE_VERSION (24) #define IDFILECOMMAND "more /home/root/executables/detid.txt" +#define FIRMWARE_VERSION_SAME_TOP_BOT_ADDR (26) #define STATUS_IDLE 0 #define STATUS_RUNNING 1 @@ -63,10 +64,10 @@ enum CLKINDEX {RUN_CLK, NUM_CLOCKS}; #define DEFAULT_SUBFRAME_DEADTIME (0) #define DEFAULT_DYNAMIC_RANGE (16) -#define DEFAULT_PARALLEL_MODE (0) +#define DEFAULT_PARALLEL_MODE (1) #define DEFAULT_READOUT_STOREINRAM_MODE (0) #define DEFAULT_READOUT_OVERFLOW32_MODE (0) -#define DEFAULT_CLK_SPEED (HALF_SPEED) +#define DEFAULT_CLK_SPEED (FULL_SPEED) #define DEFAULT_IO_DELAY (650) #define DEFAULT_TIMING_MODE (AUTO_TIMING) #define DEFAULT_PHOTON_ENERGY (-1) diff --git a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt index 7d2d6ed01..6b5cdbf5e 100644 --- a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable(gotthard2DetectorServer_virtual ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ASIC_Driver.c ../slsDetectorServer/src/programFpgaNios.c + ../slsDetectorServer/src/communication_virtual.c ) include_directories( diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index b8b11d260..8d4180245 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 89ba8ae64..bf9eff71f 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -9,10 +9,12 @@ #include "ASIC_Driver.h" #ifdef VIRTUAL #include "communication_funcs_UDP.h" +#include "communication_virtual.h" #endif #include #include // usleep +#include #ifdef VIRTUAL #include #include @@ -25,6 +27,11 @@ extern int checkModuleFlag; extern udpStruct udpDetails; extern const enum detectorType myDetectorType; +// Global variable from communication_funcs.c +extern int isControlServer; +extern void getMacAddressinString(char* cmac, int size, uint64_t mac); +extern void getIpAddressinString(char* cip, uint32_t ip); + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -332,6 +339,12 @@ void initStopServer() { LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); exit(EXIT_FAILURE); } +#ifdef VIRTUAL + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } +#endif } @@ -381,9 +394,13 @@ void setupDetector() { } } } +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif - -#ifndef VIRTUAL // pll defines ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ); ALTERA_PLL_C10_ResetPLL(READOUT_PLL); @@ -394,7 +411,6 @@ void setupDetector() { LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC); // on chip dacs ASIC_Driver_SetDefines(ONCHIP_DAC_DRIVER_FILE_NAME); -#endif setTimingSource(DEFAULT_TIMING_SOURCE); // Default values @@ -431,12 +447,10 @@ void setupDetector() { // power on chip powerChip(1); -#ifndef VIRTUAL // also sets default dac and on chip dac values if (readConfigFile() == FAIL) { return; } -#endif setBurstMode(DEFAULT_BURST_MODE); setSettings(DEFAULT_SETTINGS); @@ -1187,42 +1201,30 @@ int configureMAC() { int srcport = udpDetails.srcport; int dstport = udpDetails.dstport; + LOG(logINFOBLUE, ("Configuring MAC\n")); + char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); + + LOG(logINFO, ( + "\tSource IP : %s\n" + "\tSource MAC : %s\n" + "\tSource Port : %d\n" + "\tDest IP : %s\n" + "\tDest MAC : %s\n" + "\tDest Port : %d\n", + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport)); + #ifdef VIRTUAL - char cDestIp[MAX_STR_LENGTH]; - memset(cDestIp, 0, MAX_STR_LENGTH); - sprintf(cDestIp, "%d.%d.%d.%d", (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff); - LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, dstport)); - if (setUDPDestinationDetails(0, cDestIp, dstport) == FAIL) { + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { LOG(logERROR, ("could not set udp destination IP and port\n")); return FAIL; } return OK; #endif - LOG(logINFOBLUE, ("Configuring MAC\n")); - - LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (srcip>>24)&0xff,(srcip>>16)&0xff,(srcip>>8)&0xff,(srcip)&0xff, srcip)); - LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((srcmac>>40)&0xFF), - (unsigned int)((srcmac>>32)&0xFF), - (unsigned int)((srcmac>>24)&0xFF), - (unsigned int)((srcmac>>16)&0xFF), - (unsigned int)((srcmac>>8)&0xFF), - (unsigned int)((srcmac>>0)&0xFF), - (long long unsigned int)srcmac)); - LOG(logINFO, ("\tSource Port : %d \t\t\t(0x%08x)\n", srcport, srcport)); - - LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff, dstip)); - LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((dstmac>>40)&0xFF), - (unsigned int)((dstmac>>32)&0xFF), - (unsigned int)((dstmac>>24)&0xFF), - (unsigned int)((dstmac>>16)&0xFF), - (unsigned int)((dstmac>>8)&0xFF), - (unsigned int)((dstmac>>0)&0xFF), - (long long unsigned int)dstmac)); - LOG(logINFO, ("\tDest. Port : %d \t\t\t(0x%08x)\n\n",dstport, dstport)); // start addr uint32_t addr = BASE_UDP_RAM; @@ -1340,6 +1342,9 @@ int* getDetectorPosition() { // Detector Specific int checkDetectorType() { +#ifdef VIRTUAL + return OK; +#endif LOG(logINFO, ("Checking type of module\n")); FILE* fd = fopen(TYPE_FILE_NAME, "r"); if (fd == NULL) { @@ -2011,13 +2016,24 @@ int startStateMachine(){ if(createUDPSocket(0) != OK) { return FAIL; } - LOG(logINFOBLUE, ("starting state machine\n")); + LOG(logINFOBLUE, ("Starting State Machine\n")); // set status to running virtual_status = 1; - virtual_stop = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { LOG(logERROR, ("Could not start Virtual acquisition thread\n")); virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFOGREEN, ("Virtual Acquisition started\n")); @@ -2036,10 +2052,22 @@ int startStateMachine(){ #ifdef VIRTUAL void* start_timer(void* arg) { - int64_t periodns = getPeriod(); - int numFrames = (getNumFrames() * - getNumTriggers() ); - int64_t exp_ns = getExpTime(); + if (!isControlServer) { + return NULL; + } + + int numRepeats = getNumTriggers(); + if (getTiming() == AUTO_TIMING) { + if (burstMode == BURST_OFF) { + numRepeats = 1; + } else { + numRepeats = getNumBursts(); + } + } + int repeatPeriodNs = getBurstPeriod(); + int numFrames = getNumFrames(); + int64_t periodNs = getPeriod(); + int64_t expUs = getExpTime() / 1000; int imagesize = NCHAN * NCHIP * 2; int datasize = imagesize; int packetsize = datasize + sizeof(sls_detector_header); @@ -2049,62 +2077,87 @@ void* start_timer(void* arg) { memset(imageData, 0, imagesize); { int i = 0; - for (i = 0; i < imagesize; i += sizeof(uint8_t)) { - *((uint8_t*)(imageData + i)) = i; + for (i = 0; i < imagesize; i += sizeof(uint16_t)) { + *((uint16_t*)(imageData + i)) = i; } } - int frameNr = 0; - // loop over number of frames - for(frameNr=0; frameNr!= numFrames; ++frameNr ) { + { + int repeatNr = 0; + int frameHeaderNr = 0; + // loop over number of repeats + for(repeatNr=0; repeatNr!= numRepeats; ++repeatNr ) { - //check if virtual_stop is high - if(virtual_stop == 1){ - break; - } + struct timespec rbegin, rend; + clock_gettime(CLOCK_REALTIME, &rbegin); - // sleep for exposure time - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); - usleep(exp_ns / 1000); - clock_gettime(CLOCK_REALTIME, &end); + int frameNr = 0; + // loop over number of frames + for(frameNr = 0; frameNr != numFrames; ++frameNr ) { + + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + break; + } - char packetData[packetsize]; - memset(packetData, 0, packetsize); - // set header - sls_detector_header* header = (sls_detector_header*)(packetData); - header->frameNumber = frameNr; - header->packetNumber = 0; - header->modId = 0; - header->row = detPos[X]; - header->column = detPos[Y]; - header->detType = (uint16_t)myDetectorType; - header->version = SLS_DETECTOR_HEADER_VERSION - 1; + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); - // fill data - memcpy(packetData + sizeof(sls_detector_header), imageData, datasize); + char packetData[packetsize]; + memset(packetData, 0, packetsize); + // set header + sls_detector_header* header = (sls_detector_header*)(packetData); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameHeaderNr; + ++frameHeaderNr; + header->packetNumber = 0; + header->modId = 0; + header->row = detPos[X]; + header->column = detPos[Y]; - // send 1 packet = 1 frame - sendUDPPacket(0, packetData, packetsize); - LOG(logINFO, ("Sent frame: %d\n", frameNr)); + // fill data + memcpy(packetData + sizeof(sls_detector_header), imageData, datasize) ; - // calculate time left in period - int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); + // send 1 packet = 1 frame + sendUDPPacket(0, packetData, packetsize); - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodns > time_ns) { - usleep((periodns - time_ns)/ 1000); + clock_gettime(CLOCK_REALTIME, &end); + LOG(logINFO, ("Sent frame: %d (bursts: %d)\n", frameNr, repeatNr)); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + + // sleep for (period - exptime) + if (frameNr < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); + } + } + } + clock_gettime(CLOCK_REALTIME, &rend); + int64_t timeNs = ((rend.tv_sec - rbegin.tv_sec) * 1E9 + + (rend.tv_nsec - rbegin.tv_nsec)); + + // sleep for (repeatPeriodNs - time remaining) + if (repeatNr < numRepeats) { // if there is a next repeat + if (repeatPeriodNs > timeNs) { + usleep((repeatPeriodNs - timeNs)/ 1000); + } } - } - // set register frames left - } + } + } closeUDPSocket(0); - // set status to idle + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } @@ -2114,7 +2167,18 @@ void* start_timer(void* arg) { int stopStateMachine(){ LOG(logINFORED, ("Stopping State Machine\n")); #ifdef VIRTUAL - virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #endif //stop state machine @@ -2125,7 +2189,10 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - if(virtual_status == 0){ + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if(virtual_status == 0) { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; }else{ @@ -2199,6 +2266,9 @@ void readFrame(int *ret, char *mess) { u_int32_t runBusy() { #ifdef VIRTUAL + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } return virtual_status; #endif u_int32_t s = (bus_r(FLOW_STATUS_REG) & FLOW_STATUS_RUN_BUSY_MSK); diff --git a/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt b/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt index 6055fcbc4..eb2c60299 100644 --- a/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt @@ -9,6 +9,8 @@ add_executable(gotthardDetectorServer_virtual ../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/common.c ../slsDetectorServer/src/commonServerFunctions.c + ../slsDetectorServer/src/communication_funcs_UDP.c + ../slsDetectorServer/src/communication_virtual.c ) include_directories( diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index 83c0ff984..e56baa831 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 e9e7b568e..9f5349b4b 100755 --- a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c @@ -4,19 +4,30 @@ #include "RegisterDefs.h" #include "LTC2620.h" // dacs +#ifdef VIRTUAL +#include "communication_funcs_UDP.h" +#include "communication_virtual.h" +#endif #include "string.h" #include // usleep +#include #ifdef VIRTUAL #include #include #endif extern udpStruct udpDetails; +extern const enum detectorType myDetectorType; // Variables that will be exported int phaseShift = DEFAULT_PHASE_SHIFT; +// Global variable from communication_funcs.c +extern int isControlServer; +extern void getMacAddressinString(char* cmac, int size, uint64_t mac); +extern void getIpAddressinString(char* cip, uint32_t ip); + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -239,10 +250,10 @@ void setTestImageMode(int ival) { uint32_t addr = MULTI_PURPOSE_REG; if (ival >= 0) { if (ival == 0) { - LOG(logINFO, ("Switching on Image Test Mode\n")); + LOG(logINFO, ("Switching off Image Test Mode\n")); bus_w (addr, bus_r(addr) & ~DGTL_TST_MSK); } else { - LOG(logINFO, ("Switching off Image Test Mode\n")); + LOG(logINFO, ("Switching on Image Test Mode\n")); bus_w (addr, bus_r(addr) | DGTL_TST_MSK); } } @@ -345,6 +356,12 @@ void initStopServer() { LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); exit(EXIT_FAILURE); } +#ifdef VIRTUAL + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } +#endif } @@ -353,6 +370,13 @@ void initStopServer() { void setupDetector() { LOG(logINFO, ("This Server is for 1 Gotthard module (1280 channels)\n")); +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif + // Initialization setPhaseShiftOnce(); @@ -915,8 +939,9 @@ int getModule(sls_detector_module *myMod){ if (dacValues[idac] >= 0) initialized = 1; } - if (initialized) + if (initialized) { return OK; + } return FAIL; } @@ -1088,11 +1113,6 @@ int getADC(enum ADCINDEX ind){ } int setHighVoltage(int val){ -#ifdef VIRTUAL - if (val >= 0) - highvoltage = val; - return highvoltage; -#endif u_int32_t addr = HV_REG; u_int32_t sel = 0x0; @@ -1262,44 +1282,42 @@ void calcChecksum(mac_conf* mac, int sourceip, int destip) { } int configureMAC() { - uint32_t sourceip = udpDetails.srcip; - uint32_t destip = udpDetails.dstip; - uint64_t sourcemac = udpDetails.srcmac; - uint64_t destmac = udpDetails.dstmac; - int sourceport = udpDetails.srcport; - int destport = udpDetails.dstport; + uint32_t srcip = udpDetails.srcip; + uint32_t dstip = udpDetails.dstip; + uint64_t srcmac = udpDetails.srcmac; + uint64_t dstmac = udpDetails.dstmac; + int srcport = udpDetails.srcport; + int dstport = udpDetails.dstport; + + LOG(logINFOBLUE, ("Configuring MAC\n")); + char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); + + LOG(logINFO, ( + "\tSource IP : %s\n" + "\tSource MAC : %s\n" + "\tSource Port : %d\n" + "\tDest IP : %s\n" + "\tDest MAC : %s\n" + "\tDest Port : %d\n", + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport)); + #ifdef VIRTUAL + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { + LOG(logERROR, ("could not set udp 1G destination IP and port\n")); + return FAIL; + } return OK; #endif - LOG(logINFOBLUE, ("Configuring MAC\n")); u_int32_t addr = MULTI_PURPOSE_REG; LOG(logDEBUG1, ("\tRoi: %d, Ip Packet size: %d UDP Packet size: %d\n", adcConfigured, ipPacketSize, udpPacketSize)); - LOG(logINFO, ("\tSource IP : %d.%d.%d.%d (0x%08x)\n", - (sourceip>>24)&0xff,(sourceip>>16)&0xff,(sourceip>>8)&0xff,(sourceip)&0xff, sourceip)); - LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x (0x%010llx)\n", - (unsigned int)((sourcemac>>40)&0xFF), - (unsigned int)((sourcemac>>32)&0xFF), - (unsigned int)((sourcemac>>24)&0xFF), - (unsigned int)((sourcemac>>16)&0xFF), - (unsigned int)((sourcemac>>8)&0xFF), - (unsigned int)((sourcemac>>0)&0xFF), - (long long unsigned int)sourcemac)); - LOG(logINFO, ("\tSource Port : %d (0x%08x)\n",sourceport, sourceport)); - LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d (0x%08x)\n", - (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff, destip)); - LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x (0x%010llx)\n", - (unsigned int)((destmac>>40)&0xFF), - (unsigned int)((destmac>>32)&0xFF), - (unsigned int)((destmac>>24)&0xFF), - (unsigned int)((destmac>>16)&0xFF), - (unsigned int)((destmac>>8)&0xFF), - (unsigned int)((destmac>>0)&0xFF), - (long long unsigned int)destmac)); - LOG(logINFO, ("\tDest. Port : %d (0x%08x)\n",destport, destport)); - //reset mac bus_w (addr, bus_r(addr) | RST_MSK); LOG(logDEBUG1, ("\tReset Mac. MultiPurpose reg: 0x%x\n", bus_r(addr))); @@ -1320,28 +1338,28 @@ int configureMAC() { LOG(logDEBUG1, ("\tConfiguring MAC CONF\n")); mac_conf *mac_conf_regs = (mac_conf*)(Blackfin_getBaseAddress() + ENET_CONF_REG / 2); // direct write - mac_conf_regs->mac.mac_dest_mac1 = ((destmac >> (8 * 5)) & 0xFF); - mac_conf_regs->mac.mac_dest_mac2 = ((destmac >> (8 * 4)) & 0xFF); - mac_conf_regs->mac.mac_dest_mac3 = ((destmac >> (8 * 3)) & 0xFF); - mac_conf_regs->mac.mac_dest_mac4 = ((destmac >> (8 * 2)) & 0xFF); - mac_conf_regs->mac.mac_dest_mac5 = ((destmac >> (8 * 1)) & 0xFF); - mac_conf_regs->mac.mac_dest_mac6 = ((destmac >> (8 * 0)) & 0xFF); + mac_conf_regs->mac.mac_dest_mac1 = ((dstmac >> (8 * 5)) & 0xFF); + mac_conf_regs->mac.mac_dest_mac2 = ((dstmac >> (8 * 4)) & 0xFF); + mac_conf_regs->mac.mac_dest_mac3 = ((dstmac >> (8 * 3)) & 0xFF); + mac_conf_regs->mac.mac_dest_mac4 = ((dstmac >> (8 * 2)) & 0xFF); + mac_conf_regs->mac.mac_dest_mac5 = ((dstmac >> (8 * 1)) & 0xFF); + mac_conf_regs->mac.mac_dest_mac6 = ((dstmac >> (8 * 0)) & 0xFF); LOG(logDEBUG1, ("\tDestination Mac: %llx %x:%x:%x:%x:%x:%x\n", - destmac, + dstmac, mac_conf_regs->mac.mac_dest_mac1, mac_conf_regs->mac.mac_dest_mac2, mac_conf_regs->mac.mac_dest_mac3, mac_conf_regs->mac.mac_dest_mac4, mac_conf_regs->mac.mac_dest_mac5, mac_conf_regs->mac.mac_dest_mac6)); - mac_conf_regs->mac.mac_src_mac1 = ((sourcemac >> (8 * 5)) & 0xFF); - mac_conf_regs->mac.mac_src_mac2 = ((sourcemac >> (8 * 4)) & 0xFF); - mac_conf_regs->mac.mac_src_mac3 = ((sourcemac >> (8 * 3)) & 0xFF); - mac_conf_regs->mac.mac_src_mac4 = ((sourcemac >> (8 * 2)) & 0xFF); - mac_conf_regs->mac.mac_src_mac5 = ((sourcemac >> (8 * 1)) & 0xFF); - mac_conf_regs->mac.mac_src_mac6 = ((sourcemac >> (8 * 0)) & 0xFF); + mac_conf_regs->mac.mac_src_mac1 = ((srcmac >> (8 * 5)) & 0xFF); + mac_conf_regs->mac.mac_src_mac2 = ((srcmac >> (8 * 4)) & 0xFF); + mac_conf_regs->mac.mac_src_mac3 = ((srcmac >> (8 * 3)) & 0xFF); + mac_conf_regs->mac.mac_src_mac4 = ((srcmac >> (8 * 2)) & 0xFF); + mac_conf_regs->mac.mac_src_mac5 = ((srcmac >> (8 * 1)) & 0xFF); + mac_conf_regs->mac.mac_src_mac6 = ((srcmac >> (8 * 0)) & 0xFF); LOG(logDEBUG1, ("\tSource Mac: %llx %x:%x:%x:%x:%x:%x\n", - sourcemac, + srcmac, mac_conf_regs->mac.mac_src_mac1, mac_conf_regs->mac.mac_src_mac2, mac_conf_regs->mac.mac_src_mac3, @@ -1350,9 +1368,9 @@ int configureMAC() { mac_conf_regs->mac.mac_src_mac6)); mac_conf_regs->mac.mac_ether_type = 0x0800; //ipv4 - calcChecksum(mac_conf_regs, sourceip, destip); - mac_conf_regs->udp.udp_srcport = sourceport; - mac_conf_regs->udp.udp_destport = destport; + calcChecksum(mac_conf_regs, srcip, dstip); + mac_conf_regs->udp.udp_srcport = srcport; + mac_conf_regs->udp.udp_destport = dstport; mac_conf_regs->udp.udp_len = udpPacketSize; mac_conf_regs->udp.udp_chksum = 0x0000; @@ -1487,11 +1505,27 @@ int setPhase(enum CLKINDEX ind, int val, int degrees) { int startStateMachine(){ #ifdef VIRTUAL - virtual_status = 1; - virtual_stop = 0; + // create udp socket + if(createUDPSocket(0) != OK) { + return FAIL; + } + LOG(logINFOBLUE, ("Starting State Machine\n")); + virtual_status = 1; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { - virtual_status = 0; LOG(logERROR, ("Could not start Virtual acquisition thread\n")); + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFOGREEN, ("Virtual Acquisition started\n")); @@ -1511,17 +1545,92 @@ int startStateMachine(){ #ifdef VIRTUAL void* start_timer(void* arg) { - int wait_in_s = (getNumFrames() * - getNumTriggers() * - (getPeriod()/(1E9))); - LOG(logDEBUG1, ("going to wait for %d s\n", wait_in_s)); - while(!virtual_stop && (wait_in_s >= 0)) { - usleep(1000 * 1000); - wait_in_s--; + if (!isControlServer) { + return NULL; } - LOG(logINFOGREEN, ("Virtual Timer Done\n")); + + int64_t periodNs = getPeriod(); + int numFrames = (getNumFrames() * + getNumTriggers() ); + int64_t expUs = getExpTime() / 1000; + + int imageSize = adcConfigured == -1 ? DATA_BYTES : NCHAN_PER_ADC * NUM_BITS_PER_PIXEL; + int dataSize = adcConfigured == -1 ? 1280 : 512; + int packetSize = adcConfigured == -1 ? 1286 : 518; + int packetsPerFrame = adcConfigured == -1 ? 2 : 1; + + // Generate Data + char imageData[imageSize]; + memset(imageData, 0, imageSize); + { + int i = 0; + if (adcConfigured == -1) { + *((uint32_t*)(imageData)) = 0xCACACACA; + } + for (i = sizeof(uint32_t); i < imageSize; i += sizeof(uint16_t)) { + *((uint16_t*)(imageData + i)) = (uint16_t)i; + } + } + + // Send data + { + int frameNr = 0; + uint16_t frameHeaderNr = 2; + // loop over number of frames + for(frameNr = 0; frameNr != numFrames; ++frameNr ) { + + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + break; + } + + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); + + int srcOffset = 0; + // loop packet + { + int i = 0; + for(i = 0; i != packetsPerFrame; ++i) { + + char packetData[packetSize]; + memset(packetData, 0, packetSize); + // set header + *((uint16_t*)(packetData)) = frameHeaderNr; + ++frameHeaderNr; + + // fill data + memcpy(packetData + 4, imageData + srcOffset, dataSize); + srcOffset += dataSize; + + sendUDPPacket(0, packetData, packetSize); + } + } + LOG(logINFO, ("Sent frame: %d\n", frameNr)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + + // sleep for (period - exptime) + if (frameNr < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); + } + } + } + } + + closeUDPSocket(0); virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } + LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } #endif @@ -1529,7 +1638,18 @@ void* start_timer(void* arg) { int stopStateMachine(){ LOG(logINFORED, ("Stopping State Machine\n")); #ifdef VIRTUAL - virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #endif //stop state machine @@ -1551,7 +1671,10 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - if(virtual_status == 0){ + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if(virtual_status == 0) { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; }else{ @@ -1653,6 +1776,9 @@ void readFrame(int *ret, char *mess){ u_int32_t runBusy() { #ifdef VIRTUAL + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } return virtual_status; #endif return runState(logDEBUG1) & STATUS_RN_BSY_MSK; diff --git a/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt b/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt index 0215225ee..b3aac94aa 100644 --- a/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(jungfrauDetectorServer_virtual ../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/communication_funcs_UDP.c + ../slsDetectorServer/src/communication_virtual.c ) target_include_directories(jungfrauDetectorServer_virtual diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 09b83a2be..8b0dd3727 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 de6dcfbf8..42a30b2b0 100755 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -8,11 +8,13 @@ #include "common.h" #ifdef VIRTUAL #include "communication_funcs_UDP.h" +#include "communication_virtual.h" #endif #include #include // usleep #include +#include #ifdef VIRTUAL #include #include @@ -23,6 +25,11 @@ extern int debugflag; extern udpStruct udpDetails; extern const enum detectorType myDetectorType; +// Global variable from communication_funcs.c +extern int isControlServer; +extern void getMacAddressinString(char* cmac, int size, uint64_t mac); +extern void getIpAddressinString(char* cip, uint32_t ip); + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -31,6 +38,7 @@ char initErrorMessage[MAX_STR_LENGTH]; pthread_t pthread_virtual_tid; int virtual_status = 0; int virtual_stop = 0; +int virtual_image_test_mode = 0; #endif enum detectorSettings thisSettings = UNINITIALIZED; @@ -41,6 +49,7 @@ int detPos[4] = {}; int numUDPInterfaces = 1; + int isInitCheckDone() { return initCheckDone; } @@ -226,6 +235,23 @@ int testBus() { } +#ifdef VIRTUAL +void setTestImageMode(int ival) { + if (ival >= 0) { + if (ival == 0) { + LOG(logINFO, ("Switching off Image Test Mode\n")); + virtual_image_test_mode = 0; + } else { + LOG(logINFO, ("Switching on Image Test Mode\n")); + virtual_image_test_mode = 1; + } + } +} + +int getTestImageMode() { + return virtual_image_test_mode; +} +#endif /* Ids */ @@ -349,6 +375,12 @@ void initStopServer() { LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); exit(EXIT_FAILURE); } +#ifdef VIRTUAL + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } +#endif } @@ -370,6 +402,13 @@ void setupDetector() { clkPhase[i] = 0; } } +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif + ALTERA_PLL_ResetPLL(); resetCore(); resetPeripheral(); @@ -521,16 +560,24 @@ int selectStoragecellStart(int pos) { int setStartingFrameNumber(uint64_t value) { LOG(logINFO, ("Setting starting frame number: %llu\n",(long long unsigned int)value)); +#ifdef VIRTUAL + setU64BitReg(value, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); +#else // decrement is for firmware setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); // need to set it twice for the firmware to catch setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); +#endif return OK; } int getStartingFrameNumber(uint64_t* retval) { +#ifdef VIRTUAL + *retval = getU64BitReg(FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); +#else // increment is for firmware *retval = (getU64BitReg(GET_FRAME_NUMBER_LSB_REG, GET_FRAME_NUMBER_MSB_REG) + 1); +#endif return OK; } @@ -727,8 +774,9 @@ int getModule(sls_detector_module *myMod){ if (dacValues[idac] >= 0) initialized = 1; } - if (initialized) + if (initialized) { return OK; + } return FAIL; } @@ -896,16 +944,10 @@ int getADC(enum ADCINDEX ind){ int setHighVoltage(int val){ -#ifdef VIRTUAL - if (val >= 0) - highvoltage = val; - return highvoltage; -#endif - // setting hv if (val >= 0) { LOG(logINFO, ("Setting High voltage: %d V", val)); - MAX1932_Set(val); + MAX1932_Set(&val); highvoltage = val; } return highvoltage; @@ -1074,73 +1116,57 @@ int configureMAC() { int dstport = udpDetails.dstport; int dstport2 = udpDetails.dstport2; -#ifdef VIRTUAL - char cDestIp[MAX_STR_LENGTH]; - memset(cDestIp, 0, MAX_STR_LENGTH); - sprintf(cDestIp, "%d.%d.%d.%d", (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff); - LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, dstport)); - if (setUDPDestinationDetails(0, cDestIp, dstport) == FAIL) { - LOG(logERROR, ("could not set udp destination IP and port\n")); - return FAIL; - } - return OK; -#endif LOG(logINFOBLUE, ("Configuring MAC\n")); + char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); + char src_mac2[50], src_ip2[INET_ADDRSTRLEN],dst_mac2[50], dst_ip2[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac2, 50, srcmac2); + getMacAddressinString(dst_mac2, 50, dstmac2); + getIpAddressinString(src_ip2, srcip2); + getIpAddressinString(dst_ip2, dstip2); + int numInterfaces = getNumberofUDPInterfaces(); int selInterface = getPrimaryInterface(); LOG(logINFO, ("\t#Interfaces : %d\n", numInterfaces)); LOG(logINFO, ("\tInterface : %d %s\n\n", selInterface, (selInterface ? "Inner" : "Outer"))); LOG(logINFO, ("\tOuter %s\n", (numInterfaces == 2) ? "(Bottom)": (selInterface ? "Not Used" : "Used"))); - LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (srcip>>24)&0xff,(srcip>>16)&0xff,(srcip>>8)&0xff,(srcip)&0xff, srcip)); - LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((srcmac>>40)&0xFF), - (unsigned int)((srcmac>>32)&0xFF), - (unsigned int)((srcmac>>24)&0xFF), - (unsigned int)((srcmac>>16)&0xFF), - (unsigned int)((srcmac>>8)&0xFF), - (unsigned int)((srcmac>>0)&0xFF), - (long long unsigned int)srcmac)); - LOG(logINFO, ("\tSource Port : %d \t\t\t(0x%08x)\n", srcport, srcport)); - - LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff, dstip)); - LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((dstmac>>40)&0xFF), - (unsigned int)((dstmac>>32)&0xFF), - (unsigned int)((dstmac>>24)&0xFF), - (unsigned int)((dstmac>>16)&0xFF), - (unsigned int)((dstmac>>8)&0xFF), - (unsigned int)((dstmac>>0)&0xFF), - (long long unsigned int)dstmac)); - LOG(logINFO, ("\tDest. Port : %d \t\t\t(0x%08x)\n\n",dstport, dstport)); + LOG(logINFO, ( + "\tSource IP : %s\n" + "\tSource MAC : %s\n" + "\tSource Port : %d\n" + "\tDest IP : %s\n" + "\tDest MAC : %s\n" + "\tDest Port : %d\n", + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport)); LOG(logINFO, ("\tInner %s\n", (numInterfaces == 2) ? "(Top)": (selInterface ? "Used" : "Not Used"))); - LOG(logINFO, ("\tSource IP2 : %d.%d.%d.%d \t\t(0x%08x)\n", - (srcip2>>24)&0xff,(srcip2>>16)&0xff,(srcip2>>8)&0xff,(srcip2)&0xff, srcip2)); - LOG(logINFO, ("\tSource MAC2 : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((srcmac2>>40)&0xFF), - (unsigned int)((srcmac2>>32)&0xFF), - (unsigned int)((srcmac2>>24)&0xFF), - (unsigned int)((srcmac2>>16)&0xFF), - (unsigned int)((srcmac2>>8)&0xFF), - (unsigned int)((srcmac2>>0)&0xFF), - (long long unsigned int)srcmac2)); - LOG(logINFO, ("\tSource Port2: %d \t\t\t(0x%08x)\n", srcport2, srcport2)); + LOG(logINFO, ( + "\tSource IP2 : %s\n" + "\tSource MAC2 : %s\n" + "\tSource Port2: %d\n" + "\tDest IP2 : %s\n" + "\tDest MAC2 : %s\n" + "\tDest Port2 : %d\n", + src_ip2, src_mac2, srcport2, + dst_ip2, dst_mac2, dstport2)); - LOG(logINFO, ("\tDest. IP2 : %d.%d.%d.%d \t\t(0x%08x)\n", - (dstip2>>24)&0xff,(dstip2>>16)&0xff,(dstip2>>8)&0xff,(dstip2)&0xff, dstip2)); - LOG(logINFO, ("\tDest. MAC2 : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((dstmac2>>40)&0xFF), - (unsigned int)((dstmac2>>32)&0xFF), - (unsigned int)((dstmac2>>24)&0xFF), - (unsigned int)((dstmac2>>16)&0xFF), - (unsigned int)((dstmac2>>8)&0xFF), - (unsigned int)((dstmac2>>0)&0xFF), - (long long unsigned int)dstmac2)); - LOG(logINFO, ("\tDest. Port2 : %d \t\t\t(0x%08x)\n", dstport2, dstport2)); +#ifdef VIRTUAL + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { + LOG(logERROR, ("could not set udp destination IP and port for interface 1\n")); + return FAIL; + } + if (numInterfaces == 2 && setUDPDestinationDetails(1, dst_ip2, dstport2) == FAIL) { + LOG(logERROR, ("could not set udp destination IP and port for interface 2\n")); + return FAIL; + } + return OK; +#endif // default one rxr entry (others not yet implemented in client yet) int iRxEntry = 0; @@ -1281,7 +1307,9 @@ int powerChip (int on){ bus_w(CHIP_POWER_REG, bus_r(CHIP_POWER_REG) & ~CHIP_POWER_ENABLE_MSK); } } - +#ifdef VIRTUAL + return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_ENABLE_MSK) >> CHIP_POWER_ENABLE_OFST); +#endif return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_STATUS_MSK) >> CHIP_POWER_STATUS_OFST); } @@ -1615,12 +1643,26 @@ int startStateMachine(){ if(createUDPSocket(0) != OK) { return FAIL; } + if (getNumberofUDPInterfaces() == 2 && createUDPSocket(1) != OK) { + return FAIL; + } LOG(logINFOBLUE, ("starting state machine\n")); virtual_status = 1; - virtual_stop = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { LOG(logERROR, ("Could not start Virtual acquisition thread\n")); virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFOGREEN, ("Virtual Acquisition started\n")); @@ -1641,85 +1683,127 @@ int startStateMachine(){ #ifdef VIRTUAL void* start_timer(void* arg) { - int64_t periodns = getPeriod(); + if (!isControlServer) { + return NULL; + } + + int numInterfaces = getNumberofUDPInterfaces(); + int64_t periodNs = getPeriod(); int numFrames = (getNumFrames() * getNumTriggers() * (getNumAdditionalStorageCells() + 1)); - int64_t exp_us = getExpTime() / 1000; + int64_t expUs = getExpTime() / 1000; + const int npixels = 256 * 256 * 8; + const int dataSize = 8192; + const int packetsize = dataSize + sizeof(sls_detector_header); + const int packetsPerFrame = numInterfaces == 1 ? 128 : 64; + int transmissionDelayUs = getTransmissionDelayFrame() * 1000; - //TODO: Generate data - char imageData[DATA_BYTES]; - memset(imageData, 0, DATA_BYTES); - { - int i = 0; - for (i = 0; i < DATA_BYTES; i += sizeof(uint16_t)) { - *((uint16_t*)(imageData + i)) = i; - } + // Generate data + char imageData[DATA_BYTES]; + memset(imageData, 0, DATA_BYTES); + { + int i = 0; + for (i = 0; i < npixels; ++i) { + // avoiding gain also being divided when gappixels enabled in call back + *((uint16_t*)(imageData + i * sizeof(uint16_t))) = virtual_image_test_mode ? 0x0FFE : (uint16_t)i; } - int datasize = 8192; - - - //TODO: Send data - { - int frameNr = 0; - for(frameNr=0; frameNr!= numFrames; ++frameNr ) { + } + + + // Send data + { + uint64_t frameNr = 0; + getStartingFrameNumber(&frameNr); + int iframes = 0; + for(iframes = 0; iframes != numFrames; ++iframes ) { - //check if virtual_stop is high - if(virtual_stop == 1){ - break; - } + usleep(transmissionDelayUs); - int srcOffset = 0; - - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + setStartingFrameNumber(frameNr + iframes + 1); + break; + } - usleep(exp_us); + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); - const int size = datasize + sizeof(sls_detector_header); - char packetData[size]; - memset(packetData, 0, sizeof(sls_detector_header)); - - // loop packet - { - int i = 0; - for(i=0; i!=128; ++i) { - // set header - sls_detector_header* header = (sls_detector_header*)(packetData); + int srcOffset = 0; + int srcOffset2 = DATA_BYTES / 2; + // loop packet + { + int i = 0; + for(i = 0; i != packetsPerFrame; ++i) { + // set header + char packetData[packetsize]; + memset(packetData, 0, packetsize); + sls_detector_header* header = (sls_detector_header*)(packetData); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameNr + iframes; + header->packetNumber = i; + header->modId = 0; + header->row = detPos[2]; + header->column = detPos[3]; + + // fill data + memcpy(packetData + sizeof(sls_detector_header), + imageData + srcOffset, dataSize); + srcOffset += dataSize; + + sendUDPPacket(0, packetData, packetsize); + + // second interface + char packetData2[packetsize]; + memset(packetData2, 0, packetsize); + if (numInterfaces == 2) { + header = (sls_detector_header*)(packetData2); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION - 1; header->frameNumber = frameNr; header->packetNumber = i; header->modId = 0; - header->row = detPos[X]; - header->column = detPos[Y]; - header->detType = (uint16_t)myDetectorType; - header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->row = detPos[0]; + header->column = detPos[1]; + // fill data - memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize); - srcOffset += datasize; + memcpy(packetData2 + sizeof(sls_detector_header), + imageData + srcOffset2, dataSize); + srcOffset2 += dataSize; - sendUDPPacket(0, packetData, size); - } - } - LOG(logINFO, ("Sent frame: %d\n", frameNr)); - clock_gettime(CLOCK_REALTIME, &end); - int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); - - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodns > time_ns) { - usleep((periodns - time_ns)/ 1000); + sendUDPPacket(1, packetData2, packetsize); } } } - } - - // } - + LOG(logINFO, ("Sent frame: %d\n", iframes)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + // sleep for (period - exptime) + if (iframes < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); + } + } + } + setStartingFrameNumber(frameNr + numFrames); + } + closeUDPSocket(0); + if (numInterfaces == 2) { + closeUDPSocket(1); + } virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } @@ -1728,7 +1812,18 @@ void* start_timer(void* arg) { int stopStateMachine(){ LOG(logINFORED, ("Stopping State Machine\n")); #ifdef VIRTUAL - virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #endif //stop state machine @@ -1746,7 +1841,10 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - if(virtual_status == 0){ + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if(virtual_status == 0) { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; }else{ @@ -1820,6 +1918,9 @@ void readFrame(int *ret, char *mess){ u_int32_t runBusy() { #ifdef VIRTUAL + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } return virtual_status; #endif u_int32_t s = (bus_r(STATUS_REG) & RUN_BUSY_MSK); diff --git a/slsDetectorServers/moenchDetectorServer/CMakeLists.txt b/slsDetectorServers/moenchDetectorServer/CMakeLists.txt index 4d51f71bf..ff6dd94a0 100644 --- a/slsDetectorServers/moenchDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/moenchDetectorServer/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(moenchDetectorServer_virtual ../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/readDefaultPattern.c + ../slsDetectorServer/src/communication_virtual.c ) include_directories( @@ -31,6 +32,7 @@ target_compile_definitions(moenchDetectorServer_virtual target_link_libraries(moenchDetectorServer_virtual PUBLIC pthread rt slsProjectCWarnings + m ) set_target_properties(moenchDetectorServer_virtual PROPERTIES diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index f3756181a..d20b12e58 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 1746ea4bd..9562adec2 100755 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -8,22 +8,33 @@ #include "MAX1932.h" // hv #include "ALTERA_PLL.h" // pll #include "common.h" +#ifdef VIRTUAL +#include "communication_virtual.h" +#endif #include #include // usleep +#include #ifdef VIRTUAL #include #include +#include //ceil #endif // Global variable from slsDetectorServer_funcs extern int debugflag; extern udpStruct udpDetails; +extern const enum detectorType myDetectorType; // Global variable from UDPPacketHeaderGenerator extern uint64_t udpFrameNumber; extern uint32_t udpPacketNumber; +// Global variable from communication_funcs.c +extern int isControlServer; +extern void getMacAddressinString(char* cmac, int size, uint64_t mac); +extern void getIpAddressinString(char* cip, uint32_t ip); + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -415,6 +426,12 @@ void initStopServer() { LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); exit(EXIT_FAILURE); } +#ifdef VIRTUAL + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } +#endif } @@ -467,6 +484,12 @@ void setupDetector() { adcEnableMask_1g = 0; adcEnableMask_10g = 0; nSamples = 1; +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif ALTERA_PLL_ResetPLLAndReconfiguration(); resetCore(); @@ -969,8 +992,9 @@ enum detectorSettings getSettings() { void setDAC(enum DACINDEX ind, int val, int mV) { - if (val < 0 && val != LTC2620_GetPowerDownValue()) + if (val < 0 && val != LTC2620_GetPowerDownValue()) { return; + } char* dac_names[] = {DAC_NAMES}; LOG(logINFO, ("Setting DAC %s\n", dac_names[ind])); @@ -1041,12 +1065,6 @@ void setVLimit(int l) { int setHighVoltage(int val){ -#ifdef VIRTUAL - if (val >= 0) - highvoltage = val; - return highvoltage; -#endif - // setting hv if (val >= 0) { LOG(logINFO, ("Setting High voltage: %d V\n", val)); @@ -1055,7 +1073,7 @@ int setHighVoltage(int val){ // switch to external high voltage bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK)); - MAX1932_Set(val); + MAX1932_Set(&val); // switch on internal high voltage, if set if (val > 0) @@ -1135,26 +1153,36 @@ void calcChecksum(udp_header* udp) { int configureMAC(){ - uint32_t sourceip = udpDetails.srcip; - uint32_t destip = udpDetails.dstip; - uint64_t sourcemac = udpDetails.srcmac; - uint64_t destmac = udpDetails.dstmac; - int sourceport = udpDetails.srcport; - int destport = udpDetails.dstport; -#ifdef VIRTUAL - return OK; -#endif + uint32_t srcip = udpDetails.srcip; + uint32_t dstip = udpDetails.dstip; + uint64_t srcmac = udpDetails.srcmac; + uint64_t dstmac = udpDetails.dstmac; + int srcport = udpDetails.srcport; + int dstport = udpDetails.dstport; + LOG(logINFOBLUE, ("Configuring MAC\n")); + char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); + + LOG(logINFO, ( + "\tSource IP : %s\n" + "\tSource MAC : %s\n" + "\tSource Port : %d\n" + "\tDest IP : %s\n" + "\tDest MAC : %s\n" + "\tDest Port : %d\n", + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport)); + // 1 giga udp if (!enableTenGigabitEthernet(-1)) { - LOG(logINFOBLUE, ("Configuring 1G MAC\n")); + LOG(logINFOBLUE, ("\t1G MAC\n")); if (updateDatabytesandAllocateRAM() == FAIL) return -1; - char cDestIp[MAX_STR_LENGTH]; - memset(cDestIp, 0, MAX_STR_LENGTH); - sprintf(cDestIp, "%d.%d.%d.%d", (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff); - LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, destport)); - if (setUDPDestinationDetails(0, cDestIp, destport) == FAIL) { + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { LOG(logERROR, ("could not set udp 1G destination IP and port\n")); return FAIL; } @@ -1162,31 +1190,7 @@ int configureMAC(){ } // 10 G - LOG(logINFOBLUE, ("Configuring 10G MAC\n")); - - LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (sourceip>>24)&0xff,(sourceip>>16)&0xff,(sourceip>>8)&0xff,(sourceip)&0xff, sourceip)); - LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((sourcemac>>40)&0xFF), - (unsigned int)((sourcemac>>32)&0xFF), - (unsigned int)((sourcemac>>24)&0xFF), - (unsigned int)((sourcemac>>16)&0xFF), - (unsigned int)((sourcemac>>8)&0xFF), - (unsigned int)((sourcemac>>0)&0xFF), - (long long unsigned int)sourcemac)); - LOG(logINFO, ("\tSource Port : %d \t\t\t(0x%08x)\n",sourceport, sourceport)); - - LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff, destip)); - LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((destmac>>40)&0xFF), - (unsigned int)((destmac>>32)&0xFF), - (unsigned int)((destmac>>24)&0xFF), - (unsigned int)((destmac>>16)&0xFF), - (unsigned int)((destmac>>8)&0xFF), - (unsigned int)((destmac>>0)&0xFF), - (long long unsigned int)destmac)); - LOG(logINFO, ("\tDest. Port : %d \t\t\t(0x%08x)\n",destport, destport)); + LOG(logINFOBLUE, ("\t10G MAC\n")); // start addr uint32_t addr = RXR_ENDPOINT_START_REG; @@ -1196,21 +1200,21 @@ int configureMAC(){ // mac addresses // msb (32) + lsb (16) - udp->udp_destmac_msb = ((destmac >> 16) & BIT32_MASK); - udp->udp_destmac_lsb = ((destmac >> 0) & BIT16_MASK); + udp->udp_destmac_msb = ((dstmac >> 16) & BIT32_MASK); + udp->udp_destmac_lsb = ((dstmac >> 0) & BIT16_MASK); // msb (16) + lsb (32) - udp->udp_srcmac_msb = ((sourcemac >> 32) & BIT16_MASK); - udp->udp_srcmac_lsb = ((sourcemac >> 0) & BIT32_MASK); + udp->udp_srcmac_msb = ((srcmac >> 32) & BIT16_MASK); + udp->udp_srcmac_lsb = ((srcmac >> 0) & BIT32_MASK); // ip addresses - udp->ip_srcip_msb = ((sourceip >> 16) & BIT16_MASK); - udp->ip_srcip_lsb = ((sourceip >> 0) & BIT16_MASK); - udp->ip_destip_msb = ((destip >> 16) & BIT16_MASK); - udp->ip_destip_lsb = ((destip >> 0) & BIT16_MASK); + udp->ip_srcip_msb = ((srcip >> 16) & BIT16_MASK); + udp->ip_srcip_lsb = ((srcip >> 0) & BIT16_MASK); + udp->ip_destip_msb = ((dstip >> 16) & BIT16_MASK); + udp->ip_destip_lsb = ((dstip >> 0) & BIT16_MASK); // source port - udp->udp_srcport = sourceport; - udp->udp_destport = destport; + udp->udp_srcport = srcport; + udp->udp_destport = dstport; // other defines udp->udp_ethertype = 0x800; @@ -1241,6 +1245,9 @@ int* getDetectorPosition() { } int enableTenGigabitEthernet(int val) { +#ifdef VIRTUAL + return 0; +#endif uint32_t addr = CONFIG_REG; // set @@ -1818,11 +1825,27 @@ uint64_t getPatternBitMask() { int startStateMachine(){ #ifdef VIRTUAL - virtual_status = 1; - virtual_stop = 0; + // create udp socket + if(createUDPSocket(0) != OK) { + return FAIL; + } + LOG(logINFOBLUE, ("Starting State Machine\n")); + virtual_status = 1; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { - virtual_status = 0; LOG(logERROR, ("Could not start Virtual acquisition thread\n")); + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFOGREEN, ("Virtual Acquisition started\n")); @@ -1856,42 +1879,92 @@ int startStateMachine(){ #ifdef VIRTUAL void* start_timer(void* arg) { - int64_t periodns = getPeriod(); + if (!isControlServer) { + return NULL; + } + + int64_t periodNs = getPeriod(); int numFrames = (getNumFrames() * getNumTriggers() ); - int64_t exp_ns = getExpTime(); + int64_t expNs = getExpTime(); - int frameNr = 0; - // loop over number of frames - for(frameNr=0; frameNr!= numFrames; ++frameNr ) { + int imageSize = dataBytes; + int dataSize = UDP_PACKET_DATA_BYTES; + int packetSize = sizeof(sls_detector_header) + dataSize; + int packetsPerFrame = ceil((double)imageSize / (double)dataSize); - //check if virtual_stop is high - if(virtual_stop == 1){ - break; - } - - // sleep for exposure time - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); - usleep(exp_ns / 1000); - clock_gettime(CLOCK_REALTIME, &end); - - // calculate time left in period - int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); - - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodns > time_ns) { - usleep((periodns - time_ns)/ 1000); - } - } - - // set register frames left + // Generate Data + char imageData[imageSize]; + memset(imageData, 0, imageSize); + { + int i = 0; + for (i = 0; i < imageSize; i += sizeof(uint16_t)) { + *((uint16_t*)(imageData + i)) = i; + } } - // set status to idle + // Send data + { + int frameNr = 0; + // loop over number of frames + for(frameNr = 0; frameNr != numFrames; ++frameNr ) { + + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + break; + } + + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expNs / 1000); + + int srcOffset = 0; + // loop packet + { + int i = 0; + for(i = 0; i != packetsPerFrame; ++i) { + // set header + char packetData[packetSize]; + memset(packetData, 0, packetSize); + sls_detector_header* header = (sls_detector_header*)(packetData); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameNr; + header->packetNumber = i; + header->modId = 0; + header->row = detPos[X]; + header->column = detPos[Y]; + + // fill data + memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, dataSize); + srcOffset += dataSize; + + sendUDPPacket(0, packetData, packetSize); + } + } + LOG(logINFO, ("Sent frame: %d\n", frameNr)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + + // sleep for (period - exptime) + if (frameNr < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); + } + } + } + } + + closeUDPSocket(0); + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } @@ -1900,7 +1973,18 @@ void* start_timer(void* arg) { int stopStateMachine(){ LOG(logINFORED, ("Stopping State Machine\n")); #ifdef VIRTUAL - virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #endif //stop state machine @@ -1919,7 +2003,10 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - if(virtual_status == 0){ + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if(virtual_status == 0) { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; }else{ @@ -2154,6 +2241,9 @@ int readFrameFromFifo() { uint32_t runBusy() { #ifdef VIRTUAL + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } return virtual_status; #endif uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK); diff --git a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt index f6a4c841c..72bb24351 100644 --- a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(mythen3DetectorServer_virtual ../slsDetectorServer/src/LTC2620_Driver.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/programFpgaNios.c + ../slsDetectorServer/src/communication_virtual.c ) include_directories( diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 140e67239..b0f19a1fd 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 9d8158ec2..f34f6c124 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -8,10 +8,12 @@ #include "ALTERA_PLL_CYCLONE10.h" #ifdef VIRTUAL #include "communication_funcs_UDP.h" +#include "communication_virtual.h" #endif #include #include // usleep +#include #ifdef VIRTUAL #include #include @@ -22,6 +24,11 @@ extern int debugflag; extern udpStruct udpDetails; extern const enum detectorType myDetectorType; +// Global variable from communication_funcs.c +extern int isControlServer; +extern void getMacAddressinString(char* cmac, int size, uint64_t mac); +extern void getIpAddressinString(char* cip, uint32_t ip); + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -319,6 +326,12 @@ void initStopServer() { LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); exit(EXIT_FAILURE); } +#ifdef VIRTUAL + virtual_stop = 0; + if (!isControlServer) { + ComVirtual_setStop(virtual_stop); + } +#endif } @@ -343,8 +356,13 @@ void setupDetector() { dacValues[i] = 0; } } +#ifdef VIRTUAL + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } +#endif -#ifndef VIRTUAL // pll defines ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ); ALTERA_PLL_C10_ResetPLL(READOUT_PLL); @@ -353,7 +371,6 @@ void setupDetector() { DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME); //dac LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC); -#endif resetCore(); resetPeripheral(); @@ -738,41 +755,29 @@ int configureMAC() { int srcport = udpDetails.srcport; int dstport = udpDetails.dstport; + LOG(logINFOBLUE, ("Configuring MAC\n")); + char src_mac[50], src_ip[INET_ADDRSTRLEN],dst_mac[50], dst_ip[INET_ADDRSTRLEN]; + getMacAddressinString(src_mac, 50, srcmac); + getMacAddressinString(dst_mac, 50, dstmac); + getIpAddressinString(src_ip, srcip); + getIpAddressinString(dst_ip, dstip); + + LOG(logINFO, ( + "\tSource IP : %s\n" + "\tSource MAC : %s\n" + "\tSource Port : %d\n" + "\tDest IP : %s\n" + "\tDest MAC : %s\n" + "\tDest Port : %d\n", + src_ip, src_mac, srcport, + dst_ip, dst_mac, dstport)); + #ifdef VIRTUAL - char cDestIp[MAX_STR_LENGTH]; - memset(cDestIp, 0, MAX_STR_LENGTH); - sprintf(cDestIp, "%d.%d.%d.%d", (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff); - LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, dstport)); - if (setUDPDestinationDetails(0, cDestIp, dstport) == FAIL) { + if (setUDPDestinationDetails(0, dst_ip, dstport) == FAIL) { LOG(logERROR, ("could not set udp destination IP and port\n")); return FAIL; } #endif - LOG(logINFOBLUE, ("Configuring MAC\n")); - - LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (srcip>>24)&0xff,(srcip>>16)&0xff,(srcip>>8)&0xff,(srcip)&0xff, srcip)); - LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((srcmac>>40)&0xFF), - (unsigned int)((srcmac>>32)&0xFF), - (unsigned int)((srcmac>>24)&0xFF), - (unsigned int)((srcmac>>16)&0xFF), - (unsigned int)((srcmac>>8)&0xFF), - (unsigned int)((srcmac>>0)&0xFF), - (long long unsigned int)srcmac)); - LOG(logINFO, ("\tSource Port : %d \t\t\t(0x%08x)\n", srcport, srcport)); - - LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d \t\t(0x%08x)\n", - (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff, dstip)); - LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", - (unsigned int)((dstmac>>40)&0xFF), - (unsigned int)((dstmac>>32)&0xFF), - (unsigned int)((dstmac>>24)&0xFF), - (unsigned int)((dstmac>>16)&0xFF), - (unsigned int)((dstmac>>8)&0xFF), - (unsigned int)((dstmac>>0)&0xFF), - (long long unsigned int)dstmac)); - LOG(logINFO, ("\tDest. Port : %d \t\t\t(0x%08x)\n\n",dstport, dstport)); // start addr uint32_t addr = BASE_UDP_RAM; @@ -1121,6 +1126,9 @@ uint64_t getPatternBitMask() { } int checkDetectorType() { +#ifdef VIRTUAL + return OK; +#endif LOG(logINFO, ("Checking type of module\n")); FILE* fd = fopen(TYPE_FILE_NAME, "r"); if (fd == NULL) { @@ -1354,13 +1362,24 @@ int startStateMachine(){ if(createUDPSocket(0) != OK) { return FAIL; } - LOG(logINFOBLUE, ("starting state machine\n")); + LOG(logINFOBLUE, ("Starting State Machine\n")); // set status to running virtual_status = 1; - virtual_stop = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + virtual_stop = ComVirtual_getStop(); + if (virtual_stop != 0) { + LOG(logERROR, ("Cant start acquisition. " + "Stop server has not updated stop status to 0\n")); + return FAIL; + } + } if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { LOG(logERROR, ("Could not start Virtual acquisition thread\n")); virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } return FAIL; } LOG(logINFOGREEN, ("Virtual Acquisition started\n")); @@ -1381,14 +1400,19 @@ int startStateMachine(){ #ifdef VIRTUAL void* start_timer(void* arg) { - int64_t periodns = getPeriod(); + if (!isControlServer) { + return NULL; + } + + int64_t periodNs = getPeriod(); int numFrames = (getNumFrames() * getNumTriggers() ); - int64_t exp_ns = getExpTime(); + int64_t expUs = getExpTime() / 1000; + //int dr = setDynamicRange(-1); int imagesize = calculateDataBytes(); - int datasize = imagesize / PACKETS_PER_FRAME; - int packetsize = datasize + sizeof(sls_detector_header); + int dataSize = imagesize / PACKETS_PER_FRAME; + int packetSize = dataSize + sizeof(sls_detector_header); // Generate data char imageData[imagesize]; @@ -1400,66 +1424,71 @@ void* start_timer(void* arg) { } } - int frameNr = 1; - // loop over number of frames - for (frameNr = 0; frameNr != numFrames; ++frameNr) { + // Send data + { + int frameNr = 1; + // loop over number of frames + for (frameNr = 0; frameNr != numFrames; ++frameNr) { - //check if virtual_stop is high - if(virtual_stop == 1){ - break; - } - - int srcOffset = 0; - - // sleep for exposure time - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); - usleep(exp_ns / 1000); - - // loop packet - { - int i = 0; - for(i = 0; i!=PACKETS_PER_FRAME; ++i) { - char packetData[packetsize]; - memset(packetData, 0, packetsize); - - // set header - sls_detector_header* header = (sls_detector_header*)(packetData); - header->frameNumber = frameNr + 1; - header->packetNumber = i; - header->modId = 0; - header->row = detPos[X]; - header->column = detPos[Y]; - header->detType = (uint16_t)myDetectorType; - header->version = SLS_DETECTOR_HEADER_VERSION - 1; - - // fill data - memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize); - srcOffset += datasize; - - sendUDPPacket(0, packetData, packetsize); + // update the virtual stop from stop server + virtual_stop = ComVirtual_getStop(); + //check if virtual_stop is high + if(virtual_stop == 1){ + break; } - } - LOG(logINFO, ("Sent frame: %d\n", frameNr)); - // calculate time left in period - clock_gettime(CLOCK_REALTIME, &end); - int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodns > time_ns) { - usleep((periodns - time_ns)/ 1000); + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); + + int srcOffset = 0; + // loop packet + { + int i = 0; + for(i = 0; i != PACKETS_PER_FRAME; ++i) { + char packetData[packetSize]; + memset(packetData, 0, packetSize); + + // set header + sls_detector_header* header = (sls_detector_header*) (packetData); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION - 1; + header->frameNumber = frameNr + 1; + header->packetNumber = i; + header->modId = 0; + header->row = detPos[X]; + header->column = detPos[Y]; + + // fill data + memcpy(packetData + sizeof(sls_detector_header), + imageData + srcOffset, dataSize); + srcOffset += dataSize; + + sendUDPPacket(0, packetData, packetSize); + } } - } + LOG(logINFO, ("Sent frame: %d\n", frameNr)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); - // set register frames left - } + // sleep for (period - exptime) + if (frameNr < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs)/ 1000); + } + } + } + } closeUDPSocket(0); - // set status to idle + virtual_status = 0; + if (isControlServer) { + ComVirtual_setStatus(virtual_status); + } LOG(logINFOBLUE, ("Finished Acquiring\n")); return NULL; } @@ -1469,7 +1498,18 @@ void* start_timer(void* arg) { int stopStateMachine(){ LOG(logINFORED, ("Stopping State Machine\n")); #ifdef VIRTUAL - virtual_stop = 0; + if (!isControlServer) { + virtual_stop = 1; + ComVirtual_setStop(virtual_stop); + // read till status is idle + int tempStatus = 1; + while(tempStatus == 1) { + tempStatus = ComVirtual_getStatus(); + } + virtual_stop = 0; + ComVirtual_setStop(virtual_stop); + LOG(logINFO, ("Stopped State Machine\n")); + } return OK; #endif //stop state machine @@ -1480,10 +1520,13 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - if(virtual_status == 0){ + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } + if(virtual_status == 0) { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; - }else{ + } else{ LOG(logINFOBLUE, ("Status: RUNNING\n")); return RUNNING; } @@ -1555,6 +1598,9 @@ void readFrame(int *ret, char *mess) { u_int32_t runBusy() { #ifdef VIRTUAL + if (!isControlServer) { + virtual_status = ComVirtual_getStatus(); + } return virtual_status; #endif u_int32_t s = (bus_r(PAT_STATUS_REG) & PAT_STATUS_RUN_BUSY_MSK); diff --git a/slsDetectorServers/slsDetectorServer/include/MAX1932.h b/slsDetectorServers/slsDetectorServer/include/MAX1932.h index d3f9668c0..2a3ed7d78 100755 --- a/slsDetectorServers/slsDetectorServer/include/MAX1932.h +++ b/slsDetectorServers/slsDetectorServer/include/MAX1932.h @@ -21,11 +21,11 @@ void MAX1932_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t d void MAX1932_Disable(); /** - * Set value - * @param val value to set + * Set value (value is updated to correct range) + * @param val pointer to value to set * @return OK or FAIL */ -int MAX1932_Set (int val) ; +int MAX1932_Set (int* val) ; diff --git a/slsDetectorServers/slsDetectorServer/include/communication_funcs.h b/slsDetectorServers/slsDetectorServer/include/communication_funcs.h index bfe60c75a..7b465af6a 100755 --- a/slsDetectorServers/slsDetectorServer/include/communication_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/communication_funcs.h @@ -11,6 +11,13 @@ typedef enum{ OTHER }intType; +// communciate with stop server +#ifdef VIRTUAL +#define FILE_STATUS "/tmp/Sls_virtual_server_status_" +#define FILE_STOP "/tmp/Sls_virtual_server_stop_" +#define FD_STATUS 0 +#define FD_STOP 1 +#endif int bindSocket(unsigned short int port_number); int acceptConnection(int socketDescriptor); diff --git a/slsDetectorServers/slsDetectorServer/include/communication_virtual.h b/slsDetectorServers/slsDetectorServer/include/communication_virtual.h new file mode 100755 index 000000000..06c6558d4 --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/include/communication_virtual.h @@ -0,0 +1,14 @@ +#pragma once +#ifdef VIRTUAL +// communciate between control and stop server + +int ComVirtual_createFiles(const int port); +void ComVirtual_setFileNames(const int port); +void ComVirtual_setStatus(int value); +int ComVirtual_getStatus(); +void ComVirtual_setStop(int value); +int ComVirtual_getStop(); +int ComVirtual_writeToFile(int value, const char* fname, const char* serverName); +int ComVirtual_readFromFile(int* value, const char* fname, const char* serverName); + +#endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 4e7e0d9ff..fcc22c2eb 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -61,7 +61,7 @@ int testFpga(); int testBus(); #endif -#ifdef GOTTHARDD +#if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL)) void setTestImageMode(int ival); int getTestImageMode(); #endif @@ -413,7 +413,9 @@ int setCounterBit(int val); int pulsePixel(int n, int x, int y); int pulsePixelNMove(int n, int x, int y); int pulseChip(int n); -int64_t setRateCorrection(int64_t custom_tau_in_nsec); +int updateRateCorrection(char* mess); +int validateAndSetRateCorrection(int64_t tau_ns, char* mess); +int setRateCorrection(int64_t custom_tau_in_nsec); int getRateCorrectionEnable(); int getDefaultSettingsTau_in_nsec(); void setDefaultSettingsTau_in_nsec(int t); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 12c97c534..493a34da5 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -88,8 +88,6 @@ int exit_server(int); int lock_server(int); int get_last_client_ip(int); int set_port(int); -int update_client(int); -int send_update(int); int calibrate_pedestal(int); int enable_ten_giga(int); int set_all_trimbits(int); @@ -217,3 +215,5 @@ int set_current_source(int); int get_timing_source(int); int set_timing_source(int); int get_num_channels(int); +int update_rate_correction(int); + diff --git a/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c b/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c index c5f5acc60..af5da114a 100755 --- a/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c +++ b/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c @@ -26,8 +26,12 @@ void ASIC_Driver_SetDefines(char* driverfname) { } int ASIC_Driver_Set (int index, int length, char* buffer) { + char temp[20]; + memset(temp, 0, sizeof(temp)); + sprintf(temp, "%d", index + 1); char fname[MAX_STR_LENGTH]; - sprintf(fname, "%s%d", ASIC_Driver_DriverFileName, index + 1); + strcpy(fname, ASIC_Driver_DriverFileName); + strcat(fname, temp); LOG(logDEBUG2, ("\t[chip index: %d, length: %d, fname: %s]\n", index, length, fname)); { LOG(logDEBUG2, ("\t[values: \n")); @@ -38,9 +42,7 @@ int ASIC_Driver_Set (int index, int length, char* buffer) { LOG(logDEBUG2, ("\t]\n")); } -#ifdef VIRTUAL - return OK; -#endif +#ifndef VIRTUAL int fd=open(fname, O_RDWR); if (fd == -1) { LOG(logERROR, ("Could not open file %s for writing to control ASIC (%d)\n", fname, index)); @@ -62,6 +64,7 @@ int ASIC_Driver_Set (int index, int length, char* buffer) { return FAIL; } close(fd); +#endif return OK; } diff --git a/slsDetectorServers/slsDetectorServer/src/DAC6571.c b/slsDetectorServers/slsDetectorServer/src/DAC6571.c index f83e28fee..ba18cb865 100755 --- a/slsDetectorServers/slsDetectorServer/src/DAC6571.c +++ b/slsDetectorServers/slsDetectorServer/src/DAC6571.c @@ -36,6 +36,7 @@ int DAC6571_Set (int val) { LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue)); +#ifndef VIRTUAL //open file FILE* fd=fopen(DAC6571_DriverFileName,"w"); if (fd==NULL) { @@ -45,6 +46,7 @@ int DAC6571_Set (int val) { //convert to string, add 0 and write to file fprintf(fd, "%d\n", dacvalue); fclose(fd); +#endif return OK; } diff --git a/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c b/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c index 96ab3261e..a5aa214c9 100755 --- a/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c +++ b/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c @@ -72,8 +72,14 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv if ( (*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) { LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n",dacnum, dacname, *dacval, dacmV)); + +#ifndef VIRTUAL char fname[MAX_STR_LENGTH]; - sprintf(fname, "%s%d", LTC2620_D_DriverFileName, dacnum); + strcpy(fname, LTC2620_D_DriverFileName); + char temp[20]; + memset(temp, 0, sizeof(temp)); + sprintf(temp, "%d", dacnum); + strcat(fname, temp); LOG(logDEBUG1, ("fname %s\n",fname)); //open file @@ -85,6 +91,8 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv //convert to string, add 0 and write to file fprintf(fd, "%d\n", *dacval); fclose(fd); +#endif + } return OK; } diff --git a/slsDetectorServers/slsDetectorServer/src/MAX1932.c b/slsDetectorServers/slsDetectorServer/src/MAX1932.c index fc6885dc6..c7fca3733 100755 --- a/slsDetectorServers/slsDetectorServer/src/MAX1932.c +++ b/slsDetectorServers/slsDetectorServer/src/MAX1932.c @@ -43,33 +43,33 @@ void MAX1932_Disable() { & ~(MAX1932_DigMask)); } -int MAX1932_Set (int val) { - LOG(logDEBUG1, ("Setting high voltage to %d\n", val)); - if (val < 0) +int MAX1932_Set (int* val) { + LOG(logDEBUG1, ("Setting high voltage to %d\n", *val)); + if (*val < 0) return FAIL; int dacvalue = 0; // limit values (normally < 60 => 0 (off)) - if (val < MAX1932_MinVoltage) { + if (*val < MAX1932_MinVoltage) { dacvalue = MAX1932_POWER_OFF_DAC_VAL; - val = 0; + *val = 0; } // limit values (normally > 200 => 0x1 (max)) - else if (val > MAX1932_MaxVoltage) { + else if (*val > MAX1932_MaxVoltage) { dacvalue = MAX1932_MAX_DAC_VAL; - val = MAX1932_MaxVoltage; + *val = MAX1932_MaxVoltage; } // convert value else { // no failure in conversion as limits handled (range from 0x1 to 0xFF) ConvertToDifferentRange(MAX1932_MinVoltage, MAX1932_MaxVoltage, MAX1932_MIN_DAC_VAL, MAX1932_MAX_DAC_VAL, - val, &dacvalue); + *val, &dacvalue); dacvalue &= MAX1932_HV_DATA_MSK; } - LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue)); + LOG(logINFO, ("\t%dV (dacval %d)\n", *val, dacvalue)); serializeToSPI(MAX1932_Reg, dacvalue, MAX1932_CsMask, MAX1932_HV_NUMBITS, MAX1932_ClkMask, MAX1932_DigMask, MAX1932_DigOffset, 0); return OK; diff --git a/slsDetectorServers/slsDetectorServer/src/communication_funcs.c b/slsDetectorServers/slsDetectorServer/src/communication_funcs.c index 18c2ba516..5bed206a3 100755 --- a/slsDetectorServers/slsDetectorServer/src/communication_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/communication_funcs.c @@ -579,10 +579,6 @@ int Server_VerifyLock() { int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) { - // update if different clients (ret can be ok or acquisition finished), not fail to not overwrite e message - if (update && isControlServer && ret != FAIL && differentClients) - ret = FORCE_UPDATE; - // send success of operation int ret1 = ret; sendData(fileDes, &ret1,sizeof(ret1), INT32); @@ -616,7 +612,12 @@ void getMacAddressinString(char* cmac, int size, uint64_t mac) { void getIpAddressinString(char* cip, uint32_t ip) { memset(cip, 0, INET_ADDRSTRLEN); +#if defined(EIGERD) && !defined(VIRTUAL) inet_ntop(AF_INET, &ip, cip, INET_ADDRSTRLEN); +#else + sprintf(cip, "%d.%d.%d.%d", + (ip>>24)&0xff,(ip>>16)&0xff,(ip>>8)&0xff,(ip)&0xff); +#endif } diff --git a/slsDetectorServers/slsDetectorServer/src/communication_funcs_UDP.c b/slsDetectorServers/slsDetectorServer/src/communication_funcs_UDP.c index dd3a4d635..6ebfcac02 100755 --- a/slsDetectorServers/slsDetectorServer/src/communication_funcs_UDP.c +++ b/slsDetectorServers/slsDetectorServer/src/communication_funcs_UDP.c @@ -16,7 +16,7 @@ int udpSockfd[2] = {-1, -1}; struct addrinfo* udpServerAddrInfo[2] = {0, 0}; unsigned short int udpDestinationPort[2] = {0, 0}; -char udpDestinationIp[2][MAX_STR_LENGTH] = {"", ""}; +char udpDestinationIp[2][INET_ADDRSTRLEN] = {"", ""}; //DEFAULT_TX_UDP_PORT;// src port int getUdPSocketDescriptor(int index) { @@ -26,8 +26,8 @@ int getUdPSocketDescriptor(int index) { int setUDPDestinationDetails(int index, const char* ip, unsigned short int port) { udpDestinationPort[index] = port; size_t len = strlen(ip); - memset(udpDestinationIp[index], 0, MAX_STR_LENGTH); - strncpy(udpDestinationIp[index], ip, len > MAX_STR_LENGTH ? MAX_STR_LENGTH : len ); + memset(udpDestinationIp[index], 0, INET_ADDRSTRLEN); + strncpy(udpDestinationIp[index], ip, len > INET_ADDRSTRLEN ? INET_ADDRSTRLEN : len ); if (udpServerAddrInfo[index]) { freeaddrinfo(udpServerAddrInfo[index]); @@ -37,7 +37,7 @@ int setUDPDestinationDetails(int index, const char* ip, unsigned short int port) // convert ip to internet address struct addrinfo hints; memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; + hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = 0; hints.ai_protocol = 0; @@ -83,19 +83,16 @@ int createUDPSocket(int index) { LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n", udpDestinationPort[index], udpDestinationIp[index])); + // Using connect expects that the receiver (udp server) exists to listen to these packets // connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet - // using write without a connect will end in segv - if (connect(udpSockfd[index],udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen)==-1) { - LOG(logERROR, ("Could not connect to UDP server at ip:%s, port:%d. (Error code:%d, %s)\n", - udpDestinationIp[index], udpDestinationPort[index], errno, gai_strerror(errno))); - } + // using write without a connect will end in segv LOG(logINFO, ("Udp client socket connected\n", udpDestinationPort[index], udpDestinationIp[index])); return OK; } int sendUDPPacket(int index, const char* buf, int length) { - int n = write(udpSockfd[index], buf, length); + int n = sendto(udpSockfd[index], buf, length, 0, udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen); // udp sends atomically, no need to handle partial data if (n == -1) { LOG(logERROR, ("Could not send udp packet for socket %d. (Error code:%d, %s)\n", diff --git a/slsDetectorServers/slsDetectorServer/src/communication_virtual.c b/slsDetectorServers/slsDetectorServer/src/communication_virtual.c new file mode 100755 index 000000000..cb1cdf5d9 --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/src/communication_virtual.c @@ -0,0 +1,120 @@ +#ifdef VIRTUAL +#include "communication_virtual.h" +#include "clogger.h" + +#include +#include // usleep + +#define FILE_STATUS "/tmp/sls_virtual_server_status_" +#define FILE_STOP "/tmp/sls_virtual_server_stop_" +#define FD_STATUS 0 +#define FD_STOP 1 +#define FILE_NAME_LENGTH 1000 + +FILE* fd[2] = {NULL, NULL}; +char fnameStatus[FILE_NAME_LENGTH]; +char fnameStop[FILE_NAME_LENGTH]; +int portNumber = 0; + +int ComVirtual_createFiles(const int port) { + portNumber = port; + // control server writign status file + memset(fnameStatus, 0, FILE_NAME_LENGTH); + sprintf(fnameStatus, "%s%d", FILE_STATUS, port); + FILE* fd = NULL; + if (NULL == (fd = fopen(fnameStatus, "w"))) { + LOG(logERROR, ("Could not open the file %s for virtual communication\n", + fnameStatus)); + return 0; + } + fclose(fd); + LOG(logINFOBLUE, ("Created status file %s\n", fnameStatus)); + + // stop server writing stop file + memset(fnameStop, 0, FILE_NAME_LENGTH); + sprintf(fnameStop, "%s%d", FILE_STOP, port); + if (NULL == (fd = fopen(fnameStop, "w"))) { + LOG(logERROR, ("Could not open the file %s for virtual communication\n", + fnameStop)); + return 0; + } + fclose(fd); + LOG(logINFOBLUE, ("Created stop file %s\n", fnameStop)); + + return 1; +} + +void ComVirtual_setFileNames(const int port) { + portNumber = port; + memset(fnameStatus, 0, FILE_NAME_LENGTH); + memset(fnameStop, 0, FILE_NAME_LENGTH); + sprintf(fnameStatus, "%s%d", FILE_STATUS, port); + sprintf(fnameStop, "%s%d", FILE_STOP, port); +} + +void ComVirtual_setStatus(int value) { + while (!ComVirtual_writeToFile(value, fnameStatus, "Control")) { + usleep(100); + } +} + +int ComVirtual_getStatus() { + int retval = 0; + while (!ComVirtual_readFromFile(&retval, fnameStatus, "Stop")) { + usleep(100); + } + return retval; +} + +void ComVirtual_setStop(int value) { + while (!ComVirtual_writeToFile(value, fnameStop, "Stop")) { + usleep(100); + } +} + +int ComVirtual_getStop() { + int retval = 0; + while (!ComVirtual_readFromFile(&retval, fnameStop, "Control")) { + usleep(100); + } + return retval; +} + +int ComVirtual_writeToFile(int value, const char* fname, const char* serverName) { + FILE* fd = NULL; + if (NULL == (fd = fopen(fname, "w"))) { + LOG(logERROR, ("Vritual %s Server [%d] could not open " + "the file %s for writing\n", + serverName, portNumber, fname)); + return 0; + } + while (fwrite(&value, sizeof(value), 1, fd) < 1) { + LOG(logERROR, ("Vritual %s Server [%d] could not write " + "to file %s\n", + serverName, portNumber, fname)); + return 0; + } + fclose(fd); + return 1; +} + +int ComVirtual_readFromFile(int* value, const char* fname, const char* serverName) { + FILE* fd = NULL; + if (NULL == (fd = fopen(fname, "r"))) { + LOG(logERROR, ("Vritual %s Server [%d] could not open " + "the file %s for reading\n", + serverName, portNumber, fname)); + return 0; + } + while (fread(value, sizeof(int), 1, fd) < 1) { + LOG(logERROR, ("Vritual %s Server [%d] could not read " + "from file %s\n", + serverName, portNumber, fname)); + return 0; + } + fclose(fd); + return 1; +} + + +#endif \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c index 76e5bc705..c324a9f2b 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c @@ -7,6 +7,9 @@ #include "slsDetectorServer_funcs.h" #include "slsDetectorServer_defs.h" #include "versionAPI.h" +#ifdef VIRTUAL +#include "communication_virtual.h" +#endif #include #include @@ -31,7 +34,8 @@ void error(char *msg){ perror(msg); } -int main(int argc, char *argv[]){ +int main(int argc, char *argv[]) { + // print version if (argc > 1 && !strcasecmp(argv[1], "-version")) { int version = 0; @@ -50,8 +54,9 @@ int main(int argc, char *argv[]){ } int portno = DEFAULT_PORTNO; - int retval = OK; - int fd = 0; + isControlServer = 1; + debugflag = 0; + checkModuleFlag = 1; // if socket crash, ignores SISPIPE, prevents global signal handler // subsequent read/write to socket gives error - must handle locally @@ -100,46 +105,68 @@ int main(int argc, char *argv[]){ } } -#ifdef STOP_SERVER - char cmd[100]; - memset(cmd, 0, 100); -#endif + // control server if (isControlServer) { - LOG(logINFO, ("Opening control server on port %d \n", portno)); #ifdef STOP_SERVER + // start stop server process + char cmd[MAX_STR_LENGTH]; + memset(cmd, 0, MAX_STR_LENGTH); { int i; - for (i = 0; i < argc; ++i) - sprintf(cmd, "%s %s", cmd, argv[i]); - sprintf(cmd,"%s -stopserver -port %d &", cmd, portno + 1); + for (i = 0; i < argc; ++i) { + if (!strcasecmp(argv[i], "-port")) { + i +=2; + continue; + } + if (i > 0) { + strcat(cmd, " "); + } + strcat(cmd, argv[i]); + } + char temp[50]; + memset(temp, 0, sizeof(temp)); + sprintf(temp, " -stopserver -port %d &", portno + 1); + strcat(cmd, temp); + LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd)); system(cmd); } + LOG(logINFOBLUE, ("Control Server [%d]\n", portno)); +#ifdef VIRTUAL + // creating files for virtual servers to communicate with each other + if (!ComVirtual_createFiles(portno)) { + return -1; + } +#endif +#endif + } + // stop server + else { + LOG(logINFOBLUE, ("Stop Server [%d]\n", portno)); +#ifdef VIRTUAL + ComVirtual_setFileNames(portno - 1); #endif - } else { - LOG(logINFO,("Opening stop server on port %d \n", portno)); } + init_detector(); - - { // bind socket - sockfd = bindSocket(portno); - if (ret == FAIL) - return -1; - } - + // bind socket + sockfd = bindSocket(portno); + if (ret == FAIL) + return -1; // assign function table function_table(); if (isControlServer) { LOG(logINFOBLUE, ("Control Server Ready...\n\n")); } else { - LOG(logINFO, ("Stop Server Ready...\n\n")); + LOG(logINFOBLUE, ("Stop Server Ready...\n\n")); } // waits for connection + int retval = OK; while(retval != GOODBYE && retval != REBOOT) { - fd = acceptConnection(sockfd); + int fd = acceptConnection(sockfd); if (fd > 0) { retval = decode_function(fd); closeConnection(fd); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index fa3fb4ab8..8700b6493 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -108,7 +108,6 @@ const char* getRetName() { switch(ret) { case OK: return "OK"; case FAIL: return "FAIL"; - case FORCE_UPDATE: return "FORCE_UPDATE"; case GOODBYE: return "GOODBYE"; case REBOOT: return "REBOOT"; default: return "unknown"; @@ -194,7 +193,6 @@ const char* getFunctionName(enum detFuncs func) { 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"; - case F_UPDATE_CLIENT: return "F_UPDATE_CLIENT"; case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA"; case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS"; case F_SET_PATTERN_IO_CONTROL: return "F_SET_PATTERN_IO_CONTROL"; @@ -317,6 +315,7 @@ const char* getFunctionName(enum detFuncs func) { case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE"; case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE"; case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS"; + case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION"; default: return "Unknown Function"; } @@ -387,7 +386,6 @@ void function_table() { flist[F_LOCK_SERVER] = &lock_server; flist[F_GET_LAST_CLIENT_IP] = &get_last_client_ip; flist[F_SET_PORT] = &set_port; - flist[F_UPDATE_CLIENT] = &update_client; flist[F_ENABLE_TEN_GIGA] = &enable_ten_giga; flist[F_SET_ALL_TRIMBITS] = &set_all_trimbits; flist[F_SET_PATTERN_IO_CONTROL] = &set_pattern_io_control; @@ -510,6 +508,7 @@ void function_table() { flist[F_GET_TIMING_SOURCE] = &get_timing_source; flist[F_SET_TIMING_SOURCE] = &set_timing_source; flist[F_GET_NUM_CHANNELS] = &get_num_channels; + flist[F_UPDATE_RATE_CORRECTION] = &update_rate_correction; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -776,10 +775,10 @@ int set_image_test_mode(int file_des) { return printSocketReadError(); LOG(logDEBUG1, ("Setting image test mode to \n", arg)); -#ifndef GOTTHARDD - functionNotImplemented(); -#else +#if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL)) setTestImageMode(arg); +#else + functionNotImplemented(); #endif return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); } @@ -790,11 +789,11 @@ int get_image_test_mode(int file_des) { int retval = -1; LOG(logDEBUG1, ("Getting image test mode\n")); -#ifndef GOTTHARDD - functionNotImplemented(); -#else +#if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL)) retval = getTestImageMode(); LOG(logDEBUG1, ("image test mode retval: %d\n", retval)); +#else + functionNotImplemented(); #endif return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } @@ -1844,7 +1843,8 @@ int start_acquisition(int file_des) { #endif if (configured == FAIL) { ret = FAIL; - sprintf(mess, "Could not start acquisition because %s\n", configureMessage); + strcpy(mess, "Could not start acquisition because "); + strcat(mess, configureMessage); LOG(logERROR,(mess)); } else { ret = startStateMachine(); @@ -1979,7 +1979,8 @@ int start_and_read_all(int file_des) { #endif if (configured == FAIL) { ret = FAIL; - sprintf(mess, "Could not start acquisition because %s\n", configureMessage); + strcpy(mess, "Could not start acquisition because "); + strcat(mess, configureMessage); LOG(logERROR,(mess)); } else { ret = startStateMachine(); @@ -2826,107 +2827,6 @@ int set_port(int file_des) { } - - -int update_client(int file_des) { - ret = FORCE_UPDATE; - memset(mess, 0, sizeof(mess)); - Server_SendResult(file_des, INT32, NO_UPDATE, NULL, 0); - return send_update(file_des); -} - - - - -int send_update(int file_des) { - ret = OK; - int n = 0; - int i32 = -1; - int64_t i64 = -1; - - i32 = lastClientIP; - i32 = __builtin_bswap32(i32); - n = sendData(file_des, &i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); - - // dr - i32 = setDynamicRange(GET_FLAG); - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); - - // settings -#if defined(EIGERD) || defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(GOTTHARD2D)|| defined(MOENCHD) - i32 = (int)getSettings(); - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); -#endif - - // #frames - i64 = getNumFrames(); - n = sendData(file_des,&i64,sizeof(i64),INT64); - if (n < 0) return printSocketReadError(); - - // #storage cell -#ifdef JUNGFRAUD - i64 = getNumAdditionalStorageCells(); - n = sendData(file_des,&i64,sizeof(i64),INT64); - if (n < 0) return printSocketReadError(); -#endif - - // #triggers - i64 = getNumTriggers(); - n = sendData(file_des,&i64,sizeof(i64),INT64); - if (n < 0) return printSocketReadError(); - - // #bursts -#ifdef GOTTHARD2D - i64 = getNumBursts(); - n = sendData(file_des,&i64,sizeof(i64),INT64); - if (n < 0) return printSocketReadError(); -#endif - - // timing mode - i32 = (int)getTiming(); - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); - - // burst mode -#ifdef GOTTHARD2D - i32 = (int)getBurstMode(); - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); -#endif - - // number of channels -#if defined(MOENCHD) || defined(CHIPTESTBOARDD) - { - int nx = 0, ny = 0; - getNumberOfChannels(&nx, &ny); - i32 = nx; - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); - i32 = ny; - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); - } -#endif - - // num udp interfaces -#ifdef JUNGFRAUD - i32 = getNumberofUDPInterfaces(); - n = sendData(file_des,&i32,sizeof(i32),INT32); - if (n < 0) return printSocketReadError(); -#endif - - if (lockStatus == 0) { - lastClientIP = thisClientIP; - } - - return ret; -} - - - int enable_ten_giga(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -3496,35 +3396,13 @@ int set_rate_correct(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - - int dr = setDynamicRange(-1); - - // switching on in wrong bit mode - if ((tau_ns != 0) && (dr != 32) && (dr != 16)) { - ret = FAIL; - strcpy(mess,"Rate correction Deactivated, must be in 32 or 16 bit mode\n"); - LOG(logERROR,(mess)); - } - - // switching on in right mode - else { - if (tau_ns < 0) { - tau_ns = getDefaultSettingsTau_in_nsec(); - if (tau_ns < 0) { - ret = FAIL; - strcpy(mess,"Default settings file not loaded. No default tau yet\n"); - LOG(logERROR,(mess)); - } - } - else if (tau_ns > 0) { - //changing tau to a user defined value changes settings to undefined - setSettings(UNDEFINED); - LOG(logERROR, ("Settings has been changed to undefined (tau changed)\n")); - } - if (ret == OK) { - int64_t retval = setRateCorrection(tau_ns); - validate64(tau_ns, retval, "set rate correction", DEC); - } + ret = validateAndSetRateCorrection(tau_ns, mess); + int64_t retval = getCurrentTau(); // to update eiger_tau_ns (for update rate correction) + if (ret == FAIL) { + strcpy(mess, "Rate correction failed\n"); + LOG(logERROR, (mess)); + } else { + validate64(tau_ns, retval, "set rate correction", DEC); } } #endif @@ -3920,7 +3798,6 @@ int reset_fpga(int file_des) { initControlServer(); } else initStopServer(); //remapping of stop server - ret = FORCE_UPDATE; } #endif return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); @@ -4352,7 +4229,11 @@ int copy_detector_server(int file_des) { memset(cmd, 0, MAX_STR_LENGTH); // copy server - sprintf(cmd, "tftp %s -r %s -g", hostname, sname); + strcpy(cmd, "tftp "); + strcat(cmd, hostname); + strcat(cmd, " -r "); + strcat(cmd, sname); + strcat(cmd, " -g"); int success = executeCommand(cmd, retvals, logDEBUG1); if (success == FAIL) { ret = FAIL; @@ -4364,7 +4245,8 @@ int copy_detector_server(int file_des) { else { LOG(logINFO, ("Server copied successfully\n")); // give permissions - sprintf(cmd, "chmod 777 %s", sname); + strcpy(cmd, "chmod 777 "); + strcat(cmd, sname); executeCommand(cmd, retvals, logDEBUG1); // edit /etc/inittab @@ -4384,7 +4266,9 @@ int copy_detector_server(int file_des) { LOG(logINFO, ("Deleted all lines containing DetectorServer in /etc/inittab\n")); // append line - sprintf(cmd, "echo \"ttyS0::respawn:/./%s\" >> /etc/inittab", sname); + strcpy(cmd, "echo \"ttyS0::respawn:/./"); + strcat(cmd, sname); + strcat(cmd, "\" >> /etc/inittab"); executeCommand(cmd, retvals, logDEBUG1); LOG(logINFO, ("/etc/inittab modified to have %s\n", sname)); @@ -5795,9 +5679,11 @@ int set_clock_frequency(int file_des) { case ADC_CLOCK: c = ADC_CLK; break; +#ifdef CHIPTESTBOARDD case DBIT_CLOCK: c = DBIT_CLK; break; +#endif case RUN_CLOCK: c = RUN_CLK; break; @@ -5851,9 +5737,11 @@ int get_clock_frequency(int file_des) { case ADC_CLOCK: c = ADC_CLK; break; +#ifdef CHIPTESTBOARDD case DBIT_CLOCK: c = DBIT_CLK; break; +#endif case RUN_CLOCK: c = RUN_CLK; break; @@ -5907,14 +5795,14 @@ int set_clock_phase(int file_des) { c = ADC_CLK; break; #endif -#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(JUNGFRAUD) +#if defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) case DBIT_CLOCK: c = DBIT_CLK; break; #endif default: #if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (c < NUM_CLOCKS) { + if (ind < NUM_CLOCKS) { c = (enum CLKINDEX)ind; break; } @@ -5986,7 +5874,7 @@ int get_clock_phase(int file_des) { if (receiveData(file_des, args, sizeof(args), INT32) < 0) return printSocketReadError(); - LOG(logDEBUG1, ("Getting clock (%d) phase %s \n", args[0], (args[1] == 0 ? "" : "in degrees"))); + LOG(logINFOBLUE, ("Getting clock (%d) phase %s \n", args[0], (args[1] == 0 ? "" : "in degrees"))); #if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(JUNGFRAUD) && !defined(GOTTHARD2D) && !defined(MYTHEN3D) functionNotImplemented(); @@ -6000,14 +5888,17 @@ int get_clock_phase(int file_des) { case ADC_CLOCK: c = ADC_CLK; break; +#endif +#if defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) case DBIT_CLOCK: c = DBIT_CLK; break; #endif default: #if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (c < NUM_CLOCKS) { + if (ind < NUM_CLOCKS) { c = (enum CLKINDEX)ind; + LOG(logINFOBLUE, ("NUMclocks:%d c:%d\n", NUM_CLOCKS, c)); break; } #endif @@ -6044,13 +5935,15 @@ int get_max_clock_phase_shift(int file_des) { case ADC_CLOCK: c = ADC_CLK; break; +#endif +#if defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) case DBIT_CLOCK: c = DBIT_CLK; break; #endif default: #if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (c < NUM_CLOCKS) { + if (arg < NUM_CLOCKS) { c = (enum CLKINDEX)arg; break; } @@ -6095,7 +5988,7 @@ int set_clock_divider(int file_des) { default: // any clock index #if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (c < NUM_CLOCKS) { + if (ind < NUM_CLOCKS) { c = (enum CLKINDEX)ind; break; } @@ -6178,7 +6071,7 @@ int get_clock_divider(int file_des) { #endif default: #if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (c < NUM_CLOCKS) { + if (arg < NUM_CLOCKS) { c = (enum CLKINDEX)arg; break; } @@ -6263,9 +6156,11 @@ int get_pipeline(int file_des) { case ADC_CLOCK: c = ADC_CLK; break; +#ifdef CHIPTESTBOARDD case DBIT_CLOCK: c = DBIT_CLK; break; +#endif default: modeNotImplemented("clock index (pipeline get)", arg); break; @@ -6910,4 +6805,22 @@ int get_num_channels(int file_des) { LOG(logDEBUG1, ("Get number of channels sretval:[%d, %d]\n", retvals[0], retvals[1])); #endif return Server_SendResult(file_des, INT32, UPDATE, retvals, sizeof(retvals)); +} + + + +int update_rate_correction(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + +#ifndef EIGERD + functionNotImplemented(); +#else + LOG(logINFO, ("Update Rate Correction\n")); + // only set + if (Server_VerifyLock() == OK) { + ret = updateRateCorrection(mess); + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); } \ No newline at end of file diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index cc08a6ff9..692711507 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -5,6 +5,7 @@ #include #include #include +#include class detectorData; @@ -137,6 +138,16 @@ class Detector { void *), void *pArg); + /**[Eiger][Jungfrau] */ + bool getGapPixelsinCallback() const; + + /** + * [Eiger][Jungfrau] + * Only in client data call back + * Fills in gap pixels in data + */ + void setGapPixelsinCallback(const bool enable); + /************************************************** * * * Acquisition Parameters * @@ -255,12 +266,6 @@ class Detector { Result getHighVoltage(Positions pos = {}) const; - /** [Jungfrau][Mythen3][Gotthard2][Moench] */ - Result getPowerChip(Positions pos = {}) const; - - /** [Jungfrau][Mythen3][Gotthard2][Moench] */ - void setPowerChip(bool on, Positions pos = {}); - /** * [Gotthard] Options: 0, 90, 110, 120, 150, 180, 200 * [Jungfrau][CTB][Moench] Options: 0, 60 - 200 @@ -268,6 +273,21 @@ class Detector { */ void setHighVoltage(int value, Positions pos = {}); + /** [Jungfrau][Mythen3][Gotthard2][Moench] */ + Result getPowerChip(Positions pos = {}) const; + + /** [Jungfrau][Mythen3][Gotthard2][Moench] */ + void setPowerChip(bool on, Positions pos = {}); + + /** [Gotthard][Eiger virtual] */ + Result getImageTestMode(Positions pos = {}); + + /** [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, Positions pos = {}); + /** * (Degrees) * [Gotthard] Options: TEMPERATURE_ADC, TEMPERATURE_FPGA @@ -694,16 +714,6 @@ class Detector { /** [Eiger] */ void loadTrimbits(const std::string &fname, Positions pos = {}); - /**[Eiger] */ - Result getRxAddGapPixels(Positions pos = {}) const; - - /** - * [Eiger] - * 4 bit mode not implemented in Receiver, but in client data call back - * Fills in gap pixels in data - */ - void setRxAddGapPixels(bool enable); - /** [Eiger] */ Result getParallelMode(Positions pos = {}) const; @@ -905,12 +915,6 @@ class Detector { void setExternalSignalFlags(defs::externalSignalFlag value, Positions pos = {}); - /** [Gotthard] */ - Result getImageTestMode(Positions pos = {}); - - /** [Gotthard] If 1, adds channel intensity with precalculated values. - * Default is 0 */ - void setImageTestMode(const int value, Positions pos = {}); /************************************************** * * @@ -1196,10 +1200,10 @@ class Detector { * ************************************************/ /** [Moench] */ - Result getAdditionalJsonHeader(Positions pos = {}) const; + Result> getAdditionalJsonHeader(Positions pos = {}) const; - /** [Moench] */ - void setAdditionalJsonHeader(const std::string &jsonheader, + /** [Moench] If empty, reset additional json header. Max 20 characters for each key/value */ + void setAdditionalJsonHeader(const std::map &jsonHeader, Positions pos = {}); /** [Moench] */ @@ -1207,12 +1211,11 @@ class Detector { Positions pos = {}) const; /** * [Moench] - * Sets the value for additional json header parameter if found, + * Sets the value for additional json header parameters if found, * else appends the parameter key and value - * The value cannot be empty + * If empty, deletes parameter. Max 20 characters for each key/value */ - void setAdditionalJsonParameter(const std::string &key, - const std::string &value, + void setAdditionalJsonParameter(const std::string &key, const std::string &value, Positions pos = {}); /** [Moench] TODO! How do we do this best??? Can be refactored to something diff --git a/slsDetectorSoftware/include/detectorData.h b/slsDetectorSoftware/include/detectorData.h index 528def82d..6e6b912e3 100755 --- a/slsDetectorSoftware/include/detectorData.h +++ b/slsDetectorSoftware/include/detectorData.h @@ -16,9 +16,10 @@ class detectorData { * @param dbytes number of bytes of image pointed to by cval pointer * @param dr dynamic range or bits per pixel * @param fIndex file index + * @param complete true if complete image, else missing packets */ - detectorData(double progress, std::string fname, int x, int y, char *d, int dbytes, int dr, uint64_t fIndex) : - progressIndex(progress), fileName(fname), fileIndex(fIndex), nx(x), ny(y), data(d), databytes(dbytes), dynamicRange(dr) {}; + detectorData(double progress, std::string fname, int x, int y, char *d, int dbytes, int dr, uint64_t fIndex, bool complete) : + progressIndex(progress), fileName(fname), fileIndex(fIndex), nx(x), ny(y), data(d), databytes(dbytes), dynamicRange(dr), completeImage(complete) {}; /** * Destructor @@ -55,4 +56,5 @@ class detectorData { char* data; int databytes; int dynamicRange; + bool completeImage; }; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 1822478fe..1c578757e 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -314,7 +314,7 @@ std::string CmdProxy::DetectorSize(int action) { WrongNumberOfParameters(0); } auto t = det->getDetectorSize(); - os << "[" << t.x << "," << t.y << "]\n"; + os << "[" << t.x << ", " << t.y << "]\n"; } else if (action == defs::PUT_ACTION) { if (args.size() != 2) { WrongNumberOfParameters(2); @@ -402,37 +402,45 @@ std::string CmdProxy::Adcphase(int action) { "resets adcphase and sets it to previous values.\n\t[Gotthard] " "Relative phase shift" << '\n'; - } else if (action == defs::GET_ACTION) { - Result t; - if (args.empty()) { - t = det->getADCPhase({det_id}); - os << OutString(t) << '\n'; - } else if (args.size() == 1) { - if (args[0] != "deg") { - throw sls::RuntimeError("Unknown adcphase argument " + args[0] + - ". Did you mean deg?"); + } else { + auto det_type = det->getDetectorType().squash(defs::GENERIC); + if (det_type == defs::EIGER || + det_type == defs::MYTHEN3 || + det_type == defs::GOTTHARD2) { + throw sls::RuntimeError("adcphase not implemented for this detector"); } - t = det->getADCPhaseInDegrees({det_id}); - os << OutString(t) << " deg\n"; - } else { - WrongNumberOfParameters(0); - } - } else if (action == defs::PUT_ACTION) { - if (args.size() == 1) { - det->setADCPhase(StringTo(args[0]), {det_id}); - os << args.front() << '\n'; - } else if (args.size() == 2) { - if (args[1] != "deg") { - throw sls::RuntimeError("Unknown adcphase 2nd argument " + - args[1] + ". Did you mean deg?"); + if (action == defs::GET_ACTION) { + Result t; + if (args.empty()) { + t = det->getADCPhase({det_id}); + os << OutString(t) << '\n'; + } else if (args.size() == 1) { + if (args[0] != "deg") { + throw sls::RuntimeError("Unknown adcphase argument " + args[0] + + ". Did you mean deg? "); + } + t = det->getADCPhaseInDegrees({det_id}); + os << OutString(t) << " deg\n"; + } else { + WrongNumberOfParameters(0); + } + } else if (action == defs::PUT_ACTION) { + if (args.size() == 1) { + det->setADCPhase(StringTo(args[0]), {det_id} ); + os << args.front() << '\n'; + } else if (args.size() == 2) { + if (args[1] != "deg") { + throw sls::RuntimeError("Unknown adcphase 2nd argument " + + args[1] + ". Did you mean deg?"); + } + det->setADCPhaseInDegrees(StringTo(args[0]) , {det_id}); + os << args[0] << " " << args[1] << '\n'; + } else { + WrongNumberOfParameters(1); } - det->setADCPhaseInDegrees(StringTo(args[0]), {det_id}); - os << args[0] << args[1] << '\n'; } else { - WrongNumberOfParameters(1); + throw sls::RuntimeError("Unknown action"); } - } else { - throw sls::RuntimeError("Unknown action"); } return os.str(); } @@ -446,37 +454,45 @@ std::string CmdProxy::Dbitphase(int action) { "shift in degrees. \n\t[Ctb]Changing dbitclk also resets dbitphase and " "sets to previous values." << '\n'; - } else if (action == defs::GET_ACTION) { - Result t; - if (args.empty()) { - t = det->getDBITPhase({det_id}); - os << OutString(t) << '\n'; - } else if (args.size() == 1) { - if (args[0] != "deg") { - throw sls::RuntimeError("Unknown dbitphase argument " + - args[0] + ". Did you mean deg?"); - } - t = det->getDBITPhaseInDegrees({det_id}); - os << OutString(t) << " deg\n"; - } else { - WrongNumberOfParameters(0); + } else { + auto det_type = det->getDetectorType().squash(defs::GENERIC); + if (det_type == defs::EIGER || + det_type == defs::MYTHEN3 || + det_type == defs::GOTTHARD2) { + throw sls::RuntimeError("dbitphase not implemented for this detector"); } - } else if (action == defs::PUT_ACTION) { - if (args.size() == 1) { - det->setDBITPhase(StringTo(args[0]), {det_id}); - os << args.front() << '\n'; - } else if (args.size() == 2) { - if (args[1] != "deg") { - throw sls::RuntimeError("Unknown dbitphase 2nd argument " + - args[1] + ". Did you mean deg?"); + if (action == defs::GET_ACTION) { + Result t; + if (args.empty()) { + t = det->getDBITPhase({det_id}); + os << OutString(t) << '\n'; + } else if (args.size() == 1) { + if (args[0] != "deg") { + throw sls::RuntimeError("Unknown dbitphase argument " + + args[0] + ". Did you mean deg? "); + } + t = det->getDBITPhaseInDegrees({det_id}); + os << OutString(t) << " deg\n"; + } else { + WrongNumberOfParameters(0); + } + } else if (action == defs::PUT_ACTION) { + if (args.size() == 1) { + det->setDBITPhase(StringTo(args[0]), {det_id}); + os << args.front() << '\n'; + } else if (args.size() == 2) { + if (args[1] != "deg") { + throw sls::RuntimeError("Unknown dbitphase 2nd argument " + + args[1] + ". Did you mean deg? "); + } + det->setDBITPhaseInDegrees(StringTo(args[0]), {det_id} ); + os << args[0] << " " << args[1] << '\n'; + } else { + WrongNumberOfParameters(1); } - det->setDBITPhaseInDegrees(StringTo(args[0]), {det_id}); - os << args[0] << args[1] << '\n'; } else { - WrongNumberOfParameters(1); + throw sls::RuntimeError("Unknown action"); } - } else { - throw sls::RuntimeError("Unknown action"); } return os.str(); } @@ -538,7 +554,7 @@ std::string CmdProxy::ClockPhase(int action) { } auto t = det->getClockPhaseinDegrees(StringTo(args[0]), {det_id}); - os << OutString(t) << '\n'; + os << OutString(t) << " deg\n"; } else { WrongNumberOfParameters(1); } @@ -554,7 +570,7 @@ std::string CmdProxy::ClockPhase(int action) { } det->setClockPhaseinDegrees(StringTo(args[0]), StringTo(args[1]), {det_id}); - os << args[1] << '\n'; + os << args[1] << " " << args[2] << '\n'; } else { WrongNumberOfParameters(1); } @@ -769,6 +785,47 @@ std::vector CmdProxy::DacCommands() { } /* acquisition */ + +std::string CmdProxy::ReceiverStatus(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "running, idle]\n\tReceiver listener status." + << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 0) { + WrongNumberOfParameters(0); + } + auto t = det->getReceiverStatus({det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + throw sls::RuntimeError("Cannot put. Did you mean to use command 'rx_start' or 'rx_stop'?"); + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + +std::string CmdProxy::DetectorStatus(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[running, error, transmitting, finished, waiting, idle]\n\tDetector status." + << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 0) { + WrongNumberOfParameters(0); + } + auto t = det->getDetectorStatus({det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + throw sls::RuntimeError("Cannot put. Did you mean to use command 'start' or 'stop'?"); + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + /* Network Configuration (Detector<->Receiver) */ std::string CmdProxy::UDPDestinationIP(int action) { @@ -1001,24 +1058,27 @@ std::string CmdProxy::GapPixels(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[0, 1]\n\t[Eiger] Include Gap pixels in data file or data call " - "back. 4 bit mode gap pixels only ind ata call back." + os << "[0, 1]\n\t[Eiger][Jungfrau] Include Gap pixels only in data call back." << '\n'; } else if (action == defs::GET_ACTION) { + if (det_id != -1) { + throw sls::RuntimeError( + "Cannot get gap pixels at module level"); + } if (!args.empty()) { WrongNumberOfParameters(0); } - auto t = det->getRxAddGapPixels({det_id}); - os << OutString(t) << '\n'; + auto t = det->getGapPixelsinCallback(); + os << t << '\n'; } else if (action == defs::PUT_ACTION) { if (det_id != -1) { throw sls::RuntimeError( - "Cannot execute dynamic range at module level"); + "Cannot add gap pixels at module level"); } if (args.size() != 1) { WrongNumberOfParameters(1); } - det->setRxAddGapPixels(StringTo(args[0])); + det->setGapPixelsinCallback(StringTo(args[0])); os << args.front() << '\n'; } else { throw sls::RuntimeError("Unknown action"); @@ -1224,7 +1284,7 @@ std::string CmdProxy::Quad(int action) { } else if (action == defs::PUT_ACTION) { if (det_id != -1) { throw sls::RuntimeError( - "Cannot execute dynamic range at module level"); + "Cannot execute quad at module level"); } if (args.size() != 1) { WrongNumberOfParameters(1); @@ -1879,13 +1939,47 @@ std::string CmdProxy::PatternWaitTime(int action) { /* Moench */ +std::string CmdProxy::AdditionalJsonHeader(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[key1] [value1] [key2] [value2]...[keyn] [valuen]" + "\n\tAdditional json header to be streamed out from receiver via zmq. " + "Default is empty. Use only if to be processed by an intermediate user process " + "listening to receiver zmq packets. Empty value deletes header. " + << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 0) { + WrongNumberOfParameters(0); + } + auto t = det->getAdditionalJsonHeader({det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + // arguments can be empty + std::map json; + for (size_t i = 0; i < args.size(); i = i + 2) { + // last value is empty + if (i + 1 >= args.size()) { + json[args[i]] = ""; + } else { + json[args[i]] = args[i + 1]; + } + } + det->setAdditionalJsonHeader(json, {det_id}); + os << sls::ToString(json) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + std::string CmdProxy::JsonParameter(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { os << "[key1] [value1]\n\tAdditional json header parameter streamed " - "out from receiver. If empty in a get, then no parameter found. " - "This is same as calling rx_jsonaddheader \"key\":\"value1\"." + "out from receiver. If not found in header, the pair is appended. " + "An empty values deletes parameter." << '\n'; } else if (action == defs::GET_ACTION) { if (args.size() != 1) { @@ -1894,11 +1988,21 @@ std::string CmdProxy::JsonParameter(int action) { auto t = det->getAdditionalJsonParameter(args[0], {det_id}); os << OutString(t) << '\n'; } else if (action == defs::PUT_ACTION) { - if (args.size() != 2) { - WrongNumberOfParameters(2); + switch (args.size()) { + case 1: + det->setAdditionalJsonParameter(args[0], "", {det_id}); + break; + case 2: + det->setAdditionalJsonParameter(args[0], args[1], {det_id}); + break; + default: + WrongNumberOfParameters(1); + } + if (args.size() == 1) { + os << args[0] << " deleted" << '\n'; + } else { + os << "{" << args[0] << ": " << args[1] << "}" << '\n'; } - det->setAdditionalJsonParameter(args[0], args[1], {det_id}); - os << sls::ToString(args) << '\n'; } else { throw sls::RuntimeError("Unknown action"); } diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index eb6ad61e8..bc48de4ba 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -477,6 +477,7 @@ class CmdProxy { {"cycles", "triggers"}, {"cyclesl", "triggersl"}, {"clkdivider", "speed"}, + {"digitest", "imagetest"}, /** temperature */ /** dacs */ @@ -527,8 +528,6 @@ class CmdProxy { /* Jungfrau Specific */ /* Gotthard Specific */ - {"digitest", "imagetest"}, - /* Gotthard2 Specific */ /* Mythen3 Specific */ /* CTB Specific */ @@ -572,11 +571,9 @@ class CmdProxy { {"acquire", &CmdProxy::acquire}, {"frames", &CmdProxy::frames}, {"triggers", &CmdProxy::triggers}, - {"bursts", &CmdProxy::bursts}, {"exptime", &CmdProxy::exptime}, {"period", &CmdProxy::period}, {"delay", &CmdProxy::delay}, - {"burstperiod", &CmdProxy::burstperiod}, {"framesl", &CmdProxy::framesl}, {"triggersl", &CmdProxy::triggersl}, {"delayl", &CmdProxy::delayl}, @@ -593,6 +590,7 @@ class CmdProxy { {"clkdiv", &CmdProxy::ClockDivider}, {"vhighvoltage", &CmdProxy::vhighvoltage}, {"powerchip", &CmdProxy::powerchip}, + {"imagetest", &CmdProxy::imagetest}, /** temperature */ {"temp_adc", &CmdProxy::temp_adc}, @@ -693,8 +691,8 @@ class CmdProxy { {"rx_stop", &CmdProxy::rx_stop}, {"start", &CmdProxy::start}, {"stop", &CmdProxy::stop}, - {"rx_status", &CmdProxy::rx_status}, - {"status", &CmdProxy::status}, + {"rx_status", &CmdProxy::ReceiverStatus}, + {"status", &CmdProxy::DetectorStatus}, {"rx_framescaught", &CmdProxy::rx_framescaught}, {"rx_missingpackets", &CmdProxy::rx_missingpackets}, {"startingfnum", &CmdProxy::startingfnum}, @@ -791,9 +789,10 @@ class CmdProxy { {"clearroi", &CmdProxy::ClearROI}, {"exptimel", &CmdProxy::exptimel}, {"extsig", &CmdProxy::extsig}, - {"imagetest", &CmdProxy::imagetest}, /* Gotthard2 Specific */ + {"bursts", &CmdProxy::bursts}, + {"burstperiod", &CmdProxy::burstperiod}, {"inj_ch", &CmdProxy::InjectChannel}, {"vetophoton", &CmdProxy::VetoPhoton}, {"vetoref", &CmdProxy::VetoReference}, @@ -867,7 +866,7 @@ class CmdProxy { {"patsetbit", &CmdProxy::patsetbit}, /* Moench */ - {"rx_jsonaddheader", &CmdProxy::rx_jsonaddheader}, + {"rx_jsonaddheader", &CmdProxy::AdditionalJsonHeader}, {"rx_jsonpara", &CmdProxy::JsonParameter}, {"emin", &CmdProxy::MinMaxEnergyThreshold}, {"emax", &CmdProxy::MinMaxEnergyThreshold}, @@ -935,6 +934,8 @@ class CmdProxy { std::string DacValues(int action); std::vector DacCommands(); /* acquisition */ + std::string ReceiverStatus(int action); + std::string DetectorStatus(int action); /* Network Configuration (Detector<->Receiver) */ std::string UDPDestinationIP(int action); std::string UDPDestinationIP2(int action); @@ -980,6 +981,7 @@ class CmdProxy { std::string PatternWaitAddress(int action); std::string PatternWaitTime(int action); /* Moench */ + std::string AdditionalJsonHeader(int action); std::string JsonParameter(int action); std::string MinMaxEnergyThreshold(int action); /* Advanced */ @@ -1036,10 +1038,6 @@ class CmdProxy { StringTo, "[n_triggers]\n\tNumber of triggers per aquire. Use timing command to set timing mode."); - INTEGER_COMMAND_NOID(bursts, getNumberOfBursts, setNumberOfBursts, - StringTo, - "[n_bursts]\n\t[Gotthard2] Number of bursts per aquire. Only in auto timing mode and burst mode. Use timing command to set timing mode and burstmode command to set burst mode."); - TIME_COMMAND(exptime, getExptime, setExptime, "[duration] [(optional unit) ns|us|ms|s]\n\tExposure time" "\n\t[Gotthard2] Uploaded to detector just before acquisition starts"); @@ -1092,6 +1090,10 @@ class CmdProxy { "\n\t[Mythen3] If module not connected or wrong module, 1 will fail. By default, not powered on" "\n\t[Gotthard2] If module not connected or wrong module, 1 will fail. By default, powered on at server start up."); + INTEGER_COMMAND(imagetest, getImageTestMode, setImageTestMode, StringTo, + "[0, 1]\n\t[Gotthard] 1 adds channel intensity with precalculated values when taking an acquisition. Default is 0." + "\n\t[Eiger][Jungfrau] Only for Virtual servers. If 0, each pixel intensity incremented by 1. If 1, all pixels almost saturated."); + /** temperature */ GET_IND_COMMAND(temp_adc, getTemperature, slsDetectorDefs::TEMPERATURE_ADC, " °C", @@ -1363,12 +1365,6 @@ class CmdProxy { EXECUTE_SET_COMMAND_NOID(stop, stopDetector, "\n\tStops detector state machine."); - GET_COMMAND(rx_status, getReceiverStatus, - "running, idle]\n\tReceiver listener status."); - - GET_COMMAND(status, getDetectorStatus, - "[running, error, transmitting, finished, waiting, idle]\n\tDetector status."); - GET_COMMAND(rx_framescaught, getFramesCaught, "\n\tNumber of frames caught by receiver."); @@ -1586,10 +1582,11 @@ class CmdProxy { INTEGER_COMMAND(extsig, getExternalSignalFlags, setExternalSignalFlags, sls::StringTo, "[trigger_in_rising_edge|trigger_in_falling_edge]\n\t[Gotthard] External signal mode for trigger timing mode."); - INTEGER_COMMAND(imagetest, getImageTestMode, setImageTestMode, StringTo, - "[0, 1]\n\t[Gotthard] 1 adds channel intensity with precalculated values when taking an acquisition. Default is 0."); - /* Gotthard2 Specific */ + INTEGER_COMMAND_NOID(bursts, getNumberOfBursts, setNumberOfBursts, + StringTo, + "[n_bursts]\n\t[Gotthard2] Number of bursts per aquire. Only in auto timing mode and burst mode. Use timing command to set timing mode and burstmode command to set burst mode."); + INTEGER_COMMAND(currentsource, getCurrentSource, setCurrentSource, StringTo, "[0, 1]\n\t[Gotthard2] Enable or disable current source. Default is disabled."); @@ -1719,9 +1716,6 @@ class CmdProxy { /* Moench */ - STRING_COMMAND(rx_jsonaddheader, getAdditionalJsonHeader, setAdditionalJsonHeader, - "[\\\"label1\\\":\\\"value1\\\"], [\\\"label2\\\":\\\"value2\\\"]\n\tAdditional json header to be streamd out from receiver via zmq. Default is empty. Use only if to be processed by an intermediate user process listening to receiver zmq packets."); - INTEGER_COMMAND(framemode, getFrameMode, setFrameMode, sls::StringTo, "[pedestal|newpedestal|flatfield|newflatfield]\n\t[Moench] Frame mode (soft setting) in processor."); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index e2f2088c5..f5bc47b37 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -167,6 +167,14 @@ void Detector::registerDataCallback(void (*func)(detectorData *, uint64_t, pimpl->registerDataCallback(func, pArg); } +bool Detector::getGapPixelsinCallback() const { + return pimpl->getGapPixelsinCallback(); +} + +void Detector::setGapPixelsinCallback(bool enable) { + pimpl->setGapPixelsinCallback(enable); +} + // Acquisition Parameters Result Detector::getNumberOfFrames(Positions pos) const { @@ -226,8 +234,7 @@ Result Detector::getPeriodLeft(Positions pos) const { } Result Detector::getTimingMode(Positions pos) const { - return pimpl->Parallel(&Module::setTimingMode, pos, - defs::GET_TIMING_MODE); + return pimpl->Parallel(&Module::getTimingMode, pos); } void Detector::setTimingMode(defs::timingMode value, Positions pos) { @@ -359,6 +366,14 @@ void Detector::setPowerChip(bool on, Positions pos) { } } +Result Detector::getImageTestMode(Positions pos) { + return pimpl->Parallel(&Module::getImageTestMode, pos); +} + +void Detector::setImageTestMode(int value, Positions pos) { + pimpl->Parallel(&Module::setImageTestMode, pos, value); +} + Result Detector::getTemperature(defs::dacIndex index, Positions pos) const { switch (index) { @@ -907,7 +922,7 @@ void Detector::setClientZmqIp(const IpAddr ip, Positions pos) { // Eiger Specific Result Detector::getDynamicRange(Positions pos) const { - return pimpl->Parallel(&Module::setDynamicRange, pos, -1); + return pimpl->Parallel(&Module::getDynamicRange, pos); } void Detector::setDynamicRange(int value) { @@ -953,14 +968,6 @@ void Detector::loadTrimbits(const std::string &fname, Positions pos) { pimpl->Parallel(&Module::loadSettingsFile, pos, fname); } -Result Detector::getRxAddGapPixels(Positions pos) const { - return pimpl->Parallel(&Module::enableGapPixels, pos, -1); -} - -void Detector::setRxAddGapPixels(bool enable) { - pimpl->setGapPixelsinReceiver(enable); -} - Result Detector::getParallelMode(Positions pos) const { return pimpl->Parallel(&Module::getParallelMode, pos); } @@ -1195,14 +1202,6 @@ void Detector::setExternalSignalFlags(defs::externalSignalFlag value, pimpl->Parallel(&Module::setExternalSignalFlags, pos, value); } -Result Detector::getImageTestMode(Positions pos) { - return pimpl->Parallel(&Module::getImageTestMode, pos); -} - -void Detector::setImageTestMode(int value, Positions pos) { - pimpl->Parallel(&Module::setImageTestMode, pos, value); -} - // Gotthard2 Specific Result Detector::getNumberOfBursts(Positions pos) const { @@ -1612,13 +1611,13 @@ void Detector::setPatternBitMask(uint64_t mask, Positions pos) { // Moench -Result Detector::getAdditionalJsonHeader(Positions pos) const { +Result> Detector::getAdditionalJsonHeader(Positions pos) const { return pimpl->Parallel(&Module::getAdditionalJsonHeader, pos); } -void Detector::setAdditionalJsonHeader(const std::string &jsonheader, +void Detector::setAdditionalJsonHeader(const std::map &jsonHeader, Positions pos) { - pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonheader); + pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonHeader); } Result Detector::getAdditionalJsonParameter(const std::string &key, @@ -1626,8 +1625,7 @@ Result Detector::getAdditionalJsonParameter(const std::string &key, return pimpl->Parallel(&Module::getAdditionalJsonParameter, pos, key); } -void Detector::setAdditionalJsonParameter(const std::string &key, - const std::string &value, +void Detector::setAdditionalJsonParameter(const std::string &key, const std::string &value, Positions pos) { pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, key, value); } diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 42d6713f5..5867b4f4c 100755 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -157,6 +157,7 @@ void DetectorImpl::initializeDetectorStructure() { multi_shm()->numberOfChannels.y = 0; multi_shm()->acquiringFlag = false; multi_shm()->initialChecks = true; + multi_shm()->gapPixels = false; } void DetectorImpl::initializeMembers(bool verify) { @@ -339,17 +340,30 @@ void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) { multi_shm()->numberOfChannels = c; } -void DetectorImpl::setGapPixelsinReceiver(bool enable) { - Parallel(&Module::enableGapPixels, {}, static_cast(enable)); - // update number of channels - Result res = - Parallel(&Module::getNumberOfChannels, {}); - multi_shm()->numberOfChannels.x = 0; - multi_shm()->numberOfChannels.y = 0; - for (auto &it : res) { - multi_shm()->numberOfChannels.x += it.x; - multi_shm()->numberOfChannels.y += it.y; +bool DetectorImpl::getGapPixelsinCallback() const { + return multi_shm()->gapPixels; +} + +void DetectorImpl::setGapPixelsinCallback(const bool enable) { + if (enable) { + switch (multi_shm()->multiDetectorType) { + case JUNGFRAU: + break; + case EIGER: + if (size() && detectors[0]->getQuad()) { + break; + } + if (multi_shm()->numberOfDetector.y % 2 != 0) { + throw RuntimeError("Gap pixels can only be used " + "for full modules."); + } + break; + default: + throw RuntimeError("Gap Pixels is not implemented for " + + multi_shm()->multiDetectorType); + } } + multi_shm()->gapPixels = enable; } int DetectorImpl::createReceivingDataSockets(const bool destroy) { @@ -406,11 +420,13 @@ int DetectorImpl::createReceivingDataSockets(const bool destroy) { void DetectorImpl::readFrameFromReceiver() { + bool gapPixels = multi_shm()->gapPixels; + LOG(logDEBUG) << "Gap pixels: " << gapPixels; + int nX = 0; int nY = 0; int nDetPixelsX = 0; int nDetPixelsY = 0; - bool gappixelsenable = false; bool quadEnable = false; bool eiger = false; bool numInterfaces = @@ -434,6 +450,7 @@ void DetectorImpl::readFrameFromReceiver() { } int numConnected = numRunning; bool data = false; + bool completeImage = false; char *image = nullptr; char *multiframe = nullptr; char *multigappixels = nullptr; @@ -445,6 +462,7 @@ void DetectorImpl::readFrameFromReceiver() { std::string currentFileName; uint64_t currentAcquisitionIndex = -1, currentFrameIndex = -1, currentFileIndex = -1; + int currentProgress = -1; uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1, flippedDataX = -1; @@ -461,6 +479,7 @@ void DetectorImpl::readFrameFromReceiver() { if (multiframe != nullptr) { memset(multiframe, 0xFF, multisize); } + completeImage = true; // get each frame for (unsigned int isocket = 0; isocket < zmqSocket.size(); ++isocket) { @@ -470,9 +489,9 @@ void DetectorImpl::readFrameFromReceiver() { // HEADER { - rapidjson::Document doc; + zmqHeader zHeader; if (zmqSocket[isocket]->ReceiveHeader( - isocket, doc, SLS_DETECTOR_JSON_HEADER_VERSION) == + isocket, zHeader, SLS_DETECTOR_JSON_HEADER_VERSION) == 0) { // parse error, version error or end of acquisition for // socket @@ -484,33 +503,29 @@ void DetectorImpl::readFrameFromReceiver() { // if first message, allocate (all one time stuff) if (image == nullptr) { // allocate - size = doc["size"].GetUint(); + size = zHeader.imageSize; multisize = size * zmqSocket.size(); image = new char[size]; multiframe = new char[multisize]; memset(multiframe, 0xFF, multisize); // dynamic range - dynamicRange = doc["bitmode"].GetUint(); + dynamicRange = zHeader.dynamicRange; bytesPerPixel = (float)dynamicRange / 8; // shape - nPixelsX = doc["shape"][0].GetUint(); - nPixelsY = doc["shape"][1].GetUint(); + nPixelsX = zHeader.npixelsx; + nPixelsY = zHeader.npixelsy; // detector shape - nX = doc["detshape"][0].GetUint(); - nY = doc["detshape"][1].GetUint(); + nX = zHeader.ndetx; + nY = zHeader.ndety; nY *= numInterfaces; nDetPixelsX = nX * nPixelsX; nDetPixelsY = nY * nPixelsY; // det type - eiger = - (doc["detType"].GetUint() == static_cast(3)) + eiger = (zHeader.detType == static_cast(3)) ? true : false; // to be changed to EIGER when firmware // updates its header data - gappixelsenable = - (doc["gappixels"].GetUint() == 0) ? false : true; - quadEnable = - (doc["quad"].GetUint() == 0) ? false : true; + quadEnable = (zHeader.quad == 0) ? false : true; LOG(logDEBUG1) << "One Time Header Info:" "\n\tsize: " @@ -520,21 +535,24 @@ void DetectorImpl::readFrameFromReceiver() { << "\n\tnPixelsX: " << nPixelsX << "\n\tnPixelsY: " << nPixelsY << "\n\tnX: " << nX << "\n\tnY: " << nY << "\n\teiger: " << eiger - << "\n\tgappixelsenable: " << gappixelsenable << "\n\tquadEnable: " << quadEnable; } // each time, parse rest of header - currentFileName = doc["fname"].GetString(); - currentAcquisitionIndex = doc["acqIndex"].GetUint64(); - currentFrameIndex = doc["fIndex"].GetUint64(); - currentFileIndex = doc["fileIndex"].GetUint64(); - currentSubFrameIndex = doc["expLength"].GetUint(); - coordY = doc["row"].GetUint(); - coordX = doc["column"].GetUint(); + currentFileName = zHeader.fname; + currentAcquisitionIndex = zHeader.acqIndex; + currentFrameIndex = zHeader.frameIndex; + currentProgress = zHeader.progress; + currentFileIndex = zHeader.fileIndex; + currentSubFrameIndex = zHeader.expLength; + coordY = zHeader.row; + coordX = zHeader.column; if (eiger) { coordY = (nY - 1) - coordY; } - flippedDataX = doc["flippedDataX"].GetUint(); + flippedDataX = zHeader.flippedDataX; + if (zHeader.completeImage == 0) { + completeImage = false; + } LOG(logDEBUG1) << "Header Info:" "\n\tcurrentFileName: " @@ -543,13 +561,16 @@ void DetectorImpl::readFrameFromReceiver() { << "\n\tcurrentFrameIndex: " << currentFrameIndex << "\n\tcurrentFileIndex: " << currentFileIndex << "\n\tcurrentSubFrameIndex: " << currentSubFrameIndex + << "\n\tcurrentProgress: " << currentProgress << "\n\tcoordX: " << coordX << "\n\tcoordY: " << coordY - << "\n\tflippedDataX: " << flippedDataX; + << "\n\tflippedDataX: " << flippedDataX + << "\n\tcompleteImage: " << completeImage; } // DATA data = true; zmqSocket[isocket]->ReceiveData(isocket, image, size); + // creating multi image { uint32_t xoffset = coordX * nPixelsX * bytesPerPixel; @@ -586,43 +607,35 @@ void DetectorImpl::readFrameFromReceiver() { } } } + LOG(logDEBUG)<< "Call Back Info:" << "\n\t nDetPixelsX: " << nDetPixelsX << "\n\t nDetPixelsY: " << nDetPixelsY << "\n\t databytes: " << multisize - << "\n\t dynamicRange: " << dynamicRange ; + << "\n\t dynamicRange: " << dynamicRange; // send data to callback if (data) { - setCurrentProgress(currentFrameIndex + 1); - // 4bit gap pixels - if (dynamicRange == 4 && gappixelsenable) { - if (quadEnable) { - nDetPixelsX += 2; - nDetPixelsY += 2; - } else { - nDetPixelsX = nX * (nPixelsX + 3); - nDetPixelsY = nY * (nPixelsY + 1); - } - int n = processImageWithGapPixels(multiframe, multigappixels, - quadEnable); - LOG(logDEBUG) - << "Call Back Info Recalculated:" - << "\n\t nDetPixelsX: " << nDetPixelsX - << "\n\t nDetPixelsY: " << nDetPixelsY - << "\n\t databytes: " << n; - thisData = - new detectorData(getCurrentProgress(), currentFileName, - nDetPixelsX, nDetPixelsY, multigappixels, - n, dynamicRange, currentFileIndex); - } - // normal pixels - else { - thisData = - new detectorData(getCurrentProgress(), currentFileName, - nDetPixelsX, nDetPixelsY, multiframe, - multisize, dynamicRange, currentFileIndex); + char* image = multiframe; + int imagesize = multisize; + + if (gapPixels) { + int n = InsertGapPixels(multiframe, multigappixels, + quadEnable, dynamicRange, nDetPixelsX, nDetPixelsY); + image = multigappixels; + imagesize = n; } + LOG(logDEBUG) + << "Image Info:" + << "\n\tnDetPixelsX: " << nDetPixelsX + << "\n\tnDetPixelsY: " << nDetPixelsY + << "\n\timagesize: " << imagesize + << "\n\tdynamicRange: " << dynamicRange; + + thisData = new detectorData(currentProgress, + currentFileName, nDetPixelsX, nDetPixelsY, image, + imagesize, dynamicRange, currentFileIndex, completeImage); + dataReady( thisData, currentFrameIndex, ((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1), @@ -667,141 +680,301 @@ void DetectorImpl::readFrameFromReceiver() { delete[] multigappixels; } -int DetectorImpl::processImageWithGapPixels(char *image, char *&gpImage, - bool quadEnable) { - // eiger 4 bit mode - int nxb = - multi_shm()->numberOfDetector.x * (512 + 3); //(divided by 2 already) - int nyb = multi_shm()->numberOfDetector.y * (256 + 1); - int nchipInRow = 4; - int nxchip = multi_shm()->numberOfDetector.x * 4; - int nychip = multi_shm()->numberOfDetector.y * 1; +int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, + bool quadEnable, int dr, int &nPixelsx, int &nPixelsy) { + + LOG(logDEBUG)<< "Insert Gap pixels:" + << "\n\t nPixelsx: " << nPixelsx + << "\n\t nPixelsy: " << nPixelsy + << "\n\t quadEnable: " << quadEnable + << "\n\t dr: " << dr; + + // inter module gap pixels + int modGapPixelsx = 8; + int modGapPixelsy = 36; + // inter chip gap pixels + int chipGapPixelsx = 2; + int chipGapPixelsy = 2; + // number of pixels in a chip + int nChipPixelsx = 256; + int nChipPixelsy = 256; + // 1 module + // number of chips in a module + int nMod1Chipx = 4; + int nMod1Chipy = 2; if (quadEnable) { - nxb = multi_shm()->numberOfDetector.x * - (256 + 1); //(divided by 2 already) - nyb = multi_shm()->numberOfDetector.y * (512 + 2); - nxchip /= 2; - nychip *= 2; - nchipInRow /= 2; + nMod1Chipx = 2; } - int gapdatabytes = nxb * nyb; + // number of pixels in a module + int nMod1Pixelsx = nChipPixelsx * nMod1Chipx; + int nMod1Pixelsy = nChipPixelsy * nMod1Chipy; + // number of gap pixels in a module + int nMod1GapPixelsx = (nMod1Chipx - 1) * chipGapPixelsx; + int nMod1GapPixelsy = (nMod1Chipy - 1) * chipGapPixelsy; + // total number of modules + int nModx = nPixelsx / nMod1Pixelsx; + int nMody = nPixelsy / nMod1Pixelsy; - // allocate - if (gpImage == nullptr) { - gpImage = new char[gapdatabytes]; + // check if not full modules + // (setting gap pixels and then adding half module or disabling quad) + if (nPixelsy / nMod1Pixelsy == 0) { + LOG(logERROR) << "Gap pixels can only be enabled with full modules. " + "Sending dummy data without gap pixels.\n"; + double bytesPerPixel = (double)dr / 8.00; + int imagesize = nPixelsy * nPixelsx * bytesPerPixel; + if (gpImage == NULL) { + gpImage = new char[imagesize]; + } + memset(gpImage, 0xFF, imagesize); + return imagesize; } - // fill value - memset(gpImage, 0xFF, gapdatabytes); - const int b1chipx = 128; - const int b1chipy = 256; + // total number of pixels + int nTotx = nPixelsx + (nMod1GapPixelsx * nModx) + (modGapPixelsx * (nModx - 1)); + int nToty = nPixelsy + (nMod1GapPixelsy * nMody) + (modGapPixelsy * (nMody - 1)); + // total number of chips + int nChipx = nPixelsx / nChipPixelsx; + int nChipy = nPixelsy / nChipPixelsy; + + double bytesPerPixel = (double)dr / 8.00; + int imagesize = nTotx * nToty * bytesPerPixel; + + int nChipBytesx = nChipPixelsx * bytesPerPixel; // 1 chip bytes in x + int nChipGapBytesx = chipGapPixelsx * bytesPerPixel; // 2 pixel bytes + int nModGapBytesx = modGapPixelsx * bytesPerPixel; // 8 pixel bytes + int nChipBytesy = nChipPixelsy * nTotx * bytesPerPixel; // 1 chip bytes in y + int nChipGapBytesy = chipGapPixelsy * nTotx * bytesPerPixel; // 2 lines + int nModGapBytesy = modGapPixelsy * nTotx * bytesPerPixel; // 36 lines + // 4 bit mode, its 1 byte (because for 4 bit mode, we handle 1 byte at a time) + int pixel1 = (int)(ceil(bytesPerPixel)); + int row1Bytes = nTotx * bytesPerPixel; + int nMod1TotPixelsx = nMod1Pixelsx + nMod1GapPixelsx; + if (dr == 4) { + nMod1TotPixelsx /= 2; + } + // eiger requires inter chip gap pixels are halved + // jungfrau prefers same inter chip gap pixels as the boundary pixels + int divisionValue = 2; + slsDetectorDefs::detectorType detType = multi_shm()->multiDetectorType; + if (detType == JUNGFRAU) { + divisionValue = 1; + } + LOG(logDEBUG) + << "Insert Gap pixels Calculations:\n\t" + << "nPixelsx: " << nPixelsx << "\n\t" + << "nPixelsy: " << nPixelsy << "\n\t" + << "nMod1Pixelsx: " << nMod1Pixelsx << "\n\t" + << "nMod1Pixelsy: " << nMod1Pixelsy << "\n\t" + << "nMod1GapPixelsx: " << nMod1GapPixelsx << "\n\t" + << "nMod1GapPixelsy: " << nMod1GapPixelsy << "\n\t" + << "nChipy: " << nChipy << "\n\t" + << "nChipx: " << nChipx << "\n\t" + << "nModx: " << nModx << "\n\t" + << "nMody: " << nMody << "\n\t" + << "nTotx: " << nTotx << "\n\t" + << "nToty: " << nToty << "\n\t" + << "bytesPerPixel: " << bytesPerPixel << "\n\t" + << "imagesize: " << imagesize << "\n\t" + << "nChipBytesx: " << nChipBytesx << "\n\t" + << "nChipGapBytesx: " << nChipGapBytesx << "\n\t" + << "nModGapBytesx: " << nModGapBytesx << "\n\t" + << "nChipBytesy: " << nChipBytesy << "\n\t" + << "nChipGapBytesy: " << nChipGapBytesy << "\n\t" + << "nModGapBytesy: " << nModGapBytesy << "\n\t" + << "pixel1: " << pixel1 << "\n\t" + << "row1Bytes: " << row1Bytes << "\n\t" + << "nMod1TotPixelsx: " << nMod1TotPixelsx << "\n\t" + << "divisionValue: " << divisionValue << "\n\n"; + + if (gpImage == NULL) { + gpImage = new char[imagesize]; + } + memset(gpImage, 0xFF, imagesize); + //memcpy(gpImage, image, imagesize); char *src = nullptr; char *dst = nullptr; // copying line by line src = image; dst = gpImage; - for (int row = 0; row < nychip; ++row) { // for each chip row - for (int ichipy = 0; ichipy < b1chipy; - ++ichipy) { // for each row in a chip - for (int col = 0; col < nxchip; ++col) { // for each chip in a row - memcpy(dst, src, b1chipx); - src += b1chipx; - dst += b1chipx; - if (((col + 1) % nchipInRow) != 0) { // skip gap pixels - ++dst; + // for each chip row in y + for (int iChipy = 0; iChipy < nChipy; ++iChipy) { + // for each row + for (int iy = 0; iy < nChipPixelsy; ++iy) { + // in each row, for every chip + for (int iChipx = 0; iChipx < nChipx; ++iChipx) { + // copy 1 chip line + memcpy(dst, src, nChipBytesx); + src += nChipBytesx; + dst += nChipBytesx; + // skip inter chip gap pixels in x + if (((iChipx + 1) % nMod1Chipx) != 0) { + dst += nChipGapBytesx; + } + // skip inter module gap pixels in x + else if (iChipx + 1 != nChipx) { + dst += nModGapBytesx; } } } - - dst += (2 * nxb); + // skip inter chip gap pixels in y + if (((iChipy + 1) % nMod1Chipy) != 0) { + dst += nChipGapBytesy; + } + // skip inter module gap pixels in y + else if (iChipy + 1 != nChipy) { + dst += nModGapBytesy; + } } - // vertical filling of values - { - uint8_t temp, g1, g2; - int mod; - dst = gpImage; - for (int row = 0; row < nychip; ++row) { // for each chip row - for (int ichipy = 0; ichipy < b1chipy; - ++ichipy) { // for each row in a chip - for (int col = 0; col < nxchip; - ++col) { // for each chip in a row - dst += b1chipx; - mod = (col + 1) % nchipInRow; // get gap pixels - // copy gap pixel(chip 0, 1, 2) - if (mod != 0) { + // iner chip gap pixel values is half of neighboring one + // (corners becomes divide by 4 automatically after horizontal filling) + + // vertical filling of inter chip gap pixels + dst = gpImage; + // for each chip row in y + for (int iChipy = 0; iChipy < nChipy; ++iChipy) { + // for each row + for (int iy = 0; iy < nChipPixelsy; ++iy) { + // in each row, for every chip + for (int iChipx = 0; iChipx < nChipx; ++iChipx) { + // go to gap pixels + dst += nChipBytesx; + // fix inter chip gap pixels in x + if (((iChipx + 1) % nMod1Chipx) != 0) { + uint8_t temp8 = 0; + uint16_t temp16 = 0; + uint32_t temp32 = 0; + uint8_t g1 = 0; + uint8_t g2 = 0; + switch (dr) { + case 4: // neighbouring gap pixels to left - temp = (*((uint8_t *)(dst - 1))); - g1 = ((temp & 0xF) / 2); - (*((uint8_t *)(dst - 1))) = (temp & 0xF0) + g1; - + temp8 = (*((uint8_t *)(dst - 1))); + g1 = ((temp8 & 0xF) / 2); + (*((uint8_t *)(dst - 1))) = (temp8 & 0xF0) + g1; // neighbouring gap pixels to right - temp = (*((uint8_t *)(dst + 1))); - g2 = ((temp >> 4) / 2); - (*((uint8_t *)(dst + 1))) = (g2 << 4) + (temp & 0x0F); - + temp8 = (*((uint8_t *)(dst + 1))); + g2 = ((temp8 >> 4) / 2); + (*((uint8_t *)(dst + 1))) = (g2 << 4) + (temp8 & 0x0F); // gap pixels - (*((uint8_t *)dst)) = (g1 << 4) + g2; - - // increment to point to proper chip destination - ++dst; - } + (*((uint8_t *)dst)) = (g1 << 4) + g2; + break; + case 8: + // neighbouring gap pixels to left + temp8 = (*((uint8_t *)(dst - pixel1))) / 2; + (*((uint8_t *)dst)) = temp8; + (*((uint8_t *)(dst - pixel1))) = temp8; + // neighbouring gap pixels to right + temp8 = (*((uint8_t *)(dst + 2 * pixel1))) / 2; + (*((uint8_t *)(dst + pixel1))) = temp8; + (*((uint8_t *)(dst + 2 * pixel1))) = temp8; + break; + case 16: + // neighbouring gap pixels to left + temp16 = (*((uint16_t *)(dst - pixel1))) / divisionValue; + (*((uint16_t *)dst)) = temp16; + (*((uint16_t *)(dst - pixel1))) = temp16; + // neighbouring gap pixels to right + temp16 = (*((uint16_t *)(dst + 2 * pixel1))) / divisionValue; + (*((uint16_t *)(dst + pixel1))) = temp16; + (*((uint16_t *)(dst + 2 * pixel1))) = temp16; + break; + default: + // neighbouring gap pixels to left + temp32 = (*((uint32_t *)(dst - pixel1))) / 2; + (*((uint32_t *)dst)) = temp32; + (*((uint32_t *)(dst - pixel1))) = temp32; + // neighbouring gap pixels to right + temp32 = (*((uint32_t *)(dst + 2 * pixel1))) / 2; + (*((uint32_t *)(dst + pixel1))) = temp32; + (*((uint32_t *)(dst + 2 * pixel1))) = temp32; + break; + } + dst += nChipGapBytesx; + } + // skip inter module gap pixels in x + else if (iChipx + 1 != nChipx) { + dst += nModGapBytesx; } } + } + // skip inter chip gap pixels in y + if (((iChipy + 1) % nMod1Chipy) != 0) { + dst += nChipGapBytesy; + } + // skip inter module gap pixels in y + else if (iChipy + 1 != nChipy) { + dst += nModGapBytesy; + } + } - dst += (2 * nxb); + // horizontal filling of inter chip gap pixels + // starting at bottom part (1 line below to copy from) + src = gpImage + (nChipBytesy - row1Bytes); + dst = gpImage + nChipBytesy; + // for each chip row in y + for (int iChipy = 0; iChipy < nChipy; ++iChipy) { + // for each module in x + for (int iModx = 0; iModx < nModx; ++iModx) { + // in each module, for every pixel in x + for (int iPixel = 0; iPixel < nMod1TotPixelsx; ++iPixel) { + uint8_t temp8 = 0, g1 = 0, g2 = 0; + uint16_t temp16 = 0; + uint32_t temp32 = 0; + switch (dr) { + case 4: + temp8 = (*((uint8_t *)src)); + g1 = ((temp8 >> 4) / 2); + g2 = ((temp8 & 0xF) / 2); + temp8 = (g1 << 4) + g2; + (*((uint8_t *)dst)) = temp8; + (*((uint8_t *)src)) = temp8; + break; + case 8: + temp8 = (*((uint8_t *)src)) / divisionValue; + (*((uint8_t *)dst)) = temp8; + (*((uint8_t *)src)) = temp8; + break; + case 16: + temp16 = (*((uint16_t *)src)) / divisionValue; + (*((uint16_t *)dst)) = temp16; + (*((uint16_t *)src)) = temp16; + break; + default: + temp32 = (*((uint32_t *)src)) / 2; + (*((uint32_t *)dst)) = temp32; + (*((uint32_t *)src)) = temp32; + break; + } + // every pixel (but 4 bit mode, every byte) + src += pixel1; + dst += pixel1; + } + // skip inter module gap pixels in x + if (iModx + 1 < nModx) { + src += nModGapBytesx; + dst += nModGapBytesx; + } + } + // bottom parts, skip inter chip gap pixels + if ((iChipy % nMod1Chipy) == 0) { + src += nChipGapBytesy; + } + // top parts, skip inter module gap pixels and two chips + else { + src += (nModGapBytesy + 2 * nChipBytesy - 2 * row1Bytes); + dst += (nModGapBytesy + 2 * nChipBytesy); } } - // return gapdatabytes; - // horizontal filling - { - uint8_t temp, g1, g2; - char *dst_prevline = nullptr; - dst = gpImage; - for (int row = 0; row < nychip; ++row) { // for each chip row - dst += (b1chipy * nxb); - // horizontal copying of gap pixels from neighboring past line - // (bottom parts) - if (row < nychip - 1) { - dst_prevline = dst - nxb; - for (int gapline = 0; gapline < nxb; ++gapline) { - temp = (*((uint8_t *)dst_prevline)); - g1 = ((temp >> 4) / 2); - g2 = ((temp & 0xF) / 2); - (*((uint8_t *)dst_prevline)) = (g1 << 4) + g2; - (*((uint8_t *)dst)) = (*((uint8_t *)dst_prevline)); - ++dst; - ++dst_prevline; - } - } - - // horizontal copying of gap pixels from neihboring future line (top - // part) - if (row > 0) { - dst -= ((b1chipy + 1) * nxb); - dst_prevline = dst + nxb; - for (int gapline = 0; gapline < nxb; ++gapline) { - temp = (*((uint8_t *)dst_prevline)); - g1 = ((temp >> 4) / 2); - g2 = ((temp & 0xF) / 2); - temp = (g1 << 4) + g2; - (*((uint8_t *)dst_prevline)) = temp; - (*((uint8_t *)dst)) = temp; - ++dst; - ++dst_prevline; - } - dst += ((b1chipy + 1) * nxb); - } - - dst += nxb; - } - } - - return gapdatabytes; + nPixelsx = nTotx; + nPixelsy = nToty; + return imagesize; } + + bool DetectorImpl::enableDataStreamingToClient(int enable) { if (enable >= 0) { // destroy data threads @@ -833,38 +1006,6 @@ void DetectorImpl::registerDataCallback(void (*userCallback)(detectorData *, enableDataStreamingToClient(dataReady == nullptr ? 0 : 1); } -double DetectorImpl::setTotalProgress() { - int64_t tot = Parallel(&Module::getTotalNumFramesToReceive, {}) - .tsquash("Inconsistent number of total frames (#frames x #triggers(or bursts) x #storage cells)"); - if (tot == 0) { - throw RuntimeError("Invalid Total Number of frames (0)"); - } - totalProgress = tot; - LOG(logDEBUG1) << "Set total progress " << totalProgress << std::endl; - return totalProgress; -} - -double DetectorImpl::getCurrentProgress() { - std::lock_guard lock(mp); - return 100. * progressIndex / totalProgress; -} - -void DetectorImpl::incrementProgress() { - std::lock_guard lock(mp); - progressIndex += 1; - std::cout << std::fixed << std::setprecision(2) << std::setw(6) - << 100. * progressIndex / totalProgress << " \%"; - std::cout << '\r' << std::flush; -} - -void DetectorImpl::setCurrentProgress(int64_t i) { - std::lock_guard lock(mp); - progressIndex = (double)i; - std::cout << std::fixed << std::setprecision(2) << std::setw(6) - << 100. * progressIndex / totalProgress << " \%"; - std::cout << '\r' << std::flush; -} - int DetectorImpl::acquire() { // ensure acquire isnt started multiple times by same client if (!isAcquireReady()) { @@ -885,7 +1026,7 @@ int DetectorImpl::acquire() { bool receiver = Parallel(&Module::getUseReceiverFlag, {}).squash(false); - progressIndex = 0; + setJoinThreadFlag(false); // verify receiver is idle @@ -895,7 +1036,6 @@ int DetectorImpl::acquire() { Parallel(&Module::stopReceiver, {}); } } - setTotalProgress(); startProcessingThread(); @@ -935,12 +1075,10 @@ int DetectorImpl::acquire() { dataProcessingThread.join(); if (acquisition_finished != nullptr) { - // same status for all, else error - int status = static_cast(ERROR); - auto t = Parallel(&Module::getRunStatus, {}); - if (t.equal()) - status = t.front(); - acquisition_finished(getCurrentProgress(), status, acqFinished_p); + int status = Parallel(&Module::getRunStatus, {}).squash(ERROR); + auto a = Parallel(&Module::getReceiverProgress, {}); + int progress = (*std::min_element (a.begin(), a.end())); + acquisition_finished((double)progress, status, acqFinished_p); } sem_destroy(&sem_newRTAcquisition); @@ -959,8 +1097,14 @@ int DetectorImpl::acquire() { return OK; } +void DetectorImpl::printProgress(double progress) { + std::cout << std::fixed << std::setprecision(2) << std::setw(6) + << progress << " \%"; + std::cout << '\r' << std::flush; +} + + void DetectorImpl::startProcessingThread() { - setTotalProgress(); dataProcessingThread = std::thread(&DetectorImpl::processData, this); } @@ -971,7 +1115,9 @@ void DetectorImpl::processData() { } // only update progress else { - int64_t caught = -1; + double progress = 0; + printProgress(progress); + while (true) { // to exit acquire by typing q if (kbhit() != 0) { @@ -981,16 +1127,18 @@ void DetectorImpl::processData() { Parallel(&Module::stopAcquisition, {}); } } - // get progress - caught = Parallel(&Module::getFramesCaughtByReceiver, {0}) - .squash(); - - // updating progress - if (caught != -1) { - setCurrentProgress(caught); + // get and print progress + double temp = (double)Parallel(&Module::getReceiverProgress, {0}).squash(); + if (temp != progress) { + printProgress(progress); + progress = temp; } + // exiting loop if (getJoinThreadFlag()) { + // print progress one final time before exiting + progress = (double)Parallel(&Module::getReceiverProgress, {0}).squash(); + printProgress(progress); break; } // otherwise error when connecting to the receiver too fast diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index 107aada8a..21424c712 100755 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -16,7 +16,7 @@ class detectorData; #include #define MULTI_SHMAPIVERSION 0x190809 -#define MULTI_SHMVERSION 0x200131 +#define MULTI_SHMVERSION 0x200319 #define SHORT_STRING_LENGTH 50 #include @@ -47,10 +47,7 @@ struct sharedMultiSlsDetector { /** last time stamp when accessing the shared memory */ char lastDate[SHORT_STRING_LENGTH]; - /** number of sls detectors in shared memory */ int numberOfDetectors; - - /** multi detector type */ slsDetectorDefs::detectorType multiDetectorType; /** END OF FIXED PATTERN @@ -62,11 +59,9 @@ struct sharedMultiSlsDetector { /** max number of channels for complete detector*/ slsDetectorDefs::xy numberOfChannels; - /** flag for acquiring */ bool acquiringFlag; - - /** initial checks */ bool initialChecks; + bool gapPixels; }; class DetectorImpl : public virtual slsDetectorDefs { @@ -236,11 +231,10 @@ class DetectorImpl : public virtual slsDetectorDefs { * Sets maximum number of channels of all sls detectors */ void setNumberOfChannels(const slsDetectorDefs::xy c); - /** - * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) - * 4 bit mode gap pixels only in gui call back - */ - void setGapPixelsinReceiver(bool enable); + /** [Eiger][Jungfrau] */ + bool getGapPixelsinCallback() const; + /** [Eiger][Jungfrau] */ + void setGapPixelsinCallback(const bool enable); /** * Enable data streaming to client @@ -347,23 +341,20 @@ class DetectorImpl : public virtual slsDetectorDefs { */ void readFrameFromReceiver(); - /** - * add gap pixels to the image (only for Eiger in 4 bit mode) + /** [Eiger][Jungfrau] + * add gap pixels to the imag * @param image pointer to image without gap pixels * @param gpImage poiner to image with gap pixels, if NULL, allocated - * inside function - * quadEnable quad enabled - * @returns number of data bytes of image with gap pixels + * @param quadEnable quad enabled + * @param dr dynamic range + * @param nPixelsx number of pixels in X axis (updated) + * @param nPixelsy number of pixels in Y axis (updated) + * @returns total data bytes for updated image */ - int processImageWithGapPixels(char *image, char *&gpImage, bool quadEnable); + int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, + int &nPixelsx, int &nPixelsy); - double setTotalProgress(); - - double getCurrentProgress(); - - void incrementProgress(); - - void setCurrentProgress(int64_t i = 0); + void printProgress(double progress); void startProcessingThread(); @@ -408,12 +399,6 @@ class DetectorImpl : public virtual slsDetectorDefs { * from ext. process) */ sem_t sem_endRTAcquisition; - /** Total number of frames/images for next acquisition */ - double totalProgress{0}; - - /** Current progress or frames/images processed in current acquisition */ - double progressIndex{0}; - /** mutex to synchronize main and data processing threads */ mutable std::mutex mp; diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 21a7b87d0..a8a41517e 100755 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -137,12 +137,8 @@ int64_t Module::getReceiverSoftwareVersion() const { 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); - auto ret = - client.sendCommandThenRead(fnum, args, args_size, retval, retval_size); + client.sendCommandThenRead(fnum, args, args_size, retval, retval_size); client.close(); - if (ret == FORCE_UPDATE) { - updateCachedDetectorVariables(); - } } template @@ -363,7 +359,6 @@ void Module::setHostname(const std::string &hostname, const bool initialChecks) } LOG(logINFO) << "Detector connecting - updating!"; - updateCachedDetectorVariables(); } std::string Module::getHostname() const { return shm()->hostname; } @@ -396,21 +391,12 @@ void Module::initializeDetectorStructure(detectorType type) { shm()->controlPort = DEFAULT_PORTNO; shm()->stopPort = DEFAULT_PORTNO + 1; sls::strcpy_safe(shm()->settingsDir, getenv("HOME")); - shm()->currentSettings = UNINITIALIZED; - shm()->nFrames = 1; - shm()->nTriggers = 1; - shm()->nBursts = 1; - shm()->nAddStorageCells = 0; - shm()->timingMode = AUTO_TIMING; - shm()->burstMode = BURST_INTERNAL; - shm()->deadTime = 0; 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()->gappixels = 0U; shm()->numUDPInterfaces = 1; shm()->stoppedFlag = false; @@ -421,9 +407,6 @@ void Module::initializeDetectorStructure(detectorType type) { shm()->nChip.x = parameters.nChipX; shm()->nChip.y = parameters.nChipY; shm()->nDacs = parameters.nDacs; - shm()->dynamicRange = parameters.dynamicRange; - shm()->nGappixels.x = parameters.nGappixelsX; - shm()->nGappixels.y = parameters.nGappixelsY; } int Module::sendModule(sls_detector_module *myMod, @@ -582,10 +565,8 @@ void Module::updateNumberOfChannels() { slsDetectorDefs::xy Module::getNumberOfChannels() const { slsDetectorDefs::xy coord{}; - coord.x = (shm()->nChan.x * shm()->nChip.x + - shm()->gappixels * shm()->nGappixels.x); - coord.y = (shm()->nChan.y * shm()->nChip.y + - shm()->gappixels * shm()->nGappixels.y); + coord.x = (shm()->nChan.x * shm()->nChip.x); + coord.y = (shm()->nChan.y * shm()->nChip.y); return coord; } @@ -717,82 +698,6 @@ void Module::execCommand(const std::string &cmd) { } } -void Module::updateCachedDetectorVariables() { - int fnum = F_UPDATE_CLIENT; - LOG(logDEBUG1) << "Sending update client to detector server"; - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - if (client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0) == - FORCE_UPDATE) { - int n = 0, i32 = 0; - int64_t i64 = 0; - sls::IpAddr lastClientIP; - n += client.Receive(&lastClientIP, sizeof(lastClientIP)); - LOG(logDEBUG1) - << "Updating detector last modified by " << lastClientIP; - - // dr - n += client.Receive(&i32, sizeof(i32)); - shm()->dynamicRange = i32; - - // settings - if (shm()->myDetectorType == EIGER || shm()->myDetectorType == JUNGFRAU || - shm()->myDetectorType == GOTTHARD || shm()->myDetectorType == GOTTHARD2 || - shm()->myDetectorType == MOENCH) { - n += client.Receive(&i32, sizeof(i32)); - shm()->currentSettings = static_cast(i32); - } - - // frame number - n += client.Receive(&i64, sizeof(i64)); - shm()->nFrames = i64; - - // storage cell - if (shm()->myDetectorType == JUNGFRAU) { - n += client.Receive(&i64, sizeof(i64)); - shm()->nAddStorageCells = i64; - } - - // triggers - n += client.Receive(&i64, sizeof(i64)); - shm()->nTriggers = i64; - - // bursts - if (shm()->myDetectorType == GOTTHARD2) { - n += client.Receive(&i64, sizeof(i64)); - shm()->nBursts = i64; - } - - // timing mode - n += client.Receive(&i32, sizeof(i32)); - shm()->timingMode = static_cast(i32); - - // burst mode - if (shm()->myDetectorType == GOTTHARD2) { - n += client.Receive(&i32, sizeof(i32)); - shm()->burstMode = static_cast(i32); - } - - // number of channels (depends on #samples, adcmask) - if (shm()->myDetectorType == CHIPTESTBOARD || - shm()->myDetectorType == MOENCH) { - n += client.Receive(&i32, sizeof(i32)); - shm()->nChan.x = i32; - n += client.Receive(&i32, sizeof(i32)); - shm()->nChan.y = i32; - } - - // num udp interfaces - if (shm()->myDetectorType == JUNGFRAU) { - n += client.Receive(&i32, sizeof(i32)); - shm()->numUDPInterfaces = i32; - } - - if (n == 0) { - LOG(logERROR) << "Could not update detector, received 0 bytes"; - } - } -} - std::vector Module::getConfigFileCommands() { std::vector base{"hostname", "port", "stopport", "settingsdir", "fpath", "lock", @@ -868,49 +773,21 @@ std::vector Module::getConfigFileCommands() { } slsDetectorDefs::detectorSettings Module::getSettings() { - return sendSettingsOnly(GET_SETTINGS); + int arg = -1; + int retval = -1; + sendToDetector(F_SET_SETTINGS, arg, retval); + LOG(logDEBUG1) << "Settings: " << retval; + return static_cast(retval); } -slsDetectorDefs::detectorSettings -Module::setSettings(detectorSettings isettings) { - LOG(logDEBUG1) << "Module setSettings " << isettings; - - if (isettings == -1) { - return getSettings(); - } - - // eiger: only set shm, setting threshold loads the module data +void Module::setSettings(detectorSettings isettings) { if (shm()->myDetectorType == EIGER) { - switch (isettings) { - case STANDARD: - case HIGHGAIN: - case LOWGAIN: - case VERYHIGHGAIN: - case VERYLOWGAIN: - shm()->currentSettings = isettings; - return shm()->currentSettings; - default: - std::ostringstream ss; - ss << "Unknown settings " << ToString(isettings) - << " for this detector!"; - throw RuntimeError(ss.str()); - } + throw RuntimeError("Cannot set settings for Eiger. Use threshold energy."); } - - // others: send only the settings, detector server will update dac values - // already in server - return sendSettingsOnly(isettings); -} - -slsDetectorDefs::detectorSettings -Module::sendSettingsOnly(detectorSettings isettings) { int arg = static_cast(isettings); int retval = -1; LOG(logDEBUG1) << "Setting settings to " << arg; sendToDetector(F_SET_SETTINGS, arg, retval); - LOG(logDEBUG1) << "Settings: " << retval; - shm()->currentSettings = static_cast(retval); - return shm()->currentSettings; } int Module::getThresholdEnergy() { @@ -937,26 +814,23 @@ int Module::getThresholdEnergy() { return retval; } -int Module::setThresholdEnergy(int e_eV, detectorSettings isettings, +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); - return e_eV; } // moench - send threshold energy to processor else if (shm()->myDetectorType == MOENCH) { - std::string result = - setAdditionalJsonParameter("threshold", std::to_string(e_eV)); - if (result == std::to_string(e_eV)) { - return e_eV; - } - return -1; + setAdditionalJsonParameter("threshold", std::to_string(e_eV)); } - throw RuntimeError( + + else { + throw RuntimeError( "Set threshold energy not implemented for this detector"); + } } void Module::setThresholdEnergyAndSettings(int e_eV, @@ -965,7 +839,7 @@ void Module::setThresholdEnergyAndSettings(int e_eV, // if settings provided, use that, else use the shared memory variable detectorSettings is = - ((isettings != GET_SETTINGS) ? isettings : shm()->currentSettings); + ((isettings != GET_SETTINGS) ? isettings : getSettings()); // verify e_eV exists in trimEneregies[] if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) || @@ -1010,8 +884,7 @@ void Module::setThresholdEnergyAndSettings(int e_eV, linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau); } - shm()->currentSettings = is; - myMod.reg = shm()->currentSettings; + myMod.reg = is; myMod.eV = e_eV; setModule(myMod, tb); if (getSettings() != is) { @@ -1172,96 +1045,64 @@ uint64_t Module::getStartingFrameNumber() { return retval; } -int64_t Module::getTotalNumFramesToReceive() { - int64_t repeats = shm()->nTriggers; - // gotthard2 & auto & burst mode, use nBursts instead of nTriggers - if (shm()->myDetectorType == GOTTHARD2) { - if (shm()->burstMode != BURST_OFF && shm()->timingMode == AUTO_TIMING) { - repeats = shm()->nBursts; - } - } - return (shm()->nFrames * repeats * (int64_t)(shm()->nAddStorageCells + 1)); -} - -void Module::sendTotalNumFramestoReceiver() { - if (shm()->useReceiverFlag) { - int64_t arg = getTotalNumFramesToReceive(); - LOG(logDEBUG1) << "Sending total number of frames (#f x #t x #s) to Receiver: " << arg; - sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, arg, nullptr); - } -} - int64_t Module::getNumberOfFrames() { int64_t retval = -1; sendToDetector(F_GET_NUM_FRAMES, nullptr, retval); LOG(logDEBUG1) << "number of frames :" << retval; - if (shm()->nFrames != retval) { - shm()->nFrames = retval; - sendTotalNumFramestoReceiver(); - } - return shm()->nFrames; + return retval; } void Module::setNumberOfFrames(int64_t value) { LOG(logDEBUG1) << "Setting number of frames to " << value; sendToDetector(F_SET_NUM_FRAMES, value, nullptr); - shm()->nFrames = value; - sendTotalNumFramestoReceiver(); + if (shm()->useReceiverFlag) { + LOG(logDEBUG1) << "Sending number of frames to Receiver: " << value; + sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr); + } } int64_t Module::getNumberOfTriggers() { int64_t retval = -1; sendToDetector(F_GET_NUM_TRIGGERS, nullptr, retval); LOG(logDEBUG1) << "number of triggers :" << retval; - if (shm()->nTriggers != retval) { - shm()->nTriggers = retval; - sendTotalNumFramestoReceiver(); - } - return shm()->nTriggers; + return retval; } void Module::setNumberOfTriggers(int64_t value) { LOG(logDEBUG1) << "Setting number of triggers to " << value; sendToDetector(F_SET_NUM_TRIGGERS, value, nullptr); - shm()->nTriggers = value; - sendTotalNumFramestoReceiver(); + if (shm()->useReceiverFlag) { + LOG(logDEBUG1) << "Sending number of triggers to Receiver: " << value; + sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr); + } } int64_t Module::getNumberOfBursts() { int64_t retval = -1; sendToDetector(F_GET_NUM_BURSTS, nullptr, retval); LOG(logDEBUG1) << "number of bursts :" << retval; - if (shm()->nBursts != retval) { - shm()->nBursts = retval; - sendTotalNumFramestoReceiver(); - } - return shm()->nBursts; + return retval; } void Module::setNumberOfBursts(int64_t value) { LOG(logDEBUG1) << "Setting number of bursts to " << value; sendToDetector(F_SET_NUM_BURSTS, value, nullptr); - shm()->nBursts = value; - sendTotalNumFramestoReceiver(); + if (shm()->useReceiverFlag) { + LOG(logDEBUG1) << "Sending number of bursts to Receiver: " << value; + sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr); + } } int Module::getNumberOfAdditionalStorageCells() { - int prevVal = shm()->nAddStorageCells; int retval = -1; sendToDetector(F_GET_NUM_ADDITIONAL_STORAGE_CELLS, nullptr, retval); LOG(logDEBUG1) << "number of storage cells :" << retval; - shm()->nAddStorageCells = retval; - if (prevVal != retval) { - sendTotalNumFramestoReceiver(); - } - return shm()->nAddStorageCells; + return retval; } void Module::setNumberOfAdditionalStorageCells(int value) { LOG(logDEBUG1) << "Setting number of storage cells to " << value; sendToDetector(F_SET_NUM_ADDITIONAL_STORAGE_CELLS, value, nullptr); - shm()->nAddStorageCells = value; - sendTotalNumFramestoReceiver(); } int Module::getNumberOfAnalogSamples() { @@ -1311,16 +1152,13 @@ void Module::setExptime(int64_t value) { } LOG(logDEBUG1) << "Setting exptime to " << value << "ns"; sendToDetector(F_SET_EXPTIME, value, nullptr); - if (shm()->myDetectorType == EIGER && prevVal != value && shm()->dynamicRange == 16) { - int r = getRateCorrection(); - if (r != 0) { - setRateCorrection(r); - } - } if (shm()->useReceiverFlag) { LOG(logDEBUG1) << "Sending exptime to Receiver: " << value; sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr); } + if (prevVal != value) { + updateRateCorrection(); + } } int64_t Module::getPeriod() { @@ -1364,17 +1202,14 @@ void Module::setSubExptime(int64_t value) { prevVal = getSubExptime(); } LOG(logDEBUG1) << "Setting sub exptime to " << value << "ns"; - sendToDetector(F_SET_SUB_EXPTIME, value, nullptr); - if (shm()->myDetectorType == EIGER && prevVal != value && shm()->dynamicRange == 32) { - int r = getRateCorrection(); - if (r != 0) { - setRateCorrection(r); - } - } + 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() { @@ -1472,48 +1307,63 @@ int64_t Module::getMeasurementTime() const { return retval; } -slsDetectorDefs::timingMode Module::setTimingMode(timingMode value) { - int fnum = F_SET_TIMING_MODE; - //auto arg = static_cast(pol); +slsDetectorDefs::timingMode Module::getTimingMode() { + int arg = -1; timingMode retval = GET_TIMING_MODE; - LOG(logDEBUG1) << "Setting communication to mode " << value; - sendToDetector(fnum, static_cast(value), retval); + sendToDetector(F_SET_TIMING_MODE, arg, retval); LOG(logDEBUG1) << "Timing Mode: " << retval; - shm()->timingMode = retval; return retval; } -int Module::setDynamicRange(int n) { - // TODO! Properly handle fail - int prevDr = shm()->dynamicRange; +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() { + int arg = -1; + int retval = -1; + sendToDetector(F_SET_DYNAMIC_RANGE, arg, retval); + LOG(logDEBUG1) << "Dynamic Range: " << retval; + return retval; +} + +void Module::setDynamicRange(int n) { + int prev_val = n; + if (shm()->myDetectorType == EIGER) { + prev_val = getDynamicRange(); + } int retval = -1; LOG(logDEBUG1) << "Setting dynamic range to " << n; sendToDetector(F_SET_DYNAMIC_RANGE, n, retval); LOG(logDEBUG1) << "Dynamic Range: " << retval; - shm()->dynamicRange = retval; if (shm()->useReceiverFlag) { - n = shm()->dynamicRange; + int arg = retval; retval = -1; - LOG(logDEBUG1) << "Sending dynamic range to receiver: " << n; - sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, n, retval); + 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 - int dr = shm()->dynamicRange; - if (prevDr != dr && shm()->myDetectorType == EIGER) { - updateRateCorrection(); + if (n != prev_val) { // update speed for usability - if (dr == 32) { - LOG(logINFO) << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32"; setClockDivider(RUN_CLOCK, 2); - } else { - LOG(logINFO) << "Setting Clock to Full Speed to cope with Dynamic Range of " << dr; setClockDivider(RUN_CLOCK, 0); + 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(); } - - return shm()->dynamicRange; } int Module::setDAC(int val, dacIndex index, int mV) { @@ -1675,8 +1525,6 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) { LOG(logWARNING) << "Acquisition already running, Stopping it."; stopAcquisition(); } - // update detector before receiver - updateCachedDetectorVariables(); // start updating std::string host = receiverIP; @@ -1707,7 +1555,9 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) { LOG(logDEBUG1) << printReceiverConfiguration(); setReceiverUDPSocketBufferSize(0); - sendTotalNumFramestoReceiver(); + setNumberOfFrames(getNumberOfFrames()); + setNumberOfTriggers(getNumberOfTriggers()); + setTimingMode(getTimingMode()); setExptime(getExptime()); setPeriod(getPeriod()); @@ -1717,9 +1567,8 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) { case EIGER: setSubExptime(getSubExptime()); setSubDeadTime(getSubDeadTime()); - setDynamicRange(shm()->dynamicRange); + setDynamicRange(getDynamicRange()); activate(-1); - enableGapPixels(shm()->gappixels); enableTenGigabitEthernet(-1); setQuad(getQuad()); break; @@ -1746,7 +1595,12 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) { case MYTHEN3: sendNumberofCounterstoReceiver(getCounterMask()); - setDynamicRange(shm()->dynamicRange); + setDynamicRange(getDynamicRange()); + break; + + case GOTTHARD2: + setNumberOfBursts(getNumberOfBursts()); + setBurstMode(getBurstMode()); break; default: @@ -2105,106 +1959,99 @@ void Module::setTransmissionDelayRight(int value) { } -void Module::setAdditionalJsonHeader(const std::string &jsonheader) { +void Module::setAdditionalJsonHeader(const std::map &jsonHeader) { if (!shm()->useReceiverFlag) { throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)"); } - char args[MAX_STR_LENGTH]{}; - sls::strcpy_safe(args, jsonheader.c_str()); - sendToReceiver(F_SET_ADDITIONAL_JSON_HEADER, args, nullptr); -} - -std::string Module::getAdditionalJsonHeader() { - if (!shm()->useReceiverFlag) { - throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)"); - } - char retvals[MAX_STR_LENGTH]{}; - sendToReceiver(F_GET_ADDITIONAL_JSON_HEADER, nullptr, retvals); - return std::string(retvals); -} - -std::string Module::setAdditionalJsonParameter(const std::string &key, - const std::string &value) { - if (key.empty() || value.empty()) { - throw RuntimeError( - "Could not set additional json header parameter as the key or " - "value is empty"); - } - - // validation (ignore if key or value has , : ") - if (key.find_first_of(",\":") != std::string::npos || - value.find_first_of(",\":") != std::string::npos) { - throw RuntimeError("Could not set additional json header parameter as " - "the key or value has " - "illegal characters (,\":)"); - } - - // create actual key to search for and actual value to put, (key has - // additional ':' as value could exist the same way) - std::string keyLiteral(std::string("\"") + key + std::string("\":")); - std::string valueLiteral(value); - // add quotations to value only if it is a string - try { - std::stoi(valueLiteral); - } catch (...) { - // add quotations if it failed to convert to integer, otherwise nothing - valueLiteral.insert(0, "\""); - valueLiteral.append("\""); - } - - std::string header = getAdditionalJsonHeader(); - size_t keyPos = header.find(keyLiteral); - - // if key found, replace value - if (keyPos != std::string::npos) { - size_t valueStartPos = header.find(std::string(":"), keyPos) + 1; - size_t valueEndPos = header.find(std::string(","), valueStartPos) - 1; - // if valueEndPos doesnt find comma (end of string), it goes anyway to - // end of line - header.replace(valueStartPos, valueEndPos - valueStartPos + 1, - valueLiteral); - } - - // key not found, append key value pair - else { - if (header.length() != 0U) { - header.append(","); + 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"); } - header.append(keyLiteral + valueLiteral); } + 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)); + } +} - // update additional json header - setAdditionalJsonHeader(header); - return getAdditionalJsonParameter(key); +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(detId) + + " 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; + } +} + +void Module::setAdditionalJsonParameter(const std::string &key, const std::string &value) { + if (!shm()->useReceiverFlag) { + throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json parameter)"); + } + 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); } std::string Module::getAdditionalJsonParameter(const std::string &key) { - // additional json header is empty - std::string jsonheader = getAdditionalJsonHeader(); - if (jsonheader.empty()) - return jsonheader; - - // add quotations before and after the key value - std::string keyLiteral = key; - keyLiteral.insert(0, "\""); - keyLiteral.append("\""); - - // loop through the parameters - for (const auto ¶meter : - sls::split(jsonheader, ',')) { - // get a vector of key value pair for each parameter - const auto &pairs = sls::split(parameter, ':'); - // match for key - if (pairs[0] == keyLiteral) { - // return value without quotations (if it has any) - if (pairs[1][0] == '\"') - return pairs[1].substr(1, pairs[1].length() - 2); - else - return pairs[1]; - } + if (!shm()->useReceiverFlag) { + throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json parameter)"); } - // return empty string as no match found with key - return std::string(); + 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; } int64_t Module::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize) { @@ -2282,9 +2129,6 @@ std::vector Module::getVetoPhoton(const int chipIndex) { client.Receive(adus, sizeof(adus)); std::vector retvals(adus, adus + nch); LOG(logDEBUG1) << "Getting veto photon [" << chipIndex << "]: " << nch << " channels\n"; - if (ret == FORCE_UPDATE) { - updateCachedDetectorVariables(); - } return retvals; } } @@ -2371,11 +2215,7 @@ void Module::setVetoPhoton(const int chipIndex, const int numPhotons, const int client.Receive(mess, MAX_STR_LENGTH); throw RuntimeError("Detector " + std::to_string(detId) + " returned error: " + std::string(mess)); - } else { - if (ret == FORCE_UPDATE) { - updateCachedDetectorVariables(); - } - } + } } void Module::setVetoReference(const int gainIndex, const int value) { @@ -2388,15 +2228,17 @@ slsDetectorDefs::burstMode Module::getBurstMode() { int retval = -1; sendToDetector(F_GET_BURST_MODE, nullptr, retval); LOG(logDEBUG1) << "Burst mode:" << retval; - shm()->burstMode = static_cast(retval); - return shm()->burstMode; + return static_cast(retval); } 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); - shm()->burstMode = value; + if (shm()->useReceiverFlag) { + LOG(logDEBUG1) << "Sending burst mode to Receiver: " << value; + sendToReceiver(F_SET_RECEIVER_BURST_MODE, value, nullptr); + } } bool Module::getCurrentSource() { @@ -2672,24 +2514,6 @@ int Module::setAllTrimbits(int val) { return retval; } -int Module::enableGapPixels(int val) { - if (val >= 0) { - if (shm()->myDetectorType != EIGER) { - throw NotImplementedError( - "Function (enableGapPixels) not implemented for this detector"); - } - int fnum = F_ENABLE_GAPPIXELS_IN_RECEIVER; - int retval = -1; - LOG(logDEBUG1) << "Sending gap pixels enable to receiver: " << val; - if (shm()->useReceiverFlag) { - sendToReceiver(fnum, val, retval); - LOG(logDEBUG1) << "Gap pixels enable to receiver:" << retval; - shm()->gappixels = retval; - } - } - return shm()->gappixels; -} - int Module::setTrimEn(const std::vector& energies) { if (shm()->myDetectorType != EIGER) { throw RuntimeError("setTrimEn not implemented for this detector."); @@ -2959,22 +2783,15 @@ void Module::setModule(sls_detector_module &module, int tb) { } client.Receive(&retval, sizeof(retval)); LOG(logDEBUG1) << "Set Module returned: " << retval; - if (ret == FORCE_UPDATE) { - updateCachedDetectorVariables(); - } } sls_detector_module Module::getModule() { int fnum = F_GET_MODULE; - int ret = FAIL; LOG(logDEBUG1) << "Getting module"; sls_detector_module myMod{shm()->myDetectorType}; auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - ret = client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); + client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); receiveModule(&myMod, client); - if (ret == FORCE_UPDATE) { - updateCachedDetectorVariables(); - } return myMod; } @@ -2982,37 +2799,23 @@ void Module::setDefaultRateCorrection() { LOG(logDEBUG1) << "Setting Default Rate Correction"; int64_t arg = -1; sendToDetector(F_SET_RATE_CORRECT, arg, nullptr); - shm()->deadTime = -1; } void Module::setRateCorrection(int64_t t) { LOG(logDEBUG1) << "Setting Rate Correction to " << t; sendToDetector(F_SET_RATE_CORRECT, t, nullptr); - shm()->deadTime = t; } int64_t Module::getRateCorrection() { int64_t retval = -1; - LOG(logDEBUG1) << "Getting rate correction"; sendToDetector(F_GET_RATE_CORRECT, nullptr, retval); - shm()->deadTime = retval; LOG(logDEBUG1) << "Rate correction: " << retval; return retval; } void Module::updateRateCorrection() { - if (shm()->deadTime != 0) { - switch (shm()->dynamicRange) { - case 16: - case 32: - setRateCorrection(shm()->deadTime); - break; - default: - setRateCorrection(0); - throw sls::RuntimeError( - "Rate correction Deactivated, must be in 32 or 16 bit mode"); - } - } + LOG(logDEBUG1) << "Updating rate correction"; + sendToDetector(F_UPDATE_RATE_CORRECTION); } std::string Module::printReceiverConfiguration() { @@ -3084,33 +2887,6 @@ void Module::execReceiverCommand(const std::string &cmd) { } } -void Module::updateCachedReceiverVariables() const { - int fnum = F_UPDATE_RECEIVER_CLIENT; - LOG(logDEBUG1) << "Sending update client to receiver server"; - - if (shm()->useReceiverFlag) { - auto receiver = - sls::ClientSocket("Receiver", shm()->rxHostname, shm()->rxTCPPort); - receiver.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); - int n = 0, i32 = 0; - IpAddr ip; - - n += receiver.Receive(&ip, sizeof(ip)); - LOG(logDEBUG1) - << "Updating receiver last modified by " << ip; - - // gap pixels - n += receiver.Receive(&i32, sizeof(i32)); - shm()->gappixels = i32; - - if (n == 0) { - throw RuntimeError( - "Could not update receiver: " + std::string(shm()->rxHostname) + - ", received 0 bytes\n"); - } - } -} - void Module::sendMultiDetectorSize() { int args[]{shm()->multiSize.x, shm()->multiSize.y}; int retval = -1; @@ -3269,6 +3045,7 @@ void Module::setPartialFramesPadding(bool padding) { void Module::startReceiver() { LOG(logDEBUG1) << "Starting Receiver"; + shm()->stoppedFlag = false; if (shm()->useReceiverFlag) { sendToReceiver(F_START_RECEIVER, nullptr, nullptr); } @@ -3316,9 +3093,6 @@ std::vector Module::getNumMissingPackets() const { throw RuntimeError("Receiver " + std::to_string(detId) + " returned error: " + std::string(mess)); } else { - if (ret == FORCE_UPDATE) { - updateCachedReceiverVariables(); - } int nports = -1; client.Receive(&nports, sizeof(nports)); uint64_t mp[nports]; @@ -3342,6 +3116,15 @@ uint64_t Module::getReceiverCurrentFrameIndex() const { return retval; } +int Module::getReceiverProgress() const { + int retval = -1; + if (shm()->useReceiverFlag) { + sendToReceiver(F_GET_RECEIVER_PROGRESS, nullptr, retval); + LOG(logDEBUG1) << "Current Progress of Receiver: " << retval; + } + return retval; +} + void Module::setFileWrite(bool value) { if (!shm()->useReceiverFlag) { throw RuntimeError("Set rx_hostname first to use receiver parameters (file write enable)"); @@ -3433,6 +3216,10 @@ 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) { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 1567c6165..270db3c68 100755 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -9,11 +9,12 @@ #include #include #include +#include class ServerInterface; #define SLS_SHMAPIVERSION 0x190726 -#define SLS_SHMVERSION 0x200318 +#define SLS_SHMVERSION 0x200402 namespace sls{ @@ -61,33 +62,6 @@ struct sharedSlsDetector { /** number of dacs per module*/ int nDacs; - /** dynamic range of the detector data */ - int dynamicRange; - - /** detector settings (standard, fast, etc.) */ - slsDetectorDefs::detectorSettings currentSettings; - - /** number of frames */ - int64_t nFrames; - - /** number of triggers */ - int64_t nTriggers; - - /** number of bursts */ - int64_t nBursts; - - /** number of additional storage cells */ - int nAddStorageCells; - - /** timing mode */ - slsDetectorDefs::timingMode timingMode; - - /** burst mode */ - slsDetectorDefs::burstMode burstMode; - - /** rate correction in ns (needed for default -1) */ - int64_t deadTime; - /** ip address/hostname of the receiver for client control via TCP */ char rxHostname[MAX_STR_LENGTH]; @@ -104,12 +78,6 @@ struct sharedSlsDetector { /** zmq tcp src ip address in client (only data) **/ sls::IpAddr zmqip; - /** gap pixels enable */ - int gappixels; - - /** gap pixels in each direction */ - slsDetectorDefs::xy nGappixels; - /** num udp interfaces */ int numUDPInterfaces; @@ -221,10 +189,7 @@ class Module : public virtual slsDetectorDefs { */ void updateNumberOfChannels(); - /** - * Returns the total number of channels including gap pixels - * @returns the total number of channels including gap pixels - */ + slsDetectorDefs::xy getNumberOfChannels() const; /** @@ -306,21 +271,12 @@ class Module : public virtual slsDetectorDefs { */ void execCommand(const std::string &cmd); - /** - * Updates some of the shared memory receiving the data from the detector - */ - void updateCachedDetectorVariables(); - /** * Get detector specific commands to write into config file * @returns vector of strings with commands */ std::vector getConfigFileCommands(); - /** - * Get detector settings - * @returns current settings - */ detectorSettings getSettings(); /** [Jungfrau] Options:DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2 @@ -328,18 +284,8 @@ class Module : public virtual slsDetectorDefs { * [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 - * [Eiger] Only stores them locally in shm Options: STANDARD, HIGHGAIN, LOWGAIN, VERYHIGHGAIN, VERYLOWGAIN */ - detectorSettings setSettings(detectorSettings isettings); - - /** - * Send detector settings only (set only for Jungfrau, Gotthard, Moench, get - * for all) Only the settings enum is sent to the detector, where it will - * initialize al the dacs already hard coded in the detector server - * @param isettings settings - * @returns current settings - */ - detectorSettings sendSettingsOnly(detectorSettings isettings); + void setSettings(detectorSettings isettings); /** * Get threshold energy (Mythen and Eiger) @@ -353,9 +299,8 @@ class Module : public virtual slsDetectorDefs { * @param e_eV threshold in eV * @param isettings ev. change settings * @param tb 1 to include trimbits, 0 to exclude - * @returns current threshold value in ev (-1 failed) */ - int setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS, + void setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS, int tb = 1); /** @@ -454,10 +399,6 @@ class Module : public virtual slsDetectorDefs { */ uint64_t getStartingFrameNumber(); - int64_t getTotalNumFramesToReceive(); - - void sendTotalNumFramestoReceiver(); - int64_t getNumberOfFrames(); void setNumberOfFrames(int64_t value); @@ -565,22 +506,17 @@ class Module : public virtual slsDetectorDefs { * [Gotthard2] only in continuous mode */ int64_t getMeasurementTime() const; - /** - * Set/get timing mode - * @param value timing mode (-1 gets) - * @returns current timing mode - */ - timingMode setTimingMode(timingMode value = GET_TIMING_MODE); + 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) - * @param i dynamic range (-1 get) - * @returns current dynamic range - * \sa sharedSlsDetector */ - int setDynamicRange(int n = -1); + void setDynamicRange(int n); /** * Set/get dacs value @@ -988,36 +924,14 @@ class Module : public virtual slsDetectorDefs { */ void setTransmissionDelayRight(int value); - /** - * Sets the additional json header\sa sharedSlsDetector - * @param jsonheader additional json header - */ - void setAdditionalJsonHeader(const std::string &jsonheader); + /** empty vector deletes entire additional json header */ + void setAdditionalJsonHeader(const std::map &jsonHeader); + std::map getAdditionalJsonHeader(); /** - * Returns the additional json header \sa sharedSlsDetector - * @returns the additional json header, returns "none" if default setting - * and no custom ip set - */ - std::string getAdditionalJsonHeader(); - - /** - * Sets the value for the additional json header parameter if found, else - * append it - * @param key additional json header parameter - * @param value additional json header parameter value (cannot be empty) - * @returns the additional json header parameter value, - * empty if no parameter found in additional json header - */ - std::string setAdditionalJsonParameter(const std::string &key, - const std::string &value); - - /** - * Returns the additional json header parameter value - * @param key additional json header parameter - * @returns the additional json header parameter value, - * empty if no parameter found in additional json header - */ + * 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); /** @@ -1045,11 +959,13 @@ class Module : public virtual slsDetectorDefs { /** [Gotthard][Jungfrau][CTB][Moench] */ void executeBusTest(); - /** [Gotthard] */ + /** [Gotthard][Eiger virtual] */ int getImageTestMode(); /** [Gotthard] If 1, adds channel intensity with precalculated values. - * Default is 0 */ + * Default is 0 + * [Eiger virtual] If 1, pixels are saturated. If 0, increasing intensity + * Only for virtual servers */ void setImageTestMode(const int value); @@ -1232,14 +1148,6 @@ class Module : public virtual slsDetectorDefs { */ int setAllTrimbits(int val); - /** - * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) - * 4 bit mode gap pixels only in gui call back - * @param val 1 sets, 0 unsets, -1 gets - * @returns gap pixel enable or -1 for error - */ - int enableGapPixels(int val = -1); - /** * Sets the number of trim energies and their value (Eiger) * \sa sharedSlsDetector @@ -1436,11 +1344,6 @@ class Module : public virtual slsDetectorDefs { */ void execReceiverCommand(const std::string &cmd); - /** - * Updates the shared memory receiving the data from the detector - */ - void updateCachedReceiverVariables() const; - /** * Send the multi detector size to the detector * @param detx number of detectors in x dir @@ -1509,6 +1412,7 @@ class Module : public virtual slsDetectorDefs { * @returns current frame index of receiver */ uint64_t getReceiverCurrentFrameIndex() const; + int getReceiverProgress() const; void setFileWrite(bool value); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp b/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp index 31de04247..b6446ea5f 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp @@ -15,7 +15,9 @@ using sls::Detector; using test::GET; using test::PUT; -TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") { +/* dacs */ + +TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs][.new]") { // dac 0 to dac 17 Detector det; @@ -23,12 +25,12 @@ TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") { auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { for (int i = 0; i < 18; ++i) { - SECTION("dac " + std::to_string(i)) { test_dac(static_cast(i), "dac " + std::to_string(i), 0); } + SECTION("dac " + std::to_string(i)) { test_dac(static_cast(i), "dac", 0); } } // eiger - REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET)); @@ -51,30 +53,30 @@ TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") { REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); // gotthard - REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); // mythen3 - REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); + //REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp index 10bbb7cf6..7b254acff 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp @@ -13,6 +13,245 @@ using sls::CmdProxy; using sls::Detector; using test::GET; using test::PUT; + + +/** temperature */ + +TEST_CASE("temp_fpgaext", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_fpgaext", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_fpgaext", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_fpgaext ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_fpgaext", {}, -1, GET)); + } +} + +TEST_CASE("temp_10ge", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_10ge", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_10ge", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_10ge ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_10ge", {}, -1, GET)); + } +} + +TEST_CASE("temp_dcdc", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_dcdc", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_dcdc", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_dcdc ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_dcdc", {}, -1, GET)); + } +} + +TEST_CASE("temp_sodl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_sodl", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_sodl", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_sodl ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_sodl", {}, -1, GET)); + } +} + +TEST_CASE("temp_sodr", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_sodr", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_sodr", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_sodr ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_sodr", {}, -1, GET)); + } +} + +TEST_CASE("temp_fpgafl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_fpgafl", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_fpgafl", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_fpgafl ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_fpgafl", {}, -1, GET)); + } +} + +TEST_CASE("temp_fpgafr", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_fpgafr", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_fpgafr", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_fpgafr ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_fpgafr", {}, -1, GET)); + } +} + +/* dacs */ + +TEST_CASE("Setting and reading back EIGER dacs", "[.cmd][.dacs][.new]") { + // vsvp, vtr, vrf, vrs, vsvn, vtgstv, vcmp_ll, vcmp_lr, vcal, vcmp_rl, + // rxb_rb, rxb_lb, vcmp_rr, vcp, vcn, vis, vthreshold + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + SECTION("vsvp") { test_dac(defs::SVP, "vsvp", 5); } + SECTION("vtr") { test_dac(defs::VRF, "vtr", 1200); } + SECTION("vrf") { test_dac(defs::VRF, "vrf", 1500); } + SECTION("vrs") { test_dac(defs::VRF, "vrs", 1510); } + SECTION("vsvn") { test_dac(defs::SVN, "vsvn", 3800); } + SECTION("vtgstv") { test_dac(defs::VTGSTV, "vtgstv", 2550); } + SECTION("vcmp_ll") { test_dac(defs::VCMP_LL, "vcmp_ll", 1400); } + SECTION("vcmp_lr") { test_dac(defs::VCMP_LR, "vcmp_lr", 1400); } + SECTION("vcal") { test_dac(defs::CAL, "vcal", 1400); } + SECTION("vcmp_rl") { test_dac(defs::VCMP_RL, "vcmp_rl", 1400); } + SECTION("rxb_rb") { test_dac(defs::RXB_RB, "rxb_rb", 1400); } + SECTION("rxb_lb") { test_dac(defs::RXB_LB, "rxb_lb", 1400); } + SECTION("vcmp_rr") { test_dac(defs::VCMP_RR, "vcmp_rr", 1400); } + SECTION("vcp") { test_dac(defs::VCP, "vcp", 1400); } + SECTION("vcn") { test_dac(defs::VCN, "vcn", 1400); } + SECTION("vis") { test_dac(defs::VIS, "vis", 1400); } + SECTION("iodelay") { test_dac(defs::IO_DELAY, "iodelay", 1400); } + SECTION("vthreshold") { + // Read out individual vcmp to be able to reset after + // the test is done + auto vcmp_ll = det.getDAC(defs::VCMP_LL, false); + auto vcmp_lr = det.getDAC(defs::VCMP_LR, false); + auto vcmp_rl = det.getDAC(defs::VCMP_RL, false); + auto vcmp_rr = det.getDAC(defs::VCMP_RR, false); + auto vcp = det.getDAC(defs::VCP, false); + + { + std::ostringstream oss; + proxy.Call("vthreshold", {"1234"}, -1, PUT, oss); + REQUIRE(oss.str() == "vthreshold 1234\n"); + } + { + std::ostringstream oss; + proxy.Call("vthreshold", {}, -1, GET, oss); + REQUIRE(oss.str() == "vthreshold 1234\n"); + } + + // Reset dacs after test + for (int i = 0; i != det.size(); ++i) { + det.setDAC(defs::VCMP_LL, vcmp_ll[i], false, {i}); + det.setDAC(defs::VCMP_LR, vcmp_ll[i], false, {i}); + det.setDAC(defs::VCMP_RL, vcmp_ll[i], false, {i}); + det.setDAC(defs::VCMP_RR, vcmp_ll[i], false, {i}); + det.setDAC(defs::VCP, vcp[i], false, {i}); + } + } + // gotthard + REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); + // mythen3 + REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); + // REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); + // REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET)); + // gotthard2 + REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET)); + // jungfrau + REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); + } +} + + + + + + + + + + + + + + + + + + + + + + + + TEST_CASE("Eiger transmission delay", "[.cmd]") { Detector det; @@ -280,110 +519,7 @@ TEST_CASE("quad", "[.cmd]") { } } -TEST_CASE("Setting and reading back EIGER dacs", "[.cmd][.dacs]") { - // vsvp, vtr, vrf, vrs, vsvn, vtgstv, vcmp_ll, vcmp_lr, vcal, vcmp_rl, - // rxb_rb, rxb_lb, vcmp_rr, vcp, vcn, vis, vthreshold - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::EIGER) { - SECTION("vsvp") { test_dac(defs::SVP, "vsvp", 5); } - SECTION("vtr") { test_dac(defs::VRF, "vtr", 1200); } - SECTION("vrf") { test_dac(defs::VRF, "vrf", 1500); } - SECTION("vrs") { test_dac(defs::VRF, "vrs", 1510); } - SECTION("vsvn") { test_dac(defs::SVN, "vsvn", 3800); } - SECTION("vtgstv") { test_dac(defs::VTGSTV, "vtgstv", 2550); } - SECTION("vcmp_ll") { test_dac(defs::VCMP_LL, "vcmp_ll", 1400); } - SECTION("vcmp_lr") { test_dac(defs::VCMP_LR, "vcmp_lr", 1400); } - SECTION("vcal") { test_dac(defs::CAL, "vcal", 1400); } - SECTION("vcmp_rl") { test_dac(defs::VCMP_RL, "vcmp_rl", 1400); } - SECTION("rxb_rb") { test_dac(defs::RXB_RB, "rxb_rb", 1400); } - SECTION("rxb_lb") { test_dac(defs::RXB_LB, "rxb_lb", 1400); } - SECTION("vcmp_rr") { test_dac(defs::VCMP_RR, "vcmp_rr", 1400); } - SECTION("vcp") { test_dac(defs::VCP, "vcp", 1400); } - SECTION("vcn") { test_dac(defs::VCN, "vcn", 1400); } - SECTION("vis") { test_dac(defs::VIS, "vis", 1400); } - SECTION("iodelay") { test_dac(defs::IO_DELAY, "iodelay", 1400); } - SECTION("vthreshold") { - // Read out individual vcmp to be able to reset after - // the test is done - auto vcmp_ll = det.getDAC(defs::VCMP_LL, false); - auto vcmp_lr = det.getDAC(defs::VCMP_LR, false); - auto vcmp_rl = det.getDAC(defs::VCMP_RL, false); - auto vcmp_rr = det.getDAC(defs::VCMP_RR, false); - auto vcp = det.getDAC(defs::VCP, false); - { - std::ostringstream oss; - proxy.Call("vthreshold", {"1234"}, -1, PUT, oss); - REQUIRE(oss.str() == "vthreshold 1234\n"); - } - { - std::ostringstream oss; - proxy.Call("vthreshold", {}, -1, GET, oss); - REQUIRE(oss.str() == "vthreshold 1234\n"); - } - - // Reset dacs after test - for (int i = 0; i != det.size(); ++i) { - det.setDAC(defs::VCMP_LL, vcmp_ll[i], false, {i}); - det.setDAC(defs::VCMP_LR, vcmp_ll[i], false, {i}); - det.setDAC(defs::VCMP_RL, vcmp_ll[i], false, {i}); - det.setDAC(defs::VCMP_RR, vcmp_ll[i], false, {i}); - det.setDAC(defs::VCP, vcp[i], false, {i}); - } - } - // gotthard - REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); - // mythen3 - REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); - // REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); - // REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET)); - // gotthard2 - REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET)); - // jungfrau - REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); - } -} // TEST_CASE("trigger", "[.cmd]") { // Detector det; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-global.cpp b/slsDetectorSoftware/tests/test-CmdProxy-global.cpp index c0104b85d..b8de30eea 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-global.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-global.cpp @@ -16,12 +16,46 @@ void test_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) { std::ostringstream oss_set, oss_get; auto dacstr = std::to_string(dacvalue); auto previous = det.getDAC(index, false); - proxy.Call(dacname, {dacstr}, -1, PUT, oss_set); - REQUIRE(oss_set.str() == dacname + " " + dacstr + "\n"); - proxy.Call(dacname, {}, -1, GET, oss_get); - REQUIRE(oss_get.str() == dacname + " " + dacstr + "\n"); + // chip test board + if (dacname == "dac") { + auto dacIndexstr = std::to_string(static_cast(index)); + proxy.Call(dacname, {dacIndexstr, dacstr}, -1, PUT, oss_set); + REQUIRE(oss_set.str() == dacname + " " + dacIndexstr + " " + dacstr + "\n"); + proxy.Call(dacname, {dacIndexstr}, -1, GET, oss_get); + REQUIRE(oss_get.str() == dacname + " " + dacIndexstr + " " + dacstr + "\n"); + } + // other detectors + else { + proxy.Call(dacname, {dacstr}, -1, PUT, oss_set); + REQUIRE(oss_set.str() == dacname + " " + dacstr + "\n"); + proxy.Call(dacname, {}, -1, GET, oss_get); + REQUIRE(oss_get.str() == dacname + " " + dacstr + "\n"); + } // Reset all dacs to previous value for (int i = 0; i != det.size(); ++i) { det.setDAC(index, previous[i], false, {i}); } } + +void test_onchip_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) { + Detector det; + CmdProxy proxy(&det); + REQUIRE_THROWS(proxy.Call(dacname, {}, -1, GET)); + REQUIRE_THROWS(proxy.Call(dacname, {"10", "0x0"}, -1, PUT)); // chip index (-1 to 9) + REQUIRE_THROWS(proxy.Call(dacname, {"-1", "0x400"}, -1, PUT)); // max val is 0x3ff + + int chipIndex = -1; // for now, it is -1 only + auto prev_val = det.getOnChipDAC(index, chipIndex); + auto dacValueStr = sls::ToStringHex(dacvalue); + auto chipIndexStr = std::to_string(chipIndex); + std::ostringstream oss_set, oss_get; + proxy.Call(dacname, {chipIndexStr, dacValueStr}, -1, PUT, oss_set); + REQUIRE(oss_set.str() == dacname + " " + chipIndexStr + " " + dacValueStr + "\n"); + proxy.Call(dacname, {chipIndexStr}, -1, GET, oss_get); + REQUIRE(oss_get.str() == dacname + " " + chipIndexStr + " " + dacValueStr + "\n"); + + // Reset all dacs to previous value + for (int i = 0; i != det.size(); ++i) { + det.setOnChipDAC(index, chipIndex, prev_val[i], {i}); + } +} \ No newline at end of file diff --git a/slsDetectorSoftware/tests/test-CmdProxy-global.h b/slsDetectorSoftware/tests/test-CmdProxy-global.h index 32a56f42a..4d14cdfa5 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-global.h +++ b/slsDetectorSoftware/tests/test-CmdProxy-global.h @@ -1,4 +1,5 @@ #pragma once #include "sls_detector_defs.h" -void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue); \ No newline at end of file +void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue); +void test_onchip_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-gotthard.cpp b/slsDetectorSoftware/tests/test-CmdProxy-gotthard.cpp index b253eca03..70b22ee17 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-gotthard.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-gotthard.cpp @@ -15,7 +15,9 @@ using sls::Detector; using test::GET; using test::PUT; -TEST_CASE("Setting and reading back GOTTHARD dacs", "[.cmd][.dacs]") { +/* dacs */ + +TEST_CASE("Setting and reading back GOTTHARD dacs", "[.cmd][.dacs][.new]") { // vref_ds, vcascn_pb, vcascp_pb, vout_cm, vcasc_out, vin_cm, vref_comp, ib_test_c Detector det; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp index 6b70975b7..88e0169d9 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp @@ -15,7 +15,82 @@ using sls::Detector; using test::GET; using test::PUT; -TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") { +/* acquisition parameters */ + +TEST_CASE("bursts", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + auto prev_burst = det.getNumberOfBursts().tsquash("#bursts should be same to test"); + auto prev_trigger = det.getNumberOfFrames().tsquash("#frames should be same to test"); + auto prev_frames = det.getNumberOfTriggers().tsquash("#triggers should be same to test"); + auto prev_timingMode = det.getTimingMode(); + auto prev_burstMode = det.getBurstMode(); + // changing continuous mode frames and bursts + det.setBurstMode(defs::BURST_INTERNAL); + det.setTimingMode(defs::AUTO_TIMING); + { + std::ostringstream oss; + proxy.Call("bursts", {"3"}, -1, PUT, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + { + std::ostringstream oss; + proxy.Call("bursts", {}, -1, GET, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + REQUIRE_THROWS(proxy.Call("bursts", {"0"}, -1, PUT)); + // trigger mode: reg set to 1, but bursts must be same + det.setTimingMode(defs::TRIGGER_EXPOSURE); + { + std::ostringstream oss; + proxy.Call("bursts", {}, -1, GET, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + det.setTimingMode(defs::AUTO_TIMING); + { + std::ostringstream oss; + proxy.Call("bursts", {}, -1, GET, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + // continuous mode: reg set to #frames, + // but bursts should return same value + det.setBurstMode(defs::BURST_OFF); + det.setNumberOfFrames(2); + { + std::ostringstream oss; + proxy.Call("bursts", {}, -1, GET, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + det.setTimingMode(defs::TRIGGER_EXPOSURE); + { + std::ostringstream oss; + proxy.Call("bursts", {}, -1, GET, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + det.setBurstMode(defs::BURST_INTERNAL); + { + std::ostringstream oss; + proxy.Call("bursts", {}, -1, GET, oss); + REQUIRE(oss.str() == "bursts 3\n"); + } + // set to previous values + det.setNumberOfBursts(prev_burst); + det.setNumberOfFrames(prev_frames); + det.setNumberOfTriggers(prev_trigger); + for (int i = 0; i != det.size(); ++i) { + det.setTimingMode(prev_timingMode[i], {i}); + det.setBurstMode(prev_burstMode[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("bursts", {}, -1, GET)); + } +} + +/* dacs */ + +TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs][.new]") { // vref_h_adc, vb_comp_fe, vb_comp_adc, vcom_cds, // vref_restore, vb_opa_1st, vref_comp_fe, vcom_adc1, // vref_prech, vref_l_adc, vref_cds, vb_cs, @@ -96,45 +171,89 @@ TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") { } } -TEST_CASE("vchip", "[.cmd][.onchipdacs]") { +/* on chip dacs */ + +TEST_CASE("vchip_comp_fe", "[.cmd][.onchipdacs][.new]") { Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::GOTTHARD2) { - std::vector on_chip_dac_names = {"vchip_comp_fe", "vchip_opa_1st", "vchip_opa_fd", "vchip_comp_adc", "vchip_ref_comp_fe", "vchip_cs"}; - std::vector on_chip_dac_indices = {defs::VB_COMP_FE, defs::VB_OPA_1ST, defs::VB_OPA_FD, defs::VB_COMP_ADC, defs::VREF_COMP_FE, defs::VB_CS}; - std::vector values = {0x137, 0x000, 0x134, 0x3FF, 0x100, 0x0D0}; - - for (size_t i = 0; i < on_chip_dac_names.size(); ++i) { - REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {}, -1, GET)); - REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"10", "0x0"}, -1, GET)); // chip index (-1 to 9) - REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"-1", "0x400"}, -1, GET)); // max val is 0x3ff - - auto previous = det.getOnChipDAC(on_chip_dac_indices[i], -1); - auto dacstr = sls::ToStringHex(values[i]); - int chip_index = -1; - auto chip_index_str = std::to_string(chip_index); - - std::ostringstream oss_set, oss_get; - proxy.Call(on_chip_dac_names[i], {chip_index_str, dacstr}, -1, PUT, oss_set); - REQUIRE(oss_set.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n"); - proxy.Call(on_chip_dac_names[i], {chip_index_str}, -1, GET, oss_get); - REQUIRE(oss_get.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n"); - // Reset all dacs to previous value - for (int i = 0; i != det.size(); ++i) { - det.setOnChipDAC(on_chip_dac_indices[i], chip_index, previous[i], {i}); - } - } + SECTION("vchip_comp_fe") { test_onchip_dac(defs::VB_COMP_FE, "vchip_comp_fe", 0x137); } } else { REQUIRE_THROWS(proxy.Call("vchip_comp_fe", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET)); } } +TEST_CASE("vchip_opa_1st", "[.cmd][.onchipdacs][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + SECTION("vchip_opa_1st") { test_onchip_dac(defs::VB_OPA_1ST, "vchip_opa_1st", 0x000); } + } else { + REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET)); + } +} + +TEST_CASE("vchip_opa_fd", "[.cmd][.onchipdacs][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + SECTION("vchip_opa_fd") { test_onchip_dac(defs::VB_OPA_FD, "vchip_opa_fd", 0x134); } + } else { + REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET)); + } +} + +TEST_CASE("vchip_comp_adc", "[.cmd][.onchipdacs][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + SECTION("vchip_comp_adc") { test_onchip_dac(defs::VB_COMP_ADC, "vchip_comp_adc", 0x3FF); } + } else { + REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET)); + } +} + +TEST_CASE("vchip_ref_comp_fe", "[.cmd][.onchipdacs][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + SECTION("vchip_ref_comp_fe") { test_onchip_dac(defs::VREF_COMP_FE, "vchip_ref_comp_fe", 0x100); } + } else { + REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET)); + } +} + +TEST_CASE("vchip_cs", "[.cmd][.onchipdacs][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + SECTION("vchip_cs") { test_onchip_dac(defs::VB_CS, "vchip_cs", 0x0D0); } + } else { + REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET)); + } +} + + + + + + + + + + + + + + + + TEST_CASE("burstmode", "[.cmd]") { Detector det; @@ -229,35 +348,7 @@ TEST_CASE("inj_ch", "[.cmd]") { } -TEST_CASE("bursts", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::GOTTHARD2) { - auto previous = det.getNumberOfBursts().squash(1); - auto previousTrigger = det.getNumberOfTriggers().squash(1); - - std::ostringstream oss_set, oss_get; - proxy.Call("bursts", {"3"}, -1, PUT, oss_set); - REQUIRE(oss_set.str() == "bursts 3\n"); - - // change to trigger and back (bursts should still be same) - proxy.Call("timing", {"trigger"}, -1, PUT); - proxy.Call("triggers", {"2"}, -1, PUT); - proxy.Call("timing", {"auto"}, -1, PUT); - - - proxy.Call("bursts", {}, -1, GET, oss_get); - REQUIRE(oss_get.str() == "bursts 3\n"); - - - det.setNumberOfBursts(previous); - det.setNumberOfTriggers(previousTrigger); - } else { - REQUIRE_THROWS(proxy.Call("bursts", {}, -1, GET)); - } -} TEST_CASE("burstperiod", "[.cmd]") { Detector det; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp index 30dda3df2..e387d3462 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp @@ -13,38 +13,116 @@ using sls::Detector; using test::GET; using test::PUT; -TEST_CASE("powerchip", "[.cmd][!mayfail]") { - // TODO! this test currently fails with the - // virtual detecto server +/* dacs */ + +TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd][.dacs][.new]") { + // vb_comp, vdd_prot, vin_com, vref_prech, vb_pixbuf, vb_ds, vref_ds, vref_comp Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); - if (det_type == defs::JUNGFRAU) { - auto pc = det.getPowerChip(); - { - std::ostringstream oss; - proxy.Call("powerchip", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "powerchip 1\n"); - } - { - std::ostringstream oss; - proxy.Call("powerchip", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "powerchip 0\n"); - } - { - std::ostringstream oss; - proxy.Call("powerchip", {}, -1, GET, oss); - REQUIRE(oss.str() == "powerchip 0\n"); - } - for (int i = 0; i != det.size(); ++i) { - det.setPowerChip(pc[i], {i}); - } - } else { - REQUIRE_THROWS(proxy.Call("powerchip", {}, -1, GET)); + SECTION("vb_comp") { test_dac(defs::VB_COMP, "vb_comp", 1220); } + SECTION("vdd_prot") { test_dac(defs::VDD_PROT, "vdd_prot", 3000); } + SECTION("vin_com") { test_dac(defs::VIN_COM, "vin_com", 1053); } + SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1450); } + SECTION("vb_pixbuf") { test_dac(defs::VB_PIXBUF, "vb_pixbuf", 750); } + SECTION("vb_ds") { test_dac(defs::VB_DS, "vb_ds", 1000); } + SECTION("vref_ds") { test_dac(defs::VREF_DS, "vref_ds", 480); } + SECTION("vref_comp") { test_dac(defs::VREF_COMP, "vref_comp", 420); } + // eiger + REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET)); + // gotthard + // REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); + // REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); + // mythen3 + REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET)); + // gotthard2 + REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET)); } } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TEST_CASE("nframes", "[.cmd]") { Detector det; CmdProxy proxy(&det); @@ -158,78 +236,3 @@ TEST_CASE("resetfpga", "[.cmd]") { } -TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd]") { - // vb_comp, vdd_prot, vin_com, vref_prech, vb_pixbuf, vb_ds, vref_ds, vref_comp - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::JUNGFRAU) { - SECTION("vb_comp") { test_dac(defs::VB_COMP, "vb_comp", 1220); } - SECTION("vdd_prot") { test_dac(defs::VDD_PROT, "vdd_prot", 3000); } - SECTION("vin_com") { test_dac(defs::VIN_COM, "vin_com", 1053); } - SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1450); } - SECTION("vb_pixbuf") { test_dac(defs::VB_PIXBUF, "vb_pixbuf", 750); } - SECTION("vb_ds") { test_dac(defs::VB_DS, "vb_ds", 1000); } - SECTION("vref_ds") { test_dac(defs::VREF_DS, "vref_ds", 480); } - SECTION("vref_comp") { test_dac(defs::VREF_COMP, "vref_comp", 420); } - // eiger - REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET)); - // gotthard - // REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); - // REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); - // mythen3 - REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET)); - // gotthard2 - REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET)); - } -} diff --git a/slsDetectorSoftware/tests/test-CmdProxy-moench.cpp b/slsDetectorSoftware/tests/test-CmdProxy-moench.cpp index b7d62c1d9..03cd5e59b 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-moench.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-moench.cpp @@ -15,7 +15,9 @@ using sls::Detector; using test::GET; using test::PUT; -TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs]") { +/* dacs */ + +TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs][.new]") { // vbp_colbuf, vipre, vin_cm", vb_sda, vcasc_sfp, vout_cm, vipre_cds, ibias_sfp Detector det; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp b/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp index 406d43d66..be749292c 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp @@ -15,7 +15,9 @@ using sls::Detector; using test::GET; using test::PUT; -TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs]") { +/* dacs */ + +TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs][.new]") { // vcassh, vth2, vshaper, vshaperneg, vipre_out, vth3, vth1, // vicin, vcas, vpreamp, vpl, vipre, viinsh, vph, vtrim, vdcsh, @@ -87,88 +89,21 @@ TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs]") { } } -TEST_CASE("clkfreq", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { - REQUIRE_THROWS(proxy.Call("clkfreq", {"0", "2"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("clkfreq", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("clkfreq", {"7"}, -1, GET)); - auto value = det.getClockFrequency(0).squash(-1); - std::ostringstream oss_set, oss_get; - proxy.Call("clkfreq", {"0"}, -1, GET, oss_get); - REQUIRE(oss_get.str() == "clkfreq " + std::to_string(value) + "\n"); - } else { - REQUIRE_THROWS(proxy.Call("clkfreq", {"0"}, -1, GET)); - } -} -TEST_CASE("clkphase", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { - REQUIRE_THROWS(proxy.Call("clkphase", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("clkphase", {"7"}, -1, GET)); - REQUIRE_THROWS(proxy.Call("clkphase", {"4"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("clkphase", {"7", "4"}, -1, PUT)); - auto previous = det.getClockFrequency(0).squash(-1); - auto previous_string = std::to_string(previous); - std::ostringstream oss_set, oss_get, oss_get2; - proxy.Call("clkfreq", {"0", previous_string}, -1, PUT, oss_set); - REQUIRE(oss_set.str() == "clkfreq" + previous_string + "\n"); - proxy.Call("clkfreq", {"0"}, -1, GET, oss_get); - REQUIRE(oss_get.str() == "clkfreq " + previous_string + "\n"); - REQUIRE_NOTHROW(proxy.Call("clkphase", {"0", "deg"}, -1, GET)); - } else { - REQUIRE_THROWS(proxy.Call("clkphase", {"0"}, -1, GET)); - } -} -TEST_CASE("clkdiv", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { - REQUIRE_THROWS(proxy.Call("clkdiv", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("clkdiv", {"7"}, -1, GET)); - REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("clkdiv", {"0", "1"}, -1, PUT)); - auto previous = det.getClockDivider(0).squash(-1); - auto previous_string = std::to_string(previous); - std::ostringstream oss_set, oss_get; - proxy.Call("clkdiv", {"0", previous_string}, -1, PUT, oss_set); - REQUIRE(oss_set.str() == "clkdiv" + previous_string + "\n"); - proxy.Call("clkdiv", {"0"}, -1, GET, oss_get); - REQUIRE(oss_get.str() == "clkdiv " + previous_string + "\n"); - } else { - REQUIRE_THROWS(proxy.Call("clkdiv", {"0"}, -1, GET)); - } -} -TEST_CASE("maxclkphaseshift", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { - REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0", "2"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"7"}, -1, GET)); - auto value = det.getMaxClockPhaseShift(0).squash(-1); - std::ostringstream oss_set, oss_get; - proxy.Call("maxclkphaseshift", {"0"}, -1, GET, oss_get); - REQUIRE(oss_get.str() == - "maxclkphaseshift " + std::to_string(value) + "\n"); - } else { - REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0"}, -1, GET)); - } -} + + + + + + + + TEST_CASE("counters", "[.cmd]") { Detector det; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp b/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp index f47d95864..767e646e2 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp @@ -15,97 +15,11 @@ using test::PUT; /* This file should contain receiver specific tests use python/scripts/list_tested_cmd.py to check if all commands are covered - */ -// TEST_CASE("A test", "[.hey]"){ -// std::cout << "start\n"; -// SECTION("a section"){ -// std::cout << "s1\n"; -// } -// SECTION("another section"){ -// std::cout << "s2\n"; -// } -// std::cout << "end\n"; -// } +/* configuration */ -TEST_CASE("rx_hostname", "[.cmd][.rx]") { - // TODO! find a proper way to test, now we read out the rx_hostname - // and then put it to see that we don't crash - Detector det; - CmdProxy proxy(&det); - std::string hostname = - det.getRxHostname().tsquash("hostname must be same for test"); - - auto det_type = det.getDetectorType().squash(); - sls::Result time; - if (det_type == defs::EIGER) { - time = det.getSubDeadTime(); - } - - { - // disable receiver - std::ostringstream oss1, oss2; - proxy.Call("rx_hostname", {"none"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "rx_hostname none\n"); - proxy.Call("rx_hostname", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "rx_hostname none\n"); - // receiver should be disabled - REQUIRE(det.getUseReceiverFlag().tsquash( - "different values of flag in test") == false); - } - { - // put back the old hostname - std::ostringstream oss1, oss2; - proxy.Call("rx_hostname", {hostname}, -1, PUT, oss1); - REQUIRE(oss1.str() == "rx_hostname " + hostname + "\n"); - proxy.Call("rx_hostname", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "rx_hostname " + hostname + "\n"); - } - - //Bug rx_hostname could change subdeadtime - if (det_type == defs::EIGER) { - auto time2 = det.getSubDeadTime(); - for (int i = 0; i != det.size(); ++i) { - REQUIRE(time[i].count() == time2[i].count()); - } - } -} - -TEST_CASE("rx_framescaught", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - - // This ensures 0 caught frames - det.startReceiver(); - det.stopReceiver(); - - { - std::ostringstream oss; - proxy.Call("rx_framescaught", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_framescaught 0\n"); - } - - // Currently disabled may activate if we have a stable env - // Now take one frame and see that we caught it - // det.setNumberOfFrames(1); - // det.acquire(); - // { - // std::ostringstream oss; - // proxy.Call("rx_framescaught", {}, -1, GET, oss); - // REQUIRE(oss.str() == "rx_framescaught 1\n"); - // } -} - -TEST_CASE("rx_status", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - std::ostringstream oss; - proxy.Call("rx_status", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_status idle\n"); -} - -TEST_CASE("rx_version", "[.cmd][.rx]") { +TEST_CASE("rx_version", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); std::ostringstream oss; @@ -113,9 +27,13 @@ TEST_CASE("rx_version", "[.cmd][.rx]") { std::ostringstream vs; vs << "rx_version 0x" << std::hex << APIRECEIVER << '\n'; REQUIRE(oss.str() == vs.str()); + + REQUIRE_THROWS(proxy.Call("rx_version", {"0"}, -1, PUT)); } -TEST_CASE("rx_start", "[.cmd][.rx]") { +/* acquisition */ + +TEST_CASE("rx_start", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); // PUT only command @@ -132,7 +50,7 @@ TEST_CASE("rx_start", "[.cmd][.rx]") { } } -TEST_CASE("rx_stop", "[.cmd][.rx]") { +TEST_CASE("rx_stop", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); // PUT only command @@ -149,41 +67,143 @@ TEST_CASE("rx_stop", "[.cmd][.rx]") { } } -TEST_CASE("rx_missingpackets", "[.cmd][.rx]") { - // TODO! This only tests for no crash how can we test - // for correct values? +TEST_CASE("rx_status", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); - proxy.Call("rx_missingpackets", {}, -1, GET); + det.startReceiver(); + { + std::ostringstream oss; + proxy.Call("rx_status", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_status running\n"); + } + det.stopReceiver(); + { + std::ostringstream oss; + proxy.Call("rx_status", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_status idle\n"); + } } -TEST_CASE("rx_frameindex", "[.cmd][.rx]") { +TEST_CASE("rx_framescaught", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); - proxy.Call("rx_frameindex", {}, -1, GET); - // This is a get only command - REQUIRE_THROWS(proxy.Call("rx_frameindex", {"2"}, -1, PUT)); + // This ensures 0 caught frames + det.startReceiver(); + det.stopReceiver(); + { + std::ostringstream oss; + proxy.Call("rx_framescaught", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_framescaught 0\n"); + } + + // Currently disabled may activate if we have a stable env + // Now take one frame and see that we caught it + // det.setNumberOfFrames(1); + // det.acquire(); + // { + // std::ostringstream oss; + // proxy.Call("rx_framescaught", {}, -1, GET, oss); + // REQUIRE(oss.str() == "rx_framescaught 1\n"); + // } + } -TEST_CASE("rx_lastclient", "[.cmd][.rx]") { +TEST_CASE("rx_missingpackets", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); - std::ostringstream oss; - proxy.Call("rx_lastclient", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_lastclient " + test::my_ip + "\n"); + { + // some missing packets + det.startReceiver(); + det.stopReceiver(); + std::ostringstream oss; + proxy.Call("rx_missingpackets", {}, -1, GET, oss); + std::string s = (oss.str()).erase(0, strlen("rx_missingpackets [")); + REQUIRE(std::stoi(s) > 0); + } + { + // 0 missing packets (takes into account that acquisition is stopped) + det.startReceiver(); + det.stopDetector(); + det.stopReceiver(); + std::ostringstream oss; + proxy.Call("rx_missingpackets", {}, -1, GET, oss); + std::string s = (oss.str()).erase(0, strlen("rx_missingpackets [")); + REQUIRE(std::stoi(s) == 0); + } } -TEST_CASE("rx_printconfig", "[.cmd][.rx]") { +/* Network Configuration (Detector<->Receiver) */ + +TEST_CASE("rx_printconfig", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); - proxy.Call("rx_printconfig", {}, -1, GET); + REQUIRE_NOTHROW(proxy.Call("rx_printconfig", {}, -1, GET)); } -TEST_CASE("rx_fifodepth", "[.cmd][.rx]") { + +/* Receiver Config */ + +TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); - int prev_val = det.getRxFifoDepth().squash(); + auto prev_val = det.getRxHostname(); + + // Cannot set rx_hostname (will reset parameters in rxr and no shm variables to update) + // { + // // disable receiver + // std::ostringstream oss; + // proxy.Call("rx_hostname", {"none"}, -1, PUT, oss); + // REQUIRE(oss.str() == "rx_hostname [none]\n"); + // } + // { + // std::ostringstream oss; + // proxy.Call("rx_hostname", {}, -1, GET, oss); + // REQUIRE(oss.str() == "rx_hostname none\n"); + // // receiver should be disabled + // REQUIRE(det.getUseReceiverFlag().tsquash( + // "different values of flag in test") == false); + // } + // put back old values (not necessary when we dont set it to none) + // for (int i = 0; i != det.size(); ++i) { + // det.setRxHostname(prev_val[i], {i}); + // } + { + std::ostringstream oss; + proxy.Call("rx_hostname", {}, 0, GET, oss); + REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n"); + } +} + +TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getRxPort(); + + int port = 3500; + proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT); + for (int i = 0; i != det.size(); ++i) { + std::ostringstream oss; + proxy.Call("rx_tcpport", {}, i, GET, oss); + REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); + } + REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT)); + port = 5754; + proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT); + for (int i = 0; i != det.size(); ++i) { + std::ostringstream oss; + proxy.Call("rx_tcpport", {}, i, GET, oss); + REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); + } + for (int i = 0; i != det.size(); ++i) { + det.setRxPort(prev_val[i], i); + } +} + +TEST_CASE("rx_fifodepth", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getRxFifoDepth(); { std::ostringstream oss; proxy.Call("rx_fifodepth", {"10"}, -1, PUT, oss); @@ -194,18 +214,20 @@ TEST_CASE("rx_fifodepth", "[.cmd][.rx]") { proxy.Call("rx_fifodepth", {"100"}, -1, PUT, oss); REQUIRE(oss.str() == "rx_fifodepth 100\n"); } - { std::ostringstream oss; proxy.Call("rx_fifodepth", {}, -1, GET, oss); REQUIRE(oss.str() == "rx_fifodepth 100\n"); } - det.setRxFifoDepth(prev_val); + for (int i = 0; i != det.size(); ++i) { + det.setRxFifoDepth(prev_val[i], {i}); + } } -TEST_CASE("rx_silent", "[.cmd][.rx]") { +TEST_CASE("rx_silent", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + auto prev_val = det.getRxSilentMode(); { std::ostringstream oss; proxy.Call("rx_silent", {"1"}, -1, PUT, oss); @@ -221,87 +243,15 @@ TEST_CASE("rx_silent", "[.cmd][.rx]") { proxy.Call("rx_silent", {"0"}, -1, PUT, oss); REQUIRE(oss.str() == "rx_silent 0\n"); } -} - -TEST_CASE("rx_jsonaddheader", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - - { - std::ostringstream oss; - proxy.Call("rx_jsonaddheader", {"\"hej\":\"5\""}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_jsonaddheader \"hej\":\"5\"\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_jsonaddheader", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_jsonaddheader \"hej\":\"5\"\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_jsonaddheader", {"\"\""}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_jsonaddheader \"\"\n"); + for (int i = 0; i != det.size(); ++i) { + det.setRxSilentMode(prev_val[i], {i}); } } -TEST_CASE("rx_udpsocksize", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("rx_udpsocksize", {"4857600"}, -1, PUT, oss); - REQUIRE(oss.str() >= "rx_udpsocksize 4857600\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_udpsocksize", {}, -1, GET, oss); - REQUIRE(oss.str() >= "rx_udpsocksize 4857600\n"); - } -} - -TEST_CASE("rx_realudpsocksize", "[.cmd][.rx]") { - // TODO! Is the real socket size always twice? - Detector det; - CmdProxy proxy(&det); - uint64_t val = 0; - { - std::ostringstream oss; - proxy.Call("rx_udpsocksize", {}, -1, GET, oss); - std::string s = (oss.str()).erase(0, strlen("rx_udpsocksize ")); - val = std::stol(s); - } - { - std::ostringstream oss; - proxy.Call("rx_realudpsocksize", {}, -1, GET, oss); - std::string s = (oss.str()).erase(0, strlen("rx_realudpsocksize ")); - uint64_t rval = std::stol(s); - REQUIRE(rval >= val * 2); - } -} - -TEST_CASE("rx_framesperfile", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("rx_framesperfile", {"50"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_framesperfile 50\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_framesperfile", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_framesperfile 50\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_framesperfile", {"10000"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_framesperfile 10000\n"); - } -} - -TEST_CASE("rx_discardpolicy", "[.cmd][.rx]") { +TEST_CASE("rx_discardpolicy", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + auto prev_val = det.getRxFrameDiscardPolicy(); { std::ostringstream oss; proxy.Call("rx_discardpolicy", {"discardempty"}, -1, PUT, oss); @@ -322,11 +272,15 @@ TEST_CASE("rx_discardpolicy", "[.cmd][.rx]") { proxy.Call("rx_discardpolicy", {"nodiscard"}, -1, PUT, oss); REQUIRE(oss.str() == "rx_discardpolicy nodiscard\n"); } + for (int i = 0; i != det.size(); ++i) { + det.setRxFrameDiscardPolicy(prev_val[i], {i}); + } } -TEST_CASE("rx_padding", "[.cmd][.rx]") { +TEST_CASE("rx_padding", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + auto prev_val = det.getPartialFramesPadding(); { std::ostringstream oss; proxy.Call("rx_padding", {"0"}, -1, PUT, oss); @@ -342,31 +296,52 @@ TEST_CASE("rx_padding", "[.cmd][.rx]") { proxy.Call("rx_padding", {"1"}, -1, PUT, oss); REQUIRE(oss.str() == "rx_padding 1\n"); } -} - -TEST_CASE("rx_readfreq", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("rx_readfreq", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_readfreq 1\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_readfreq", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_readfreq 1\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_readfreq", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_readfreq 0\n"); + for (int i = 0; i != det.size(); ++i) { + det.setPartialFramesPadding(prev_val[i], {i}); } } -TEST_CASE("rx_lock", "[.cmd][.rx]") { +TEST_CASE("rx_udpsocksize", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + int64_t prev_val = det.getRxUDPSocketBufferSize().tsquash("Need same udp socket buffer size to test"); + std::string s_new_val = std::to_string(prev_val - 1000); + { + std::ostringstream oss; + proxy.Call("rx_udpsocksize", {s_new_val}, -1, PUT, oss); + REQUIRE(oss.str() >= "rx_udpsocksize " + s_new_val + "\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_udpsocksize", {}, -1, GET, oss); + REQUIRE(oss.str() >= "rx_udpsocksize " + s_new_val + "\n"); + } + det.setRxUDPSocketBufferSize(prev_val); +} + +TEST_CASE("rx_realudpsocksize", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + uint64_t val = 0; + { + std::ostringstream oss; + proxy.Call("rx_udpsocksize", {}, -1, GET, oss); + std::string s = (oss.str()).erase(0, strlen("rx_udpsocksize ")); + val = std::stol(s); + } + { + std::ostringstream oss; + proxy.Call("rx_realudpsocksize", {}, -1, GET, oss); + std::string s = (oss.str()).erase(0, strlen("rx_realudpsocksize ")); + uint64_t rval = std::stol(s); + REQUIRE(rval >= val * 2); + } +} + +TEST_CASE("rx_lock", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getRxLock(); { std::ostringstream oss; proxy.Call("rx_lock", {"1"}, -1, PUT, oss); @@ -382,46 +357,216 @@ TEST_CASE("rx_lock", "[.cmd][.rx]") { proxy.Call("rx_lock", {"0"}, -1, PUT, oss); REQUIRE(oss.str() == "rx_lock 0\n"); } -} - -TEST_CASE("rx_zmqport", "[.cmd][.rx]") { - Detector det; - CmdProxy proxy(&det); - int socketsperdetector = 1; - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::EIGER) { - socketsperdetector *= 2; - } else if (det_type == defs::JUNGFRAU) { - proxy.Call("numinterfaces", {"2"}, -1, PUT); - socketsperdetector *= 2; - } - int port = 3500; - proxy.Call("rx_zmqport", {std::to_string(port)}, -1, PUT); for (int i = 0; i != det.size(); ++i) { - std::ostringstream oss; - proxy.Call("rx_zmqport", {}, i, GET, oss); - std::cout << "oss: " << oss.str() << "\n"; - REQUIRE(oss.str() == "rx_zmqport " + - std::to_string(port + i * socketsperdetector) + - '\n'); - } - port = 30001; - proxy.Call("rx_zmqport", {std::to_string(port)}, -1, PUT); - for (int i = 0; i != det.size(); ++i) { - std::ostringstream oss; - proxy.Call("rx_zmqport", {}, i, GET, oss); - REQUIRE(oss.str() == "rx_zmqport " + - std::to_string(port + i * socketsperdetector) + - '\n'); - } - if (det_type == slsDetectorDefs::JUNGFRAU) { - proxy.Call("numinterfaces", {"1"}, -1, PUT); + det.setRxLock(prev_val[i], {i}); } } -TEST_CASE("rx_datastream", "[.cmd][.rx]") { +TEST_CASE("rx_lastclient", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("rx_lastclient", {}, -1, GET, oss)); + if (test::my_ip != "undefined") { + REQUIRE(oss.str() == "rx_lastclient " + test::my_ip + "\n"); + } +} + +/* File */ + +TEST_CASE("fformat", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getFileFormat(); + { + std::ostringstream oss; + proxy.Call("fformat", {"binary"}, -1, PUT, oss); + REQUIRE(oss.str() == "fformat binary\n"); + } + { + std::ostringstream oss; + proxy.Call("fformat", {}, -1, GET, oss); + REQUIRE(oss.str() == "fformat binary\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setFileFormat(prev_val[i], {i}); + } +} + +TEST_CASE("fpath", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getFilePath(); + { + std::ostringstream oss; + proxy.Call("fpath", {"/tmp"}, -1, PUT, oss); + REQUIRE(oss.str() == "fpath /tmp\n"); + } + { + std::ostringstream oss; + proxy.Call("fpath", {}, -1, GET, oss); + REQUIRE(oss.str() == "fpath /tmp\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setFilePath(prev_val[i], {i}); + } +} + +TEST_CASE("fname", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getFileNamePrefix(); + { + std::ostringstream oss; + proxy.Call("fname", {"somename"}, -1, PUT, oss); + REQUIRE(oss.str() == "fname somename\n"); + } + { + std::ostringstream oss; + proxy.Call("fname", {}, -1, GET, oss); + REQUIRE(oss.str() == "fname somename\n"); + } + { + std::ostringstream oss; + proxy.Call("fname", {"run"}, -1, PUT, oss); + REQUIRE(oss.str() == "fname run\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setFileNamePrefix(prev_val[i], {i}); + } +} + +TEST_CASE("findex", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getAcquisitionIndex(); + { + std::ostringstream oss; + proxy.Call("findex", {"57"}, -1, PUT, oss); + REQUIRE(oss.str() == "findex 57\n"); + } + { + std::ostringstream oss; + proxy.Call("findex", {}, -1, GET, oss); + REQUIRE(oss.str() == "findex 57\n"); + } + { + std::ostringstream oss; + proxy.Call("findex", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "findex 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setAcquisitionIndex(prev_val[i], {i}); + } +} + +TEST_CASE("fwrite", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getFileWrite(); + { + std::ostringstream oss; + proxy.Call("fwrite", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "fwrite 1\n"); + } + { + std::ostringstream oss; + proxy.Call("fwrite", {}, -1, GET, oss); + REQUIRE(oss.str() == "fwrite 1\n"); + } + { + std::ostringstream oss; + proxy.Call("fwrite", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "fwrite 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setFileWrite(prev_val[i], {i}); + } +} + +TEST_CASE("fmaster", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getMasterFileWrite(); + { + std::ostringstream oss; + proxy.Call("fmaster", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "fmaster 0\n"); + } + { + std::ostringstream oss; + proxy.Call("fmaster", {}, -1, GET, oss); + REQUIRE(oss.str() == "fmaster 0\n"); + } + { + std::ostringstream oss; + proxy.Call("fmaster", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "fmaster 1\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setMasterFileWrite(prev_val[i], {i}); + } +} + +TEST_CASE("foverwrite", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getFileOverWrite(); + { + std::ostringstream oss; + proxy.Call("foverwrite", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "foverwrite 1\n"); + } + { + std::ostringstream oss; + proxy.Call("foverwrite", {}, -1, GET, oss); + REQUIRE(oss.str() == "foverwrite 1\n"); + } + { + std::ostringstream oss; + proxy.Call("foverwrite", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "foverwrite 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setFileOverWrite(prev_val[i], {i}); + } +} + +TEST_CASE("rx_framesperfile", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getFramesPerFile(); + { + std::ostringstream oss; + proxy.Call("rx_framesperfile", {"50"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_framesperfile 50\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_framesperfile", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_framesperfile 50\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_framesperfile", {"10000"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_framesperfile 10000\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_framesperfile", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_framesperfile 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setFramesPerFile(prev_val[i], {i}); + } +} + +/* ZMQ Streaming Parameters (Receiver<->Client) */ + +TEST_CASE("rx_datastream", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getRxZmqDataStream(); { std::ostringstream oss; proxy.Call("rx_datastream", {"1"}, -1, PUT, oss); @@ -439,33 +584,79 @@ TEST_CASE("rx_datastream", "[.cmd][.rx]") { REQUIRE(oss.str() == "rx_datastream 0\n"); REQUIRE(det.getRxZmqDataStream().squash() == false); } + for (int i = 0; i != det.size(); ++i) { + det.setRxZmqDataStream(prev_val[i], {i}); + } } -TEST_CASE("rx_tcpport", "[.cmd][.rx]") { +TEST_CASE("rx_readfreq", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + auto prev_val = det.getRxZmqFrequency(); + { + std::ostringstream oss; + proxy.Call("rx_readfreq", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_readfreq 1\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_readfreq", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_readfreq 1\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_readfreq", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_readfreq 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setRxZmqFrequency(prev_val[i], {i}); + } +} +TEST_CASE("rx_zmqport", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val_zmqport = det.getRxZmqPort(); + auto prev_val_numinterfaces = det.getNumberofUDPInterfaces(); + + int socketsperdetector = 1; + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + socketsperdetector *= 2; + } else if (det_type == defs::JUNGFRAU) { + proxy.Call("numinterfaces", {"2"}, -1, PUT); + socketsperdetector *= 2; + } int port = 3500; - - proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT); + proxy.Call("rx_zmqport", {std::to_string(port)}, -1, PUT); for (int i = 0; i != det.size(); ++i) { std::ostringstream oss; - proxy.Call("rx_tcpport", {}, i, GET, oss); - REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); + proxy.Call("rx_zmqport", {}, i, GET, oss); + REQUIRE(oss.str() == "rx_zmqport " + + std::to_string(port + i * socketsperdetector) + + '\n'); } - REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT)); - port = 1954; - proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT); + port = 30001; + proxy.Call("rx_zmqport", {std::to_string(port)}, -1, PUT); for (int i = 0; i != det.size(); ++i) { std::ostringstream oss; - proxy.Call("rx_tcpport", {}, i, GET, oss); - REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); + proxy.Call("rx_zmqport", {}, i, GET, oss); + REQUIRE(oss.str() == "rx_zmqport " + + std::to_string(port + i * socketsperdetector) + + '\n'); + } + for (int i = 0; i != det.size(); ++i) { + det.setRxZmqPort(prev_val_zmqport[i], i); + if (det_type == defs::JUNGFRAU) { + det.setNumberofUDPInterfaces(prev_val_numinterfaces[i], {i}); + } } } -TEST_CASE("rx_zmqip", "[.cmd][.rx]") { +TEST_CASE("rx_zmqip", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); + auto prev_val = det.getRxZmqIP(); { std::ostringstream oss; proxy.Call("rx_zmqip", {"127.0.0.1"}, 0, PUT, oss); @@ -477,14 +668,46 @@ TEST_CASE("rx_zmqip", "[.cmd][.rx]") { proxy.Call("rx_zmqip", {}, 0, GET, oss); REQUIRE(oss.str() == "rx_zmqip 127.0.0.1\n"); } + for (int i = 0; i != det.size(); ++i) { + det.setRxZmqIP(prev_val[i], {i}); + } } -TEST_CASE("rx_dbitoffset", "[.cmd][.rx]") { +/* CTB Specific */ + +TEST_CASE("rx_dbitlist", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto previous = det.getRxDbitOffset(); + auto prev_val = det.getRxDbitList(); + { + std::ostringstream oss; + proxy.Call("rx_dbitlist", {"0", "4", "5", "8", "9", "10", "52", "63"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_dbitlist [0, 4, 5, 8, 9, 10, 52, 63]\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_dbitlist", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_dbitlist [0, 4, 5, 8, 9, 10, 52, 63]\n"); + } + REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"67"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"-1"}, -1, PUT)); + REQUIRE_NOTHROW(proxy.Call("rx_dbitlist", {"all"}, -1, PUT)); + for (int i = 0; i != det.size(); ++i) { + det.setRxDbitList(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("rx_dbitlist", {}, -1, GET)); + } +} + +TEST_CASE("rx_dbitoffset", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::CHIPTESTBOARD) { + auto prev_val = det.getRxDbitOffset(); { std::ostringstream oss; proxy.Call("rx_dbitoffset", {"1"}, -1, PUT, oss); @@ -505,41 +728,82 @@ TEST_CASE("rx_dbitoffset", "[.cmd][.rx]") { proxy.Call("rx_dbitoffset", {}, -1, GET, oss); REQUIRE(oss.str() == "rx_dbitoffset 15\n"); } - // Reset to previous value for (int i = 0; i != det.size(); ++i) { - det.setRxDbitOffset(previous[i], {i}); + det.setRxDbitOffset(prev_val[i], {i}); } } else { REQUIRE_THROWS(proxy.Call("rx_dbitoffset", {}, -1, GET)); } } +/* Moench */ - -TEST_CASE("rx_dbitlist", "[.cmd][.rx]") { +TEST_CASE("rx_jsonaddheader", "[.cmd][.rx][.new]") { Detector det; CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD) { - auto previous = det.getRxDbitList(); - { - std::ostringstream oss; - proxy.Call("rx_dbitlist", {"0", "4", "5", "8", "9", "10", "52", "63"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_dbitlist [0, 4, 5, 8, 9, 10, 52, 63]\n"); - } - { - std::ostringstream oss; - proxy.Call("rx_dbitlist", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_dbitlist [0, 4, 5, 8, 9, 10, 52, 63]\n"); - } - REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"67"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"-1"}, -1, PUT)); - REQUIRE_NOTHROW(proxy.Call("rx_dbitlist", {"all"}, -1, PUT)); - // Reset to previous value - for (int i = 0; i != det.size(); ++i) { - det.setRxDbitList(previous[i], {i}); - } - } else { - REQUIRE_THROWS(proxy.Call("rx_dbitlist", {}, -1, GET)); + auto prev_val = det.getAdditionalJsonHeader(); + + { + std::ostringstream oss; + proxy.Call("rx_jsonaddheader", {"key1", "value1", "key2", "value2"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_jsonaddheader {key1: value1, key2: value2}\n"); } -} \ No newline at end of file + { + std::ostringstream oss; + proxy.Call("rx_jsonaddheader", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_jsonaddheader {key1: value1, key2: value2}\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_jsonaddheader", {}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_jsonaddheader {}\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setAdditionalJsonHeader(prev_val[i], {i}); + } +} + +TEST_CASE("rx_jsonpara", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getAdditionalJsonHeader(); + { + std::ostringstream oss; + proxy.Call("rx_jsonpara", {"key1", "value1"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_jsonpara {key1: value1}\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_jsonpara", {"key1", "value2"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_jsonpara {key1: value2}\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_jsonpara", {"key1"}, -1, GET, oss); + REQUIRE(oss.str() == "rx_jsonpara value2\n"); + } + { + std::ostringstream oss; + proxy.Call("rx_jsonpara", {"key1"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_jsonpara key1 deleted\n"); + } + REQUIRE_THROWS(proxy.Call("rx_jsonpara", {"key1"}, -1, GET)); + for (int i = 0; i != det.size(); ++i) { + det.setAdditionalJsonHeader(prev_val[i], {i}); + } +} + +/* Insignificant */ + +TEST_CASE("rx_frameindex", "[.cmd][.rx][.new]") { + Detector det; + CmdProxy proxy(&det); + proxy.Call("rx_frameindex", {}, -1, GET); + + // This is a get only command + REQUIRE_THROWS(proxy.Call("rx_frameindex", {"2"}, -1, PUT)); + std::ostringstream oss; + proxy.Call("rx_frameindex", {}, 0, GET, oss); + std::string s = (oss.str()).erase(0, strlen("rx_frameindex ")); + REQUIRE(std::stoi(s) >= 0); +} diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index a43b47381..d4785705d 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -3,12 +3,11 @@ #include "catch.hpp" #include "sls_detector_defs.h" #include +#include +#include #include "tests/globals.h" -// auto GET = slsDetectorDefs::GET_ACTION; -// auto PUT = slsDetectorDefs::PUT_ACTION; - using sls::CmdProxy; using sls::Detector; using test::GET; @@ -21,7 +20,93 @@ TEST_CASE("Unknown command", "[.cmd]") { REQUIRE_THROWS(proxy.Call("vsaevrreavv", {}, -1, PUT)); } -TEST_CASE("type", "[.cmd]"){ +/* configuration */ + +TEST_CASE("config", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + // put only + REQUIRE_THROWS(proxy.Call("config", {}, -1, GET)); +} + +// free: not testing + +TEST_CASE("parameters", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + // put only + REQUIRE_THROWS(proxy.Call("parameters", {}, -1, GET)); +/* + auto prev_val = det.getNumberOfFrames().tsquash("Number of frames has to be same to test"); + { + system("echo 'frames 2' > /tmp/tempsetup.det "); + std::ostringstream oss; + proxy.Call("parameters", {"/tmp/tempsetup.det"}, -1, PUT, oss); + REQUIRE(oss.str() == "parameters /tmp/tempsetup.det\n"); + REQUIRE(det.getNumberOfFrames().tsquash("failed") == 2); + } + { + system("echo '0:frames 1' > /tmp/tempsetup.det "); + std::ostringstream oss; + proxy.Call("parameters", {"/tmp/tempsetup.det"}, -1, PUT, oss); + REQUIRE(oss.str() == "parameters /tmp/tempsetup.det\n"); + REQUIRE(det.getNumberOfFrames({0}).tsquash("failed") == 1); + } + det.setNumberOfFrames(prev_val); + */ +} + +TEST_CASE("hostname", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("hostname", {}, -1, GET)); +} + +// virtual: not testing + +TEST_CASE("versions", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("versions", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("versions", {"0"}, -1, PUT)); +} + +TEST_CASE("packageversion", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("packageversion", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("packageversion", {"0"}, -1, PUT)); +} + +TEST_CASE("clientversion", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("clientversion", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("clientversion", {"0"}, -1, PUT)); +} + +TEST_CASE("firmwareversion", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("firmwareversion", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("firmwareversion", {"0"}, -1, PUT)); +} + +TEST_CASE("detectorserverversion", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("detectorserverversion", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("detectorserverversion", {"0"}, -1, PUT)); +} + +TEST_CASE("detectornumber", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("detectornumber", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("detectornumber", {"0"}, -1, PUT)); +} + +TEST_CASE("type", "[.cmd][.new]"){ Detector det; CmdProxy proxy(&det); auto dt = det.getDetectorType().squash(); @@ -31,8 +116,891 @@ TEST_CASE("type", "[.cmd]"){ auto ans = oss.str().erase(0, strlen("type ")); REQUIRE(ans == sls::ToString(dt) + '\n'); REQUIRE(dt == test::type); - } + +TEST_CASE("detsize", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("detsize", {}, -1, GET)); +} + +TEST_CASE("settings", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + std::vector sett; + switch (det_type) { + case defs::EIGER: + //FIXME: need to remove when settings removed + break; + case defs::JUNGFRAU: + sett.push_back("dynamicgain"); + sett.push_back("dynamichg0"); + sett.push_back("fixgain1"); + sett.push_back("fixgain2"); + sett.push_back("forceswitchg1"); + sett.push_back("forceswitchg2"); + break; + case defs::GOTTHARD: + sett.push_back("highgain"); + sett.push_back("dynamicgain"); + sett.push_back("lowgain"); + sett.push_back("mediumgain"); + sett.push_back("veryhighgain"); + break; + case defs::GOTTHARD2: + sett.push_back("dynamicgain"); + sett.push_back("fixgain1"); + sett.push_back("fixgain2"); + break; + case defs::MOENCH: + sett.push_back("g1_hg"); + sett.push_back("g1_lg"); + sett.push_back("g2_hc_hg"); + sett.push_back("g2_hc_lg"); + sett.push_back("g2_lc_hg"); + sett.push_back("g2_lc_lg"); + sett.push_back("g4_hg"); + sett.push_back("g4_lg"); + break; + default: + REQUIRE_THROWS(proxy.Call("settings", {}, -1, GET)); + return; + } + + auto prev_val = det.getSettings(); + for (auto & it : sett) { + { + std::ostringstream oss; + proxy.Call("settings", {it}, -1, PUT, oss); + REQUIRE(oss.str() == "settings " + it + "\n"); + } + { + std::ostringstream oss; + proxy.Call("settings", {}, -1, GET, oss); + REQUIRE(oss.str() == "settings " + it + "\n"); + } + } + for (int i = 0; i != det.size(); ++i) { + if (prev_val[i] != defs::UNDEFINED && + prev_val[i] != defs::UNINITIALIZED) { + det.setSettings(prev_val[i], {i}); + } + } +} + +/* acquisition parameters */ + +// acquire: not testing + +TEST_CASE("frames", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getNumberOfFrames().tsquash("#frames must be same to test"); + { + std::ostringstream oss; + proxy.Call("frames", {"1000"}, -1, PUT, oss); + REQUIRE(oss.str() == "frames 1000\n"); + } + { + std::ostringstream oss; + proxy.Call("frames", {}, -1, GET, oss); + REQUIRE(oss.str() == "frames 1000\n"); + } + { + std::ostringstream oss; + proxy.Call("frames", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "frames 1\n"); + } + REQUIRE_THROWS(proxy.Call("frames", {"0"}, -1, PUT)); + det.setNumberOfFrames(prev_val); +} + +TEST_CASE("triggers", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getNumberOfTriggers().tsquash("#triggers must be same to test"); + { + std::ostringstream oss; + proxy.Call("triggers", {"1000"}, -1, PUT, oss); + REQUIRE(oss.str() == "triggers 1000\n"); + } + { + std::ostringstream oss; + proxy.Call("triggers", {}, -1, GET, oss); + REQUIRE(oss.str() == "triggers 1000\n"); + } + { + std::ostringstream oss; + proxy.Call("triggers", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "triggers 1\n"); + } + REQUIRE_THROWS(proxy.Call("triggers", {"0"}, -1, PUT)); + det.setNumberOfTriggers(prev_val); +} + +TEST_CASE("exptime", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getExptime(); + { + std::ostringstream oss; + proxy.Call("exptime", {"0.05"}, -1, PUT, oss); + REQUIRE(oss.str() == "exptime 0.05\n"); + } + { + std::ostringstream oss; + proxy.Call("exptime", {}, -1, GET, oss); + REQUIRE(oss.str() == "exptime 50ms\n"); + } + { + std::ostringstream oss; + proxy.Call("exptime", {"1s"}, -1, PUT, oss); + REQUIRE(oss.str() == "exptime 1s\n"); + } + { + std::ostringstream oss; + proxy.Call("exptime", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "exptime 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setExptime(prev_val[i], {i}); + } +} + +TEST_CASE("period", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getPeriod(); + { + std::ostringstream oss; + proxy.Call("period", {"1.25s"}, -1, PUT, oss); + REQUIRE(oss.str() == "period 1.25s\n"); + } + { + std::ostringstream oss; + proxy.Call("period", {}, -1, GET, oss); + REQUIRE(oss.str() == "period 1.25s\n"); + } + { + std::ostringstream oss; + proxy.Call("period", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "period 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setPeriod(prev_val[i], {i}); + } +} + +TEST_CASE("delay", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_THROWS(proxy.Call("delay", {"1"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("delay", {}, -1, GET)); + } else if (det_type == defs::GOTTHARD) { + // extra delays for master (can throw when setting) + REQUIRE_NOTHROW(proxy.Call("delay", {}, -1, GET)); + } else { + auto prev_val = det.getDelayAfterTrigger(); + { + std::ostringstream oss; + proxy.Call("delay", {"1.25s"}, -1, PUT, oss); + REQUIRE(oss.str() == "delay 1.25s\n"); + } + { + std::ostringstream oss; + proxy.Call("delay", {}, -1, GET, oss); + REQUIRE(oss.str() == "delay 1.25s\n"); + } + { + std::ostringstream oss; + proxy.Call("delay", {"0s"}, -1, PUT, oss); + REQUIRE(oss.str() == "delay 0s\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setDelayAfterTrigger(prev_val[i], {i}); + } + } +} + +TEST_CASE("framesl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_THROWS(proxy.Call("framesl", {}, -1, GET)); + } else { + REQUIRE_NOTHROW(proxy.Call("framesl", {}, -1, GET)); + } +} + +TEST_CASE("triggersl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_THROWS(proxy.Call("triggersl", {}, -1, GET)); + } else { + REQUIRE_NOTHROW(proxy.Call("triggersl", {}, -1, GET)); + } +} + +TEST_CASE("delayl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_THROWS(proxy.Call("delayl", {}, -1, GET)); + } else { + REQUIRE_NOTHROW(proxy.Call("delayl", {}, -1, GET)); + } +} + +TEST_CASE("periodl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + REQUIRE_THROWS(proxy.Call("periodl", {}, -1, GET)); + } else { + REQUIRE_NOTHROW(proxy.Call("periodl", {}, -1, GET)); + } +} + +TEST_CASE("timing", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getTimingMode(); + det.setTimingMode(defs::AUTO_TIMING); + { + std::ostringstream oss1, oss2; + proxy.Call("timing", {"auto"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "timing auto\n"); + proxy.Call("timing", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "timing auto\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("timing", {"trigger"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "timing trigger\n"); + proxy.Call("timing", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "timing trigger\n"); + } + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + { + std::ostringstream oss1, oss2; + proxy.Call("timing", {"gating"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "timing gating\n"); + proxy.Call("timing", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "timing gating\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("timing", {"burst_trigger"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "timing burst_trigger\n"); + proxy.Call("timing", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "timing burst_trigger\n"); + } + } else { + REQUIRE_THROWS(proxy.Call("timing", {"gating"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("timing", {"burst_trigger"}, -1, PUT)); + } + for (int i = 0; i != det.size(); ++i) { + det.setTimingMode(prev_val[i], {i}); + } +} + +TEST_CASE("speed", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) { + auto prev_val = det.getSpeed(); + // full speed for jungfrau only works for new boards + /* + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("speed", {"0"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "speed full_speed\n"); + proxy.Call("speed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "speed full_speed\n"); + proxy.Call("speed", {"full_speed"}, -1, PUT, oss3); + REQUIRE(oss3.str() == "speed full_speed\n"); + proxy.Call("speed", {}, -1, GET, oss4); + REQUIRE(oss4.str() == "speed full_speed\n"); + } + */ + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("speed", {"1"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "speed half_speed\n"); + proxy.Call("speed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "speed half_speed\n"); + proxy.Call("speed", {"half_speed"}, -1, PUT, oss3); + REQUIRE(oss3.str() == "speed half_speed\n"); + proxy.Call("speed", {}, -1, GET, oss4); + REQUIRE(oss4.str() == "speed half_speed\n"); + } + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("speed", {"2"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "speed quarter_speed\n"); + proxy.Call("speed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "speed quarter_speed\n"); + proxy.Call("speed", {"quarter_speed"}, -1, PUT, oss3); + REQUIRE(oss3.str() == "speed quarter_speed\n"); + proxy.Call("speed", {}, -1, GET, oss4); + REQUIRE(oss4.str() == "speed quarter_speed\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setSpeed(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("speed", {"0"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("speed", {}, -1, GET)); + } +} + +TEST_CASE("adcphase", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD || + det_type == defs::JUNGFRAU || + det_type == defs::CHIPTESTBOARD || + det_type == defs::MOENCH) { + if (det_type == defs::GOTTHARD) { + std::ostringstream oss1; + proxy.Call("adcphase", {"20"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "adcphase 20\n"); + // cant get, cant use deg + REQUIRE_THROWS(proxy.Call("adcphase", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("adcphase", {"20", "deg"}, -1, PUT)); + } else { + auto prev_val = det.getADCPhase(); + { + std::ostringstream oss1, oss2; + proxy.Call("adcphase", {"20"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "adcphase 20\n"); + proxy.Call("adcphase", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "adcphase 20\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("adcphase", {"20", "deg"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "adcphase 20 deg\n"); + proxy.Call("adcphase", {"deg"}, -1, GET, oss2); + REQUIRE(oss2.str() == "adcphase 20 deg\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setADCPhase(prev_val[i], {i}); + } + } + } else { + REQUIRE_THROWS(proxy.Call("adcphase", {"0"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("adcphase", {}, -1, GET)); + } +} + +TEST_CASE("maxadcphaseshift", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU || + det_type == defs::CHIPTESTBOARD || + det_type == defs::MOENCH || + det_type == defs::MYTHEN3 || // only because clk index of 0 exists + det_type == defs::GOTTHARD2) { // only because clk index of 0 exists + REQUIRE_NOTHROW(proxy.Call("maxadcphaseshift", {}, -1, GET)); + } else { + REQUIRE_THROWS(proxy.Call("maxadcphaseshift", {}, -1, GET)); + } +} + +TEST_CASE("dbitphase", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU || + det_type == defs::CHIPTESTBOARD) { + auto prev_val = det.getDBITPhase(); + { + std::ostringstream oss1, oss2; + proxy.Call("dbitphase", {"20"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "dbitphase 20\n"); + proxy.Call("dbitphase", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "dbitphase 20\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("dbitphase", {"20", "deg"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "dbitphase 20 deg\n"); + proxy.Call("dbitphase", {"deg"}, -1, GET, oss2); + REQUIRE(oss2.str() == "dbitphase 20 deg\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setDBITPhase(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("dbitphase", {"0"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("dbitphase", {}, -1, GET)); + } +} + +TEST_CASE("maxdbitphaseshift", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU || + det_type == defs::CHIPTESTBOARD || + det_type == defs::MYTHEN3 || // only because clk index of 0 exists + det_type == defs::GOTTHARD2) { // only because clk index of 0 exists + REQUIRE_NOTHROW(proxy.Call("maxdbitphaseshift", {}, -1, GET)); + } else { + REQUIRE_THROWS(proxy.Call("maxdbitphaseshift", {}, -1, GET)); + } +} + +TEST_CASE("clkfreq", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("clkfreq", {"0", "2"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("clkfreq", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("clkfreq", {"7"}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("clkfreq", {"0"}, -1, GET)); + } else { + REQUIRE_THROWS(proxy.Call("clkfreq", {"0"}, -1, GET)); + } +} + +TEST_CASE("clkphase", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("clkphase", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("clkphase", {"7"}, -1, GET)); + REQUIRE_THROWS(proxy.Call("clkphase", {"4"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("clkphase", {"7", "4"}, -1, PUT)); + auto prev_val = det.getClockPhase(0); + { + std::ostringstream oss1, oss2; + proxy.Call("clkphase", {"0", "20"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "clkphase 20\n"); + proxy.Call("clkphase", {"0"}, -1, GET, oss2); + REQUIRE(oss2.str() == "clkphase 20\n"); + } + std::string s_deg_val = "15"; + if (det_type == defs::MYTHEN3) { + s_deg_val = "14"; + } + { + std::ostringstream oss1, oss2; + proxy.Call("clkphase", {"0", s_deg_val, "deg"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "clkphase " + s_deg_val + " deg\n"); + proxy.Call("clkphase", {"0", "deg"}, -1, GET, oss2); + REQUIRE(oss2.str() == "clkphase " + s_deg_val + " deg\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setClockPhase(0, prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("clkphase", {"0"}, -1, GET)); + } +} + +TEST_CASE("clkdiv", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("clkdiv", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("clkdiv", {"7"}, -1, GET)); + REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("clkdiv", {"0", "1"}, -1, PUT)); + auto prev_val = det.getClockDivider(0); + { + std::ostringstream oss1, oss2; + proxy.Call("clkdiv", {"0", "3"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "clkdiv 3\n"); + proxy.Call("clkdiv", {"0"}, -1, GET, oss2); + REQUIRE(oss2.str() == "clkdiv 3\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setClockDivider(0, prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("clkdiv", {"0"}, -1, GET)); + } +} + +TEST_CASE("maxclkphaseshift", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0", "2"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"7"}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("maxclkphaseshift", {"0"}, -1, GET)); + } else { + REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0"}, -1, GET)); + } +} + + +TEST_CASE("vhighvoltage", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + auto prev_val = det.getHighVoltage(); + // selected values + if (det_type == defs::GOTTHARD) { + REQUIRE_THROWS(proxy.Call("vhighvoltage", {"50"}, -1, PUT)); + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"90"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 90\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 90\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 0\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 0\n"); + } + } + // range 0, 60 - 200 + else if (det_type == defs::JUNGFRAU || + det_type == defs::CHIPTESTBOARD || + det_type == defs::MOENCH) { + REQUIRE_THROWS(proxy.Call("vhighvoltage", {"50"}, -1, PUT)); + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"90"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 90\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 90\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 0\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 0\n"); + } + } + // full range 0 - 200 (get needs to wait) + else if (det_type == defs::EIGER) { + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"50"}, 0, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 50\n"); + std::this_thread::sleep_for(std::chrono::seconds(2)); + proxy.Call("vhighvoltage", {}, 0, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 50\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"120"}, 0, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 120\n"); + std::this_thread::sleep_for(std::chrono::seconds(2)); + proxy.Call("vhighvoltage", {}, 0, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 120\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"0"}, 0, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 0\n"); + std::this_thread::sleep_for(std::chrono::seconds(2)); + proxy.Call("vhighvoltage", {}, 0, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 0\n"); + } + } + // full range 0 - 200 + else { + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"50"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 50\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 50\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"120"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 120\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 120\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "vhighvoltage 0\n"); + proxy.Call("vhighvoltage", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "vhighvoltage 0\n"); + } + } + for (int i = 0; i != det.size(); ++i) { + det.setHighVoltage(prev_val[i], {i}); + } +} + +TEST_CASE("powerchip", "[.cmd][.new]") { + // TODO! this test currently fails with the + // virtual detecto server + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + + if (det_type == defs::JUNGFRAU || + det_type == defs::MYTHEN3 || + det_type == defs::GOTTHARD2 || + det_type == defs::MOENCH) { + auto prev_val = det.getPowerChip(); + { + std::ostringstream oss; + proxy.Call("powerchip", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "powerchip 1\n"); + } + { + std::ostringstream oss; + proxy.Call("powerchip", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "powerchip 0\n"); + } + { + std::ostringstream oss; + proxy.Call("powerchip", {}, -1, GET, oss); + REQUIRE(oss.str() == "powerchip 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setPowerChip(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("powerchip", {}, -1, GET)); + } +} + +TEST_CASE("imagetest", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD) { + auto prev_val = det.getImageTestMode(); + { + std::ostringstream oss1, oss2; + proxy.Call("imagetest", {"1"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "imagetest 1\n"); + proxy.Call("imagetest", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "imagetest 1\n"); + } + { + std::ostringstream oss1, oss2; + proxy.Call("imagetest", {"0"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "imagetest 0\n"); + proxy.Call("imagetest", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "imagetest 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setImageTestMode(prev_val[i], {i}); + } + } else if (det_type != defs::JUNGFRAU && + det_type != defs::EIGER) { + // wont fail for eiger and jungfrau virtual servers + REQUIRE_THROWS(proxy.Call("imagetest", {}, -1, GET)); + } +} + +/** temperature */ + +TEST_CASE("temp_adc", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU || det_type == defs::GOTTHARD) { + REQUIRE_NOTHROW(proxy.Call("temp_adc", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_adc", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_adc ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_adc", {}, -1, GET)); + } +} + +TEST_CASE("temp_fpga", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU || det_type == defs::GOTTHARD || + det_type == defs::EIGER) { + REQUIRE_NOTHROW(proxy.Call("temp_fpga", {}, -1, GET)); + std::ostringstream oss; + REQUIRE_NOTHROW(proxy.Call("temp_fpga", {}, 0, GET, oss)); + std::string s = (oss.str()).erase (0, strlen("temp_fpga ")); + REQUIRE(std::stoi(s) != -1); + } else { + REQUIRE_THROWS(proxy.Call("temp_fpga", {}, -1, GET)); + } +} + +/* acquisition */ + +TEST_CASE("clearbusy", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_NOTHROW(proxy.Call("clearbusy", {}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("clearbusy", {"0"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("clearbusy", {}, -1, GET)); +} + +TEST_CASE("start", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + // PUT only command + REQUIRE_THROWS(proxy.Call("start", {}, -1, GET)); + auto prev_val = det.getExptime(); + det.setExptime(std::chrono::seconds(2)); + { + std::ostringstream oss; + proxy.Call("start", {}, -1, PUT, oss); + REQUIRE(oss.str() == "start successful\n"); + } + { + std::ostringstream oss; + proxy.Call("status", {}, -1, GET, oss); + REQUIRE(oss.str() == "status running\n"); + } + det.stopDetector(); + for (int i = 0; i != det.size(); ++i) { + det.setExptime(prev_val[i], {i}); + } +} + +TEST_CASE("stop", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + // PUT only command + REQUIRE_THROWS(proxy.Call("stop", {}, -1, GET)); + auto prev_val = det.getExptime(); + det.setExptime(std::chrono::seconds(2)); + det.startDetector(); + { + std::ostringstream oss; + proxy.Call("status", {}, -1, GET, oss); + REQUIRE(oss.str() == "status running\n"); + } + { + std::ostringstream oss; + proxy.Call("stop", {}, -1, PUT, oss); + REQUIRE(oss.str() == "stop successful\n"); + } + { + std::ostringstream oss; + proxy.Call("status", {}, -1, GET, oss); + REQUIRE(oss.str() == "status idle\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setExptime(prev_val[i], {i}); + } +} + +TEST_CASE("status", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto prev_val = det.getExptime(); + det.setExptime(std::chrono::seconds(2)); + det.startDetector(); + { + std::ostringstream oss; + proxy.Call("status", {}, -1, GET, oss); + REQUIRE(oss.str() == "status running\n"); + } + det.stopDetector(); + { + std::ostringstream oss; + proxy.Call("status", {}, -1, GET, oss); + REQUIRE(oss.str() == "status idle\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setExptime(prev_val[i], {i}); + } +} + +TEST_CASE("startingfnum", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) { + auto prev_sfnum = det.getStartingFrameNumber(); + REQUIRE_THROWS(proxy.Call("startingfnum", {"0"}, -1, PUT)); + { + std::ostringstream oss; + proxy.Call("startingfnum", {"3"}, -1, PUT, oss); + REQUIRE(oss.str() == "startingfnum 3\n"); + } + { + std::ostringstream oss; + proxy.Call("startingfnum", {}, -1, GET, oss); + REQUIRE(oss.str() == "startingfnum 3\n"); + } + { + std::ostringstream oss; + proxy.Call("startingfnum", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "startingfnum 1\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setStartingFrameNumber(prev_sfnum[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("startingfnum", {}, -1, GET)); + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TEST_CASE("initialchecks", "[.cmd]") { @@ -113,7 +1081,7 @@ TEST_CASE("stopport", "[.cmd]") { } // TEST_CASE("reg", "[.cmd]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("reg 0x01", GET, nullptr, @@ -150,7 +1118,7 @@ TEST_CASE("stopport", "[.cmd]") { // oss)); REQUIRE(oss.str() == "frames 6\n"); // } // REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); -// } else if (test::type == slsDetectorDefs::GOTTHARD) { +// } else if (test::type == defs::GOTTHARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("reg 0x023", GET, nullptr, @@ -187,7 +1155,7 @@ TEST_CASE("stopport", "[.cmd]") { // oss)); REQUIRE(oss.str() == "frames 6\n"); // } // REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); -// } else if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// } else if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("reg 0x01", GET, nullptr, @@ -228,8 +1196,8 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("update", "[.cmd][.ctb][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU || test::type == -// slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::JUNGFRAU || test::type == +// defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("update", PUT)); // REQUIRE_THROWS(multiSlsDetectorClient("update // jungfrauDetectorServer_developer", PUT)); @@ -247,8 +1215,8 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("copydetectorserver", "[.cmd][.ctb][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU || test::type == -// slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::JUNGFRAU || test::type == +// defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("copydetectorserver", PUT)); // REQUIRE_THROWS(multiSlsDetectorClient("copydetectorserver // jungfrauDetectorServer_developer", PUT)); @@ -260,8 +1228,8 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("rebootcontroller", "[.cmd][.ctb][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU || test::type == -// slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::JUNGFRAU || test::type == +// defs::CHIPTESTBOARD) { // ;//REQUIRE_NOTHROW(multiSlsDetectorClient("rebootcontroller", PUT)); // } else { // REQUIRE_THROWS(multiSlsDetectorClient("rebootcontroller", GET)); @@ -269,8 +1237,8 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("programfpga", "[.cmd][.ctb][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU || test::type == -// slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::JUNGFRAU || test::type == +// defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("programfpga fdgd.oki", PUT)); // //REQUIRE_NOTHROW(multiSlsDetectorClient("programfpga // /afs/psi.ch/project/sls_det_firmware/jungfrau_firmware/cyclone_V/v0_8/Jungfrau_MCB.pof", @@ -345,36 +1313,9 @@ TEST_CASE("stopport", "[.cmd]") { // REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader \"\"", PUT)); // } -// TEST_CASE("rx_jsonpara", "[.cmd][.moench]") { -// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader -// \"key1\":\"value1\"", PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonpara key1", GET, -// nullptr, oss)); REQUIRE(oss.str() == "rx_jsonpara value1\n"); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonpara key1 value2", -// PUT, nullptr, oss)); REQUIRE(oss.str() == "rx_jsonpara [key1, -// value2]\n"); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonpara key2 98", PUT, -// nullptr, oss)); REQUIRE(oss.str() == "rx_jsonpara [key2, 98]\n"); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader", GET, -// nullptr, oss)); REQUIRE(oss.str() == "rx_jsonaddheader -// \"key1\":\"value2\",\"key2\":98\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader \"\"", PUT)); -// } // TEST_CASE("patsetbit", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t val = 0; // { // std::ostringstream oss; @@ -396,7 +1337,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("patmask", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t val = 0; // { // std::ostringstream oss; @@ -419,7 +1360,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("patwaittime", "[.cmd][.ctb]") { // for (int loop = 0; loop < 3; ++loop) { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t val = 0; // { // std::ostringstream oss; @@ -446,7 +1387,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("patwait", "[.cmd][.ctb]") { // for (int loop = 0; loop < 3; ++loop) { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // int val = 0; // { // std::ostringstream oss; @@ -473,7 +1414,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("patnloop", "[.cmd][.ctb]") { // for (int loop = 0; loop < 3; ++loop) { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // int val = 0; // { // std::ostringstream oss; @@ -500,7 +1441,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("patloop", "[.cmd][.ctb]") { // for (int loop = 0; loop < 3; ++loop) { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint32_t limit1 = 0, limit2 = 0; // { // std::ostringstream oss; @@ -529,7 +1470,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("patlimits", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint32_t patlimit1 = 0, patlimit2 = 0; // { // std::ostringstream oss; @@ -553,7 +1494,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("patword", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t prev_value = 0; // { // std::ostringstream oss; @@ -585,7 +1526,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("patclkctrl", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t prev_value = 0; // { // std::ostringstream oss; @@ -617,7 +1558,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("patioctrl", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t prev_value = 0; // { // std::ostringstream oss; @@ -650,7 +1591,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("savepattern", "[.cmd][.ctb]") { // REQUIRE_THROWS(multiSlsDetectorClient("savepattern", GET)); -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("savepattern @@ -665,13 +1606,13 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("pattern", "[.cmd][.ctb]") { // REQUIRE_THROWS(multiSlsDetectorClient("pattern", GET)); -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // ;// todo test with real file? // } // } // TEST_CASE("led", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("led 1", PUT, nullptr, @@ -693,7 +1634,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("diodelay", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // REQUIRE_NOTHROW(multiSlsDetectorClient("diodelay 0x01010 125", PUT)); // { // std::ostringstream oss; @@ -710,7 +1651,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("extsampling", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("extsampling 1", PUT, @@ -732,7 +1673,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("extsamplingsrc", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("extsamplingsrc 1", PUT, @@ -760,8 +1701,8 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("adcinvert", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD || test::type == -// slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::CHIPTESTBOARD || test::type == +// defs::JUNGFRAU) { // std::string s; // { // std::ostringstream oss; @@ -785,7 +1726,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("adcenable", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // std::string s; // { // std::ostringstream oss; @@ -809,7 +1750,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("vm_a", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // REQUIRE_NOTHROW(multiSlsDetectorClient("vm_a", GET)); // REQUIRE_NOTHROW(multiSlsDetectorClient("vm_b", GET)); // REQUIRE_NOTHROW(multiSlsDetectorClient("vm_c", GET)); @@ -835,7 +1776,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("v_a", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // std::string s; // { // std::ostringstream oss; @@ -908,7 +1849,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("adcvpp", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // int prev_val = 0; // { // std::ostringstream oss; @@ -936,7 +1877,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("dbitpipeline", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("dbitpipeline 1", PUT, @@ -964,7 +1905,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("adcpipeline", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("adcpipeline 1", PUT, @@ -991,53 +1932,10 @@ TEST_CASE("stopport", "[.cmd]") { // } // } -// TEST_CASE("maxdbitphaseshift", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD ) { -// REQUIRE_NOTHROW(multiSlsDetectorClient("maxdbitphaseshift", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("maxdbitphaseshift 120", PUT)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("maxdbitphaseshift", GET)); -// } -// } -// TEST_CASE("dbitphase", "[.cmd][.ctb]") { -// if (test::type != slsDetectorDefs::CHIPTESTBOARD) { -// REQUIRE_THROWS(multiSlsDetectorClient("dbitphase", GET)); -// } else { -// int prev_val = 0; -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("dbitphase -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase 20", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase", GET, nullptr, -// oss)); REQUIRE(oss.str() == "dbitphase 20\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase", GET, nullptr, -// oss)); REQUIRE(oss.str() == "dbitphase 0\n"); -// } -// if (test::type == slsDetectorDefs::GOTTHARD) { -// REQUIRE_THROWS(multiSlsDetectorClient("dbitphase deg", GET)); -// } else { -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase 20 deg", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase deg", GET, -// nullptr, oss)); REQUIRE(oss.str() == "dbitphase 20 deg\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("dbitphase " + -// std::to_string(prev_val), PUT)); -// } -// } // TEST_CASE("romode", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("romode digital", PUT, @@ -1065,7 +1963,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("samples", "[.cmd][.ctb]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::CHIPTESTBOARD) { // uint64_t prev_value1 = 0; // { // std::ostringstream oss; @@ -1124,7 +2022,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("imagetest", "[.cmd][.gotthard]") { -// if (test::type == slsDetectorDefs::GOTTHARD) { +// if (test::type == defs::GOTTHARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("imagetest 1", PUT, @@ -1146,7 +2044,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("extsig", "[.cmd][.gotthard]") { -// if (test::type == slsDetectorDefs::GOTTHARD) { +// if (test::type == defs::GOTTHARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("extsig @@ -1171,7 +2069,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("exptimel", "[.cmd][.gotthard]") { -// if (test::type == slsDetectorDefs::GOTTHARD) { +// if (test::type == defs::GOTTHARD) { // REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("exptime 5 s", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); @@ -1191,9 +2089,9 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("periodl", "[.cmd][.gotthard]") { -// if (test::type == slsDetectorDefs::GOTTHARD || test::type == -// slsDetectorDefs::JUNGFRAU || test::type == -// slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type == defs::GOTTHARD || test::type == +// defs::JUNGFRAU || test::type == +// defs::CHIPTESTBOARD) { // REQUIRE_NOTHROW(multiSlsDetectorClient("frames 2", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("period 5", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); @@ -1214,7 +2112,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("roi", "[.cmd][.gotthard]") { -// if (test::type == slsDetectorDefs::GOTTHARD) { +// if (test::type == defs::GOTTHARD) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("roi 0 255", PUT, nullptr, @@ -1238,7 +2136,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("storagecell_delay", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("storagecell_delay 1.62ms", @@ -1264,7 +2162,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("storagecell_start", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("storagecell_start 1", @@ -1295,7 +2193,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("storagecells", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("storagecells 1", PUT, @@ -1323,7 +2221,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("auto_comp_disable", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("auto_comp_disable 1", @@ -1347,7 +2245,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("temp_", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // std::string s; // { // std::ostringstream oss; @@ -1396,7 +2294,7 @@ TEST_CASE("stopport", "[.cmd]") { // REQUIRE_THROWS(multiSlsDetectorClient("pulse", GET)); // REQUIRE_THROWS(multiSlsDetectorClient("pulsenmove", GET)); // REQUIRE_THROWS(multiSlsDetectorClient("pulsechip", GET)); -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // REQUIRE_NOTHROW(multiSlsDetectorClient("pulse 1 1 5", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("pulsenmove 1 1 5", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("pulsechip 1", PUT)); @@ -1408,7 +2306,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("partialreset", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("partialreset 1", PUT, @@ -1432,7 +2330,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("measuredsubperiod", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("dr 32", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); @@ -1451,7 +2349,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("measuredperiod", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // REQUIRE_NOTHROW(multiSlsDetectorClient("frames 2", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("period 1", PUT)); // REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); @@ -1470,7 +2368,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("readnlines", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("readnlines 256", PUT, @@ -1494,7 +2392,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("ratecorr", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("ratecorr 120", PUT, @@ -1520,7 +2418,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("trimval", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("trimval 63", PUT, @@ -1543,7 +2441,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("flippeddatax", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("0:flippeddatax", GET, @@ -1565,7 +2463,7 @@ TEST_CASE("stopport", "[.cmd]") { // TEST_CASE("parallel", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("parallel 1", PUT, @@ -1587,7 +2485,7 @@ TEST_CASE("stopport", "[.cmd]") { // } // TEST_CASE("gappixels", "[.cmd][.eiger]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("gappixels 1", PUT, @@ -1641,9 +2539,9 @@ TEST_CASE("zmqport", "[.cmd]") { int socketsperdetector = 1; auto det_type = det.getDetectorType().squash(); int prev = 1; - if (det_type == slsDetectorDefs::EIGER) { + if (det_type == defs::EIGER) { socketsperdetector *= 2; - } else if (det_type == slsDetectorDefs::JUNGFRAU) { + } else if (det_type == defs::JUNGFRAU) { prev = det.getNumberofUDPInterfaces().squash(); det.setNumberofUDPInterfaces(2); socketsperdetector *= 2; @@ -1673,49 +2571,18 @@ TEST_CASE("zmqport", "[.cmd]") { proxy.Call("zmqport", {}, i, GET, oss); REQUIRE(oss.str() == "zmqport " + std::to_string(port + i * socketsperdetector) + '\n'); } - if (det_type == slsDetectorDefs::JUNGFRAU) { + if (det_type == defs::JUNGFRAU) { det.setNumberofUDPInterfaces(prev); } } -TEST_CASE("fpath", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto fpath = det.getFilePath().squash(); - std::ostringstream oss1, oss2, oss3; - proxy.Call("fpath", {}, -1, GET, oss1); - REQUIRE(oss1.str() == "fpath " + fpath + "\n"); - proxy.Call("fpath", {fpath}, -1, PUT, oss2); - REQUIRE(oss2.str() == "fpath " + fpath + "\n"); - proxy.Call("fpath", {}, -1, GET, oss3); - REQUIRE(oss3.str() == "fpath " + fpath + "\n"); -} -TEST_CASE("fformat", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto fformat = det.getFileFormat(); - { - std::ostringstream oss; - proxy.Call("fformat", {"binary"}, -1, PUT, oss); - REQUIRE(oss.str() == "fformat binary\n"); - } - { - std::ostringstream oss; - proxy.Call("fformat", {}, -1, GET, oss); - REQUIRE(oss.str() == "fformat binary\n"); - } - // Reset file format after test - for (int i = 0; i != det.size(); ++i) { - det.setFileFormat(fformat[i], {i}); - } -} // TEST_CASE("txndelay", "[.cmd][.eiger][.jungfrau]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // { // REQUIRE_NOTHROW(multiSlsDetectorClient("0:txndelay_frame 50000", // PUT)); std::ostringstream oss; @@ -1752,7 +2619,7 @@ TEST_CASE("fformat", "[.cmd]") { // REQUIRE_NOTHROW(multiSlsDetectorClient("0:txndelay_right", GET, // nullptr, oss)); REQUIRE(oss.str() == "txndelay_right 0\n"); // } -// } else if (test::type == slsDetectorDefs::JUNGFRAU) { +// } else if (test::type == defs::JUNGFRAU) { // { // REQUIRE_NOTHROW(multiSlsDetectorClient("txndelay_frame 5", PUT)); // std::ostringstream oss; @@ -1776,8 +2643,8 @@ TEST_CASE("fformat", "[.cmd]") { // } // TEST_CASE("flowcontrol_10g", "[.cmd][.eiger][.jungfrau]") { -// if (test::type == slsDetectorDefs::EIGER || test::type == -// slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::EIGER || test::type == +// defs::JUNGFRAU) { // { // REQUIRE_NOTHROW(multiSlsDetectorClient("flowcontrol_10g 1", // PUT)); std::ostringstream oss; @@ -1829,9 +2696,9 @@ TEST_CASE("fformat", "[.cmd]") { // { // DetectorImpl d; // int socketsperdetector = 1; -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // socketsperdetector *= 2; -// } else if (test::type == slsDetectorDefs::JUNGFRAU) { +// } else if (test::type == defs::JUNGFRAU) { // REQUIRE_NOTHROW(multiSlsDetectorClient("numinterfaces 2", PUT)); // socketsperdetector *= 2; // } @@ -1853,7 +2720,7 @@ TEST_CASE("fformat", "[.cmd]") { // "udp_dstport " + std::to_string(port + i * socketsperdetector) + // '\n'); // } -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // REQUIRE_NOTHROW(multiSlsDetectorClient("numinterfaces 1", PUT)); // } // REQUIRE_NOTHROW(multiSlsDetectorClient("udp_dstport 50001", PUT)); @@ -1862,7 +2729,7 @@ TEST_CASE("fformat", "[.cmd]") { // REQUIRE_THROWS(multiSlsDetectorClient("udp_srcip 124586954", PUT)); // REQUIRE_THROWS(multiSlsDetectorClient("udp_srcip 999.999.0.0.0.5", PUT)); -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // /* {TODO custom srcip2 in globals // REQUIRE_NOTHROW(multiSlsDetectorClient("0:udp_srcip2 // 129.129.205.203", PUT)); std::ostringstream oss; @@ -1895,7 +2762,7 @@ TEST_CASE("fformat", "[.cmd]") { // nullptr, oss)); REQUIRE(oss.str() == "udp_dstport2 6400\n"); // } // REQUIRE_NOTHROW(multiSlsDetectorClient("udp_dstport2 50002", PUT)); -// } else if (test::type == slsDetectorDefs::EIGER) { +// } else if (test::type == defs::EIGER) { // { // REQUIRE_NOTHROW(multiSlsDetectorClient("0:udp_dstport2 6400", // PUT)); std::ostringstream oss; @@ -1913,7 +2780,7 @@ TEST_CASE("fformat", "[.cmd]") { // } // TEST_CASE("selinterface", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // REQUIRE_NOTHROW(multiSlsDetectorClient("numinterfaces 1", PUT)); // { // REQUIRE_NOTHROW(multiSlsDetectorClient("selinterface 0", PUT)); @@ -1934,7 +2801,7 @@ TEST_CASE("fformat", "[.cmd]") { // } // TEST_CASE("numinterfaces", "[.cmd][.jungfrau]") { -// if (test::type == slsDetectorDefs::JUNGFRAU) { +// if (test::type == defs::JUNGFRAU) { // { // REQUIRE_NOTHROW(multiSlsDetectorClient("numinterfaces 2", PUT)); // std::ostringstream oss; @@ -1956,49 +2823,10 @@ TEST_CASE("fformat", "[.cmd]") { // REQUIRE_THROWS(multiSlsDetectorClient("numinterfaces 0", PUT)); // } -TEST_CASE("timing", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - det.setTimingMode(defs::AUTO_TIMING); // start in auto - { - std::ostringstream oss1, oss2; - proxy.Call("timing", {"auto"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "timing auto\n"); - proxy.Call("timing", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "timing auto\n"); - } - { - std::ostringstream oss1, oss2; - proxy.Call("timing", {"trigger"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "timing trigger\n"); - proxy.Call("timing", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "timing trigger\n"); - } - auto det_type = det.getDetectorType().squash(); - if (det_type == slsDetectorDefs::EIGER) { - { - std::ostringstream oss1, oss2; - proxy.Call("timing", {"gating"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "timing gating\n"); - proxy.Call("timing", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "timing gating\n"); - } - { - std::ostringstream oss1, oss2; - proxy.Call("timing", {"burst_trigger"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "timing burst_trigger\n"); - proxy.Call("timing", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "timing burst_trigger\n"); - } - } else { - REQUIRE_THROWS(proxy.Call("timing", {"gating"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("timing", {"burst_trigger"}, -1, PUT)); - } - det.setTimingMode(defs::AUTO_TIMING); // reset to auto -} + // TEST_CASE("adc", "[.cmd][.ctb]") { -// if (test::type != slsDetectorDefs::CHIPTESTBOARD) { +// if (test::type != defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("adc 8", GET)); // } else { // REQUIRE_THROWS(multiSlsDetectorClient("adc", GET)); @@ -2010,199 +2838,11 @@ TEST_CASE("timing", "[.cmd]") { // } // } -// TEST_CASE("temp_fpga", "[.cmd][.eiger][.jungfrau][.gotthard]") { -// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpga", GET)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpga 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_fpga", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("temp_fpga ")); -// REQUIRE(std::stoi(s) != -1); -// } -// } -// TEST_CASE("temp_adc", "[.cmd][.jungfrau][.gotthard]") { -// if (test::type != slsDetectorDefs::GOTTHARD && test::type != -// slsDetectorDefs::JUNGFRAU ) { -// REQUIRE_THROWS(multiSlsDetectorClient("temp_adc", GET)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("temp_adc 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_adc", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("temp_adc ")); -// REQUIRE(std::stoi(s) != -1); -// } -// } -// TEST_CASE("temp", "[.cmd][.eiger]") { -// if (test::type != slsDetectorDefs::EIGER) { -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpgaext", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_10ge", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_dcdc", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_sodl", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_sodr", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpgafl", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpgafr", GET)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpgaext 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_10ge 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_dcdc 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_sodl 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_sodr 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpgafl 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("temp_fpgafr 0", PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_fpgaext", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_fpgaext ")); REQUIRE(std::stoi(s) != -1); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_10ge", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_10ge ")); REQUIRE(std::stoi(s) != -1); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_dcdc", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_dcdc ")); REQUIRE(std::stoi(s) != -1); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_sodl", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_sodl ")); REQUIRE(std::stoi(s) != -1); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_sodr", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_sodr ")); REQUIRE(std::stoi(s) != -1); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_fpgafl", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_fpgafl ")); REQUIRE(std::stoi(s) != -1); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:temp_fpgafr", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("temp_fpgafr ")); REQUIRE(std::stoi(s) != -1); -// } -// } -// } - -// TEST_CASE("vhighvoltage", "[.cmd]") { -// if (test::type == slsDetectorDefs::GOTTHARD) { -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 90", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 90\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 0\n"); -// } -// REQUIRE_THROWS(multiSlsDetectorClient("vhighvoltage 50", PUT)); -// } else if (test::type == slsDetectorDefs::EIGER) { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 50", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 120", PUT)); -// sleep(2); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 120\n"); -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 0", PUT)); -// sleep(2); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("0:vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 0\n"); -// } -// } else { -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 50", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 50\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 120", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 120\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vhighvoltage", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vhighvoltage 0\n"); -// } -// } -// } - -// TEST_CASE("maxadcphaseshift", "[.cmd][.ctb][.jungfrau]") { -// if (test::type != slsDetectorDefs::CHIPTESTBOARD && test::type != -// slsDetectorDefs::JUNGFRAU) { -// REQUIRE_THROWS(multiSlsDetectorClient("maxadcphaseshift", GET)); -// } else { -// REQUIRE_NOTHROW(multiSlsDetectorClient("maxadcphaseshift", GET)); -// } -// } - -// TEST_CASE("adcphase", "[.cmd][.ctb][.jungfrau][.gotthard]") { - -// if (test::type == slsDetectorDefs::GOTTHARD) { -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase 120", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase 0", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("adcphase 120 deg", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("adcphase", GET)); -// // get is -1 -// } else if (test::type == slsDetectorDefs::CHIPTESTBOARD || test::type == -// slsDetectorDefs::JUNGFRAU) { -// int prev_val = 0; -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("adcphase -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase 20", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase", GET, nullptr, -// oss)); REQUIRE(oss.str() == "adcphase 20\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase", GET, nullptr, -// oss)); REQUIRE(oss.str() == "adcphase 0\n"); -// } -// if (test::type == slsDetectorDefs::GOTTHARD) { -// REQUIRE_THROWS(multiSlsDetectorClient("adcphase deg", GET)); -// } else { -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase 20 deg", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase deg", GET, -// nullptr, oss)); REQUIRE(oss.str() == "adcphase 20 deg\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("adcphase " + -// std::to_string(prev_val), PUT)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("adcphase", GET)); -// } -// } // TEST_CASE("syncclk", "[.cmd][.ctb]") { -// if(test::type != slsDetectorDefs::CHIPTESTBOARD) { +// if(test::type != defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("syncclk", GET)); // } else { // REQUIRE_NOTHROW(multiSlsDetectorClient("syncclk", GET)); @@ -2211,7 +2851,7 @@ TEST_CASE("timing", "[.cmd]") { // } // TEST_CASE("adcclk", "[.cmd][.ctb]") { -// if(test::type != slsDetectorDefs::CHIPTESTBOARD) { +// if(test::type != defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("adcclk", GET)); // } else { // int prev_clk = 0; @@ -2239,7 +2879,7 @@ TEST_CASE("timing", "[.cmd]") { // } // TEST_CASE("dbitclk", "[.cmd][.ctb]") { -// if(test::type != slsDetectorDefs::CHIPTESTBOARD) { +// if(test::type != defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("dbitclk", GET)); // } else { // int prev_clk = 0; @@ -2267,7 +2907,7 @@ TEST_CASE("timing", "[.cmd]") { // } // TEST_CASE("runclk", "[.cmd][.ctb]") { -// if(test::type != slsDetectorDefs::CHIPTESTBOARD) { +// if(test::type != defs::CHIPTESTBOARD) { // REQUIRE_THROWS(multiSlsDetectorClient("runclk", GET)); // } else { // int prev_runclk = 0; @@ -2294,97 +2934,10 @@ TEST_CASE("timing", "[.cmd]") { // } // } -// TEST_CASE("speed", "[.cmd][.eiger][.jungfrau]") { -// if(test::type != slsDetectorDefs::EIGER && test::type != -// slsDetectorDefs::JUNGFRAU) { -// REQUIRE_THROWS(multiSlsDetectorClient("speed", GET)); -// } else { -// /*{TODO : only for new jungfrau boards -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed 0", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed", GET, nullptr, -// oss)); REQUIRE(oss.str() == "speed full_speed\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed full_speed", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed", GET, nullptr, -// oss)); REQUIRE(oss.str() == "speed full_speed\n"); -// }*/ -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed 1", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed", GET, nullptr, -// oss)); REQUIRE(oss.str() == "speed half_speed\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed half_speed", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed", GET, nullptr, -// oss)); REQUIRE(oss.str() == "speed half_speed\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed 2", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed", GET, nullptr, -// oss)); REQUIRE(oss.str() == "speed quarter_speed\n"); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed quarter_speed", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("speed", GET, nullptr, -// oss)); REQUIRE(oss.str() == "speed quarter_speed\n"); -// } -// REQUIRE_THROWS(multiSlsDetectorClient("speed 3", PUT)); -// } -// } -// TEST_CASE("triggers", "[.cmd]") { -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers 10", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers", GET, nullptr, -// oss)); REQUIRE(oss.str() == "triggers 10\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers 1", PUT)); -// } - -// TEST_CASE("settings", "[.cmd]") { -// switch(test::type) { -// case slsDetectorDefs::EIGER: -// REQUIRE_THROWS(multiSlsDetectorClient("settings mediumgain", -// PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("settings -// standard", PUT)); break; - -// case slsDetectorDefs::JUNGFRAU: -// REQUIRE_THROWS(multiSlsDetectorClient("settings standard", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("settings dynamicgain", -// PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("settings -// dynamichg0", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("settings fixgain1", -// PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("settings -// fixgain2", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("settings forceswitchg1", -// PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("settings -// forceswitchg2", PUT)); break; - -// case slsDetectorDefs::GOTTHARD: -// REQUIRE_NOTHROW(multiSlsDetectorClient("settings dynamicgain", -// PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("settings -// highgain", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("settings lowgain", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("settings mediumgain", -// PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("settings -// veryhighgain", PUT)); break; - -// default: -// REQUIRE_THROWS(multiSlsDetectorClient("settings", GET)); -// break; -// } -// } // TEST_CASE("threshold", "[.cmd]") { -// if (test::type == slsDetectorDefs::EIGER) { +// if (test::type == defs::EIGER) { // REQUIRE_NOTHROW(multiSlsDetectorClient("threshold 6400 standard", // PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("thresholdnotb 6400 // standard", PUT)); REQUIRE_NOTHROW(multiSlsDetectorClient("threshold @@ -2411,13 +2964,7 @@ TEST_CASE("timing", "[.cmd]") { // CHECK_NOTHROW(multiSlsDetectorClient("type", GET)); // } -TEST_CASE("firmwareversion", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - std::ostringstream oss; - proxy.Call("firmwareversion", {}, -1, GET, oss); - REQUIRE_THROWS(proxy.Call("firmwareversion", {"4"}, -1, PUT, oss)); -} + // TEST_CASE("status", "[.cmd]") { // Detector det; // CmdProxy proxy(&det); @@ -2452,193 +2999,10 @@ TEST_CASE("firmwareversion", "[.cmd]") { // proxy.Call("frames", {"1"}, -1, PUT); // } -// TEST_CASE("framesl", "[.cmd][.jungfrau][gotthard][ctb]") { -// if(test::type == slsDetectorDefs::EIGER) { -// REQUIRE_THROWS(multiSlsDetectorClient("framesl", GET)); -// } else { -// REQUIRE_NOTHROW(multiSlsDetectorClient("timing auto", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("frames 10", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("period 1", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("framesl", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("framesl ")); -// int framesl = std::stoi(s); -// REQUIRE(framesl > 0); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("stop", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); -// } -// } - -// TEST_CASE("triggersl", "[.cmd][.jungfrau][gotthard][ctb]") { -// if(test::type == slsDetectorDefs::EIGER) { -// REQUIRE_THROWS(multiSlsDetectorClient("triggersl", GET)); -// } else { -// REQUIRE_NOTHROW(multiSlsDetectorClient("timing trigger", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers 10", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggersl", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("triggersl -// ")); int triggersl = std::stoi(s); REQUIRE(triggersl == 8); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("stop", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("timing auto", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers 1", PUT)); -// } -// } - -// TEST_CASE("delayl", "[.cmd][.jungfrau][gotthard][ctb]") { -// if(test::type == slsDetectorDefs::EIGER) { -// REQUIRE_THROWS(multiSlsDetectorClient("delayl", GET)); -// } else if(test::type == slsDetectorDefs::GOTTHARD) { -// REQUIRE_NOTHROW(multiSlsDetectorClient("delay 0", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("delayl", GET)); -// // delayl always gives 0 for gotthard -// } else { -// REQUIRE_NOTHROW(multiSlsDetectorClient("timing trigger", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("frames 1", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers 2", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("delay 1", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("start", PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("delayl s", GET, nullptr, -// oss)); REQUIRE(oss.str() == "delayl 1s\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("stop", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("timing auto", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("triggers 1", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("delay 0", PUT)); -// } -// } -TEST_CASE("frames", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("frames", {"1000"}, -1, PUT, oss); - REQUIRE(oss.str() == "frames 1000\n"); - } - { - std::ostringstream oss; - proxy.Call("frames", {}, -1, GET, oss); - REQUIRE(oss.str() == "frames 1000\n"); - } - { - std::ostringstream oss; - proxy.Call("frames", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "frames 1\n"); - } -} -TEST_CASE("fwrite", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("fwrite", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "fwrite 1\n"); - } - { - std::ostringstream oss; - proxy.Call("fwrite", {}, -1, GET, oss); - REQUIRE(oss.str() == "fwrite 1\n"); - } - { - std::ostringstream oss; - proxy.Call("fwrite", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "fwrite 0\n"); - } -} - -TEST_CASE("foverwrite", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("foverwrite", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "foverwrite 1\n"); - } - { - std::ostringstream oss; - proxy.Call("foverwrite", {}, -1, GET, oss); - REQUIRE(oss.str() == "foverwrite 1\n"); - } - { - std::ostringstream oss; - proxy.Call("foverwrite", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "foverwrite 0\n"); - } -} - -TEST_CASE("fmaster", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("fmaster", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "fmaster 0\n"); - } - { - std::ostringstream oss; - proxy.Call("fmaster", {}, -1, GET, oss); - REQUIRE(oss.str() == "fmaster 0\n"); - } - { - std::ostringstream oss; - proxy.Call("fmaster", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "fmaster 1\n"); - } -} - -TEST_CASE("findex", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("findex", {"57"}, -1, PUT, oss); - REQUIRE(oss.str() == "findex 57\n"); - } - { - std::ostringstream oss; - proxy.Call("findex", {}, -1, GET, oss); - REQUIRE(oss.str() == "findex 57\n"); - } - { - - std::ostringstream oss; - proxy.Call("findex", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "findex 0\n"); - } -} - -TEST_CASE("fname", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("fname", {"somename"}, -1, PUT, oss); - REQUIRE(oss.str() == "fname somename\n"); - } - { - std::ostringstream oss; - proxy.Call("fname", {}, -1, GET, oss); - REQUIRE(oss.str() == "fname somename\n"); - } - { - std::ostringstream oss; - proxy.Call("fname", {"run"}, -1, PUT, oss); - REQUIRE(oss.str() == "fname run\n"); - } -} TEST_CASE("lock", "[.cmd]") { Detector det; @@ -2664,69 +3028,7 @@ TEST_CASE("lock", "[.cmd]") { // REQUIRE_NOTHROW(multiSlsDetectorClient("lastclient", GET)); // } -TEST_CASE("exptime", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("exptime", {"0.05"}, -1, PUT, oss); - REQUIRE(oss.str() == "exptime 0.05\n"); - } - { - std::ostringstream oss; - proxy.Call("exptime", {}, -1, GET, oss); - REQUIRE(oss.str() == "exptime 50ms\n"); - } - { - std::ostringstream oss; - proxy.Call("exptime", {"1s"}, -1, PUT, oss); - REQUIRE(oss.str() == "exptime 1s\n"); - } -} -TEST_CASE("period", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - { - std::ostringstream oss; - proxy.Call("period", {"1.25s"}, -1, PUT, oss); - REQUIRE(oss.str() == "period 1.25s\n"); - } - { - std::ostringstream oss; - proxy.Call("period", {}, -1, GET, oss); - REQUIRE(oss.str() == "period 1.25s\n"); - } - { - std::ostringstream oss; - proxy.Call("period", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "period 0\n"); - } -} -TEST_CASE("delay", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::EIGER) { - REQUIRE_THROWS(proxy.Call("delay", {"1"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("delay", {}, -1, GET)); - } else { - { - std::ostringstream oss; - proxy.Call("delay", {"1.25s"}, -1, PUT, oss); - REQUIRE(oss.str() == "delay 1.25s\n"); - } - { - std::ostringstream oss; - proxy.Call("delay", {}, -1, GET, oss); - REQUIRE(oss.str() == "delay 1.25s\n"); - } - { - std::ostringstream oss; - proxy.Call("delay", {"0s"}, -1, PUT, oss); - REQUIRE(oss.str() == "delay 0s\n"); - } - } -} \ No newline at end of file + diff --git a/slsDetectorSoftware/tests/test-Result.cpp b/slsDetectorSoftware/tests/test-Result.cpp index 6cc668a16..5fd666d82 100644 --- a/slsDetectorSoftware/tests/test-Result.cpp +++ b/slsDetectorSoftware/tests/test-Result.cpp @@ -2,6 +2,7 @@ #include "TypeTraits.h" #include "catch.hpp" #include +#include "ToString.h" using sls::Result; @@ -172,3 +173,26 @@ TEST_CASE("Printing Result"){ REQUIRE(os.str() == "[1, 2, 3]"); } + +TEST_CASE("String conversions"){ + Result res{1,2,3}; + REQUIRE(ToString(res) == "[1, 2, 3]"); + + Result res2{"one", "two", "three"}; + REQUIRE(ToString(res2) == "[one, two, three]"); + + using Smap = std::map; + Smap m; + m["one"] = "1"; + Result res3{m, m, m}; + REQUIRE(res3.size()== 3); + REQUIRE(ToString(res3) == "[{one: 1}, {one: 1}, {one: 1}]"); + + Smap m2; + m2["one"] = "1"; + m2["two"] = "2"; + m2["three"] = "3"; + + Result res4{m, m2, m}; + REQUIRE(ToString(res4) == "[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]"); +} diff --git a/slsReceiverSoftware/src/BinaryFileStatic.h b/slsReceiverSoftware/src/BinaryFileStatic.h index c6181eb53..80f86fbc2 100755 --- a/slsReceiverSoftware/src/BinaryFileStatic.h +++ b/slsReceiverSoftware/src/BinaryFileStatic.h @@ -128,7 +128,6 @@ class BinaryFileStatic { "SubExptime (ns) : %lld\n" "SubPeriod(ns) : %lld\n" "Period (ns) : %lld\n" - "Gap Pixels Enable : %d\n" "Quad Enable : %d\n" "Analog Flag : %d\n" "Digital Flag : %d\n" @@ -167,7 +166,6 @@ class BinaryFileStatic { (long long int)attr.subExptimeNs, (long long int)attr.subPeriodNs, (long long int)attr.periodNs, - attr.gapPixelsEnable, attr.quadEnable, attr.analogFlag, attr.digitalFlag, diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 7563fe754..2926ed72e 100755 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -16,6 +16,7 @@ #include #include #include +#include using sls::RuntimeError; using sls::SocketError; @@ -113,12 +114,16 @@ int ClientInterface::functionTable(){ 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; - flist[F_UPDATE_RECEIVER_CLIENT] = &ClientInterface::update_client; flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version; flist[F_GET_RECEIVER_TYPE] = &ClientInterface::set_detector_type; flist[F_SEND_RECEIVER_DETHOSTNAME] = &ClientInterface::set_detector_hostname; flist[F_RECEIVER_SET_ROI] = &ClientInterface::set_roi; - flist[F_RECEIVER_SET_NUM_FRAMES] = &ClientInterface::set_num_frames; + flist[F_RECEIVER_SET_NUM_FRAMES] = &ClientInterface::set_num_frames; + flist[F_SET_RECEIVER_NUM_TRIGGERS] = &ClientInterface::set_num_triggers; + flist[F_SET_RECEIVER_NUM_BURSTS] = &ClientInterface::set_num_bursts; + flist[F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS] = &ClientInterface::set_num_add_storage_cells; + flist[F_SET_RECEIVER_TIMING_MODE] = &ClientInterface::set_timing_mode; + flist[F_SET_RECEIVER_BURST_MODE] = &ClientInterface::set_burst_mode; flist[F_RECEIVER_SET_NUM_ANALOG_SAMPLES]= &ClientInterface::set_num_analog_samples; flist[F_RECEIVER_SET_NUM_DIGITAL_SAMPLES]= &ClientInterface::set_num_digital_samples; flist[F_RECEIVER_SET_EXPTIME] = &ClientInterface::set_exptime; @@ -163,7 +168,6 @@ int ClientInterface::functionTable(){ flist[F_GET_RECEIVER_STREAMING_SRC_IP] = &ClientInterface::get_streaming_source_ip; flist[F_SET_RECEIVER_SILENT_MODE] = &ClientInterface::set_silent_mode; flist[F_GET_RECEIVER_SILENT_MODE] = &ClientInterface::get_silent_mode; - flist[F_ENABLE_GAPPIXELS_IN_RECEIVER] = &ClientInterface::enable_gap_pixels; flist[F_RESTREAM_STOP_FROM_RECEIVER] = &ClientInterface::restream_stop; flist[F_SET_ADDITIONAL_JSON_HEADER] = &ClientInterface::set_additional_json_header; flist[F_GET_ADDITIONAL_JSON_HEADER] = &ClientInterface::get_additional_json_header; @@ -194,7 +198,10 @@ int ClientInterface::functionTable(){ flist[F_RECEIVER_SET_ADC_MASK_10G] = &ClientInterface::set_adc_mask_10g; flist[F_RECEIVER_SET_NUM_COUNTERS] = &ClientInterface::set_num_counters; flist[F_INCREMENT_FILE_INDEX] = &ClientInterface::increment_file_index; - + flist[F_SET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::set_additional_json_parameter; + flist[F_GET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::get_additional_json_parameter; + flist[F_GET_RECEIVER_PROGRESS] = &ClientInterface::get_progress; + for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { LOG(logDEBUG1) << "function fnum: " << i << " (" << getFunctionNameFromEnum((enum detFuncs)i) << ") located at " << flist[i]; @@ -325,29 +332,6 @@ int ClientInterface::set_port(Interface &socket) { return OK; } -int ClientInterface::update_client(Interface &socket) { - if (receiver == nullptr) - throw sls::SocketError( - "Receiver not set up. Please use rx_hostname first.\n"); - socket.Send(OK); - return send_update(socket); -} - -int ClientInterface::send_update(Interface &socket) { - int n = 0; - int i32 = -1; - - sls::IpAddr ip; - ip = server->getLastClient(); - n += socket.Send(&ip, sizeof(ip)); - - // gap pixels - i32 = (int)receiver->getGapPixelsEnable(); - n += socket.Send(&i32, sizeof(i32)); - - return OK; -} - int ClientInterface::get_version(Interface &socket) { return socket.sendResult(getReceiverVersion()); } @@ -437,8 +421,85 @@ int ClientInterface::set_roi(Interface &socket) { int ClientInterface::set_num_frames(Interface &socket) { auto value = socket.Receive(); + if (value <= 0) { + throw RuntimeError("Invalid number of frames " + + std::to_string(value)); + } + verifyIdle(socket); LOG(logDEBUG1) << "Setting num frames to " << value; impl()->setNumberOfFrames(value); + int64_t retval = impl()->getNumberOfFrames(); + validate(value, retval, "set number of frames", DEC); + return socket.Send(OK); +} + +int ClientInterface::set_num_triggers(Interface &socket) { + auto value = socket.Receive(); + if (value <= 0) { + throw RuntimeError("Invalid number of triggers " + + std::to_string(value)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting num triggers to " << value; + impl()->setNumberOfTriggers(value); + int64_t retval = impl()->getNumberOfTriggers(); + validate(value, retval, "set number of triggers", DEC); + return socket.Send(OK); +} + +int ClientInterface::set_num_bursts(Interface &socket) { + auto value = socket.Receive(); + if (value <= 0) { + throw RuntimeError("Invalid number of bursts " + + std::to_string(value)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting num bursts to " << value; + impl()->setNumberOfBursts(value); + int64_t retval = impl()->getNumberOfBursts(); + validate(value, retval, "set number of bursts", DEC); + return socket.Send(OK); +} + +int ClientInterface::set_num_add_storage_cells(Interface &socket) { + auto value = socket.Receive(); + if (value < 0) { + throw RuntimeError("Invalid number of additional storage cells " + + std::to_string(value)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting num additional storage cells to " << value; + impl()->setNumberOfAdditionalStorageCells(value); + int retval = impl()->getNumberOfAdditionalStorageCells(); + validate(value, retval, "set number of additional storage cells", DEC); + return socket.Send(OK); +} + +int ClientInterface::set_timing_mode(Interface &socket) { + auto value = socket.Receive(); + if (value < 0 || value >= NUM_TIMING_MODES) { + throw RuntimeError("Invalid timing mode " + + std::to_string(value)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting timing mode to " << value; + impl()->setTimingMode(static_cast(value)); + int retval = impl()->getTimingMode(); + validate(value, retval, "set timing mode", DEC); + return socket.Send(OK); +} + +int ClientInterface::set_burst_mode(Interface &socket) { + auto value = socket.Receive(); + if (value < 0 || value >= NUM_BURST_MODES) { + throw RuntimeError("Invalid burst mode " + + std::to_string(value)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting burst mode to " << value; + impl()->setBurstMode(static_cast(value)); + int retval = impl()->getBurstMode(); + validate(value, retval, "set burst mode", DEC); return socket.Send(OK); } @@ -989,26 +1050,6 @@ int ClientInterface::get_silent_mode(Interface &socket) { return socket.sendResult(retval); } -int ClientInterface::enable_gap_pixels(Interface &socket) { - auto enable = socket.Receive(); - if (myDetectorType != EIGER) - functionNotImplemented(); - - if (enable >= 0) { - verifyIdle(socket); - LOG(logDEBUG1) << "Setting gap pixels enable:" << enable; - try { - impl()->setGapPixelsEnable(static_cast(enable)); - } catch(const RuntimeError &e) { - throw RuntimeError("Could not set gap pixels enable to " + std::to_string(enable)); - } - } - auto retval = static_cast(impl()->getGapPixelsEnable()); - validate(enable, retval, "set gap pixels enable", DEC); - LOG(logDEBUG1) << "Gap Pixels Enable: " << retval; - return socket.sendResult(retval); -} - int ClientInterface::restream_stop(Interface &socket) { verifyIdle(socket); if (!impl()->getDataStreamEnable()) { @@ -1022,19 +1063,39 @@ int ClientInterface::restream_stop(Interface &socket) { } int ClientInterface::set_additional_json_header(Interface &socket) { - char arg[MAX_STR_LENGTH]{}; - socket.Receive(arg); + std::map json; + int size = socket.Receive(); + if (size > 0) { + char args[size * 2][SHORT_STR_LENGTH]; + memset(args, 0, sizeof(args)); + socket.Receive(args, sizeof(args)); + for (int i = 0; i < size; ++i) { + json[args[2 * i]] = args[2 * i + 1]; + } + } verifyIdle(socket); - LOG(logDEBUG1) << "Setting additional json header: " << arg; - impl()->setAdditionalJsonHeader(arg); + LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json); + impl()->setAdditionalJsonHeader(json); return socket.Send(OK); } int ClientInterface::get_additional_json_header(Interface &socket) { - char retval[MAX_STR_LENGTH]{}; - sls::strcpy_safe(retval, impl()->getAdditionalJsonHeader().c_str()); - LOG(logDEBUG1) << "additional json header:" << retval; - return socket.sendResult(retval); + std::map json = impl()->getAdditionalJsonHeader(); + LOG(logDEBUG1) << "additional json header:" << sls::ToString(json); + int size = json.size(); + socket.sendResult(size); + if (size > 0) { + char retvals[size * 2][SHORT_STR_LENGTH]; + memset(retvals, 0, sizeof(retvals)); + int iarg = 0; + for (auto & it : json) { + sls::strcpy_safe(retvals[iarg], it.first.c_str()); + sls::strcpy_safe(retvals[iarg + 1], it.second.c_str()); + iarg += 2; + } + socket.Send(retvals, sizeof(retvals)); + } + return OK; } int ClientInterface::set_udp_socket_buffer_size(Interface &socket) { @@ -1427,4 +1488,29 @@ int ClientInterface::increment_file_index(Interface &socket) { impl()->setFileIndex(impl()->getFileIndex() + 1); } return socket.Send(OK); +} + + +int ClientInterface::set_additional_json_parameter(Interface &socket) { + char args[2][SHORT_STR_LENGTH]{}; + socket.Receive(args); + verifyIdle(socket); + LOG(logDEBUG1) << "Setting additional json parameter (" << args[0] << "): " << args[1]; + impl()->setAdditionalJsonParameter(args[0], args[1]); + return socket.Send(OK); +} + +int ClientInterface::get_additional_json_parameter(Interface &socket) { + char arg[SHORT_STR_LENGTH]{}; + socket.Receive(arg); + char retval[SHORT_STR_LENGTH]{}; + sls::strcpy_safe(retval, impl()->getAdditionalJsonParameter(arg).c_str()); + LOG(logDEBUG1) << "additional json parameter (" << arg << "):" << retval; + return socket.sendResult(retval); +} + +int ClientInterface::get_progress(Interface &socket) { + int retval = impl()->getProgress(); + LOG(logDEBUG1) << "progress retval: " << retval; + return socket.sendResult(retval); } \ No newline at end of file diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index 6e1f3bc39..5aaa60ec3 100755 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -55,13 +55,16 @@ class ClientInterface : private virtual slsDetectorDefs { int lock_receiver(sls::ServerInterface &socket); int get_last_client_ip(sls::ServerInterface &socket); int set_port(sls::ServerInterface &socket); - int update_client(sls::ServerInterface &socket); - int send_update(sls::ServerInterface &socket); int get_version(sls::ServerInterface &socket); int set_detector_type(sls::ServerInterface &socket); int set_detector_hostname(sls::ServerInterface &socket); int set_roi(sls::ServerInterface &socket); int set_num_frames(sls::ServerInterface &socket); + int set_num_triggers(sls::ServerInterface &socket); + int set_num_bursts(sls::ServerInterface &socket); + int set_num_add_storage_cells(sls::ServerInterface &socket); + int set_timing_mode(sls::ServerInterface &socket); + int set_burst_mode(sls::ServerInterface &socket); int set_num_analog_samples(sls::ServerInterface &socket); int set_num_digital_samples(sls::ServerInterface &socket); int set_exptime(sls::ServerInterface &socket); @@ -107,7 +110,6 @@ class ClientInterface : private virtual slsDetectorDefs { int get_streaming_source_ip(sls::ServerInterface &socket); int set_silent_mode(sls::ServerInterface &socket); int get_silent_mode(sls::ServerInterface &socket); - int enable_gap_pixels(sls::ServerInterface &socket); int restream_stop(sls::ServerInterface &socket); int set_additional_json_header(sls::ServerInterface &socket); int get_additional_json_header(sls::ServerInterface &socket); @@ -138,6 +140,10 @@ class ClientInterface : private virtual slsDetectorDefs { int set_adc_mask_10g(sls::ServerInterface &socket); int set_num_counters(sls::ServerInterface &socket); int increment_file_index(sls::ServerInterface &socket); + int set_additional_json_parameter(sls::ServerInterface &socket); + int get_additional_json_parameter(sls::ServerInterface &socket); + int get_progress(sls::ServerInterface &socket); + Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index ed4d42e25..ad8a89a77 100755 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -25,7 +25,7 @@ const std::string DataProcessor::TypeName = "DataProcessor"; DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, bool fwenable, bool* mfwenable, - bool* dsEnable, bool* gpEnable, uint32_t* dr, + bool* dsEnable, uint32_t* dr, uint32_t* freq, uint32_t* timer, bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, std::vector * cdl, int* cdo, int* cad) : @@ -40,12 +40,10 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormatType(ftype), fileWriteEnable(fwenable), masterFileWriteEnable(mfwenable), - gapPixelsEnable(gpEnable), dynamicRange(dr), streamingFrequency(freq), streamingTimerInMs(timer), currentFreqCount(0), - tempBuffer(nullptr), activated(act), deactivatedPaddingEnable(depaden), silentMode(sm), @@ -69,7 +67,6 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, DataProcessor::~DataProcessor() { delete file; - delete [] tempBuffer; } /** getters */ @@ -116,15 +113,6 @@ void DataProcessor::ResetParametersforNewAcquisition(){ numFramesCaught = 0; firstIndex = 0; currentFrameIndex = 0; - - if (tempBuffer != nullptr) { - delete [] tempBuffer; - tempBuffer = nullptr; - } - if (*gapPixelsEnable) { - tempBuffer = new char[generalData->imageSize]; - memset(tempBuffer, 0, generalData->imageSize); - } } @@ -296,11 +284,6 @@ void DataProcessor::ProcessAnImage(char* buf) { } } - if (*gapPixelsEnable && (*dynamicRange!=4)) - InsertGapPixels(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), - *dynamicRange); - - // frame padding if (*activated && *framePadding && nump < generalData->packetsPerFrame) PadMissingPackets(buf); @@ -512,103 +495,3 @@ void DataProcessor::RearrangeDbitData(char* buf) { (*((uint32_t*)buf)) = numResult8Bits * sizeof(uint8_t); } -/** eiger specific */ -void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) { - - memset(tempBuffer, 0xFF, generalData->imageSize); - - int rightChip = ((*quadEnable) ? 0 : index); // quad enable, then faking both to be left chips - const uint32_t nx = generalData->nPixelsX; - const uint32_t ny = generalData->nPixelsY; - const uint32_t npx = nx * ny; - bool group3 = (*quadEnable) ? false : true; // if quad enabled, no last line for left chips - char* srcptr = nullptr; - char* dstptr = nullptr; - - const uint32_t b1px = generalData->imageSize / (npx); // not double as not dealing with 4 bit mode - const uint32_t b2px = 2 * b1px; - const uint32_t b1pxofst = (rightChip == 0 ? 0 : b1px); // left fpga (rightChip 0) has no extra 1px offset, but right fpga has - const uint32_t b1chip = 256 * b1px; - const uint32_t b1line = (nx * b1px); - const uint32_t bgroup3chip = b1chip + (group3 ? b1px : 0); - - // copying line by line - srcptr = buf; - dstptr = tempBuffer + b1line + b1pxofst; // left fpga (rightChip 0) has no extra 1px offset, but right fpga has - for (uint32_t i = 0; i < (ny-1); ++i) { - memcpy(dstptr, srcptr, b1chip); - srcptr += b1chip; - dstptr += (b1chip + b2px); - memcpy(dstptr, srcptr, b1chip); - srcptr += b1chip; - dstptr += bgroup3chip; - } - - // vertical filling of values - { - char* srcgp1 = nullptr; char* srcgp2 = nullptr; char* srcgp3 = nullptr; - char* dstgp1 = nullptr; char* dstgp2 = nullptr; char* dstgp3 = nullptr; - const uint32_t b3px = 3 * b1px; - - srcptr = tempBuffer + b1line; - dstptr = tempBuffer + b1line; - - for (uint32_t i = 0; i < (ny-1); ++i) { - srcgp1 = srcptr + b1pxofst + b1chip - b1px; - dstgp1 = srcgp1 + b1px; - srcgp2 = srcgp1 + b3px; - dstgp2 = dstgp1 + b1px; - if (group3) { - if (rightChip == 0u) { - srcgp3 = srcptr + b1line - b2px; - dstgp3 = srcgp3 + b1px; - } else { - srcgp3 = srcptr + b1px; - dstgp3 = srcptr; - } - } - switch (dr) { - case 8: - (*((uint8_t*)srcgp1)) = (*((uint8_t*)srcgp1))/2; (*((uint8_t*)dstgp1)) = (*((uint8_t*)srcgp1)); - (*((uint8_t*)srcgp2)) = (*((uint8_t*)srcgp2))/2; (*((uint8_t*)dstgp2)) = (*((uint8_t*)srcgp2)); - if (group3) { - (*((uint8_t*)srcgp3)) = (*((uint8_t*)srcgp3))/2; (*((uint8_t*)dstgp3)) = (*((uint8_t*)srcgp3)); - } - break; - case 16: - (*((uint16_t*)srcgp1)) = (*((uint16_t*)srcgp1))/2; (*((uint16_t*)dstgp1)) = (*((uint16_t*)srcgp1)); - (*((uint16_t*)srcgp2)) = (*((uint16_t*)srcgp2))/2; (*((uint16_t*)dstgp2)) = (*((uint16_t*)srcgp2)); - if (group3) { - (*((uint16_t*)srcgp3)) = (*((uint16_t*)srcgp3))/2; (*((uint16_t*)dstgp3)) = (*((uint16_t*)srcgp3)); - } - break; - default: - (*((uint32_t*)srcgp1)) = (*((uint32_t*)srcgp1))/2; (*((uint32_t*)dstgp1)) = (*((uint32_t*)srcgp1)); - (*((uint32_t*)srcgp2)) = (*((uint32_t*)srcgp2))/2; (*((uint32_t*)dstgp2)) = (*((uint32_t*)srcgp2)); - if (group3) { - (*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3)); - } - break; - } - srcptr += b1line; - dstptr += b1line; - } - - } - - // horizontal filling of values - srcptr = tempBuffer + b1line; - dstptr = tempBuffer; - for (uint32_t i = 0; i < nx; ++i) { - switch (dr) { - case 8: (*((uint8_t*)srcptr)) = (*((uint8_t*)srcptr))/2; (*((uint8_t*)dstptr)) = (*((uint8_t*)srcptr)); break; - case 16:(*((uint16_t*)srcptr)) = (*((uint16_t*)srcptr))/2; (*((uint16_t*)dstptr)) = (*((uint16_t*)srcptr)); break; - default:(*((uint32_t*)srcptr)) = (*((uint32_t*)srcptr))/2; (*((uint32_t*)dstptr)) = (*((uint32_t*)srcptr)); break; - } - srcptr += b1px; - dstptr += b1px; - } - - memcpy(buf, tempBuffer, generalData->imageSize); - return; -} diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 7dbce1eb1..b6cdbd21d 100755 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -33,7 +33,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { * @param fwenable file writer enable * @apram mfwenable pointer to master file write enable * @param dsEnable pointer to data stream enable - * @param gpEnable pointer to gap pixels enable * @param dr pointer to dynamic range * @param freq pointer to streaming frequency * @param timer pointer to timer if streaming frequency is random @@ -47,7 +46,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { * @param cad pointer to ctb analog databytes */ DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, - bool fwenable, bool* mfwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr, + bool fwenable, bool* mfwenable, bool* dsEnable, uint32_t* dr, uint32_t* freq, uint32_t* timer, bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, std::vector * cdl, int* cdo, int* cad); @@ -252,13 +251,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { */ void RearrangeDbitData(char* buf); - /** - * Processing Function (inserting gap pixels) eiger specific - * @param buf pointer to image - * @param dr dynamic range - */ - void InsertGapPixels(char* buf, uint32_t dr); - /** type of thread */ static const std::string TypeName; @@ -291,10 +283,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** Master File Write Enable */ bool* masterFileWriteEnable; - /** Gap Pixels Enable */ - bool* gapPixelsEnable; - - /** Dynamic Range */ uint32_t* dynamicRange; @@ -310,9 +298,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** timer beginning stamp for random streaming */ struct timespec timerBegin; - /** temporary buffer for processing */ - char* tempBuffer; - /** Activated/Deactivated */ bool* activated; diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index 9c96692cc..2b840dab1 100755 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -17,7 +17,7 @@ const std::string DataStreamer::TypeName = "DataStreamer"; DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, - uint64_t* fi, int fd, std::string* ajh, int* nd, bool* gpEnable, bool* qe) : + uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot) : ThreadObject(ind, TypeName), runningFlag(0), generalData(nullptr), @@ -28,12 +28,11 @@ DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, adcConfigured(-1), fileIndex(fi), flippedDataX(fd), - additionJsonHeader(ajh), startedFlag(false), firstIndex(0), completeBuffer(nullptr), - gapPixelsEnable(gpEnable), - quadEnable(qe) + quadEnable(qe), + totalNumFrames(tot) { numDet[0] = nd[0]; numDet[1] = nd[1]; @@ -108,6 +107,10 @@ void DataStreamer::SetFlippedDataX(int fd) { flippedDataX = fd; } +void DataStreamer::SetAdditionalJsonHeader(const std::map &json) { + additionJsonHeader = json; +} + void DataStreamer::CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip) { uint32_t portnum = port + index; std::string sip = ip.str(); @@ -217,31 +220,59 @@ void DataStreamer::ProcessAnImage(char* buf) { int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) { - if (dummy) - return zmqSocket->SendHeaderData(index, dummy,SLS_DETECTOR_JSON_HEADER_VERSION); + zmqHeader zHeader; + zHeader.data = !dummy; + zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION; + + if (dummy) { + return zmqSocket->SendHeader(index, zHeader); + } sls_detector_header header = rheader->detHeader; uint64_t frameIndex = header.frameNumber - firstIndex; uint64_t acquisitionIndex = header.frameNumber; - return zmqSocket->SendHeaderData(index, dummy, SLS_DETECTOR_JSON_HEADER_VERSION, *dynamicRange, *fileIndex, - numDet[0], numDet[1], nx, ny, size, - acquisitionIndex, frameIndex, fileNametoStream, - header.frameNumber, header.expLength, header.packetNumber, header.bunchId, header.timestamp, - header.modId, header.row, header.column, header.reserved, - header.debug, header.roundRNumber, - header.detType, header.version, - *gapPixelsEnable ? 1 : 0, flippedDataX, *quadEnable, - additionJsonHeader - ); + zHeader.dynamicRange = *dynamicRange; + zHeader.fileIndex = *fileIndex; + zHeader.ndetx = numDet[0]; + zHeader.ndety = numDet[1]; + zHeader.npixelsx = nx; + zHeader.npixelsy = ny; + zHeader.imageSize = size; + zHeader.acqIndex = acquisitionIndex; + zHeader.frameIndex = frameIndex; + zHeader.progress = 100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames)); + zHeader.fname = fileNametoStream; + zHeader.frameNumber = header.frameNumber; + zHeader.expLength = header.expLength; + zHeader.packetNumber = header.packetNumber; + zHeader.bunchId = header.bunchId; + zHeader.timestamp = header.timestamp; + zHeader.modId = header.modId; + zHeader.row = header.row; + zHeader.column = header.column; + zHeader.reserved = header.reserved; + zHeader.debug = header.debug; + zHeader.roundRNumber = header.roundRNumber; + zHeader.detType = header.detType; + zHeader.version = header.version; + zHeader.flippedDataX = flippedDataX; + zHeader.quad = *quadEnable; + zHeader.completeImage = (header.packetNumber < generalData->packetsPerFrame ? false : true); + zHeader.addJsonHeader = additionJsonHeader; + + return zmqSocket->SendHeader(index, zHeader); } void DataStreamer::RestreamStop() { //send dummy header - int ret = zmqSocket->SendHeaderData(index, true, SLS_DETECTOR_JSON_HEADER_VERSION); + zmqHeader zHeader; + zHeader.data = false; + zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION; + int ret = zmqSocket->SendHeader(index, zHeader); if (!ret) { throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber())); } diff --git a/slsReceiverSoftware/src/DataStreamer.h b/slsReceiverSoftware/src/DataStreamer.h index c3fdd8d22..4a31fa550 100755 --- a/slsReceiverSoftware/src/DataStreamer.h +++ b/slsReceiverSoftware/src/DataStreamer.h @@ -15,7 +15,7 @@ class Fifo; class DataStreamer; class ZmqSocket; -#include +#include class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { @@ -29,13 +29,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { * @param r roi * @param fi pointer to file index * @param fd flipped data enable for x dimension - * @param ajh additional json header * @param nd pointer to number of detectors in each dimension - * @param gpEnable pointer to gap pixels enable * @param qe pointer to quad Enable + * @param tot pointer to total number of frames */ DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, - uint64_t* fi, int fd, std::string* ajh, int* nd, bool* gpEnable, bool* qe); + uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot); /** * Destructor @@ -90,6 +89,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { * @param flipped data enable in x dimension */ void SetFlippedDataX(int fd); + + /** + * Set additional json header + * @param json additional json header + */ + void SetAdditionalJsonHeader(const std::map &json); /** * Creates Zmq Sockets @@ -183,7 +188,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { int flippedDataX; /** additional json header */ - std::string* additionJsonHeader; + std::map additionJsonHeader; /** Aquisition Started flag */ bool startedFlag; @@ -200,11 +205,11 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { /** Number of Detectors in X and Y dimension */ int numDet[2]; - /** Gap Pixels Enable */ - bool* gapPixelsEnable; - /** Quad Enable */ bool* quadEnable; + /** Total number of frames */ + uint64_t* totalNumFrames; + }; diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index c51fc79d6..4aec7f4ff 100755 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -171,16 +171,6 @@ public: LOG(logERROR) << "SetTenGigaEnable is a generic function that should be overloaded by a derived class"; }; - /** - * Enable Gap Pixels changes member variables - * @param enable true if gap pixels enable, else false - * @param dr dynamic range - * @param q quad enable - */ - virtual void SetGapPixelsEnable(bool b, int dr, bool q) { - LOG(logERROR) << "SetGapPixelsEnable is a generic function that should be overloaded by a derived class"; - }; - /** * Set odd starting packet (gotthard) * @param index thread index for debugging purposes @@ -424,7 +414,7 @@ class EigerData : public GeneralData { imageSize = dataSize*packetsPerFrame; maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); - defaultFifoDepth = 100; + defaultFifoDepth = 1000; threadsPerReceiver = 2; headerPacketSize = 40; standardheader = true; @@ -438,6 +428,7 @@ class EigerData : public GeneralData { void SetDynamicRange(int dr, bool tgEnable) { packetsPerFrame = (tgEnable ? 4 : 16) * dr; imageSize = dataSize*packetsPerFrame; + defaultFifoDepth = (dr == 32 ? 100 : 1000); } /** @@ -452,39 +443,6 @@ class EigerData : public GeneralData { imageSize = dataSize*packetsPerFrame; }; - /** - * Enable Gap Pixels changes member variables - * @param enable true if gap pixels enable, else false - * @param dr dynamic range - * @param q quad enable - */ - void SetGapPixelsEnable(bool b, int dr, bool q) { - if (dr == 4) - b = 0; - switch((int)b) { - case 1: - nPixelsX = (256 * 2) + 3; - if (q) { - nPixelsX = (256 * 2) + 2; - } - nPixelsY = 256 + 1; - imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit - ((dr > 8) ? 2 : // 16 bit - ((dr > 4) ? 1 : // 8 bit - 0.5))); // 4 bit - break; - default: - nPixelsX = (256*2); - nPixelsY = 256; - imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit - ((dr > 8) ? 2 : // 16 bit - ((dr > 4) ? 1 : // 8 bit - 0.5))); // 4 bit - break; - } - }; - - }; diff --git a/slsReceiverSoftware/src/HDF5FileStatic.h b/slsReceiverSoftware/src/HDF5FileStatic.h index cea07edd4..a2d4cb89a 100755 --- a/slsReceiverSoftware/src/HDF5FileStatic.h +++ b/slsReceiverSoftware/src/HDF5FileStatic.h @@ -383,41 +383,29 @@ public: attribute = dataset.createAttribute("unit",strdatatype, dataspace); attribute.write(strdatatype, std::string("ns")); - //Gap Pixels Enable - dataset = group5.createDataSet ( "gap pixels enable", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT); - - //Quad Enable - dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT); - - //Gap Pixels Enable - dataset = group5.createDataSet ( "gap pixels enable", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT); - //Quad Enable dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace ); dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT); //Analog Flag dataset = group5.createDataSet ( "analog flag", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT); + dataset.write ( &(attr.analogFlag), PredType::NATIVE_INT); //Digital Flag dataset = group5.createDataSet ( "digital flag", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT); + dataset.write ( &(attr.digitalFlag), PredType::NATIVE_INT); //ADC Mask dataset = group5.createDataSet ( "adc mask", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT); + dataset.write ( &(attr.adcmask), PredType::NATIVE_INT); //Dbit Offset dataset = group5.createDataSet ( "dbit offset", PredType::NATIVE_INT, dataspace ); - dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT); + dataset.write ( &(attr.dbitoffset), PredType::NATIVE_INT); // Dbit List dataset = group5.createDataSet ( "dbit bitset list", PredType::STD_U64LE, dataspace ); - dataset.write ( &(attr.periodNs), PredType::STD_U64LE); + dataset.write ( &(attr.dbitlist), PredType::STD_U64LE); // Roi xmin dataset = group5.createDataSet ( "roi xmin", PredType::NATIVE_INT, dataspace ); diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index d5f323c4c..73dad4599 100755 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -37,6 +37,7 @@ void Implementation::DeleteMembers() { generalData = nullptr; } + additionalJsonHeader.clear(); listener.clear(); dataProcessor.clear(); dataStreamer.clear(); @@ -92,10 +93,15 @@ void Implementation::InitializeMembers() { streamingTimerInMs = DEFAULT_STREAMING_TIMER_IN_MS; streamingPort = 0; streamingSrcIP = sls::IpAddr{}; - additionalJsonHeader = ""; // detector parameters - numberOfFrames = 0; + numberOfTotalFrames = 0; + numberOfFrames = 1; + numberOfTriggers = 1; + numberOfBursts = 1; + numberOfAdditionalStorageCells = 0; + timingMode = AUTO_TIMING; + burstMode = BURST_OFF; acquisitionPeriod = SAMPLE_TIME_IN_NS; acquisitionTime = 0; subExpTime = 0; @@ -108,7 +114,6 @@ void Implementation::InitializeMembers() { roi.xmax = -1; tengigaEnable = false; flippedDataX = 0; - gapPixelsEnable = false; quadEnable = false; activated = true; deactivatedPaddingEnable = true; @@ -182,7 +187,9 @@ void Implementation::SetupFifoStructure() { fifoDepth)); } catch (...) { fifo.clear(); - throw sls::RuntimeError("Could not allocate memory for fifo structure " + std::to_string(i)); + fifoDepth = 0; + throw sls::RuntimeError("Could not allocate memory for fifo structure " + + std::to_string(i) + ". FifoDepth is now 0."); } // set the listener & dataprocessor threads to point to the right fifo if (listener.size()) @@ -268,12 +275,12 @@ void Implementation::setDetectorType(const detectorType d) { auto fifo_ptr = fifo[i].get(); listener.push_back(sls::make_unique( i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], ð[i], - &numberOfFrames, &dynamicRange, &udpSocketBufferSize, + &numberOfTotalFrames, &dynamicRange, &udpSocketBufferSize, &actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode, &activated, &deactivatedPaddingEnable, &silentMode)); dataProcessor.push_back(sls::make_unique( i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, - &masterFileWriteEnable, &dataStreamEnable, &gapPixelsEnable, + &masterFileWriteEnable, &dataStreamEnable, &dynamicRange, &streamingFrequency, &streamingTimerInMs, &framePadding, &activated, &deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, @@ -348,7 +355,7 @@ void Implementation::setDetectorPositionId(const int id) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) { dataProcessor[i]->SetupFileWriter( fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath, - &fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfFrames, + &fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData); } assert(numDet[1] != 0); @@ -509,7 +516,7 @@ void Implementation::setFileWriteEnable(const bool b) { dataProcessor[i]->SetupFileWriter( fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads, - &numberOfFrames, &dynamicRange, &udpPortNum[i], generalData); + &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData); } } @@ -595,6 +602,24 @@ uint64_t Implementation::getAcquisitionIndex() const { return min; } +int Implementation::getProgress() const { + // get minimum of processed frame indices + uint64_t currentFrameIndex = -1; + uint32_t flagsum = 0; + + for (const auto &it : dataProcessor) { + flagsum += it->GetStartedFlag(); + uint64_t curr = it->GetProcessedIndex(); + currentFrameIndex = curr < currentFrameIndex ? curr : currentFrameIndex; + } + // no data processed + if (flagsum != dataProcessor.size()) { + currentFrameIndex = -1; + } + + return (100.00 * ((double)(currentFrameIndex + 1) / (double)numberOfTotalFrames)); +} + std::vector Implementation::getNumMissingPackets() const { std::vector mp(numThreads); for (int i = 0; i < numThreads; i++) { @@ -604,7 +629,7 @@ std::vector Implementation::getNumMissingPackets() const { if (numLinesReadout != MAX_EIGER_ROWS_PER_READOUT) { totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT); } - totnp *= numberOfFrames; + totnp *= numberOfTotalFrames; mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp); } return mp; @@ -746,7 +771,7 @@ void Implementation::startReadout() { // wait for all packets const int numPacketsToReceive = - numberOfFrames * generalData->packetsPerFrame * listener.size(); + numberOfTotalFrames * generalData->packetsPerFrame * listener.size(); if (totalPacketsReceived != numPacketsToReceive) { while (totalPacketsReceived != previousValue) { LOG(logDEBUG3) @@ -843,12 +868,11 @@ void Implementation::SetupWriter() { attr.nPixelsX = generalData->nPixelsX; attr.nPixelsY = generalData->nPixelsY; attr.maxFramesPerFile = framesPerFile; - attr.totalFrames = numberOfFrames; + attr.totalFrames = numberOfTotalFrames; attr.exptimeNs = acquisitionTime; attr.subExptimeNs = subExpTime; attr.subPeriodNs = subPeriod; attr.periodNs = acquisitionPeriod; - attr.gapPixelsEnable = gapPixelsEnable; attr.quadEnable = quadEnable; attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; attr.digitalFlag = (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; @@ -934,7 +958,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) { auto fifo_ptr = fifo[i].get(); listener.push_back(sls::make_unique( i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], - ð[i], &numberOfFrames, &dynamicRange, + ð[i], &numberOfTotalFrames, &dynamicRange, &udpSocketBufferSize, &actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode, &activated, &deactivatedPaddingEnable, &silentMode)); @@ -943,7 +967,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) { dataProcessor.push_back(sls::make_unique( i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, - &gapPixelsEnable, &dynamicRange, &streamingFrequency, + &dynamicRange, &streamingFrequency, &streamingTimerInMs, &framePadding, &activated, &deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes)); @@ -965,10 +989,11 @@ void Implementation::setNumberofUDPInterfaces(const int n) { } dataStreamer.push_back(sls::make_unique( i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, - fd, &additionalJsonHeader, (int*)nd, &gapPixelsEnable, &quadEnable)); + fd, (int*)nd, &quadEnable, &numberOfTotalFrames)); dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->CreateZmqSockets( &numThreads, streamingPort, streamingSrcIP); + dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); } catch (...) { if (dataStreamEnable) { @@ -1108,10 +1133,11 @@ void Implementation::setDataStreamEnable(const bool enable) { } dataStreamer.push_back(sls::make_unique( i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, - fd, &additionalJsonHeader, (int*)nd, &gapPixelsEnable, &quadEnable)); + fd, (int*)nd, &quadEnable, &numberOfTotalFrames)); dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->CreateZmqSockets( &numThreads, streamingPort, streamingSrcIP); + dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); } catch (...) { dataStreamer.clear(); dataStreamEnable = false; @@ -1170,23 +1196,81 @@ void Implementation::setStreamingSourceIP(const sls::IpAddr ip) { LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP; } -std::string Implementation::getAdditionalJsonHeader() const { +std::map Implementation::getAdditionalJsonHeader() const { LOG(logDEBUG3) << __SHORT_AT__ << " called"; return additionalJsonHeader; } -void Implementation::setAdditionalJsonHeader(const std::string& c) { +void Implementation::setAdditionalJsonHeader(const std::map &c) { LOG(logDEBUG3) << __SHORT_AT__ << " called"; additionalJsonHeader = c; - LOG(logINFO) << "Additional JSON Header: " << additionalJsonHeader; + for (const auto &it : dataStreamer) { + it->SetAdditionalJsonHeader(c); + } + LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader); } +std::string Implementation::getAdditionalJsonParameter(const std::string &key) const { + if (additionalJsonHeader.find(key) != additionalJsonHeader.end()) { + return additionalJsonHeader.at(key); + } + throw sls::RuntimeError("No key " + key + " found in additional json header"); +} + +void Implementation::setAdditionalJsonParameter(const std::string &key, const std::string &value) { + auto pos = additionalJsonHeader.find(key); + + // if value is empty, delete + if (value.empty()) { + // doesnt exist + if (pos == additionalJsonHeader.end()) { + LOG(logINFO) << "Additional json parameter (" << key << ") does not exist anyway"; + } else { + LOG(logINFO) << "Deleting additional json parameter (" << key << ")"; + additionalJsonHeader.erase(pos); + } + } + // if found, set it + else if (pos != additionalJsonHeader.end()) { + additionalJsonHeader[key] = value; + LOG(logINFO) << "Setting additional json parameter (" << key << ") to " << value; + } + // append if not found + else { + additionalJsonHeader[key] = value; + LOG(logINFO) << "Adding additional json parameter (" << key << ") to " << value; + } + for (const auto &it : dataStreamer) { + it->SetAdditionalJsonHeader(additionalJsonHeader); + } + LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader); +} /************************************************** * * * Detector Parameters * * * * ************************************************/ +void Implementation::updateTotalNumberOfFrames() { + int64_t repeats = numberOfTriggers; + // gotthard2: auto mode + // burst mode: (bursts instead of triggers) + // non burst mode: no bursts or triggers + if (myDetectorType == GOTTHARD2 &&timingMode == AUTO_TIMING) { + if (burstMode == BURST_OFF) { + repeats = numberOfBursts; + } else { + repeats = 1; + } + } + numberOfTotalFrames = numberOfFrames * repeats * + (int64_t)(numberOfAdditionalStorageCells + 1); + if (numberOfTotalFrames == 0) { + throw sls::RuntimeError("Invalid total number of frames to receive: 0"); + } + LOG(logINFO) << "Total Number of Frames: " << numberOfTotalFrames; +} + uint64_t Implementation::getNumberOfFrames() const { LOG(logDEBUG3) << __SHORT_AT__ << " called"; return numberOfFrames; @@ -1194,9 +1278,69 @@ uint64_t Implementation::getNumberOfFrames() const { void Implementation::setNumberOfFrames(const uint64_t i) { LOG(logDEBUG3) << __SHORT_AT__ << " called"; - numberOfFrames = i; LOG(logINFO) << "Number of Frames: " << numberOfFrames; + updateTotalNumberOfFrames(); +} + +uint64_t Implementation::getNumberOfTriggers() const { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return numberOfTriggers; +} + +void Implementation::setNumberOfTriggers(const uint64_t i) { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + numberOfTriggers = i; + LOG(logINFO) << "Number of Triggers: " << numberOfTriggers; + updateTotalNumberOfFrames(); +} + +uint64_t Implementation::getNumberOfBursts() const { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return numberOfBursts; +} + +void Implementation::setNumberOfBursts(const uint64_t i) { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + numberOfBursts = i; + LOG(logINFO) << "Number of Bursts: " << numberOfBursts; + updateTotalNumberOfFrames(); +} + +int Implementation::getNumberOfAdditionalStorageCells() const { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return numberOfAdditionalStorageCells; +} + +void Implementation::setNumberOfAdditionalStorageCells(const int i) { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + numberOfAdditionalStorageCells = i; + LOG(logINFO) << "Number of Additional Storage Cells: " << numberOfAdditionalStorageCells; + updateTotalNumberOfFrames(); +} + +slsDetectorDefs::timingMode Implementation::getTimingMode() const { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return timingMode; +} + +void Implementation::setTimingMode(const slsDetectorDefs::timingMode i) { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + timingMode = i; + LOG(logINFO) << "Timing Mode: " << timingMode; + updateTotalNumberOfFrames(); +} + +slsDetectorDefs::burstMode Implementation::getBurstMode() const { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return burstMode; +} + +void Implementation::setBurstMode(const slsDetectorDefs::burstMode i) { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + burstMode = i; + LOG(logINFO) << "Burst Mode: " << burstMode; + updateTotalNumberOfFrames(); } uint64_t Implementation::getAcquisitionPeriod() const { @@ -1330,12 +1474,10 @@ void Implementation::setDynamicRange(const uint32_t i) { if (myDetectorType == EIGER || myDetectorType == MYTHEN3) { generalData->SetDynamicRange(i, tengigaEnable); - if (myDetectorType == EIGER) { - generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable); - } // to update npixelsx, npixelsy in file writer for (const auto &it : dataProcessor) it->SetPixelDimension(); + fifoDepth = generalData->defaultFifoDepth; SetupFifoStructure(); } } @@ -1377,7 +1519,6 @@ void Implementation::setTenGigaEnable(const bool b) { switch (myDetectorType) { case EIGER: generalData->SetTenGigaEnable(b, dynamicRange); - generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable); break; case MOENCH: case CHIPTESTBOARD: @@ -1421,24 +1562,6 @@ void Implementation::setFlippedDataX(int enable) { LOG(logINFO) << "Flipped Data X: " << flippedDataX; } -bool Implementation::getGapPixelsEnable() const { - LOG(logDEBUG3) << __SHORT_AT__ << " called"; - return gapPixelsEnable; -} - -void Implementation::setGapPixelsEnable(const bool b) { - if (gapPixelsEnable != b) { - gapPixelsEnable = b; - - // side effects - generalData->SetGapPixelsEnable(b, dynamicRange, quadEnable); - for (const auto &it : dataProcessor) - it->SetPixelDimension(); - SetupFifoStructure(); - } - LOG(logINFO) << "Gap Pixels Enable: " << gapPixelsEnable; -} - bool Implementation::getQuad() const { LOG(logDEBUG) << __AT__ << " starting"; return quadEnable; @@ -1448,12 +1571,6 @@ void Implementation::setQuad(const bool b) { if (quadEnable != b) { quadEnable = b; - generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, b); - // to update npixelsx, npixelsy in file writer - for (const auto &it : dataProcessor) - it->SetPixelDimension(); - SetupFifoStructure(); - if (!quadEnable) { for (const auto &it : dataStreamer) { it->SetNumberofDetectors(numDet); diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index a5206593e..a815b14b7 100755 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -14,6 +14,7 @@ class slsDetectorDefs; #include #include #include +#include class Implementation : private virtual slsDetectorDefs { public: @@ -74,6 +75,7 @@ class Implementation : private virtual slsDetectorDefs { runStatus getStatus() const; uint64_t getFramesCaught() const; uint64_t getAcquisitionIndex() const; + int getProgress() const; std::vector getNumMissingPackets() const; void startReceiver(); void setStoppedFlag(bool stopped); @@ -123,16 +125,29 @@ class Implementation : private virtual slsDetectorDefs { void setStreamingPort(const uint32_t i); sls::IpAddr getStreamingSourceIP() const; void setStreamingSourceIP(const sls::IpAddr ip); - std::string getAdditionalJsonHeader() const; - void setAdditionalJsonHeader(const std::string& c); + std::map getAdditionalJsonHeader() const; + void setAdditionalJsonHeader(const std::map &c); + std::string getAdditionalJsonParameter(const std::string &key) const; + void setAdditionalJsonParameter(const std::string &key, const std::string &value); /************************************************** * * * Detector Parameters * * * * ************************************************/ + void updateTotalNumberOfFrames(); uint64_t getNumberOfFrames() const; void setNumberOfFrames(const uint64_t i); + uint64_t getNumberOfTriggers() const; + void setNumberOfTriggers(const uint64_t i); + uint64_t getNumberOfBursts() const; + void setNumberOfBursts(const uint64_t i); + int getNumberOfAdditionalStorageCells() const; + void setNumberOfAdditionalStorageCells(const int i); + timingMode getTimingMode() const; + void setTimingMode(const timingMode i); + burstMode getBurstMode() const; + void setBurstMode(const burstMode i); uint64_t getAcquisitionTime() const; void setAcquisitionTime(const uint64_t i); uint64_t getAcquisitionPeriod() const; @@ -161,9 +176,6 @@ class Implementation : private virtual slsDetectorDefs { void setTenGigaEnable(const bool b); int getFlippedDataX() const; void setFlippedDataX(int enable = -1); - bool getGapPixelsEnable() const; - /* [Eiger] */ - void setGapPixelsEnable(const bool b); bool getQuad() const; /* [Eiger] */ void setQuad(const bool b); @@ -263,10 +275,16 @@ class Implementation : private virtual slsDetectorDefs { uint32_t streamingTimerInMs; uint32_t streamingPort; sls::IpAddr streamingSrcIP; - std::string additionalJsonHeader; + std::map additionalJsonHeader; // detector parameters + uint64_t numberOfTotalFrames; uint64_t numberOfFrames; + uint64_t numberOfTriggers; + uint64_t numberOfBursts; + int numberOfAdditionalStorageCells; + timingMode timingMode; + burstMode burstMode; uint64_t acquisitionPeriod; uint64_t acquisitionTime; uint64_t subExpTime; @@ -278,7 +296,6 @@ class Implementation : private virtual slsDetectorDefs { ROI roi; bool tengigaEnable; int flippedDataX; - bool gapPixelsEnable; bool quadEnable; bool activated; bool deactivatedPaddingEnable; diff --git a/slsReceiverSoftware/src/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h index 2880d28fb..41eaaae16 100755 --- a/slsReceiverSoftware/src/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -74,7 +74,6 @@ struct masterAttributes { uint64_t subExptimeNs; uint64_t subPeriodNs; uint64_t periodNs; - uint32_t gapPixelsEnable; uint32_t quadEnable; uint32_t analogFlag; uint32_t digitalFlag; diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index 49c12ac93..98904031e 100755 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCES src/DataSocket.cpp src/ServerSocket.cpp src/ServerInterface.cpp + src/ToString.cpp src/network_utils.cpp src/ZmqSocket.cpp ) @@ -61,8 +62,6 @@ set_target_properties(slsSupportLib PROPERTIES PUBLIC_HEADER "${PUBLICHEADERS}" ) -message(${ZeroMQ_LIBRARIES}) - target_link_libraries(slsSupportLib PUBLIC slsProjectOptions diff --git a/slsSupportLib/include/ToString.h b/slsSupportLib/include/ToString.h index 64e442e6d..3e8dc72b8 100644 --- a/slsSupportLib/include/ToString.h +++ b/slsSupportLib/include/ToString.h @@ -14,6 +14,7 @@ #include "string_utils.h" #include #include +#include #include #include #include @@ -21,231 +22,21 @@ namespace sls { using defs = slsDetectorDefs; +std::string ToString(const defs::runStatus s); +std::string ToString(const defs::detectorType s); +std::string ToString(const defs::detectorSettings s); +std::string ToString(const defs::speedLevel s); +std::string ToString(const defs::timingMode s); +std::string ToString(const defs::frameDiscardPolicy s); +std::string ToString(const defs::fileFormat s); +std::string ToString(const defs::externalSignalFlag s); +std::string ToString(const defs::readoutMode s); +std::string ToString(const defs::frameModeType s); +std::string ToString(const defs::detectorModeType s); +std::string ToString(const defs::burstMode s); +std::string ToString(const defs::timingSourceType s); -inline std::string ToString(const defs::runStatus s) { - switch (s) { - case defs::ERROR: - return std::string("error"); - case defs::WAITING: - return std::string("waiting"); - case defs::RUNNING: - return std::string("running"); - case defs::TRANSMITTING: - return std::string("data"); - case defs::RUN_FINISHED: - return std::string("finished"); - case defs::STOPPED: - return std::string("stopped"); - default: - return std::string("idle"); - } -} - -inline std::string ToString(const defs::detectorType s) { - switch (s) { - case defs::EIGER: - return std::string("Eiger"); - case defs::GOTTHARD: - return std::string("Gotthard"); - case defs::JUNGFRAU: - return std::string("Jungfrau"); - case defs::CHIPTESTBOARD: - return std::string("ChipTestBoard"); - case defs::MOENCH: - return std::string("Moench"); - case defs::MYTHEN3: - return std::string("Mythen3"); - case defs::GOTTHARD2: - return std::string("Gotthard2"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::detectorSettings s) { - switch (s) { - case defs::STANDARD: - return std::string("standard"); - case defs::FAST: - return std::string("fast"); - case defs::HIGHGAIN: - return std::string("highgain"); - case defs::DYNAMICGAIN: - return std::string("dynamicgain"); - case defs::LOWGAIN: - return std::string("lowgain"); - case defs::MEDIUMGAIN: - return std::string("mediumgain"); - case defs::VERYHIGHGAIN: - return std::string("veryhighgain"); - case defs::DYNAMICHG0: - return std::string("dynamichg0"); - case defs::FIXGAIN1: - return std::string("fixgain1"); - case defs::FIXGAIN2: - return std::string("fixgain2"); - case defs::FORCESWITCHG1: - return std::string("forceswitchg1"); - case defs::FORCESWITCHG2: - return std::string("forceswitchg2"); - case defs::VERYLOWGAIN: - return std::string("verylowgain"); - case defs::G1_HIGHGAIN: - return std::string("g1_hg"); - case defs::G1_LOWGAIN: - return std::string("g1_lg"); - case defs::G2_HIGHCAP_HIGHGAIN: - return std::string("g2_hc_hg"); - case defs::G2_HIGHCAP_LOWGAIN: - return std::string("g2_hc_lg"); - case defs::G2_LOWCAP_HIGHGAIN: - return std::string("g2_lc_hg"); - case defs::G2_LOWCAP_LOWGAIN: - return std::string("g2_lc_lg"); - case defs::G4_HIGHGAIN: - return std::string("g4_hg"); - case defs::G4_LOWGAIN: - return std::string("g4_lg"); - case defs::UNDEFINED: - return std::string("undefined"); - case defs::UNINITIALIZED: - return std::string("uninitialized"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::speedLevel s) { - switch (s) { - case defs::FULL_SPEED: - return std::string("full_speed"); - case defs::HALF_SPEED: - return std::string("half_speed"); - case defs::QUARTER_SPEED: - return std::string("quarter_speed"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::timingMode s) { - switch (s) { - case defs::AUTO_TIMING: - return std::string("auto"); - case defs::TRIGGER_EXPOSURE: - return std::string("trigger"); - case defs::GATED: - return std::string("gating"); - case defs::BURST_TRIGGER: - return std::string("burst_trigger"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::frameDiscardPolicy s) { - switch (s) { - case defs::NO_DISCARD: - return std::string("nodiscard"); - case defs::DISCARD_EMPTY_FRAMES: - return std::string("discardempty"); - case defs::DISCARD_PARTIAL_FRAMES: - return std::string("discardpartial"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::fileFormat s) { - switch (s) { - case defs::HDF5: - return std::string("hdf5"); - case defs::BINARY: - return std::string("binary"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::externalSignalFlag s) { - switch (s) { - case defs::TRIGGER_IN_RISING_EDGE: - return std::string("trigger_in_rising_edge"); - case defs::TRIGGER_IN_FALLING_EDGE: - return std::string("trigger_in_falling_edge"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::readoutMode s) { - switch (s) { - case defs::ANALOG_ONLY: - return std::string("analog"); - case defs::DIGITAL_ONLY: - return std::string("digital"); - case defs::ANALOG_AND_DIGITAL: - return std::string("analog_digital"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::frameModeType s) { - switch (s) { - case defs::PEDESTAL: - return std::string("pedestal"); - case defs::NEW_PEDESTAL: - return std::string("newpedestal"); - case defs::FLATFIELD: - return std::string("flatfield"); - case defs::NEW_FLATFIELD: - return std::string("newflatfield"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::detectorModeType s) { - switch (s) { - case defs::COUNTING: - return std::string("counting"); - case defs::INTERPOLATING: - return std::string("interpolating"); - case defs::ANALOG: - return std::string("analog"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::burstMode s) { - switch (s) { - case defs::BURST_OFF: - return std::string("off"); - case defs::BURST_INTERNAL: - return std::string("internal"); - case defs::BURST_EXTERNAL: - return std::string("external"); - default: - return std::string("Unknown"); - } -} - -inline std::string ToString(const defs::timingSourceType s) { - switch (s) { - case defs::TIMING_INTERNAL: - return std::string("internal"); - case defs::TIMING_EXTERNAL: - return std::string("external"); - default: - return std::string("Unknown"); - } -} - -// in case we already have a string -// causes a copy but might be needed in generic code -inline std::string ToString(const std::string &s) { return s; } +const std::string &ToString(const std::string &s); /** Convert std::chrono::duration with specified output unit */ template @@ -332,6 +123,23 @@ ToStringHex(const T &container) { return os.str(); } +template +std::string ToString(const std::map &m) { + std::ostringstream os; + os << '{'; + if (!m.empty()) { + auto it = m.cbegin(); + os << ToString(it->first) << ": " << ToString(it->second); + it++; + while (it != m.cend()) { + os << ", " << ToString(it->first) << ": " << ToString(it->second); + it++; + } + } + os << '}'; + return os.str(); +} + /** * For a container loop over all elements and call ToString on the element * Container is excluded @@ -424,215 +232,24 @@ template T StringTo(const std::string &t) { return StringTo(tmp, unit); } -template <> inline defs::detectorType StringTo(const std::string &s) { - if (s == "Eiger") - return defs::EIGER; - if (s == "Gotthard") - return defs::GOTTHARD; - if (s == "Jungfrau") - return defs::JUNGFRAU; - if (s == "ChipTestBoard") - return defs::CHIPTESTBOARD; - if (s == "Moench") - return defs::MOENCH; - if (s == "Mythen3") - return defs::MYTHEN3; - if (s == "Gotthard2") - return defs::GOTTHARD2; - throw sls::RuntimeError("Unknown detector type " + s); -} +template <> defs::detectorType StringTo(const std::string &s); +template <> defs::detectorSettings StringTo(const std::string &s); +template <> defs::speedLevel StringTo(const std::string &s); +template <> defs::timingMode StringTo(const std::string &s); +template <> defs::frameDiscardPolicy StringTo(const std::string &s); +template <> defs::fileFormat StringTo(const std::string &s); +template <> defs::externalSignalFlag StringTo(const std::string &s); +template <> defs::readoutMode StringTo(const std::string &s); +template <> defs::frameModeType StringTo(const std::string &s); +template <> defs::detectorModeType StringTo(const std::string &s); +template <> defs::dacIndex StringTo(const std::string &s); +template <> defs::burstMode StringTo(const std::string &s); +template <> defs::timingSourceType StringTo(const std::string &s); -template <> inline defs::detectorSettings StringTo(const std::string &s) { - if (s == "standard") - return defs::STANDARD; - if (s == "fast") - return defs::FAST; - if (s == "highgain") - return defs::HIGHGAIN; - if (s == "dynamicgain") - return defs::DYNAMICGAIN; - if (s == "lowgain") - return defs::LOWGAIN; - if (s == "mediumgain") - return defs::MEDIUMGAIN; - if (s == "veryhighgain") - return defs::VERYHIGHGAIN; - if (s == "dynamichg0") - return defs::DYNAMICHG0; - if (s == "fixgain1") - return defs::FIXGAIN1; - if (s == "fixgain2") - return defs::FIXGAIN2; - if (s == "forceswitchg1") - return defs::FORCESWITCHG1; - if (s == "forceswitchg2") - return defs::FORCESWITCHG2; - if (s == "verylowgain") - return defs::VERYLOWGAIN; - if (s == "g1_hg") - return defs::G1_HIGHGAIN; - if (s == "g1_lg") - return defs::G1_LOWGAIN; - if (s == "g2_hc_hg") - return defs::G2_HIGHCAP_HIGHGAIN; - if (s == "g2_hc_lg") - return defs::G2_HIGHCAP_LOWGAIN; - if (s == "g2_lc_hg") - return defs::G2_LOWCAP_HIGHGAIN; - if (s == "g2_lc_lg") - return defs::G2_LOWCAP_LOWGAIN; - if (s == "g4_hg") - return defs::G4_HIGHGAIN; - if (s == "g4_lg") - return defs::G4_LOWGAIN; - throw sls::RuntimeError("Unknown setting " + s); -} - -template <> inline defs::speedLevel StringTo(const std::string &s) { - if (s == "full_speed") - return defs::FULL_SPEED; - if (s == "half_speed") - return defs::HALF_SPEED; - if (s == "quarter_speed") - return defs::QUARTER_SPEED; - throw sls::RuntimeError("Unknown speed " + s); -} - -template <> inline defs::timingMode StringTo(const std::string &s) { - if (s == "auto") - return defs::AUTO_TIMING; - if (s == "trigger") - return defs::TRIGGER_EXPOSURE; - if (s == "gating") - return defs::GATED; - if (s == "burst_trigger") - return defs::BURST_TRIGGER; - throw sls::RuntimeError("Unknown timing mode " + s); -} - -template <> inline defs::frameDiscardPolicy StringTo(const std::string &s) { - if (s == "nodiscard") - return defs::NO_DISCARD; - if (s == "discardempty") - return defs::DISCARD_EMPTY_FRAMES; - if (s == "discardpartial") - return defs::DISCARD_PARTIAL_FRAMES; - throw sls::RuntimeError("Unknown frame discard policy " + s); -} - -template <> inline defs::fileFormat StringTo(const std::string &s) { - if (s == "hdf5") - return defs::HDF5; - if (s == "binary") - return defs::BINARY; - throw sls::RuntimeError("Unknown file format " + s); -} - -template <> inline defs::externalSignalFlag StringTo(const std::string &s) { - if (s == "trigger_in_rising_edge") - return defs::TRIGGER_IN_RISING_EDGE; - if (s == "trigger_in_falling_edge") - return defs::TRIGGER_IN_FALLING_EDGE; - throw sls::RuntimeError("Unknown external signal flag " + s); -} - -template <> inline defs::readoutMode StringTo(const std::string &s) { - if (s == "analog") - return defs::ANALOG_ONLY; - if (s == "digital") - return defs::DIGITAL_ONLY; - if (s == "analog_digital") - return defs::ANALOG_AND_DIGITAL; - throw sls::RuntimeError("Unknown readout mode " + s); -} - -template <> inline defs::frameModeType StringTo(const std::string &s) { - if (s == "pedestal") - return defs::PEDESTAL; - if (s == "newpedestal") - return defs::NEW_PEDESTAL; - if (s == "flatfield") - return defs::FLATFIELD; - if (s == "newflatfield") - return defs::NEW_FLATFIELD; - throw sls::RuntimeError("Unknown frame mode " + s); -} - -template <> inline defs::detectorModeType StringTo(const std::string &s) { - if (s == "counting") - return defs::COUNTING; - if (s == "interpolating") - return defs::INTERPOLATING; - if (s == "analog") - return defs::ANALOG; - throw sls::RuntimeError("Unknown detector mode " + s); -} - -template <> inline defs::dacIndex StringTo(const std::string &s) { - if (s == "vcmp_ll") - return defs::VCMP_LL; - if (s == "vcmp_lr") - return defs::VCMP_LR; - if (s == "vcmp_rl") - return defs::VCMP_RL; - if (s == "vcmp_rr") - return defs::VCMP_RR; - if (s == "vthreshold") - return defs::THRESHOLD; - if (s == "vrf") - return defs::VRF; - if (s == "vrs") - return defs::VRS; - if (s == "vtr") - return defs::VTR; - if (s == "vcall") - return defs::CAL; - if (s == "vcp") - return defs::VCP; - throw sls::RuntimeError("Unknown dac Index " + s); -} - -template <> inline defs::burstMode StringTo(const std::string &s) { - if (s == "off") - return defs::BURST_OFF; - if (s == "internal") - return defs::BURST_INTERNAL; - if (s == "external") - return defs::BURST_EXTERNAL; - throw sls::RuntimeError("Unknown burst mode " + s); -} - -template <> inline defs::timingSourceType StringTo(const std::string &s) { - if (s == "internal") - return defs::TIMING_INTERNAL; - if (s == "external") - return defs::TIMING_EXTERNAL; - throw sls::RuntimeError("Unknown timing source type " + s); -} - -template <> -inline uint32_t StringTo(const std::string &s) { - int base = s.find("0x") != std::string::npos ? 16 : 10; - return std::stoul(s, nullptr, base); -} - -template <> -inline uint64_t StringTo(const std::string &s) { - int base = s.find("0x") != std::string::npos ? 16 : 10; - return std::stoull(s, nullptr, base); -} - -template <> -inline int StringTo(const std::string &s) { - int base = s.find("0x") != std::string::npos ? 16 : 10; - return std::stoi(s, nullptr, base); -} - -template <> -inline int64_t StringTo(const std::string &s) { - int base = s.find("0x") != std::string::npos ? 16 : 10; - return std::stol(s, nullptr, base); -} +template <> uint32_t StringTo(const std::string &s); +template <> uint64_t StringTo(const std::string &s); +template <> int StringTo(const std::string &s); +template <> int64_t StringTo(const std::string &s); /** For types with a .str() method use this for conversion */ template diff --git a/slsSupportLib/include/ZmqSocket.h b/slsSupportLib/include/ZmqSocket.h index ff1efac43..666c9e7ea 100755 --- a/slsSupportLib/include/ZmqSocket.h +++ b/slsSupportLib/include/ZmqSocket.h @@ -17,9 +17,61 @@ class zmq_msg_t; +#include + +/** zmq header structure */ +struct zmqHeader { + /** true if incoming data, false if end of acquisition */ + bool data{true}; + uint32_t jsonversion{0}; + uint32_t dynamicRange{0}; + uint64_t fileIndex{0}; + /** number of detectors in x axis */ + uint32_t ndetx{0}; + /** number of detectors in y axis */ + uint32_t ndety{0}; + /** number of pixels/channels in x axis for this zmq socket */ + uint32_t npixelsx{0}; + /** number of pixels/channels in y axis for this zmq socket */ + uint32_t npixelsy{0}; + /** number of bytes for an image in this socket */ + uint32_t imageSize{0}; + /** frame number from detector */ + uint64_t acqIndex{0}; + /** frame index (starting at 0 for each acquisition) */ + uint64_t frameIndex{0}; + /** progress in percentage */ + int progress{0}; + /** file name prefix */ + std::string fname{""}; + /** header from detector */ + uint64_t frameNumber{0}; + uint32_t expLength{0}; + uint32_t packetNumber{0}; + uint64_t bunchId{0}; + uint64_t timestamp{0}; + uint16_t modId{0}; + uint16_t row{0}; + uint16_t column{0}; + uint16_t reserved{0}; + uint32_t debug{0}; + uint16_t roundRNumber{0}; + uint8_t detType{0}; + uint8_t version{0}; + /** if image should be flipped across x axis */ + int flippedDataX{0}; + /** quad type (eiger hardware specific) */ + uint32_t quad{0}; + /** true if complete image, else missing packets */ + bool completeImage{false}; + /** additional json header */ + std::map addJsonHeader; +}; + class ZmqSocket { public: + // Socket Options for optimization // ZMQ_LINGER default is already -1 means no messages discarded. use this // options if optimizing required ZMQ_SNDHWM default is 0 means no limit. use @@ -110,47 +162,10 @@ class ZmqSocket { /** * Send Message Header * @param index self index for debugging - * @param dummy true if a dummy message for end of acquisition - * @param jsonversion json version - * @param dynamicrange dynamic range - * @param fileIndex file or acquisition index - * @param ndetx number of detectors in x axis - * @param ndety number of detectors in y axis - * @param npixelsx number of pixels/channels in x axis for this zmq socket - * @param npixelsy number of pixels/channels in y axis for this zmq socket - * @param imageSize number of bytes for an image in this socket - * @param frameNumber current frame number - * @param expLength exposure length or subframe index if eiger - * @param packetNumber number of packets caught for this frame - * @param bunchId bunch id - * @param timestamp time stamp - * @param modId module Id - * @param row row index in complete detector - * @param column column index in complete detector - * @param reserved reserved - * @param debug debug - * @param roundRNumber not used yet - * @param detType detector enum - * @param version detector header version - * @param gapPixelsEnable gap pixels enable (exception: if gap pixels enable - * for 4 bit mode, data is not yet gap pixel enabled in receiver) - * @param flippedDataX if it is flipped across x axis - * @param quadEnable if quad is enabled - * @param additionalJsonHeader additional json header + * @param header zmq header (from json) * @returns 0 if error, else 1 */ - int SendHeaderData( - int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange = 0, - uint64_t fileIndex = 0, uint32_t ndetx = 0, uint32_t ndety = 0, - uint32_t npixelsx = 0, uint32_t npixelsy = 0, uint32_t imageSize = 0, - uint64_t acqIndex = 0, uint64_t fIndex = 0, std::string fname = "", - uint64_t frameNumber = 0, uint32_t expLength = 0, - uint32_t packetNumber = 0, uint64_t bunchId = 0, uint64_t timestamp = 0, - uint16_t modId = 0, uint16_t row = 0, uint16_t column = 0, - uint16_t reserved = 0, uint32_t debug = 0, uint16_t roundRNumber = 0, - uint8_t detType = 0, uint8_t version = 0, int gapPixelsEnable = 0, - int flippedDataX = 0, uint32_t quadEnable = 0, - std::string *additionalJsonHeader = 0); + int SendHeader(int index, zmqHeader header); /** * Send Message Body @@ -159,39 +174,16 @@ class ZmqSocket { * @returns 0 if error, else 1 */ int SendData(char *buf, int length); - - - + /** - * Receive Header (Important to close message after parsing header) + * Receive Header * @param index self index for debugging - * @param document parsed document reference + * @param zHeader filled out zmqHeader structure (parsed from json header) * @param version version that has to match, -1 to not care * @returns 0 if error or end of acquisition, else 1 (call * CloseHeaderMessage after parsing header) */ - int ReceiveHeader(const int index, rapidjson::Document &document, uint32_t version); - - /** - * Close Header Message. Call this function if ReceiveHeader returned 1 - */ - // void CloseHeaderMessage() { - // if (headerMessage) - // zmq_msg_close(headerMessage); - // headerMessage = 0; - // }; - /** - * Parse Header - * @param index self index for debugging - * @param length length of message - * @param message message - * @param document parsed document reference - * @param dummy true if end of acqusition, else false, loaded upon parsing - * @param version version that has to match, -1 to not care - * @returns true if successful else false - */ - int ParseHeader(const int index, int length, char *buff, rapidjson::Document &document, - bool &dummy, uint32_t version); + int ReceiveHeader(const int index, zmqHeader& zHeader, uint32_t version); /** * Receive Data @@ -216,6 +208,19 @@ class ZmqSocket { * @returns length of message, -1 if error */ int ReceiveMessage(const int index, zmq_msg_t &message); + + /** + * Parse Header + * @param index self index for debugging + * @param length length of message + * @param message message + * @param zHeader filled out zmqHeader structure (parsed from json header) + * @param version version that has to match, -1 to not care + * @returns true if successful else false + */ + int ParseHeader(const int index, int length, char *buff, + zmqHeader& zHeader, uint32_t version); + /** * Class to close socket descriptors automatically * upon encountering exceptions in the ZmqSocket constructor @@ -246,4 +251,6 @@ class ZmqSocket { /** Socket descriptor */ mySocketDescriptors sockfd; + + }; diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 7e88d989d..8cdcee9cc 100755 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -37,7 +37,7 @@ #define DEFAULT_ZMQ_RX_PORTNO 30001 #define SLS_DETECTOR_HEADER_VERSION 0x2 -#define SLS_DETECTOR_JSON_HEADER_VERSION 0x3 +#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4 // ctb/ moench 1g udp (read from fifo) #define UDP_PACKET_DATA_BYTES (1344) @@ -61,6 +61,7 @@ /** default maximum string length */ #define MAX_STR_LENGTH 1000 +#define SHORT_STR_LENGTH 20 #define DEFAULT_STREAMING_TIMER_IN_MS 200 @@ -86,8 +87,7 @@ class slsDetectorDefs { /** return values */ enum { OK, /**< function succeeded */ - FAIL, /**< function failed */ - FORCE_UPDATE + FAIL /**< function failed */ }; /** staus mask */ @@ -244,7 +244,8 @@ class slsDetectorDefs { AUTO_TIMING, /**< internal timing */ TRIGGER_EXPOSURE, /**< trigger mode i.e. exposure is triggered */ GATED, /**< gated */ - BURST_TRIGGER /**< trigger a burst of frames */ + BURST_TRIGGER, /**< trigger a burst of frames */ + NUM_TIMING_MODES }; /** @@ -447,7 +448,8 @@ class slsDetectorDefs { enum burstMode { BURST_OFF, BURST_INTERNAL, - BURST_EXTERNAL + BURST_EXTERNAL, + NUM_BURST_MODES }; /** @@ -479,9 +481,6 @@ struct detParameters { int nChipX{0}; int nChipY{0}; int nDacs{0}; - int dynamicRange{0}; - int nGappixelsX{0}; - int nGappixelsY{0}; detParameters() = default; explicit detParameters(slsDetectorDefs::detectorType type) { @@ -492,9 +491,6 @@ struct detParameters { nChipX = 10; nChipY = 1; nDacs = 8; - dynamicRange = 16; - nGappixelsX = 0; - nGappixelsY = 0; break; case slsDetectorDefs::detectorType::JUNGFRAU: nChanX = 256; @@ -502,9 +498,6 @@ struct detParameters { nChipX = 4; nChipY = 2; nDacs = 8; - dynamicRange = 16; - nGappixelsX = 0; - nGappixelsY = 0; break; case slsDetectorDefs::detectorType::CHIPTESTBOARD: nChanX = 36; @@ -512,9 +505,6 @@ struct detParameters { nChipX = 1; nChipY = 1; nDacs = 24; - dynamicRange = 16; - nGappixelsX = 0; - nGappixelsY = 0; break; case slsDetectorDefs::detectorType::MOENCH: nChanX = 32; @@ -522,9 +512,6 @@ struct detParameters { nChipX = 1; nChipY = 1; nDacs = 8; - dynamicRange = 16; - nGappixelsX = 0; - nGappixelsY = 0; break; case slsDetectorDefs::detectorType::EIGER: nChanX = 256; @@ -532,9 +519,6 @@ struct detParameters { nChipX = 4; nChipY = 1; nDacs = 16; - dynamicRange = 16; - nGappixelsX = 6; - nGappixelsY = 1; break; case slsDetectorDefs::detectorType::MYTHEN3: nChanX = 128 * 3; @@ -542,9 +526,6 @@ struct detParameters { nChipX = 10; nChipY = 1; nDacs = 16; - dynamicRange = 32; - nGappixelsX = 0; - nGappixelsY = 0; break; case slsDetectorDefs::detectorType::GOTTHARD2: nChanX = 128; @@ -552,9 +533,6 @@ struct detParameters { nChipX = 10; nChipY = 1; nDacs = 14; - dynamicRange = 16; - nGappixelsX = 0; - nGappixelsY = 0; break; default: throw sls::RuntimeError("Unknown detector type! " + std::to_string(type)); diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index f4a4bd941..a574099f5 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -74,7 +74,6 @@ enum detFuncs{ F_LOCK_SERVER, F_GET_LAST_CLIENT_IP, F_SET_PORT, - F_UPDATE_CLIENT, F_ENABLE_TEN_GIGA, F_SET_ALL_TRIMBITS, F_SET_PATTERN_IO_CONTROL, @@ -197,6 +196,7 @@ enum detFuncs{ F_GET_TIMING_SOURCE, F_SET_TIMING_SOURCE, F_GET_NUM_CHANNELS, + F_UPDATE_RATE_CORRECTION, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */ @@ -206,12 +206,16 @@ enum detFuncs{ F_LOCK_RECEIVER, F_GET_LAST_RECEIVER_CLIENT_IP, F_SET_RECEIVER_PORT, - F_UPDATE_RECEIVER_CLIENT, F_GET_RECEIVER_VERSION, F_GET_RECEIVER_TYPE, F_SEND_RECEIVER_DETHOSTNAME, F_RECEIVER_SET_ROI, F_RECEIVER_SET_NUM_FRAMES, + F_SET_RECEIVER_NUM_TRIGGERS, + F_SET_RECEIVER_NUM_BURSTS, + F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS, + F_SET_RECEIVER_TIMING_MODE, + F_SET_RECEIVER_BURST_MODE, F_RECEIVER_SET_NUM_ANALOG_SAMPLES, F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, F_RECEIVER_SET_EXPTIME, @@ -256,7 +260,6 @@ enum detFuncs{ F_GET_RECEIVER_STREAMING_SRC_IP, F_SET_RECEIVER_SILENT_MODE, F_GET_RECEIVER_SILENT_MODE, - F_ENABLE_GAPPIXELS_IN_RECEIVER, F_RESTREAM_STOP_FROM_RECEIVER, F_SET_ADDITIONAL_JSON_HEADER, F_GET_ADDITIONAL_JSON_HEADER, @@ -287,6 +290,10 @@ enum detFuncs{ F_RECEIVER_SET_ADC_MASK_10G, F_RECEIVER_SET_NUM_COUNTERS, F_INCREMENT_FILE_INDEX, + F_SET_ADDITIONAL_JSON_PARAMETER, + F_GET_ADDITIONAL_JSON_PARAMETER, + F_GET_RECEIVER_PROGRESS, + NUM_REC_FUNCTIONS }; @@ -357,7 +364,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { 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"; - case F_UPDATE_CLIENT: return "F_UPDATE_CLIENT"; case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA"; case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS"; case F_SET_PATTERN_IO_CONTROL: return "F_SET_PATTERN_IO_CONTROL"; @@ -480,6 +486,7 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE"; case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE"; case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS"; + case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; @@ -489,12 +496,16 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { 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"; - case F_UPDATE_RECEIVER_CLIENT: return "F_UPDATE_RECEIVER_CLIENT"; case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION"; case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE"; case F_SEND_RECEIVER_DETHOSTNAME: return "F_SEND_RECEIVER_DETHOSTNAME"; case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI"; case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES"; + case F_SET_RECEIVER_NUM_TRIGGERS: return "F_SET_RECEIVER_NUM_TRIGGERS"; + case F_SET_RECEIVER_NUM_BURSTS: return "F_SET_RECEIVER_NUM_BURSTS"; + case F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS: return "F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS"; + case F_SET_RECEIVER_TIMING_MODE: return "F_SET_RECEIVER_TIMING_MODE"; + case F_SET_RECEIVER_BURST_MODE: return "F_SET_RECEIVER_BURST_MODE"; case F_RECEIVER_SET_NUM_ANALOG_SAMPLES: return "F_RECEIVER_SET_NUM_ANALOG_SAMPLES"; case F_RECEIVER_SET_NUM_DIGITAL_SAMPLES:return "F_RECEIVER_SET_NUM_DIGITAL_SAMPLES"; case F_RECEIVER_SET_EXPTIME: return "F_RECEIVER_SET_EXPTIME"; @@ -539,7 +550,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_RECEIVER_STREAMING_SRC_IP: return "F_GET_RECEIVER_STREAMING_SRC_IP"; case F_SET_RECEIVER_SILENT_MODE: return "F_SET_RECEIVER_SILENT_MODE"; case F_GET_RECEIVER_SILENT_MODE: return "F_GET_RECEIVER_SILENT_MODE"; - case F_ENABLE_GAPPIXELS_IN_RECEIVER: return "F_ENABLE_GAPPIXELS_IN_RECEIVER"; case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER"; case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER"; case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_ADDITIONAL_JSON_HEADER"; @@ -570,7 +580,9 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G"; case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS"; case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX"; - + case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER"; + case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER"; + case F_GET_RECEIVER_PROGRESS: return "F_GET_RECEIVER_PROGRESS"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function"; diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 9067d6269..9484a2c81 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -1,12 +1,12 @@ /** API versions */ -#define GITBRANCH "developer" -#define APILIB 0x200227 -#define APIRECEIVER 0x200227 -#define APIGUI 0x200227 -#define APICTB 0x200310 -#define APIGOTTHARD 0x200310 -#define APIJUNGFRAU 0x200310 -#define APIMYTHEN3 0x200310 -#define APIMOENCH 0x200310 -#define APIEIGER 0x200310 -#define APIGOTTHARD2 0x200313 +#define GITBRANCH "removeshm" +#define APILIB 0x200402 +#define APIRECEIVER 0x200402 +#define APIGUI 0x200331 +#define APICTB 0x200407 +#define APIGOTTHARD 0x200407 +#define APIGOTTHARD2 0x200407 +#define APIJUNGFRAU 0x200407 +#define APIMYTHEN3 0x200407 +#define APIMOENCH 0x200407 +#define APIEIGER 0x200408 diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp new file mode 100644 index 000000000..e119a7422 --- /dev/null +++ b/slsSupportLib/src/ToString.cpp @@ -0,0 +1,435 @@ +#include "ToString.h" + +namespace sls { + +std::string ToString(const defs::runStatus s) { + switch (s) { + case defs::ERROR: + return std::string("error"); + case defs::WAITING: + return std::string("waiting"); + case defs::RUNNING: + return std::string("running"); + case defs::TRANSMITTING: + return std::string("transmitting"); + case defs::RUN_FINISHED: + return std::string("finished"); + case defs::STOPPED: + return std::string("stopped"); + default: + return std::string("idle"); + } +} + +std::string ToString(const defs::detectorType s) { + switch (s) { + case defs::EIGER: + return std::string("Eiger"); + case defs::GOTTHARD: + return std::string("Gotthard"); + case defs::JUNGFRAU: + return std::string("Jungfrau"); + case defs::CHIPTESTBOARD: + return std::string("ChipTestBoard"); + case defs::MOENCH: + return std::string("Moench"); + case defs::MYTHEN3: + return std::string("Mythen3"); + case defs::GOTTHARD2: + return std::string("Gotthard2"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::detectorSettings s) { + switch (s) { + case defs::STANDARD: + return std::string("standard"); + case defs::FAST: + return std::string("fast"); + case defs::HIGHGAIN: + return std::string("highgain"); + case defs::DYNAMICGAIN: + return std::string("dynamicgain"); + case defs::LOWGAIN: + return std::string("lowgain"); + case defs::MEDIUMGAIN: + return std::string("mediumgain"); + case defs::VERYHIGHGAIN: + return std::string("veryhighgain"); + case defs::DYNAMICHG0: + return std::string("dynamichg0"); + case defs::FIXGAIN1: + return std::string("fixgain1"); + case defs::FIXGAIN2: + return std::string("fixgain2"); + case defs::FORCESWITCHG1: + return std::string("forceswitchg1"); + case defs::FORCESWITCHG2: + return std::string("forceswitchg2"); + case defs::VERYLOWGAIN: + return std::string("verylowgain"); + case defs::G1_HIGHGAIN: + return std::string("g1_hg"); + case defs::G1_LOWGAIN: + return std::string("g1_lg"); + case defs::G2_HIGHCAP_HIGHGAIN: + return std::string("g2_hc_hg"); + case defs::G2_HIGHCAP_LOWGAIN: + return std::string("g2_hc_lg"); + case defs::G2_LOWCAP_HIGHGAIN: + return std::string("g2_lc_hg"); + case defs::G2_LOWCAP_LOWGAIN: + return std::string("g2_lc_lg"); + case defs::G4_HIGHGAIN: + return std::string("g4_hg"); + case defs::G4_LOWGAIN: + return std::string("g4_lg"); + case defs::UNDEFINED: + return std::string("undefined"); + case defs::UNINITIALIZED: + return std::string("uninitialized"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::speedLevel s) { + switch (s) { + case defs::FULL_SPEED: + return std::string("full_speed"); + case defs::HALF_SPEED: + return std::string("half_speed"); + case defs::QUARTER_SPEED: + return std::string("quarter_speed"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::timingMode s) { + switch (s) { + case defs::AUTO_TIMING: + return std::string("auto"); + case defs::TRIGGER_EXPOSURE: + return std::string("trigger"); + case defs::GATED: + return std::string("gating"); + case defs::BURST_TRIGGER: + return std::string("burst_trigger"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::frameDiscardPolicy s) { + switch (s) { + case defs::NO_DISCARD: + return std::string("nodiscard"); + case defs::DISCARD_EMPTY_FRAMES: + return std::string("discardempty"); + case defs::DISCARD_PARTIAL_FRAMES: + return std::string("discardpartial"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::fileFormat s) { + switch (s) { + case defs::HDF5: + return std::string("hdf5"); + case defs::BINARY: + return std::string("binary"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::externalSignalFlag s) { + switch (s) { + case defs::TRIGGER_IN_RISING_EDGE: + return std::string("trigger_in_rising_edge"); + case defs::TRIGGER_IN_FALLING_EDGE: + return std::string("trigger_in_falling_edge"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::readoutMode s) { + switch (s) { + case defs::ANALOG_ONLY: + return std::string("analog"); + case defs::DIGITAL_ONLY: + return std::string("digital"); + case defs::ANALOG_AND_DIGITAL: + return std::string("analog_digital"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::frameModeType s) { + switch (s) { + case defs::PEDESTAL: + return std::string("pedestal"); + case defs::NEW_PEDESTAL: + return std::string("newpedestal"); + case defs::FLATFIELD: + return std::string("flatfield"); + case defs::NEW_FLATFIELD: + return std::string("newflatfield"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::detectorModeType s) { + switch (s) { + case defs::COUNTING: + return std::string("counting"); + case defs::INTERPOLATING: + return std::string("interpolating"); + case defs::ANALOG: + return std::string("analog"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::burstMode s) { + switch (s) { + case defs::BURST_OFF: + return std::string("off"); + case defs::BURST_INTERNAL: + return std::string("internal"); + case defs::BURST_EXTERNAL: + return std::string("external"); + default: + return std::string("Unknown"); + } +} + +std::string ToString(const defs::timingSourceType s) { + switch (s) { + case defs::TIMING_INTERNAL: + return std::string("internal"); + case defs::TIMING_EXTERNAL: + return std::string("external"); + default: + return std::string("Unknown"); + } +} + +const std::string &ToString(const std::string &s) { return s; } + +template <> defs::detectorType StringTo(const std::string &s) { + if (s == "Eiger") + return defs::EIGER; + if (s == "Gotthard") + return defs::GOTTHARD; + if (s == "Jungfrau") + return defs::JUNGFRAU; + if (s == "ChipTestBoard") + return defs::CHIPTESTBOARD; + if (s == "Moench") + return defs::MOENCH; + if (s == "Mythen3") + return defs::MYTHEN3; + if (s == "Gotthard2") + return defs::GOTTHARD2; + throw sls::RuntimeError("Unknown detector type " + s); +} + +template <> defs::detectorSettings StringTo(const std::string &s) { + if (s == "standard") + return defs::STANDARD; + if (s == "fast") + return defs::FAST; + if (s == "highgain") + return defs::HIGHGAIN; + if (s == "dynamicgain") + return defs::DYNAMICGAIN; + if (s == "lowgain") + return defs::LOWGAIN; + if (s == "mediumgain") + return defs::MEDIUMGAIN; + if (s == "veryhighgain") + return defs::VERYHIGHGAIN; + if (s == "dynamichg0") + return defs::DYNAMICHG0; + if (s == "fixgain1") + return defs::FIXGAIN1; + if (s == "fixgain2") + return defs::FIXGAIN2; + if (s == "forceswitchg1") + return defs::FORCESWITCHG1; + if (s == "forceswitchg2") + return defs::FORCESWITCHG2; + if (s == "verylowgain") + return defs::VERYLOWGAIN; + if (s == "g1_hg") + return defs::G1_HIGHGAIN; + if (s == "g1_lg") + return defs::G1_LOWGAIN; + if (s == "g2_hc_hg") + return defs::G2_HIGHCAP_HIGHGAIN; + if (s == "g2_hc_lg") + return defs::G2_HIGHCAP_LOWGAIN; + if (s == "g2_lc_hg") + return defs::G2_LOWCAP_HIGHGAIN; + if (s == "g2_lc_lg") + return defs::G2_LOWCAP_LOWGAIN; + if (s == "g4_hg") + return defs::G4_HIGHGAIN; + if (s == "g4_lg") + return defs::G4_LOWGAIN; + throw sls::RuntimeError("Unknown setting " + s); +} + +template <> defs::speedLevel StringTo(const std::string &s) { + if (s == "full_speed") + return defs::FULL_SPEED; + if (s == "half_speed") + return defs::HALF_SPEED; + if (s == "quarter_speed") + return defs::QUARTER_SPEED; + throw sls::RuntimeError("Unknown speed " + s); +} + +template <> defs::timingMode StringTo(const std::string &s) { + if (s == "auto") + return defs::AUTO_TIMING; + if (s == "trigger") + return defs::TRIGGER_EXPOSURE; + if (s == "gating") + return defs::GATED; + if (s == "burst_trigger") + return defs::BURST_TRIGGER; + throw sls::RuntimeError("Unknown timing mode " + s); +} + +template <> defs::frameDiscardPolicy StringTo(const std::string &s) { + if (s == "nodiscard") + return defs::NO_DISCARD; + if (s == "discardempty") + return defs::DISCARD_EMPTY_FRAMES; + if (s == "discardpartial") + return defs::DISCARD_PARTIAL_FRAMES; + throw sls::RuntimeError("Unknown frame discard policy " + s); +} + +template <> defs::fileFormat StringTo(const std::string &s) { + if (s == "hdf5") + return defs::HDF5; + if (s == "binary") + return defs::BINARY; + throw sls::RuntimeError("Unknown file format " + s); +} + +template <> defs::externalSignalFlag StringTo(const std::string &s) { + if (s == "trigger_in_rising_edge") + return defs::TRIGGER_IN_RISING_EDGE; + if (s == "trigger_in_falling_edge") + return defs::TRIGGER_IN_FALLING_EDGE; + throw sls::RuntimeError("Unknown external signal flag " + s); +} + +template <> defs::readoutMode StringTo(const std::string &s) { + if (s == "analog") + return defs::ANALOG_ONLY; + if (s == "digital") + return defs::DIGITAL_ONLY; + if (s == "analog_digital") + return defs::ANALOG_AND_DIGITAL; + throw sls::RuntimeError("Unknown readout mode " + s); +} + +template <> defs::frameModeType StringTo(const std::string &s) { + if (s == "pedestal") + return defs::PEDESTAL; + if (s == "newpedestal") + return defs::NEW_PEDESTAL; + if (s == "flatfield") + return defs::FLATFIELD; + if (s == "newflatfield") + return defs::NEW_FLATFIELD; + throw sls::RuntimeError("Unknown frame mode " + s); +} + +template <> defs::detectorModeType StringTo(const std::string &s) { + if (s == "counting") + return defs::COUNTING; + if (s == "interpolating") + return defs::INTERPOLATING; + if (s == "analog") + return defs::ANALOG; + throw sls::RuntimeError("Unknown detector mode " + s); +} + +template <> defs::dacIndex StringTo(const std::string &s) { + if (s == "vcmp_ll") + return defs::VCMP_LL; + if (s == "vcmp_lr") + return defs::VCMP_LR; + if (s == "vcmp_rl") + return defs::VCMP_RL; + if (s == "vcmp_rr") + return defs::VCMP_RR; + if (s == "vthreshold") + return defs::THRESHOLD; + if (s == "vrf") + return defs::VRF; + if (s == "vrs") + return defs::VRS; + if (s == "vtr") + return defs::VTR; + if (s == "vcall") + return defs::CAL; + if (s == "vcp") + return defs::VCP; + throw sls::RuntimeError("Unknown dac Index " + s); +} + +template <> defs::burstMode StringTo(const std::string &s) { + if (s == "off") + return defs::BURST_OFF; + if (s == "internal") + return defs::BURST_INTERNAL; + if (s == "external") + return defs::BURST_EXTERNAL; + throw sls::RuntimeError("Unknown burst mode " + s); +} + + +template <> defs::timingSourceType StringTo(const std::string &s) { + if (s == "internal") + return defs::TIMING_INTERNAL; + if (s == "external") + return defs::TIMING_EXTERNAL; + throw sls::RuntimeError("Unknown timing source type " + s); +} + +template <> uint32_t StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + return std::stoul(s, nullptr, base); +} + +template <> uint64_t StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + return std::stoull(s, nullptr, base); +} + +template <> int StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + return std::stoi(s, nullptr, base); +} + +template <> int64_t StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + return std::stol(s, nullptr, base); +} + +} // namespace sls \ No newline at end of file diff --git a/slsSupportLib/src/ZmqSocket.cpp b/slsSupportLib/src/ZmqSocket.cpp index 3ef63f91d..2920dd4b2 100644 --- a/slsSupportLib/src/ZmqSocket.cpp +++ b/slsSupportLib/src/ZmqSocket.cpp @@ -145,6 +145,247 @@ int ZmqSocket::ConvertInternetAddresstoIpString(struct addrinfo *res, char *ip, return 1; } +int ZmqSocket::SendHeader( + int index, zmqHeader header) { + + /** Json Header Format */ + const char jsonHeaderFormat[] = "{" + "\"jsonversion\":%u, " + "\"bitmode\":%u, " + "\"fileIndex\":%lu, " + "\"detshape\":[%u, %u], " + "\"shape\":[%u, %u], " + "\"size\":%u, " + "\"acqIndex\":%lu, " + "\"frameIndex\":%lu, " + "\"progress\":%u, " + "\"fname\":\"%s\", " + "\"data\": %d, " + "\"completeImage\": %d, " + + "\"frameNumber\":%lu, " + "\"expLength\":%u, " + "\"packetNumber\":%u, " + "\"bunchId\":%lu, " + "\"timestamp\":%lu, " + "\"modId\":%u, " + "\"row\":%u, " + "\"column\":%u, " + "\"reserved\":%u, " + "\"debug\":%u, " + "\"roundRNumber\":%u, " + "\"detType\":%u, " + "\"version\":%u, " + + // additional stuff + "\"flippedDataX\":%u, " + "\"quad\":%u" + + ; //"}\n"; + char buf[MAX_STR_LENGTH] = ""; + sprintf(buf, jsonHeaderFormat, + header.jsonversion, + header.dynamicRange, + header.fileIndex, + header.ndetx, + header.ndety, + header.npixelsx, + header.npixelsy, + header.imageSize, + header.acqIndex, + header.frameIndex, + header.progress, + header.fname.c_str(), + header.data ? 1 : 0, + header.completeImage ? 1 : 0, + + header.frameNumber, + header.expLength, + header.packetNumber, + header.bunchId, + header.timestamp, + header.modId, + header.row, + header.column, + header.reserved, + header.debug, + header.roundRNumber, + header.detType, + header.version, + + // additional stuff + header.flippedDataX, + header.quad); + + if (header.addJsonHeader.size() > 0) { + strcat(buf, ", "); + strcat(buf, "\"addJsonHeader\": {"); + for (auto it = header.addJsonHeader.begin(); it != header.addJsonHeader.end(); ++it) { + if (it != header.addJsonHeader.begin()) { + strcat(buf, ", "); + } + strcat(buf, "\""); + strcat(buf, it->first.c_str()); + strcat(buf, "\":\""); + strcat(buf, it->second.c_str()); + strcat(buf, "\""); + } + strcat(buf, " } "); + } + + strcat(buf, "}\n"); + int length = strlen(buf); + +#ifdef VERBOSE + // if(!index) + cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf); +#endif + + if (zmq_send(sockfd.socketDescriptor, buf, length, + header.data ? ZMQ_SNDMORE : 0) < 0) { + PrintError(); + return 0; + } +#ifdef VERBOSE + cprintf(GREEN, "[%u] send header data\n", portno); +#endif + return 1; +} + +int ZmqSocket::SendData(char *buf, int length) { + if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) { + PrintError(); + return 0; + } + return 1; +} + +int ZmqSocket::ReceiveHeader(const int index, zmqHeader& zHeader, + uint32_t version) { + std::vector buffer(MAX_STR_LENGTH); + int len = + zmq_recv(sockfd.socketDescriptor, buffer.data(), buffer.size(), 0); + if (len > 0) { +#ifdef ZMQ_DETAIL + cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno, + len, buffer.data()); +#endif + if (ParseHeader(index, len, buffer.data(), zHeader, version)) { +#ifdef ZMQ_DETAIL + cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index, + portno, len, buffer.data()); +#endif + if (!zHeader.data) { +#ifdef ZMQ_DETAIL + cprintf(RED, "%d [%d] Received end of acquisition\n", index, + portno); +#endif + return 0; + } +#ifdef ZMQ_DETAIL + cprintf(GREEN, "%d [%d] data\n", index, portno); +#endif + return 1; + } + } + return 0; +}; + +int ZmqSocket::ParseHeader(const int index, int length, char *buff, + zmqHeader& zHeader, uint32_t version) { + Document document; + if (document.Parse(buff, length).HasParseError()) { + LOG(logERROR) << index << " Could not parse. len:" << length + << ": Message:" << buff; + fflush(stdout); + // char* buf = (char*) zmq_msg_data (&message); + for (int i = 0; i < length; ++i) { + cprintf(RED, "%02x ", buff[i]); + } + printf("\n"); + fflush(stdout); + return 0; + } + + // version check + zHeader.jsonversion = document["jsonversion"].GetUint(); + if (zHeader.jsonversion != version) { + LOG(logERROR) << "version mismatch. required " << version << ", got " + << zHeader.jsonversion; + return 0; + } + + // parse + zHeader.data = ((document["data"].GetUint()) == 0) ? false : true; + zHeader.dynamicRange = document["bitmode"].GetUint(); + zHeader.fileIndex = document["fileIndex"].GetUint64(); + zHeader.ndetx = document["detshape"][0].GetUint(); + zHeader.ndety = document["detshape"][1].GetUint(); + zHeader.npixelsx = document["shape"][0].GetUint(); + zHeader.npixelsy = document["shape"][1].GetUint(); + zHeader.imageSize = document["size"].GetUint(); + zHeader.acqIndex = document["acqIndex"].GetUint64(); + zHeader.frameIndex = document["frameIndex"].GetUint64(); + zHeader.progress = document["progress"].GetUint(); + zHeader.fname = document["fname"].GetString(); + + zHeader.frameNumber = document["frameNumber"].GetUint64(); + zHeader.expLength = document["expLength"].GetUint(); + zHeader.packetNumber = document["packetNumber"].GetUint(); + zHeader.bunchId = document["bunchId"].GetUint64(); + zHeader.timestamp = document["timestamp"].GetUint64(); + zHeader.modId = document["modId"].GetUint(); + zHeader.row = document["row"].GetUint(); + zHeader.column = document["column"].GetUint(); + zHeader.reserved = document["reserved"].GetUint(); + zHeader.debug = document["debug"].GetUint(); + zHeader.roundRNumber = document["roundRNumber"].GetUint(); + zHeader.detType = document["detType"].GetUint(); + zHeader.version = document["version"].GetUint(); + + zHeader.flippedDataX = document["flippedDataX"].GetUint(); + zHeader.quad = document["quad"].GetUint(); + zHeader.completeImage = document["completeImage"].GetUint(); + + if (document.HasMember("addJsonHeader")) { + const Value& V = document["addJsonHeader"]; + zHeader.addJsonHeader.clear(); + for (Value::ConstMemberIterator iter = V.MemberBegin(); iter != V.MemberEnd(); ++iter){ + zHeader.addJsonHeader[iter->name.GetString()] = iter->value.GetString(); + } + } + + return 1; +} + +int ZmqSocket::ReceiveData(const int index, char *buf, const int size) { + zmq_msg_t message; + zmq_msg_init(&message); + int length = ReceiveMessage(index, message); + if (length == size) { + memcpy(buf, (char *)zmq_msg_data(&message), size); + } else if (length < size) { + memcpy(buf, (char *)zmq_msg_data(&message), length); + memset(buf + length, 0xFF, size - length); + } else { + LOG(logERROR) << "Received weird packet size " << length + << " for socket " << index; + memset(buf, 0xFF, size); + } + + zmq_msg_close(&message); + return length; +} + +int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) { + int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0); + if (length == -1) { + PrintError(); + LOG(logERROR) << "Could not read header for socket " << index; + } + return length; +} + void ZmqSocket::PrintError() { switch (errno) { case EINVAL: @@ -210,181 +451,6 @@ void ZmqSocket::PrintError() { } } -int ZmqSocket::ReceiveData(const int index, char *buf, const int size) { - zmq_msg_t message; - zmq_msg_init(&message); - int length = ReceiveMessage(index, message); - if (length == size) { - memcpy(buf, (char *)zmq_msg_data(&message), size); - } else if (length < size) { - memcpy(buf, (char *)zmq_msg_data(&message), length); - memset(buf + length, 0xFF, size - length); - } else { - LOG(logERROR) << "Received weird packet size " << length - << " for socket " << index; - memset(buf, 0xFF, size); - } - - zmq_msg_close(&message); - return length; -} - -int ZmqSocket::ParseHeader(const int index, int length, char *buff, - Document &document, bool &dummy, uint32_t version) { - if (document.Parse(buff, length).HasParseError()) { - LOG(logERROR) << index << " Could not parse. len:" << length - << ": Message:" << buff; - fflush(stdout); - // char* buf = (char*) zmq_msg_data (&message); - for (int i = 0; i < length; ++i) { - cprintf(RED, "%02x ", buff[i]); - } - printf("\n"); - fflush(stdout); - return 0; - } - - if (document["jsonversion"].GetUint() != version) { - LOG(logERROR) << "version mismatch. required " << version << ", got " - << document["jsonversion"].GetUint(); - return 0; - } - - dummy = false; - int temp = document["data"].GetUint(); - dummy = temp ? false : true; - - return 1; -} - -int ZmqSocket::ReceiveHeader(const int index, Document &document, - uint32_t version) { - std::vector buffer(MAX_STR_LENGTH); - int len = - zmq_recv(sockfd.socketDescriptor, buffer.data(), buffer.size(), 0); - if (len > 0) { - bool dummy = false; -#ifdef ZMQ_DETAIL - cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno, - len, buffer.data()); -#endif - if (ParseHeader(index, len, buffer.data(), document, dummy, version)) { -#ifdef ZMQ_DETAIL - cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index, - portno, len, buffer.data()); -#endif - if (dummy) { -#ifdef ZMQ_DETAIL - cprintf(RED, "%d [%d] Received end of acquisition\n", index, - portno); -#endif - return 0; - } -#ifdef ZMQ_DETAIL - cprintf(GREEN, "%d [%d] data\n", index, portno); -#endif - return 1; - } - } - return 0; -}; - -int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) { - int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0); - if (length == -1) { - PrintError(); - LOG(logERROR) << "Could not read header for socket " << index; - } - return length; -} - -int ZmqSocket::SendData(char *buf, int length) { - if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) { - PrintError(); - return 0; - } - return 1; -} - -int ZmqSocket::SendHeaderData( - int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange, - uint64_t fileIndex, uint32_t ndetx, uint32_t ndety, uint32_t npixelsx, - uint32_t npixelsy, uint32_t imageSize, uint64_t acqIndex, uint64_t fIndex, - std::string fname, uint64_t frameNumber, uint32_t expLength, - uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, uint16_t modId, - uint16_t row, uint16_t column, uint16_t reserved, uint32_t debug, - uint16_t roundRNumber, uint8_t detType, uint8_t version, - int gapPixelsEnable, int flippedDataX, uint32_t quadEnable, - std::string *additionalJsonHeader) { - - /** Json Header Format */ - const char jsonHeaderFormat[] = "{" - "\"jsonversion\":%u, " - "\"bitmode\":%u, " - "\"fileIndex\":%lu, " - "\"detshape\":[%u, %u], " - "\"shape\":[%u, %u], " - "\"size\":%u, " - "\"acqIndex\":%lu, " - "\"fIndex\":%lu, " - "\"fname\":\"%s\", " - "\"data\": %d, " - - "\"frameNumber\":%lu, " - "\"expLength\":%u, " - "\"packetNumber\":%u, " - "\"bunchId\":%lu, " - "\"timestamp\":%lu, " - "\"modId\":%u, " - "\"row\":%u, " - "\"column\":%u, " - "\"reserved\":%u, " - "\"debug\":%u, " - "\"roundRNumber\":%u, " - "\"detType\":%u, " - "\"version\":%u, " - - // additional stuff - "\"gappixels\":%u, " - "\"flippedDataX\":%u, " - "\"quad\":%u" - - ; //"}\n"; - char buf[MAX_STR_LENGTH] = ""; - sprintf(buf, jsonHeaderFormat, jsonversion, dynamicrange, fileIndex, ndetx, - ndety, npixelsx, npixelsy, imageSize, acqIndex, fIndex, - fname.c_str(), dummy ? 0 : 1, - - frameNumber, expLength, packetNumber, bunchId, timestamp, modId, - row, column, reserved, debug, roundRNumber, detType, version, - - // additional stuff - gapPixelsEnable, flippedDataX, quadEnable); - - if (additionalJsonHeader && !((*additionalJsonHeader).empty())) { - strcat(buf, ", "); - strcat(buf, (*additionalJsonHeader).c_str()); - } - strcat(buf, "}\n"); - int length = strlen(buf); - -#ifdef VERBOSE - // if(!index) - cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf); -#endif - - if (zmq_send(sockfd.socketDescriptor, buf, length, - dummy ? 0 : ZMQ_SNDMORE) < 0) { - PrintError(); - return 0; - } -#ifdef VERBOSE - cprintf(GREEN, "[%u] send header data\n", portno); -#endif - return 1; -} - - //Nested class to do RAII handling of socket descriptors ZmqSocket::mySocketDescriptors::mySocketDescriptors() : server(false), contextDescriptor(0), socketDescriptor(0){}; diff --git a/slsSupportLib/tests/test-ToString.cpp b/slsSupportLib/tests/test-ToString.cpp index b469b2b2f..7fc6b4bcc 100644 --- a/slsSupportLib/tests/test-ToString.cpp +++ b/slsSupportLib/tests/test-ToString.cpp @@ -4,11 +4,13 @@ #include "sls_detector_defs.h" #include "catch.hpp" #include +#include #include // using namespace sls; using sls::StringTo; using sls::ToString; +using sls::defs; using namespace sls::time; TEST_CASE("Integer conversions", "[support]") { @@ -194,3 +196,36 @@ TEST_CASE("int64_t from string"){ REQUIRE(StringTo("0xffffff") == 0xffffff); } + + +TEST_CASE("std::map of strings"){ + std::map m; + m["key"] = "value"; + auto s = ToString(m); + REQUIRE(s == "{key: value}"); + + m["chrusi"] = "musi"; + REQUIRE(ToString(m) == "{chrusi: musi, key: value}"); + + m["test"] = "tree"; + REQUIRE(ToString(m) == "{chrusi: musi, key: value, test: tree}"); + +} + +TEST_CASE("std::map of ints"){ + + std::map m; + m[5] = 10; + REQUIRE(ToString(m) == "{5: 10}"); + m[500] = 50; + REQUIRE(ToString(m) == "{5: 10, 500: 50}"); + m[372] = 999; + REQUIRE(ToString(m) == "{5: 10, 372: 999, 500: 50}"); + +} + +TEST_CASE("Detector type"){ + auto dt = defs::detectorType::EIGER; + REQUIRE(ToString(dt) == "Eiger"); + REQUIRE(StringTo("Eiger") == dt); +} \ No newline at end of file