Compare commits

..

6 Commits

Author SHA1 Message Date
Erik Fröjdh
25e2a0425f Merge branch 'developer' into dev/include_file
All checks were successful
Build on RHEL9 / build (push) Successful in 4m32s
Build on RHEL8 / build (push) Successful in 4m43s
2025-10-27 16:31:00 +01:00
530c80e41f moved test_free and test_command python tests to tests/scripts folder from python/tests due to CI issues with dependencies
Some checks failed
Build on RHEL9 / build (push) Failing after 3m17s
Build on RHEL8 / build (push) Failing after 4m27s
2025-10-27 11:51:38 +01:00
Erik Fröjdh
323114d6e2 added colorama
Some checks failed
Build on RHEL9 / build (push) Failing after 42s
Build on RHEL8 / build (push) Failing after 4m40s
2025-10-22 15:42:57 +02:00
Erik Fröjdh
0c45c94c38 Merge branch 'developer' into dev/include_file 2025-10-22 15:33:24 +02:00
27a74d6988 added include in command line and python and its supposed to do the same as parameters command. both are tested 2025-09-17 15:26:50 +02:00
37bd2597dd create a include command calling the same function as parameters (cmd generation and autocompletion), testing parameters and include 2025-09-17 11:23:29 +02:00
38 changed files with 483 additions and 536 deletions

View File

@@ -1,33 +0,0 @@
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

@@ -1,30 +0,0 @@
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

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

View File

@@ -19,7 +19,7 @@ jobs:
with:
python-version: 3.12
cache: 'pip'
- run: pip install pytest numpy colorama
- run: pip install pytest numpy
- uses: awalsh128/cache-apt-pkgs-action@latest
with:

View File

@@ -1,7 +1,7 @@
SLS Detector Package Major Release x.x.x released on xx.xx.202x
===============================================================
This document describes the differences between vx.x.x and v10.0.0
This document describes the differences between vx.x.x and vx.0.2
@@ -35,10 +35,6 @@ instead of the one included in our repo.
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
==========================================

View File

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

View File

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

View File

@@ -50,12 +50,6 @@ datetime.timedelta, DurationWrapper or by setting the time in seconds.
>>> d.getExptime()
[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

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

View File

@@ -24,7 +24,6 @@ import datetime as dt
from functools import wraps
from collections import namedtuple
from collections.abc import Sequence
import socket
import numpy as np
@@ -148,6 +147,33 @@ class Detector(CppDetectorApi):
value = ut.make_string_path(value)
self.loadParameters(value)
@property
def include(self):
"""Sets detector measurement parameters to those contained in fname.
Set up per measurement.
Note
-----
Equivalent to config, but does not free shared memory. Same as parameters command.
:getter: Not implemented
:setter: loads parameters file
Example
---------
>>> d.include = 'path/to/file.par'
"""
return NotImplementedError("include is set only")
@include.setter
def include(self, value):
if isinstance(value, str):
value = ut.make_string_path(value)
self.loadParameters(value)
@property
def hostname(self):
"""Frees shared memory and sets hostname (or IP address) of all modules concatenated by +
@@ -302,46 +328,6 @@ class Detector(CppDetectorApi):
def rx_arping(self, 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
@element

View File

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

View File

@@ -1,12 +1,11 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include <datetime.h>
#include <pybind11/pybind11.h>
#include <datetime.h>
#include "DurationWrapper.h"
#include "sls/Result.h"
#include "sls/sls_detector_defs.h"
#include "DurationWrapper.h"
namespace py = pybind11;
namespace pybind11 {
@@ -15,130 +14,84 @@ template <typename Type, typename Alloc>
struct type_caster<sls::Result<Type, Alloc>>
: list_caster<sls::Result<Type, Alloc>, Type> {};
// Based on the typecaster in pybind11/chrono.h
template <> struct type_caster<std::chrono::nanoseconds> {
public:
PYBIND11_TYPE_CASTER(std::chrono::nanoseconds,
const_name("DurationWrapper"));
public:
PYBIND11_TYPE_CASTER(std::chrono::nanoseconds, const_name("DurationWrapper"));
// signed 25 bits required by the standard.
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
// signed 25 bits required by the standard.
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
/**
* Conversion part 1 (Python->C++): convert a PyObject into
* std::chrono::nanoseconds try datetime.timedelta, floats and our
* DurationWrapper wrapper
*/
/**
* Conversion part 1 (Python->C++): convert a PyObject into std::chrono::nanoseconds
* try datetime.timedelta, floats and our DurationWrapper wrapper
*/
bool load(handle src, bool) {
using namespace std::chrono;
bool load(handle src, bool) {
using namespace std::chrono;
// Lazy initialise the PyDateTime import
if (!PyDateTimeAPI) {
PyDateTime_IMPORT;
}
// Lazy initialise the PyDateTime import
if (!PyDateTimeAPI) {
PyDateTime_IMPORT;
}
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)) {
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;
}
value.xmin = seq[0].cast<int>();
value.xmax = seq[1].cast<int>();
if (seq.size() == 4) {
value.ymin = seq[2].cast<int>();
value.ymax = seq[3].cast<int>();
/**
* 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;
}
};
return true;
}
};
} // namespace detail
} // namespace pybind11

View File

@@ -1,85 +0,0 @@
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

@@ -1,48 +0,0 @@
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

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

View File

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

View File

@@ -80,7 +80,7 @@ _sd() {
local IS_PATH=0
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -1214,6 +1214,21 @@ fi
fi
return 0
}
__include() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="0 1"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
IS_PATH=1
fi
fi
return 0
}
__initialchecks() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then

View File

@@ -4,7 +4,7 @@
_sd() {
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -1138,6 +1138,21 @@ fi
fi
return 0
}
__include() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="0 1"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
IS_PATH=1
fi
fi
return 0
}
__initialchecks() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then

View File

@@ -1846,6 +1846,13 @@ parameters:
PUT:
function: loadParameters
include:
inherit_actions: EXECUTE_SET_COMMAND_NOID_1ARG
help: "\n\tSets detector measurement parameters to those contained in fname. Set up per measurement. Same as parameters command."
actions:
PUT:
function: loadParameters
savepattern:
inherit_actions: EXECUTE_SET_COMMAND_NOID_1ARG
help: "\n\t[Ctb][Mythen3][Xilinx Ctb] Saves pattern to file (ascii). \n\t[Ctb] Also executes pattern."

View File

@@ -4988,6 +4988,32 @@ imagetest:
\ pixel intensity incremented by 1. If 1, all pixels almost saturated."
infer_action: true
template: true
include:
actions:
PUT:
args:
- arg_types:
- special::path
argc: 1
cast_input:
- false
check_det_id: true
convert_det_id: true
function: loadParameters
input:
- args[0]
input_types:
- std::string
output:
- args.front()
require_det_id: false
store_result_in_t: false
command_name: include
function_alias: include
help: "\n\tSets detector measurement parameters to those contained in fname. Set\
\ up per measurement. Same as parameters command."
infer_action: true
template: true
initialchecks:
actions:
GET:

View File

@@ -6375,6 +6375,48 @@ std::string Caller::imagetest(int action) {
return os.str();
}
std::string Caller::include(int action) {
std::ostringstream os;
// print help
if (action == slsDetectorDefs::HELP_ACTION) {
os << R"V0G0N(
Sets detector measurement parameters to those contained in fname. Set up per measurement. Same as parameters command. )V0G0N"
<< std::endl;
return os.str();
}
// check if action and arguments are valid
if (action == slsDetectorDefs::PUT_ACTION) {
if (1 && args.size() != 1) {
throw RuntimeError("Wrong number of arguments for action PUT");
}
if (args.size() == 1) {
}
}
else {
throw RuntimeError(
"INTERNAL ERROR: Invalid action: supported actions are ['PUT']");
}
// generate code for each action
if (action == slsDetectorDefs::PUT_ACTION) {
if (args.size() == 1) {
if (det_id != -1) {
throw RuntimeError("Cannot execute include at module level");
}
det->loadParameters(args[0]);
os << args.front() << '\n';
}
}
return os.str();
}
std::string Caller::initialchecks(int action) {
std::ostringstream os;

View File

@@ -161,6 +161,7 @@ class Caller {
std::string im_d(int action);
std::string im_io(int action);
std::string imagetest(int action);
std::string include(int action);
std::string initialchecks(int action);
std::string inj_ch(int action);
std::string interpolation(int action);
@@ -505,6 +506,7 @@ class Caller {
{"im_d", &Caller::im_d},
{"im_io", &Caller::im_io},
{"imagetest", &Caller::imagetest},
{"include", &Caller::include},
{"initialchecks", &Caller::initialchecks},
{"inj_ch", &Caller::inj_ch},
{"interpolation", &Caller::interpolation},

View File

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

View File

@@ -1618,6 +1618,18 @@ int InferAction::imagetest() {
}
}
int InferAction::include() {
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::initialchecks() {
if (args.size() == 0) {

View File

@@ -116,6 +116,7 @@ class InferAction {
int im_d();
int im_io();
int imagetest();
int include();
int initialchecks();
int inj_ch();
int interpolation();
@@ -448,6 +449,7 @@ class InferAction {
{"im_d", &InferAction::im_d},
{"im_io", &InferAction::im_io},
{"imagetest", &InferAction::imagetest},
{"include", &InferAction::include},
{"initialchecks", &InferAction::initialchecks},
{"inj_ch", &InferAction::inj_ch},
{"interpolation", &InferAction::interpolation},

View File

@@ -46,32 +46,46 @@ TEST_CASE("config", "[.cmdcall]") {
// free: not testing
TEST_CASE("parameters", "[.cmdcall]") {
void test_include_file(const std::string &cmd) {
Detector det;
Caller caller(&det);
// put only
REQUIRE_THROWS(caller.call("parameters", {}, -1, GET));
/*
auto prev_val = det.getNumberOfFrames().tsquash("Number of frames has to
be same to test");
{
system("echo 'frames 2' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call("parameters", {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == "parameters /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames().tsquash("failed") == 2);
}
{
system("echo '0:frames 1' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call("parameters", {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == "parameters /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames({0}).tsquash("failed") == 1);
}
det.setNumberOfFrames(prev_val);
*/
REQUIRE_THROWS(caller.call(cmd, {}, -1, GET));
auto prev_frames = det.getNumberOfFrames().tsquash(
"Number of frames has to be same to test");
auto prev_fwrite =
det.getFileWrite().tsquash("File write enable has to be same to test");
{
system("echo -e 'frames 2\nfwrite 1' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call(cmd, {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == cmd + " /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames().tsquash(
"frames inconsistent and failed") == 2);
REQUIRE(det.getFileWrite().tsquash("fwrite inconsistent and failed") ==
1);
}
{
system("echo -e 'frames 3\nfwrite 0' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call(cmd, {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == cmd + " /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames().tsquash(
"frames inconsistent and failed") == 3);
REQUIRE(det.getFileWrite().tsquash("fwrite inconsistent and failed") ==
0);
}
det.setNumberOfFrames(prev_frames);
det.setFileWrite(prev_fwrite);
}
TEST_CASE("parameters", "[.cmdcall]") { test_include_file("parameters"); }
TEST_CASE("include", "[.cmdcall]") { test_include_file("include"); }
TEST_CASE("hostname", "[.cmdcall]") {
Detector det;
Caller caller(&det);

View File

@@ -138,8 +138,7 @@ TEST_CASE("Parse version and help", "[detector]") {
}
}
// TODO: fails on gitea CI due to uid issue, fix later
TEST_CASE("Parse port and uid", "[.failsongitea][detector]") {
TEST_CASE("Parse port and uid", "[detector]") {
uid_t uid = getuid();
std::string uidStr = std::to_string(uid);
uid_t invalidUid = uid + 1000;

View File

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

View File

@@ -6,7 +6,6 @@
#include <algorithm>
#include <memory>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
@@ -156,10 +155,6 @@ template <typename Container> bool hasDuplicates(Container c) {
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>
typename std::enable_if<is_container<T>::value, bool>::type
removeDuplicates(T &c) {
@@ -172,29 +167,6 @@ removeDuplicates(T &c) {
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
#endif // CONTAINER_UTILS_H

View File

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

View File

@@ -153,35 +153,13 @@ TEST_CASE("check for duplicates in vector of pairs") {
REQUIRE(hasDuplicates(vec) == true);
}
TEST_CASE("sorts the vector and remove duplicates") {
TEST_CASE("remove duplicates from vector") {
std::vector<int> v{5, 6, 5, 3};
auto r = removeDuplicates(v);
CHECK(r == true); // did indeed remove elements
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") {
std::vector<int> v;
auto r = removeDuplicates(v);
@@ -189,11 +167,4 @@ TEST_CASE("remove duplicated empty vector") {
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

View File

@@ -62,3 +62,5 @@ configure_file(scripts/test_frame_synchronizer.py ${CMAKE_BINARY_DIR}/bin/test_f
configure_file(scripts/utils_for_test.py ${CMAKE_BINARY_DIR}/bin/utils_for_test.py COPYONLY)
configure_file(scripts/test_roi.py ${CMAKE_BINARY_DIR}/bin/test_roi.py COPYONLY)
configure_file(scripts/test_free.py ${CMAKE_BINARY_DIR}/bin/test_free.py COPYONLY)
configure_file(scripts/test_commands.py ${CMAKE_BINARY_DIR}/bin/test_commands.py COPYONLY)

View File

@@ -0,0 +1,100 @@
# 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 and test for freeing shm and accessing it from python.
Run this using: pytest -s test_free.py
'''
from time import time
import pytest, sys, time
from slsdet import Detector, Ctb, freeSharedMemory
from slsdet.defines import DEFAULT_TCP_RX_PORTNO
from utils_for_test import (
Log,
LogLevel,
cleanup,
startDetectorVirtualServer,
startProcessInBackground,
loadConfig,
loadBasicSettings
)
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)
'''
scope = module =>Once per test file/module
to share expensive setup like startDetectorVirtualServer
'''
@pytest.fixture(scope="module")
def det_config():
return {
"name": "ctb",
"num_mods": 1
}
# autouse is false to pass explictly
@pytest.fixture(scope="module", autouse=False)
def setup_simulator(det_config):
"""Fixture to start the detector server once and clean up at the end."""
fp = sys.stdout
cleanup(fp)
# server
startDetectorVirtualServer(det_config["name"], det_config["num_mods"], fp)
# receiver
startReceiver(det_config["num_mods"], fp)
# config and basic settings
d = loadConfig(name=det_config["name"], rx_hostname="localhost", settingsdir="", fp=fp, num_mods=det_config["num_mods"])
loadBasicSettings(name=det_config["name"], d=d, fp=fp)
yield d # tests run here
cleanup(fp)
def test_parameters_file(setup_simulator):
d = setup_simulator
Log(LogLevel.INFOBLUE, f'\nRunning test_parameters_file')
assert isinstance(d, Detector)
with open("/tmp/params.det", "w") as f:
f.write("frames 2\n")
f.write("fwrite 1\n")
# this should not throw
d.parameters = "/tmp/params.det"
assert d.frames == 2
assert d.fwrite == 1
Log(LogLevel.INFOGREEN, f"✅ Test passed. Command: parameters")
def test_include_file(setup_simulator):
d = setup_simulator
Log(LogLevel.INFOBLUE, f'\test_include_file test_parameters_file')
assert isinstance(d, Detector)
with open("/tmp/params.det", "w") as f:
f.write("frames 3\n")
f.write("fwrite 0\n")
# this should not throw
d.include = "/tmp/params.det"
assert d.frames == 3
assert d.fwrite == 0
Log(LogLevel.INFOGREEN, f"✅ Test passed. Command: include")

View File

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

View File

@@ -18,11 +18,9 @@ from utils_for_test import (
RuntimeException,
cleanup,
startProcessInBackground,
startReceiver,
startDetectorVirtualServer,
connectToVirtualServers,
loadBasicSettings,
loadConfig,
runProcessWithLogFile
)
@@ -30,6 +28,45 @@ LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_roi_test'
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
ROI_TEST_FNAME = LOG_PREFIX_FNAME + '_results_'
def startReceiver(num_mods, fp):
if num_mods == 1:
cmd = ['slsReceiver']
else:
cmd = ['slsMultiReceiver', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)]
# in 10.0.0
#cmd = ['slsMultiReceiver', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)]
startProcessInBackground(cmd, fp)
time.sleep(1)
def loadConfigForRoi(name, fp, num_mods = 1, num_interfaces = 1):
Log(LogLevel.INFO, 'Loading config')
Log(LogLevel.INFO, 'Loading config', fp)
try:
d = connectToVirtualServers(name, num_mods)
if name == 'jungfrau' or name == 'moench':
d.numinterfaces = num_interfaces
d.udp_dstport = DEFAULT_UDP_DST_PORTNO
if name == 'eiger' or name == 'jungfrau' or name == 'moench':
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
d.rx_hostname = 'localhost'
d.udp_dstip = 'auto'
if name != "eiger":
d.udp_srcip = 'auto'
if name == 'jungfrau' or name == 'moench':
d.udp_dstip2 = 'auto'
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):
servers = [
'eiger',
@@ -52,7 +89,7 @@ def startTestsForAll(fp):
cleanup(fp)
startDetectorVirtualServer(server, nmods, fp)
startReceiver(nmods, fp)
d = loadConfig(name=server, log_file_fp = fp, num_mods=nmods, num_frames=5, num_interfaces=ninterfaces)
d = loadConfigForRoi(name=server, fp=fp, num_mods=nmods, num_interfaces=ninterfaces)
loadBasicSettings(name=server, d=d, fp=fp)
fname = ROI_TEST_FNAME + server + '.txt'

View File

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

View File

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

View File

@@ -1,14 +1,39 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-3.0-or-other
# 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
# Since this script could be sourced, $0 is not sufficent, BASH_SOURCE[0] is necessary
SCRIPT_LOCATION="$(realpath ${BASH_SOURCE[0]})"
SCRIPT_LOCATION="$(dirname ${SCRIPT_LOCATION})"
BUILDBIN_LOCATION="${SCRIPT_LOCATION}/build/bin"
if [ ! -d "${BUILDBIN_LOCATION}" ]; then
echo Cannot find path ${BUILDBIN_LOCATION}
else
echo Adding ${BUILDBIN_LOCATION} to PATH and PYTHONPATH
export PATH=${BUILDBIN_LOCATION}:${PATH}
export PYTHONPATH=${BUILDBIN_LOCATION}:${PYTHONPATH}
fi
echo "this_path="$THIS_PATH
export PATH=$THIS_PATH:$PATH
export LD_LIBRARY_PATH=$THIS_PATH:$LD_LIBRARY_PATH
export PYTHONPATH=$THIS_PATH:$PYTHONPATH
echo "path="$PATH
echo "ld_library_path="$LD_LIBRARY_PATH
echo "pythonpath="$PYTHON_PATH