mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-14 13:57:13 +02:00
Compare commits
8 Commits
dev/client
...
dev/fix/bl
Author | SHA1 | Date | |
---|---|---|---|
5df8dfe68d | |||
bccdc32d4b | |||
cfe9600d49 | |||
d368d59ddb | |||
361cd14fde | |||
6cfe656728 | |||
ffbb84e778 | |||
9a7758655c |
@ -21,7 +21,6 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.24")
|
||||
endif()
|
||||
include(cmake/project_version.cmake)
|
||||
include(cmake/SlsAddFlag.cmake)
|
||||
include(cmake/helpers.cmake)
|
||||
|
||||
|
||||
|
||||
@ -194,9 +193,11 @@ find_package(ClangFormat)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
default_build_type("Release")
|
||||
set_std_fs_lib()
|
||||
message(STATUS "Extra linking to fs lib:${STD_FS_LIB}")
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "No build type selected, default to Release")
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Release)" FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
#Enable LTO if available
|
||||
include(CheckIPOSupported)
|
||||
|
@ -25,9 +25,7 @@ mark_as_advanced(
|
||||
ClangFormat_BIN)
|
||||
|
||||
if(ClangFormat_FOUND)
|
||||
execute_process(COMMAND ${ClangFormat_BIN} --version
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE CLANG_VERSION_TEXT)
|
||||
exec_program(${ClangFormat_BIN} ${CMAKE_CURRENT_SOURCE_DIR} ARGS --version OUTPUT_VARIABLE CLANG_VERSION_TEXT)
|
||||
string(REGEX MATCH "([0-9]+)\\.[0-9]+\\.[0-9]+" CLANG_VERSION ${CLANG_VERSION_TEXT})
|
||||
if((${CLANG_VERSION} GREATER "9") OR (${CLANG_VERSION} EQUAL "9"))
|
||||
# A CMake script to find all source files and setup clang-format targets for them
|
||||
|
@ -1,46 +0,0 @@
|
||||
function(default_build_type val)
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "No build type selected, default to Release")
|
||||
set(CMAKE_BUILD_TYPE ${val} CACHE STRING "Build type (default ${val})" FORCE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(set_std_fs_lib)
|
||||
# from pybind11
|
||||
# Check if we need to add -lstdc++fs or -lc++fs or nothing
|
||||
if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 17)
|
||||
set(STD_FS_NO_LIB_NEEDED TRUE)
|
||||
elseif(MSVC)
|
||||
set(STD_FS_NO_LIB_NEEDED TRUE)
|
||||
else()
|
||||
file(
|
||||
WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
"#include <filesystem>\nint main(int argc, char ** argv) {\n std::filesystem::path p(argv[0]);\n return p.string().length();\n}"
|
||||
)
|
||||
try_compile(
|
||||
STD_FS_NO_LIB_NEEDED ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17)
|
||||
try_compile(
|
||||
STD_FS_NEEDS_STDCXXFS ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17
|
||||
LINK_LIBRARIES stdc++fs)
|
||||
try_compile(
|
||||
STD_FS_NEEDS_CXXFS ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17
|
||||
LINK_LIBRARIES c++fs)
|
||||
endif()
|
||||
|
||||
if(${STD_FS_NEEDS_STDCXXFS})
|
||||
set(STD_FS_LIB stdc++fs PARENT_SCOPE)
|
||||
elseif(${STD_FS_NEEDS_CXXFS})
|
||||
set(STD_FS_LIB c++fs PARENT_SCOPE)
|
||||
elseif(${STD_FS_NO_LIB_NEEDED})
|
||||
set(STD_FS_LIB "" PARENT_SCOPE)
|
||||
else()
|
||||
message(WARNING "Unknown C++17 compiler - not passing -lstdc++fs")
|
||||
set(STD_FS_LIB "")
|
||||
endif()
|
||||
endfunction()
|
@ -28,8 +28,7 @@ requirements:
|
||||
- libgl-devel # [linux]
|
||||
- libtiff
|
||||
- zlib
|
||||
- expat
|
||||
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
@ -58,7 +57,6 @@ outputs:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
||||
|
||||
run:
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
@ -81,9 +81,8 @@ Welcome to slsDetectorPackage's documentation!
|
||||
:caption: Receiver
|
||||
:maxdepth: 2
|
||||
|
||||
slsreceiver
|
||||
receivers
|
||||
|
||||
slsreceiver
|
||||
|
||||
.. toctree::
|
||||
:caption: Receiver Files
|
||||
|
@ -6,33 +6,18 @@
|
||||
Installation
|
||||
===============
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 2
|
||||
:backlinks: top
|
||||
|
||||
|
||||
Overview
|
||||
--------------
|
||||
|
||||
The ``slsDetectorPackage`` provides core detector software implemented in C++, along with Python bindings packaged as the ``slsdet`` Python extension module. Choose the option that best fits your environment and use case.
|
||||
|
||||
:ref:`conda pre-built binaries`:
|
||||
Install pre-built binaries for the C++ client, receiver, GUI and the Python API (``slsdet``), simplifying setup across platforms.
|
||||
|
||||
:ref:`pip`:
|
||||
Install only the Python extension module, either by downloading the pre-built library from PyPI or by building the extension locally from source. Available only from v9.2.0 onwards.
|
||||
|
||||
:ref:`build from source`:
|
||||
Compile the entire package yourself, including both the C++ core and the Python bindings, for maximum control and customization. However, make sure that you have the :doc:`dependencies <../dependencies>` installed. If installing using conda, conda will manage the dependencies. Avoid installing packages with pip and conda simultaneously.
|
||||
|
||||
|
||||
One can either install pre-built binaries using conda or build from source.
|
||||
|
||||
.. warning ::
|
||||
|
||||
Before building from source make sure that you have the
|
||||
:doc:`dependencies <../dependencies>` installed. If installing using conda, conda will
|
||||
manage the dependencies. Avoid also installing packages with pip.
|
||||
|
||||
.. _conda pre-built binaries:
|
||||
|
||||
1. Install pre-built binaries using conda (Recommended)
|
||||
--------------------------------------------------------
|
||||
|
||||
Install binaries using conda
|
||||
----------------------------------
|
||||
|
||||
Conda is not only useful to manage python environments but can also
|
||||
be used as a user space package manager. Dates in the tag (for eg. 2020.07.23.dev0)
|
||||
@ -78,29 +63,12 @@ We have four different packages available:
|
||||
conda search moenchzmq
|
||||
|
||||
|
||||
.. _pip:
|
||||
|
||||
2. Pip
|
||||
-------
|
||||
The Python extension module ``slsdet`` can be installed using pip. This is available from v9.2.0 onwards.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
#Install the Python extension module from PyPI
|
||||
pip install slsdet
|
||||
|
||||
# or install the python extension locally from source
|
||||
git clone https://github.com/slsdetectorgroup/slsDetectorPackage.git --branch 9.2.0
|
||||
cd slsDetectorPackage
|
||||
pip install .
|
||||
|
||||
|
||||
.. _build from source:
|
||||
Build from source
|
||||
----------------------
|
||||
|
||||
3. Build from source
|
||||
-------------------------
|
||||
|
||||
3.1. Download Source Code from github
|
||||
1. Download Source Code from github
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: bash
|
||||
@ -115,12 +83,12 @@ The Python extension module ``slsdet`` can be installed using pip. This is avail
|
||||
|
||||
|
||||
|
||||
3.2. Build from Source
|
||||
2. Build from Source
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
One can either build using cmake or use the in-built cmk.sh script.
|
||||
|
||||
3.2.1. Build using CMake
|
||||
Build using CMake
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: bash
|
||||
@ -167,7 +135,7 @@ Example cmake options Comment
|
||||
For v7.x.x of slsDetectorPackage and older, refer :ref:`zeromq notes for cmake option to hint library location. <zeromq for different slsDetectorPackage versions>`
|
||||
|
||||
|
||||
3.2.2. Build using in-built cmk.sh script
|
||||
Build using in-built cmk.sh script
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@ -217,8 +185,8 @@ Example cmake options Comment
|
||||
For v7.x.x of slsDetectorPackage and older, refer :ref:`zeromq notes for cmk script option to hint library location. <zeromq for different slsDetectorPackage versions>`
|
||||
|
||||
|
||||
3.3. Build on old distributions using conda
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Build on old distributions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If your linux distribution doesn't come with a C++11 compiler (gcc>4.8) then
|
||||
it's possible to install a newer gcc using conda and build the slsDetectorPackage
|
||||
@ -242,7 +210,7 @@ using this compiler
|
||||
|
||||
|
||||
|
||||
3.4. Build slsDetectorGui (Qt5)
|
||||
Build slsDetectorGui (Qt5)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1. Using pre-built binary on conda
|
||||
@ -303,7 +271,7 @@ using this compiler
|
||||
|
||||
|
||||
|
||||
3.5. Build this documentation
|
||||
Build this documentation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The documentation for the slsDetectorPackage is build using a combination
|
||||
@ -326,8 +294,8 @@ is to use conda
|
||||
make rst # rst only, saves time in case the API did not change
|
||||
|
||||
|
||||
4. Pybind and Zeromq
|
||||
-------------------------
|
||||
Pybind and Zeromq
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. _pybind for different slsDetectorPackage versions:
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
Custom Receiver
|
||||
Receivers
|
||||
=================
|
||||
|
||||
The receiver essentially listens to UDP data packets sent out by the detector.
|
||||
|
||||
To know more about detector receiver setup in the config file, please check out :ref:`the detector-receiver UDP configuration in the config file<detector udp header config>` and the :ref:`detector udp format<detector udp header>`.
|
||||
Receiver processes can be run on same or different machines as the client, receives the data from the detector (via UDP packets).
|
||||
When using the slsReceiver/ slsMultiReceiver, they can be further configured by the client control software (via TCP/IP) to set file name, file path, progress of acquisition etc.
|
||||
|
||||
|
||||
| Please note the following when using a custom receiver:
|
||||
To know more about detector receiver configuration, please check out :ref:`detector udp header and udp commands in the config file <detector udp header>`
|
||||
|
||||
* **udp_dstmac** must be configured in the config file. This parameter is not required when using an in-built receiver.
|
||||
Custom Receiver
|
||||
----------------
|
||||
|
||||
* Cannot use "auto" for **udp_dstip**.
|
||||
| When using custom receiver with our package, ensure that **udp_dstmac** is also configured in the config file. This parameter is not required when using slsReceiver.
|
||||
|
||||
* No **rx_** commands in the config file. These commands are for configuring the slsReceiver.
|
||||
| Cannot use "auto" for **udp_dstip**.
|
||||
|
||||
|
||||
|
||||
The main difference is the lack of **rx_** commands or file commands (eg. **f**write, **f**path) and the **udp_dstmac** is required in config file.
|
||||
| Also ensure that there are no **rx_** commands in the config file. These commands are for configuring the slsReceiver.
|
||||
|
||||
Example of a custom receiver config file
|
||||
|
||||
* The main difference is the lack of **rx_** commands or file commands (eg. fwrite, fpath) and the udp_dstmac is required in config file.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# detector hostname
|
||||
|
@ -1,5 +1,4 @@
|
||||
.. _Detector Server Upgrade:
|
||||
|
||||
Upgrade
|
||||
========
|
||||
|
||||
|
@ -1,55 +1,16 @@
|
||||
In-built Receiver
|
||||
slsReceiver/ slsMultiReceiver
|
||||
================================
|
||||
|
||||
| One has to start the slsReceiver before loading config file or using any receiver commands (prefix: **rx_** )
|
||||
|
||||
|
||||
The receiver essentially listens to UDP data packets sent out by the detector. It's main features are:
|
||||
|
||||
- **Listening**: Receives UDP data from the detector.
|
||||
- **Writing to File**: Optionally writes received data to disk.
|
||||
- **Streaming via ZMQ**: Optionally streams out the data using ZeroMQ.
|
||||
|
||||
Each of these operations runs asynchronously and in parallel for each UDP port.
|
||||
|
||||
|
||||
.. note ::
|
||||
|
||||
* Can be run on the same or different machine as the client.
|
||||
* Can be configured by the client. (set file name/ discard policy, get progress etc.)
|
||||
* Has to be started before the client runs any receiver specific command.
|
||||
|
||||
|
||||
Receiver Variants
|
||||
-----------------
|
||||
There are three main receiver types. How to start them is described :ref:`below<Starting up the Receiver>`.
|
||||
|
||||
+----------------------+--------------------+-----------------------------------------+--------------------------------+
|
||||
| Receiver Type | slsReceiver | slsMultiReceiver |slsFrameSynchronizer |
|
||||
+======================+====================+=========================================+================================+
|
||||
| Modules Supported | 1 | Multiple | Multiple |
|
||||
+----------------------+--------------------+-----------------------------------------+--------------------------------+
|
||||
| Internal Architecture| Threads per porttt | Multiple child processes of slsReceiver | Multi-threading of slsReceiver |
|
||||
+----------------------+--------------------+-----------------------------------------+--------------------------------+
|
||||
| ZMQ Streaming | Disabled by default| Disabled by default | Enabled, not optional |
|
||||
+----------------------+--------------------+-----------------------------------------+--------------------------------+
|
||||
| ZMQ Synchronization | No | No | Yes, across ports |
|
||||
+----------------------+--------------------+-----------------------------------------+--------------------------------+
|
||||
| Image Reconstruction | No | No | No |
|
||||
+----------------------+--------------------+-----------------------------------------+--------------------------------+
|
||||
|
||||
|
||||
|
||||
|
||||
.. _Starting up the Receiver:
|
||||
|
||||
Starting up the Receiver
|
||||
-------------------------
|
||||
For a Single Module
|
||||
.. code-block:: bash
|
||||
|
||||
slsReceiver # default port 1954
|
||||
|
||||
slsReceiver -t2012 # custom port 2012
|
||||
# default port 1954
|
||||
slsReceiver
|
||||
|
||||
# custom port 2012
|
||||
slsReceiver -t2012
|
||||
|
||||
|
||||
For Multiple Modules
|
||||
@ -57,66 +18,57 @@ For Multiple Modules
|
||||
|
||||
# each receiver (for each module) requires a unique tcp port (if all on same machine)
|
||||
|
||||
# option 1 (one for each module)
|
||||
# using slsReceiver in multiple consoles
|
||||
slsReceiver
|
||||
slsReceiver -t1955
|
||||
|
||||
# option 2
|
||||
# slsMultiReceiver [starting port] [number of receivers]
|
||||
slsMultiReceiver 2012 2
|
||||
|
||||
# option 3
|
||||
slsFrameSynchronizer 2012 2
|
||||
|
||||
# slsMultiReceiver [starting port] [number of receivers] [print each frame header for debugging]
|
||||
slsMultiReceiver 2012 2 1
|
||||
|
||||
|
||||
Client Commands
|
||||
-----------------
|
||||
|
||||
* Client commands to the receiver begin with **rx_** or **f_** (file commands).
|
||||
| One can remove **udp_dstmac** from the config file, as the slsReceiver fetches this from the **udp_ip**.
|
||||
|
||||
* **rx_hostname** has to be the first command to the receiver so the client knows which receiver process to communicate with.
|
||||
| One can use "auto" for **udp_dstip** if one wants to use default ip of **rx_hostname**.
|
||||
|
||||
* Can use 'auto' for **udp_dstip** if using 1GbE interface or the :ref:`virtual simulators<Virtual Detector Servers>`.
|
||||
|
||||
|
||||
To know more about detector receiver setup in the config file, please check out :ref:`the detector-receiver UDP configuration in the config file<detector udp header config>` and the :ref:`detector udp format<detector udp header>`.
|
||||
|
||||
|
||||
The following are the different ways to establish contact using **rx_hostname** command.
|
||||
| The first command to the receiver (**rx_** commands) should be **rx_hostname**. The following are the different ways to establish contact.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# ---single module---
|
||||
|
||||
# default receiver port at 1954
|
||||
# default receiver tcp port (1954)
|
||||
rx_hostname xxx
|
||||
|
||||
|
||||
# custom receiver port
|
||||
rx_hostname xxx:1957 # option 1
|
||||
|
||||
rx_tcpport 1957 # option 2
|
||||
rx_hostname xxx:1957
|
||||
|
||||
# custom receiver port
|
||||
rx_tcpport 1954
|
||||
rx_hostname xxx
|
||||
|
||||
|
||||
# ---multi module---
|
||||
|
||||
# using increasing tcp ports
|
||||
# multi modules with custom ports
|
||||
rx_hostname xxx:1955+xxx:1956+
|
||||
|
||||
|
||||
# multi modules using increasing tcp ports when using multi detector command
|
||||
rx_tcpport 1955
|
||||
rx_hostname xxx
|
||||
|
||||
# custom ports
|
||||
rx_hostname xxx:1955+xxx:1958+ # option 1
|
||||
|
||||
0:rx_tcpport 1954 # option 2
|
||||
# or specify multi modules with custom ports on same rxr pc
|
||||
0:rx_tcpport 1954
|
||||
1:rx_tcpport 1955
|
||||
2:rx_tcpport 1956
|
||||
rx_hostname xxx
|
||||
|
||||
# custom ports on different receiver machines
|
||||
# multi modules with custom ports on different rxr pc
|
||||
0:rx_tcpport 1954
|
||||
0:rx_hostname xxx
|
||||
1:rx_tcpport 1955
|
||||
1:rx_hostname yyyrxr
|
||||
1:rx_hostname yyy
|
||||
|
||||
|
||||
| Example commands:
|
||||
@ -139,32 +91,6 @@ The following are the different ways to establish contact using **rx_hostname**
|
||||
sls_detector_get -h rx_framescaught
|
||||
|
||||
|
||||
Example of a config file using in-built receiver
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# detector hostname
|
||||
hostname bchip052+bchip053+
|
||||
|
||||
# udp destination port (receiver)
|
||||
# sets increasing destination udp ports starting at 50004
|
||||
udp_dstport 50004
|
||||
|
||||
# udp destination ip (receiver)
|
||||
0:udp_dstip 10.0.1.100
|
||||
1:udp_dstip 10.0.2.100
|
||||
|
||||
# udp source ip (same subnet as udp_dstip)
|
||||
0:udp_srcip 10.0.1.184
|
||||
1:udp_srcip 10.0.2.184
|
||||
|
||||
# udp destination mac - not required (picked up from udp_dstip)
|
||||
#udp_dstmac 22:47:d5:48:ad:ef
|
||||
|
||||
# connects to receivers at increasing tcp port starting at 1954
|
||||
rx_hostname mpc3434
|
||||
# same as rx_hostname mpc3434:1954+mpc3434:1955+
|
||||
|
||||
|
||||
|
||||
Performance
|
||||
|
@ -1,4 +1,4 @@
|
||||
.. _detector udp header config:
|
||||
.. _detector udp header:
|
||||
|
||||
|
||||
Config file
|
||||
|
@ -1,5 +1,4 @@
|
||||
.. _Virtual Detector Servers:
|
||||
|
||||
Simulators
|
||||
===========
|
||||
|
||||
|
@ -13,5 +13,5 @@ slsDetectorPackage/8.0.2_rh7 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/8.0.2_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/9.0.0_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/9.1.0_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/9.1.1_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
|
||||
|
||||
|
@ -11,13 +11,9 @@ build-backend = "scikit_build_core.build"
|
||||
[project]
|
||||
name = "slsdet"
|
||||
dynamic = ["version"]
|
||||
dependencies = [
|
||||
"numpy",
|
||||
]
|
||||
|
||||
[tool.cibuildwheel]
|
||||
before-all = "uname -a"
|
||||
build = "cp{311,312,313}-manylinux_x86_64"
|
||||
|
||||
[tool.scikit-build.build]
|
||||
verbose = true
|
||||
|
@ -65,9 +65,6 @@ configure_file( scripts/test_virtual.py
|
||||
${CMAKE_BINARY_DIR}/test_virtual.py
|
||||
)
|
||||
|
||||
configure_file(scripts/frameSynchronizerPullSocket.py
|
||||
${CMAKE_BINARY_DIR}/bin/frameSynchronizerPullSocket.py COPYONLY)
|
||||
|
||||
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION
|
||||
${CMAKE_BINARY_DIR}/bin/slsdet/VERSION
|
||||
)
|
||||
|
28
slsDetectorServers/compileAllServers.sh
Executable file → Normal file
28
slsDetectorServers/compileAllServers.sh
Executable file → Normal file
@ -1,19 +1,16 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
# empty branch = developer branch in updateAPIVersion.sh
|
||||
branch=""
|
||||
det_list=("ctbDetectorServer
|
||||
gotthard2DetectorServer
|
||||
jungfrauDetectorServer
|
||||
mythen3DetectorServer
|
||||
moenchDetectorServer
|
||||
xilinx_ctbDetectorServer"
|
||||
xilinx_ctbDetectorServer"
|
||||
)
|
||||
usage="\nUsage: compileAllServers.sh [server|all(opt)] [update_api(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tupdate_api if true updates the api to version in VERSION file"
|
||||
|
||||
update_api=true
|
||||
target=version
|
||||
|
||||
|
||||
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
|
||||
|
||||
# arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
@ -37,12 +34,15 @@ elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
||||
declare -a det=("${1}")
|
||||
#echo "Compiling only $1"
|
||||
fi
|
||||
|
||||
# branch
|
||||
if [ $# -eq 2 ]; then
|
||||
update_api=$2
|
||||
if not $update_api ; then
|
||||
target=clean
|
||||
# arg in list
|
||||
if [[ $det_list == *$2* ]]; then
|
||||
echo -e "Invalid argument 2: $2. $usage"
|
||||
return 1
|
||||
fi
|
||||
branch+=$2
|
||||
#echo "with branch $branch"
|
||||
fi
|
||||
else
|
||||
echo -e "Too many arguments.$usage"
|
||||
@ -53,9 +53,6 @@ declare -a deterror=("OK" "OK" "OK" "OK" "OK" "OK")
|
||||
|
||||
echo -e "list is ${det[@]}"
|
||||
|
||||
if $update_api; then
|
||||
echo "updating api to $(cat ../VERSION)"
|
||||
fi
|
||||
# compile each server
|
||||
idet=0
|
||||
for i in ${det[@]}
|
||||
@ -65,13 +62,14 @@ do
|
||||
echo -e "Compiling $dir [$file]"
|
||||
cd $dir
|
||||
make clean
|
||||
if make $target; then
|
||||
if make version API_BRANCH=$branch; then
|
||||
deterror[$idet]="OK"
|
||||
else
|
||||
deterror[$idet]="FAIL"
|
||||
fi
|
||||
mv bin/$dir bin/$file
|
||||
git add -f bin/$file
|
||||
cp bin/$file /tftpboot/
|
||||
cd ..
|
||||
echo -e "\n\n"
|
||||
((++idet))
|
||||
|
86
slsDetectorServers/compileAllServers_noAPIUpdate.sh
Normal file
86
slsDetectorServers/compileAllServers_noAPIUpdate.sh
Normal file
@ -0,0 +1,86 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
# empty branch = developer branch in updateAPIVersion.sh
|
||||
branch=""
|
||||
det_list=("ctbDetectorServer"
|
||||
"gotthard2DetectorServer"
|
||||
"jungfrauDetectorServer"
|
||||
"mythen3DetectorServer"
|
||||
"moenchDetectorServer"
|
||||
"xilinx_ctbDetectorServer"
|
||||
)
|
||||
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
|
||||
|
||||
# arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
# no argument, all servers
|
||||
declare -a det=${det_list[@]}
|
||||
echo "Compiling all servers"
|
||||
elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
||||
# 'all' servers
|
||||
if [[ $1 == "all" ]]; then
|
||||
declare -a det=${det_list[@]}
|
||||
echo "Compiling all servers"
|
||||
else
|
||||
# only one server
|
||||
# arg not in list
|
||||
if [[ $det_list != *$1* ]]; then
|
||||
echo -e "Invalid argument 1: $1. $usage"
|
||||
return -1
|
||||
fi
|
||||
declare -a det=("${1}")
|
||||
#echo "Compiling only $1"
|
||||
fi
|
||||
# branch
|
||||
if [ $# -eq 2 ]; then
|
||||
# arg in list
|
||||
if [[ $det_list == *$2* ]]; then
|
||||
echo -e "Invalid argument 2: $2. $usage"
|
||||
return -1
|
||||
fi
|
||||
branch+=$2
|
||||
#echo "with branch $branch"
|
||||
fi
|
||||
else
|
||||
echo -e "Too many arguments.$usage"
|
||||
return -1
|
||||
fi
|
||||
|
||||
declare -a deterror=("OK" "OK" "OK" "OK" "OK" "OK")
|
||||
|
||||
echo -e "list is ${det[@]}"
|
||||
|
||||
# compile each server
|
||||
idet=0
|
||||
for i in ${det[@]}
|
||||
do
|
||||
dir=$i
|
||||
file="${i}_developer"
|
||||
echo -e "Compiling $dir [$file]"
|
||||
cd $dir
|
||||
make clean
|
||||
if make API_BRANCH=$branch; then
|
||||
deterror[$idet]="OK"
|
||||
else
|
||||
deterror[$idet]="FAIL"
|
||||
fi
|
||||
mv bin/$dir bin/$file
|
||||
git add -f bin/$file
|
||||
cp bin/$file /tftpboot/
|
||||
cd ..
|
||||
echo -e "\n\n"
|
||||
((++idet))
|
||||
done
|
||||
|
||||
echo -e "Results:"
|
||||
idet=0
|
||||
for i in ${det[@]}
|
||||
do
|
||||
printf "%s\t\t= %s\n" "$i" "${deterror[$idet]}"
|
||||
((++idet))
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
23
slsDetectorServers/compileEigerServer.sh
Executable file → Normal file
23
slsDetectorServers/compileEigerServer.sh
Executable file → Normal file
@ -3,31 +3,21 @@
|
||||
deterror="OK"
|
||||
dir="eigerDetectorServer"
|
||||
file="${dir}_developer"
|
||||
|
||||
usage="\nUsage: compileAllServers.sh [update_api(opt)]. \n\t update_api if true updates the api to version in VERSION file"
|
||||
|
||||
update_api=true
|
||||
target=version
|
||||
branch=""
|
||||
|
||||
# arguments
|
||||
if [ $# -eq 1 ]; then
|
||||
update_api=$1
|
||||
if not $update_api ; then
|
||||
target=clean
|
||||
|
||||
fi
|
||||
branch+=$1
|
||||
#echo "with branch $branch"
|
||||
elif [ ! $# -eq 0 ]; then
|
||||
echo -e "Only one optional argument allowed for update_api."
|
||||
echo -e "Only one optional argument allowed for branch."
|
||||
return -1
|
||||
fi
|
||||
|
||||
if $update_api; then
|
||||
echo "updating api to $(cat ../VERSION)"
|
||||
fi
|
||||
|
||||
echo -e "Compiling $dir [$file]"
|
||||
cd $dir
|
||||
if make $target; then
|
||||
make clean
|
||||
if make version API_BRANCH=$branch; then
|
||||
deterror="OK"
|
||||
else
|
||||
deterror="FAIL"
|
||||
@ -35,6 +25,7 @@ fi
|
||||
|
||||
mv bin/$dir bin/$file
|
||||
git add -f bin/$file
|
||||
cp bin/$file /tftpboot/
|
||||
cd ..
|
||||
echo -e "\n\n"
|
||||
printf "Result:\t\t= %s\n" "${deterror}"
|
||||
|
@ -25,10 +25,11 @@ version: clean versioning $(PROGS)
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APICTB
|
||||
version_path=slsDetectorServers/ctbDetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
Binary file not shown.
@ -15,7 +15,6 @@
|
||||
#include "loadPattern.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> // usleep
|
||||
@ -94,10 +93,6 @@ void basictests() {
|
||||
LOG(logINFOBLUE, ("********* Chip Test Board Virtual Server *********\n"));
|
||||
#else
|
||||
LOG(logINFOBLUE, ("************* Chip Test Board Server *************\n"));
|
||||
initError = enableBlackfinAMCExternalAccessExtension(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
initError = defineGPIOpins(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
@ -443,32 +438,6 @@ uint32_t getDetectorIP() {
|
||||
return res;
|
||||
}
|
||||
|
||||
int enableBlackfinAMCExternalAccessExtension(char *mess) {
|
||||
unsigned int value;
|
||||
const char *file_path = BFIN_AMC_ACCESS_EXTENSION_FNAME;
|
||||
FILE *file = fopen(file_path, "r");
|
||||
if (!file) {
|
||||
strcpy(mess, "Failed to enable blackfin AMC access extension. Could "
|
||||
"not read EBIU_AMBCTL1\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
fscanf(file, "%x", &value);
|
||||
fclose(file);
|
||||
|
||||
value |= BFIN_AMC_ACCESS_EXTENSION_ENA_VAL;
|
||||
file = fopen(file_path, "w");
|
||||
if (!file) {
|
||||
strcpy(mess, "Failed to enable blackfin AMC access extension. Could "
|
||||
"not write EBIU_AMBCTL1\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
fprintf(file, "0x%x", value);
|
||||
fclose(file);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* initialization */
|
||||
|
||||
void initControlServer() {
|
||||
|
@ -25,10 +25,11 @@ version: clean versioning $(PROGS) #hv9m_blackfin_server
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APIEIGER
|
||||
version_path=slsDetectorServers/eigerDetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
@ -24,10 +24,11 @@ version: clean versioning $(PROGS)
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APIGOTTHARD2
|
||||
version_path=slsDetectorServers/gotthard2DetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
@ -24,10 +24,11 @@ version: clean versioning $(PROGS)
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APIJUNGFRAU
|
||||
version_path=slsDetectorServers/jungfrauDetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
@ -24,10 +24,11 @@ version: clean versioning $(PROGS)
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APIMOENCH
|
||||
version_path=slsDetectorServers/moenchDetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
@ -25,10 +25,11 @@ version: clean versioning $(PROGS)
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APIMYTHEN3
|
||||
version_path=slsDetectorServers/mythen3DetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
@ -5,23 +5,6 @@
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/** enable support for ARDY signal on interface to FPGA
|
||||
* needed to properly translate avalon_mm_waitrequest in the CTB firmware
|
||||
* https://www.analog.com/media/en/dsp-documentation/processor-manuals/bf537_hwr_Rev3.2.pdf
|
||||
* page 274
|
||||
* */
|
||||
#define BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_OFST (0)
|
||||
#define BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_MSK \
|
||||
(1 << BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_OFST)
|
||||
#define BFIN_EBIU_AMBCTL1_B2_ARDY_POL_OFST (1)
|
||||
#define BFIN_EBIU_AMBCTL1_B2_ARDY_POL_MSK \
|
||||
(1 << BFIN_EBIU_AMBCTL1_B2_ARDY_POL_OFST)
|
||||
|
||||
#define BFIN_AMC_ACCESS_EXTENSION_ENA_VAL \
|
||||
(BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_MSK | BFIN_EBIU_AMBCTL1_B2_ARDY_POL_MSK)
|
||||
#define BFIN_AMC_ACCESS_EXTENSION_FNAME \
|
||||
"/sys/kernel/debug/blackfin/ebiu_amc/EBIU_AMBCTL1"
|
||||
|
||||
/** I2C defines */
|
||||
#define I2C_CLOCK_MHZ (131.25)
|
||||
|
||||
|
@ -113,10 +113,6 @@ void setModuleId(int modid);
|
||||
u_int64_t getDetectorMAC();
|
||||
u_int32_t getDetectorIP();
|
||||
|
||||
#if defined(CHIPTESTBOARDD)
|
||||
int enableBlackfinAMCExternalAccessExtension(char *mess);
|
||||
#endif
|
||||
|
||||
// initialization
|
||||
void initControlServer();
|
||||
void initStopServer();
|
||||
|
@ -36,10 +36,11 @@ version: clean versioning $(PROGS)
|
||||
|
||||
boot: $(OBJS)
|
||||
|
||||
version_branch=$(API_BRANCH)
|
||||
version_name=APIXILINXCTB
|
||||
version_path=slsDetectorServers/xilinx_ctbDetectorServer
|
||||
versioning:
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
||||
|
||||
|
||||
$(PROGS): $(OBJS)
|
||||
|
@ -29,6 +29,7 @@ target_link_libraries(slsDetectorObject
|
||||
slsProjectOptions
|
||||
slsSupportStatic
|
||||
pthread
|
||||
rt
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
)
|
||||
@ -97,7 +98,9 @@ if(SLS_USE_TEXTCLIENT)
|
||||
add_executable(${val1} src/CmdApp.cpp)
|
||||
|
||||
target_link_libraries(${val1}
|
||||
slsDetectorStatic
|
||||
slsDetectorStatic
|
||||
pthread
|
||||
rt
|
||||
)
|
||||
SET_SOURCE_FILES_PROPERTIES( src/Caller.cpp PROPERTIES COMPILE_FLAGS "-Wno-unused-variable -Wno-unused-but-set-variable")
|
||||
|
||||
|
@ -1203,7 +1203,7 @@ void Module::setDestinationUDPIP(const IpAddr ip) {
|
||||
}
|
||||
sendToDetector(F_SET_DEST_UDP_IP, ip, nullptr);
|
||||
if (shm()->useReceiverFlag) {
|
||||
MacAddr retval{uint64_t(0)};
|
||||
MacAddr retval(0LU);
|
||||
sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval);
|
||||
LOG(logINFO) << "Setting destination udp mac of Module " << moduleIndex
|
||||
<< " to " << retval;
|
||||
@ -1226,7 +1226,7 @@ void Module::setDestinationUDPIP2(const IpAddr ip) {
|
||||
}
|
||||
sendToDetector(F_SET_DEST_UDP_IP2, ip, nullptr);
|
||||
if (shm()->useReceiverFlag) {
|
||||
MacAddr retval{uint64_t(0)};
|
||||
MacAddr retval(0LU);
|
||||
sendToReceiver(F_SET_RECEIVER_UDP_IP2, ip, retval);
|
||||
LOG(logINFO) << "Setting destination udp mac2 of Module " << moduleIndex
|
||||
<< " to " << retval;
|
||||
|
@ -25,12 +25,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
namespace sls {
|
||||
#ifdef __APPLE__
|
||||
// On macOS SHM_NAME_MAX is 31 so we need the shortest possible prefix
|
||||
#define SHM_DETECTOR_PREFIX "/sls_"
|
||||
#else
|
||||
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
|
||||
#endif
|
||||
|
||||
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
|
||||
#define SHM_MODULE_PREFIX "_module_"
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
|
||||
@ -207,11 +203,6 @@ template <typename T> class SharedMemory {
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// On macOS, fstat returns the allocated size and not the requested size.
|
||||
// This means we can't check for size since we always get for example 16384 bytes.
|
||||
return;
|
||||
#endif
|
||||
auto actual_size = static_cast<size_t>(sb.st_size);
|
||||
auto expected_size = sizeof(T);
|
||||
if (actual_size != expected_size) {
|
||||
|
@ -8,6 +8,7 @@ target_sources(tests PRIVATE
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-rx.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-rx-running.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-pattern.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-eiger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-jungfrau.cpp
|
||||
|
72
slsDetectorSoftware/tests/Caller/test-Caller-rx-running.cpp
Normal file
72
slsDetectorSoftware/tests/Caller/test-Caller-rx-running.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2025 Contributors to the SLS Detector Package
|
||||
#include "Caller.h"
|
||||
#include "catch.hpp"
|
||||
#include "sls/Detector.h"
|
||||
#include "tests/globals.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace sls {
|
||||
|
||||
using test::PUT;
|
||||
|
||||
/*
|
||||
detfuncs::F_RECEIVER_SET_NUM_FRAMES
|
||||
detfuncs::F_RECEIVER_SET_NUM_TRIGGERS
|
||||
detfuncs::F_RECEIVER_SET_NUM_BURSTS
|
||||
detfuncs::F_RECEIVER_SET_TIMING_MODE
|
||||
detfuncs::F_RECEIVER_SET_BURST_MODE
|
||||
detfuncs::F_RECEIVER_SET_NUM_ANALOG_SAMPLES
|
||||
detfuncs::F_RECEIVER_SET_NUM_DIGITAL_SAMPLES
|
||||
detfuncs::F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES
|
||||
detfuncs::F_RECEIVER_SET_DYNAMIC_RANGE
|
||||
detfuncs::F_RECEIVER_SET_STREAMING_FREQUENCY
|
||||
detfuncs::F_RECEIVER_SET_FILE_INDEX
|
||||
detfuncs::F_RECEIVER_SET_FILE_WRITE
|
||||
detfuncs::F_RECEIVER_SET_MASTER_FILE_WRITE
|
||||
detfuncs::F_RECEIVER_SET_OVERWRITE
|
||||
detfuncs::F_RECEIVER_ENABLE_TENGIGA
|
||||
detfuncs::F_RECEIVER_SET_FIFO_DEPTH
|
||||
detfuncs::F_RECEIVER_SET_ACTIVATE
|
||||
detfuncs::F_RECEIVER_SET_STREAMING
|
||||
detfuncs::F_RECEIVER_SET_STREAMING_TIMER
|
||||
detfuncs::F_RECEIVER_SET_FLIP_ROWS
|
||||
detfuncs::F_RECEIVER_SET_DBIT_LIST
|
||||
detfuncs::F_RECEIVER_SET_DBIT_OFFSET
|
||||
detfuncs::F_RECEIVER_SET_DBIT_REORDE
|
||||
*/
|
||||
|
||||
auto get_test_parameters() {
|
||||
return GENERATE(
|
||||
std::make_tuple("asamples", std::vector<std::string>{"5"}),
|
||||
std::make_tuple("tsamples", std::vector<std::string>{"2"}),
|
||||
std::make_tuple("dsamples", std::vector<std::string>{"100"}),
|
||||
std::make_tuple("frames", std::vector<std::string>{"10"}),
|
||||
std::make_tuple("triggers", std::vector<std::string>{"5"}),
|
||||
std::make_tuple("rx_dbitlist", std::vector<std::string>{"{1,2,10}"}),
|
||||
std::make_tuple("rx_dbitreorder", std::vector<std::string>{"0"}),
|
||||
std::make_tuple("rx_dbitoffset", std::vector<std::string>{"5"}),
|
||||
std::make_tuple("findex", std::vector<std::string>{"2"}),
|
||||
std::make_tuple("fwrite", std::vector<std::string>{"0"}),
|
||||
std::make_tuple("bursts", std::vector<std::string>{"20"}));
|
||||
}
|
||||
|
||||
TEST_CASE("cant put if receiver is not idle", "[.cmdcall][.rx]") {
|
||||
auto [command, function_arguments] = get_test_parameters();
|
||||
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
|
||||
// start receiver
|
||||
std::ostringstream oss;
|
||||
caller.call("rx_start", {}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_start successful\n");
|
||||
|
||||
REQUIRE_THROWS(caller.call(command, function_arguments, -1, PUT, oss, -1));
|
||||
|
||||
std::ostringstream oss_stop;
|
||||
caller.call("rx_stop", {}, -1, PUT, oss_stop);
|
||||
REQUIRE(oss_stop.str() == "rx_stop successful\n");
|
||||
}
|
||||
} // namespace sls
|
@ -551,6 +551,7 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
|
||||
if (detType != CHIPTESTBOARD && detType != XILINX_CHIPTESTBOARD) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
verifyIdle(socket);
|
||||
try {
|
||||
impl()->setNumberofAnalogSamples(value);
|
||||
} catch (const std::exception &e) {
|
||||
@ -567,6 +568,7 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
|
||||
if (detType != CHIPTESTBOARD && detType != XILINX_CHIPTESTBOARD) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
verifyIdle(socket);
|
||||
try {
|
||||
impl()->setNumberofDigitalSamples(value);
|
||||
} catch (const std::exception &e) {
|
||||
@ -1736,6 +1738,7 @@ int ClientInterface::set_num_transceiver_samples(Interface &socket) {
|
||||
if (detType != CHIPTESTBOARD && detType != XILINX_CHIPTESTBOARD) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
verifyIdle(socket);
|
||||
try {
|
||||
impl()->setNumberofTransceiverSamples(value);
|
||||
} catch (const std::exception &e) {
|
||||
|
@ -168,7 +168,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
uint32_t streamingTimerInMs;
|
||||
uint32_t streamingStartFnum;
|
||||
uint32_t currentFreqCount{0};
|
||||
struct timespec timerbegin {};
|
||||
struct timespec timerbegin{};
|
||||
bool framePadding;
|
||||
std::atomic<bool> startedFlag{false};
|
||||
std::atomic<uint64_t> firstIndex{0};
|
||||
|
@ -104,11 +104,11 @@ void zmq_free(void *data, void *hint) { delete[] static_cast<char *>(data); }
|
||||
void print_frames(const PortFrameMap &frame_port_map) {
|
||||
LOG(sls::logDEBUG) << "Printing frames";
|
||||
for (const auto &it : frame_port_map) {
|
||||
const uint16_t udpPort = it.first;
|
||||
uint16_t udpPort = it.first;
|
||||
const auto &frame_map = it.second;
|
||||
LOG(sls::logDEBUG) << "UDP port: " << udpPort;
|
||||
for (const auto &frame : frame_map) {
|
||||
const uint64_t fnum = frame.first;
|
||||
uint64_t fnum = frame.first;
|
||||
const auto &msg_list = frame.second;
|
||||
LOG(sls::logDEBUG)
|
||||
<< " acq index: " << fnum << '[' << msg_list.size() << ']';
|
||||
@ -127,26 +127,30 @@ std::set<uint64_t> get_valid_fnums(const PortFrameMap &port_frame_map) {
|
||||
|
||||
// collect all unique frame numbers from all ports
|
||||
std::set<uint64_t> unique_fnums;
|
||||
for (const auto &it : port_frame_map) {
|
||||
const FrameMap &frame_map = it.second;
|
||||
for (const auto &frame : frame_map) {
|
||||
unique_fnums.insert(frame.first);
|
||||
for (auto it = port_frame_map.begin(); it != port_frame_map.begin(); ++it) {
|
||||
const FrameMap &frame_map = it->second;
|
||||
for (auto frame = frame_map.begin(); frame != frame_map.end();
|
||||
++frame) {
|
||||
unique_fnums.insert(frame->first);
|
||||
}
|
||||
}
|
||||
|
||||
// collect valid frame numbers
|
||||
for (auto &fnum : unique_fnums) {
|
||||
bool is_valid = true;
|
||||
for (const auto &it : port_frame_map) {
|
||||
const uint16_t port = it.first;
|
||||
const FrameMap &frame_map = it.second;
|
||||
for (auto it = port_frame_map.begin(); it != port_frame_map.end();
|
||||
++it) {
|
||||
uint16_t port = it->first;
|
||||
const FrameMap &frame_map = it->second;
|
||||
auto frame = frame_map.find(fnum);
|
||||
// invalid: fnum missing in one port
|
||||
if (frame == frame_map.end()) {
|
||||
LOG(sls::logDEBUG)
|
||||
<< "Fnum " << fnum << " is missing in port " << port;
|
||||
auto upper_frame = frame_map.upper_bound(fnum);
|
||||
if (upper_frame == frame_map.end()) {
|
||||
// invalid: fnum greater than all in that port
|
||||
auto last_frame = std::prev(frame_map.end());
|
||||
auto last_fnum = last_frame->first;
|
||||
if (fnum > last_fnum) {
|
||||
LOG(sls::logDEBUG) << "And no larger fnum found. Fnum "
|
||||
<< fnum << " is invalid.\n";
|
||||
is_valid = false;
|
||||
@ -216,26 +220,18 @@ void Correlate(FrameStatus *stat) {
|
||||
// sending all valid fnum data packets
|
||||
for (const auto &fnum : valid_fnums) {
|
||||
ZmqMsgList msg_list;
|
||||
for (const auto &it : stat->frames) {
|
||||
const uint16_t port = it.first;
|
||||
const FrameMap &frame_map = it.second;
|
||||
PortFrameMap &port_frame_map = stat->frames;
|
||||
for (auto it = port_frame_map.begin();
|
||||
it != port_frame_map.end(); ++it) {
|
||||
uint16_t port = it->first;
|
||||
const FrameMap &frame_map = it->second;
|
||||
auto frame = frame_map.find(fnum);
|
||||
if (frame != frame_map.end()) {
|
||||
msg_list.insert(msg_list.end(),
|
||||
stat->frames[port][fnum].begin(),
|
||||
stat->frames[port][fnum].end());
|
||||
}
|
||||
}
|
||||
LOG(printHeadersLevel)
|
||||
<< "Sending data packets for fnum " << fnum;
|
||||
zmq_send_multipart(socket, msg_list);
|
||||
// clean up
|
||||
for (const auto &it : stat->frames) {
|
||||
const uint16_t port = it.first;
|
||||
const FrameMap &frame_map = it.second;
|
||||
auto frame = frame_map.find(fnum);
|
||||
if (frame != frame_map.end()) {
|
||||
for (zmq_msg_t *msg : frame->second) {
|
||||
// clean up
|
||||
for (zmq_msg_t *msg : stat->frames[port][fnum]) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
@ -244,6 +240,9 @@ void Correlate(FrameStatus *stat) {
|
||||
stat->frames[port].erase(fnum);
|
||||
}
|
||||
}
|
||||
LOG(printHeadersLevel)
|
||||
<< "Sending data packets for fnum " << fnum;
|
||||
zmq_send_multipart(socket, msg_list);
|
||||
}
|
||||
}
|
||||
// sending all end packets
|
||||
@ -257,21 +256,6 @@ void Correlate(FrameStatus *stat) {
|
||||
}
|
||||
}
|
||||
stat->ends.clear();
|
||||
// clean up old frames
|
||||
for (auto &it : stat->frames) {
|
||||
FrameMap &frame_map = it.second;
|
||||
for (auto &frame : frame_map) {
|
||||
for (zmq_msg_t *msg : frame.second) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
frame.second.clear();
|
||||
}
|
||||
frame_map.clear();
|
||||
}
|
||||
stat->frames.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ class GeneralData {
|
||||
slsDetectorDefs::frameDiscardPolicy frameDiscardMode{
|
||||
slsDetectorDefs::NO_DISCARD};
|
||||
|
||||
GeneralData(){};
|
||||
virtual ~GeneralData(){};
|
||||
GeneralData() {};
|
||||
virtual ~GeneralData() {};
|
||||
|
||||
// Returns the pixel depth in byte, 4 bits being 0.5 byte
|
||||
float GetPixelDepth() { return float(dynamicRange) / 8; }
|
||||
|
@ -47,8 +47,8 @@ class GeneralDataTest : public GeneralData {
|
||||
// dummy DataProcessor class for testing
|
||||
class DataProcessorTest : public DataProcessor {
|
||||
public:
|
||||
DataProcessorTest() : DataProcessor(0){};
|
||||
~DataProcessorTest(){};
|
||||
DataProcessorTest() : DataProcessor(0) {};
|
||||
~DataProcessorTest() {};
|
||||
void ArrangeDbitData(size_t &size, char *data) {
|
||||
DataProcessor::ArrangeDbitData(size, data);
|
||||
}
|
||||
|
@ -88,7 +88,6 @@ message(STATUS "RAPID: ${SLS_INTERNAL_RAPIDJSON_DIR}")
|
||||
target_link_libraries(slsSupportObject
|
||||
PUBLIC
|
||||
slsProjectOptions
|
||||
${STD_FS_LIB} # from helpers.cmake
|
||||
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
|
@ -113,10 +113,10 @@ template <typename T, size_t Capacity> class StaticVector {
|
||||
// auto begin() noexcept -> decltype(data_.begin()) { return data_.begin();
|
||||
// }
|
||||
const_iterator begin() const noexcept { return data_.begin(); }
|
||||
iterator end() noexcept { return data_.begin()+current_size; }
|
||||
const_iterator end() const noexcept { return data_.begin()+current_size; }
|
||||
iterator end() noexcept { return &data_[current_size]; }
|
||||
const_iterator end() const noexcept { return &data_[current_size]; }
|
||||
const_iterator cbegin() const noexcept { return data_.cbegin(); }
|
||||
const_iterator cend() const noexcept { return data_.cbegin()+current_size; }
|
||||
const_iterator cend() const noexcept { return &data_[current_size]; }
|
||||
|
||||
void size_check(size_type s) const {
|
||||
if (s > Capacity) {
|
||||
|
@ -47,8 +47,6 @@ std::string ToString(const defs::polarity s);
|
||||
std::string ToString(const defs::timingInfoDecoder s);
|
||||
std::string ToString(const defs::collectionMode s);
|
||||
|
||||
std::string ToString(bool value);
|
||||
|
||||
std::string ToString(const slsDetectorDefs::xy &coord);
|
||||
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
|
||||
std::string ToString(const slsDetectorDefs::ROI &roi);
|
||||
|
@ -11,7 +11,7 @@ class Version {
|
||||
private:
|
||||
std::string version_;
|
||||
std::string date_;
|
||||
inline static const std::string defaultVersion_[] = {"developer", "0.0.0"};
|
||||
const std::string defaultBranch_ = "developer";
|
||||
|
||||
public:
|
||||
explicit Version(const std::string &s);
|
||||
|
@ -1,13 +1,12 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
/** API versions */
|
||||
#define APILIB "0.0.0 0x250523"
|
||||
#define APIRECEIVER "0.0.0 0x250523"
|
||||
#define APICTB "0.0.0 0x250523"
|
||||
#define APIGOTTHARD2 "0.0.0 0x250523"
|
||||
#define APIMOENCH "0.0.0 0x250523"
|
||||
#define APIEIGER "0.0.0 0x250523"
|
||||
#define APIXILINXCTB "0.0.0 0x250523"
|
||||
#define APIJUNGFRAU "0.0.0 0x250523"
|
||||
#define APIMYTHEN3 "0.0.0 0x250523"
|
||||
|
||||
#define APILIB "developer 0x241122"
|
||||
#define APIRECEIVER "developer 0x241122"
|
||||
#define APICTB "developer 0x250310"
|
||||
#define APIGOTTHARD2 "developer 0x250310"
|
||||
#define APIMOENCH "developer 0x250310"
|
||||
#define APIEIGER "developer 0x250310"
|
||||
#define APIXILINXCTB "developer 0x250311"
|
||||
#define APIJUNGFRAU "developer 0x250318"
|
||||
#define APIMYTHEN3 "developer 0x250409"
|
||||
|
@ -5,13 +5,6 @@
|
||||
|
||||
namespace sls {
|
||||
|
||||
|
||||
std::string ToString(bool value) {
|
||||
return value ? "1" : "0";
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string ToString(const slsDetectorDefs::xy &coord) {
|
||||
std::ostringstream oss;
|
||||
oss << '[' << coord.x << ", " << coord.y << ']';
|
||||
|
@ -21,8 +21,7 @@ Version::Version(const std::string &s) {
|
||||
}
|
||||
|
||||
bool Version::hasSemanticVersioning() const {
|
||||
|
||||
return (version_ != defaultVersion_[0]) && (version_ != defaultVersion_[1]);
|
||||
return version_ != defaultBranch_;
|
||||
}
|
||||
|
||||
std::string Version::getVersion() const { return version_; }
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <netdb.h>
|
||||
#include <sstream>
|
||||
#include <sys/ioctl.h>
|
||||
// #include <sys/prctl.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@ -178,30 +178,30 @@ IpAddr InterfaceNameToIp(const std::string &ifn) {
|
||||
|
||||
MacAddr InterfaceNameToMac(const std::string &inf) {
|
||||
// TODO! Copied from genericSocket needs to be refactored!
|
||||
// struct ifreq ifr;
|
||||
// char mac[32];
|
||||
// const int mac_len = sizeof(mac);
|
||||
// memset(mac, 0, mac_len);
|
||||
struct ifreq ifr;
|
||||
char mac[32];
|
||||
const int mac_len = sizeof(mac);
|
||||
memset(mac, 0, mac_len);
|
||||
|
||||
// int sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
// strncpy(ifr.ifr_name, inf.c_str(), sizeof(ifr.ifr_name) - 1);
|
||||
// ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
|
||||
int sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
strncpy(ifr.ifr_name, inf.c_str(), sizeof(ifr.ifr_name) - 1);
|
||||
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
|
||||
|
||||
// if (-1 == ioctl(sock, SIOCGIFHWADDR, &ifr)) {
|
||||
// perror("ioctl(SIOCGIFHWADDR) ");
|
||||
// return MacAddr{};
|
||||
// }
|
||||
// for (int j = 0, k = 0; j < 6; j++) {
|
||||
// k += snprintf(
|
||||
// mac + k, mac_len - k - 1, j ? ":%02X" : "%02X",
|
||||
// (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
|
||||
// }
|
||||
// mac[mac_len - 1] = '\0';
|
||||
if (-1 == ioctl(sock, SIOCGIFHWADDR, &ifr)) {
|
||||
perror("ioctl(SIOCGIFHWADDR) ");
|
||||
return MacAddr{};
|
||||
}
|
||||
for (int j = 0, k = 0; j < 6; j++) {
|
||||
k += snprintf(
|
||||
mac + k, mac_len - k - 1, j ? ":%02X" : "%02X",
|
||||
(int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
|
||||
}
|
||||
mac[mac_len - 1] = '\0';
|
||||
|
||||
// if (sock != 1) {
|
||||
// close(sock);
|
||||
// }
|
||||
return MacAddr();
|
||||
if (sock != 1) {
|
||||
close(sock);
|
||||
}
|
||||
return MacAddr(mac);
|
||||
}
|
||||
|
||||
void validatePortNumber(uint16_t port) {
|
||||
|
@ -14,7 +14,6 @@ target_sources(tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-TypeTraits.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-UdpRxSocket.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-logger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Version.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-ZmqSocket.cpp
|
||||
)
|
||||
|
||||
|
@ -8,15 +8,12 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
using sls::StaticVector;
|
||||
namespace sls {
|
||||
|
||||
TEST_CASE("StaticVector is a container") {
|
||||
REQUIRE(sls::is_container<StaticVector<int, 7>>::value == true);
|
||||
REQUIRE(is_container<StaticVector<int, 7>>::value == true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("Comparing StaticVector containers") {
|
||||
StaticVector<int, 5> a{0, 1, 2};
|
||||
StaticVector<int, 5> b{0, 1, 2};
|
||||
@ -93,17 +90,10 @@ TEST_CASE("Copy construct from array") {
|
||||
REQUIRE(fcc == arr);
|
||||
}
|
||||
|
||||
TEST_CASE("Construct from a smaller StaticVector") {
|
||||
StaticVector<int, 3> sv{1, 2, 3};
|
||||
StaticVector<int, 5> sv2{sv};
|
||||
REQUIRE(sv == sv2);
|
||||
}
|
||||
|
||||
TEST_CASE("Free function and method gives the same iterators") {
|
||||
StaticVector<int, 3> fcc{1, 2, 3};
|
||||
REQUIRE(std::begin(fcc) == fcc.begin());
|
||||
}
|
||||
|
||||
SCENARIO("StaticVectors can be sized and resized", "[support]") {
|
||||
|
||||
GIVEN("A default constructed container") {
|
||||
@ -256,23 +246,23 @@ SCENARIO("Sorting, removing and other manipulation of a container",
|
||||
REQUIRE(a[3] == 90);
|
||||
}
|
||||
}
|
||||
WHEN("Sorting is done using free function for begin and end") {
|
||||
std::sort(std::begin(a), std::end(a));
|
||||
THEN("it also works") {
|
||||
REQUIRE(a[0] == 12);
|
||||
REQUIRE(a[1] == 12);
|
||||
REQUIRE(a[2] == 14);
|
||||
REQUIRE(a[3] == 90);
|
||||
}
|
||||
}
|
||||
WHEN("Erasing elements of a certain value") {
|
||||
a.erase(std::remove(std::begin(a), std::end(a), 12));
|
||||
THEN("all elements of that value are removed") {
|
||||
REQUIRE(a.size() == 2);
|
||||
REQUIRE(a[0] == 14);
|
||||
REQUIRE(a[1] == 90);
|
||||
}
|
||||
}
|
||||
// WHEN("Sorting is done using free function for begin and end") {
|
||||
// std::sort(begin(a), end(a));
|
||||
// THEN("it also works") {
|
||||
// REQUIRE(a[0] == 12);
|
||||
// REQUIRE(a[1] == 12);
|
||||
// REQUIRE(a[2] == 14);
|
||||
// REQUIRE(a[3] == 90);
|
||||
// }
|
||||
// }
|
||||
// WHEN("Erasing elements of a certain value") {
|
||||
// a.erase(std::remove(begin(a), end(a), 12));
|
||||
// THEN("all elements of that value are removed") {
|
||||
// REQUIRE(a.size() == 2);
|
||||
// REQUIRE(a[0] == 14);
|
||||
// REQUIRE(a[1] == 90);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,3 +335,4 @@ TEST_CASE("StaticVector stream") {
|
||||
REQUIRE(oss.str() == "[33, 85667, 2]");
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
@ -16,17 +16,6 @@ namespace sls {
|
||||
|
||||
using namespace sls::time;
|
||||
|
||||
TEST_CASE("Convert bool to string", "[support]") {
|
||||
REQUIRE(ToString(true) == "1");
|
||||
REQUIRE(ToString(false) == "0");
|
||||
}
|
||||
|
||||
TEST_CASE("Convert string to bool", "[support]") {
|
||||
REQUIRE(StringTo<bool>("1") == true);
|
||||
REQUIRE(StringTo<bool>("0") == false);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Integer conversions", "[support]") {
|
||||
REQUIRE(ToString(0) == "0");
|
||||
REQUIRE(ToString(1) == "1");
|
||||
|
@ -1,19 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "catch.hpp"
|
||||
#include "sls/Version.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
TEST_CASE("check if version is semantic", "[.version]") {
|
||||
|
||||
auto [version_string, has_semantic_version] =
|
||||
GENERATE(std::make_tuple("developer 0x250512", false),
|
||||
std::make_tuple("0.0.0 0x250512", false));
|
||||
|
||||
Version version(version_string);
|
||||
|
||||
CHECK(version.hasSemanticVersioning() == has_semantic_version);
|
||||
}
|
||||
|
||||
} // namespace sls
|
@ -25,6 +25,7 @@ target_link_libraries(tests
|
||||
slsProjectOptions
|
||||
slsSupportStatic
|
||||
pthread
|
||||
rt
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
)
|
||||
@ -59,5 +60,3 @@ include(Catch)
|
||||
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)
|
||||
|
@ -1,140 +0,0 @@
|
||||
# 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, frame synchronizer, pull sockets, acquire, test and kill them finally.
|
||||
'''
|
||||
|
||||
import sys, time
|
||||
import traceback, json
|
||||
|
||||
from slsdet import Detector
|
||||
from slsdet.defines import DEFAULT_TCP_RX_PORTNO
|
||||
|
||||
from utils_for_test import (
|
||||
Log,
|
||||
LogLevel,
|
||||
RuntimeException,
|
||||
checkIfProcessRunning,
|
||||
killProcess,
|
||||
cleanup,
|
||||
cleanSharedmemory,
|
||||
startProcessInBackground,
|
||||
startProcessInBackgroundWithLogFile,
|
||||
startDetectorVirtualServer,
|
||||
loadConfig,
|
||||
ParseArguments
|
||||
)
|
||||
|
||||
LOG_PREFIX_FNAME = '/tmp/slsFrameSynchronizer_test'
|
||||
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
|
||||
PULL_SOCKET_PREFIX_FNAME = LOG_PREFIX_FNAME + '_pull_socket_'
|
||||
|
||||
|
||||
def startFrameSynchronizerPullSocket(name, fp):
|
||||
fname = PULL_SOCKET_PREFIX_FNAME + name + '.txt'
|
||||
cmd = ['python', '-u', 'frameSynchronizerPullSocket.py']
|
||||
startProcessInBackgroundWithLogFile(cmd, fp, fname)
|
||||
|
||||
|
||||
def startFrameSynchronizer(num_mods, fp):
|
||||
cmd = ['slsFrameSynchronizer', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)]
|
||||
# in 10.0.0
|
||||
#cmd = ['slsFrameSynchronizer', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)]
|
||||
startProcessInBackground(cmd, fp)
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def acquire(fp):
|
||||
Log(LogLevel.INFO, 'Acquiring')
|
||||
Log(LogLevel.INFO, 'Acquiring', fp)
|
||||
d = Detector()
|
||||
d.acquire()
|
||||
|
||||
|
||||
def testFramesCaught(name, num_frames):
|
||||
d = Detector()
|
||||
fnum = d.rx_framescaught[0]
|
||||
if fnum != num_frames:
|
||||
raise RuntimeException(f"{name} caught only {fnum}. Expected {num_frames}")
|
||||
|
||||
Log(LogLevel.INFOGREEN, f'Frames caught test passed for {name}')
|
||||
Log(LogLevel.INFOGREEN, f'Frames caught test passed for {name}', fp)
|
||||
|
||||
|
||||
def testZmqHeadetTypeCount(name, num_mods, num_frames, fp):
|
||||
|
||||
Log(LogLevel.INFO, f"Testing Zmq Header type count for {name}")
|
||||
Log(LogLevel.INFO, f"Testing Zmq Header type count for {name}", fp)
|
||||
htype_counts = {
|
||||
"header": 0,
|
||||
"series_end": 0,
|
||||
"module": 0
|
||||
}
|
||||
|
||||
try:
|
||||
# get a count of each htype from file
|
||||
pull_socket_fname = PULL_SOCKET_PREFIX_FNAME + name + '.txt'
|
||||
with open(pull_socket_fname, 'r') as log_fp:
|
||||
for line in log_fp:
|
||||
line = line.strip()
|
||||
if not line or not line.startswith('{'):
|
||||
continue
|
||||
try:
|
||||
data = json.loads(line)
|
||||
htype = data.get("htype")
|
||||
if htype in htype_counts:
|
||||
htype_counts[htype] += 1
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
|
||||
# test if file contents matches expected counts
|
||||
d = Detector()
|
||||
num_ports_per_module = 1 if name == "gotthard2" else d.numinterfaces
|
||||
total_num_frame_parts = num_ports_per_module * num_mods * num_frames
|
||||
for htype, expected_count in [("header", num_mods), ("series_end", num_mods), ("module", total_num_frame_parts)]:
|
||||
if htype_counts[htype] != expected_count:
|
||||
msg = f"Expected {expected_count} '{htype}' entries, found {htype_counts[htype]}"
|
||||
raise RuntimeException(msg)
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Failed to get zmq header count type. Error:{str(e)}') from e
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"Zmq Header type count test passed for {name}")
|
||||
Log(LogLevel.INFOGREEN, f"Zmq Header type count test passed for {name}", fp)
|
||||
|
||||
|
||||
def startTestsForAll(args, fp):
|
||||
for server in args.servers:
|
||||
try:
|
||||
Log(LogLevel.INFOBLUE, f'Synchronizer Tests for {server}')
|
||||
Log(LogLevel.INFOBLUE, f'Synchronizer Tests for {server}', fp)
|
||||
cleanup(fp)
|
||||
startDetectorVirtualServer(server, args.num_mods, fp)
|
||||
startFrameSynchronizerPullSocket(server, fp)
|
||||
startFrameSynchronizer(args.num_mods, fp)
|
||||
loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=args.num_mods, num_frames=args.num_frames)
|
||||
acquire(fp)
|
||||
testFramesCaught(server, args.num_frames)
|
||||
testZmqHeadetTypeCount(server, args.num_mods, args.num_frames, fp)
|
||||
Log(LogLevel.INFO, '\n')
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Synchronizer Tests failed') from e
|
||||
|
||||
Log(LogLevel.INFOGREEN, 'Passed all synchronizer tests for all detectors \n' + str(args.servers))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = ParseArguments(description='Automated tests to test frame synchronizer', default_num_mods=2)
|
||||
|
||||
Log(LogLevel.INFOBLUE, '\nLog File: ' + MAIN_LOG_FNAME + '\n')
|
||||
|
||||
with open(MAIN_LOG_FNAME, 'w') as fp:
|
||||
try:
|
||||
startTestsForAll(args, fp)
|
||||
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.')
|
||||
|
||||
|
@ -4,86 +4,244 @@
|
||||
This file is used to start up simulators, receivers and run all the tests on them and finally kill the simulators and receivers.
|
||||
'''
|
||||
import argparse
|
||||
import sys, subprocess, time, traceback
|
||||
import os, sys, subprocess, time, colorama
|
||||
|
||||
from slsdet import Detector
|
||||
from slsdet.defines import DEFAULT_TCP_RX_PORTNO
|
||||
from colorama import Fore, Style
|
||||
from slsdet import Detector, detectorType, detectorSettings
|
||||
from slsdet.defines import DEFAULT_TCP_CNTRL_PORTNO, DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO
|
||||
HALFMOD2_TCP_CNTRL_PORTNO=1955
|
||||
HALFMOD2_TCP_RX_PORTNO=1957
|
||||
|
||||
from utils_for_test import (
|
||||
Log,
|
||||
LogLevel,
|
||||
RuntimeException,
|
||||
checkIfProcessRunning,
|
||||
killProcess,
|
||||
cleanup,
|
||||
cleanSharedmemory,
|
||||
startProcessInBackground,
|
||||
runProcessWithLogFile,
|
||||
startDetectorVirtualServer,
|
||||
loadConfig,
|
||||
ParseArguments
|
||||
)
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
def Log(color, message):
|
||||
print(f"{color}{message}{Style.RESET_ALL}", flush=True)
|
||||
|
||||
class RuntimeException (Exception):
|
||||
def __init__ (self, message):
|
||||
super().__init__(Log(Fore.RED, message))
|
||||
|
||||
def checkIfProcessRunning(processName):
|
||||
cmd = f"pgrep {processName}"
|
||||
res = subprocess.getoutput(cmd)
|
||||
return res.strip().splitlines()
|
||||
|
||||
|
||||
LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_test'
|
||||
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
|
||||
GENERAL_TESTS_LOG_FNAME = LOG_PREFIX_FNAME + '_results_general.txt'
|
||||
CMD_TEST_LOG_PREFIX_FNAME = LOG_PREFIX_FNAME + '_results_cmd_'
|
||||
def killProcess(name):
|
||||
pids = checkIfProcessRunning(name)
|
||||
if pids:
|
||||
Log(Fore.GREEN, f"Killing '{name}' processes with PIDs: {', '.join(pids)}")
|
||||
for pid in pids:
|
||||
try:
|
||||
p = subprocess.run(['kill', pid])
|
||||
if p.returncode != 0 and bool(checkIfProcessRunning(name)):
|
||||
raise RuntimeException(f"Could not kill {name} with pid {pid}")
|
||||
except Exception as e:
|
||||
Log(Fore.RED, f"Failed to kill process {name} pid:{pid}. Exception occured: [code:{e}, msg:{e.stderr}]")
|
||||
raise
|
||||
#else:
|
||||
# Log(Fore.WHITE, 'process not running : ' + name)
|
||||
|
||||
|
||||
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 cleanup(fp):
|
||||
'''
|
||||
kill both servers, receivers and clean shared memory
|
||||
'''
|
||||
Log(Fore.GREEN, 'Cleaning up...')
|
||||
killProcess('DetectorServer_virtual')
|
||||
killProcess('slsReceiver')
|
||||
killProcess('slsMultiReceiver')
|
||||
cleanSharedmemory(fp)
|
||||
|
||||
def cleanSharedmemory(fp):
|
||||
Log(Fore.GREEN, 'Cleaning up shared memory...')
|
||||
try:
|
||||
p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp)
|
||||
except:
|
||||
Log(Fore.RED, 'Could not free shared memory')
|
||||
raise
|
||||
|
||||
def startProcessInBackground(name):
|
||||
try:
|
||||
# in background and dont print output
|
||||
p = subprocess.Popen(name.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False)
|
||||
Log(Fore.GREEN, 'Starting up ' + name + ' ...')
|
||||
except Exception as e:
|
||||
Log(Fore.RED, f'Could not start {name}:{e}')
|
||||
raise
|
||||
|
||||
def startServer(name):
|
||||
|
||||
startProcessInBackground(name + 'DetectorServer_virtual')
|
||||
# second half
|
||||
if name == 'eiger':
|
||||
startProcessInBackground(name + 'DetectorServer_virtual -p' + str(HALFMOD2_TCP_CNTRL_PORTNO))
|
||||
tStartup = 6
|
||||
Log(Fore.WHITE, 'Takes ' + str(tStartup) + ' seconds... Please be patient')
|
||||
time.sleep(tStartup)
|
||||
|
||||
def startReceiver(name):
|
||||
startProcessInBackground('slsReceiver')
|
||||
# second half
|
||||
if name == 'eiger':
|
||||
startProcessInBackground('slsReceiver -t' + str(HALFMOD2_TCP_RX_PORTNO))
|
||||
time.sleep(2)
|
||||
|
||||
def loadConfig(name, rx_hostname, settingsdir):
|
||||
Log(Fore.GREEN, 'Loading config')
|
||||
try:
|
||||
d = Detector()
|
||||
if name == 'eiger':
|
||||
d.hostname = 'localhost:' + str(DEFAULT_TCP_CNTRL_PORTNO) + '+localhost:' + str(HALFMOD2_TCP_CNTRL_PORTNO)
|
||||
#d.udp_dstport = {2: 50003}
|
||||
# will set up for every module
|
||||
d.udp_dstport = DEFAULT_UDP_DST_PORTNO
|
||||
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
|
||||
d.rx_hostname = rx_hostname + ':' + str(DEFAULT_TCP_RX_PORTNO) + '+' + rx_hostname + ':' + str(HALFMOD2_TCP_RX_PORTNO)
|
||||
d.udp_dstip = 'auto'
|
||||
d.trimen = [4500, 5400, 6400]
|
||||
d.settingspath = settingsdir + '/eiger/'
|
||||
d.setThresholdEnergy(4500, detectorSettings.STANDARD)
|
||||
else:
|
||||
d.hostname = 'localhost'
|
||||
d.rx_hostname = rx_hostname
|
||||
d.udp_dstip = 'auto'
|
||||
d.udp_srcip = 'auto'
|
||||
if d.type == detectorType.JUNGFRAU or d.type == detectorType.MOENCH or d.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
d.powerchip = 1
|
||||
if d.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
d.configureTransceiver()
|
||||
except:
|
||||
Log(Fore.RED, 'Could not load config for ' + name)
|
||||
raise
|
||||
|
||||
def startCmdTests(name, fp, fname):
|
||||
Log(Fore.GREEN, 'Cmd Tests for ' + name)
|
||||
cmd = 'tests --abort [.cmdcall] -s -o ' + fname
|
||||
try:
|
||||
subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
pass
|
||||
|
||||
with open (fname, 'r') as f:
|
||||
for line in f:
|
||||
if "FAILED" in line:
|
||||
msg = 'Cmd tests failed for ' + name + '!!!'
|
||||
sys.stdout = original_stdout
|
||||
Log(Fore.RED, msg)
|
||||
Log(Fore.RED, line)
|
||||
sys.stdout = fp
|
||||
raise Exception(msg)
|
||||
|
||||
Log(Fore.GREEN, 'Cmd Tests successful for ' + name)
|
||||
|
||||
def startGeneralTests(fp, fname):
|
||||
Log(Fore.GREEN, 'General Tests')
|
||||
cmd = 'tests --abort -s -o ' + fname
|
||||
try:
|
||||
subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
pass
|
||||
|
||||
with open (fname, 'r') as f:
|
||||
for line in f:
|
||||
if "FAILED" in line:
|
||||
msg = 'General tests failed !!!'
|
||||
sys.stdout = original_stdout
|
||||
Log(Fore.RED, msg + '\n' + line)
|
||||
sys.stdout = fp
|
||||
raise Exception(msg)
|
||||
|
||||
Log(Fore.GREEN, 'General Tests successful')
|
||||
|
||||
|
||||
|
||||
# parse cmd line for rx_hostname and settingspath using the argparse library
|
||||
parser = argparse.ArgumentParser(description = 'automated tests with the virtual detector servers')
|
||||
parser.add_argument('rx_hostname', nargs='?', default='localhost', help = 'hostname/ip of the current machine')
|
||||
parser.add_argument('settingspath', nargs='?', default='../../settingsdir', help = 'Relative or absolut path to the settingspath')
|
||||
parser.add_argument('-s', '--servers', help='Detector servers to run', nargs='*')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.servers is None:
|
||||
servers = [
|
||||
'eiger',
|
||||
'jungfrau',
|
||||
'mythen3',
|
||||
'gotthard2',
|
||||
'ctb',
|
||||
'moench',
|
||||
'xilinx_ctb'
|
||||
]
|
||||
else:
|
||||
servers = args.servers
|
||||
|
||||
|
||||
Log(Fore.WHITE, 'Arguments:\nrx_hostname: ' + args.rx_hostname + '\nsettingspath: \'' + args.settingspath + '\nservers: \'' + ' '.join(servers) + '\'')
|
||||
|
||||
|
||||
# redirect to file
|
||||
prefix_fname = '/tmp/slsDetectorPackage_virtual_test'
|
||||
original_stdout = sys.stdout
|
||||
original_stderr = sys.stderr
|
||||
fname = prefix_fname + '_log.txt'
|
||||
Log(Fore.BLUE, '\nLog File: ' + fname)
|
||||
|
||||
with open(fname, 'w') as fp:
|
||||
|
||||
|
||||
|
||||
# general tests
|
||||
file_results = prefix_fname + '_results_general.txt'
|
||||
Log(Fore.BLUE, 'General tests (results: ' + file_results + ')')
|
||||
sys.stdout = fp
|
||||
sys.stderr = fp
|
||||
Log(Fore.BLUE, 'General tests (results: ' + file_results + ')')
|
||||
|
||||
def startGeneralTests(fp):
|
||||
fname = GENERAL_TESTS_LOG_FNAME
|
||||
cmd = ['tests', '--abort', '-s']
|
||||
try:
|
||||
cleanup(fp)
|
||||
runProcessWithLogFile('General Tests', cmd, fp, fname)
|
||||
startGeneralTests(fp, file_results)
|
||||
|
||||
testError = False
|
||||
for server in servers:
|
||||
try:
|
||||
# print to terminal for progress
|
||||
sys.stdout = original_stdout
|
||||
sys.stderr = original_stderr
|
||||
file_results = prefix_fname + '_results_cmd_' + server + '.txt'
|
||||
Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')')
|
||||
sys.stdout = fp
|
||||
sys.stderr = fp
|
||||
Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')')
|
||||
|
||||
# cmd tests for det
|
||||
cleanup(fp)
|
||||
startServer(server)
|
||||
startReceiver(server)
|
||||
loadConfig(server, args.rx_hostname, args.settingspath)
|
||||
startCmdTests(server, fp, file_results)
|
||||
cleanup(fp)
|
||||
|
||||
except Exception as e:
|
||||
# redirect to terminal
|
||||
sys.stdout = original_stdout
|
||||
sys.stderr = original_stderr
|
||||
Log(Fore.RED, f'Exception caught while testing {server}. Cleaning up...')
|
||||
testError = True
|
||||
break
|
||||
|
||||
# redirect to terminal
|
||||
sys.stdout = original_stdout
|
||||
sys.stderr = original_stderr
|
||||
if not testError:
|
||||
Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers))
|
||||
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'General tests failed.') from e
|
||||
# redirect to terminal
|
||||
sys.stdout = original_stdout
|
||||
sys.stderr = original_stderr
|
||||
Log(Fore.RED, f'Exception caught with general testing. Cleaning up...')
|
||||
cleanSharedmemory(sys.stdout)
|
||||
|
||||
|
||||
|
||||
def startCmdTestsForAll(args, fp):
|
||||
for server in args.servers:
|
||||
try:
|
||||
num_mods = 2 if server == 'eiger' else 1
|
||||
fname = CMD_TEST_LOG_PREFIX_FNAME + server + '.txt'
|
||||
cmd = ['tests', '--abort', '[.cmdcall]', '-s']
|
||||
|
||||
Log(LogLevel.INFOBLUE, f'Starting Cmd Tests for {server}')
|
||||
cleanup(fp)
|
||||
startDetectorVirtualServer(name=server, num_mods=num_mods, fp=fp)
|
||||
startReceiver(num_mods, fp)
|
||||
loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=num_mods)
|
||||
runProcessWithLogFile('Cmd Tests for ' + server, cmd, fp, fname)
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Cmd Tests failed for {server}.') from e
|
||||
|
||||
Log(LogLevel.INFOGREEN, 'Passed all tests for all detectors \n' + str(args.servers))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = ParseArguments('Automated tests with the virtual detector servers')
|
||||
if args.num_mods > 1:
|
||||
raise RuntimeException(f'Cannot support multiple modules at the moment (except Eiger).')
|
||||
|
||||
Log(LogLevel.INFOBLUE, '\nLog File: ' + MAIN_LOG_FNAME + '\n')
|
||||
|
||||
with open(MAIN_LOG_FNAME, 'w') as fp:
|
||||
try:
|
||||
startGeneralTests(fp)
|
||||
startCmdTestsForAll(args, fp)
|
||||
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.')
|
||||
|
@ -1,241 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
'''
|
||||
This file is used for common utils used for integration tests between simulators and receivers.
|
||||
'''
|
||||
|
||||
import sys, subprocess, time, argparse
|
||||
from enum import Enum
|
||||
from colorama import Fore, Style, init
|
||||
|
||||
from slsdet import Detector, detectorSettings
|
||||
from slsdet.defines import DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO
|
||||
SERVER_START_PORTNO=1900
|
||||
|
||||
init(autoreset=True)
|
||||
|
||||
|
||||
class LogLevel(Enum):
|
||||
INFO = 0
|
||||
INFORED = 1
|
||||
INFOGREEN = 2
|
||||
INFOBLUE = 3
|
||||
WARNING = 4
|
||||
ERROR = 5
|
||||
DEBUG = 6
|
||||
|
||||
|
||||
LOG_LABELS = {
|
||||
LogLevel.WARNING: "WARNING: ",
|
||||
LogLevel.ERROR: "ERROR: ",
|
||||
LogLevel.DEBUG: "DEBUG: "
|
||||
}
|
||||
|
||||
|
||||
LOG_COLORS = {
|
||||
LogLevel.INFO: Fore.WHITE,
|
||||
LogLevel.INFORED: Fore.RED,
|
||||
LogLevel.INFOGREEN: Fore.GREEN,
|
||||
LogLevel.INFOBLUE: Fore.BLUE,
|
||||
LogLevel.WARNING: Fore.YELLOW,
|
||||
LogLevel.ERROR: Fore.RED,
|
||||
LogLevel.DEBUG: Fore.CYAN
|
||||
}
|
||||
|
||||
|
||||
def Log(level: LogLevel, message: str, stream=sys.stdout):
|
||||
color = LOG_COLORS.get(level, Fore.WHITE)
|
||||
label = LOG_LABELS.get(level, "")
|
||||
print(f"{color}{label}{message}{Style.RESET_ALL}", file=stream, flush=True)
|
||||
|
||||
|
||||
class RuntimeException (Exception):
|
||||
def __init__ (self, message):
|
||||
Log(LogLevel.ERROR, message)
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
def checkIfProcessRunning(processName):
|
||||
cmd = f"pgrep -f {processName}"
|
||||
res = subprocess.getoutput(cmd)
|
||||
return res.strip().splitlines()
|
||||
|
||||
|
||||
def killProcess(name, fp):
|
||||
pids = checkIfProcessRunning(name)
|
||||
if pids:
|
||||
Log(LogLevel.INFO, f"Killing '{name}' processes with PIDs: {', '.join(pids)}", fp)
|
||||
for pid in pids:
|
||||
try:
|
||||
p = subprocess.run(['kill', pid])
|
||||
if p.returncode != 0 and bool(checkIfProcessRunning(name)):
|
||||
raise RuntimeException(f"Could not kill {name} with pid {pid}")
|
||||
except Exception as e:
|
||||
raise RuntimeException(f"Failed to kill process {name} pid:{pid}. Error: {str(e)}") from e
|
||||
#else:
|
||||
# Log(LogLevel.INFO, 'process not running : ' + name)
|
||||
|
||||
|
||||
def cleanSharedmemory(fp):
|
||||
Log(LogLevel.INFO, 'Cleaning up shared memory', fp)
|
||||
try:
|
||||
p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp)
|
||||
except:
|
||||
raise RuntimeException('Could not free shared memory')
|
||||
|
||||
|
||||
def cleanup(fp):
|
||||
Log(LogLevel.INFO, 'Cleaning up')
|
||||
Log(LogLevel.INFO, 'Cleaning up', fp)
|
||||
killProcess('DetectorServer_virtual', fp)
|
||||
killProcess('slsReceiver', fp)
|
||||
killProcess('slsMultiReceiver', fp)
|
||||
killProcess('slsFrameSynchronizer', fp)
|
||||
killProcess('frameSynchronizerPullSocket', fp)
|
||||
cleanSharedmemory(fp)
|
||||
|
||||
|
||||
def startProcessInBackground(cmd, fp):
|
||||
Log(LogLevel.INFO, 'Starting up ' + ' '.join(cmd))
|
||||
Log(LogLevel.INFO, 'Starting up ' + ' '.join(cmd), fp)
|
||||
try:
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False)
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Failed to start {cmd}:{str(e)}') from e
|
||||
|
||||
|
||||
def startProcessInBackgroundWithLogFile(cmd, fp, log_file_name):
|
||||
Log(LogLevel.INFOBLUE, 'Starting up ' + ' '.join(cmd) + '. Log: ' + log_file_name)
|
||||
Log(LogLevel.INFOBLUE, 'Starting up ' + ' '.join(cmd) + '. Log: ' + log_file_name, fp)
|
||||
try:
|
||||
with open(log_file_name, 'w') as log_fp:
|
||||
subprocess.Popen(cmd, stdout=log_fp, stderr=log_fp, text=True)
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Failed to start {cmd}:{str(e)}') from e
|
||||
|
||||
|
||||
def runProcessWithLogFile(name, cmd, fp, log_file_name):
|
||||
Log(LogLevel.INFOBLUE, 'Running ' + name + '. Log: ' + log_file_name)
|
||||
Log(LogLevel.INFOBLUE, 'Running ' + name + '. Log: ' + log_file_name, fp)
|
||||
Log(LogLevel.INFOBLUE, 'Cmd: ' + ' '.join(cmd), fp)
|
||||
try:
|
||||
with open(log_file_name, 'w') as log_fp:
|
||||
subprocess.run(cmd, stdout=log_fp, stderr=log_fp, check=True, text=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
pass
|
||||
except Exception as e:
|
||||
Log(LogLevel.ERROR, f'Failed to run {name}:{str(e)}', fp)
|
||||
raise RuntimeException(f'Failed to run {name}:{str(e)}')
|
||||
|
||||
with open (log_file_name, 'r') as f:
|
||||
for line in f:
|
||||
if "FAILED" in line:
|
||||
raise RuntimeException(f'{line}')
|
||||
|
||||
Log(LogLevel.INFOGREEN, name + ' successful!\n')
|
||||
Log(LogLevel.INFOGREEN, name + ' successful!\n', fp)
|
||||
|
||||
|
||||
def startDetectorVirtualServer(name :str, num_mods, fp):
|
||||
for i in range(num_mods):
|
||||
port_no = SERVER_START_PORTNO + (i * 2)
|
||||
cmd = [name + 'DetectorServer_virtual', '-p', str(port_no)]
|
||||
startProcessInBackground(cmd, fp)
|
||||
match name:
|
||||
case 'jungfrau':
|
||||
time.sleep(7)
|
||||
case 'gotthard2':
|
||||
time.sleep(5)
|
||||
case _:
|
||||
time.sleep(3)
|
||||
|
||||
|
||||
def connectToVirtualServers(name, num_mods):
|
||||
try:
|
||||
d = Detector()
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Could not create Detector object for {name}. Error: {str(e)}') from e
|
||||
|
||||
counts_sec = 5
|
||||
while (counts_sec != 0):
|
||||
try:
|
||||
d.virtual = [num_mods, SERVER_START_PORTNO]
|
||||
break
|
||||
except Exception as e:
|
||||
# stop server still not up, wait a bit longer
|
||||
if "Cannot connect to" in str(e):
|
||||
Log(LogLevel.WARNING, f'Still waiting for {name} virtual server to be up...{counts_sec}s left')
|
||||
time.sleep(1)
|
||||
counts_sec -= 1
|
||||
else:
|
||||
raise
|
||||
|
||||
return d
|
||||
|
||||
|
||||
def loadConfig(name, rx_hostname, settingsdir, fp, num_mods = 1, num_frames = 1):
|
||||
Log(LogLevel.INFO, 'Loading config')
|
||||
Log(LogLevel.INFO, 'Loading config', fp)
|
||||
try:
|
||||
d = connectToVirtualServers(name, num_mods)
|
||||
d.udp_dstport = DEFAULT_UDP_DST_PORTNO
|
||||
if name == 'eiger':
|
||||
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
|
||||
|
||||
d.rx_hostname = rx_hostname
|
||||
d.udp_dstip = 'auto'
|
||||
if name != "eiger":
|
||||
d.udp_srcip = 'auto'
|
||||
|
||||
if name == "jungfrau" or name == "moench" or name == "xilinx_ctb":
|
||||
d.powerchip = 1
|
||||
|
||||
if name == "xilinx_ctb":
|
||||
d.configureTransceiver()
|
||||
|
||||
if name == "eiger":
|
||||
d.trimen = [4500, 5400, 6400]
|
||||
d.settingspath = settingsdir + '/eiger/'
|
||||
d.setThresholdEnergy(4500, detectorSettings.STANDARD)
|
||||
|
||||
d.frames = num_frames
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Could not load config for {name}. Error: {str(e)}') from e
|
||||
|
||||
|
||||
def ParseArguments(description, default_num_mods=1):
|
||||
parser = argparse.ArgumentParser(description)
|
||||
|
||||
parser.add_argument('rx_hostname', nargs='?', default='localhost',
|
||||
help='Hostname/IP of the current machine')
|
||||
parser.add_argument('settingspath', nargs='?', default='../../settingsdir',
|
||||
help='Relative or absolute path to the settings directory')
|
||||
parser.add_argument('-n', '--num-mods', nargs='?', default=default_num_mods, type=int,
|
||||
help='Number of modules to test with')
|
||||
parser.add_argument('-f', '--num-frames', nargs='?', default=1, type=int,
|
||||
help='Number of frames to test with')
|
||||
parser.add_argument('-s', '--servers', nargs='*',
|
||||
help='Detector servers to run')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Set default server list if not provided
|
||||
if args.servers is None:
|
||||
args.servers = [
|
||||
'eiger',
|
||||
'jungfrau',
|
||||
'mythen3',
|
||||
'gotthard2',
|
||||
'ctb',
|
||||
'moench',
|
||||
'xilinx_ctb'
|
||||
]
|
||||
|
||||
Log(LogLevel.INFO, 'Arguments:\n' +
|
||||
'rx_hostname: ' + args.rx_hostname +
|
||||
'\nsettingspath: \'' + args.settingspath +
|
||||
'\nservers: \'' + ' '.join(args.servers) +
|
||||
'\nnum_mods: \'' + str(args.num_mods) +
|
||||
'\nnum_frames: \'' + str(args.num_frames) + '\'')
|
||||
|
||||
return args
|
@ -1,81 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2025 Contributors to the SLS Detector Package
|
||||
"""
|
||||
Script to update API VERSION file based on the version in VERSION file.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
API_FILE = SCRIPT_DIR + "/slsSupportLib/include/sls/versionAPI.h"
|
||||
|
||||
VERSION_FILE = SCRIPT_DIR + "/VERSION"
|
||||
|
||||
parser = argparse.ArgumentParser(description = 'updates API version')
|
||||
parser.add_argument('api_module_name', choices=["APILIB", "APIRECEIVER", "APICTB", "APIGOTTHARD2", "APIMOENCH", "APIEIGER", "APIXILINXCTB", "APIJUNGFRAU", "APIMYTHEN3"], help = 'module name to change api version options are: ["APILIB", "APIRECEIVER", "APICTB", "APIGOTTHARD2", "APIMOENCH", "APIEIGER", "APIXILINXCTB", "APIJUNGFRAU", "APIMYTHEN3"]')
|
||||
parser.add_argument('api_dir', help = 'Relative or absolute path to the module code')
|
||||
|
||||
def update_api_file(new_api : str, api_module_name : str, api_file_name : str):
|
||||
|
||||
regex_pattern = re.compile(rf'#define\s+{api_module_name}\s+')
|
||||
with open(api_file_name, "r") as api_file:
|
||||
lines = api_file.readlines()
|
||||
|
||||
with open(api_file_name, "w") as api_file:
|
||||
for line in lines:
|
||||
if regex_pattern.match(line):
|
||||
api_file.write(f'#define {api_module_name} "{new_api}"\n')
|
||||
else:
|
||||
api_file.write(line)
|
||||
|
||||
def get_latest_modification_date(directory : str):
|
||||
latest_time = 0
|
||||
latest_date = None
|
||||
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
if file.endswith(".o"):
|
||||
continue
|
||||
full_path = os.path.join(root, file)
|
||||
try:
|
||||
mtime = os.path.getmtime(full_path)
|
||||
if mtime > latest_time:
|
||||
latest_time = mtime
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
|
||||
latest_date = datetime.fromtimestamp(latest_time).strftime("%y%m%d")
|
||||
|
||||
return latest_date
|
||||
|
||||
|
||||
def update_api_version(api_module_name : str, api_dir : str):
|
||||
api_date = get_latest_modification_date(api_dir)
|
||||
api_date = "0x"+str(api_date)
|
||||
|
||||
with open(VERSION_FILE, "r") as version_file:
|
||||
api_version = version_file.read().strip()
|
||||
|
||||
api_version = api_version + " " + api_date #not sure if we should give an argument option version_branch
|
||||
|
||||
update_api_file(api_version, api_module_name, API_FILE)
|
||||
|
||||
print(f"updated {api_module_name} api version to: {api_version}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
api_dir = SCRIPT_DIR + "/" + args.api_dir
|
||||
|
||||
|
||||
update_api_version(args.api_module_name, api_dir)
|
||||
|
||||
|
65
updateAPIVersion.sh
Executable file
65
updateAPIVersion.sh
Executable file
@ -0,0 +1,65 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
usage="\nUsage: updateAPIVersion.sh [API_NAME] [API_DIR] [API_BRANCH(opt)]."
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo -e "Requires atleast 2 arguments. $usage"
|
||||
return [-1]
|
||||
fi
|
||||
|
||||
API_NAME=$1
|
||||
PACKAGE_DIR=$PWD
|
||||
API_DIR=$PACKAGE_DIR/$2
|
||||
API_FILE=$PACKAGE_DIR/slsSupportLib/include/sls/versionAPI.h
|
||||
CURR_DIR=$PWD
|
||||
|
||||
if [ ! -d "$API_DIR" ]; then
|
||||
echo "[API_DIR] does not exist. $usage"
|
||||
return [-1]
|
||||
fi
|
||||
|
||||
#go to directory
|
||||
cd $API_DIR
|
||||
|
||||
#deleting line from file
|
||||
NUM=$(sed -n '/'$API_NAME' /=' $API_FILE)
|
||||
#echo $NUM
|
||||
|
||||
|
||||
if [ "$NUM" -gt 0 ]; then
|
||||
sed -i ${NUM}d $API_FILE
|
||||
fi
|
||||
|
||||
#find new API date
|
||||
API_DATE="find . -printf \"%T@ %CY-%Cm-%Cd\n\"| sort -nr | cut -d' ' -f2- | egrep -v '(\.)o' | head -n 1"
|
||||
|
||||
API_DATE=`eval $API_DATE`
|
||||
|
||||
API_DATE=$(sed "s/-//g" <<< $API_DATE | awk '{print $1;}' )
|
||||
|
||||
#extracting only date
|
||||
API_DATE=${API_DATE:2:6}
|
||||
|
||||
#prefix of 0x
|
||||
API_DATE=${API_DATE/#/0x}
|
||||
echo "date="$API_DATE
|
||||
|
||||
|
||||
# API_VAL concatenates branch and date
|
||||
API_VAL=""
|
||||
# API branch is defined (3rd argument)
|
||||
if [ $# -eq 3 ]; then
|
||||
API_BRANCH=$3
|
||||
echo "branch="$API_BRANCH
|
||||
API_VAL+="\"$API_BRANCH $API_DATE\""
|
||||
else
|
||||
# API branch not defined (default is developer)
|
||||
echo "branch=developer"
|
||||
API_VAL+="\"developer $API_DATE\""
|
||||
fi
|
||||
|
||||
#copy it to versionAPI.h
|
||||
echo "#define "$API_NAME $API_VAL >> $API_FILE
|
||||
|
||||
#go back to original directory
|
||||
cd $CURR_DIR
|
@ -1,34 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2025 Contributors to the SLS Detector Package
|
||||
"""
|
||||
Script to update API VERSION for slsReceiverSoftware or slsDetectorSoftware
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
|
||||
from updateAPIVersion import update_api_version
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
parser = argparse.ArgumentParser(description = 'updates API version')
|
||||
parser.add_argument('module_name', nargs="?", choices=["slsDetectorSoftware", "slsReceiverSoftware", "all"], default="all", help = 'module name to change api version options are: ["slsDetectorSoftware", "slsReceiverSoftware, "all"]')
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.module_name == "all":
|
||||
client_names = ["APILIB", "APIRECEIVER"]
|
||||
client_directories = [SCRIPT_DIR+"/slsDetectorSoftware", SCRIPT_DIR+"/slsReceiverSoftware"]
|
||||
elif args.module_name == "slsDetectorSoftware":
|
||||
client_names = ["APILIB"]
|
||||
client_directories = [SCRIPT_DIR+"/slsDetectorSoftware"]
|
||||
else:
|
||||
client_names = ["APIRECEIVER"]
|
||||
client_directories = [SCRIPT_DIR+"/slsReceiverSoftware"]
|
||||
|
||||
for client_name, client_directory in zip(client_names, client_directories):
|
||||
update_api_version(client_name, client_directory)
|
||||
|
||||
|
||||
|
59
updateClientAPIVersion.sh
Executable file
59
updateClientAPIVersion.sh
Executable file
@ -0,0 +1,59 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
branch=""
|
||||
client_list=("slsDetectorSoftware" "slsReceiverSoftware")
|
||||
usage="\nUsage: updateClientAPI.sh [all|slsDetectorSoftware|slsReceiverSoftware] [branch]. \n\tNo arguments means all with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
|
||||
|
||||
# arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
declare -a client=${client_list[@]}
|
||||
echo "API Versioning all"
|
||||
elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
||||
# 'all' client
|
||||
if [[ $1 == "all" ]]; then
|
||||
declare -a client=${client_list[@]}
|
||||
echo "API Versioning all"
|
||||
else
|
||||
# only one server
|
||||
if [[ $client_list != *$1* ]]; then
|
||||
echo -e "Invalid argument 1: $1. $usage"
|
||||
return -1
|
||||
fi
|
||||
declare -a client=("${1}")
|
||||
#echo "Versioning only $1"
|
||||
fi
|
||||
if [ $# -eq 2 ]; then
|
||||
if [[ $client_list == *$2* ]]; then
|
||||
echo -e "Invalid argument 2: $2. $usage"
|
||||
return -1
|
||||
fi
|
||||
branch+=$2
|
||||
#echo "with branch $branch"
|
||||
fi
|
||||
else
|
||||
echo -e "Too many arguments.$usage"
|
||||
return -1
|
||||
fi
|
||||
|
||||
#echo "list is: ${client[@]}"
|
||||
|
||||
# versioning each client
|
||||
for i in ${client[@]}
|
||||
do
|
||||
dir=$i
|
||||
case $dir in
|
||||
slsDetectorSoftware)
|
||||
declare -a name=APILIB
|
||||
;;
|
||||
slsReceiverSoftware)
|
||||
declare -a name=APIRECEIVER
|
||||
;;
|
||||
*)
|
||||
echo -n "unknown client argument $i"
|
||||
return -1
|
||||
;;
|
||||
esac
|
||||
echo -e "Versioning $dir [$name]"
|
||||
./updateAPIVersion.sh $name $dir $branch
|
||||
done
|
||||
|
Reference in New Issue
Block a user