Compare commits

..

37 Commits

Author SHA1 Message Date
froejdh_e
247b71a67a marked unused functions readDataFile/writeDataFile deprecated in file_utils.h 2025-12-16 17:13:46 +01:00
497b3ed00e Merge pull request #1343 from slsdetectorgroup/dev/update_release_notes
All checks were successful
Build on local RHEL9 / build (push) Successful in 1m23s
Build on local RHEL8 / build (push) Successful in 3m26s
Build on RHEL9 / build (push) Successful in 3m35s
Build on RHEL8 / build (push) Successful in 5m10s
updated release notes
2025-12-11 09:52:56 +01:00
300a296c20 updated release notes 2025-12-10 16:21:00 +01:00
01e392b112 Merge pull request #1342 from slsdetectorgroup/dev/dbitorder
All checks were successful
Build on local RHEL9 / build (push) Successful in 1m22s
Build on local RHEL8 / build (push) Successful in 3m26s
Build on RHEL9 / build (push) Successful in 3m49s
Build on RHEL8 / build (push) Successful in 4m31s
Preserve order in receiver dbit list
2025-12-04 16:03:48 +01:00
5409cec73e adapted test to test no reorder behavior
All checks were successful
Build on RHEL9 / build (push) Successful in 4m12s
Build on RHEL8 / build (push) Successful in 4m30s
2025-12-04 10:58:37 +01:00
Erik Fröjdh
1c31a85a43 added function to remove duplicates, preserve order of dbit 2025-12-03 12:14:35 +01:00
134137ead0 build RH8 in conda env
All checks were successful
Build on local RHEL8 / build (push) Successful in 3m24s
Build on RHEL9 / build (push) Successful in 3m24s
Build on local RHEL9 / build (push) Successful in 1m21s
Build on RHEL8 / build (push) Successful in 5m25s
2025-11-27 16:28:21 +01:00
6d3922f487 typo
All checks were successful
Build on RHEL9 / build (push) Successful in 3m24s
Build on RHEL8 / build (push) Successful in 5m14s
Build on local RHEL9 / build (push) Successful in 1m22s
Build on local RHEL8 / build (push) Successful in 3m23s
2025-11-27 15:27:17 +01:00
f14cfb0b31 deploy python ui
Some checks failed
Build on local RHEL9 / build (push) Successful in 1m23s
Build on local RHEL8 / build (push) Successful in 3m23s
Build on RHEL9 / build (push) Successful in 4m26s
Build on RHEL8 / build (push) Has been cancelled
2025-11-27 15:21:34 +01:00
cf4e6b65c1 Merge branch 'dev/NFS_testing' into developer 2025-11-27 11:00:29 +01:00
0da80cd898 local runners only for developer
All checks were successful
Build on RHEL9 / build (push) Successful in 3m53s
Build on RHEL8 / build (push) Successful in 5m30s
2025-11-27 10:43:51 +01:00
8e7921ae45 Merge pull request #1339 from slsdetectorgroup/dev/python_cmd_for_ROI
All checks were successful
Build on RHEL9 / build (push) Successful in 4m30s
Build on RHEL8 / build (push) Successful in 5m46s
Dev/python cmd for roi
2025-11-26 15:29:40 +01:00
b90851a855 clang-format 12 2025-11-26 14:15:04 +01:00
683accd914 fix unsuccesful merge in RELEASE.txt 2025-11-26 14:04:55 +01:00
30e82e4740 removed tests for eiger 2025-11-26 13:51:38 +01:00
08486b9812 rx_roi also accepts sequence of 2 ints 2025-11-26 13:51:22 +01:00
a5c661ce22 another bug for xilinx in test script 2025-11-26 13:51:08 +01:00
50448cefb4 Code Review 2025-11-26 13:50:45 +01:00
c1e5cfa101 fixed virtual detector test scripts 2025-11-26 12:25:25 +01:00
ae8c9175bf disable user id and port test 2025-11-26 12:24:48 +01:00
e7f5a2aa11 added colorama in github workflows 2025-11-26 12:24:27 +01:00
cad44943c3 wrapped virtual detector setup in a test fixture 2025-11-26 12:24:07 +01:00
d4f8049623 added tests 2025-11-26 12:23:40 +01:00
925cd55b1c API also allows single sequence for single ROI 2025-11-26 12:23:22 +01:00
ec11ba5a54 added typecaster for slsdefs::ROI and added setter and getter for ROI 2025-11-26 12:23:04 +01:00
eea4dca449 remove branch restrictions
All checks were successful
Build on local RHEL9 / build (push) Successful in 1m44s
Build on local RHEL8 / build (push) Successful in 4m34s
Build on RHEL9 / build (push) Successful in 4m31s
Build on RHEL8 / build (push) Successful in 5m47s
2025-11-26 09:11:55 +01:00
3285221e8a added RH9 workflow
All checks were successful
Build on local RHEL8 / build (push) Successful in 4m37s
Build on RHEL8 / build (push) Successful in 5m18s
Build on RHEL9 / build (push) Successful in 5m26s
Build on local RHEL9 / build (push) Successful in 1m54s
2025-11-25 17:56:20 +01:00
Erik Fröjdh
f32fcf1e88 Using system libzmq in conda builds (#1327)
All checks were successful
Build on RHEL8 / build (push) Successful in 5m18s
Build on RHEL9 / build (push) Successful in 5m21s
* system (conda) libzmq
* added python 3.14 and bumped cibuildwheel version
2025-11-25 16:53:20 +01:00
3ff199822d change path to RH8
All checks were successful
Build on local RHEL8 / build (push) Successful in 4m37s
Build on RHEL8 / build (push) Successful in 5m13s
Build on RHEL9 / build (push) Successful in 6m0s
2025-11-25 16:37:42 +01:00
0ba9a269a1 New this build bin path script (#1335)
All checks were successful
Build on RHEL8 / build (push) Successful in 5m34s
Build on RHEL9 / build (push) Successful in 5m54s
* better this_build_bin_path script
* Put new values first in PATH and PYTHONPATH. Remove LD_LIBRARY_PATH
2025-11-25 16:29:48 +01:00
afc51c9771 testing NFS deploy 2025-11-25 16:14:33 +01:00
1cf9dc21ab Merge pull request #1326 from slsdetectorgroup/doc/exptime
All checks were successful
Build on RHEL9 / build (push) Successful in 4m24s
Build on RHEL8 / build (push) Successful in 5m23s
added example to time conversion
2025-11-19 16:16:34 +01:00
3b92ffb902 Merge branch 'developer' into doc/exptime
All checks were successful
Build on RHEL9 / build (push) Successful in 3m27s
Build on RHEL8 / build (push) Successful in 5m31s
2025-11-19 09:58:21 +01:00
Martin Mueller
0490c0ef23 Merge pull request #1332 from slsdetectorgroup/MH02_debug
All checks were successful
Build on RHEL9 / build (push) Successful in 3m43s
Build on RHEL8 / build (push) Successful in 5m18s
MH02 change clock switching method during periphery reset
2025-11-17 13:40:43 +01:00
af2c6eca0c MH02 change clock switching method during periphery reset 2025-11-10 10:35:20 +01:00
Erik Fröjdh
d3dc92b18b Using find_package(Threads REQUIRED) instead of linking pthread directly (#1324)
All checks were successful
Build on RHEL9 / build (push) Successful in 4m30s
Build on RHEL8 / build (push) Successful in 4m42s
* Linking to Threads::Threads instead of pthread directly 
* moved rt linking to slsSupportObject and only enable for linux
2025-10-27 16:30:40 +01:00
froejdh_e
e243af045d added example to time conversion 2025-10-27 16:28:36 +01:00
51 changed files with 584 additions and 500 deletions

View File

@@ -0,0 +1,33 @@
name: Build on local RHEL8
on:
push:
branches:
- developer
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: "detectors-software-RH8"
steps:
- uses: actions/checkout@v4
- name: Build library
run: |
source /home/gitea_runner/.bashrc
conda activate det
mkdir build && cd build
conda activate det
cmake .. -DSLS_USE_PYTHON=ON
make -j 2
cd ../pyctbgui
make
- name: Deploy to NFS update server
if: gitea.ref == 'refs/heads/developer'
run: |
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH8 <<< $'put build/bin'
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH8 <<< $'put pyctbgui'

View File

@@ -21,9 +21,9 @@ jobs:
- name: Build library - name: Build library
run: | run: |
mkdir build && cd build mkdir build && cd build
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON -DSLS_USE_SIMULATOR=ON
make -j 2 make -j 2
- name: C++ unit tests - name: C++ unit tests
working-directory: ${{gitea.workspace}}/build working-directory: ${{gitea.workspace}}/build
run: ctest run: ctest -j1 --rerun-failed --output-on-failure

View File

@@ -0,0 +1,30 @@
name: Build on local RHEL9
on:
push:
branches:
- developer
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: "detectors-software-RH9"
steps:
- uses: actions/checkout@v4
- name: Build library
run: |
mkdir build && cd build
cmake -DSLS_USE_PYTHON=ON -DPython_EXECUTABLE=/usr/bin/python3.13 -DPython_INCLUDE_DIR=/usr/include/python3.13 -DPython_LIBRARY=/usr/lib64/libpython3.13.so ..
make -j 2
cd ../pyctbgui
make
- name: Deploy to NFS update server
if: gitea.ref == 'refs/heads/developer'
run: |
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH9 <<< $'put build/bin'
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH9 <<< $'put pyctbgui'

View File

@@ -19,9 +19,9 @@ jobs:
- name: Build library - name: Build library
run: | run: |
mkdir build && cd build mkdir build && cd build
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON -DSLS_USE_SIMULATOR=ON
make -j 2 make -j 2
- name: C++ unit tests - name: C++ unit tests
working-directory: ${{gitea.workspace}}/build working-directory: ${{gitea.workspace}}/build
run: ctest run: ctest -j1 --rerun-failed --output-on-failure

View File

@@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build wheels - name: Build wheels
run: pipx run cibuildwheel==2.23.0 run: pipx run cibuildwheel==3.2.1
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:

View File

@@ -19,7 +19,7 @@ jobs:
with: with:
python-version: 3.12 python-version: 3.12
cache: 'pip' cache: 'pip'
- run: pip install pytest numpy - run: pip install pytest numpy colorama
- uses: awalsh128/cache-apt-pkgs-action@latest - uses: awalsh128/cache-apt-pkgs-action@latest
with: with:
@@ -37,7 +37,7 @@ jobs:
- name: C++ unit tests - name: C++ unit tests
working-directory: ${{github.workspace}}/build working-directory: ${{github.workspace}}/build
run: ctest -C ${{env.BUILD_TYPE}} -j1 run: ctest -C ${{env.BUILD_TYPE}} -j1 --rerun-failed --output-on-failure
- name: Python unit tests - name: Python unit tests
working-directory: ${{github.workspace}}/build/bin working-directory: ${{github.workspace}}/build/bin

View File

@@ -24,6 +24,15 @@ include(cmake/SlsAddFlag.cmake)
include(cmake/helpers.cmake) include(cmake/helpers.cmake)
find_package(Threads REQUIRED)
# POSIX threads are required for the moment but we use CMake to find them
# Once migrated to std::thread this can be removed
if(NOT CMAKE_USE_PTHREADS_INIT)
message(FATAL_ERROR "A POSIX threads (pthread) implementation is required, but was not found.")
endif()
option(SLS_USE_SYSTEM_ZMQ "Use system installed libzmq" OFF) option(SLS_USE_SYSTEM_ZMQ "Use system installed libzmq" OFF)
# Using FetchContent to get libzmq # Using FetchContent to get libzmq
@@ -332,6 +341,9 @@ if (NOT TARGET slsProjectCSettings)
-Wno-format-truncation -Wno-format-truncation
) )
sls_disable_c_warning("-Wstringop-truncation") sls_disable_c_warning("-Wstringop-truncation")
target_link_libraries(slsProjectCSettings INTERFACE
Threads::Threads
)
endif() endif()

View File

@@ -1,7 +1,7 @@
SLS Detector Package Major Release x.x.x released on xx.xx.202x SLS Detector Package Major Release x.x.x released on xx.xx.202x
=============================================================== ===============================================================
This document describes the differences between vx.x.x and vx.0.2 This document describes the differences between vx.x.x and v10.0.0
@@ -35,6 +35,10 @@ instead of the one included in our repo.
Experimental support for building the detector client (including python bindings) on macOS Experimental support for building the detector client (including python bindings) on macOS
``rx_dbitlist`` keeps the order of the passed bit list
Marked unused functions readDataFile/writeDataFile deprecated in file_utils.h
2 On-board Detector Server Compatibility 2 On-board Detector Server Compatibility
========================================== ==========================================

View File

@@ -19,6 +19,7 @@ cmake .. -G Ninja \
-DSLS_USE_PYTHON=OFF \ -DSLS_USE_PYTHON=OFF \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DSLS_USE_HDF5=OFF \ -DSLS_USE_HDF5=OFF \
-DSLS_USE_SYSTEM_ZMQ=ON \
NCORES=$(getconf _NPROCESSORS_ONLN) NCORES=$(getconf _NPROCESSORS_ONLN)
echo "Building using: ${NCORES} cores" echo "Building using: ${NCORES} cores"

View File

@@ -29,6 +29,7 @@ requirements:
- libtiff - libtiff
- zlib - zlib
- expat - expat
- zeromq
run: run:
- libstdcxx-ng - libstdcxx-ng

View File

@@ -2,6 +2,8 @@ python:
- 3.11 - 3.11
- 3.12 - 3.12
- 3.13 - 3.13
- 3.14
c_compiler: c_compiler:
- gcc # [linux] - gcc # [linux]
@@ -13,4 +15,4 @@ cxx_compiler:
- gxx # [linux] - gxx # [linux]
c_stdlib_version: # [linux] c_stdlib_version: # [linux]
- 2.17 # [linux] - 2.17 # [linux]

View File

@@ -9,11 +9,11 @@ package:
build: build:
number: 0 number: 0
script: script:
- unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win] - unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv --config-settings=cmake.define.SLS_USE_SYSTEM_ZMQ=ON # [not win]
requirements: requirements:
build: build:
- python {{python}} - python
- {{ compiler('c') }} - {{ compiler('c') }}
- {{ stdlib("c") }} - {{ stdlib("c") }}
- {{ compiler('cxx') }} - {{ compiler('cxx') }}
@@ -21,7 +21,7 @@ requirements:
host: host:
- cmake - cmake
- ninja - ninja
- python {{python}} - python
- pip - pip
- scikit-build-core - scikit-build-core
- pybind11 >=2.13.0 - pybind11 >=2.13.0
@@ -31,7 +31,7 @@ requirements:
- catch2 - catch2
run: run:
- python {{python}} - python
- numpy - numpy

View File

@@ -50,6 +50,12 @@ datetime.timedelta, DurationWrapper or by setting the time in seconds.
>>> d.getExptime() >>> d.getExptime()
[sls::DurationWrapper(total_seconds: 181.23 count: 181230000000)] [sls::DurationWrapper(total_seconds: 181.23 count: 181230000000)]
# In C++ it is possible to use chrono literals to set time more easily
# d.setExptime(7ms). However, this is not possible due to pythons syntax.
# instead we can create a unit that we use for conversion.
>>> ms = dt.timedelta(milliseconds = 1)
>>> d.exptime = 7.5*ms
------------------------------------ ------------------------------------

View File

@@ -5,18 +5,18 @@ nsigma 5
gainfile none gainfile none
detectorMode counting detectorMode counting
threshold 0 threshold 0
pedestalfile /mnt/sls_det_storage/moench_data/testNewFW20230714/cu_half_speed_d0_f0_4.raw pedestalfile none
nframes 0 nframes 0
xMin 0 xMin 0
xMax 400 xMax 400
yMin 0 yMin 0
yMax 400 yMax 400
outdir /mnt/sls_det_storage/moench_data/testNewFW20230714/clustNew/ outdir ./
indir /mnt/sls_det_storage/moench_data/testNewFW20230714/ indir ./
flist none flist none
fformat cu_half_speed_d0_f0_4 fformat none
runmin 0 runmin 0
runmax 0 runmax -1
readnrows 400 readnrows 400
eMin 0 eMin 0
eMax 16000 eMax 16000

View File

@@ -17,7 +17,7 @@ dependencies = [
[tool.cibuildwheel] [tool.cibuildwheel]
before-all = "uname -a" before-all = "uname -a"
build = "cp{311,312,313}-manylinux_x86_64" build = "cp{311,312,313,314}-manylinux_x86_64"
[tool.scikit-build.build] [tool.scikit-build.build]
verbose = true verbose = true

View File

@@ -24,6 +24,7 @@ import datetime as dt
from functools import wraps from functools import wraps
from collections import namedtuple from collections import namedtuple
from collections.abc import Sequence
import socket import socket
import numpy as np import numpy as np
@@ -301,6 +302,46 @@ class Detector(CppDetectorApi):
def rx_arping(self, value): def rx_arping(self, value):
ut.set_using_dict(self.setRxArping, value) ut.set_using_dict(self.setRxArping, value)
@property
def rx_roi(self):
"""Gets the list of ROIs configured in the receiver.
Note
-----
Each ROI is represented as a tuple of (x_start, y_start, x_end, y_end). \n
If no ROIs are configured, returns [[-1,-1,-1,-1]].
"""
return self.getRxROI() #vector of Roi structs how represented?
@rx_roi.setter
def rx_roi(self, rois):
"""
Sets the list of ROIs in the receiver.
Can only set multiple ROIs at multi module level without gap pixels. If more than 1 ROI per
UDP port, it will throw. Setting number of udp interfaces will clear the
roi. Cannot be set for CTB or Xilinx CTB.
Note
-----
Each ROI should be represented as a sequence of 4 ints (x_start, y_start, x_end, y_end). \n
For mythen3 or gotthard2 pass a sequence of 2 ints (x_start, x_end) \n
For multiple ROI's pass a sequence of sequence \n
Example: [[0, 100, 50, 100], [260, 270, 50,100]] \n
"""
# TODO: maybe better to accept py::object in setRxROI and handle there?
if not isinstance(rois, Sequence):
raise TypeError(
"setRxROI failed: expected a tuple/list of ints x_min, x_max, y_min, y_max "
"or a sequence of such."
)
if(not isinstance(rois[0], Sequence)):
self.setRxROI([rois])
else:
self.setRxROI(rois)
def rx_clearroi(self):
"""Clears all the ROIs configured in the receiver."""
self.clearRxROI()
@property @property
@element @element

View File

@@ -942,6 +942,7 @@ void init_det(py::module &m) {
(void (Detector::*)(const std::vector<defs::ROI> &)) & (void (Detector::*)(const std::vector<defs::ROI> &)) &
Detector::setRxROI, Detector::setRxROI,
py::arg()); py::arg());
CppDetectorApi.def("clearRxROI", CppDetectorApi.def("clearRxROI",
(void (Detector::*)()) & Detector::clearRxROI); (void (Detector::*)()) & Detector::clearRxROI);
CppDetectorApi.def( CppDetectorApi.def(

View File

@@ -1,11 +1,12 @@
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once #pragma once
#include <pybind11/pybind11.h>
#include <datetime.h> #include <datetime.h>
#include <pybind11/pybind11.h>
#include "sls/Result.h"
#include "DurationWrapper.h" #include "DurationWrapper.h"
#include "sls/Result.h"
#include "sls/sls_detector_defs.h"
namespace py = pybind11; namespace py = pybind11;
namespace pybind11 { namespace pybind11 {
@@ -14,84 +15,130 @@ template <typename Type, typename Alloc>
struct type_caster<sls::Result<Type, Alloc>> struct type_caster<sls::Result<Type, Alloc>>
: list_caster<sls::Result<Type, Alloc>, Type> {}; : list_caster<sls::Result<Type, Alloc>, Type> {};
// Based on the typecaster in pybind11/chrono.h // Based on the typecaster in pybind11/chrono.h
template <> struct type_caster<std::chrono::nanoseconds> { template <> struct type_caster<std::chrono::nanoseconds> {
public: public:
PYBIND11_TYPE_CASTER(std::chrono::nanoseconds, const_name("DurationWrapper")); PYBIND11_TYPE_CASTER(std::chrono::nanoseconds,
const_name("DurationWrapper"));
// signed 25 bits required by the standard. // signed 25 bits required by the standard.
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>; using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
/** /**
* Conversion part 1 (Python->C++): convert a PyObject into std::chrono::nanoseconds * Conversion part 1 (Python->C++): convert a PyObject into
* try datetime.timedelta, floats and our DurationWrapper wrapper * std::chrono::nanoseconds try datetime.timedelta, floats and our
*/ * DurationWrapper wrapper
*/
bool load(handle src, bool) { bool load(handle src, bool) {
using namespace std::chrono; using namespace std::chrono;
// Lazy initialise the PyDateTime import // Lazy initialise the PyDateTime import
if (!PyDateTimeAPI) { if (!PyDateTimeAPI) {
PyDateTime_IMPORT; PyDateTime_IMPORT;
} }
if (!src) { if (!src) {
return false;
}
// If invoked with datetime.delta object, same as in chrono.h
if (PyDelta_Check(src.ptr())) {
value = duration_cast<nanoseconds>(
days(PyDateTime_DELTA_GET_DAYS(src.ptr())) +
seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) +
microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))
);
return true;
}
// If invoked with a float we assume it is seconds and convert, same as
// in chrono.h
if (PyFloat_Check(src.ptr())) {
value = duration_cast<nanoseconds>(
duration<double>(PyFloat_AsDouble(src.ptr())));
return true;
}
// If invoked with an int we assume it is nanoseconds and convert, same
// as in chrono.h
if (PyLong_Check(src.ptr())) {
value = duration_cast<nanoseconds>(
duration<int64_t>(PyLong_AsLongLong(src.ptr())));
return true;
}
// Lastly if we were actually called with a DurationWrapper object we
// get the number of nanoseconds and create a std::chrono::nanoseconds
// from it
py::object py_cls =
py::module::import("slsdet._slsdet").attr("DurationWrapper");
if (py::isinstance(src, py_cls)) {
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
value = nanoseconds(cls->count());
return true;
}
return false;
}
/**
* Conversion part 2 (C++ -> Python)
* import the module to get a handle to the wrapped class
* Default construct an object of (wrapped) DurationWrapper
* set the count from chrono::nanoseconds and return
*/
static handle cast(std::chrono::nanoseconds src,
return_value_policy /* policy */, handle /* parent */) {
py::object py_cls =
py::module::import("slsdet._slsdet").attr("DurationWrapper");
py::object *obj = new py::object;
*obj = py_cls();
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
dur->set_count(src.count());
return *obj;
}
};
// Type caster for sls::defs::ROI from tuple
template <> struct type_caster<sls::defs::ROI> {
PYBIND11_TYPE_CASTER(sls::defs::ROI, _("Sequence[int, int, int, int] or "
"Sequence[int, int]"));
// convert c++ ROI to python tuple
static handle cast(const sls::defs::ROI &roi, return_value_policy, handle) {
return py::make_tuple(roi.xmin, roi.xmax, roi.ymin, roi.ymax).release();
}
// convert from python to c++ ROI
bool load(handle roi, bool /*allow implicit conversion*/) {
// accept tuple, list, numpy array any sequence
py::sequence seq;
try {
seq = py::reinterpret_borrow<py::sequence>(roi);
} catch (...) {
return false;
}
if (seq.size() != 4 && seq.size() != 2)
return false;
// Check if each element is an int
for (auto item : seq) {
if (!py::isinstance<py::int_>(item)) {
return false; return false;
} }
// If invoked with datetime.delta object, same as in chrono.h
if (PyDelta_Check(src.ptr())) {
value = duration_cast<nanoseconds>(
days(PyDateTime_DELTA_GET_DAYS(src.ptr())) +
seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) +
microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))
);
return true;
}
// If invoked with a float we assume it is seconds and convert, same as in chrono.h
if (PyFloat_Check(src.ptr())) {
value = duration_cast<nanoseconds>(duration<double>(PyFloat_AsDouble(src.ptr())));
return true;
}
// If invoked with an int we assume it is nanoseconds and convert, same as in chrono.h
if (PyLong_Check(src.ptr())) {
value = duration_cast<nanoseconds>(duration<int64_t>(PyLong_AsLongLong(src.ptr())));
return true;
}
// Lastly if we were actually called with a DurationWrapper object we get
// the number of nanoseconds and create a std::chrono::nanoseconds from it
py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper");
if (py::isinstance(src, py_cls)){
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
value = nanoseconds(cls->count());
return true;
}
return false;
} }
/** value.xmin = seq[0].cast<int>();
* Conversion part 2 (C++ -> Python) value.xmax = seq[1].cast<int>();
* import the module to get a handle to the wrapped class
* Default construct an object of (wrapped) DurationWrapper if (seq.size() == 4) {
* set the count from chrono::nanoseconds and return value.ymin = seq[2].cast<int>();
*/ value.ymax = seq[3].cast<int>();
static handle cast(std::chrono::nanoseconds src, return_value_policy /* policy */, handle /* parent */) {
py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper");
py::object* obj = new py::object;
*obj = py_cls();
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
dur->set_count(src.count());
return *obj;
} }
};
return true;
}
};
} // namespace detail } // namespace detail
} // namespace pybind11 } // namespace pybind11

85
python/tests/conftest.py Normal file
View File

@@ -0,0 +1,85 @@
import pytest
import sys
import traceback
from pathlib import Path
current_dir = Path(__file__).resolve().parents[2]
scripts_dir = current_dir / "tests" / "scripts"
sys.path.append(str(scripts_dir))
print(sys.path)
from utils_for_test import (
Log,
LogLevel,
cleanup,
startReceiver,
startDetectorVirtualServer,
loadConfig,
loadBasicSettings,
)
def pytest_addoption(parser):
parser.addoption(
"--with-detector-simulators", action="store_true", default=False, help="Run tests that require detector simulators"
)
def pytest_configure(config):
config.addinivalue_line("markers", "withdetectorsimulators: mark test as needing detector simulators to run")
def pytest_collection_modifyitems(config, items):
if config.getoption("--with-detector-simulators"):
return
skip = pytest.mark.skip(reason="need --with-detector-simulators option to run")
for item in items:
if "withdetectorsimulators" in item.keywords:
item.add_marker(skip)
#helper fixture for servers
@pytest.fixture
def servers(request):
try:
return request.param # comes from @pytest.mark.parametrize(..., indirect=True)
except AttributeError:
# fallback default if the test did not parametrize
return ['eiger', 'jungfrau', 'mythen3', 'gotthard2', 'ctb', 'moench', 'xilinx_ctb']
return request.param
@pytest.fixture
def test_with_simulators(servers):
""" Fixture to automatically setup virtual detector servers for testing. """
LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_PythonAPI_test'
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
with open(MAIN_LOG_FNAME, 'w') as fp:
try:
nmods = 2
for server in servers:
for ninterfaces in range(1,2):
if ninterfaces == 2 and server != 'jungfrau' and server != 'moench':
continue
msg = f'Starting Python API Tests for {server}'
if server == 'jungfrau' or server == 'moench':
msg += f' with {ninterfaces} interfaces'
Log(LogLevel.INFOBLUE, msg, fp)
cleanup(fp)
startDetectorVirtualServer(server, nmods, fp)
startReceiver(nmods, fp)
d = loadConfig(name=server, log_file_fp=fp, num_mods=nmods, num_frames=1, num_interfaces=ninterfaces)
loadBasicSettings(name=server, d=d, fp=fp)
yield # run test
cleanup(fp) # teardown
except Exception as e:
with open(MAIN_LOG_FNAME, 'a') as fp_error:
traceback.print_exc(file=fp_error)
Log(LogLevel.ERROR, f'Tests Failed.', fp)
cleanup(fp)

View File

@@ -0,0 +1,48 @@
import pytest
import sys
from conftest import test_with_simulators
from slsdet import Detector
@pytest.mark.withdetectorsimulators
@pytest.mark.parametrize("servers", [["moench"]], indirect=True)
def test_rx_ROI_moench(test_with_simulators, servers):
""" Test setting and getting rx_ROI property of Detector class for moench. """
d = Detector()
d.rx_roi = (0, 10, 10, 20)
roi = d.rx_roi
assert roi == [(0, 10, 10, 20)]
d.rx_roi = [5,15,15,25]
assert d.rx_roi == [(5,15,15,25)]
d.rx_roi = [[0,10,0,20], [5,20,410,420]]
roi = d.rx_roi
assert roi == [(0,10,0,20), (5,20,410,420)]
d.rx_clearroi()
roi = d.rx_roi
assert roi == [(-1,-1,-1,-1)]
@pytest.mark.withdetectorsimulators
@pytest.mark.parametrize("servers", [["mythen3"]], indirect=True)
def test_rx_ROI_mythen(test_with_simulators, servers):
""" Test setting and getting rx_ROI property of Detector class for mythen. """
d = Detector()
d.rx_roi = (0, 10)
roi = d.rx_roi
assert roi == [(0, 10, -1, -1)]
#d.rx_roi = [[5,15, 0, 1]] # not allowed for mythen3
d.rx_roi = [0,10, -1, -1]
assert d.rx_roi == [(0,10,-1,-1)]

View File

@@ -3,8 +3,6 @@
add_executable(using_logger using_logger.cpp) add_executable(using_logger using_logger.cpp)
target_link_libraries(using_logger target_link_libraries(using_logger
slsSupportShared slsSupportShared
pthread
rt
) )
set_target_properties(using_logger PROPERTIES set_target_properties(using_logger PROPERTIES

View File

@@ -200,9 +200,6 @@ class etaInterpolationBase : public slsInterpolation {
// virtual void prepareInterpolation(int &ok)=0; // virtual void prepareInterpolation(int &ok)=0;
void debugSaveAll(int ind = 0) { void debugSaveAll(int ind = 0) {
std::cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++SAVING ETAS"<< std::endl;
int ibx, iby; int ibx, iby;
char tit[10000]; char tit[10000];
@@ -217,21 +214,21 @@ class etaInterpolationBase : public slsInterpolation {
etah[ii] = heta[ii]; etah[ii] = heta[ii];
tot_eta += heta[ii]; tot_eta += heta[ii];
} }
sprintf(tit, "eta_%d.tiff", ind); sprintf(tit, "/scratch/eta_%d.tiff", ind);
WriteToTiff(etah, tit, nbetaX, nbetaY); WriteToTiff(etah, tit, nbetaX, nbetaY);
for (int ii = 0; ii < nbetaX * nbetaY; ii++) { for (int ii = 0; ii < nbetaX * nbetaY; ii++) {
ibb = (hhx[ii] * nSubPixelsX); ibb = (hhx[ii] * nSubPixelsX);
etah[ii] = ibb; etah[ii] = ibb;
} }
sprintf(tit, "eta_hhx_%d.tiff", ind); sprintf(tit, "/scratch/eta_hhx_%d.tiff", ind);
WriteToTiff(etah, tit, nbetaX, nbetaY); WriteToTiff(etah, tit, nbetaX, nbetaY);
for (int ii = 0; ii < nbetaX * nbetaY; ii++) { for (int ii = 0; ii < nbetaX * nbetaY; ii++) {
ibb = hhy[ii] * nSubPixelsY; ibb = hhy[ii] * nSubPixelsY;
etah[ii] = ibb; etah[ii] = ibb;
} }
sprintf(tit, "eta_hhy_%d.tiff", ind); sprintf(tit, "/scratch/eta_hhy_%d.tiff", ind);
WriteToTiff(etah, tit, nbetaX, nbetaY); WriteToTiff(etah, tit, nbetaX, nbetaY);
float *ftest = new float[nSubPixelsX * nSubPixelsY]; float *ftest = new float[nSubPixelsX * nSubPixelsY];
@@ -265,7 +262,7 @@ class etaInterpolationBase : public slsInterpolation {
<< std::endl; << std::endl;
} }
sprintf(tit, "./ftest_%d.tiff", ind); sprintf(tit, "/scratch/ftest_%d.tiff", ind);
WriteToTiff(ftest, tit, nSubPixelsX, nSubPixelsY); WriteToTiff(ftest, tit, nSubPixelsX, nSubPixelsY);
// int ibx=0, iby=0; // int ibx=0, iby=0;
@@ -283,7 +280,7 @@ class etaInterpolationBase : public slsInterpolation {
} else } else
etah[ii] = 0; etah[ii] = 0;
} }
sprintf(tit, "./eta_bad_%d.tiff", ind); sprintf(tit, "/scratch/eta_bad_%d.tiff", ind);
WriteToTiff(etah, tit, nbetaX, nbetaY); WriteToTiff(etah, tit, nbetaX, nbetaY);
// std::cout << "Index: " << ind << "\t Bad bins: "<< nbad << std::endl; // std::cout << "Index: " << ind << "\t Bad bins: "<< nbad << std::endl;
// int ibx=0, iby=0; // int ibx=0, iby=0;

View File

@@ -1,232 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#ifndef ETA_INTERPOLATION_POSXY_H
#define ETA_INTERPOLATION_POSXY_H
//#define SAVE_ALL
//#include "sls/tiffIO.h"
#include "eta2InterpolationBase.h"
#include "eta3InterpolationBase.h"
#include "etaInterpolationBase.h"
class etaInterpolationRosenblatt : public virtual etaInterpolationBase {
public:
etaInterpolationRosenblatt(int nx = 400, int ny = 400, int ns = 25, int nsy = 25,
int nb = -1, int nby = -1, double emin = 1,
double emax = 0)
: etaInterpolationBase(nx, ny, ns, nsy, nb, nby, emin, emax){
// std::cout << "epxy " << nb << " " << emin << " " << emax << std::endl;
// std::cout << nbeta << " " << etamin << " " << etamax << std::endl;
};
etaInterpolationRosenblatt(etaInterpolationRosenblatt *orig)
: etaInterpolationBase(orig){};
virtual etaInterpolationRosenblatt *Clone() = 0; /* { */
/* return new etaInterpolationPosXY(this); */
/* }; */
virtual void prepareInterpolation(int &ok) {
ok = 1;
///*Eta Distribution Rebinning*///
// double bsize=1./nSubPixels; //precision
// std::cout<<"nPixelsX = "<<nPixelsX<<" nPixelsY = "<<nPixelsY<<" nSubPixels
// = "<<nSubPixels<<endl;
double tot_eta = 0;
double tot_eta_x = 0;
double tot_eta_y = 0;
for (int ip = 0; ip < nbetaX * nbetaY; ip++)
tot_eta += heta[ip];
std::cout << "total eta entries is :" << tot_eta << std::endl;
if (tot_eta <= 0) {
ok = 0;
return;
};
double *hx = new double[nbetaX]; // profile x
double *hy = new double[nbetaY]; // profile y
double *hix = new double[nbetaX]; // integral of projection x
double *hiy = new double[nbetaY]; // integral of projection y
// int ii=0;
double etax, etay;
for (int ib = 0; ib < nbetaX; ib++) {
// tot_eta_y=0;
for (int iby = 0; iby < nbetaY; iby++) {
etay = etamin + iby * etastepY;
// std::cout << etax << std::endl;
// tot_eta_x+=hx[iby];
if (etay >= 0 && etay <= 1)
hy[iby] = heta[ib + iby * nbetaX];
else
hy[iby] = 0;
// tot_eta_y+=hy[iby];
}
hiy[0] = hy[0];
for (int iby = 1; iby < nbetaY; iby++) {
hiy[iby] = hiy[iby - 1] + hy[iby];
}
tot_eta_y = hiy[nbetaY - 1] + 1;
for (int iby = 0; iby < nbetaY; iby++) {
if (tot_eta_y <= 0) {
hhy[ib + iby * nbetaX] = -1;
// ii=(ibx*nSubPixels)/nbeta;
} else {
// if (hiy[ibx]>tot_eta_y*(ii+1)/nSubPixels) ii++;
hhy[ib + iby * nbetaX] = hiy[iby] / tot_eta_y;
}
}
}
for (int ib = 0; ib < nbetaY; ib++) {
for (int ibx = 0; ibx < nbetaX; ibx++) {
etax = etamin + ibx * etastepX;
// std::cout << etax << std::endl;
if (etax >= 0 && etax <= 1)
hx[ibx] = heta[ibx + ib * nbetaX];
else {
hx[ibx] = 0;
}
}
hix[0] = hx[0];
for (int ibx = 1; ibx < nbetaX; ibx++) {
hix[ibx] = hix[ibx - 1] + hx[ibx];
}
// tot_eta_x = hix[nbetaX - 1] + 1;
for (int ibx = 0; ibx < nbetaX; ibx++) {
//if (tot_eta_x <= 0) {
// hhx[ibx + ib * nbetaX] = -1;
// } else {
hhx[ibx + ib * nbetaX] = hix[ibx];// / tot_eta_x;
//}
}
}
for (int ibx = 0; ibx < nbetaX; ibx++) {
int val=0;
for (int ib = 0; ib < nbetaY; ib++) {
val+=hhx[ibx + ib * nbetaX];
}
// for (int ibx = 0; ibx < nbetaX; ibx++) {
for (int ib = 0; ib < nbetaY; ib++) {
hhx[ibx + ib * nbetaX]=val;
}
}
tot_eta_x = hhx[nbetaX - 1] + 1;
for (int ib = 0; ib < nbetaY; ib++) {
//tot_eta_x = hix[nbetaX - 1] + 1;
for (int ibx = 0; ibx < nbetaX; ibx++) {
if (tot_eta_x <= 0) {
hhx[ibx + ib * nbetaX] = -1;
} else {
hhx[ibx + ib * nbetaX] = hhx[ibx + ib * nbetaX] / tot_eta_x;
}
}
}
/*
int ibx, iby, ib;
iby = 0;
while (hhx[iby * nbetaY + nbetaY / 2] < 0)
iby++;
for (ib = 0; ib < iby; ib++) {
for (ibx = 0; ibx < nbetaX; ibx++)
hhx[ibx + nbetaX * ib] = hhx[ibx + nbetaX * iby];
}
iby = nbetaY - 1;
while (hhx[iby * nbetaY + nbetaY / 2] < 0)
iby--;
for (ib = iby + 1; ib < nbetaY; ib++) {
for (ibx = 0; ibx < nbetaX; ibx++)
hhx[ibx + nbetaX * ib] = hhx[ibx + nbetaX * iby];
}
iby = 0;
while (hhy[nbetaX / 2 * nbetaX + iby] < 0)
iby++;
for (ib = 0; ib < iby; ib++) {
for (ibx = 0; ibx < nbetaY; ibx++)
hhy[ib + nbetaX * ibx] = hhy[iby + nbetaX * ibx];
}
iby = nbetaX - 1;
while (hhy[nbetaX / 2 * nbetaX + iby] < 0)
iby--;
for (ib = iby + 1; ib < nbetaX; ib++) {
for (ibx = 0; ibx < nbetaY; ibx++)
hhy[ib + nbetaX * ibx] = hhy[iby + nbetaX * ibx];
}
*/
//#ifdef SAVE_ALL
debugSaveAll();
//#endif
delete[] hx;
delete[] hy;
delete[] hix;
delete[] hiy;
return;
}
};
class eta2InterpolationRosenblatt : public virtual eta2InterpolationBase,
public virtual etaInterpolationRosenblatt {
public:
eta2InterpolationRosenblatt(int nx = 400, int ny = 400, int ns = 25,
int nsy = 25, int nb = -1, int nby = -1,
double emin = 1, double emax = 0)
: etaInterpolationBase(nx, ny, ns, nsy, nb, nby, emin, emax),
eta2InterpolationBase(nx, ny, ns, nsy, nb, nby, emin, emax),
etaInterpolationRosenblatt(nx, ny, ns, nsy, nb, nby, emin, emax){
// std::cout << "e2pxy " << nb << " " << emin << " " << emax << std::endl;
};
eta2InterpolationRosenblatt(eta2InterpolationRosenblatt *orig)
: etaInterpolationBase(orig), etaInterpolationRosenblatt(orig){};
virtual eta2InterpolationRosenblatt *Clone() {
return new eta2InterpolationRosenblatt(this);
};
};
class eta3InterpolationRosenblatt : public virtual eta3InterpolationBase,
public virtual etaInterpolationRosenblatt {
public:
eta3InterpolationRosenblatt(int nx = 400, int ny = 400, int ns = 25,
int nsy = 25, int nb = -1, int nby = -1,
double emin = 1, double emax = 0)
: etaInterpolationBase(nx, ny, ns, nsy, nb, nby, emin, emax),
eta3InterpolationBase(nx, ny, ns, nsy, nb, nby, emin, emax),
etaInterpolationRosenblatt(nx, ny, ns, nsy, nb, nby, emin, emax){
// std::cout << "e3pxy " << nbeta << " " << etamin << " " << etamax
// << " " << nSubPixels<< std::endl;
};
eta3InterpolationRosenblatt(eta3InterpolationRosenblatt *orig)
: etaInterpolationBase(orig), etaInterpolationRosenblatt(orig){};
virtual eta3InterpolationRosenblatt *Clone() {
return new eta3InterpolationRosenblatt(this);
};
};
#endif

View File

@@ -76,11 +76,8 @@ foreach(exe ${JUNGFRAU_EXECUTABLES})
target_link_libraries(${exe} target_link_libraries(${exe}
PUBLIC PUBLIC
slsSupportStatic slsSupportStatic
pthread
tiffio tiffio
fmt::fmt fmt::fmt
#-L/usr/lib64/
#-lm -lstdc++ -lrt
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings

View File

@@ -69,7 +69,6 @@ foreach(exe ${MOENCH_EXECUTABLES})
PUBLIC PUBLIC
slsSupportStatic slsSupportStatic
${ZeroMQ_LIBRARIES} ${ZeroMQ_LIBRARIES}
pthread
tiffio tiffio
PRIVATE PRIVATE

View File

@@ -17,7 +17,7 @@
#endif #endif
//#include "etaInterpolationPosXY.h" //#include "etaInterpolationPosXY.h"
#include "etaInterpolationRosenblatt.h" #include "etaInterpolationPosXY.h"
#include "noInterpolation.h" #include "noInterpolation.h"
//#include "etaInterpolationCleverAdaptiveBins.h" //#include "etaInterpolationCleverAdaptiveBins.h"
//#include "etaInterpolationRandomBins.h" //#include "etaInterpolationRandomBins.h"
@@ -114,8 +114,8 @@ int main(int argc, char *argv[]) {
//int f0 = -1; //int f0 = -1;
// int nSubPixels = nsubpix; // int nSubPixels = nsubpix;
#ifndef NOINTERPOLATION #ifndef NOINTERPOLATION
eta2InterpolationRosenblatt *interp = eta2InterpolationPosXY *interp =
new eta2InterpolationRosenblatt(NC, NR, nsubpix, nsubpix, etabins, etabins, etamin, etamax); new eta2InterpolationPosXY(NC, NR, nsubpix, nsubpix, etabins, etabins, etamin, etamax);
// eta2InterpolationCleverAdaptiveBins *interp=new // eta2InterpolationCleverAdaptiveBins *interp=new
// eta2InterpolationCleverAdaptiveBins(NC, NR, nsubpix, etabins, etamin, // eta2InterpolationCleverAdaptiveBins(NC, NR, nsubpix, etabins, etamin,
// etamax); // etamax);
@@ -134,7 +134,6 @@ int main(int argc, char *argv[]) {
cout << "read ff " << argv[2] << endl; cout << "read ff " << argv[2] << endl;
sprintf(fname, "%s", argv[2]); sprintf(fname, "%s", argv[2]);
interp->readFlatField(fname); interp->readFlatField(fname);
interp->prepareInterpolation(ok); //, MAX_ITERATIONS); interp->prepareInterpolation(ok); //, MAX_ITERATIONS);
#endif #endif
// return 0; // return 0;

View File

@@ -174,7 +174,6 @@ int main(int argc, char *argv[]) {
int nped = 1000; int nped = 1000;
int cf = 0; int cf = 0;
int numberOfPackets=nrows/8; int numberOfPackets=nrows/8;
#ifdef RECT #ifdef RECT
cout << "Should be rectangular but now it will crash! No data structure defined!" << endl; cout << "Should be rectangular but now it will crash! No data structure defined!" << endl;
@@ -182,7 +181,7 @@ int main(int argc, char *argv[]) {
#ifndef MOENCH04 #ifndef MOENCH04
moench03v2Data *decoder = new moench03v2Data(nrows/2); moench03v2Data *decoder = new moench03v2Data(nrows/2);
cout << "MOENCH03 V2!" << endl; cout << "MOENCH03!" << endl;
#endif #endif
#ifdef MOENCH04 #ifdef MOENCH04
@@ -299,7 +298,7 @@ int main(int argc, char *argv[]) {
double *ped=new double[nx * ny];//, *ped1; double *ped=new double[nx * ny];//, *ped1;
int pos,pos1; int pos,pos1;
//return 0; //return 0;
if (pedfile.find(".raw") != std::string::npos) { if (pedfile.find(".raw") != std::string::npos) {
pos1=pedfile.rfind("/"); pos1=pedfile.rfind("/");
strcpy(froot,pedfile.substr(pos1).c_str()); strcpy(froot,pedfile.substr(pos1).c_str());
@@ -310,7 +309,6 @@ int main(int argc, char *argv[]) {
cout << "PEDESTAL " << endl; cout << "PEDESTAL " << endl;
if (pedfile.find(".tif") == std::string::npos) { if (pedfile.find(".tif") == std::string::npos) {
sprintf(fname, "%s", pedfile.c_str()); sprintf(fname, "%s", pedfile.c_str());
cout << fname << endl; cout << fname << endl;
std::time(&end_time); std::time(&end_time);
//cout << "aaa" << std::ctime(&end_time) << endl; //cout << "aaa" << std::ctime(&end_time) << endl;
@@ -322,28 +320,24 @@ int main(int argc, char *argv[]) {
if (filebin.is_open()) { if (filebin.is_open()) {
ff = -1; ff = -1;
while (decoder->readNextFrame(filebin, ff, np, buff)) { while (decoder->readNextFrame(filebin, ff, np, buff)) {
if (np == numberOfPackets) { if (np == numberOfPackets) {
mt->pushData(buff); mt->pushData(buff);
mt->nextThread(); mt->nextThread();
mt->popFree(buff); mt->popFree(buff);
ifr++; ifr++;
if (ifr % 100 == 0) if (ifr % 100 == 0)
cout << ifr << " " << ff << " " << np << endl; cout << ifr << " " << ff << " " << np << endl;
// break; // break;
} else { } else {
cout << "bp "<< ifr << " " << ff << " " << np << endl; cout << ifr << " " << ff << " " << np << endl;
break; break;
} }
ff = -1; ff = -1;
} }
filebin.close(); filebin.close();
while (mt->isBusy()) { while (mt->isBusy()) {
;
; }
}
sprintf(imgfname, "%s/%s_ped.tiff", outdir.c_str(),froot); sprintf(imgfname, "%s/%s_ped.tiff", outdir.c_str(),froot);
mt->writePedestal(imgfname); mt->writePedestal(imgfname);
@@ -388,7 +382,7 @@ int main(int argc, char *argv[]) {
runmax--; runmax--;
flist.close(); flist.close();
cout << "Found " << runmax << " files " << endl; cout << "Found " << runmax << " files " << endl;
flist.open (args["flist"].c_str(), std::ifstream::in); flist.open (fformat, std::ifstream::in);
} }
for (int irun = runmin; irun <= runmax; irun++) { for (int irun = runmin; irun <= runmax; irun++) {
@@ -441,7 +435,6 @@ int main(int argc, char *argv[]) {
ff = -1; ff = -1;
ifr = 0; ifr = 0;
while (decoder->readNextFrame(filebin, ff, np, buff)) { while (decoder->readNextFrame(filebin, ff, np, buff)) {
if (np == numberOfPackets) { if (np == numberOfPackets) {
// //push // //push
mt->pushData(buff); mt->pushData(buff);
@@ -469,19 +462,8 @@ int main(int argc, char *argv[]) {
} }
} else { } else {
cout << "bp " << ifr << " " << ff << " " << np << endl; cout << "bp " << ifr << " " << ff << " " << np << endl;
} }
ff = -1; ff = -1;
if (ifr % 100 == 0){
sprintf(imgfname, "%s/%s_f%05d_ped.tiff", outdir.c_str(),froot, ifile++);
while (mt->isBusy()) {
;
}
mt->writePedestal(imgfname);
}
} }
cout << "--" << endl; cout << "--" << endl;
filebin.close(); filebin.close();

View File

@@ -37,7 +37,9 @@ target_compile_definitions(ctbDetectorServer_virtual
) )
target_link_libraries(ctbDetectorServer_virtual target_link_libraries(ctbDetectorServer_virtual
PUBLIC pthread rt m slsProjectCSettings PUBLIC
m
slsProjectCSettings
) )
set_target_properties(ctbDetectorServer_virtual PROPERTIES set_target_properties(ctbDetectorServer_virtual PROPERTIES

View File

@@ -30,7 +30,8 @@ target_compile_definitions(eigerDetectorServer_virtual
) )
target_link_libraries(eigerDetectorServer_virtual target_link_libraries(eigerDetectorServer_virtual
PUBLIC pthread rt slsProjectCSettings PUBLIC
slsProjectCSettings
) )
set_target_properties(eigerDetectorServer_virtual PROPERTIES set_target_properties(eigerDetectorServer_virtual PROPERTIES

View File

@@ -31,7 +31,8 @@ target_compile_definitions(gotthard2DetectorServer_virtual
) )
target_link_libraries(gotthard2DetectorServer_virtual target_link_libraries(gotthard2DetectorServer_virtual
PUBLIC pthread rt slsProjectCSettings PUBLIC
slsProjectCSettings
) )
set_target_properties(gotthard2DetectorServer_virtual PROPERTIES set_target_properties(gotthard2DetectorServer_virtual PROPERTIES

View File

@@ -29,7 +29,8 @@ target_compile_definitions(jungfrauDetectorServer_virtual
) )
target_link_libraries(jungfrauDetectorServer_virtual target_link_libraries(jungfrauDetectorServer_virtual
PUBLIC pthread rt slsProjectCSettings PUBLIC
slsProjectCSettings
) )
set_target_properties(jungfrauDetectorServer_virtual PROPERTIES set_target_properties(jungfrauDetectorServer_virtual PROPERTIES

View File

@@ -29,7 +29,8 @@ target_compile_definitions(moenchDetectorServer_virtual
) )
target_link_libraries(moenchDetectorServer_virtual target_link_libraries(moenchDetectorServer_virtual
PUBLIC pthread rt slsProjectCSettings PUBLIC
slsProjectCSettings
) )
set_target_properties(moenchDetectorServer_virtual PROPERTIES set_target_properties(moenchDetectorServer_virtual PROPERTIES

View File

@@ -33,7 +33,8 @@ target_compile_definitions(mythen3DetectorServer_virtual
) )
target_link_libraries(mythen3DetectorServer_virtual target_link_libraries(mythen3DetectorServer_virtual
PUBLIC pthread rt slsProjectCSettings PUBLIC
slsProjectCSettings
) )
set_target_properties(mythen3DetectorServer_virtual PROPERTIES set_target_properties(mythen3DetectorServer_virtual PROPERTIES

View File

@@ -31,7 +31,9 @@ target_compile_definitions(xilinx_ctbDetectorServer_virtual
) )
target_link_libraries(xilinx_ctbDetectorServer_virtual target_link_libraries(xilinx_ctbDetectorServer_virtual
PUBLIC pthread rt m slsProjectCSettings PUBLIC
m
slsProjectCSettings
) )
set_target_properties(xilinx_ctbDetectorServer_virtual PROPERTIES set_target_properties(xilinx_ctbDetectorServer_virtual PROPERTIES

View File

@@ -1,5 +1,5 @@
# Prepare MH02 configuration # Prepare MH02 configuration
reg 0xC00C 0x00000041 reg 0xC00C 0x00040041
reg 0xC010 0x01200004 reg 0xC010 0x01200004
# configure Matterhorn SPI # configure Matterhorn SPI
@@ -14,7 +14,7 @@ reg 0xC120 0x1
reg 0xC120 0x0 reg 0xC120 0x0
# set MSB LSB inversions and polarity for transceiver # set MSB LSB inversions and polarity for transceiver
reg 0xC120 0x61e0 reg 0xC120 0x1e0
# Enable MH02 PLL clock # Enable MH02 PLL clock
pattern enable_clock_pattern.pyat pattern enable_clock_pattern.pyat

View File

@@ -1,7 +1,7 @@
# turn off clock # turn off clock
setbit 0xC00C 16 clearbit 0xB018 15
setbit 0xC014 0 setbit 0xB010 15
sleep 1 sleep 1
# reset Matterhorn periphery # reset Matterhorn periphery
@@ -9,8 +9,7 @@ setbit 0xC014 1
sleep 1 sleep 1
# turn on clock # turn on clock
clearbit 0xC00C 16 clearbit 0xB010 15
setbit 0xC014 0
sleep 1 sleep 1
# reset rx transceiver datapath # reset rx transceiver datapath

View File

@@ -28,11 +28,11 @@ target_link_libraries(slsDetectorObject
PUBLIC PUBLIC
slsProjectOptions slsProjectOptions
slsSupportStatic slsSupportStatic
pthread
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings
) )
set(DETECTOR_LIBRARY_TARGETS slsDetectorObject) set(DETECTOR_LIBRARY_TARGETS slsDetectorObject)
@@ -97,8 +97,7 @@ if(SLS_USE_TEXTCLIENT)
add_executable(${val1} src/CmdApp.cpp) add_executable(${val1} src/CmdApp.cpp)
target_link_libraries(${val1} target_link_libraries(${val1}
slsDetectorStatic slsDetectorStatic
pthread
) )
SET_SOURCE_FILES_PROPERTIES( src/Caller.cpp PROPERTIES COMPILE_FLAGS "-Wno-unused-variable -Wno-unused-but-set-variable") SET_SOURCE_FILES_PROPERTIES( src/Caller.cpp PROPERTIES COMPILE_FLAGS "-Wno-unused-variable -Wno-unused-but-set-variable")

View File

@@ -2568,17 +2568,15 @@ std::vector<int> Module::getReceiverDbitList() const {
void Module::setReceiverDbitList(std::vector<int> list) { void Module::setReceiverDbitList(std::vector<int> list) {
LOG(logDEBUG1) << "Setting Receiver Dbit List"; LOG(logDEBUG1) << "Setting Receiver Dbit List";
if (list.size() > 64) {
throw RuntimeError("Dbit list size cannot be greater than 64\n");
}
for (auto &it : list) { for (auto &it : list) {
if (it < 0 || it > 63) { if (it < 0 || it > 63) {
throw RuntimeError("Dbit list value must be between 0 and 63\n"); throw RuntimeError("Dbit list value must be between 0 and 63\n");
} }
} }
std::sort(begin(list), end(list)); auto r = stableRemoveDuplicates(list);
auto last = std::unique(begin(list), end(list)); if(r)
list.erase(last, list.end()); LOG(logWARNING) << "Removed duplicated from receiver dbit list";
StaticVector<int, MAX_RX_DBIT> arg = list; StaticVector<int, MAX_RX_DBIT> arg = list;
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr); sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);

View File

@@ -49,7 +49,7 @@ target_link_libraries(slsReceiverObject
slsProjectOptions slsProjectOptions
slsSupportStatic slsSupportStatic
PRIVATE PRIVATE
slsProjectWarnings #don't propagate warnigns slsProjectWarnings #don't propagate warnings
) )
target_compile_definitions(slsReceiverObject target_compile_definitions(slsReceiverObject
@@ -118,8 +118,6 @@ if (SLS_USE_RECEIVER_BINARIES)
target_link_libraries(slsReceiver PUBLIC target_link_libraries(slsReceiver PUBLIC
PUBLIC PUBLIC
slsReceiverStatic slsReceiverStatic
pthread
rt
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings
) )
@@ -138,8 +136,6 @@ if (SLS_USE_RECEIVER_BINARIES)
target_link_libraries(slsMultiReceiver target_link_libraries(slsMultiReceiver
PUBLIC PUBLIC
slsReceiverStatic slsReceiverStatic
pthread
rt
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings
) )
@@ -158,8 +154,6 @@ if (SLS_USE_RECEIVER_BINARIES)
target_link_libraries(slsFrameSynchronizer target_link_libraries(slsFrameSynchronizer
PUBLIC PUBLIC
slsReceiverStatic slsReceiverStatic
pthread
rt
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings

View File

@@ -138,7 +138,8 @@ TEST_CASE("Parse version and help", "[detector]") {
} }
} }
TEST_CASE("Parse port and uid", "[detector]") { // TODO: fails on gitea CI due to uid issue, fix later
TEST_CASE("Parse port and uid", "[.failsongitea][detector]") {
uid_t uid = getuid(); uid_t uid = getuid();
std::string uidStr = std::to_string(uid); std::string uidStr = std::to_string(uid);
uid_t invalidUid = uid + 1000; uid_t invalidUid = uid + 1000;
@@ -147,8 +148,12 @@ TEST_CASE("Parse port and uid", "[detector]") {
for (auto app : {AppType::SingleReceiver, AppType::MultiReceiver, for (auto app : {AppType::SingleReceiver, AppType::MultiReceiver,
AppType::FrameSynchronizer}) { AppType::FrameSynchronizer}) {
CommandLineOptions s(app); CommandLineOptions s(app);
REQUIRE_THROWS(
s.parse({"", "-p", "1234", "-u", invalidUidStr})); // invalid uid // TODO! This test fails on gitea CI probably because the user can set the uid
// commenting it out for now. Revisit later.
// REQUIRE_THROWS(
// s.parse({"", "-p", "1234", "-u", invalidUidStr})); // invalid uid
REQUIRE_THROWS(s.parse({"", "-p", "500"})); // invalid port REQUIRE_THROWS(s.parse({"", "-p", "500"})); // invalid port
auto opts = s.parse({"", "-p", "1234", "-u", uidStr}); auto opts = s.parse({"", "-p", "1234", "-u", uidStr});

View File

@@ -64,7 +64,8 @@ class DataProcessorTest : public DataProcessor {
* num_transceiver_bytes = 2 both bytes have a value of 125 * num_transceiver_bytes = 2 both bytes have a value of 125
* num_digital_bytes is variable and is defined by number of samples * num_digital_bytes is variable and is defined by number of samples
* default num sample is 5 * default num sample is 5
* all bytes in digital data take a value of 255 * all bytes in digital data take a value of 0xFF (alternating bits between 0,
* 1)
*/ */
class DataProcessorTestFixture { class DataProcessorTestFixture {
public: public:
@@ -106,7 +107,7 @@ class DataProcessorTestFixture {
num_random_offset_bytes); num_random_offset_bytes);
} }
void set_data() { void set_data(const std::bitset<8> pattern = 0xFF) {
delete[] data; delete[] data;
uint64_t max_bytes_per_bit = uint64_t max_bytes_per_bit =
num_samples % 8 == 0 ? num_samples / 8 : num_samples / 8 + 1; num_samples % 8 == 0 ? num_samples / 8 : num_samples / 8 + 1;
@@ -118,7 +119,8 @@ class DataProcessorTestFixture {
memset(data, dummy_value, num_analog_bytes); // set to dummy value memset(data, dummy_value, num_analog_bytes); // set to dummy value
memset(data + num_analog_bytes, 0, memset(data + num_analog_bytes, 0,
num_random_offset_bytes); // set to zero num_random_offset_bytes); // set to zero
memset(data + num_analog_bytes + num_random_offset_bytes, 0xFF, memset(data + num_analog_bytes + num_random_offset_bytes,
static_cast<uint8_t>(pattern.to_ulong()),
num_digital_bytes); // all digital bits are one num_digital_bytes); // all digital bits are one
memset(data + num_digital_bytes + num_analog_bytes + memset(data + num_digital_bytes + num_analog_bytes +
num_random_offset_bytes, num_random_offset_bytes,
@@ -170,7 +172,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Remove Trailing Bits",
TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all", TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all",
"[.dataprocessor][.reorder]") { "[.dataprocessor][.reorder]") {
// parameters: num_samples, expected_num_digital_bytes, // parameters: num_samples, expected_num_digital_bytes,
// expected_digital_part // expected_digital_part_for_each_bit
auto parameters = GENERATE( auto parameters = GENERATE(
std::make_tuple(5, 64, std::vector<uint8_t>{0b00011111}), std::make_tuple(5, 64, std::vector<uint8_t>{0b00011111}),
std::make_tuple(10, 2 * 64, std::vector<uint8_t>{0xFF, 0b00000011}), std::make_tuple(10, 2 * 64, std::vector<uint8_t>{0xFF, 0b00000011}),
@@ -264,11 +266,13 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false",
// expected_digital_part // expected_digital_part
auto parameters = GENERATE( auto parameters = GENERATE(
std::make_tuple(5, std::vector<int>{1, 4, 5}, 5, std::make_tuple(5, std::vector<int>{1, 4, 5}, 5,
std::vector<uint8_t>{0b00000111}), std::vector<uint8_t>{0b00000010}),
std::make_tuple(5, std::vector<int>{1, 5, 4}, 5,
std::vector<uint8_t>{0b00000100}),
std::make_tuple(5, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60, 39}, 10, std::make_tuple(5, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60, 39}, 10,
std::vector<uint8_t>{0xFF, 0b00000001}), std::vector<uint8_t>{0b11110000, 0b00000000}),
std::make_tuple(5, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60}, 5, std::make_tuple(5, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60}, 5,
std::vector<uint8_t>{0xFF})); std::vector<uint8_t>{0b11110000}));
size_t num_samples, expected_num_digital_bytes; size_t num_samples, expected_num_digital_bytes;
std::vector<uint8_t> expected_digital_part; std::vector<uint8_t> expected_digital_part;
@@ -281,7 +285,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false",
generaldata->SetCtbDbitReorder(false); generaldata->SetCtbDbitReorder(false);
set_num_samples(num_samples); set_num_samples(num_samples);
set_data(); set_data(0b01010101); // set digital data to 0x55 to have alternating bits
size_t expected_size = size_t expected_size =
num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes;
@@ -316,11 +320,15 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true",
// expected_digital_part // expected_digital_part
auto parameters = GENERATE( auto parameters = GENERATE(
std::make_tuple(5, std::vector<int>{1, 4, 5}, 3, std::make_tuple(5, std::vector<int>{1, 4, 5}, 3,
std::vector<uint8_t>{0b00011111}), std::vector<uint8_t>{0x00, 0b00011111, 0x00}),
std::make_tuple(5, std::vector<int>{1, 5, 4}, 3,
std::vector<uint8_t>{0x00, 0x00, 0b00011111}),
std::make_tuple(10, std::vector<int>{1, 4, 5}, 6, std::make_tuple(10, std::vector<int>{1, 4, 5}, 6,
std::vector<uint8_t>{0xFF, 0b00000011}), std::vector<uint8_t>{0x00, 0x00, 0b11111111, 0b00000011,
0x00, 0x00}),
std::make_tuple(8, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60, 39}, 9, std::make_tuple(8, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60, 39}, 9,
std::vector<uint8_t>{0xFF})); std::vector<uint8_t>{0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0x00}));
size_t num_samples, expected_num_digital_bytes; size_t num_samples, expected_num_digital_bytes;
std::vector<uint8_t> expected_digital_part; std::vector<uint8_t> expected_digital_part;
@@ -333,7 +341,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true",
generaldata->SetCtbDbitReorder(true); generaldata->SetCtbDbitReorder(true);
set_num_samples(num_samples); set_num_samples(num_samples);
set_data(); set_data(0b01010101);
size_t expected_size = size_t expected_size =
num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes;
@@ -343,11 +351,8 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true",
memset(expected_data, dummy_value, num_analog_bytes); memset(expected_data, dummy_value, num_analog_bytes);
for (size_t sample = 0; sample < bitlist.size(); ++sample) { memcpy(expected_data + num_analog_bytes, expected_digital_part.data(),
memcpy(expected_data + num_analog_bytes + expected_digital_part.size());
expected_digital_part.size() * sample,
expected_digital_part.data(), expected_digital_part.size());
}
memset(expected_data + expected_num_digital_bytes + num_analog_bytes, memset(expected_data + expected_num_digital_bytes + num_analog_bytes,
dummy_value, num_transceiver_bytes); dummy_value, num_transceiver_bytes);

View File

@@ -1,5 +1,8 @@
# SPDX-License-Identifier: LGPL-3.0-or-other # SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package # Copyright (C) 2021 Contributors to the SLS Detector Package
set(SOURCES set(SOURCES
src/string_utils.cpp src/string_utils.cpp
src/file_utils.cpp src/file_utils.cpp
@@ -89,12 +92,17 @@ target_link_libraries(slsSupportObject
PUBLIC PUBLIC
slsProjectOptions slsProjectOptions
${STD_FS_LIB} # from helpers.cmake ${STD_FS_LIB} # from helpers.cmake
Threads::Threads # slsDetector and Receiver need this
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings
md5sls md5sls
) )
#RH8 glibc 2.28, RH9 glibc 2.34 linking rt is only needed with glibc < 2.34
#but we do it for all Linux builds to avoid too many conditionals
target_link_libraries (slsSupportObject PUBLIC $<$<PLATFORM_ID:Linux>:rt>)
#Treat both vendored and system zmq as interface for receiver binaries #Treat both vendored and system zmq as interface for receiver binaries
if(SLS_USE_SYSTEM_ZMQ) if(SLS_USE_SYSTEM_ZMQ)
message(STATUS "slsSupportLib using ZEROMQ_TARGET=${ZEROMQ_TARGET}") message(STATUS "slsSupportLib using ZEROMQ_TARGET=${ZEROMQ_TARGET}")

View File

@@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
#include <numeric> #include <numeric>
#include <set>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
@@ -155,6 +156,10 @@ template <typename Container> bool hasDuplicates(Container c) {
return pos != c.end(); // if we found something there are duplicates return pos != c.end(); // if we found something there are duplicates
} }
/**
* @brief Sorts the container and removes duplicated elements
* returns true if elements were removed otherwiese false
*/
template <typename T> template <typename T>
typename std::enable_if<is_container<T>::value, bool>::type typename std::enable_if<is_container<T>::value, bool>::type
removeDuplicates(T &c) { removeDuplicates(T &c) {
@@ -167,6 +172,29 @@ removeDuplicates(T &c) {
return false; return false;
} }
/**
* @brief Removed duplicated entries while preserving the oder
* returns true if elements were removed otherwiese false
*/
template <typename T>
typename std::enable_if<is_container<T>::value, bool>::type
stableRemoveDuplicates(T &c) {
auto containerSize = c.size();
std::set<typename T::value_type> seen;
c.erase(
std::remove_if(c.begin(), c.end(),
[&](const typename T::value_type& val) {
return !seen.insert(val).second; // erase if already seen
}),
c.end()
);
if (c.size() != containerSize) {
return true;
}
return false;
}
} // namespace sls } // namespace sls
#endif // CONTAINER_UTILS_H #endif // CONTAINER_UTILS_H

View File

@@ -16,6 +16,7 @@ namespace sls {
* @param nch number of channels * @param nch number of channels
* @param offset start channel value * @param offset start channel value
*/ */
[[deprecated]]
int readDataFile(std::ifstream &infile, short int *data, int nch, int readDataFile(std::ifstream &infile, short int *data, int nch,
int offset = 0); int offset = 0);
@@ -23,6 +24,7 @@ int readDataFile(std::ifstream &infile, short int *data, int nch,
* @param data array of data value * @param data array of data value
* @param nch number of channels * @param nch number of channels
*/ */
[[deprecated]]
int readDataFile(std::string fname, short int *data, int nch); int readDataFile(std::string fname, short int *data, int nch);
std::vector<char> readBinaryFile(const std::string &fname, std::vector<char> readBinaryFile(const std::string &fname,
@@ -33,6 +35,7 @@ std::vector<char> readBinaryFile(const std::string &fname,
* @param data array of data values * @param data array of data values
* @param offset start channel number * @param offset start channel number
*/ */
[[deprecated]]
int writeDataFile(std::ofstream &outfile, int nch, short int *data, int writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset = 0); int offset = 0);
@@ -40,6 +43,7 @@ int writeDataFile(std::ofstream &outfile, int nch, short int *data,
* @param nch number of channels * @param nch number of channels
* @param data array of data values * @param data array of data values
*/ */
[[deprecated]]
int writeDataFile(std::string fname, int nch, short int *data); int writeDataFile(std::string fname, int nch, short int *data);
// mkdir -p path implemented by recursive calls // mkdir -p path implemented by recursive calls

View File

@@ -153,13 +153,35 @@ TEST_CASE("check for duplicates in vector of pairs") {
REQUIRE(hasDuplicates(vec) == true); REQUIRE(hasDuplicates(vec) == true);
} }
TEST_CASE("remove duplicates from vector") { TEST_CASE("sorts the vector and remove duplicates") {
std::vector<int> v{5, 6, 5, 3}; std::vector<int> v{5, 6, 5, 3};
auto r = removeDuplicates(v); auto r = removeDuplicates(v);
CHECK(r == true); // did indeed remove elements CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<int>{3, 5, 6}); CHECK(v == std::vector<int>{3, 5, 6});
} }
TEST_CASE("remove duplicates but keep order") {
std::vector<int> v{5, 6, 5, 3};
auto r = stableRemoveDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<int>{5, 6, 3});
}
TEST_CASE("remove duplicates but keep order, all elements the same ") {
std::vector<char> v{'c', 'c', 'c', 'c', 'c', 'c'};
auto r = stableRemoveDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<char>{'c'});
}
TEST_CASE("remove duplicates but keep order, pattern ") {
std::vector<int> v{8,1,2,8,8,3,2};
auto r = stableRemoveDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<int>{8,1,2,3});
}
TEST_CASE("remove duplicated empty vector") { TEST_CASE("remove duplicated empty vector") {
std::vector<int> v; std::vector<int> v;
auto r = removeDuplicates(v); auto r = removeDuplicates(v);
@@ -167,4 +189,11 @@ TEST_CASE("remove duplicated empty vector") {
CHECK(v == std::vector<int>{}); CHECK(v == std::vector<int>{});
} }
TEST_CASE("remove duplicated empty vector using stable version") {
std::vector<int> v;
auto r = stableRemoveDuplicates(v);
CHECK(r == false); // no elements to remove
CHECK(v == std::vector<int>{});
}
} // namespace sls } // namespace sls

View File

@@ -24,7 +24,6 @@ target_link_libraries(tests
PUBLIC PUBLIC
slsProjectOptions slsProjectOptions
slsSupportStatic slsSupportStatic
pthread
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings
) )

View File

@@ -113,7 +113,7 @@ def startTestsForAll(args, fp):
startDetectorVirtualServer(server, args.num_mods, fp) startDetectorVirtualServer(server, args.num_mods, fp)
startFrameSynchronizerPullSocket(server, fp) startFrameSynchronizerPullSocket(server, fp)
startFrameSynchronizer(args.num_mods, fp) startFrameSynchronizer(args.num_mods, fp)
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=args.num_mods, num_frames=args.num_frames) d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, log_file_fp=fp, num_mods=args.num_mods, num_frames=args.num_frames)
loadBasicSettings(name=server, d=d, fp=fp) loadBasicSettings(name=server, d=d, fp=fp)
acquire(fp, d) acquire(fp, d)
testFramesCaught(server, d, args.num_frames) testFramesCaught(server, d, args.num_frames)

View File

@@ -18,9 +18,11 @@ from utils_for_test import (
RuntimeException, RuntimeException,
cleanup, cleanup,
startProcessInBackground, startProcessInBackground,
startReceiver,
startDetectorVirtualServer, startDetectorVirtualServer,
connectToVirtualServers, connectToVirtualServers,
loadBasicSettings, loadBasicSettings,
loadConfig,
runProcessWithLogFile runProcessWithLogFile
) )
@@ -28,45 +30,6 @@ LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_roi_test'
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt' MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
ROI_TEST_FNAME = LOG_PREFIX_FNAME + '_results_' 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'
d.powerchip = 1
d.frames = 5
except Exception as e:
raise RuntimeException(f'Could not load config for {name}. Error: {str(e)}') from e
return d
def startTestsForAll(fp): def startTestsForAll(fp):
servers = [ servers = [
'eiger', 'eiger',
@@ -89,7 +52,7 @@ def startTestsForAll(fp):
cleanup(fp) cleanup(fp)
startDetectorVirtualServer(server, nmods, fp) startDetectorVirtualServer(server, nmods, fp)
startReceiver(nmods, fp) startReceiver(nmods, fp)
d = loadConfigForRoi(name=server, fp=fp, num_mods=nmods, num_interfaces=ninterfaces) d = loadConfig(name=server, log_file_fp = fp, num_mods=nmods, num_frames=5, num_interfaces=ninterfaces)
loadBasicSettings(name=server, d=d, fp=fp) loadBasicSettings(name=server, d=d, fp=fp)
fname = ROI_TEST_FNAME + server + '.txt' fname = ROI_TEST_FNAME + server + '.txt'

View File

@@ -63,7 +63,7 @@ def startCmdTestsForAll(args, fp):
cleanup(fp) cleanup(fp)
startDetectorVirtualServer(name=server, num_mods=num_mods, fp=fp) startDetectorVirtualServer(name=server, num_mods=num_mods, fp=fp)
startReceiver(num_mods, fp) startReceiver(num_mods, fp)
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=num_mods) d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, log_file_fp=fp, num_mods=num_mods)
loadBasicSettings(name=server, d=d, fp=fp) loadBasicSettings(name=server, d=d, fp=fp)
runProcessWithLogFile('Cmd Tests (' + args.markers + ') for ' + server, cmd, fp, fname) runProcessWithLogFile('Cmd Tests (' + args.markers + ') for ' + server, cmd, fp, fname)
except Exception as e: except Exception as e:

View File

@@ -16,7 +16,6 @@ SERVER_START_PORTNO=1900
init(autoreset=True) init(autoreset=True)
class LogLevel(Enum): class LogLevel(Enum):
INFO = 0 INFO = 0
INFORED = 1 INFORED = 1
@@ -193,32 +192,51 @@ def connectToVirtualServers(name, num_mods, ctb_object=False):
return d return d
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 loadConfig(name, rx_hostname, settingsdir, fp, num_mods = 1, num_frames = 1):
def loadConfig(name, rx_hostname = 'localhost', settingsdir = None, log_file_fp = None, num_mods = 1, num_frames = 1, num_interfaces = 1):
Log(LogLevel.INFO, 'Loading config') Log(LogLevel.INFO, 'Loading config')
Log(LogLevel.INFO, 'Loading config', fp) Log(LogLevel.INFO, 'Loading config', log_file_fp)
try: try:
d = connectToVirtualServers(name, num_mods) d = connectToVirtualServers(name, num_mods)
if name == 'jungfrau' or name == 'moench':
d.numinterfaces = num_interfaces
d.udp_dstport = DEFAULT_UDP_DST_PORTNO d.udp_dstport = DEFAULT_UDP_DST_PORTNO
if name == 'eiger': if name == 'eiger' or name == 'jungfrau' or name == 'moench':
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1 d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
d.rx_hostname = rx_hostname d.rx_hostname = rx_hostname
d.udp_dstip = 'auto' d.udp_dstip = 'auto'
if name != "eiger": if name != "eiger":
d.udp_srcip = 'auto' d.udp_srcip = 'auto'
if name == "jungfrau" or name == "moench":
d.udp_dstip2 = 'auto'
if name == "jungfrau" or name == "moench" or name == "xilinx_ctb": if name == "jungfrau" or name == "moench" or name == "xilinx_ctb":
d.powerchip = 1 d.powerchip = 1
if name == "xilinx_ctb": if name == "xilinx_ctb":
d.configureTransceiver() d.configureTransceiver()
if name == "eiger": if settingsdir is not None and name in ['eiger', 'mythen3']:
d.trimen = [4500, 5400, 6400] d.settingspath = settingsdir + '/' + name + '/'
d.settingspath = settingsdir + '/eiger/' d.trimen = [4500, 5400, 6400] if name == 'eiger' else [4000, 6000, 8000, 12000]
d.setThresholdEnergy(4500, detectorSettings.STANDARD) d.setThresholdEnergy(4500, detectorSettings.STANDARD)
d.frames = num_frames d.frames = num_frames
except Exception as e: except Exception as e:

View File

@@ -1,39 +1,14 @@
# SPDX-License-Identifier: LGPL-3.0-or-other #!/bin/bash
# Copyright (C) 2021 Contributors to the SLS Detector Package
#echo $#
#if [ $# = 0 ]; then
# f=$0
#else
# f=$1
#fi
#echo $f
if [ "x${BASH_ARGV[0]}" = "x" ]; then
#if [ "x$f" = "x" ]; then
if [ ! -f this_build_bin_path.sh ]; then
f=$0
echo "aaaa"
#thispath=$(dirname ${BASH_ARGV[0]})
thispath=$(dirname $f)
p=$(cd ${thispath};pwd);
THIS_PATH="$p/build/bin/"
# echo "ERROR: must cd where/this/package/is before calling this_path.sh"
# echo "Try sourcing it"
else
echo "bbb"
THIS_PATH="$PWD/build/bin/";
fi
else
thispath=$(dirname ${BASH_ARGV[0]})
p=$(cd ${thispath};pwd);
THIS_PATH="$p/build/bin/"
echo "ccc"
fi
echo "this_path="$THIS_PATH # Since this script could be sourced, $0 is not sufficent, BASH_SOURCE[0] is necessary
export PATH=$THIS_PATH:$PATH SCRIPT_LOCATION="$(realpath ${BASH_SOURCE[0]})"
export LD_LIBRARY_PATH=$THIS_PATH:$LD_LIBRARY_PATH SCRIPT_LOCATION="$(dirname ${SCRIPT_LOCATION})"
export PYTHONPATH=$THIS_PATH:$PYTHONPATH BUILDBIN_LOCATION="${SCRIPT_LOCATION}/build/bin"
echo "path="$PATH if [ ! -d "${BUILDBIN_LOCATION}" ]; then
echo "ld_library_path="$LD_LIBRARY_PATH echo Cannot find path ${BUILDBIN_LOCATION}
echo "pythonpath="$PYTHON_PATH else
echo Adding ${BUILDBIN_LOCATION} to PATH and PYTHONPATH
export PATH=${BUILDBIN_LOCATION}:${PATH}
export PYTHONPATH=${BUILDBIN_LOCATION}:${PYTHONPATH}
fi