From 23f898134610bad10ad2f94be42c46cec6ff8b56 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 25 Jun 2025 13:41:47 +0200 Subject: [PATCH] fix for eiger, added python test for testig roi in different module and detector type configurations --- slsDetectorSoftware/src/DetectorImpl.cpp | 4 + .../tests/Caller/test-Caller-rx.cpp | 17 ++- slsReceiverSoftware/src/Implementation.cpp | 14 ++- slsReceiverSoftware/src/MasterFileUtility.cpp | 4 +- tests/CMakeLists.txt | 1 + tests/scripts/test_roi.py | 114 ++++++++++++++++++ 6 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 tests/scripts/test_roi.py diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 5cb2744b5..236447a9a 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1860,6 +1860,10 @@ void DetectorImpl::setRxROI(const std::vector &args) { throw RuntimeError("No Modules added"); } + if (args.empty()) { + return clearRxROI(); + } + validateROIs(args); int nPortsPerModule = Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).tsquash("Inconsistent number of udp ports set up per module"); diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp index 9b0a42997..24f815cc7 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp @@ -626,10 +626,13 @@ TEST_CASE("rx_roi", "[.cmdcall]") { REQUIRE(oss1.str() == "rx_roi [[" + stringMin + ", " + std::to_string(portSize.x - 1) + "20, 30]]\n"); } } + std::cout << "done with eiger roi tests" << std::endl; } // multiple ports vertically - else if (numinterfaces == 2 || (det.size() == 2 && det.getModuleGeometry().y > 1)) { + if (((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) && (numinterfaces == 2)) || + (det.size() == 2 && det.getModuleGeometry().y > 1)) { + std::cout << "starting with jungfrau or other tests" << std::endl; std::string stringMin = std::to_string(portSize.y); std::string stringMax = std::to_string(portSize.y + 1); @@ -653,13 +656,19 @@ TEST_CASE("rx_roi", "[.cmdcall]") { REQUIRE(oss.str() == "rx_roi [[20, 30, " + stringMin + ", " + stringMax + "]]\n"); REQUIRE_NOTHROW( caller.call("rx_roi", {}, 0, GET, oss1)); - // non-eiger with 2 interfaces returns 2 values for 2 ports per module - if (numinterfaces == 2) { + + // non-eiger with 2 interfaces returns 2 values for 2 ports per module + if ((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) && (numinterfaces == 2)) { REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "], [20, 30, " + std::to_string(portSize.y) + ", " + stringMax + "]]\n"); } // others return only 1 roi per module (1 port per module) else { - REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "]]\n"); + // (eiger 2 ports) + if (det_type == defs::EIGER) { + REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "], [-1, -1]]\n"); + } else { + REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "]]\n"); + } } } } diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 8a9dcdd4b..9a50d3dcb 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -155,9 +155,18 @@ void Implementation::setDetectorType(const detectorType d) { break; } + if (d == EIGER) { + // resets ROIs and sets size to 2 + std::vector rois(2); + std::vector multiRoi(1); + setPortROIs(rois); + setMultiROIMetadata(multiRoi); + } + SetLocalNetworkParameters(); SetupFifoStructure(); + // create threads for (int i = 0; i < generalData->numUDPInterfaces; ++i) { @@ -1013,6 +1022,8 @@ int Implementation::getNumberofUDPInterfaces() const { // not Eiger void Implementation::setNumberofUDPInterfaces(const int n) { + LOG(logDEBUG) << "Setting Number of UDP Interfaces: " << n; + if (generalData->detType == EIGER) { throw RuntimeError("Cannot set number of UDP interfaces for Eiger"); } @@ -1031,10 +1042,9 @@ void Implementation::setNumberofUDPInterfaces(const int n) { // fifo SetupFifoStructure(); - // roi cleared - complete detector + // roi cleared - complete detector and sets roi vector size std::vector rois(n); std::vector multiRoi(1); - // recalculate port rois booleans for listener, processor and streamer setPortROIs(rois); setMultiROIMetadata(multiRoi); diff --git a/slsReceiverSoftware/src/MasterFileUtility.cpp b/slsReceiverSoftware/src/MasterFileUtility.cpp index bc9d06586..172f529d0 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.cpp +++ b/slsReceiverSoftware/src/MasterFileUtility.cpp @@ -208,7 +208,7 @@ std::string CreateVirtualHDF5File( attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue); // complete detector in roi - if (multiRoi.size() == 1 && multiRoi[0].isComplete()) { + /*if (multiRoi.size() == 1 && multiRoi[0].completeRoi()) { int ny = nPixelsY * numModY; int nx = nPixelsX * numModX; if (nPixelsY == 1) { @@ -216,7 +216,7 @@ std::string CreateVirtualHDF5File( } else { multiRoi.push_back(defs::ROI{0, nx - 1, 0, ny - 1}); } - } + }*/ for (size_t iRoi = 0; iRoi != multiRoi.size(); ++iRoi) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4811f1798..e585c90ab 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -62,3 +62,4 @@ catch_discover_tests(tests) configure_file(scripts/test_simulators.py ${CMAKE_BINARY_DIR}/bin/test_simulators.py COPYONLY) configure_file(scripts/test_frame_synchronizer.py ${CMAKE_BINARY_DIR}/bin/test_frame_synchronizer.py COPYONLY) configure_file(scripts/utils_for_test.py ${CMAKE_BINARY_DIR}/bin/utils_for_test.py COPYONLY) +configure_file(scripts/test_roi.py ${CMAKE_BINARY_DIR}/bin/test_roi.py COPYONLY) diff --git a/tests/scripts/test_roi.py b/tests/scripts/test_roi.py new file mode 100644 index 000000000..07565b591 --- /dev/null +++ b/tests/scripts/test_roi.py @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: LGPL-3.0-or-other +# Copyright (C) 2021 Contributors to the SLS Detector Package +''' +This file is used to start up simulators, receivers and test roi for every detector in many configurations. +''' + +import sys, time +import traceback + +from slsdet import Detector +from slsdet.defines import DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO + + +from utils_for_test import ( + Log, + LogLevel, + RuntimeException, + cleanup, + startProcessInBackground, + startDetectorVirtualServer, + connectToVirtualServers, + runProcessWithLogFile +) + +LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_roi_test' +MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt' +ROI_TEST_FNAME = LOG_PREFIX_FNAME + '_results_' + +def startReceiver(num_mods, fp): + if num_mods == 1: + cmd = ['slsReceiver'] + else: + cmd = ['slsMultiReceiver', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)] + # in 10.0.0 + #cmd = ['slsMultiReceiver', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)] + startProcessInBackground(cmd, fp) + time.sleep(1) + + +def loadConfigForRoi(name, fp, num_mods = 1, num_interfaces = 1): + Log(LogLevel.INFO, 'Loading config') + Log(LogLevel.INFO, 'Loading config', fp) + try: + d = connectToVirtualServers(name, num_mods) + + if name == 'jungfrau' or name == 'moench': + d.numinterfaces = num_interfaces + + d.udp_dstport = DEFAULT_UDP_DST_PORTNO + if name == 'eiger' or name == 'jungfrau' or name == 'moench': + d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1 + + d.rx_hostname = 'localhost' + d.udp_dstip = 'auto' + if name != "eiger": + d.udp_srcip = 'auto' + if name == 'jungfrau' or name == 'moench': + d.udp_dstip2 = 'auto' + + except Exception as e: + raise RuntimeException(f'Could not load config for {name}. Error: {str(e)}') from e + + + + +def startTestsForAll(fp): + servers = [ + 'eiger', + 'jungfrau', + 'mythen3', + 'gotthard2', + 'moench', + ] + nmods = 2 + for server in servers: + for ninterfaces in range(1, 2): + if ninterfaces == 2 and server != 'jungfrau' and server != 'moench': + continue + try: + msg = f'Starting Roi Tests for {server}' + if server == 'jungfrau' or server == 'moench': + msg += f' with {ninterfaces} interfaces' + Log(LogLevel.INFOBLUE, msg) + Log(LogLevel.INFOBLUE, msg, fp) + cleanup(fp) + startDetectorVirtualServer(server, nmods, fp) + startReceiver(nmods, fp) + loadConfigForRoi(name=server, fp=fp, num_mods=nmods, num_interfaces=ninterfaces) + + fname = ROI_TEST_FNAME + server + '.txt' + cmd = ['tests', 'rx_roi', '--abort', '-s'] + runProcessWithLogFile('Roi Tests for ' + server, cmd, fp, fname) + Log(LogLevel.INFO, '\n') + except Exception as e: + raise RuntimeException(f'Roi Tests failed') from e + + Log(LogLevel.INFOGREEN, 'Passed all Roi tests for all detectors \n' + str(servers)) + + +if __name__ == '__main__': + Log(LogLevel.INFOBLUE, '\nLog File: ' + MAIN_LOG_FNAME + '\n') + + with open(MAIN_LOG_FNAME, 'w') as fp: + try: + startTestsForAll(fp) + #TODO: check master file as well for both json and hdf5 as well + cleanup(fp) + except Exception as e: + with open(MAIN_LOG_FNAME, 'a') as fp_error: + traceback.print_exc(file=fp_error) + cleanup(fp) + Log(LogLevel.ERROR, f'Tests Failed.') + +