mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-13 13:27:14 +02:00
Compare commits
86 Commits
ctb/contin
...
9.0.0
Author | SHA1 | Date | |
---|---|---|---|
1b41e39ad1 | |||
64fea22c2b | |||
9beaed7813 | |||
0aeb7e4417 | |||
4880f87791 | |||
97f0c1fe46 | |||
a86fd00e59 | |||
24894667b7 | |||
4b414bfddb | |||
15d357d9ab | |||
f95de054f9 | |||
0aef8113dd | |||
9785a41048 | |||
417e1a88a5 | |||
9c0dd0385d | |||
5ab64efe3e | |||
8f77e4d4fe | |||
41c5b75b10 | |||
bfe53c6693 | |||
f7997dd09a | |||
c64e87a2b6 | |||
5eeb8e29c1 | |||
09697fa325 | |||
90b4daef39 | |||
2082f1eee7 | |||
d3a636b563 | |||
50b9b6ca39 | |||
e86b57cdfc | |||
14e11e8b5b | |||
beafe86554 | |||
af3dc1e7f4 | |||
573177203b | |||
a3ca9ebce5 | |||
8174fc9691 | |||
d6eac6da71 | |||
56c7ae4852 | |||
9b9b09ceaf | |||
cfebaee2a5 | |||
4613c54f57 | |||
51f9d6f011 | |||
58ac7ac280 | |||
82edfa75d3 | |||
35ed926047 | |||
4023ed0775 | |||
b6ef3bc39e | |||
2035666792 | |||
1ff4d806e7 | |||
3861379653 | |||
91140bbb71 | |||
a5632fcbea | |||
d44329117d | |||
4a454aa698 | |||
0e43072db8 | |||
6c67025ea8 | |||
e5ee27dbfa | |||
601249cc71 | |||
ff60b8c379 | |||
37ce3d6f59 | |||
bf26533fd8 | |||
7106273521 | |||
1484d038de | |||
fb0090c79e | |||
adc68cd519 | |||
1566eef247 | |||
e7cd90db78 | |||
45414149fe | |||
48759f440e | |||
b367b7e431 | |||
f0b2a6f6f9 | |||
f761046bfc | |||
1a859b83db | |||
70bfc875a6 | |||
c0755308a4 | |||
ab5509e10c | |||
004cb26646 | |||
a4f47a5945 | |||
312f3f473d | |||
5871086cd6 | |||
6a0fe823b3 | |||
5912aae53e | |||
8833ccf5cc | |||
77c558a7be | |||
378fc301b8 | |||
87d6e16090 | |||
2ef021041c | |||
574127b5ac |
@ -1,29 +0,0 @@
|
||||
name: Build on RHEL8
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "ubuntu-latest"
|
||||
container:
|
||||
image: gitea.psi.ch/detectors/rhel8-detectors-dev
|
||||
steps:
|
||||
- name: Clone repository
|
||||
run: |
|
||||
echo Cloning ${{ github.ref_name }}
|
||||
git clone https://${{secrets.GITHUB_TOKEN}}@gitea.psi.ch/${{ github.repository }}.git --branch=${{ github.ref_name }} .
|
||||
|
||||
- name: Build library
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON
|
||||
make -j 2
|
||||
|
||||
- name: C++ unit tests
|
||||
working-directory: ${{gitea.workspace}}/build
|
||||
run: ctest
|
@ -1,27 +0,0 @@
|
||||
name: Build on RHEL9
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "ubuntu-latest"
|
||||
container:
|
||||
image: gitea.psi.ch/detectors/rhel9-detectors-dev
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Build library
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON
|
||||
make -j 2
|
||||
|
||||
- name: C++ unit tests
|
||||
working-directory: ${{gitea.workspace}}/build
|
||||
run: ctest
|
@ -1,4 +1,4 @@
|
||||
name: Native CMake Build
|
||||
name: CMake
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
@ -14,16 +14,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Configure and build using cmake
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: 'pip'
|
||||
- run: pip install pytest numpy
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev libpng-dev libtiff-dev
|
||||
packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev
|
||||
version: 1.0
|
||||
|
||||
- name: Configure CMake
|
||||
@ -33,15 +27,12 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
# Build your program with the given configuration
|
||||
run: cmake --build ${{github.workspace}}/build -j4 --config ${{env.BUILD_TYPE}}
|
||||
run: cmake --build ${{github.workspace}}/build -j2 --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: C++ unit tests
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}/build
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: ctest -C ${{env.BUILD_TYPE}} -j1
|
||||
|
||||
- name: Python unit tests
|
||||
working-directory: ${{github.workspace}}/build/bin
|
||||
run: |
|
||||
python -m pytest ${{github.workspace}}/python/tests
|
||||
|
||||
|
42
.github/workflows/conda_library.yaml
vendored
42
.github/workflows/conda_library.yaml
vendored
@ -1,42 +0,0 @@
|
||||
name: Build slsdetlib
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, ] # macos-12, windows-2019]
|
||||
python-version: ["3.12",]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
# The setup-miniconda action needs this to activate miniconda
|
||||
defaults:
|
||||
run:
|
||||
shell: "bash -l {0}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get conda
|
||||
uses: conda-incubator/setup-miniconda@v3.0.4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
channels: conda-forge
|
||||
|
||||
- name: Prepare
|
||||
run: conda install conda-build conda-verify pytest anaconda-client
|
||||
|
||||
- name: Disable upload
|
||||
run: conda config --set anaconda_upload no
|
||||
|
||||
- name: Build
|
||||
run: conda build conda-recipes/main-library --output-folder build_output
|
||||
|
||||
- name: Upload all Conda packages
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: conda-packages
|
||||
path: build_output/** # Uploads all packages
|
42
.github/workflows/conda_python.yaml
vendored
42
.github/workflows/conda_python.yaml
vendored
@ -1,42 +0,0 @@
|
||||
name: slsdet
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, ] # macos-12, windows-2019]
|
||||
python-version: ["3.12",]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
# The setup-miniconda action needs this to activate miniconda
|
||||
defaults:
|
||||
run:
|
||||
shell: "bash -l {0}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get conda
|
||||
uses: conda-incubator/setup-miniconda@v3.0.4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
channels: conda-forge
|
||||
|
||||
- name: Prepare
|
||||
run: conda install conda-build conda-verify pytest anaconda-client
|
||||
|
||||
- name: Disable upload
|
||||
run: conda config --set anaconda_upload no
|
||||
|
||||
- name: Build
|
||||
run: conda build conda-recipes/python-client --output-folder build_output
|
||||
|
||||
- name: Upload all Conda packages
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: conda-packages
|
||||
path: build_output/** # Uploads all packages
|
1
CMakeFiles/cmake.check_cache
Normal file
1
CMakeFiles/cmake.check_cache
Normal file
@ -0,0 +1 @@
|
||||
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
|
@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(slsDetectorPackage)
|
||||
|
||||
# Read VERSION file into project version
|
||||
@ -29,44 +29,20 @@ include(FetchContent)
|
||||
option(SLS_FETCH_ZMQ_FROM_GITHUB "Fetch zmq from github" OFF)
|
||||
option(SLS_FETCH_PYBIND11_FROM_GITHUB "Fetch pybind11 from github" OFF)
|
||||
|
||||
|
||||
|
||||
# Allow FetchContent_Populate to be called with a single argument
|
||||
# otherwise deprecated warning is issued
|
||||
# Note: From cmake 3.28 we can pass EXCLUDE_FROM_ALL to FetchContent_Declare
|
||||
# and avoid direct use of Populate
|
||||
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30")
|
||||
cmake_policy(SET CMP0169 OLD)
|
||||
endif()
|
||||
|
||||
# Patch libzmq to set minimum cmake version to 3.15 to avoid warnings
|
||||
# with newer cmake versions
|
||||
# Patch is applied in the FetchContent_Declare
|
||||
set(SLS_LIBZMQ_VERSION "4.3.4")
|
||||
|
||||
find_program(PATCH_EXECUTABLE patch)
|
||||
if(NOT PATCH_EXECUTABLE)
|
||||
message(FATAL_ERROR "The 'patch' tool is required for patching lib zeromq. Please install it.")
|
||||
endif()
|
||||
|
||||
if(SLS_FETCH_ZMQ_FROM_GITHUB)
|
||||
# Opt in to pull down a zmq version from github instead of
|
||||
# using the bundled version
|
||||
# using the bundled verison
|
||||
FetchContent_Declare(
|
||||
libzmq
|
||||
GIT_REPOSITORY https://github.com/zeromq/libzmq.git
|
||||
GIT_TAG v${SLS_LIBZMQ_VERSION}
|
||||
PATCH_COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR> patch -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq_cmake_version.patch
|
||||
UPDATE_DISCONNECTED 1
|
||||
GIT_TAG v4.3.4
|
||||
)
|
||||
else()
|
||||
# Standard behaviour use libzmq included in this repo (libs/libzmq)
|
||||
FetchContent_Declare(
|
||||
libzmq
|
||||
URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-${SLS_LIBZMQ_VERSION}.tar.gz
|
||||
URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-4.3.4.tar.gz
|
||||
URL_HASH MD5=cc20b769ac10afa352e5ed2769bb23b3
|
||||
PATCH_COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR> patch -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq_cmake_version.patch
|
||||
UPDATE_DISCONNECTED 1
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -78,11 +54,6 @@ set(ENABLE_CPACK OFF CACHE BOOL "")
|
||||
set(ENABLE_CLANG OFF CACHE BOOL "")
|
||||
set(ENABLE_CURVE OFF CACHE BOOL "")
|
||||
set(ENABLE_DRAFTS OFF CACHE BOOL "")
|
||||
set(ENABLE_PRECOMPILED OFF CACHE BOOL "")
|
||||
set(WITH_DOC OFF CACHE BOOL "")
|
||||
set(WITH_DOCS OFF CACHE BOOL "")
|
||||
|
||||
|
||||
|
||||
# Using GetProperties and Populate to be able to exclude zmq
|
||||
# from install (not possible with FetchContent_MakeAvailable(libzmq))
|
||||
@ -220,7 +191,7 @@ endif()
|
||||
# to control options for the libraries
|
||||
if(NOT TARGET slsProjectOptions)
|
||||
add_library(slsProjectOptions INTERFACE)
|
||||
target_compile_features(slsProjectOptions INTERFACE cxx_std_17)
|
||||
target_compile_features(slsProjectOptions INTERFACE cxx_std_11)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET slsProjectWarnings)
|
||||
@ -278,8 +249,8 @@ endif()
|
||||
if(SLS_USE_SANITIZER)
|
||||
target_compile_options(slsProjectOptions INTERFACE -fsanitize=address,undefined -fno-omit-frame-pointer)
|
||||
target_link_libraries(slsProjectOptions INTERFACE -fsanitize=address,undefined)
|
||||
#target_compile_options(slsProjectOptions INTERFACE -fsanitize=thread -fno-omit-frame-pointer)
|
||||
#target_link_libraries(slsProjectOptions INTERFACE -fsanitize=thread)
|
||||
# target_compile_options(slsProjectOptions INTERFACE -fsanitize=thread)
|
||||
# target_link_libraries(slsProjectOptions INTERFACE -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
|
||||
@ -333,8 +304,7 @@ if (SLS_USE_INTEGRATION_TESTS)
|
||||
endif (SLS_USE_INTEGRATION_TESTS)
|
||||
|
||||
if (SLS_USE_PYTHON)
|
||||
find_package (Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED)
|
||||
set(PYBIND11_FINDPYTHON ON) # Needed for RH8
|
||||
find_package (Python 3.8 COMPONENTS Interpreter Development)
|
||||
if(SLS_FETCH_PYBIND11_FROM_GITHUB)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
@ -359,15 +329,9 @@ if (SLS_USE_CTBGUI)
|
||||
add_subdirectory(pyctbgui)
|
||||
endif(SLS_USE_CTBGUI)
|
||||
|
||||
# Workaround for file note being copied to build directory
|
||||
# when issuing a python -m build
|
||||
# TODO! Proper fix
|
||||
if(EXISTS ".clang-tidy")
|
||||
configure_file(.clang-tidy
|
||||
${CMAKE_BINARY_DIR}/.clang-tidy
|
||||
)
|
||||
endif()
|
||||
|
||||
configure_file( .clang-tidy
|
||||
${CMAKE_BINARY_DIR}/.clang-tidy
|
||||
)
|
||||
|
||||
if (SLS_BUILD_EXAMPLES)
|
||||
add_subdirectory(sample)
|
||||
|
298
RELEASE.txt
298
RELEASE.txt
@ -1,34 +1,285 @@
|
||||
SLS Detector Package Major Release x.x.x released on xx.xx.202x
|
||||
SLS Detector Package Major Release 9.0.0 released on 26.11.2024
|
||||
===============================================================
|
||||
|
||||
This document describes the differences between vx.x.x and vx.0.2
|
||||
This document describes the differences between v9.0.0 and v8.0.2
|
||||
|
||||
|
||||
|
||||
CONTENTS
|
||||
--------
|
||||
1 New, Changed or Resolved Features
|
||||
1.1 Compilation
|
||||
1.2 Callback
|
||||
1.3 Python
|
||||
1.4 Client
|
||||
1.5 Detector Server
|
||||
1.6 Simulator
|
||||
1.7 Receiver
|
||||
1.8 Gui
|
||||
2 On-board Detector Server Compatibility
|
||||
3 Firmware Requirements
|
||||
4 Kernel Requirements
|
||||
5 Download, Documentation & Support
|
||||
1 Compilation Changes
|
||||
2 New or Changed Features
|
||||
2.1 Breaking API
|
||||
2.2 Resolved or Changed Features
|
||||
2.3 New Features
|
||||
3 On-board Detector Server Compatibility
|
||||
4 Firmware Requirements
|
||||
5 Kernel Requirements
|
||||
6 Download, Documentation & Support
|
||||
|
||||
|
||||
|
||||
|
||||
1 New, Changed or Resolved Features
|
||||
2 Compilation Changes
|
||||
=====================
|
||||
|
||||
|
||||
* Python version
|
||||
Minimum python version is changed from 3.6 to 3.8
|
||||
|
||||
|
||||
* Pybind11 version
|
||||
In-built version and the one picked up from github
|
||||
updated from v2.11.0 to v2.13.6
|
||||
|
||||
|
||||
* Python lib versioning
|
||||
slsdet.__version__ now returns the package release version.
|
||||
|
||||
|
||||
* Python version in conda build
|
||||
Added python 3.13 also to conda build
|
||||
|
||||
|
||||
|
||||
2 New, Changed or Resolved Features
|
||||
=====================================
|
||||
|
||||
|
||||
|
||||
|
||||
2.1 Breaking API
|
||||
==================
|
||||
|
||||
|
||||
Receiver
|
||||
--------
|
||||
|
||||
|
||||
* Receiver callbacks
|
||||
Brought much more metadata to receiver callbacks to construct the image.
|
||||
Update MultiReceiverApp to reflect this change.
|
||||
|
||||
|
||||
* File path
|
||||
At start of acquisition or at rx_start command, the file path is only
|
||||
then verified if it exists and created if it does not.
|
||||
|
||||
|
||||
Client
|
||||
------
|
||||
|
||||
|
||||
* Removed receiver/publisher ZMQ IP
|
||||
Command line: rx_zmqip gives a warning and does nothing
|
||||
Python : rx_zmqip removed
|
||||
C++ API: get/setRxZmqIP removed
|
||||
|
||||
Publisher zmq IP set to '0.0.0.0' or to listen on all interfaces.
|
||||
The publisher will determine which interface to stream out from based on
|
||||
the network route to the subscriber IP. Hence, receiver zmq IP is not
|
||||
required.
|
||||
|
||||
|
||||
* Write register, Set or Clear bit
|
||||
Validation for this advanced feature has been removed by default.
|
||||
One can force validation by using --validate in the command line or by
|
||||
setting the validate option in the API.
|
||||
|
||||
|
||||
ZMQ
|
||||
---
|
||||
|
||||
|
||||
* Publisher socket constructor does not take an IP anymore.
|
||||
The details are above under 'Removed receiver/publisher ZMQ IP'.
|
||||
|
||||
|
||||
GUI/ Client Callback
|
||||
--------------------
|
||||
|
||||
|
||||
* completeImage member in detectorData attribute now returns false only
|
||||
if any the sub images (from different udp ports) have completeImage
|
||||
set to false in the JSON header. This is set if therea are any missing
|
||||
packets for that udp port on slsReceiver/slsMultiReceiver.
|
||||
|
||||
The different subimages are anyway not synchronized. This errs when
|
||||
there are different missing images across multiple UDP ports.
|
||||
|
||||
The Gui does not show "complete image" in the status bar anymore.
|
||||
If any of the udp ports have missing packets for that current disaplayed
|
||||
image, then the "missing packets" will show in red in the status bar.
|
||||
|
||||
|
||||
Detector Server
|
||||
---------------
|
||||
|
||||
|
||||
* [Mythen3] Only run clock can be set
|
||||
Clock 0 is now the run clock and the only one that can be set.
|
||||
The others are be read only.
|
||||
This affects the following commands:
|
||||
Command line or python API: clkdiv, clkfreq, clkphase, maxclkphaseshift
|
||||
C++ API: get/setClockDivider, getClockFrequency, get/setClockPhase,
|
||||
getMaxClockPhaseShift
|
||||
|
||||
|
||||
* [Jungfrau] Temperature Control
|
||||
Temperature control is enabled by default at on-board detector server
|
||||
startup.
|
||||
As before, the default temperature threshold is 65°C and crossing this
|
||||
value will set a temperature event.
|
||||
|
||||
|
||||
|
||||
2.2 Resolved or Changed Features
|
||||
================================
|
||||
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
|
||||
* cmake_source_dir
|
||||
Fixed compilation error when using python and adding the slsDetectorPackage
|
||||
as a subfolder due to cmake source directory changing.
|
||||
|
||||
|
||||
Client
|
||||
------
|
||||
|
||||
|
||||
* Command line Code Generation
|
||||
The command line parsing code is now generated from a yaml file. This is
|
||||
transparent to the user.
|
||||
|
||||
|
||||
* Clearer error message about freeing shared memory.
|
||||
|
||||
|
||||
Detector Server
|
||||
---------------
|
||||
|
||||
|
||||
* [Gotthard2] Chip reconfiguration
|
||||
|
||||
- Powering off/on the chip will now switch off chip configuration
|
||||
property/ configure the chip every time.
|
||||
|
||||
- Switching off high voltage from a non zero value will now wait
|
||||
10s to return for safety reasons.
|
||||
|
||||
- Powering off the chip requires high voltage to have been
|
||||
switched off prior.
|
||||
|
||||
- Acquisition requires chip to have been configured prior.
|
||||
|
||||
|
||||
* [Gotthard2] Burst mode options restricted
|
||||
Burst mode external and continuous mode internal are not allowed to be set
|
||||
anymore as they are anyway not implemented.
|
||||
|
||||
|
||||
Receiver
|
||||
--------
|
||||
|
||||
|
||||
* [Gotthard I] fixed header stripping fixing segfault.
|
||||
|
||||
|
||||
* Error or help message for invalid arguments to slsMultiReceiver.
|
||||
|
||||
|
||||
Simulator
|
||||
---------
|
||||
|
||||
|
||||
* Refactored stop server to have better start up.
|
||||
|
||||
|
||||
* Fixed possible memory leak when taking non blocking acquisitions.
|
||||
|
||||
|
||||
* [Jungfrau] Valid gain values in data sent out. Previously, 2 was also sent out.
|
||||
|
||||
|
||||
ZMQ
|
||||
---
|
||||
|
||||
|
||||
* Publiser socket constructor
|
||||
|
||||
- enables keep alive socket options to send heartbeat messages to prevent
|
||||
discarded TCP flows if there is no packet for a longer period.
|
||||
|
||||
- enables IPv6 interfaces
|
||||
|
||||
* Prints specific error for ENOENT (endpoint does not exist)
|
||||
|
||||
|
||||
|
||||
2.3 New Features
|
||||
================
|
||||
|
||||
|
||||
Client
|
||||
------
|
||||
|
||||
|
||||
* Auto completion
|
||||
bash_autocomplete.sh or zsh_autocomplete.sh must be sourced from the
|
||||
main package folder to enable auto completion of commands and arguments
|
||||
for the command line on that shell.
|
||||
|
||||
|
||||
* sls_detector
|
||||
New executable that can be used instead of 'sls_detector_get' and
|
||||
'sls_detector_put' for most commands. It will infer from the number of
|
||||
arguments, which executable (sls_detector_put or sls_detector_get) to use.
|
||||
For the rare commands that cannot be inferred from the number of arguments,
|
||||
it will complain accordingly.
|
||||
|
||||
|
||||
* [Jungfrau] Timing Info Decoder (Advanced configuration)
|
||||
Command line or python API: timing_info_decoder
|
||||
C++ API: get/setTimingInfoDecoder. Options: SWISSFEL (Default), SHINE
|
||||
|
||||
|
||||
* [Jungfrau] Collection Mode (Advanced configuration)
|
||||
Command line or python API: collectionmode
|
||||
C++ API: get/setCollectionMode. Options: ELECTRON, HOLE (Default)
|
||||
If chip v1.1, also configures the chip afterwards.
|
||||
|
||||
|
||||
* [Gotthard2] Next frame number
|
||||
'Stop' in G2 25um is not synchronous and hence might trigger an extra set
|
||||
of frames in the slave module, resulting in the next acquiistion starting
|
||||
with inconsistent frame numbers between master and slave. Solved by
|
||||
setting next frame number to the larger value (max + 1) after a stop command.
|
||||
Requires a firmware update.
|
||||
|
||||
Command line or python API: nextframenumber
|
||||
C++ API: get/setNextFrameNumber
|
||||
Can set/get the starting frame number for the next acquistion.
|
||||
|
||||
|
||||
* [Mythen3] Readout speed
|
||||
Command line, python API: readoutspeed. Options: full_speed (10MHz),
|
||||
half_speed (20MHz, default), quarter_speed (40MHz)
|
||||
C++ API: get/setReadoutSpeed
|
||||
Also affect:
|
||||
Command line, python API: readoutspeedlist
|
||||
C++ API: getReadoutSpeedList
|
||||
|
||||
|
||||
* Sleep
|
||||
Command line, python/ C++ API: sleep
|
||||
Client sleeps for required time. Advanced command mainly for firmware
|
||||
developers to use in config files.
|
||||
|
||||
|
||||
* Xilinx Chip Test Board added
|
||||
|
||||
|
||||
|
||||
2 On-board Detector Server Compatibility
|
||||
@ -39,6 +290,7 @@ This document describes the differences between vx.x.x and vx.0.2
|
||||
Jungfrau 9.0.0
|
||||
Mythen3 9.0.0
|
||||
Gotthard2 9.0.0
|
||||
Gotthard 9.0.0
|
||||
Moench 9.0.0
|
||||
|
||||
|
||||
@ -68,11 +320,14 @@ This document describes the differences between vx.x.x and vx.0.2
|
||||
Jungfrau 20.09.2023 (v1.5, HW v1.0) (updated in 8.0.0)
|
||||
21.09.2023 (v2.5, HW v2.0) (updated in 8.0.0)
|
||||
|
||||
Mythen3 11.10.2024 (v1.5) (updated in 9.0.0)
|
||||
Mythen3 13.11.2024 (v2.0) (updated in 9.0.0)
|
||||
|
||||
Gotthard2 03.10.2024 (v1.0) (updated in 9.0.0)
|
||||
|
||||
Moench 26.10.2023 (v2.0) (updated in 9.0.0)
|
||||
Moench 26.10.2023 (v2.0) (updated in 8.0.2)
|
||||
|
||||
Gotthard 08.02.2018 (50um and 25um Master)
|
||||
09.02.2018 (25 um Slave)
|
||||
|
||||
|
||||
Detector Upgrade
|
||||
@ -86,6 +341,8 @@ This document describes the differences between vx.x.x and vx.0.2
|
||||
Gotthard2 via command <.rbf>
|
||||
Moench via command <.pof>
|
||||
|
||||
Gotthard cannot be upgraded remotely
|
||||
|
||||
Except Eiger,
|
||||
upgrade
|
||||
Using command 'programfpga' or
|
||||
@ -103,7 +360,6 @@ This document describes the differences between vx.x.x and vx.0.2
|
||||
4 Kernel Requirements
|
||||
======================
|
||||
|
||||
|
||||
Blackfin
|
||||
--------
|
||||
Latest version: Fri Oct 29 00:00:00 2021
|
||||
@ -111,12 +367,10 @@ This document describes the differences between vx.x.x and vx.0.2
|
||||
Older ones will work, but might have issues with programming firmware via
|
||||
the package.
|
||||
|
||||
|
||||
Nios
|
||||
-----
|
||||
Compatible version: Mon May 10 18:00:21 CEST 2021
|
||||
|
||||
|
||||
Kernel Upgrade
|
||||
---------------
|
||||
Eiger via bit files
|
||||
|
@ -8,7 +8,7 @@ if [ ! -d "install" ]; then
|
||||
mkdir install
|
||||
fi
|
||||
cd build
|
||||
cmake .. -G Ninja \
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH=$CONDA_PREFIX \
|
||||
-DCMAKE_INSTALL_PREFIX=install \
|
||||
-DSLS_USE_TEXTCLIENT=ON \
|
||||
@ -18,7 +18,7 @@ cmake .. -G Ninja \
|
||||
-DSLS_USE_TESTS=ON \
|
||||
-DSLS_USE_PYTHON=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DSLS_USE_HDF5=OFF \
|
||||
-DSLS_USE_HDF5=OFF\
|
||||
|
||||
NCORES=$(getconf _NPROCESSORS_ONLN)
|
||||
echo "Building using: ${NCORES} cores"
|
11
conda-recipe/build_pylib.sh
Executable file
11
conda-recipe/build_pylib.sh
Executable file
@ -0,0 +1,11 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
echo "|<-------- starting python build"
|
||||
|
||||
cd python
|
||||
|
||||
# copy VERSION into slsdet for installation
|
||||
cp ../VERSION slsdet/VERSION
|
||||
|
||||
${PYTHON} setup.py install
|
8
conda-recipe/conda_build_config.yaml
Normal file
8
conda-recipe/conda_build_config.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
python:
|
||||
- 3.8
|
||||
- 3.9
|
||||
- 3.10
|
||||
- 3.11
|
||||
- 3.12
|
||||
- 3.13
|
||||
|
11
conda-recipe/copy_ctbgui.sh
Normal file
11
conda-recipe/copy_ctbgui.sh
Normal file
@ -0,0 +1,11 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
mkdir $PREFIX/lib
|
||||
mkdir $PREFIX/bin
|
||||
mkdir $PREFIX/include
|
||||
|
||||
|
||||
|
||||
cp build/bin/ctbGui $PREFIX/bin/.
|
||||
cp build/bin/libctbRootLib.so $PREFIX/lib/.
|
||||
|
@ -4,20 +4,18 @@
|
||||
mkdir -p $PREFIX/lib
|
||||
mkdir -p $PREFIX/bin
|
||||
mkdir -p $PREFIX/include/sls
|
||||
# mkdir $PREFIX/include/slsDetectorPackage
|
||||
|
||||
#Shared and static libraries
|
||||
cp build/install/lib/* $PREFIX/lib/
|
||||
|
||||
#Binaries
|
||||
cp build/install/bin/sls_detector_acquire $PREFIX/bin/.
|
||||
cp build/install/bin/sls_detector_acquire_zmq $PREFIX/bin/.
|
||||
cp build/install/bin/sls_detector_get $PREFIX/bin/.
|
||||
cp build/install/bin/sls_detector_put $PREFIX/bin/.
|
||||
cp build/install/bin/sls_detector_help $PREFIX/bin/.
|
||||
cp build/install/bin/sls_detector $PREFIX/bin/.
|
||||
cp build/install/bin/slsReceiver $PREFIX/bin/.
|
||||
cp build/install/bin/slsMultiReceiver $PREFIX/bin/.
|
||||
cp build/install/bin/slsFrameSynchronizer $PREFIX/bin/.
|
||||
|
||||
|
||||
cp build/install/include/sls/* $PREFIX/include/sls
|
125
conda-recipe/meta.yaml
Executable file
125
conda-recipe/meta.yaml
Executable file
@ -0,0 +1,125 @@
|
||||
package:
|
||||
name: sls_detector_software
|
||||
version: {{ environ.get('GIT_DESCRIBE_TAG', '') }}
|
||||
|
||||
|
||||
source:
|
||||
path: ..
|
||||
|
||||
build:
|
||||
number: 0
|
||||
binary_relocation: True
|
||||
rpaths:
|
||||
- lib/
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- cmake
|
||||
- qt 5.*
|
||||
- xorg-libx11
|
||||
- xorg-libice
|
||||
- xorg-libxext
|
||||
- xorg-libsm
|
||||
- xorg-libxau
|
||||
- xorg-libxrender
|
||||
- xorg-libxfixes
|
||||
- {{ cdt('mesa-libgl-devel') }} # [linux]
|
||||
- {{ cdt('mesa-libegl-devel') }} # [linux]
|
||||
- {{ cdt('mesa-dri-drivers') }} # [linux]
|
||||
- {{ cdt('libselinux') }} # [linux]
|
||||
- {{ cdt('libxdamage') }} # [linux]
|
||||
- {{ cdt('libxxf86vm') }} # [linux]
|
||||
- expat
|
||||
|
||||
host:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
- xorg-libx11
|
||||
- xorg-libice
|
||||
- xorg-libxext
|
||||
- xorg-libsm
|
||||
- xorg-libxau
|
||||
- xorg-libxrender
|
||||
- xorg-libxfixes
|
||||
- expat
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
|
||||
|
||||
outputs:
|
||||
- name: slsdetlib
|
||||
script: copy_lib.sh
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
|
||||
- name: slsdet
|
||||
script: build_pylib.sh
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
- setuptools
|
||||
- pybind11=2.13
|
||||
|
||||
host:
|
||||
- python
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
- setuptools
|
||||
- pybind11=2.13
|
||||
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
- python
|
||||
- numpy
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
||||
test:
|
||||
imports:
|
||||
- slsdet
|
||||
|
||||
|
||||
- name: slsdetgui
|
||||
script: copy_gui.sh
|
||||
requirements:
|
||||
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
||||
run:
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
- qt 5.*
|
||||
- expat
|
||||
|
||||
- name: moenchzmq
|
||||
script: copy_moench.sh
|
||||
requirements:
|
||||
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
||||
|
||||
run:
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
- expat
|
3
conda-recipe/run_test.sh
Executable file
3
conda-recipe/run_test.sh
Executable file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
ctest -j2
|
@ -1,13 +0,0 @@
|
||||
|
||||
c_compiler:
|
||||
- gcc # [linux]
|
||||
|
||||
c_stdlib:
|
||||
- sysroot # [linux]
|
||||
|
||||
cxx_compiler:
|
||||
- gxx # [linux]
|
||||
|
||||
|
||||
c_stdlib_version: # [linux]
|
||||
- 2.17 # [linux]
|
@ -1,77 +0,0 @@
|
||||
source:
|
||||
path: ../..
|
||||
|
||||
{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*(?:[\+\w\.]+))').group(1) %}
|
||||
package:
|
||||
name: sls_detector_software
|
||||
version: {{ version }}
|
||||
|
||||
build:
|
||||
number: 0
|
||||
binary_relocation: True
|
||||
rpaths:
|
||||
- lib/
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{ stdlib("c") }}
|
||||
- {{ compiler('cxx') }}
|
||||
- git
|
||||
- cmake
|
||||
- ninja
|
||||
- qt 5.*
|
||||
|
||||
host:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
- libgl-devel # [linux]
|
||||
- libtiff
|
||||
- zlib
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
|
||||
|
||||
outputs:
|
||||
- name: slsdetlib
|
||||
script: copy_lib.sh
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{ stdlib("c") }}
|
||||
- {{ compiler('cxx') }}
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
- libgcc-ng
|
||||
|
||||
|
||||
- name: slsdetgui
|
||||
script: copy_gui.sh
|
||||
requirements:
|
||||
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
||||
run:
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
- qt 5.*
|
||||
|
||||
|
||||
- name: moenchzmq
|
||||
script: copy_moench.sh
|
||||
requirements:
|
||||
|
||||
build:
|
||||
- {{ compiler('c') }}
|
||||
- {{compiler('cxx')}}
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||
|
||||
|
||||
run:
|
||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
@ -1,16 +0,0 @@
|
||||
python:
|
||||
- 3.11
|
||||
- 3.12
|
||||
- 3.13
|
||||
|
||||
c_compiler:
|
||||
- gcc # [linux]
|
||||
|
||||
c_stdlib:
|
||||
- sysroot # [linux]
|
||||
|
||||
cxx_compiler:
|
||||
- gxx # [linux]
|
||||
|
||||
c_stdlib_version: # [linux]
|
||||
- 2.17 # [linux]
|
@ -1,45 +0,0 @@
|
||||
source:
|
||||
path: ../..
|
||||
|
||||
{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*(?:[\+\w\.]+))').group(1) %}
|
||||
package:
|
||||
name: slsdet
|
||||
version: {{ version }}
|
||||
|
||||
build:
|
||||
number: 0
|
||||
script:
|
||||
- unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win]
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python {{python}}
|
||||
- {{ compiler('c') }}
|
||||
- {{ stdlib("c") }}
|
||||
- {{ compiler('cxx') }}
|
||||
|
||||
host:
|
||||
- cmake
|
||||
- ninja
|
||||
- python {{python}}
|
||||
- pip
|
||||
- scikit-build-core
|
||||
- pybind11 >=2.13.0
|
||||
- fmt
|
||||
- zeromq
|
||||
- nlohmann_json
|
||||
- catch2
|
||||
|
||||
run:
|
||||
- python {{python}}
|
||||
- numpy
|
||||
|
||||
|
||||
test:
|
||||
imports:
|
||||
- slsdet
|
||||
|
||||
|
||||
about:
|
||||
summary: An example project built with pybind11 and scikit-build.
|
||||
# license_file: LICENSE
|
@ -40,7 +40,6 @@ set(SPHINX_SOURCE_FILES
|
||||
src/pydetector.rst
|
||||
src/pyenums.rst
|
||||
src/pyexamples.rst
|
||||
src/pyPatternGenerator.rst
|
||||
src/servers.rst
|
||||
src/receiver_api.rst
|
||||
src/result.rst
|
||||
@ -54,7 +53,6 @@ set(SPHINX_SOURCE_FILES
|
||||
src/serverdefaults.rst
|
||||
src/quick_start_guide.rst
|
||||
src/troubleshooting.rst
|
||||
src/pattern.rst
|
||||
src/receivers.rst
|
||||
src/slsreceiver.rst
|
||||
src/udpheader.rst
|
||||
|
@ -63,4 +63,4 @@ html_static_path = ['static']
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_css_file('css/extra.css') # may also be an URL
|
||||
app.add_stylesheet('css/extra.css') # may also be an URL
|
@ -21,7 +21,7 @@ print('\n\n\n\n SERVER CSV')
|
||||
|
||||
src = Path('@CMAKE_SOURCE_DIR@')/'slsDetectorServers/'
|
||||
detectors = ['Mythen3', 'Gotthard2', 'Eiger',
|
||||
'Jungfrau', 'Moench', 'Ctb']
|
||||
'Jungfrau', 'Moench', 'Gotthard', 'Ctb']
|
||||
|
||||
|
||||
for det in detectors:
|
||||
|
@ -320,6 +320,61 @@ Moench
|
||||
}
|
||||
}
|
||||
|
||||
Gotthard I
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
{
|
||||
"Version": 7.2,
|
||||
"Timestamp": "Wed Nov 13 15:16:19 2024",
|
||||
"Detector Type": "Gotthard",
|
||||
"Timing Mode": "auto",
|
||||
"Geometry": {
|
||||
"x": 1,
|
||||
"y": 1
|
||||
},
|
||||
"Image Size in bytes": 2560,
|
||||
"Pixels": {
|
||||
"x": 1280,
|
||||
"y": 1
|
||||
},
|
||||
"Max Frames Per File": 20000,
|
||||
"Frame Discard Policy": "nodiscard",
|
||||
"Frame Padding": 1,
|
||||
"Scan Parameters": "[disabled]",
|
||||
"Total Frames": 1,
|
||||
"Receiver Roi": {
|
||||
"xmin": 4294967295,
|
||||
"xmax": 4294967295,
|
||||
"ymin": 4294967295,
|
||||
"ymax": 4294967295
|
||||
},
|
||||
"Exptime": "1.00001ms",
|
||||
"Period": "1s",
|
||||
"Detector Roi": {
|
||||
"xmin": 4294967295,
|
||||
"xmax": 4294967295
|
||||
},
|
||||
"Frames in File": 1,
|
||||
"Frame Header Format": {
|
||||
"Frame Number": "8 bytes",
|
||||
"SubFrame Number/ExpLength": "4 bytes",
|
||||
"Packet Number": "4 bytes",
|
||||
"Bunch ID": "8 bytes",
|
||||
"Timestamp": "8 bytes",
|
||||
"Module Id": "2 bytes",
|
||||
"Row": "2 bytes",
|
||||
"Column": "2 bytes",
|
||||
"Reserved": "2 bytes",
|
||||
"Debug": "4 bytes",
|
||||
"Round Robin Number": "2 bytes",
|
||||
"Detector Type": "1 byte",
|
||||
"Header Version": "1 byte",
|
||||
"Packets Caught Mask": "64 bytes"
|
||||
}
|
||||
}
|
||||
|
||||
Chip Test Board
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
@ -359,7 +414,6 @@ Chip Test Board
|
||||
"Digital Flag": 0,
|
||||
"Digital Samples": 1000,
|
||||
"Dbit Offset": 0,
|
||||
"Dbit Reorder": 1,
|
||||
"Dbit Bitset": 0,
|
||||
"Transceiver Mask": "0x3",
|
||||
"Transceiver Flag": 0,
|
||||
|
@ -4,54 +4,11 @@ Command line interface
|
||||
Usage
|
||||
-------------
|
||||
|
||||
The syntax is *'[detector index]-[module index]:[command]'*, where the indices are by default '0', when not specified.
|
||||
|
||||
Module index
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Modules are indexed based on their order in the hostname command. They are used to configure a specific module within a detector and are followed by a ':' in syntax.
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Applies to all modules of detector 0
|
||||
sls_detector_put exptime 5s
|
||||
|
||||
# Applies to only the 4th module
|
||||
sls_detector_put 3:exptime 5s
|
||||
|
||||
|
||||
Detector index
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
This index is useful when configuring multiple detectors from a single host. Each detector uses a unique shared memory identified by a detector index, derived again from the hostname command. It is followed by a '-'.
|
||||
|
||||
.. code-block::
|
||||
|
||||
# For detector with index 2 in shared memory
|
||||
sls_detector_put 2-hostname bchip133+bchip123+bchip456
|
||||
|
||||
# Without '-', the detector index defaults to 0
|
||||
sls_detector_put hostname bchip133+bchip123+bchip456
|
||||
|
||||
# Accessing all modules with detector index 2
|
||||
sls_detector_put 2-exptime
|
||||
|
||||
# Starting acquisition only for detector with index 2
|
||||
sls_detector_put 2-start
|
||||
|
||||
# Applies only to the 2nd detector, 4th module
|
||||
sls_detector_put 1-3:exptime 5s
|
||||
|
||||
|
||||
Command Execution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Commands can be executed using:
|
||||
|
||||
* **sls_detector_put**: setting values
|
||||
* **sls_detector_get**: getting values
|
||||
* **sls_detector**: automatically infers based on the number of arguments.
|
||||
* **sls_detector_help**: gets help on the specific command
|
||||
* **sls_detector_acquire**: initiates acquisition with the detector. This command blocks until the entire acquisition process is completed.
|
||||
Commands can be used either with sls_detector_get or sls_detector_put
|
||||
|
||||
.. code-block::
|
||||
|
||||
sls_detector_get exptime
|
||||
|
||||
Help
|
||||
--------
|
||||
@ -71,15 +28,12 @@ Help
|
||||
# list of deprecated commands
|
||||
list deprecated
|
||||
|
||||
|
||||
Autocompletion
|
||||
---------------
|
||||
|
||||
bash_autocomplete.sh or zsh_autocomplete.sh must be sourced from the main package folder to enable auto completion of commands and arguments for the command line on that shell.
|
||||
|
||||
.. code-block::
|
||||
|
||||
# autocompletion
|
||||
# bash_autocomplete.sh or zsh_autocomplete.sh must be sourced from the
|
||||
# main package folder to enable auto completion of commands and arguments
|
||||
# for the command line on that shell.
|
||||
source bash_autocomplete.sh
|
||||
|
||||
|
||||
|
||||
Commands
|
||||
|
@ -13,6 +13,7 @@ containing results from all modules. (:ref:`Result class<Result Class>`)
|
||||
|
||||
Here are some :ref:`examples <Cplusplus Api Examples>` on how to use the API.
|
||||
|
||||
.. _Cplusplus Api Examples:
|
||||
.. doxygenclass:: sls::Detector
|
||||
:members:
|
||||
:undoc-members:
|
@ -131,6 +131,42 @@ Program from console
|
||||
|
||||
|
||||
|
||||
Gotthard I
|
||||
-----------
|
||||
|
||||
Download
|
||||
^^^^^^^^^^^^^
|
||||
- detector server corresponding to package in slsDetectorPackage/serverBin
|
||||
|
||||
- `pof files <https://github.com/slsdetectorgroup/slsDetectorFirmware>`__
|
||||
|
||||
|
||||
.. _firmware upgrade using blaster for blackfin:
|
||||
|
||||
Upgrade
|
||||
^^^^^^^^
|
||||
.. warning ::
|
||||
| Gotthard firmware cannot be upgraded remotely and requires the use of USB-Blaster.
|
||||
| It is generally updated by us.
|
||||
|
||||
#. Download `Altera Quartus software or Quartus programmer <https://fpgasoftware.intel.com/20.1/?edition=standard&platform=linux&product=qprogrammer#tabs-4>`__.
|
||||
|
||||
|
||||
#. Start Quartus programmer, click on Hardware Setup. In the "Currently selected hardware" window, select USB-Blaster.
|
||||
|
||||
#. In the Mode combo box, select "Active Serial Programming".
|
||||
|
||||
#. Plug the end of your USB-Blaster with the adaptor provided to the connector 'AS config' on the Gotthard board.
|
||||
|
||||
#. Click on 'Add file'. Select programming (pof) file provided by us.
|
||||
|
||||
#. Check "Program/Configure" and "Verify". Push the start button. Wait until the programming process is finished.
|
||||
|
||||
#. In case of error messages, check the polarity of cable (that pin1 corresponds) and that the correct programming connector is selected.
|
||||
|
||||
#. Reboot the detector.
|
||||
|
||||
|
||||
Mythen III
|
||||
-----------
|
||||
|
||||
@ -360,3 +396,7 @@ How to get back mtd3 drive remotely (udpating kernel)
|
||||
more /proc/mtd # verify mtd3 is listed
|
||||
|
||||
|
||||
Last Resort using USB Blaster
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If none of these steps work, the last resort might be physically upgrading the firmware using a USB blaster, which also requires opening up the detector. Instructions for all the blackfin detectors are the same as the one for :ref:`gotthard firmware upgrade <firmware upgrade using blaster for blackfin>`.
|
@ -36,12 +36,10 @@ Welcome to slsDetectorPackage's documentation!
|
||||
pydetector
|
||||
pyenums
|
||||
pyexamples
|
||||
pyPatternGenerator
|
||||
pattern
|
||||
|
||||
.. toctree::
|
||||
:caption: Command line
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
|
||||
commandline
|
||||
quick_start_guide
|
||||
|
@ -23,15 +23,11 @@ Conda is not only useful to manage python environments but can also
|
||||
be used as a user space package manager. Dates in the tag (for eg. 2020.07.23.dev0)
|
||||
are from the developer branch. Please use released tags for stability.
|
||||
|
||||
We have four different packages available:
|
||||
============== =============================================
|
||||
Package Description
|
||||
============== =============================================
|
||||
slsdetlib shared libraries and command line utilities
|
||||
slsdetgui GUI
|
||||
slsdet Python bindings
|
||||
moenchzmq moench
|
||||
============== =============================================
|
||||
We have three different packages available:
|
||||
|
||||
* **slsdetlib** shared libraries and command line utilities
|
||||
* **slsdetgui** GUI
|
||||
* **slsdet** Python bindings
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -47,7 +43,7 @@ We have four different packages available:
|
||||
|
||||
#ready to use
|
||||
sls_detector_get exptime
|
||||
...
|
||||
etc ...
|
||||
|
||||
|
||||
.. code-block:: bash
|
||||
@ -59,8 +55,6 @@ We have four different packages available:
|
||||
conda search slsdet
|
||||
# gui
|
||||
conda search slsdetgui
|
||||
# moench
|
||||
conda search moenchzmq
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
|
||||
.. _master file attributes:
|
||||
|
||||
Master File Attributes
|
||||
=======================
|
||||
|
||||
@ -288,6 +287,56 @@ Moench
|
||||
| Frame Header Format | Expected frame header format for the data files |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
|
||||
Gotthard I
|
||||
^^^^^^^^^^^
|
||||
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| **Key** | **Description** |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Version | Version of the master file |
|
||||
| | Current value:8.0 |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Timestamp | Timestamp of creation of master file |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Detector Type | Detector type |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Timing Mode | Timing Mode |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Geometry | Number of UDP ports in x and y dimension for |
|
||||
| | complete detector |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Image Size in bytes | Image size in bytes per UDP port |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Pixels | Number of pixels in x and y dimension |
|
||||
| | per UDP port |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Max Frames Per File | Maximum frames per file |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Frame Discard Policy | Receiever Frame discard policy |
|
||||
| | for partial frames |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Frame Padding | Receiver Frame padding enable |
|
||||
| | for partial frames |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Scan Parameters | Scanning mode on detector |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Total Frames | Total number of frames and triggers expected |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Receiver Roi | Receiver ROI in file including xmax and ymax |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Exptime | Exposure time |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Period | Period between frames |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Detector Roi | Roi in detector restricted to an ADC. |
|
||||
| | Includes xmax |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Burst Mode | Burst mode of detector |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Frames in File | Number of frames written to file by Receiver 0 |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Frame Header Format | Expected frame header format for the data files |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
|
||||
Chip Test Board
|
||||
^^^^^^^^^^^^^^^
|
||||
@ -345,9 +394,6 @@ Chip Test Board
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Dbit Offset | Digital offset of valid data in bytes |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Dbit Reorder | Reorder such that it groups each signal (0-63) |
|
||||
| | from all the different samples together |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Dbit Bitset | Digital 64 bit mask of bits enabled in receiver |
|
||||
+-----------------------+-------------------------------------------------+
|
||||
| Transceiver Mask | Mask of channels enabled in Transceiver |
|
||||
|
@ -1,122 +0,0 @@
|
||||
Pattern
|
||||
========================
|
||||
|
||||
This is a test and development feature implemented only for Ctb, Xilinx_Ctb and Mythen3.
|
||||
|
||||
A pattern is a sequence of 64-bit words which is executed using a clock on the FPGA. Each of the 64 bits is connected to a pin or internal signal of the FPGA. The purpose of a pattern is to provide a way to change these 64 signals with precise timing. Commands run by the detector server could manipulate the same signals as the pattern, but they cannot enforce a change in a specific clock cycle.
|
||||
|
||||
**Usage**
|
||||
|
||||
A pattern is written to memory on the FPGA using the patword command.
|
||||
|
||||
.. code-block::
|
||||
|
||||
patword 0x0000 0x000000000000000A
|
||||
patword 0x0001 0x000000000000000B
|
||||
patword 0x0002 0x000000000000000C
|
||||
patword 0x0003 0x000000000000000D
|
||||
patword 0x0004 0x000000000000000E
|
||||
|
||||
The example above writes a five-word pattern into FPGA memory. The first argument is the memory address, the second argument is the content to be written into this address. Before executing a pattern one has to set the address limits of the pattern:
|
||||
|
||||
.. code-block::
|
||||
|
||||
patlimits 0x0000 0x0004
|
||||
|
||||
This instructs the firmware to execute the commands from address 0 to 4 (including 0 and 4). The execution can be started from the pyctbgui or with the commands
|
||||
|
||||
.. code-block::
|
||||
|
||||
start [Ctb, Xilinx_Ctb]
|
||||
patternstart [Mythen3]
|
||||
|
||||
The maximal number of patword addresses is 8192. However, it is possible to extend the length of the pattern sequence using loops and wait commands. Loops can be configured with the following commands:
|
||||
|
||||
.. code-block::
|
||||
|
||||
patloop 0 0x0001 0x0003
|
||||
patnloop 0 7
|
||||
|
||||
The first argument of both commands is the ID of the loop. Ctb and Xilinx_Ctb can have 6 loops (ID 0-5), Mythen3 can have 4 loop definitions. The commands above configure the loop with ID 0 to run 7 times and jump from the patword with address 3 to the patword with address 1. Important: If patnloop is set to 1, the addresses 0x1-0x3 will execute exactly once; if it is set to 0, the pattern addresses will be skipped.
|
||||
|
||||
The same idea is used to introduce wait times. The example below causes the patword at address 0x0002 to be active for 9 clock cycles before the execution continues.
|
||||
|
||||
.. code-block::
|
||||
|
||||
patwait 0 0x0002
|
||||
patwaittime 0 9
|
||||
|
||||
Waits can be placed inside a loop and loops can be nested.
|
||||
|
||||
**patioctrl**
|
||||
|
||||
The function of each bit in the sequence of 64-bit words depends on the connected detector and firmware version. Some of the 64 bits might connect directly to pads of a chip. The patioctrl command is used to configure the direction of some of these signals (not all of them !! See tables below). Signals where the corresponding bit in the argument of patioctrl is set to 1 will be driven from the FPGA.
|
||||
|
||||
**patsetbit and patmask**
|
||||
|
||||
The functions patsetbit and patmask can be used to ignore a specific bit of the pattern.
|
||||
Example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
patmask 0x0101
|
||||
patsetbit 0x0001
|
||||
|
||||
Patmask configures bit 0 and 8 of the pattern to be set to their value in patsetbit. These bits will be ignored during pattern execution and will always be 0 (bit 8) and 1 (bit 0).
|
||||
|
||||
The mappings of bit positions in the pattern word to signals/pads of the FPGA are listed below for the three detector types where patterns are used. In the case of the two CTB's, connections of the signals to actual pads of a chip depend on the layout of the used detector adapter board. Therefore, each type of detector adapter board adds an additional mapping layer.
|
||||
|
||||
**CTB Pattern Bit Mapping**
|
||||
|
||||
.. table::
|
||||
|
||||
+----+---+------+----+----------+-------------------+----------------+
|
||||
| 63 | 62| 61-57| 56 | 55-48 | 47-32 | 31-0 |
|
||||
+----+---+------+----+----------+-------------------+----------------+
|
||||
| A | D| --- | T | EXTIO | DO, stream source | DIO |
|
||||
+----+---+------+----+----------+-------------------+----------------+
|
||||
|
||||
DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever one of these statemachines is running (currently bits 7,8,11,14 and 20).
|
||||
|
||||
DO: Directly connected to 16 FPGA pins. Output only. Not influenced by patioctrl. Also connected to bit 47-32 in all Ctb dbit samples. All of them can be used as dbit sample trigger. In addition, every bit of DO can be selected as trigger for sending out a udp packet with samples to the receiver.
|
||||
|
||||
EXTIO: Similar to DIO, but not used as input to the fpga. With the corresponding patioctrl bits set to 0 these pins will switch to a high impedance mode and be ignored by the firmware.
|
||||
|
||||
T: trigger output
|
||||
|
||||
D: enable signal for digital sampling
|
||||
|
||||
A: adc enable
|
||||
|
||||
**Xilinx_CTB Pattern Bit Mapping**
|
||||
|
||||
.. table::
|
||||
|
||||
+-------+----------------+
|
||||
| 63-32 | 31-0 |
|
||||
+-------+----------------+
|
||||
| --- | DIO |
|
||||
+-------+----------------+
|
||||
|
||||
DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever these sm's are running (currently bits 7,8,11,14 and 20).
|
||||
|
||||
|
||||
**Mythen3 Pattern Bit Mapping**
|
||||
|
||||
.. table::
|
||||
|
||||
+-------+--------+-------+--------+------------+----------+----------+-----+-----+
|
||||
| 63-33 | 32 | 31-25 | 24 | 23 | 22 | 21 | 20 | 19 |
|
||||
+-------+--------+-------+--------+------------+----------+----------+-----+-----+
|
||||
| --- | signARD| --- | CHSclk | cnt_rst | sto_rst | STATLOAD | STO | SIN |
|
||||
+-------+--------+-------+--------+------------+----------+----------+-----+-----+
|
||||
|
||||
.. table::
|
||||
|
||||
+---------+-----+-------+-------+----+-------+---------+--------+
|
||||
| 18 | 17 | 16-14 | 13 | 12 | 11 | 10 | 9-0 |
|
||||
+---------+-----+-------+-------+----+-------+---------+--------+
|
||||
| SR_MODE | clk | EN | PULSE | RD | CHSIN | ANAMode | TBLOAD |
|
||||
+---------+-----+-------+-------+----+-------+---------+--------+
|
||||
|
||||
For Mythen3 the pattern word only connects to output pins of the FPGA when the pattern is running. Afterwards the signals will switch back to other logic in the FPGA. Both CTB's hold the last executed pattern word until a new pattern is started.
|
@ -1,34 +0,0 @@
|
||||
PatternGenerator
|
||||
=====================================================
|
||||
|
||||
Python class to generate patterns for the Chip Test Board.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from slsdet import PatternGenerator
|
||||
|
||||
p = PatternGenerator()
|
||||
p.SB(5)
|
||||
p.PW()
|
||||
p.SB(8,9)
|
||||
p.PW()
|
||||
p.CB(5)
|
||||
|
||||
Created a pattern like this:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
patword 0x0000 0x0000000000000020
|
||||
patword 0x0001 0x0000000000000320
|
||||
patword 0x0002 0x0000000000000300
|
||||
patioctrl 0x0000000000000000
|
||||
patlimits 0x0000 0x0002
|
||||
...
|
||||
|
||||
.. py:currentmodule:: slsdet
|
||||
|
||||
.. autoclass:: PatternGenerator
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
:inherited-members:
|
@ -128,10 +128,6 @@ For Multiple Modules
|
||||
# set file path
|
||||
fpath /tmp
|
||||
|
||||
.. note ::
|
||||
The **hostname** and **detsize** command in a multi module system can affect the row and column values in the udp/zmq header. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on.
|
||||
|
||||
|
||||
Gui
|
||||
----
|
||||
|
||||
|
@ -89,3 +89,18 @@ DACS
|
||||
:widths: 35, 35
|
||||
:header-rows: 1
|
||||
|
||||
Gotthard
|
||||
-------------
|
||||
|
||||
.. csv-table:: Default values
|
||||
:file: gotthard.csv
|
||||
:widths: 35, 35
|
||||
:header-rows: 1
|
||||
|
||||
DACS
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. csv-table:: Gotthard DACS
|
||||
:file: gotthard-dacs.csv
|
||||
:widths: 35, 35
|
||||
:header-rows: 1
|
@ -27,24 +27,25 @@ Arguments
|
||||
-p, --port <port> : TCP communication port with client.
|
||||
-g, --nomodule : [Mythen3][Gotthard2]
|
||||
Generic or No Module mode. Skips detector type checks.
|
||||
-f, --phaseshift <value> : [Gotthard] only. Sets phase shift.
|
||||
-d, --devel : Developer mode. Skips firmware checks.
|
||||
-u, --update : Update mode. Skips firmware checks and initial detector setup.
|
||||
-i, --ignore-config : [Eiger][Jungfrau][Gotthard2][Moench]
|
||||
-i, --ignore-config : [Eiger][Jungfrau][Gotthard][Gotthard2][Moench]
|
||||
Ignore config file.
|
||||
-m, --master <master> : [Eiger][Mythen3][Gotthard2]
|
||||
-m, --master <master> : [Eiger][Mythen3][Gotthard][Gotthard2]
|
||||
Set Master to 0 or 1. Precedence over config file. Only for virtual servers except Eiger.
|
||||
-t, --top <top> : [Eiger] Set Top to 0 or 1. Precedence over config file.
|
||||
-s, --stopserver : Stop server. Do not use as it is created by control server
|
||||
|
||||
|
||||
.. _Automatic start servers:
|
||||
|
||||
Automatic start
|
||||
------------------
|
||||
|
||||
One can start the on-board detector server automatically upon powering on the board.
|
||||
|
||||
#. Create a soft link to the binary on board:
|
||||
#. Create a soft link to the binary on board
|
||||
:
|
||||
.. code-block:: bash
|
||||
|
||||
ln -sf someDetectorServervx.x.x someDetectorServer
|
||||
@ -64,7 +65,7 @@ One can start the on-board detector server automatically upon powering on the bo
|
||||
/home/root/executables/eigerDetectorServer &> /dev/null &
|
||||
exit 0
|
||||
|
||||
Jungfrau | Moench | CTB
|
||||
Jungfrau | Moench | CTB | Gotthard I
|
||||
.. code-block:: bash
|
||||
|
||||
# Edit inittab on board
|
||||
@ -86,7 +87,8 @@ One can start the on-board detector server automatically upon powering on the bo
|
||||
/root/xxxDetectorServer >> /dev/null &
|
||||
|
||||
|
||||
#. Sync, reboot and verify:
|
||||
#. Sync, reboot and verify
|
||||
:
|
||||
.. code-block:: bash
|
||||
|
||||
sync
|
||||
|
@ -385,6 +385,14 @@ Cannot get data without a module attached
|
||||
You cannot get data without a module attached as a specific pin is floating. Attach module to get data.
|
||||
|
||||
|
||||
Gotthard
|
||||
----------
|
||||
|
||||
|
||||
Missing first frame or next frame after a delay
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Connect the data link from the Module directly to receiver pc or to a private network.
|
||||
|
||||
|
||||
Mythen3
|
||||
--------
|
||||
|
@ -73,9 +73,9 @@ Description
|
||||
|
||||
* **modId**: module ID picked up from det_id_[detector type].txt on the detector cpu.
|
||||
|
||||
* **row**: row position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on.
|
||||
* **row**: row position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command.
|
||||
|
||||
* **column**: column position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on.
|
||||
* **column**: column position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command.
|
||||
|
||||
* **detType**: detector type from enum of detectorType in the package.
|
||||
|
||||
@ -92,14 +92,14 @@ Detector Enum
|
||||
================ ========
|
||||
GENERIC 0
|
||||
EIGER 1
|
||||
GOTTHARD* 2
|
||||
GOTTHARD 2
|
||||
JUNGFRAU 3
|
||||
CHIPTESTBOARD 4
|
||||
MOENCH 5
|
||||
MYTHEN3 6
|
||||
GOTTHARD2 7
|
||||
================ ========
|
||||
* deprecated since v10.0.0
|
||||
|
||||
|
||||
|
||||
Previous Versions
|
||||
|
@ -22,6 +22,7 @@ Binaries
|
||||
|
||||
eigerDetectorServer_virtual
|
||||
jungfrauDetectorServer_virtual
|
||||
gotthardDetectorServer_virtual
|
||||
gotthard2DetectorServer_virtual
|
||||
mythen3DetectorServer_virtual
|
||||
moenchDetectorServer_virtual
|
||||
|
12
examples/gotthard.config
Executable file
12
examples/gotthard.config
Executable file
@ -0,0 +1,12 @@
|
||||
# detector hostname
|
||||
hostname bchip007
|
||||
|
||||
# receiver pc hostname of 1Gb IP of the machine
|
||||
rx_hostname my_receiver_hostname
|
||||
|
||||
# output directory
|
||||
fpath /bigRAID/datadir_gotthard/rec_test_data
|
||||
|
||||
# high voltage
|
||||
highvoltage 120
|
||||
|
@ -1,18 +0,0 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index dd3d8eb9..c0187747 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -1,11 +1,8 @@
|
||||
# CMake build script for ZeroMQ
|
||||
project(ZeroMQ)
|
||||
|
||||
-if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
||||
- cmake_minimum_required(VERSION 3.0.2)
|
||||
-else()
|
||||
- cmake_minimum_required(VERSION 2.8.12)
|
||||
-endif()
|
||||
+cmake_minimum_required(VERSION 3.15)
|
||||
+message(STATUS "Patched cmake version")
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckCCompilerFlag)
|
@ -11,7 +11,4 @@ slsDetectorPackage/8.0.1_rh7 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/8.0.1_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/8.0.2_rh7 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/8.0.2_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/9.0.0_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
slsDetectorPackage/9.1.0_rh8 stable cmake/3.15.5 Qt/5.12.10
|
||||
|
||||
|
||||
|
@ -14,8 +14,6 @@ from pyctbgui.utils.defines import Defines
|
||||
import pyctbgui.utils.pixelmap as pm
|
||||
from pyctbgui.utils.recordOrApplyPedestal import recordOrApplyPedestal
|
||||
|
||||
from slsdet import detectorType
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from pyctbgui.services import AcquisitionTab, PlotTab
|
||||
|
||||
@ -32,7 +30,6 @@ class AdcTab(QtWidgets.QWidget):
|
||||
self.acquisitionTab: AcquisitionTab | None = None
|
||||
self.legend: LegendItem | None = None
|
||||
self.logger = logging.getLogger('AdcTab')
|
||||
self.tengiga = True
|
||||
|
||||
def setup_ui(self):
|
||||
self.plotTab = self.mainWindow.plotTab
|
||||
@ -45,12 +42,6 @@ class AdcTab(QtWidgets.QWidget):
|
||||
self.legend.clear()
|
||||
# subscribe to toggle legend
|
||||
self.plotTab.subscribeToggleLegend(self.updateLegend)
|
||||
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
self.view.checkBoxADC0_15Inv.setDisabled(True)
|
||||
self.view.checkBoxADC16_31Inv.setDisabled(True)
|
||||
self.view.lineEditADCInversion.setDisabled(True)
|
||||
self.view.labelADCInversion.setDisabled(True)
|
||||
|
||||
def initializeAllAnalogPlots(self):
|
||||
self.mainWindow.plotAnalogWaveform = pg.plot()
|
||||
@ -76,8 +67,7 @@ class AdcTab(QtWidgets.QWidget):
|
||||
|
||||
def connect_ui(self):
|
||||
for i in range(Defines.adc.count):
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
getattr(self.view, f"checkBoxADC{i}Inv").stateChanged.connect(partial(self.setADCInv, i))
|
||||
getattr(self.view, f"checkBoxADC{i}Inv").stateChanged.connect(partial(self.setADCInv, i))
|
||||
getattr(self.view, f"checkBoxADC{i}En").stateChanged.connect(partial(self.setADCEnable, i))
|
||||
getattr(self.view, f"checkBoxADC{i}Plot").stateChanged.connect(partial(self.setADCEnablePlot, i))
|
||||
getattr(self.view, f"pushButtonADC{i}").clicked.connect(partial(self.selectADCColor, i))
|
||||
@ -87,17 +77,15 @@ class AdcTab(QtWidgets.QWidget):
|
||||
self.view.checkBoxADC0_15Plot.stateChanged.connect(partial(self.setADCEnablePlotRange, 0, Defines.adc.half))
|
||||
self.view.checkBoxADC16_31Plot.stateChanged.connect(
|
||||
partial(self.setADCEnablePlotRange, Defines.adc.half, Defines.adc.count))
|
||||
self.view.lineEditADCEnable.editingFinished.connect(self.setADCEnableReg)
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.view.checkBoxADC0_15Inv.stateChanged.connect(partial(self.setADCInvRange, 0, Defines.adc.half))
|
||||
self.view.checkBoxADC16_31Inv.stateChanged.connect(
|
||||
self.view.checkBoxADC0_15Inv.stateChanged.connect(partial(self.setADCInvRange, 0, Defines.adc.half))
|
||||
self.view.checkBoxADC16_31Inv.stateChanged.connect(
|
||||
partial(self.setADCInvRange, Defines.adc.half, Defines.adc.count))
|
||||
self.view.lineEditADCInversion.editingFinished.connect(self.setADCInvReg)
|
||||
self.view.lineEditADCInversion.editingFinished.connect(self.setADCInvReg)
|
||||
self.view.lineEditADCEnable.editingFinished.connect(self.setADCEnableReg)
|
||||
|
||||
def refresh(self):
|
||||
self.updateADCNames()
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.updateADCInv()
|
||||
self.updateADCInv()
|
||||
self.updateADCEnable()
|
||||
|
||||
# ADCs Tab functions
|
||||
@ -208,11 +196,9 @@ class AdcTab(QtWidgets.QWidget):
|
||||
return decoder.decode(analog_array, pm.moench04_analog())
|
||||
|
||||
def getADCEnableReg(self):
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.tengiga = self.det.tengiga
|
||||
retval = self.det.adcenable10g
|
||||
if not self.tengiga:
|
||||
retval = self.det.adcenable
|
||||
retval = self.det.adcenable
|
||||
if self.det.tengiga:
|
||||
retval = self.det.adcenable10g
|
||||
self.view.lineEditADCEnable.editingFinished.disconnect()
|
||||
self.view.lineEditADCEnable.setText("0x{:08x}".format(retval))
|
||||
self.view.lineEditADCEnable.editingFinished.connect(self.setADCEnableReg)
|
||||
@ -221,8 +207,8 @@ class AdcTab(QtWidgets.QWidget):
|
||||
def setADCEnableReg(self):
|
||||
self.view.lineEditADCEnable.editingFinished.disconnect()
|
||||
try:
|
||||
mask = int(self.view.lineEditADCEnable.text(), 16)
|
||||
if self.tengiga:
|
||||
mask = int(self.mainWindow.lineEditADCEnable.text(), 16)
|
||||
if self.det.tengiga:
|
||||
self.det.adcenable10g = mask
|
||||
else:
|
||||
self.det.adcenable = mask
|
||||
@ -253,7 +239,7 @@ class AdcTab(QtWidgets.QWidget):
|
||||
def setADCEnable(self, i):
|
||||
checkBox = getattr(self.view, f"checkBoxADC{i}En")
|
||||
try:
|
||||
if self.tengiga:
|
||||
if self.det.tengiga:
|
||||
enableMask = manipulate_bit(checkBox.isChecked(), self.det.adcenable10g, i)
|
||||
self.det.adcenable10g = enableMask
|
||||
else:
|
||||
@ -279,7 +265,7 @@ class AdcTab(QtWidgets.QWidget):
|
||||
for i in range(start_nr, end_nr):
|
||||
mask = manipulate_bit(checkBox.isChecked(), mask, i)
|
||||
try:
|
||||
if self.tengiga:
|
||||
if self.det.tengiga:
|
||||
self.det.adcenable10g = mask
|
||||
else:
|
||||
self.det.adcenable = mask
|
||||
@ -358,7 +344,7 @@ class AdcTab(QtWidgets.QWidget):
|
||||
def setADCInvReg(self):
|
||||
self.view.lineEditADCInversion.editingFinished.disconnect()
|
||||
try:
|
||||
self.det.adcinvert = int(self.view.lineEditADCInversion.text(), 16)
|
||||
self.det.adcinvert = int(self.mainWindow.lineEditADCInversion.text(), 16)
|
||||
except Exception as e:
|
||||
QtWidgets.QMessageBox.warning(self.mainWindow, "ADC Inversion Fail", str(e), QtWidgets.QMessageBox.Ok)
|
||||
pass
|
||||
@ -409,12 +395,7 @@ class AdcTab(QtWidgets.QWidget):
|
||||
self.updateADCInv()
|
||||
|
||||
def saveParameters(self) -> list[str]:
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
return [
|
||||
f"adcenable {self.view.lineEditADCEnable.text()}",
|
||||
f"adcinvert {self.view.lineEditADCInversion.text()}",
|
||||
]
|
||||
else:
|
||||
return [
|
||||
f"adcenable {self.view.lineEditADCEnable.text()}"
|
||||
]
|
||||
return [
|
||||
f"adcenable {self.view.lineEditADCEnable.text()}",
|
||||
f"adcinvert {self.view.lineEditADCInversion.text()}",
|
||||
]
|
||||
|
@ -7,7 +7,7 @@ import zmq
|
||||
from PyQt5 import QtWidgets, uic
|
||||
import logging
|
||||
|
||||
from slsdet import readoutMode, runStatus, detectorType
|
||||
from slsdet import readoutMode, runStatus
|
||||
from pyctbgui.utils.defines import Defines
|
||||
from pyctbgui.utils.numpyWriter.npy_writer import NumpyFileManager
|
||||
from pyctbgui.utils.numpyWriter.npz_writer import NpzFileWriter
|
||||
@ -49,37 +49,20 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
self.adcTab = self.mainWindow.adcTab
|
||||
self.plotTab = self.mainWindow.plotTab
|
||||
self.toggleStartButton(False)
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
self.view.labelRunF.setDisabled(True)
|
||||
self.view.labelADCF.setDisabled(True)
|
||||
self.view.labelADCPhase.setDisabled(True)
|
||||
self.view.labelADCPipeline.setDisabled(True)
|
||||
self.view.labelDBITF.setDisabled(True)
|
||||
self.view.labelDBITPhase.setDisabled(True)
|
||||
self.view.labelDBITPipeline.setDisabled(True)
|
||||
self.view.spinBoxRunF.setDisabled(True)
|
||||
self.view.spinBoxADCF.setDisabled(True)
|
||||
self.view.spinBoxADCPhase.setDisabled(True)
|
||||
self.view.spinBoxADCPipeline.setDisabled(True)
|
||||
self.view.spinBoxDBITF.setDisabled(True)
|
||||
self.view.spinBoxDBITPhase.setDisabled(True)
|
||||
self.view.spinBoxDBITPipeline.setDisabled(True)
|
||||
|
||||
def connect_ui(self):
|
||||
# For Acquistions Tab
|
||||
self.view.comboBoxROMode.currentIndexChanged.connect(self.setReadOut)
|
||||
self.view.spinBoxRunF.editingFinished.connect(self.setRunFrequency)
|
||||
self.view.spinBoxTransceiver.editingFinished.connect(self.setTransceiver)
|
||||
self.view.spinBoxAnalog.editingFinished.connect(self.setAnalog)
|
||||
self.view.spinBoxDigital.editingFinished.connect(self.setDigital)
|
||||
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.view.spinBoxRunF.editingFinished.connect(self.setRunFrequency)
|
||||
self.view.spinBoxADCF.editingFinished.connect(self.setADCFrequency)
|
||||
self.view.spinBoxADCPhase.editingFinished.connect(self.setADCPhase)
|
||||
self.view.spinBoxADCPipeline.editingFinished.connect(self.setADCPipeline)
|
||||
self.view.spinBoxDBITF.editingFinished.connect(self.setDBITFrequency)
|
||||
self.view.spinBoxDBITPhase.editingFinished.connect(self.setDBITPhase)
|
||||
self.view.spinBoxDBITPipeline.editingFinished.connect(self.setDBITPipeline)
|
||||
self.view.spinBoxADCF.editingFinished.connect(self.setADCFrequency)
|
||||
self.view.spinBoxADCPhase.editingFinished.connect(self.setADCPhase)
|
||||
self.view.spinBoxADCPipeline.editingFinished.connect(self.setADCPipeline)
|
||||
self.view.spinBoxDBITF.editingFinished.connect(self.setDBITFrequency)
|
||||
self.view.spinBoxDBITPhase.editingFinished.connect(self.setDBITPhase)
|
||||
self.view.spinBoxDBITPipeline.editingFinished.connect(self.setDBITPipeline)
|
||||
|
||||
self.view.checkBoxFileWriteRaw.stateChanged.connect(self.setFileWrite)
|
||||
self.view.checkBoxFileWriteNumpy.stateChanged.connect(self.setFileWriteNumpy)
|
||||
@ -94,19 +77,16 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
|
||||
def refresh(self):
|
||||
self.getReadout()
|
||||
self.getRunFrequency()
|
||||
self.getTransceiver()
|
||||
self.getAnalog()
|
||||
self.getDigital()
|
||||
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.getRunFrequency()
|
||||
self.getADCFrequency()
|
||||
self.getADCPhase()
|
||||
self.getADCPipeline()
|
||||
self.getDBITFrequency()
|
||||
self.getDBITPhase()
|
||||
self.getDBITPipeline()
|
||||
|
||||
self.getADCFrequency()
|
||||
self.getADCPhase()
|
||||
self.getADCPipeline()
|
||||
self.getDBITFrequency()
|
||||
self.getDBITPhase()
|
||||
self.getDBITPipeline()
|
||||
self.getFileWrite()
|
||||
self.getFileName()
|
||||
self.getFilePath()
|
||||
@ -717,39 +697,23 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
self.socket.subscribe("")
|
||||
|
||||
def saveParameters(self) -> list[str]:
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
return [
|
||||
f'romode {self.view.comboBoxROMode.currentText().lower()}',
|
||||
f'runclk {self.view.spinBoxRunF.value()}',
|
||||
f'adcclk {self.view.spinBoxADCF.value()}',
|
||||
f'adcphase {self.view.spinBoxADCPhase.value()}',
|
||||
f'adcpipeline {self.view.spinBoxADCPipeline.value()}',
|
||||
f'dbitclk {self.view.spinBoxDBITF.value()}',
|
||||
f'dbitphase {self.view.spinBoxDBITPhase.value()}',
|
||||
f'dbitpipeline {self.view.spinBoxDBITPipeline.value()}',
|
||||
f'fwrite {int(self.view.checkBoxFileWriteRaw.isChecked())}',
|
||||
f'fname {self.view.lineEditFileName.text()}',
|
||||
f'fpath {self.view.lineEditFilePath.text()}',
|
||||
f'findex {self.view.spinBoxAcquisitionIndex.value()}',
|
||||
f'frames {self.view.spinBoxFrames.value()}',
|
||||
f'triggers {self.view.spinBoxTriggers.value()}',
|
||||
f'period {self.view.spinBoxPeriod.value()} {self.view.comboBoxPeriod.currentText().lower()}',
|
||||
f'asamples {self.view.spinBoxAnalog.value()}',
|
||||
f'dsamples {self.view.spinBoxDigital.value()}',
|
||||
f'tsamples {self.view.spinBoxTransceiver.value()}',
|
||||
]
|
||||
else:
|
||||
return [
|
||||
f'romode {self.view.comboBoxROMode.currentText().lower()}',
|
||||
f'fwrite {int(self.view.checkBoxFileWriteRaw.isChecked())}',
|
||||
f'fname {self.view.lineEditFileName.text()}',
|
||||
f'fpath {self.view.lineEditFilePath.text()}',
|
||||
f'findex {self.view.spinBoxAcquisitionIndex.value()}',
|
||||
f'frames {self.view.spinBoxFrames.value()}',
|
||||
f'triggers {self.view.spinBoxTriggers.value()}',
|
||||
f'period {self.view.spinBoxPeriod.value()} {self.view.comboBoxPeriod.currentText().lower()}',
|
||||
f'asamples {self.view.spinBoxAnalog.value()}',
|
||||
f'dsamples {self.view.spinBoxDigital.value()}',
|
||||
f'tsamples {self.view.spinBoxTransceiver.value()}',
|
||||
]
|
||||
|
||||
return [
|
||||
f'romode {self.view.comboBoxROMode.currentText().lower()}',
|
||||
f'runclk {self.view.spinBoxRunF.value()}',
|
||||
f'adcclk {self.view.spinBoxADCF.value()}',
|
||||
f'adcphase {self.view.spinBoxADCPhase.value()}',
|
||||
f'adcpipeline {self.view.spinBoxADCPipeline.value()}',
|
||||
f'dbitclk {self.view.spinBoxDBITF.value()}',
|
||||
f'dbitphase {self.view.spinBoxDBITPhase.value()}',
|
||||
f'dbitpipeline {self.view.spinBoxDBITPipeline.value()}',
|
||||
f'fwrite {int(self.view.checkBoxFileWriteRaw.isChecked())}',
|
||||
f'fname {self.view.lineEditFileName.text()}',
|
||||
f'fpath {self.view.lineEditFilePath.text()}',
|
||||
f'findex {self.view.spinBoxAcquisitionIndex.value()}',
|
||||
f'frames {self.view.spinBoxFrames.value()}',
|
||||
f'triggers {self.view.spinBoxTriggers.value()}',
|
||||
f'period {self.view.spinBoxPeriod.value()} {self.view.comboBoxPeriod.currentText().lower()}',
|
||||
f'asamples {self.view.spinBoxAnalog.value()}',
|
||||
f'dsamples {self.view.spinBoxDigital.value()}',
|
||||
f'tsamples {self.view.spinBoxTransceiver.value()}',
|
||||
]
|
||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
||||
from PyQt5 import QtWidgets, uic
|
||||
from pyctbgui.utils.defines import Defines
|
||||
|
||||
from slsdet import dacIndex, detectorType
|
||||
from slsdet import dacIndex
|
||||
|
||||
|
||||
class DacTab(QtWidgets.QWidget):
|
||||
@ -19,14 +19,7 @@ class DacTab(QtWidgets.QWidget):
|
||||
dac = getattr(dacIndex, f"DAC_{i}")
|
||||
getattr(self.view, f"spinBoxDAC{i}").setValue(self.det.getDAC(dac)[0])
|
||||
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
self.view.checkBoxHighVoltage.setDisabled(True)
|
||||
self.view.spinBoxHighVoltage.setDisabled(True)
|
||||
self.view.labelHighVoltage.setDisabled(True)
|
||||
self.view.labelADCVppDacName.setDisabled(True)
|
||||
self.view.labelADCVpp.setDisabled(True)
|
||||
self.view.comboBoxADCVpp.setDisabled(True)
|
||||
elif self.det.highvoltage == 0:
|
||||
if self.det.highvoltage == 0:
|
||||
self.view.spinBoxHighVoltage.setDisabled(True)
|
||||
self.view.checkBoxHighVoltage.setChecked(False)
|
||||
|
||||
@ -37,11 +30,9 @@ class DacTab(QtWidgets.QWidget):
|
||||
getattr(self.view, f"checkBoxDAC{i}").stateChanged.connect(partial(self.setDACTristate, i))
|
||||
getattr(self.view, f"checkBoxDAC{i}mV").stateChanged.connect(partial(self.getDAC, i))
|
||||
|
||||
if self.view.comboBoxADCVpp.isEnabled():
|
||||
self.view.comboBoxADCVpp.currentIndexChanged.connect(self.setADCVpp)
|
||||
if self.view.checkBoxHighVoltage.isEnabled():
|
||||
self.view.spinBoxHighVoltage.editingFinished.connect(self.setHighVoltage)
|
||||
self.view.checkBoxHighVoltage.stateChanged.connect(self.setHighVoltage)
|
||||
self.view.comboBoxADCVpp.currentIndexChanged.connect(self.setADCVpp)
|
||||
self.view.spinBoxHighVoltage.editingFinished.connect(self.setHighVoltage)
|
||||
self.view.checkBoxHighVoltage.stateChanged.connect(self.setHighVoltage)
|
||||
|
||||
def refresh(self):
|
||||
self.updateDACNames()
|
||||
@ -49,10 +40,8 @@ class DacTab(QtWidgets.QWidget):
|
||||
self.getDACTristate(i)
|
||||
self.getDAC(i)
|
||||
|
||||
if self.view.comboBoxADCVpp.isEnabled():
|
||||
self.getADCVpp()
|
||||
if self.view.checkBoxHighVoltage.isEnabled():
|
||||
self.getHighVoltage()
|
||||
self.getADCVpp()
|
||||
self.getHighVoltage()
|
||||
|
||||
def updateDACNames(self):
|
||||
for i, name in enumerate(self.det.getDacNames()):
|
||||
@ -176,8 +165,6 @@ class DacTab(QtWidgets.QWidget):
|
||||
unit = " mV" if inMV else ""
|
||||
commands.append(f"dac {i} {value}{unit}")
|
||||
|
||||
if self.view.comboBoxADCVpp.isEnabled():
|
||||
commands.append(f"adcvpp {self.view.comboBoxADCVpp.currentText()} mV")
|
||||
if self.view.checkBoxHighVoltage.isEnabled():
|
||||
commands.append(f"highvoltage {self.view.spinBoxHighVoltage.value()}")
|
||||
commands.append(f"adcvpp {self.view.comboBoxADCVpp.currentText()} mV")
|
||||
commands.append(f"highvoltage {self.view.spinBoxHighVoltage.value()}")
|
||||
return commands
|
||||
|
@ -10,7 +10,6 @@ from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as Navigatio
|
||||
from pyctbgui.utils.defines import Defines
|
||||
from pyctbgui.utils.plotPattern import PlotPattern
|
||||
|
||||
from slsdet import DurationWrapper
|
||||
|
||||
class PatternTab(QtWidgets.QWidget):
|
||||
|
||||
@ -62,10 +61,7 @@ class PatternTab(QtWidgets.QWidget):
|
||||
getattr(self.view, f"lineEditLoop{i}Wait").editingFinished.connect(partial(self.setPatLoopWaitAddress, i))
|
||||
getattr(self.view,
|
||||
f"spinBoxLoop{i}Repetition").editingFinished.connect(partial(self.setPatLoopRepetition, i))
|
||||
getattr(self.view, f"doubleSpinBoxLoop{i}WaitClocks").editingFinished.connect(partial(self.setPatLoopWaitClocks, i))
|
||||
getattr(self.view, f"spinBoxLoop{i}WaitInterval").editingFinished.connect(partial(self.setPatLoopWaitInterval, i))
|
||||
getattr(self.view, f"comboBoxLoop{i}WaitInterval").currentIndexChanged.connect(partial(self.setPatLoopWaitInterval, i))
|
||||
self.view.toolButtonTogglePageWaitTime.clicked.connect(self.setTogglePageWaitTime)
|
||||
getattr(self.view, f"spinBoxLoop{i}WaitTime").editingFinished.connect(partial(self.setPatLoopWaitTime, i))
|
||||
self.view.pushButtonCompiler.clicked.connect(self.setCompiler)
|
||||
self.view.pushButtonUncompiled.clicked.connect(self.setUncompiledPatternFile)
|
||||
self.view.pushButtonPatternFile.clicked.connect(self.setPatternFile)
|
||||
@ -95,8 +91,7 @@ class PatternTab(QtWidgets.QWidget):
|
||||
self.getPatLoopStartStopAddress(i)
|
||||
self.getPatLoopWaitAddress(i)
|
||||
self.getPatLoopRepetition(i)
|
||||
self.getPatLoopWaitClocks(i)
|
||||
self.getPatLoopWaitInterval(i)
|
||||
self.getPatLoopWaitTime(i)
|
||||
|
||||
# Pattern Tab functions
|
||||
|
||||
@ -187,67 +182,17 @@ class PatternTab(QtWidgets.QWidget):
|
||||
self.det.patnloop[level] = spinBox.value()
|
||||
self.getPatLoopRepetition(level)
|
||||
|
||||
def getPatLoopWaitClocks(self, level):
|
||||
def getPatLoopWaitTime(self, level):
|
||||
retval = self.det.patwaittime[level]
|
||||
spinBox = getattr(self.view, f"doubleSpinBoxLoop{level}WaitClocks")
|
||||
spinBox = getattr(self.view, f"spinBoxLoop{level}WaitTime")
|
||||
spinBox.editingFinished.disconnect()
|
||||
spinBox.setValue(retval)
|
||||
spinBox.editingFinished.connect(partial(self.setPatLoopWaitClocks, level))
|
||||
|
||||
def setPatLoopWaitClocks(self, level):
|
||||
spinBox = getattr(self.view, f"doubleSpinBoxLoop{level}WaitClocks")
|
||||
self.det.patwaittime[level] = int(spinBox.value())
|
||||
self.getPatLoopWaitClocks(level)
|
||||
|
||||
def getPatLoopWaitInterval(self, level):
|
||||
retval = self.det.getPatternWaitInterval(level)[0].count()
|
||||
spinBox = getattr(self.view, f"spinBoxLoop{level}WaitInterval")
|
||||
comboBox = getattr(self.view, f"comboBoxLoop{level}WaitInterval")
|
||||
spinBox.editingFinished.disconnect()
|
||||
comboBox.currentIndexChanged.disconnect()
|
||||
# Converting to right time unit for period
|
||||
if retval >= 1e9:
|
||||
comboBox.setCurrentIndex(0)
|
||||
spinBox.setValue(retval / 1e9)
|
||||
elif retval >= 1e6:
|
||||
comboBox.setCurrentIndex(1)
|
||||
spinBox.setValue(retval / 1e6)
|
||||
elif retval >= 1e3:
|
||||
comboBox.setCurrentIndex(2)
|
||||
spinBox.setValue(retval / 1e3)
|
||||
else:
|
||||
comboBox.setCurrentIndex(3)
|
||||
spinBox.setValue(retval)
|
||||
spinBox.editingFinished.connect(partial(self.setPatLoopWaitInterval, level))
|
||||
comboBox.currentIndexChanged.connect(partial(self.setPatLoopWaitInterval, level))
|
||||
|
||||
def setPatLoopWaitInterval(self, level):
|
||||
spinBox = getattr(self.view, f"spinBoxLoop{level}WaitInterval")
|
||||
comboBox = getattr(self.view, f"comboBoxLoop{level}WaitInterval")
|
||||
value = spinBox.value()
|
||||
if comboBox.currentIndex() == 0:
|
||||
value *= 1e9
|
||||
elif comboBox.currentIndex() == 1:
|
||||
value *= 1e6
|
||||
elif comboBox.currentIndex() == 2:
|
||||
value *= 1e3
|
||||
t = DurationWrapper()
|
||||
t.set_count(int(value))
|
||||
self.det.patwaittime[level] = t
|
||||
self.getPatLoopWaitInterval(level)
|
||||
|
||||
def setTogglePageWaitTime(self):
|
||||
if self.view.stackedWidgetWaitTime.currentIndex() == 0:
|
||||
self.view.stackedWidgetWaitTime.setCurrentIndex(1)
|
||||
self.view.labelWaitTime.setText("Time")
|
||||
for i in range(Defines.pattern.loops_count):
|
||||
self.getPatLoopWaitInterval(i)
|
||||
else:
|
||||
self.view.stackedWidgetWaitTime.setCurrentIndex(0)
|
||||
self.view.labelWaitTime.setText("Clocks")
|
||||
for i in range(Defines.pattern.loops_count):
|
||||
self.getPatLoopWaitClocks(i)
|
||||
spinBox.editingFinished.connect(partial(self.setPatLoopWaitTime, level))
|
||||
|
||||
def setPatLoopWaitTime(self, level):
|
||||
spinBox = getattr(self.view, f"spinBoxLoop{level}WaitTime")
|
||||
self.det.patwaittime[level] = spinBox.value()
|
||||
self.getPatLoopWaitTime(level)
|
||||
|
||||
def setCompiler(self):
|
||||
response = QtWidgets.QFileDialog.getOpenFileName(
|
||||
@ -505,7 +450,7 @@ class PatternTab(QtWidgets.QWidget):
|
||||
f"{getattr(self.view, f'lineEditLoop{i}Stop').text()}")
|
||||
|
||||
commands.append(f"patwait {i} {getattr(self.view, f'lineEditLoop{i}Wait').text()}")
|
||||
commands.append(f"patwaittime {i} {getattr(self.view, f'doubleSpinBoxLoop{i}WaitClocks').text()}")
|
||||
commands.append(f"patwaittime {i} {getattr(self.view, f'spinBoxLoop{i}WaitTime').text()}")
|
||||
commands.append(f"patlimits {self.view.lineEditStartAddress.text()}, {self.view.lineEditStopAddress.text()}")
|
||||
# commands.append(f"patfname {self.view.lineEditPatternFile.text()}")
|
||||
return commands
|
||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
||||
from PyQt5 import QtWidgets, uic
|
||||
from pyctbgui.utils.defines import Defines
|
||||
|
||||
from slsdet import dacIndex, detectorType
|
||||
from slsdet import dacIndex
|
||||
|
||||
|
||||
class PowerSuppliesTab(QtWidgets.QWidget):
|
||||
@ -18,8 +18,7 @@ class PowerSuppliesTab(QtWidgets.QWidget):
|
||||
self.updateVoltageNames()
|
||||
for i in Defines.powerSupplies:
|
||||
self.getVoltage(i)
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.getCurrent(i)
|
||||
self.getCurrent(i)
|
||||
|
||||
def connect_ui(self):
|
||||
for i in Defines.powerSupplies:
|
||||
@ -39,12 +38,6 @@ class PowerSuppliesTab(QtWidgets.QWidget):
|
||||
if retval == 0:
|
||||
checkBox.setChecked(False)
|
||||
spinBox.setDisabled(True)
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
label = getattr(self.view, f"labelI{i}")
|
||||
label.setDisabled(True)
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
self.view.spinBoxVChip.setDisabled(True)
|
||||
|
||||
|
||||
def updateVoltageNames(self):
|
||||
retval = self.det.getPowerNames()
|
||||
@ -63,10 +56,7 @@ class PowerSuppliesTab(QtWidgets.QWidget):
|
||||
spinBox.editingFinished.disconnect()
|
||||
checkBox.stateChanged.disconnect()
|
||||
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
retval = self.det.getPower(voltageIndex)[0]
|
||||
else:
|
||||
retval = self.det.getMeasuredPower(voltageIndex)[0]
|
||||
retval = self.det.getMeasuredPower(voltageIndex)[0]
|
||||
# spinBox.setValue(retval)
|
||||
if retval > 1:
|
||||
checkBox.setChecked(True)
|
||||
@ -78,9 +68,8 @@ class PowerSuppliesTab(QtWidgets.QWidget):
|
||||
|
||||
spinBox.editingFinished.connect(partial(self.setVoltage, i))
|
||||
checkBox.stateChanged.connect(partial(self.setVoltage, i))
|
||||
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.getVChip()
|
||||
|
||||
self.getVChip()
|
||||
|
||||
# TODO: handle multiple events when pressing enter (twice)
|
||||
|
||||
@ -102,8 +91,7 @@ class PowerSuppliesTab(QtWidgets.QWidget):
|
||||
# TODO: (properly) disconnecting and connecting to handle multiple events (out of focus and pressing enter).
|
||||
spinBox.editingFinished.connect(partial(self.setVoltage, i))
|
||||
self.getVoltage(i)
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.getCurrent(i)
|
||||
self.getCurrent(i)
|
||||
|
||||
def getCurrent(self, i):
|
||||
label = getattr(self.view, f"labelI{i}")
|
||||
|
@ -22,7 +22,6 @@ class SignalsTab(QtWidgets.QWidget):
|
||||
self.plotTab = None
|
||||
self.legend: LegendItem | None = None
|
||||
self.rx_dbitoffset = None
|
||||
self.rx_dbitreorder = None
|
||||
self.rx_dbitlist = None
|
||||
|
||||
def refresh(self):
|
||||
@ -30,7 +29,6 @@ class SignalsTab(QtWidgets.QWidget):
|
||||
self.updateDigitalBitEnable()
|
||||
self.updateIOOut()
|
||||
self.getDBitOffset()
|
||||
self.getDBitReorder()
|
||||
|
||||
def connect_ui(self):
|
||||
for i in range(Defines.signals.count):
|
||||
@ -51,7 +49,6 @@ class SignalsTab(QtWidgets.QWidget):
|
||||
partial(self.setIOOutRange, Defines.signals.half, Defines.signals.count))
|
||||
self.view.lineEditPatIOCtrl.editingFinished.connect(self.setIOOutReg)
|
||||
self.view.spinBoxDBitOffset.editingFinished.connect(self.setDbitOffset)
|
||||
self.view.checkBoxDBitReorder.stateChanged.connect(self.setDbitReorder)
|
||||
|
||||
def setup_ui(self):
|
||||
self.plotTab = self.mainWindow.plotTab
|
||||
@ -90,79 +87,60 @@ class SignalsTab(QtWidgets.QWidget):
|
||||
self.legend.addItem(plot, name)
|
||||
|
||||
@recordOrApplyPedestal
|
||||
def _processWaveformData(self, data, aSamples, dSamples, rx_dbitreorder, rx_dbitlist, isPlottedArray, romode,
|
||||
def _processWaveformData(self, data, aSamples, dSamples, rx_dbitlist, isPlottedArray, rx_dbitoffset, romode,
|
||||
nADCEnabled):
|
||||
|
||||
#transform raw waveform data into a processed numpy array
|
||||
#@param data: raw waveform data
|
||||
|
||||
start_digital_data = 0
|
||||
"""
|
||||
transform raw waveform data into a processed numpy array
|
||||
@param data: raw waveform data
|
||||
"""
|
||||
dbitoffset = rx_dbitoffset
|
||||
if romode == 2:
|
||||
start_digital_data += nADCEnabled * 2 * aSamples
|
||||
digital_array = np.array(np.frombuffer(data, offset=start_digital_data, dtype=np.uint8))
|
||||
if rx_dbitreorder:
|
||||
samples_per_bit = np.empty((len(rx_dbitlist), dSamples), dtype=np.uint8) #stored per row all the corresponding signals of all samples
|
||||
nbitsPerDBit = dSamples
|
||||
if nbitsPerDBit % 8 != 0:
|
||||
nbitsPerDBit += (8 - (dSamples % 8))
|
||||
bit_index = 0
|
||||
for idx, i in enumerate(rx_dbitlist):
|
||||
# where numbits * numsamples is not a multiple of 8
|
||||
if bit_index % 8 != 0:
|
||||
bit_index += (8 - (bit_index % 8))
|
||||
if not isPlottedArray[i]:
|
||||
bit_index += nbitsPerDBit
|
||||
samples_per_bit[idx, :] = np.nan
|
||||
continue
|
||||
for iSample in range(dSamples):
|
||||
# all samples for digital bit together from slsReceiver
|
||||
index = int(bit_index / 8)
|
||||
iBit = bit_index % 8
|
||||
bit = (digital_array[index] >> iBit) & 1
|
||||
samples_per_bit[idx,iSample] = bit
|
||||
bit_index += 1
|
||||
return samples_per_bit
|
||||
else:
|
||||
nbitsPerSample = len(rx_dbitlist) if len(rx_dbitlist) % 8 == 0 else len(rx_dbitlist) + (8 - (len(rx_dbitlist) % 8))
|
||||
bits_per_sample = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store per row all selected bits of a sample
|
||||
for iSample in range(dSamples):
|
||||
bit_index = nbitsPerSample * iSample
|
||||
for idx, i in enumerate(rx_dbitlist):
|
||||
if not isPlottedArray[i]:
|
||||
bit_index += 1
|
||||
bits_per_sample[iSample, idx] = np.nan
|
||||
dbitoffset += nADCEnabled * 2 * aSamples
|
||||
digital_array = np.array(np.frombuffer(data, offset=dbitoffset, dtype=np.uint8))
|
||||
nbitsPerDBit = dSamples
|
||||
if nbitsPerDBit % 8 != 0:
|
||||
nbitsPerDBit += (8 - (dSamples % 8))
|
||||
offset = 0
|
||||
arr = []
|
||||
for i in rx_dbitlist:
|
||||
# where numbits * numsamples is not a multiple of 8
|
||||
if offset % 8 != 0:
|
||||
offset += (8 - (offset % 8))
|
||||
if not isPlottedArray[i]:
|
||||
offset += nbitsPerDBit
|
||||
return None
|
||||
waveform = np.zeros(dSamples)
|
||||
for iSample in range(dSamples):
|
||||
# all samples for digital bit together from slsReceiver
|
||||
index = int(offset / 8)
|
||||
iBit = offset % 8
|
||||
bit = (digital_array[index] >> iBit) & 1
|
||||
waveform[iSample] = bit
|
||||
offset += 1
|
||||
arr.append(waveform)
|
||||
|
||||
index = int(bit_index/8)
|
||||
iBit = idx % 8
|
||||
bit = (digital_array[index] >> iBit) & 1
|
||||
bits_per_sample[iSample, idx] = bit
|
||||
bit_index += 1
|
||||
return bits_per_sample.T.copy()
|
||||
return np.array(arr)
|
||||
|
||||
|
||||
|
||||
def processWaveformData(self, data, aSamples, dSamples):
|
||||
|
||||
#view function
|
||||
#plots processed waveform data
|
||||
#data: raw waveform data
|
||||
#dsamples: digital samples
|
||||
#asamples: analog samples
|
||||
|
||||
self.refresh()
|
||||
|
||||
"""
|
||||
view function
|
||||
plots processed waveform data
|
||||
data: raw waveform data
|
||||
dsamples: digital samples
|
||||
asamples: analog samples
|
||||
"""
|
||||
waveforms = {}
|
||||
isPlottedArray = {i: getattr(self.view, f"checkBoxBIT{i}Plot").isChecked() for i in self.rx_dbitlist}
|
||||
|
||||
digital_array = self._processWaveformData(data, aSamples, dSamples, self.rx_dbitreorder, self.rx_dbitlist, isPlottedArray,
|
||||
self.mainWindow.romode.value,
|
||||
digital_array = self._processWaveformData(data, aSamples, dSamples, self.rx_dbitlist, isPlottedArray,
|
||||
self.rx_dbitoffset, self.mainWindow.romode.value,
|
||||
self.mainWindow.nADCEnabled)
|
||||
|
||||
irow = 0
|
||||
for idx, i in enumerate(self.rx_dbitlist):
|
||||
for idx, i in enumerate(self.rx_dbitlist):
|
||||
# bits enabled but not plotting
|
||||
waveform = digital_array[idx, :]
|
||||
if np.isnan(waveform[0]):
|
||||
waveform = digital_array[idx]
|
||||
if waveform is None:
|
||||
continue
|
||||
self.mainWindow.digitalPlots[i].setData(waveform)
|
||||
plotName = getattr(self.view, f"labelBIT{i}").text()
|
||||
@ -173,10 +151,8 @@ class SignalsTab(QtWidgets.QWidget):
|
||||
irow += 1
|
||||
else:
|
||||
self.mainWindow.digitalPlots[i].setY(0)
|
||||
|
||||
return waveforms
|
||||
|
||||
|
||||
def initializeAllDigitalPlots(self):
|
||||
self.mainWindow.plotDigitalWaveform = pg.plot()
|
||||
self.mainWindow.plotDigitalWaveform.addLegend(colCount=Defines.colCount)
|
||||
@ -384,25 +360,14 @@ class SignalsTab(QtWidgets.QWidget):
|
||||
self.view.spinBoxDBitOffset.setValue(self.rx_dbitoffset)
|
||||
self.view.spinBoxDBitOffset.editingFinished.connect(self.setDbitOffset)
|
||||
|
||||
def getDBitReorder(self):
|
||||
self.view.checkBoxDBitReorder.stateChanged.disconnect()
|
||||
self.rx_dbitreorder = self.det.rx_dbitreorder
|
||||
self.view.checkBoxDBitReorder.setChecked(self.rx_dbitreorder)
|
||||
self.view.checkBoxDBitReorder.stateChanged.connect(self.setDbitReorder)
|
||||
|
||||
|
||||
def setDbitOffset(self):
|
||||
self.det.rx_dbitoffset = self.view.spinBoxDBitOffset.value()
|
||||
|
||||
def setDbitReorder(self):
|
||||
self.det.rx_dbitreorder = self.view.checkBoxDBitReorder.isChecked()
|
||||
|
||||
def saveParameters(self) -> list:
|
||||
commands = []
|
||||
dblist = [str(i) for i in range(Defines.signals.count) if getattr(self.view, f"checkBoxBIT{i}DB").isChecked()]
|
||||
if len(dblist) > 0:
|
||||
commands.append(f"rx_dbitlist {', '.join(dblist)}")
|
||||
commands.append(f"rx_dbitoffset {self.view.spinBoxDBitOffset.value()}")
|
||||
commands.append(f"rx_dbitreorder {self.view.checkBoxDBitReorder.isChecked()}")
|
||||
commands.append(f"patioctrl {self.view.lineEditPatIOCtrl.text()}")
|
||||
return commands
|
||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
||||
from PyQt5 import uic, QtWidgets
|
||||
|
||||
from pyctbgui.utils.defines import Defines
|
||||
from slsdet import dacIndex, detectorType
|
||||
from slsdet import dacIndex
|
||||
|
||||
|
||||
class SlowAdcTab(QtWidgets.QWidget):
|
||||
@ -17,8 +17,7 @@ class SlowAdcTab(QtWidgets.QWidget):
|
||||
self.det = None
|
||||
|
||||
def setup_ui(self):
|
||||
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
|
||||
self.view.pushButtonTemp.setDisabled(True)
|
||||
pass
|
||||
|
||||
def connect_ui(self):
|
||||
for i in range(Defines.slowAdc.count):
|
||||
@ -29,8 +28,7 @@ class SlowAdcTab(QtWidgets.QWidget):
|
||||
self.updateSlowAdcNames()
|
||||
for i in range(Defines.slowAdc.count):
|
||||
self.updateSlowAdc(i)
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.updateTemperature()
|
||||
self.updateTemperature()
|
||||
|
||||
def updateSlowAdcNames(self):
|
||||
for i, name in enumerate(self.mainWindow.det.getSlowADCNames()):
|
||||
|
@ -817,7 +817,7 @@ Only pressing enter on spinbox will set DAC (with this condition).</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="labelADCVppDacName">
|
||||
<widget class="QLabel" name="label_125">
|
||||
<property name="text">
|
||||
<string>ADC_VPP</string>
|
||||
</property>
|
||||
|
@ -118,7 +118,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="labelRunF">
|
||||
<widget class="QLabel" name="label_70">
|
||||
<property name="text">
|
||||
<string>Run Clock Frequency (MHz):</string>
|
||||
</property>
|
||||
@ -218,7 +218,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="2" column="3">
|
||||
<widget class="QLabel" name="labelDBITF">
|
||||
<widget class="QLabel" name="label_74">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
@ -231,7 +231,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelADCF">
|
||||
<widget class="QLabel" name="label_71">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@ -278,7 +278,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLabel" name="labelDBITPipeline">
|
||||
<widget class="QLabel" name="label_76">
|
||||
<property name="text">
|
||||
<string>DBIT Pipeline:</string>
|
||||
</property>
|
||||
@ -338,21 +338,21 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelADCPipeline">
|
||||
<widget class="QLabel" name="label_73">
|
||||
<property name="text">
|
||||
<string>ADC Pipeline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelADCPhase">
|
||||
<widget class="QLabel" name="label_72">
|
||||
<property name="text">
|
||||
<string>ADC Clock Phase (a.u.):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="labelDBITPhase">
|
||||
<widget class="QLabel" name="label_75">
|
||||
<property name="text">
|
||||
<string>DBIT Clock Phase (a.u.):</string>
|
||||
</property>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QFrame" name="frame_ADC">
|
||||
<widget class="QFrame" name="frame_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@ -3142,7 +3142,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_20">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelADCInversion">
|
||||
<widget class="QLabel" name="label_67">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
@ -3188,7 +3188,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="labelADCEnable">
|
||||
<widget class="QLabel" name="label_68">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6074,33 +6074,6 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_17">
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="spinBoxDBitOffset">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_66">
|
||||
<property name="font">
|
||||
@ -6113,36 +6086,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QCheckBox" name="checkBoxDBitReorder">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DBit Reorder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_48">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>IO Control Register:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditPatIOCtrl">
|
||||
<property name="sizePolicy">
|
||||
@ -6190,18 +6133,50 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<spacer name="horizontalSpacer_22">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="spinBoxDBitOffset">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
<width>150</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_48">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>IO Control Register:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QFrame" name="frame_slowadcs">
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -1,33 +0,0 @@
|
||||
[tool.scikit-build.metadata.version]
|
||||
provider = "scikit_build_core.metadata.regex"
|
||||
input = "VERSION"
|
||||
regex = '^(?P<version>\d+(?:\.\d+)*(?:[\.\+\w]+)?)$'
|
||||
result = "{version}"
|
||||
|
||||
[build-system]
|
||||
requires = [ "scikit-build-core>=0.10", "pybind11", "numpy",]
|
||||
build-backend = "scikit_build_core.build"
|
||||
|
||||
[project]
|
||||
name = "slsdet"
|
||||
dynamic = ["version"]
|
||||
|
||||
[tool.cibuildwheel]
|
||||
before-all = "uname -a"
|
||||
|
||||
[tool.scikit-build.build]
|
||||
verbose = true
|
||||
|
||||
[tool.scikit-build.cmake]
|
||||
build-type = "Release"
|
||||
|
||||
[tool.scikit-build.install]
|
||||
components = [ "python",]
|
||||
|
||||
[tool.scikit-build.cmake.define]
|
||||
SLS_USE_RECEIVER = "OFF"
|
||||
SLS_USE_RECEIVER_BINARIES = "OFF"
|
||||
SLS_USE_TEXTCLIENT = "OFF"
|
||||
SLS_BUILD_SHARED_LIBRARIES = "OFF"
|
||||
SLS_USE_PYTHON = "ON"
|
||||
SLS_INSTALL_PYTHONEXT = "ON"
|
@ -20,14 +20,13 @@ target_link_libraries(_slsdet PUBLIC
|
||||
|
||||
|
||||
set_target_properties(_slsdet PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/slsdet
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
#Copy Python code
|
||||
set( PYTHON_FILES
|
||||
slsdet/__init__.py
|
||||
slsdet/adcs.py
|
||||
slsdet/bits.py
|
||||
slsdet/dacs.py
|
||||
slsdet/powers.py
|
||||
slsdet/decorators.py
|
||||
@ -38,8 +37,8 @@ set( PYTHON_FILES
|
||||
slsdet/enums.py
|
||||
slsdet/errors.py
|
||||
slsdet/gaincaps.py
|
||||
slsdet/gotthard.py
|
||||
slsdet/pattern.py
|
||||
slsdet/PatternGenerator.py
|
||||
slsdet/gotthard2.py
|
||||
slsdet/moench.py
|
||||
slsdet/proxy.py
|
||||
@ -72,18 +71,9 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION
|
||||
if(SLS_INSTALL_PYTHONEXT)
|
||||
install(TARGETS _slsdet
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
LIBRARY DESTINATION slsdet
|
||||
COMPONENT python
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/python
|
||||
)
|
||||
install(
|
||||
FILES ${PYTHON_FILES}
|
||||
DESTINATION slsdet
|
||||
COMPONENT python
|
||||
)
|
||||
install(
|
||||
FILES ../VERSION
|
||||
DESTINATION slsdet
|
||||
COMPONENT python
|
||||
)
|
||||
|
||||
install(FILES ${PYTHON_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet)
|
||||
install(FILES ../VERSION DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet)
|
||||
endif()
|
@ -55,6 +55,7 @@ servers = [
|
||||
# "jungfrauDetectorServer",
|
||||
"mythen3DetectorServer",
|
||||
# "gotthard2DetectorServer",
|
||||
# "gotthardDetectorServer",
|
||||
# "ctbDetectorServer",
|
||||
# "moenchDetectorServer",
|
||||
]
|
||||
|
@ -1,19 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
# Script to get combined zmq packets from frame synchronizer using pull zmq sockets
|
||||
import json
|
||||
import zmq
|
||||
|
||||
c = zmq.Context()
|
||||
s = c.socket(zmq.PULL)
|
||||
s.connect("tcp://127.0.0.1:5555")
|
||||
|
||||
while True:
|
||||
m = s.recv_multipart()
|
||||
for p in m:
|
||||
if p.startswith(b"{"):
|
||||
print(p.decode().strip())
|
||||
else:
|
||||
print("binary")
|
||||
print("--------")
|
||||
|
@ -123,9 +123,6 @@ def visit(node):
|
||||
if node.kind == cindex.CursorKind.CLASS_DECL:
|
||||
if node.displayname == "Detector":
|
||||
for child in node.get_children():
|
||||
# Skip assignment operators
|
||||
if child.kind == cindex.CursorKind.CXX_METHOD and child.spelling == "operator=":
|
||||
continue
|
||||
if (
|
||||
child.kind == cindex.CursorKind.CXX_METHOD
|
||||
and child.access_specifier == cindex.AccessSpecifier.PUBLIC
|
||||
|
77
python/setup.py
Executable file
77
python/setup.py
Executable file
@ -0,0 +1,77 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
"""
|
||||
Setup file for slsdet
|
||||
Build upon the pybind11 example found here: https://github.com/pybind/python_example
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup, find_packages
|
||||
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
||||
|
||||
def read_version():
|
||||
try:
|
||||
version_file = os.path.join(os.path.dirname(__file__), 'slsdet', 'VERSION')
|
||||
with open(version_file, "r") as f:
|
||||
return f.read().strip()
|
||||
except:
|
||||
raise RuntimeError("VERSION file not found in slsdet package from setup.py.")
|
||||
|
||||
__version__ = read_version()
|
||||
|
||||
|
||||
def get_conda_path():
|
||||
"""
|
||||
Keep this a function if we need some fancier logic later
|
||||
"""
|
||||
print('Prefix: ', os.environ['CONDA_PREFIX'])
|
||||
return os.environ['CONDA_PREFIX']
|
||||
|
||||
|
||||
#TODO migrate to CMake build or fetch files from cmake?
|
||||
ext_modules = [
|
||||
Pybind11Extension(
|
||||
'_slsdet',
|
||||
['src/main.cpp',
|
||||
'src/enums.cpp',
|
||||
'src/current.cpp',
|
||||
'src/detector.cpp',
|
||||
'src/network.cpp',
|
||||
'src/pattern.cpp',
|
||||
'src/scan.cpp',
|
||||
'src/duration.cpp',
|
||||
'src/DurationWrapper.cpp',
|
||||
'src/pedestal.cpp',
|
||||
]
|
||||
|
||||
|
||||
,
|
||||
include_dirs=[
|
||||
os.path.join(get_conda_path(), 'include'),
|
||||
|
||||
],
|
||||
libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver'],
|
||||
library_dirs=[
|
||||
os.path.join(get_conda_path(), 'lib'),
|
||||
],
|
||||
language='c++'
|
||||
),
|
||||
]
|
||||
|
||||
setup(
|
||||
name='slsdet',
|
||||
version=__version__,
|
||||
author='Erik Frojdh',
|
||||
author_email='erik.frojdh@psi.ch',
|
||||
url='https://github.com/slsdetectorgroup/slsDetectorPackage',
|
||||
description='Detector API for SLS Detector Group detectors',
|
||||
long_description='',
|
||||
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
|
||||
package_data={
|
||||
'slsdet': ['VERSION'],
|
||||
},
|
||||
ext_modules=ext_modules,
|
||||
cmdclass={"build_ext": build_ext},
|
||||
zip_safe=False,
|
||||
)
|
@ -1,226 +0,0 @@
|
||||
from . import Detector, Pattern
|
||||
from .bits import setbit, clearbit
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class PatternGenerator:
|
||||
"""
|
||||
Class to generate a pattern for the SLS detector. Intents to as closely as possible
|
||||
mimic the old pattern generation in the C code.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.pattern = Pattern()
|
||||
self.iaddr = 0
|
||||
|
||||
def SB(self, *bits):
|
||||
"""
|
||||
Set one or several bits. Change will take affect with the next PW.
|
||||
"""
|
||||
for bit in bits:
|
||||
self.pattern.word[self.iaddr] = setbit(bit, self.pattern.word[self.iaddr])
|
||||
return self.pattern.word[self.iaddr]
|
||||
|
||||
def CB(self, *bits):
|
||||
"""
|
||||
Clear one or several bits. Change will take affect with the next PW.
|
||||
"""
|
||||
for bit in bits:
|
||||
self.pattern.word[self.iaddr] = clearbit(bit, self.pattern.word[self.iaddr])
|
||||
return self.pattern.word[self.iaddr]
|
||||
|
||||
|
||||
def _pw(self, verbose = False):
|
||||
if verbose:
|
||||
print(f'{self.iaddr:#06x} {self.pattern.word[self.iaddr]:#018x}')
|
||||
|
||||
#Limits are inclusive so we need to increment the address before writing the next word
|
||||
self.pattern.limits[1] = self.iaddr
|
||||
self.iaddr += 1
|
||||
self.pattern.word[self.iaddr] = self.pattern.word[self.iaddr-1]
|
||||
|
||||
def PW(self, x = 1, verbose = False):
|
||||
for i in range(x):
|
||||
self._pw(verbose)
|
||||
|
||||
# def REPEAT(self, x, verbose = False):
|
||||
# for i in range(x):
|
||||
# self._pw(verbose)
|
||||
|
||||
# def PW2(self, verbose = 0):
|
||||
# self.REPEAT(2, verbose)
|
||||
|
||||
|
||||
def CLOCKS(self, bit, times = 1, length = 1, verbose = False):
|
||||
"""
|
||||
clocks "bit" n "times", every half clock is long "length"
|
||||
length is optional, default value is 1
|
||||
"""
|
||||
for i in range(0, times):
|
||||
self.SB(bit); self.PW(length, verbose)
|
||||
self.CB(bit); self.PW(length, verbose)
|
||||
|
||||
def CLOCK(self, bit, length = 1, verbose = 0):
|
||||
self.CLOCKS(bit, 1, length ,verbose)
|
||||
|
||||
def serializer(self, value, serInBit, clkBit, nbits, msbfirst = True, length = 1):
|
||||
"""serializer(value,serInBit,clkBit,nbits,msbfirst=1,length=1)
|
||||
Produces the .pat file needed to serialize a word into a shift register.
|
||||
value: value to be serialized
|
||||
serInBit: control bit corresponding to serial in
|
||||
clkBit: control bit corresponding to the clock
|
||||
nbits: number of bits of the target register to load
|
||||
msbfirst: if 1 pushes in the MSB first (default),
|
||||
if 0 pushes in the LSB first
|
||||
length: length of all the PWs in the pattern
|
||||
It produces no output because it modifies directly the members of the class pat via SB and CB"""
|
||||
|
||||
c = value
|
||||
self.CB(serInBit, clkBit)
|
||||
self.PW(length) #generate initial line with clk and serIn to 0
|
||||
|
||||
start = 0
|
||||
stop = nbits
|
||||
step = 1
|
||||
|
||||
if msbfirst:
|
||||
start = nbits - 1
|
||||
stop = -1
|
||||
step =- 1 #reverts loop if msb has to be pushed in first
|
||||
|
||||
for i in range(start, stop, step):
|
||||
if c & (1<<i):
|
||||
self.SB(serInBit)
|
||||
self.PW(length)
|
||||
else:
|
||||
self.CB(serInBit)
|
||||
self.PW(length)
|
||||
self.SB(clkBit)
|
||||
self.PW(length)
|
||||
self.CB(clkBit)
|
||||
self.PW(length)
|
||||
|
||||
self.CB(serInBit, clkBit)
|
||||
self.PW(length) #generate final line with clk and serIn to 0
|
||||
|
||||
|
||||
#NOT IMPLEMENTED YET
|
||||
#TODO! What should setstop do? Or can we remove it?
|
||||
#def setstop():
|
||||
#
|
||||
|
||||
def setoutput(self, bit):
|
||||
self.pattern.ioctrl = setbit(bit, self.pattern.ioctrl)
|
||||
|
||||
def setinput(self, bit):
|
||||
self.pattern.ioctrl= clearbit(bit, self.pattern.ioctrl)
|
||||
|
||||
#TODO! What should setclk do? Or can we remove it?
|
||||
# def setclk(bit):
|
||||
# self.clkctrl=self.setbit(bit,self.clkctrl)
|
||||
|
||||
def setinputs(self, *args):
|
||||
for i in args:
|
||||
self.setinput(i)
|
||||
|
||||
def setoutputs(self, *args):
|
||||
for i in args:
|
||||
self.setoutput(i)
|
||||
|
||||
#def setclks(self, *args):
|
||||
# for i in args:
|
||||
# self.setclk(i)
|
||||
|
||||
def setnloop(self, i, reps):
|
||||
self.pattern.nloop[i] = reps
|
||||
|
||||
def setstartloop(self, i):
|
||||
"""
|
||||
Set startloop[i] to the current address.
|
||||
"""
|
||||
self.pattern.startloop[i] = self.iaddr
|
||||
|
||||
def setstoploop(self, i):
|
||||
"""
|
||||
Set stoploop[i] to the current address.
|
||||
"""
|
||||
self.pattern.stoploop[i] = self.iaddr
|
||||
|
||||
|
||||
def setstart(self):
|
||||
"""
|
||||
Set start of pattern to the current address.
|
||||
"""
|
||||
self.pattern.limits[0]=self.iaddr
|
||||
|
||||
|
||||
def setstop(self,l):
|
||||
"""
|
||||
Set stop of pattern to the current address.
|
||||
"""
|
||||
self.pattern.limits[1] = self.iaddr
|
||||
|
||||
|
||||
def setwaitpoint(self, i):
|
||||
"""
|
||||
Set wait[i] to the current address.
|
||||
"""
|
||||
self.pattern.wait[i] = self.iaddr
|
||||
|
||||
|
||||
def setwaittime(self, i, t):
|
||||
"""
|
||||
Set waittime[i] to t.
|
||||
"""
|
||||
self.pattern.waittime[i] = t
|
||||
|
||||
|
||||
def setwait(self, i, t):
|
||||
"""
|
||||
Set wait[i] to the current address and waittime[i] to t.
|
||||
"""
|
||||
self.setwait(i)
|
||||
self.setwaittime(i, t)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return textwrap.dedent(f"""\
|
||||
PatternBuilder:
|
||||
patlimits: {self.pattern.limits}
|
||||
startloop: {self.pattern.startloop}
|
||||
stoploop: {self.pattern.stoploop}
|
||||
nloop: {self.pattern.nloop}
|
||||
wait: {self.pattern.wait}
|
||||
waittime: {self.pattern.waittime}""")
|
||||
|
||||
def __str__(self):
|
||||
return self.pattern.str()
|
||||
|
||||
def print(self):
|
||||
print(self)
|
||||
|
||||
def save(self, fname):
|
||||
"""Save pattern to text file"""
|
||||
fname = str(fname) #Accept also Path objects, but C++ code needs a string
|
||||
self.pattern.save(fname)
|
||||
|
||||
def load(self, fname):
|
||||
"""Load pattern from text file"""
|
||||
fname = str(fname) #Accept also Path objects, but C++ code needs a string
|
||||
n = self.pattern.load(fname)
|
||||
|
||||
#If the firs and only word is 0 we assume an empty pattern
|
||||
if n == 1 and self.pattern.word[0] == 0:
|
||||
n = 0
|
||||
self.iaddr = n
|
||||
|
||||
#To make PW work as expected we need to set 1+last word to the last word
|
||||
if n > 0:
|
||||
self.pattern.word[n] = self.pattern.word[n-1]
|
||||
|
||||
|
||||
def send_to_detector(self, det):
|
||||
"""
|
||||
Load the pattern into the detector.
|
||||
"""
|
||||
det.setPattern(self.pattern)
|
@ -9,12 +9,12 @@ from .detector import Detector
|
||||
from .jungfrau import Jungfrau
|
||||
from .mythen3 import Mythen3
|
||||
from .gotthard2 import Gotthard2
|
||||
from .gotthard import Gotthard
|
||||
from .moench import Moench
|
||||
from .pattern import Pattern, patternParameters
|
||||
from .gaincaps import Mythen3GainCapsWrapper
|
||||
from .PatternGenerator import PatternGenerator
|
||||
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
xy = _slsdet.xy
|
||||
defs = _slsdet.slsDetectorDefs
|
||||
|
||||
@ -41,6 +41,3 @@ def read_version():
|
||||
|
||||
__version__ = read_version()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
def setbit(bit, word):
|
||||
if isinstance(word, np.generic):
|
||||
mask = word.dtype.type(1)
|
||||
mask = mask << bit
|
||||
else:
|
||||
mask = 1 << bit
|
||||
return word | mask
|
||||
|
||||
|
||||
def setbit_arr(bit, arr):
|
||||
arr |= arr.dtype.type(1 << bit)
|
||||
|
||||
|
||||
def clearbit(bit, word):
|
||||
"""
|
||||
Clear the bit at position bit in word.
|
||||
Two paths to avoid converting the types.
|
||||
"""
|
||||
if isinstance(word, np.generic):
|
||||
mask = word.dtype.type(1)
|
||||
mask = ~(mask << bit)
|
||||
else:
|
||||
mask = ~(1 << bit)
|
||||
return word & mask
|
||||
|
||||
|
||||
def clearbit_arr(bit, arr):
|
||||
arr &= arr.dtype.type(~(1 << bit))
|
@ -4,7 +4,7 @@ from .detector import Detector, freeze
|
||||
from .utils import element_if_equal
|
||||
from .dacs import DetectorDacs, NamedDacs
|
||||
from .powers import DetectorPowers, NamedPowers
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
from .detector_property import DetectorProperty
|
||||
from functools import partial
|
||||
import numpy as np
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
from .detector import freeze
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
class Dac(DetectorProperty):
|
||||
|
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
from ._slsdet import CppDetectorApi
|
||||
from ._slsdet import slsDetectorDefs
|
||||
from ._slsdet import IpAddr, MacAddr
|
||||
from _slsdet import CppDetectorApi
|
||||
from _slsdet import slsDetectorDefs
|
||||
from _slsdet import IpAddr, MacAddr
|
||||
|
||||
runStatus = slsDetectorDefs.runStatus
|
||||
timingMode = slsDetectorDefs.timingMode
|
||||
@ -15,7 +15,7 @@ defs = slsDetectorDefs
|
||||
|
||||
from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask
|
||||
from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list
|
||||
from ._slsdet import xy
|
||||
from _slsdet import xy
|
||||
from .gaincaps import Mythen3GainCapsWrapper
|
||||
from . import utils as ut
|
||||
from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
|
||||
@ -151,10 +151,6 @@ class Detector(CppDetectorApi):
|
||||
def hostname(self):
|
||||
"""Frees shared memory and sets hostname (or IP address) of all modules concatenated by +
|
||||
Virtual servers can already use the port in hostname separated by ':' and ports incremented by 2 to accomodate the stop server as well.
|
||||
|
||||
Note
|
||||
-----
|
||||
The row and column values in the udp/zmq header are affected by the order in this command and the detsize command. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on. This only affects row and column in udp/zmq header.
|
||||
|
||||
Example
|
||||
-------
|
||||
@ -274,7 +270,7 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
@element
|
||||
def serialnumber(self):
|
||||
"""Jungfrau][Mythen3][Gotthard2][CTB][Moench] Serial number of detector """
|
||||
"""Jungfrau][Gotthard][Mythen3][Gotthard2][CTB][Moench] Serial number of detector """
|
||||
return ut.lhex(self.getSerialNumber())
|
||||
|
||||
@property
|
||||
@ -312,7 +308,7 @@ class Detector(CppDetectorApi):
|
||||
-----
|
||||
[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n
|
||||
[Mythen3] Options: 8, 16, 32 \n
|
||||
[Jungfrau][Moench][Ctb][Mythen3][Gotthard2][Xilinx Ctb] 16
|
||||
[Jungfrau][Moench][Gotthard][Ctb][Mythen3][Gotthard2][Xilinx Ctb] 16
|
||||
"""
|
||||
return self.getDynamicRange()
|
||||
|
||||
@ -372,6 +368,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
[Eiger] Use threshold command to load settings
|
||||
[Jungfrau] GAIN0, HIGHGAIN0 \n
|
||||
[Gotthard] DYNAMICGAIN, HIGHGAIN, LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN \n
|
||||
[Gotthard2] DYNAMICGAIN, FIXGAIN1, FIXGAIN2 \n
|
||||
[Eiger] settings loaded from file found in settingspath
|
||||
[Moench] G1_HIGHGAIN, G1_LOWGAIN, G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN, G2_LOWCAP_HIGHGAIN, G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN
|
||||
@ -403,7 +400,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def framesl(self):
|
||||
"""
|
||||
[Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx CTB] Number of frames left in acquisition.\n
|
||||
[Gotthard][Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx CTB] Number of frames left in acquisition.\n
|
||||
|
||||
Note
|
||||
----
|
||||
@ -634,7 +631,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def periodl(self):
|
||||
"""
|
||||
[Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Period left for current frame.
|
||||
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Period left for current frame.
|
||||
|
||||
Note
|
||||
-----
|
||||
@ -656,7 +653,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def delay(self):
|
||||
"""
|
||||
[Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Delay after trigger, accepts either a value in seconds, DurationWrapper or datetime.timedelta
|
||||
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Delay after trigger, accepts either a value in seconds, DurationWrapper or datetime.timedelta
|
||||
|
||||
:getter: always returns in seconds. To get in DurationWrapper, use getDelayAfterTrigger
|
||||
|
||||
@ -698,7 +695,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def delayl(self):
|
||||
"""
|
||||
[Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Delay left after trigger during acquisition, accepts either a value in seconds, datetime.timedelta or DurationWrapper
|
||||
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Delay left after trigger during acquisition, accepts either a value in seconds, datetime.timedelta or DurationWrapper
|
||||
|
||||
Note
|
||||
-----
|
||||
@ -1443,6 +1440,8 @@ class Detector(CppDetectorApi):
|
||||
@udp_srcip.setter
|
||||
def udp_srcip(self, ip):
|
||||
if ip == "auto":
|
||||
if self.type == detectorType.GOTTHARD:
|
||||
raise NotImplementedError('Auto for udp_srcip cannot be used for GotthardI')
|
||||
ip = socket.gethostbyname(self.hostname[0])
|
||||
ip = ut.make_ip(ip)
|
||||
ut.set_using_dict(self.setSourceUDPIP, ip)
|
||||
@ -1523,6 +1522,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
Note
|
||||
-----
|
||||
[Gotthard] 0, 90, 110, 120, 150, 180, 200 \n
|
||||
[Eiger][Mythen3][Gotthard2] 0 - 200 \n
|
||||
[Jungfrau][Moench][Ctb] 0, 60 - 200
|
||||
"""
|
||||
@ -1650,7 +1650,7 @@ class Detector(CppDetectorApi):
|
||||
def master(self):
|
||||
"""
|
||||
[Eiger][Gotthard2][Jungfrau][Moench] Sets (half) module to master and other(s) to slaves.\n
|
||||
[Gotthard2][Mythen3][Eiger][Jungfrau][Moench] Gets if the current (half) module is master.
|
||||
[Gotthard][Gotthard2][Mythen3][Eiger][Jungfrau][Moench] Gets if the current (half) module is master.
|
||||
"""
|
||||
return self.getMaster()
|
||||
|
||||
@ -1908,7 +1908,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
@property
|
||||
def adcreg(self):
|
||||
"""[Jungfrau][Moench][Ctb] Writes to an adc register
|
||||
"""[Jungfrau][Moench][Ctb][Gotthard] Writes to an adc register
|
||||
|
||||
Note
|
||||
-----
|
||||
@ -1937,7 +1937,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def triggersl(self):
|
||||
"""
|
||||
[Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx CTB] Number of triggers left in acquisition.\n
|
||||
[Gotthard][Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx CTB] Number of triggers left in acquisition.\n
|
||||
|
||||
Note
|
||||
----
|
||||
@ -2202,7 +2202,7 @@ class Detector(CppDetectorApi):
|
||||
Note
|
||||
-----
|
||||
Default: AUTO_TIMING \n
|
||||
[Jungfrau][Moench][Ctb][Gotthard2][Xilinx Ctb] AUTO_TIMING, TRIGGER_EXPOSURE \n
|
||||
[Jungfrau][Moench][Gotthard][Ctb][Gotthard2][Xilinx Ctb] AUTO_TIMING, TRIGGER_EXPOSURE \n
|
||||
[Mythen3] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, TRIGGER_GATED \n
|
||||
[Eiger] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, BURST_TRIGGER
|
||||
"""
|
||||
@ -2259,7 +2259,7 @@ class Detector(CppDetectorApi):
|
||||
def type(self):
|
||||
""" Returns detector type.
|
||||
Enum: detectorType
|
||||
[EIGER, JUNGFRAU, MOENCH, MYTHEN3, GOTTHARD2, CHIPTESTBOARD]
|
||||
[EIGER, JUNGFRAU, GOTTHARD, MOENCH, MYTHEN3, GOTTHARD2, CHIPTESTBOARD]
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
@ -2566,7 +2566,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
Note
|
||||
-----
|
||||
By default, the on-chip gain switching is active during the entire exposure. This mode disables the on-chip gain switching comparator automatically and the duration is set using compdisabletime.\n
|
||||
By default, the on-chip gain switching is active during the entire exposure. This mode disables the on-chip gain switching comparator automatically after 93.75% of exposure time (only for longer than 100us). The % is only for chipv1.0, the duration can be set for chipv1.1.\n
|
||||
Default is 0 or this mode disabled (comparator enabled throughout). 1 enables mode. 0 disables mode.
|
||||
"""
|
||||
return self.getAutoComparatorDisable()
|
||||
@ -2580,6 +2580,10 @@ class Detector(CppDetectorApi):
|
||||
def compdisabletime(self):
|
||||
"""[Jungfrau] Time before end of exposure when comparator is disabled.
|
||||
|
||||
Note
|
||||
-----
|
||||
It is only possible for chipv1.1.
|
||||
|
||||
:getter: always returns in seconds. To get in DurationWrapper, use getComparatorDisableTime
|
||||
|
||||
Example
|
||||
@ -2909,7 +2913,7 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
@element
|
||||
def timing_info_decoder(self):
|
||||
"""[Jungfrau] [Jungfrau] Advanced Command and only for SWISSFEL and SHINE. Sets the bunch id or timing info decoder. Default is SWISSFEL. Only allowed for pcbv2.0.
|
||||
"""[Jungfrau] [Jungfrau] Advanced Command and only for SWISSFEL and SHINE. Sets the bunch id or timing info decoder. Default is SWISSFEL.
|
||||
Enum: timingInfoDecoder
|
||||
"""
|
||||
return self.getTimingInfoDecoder()
|
||||
@ -3463,16 +3467,6 @@ class Detector(CppDetectorApi):
|
||||
def rx_dbitoffset(self, value):
|
||||
ut.set_using_dict(self.setRxDbitOffset, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_dbitreorder(self):
|
||||
"""[Ctb] Reorder digital data to group together all samples per signal. Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together."""
|
||||
return self.getRxDbitReorder()
|
||||
|
||||
@rx_dbitreorder.setter
|
||||
def rx_dbitreorder(self, value):
|
||||
ut.set_using_dict(self.setRxDbitReorder, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def maxadcphaseshift(self):
|
||||
@ -3485,13 +3479,15 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
@element
|
||||
def adcphase(self):
|
||||
"""[Jungfrau][Moench][CTB] Sets phase shift of ADC clock.
|
||||
"""[Gotthard][Jungfrau][Moench][CTB] Sets phase shift of ADC clock.
|
||||
|
||||
Note
|
||||
-----
|
||||
[Jungfrau][Moench] Absolute phase shift. Changing Speed also resets adcphase to recommended defaults.\n
|
||||
[Ctb] Absolute phase shift. Changing adcclk also resets adcphase and sets it to previous values.
|
||||
[Ctb] Absolute phase shift. Changing adcclk also resets adcphase and sets it to previous values.\n
|
||||
[Gotthard] Relative phase shift.
|
||||
|
||||
:getter: Not implemented for Gotthard
|
||||
"""
|
||||
return self.getADCPhase()
|
||||
|
||||
@ -3706,13 +3702,7 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
def patwaittime(self):
|
||||
"""
|
||||
[Ctb][Mythen3][Xilinx Ctb] Wait time in clock cycles of loop level provided.
|
||||
|
||||
Info
|
||||
----
|
||||
|
||||
:getter: Always return in clock cycles. To get in DurationWrapper, use getPatternWaitInterval
|
||||
:setter: Accepts either a value in clock cycles or a time unit (timedelta, DurationWrapper)
|
||||
[Ctb][Mythen3][Xilinx Ctb] Wait time in clock cycles of loop level provided.
|
||||
|
||||
Example
|
||||
-------
|
||||
@ -3723,85 +3713,41 @@ class Detector(CppDetectorApi):
|
||||
0: 5
|
||||
1: 20
|
||||
2: 30
|
||||
>>> # using timedelta (up to microseconds precision)
|
||||
>>> from datetime import timedelta
|
||||
>>> d.patwaittime[0] = timedelta(seconds=1, microseconds=3)
|
||||
>>>
|
||||
>>> # using DurationWrapper to set in seconds
|
||||
>>> from slsdet import DurationWrapper
|
||||
>>> d.patwaittime[0] = DurationWrapper(1.2)
|
||||
>>>
|
||||
>>> # using DurationWrapper to set in ns
|
||||
>>> t = DurationWrapper()
|
||||
>>> t.set_count(500)
|
||||
>>> d.patwaittime = t
|
||||
>>>
|
||||
>>> # to get in clock cycles
|
||||
>>> d.patwaittime
|
||||
1000
|
||||
>>>
|
||||
>>> d.getPatternWaitInterval(0)
|
||||
sls::DurationWrapper(total_seconds: 1.23 count: 1230000000)
|
||||
"""
|
||||
return PatWaitTimeProxy(self)
|
||||
|
||||
@property
|
||||
@element
|
||||
def patwaittime0(self):
|
||||
"""[Ctb][Mythen3][Xilinx Ctb] Wait 0 time in clock cycles."""
|
||||
return self.getPatternWaitTime(0)
|
||||
|
||||
def create_patwaittime_property(level):
|
||||
docstring_template ="""
|
||||
Deprecated command. Use patwaittime instead.
|
||||
[Ctb][Mythen3][Xilinx Ctb] Wait time in clock cycles of loop level {level} provided.
|
||||
@patwaittime0.setter
|
||||
def patwaittime0(self, nclk):
|
||||
nclk = ut.merge_args(0, nclk)
|
||||
ut.set_using_dict(self.setPatternWaitTime, *nclk)
|
||||
|
||||
Info
|
||||
----
|
||||
@property
|
||||
@element
|
||||
def patwaittime1(self):
|
||||
"""[Ctb][Mythen3][Xilinx Ctb] Wait 1 time in clock cycles."""
|
||||
return self.getPatternWaitTime(1)
|
||||
|
||||
:getter: Always return in clock cycles. To get in DurationWrapper, use getPatternWaitInterval
|
||||
:setter: Accepts either a value in clock cycles or a time unit (timedelta, DurationWrapper)
|
||||
|
||||
Example
|
||||
-------
|
||||
>>> d.patwaittime{level} = 5
|
||||
>>> d.patwaittime{level}
|
||||
5
|
||||
>>> # using timedelta (up to microseconds precision)
|
||||
>>> from datetime import timedelta
|
||||
>>> d.patwaittime{level} = timedelta(seconds=1, microseconds=3)
|
||||
>>>
|
||||
>>> # using DurationWrapper to set in seconds
|
||||
>>> from slsdet import DurationWrapper
|
||||
>>> d.patwaittime{level} = DurationWrapper(1.2)
|
||||
>>>
|
||||
>>> # using DurationWrapper to set in ns
|
||||
>>> t = DurationWrapper()
|
||||
>>> t.set_count(500)
|
||||
>>> d.patwaittime{level} = t
|
||||
>>>
|
||||
>>> # to get in clock cycles
|
||||
>>> d.patwaittime{level}
|
||||
1000
|
||||
>>>
|
||||
>>> d.getPatternWaitInterval(level)
|
||||
sls::DurationWrapper(total_seconds: 1.23 count: 1230000000)
|
||||
"""
|
||||
@property
|
||||
@element
|
||||
def patwaittime(self):
|
||||
return self.getPatternWaitClocks(level)
|
||||
@patwaittime1.setter
|
||||
def patwaittime1(self, nclk):
|
||||
nclk = ut.merge_args(1, nclk)
|
||||
ut.set_using_dict(self.setPatternWaitTime, *nclk)
|
||||
|
||||
@patwaittime.setter
|
||||
def patwaittime(self, value):
|
||||
if isinstance(value, (int, float)) and not isinstance(value, bool):
|
||||
nclk = ut.merge_args(level, value)
|
||||
ut.set_using_dict(self.setPatternWaitClocks, level, *nclk)
|
||||
else:
|
||||
ut.set_time_using_dict(self.setPatternWaitInterval, level, value)
|
||||
|
||||
patwaittime.__doc__ = docstring_template.format(level=level)
|
||||
@property
|
||||
@element
|
||||
def patwaittime2(self):
|
||||
"""[Ctb][Mythen3][Xilinx Ctb] Wait 2 time in clock cycles."""
|
||||
return self.getPatternWaitTime(2)
|
||||
|
||||
return patwaittime
|
||||
|
||||
patwaittime0 = create_patwaittime_property(0)
|
||||
patwaittime1 = create_patwaittime_property(1)
|
||||
patwaittime2 = create_patwaittime_property(2)
|
||||
@patwaittime2.setter
|
||||
def patwaittime2(self, nclk):
|
||||
nclk = ut.merge_args(2, nclk)
|
||||
ut.set_using_dict(self.setPatternWaitTime, *nclk)
|
||||
|
||||
|
||||
@property
|
||||
@ -4092,6 +4038,27 @@ class Detector(CppDetectorApi):
|
||||
return ClkDivProxy(self)
|
||||
|
||||
|
||||
"""
|
||||
---------------------------<<<Gotthard specific>>>---------------------------
|
||||
"""
|
||||
|
||||
@property
|
||||
def exptimel(self):
|
||||
"""[Gotthard] Exposure time left for current frame.
|
||||
|
||||
:getter: always returns in seconds. To get in DurationWrapper, use getExptimeLeft
|
||||
:setter: Not Implemented
|
||||
|
||||
Example
|
||||
-----------
|
||||
>>> d.exptimel
|
||||
181.23
|
||||
>>> d.getExptimeLeft()
|
||||
[sls::DurationWrapper(total_seconds: 181.23 count: 181230000000)]
|
||||
"""
|
||||
t = self.getExptimeLeft()
|
||||
return reduce_time(t)
|
||||
|
||||
|
||||
"""
|
||||
---------------------------<<<Mythen3 specific>>>---------------------------
|
||||
|
@ -11,7 +11,7 @@ Created on Wed Dec 6 11:51:18 2017
|
||||
from .detector import Detector
|
||||
from .temperature import Temperature, DetectorTemperature
|
||||
from .dacs import DetectorDacs
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
|
@ -15,8 +15,8 @@ if dt === detectorType.EIGER:
|
||||
"""
|
||||
|
||||
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
for name, cls in _slsdet.slsDetectorDefs.__dict__.items():
|
||||
if isinstance(cls, type):
|
||||
exec(f'{name} = _slsdet.{cls.__qualname__}')
|
||||
exec(f'{name} = {cls.__module__}.{cls.__qualname__}')
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
gc = _slsdet.slsDetectorDefs.M3_GainCaps
|
||||
|
||||
|
||||
|
53
python/slsdet/gotthard.py
Normal file
53
python/slsdet/gotthard.py
Normal file
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This file contains the specialization for the Moench detector
|
||||
"""
|
||||
|
||||
|
||||
from .detector import Detector, freeze
|
||||
from .dacs import DetectorDacs
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
# @freeze
|
||||
|
||||
# vref_ds, vcascn_pb, vcascp_pb, vout_cm, vcasc_out, vin_cm, vref_comp, ib_test_c
|
||||
class GotthardDacs(DetectorDacs):
|
||||
_dacs = [('vref_ds', dacIndex.VREF_DS, 0, 4000, 660),
|
||||
('vcascn_pb', dacIndex.VCASCN_PB, 0, 4000, 650),
|
||||
('vcascp_pb,', dacIndex.VCASCP_PB, 0, 4000, 1480),
|
||||
('vout_cm', dacIndex.VOUT_CM, 0, 4000, 1520),
|
||||
('vcasc_out', dacIndex.VCASC_OUT, 0, 4000, 1320),
|
||||
('vin_cm', dacIndex.VIN_CM, 0, 4000, 1350),
|
||||
('vref_comp', dacIndex.VREF_COMP, 0, 4000, 350),
|
||||
('ib_test_c', dacIndex.IB_TESTC, 0, 4000, 2001),
|
||||
]
|
||||
_dacnames = [_d[0] for _d in _dacs]
|
||||
|
||||
#vthreshold??
|
||||
|
||||
|
||||
@freeze
|
||||
class Gotthard(Detector):
|
||||
"""
|
||||
Subclassing Detector to set up correct dacs and detector specific
|
||||
functions.
|
||||
"""
|
||||
_detector_dynamic_range = [16]
|
||||
|
||||
|
||||
_settings = ['standard', 'highgain', 'lowgain', 'veryhighgain', 'verylowgain']
|
||||
"""available settings for Eiger, note almost always standard"""
|
||||
|
||||
def __init__(self, id=0):
|
||||
super().__init__(id)
|
||||
self._frozen = False
|
||||
self._dacs = GotthardDacs(self)
|
||||
|
||||
@property
|
||||
def dacs(self):
|
||||
return self._dacs
|
@ -11,7 +11,7 @@ from .detector import Detector, freeze
|
||||
|
||||
# from .adcs import Adc, DetectorAdcs
|
||||
from .dacs import DetectorDacs
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
|
@ -11,7 +11,7 @@ from .detector import Detector, freeze
|
||||
|
||||
# from .adcs import Adc, DetectorAdcs
|
||||
from .dacs import DetectorDacs
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
|
@ -9,7 +9,7 @@ This file contains the specialization for the Moench detector
|
||||
|
||||
from .detector import Detector, freeze
|
||||
from .dacs import DetectorDacs
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
|
@ -11,7 +11,7 @@ from .detector import Detector, freeze
|
||||
|
||||
# from .adcs import Adc, DetectorAdcs
|
||||
from .dacs import DetectorDacs
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
gc_enums = _slsdet.slsDetectorDefs.M3_GainCaps
|
||||
from .detector_property import DetectorProperty
|
||||
|
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
|
||||
from ._slsdet import Pattern
|
||||
from _slsdet import Pattern
|
||||
|
||||
|
||||
class patternParameters(_slsdet.patternParameters):
|
||||
|
@ -3,7 +3,7 @@
|
||||
from .detector_property import DetectorProperty
|
||||
from functools import partial
|
||||
import numpy as np
|
||||
from . import _slsdet
|
||||
import _slsdet
|
||||
from .detector import freeze
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
class Power(DetectorProperty):
|
||||
|
@ -3,7 +3,7 @@
|
||||
from .utils import element_if_equal
|
||||
from .enums import dacIndex
|
||||
from .defines import M3_MAX_PATTERN_LEVELS, MAX_PATTERN_LEVELS
|
||||
from ._slsdet import slsDetectorDefs
|
||||
from _slsdet import slsDetectorDefs
|
||||
detectorType = slsDetectorDefs.detectorType
|
||||
|
||||
|
||||
@ -275,13 +275,10 @@ class PatWaitTimeProxy:
|
||||
self.det = det
|
||||
|
||||
def __getitem__(self, key):
|
||||
return element_if_equal(self.det.getPatternWaitClocks(key))
|
||||
return element_if_equal(self.det.getPatternWaitTime(key))
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if isinstance(value, (int, float)) and not isinstance(value, bool):
|
||||
set_proxy_using_dict(self.det.setPatternWaitClocks, key, value)
|
||||
else:
|
||||
set_proxy_using_dict(self.det.setPatternWaitInterval, key, value)
|
||||
set_proxy_using_dict(self.det.setPatternWaitTime, key, value)
|
||||
|
||||
def __repr__(self):
|
||||
max_levels = MAX_PATTERN_LEVELS
|
||||
|
@ -6,7 +6,7 @@ but not directly used in controlling the detector
|
||||
"""
|
||||
|
||||
from collections import namedtuple
|
||||
from . import _slsdet #C++ lib
|
||||
import _slsdet #C++ lib
|
||||
import functools
|
||||
import datetime as dt
|
||||
import pathlib
|
||||
|
@ -1293,6 +1293,20 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(defs::collectionMode, sls::Positions)) &
|
||||
Detector::setCollectionMode,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getROI",
|
||||
(Result<defs::ROI>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getROI,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("setROI",
|
||||
(void (Detector::*)(defs::ROI, int)) & Detector::setROI,
|
||||
py::arg(), py::arg());
|
||||
CppDetectorApi.def(
|
||||
"clearROI", (void (Detector::*)(sls::Positions)) & Detector::clearROI,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("getExptimeLeft",
|
||||
(Result<sls::ns>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getExptimeLeft,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("getNumberOfBursts",
|
||||
(Result<int64_t>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getNumberOfBursts,
|
||||
@ -1664,14 +1678,6 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(int, sls::Positions)) &
|
||||
Detector::setRxDbitOffset,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getRxDbitReorder",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getRxDbitReorder,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("setRxDbitReorder",
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
Detector::setRxDbitReorder,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("setDigitalIODelay",
|
||||
(void (Detector::*)(uint64_t, int, sls::Positions)) &
|
||||
Detector::setDigitalIODelay,
|
||||
@ -1855,22 +1861,13 @@ void init_det(py::module &m) {
|
||||
Detector::setPatternWaitAddr,
|
||||
py::arg(), py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getPatternWaitClocks",
|
||||
"getPatternWaitTime",
|
||||
(Result<uint64_t>(Detector::*)(int, sls::Positions) const) &
|
||||
Detector::getPatternWaitClocks,
|
||||
Detector::getPatternWaitTime,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("setPatternWaitClocks",
|
||||
CppDetectorApi.def("setPatternWaitTime",
|
||||
(void (Detector::*)(int, uint64_t, sls::Positions)) &
|
||||
Detector::setPatternWaitClocks,
|
||||
py::arg(), py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getPatternWaitInterval",
|
||||
(Result<sls::ns>(Detector::*)(int, sls::Positions) const) &
|
||||
Detector::getPatternWaitInterval,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("setPatternWaitInterval",
|
||||
(void (Detector::*)(int, sls::ns, sls::Positions)) &
|
||||
Detector::setPatternWaitInterval,
|
||||
Detector::setPatternWaitTime,
|
||||
py::arg(), py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getPatternMask",
|
||||
(Result<uint64_t>(Detector::*)(sls::Positions)) &
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <chrono>
|
||||
#include "py_headers.h"
|
||||
|
||||
#include "DurationWrapper.h"
|
||||
@ -20,25 +19,4 @@ void init_duration(py::module &m) {
|
||||
<< " count: " << self.count() << ")";
|
||||
return ss.str();
|
||||
});
|
||||
|
||||
m.def(
|
||||
"test_return_DurationWrapper",
|
||||
[]() {
|
||||
DurationWrapper t(1.3);
|
||||
return t;
|
||||
},
|
||||
R"(
|
||||
Test function to return a DurationWrapper object. Ensures that the automatic conversion in typecaster.h works.
|
||||
)");
|
||||
|
||||
m.def(
|
||||
"test_duration_to_ns",
|
||||
[](const std::chrono::nanoseconds t) {
|
||||
//Duration wrapper is used to be able to convert from time in python to chrono::nanoseconds
|
||||
//return count to have something to test
|
||||
return t.count();
|
||||
},
|
||||
R"(
|
||||
Test function convert DurationWrapper or number to chrono::ns. Ensures that the automatic conversion in typecaster.h works.
|
||||
)"); // default value to test the default constructor
|
||||
}
|
||||
|
@ -121,9 +121,13 @@ void init_enums(py::module &m) {
|
||||
.value("VTHRESHOLD", slsDetectorDefs::dacIndex::VTHRESHOLD)
|
||||
.value("IO_DELAY", slsDetectorDefs::dacIndex::IO_DELAY)
|
||||
.value("VREF_DS", slsDetectorDefs::dacIndex::VREF_DS)
|
||||
.value("VCASCN_PB", slsDetectorDefs::dacIndex::VCASCN_PB)
|
||||
.value("VCASCP_PB", slsDetectorDefs::dacIndex::VCASCP_PB)
|
||||
.value("VOUT_CM", slsDetectorDefs::dacIndex::VOUT_CM)
|
||||
.value("VCASC_OUT", slsDetectorDefs::dacIndex::VCASC_OUT)
|
||||
.value("VIN_CM", slsDetectorDefs::dacIndex::VIN_CM)
|
||||
.value("VREF_COMP", slsDetectorDefs::dacIndex::VREF_COMP)
|
||||
.value("IB_TESTC", slsDetectorDefs::dacIndex::IB_TESTC)
|
||||
.value("VB_COMP", slsDetectorDefs::dacIndex::VB_COMP)
|
||||
.value("VDD_PROT", slsDetectorDefs::dacIndex::VDD_PROT)
|
||||
.value("VIN_COM", slsDetectorDefs::dacIndex::VIN_COM)
|
||||
|
@ -20,10 +20,8 @@ void init_pattern(py::module &m) {
|
||||
});
|
||||
|
||||
py::class_<sls::Pattern> Pattern(m, "Pattern");
|
||||
Pattern.def(py::init())
|
||||
.def("load", &sls::Pattern::load)
|
||||
.def("save", &sls::Pattern::save)
|
||||
.def("str", &sls::Pattern::str)
|
||||
.def("data", (pat * (sls::Pattern::*)()) & sls::Pattern::data,
|
||||
Pattern.def(py::init());
|
||||
Pattern.def("load", &sls::Pattern::load);
|
||||
Pattern.def("data", (pat * (sls::Pattern::*)()) & sls::Pattern::data,
|
||||
py::return_value_policy::reference);
|
||||
}
|
||||
|
@ -54,16 +54,11 @@ template <> struct type_caster<std::chrono::nanoseconds> {
|
||||
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");
|
||||
py::object py_cls = py::module::import("_slsdet").attr("DurationWrapper");
|
||||
if (py::isinstance(src, py_cls)){
|
||||
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
|
||||
value = nanoseconds(cls->count());
|
||||
@ -82,7 +77,7 @@ template <> struct type_caster<std::chrono::nanoseconds> {
|
||||
* 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 py_cls = py::module::import("_slsdet").attr("DurationWrapper");
|
||||
py::object* obj = new py::object;
|
||||
*obj = py_cls();
|
||||
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
|
||||
|
@ -1,58 +0,0 @@
|
||||
import pytest
|
||||
|
||||
from slsdet import DurationWrapper
|
||||
|
||||
#import the compiled extension to use test functions for the automatic conversion
|
||||
from slsdet import _slsdet
|
||||
|
||||
|
||||
def test_default_construction_of_DurationWrapper():
|
||||
"""Test default construction of DurationWrapper"""
|
||||
t = DurationWrapper()
|
||||
assert t.count() == 0
|
||||
assert t.total_seconds() == 0
|
||||
|
||||
def test_construction_of_DurationWrapper():
|
||||
"""Test construction of DurationWrapper with total_seconds"""
|
||||
t = DurationWrapper(5)
|
||||
assert t.count() == 5e9
|
||||
assert t.total_seconds() == 5
|
||||
|
||||
def test_set_count_on_DurationWrapper():
|
||||
"""Test set_count on DurationWrapper"""
|
||||
t = DurationWrapper()
|
||||
t.set_count(10)
|
||||
assert t.count() == 10
|
||||
assert t.total_seconds() == 10e-9
|
||||
t.set_count(0)
|
||||
assert t.count() == 0
|
||||
assert t.total_seconds() == 0
|
||||
|
||||
|
||||
def test_return_a_DurationWrapper_from_cpp():
|
||||
"""Test returning a DurationWrapper from C++"""
|
||||
t = _slsdet.test_return_DurationWrapper()
|
||||
assert t.count() == 1.3e9
|
||||
assert t.total_seconds() == 1.3
|
||||
|
||||
def test_call_a_cpp_function_with_a_duration_wrapper():
|
||||
"""C++ functions can accept a DurationWrapper"""
|
||||
t = DurationWrapper(5)
|
||||
assert _slsdet.test_duration_to_ns(t) == 5e9
|
||||
|
||||
def test_call_a_cpp_function_converting_number_to_DurationWrapper():
|
||||
"""int and float can be converted to std::chrono::nanoseconds"""
|
||||
assert _slsdet.test_duration_to_ns(0) == 0
|
||||
assert _slsdet.test_duration_to_ns(3) == 3e9
|
||||
assert _slsdet.test_duration_to_ns(1.3) == 1.3e9
|
||||
assert _slsdet.test_duration_to_ns(10e-9) == 10
|
||||
|
||||
def test_call_a_cpp_function_with_datetime_timedelta():
|
||||
"""datetime.timedelta can be converted to std::chrono::nanoseconds"""
|
||||
import datetime
|
||||
t = datetime.timedelta(seconds=5)
|
||||
assert _slsdet.test_duration_to_ns(t) == 5e9
|
||||
t = datetime.timedelta(seconds=0)
|
||||
assert _slsdet.test_duration_to_ns(t) == 0
|
||||
t = datetime.timedelta(seconds=1.3)
|
||||
assert _slsdet.test_duration_to_ns(t) == 1.3e9
|
@ -1,152 +0,0 @@
|
||||
import pytest
|
||||
from slsdet import PatternGenerator
|
||||
|
||||
|
||||
def apply_detconf(p):
|
||||
"""
|
||||
Hacky workaround to apply detConf_mh02 to a pattern
|
||||
"""
|
||||
DACMON = 0
|
||||
cnt_en_3 = 1
|
||||
pulse_counter_en = 2
|
||||
cnt_en_1 = 3
|
||||
par_load = 4
|
||||
pulse_mux_ctr = 5
|
||||
reset_cnt = 6
|
||||
reset_periphery = 7
|
||||
config_load = 8
|
||||
cnt_en_0 = 9
|
||||
tbl = 10
|
||||
clk_ext = 11
|
||||
trimbit_load_reg = 12
|
||||
store = 13
|
||||
data_in = 14
|
||||
en_pll_clk = 15
|
||||
cnt_en_2 = 16
|
||||
DACINT = 17
|
||||
data_out_slow = 18 #IN
|
||||
COMP2_MON = 19 #IN
|
||||
start_read = 20
|
||||
dac_store = 21
|
||||
CNT3_MON = 22 #IN
|
||||
EN_PIX_DIG_MON = 23
|
||||
clk_sel = 24
|
||||
BUSY = 25 #IN
|
||||
COMP3_MON = 26 #IN
|
||||
CNT2_MON = 27 #IN
|
||||
|
||||
dbit_ena=62 #FIFO LATCH
|
||||
adc_ena=63 #ADC ENABLE
|
||||
|
||||
#FPGA input/ouutputs
|
||||
p.setoutput(DACMON)
|
||||
p.setoutput(cnt_en_3)
|
||||
p.setoutput(pulse_counter_en)
|
||||
p.setoutput(cnt_en_1)
|
||||
p.setoutput(par_load)
|
||||
p.setoutput(pulse_mux_ctr)
|
||||
p.setoutput(reset_cnt)
|
||||
p.setoutput(reset_periphery)
|
||||
p.setoutput(cnt_en_0)
|
||||
p.setoutput(tbl)
|
||||
p.setoutput(clk_ext)
|
||||
p.setoutput(config_load)
|
||||
p.setoutput(trimbit_load_reg)
|
||||
p.setoutput(store)
|
||||
p.setoutput(data_in)
|
||||
p.setoutput(en_pll_clk)
|
||||
p.setoutput(cnt_en_2)
|
||||
p.setoutput(DACINT)
|
||||
p.setinput(data_out_slow)
|
||||
p.setinput(COMP2_MON)
|
||||
p.setoutput(start_read)
|
||||
p.setoutput(dac_store)
|
||||
p.setinput(CNT3_MON)
|
||||
p.setoutput(EN_PIX_DIG_MON)
|
||||
p.setoutput(clk_sel)
|
||||
p.setinput(BUSY)
|
||||
p.setinput(COMP3_MON)
|
||||
p.setinput(CNT2_MON)
|
||||
|
||||
#system signals
|
||||
p.setoutput(adc_ena)
|
||||
# FIFO LATCH
|
||||
p.setoutput(dbit_ena)
|
||||
return p
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_first_two_PW():
|
||||
p = PatternGenerator()
|
||||
|
||||
#The pattern is created with a single empty word
|
||||
assert p.pattern.limits[0] == 0
|
||||
assert p.pattern.limits[1] == 0
|
||||
|
||||
p.SB(8)
|
||||
p.PW()
|
||||
|
||||
#When doing the first PW the empty word is overwritten
|
||||
assert p.pattern.limits[0] == 0
|
||||
assert p.pattern.limits[1] == 0
|
||||
assert p.pattern.word[0] == 256
|
||||
|
||||
p.SB(9)
|
||||
p.PW()
|
||||
|
||||
#When doing the second PW we add a new word
|
||||
assert p.pattern.limits[0] == 0
|
||||
assert p.pattern.limits[1] == 1
|
||||
assert p.pattern.word[0] == 256
|
||||
assert p.pattern.word[1] == 768
|
||||
|
||||
def test_simple_pattern():
|
||||
"""
|
||||
Using enable pll pattern for MH02
|
||||
"""
|
||||
en_pll_clk = 15
|
||||
p = PatternGenerator()
|
||||
p = apply_detconf(p)
|
||||
p.SB(en_pll_clk)
|
||||
p.PW()
|
||||
p.PW()
|
||||
|
||||
lines = str(p).split("\n")
|
||||
|
||||
enable_pll_pattern = [
|
||||
"patword 0x0000 0x0000000000008000",
|
||||
"patword 0x0001 0x0000000000008000",
|
||||
"patioctrl 0xc000000001b3ffff",
|
||||
"patlimits 0x0000 0x0001",
|
||||
"patloop 0 0x1fff 0x1fff",
|
||||
"patnloop 0 0",
|
||||
"patloop 1 0x1fff 0x1fff",
|
||||
"patnloop 1 0",
|
||||
"patloop 2 0x1fff 0x1fff",
|
||||
"patnloop 2 0",
|
||||
"patloop 3 0x1fff 0x1fff",
|
||||
"patnloop 3 0",
|
||||
"patloop 4 0x1fff 0x1fff",
|
||||
"patnloop 4 0",
|
||||
"patloop 5 0x1fff 0x1fff",
|
||||
"patnloop 5 0",
|
||||
"patwait 0 0x1fff",
|
||||
"patwaittime 0 0",
|
||||
"patwait 1 0x1fff",
|
||||
"patwaittime 1 0",
|
||||
"patwait 2 0x1fff",
|
||||
"patwaittime 2 0",
|
||||
"patwait 3 0x1fff",
|
||||
"patwaittime 3 0",
|
||||
"patwait 4 0x1fff",
|
||||
"patwaittime 4 0",
|
||||
"patwait 5 0x1fff",
|
||||
"patwaittime 5 0",
|
||||
]
|
||||
|
||||
assert len(lines) == len(enable_pll_pattern)
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
assert line == enable_pll_pattern[i]
|
@ -1,50 +0,0 @@
|
||||
from slsdet.bits import clearbit, clearbit_arr, setbit, setbit_arr
|
||||
import numpy as np
|
||||
|
||||
|
||||
def test_clearbit_on_python_int():
|
||||
val = 5 # 0b101
|
||||
r = clearbit(0, val)
|
||||
assert r == 4
|
||||
assert val == 5
|
||||
|
||||
def test_setbit_on_python_int():
|
||||
val = 5 # 0b101
|
||||
r = setbit(1, val)
|
||||
assert r == 7
|
||||
assert val == 5
|
||||
|
||||
|
||||
def test_setbit_doesnt_change_type():
|
||||
word = np.int32(5)
|
||||
ret = setbit(0, word)
|
||||
assert isinstance(ret, np.int32)
|
||||
|
||||
|
||||
def test_clearbit_doesnt_change_type():
|
||||
word = np.uint8(5)
|
||||
ret = clearbit(0, word)
|
||||
assert isinstance(ret, np.uint8)
|
||||
|
||||
|
||||
|
||||
def test_setbit_on_array_element():
|
||||
arr = np.zeros(10, dtype=np.uint64)
|
||||
arr[5] = setbit(0, arr[5])
|
||||
arr[5] = setbit(1, arr[5])
|
||||
arr[5] = setbit(4, arr[5])
|
||||
assert arr[4] == 0
|
||||
assert arr[5] == 19 # 0b10011
|
||||
assert arr[6] == 0
|
||||
|
||||
|
||||
def test_setbit_arr():
|
||||
arr = np.zeros(10, dtype=np.int32)
|
||||
setbit_arr(3, arr[3:9])
|
||||
assert all(arr == np.array((0, 0, 0, 8, 8, 8, 8, 8, 8, 0), dtype=np.int32))
|
||||
|
||||
|
||||
def test_clearbit_arr():
|
||||
arr = np.array((5, 5, 5), dtype=np.int8)
|
||||
clearbit_arr(0, arr)
|
||||
assert all(arr == (4, 4, 4))
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer
|
1
serverBin/ctbDetectorServerv9.0.0
Symbolic link
1
serverBin/ctbDetectorServerv9.0.0
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv9.0.0
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer
|
1
serverBin/eigerDetectorServerv9.0.0
Symbolic link
1
serverBin/eigerDetectorServerv9.0.0
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv9.0.0
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer
|
1
serverBin/gotthard2DetectorServerv9.0.0
Symbolic link
1
serverBin/gotthard2DetectorServerv9.0.0
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv9.0.0
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer
|
1
serverBin/gotthardDetectorServerv9.0.0
Symbolic link
1
serverBin/gotthardDetectorServerv9.0.0
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv9.0.0
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer
|
1
serverBin/jungfrauDetectorServerv9.0.0
Symbolic link
1
serverBin/jungfrauDetectorServerv9.0.0
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv9.0.0
|
@ -1 +0,0 @@
|
||||
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer
|
1
serverBin/moenchDetectorServerv9.0.0
Symbolic link
1
serverBin/moenchDetectorServerv9.0.0
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv9.0.0
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user