Compare commits

...

71 Commits

Author SHA1 Message Date
88649a00b6 M3vtrim min (#454)
* Remove the vtrim min 600 check when setting threshold energy. vth1-3:200 - 2400, others 0-2800

* compile fix
2022-05-12 11:41:05 +02:00
b122c2fbdf Revert "Remove the vtrim min 600 check when setting threshold energy. vth1-3:200 - 2400, others 0-2800 (#452)" (#453)
This reverts commit 7d574375b4.
2022-05-12 11:38:34 +02:00
7d574375b4 Remove the vtrim min 600 check when setting threshold energy. vth1-3:200 - 2400, others 0-2800 (#452) 2022-05-12 11:06:14 +02:00
466d431081 update release notes 2022-05-10 15:35:44 +02:00
cd4520b051 not validating settings for dacs temporarily (#447) 2022-05-10 15:30:34 +02:00
0129c2c686 M3: master starts twice (non blocking) part 2 (#445)
* slaves and master vectors empty means all positions included: fixing double acquisition in masters

* debug print out
2022-05-10 15:23:39 +02:00
f55bdd6eae M3: master starts twice (non blocking) (#444)
* start acq for master m3 was sent twice (non blocking), removed redundant code, check that there is only one master

* m3 can have more than 1 master (when many master modules used independently)

* fix for singe mod m3 or other dets
2022-05-10 14:27:40 +02:00
36a1159f38 updated pybind11 from 2.6.2 to 2.9.2 2022-04-28 16:39:39 +02:00
98e2ddbb74 indent 2022-04-28 16:37:52 +02:00
fa12ab2858 Support external builds of python bindings, gui, ctbgui and moench stuff (#440)
Use already installed version of the slsDetectorPackage. Assumes that the library has already been built and installed either on a system wide location or pointed to by CMAKE_PREFIX_PATH
2022-04-28 16:35:29 +02:00
afeee5501c Fixpositions (#436)
* fix positions on server side

* wip

* numports wip

* wip

* jungfrau top inner interface row increment

* x, y detpos, wip

* removed eiger row indices flipping in gui (bottom flipping maintained)

* wip

* wip, jungfrau numinterfaces2

* jungfrau virtual works

* eiger, jungfrau, g2 virtual server works

* eiger positions fix, wip

* binaries in

* minor printout

* binaries in

* pointer bug

* comment to define test_mod_geometry define
2022-04-28 16:32:26 +02:00
b7153fe3e0 cmake fix 2022-04-27 11:29:04 +02:00
2db2694660 m3 rxr: inconsistent generaldata default (#435)
* inconsistent copy with generalData and implementation members, especially for m3 (non default rxr generic values), issue caught on second configure with non m3 default values, eg tengiga 0

* removing test
2022-04-22 16:02:10 +02:00
e1642cf37c bugfix cmake zeromq 2022-04-19 20:11:31 +02:00
086d22f1a3 Cleaning up the find zmq (#431) 2022-04-19 17:17:31 +02:00
52882cba20 M3: polarity, interpolation, pump probe (#421)
* wip, adding m3 functions: polarity, inerpolation, pumpprobe

* added interpol, polarity, pump probe, analog pulsing, digital pulsing

* tests

* binaries in

* update release

* added python polarity enum

* fixed python and minor readability in mythen3.c

* binarie sin

* added all the m3 funcs also in list.c and enablingall counters for enabling interpolation

* binarie sin
2022-04-08 15:18:01 +02:00
27c7fd9a97 Merge pull request #423 from slsdetectorgroup/rmoldserver
copy detector server: rm old server
2022-04-08 14:56:50 +02:00
5d16ba7e16 update release 2022-04-08 11:10:15 +02:00
d8c6f9141d Fixed crash on gendoc (#430)
Fixed by checking for help action before using the detector
added test that checks that for all helps this doesn't crash
Disabled Timer tests by default since they take ~2s
2022-04-07 16:20:54 +02:00
e9dc3d8c38 minor changes (#429)
Various small changes to the data processor
2022-04-07 14:39:26 +02:00
62418c1316 sls_receiver_header* in callbacks (#425)
* char* to sls_receiver_header* in receiver data call backs

* uint32_t to size_t in callbacks

* string to const std::string & for callbacks
2022-04-07 10:19:47 +02:00
835aa575b0 remaining for removing copydetectorserver 2022-04-05 14:55:45 +02:00
b42d65c5e2 merge fix 2022-04-05 14:33:43 +02:00
150d27cf95 removed copydetectorserver 2022-04-05 14:11:04 +02:00
95ed9551c0 Merge pull request #427 from slsdetectorgroup/m3mastertrigger
m3:bug fix: slaves shoudl always have trigger
2022-04-04 17:09:07 +02:00
0f2ec47b5f binaries in 2022-04-04 17:08:38 +02:00
fe895cd782 m3:bug fix: slaves shoudl always have trigger 2022-04-04 17:06:38 +02:00
11bf6a5c58 update release notes 2022-04-04 15:44:34 +02:00
8bce87c082 delete old servers also for copy detector server (via tftp) 2022-04-04 15:41:58 +02:00
61f38bf5a9 clearer error message for unknown detector type when hostname error 2022-04-04 13:10:27 +02:00
cbc7066620 Merge branch 'rmoldserver' of github.com:slsdetectorgroup/slsDetectorPackage into rmoldserver 2022-04-04 12:47:19 +02:00
509ed9101f comments 2022-04-04 12:47:12 +02:00
191cfa0abe binaries in 2022-04-04 12:46:14 +02:00
f712847061 minor 2022-04-04 12:45:19 +02:00
b875a95bd5 binaries in 2022-04-04 12:44:03 +02:00
45f57ebeb7 compile, wip 2022-04-04 12:41:30 +02:00
0309eba3c6 redundant of getting abs path starting with '/' 2022-04-04 12:40:10 +02:00
f0448b3cec binaries in 2022-04-04 12:36:47 +02:00
a18af0b726 fix inittab to minimum, wip 2022-04-04 12:31:26 +02:00
6aa5cb8d3e abs path of abs path, wip 2022-04-04 12:26:02 +02:00
479906a9eb minor 2022-04-04 12:16:24 +02:00
28a503ed5a minor 2022-04-04 12:12:21 +02:00
b3c5a431d0 resolve abs path in root dir, wip 2022-04-04 11:58:36 +02:00
43cde3609a minor 2022-04-04 11:27:34 +02:00
9d2d8fe1d7 resolve for doubel slashes, wip 2022-04-04 11:17:41 +02:00
1826dd46cb minor 2022-04-04 10:57:27 +02:00
cf6423dbbe delete old servers, wip 2022-04-04 10:45:44 +02:00
8b1851e652 wip, copy server delete old name 2022-04-01 17:52:27 +02:00
5913864cbb Merge pull request #419 from slsdetectorgroup/jsonmaster
Jsonmaster
2022-03-31 15:10:44 +02:00
c2ef6d700e merge fix 2022-03-31 15:09:58 +02:00
76296507ff updated release 2022-03-31 15:09:34 +02:00
03d2158472 Merge branch 'developer' into jsonmaster 2022-03-30 16:49:41 +02:00
bb7b676ca2 Merge pull request #420 from slsdetectorgroup/framesinfilehdf5
frames in file hdf5
2022-03-30 16:49:17 +02:00
e1988bf088 fixes 2022-03-30 16:47:43 +02:00
8ef1a209c9 added release notes 2022-03-30 16:06:04 +02:00
28572af3ab resetting frames in file when creating a new hdf5 file 2022-03-30 15:39:20 +02:00
c57e528447 wip, prettywriter 2022-03-30 10:43:43 +02:00
74e325edb4 removing \n in timestamp for json file 2022-03-30 09:06:09 +02:00
e68499bb09 Merge branch 'developer' into jsonmaster 2022-03-29 16:29:55 +02:00
8ce6868e46 fixed compilation 2022-03-29 16:13:33 +02:00
f5cca7a98f removed binary master file as well 2022-03-29 13:30:06 +02:00
b9aa0f46e4 wip, hdf5 refactored 2022-03-29 13:02:57 +02:00
6cd780ae99 wip 2022-03-29 11:49:30 +02:00
f2be834d55 wip, binary file refactored for stringbuffer, hdf5 mid way, masterattributes to be de (inherited) :) 2022-03-28 17:43:58 +02:00
e55e18d5e9 Refactoring of SharedMemory.h (#418)
Function names match Detector.h
Removed double print due to LOG then throw
file descriptor not kept as a member variable
2022-03-28 16:13:56 +02:00
66900da476 Minor fixes to dacnames 2022-03-28 14:39:31 +02:00
1ff35edb99 Setting dac names for CTB (C++ and Python) (#413)
# Setting DAC names for CTB
* Introduced new shared memory for CTB only
* Prepared for additional functionality 
* Works from C++ and Python

Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
2022-03-28 14:27:47 +02:00
9a969c1549 Merge branch 'developer' into jsonmaster 2022-03-28 12:32:21 +02:00
cbed2e88c6 wip, binary json master for other dets 2022-03-25 15:34:39 +01:00
0f02ffdc9a binary master json done, hdf5 left wip 2022-03-25 13:29:03 +01:00
90d1d0f8b8 wip, json master 2022-03-24 17:15:23 +01:00
88 changed files with 3048 additions and 2663 deletions

View File

@ -19,6 +19,7 @@ Checks: '*,
-google-readability-braces-around-statements,
-modernize-use-trailing-return-type,
-readability-isolate-declaration,
-readability-implicit-bool-conversion,
-llvmlibc-*'
HeaderFilterRegex: \.h

View File

@ -8,11 +8,8 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
cmake_policy(SET CMP0074 NEW)
include(cmake/project_version.cmake)
#functions to add compiler flags
include(cmake/SlsAddFlag.cmake)
# Include additional modules that are used unconditionally
include(cmake/SlsFindZeroMQ.cmake)
include(GNUInstallDirs)
# If conda build, always set lib dir to 'lib'
@ -26,7 +23,7 @@ string(TOLOWER "${PROJECT_NAME}" PROJECT_NAME_LOWER)
# Set targets export name (used by slsDetectorPackage and dependencies)
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWER}-targets")
#set(namespace "${PROJECT_NAME}::")
set(namespace "sls::")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
@ -37,6 +34,8 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(SLS_MASTER_PROJECT ON)
endif()
option(SLS_USE_HDF5 "HDF5 File format" OFF)
option(SLS_BUILD_SHARED_LIBRARIES "Build shared libaries" ON)
option(SLS_USE_TEXTCLIENT "Text Client" ON)
@ -69,6 +68,20 @@ if(SLS_BUILD_ONLY_MOENCH)
endif()
option(SLS_EXT_BUILD "external build of part of the project" OFF)
if(SLS_EXT_BUILD)
message(STATUS "External build using already installed libraries")
set(SLS_BUILD_SHARED_LIBRARIES OFF CACHE BOOL "Should already exist" FORCE)
set(SLS_USE_TEXTCLIENT OFF CACHE BOOL "Should already exist" FORCE)
set(SLS_USE_DETECTOR OFF CACHE BOOL "Should already exist" FORCE)
set(SLS_USE_RECEIVER OFF CACHE BOOL "Should already exist" FORCE)
set(SLS_USE_RECEIVER_BINARIES OFF CACHE BOOL "Should already exist" FORCE)
set(SLS_MASTER_PROJECT OFF CACHE BOOL "No master proj in case of extbuild" FORCE)
endif()
#Maybe have an option guarding this?
set(SLS_INTERNAL_RAPIDJSON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/rapidjson)
set(ClangFormat_EXCLUDE_PATTERNS "build/"
"libs/"
"slsDetectorCalibration/"
@ -79,9 +92,6 @@ set(ClangFormat_EXCLUDE_PATTERNS "build/"
${CMAKE_BINARY_DIR})
find_package(ClangFormat)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
@ -100,62 +110,68 @@ else()
endif()
#Add two fake libraries to manage options
add_library(slsProjectOptions INTERFACE)
add_library(slsProjectWarnings INTERFACE)
target_compile_features(slsProjectOptions INTERFACE cxx_std_11)
target_compile_options(slsProjectWarnings INTERFACE
-Wall
-Wextra
-Wno-unused-parameter
# -Wold-style-cast
-Wnon-virtual-dtor
-Woverloaded-virtual
-Wdouble-promotion
-Wformat=2
-Wredundant-decls
# -Wconversion
-Wvla
-Wdouble-promotion
-Werror=return-type
)
#Settings for C code
add_library(slsProjectCSettings INTERFACE)
target_compile_options(slsProjectCSettings INTERFACE
-std=gnu99 #fixed
-Wall
-Wextra
-Wno-unused-parameter
-Wdouble-promotion
-Wformat=2
-Wredundant-decls
-Wdouble-promotion
-Werror=return-type
)
#Testing for minimum version for compilers
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.2)
message(FATAL_ERROR "Clang version must be at least 3.2!")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
message(FATAL_ERROR "GCC version must be at least 4.8!")
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)
target_compile_options(slsProjectWarnings INTERFACE
-Wno-missing-field-initializers)
endif()
if(SLS_EXT_BUILD)
# Find ourself in case of external build
find_package(slsDetectorPackage ${PROJECT_VERSION} REQUIRED)
endif()
# Add or disable warnings depending on if the compiler supports them
# The function checks internally and sets HAS_warning-name
sls_enable_cxx_warning("-Wnull-dereference")
sls_enable_cxx_warning("-Wduplicated-cond")
sls_disable_cxx_warning("-Wclass-memaccess")
sls_disable_c_warning("-Wstringop-truncation")
# slsProjectOptions and slsProjectWarnings are used
# to control options for the libraries
if(NOT TARGET slsProjectOptions)
add_library(slsProjectOptions INTERFACE)
target_compile_features(slsProjectOptions INTERFACE cxx_std_11)
endif()
if (NOT TARGET slsProjectWarnings)
add_library(slsProjectWarnings INTERFACE)
target_compile_options(slsProjectWarnings INTERFACE
-Wall
-Wextra
-Wno-unused-parameter
# -Wold-style-cast
-Wnon-virtual-dtor
-Woverloaded-virtual
-Wdouble-promotion
-Wformat=2
-Wredundant-decls
# -Wconversion
-Wvla
-Wdouble-promotion
-Werror=return-type
)
# Add or disable warnings depending on if the compiler supports them
# The function checks internally and sets HAS_warning-name
sls_enable_cxx_warning("-Wnull-dereference")
sls_enable_cxx_warning("-Wduplicated-cond")
sls_disable_cxx_warning("-Wclass-memaccess")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5 AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(slsProjectWarnings INTERFACE
-Wno-missing-field-initializers)
endif()
endif()
if (NOT TARGET slsProjectCSettings)
#Settings for C code
add_library(slsProjectCSettings INTERFACE)
target_compile_options(slsProjectCSettings INTERFACE
-std=gnu99 #fixed
-Wall
-Wextra
-Wno-unused-parameter
-Wdouble-promotion
-Wformat=2
-Wredundant-decls
-Wdouble-promotion
-Werror=return-type
)
sls_disable_c_warning("-Wstringop-truncation")
endif()
if(SLS_USE_SANITIZER)
@ -170,58 +186,22 @@ if(SLS_TUNE_LOCAL)
endif()
#rapidjson
add_library(rapidjson INTERFACE)
target_include_directories(rapidjson INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libs/rapidjson>
)
# Install fake the libraries
install(TARGETS slsProjectOptions slsProjectWarnings rapidjson
if(SLS_MASTER_PROJECT)
install(TARGETS slsProjectOptions slsProjectWarnings
EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INSTALL_RPATH $ORIGIN)
# set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(ZeroMQ_HINT "" CACHE STRING "Hint where ZeroMQ could be found")
#Adapted from: https://github.com/zeromq/cppzmq/
if (NOT TARGET libzmq)
if(ZeroMQ_HINT)
message(STATUS "Looking for ZeroMQ in: ${ZeroMQ_HINT}")
find_package(ZeroMQ 4
NO_DEFAULT_PATH
HINTS ${ZeroMQ_DIR}
)
else()
find_package(ZeroMQ 4 QUIET)
endif()
# libzmq autotools install: fallback to pkg-config
if(NOT ZeroMQ_FOUND)
message(STATUS "CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)")
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/libzmq-pkg-config)
find_package(ZeroMQ 4 REQUIRED)
endif()
custom_find_zmq()
# TODO "REQUIRED" above should already cause a fatal failure if not found, but this doesn't seem to work
if(NOT ZeroMQ_FOUND)
message(FATAL_ERROR "ZeroMQ was not found, neither as a CMake package nor via pkg-config")
endif()
if (ZeroMQ_FOUND AND NOT TARGET libzmq)
message(FATAL_ERROR "ZeroMQ version not supported!")
endif()
endif()
get_target_property(VAR libzmq INTERFACE_INCLUDE_DIRECTORIES)
message(STATUS "zmq: ${VAR}")
if (SLS_USE_TESTS)
enable_testing()
@ -229,8 +209,9 @@ if (SLS_USE_TESTS)
endif(SLS_USE_TESTS)
# Common functionallity to detector and receiver
add_subdirectory(slsSupportLib)
if(NOT SLS_EXT_BUILD)
add_subdirectory(slsSupportLib)
endif()
if (SLS_USE_DETECTOR OR SLS_USE_TEXTCLIENT)
add_subdirectory(slsDetectorSoftware)
@ -254,7 +235,7 @@ endif (SLS_USE_INTEGRATION_TESTS)
if (SLS_USE_PYTHON)
find_package (Python 3.6 COMPONENTS Interpreter Development)
add_subdirectory(libs/pybind11)
add_subdirectory(libs/pybind11 ${CMAKE_BINARY_DIR}/bin/)
add_subdirectory(python)
endif(SLS_USE_PYTHON)

View File

@ -57,6 +57,18 @@ This document describes the differences between v7.0.0 and v6.x.x
- ctb: can set names for all the dacs
- fpga/kernel programming, checks if drive is a special file and not a normal file
- gotthard 25 um image reconstructed in gui and virtual hdf5 (firmware updated for slave to reverse channels)
- master binary file in json format now
- fixed bug introduced in 6.0.0: hdf5 files created 1 file per frame after the initial file which had maxframesperfile
- m3 polarity, interpolation (enables all counters when enabled), pump probe, analog pulsing, digital pulsing
- updatedetectorserver - removes old server current binary pointing to for blackfin
- removing copydetectorserver using tftp
- registerCallBackRawDataReady and registerCallBackRawDataModifyReady now gives a sls_receiver_header* instead of a char*, and uint32_t to size_t
- registerCallBackStartAcquisition gave incorrect imagesize (+120 bytes). corrected.
- registerCallBackStartAcquisition parameter is a const string reference
- m3 (runnig config second time with tengiga 0, dr !=32, counters !=0x7) calculated incorrect image size expected
- fixed row column indexing (mainly for multi module Jungfrau 2 interfaces )
- eiger gui row indices not flipped anymore (fix in config)
- m3 (settings dac check disabled temporarily?)
2. Resolved Issues
==================

38
cmake/SlsFindZeroMQ.cmake Normal file
View File

@ -0,0 +1,38 @@
function(custom_find_zmq)
set(ZeroMQ_HINT "" CACHE STRING "Hint where ZeroMQ could be found")
#Adapted from: https://github.com/zeromq/cppzmq/
if (NOT TARGET libzmq)
if(ZeroMQ_HINT)
message(STATUS "Looking for ZeroMQ in: ${ZeroMQ_HINT}")
find_package(ZeroMQ 4
NO_DEFAULT_PATH
HINTS ${ZeroMQ_HINT}
)
else()
find_package(ZeroMQ 4 QUIET)
endif()
# libzmq autotools install: fallback to pkg-config
if(ZeroMQ_FOUND)
message(STATUS "Found libzmq using find_package")
else()
message(STATUS "CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)")
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/libzmq-pkg-config)
find_package(ZeroMQ 4 REQUIRED)
endif()
# TODO "REQUIRED" above should already cause a fatal failure if not found, but this doesn't seem to work
if(NOT ZeroMQ_FOUND)
message(FATAL_ERROR "ZeroMQ was not found, neither as a CMake package nor via pkg-config")
endif()
if (ZeroMQ_FOUND AND NOT TARGET libzmq)
message(FATAL_ERROR "ZeroMQ version not supported!")
endif()
endif()
get_target_property(VAR libzmq IMPORTED_LOCATION)
message(STATUS "Using libzmq: ${VAR}")
endfunction()

View File

@ -0,0 +1,36 @@
#From: https://github.com/zeromq/cppzmq/
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
find_package(PkgConfig)
pkg_check_modules(PC_LIBZMQ QUIET libzmq)
set(ZeroMQ_VERSION ${PC_LIBZMQ_VERSION})
find_path(ZeroMQ_INCLUDE_DIR zmq.h
PATHS ${ZeroMQ_DIR}/include
${PC_LIBZMQ_INCLUDE_DIRS}
)
find_library(ZeroMQ_LIBRARY
NAMES zmq
PATHS ${ZeroMQ_DIR}/lib
${PC_LIBZMQ_LIBDIR}
${PC_LIBZMQ_LIBRARY_DIRS}
)
if(ZeroMQ_LIBRARY OR ZeroMQ_STATIC_LIBRARY)
set(ZeroMQ_FOUND ON)
message(STATUS "Found libzmq using PkgConfig")
endif()
set ( ZeroMQ_LIBRARIES ${ZeroMQ_LIBRARY} )
set ( ZeroMQ_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIR} )
if (NOT TARGET libzmq)
add_library(libzmq UNKNOWN IMPORTED)
set_target_properties(libzmq PROPERTIES
IMPORTED_LOCATION ${ZeroMQ_LIBRARIES}
INTERFACE_INCLUDE_DIRECTORIES ${ZeroMQ_INCLUDE_DIRS})
endif()
include ( FindPackageHandleStandardArgs )
find_package_handle_standard_args ( ZeroMQ DEFAULT_MSG ZeroMQ_LIBRARIES ZeroMQ_INCLUDE_DIRS )

View File

@ -26,7 +26,7 @@ install(FILES
)
install(FILES
"${CMAKE_SOURCE_DIR}/libzmq-pkg-config/FindZeroMQ.cmake"
"${CMAKE_SOURCE_DIR}/cmake/libzmq-pkg-config/FindZeroMQ.cmake"
COMPONENT devel
DESTINATION ${CMAKE_INSTALL_DIR}/libzmq-pkg-config
)

View File

@ -19,4 +19,4 @@ cp build/install/bin/slsMultiReceiver $PREFIX/bin/.
cp build/install/include/sls/* $PREFIX/include/sls
cp -r build/install/share/ $PREFIX/share
cp -rv build/install/share $PREFIX

View File

@ -45,6 +45,7 @@ int main() {
for (const auto &cmd : commands) {
std::ostringstream os;
std::cout << cmd << '\n';
proxy.Call(cmd, {}, -1, slsDetectorDefs::HELP_ACTION, os);
auto tmp = os.str().erase(0, cmd.size());

View File

@ -136,7 +136,7 @@ can use dir()
'__str__', '__subclasshook__', '_adc_register', '_frozen',
'_register', 'acquire', 'adcclk', 'adcphase', 'adcpipeline',
'adcreg', 'asamples', 'auto_comp_disable', 'clearAcquiringFlag',
'clearBit', 'clearROI', 'client_version', 'config', 'copyDetectorServer',
'clearBit', 'clearROI', 'client_version', 'config',
'counters', 'daclist', 'dacvalues', 'dbitclk', 'dbitphase' ...
Since the list for Detector is rather long it's an good idea to filter it.

View File

@ -5,17 +5,42 @@ Detector Server Upgrade
**Location:** slsDetectorPackage/serverBin/ folder for every release.
.. note ::
For Mythen3, Gotthard2 and Eiger, you need to add scripts to automatically start detector server upon power on. See :ref:`Automatic start<Automatic start servers>` for more details.
.. note ::
Eiger requires a manual reboot. Or killall the servers and restart the new linked one. If you are in the process of updating firmware, then don't reboot yet.
From 6.1.1 and above (no tftp required)
---------------------------------------
#. Program from console
.. code-block:: bash
# the following command copies new server, creates a soft link to xxxDetectorServerxxx
# [Jungfrau][CTB][Moench] also deletes the old server binary and edits initttab to respawn server on reboot
# Then, the detector controller will reboot (except Eiger)
sls_detector_put updatedetectorserver /complete-path-to-binary/xxxDetectorServerxxx
#. Copy the detector server specific config files or any others required to the detector:
.. code-block:: bash
sls_detector_put execcommand "tftp pcxxx -r configxxx -g"
5.0.0 - 6.1.1
--------------
#. Install tftp and copy detector server binary to tftp folder
#. Program from console
.. note ::
These instructions are for upgrades from v5.0.0. For earlier versions, contact us.
.. code-block:: bash
# copies new server from pc tftp folder, creates a soft link to xxxDetectorServerxxx
# the following command copies new server from pc tftp folder, creates a soft link to xxxDetectorServerxxx
# [Jungfrau][CTB][Moench] also edits initttab to respawn server on reboot
# Then, the detector controller will reboot (except Eiger)
sls_detector_put copydetectorserver xxxDetectorServerxxx pcxxx
@ -27,18 +52,15 @@ Detector Server Upgrade
sls_detector_put execcommand "tftp pcxxx -r configxxx -g"
.. note ::
For Mythen3, Gotthard2 and Eiger, you need to add scripts to automatically start detector server upon power on. See :ref:`Automatic start<Automatic start servers>` for more details.
.. note ::
Eiger requires a manual reboot. Or killall the servers and restart the new linked one. If you are in the process of updating firmware, then don't reboot yet.
Errors
------
Troubleshooting with tftp
^^^^^^^^^^^^^^^^^^^^^^^^^
#. tftp write error: There is no space left. Please delete some old binaries and try again.
#. text file busy: You are trying to copy the same server.
#. text file busy: You are trying to copy the same server.
Older than 5.0.0
-----------------
Please contact us.

View File

@ -1,27 +0,0 @@
#From: https://github.com/zeromq/cppzmq/
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
find_package(PkgConfig)
pkg_check_modules(PC_LIBZMQ QUIET libzmq)
set(ZeroMQ_VERSION ${PC_LIBZMQ_VERSION})
find_library(ZeroMQ_LIBRARY NAMES libzmq.so libzmq.dylib libzmq.dll
PATHS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS})
find_library(ZeroMQ_STATIC_LIBRARY NAMES libzmq-static.a libzmq.a libzmq.dll.a
PATHS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS})
if(ZeroMQ_LIBRARY OR ZeroMQ_STATIC_LIBRARY)
set(ZeroMQ_FOUND ON)
endif()
if (TARGET libzmq)
# avoid errors defining targets twice
return()
endif()
add_library(libzmq SHARED IMPORTED)
set_property(TARGET libzmq PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PC_LIBZMQ_INCLUDE_DIRS})
set_property(TARGET libzmq PROPERTY IMPORTED_LOCATION ${ZeroMQ_LIBRARY})
add_library(libzmq-static STATIC IMPORTED ${PC_LIBZMQ_INCLUDE_DIRS})
set_property(TARGET libzmq-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PC_LIBZMQ_INCLUDE_DIRS})
set_property(TARGET libzmq-static PROPERTY IMPORTED_LOCATION ${ZeroMQ_STATIC_LIBRARY})

View File

@ -3498,10 +3498,60 @@ class Detector(CppDetectorApi):
def readout(self):
"""
Mythen3] Starts detector readout. Status changes to TRANSMITTING and automatically returns to idle at the end of readout.
[Mythen3] Starts detector readout. Status changes to TRANSMITTING and automatically returns to idle at the end of readout.
"""
self.startDetectorReadout()
@property
@element
def polarity(self):
"""[Mythen3] Set positive or negative polarity. Enum: polarity"""
return self.getPolarity()
@polarity.setter
def polarity(self, value):
ut.set_using_dict(self.setPolarity, value)
@property
@element
def interpolation(self):
"""[Mythen3] Enable or disable interpolation. Enabling also enables all counters """
return self.getInterpolation()
@interpolation.setter
def interpolation(self, value):
ut.set_using_dict(self.setInterpolation, value)
@property
@element
def pumpprobe(self):
"""[Mythen3] Enable or disable pump probe mode. """
return self.getPumpProbe()
@pumpprobe.setter
def pumpprobe(self, value):
ut.set_using_dict(self.setPumpProbe, value)
@property
@element
def apulse(self):
"""[Mythen3] Enable or disable analog pulsing. """
return self.getAnalogPulsing()
@apulse.setter
def apulse(self, value):
ut.set_using_dict(self.setAnalogPulsing, value)
@property
@element
def dpulse(self):
"""[Mythen3] Enable or disable digital pulsing. """
return self.getDigitalPulsing()
@dpulse.setter
def dpulse(self, value):
ut.set_using_dict(self.setDigitalPulsing, value)
"""
---------------------------<<<Debug>>>---------------------------

View File

@ -1290,6 +1290,46 @@ void init_det(py::module &m) {
.def("getGainCaps",
(Result<int>(Detector::*)(sls::Positions)) & Detector::getGainCaps,
py::arg() = Positions{})
.def("getPolarity",
(Result<defs::polarity>(Detector::*)(sls::Positions) const) &
Detector::getPolarity,
py::arg() = Positions{})
.def("setPolarity",
(void (Detector::*)(defs::polarity, sls::Positions)) &
Detector::setPolarity,
py::arg(), py::arg() = Positions{})
.def("getInterpolation",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getInterpolation,
py::arg() = Positions{})
.def("setInterpolation",
(void (Detector::*)(bool, sls::Positions)) &
Detector::setInterpolation,
py::arg(), py::arg() = Positions{})
.def("getPumpProbe",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getPumpProbe,
py::arg() = Positions{})
.def("setPumpProbe",
(void (Detector::*)(bool, sls::Positions)) &
Detector::setPumpProbe,
py::arg(), py::arg() = Positions{})
.def("getAnalogPulsing",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getAnalogPulsing,
py::arg() = Positions{})
.def("setAnalogPulsing",
(void (Detector::*)(bool, sls::Positions)) &
Detector::setAnalogPulsing,
py::arg(), py::arg() = Positions{})
.def("getDigitalPulsing",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getDigitalPulsing,
py::arg() = Positions{})
.def("setDigitalPulsing",
(void (Detector::*)(bool, sls::Positions)) &
Detector::setDigitalPulsing,
py::arg(), py::arg() = Positions{})
.def("getNumberOfAnalogSamples",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfAnalogSamples,
@ -1551,11 +1591,6 @@ void init_det(py::module &m) {
.def("resetFPGA",
(void (Detector::*)(sls::Positions)) & Detector::resetFPGA,
py::arg() = Positions{})
.def("copyDetectorServer",
(void (Detector::*)(const std::string &, const std::string &,
sls::Positions)) &
Detector::copyDetectorServer,
py::arg(), py::arg(), py::arg() = Positions{})
.def("updateDetectorServer",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::updateDetectorServer,

View File

@ -315,4 +315,9 @@ void init_enums(py::module &m) {
.value("FIX_G2", slsDetectorDefs::gainMode::FIX_G2)
.value("FIX_G0", slsDetectorDefs::gainMode::FIX_G0)
.export_values();
py::enum_<slsDetectorDefs::polarity>(Defs, "polarity")
.value("POSITIVE", slsDetectorDefs::polarity::POSITIVE)
.value("NEGATIVE", slsDetectorDefs::polarity::NEGATIVE)
.export_values();
}

View File

@ -56,7 +56,8 @@ foreach(exe ${MOENCH_EXECUTABLES})
../dataStructures
../interpolations
../../slsReceiverSoftware/include/
../../slsSupportLib/include/
../../slsSupportLib/include/
${SLS_INTERNAL_RAPIDJSON_DIR}
)
target_link_libraries(${exe}

View File

@ -2060,8 +2060,8 @@ void *start_timer(void *arg) {
header->frameNumber = frameNr + iframes;
header->packetNumber = i;
header->modId = 0;
header->row = detPos[X];
header->column = detPos[Y];
header->row = detPos[Y];
header->column = detPos[X];
// fill data
memcpy(packetData + sizeof(sls_detector_header),

View File

@ -1095,19 +1095,19 @@ int *Beb_GetDetectorPosition() { return Beb_positions; }
int Beb_SetDetectorPosition(int pos[]) {
if (!Beb_activated)
return OK;
LOG(logINFO, ("Got Position values %d %d...\n", pos[0], pos[1]));
LOG(logINFO, ("Setting Position: (%d, %d)\n", pos[X], pos[Y]));
// save positions
Beb_positions[0] = pos[0];
Beb_positions[1] = pos[1];
Beb_positions[Y] = pos[Y];
Beb_positions[X] = pos[X];
// get left and right
int posLeft[2] = {pos[0], Beb_top ? pos[1] : pos[1] + 1};
int posRight[2] = {pos[0], Beb_top ? pos[1] + 1 : pos[1]};
int posLeft[2] = {Beb_top ? pos[X] : pos[X] + 1, pos[Y]};
int posRight[2] = {Beb_top ? pos[X] + 1 : pos[X], pos[Y]};
if (Beb_quadEnable) {
posRight[0] = 1; // right is next row
posRight[1] = 0; // right same first column
posRight[Y] = 1; // right is next row
posRight[X] = 0; // right same first column
}
int ret = FAIL;
@ -1122,7 +1122,7 @@ int Beb_SetDetectorPosition(int pos[]) {
uint32_t value = 0;
ret = OK;
// x left
int posval = Beb_swap_uint16(posLeft[0]);
int posval = Beb_swap_uint16(posLeft[Y]);
value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST);
value &= UDP_HEADER_ID_MSK; // to keep previous id value
Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST,
@ -1134,7 +1134,7 @@ int Beb_SetDetectorPosition(int pos[]) {
ret = FAIL;
}
// x right
posval = Beb_swap_uint16(posRight[0]);
posval = Beb_swap_uint16(posRight[Y]);
value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST);
value &= UDP_HEADER_ID_MSK; // to keep previous id value
Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST,
@ -1147,7 +1147,7 @@ int Beb_SetDetectorPosition(int pos[]) {
}
// y left (column)
posval = Beb_swap_uint16(posLeft[1]);
posval = Beb_swap_uint16(posLeft[X]);
value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST);
value &= UDP_HEADER_Z_MSK; // to keep previous z value
Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST,
@ -1160,7 +1160,7 @@ int Beb_SetDetectorPosition(int pos[]) {
}
// y right
posval = Beb_swap_uint16(posRight[1]);
posval = Beb_swap_uint16(posRight[X]);
value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST);
value &= UDP_HEADER_Z_MSK; // to keep previous z value
Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST,
@ -1176,10 +1176,10 @@ int Beb_SetDetectorPosition(int pos[]) {
Beb_close(fd, csp0base);
}
if (ret == OK) {
LOG(logINFO, ("Position set to...\n"
LOG(logINFO, ("Position set to (col, row):\n"
"\tLeft: [%d, %d]\n"
"\tRight:[%d, %d]\n",
posLeft[0], posLeft[1], posRight[0], posRight[1]));
posLeft[X], posLeft[Y], posRight[X], posRight[Y]));
}
return ret;

View File

@ -19,7 +19,7 @@
#include <pthread.h>
#include <time.h>
#endif
extern int portno;
// Global variable from slsDetectorServer_funcs
extern int debugflag;
extern int updateFlag;
@ -2473,9 +2473,9 @@ void *start_timer(void *arg) {
int maxPacketsPerFrame = (tgEnable ? 4 : 16) * dr;
int npixelsx = 256 * 2 * bytesPerPixel;
int databytes = 256 * 256 * 2 * bytesPerPixel;
int row = eiger_virtual_detPos[0];
int colLeft = top ? eiger_virtual_detPos[1] : eiger_virtual_detPos[1] + 1;
int colRight = top ? eiger_virtual_detPos[1] + 1 : eiger_virtual_detPos[1];
int row = eiger_virtual_detPos[Y];
int colLeft = top ? eiger_virtual_detPos[X] : eiger_virtual_detPos[X] + 1;
int colRight = top ? eiger_virtual_detPos[X] + 1 : eiger_virtual_detPos[X];
int readNRows = getReadNRows();
if (readNRows == -1) {
@ -2548,8 +2548,20 @@ void *start_timer(void *arg) {
}
break;
case 16:
// to debug multi module geometry (row, column) in virtual servers (all pixels
// in a module set to particular value)
#ifdef TEST_MOD_GEOMETRY
if ((i % 1024) < 512) {
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
top ? (portno % 1900) : ((portno % 1900) + 1);
} else {
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
top ? ((portno % 1900) + 1) : (portno % 1900);
}
#else
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
eiger_virtual_test_mode ? 0xFFE : (uint16_t)pixelVal;
#endif
break;
case 32:
*((uint32_t *)(imageData + i * sizeof(uint32_t))) =

View File

@ -1917,7 +1917,7 @@ int setDetectorPosition(int pos[]) {
int ret = OK;
// row
value = detPos[X];
value = detPos[Y];
bus_w(addr, (bus_r(addr) & ~COORD_ROW_MSK) |
((value << COORD_ROW_OFST) & COORD_ROW_MSK));
valueRead = ((bus_r(addr) & COORD_ROW_MSK) >> COORD_ROW_OFST);
@ -1928,7 +1928,7 @@ int setDetectorPosition(int pos[]) {
}
// col
value = detPos[Y];
value = detPos[X];
bus_w(addr, (bus_r(addr) & ~COORD_COL_MSK) |
((value << COORD_COL_OFST) & COORD_COL_MSK));
valueRead = ((bus_r(addr) & COORD_COL_MSK) >> COORD_COL_OFST);
@ -1939,7 +1939,8 @@ int setDetectorPosition(int pos[]) {
}
if (ret == OK) {
LOG(logINFO, ("\tPosition set to [%d, %d]\n", detPos[X], detPos[Y]));
LOG(logINFO,
("\tPosition set to [%d, %d] #(col, row)\n", detPos[X], detPos[Y]));
}
return ret;
@ -3095,8 +3096,8 @@ void *start_timer(void *arg) {
header->frameNumber = virtual_currentFrameNumber;
header->packetNumber = 0;
header->modId = virtual_moduleid;
header->row = detPos[X];
header->column = detPos[Y];
header->row = detPos[Y];
header->column = detPos[X];
// fill data
memcpy(packetData + sizeof(sls_detector_header), imageData,
datasize);

View File

@ -21,7 +21,7 @@
#include <pthread.h>
#include <time.h>
#endif
extern int portno;
// Global variable from slsDetectorServer_funcs
extern int debugflag;
extern int updateFlag;
@ -1621,6 +1621,7 @@ int configureMAC() {
int setDetectorPosition(int pos[]) {
int ret = OK;
// row, col
uint32_t innerPos[2] = {pos[X], pos[Y]};
uint32_t outerPos[2] = {pos[X], pos[Y]};
int selInterface = getPrimaryInterface();
@ -1630,15 +1631,16 @@ int setDetectorPosition(int pos[]) {
("Setting detector position: 1 Interface %s \n(%d, %d)\n",
(selInterface ? "Inner" : "Outer"), innerPos[X], innerPos[Y]));
} else {
++outerPos[X];
// top has row incremented by 1
++innerPos[Y];
LOG(logDEBUG, ("Setting detector position: 2 Interfaces \n"
" inner top(%d, %d), outer bottom(%d, %d)\n",
innerPos[X], innerPos[Y], outerPos[X], outerPos[Y]));
}
detPos[0] = innerPos[0];
detPos[1] = innerPos[1];
detPos[2] = outerPos[0];
detPos[3] = outerPos[1];
detPos[0] = innerPos[X];
detPos[1] = innerPos[Y];
detPos[2] = outerPos[X];
detPos[3] = outerPos[Y];
// row
// outer
@ -1676,8 +1678,8 @@ int setDetectorPosition(int pos[]) {
if (ret == OK) {
if (getNumberofUDPInterfaces() == 1) {
LOG(logINFOBLUE,
("Position set to [%d, %d]\n", innerPos[X], innerPos[Y]));
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",
innerPos[X], innerPos[Y]));
} else {
LOG(logINFOBLUE, (" Inner (top) position set to [%d, %d]\n",
innerPos[X], innerPos[Y]));
@ -2531,8 +2533,16 @@ void *start_timer(void *arg) {
if (i > 0 && i % pixelsPerPacket == 0) {
++pixelVal;
}
// to debug multi module geometry (row, column) in virtual servers (all pixels
// in a module set to particular value)
#ifdef TEST_MOD_GEOMETRY
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
portno % 1900 + (i >= npixels / 2 ? 1 : 0);
#else
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
virtual_image_test_mode ? 0x0FFE : (uint16_t)pixelVal;
#endif
}
}
@ -2557,6 +2567,10 @@ void *start_timer(void *arg) {
int srcOffset = 0;
int srcOffset2 = DATA_BYTES / 2;
int row0 = (numInterfaces == 1 ? detPos[1] : detPos[3]);
int col0 = (numInterfaces == 1 ? detPos[0] : detPos[2]);
int row1 = detPos[1];
int col1 = detPos[0];
// loop packet (128 packets)
for (int i = 0; i != maxPacketsPerFrame; ++i) {
@ -2576,8 +2590,8 @@ void *start_timer(void *arg) {
header->frameNumber = frameNr + iframes;
header->packetNumber = pnum;
header->modId = 0;
header->row = detPos[0];
header->column = detPos[1];
header->row = row0;
header->column = col0;
// fill data
memcpy(packetData + sizeof(sls_detector_header),
@ -2603,8 +2617,8 @@ void *start_timer(void *arg) {
header->frameNumber = frameNr + iframes;
header->packetNumber = pnum;
header->modId = 0;
header->row = detPos[2];
header->column = detPos[3];
header->row = row1;
header->column = col1;
// fill data
memcpy(packetData2 + sizeof(sls_detector_header),

View File

@ -1731,8 +1731,8 @@ void *start_timer(void *arg) {
header->frameNumber = frameNr + iframes;
header->packetNumber = i;
header->modId = 0;
header->row = detPos[X];
header->column = detPos[Y];
header->row = detPos[Y];
header->column = detPos[X];
// fill data
memcpy(packetData + sizeof(sls_detector_header),

View File

@ -10,20 +10,6 @@
#include <string.h>
/*
// Common C/C++ structure to handle pattern data
typedef struct __attribute__((packed)) {
uint64_t word[MAX_PATTERN_LENGTH];
uint64_t ioctrl;
uint32_t limits[2];
// loop0 start, loop0 stop .. loop2 start, loop2 stop
uint32_t loop[6];
uint32_t nloop[3];
uint32_t wait[3];
uint64_t waittime[3];
} patternParameters;
*/
int chipStatusRegister = 0;
int setBit(int ibit, int patword) { return patword |= (1 << ibit); }
@ -32,44 +18,6 @@ int clearBit(int ibit, int patword) { return patword &= ~(1 << ibit); }
int getChipStatusRegister() { return chipStatusRegister; }
int gainCapsToCsr(int caps) {
// Translates bit representation
int csr = 0;
if (!(caps & M3_C10pre))
csr |= 1 << _CSR_C10pre;
if (caps & M3_C15sh)
csr |= 1 << CSR_C15sh;
if (caps & M3_C30sh)
csr |= 1 << CSR_C30sh;
if (caps & M3_C50sh)
csr |= 1 << CSR_C50sh;
if (caps & M3_C225ACsh)
csr |= 1 << CSR_C225ACsh;
if (!(caps & M3_C15pre))
csr |= 1 << _CSR_C15pre;
return csr;
}
int csrToGainCaps(int csr) {
// Translates bit representation
int caps = 0;
if (!(csr & (1 << _CSR_C10pre)))
caps |= M3_C10pre;
if (csr & (1 << CSR_C15sh))
caps |= M3_C15sh;
if (csr & (1 << CSR_C30sh))
caps |= M3_C30sh;
if (csr & (1 << CSR_C50sh))
caps |= M3_C50sh;
if (csr & (1 << CSR_C225ACsh))
caps |= M3_C225ACsh;
if (!(csr & (1 << _CSR_C15pre)))
caps |= M3_C15pre;
return caps;
}
patternParameters *setChipStatusRegisterPattern(int csr) {
int iaddr = 0;
int nbits = 18;
@ -149,54 +97,116 @@ patternParameters *setChipStatusRegisterPattern(int csr) {
return pat;
}
patternParameters *setInterpolation(int mask) {
int csr;
if (mask)
csr = chipStatusRegister | (1 << CSR_interp);
else
csr = chipStatusRegister & ~(1 << CSR_interp);
int getGainCaps() {
int csr = chipStatusRegister;
// Translates bit representation
int caps = 0;
if (!(csr & (1 << _CSR_C10pre)))
caps |= M3_C10pre;
if (csr & (1 << CSR_C15sh))
caps |= M3_C15sh;
if (csr & (1 << CSR_C30sh))
caps |= M3_C30sh;
if (csr & (1 << CSR_C50sh))
caps |= M3_C50sh;
if (csr & (1 << CSR_C225ACsh))
caps |= M3_C225ACsh;
if (!(csr & (1 << _CSR_C15pre)))
caps |= M3_C15pre;
return setChipStatusRegisterPattern(csr);
return caps;
}
patternParameters *setPumpProbe(int mask) {
int csr;
if (mask)
csr = chipStatusRegister | (1 << CSR_pumprobe);
else
csr = chipStatusRegister & ~(1 << CSR_pumprobe);
int M3SetGainCaps(int caps) {
int csr = chipStatusRegister & ~GAIN_MASK;
return setChipStatusRegisterPattern(csr);
// Translates bit representation
if (!(caps & M3_C10pre))
csr |= 1 << _CSR_C10pre;
if (caps & M3_C15sh)
csr |= 1 << CSR_C15sh;
if (caps & M3_C30sh)
csr |= 1 << CSR_C30sh;
if (caps & M3_C50sh)
csr |= 1 << CSR_C50sh;
if (caps & M3_C225ACsh)
csr |= 1 << CSR_C225ACsh;
if (!(caps & M3_C15pre))
csr |= 1 << _CSR_C15pre;
return csr;
}
patternParameters *setDigitalPulsing(int mask) {
int csr;
if (mask)
csr = chipStatusRegister | (1 << CSR_dpulse);
else
csr = chipStatusRegister & ~(1 << CSR_dpulse);
return setChipStatusRegisterPattern(csr);
int getInterpolation() {
return ((chipStatusRegister & CSR_interp_MSK) >> CSR_interp);
}
patternParameters *setAnalogPulsing(int mask) {
int csr;
if (mask)
csr = chipStatusRegister | (1 << CSR_apulse);
int M3SetInterpolation(int enable) {
int csr = 0;
if (enable)
csr = chipStatusRegister | CSR_interp_MSK;
else
csr = chipStatusRegister & ~(1 << CSR_apulse);
return setChipStatusRegisterPattern(csr);
csr = chipStatusRegister & ~CSR_interp_MSK;
return csr;
}
patternParameters *setNegativePolarity(int mask) {
int csr;
if (mask)
csr = chipStatusRegister | (1 << CSR_invpol);
int getPumpProbe() {
return ((chipStatusRegister & CSR_pumprobe_MSK) >> CSR_pumprobe);
}
int M3SetPumpProbe(int enable) {
LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = 0;
if (enable)
csr = chipStatusRegister | CSR_pumprobe_MSK;
else
csr = chipStatusRegister & ~(1 << CSR_invpol);
csr = chipStatusRegister & ~CSR_pumprobe_MSK;
return csr;
}
return setChipStatusRegisterPattern(csr);
int getDigitalPulsing() {
return ((chipStatusRegister & CSR_dpulse_MSK) >> CSR_dpulse);
}
int M3SetDigitalPulsing(int enable) {
LOG(logINFO,
("%s Digital Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = 0;
if (enable)
csr = chipStatusRegister | CSR_dpulse_MSK;
else
csr = chipStatusRegister & ~CSR_dpulse_MSK;
return csr;
}
int getAnalogPulsing() {
return ((chipStatusRegister & CSR_apulse_MSK) >> CSR_apulse);
}
int M3SetAnalogPulsing(int enable) {
LOG(logINFO,
("%s Analog Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = 0;
if (enable)
csr = chipStatusRegister | CSR_apulse_MSK;
else
csr = chipStatusRegister & ~CSR_apulse_MSK;
return csr;
}
int getNegativePolarity() {
return ((chipStatusRegister & CSR_invpol_MSK) >> CSR_invpol);
}
int M3SetNegativePolarity(int enable) {
LOG(logINFO,
("%s Negative Polarity\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = 0;
if (enable)
csr = chipStatusRegister | CSR_invpol_MSK;
else
csr = chipStatusRegister & ~CSR_invpol_MSK;
return csr;
}
patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits) {

View File

@ -49,6 +49,12 @@
// shaper)
#define _CSR_C15pre 14 // negative polarity
#define CSR_invpol_MSK (0x1 << CSR_invpol)
#define CSR_dpulse_MSK (0x1 << CSR_dpulse)
#define CSR_interp_MSK (0x1 << CSR_interp)
#define CSR_pumprobe_MSK (0x1 << CSR_pumprobe)
#define CSR_apulse_MSK (0x1 << CSR_apulse)
#define CSR_default (1 << _CSR_C10pre) | (1 << CSR_C30sh)
#define GAIN_MASK \
@ -58,15 +64,20 @@
int setBit(int ibit, int patword);
int clearBit(int ibit, int patword);
int getChipStatusRegister();
int gainCapsToCsr(int caps);
int csrToGainCaps(int csr);
patternParameters *setChipStatusRegisterPattern(int csr);
patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits);
patternParameters *setInterpolation(int mask);
patternParameters *setPumpProbe(int mask);
patternParameters *setDigitalPulsing(int mask);
patternParameters *setAnalogPulsing(int mask);
patternParameters *setNegativePolarity(int mask);
int getGainCaps();
int M3SetGainCaps(int caps);
int getInterpolation();
int M3SetInterpolation(int enable);
int getPumpProbe();
int M3SetPumpProbe(int enable);
int getDigitalPulsing();
int M3SetDigitalPulsing(int enable);
int getAnalogPulsing();
int M3SetAnalogPulsing(int enable);
int getNegativePolarity();
int M3SetNegativePolarity(int enable);
#endif

View File

@ -1411,6 +1411,9 @@ enum detectorSettings setSettings(enum detectorSettings sett) {
}
void validateSettings() {
LOG(logWARNING, ("Not validating dac settings temporarily"));
return;
// if any special dac value is changed individually => undefined
const int specialDacs[NSPECIALDACS] = SPECIALDACINDEX;
int *specialDacValues[] = {defaultDacValue_standard, defaultDacValue_fast,
@ -1603,7 +1606,7 @@ void setTiming(enum timingMode arg) {
int master = 0;
isMaster(&master);
if (master && arg == AUTO_TIMING)
if (!master && arg == AUTO_TIMING)
arg = TRIGGER_EXPOSURE;
uint32_t addr = CONFIG_REG;
@ -1689,6 +1692,55 @@ void setInitialExtSignals() {
DOUTIF_RISING_LNGTH_PORT_1_MSK));
}
int setGainCaps(int caps) {
LOG(logINFO, ("Setting gain caps to: %u\n", caps));
int csr = M3SetGainCaps(caps);
return setChipStatusRegister(csr);
}
int setInterpolation(int enable) {
LOG(logINFO,
("%s Interpolation\n", enable == 0 ? "Disabling" : "Enabling"));
if (enable) {
setCounterMask(MAX_COUNTER_MSK);
if (getCounterMask() != MAX_COUNTER_MSK) {
LOG(logERROR,
("Could not set interpolation. Could not enable all counters"));
return FAIL;
}
LOG(logINFO, ("\tEnabled all counters\n"));
}
int csr = M3SetInterpolation(enable);
return setChipStatusRegister(csr);
}
int setPumpProbe(int enable) {
LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = M3SetPumpProbe(enable);
return setChipStatusRegister(csr);
}
int setDigitalPulsing(int enable) {
LOG(logINFO,
("%s Digital Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = M3SetDigitalPulsing(enable);
return setChipStatusRegister(csr);
}
int setAnalogPulsing(int enable) {
LOG(logINFO,
("%s Analog Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = M3SetAnalogPulsing(enable);
return setChipStatusRegister(csr);
}
int setNegativePolarity(int enable) {
LOG(logINFO,
("%s Negative Polarity\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = M3SetNegativePolarity(enable);
return setChipStatusRegister(csr);
}
void setExtSignal(int signalIndex, enum externalSignalFlag mode) {
LOG(logDEBUG1, ("Setting signal flag[%d] to %d\n", signalIndex, mode));
@ -1892,7 +1944,7 @@ int setDetectorPosition(int pos[]) {
int ret = OK;
// row
value = detPos[X];
value = detPos[Y];
bus_w(addr, (bus_r(addr) & ~COORD_ROW_MSK) |
((value << COORD_ROW_OFST) & COORD_ROW_MSK));
valueRead = ((bus_r(addr) & COORD_ROW_MSK) >> COORD_ROW_OFST);
@ -1903,7 +1955,7 @@ int setDetectorPosition(int pos[]) {
}
// col
value = detPos[Y];
value = detPos[X];
bus_w(addr, (bus_r(addr) & ~COORD_COL_MSK) |
((value << COORD_COL_OFST) & COORD_COL_MSK));
valueRead = ((bus_r(addr) & COORD_COL_MSK) >> COORD_COL_OFST);
@ -1914,7 +1966,8 @@ int setDetectorPosition(int pos[]) {
}
if (ret == OK) {
LOG(logINFO, ("\tPosition set to [%d, %d]\n", detPos[X], detPos[Y]));
LOG(logINFO,
("\tPosition set to [%d, %d] #(col, row)\n", detPos[X], detPos[Y]));
}
return ret;
@ -2336,8 +2389,8 @@ void *start_timer(void *arg) {
header->frameNumber = virtual_currentFrameNumber;
header->packetNumber = i;
header->modId = virtual_moduleid;
header->row = detPos[X];
header->column = detPos[Y];
header->row = detPos[Y];
header->column = detPos[X];
// fill data
memcpy(packetData + sizeof(sls_detector_header),
@ -2623,21 +2676,3 @@ int setChipStatusRegister(int csr) {
return iret;
}
int setGainCaps(int caps) {
LOG(logINFO, ("Setting gain caps to: %u\n", caps));
// Update only gain caps, leave the rest of the CSR unchanged
int csr = getChipStatusRegister();
csr &= ~GAIN_MASK;
caps = gainCapsToCsr(caps);
// caps &= GAIN_MASK;
csr |= caps;
return setChipStatusRegister(csr);
}
int getGainCaps() {
int csr = getChipStatusRegister();
int caps = csrToGainCaps(csr);
return caps;
}

View File

@ -66,3 +66,5 @@ int moveBinaryFile(char *mess, char *dest, char *src, char *errorPrefix);
int createEmptyFile(char *mess, char *fname, char *errorPrefix);
int deleteFile(char *mess, char *fname, char *errorPrefix);
int deleteOldServers(char *mess, char *newServerPath, char *errorPrefix);

View File

@ -376,7 +376,7 @@ int setHighVoltage(int val);
// parameters - timing, extsig
#ifdef EIGERD
int setMaster(enum MASTERINDEX m);
int setTop(enum TOPINDEX t);
int setTop(enum TOPINDEX t);
int isTop(int *retval);
#endif
#if defined(MYTHEN3D) || defined(EIGERD) || defined(GOTTHARDD) || \
@ -391,9 +391,13 @@ void setTiming(enum timingMode arg);
enum timingMode getTiming();
#ifdef MYTHEN3D
void setInitialExtSignals();
int setGainCaps(int caps);
int getGainCaps();
int setChipStatusRegister(int csr);
int setGainCaps(int caps);
int setInterpolation(int enable);
int setPumpProbe(int enable);
int setDigitalPulsing(int enable);
int setAnalogPulsing(int enable);
int setNegativePolarity(int enable);
int setDACS(int *dacs);
#endif
#if defined(GOTTHARDD) || defined(MYTHEN3D)

View File

@ -132,7 +132,6 @@ int check_version(int);
int software_trigger(int);
int led(int);
int digital_io_delay(int);
int copy_detector_server(int);
int reboot_controller(int);
int set_adc_enable_mask(int);
int get_adc_enable_mask(int);
@ -293,4 +292,14 @@ void receive_program_default(int file_des, enum PROGRAM_INDEX index,
int get_update_mode(int);
int set_update_mode(int);
int get_top(int);
int set_top(int);
int set_top(int);
int get_polarity(int);
int set_polarity(int);
int get_interpolation(int);
int set_interpolation(int);
int get_pump_probe(int);
int set_pump_probe(int);
int get_analog_pulsing(int);
int set_analog_pulsing(int);
int get_digital_pulsing(int);
int set_digital_pulsing(int);

View File

@ -50,6 +50,10 @@ int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
}
int getAbsPath(char *buf, size_t bufSize, char *fname) {
if (fname[0] == '/') {
strcpy(buf, fname);
return OK;
}
// get path of current binary
char path[bufSize];
memset(path, 0, bufSize);
@ -60,10 +64,14 @@ int getAbsPath(char *buf, size_t bufSize, char *fname) {
}
path[len] = '\0';
// get dir path and attach config file name
// get dir path and attach file name
char *dir = dirname(path);
memset(buf, 0, bufSize);
sprintf(buf, "%s/%s", dir, fname);
if (!strcmp(dir, "/")) {
sprintf(buf, "/%s", fname);
} else {
sprintf(buf, "%s/%s", dir, fname);
}
LOG(logDEBUG1, ("full path for %s: %s\n", fname, buf));
return OK;
}
@ -466,7 +474,7 @@ int setupDetectorServer(char *mess, char *sname) {
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tSymbolic link created\n"));
LOG(logINFO, ("\tSymbolic link created %s -> %s\n", linkname, sname));
// blackfin boards (respawn) (only kept for backwards compatibility)
#ifndef VIRTUAL
@ -485,7 +493,7 @@ int setupDetectorServer(char *mess, char *sname) {
// add new link name to /etc/inittab
if (snprintf(cmd, MAX_STR_LENGTH,
"echo 'ttyS0::respawn:/./%s' >> /etc/inittab",
"echo 'ttyS0::respawn:%s' >> /etc/inittab",
linkname) >= MAX_STR_LENGTH) {
strcpy(mess, "Could not copy detector server. Command "
"to add new server for spawning is too long\n");
@ -670,3 +678,26 @@ int deleteFile(char *mess, char *fname, char *errorPrefix) {
}
return OK;
}
int deleteOldServers(char *mess, char *newServerPath, char *errorPrefix) {
LOG(logINFO, ("\tChecking if current binary is to be deleted ...\n"))
// get path of current binary (get file name if link)
char currentBinary[MAX_STR_LENGTH];
memset(currentBinary, 0, MAX_STR_LENGTH);
ssize_t len = readlink("/proc/self/exe", currentBinary, MAX_STR_LENGTH - 1);
if (len < 0) {
LOG(logWARNING, ("(%s): Could not delete old servers. Could not "
"readlink current binary\n",
errorPrefix));
return FAIL;
}
currentBinary[len] = '\0';
LOG(logDEBUG1, ("Current binary:%s\n", currentBinary));
// delete file
if (deleteFile(mess, currentBinary, errorPrefix) == FAIL) {
LOG(logWARNING, ("(%s). Could not delete old servers\n", errorPrefix));
return FAIL;
}
return OK;
}

View File

@ -39,6 +39,7 @@ extern int masterCommandLine;
#ifdef EIGERD
extern int topCommandLine;
#endif
int portno = DEFAULT_PORTNO;
void error(char *msg) { perror(msg); }
@ -50,7 +51,6 @@ void sigInterruptHandler(int p) {
int main(int argc, char *argv[]) {
// options
int portno = DEFAULT_PORTNO;
isControlServer = 1;
debugflag = 0;
updateFlag = 0;

View File

@ -62,8 +62,8 @@ int firstUDPDestination = 0;
int configured = FAIL;
char configureMessage[MAX_STR_LENGTH] = "udp parameters not configured yet";
int maxydet = -1;
int detectorId = -1;
int maxYMods = -1;
int moduleIndex = -1;
// Local variables
int (*flist[NUM_DET_FUNCTIONS])(int);
@ -81,28 +81,14 @@ char scanErrMessage[MAX_STR_LENGTH] = "";
/* initialization functions */
int updateModeAllowedFunction(int file_des) {
enum detFuncs allowedFuncs[] = {F_EXEC_COMMAND,
F_GET_DETECTOR_TYPE,
F_GET_FIRMWARE_VERSION,
F_GET_SERVER_VERSION,
F_GET_SERIAL_NUMBER,
F_WRITE_REGISTER,
F_READ_REGISTER,
F_LOCK_SERVER,
F_GET_LAST_CLIENT_IP,
F_PROGRAM_FPGA,
F_RESET_FPGA,
F_CHECK_VERSION,
F_COPY_DET_SERVER,
F_REBOOT_CONTROLLER,
F_GET_KERNEL_VERSION,
F_UPDATE_KERNEL,
F_UPDATE_DETECTOR_SERVER,
F_GET_UPDATE_MODE,
F_SET_UPDATE_MODE,
F_GET_NUM_CHANNELS,
F_GET_NUM_INTERFACES,
F_ACTIVATE};
enum detFuncs allowedFuncs[] = {
F_EXEC_COMMAND, F_GET_DETECTOR_TYPE, F_GET_FIRMWARE_VERSION,
F_GET_SERVER_VERSION, F_GET_SERIAL_NUMBER, F_WRITE_REGISTER,
F_READ_REGISTER, F_LOCK_SERVER, F_GET_LAST_CLIENT_IP,
F_PROGRAM_FPGA, F_RESET_FPGA, F_CHECK_VERSION,
F_REBOOT_CONTROLLER, F_GET_KERNEL_VERSION, F_UPDATE_KERNEL,
F_UPDATE_DETECTOR_SERVER, F_GET_UPDATE_MODE, F_SET_UPDATE_MODE,
F_GET_NUM_CHANNELS, F_GET_NUM_INTERFACES, F_ACTIVATE};
size_t allowedFuncsSize = sizeof(allowedFuncs) / sizeof(enum detFuncs);
for (unsigned int i = 0; i < allowedFuncsSize; ++i) {
@ -130,6 +116,7 @@ void init_detector() {
#ifdef VIRTUAL
LOG(logINFO, ("This is a VIRTUAL detector\n"));
udpDetails[0].srcip = LOCALHOSTIP_INT;
udpDetails[0].srcip2 = LOCALHOSTIP_INT;
#endif
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
@ -322,7 +309,6 @@ void function_table() {
flist[F_SOFTWARE_TRIGGER] = &software_trigger;
flist[F_LED] = &led;
flist[F_DIGITAL_IO_DELAY] = &digital_io_delay;
flist[F_COPY_DET_SERVER] = &copy_detector_server;
flist[F_REBOOT_CONTROLLER] = &reboot_controller;
flist[F_SET_ADC_ENABLE_MASK] = &set_adc_enable_mask;
flist[F_GET_ADC_ENABLE_MASK] = &get_adc_enable_mask;
@ -472,6 +458,16 @@ void function_table() {
flist[F_SET_MASTER] = &set_master;
flist[F_GET_TOP] = &get_top;
flist[F_SET_TOP] = &set_top;
flist[F_GET_POLARITY] = &get_polarity;
flist[F_SET_POLARITY] = &set_polarity;
flist[F_GET_INTERPOLATION] = &get_interpolation;
flist[F_SET_INTERPOLATION] = &set_interpolation;
flist[F_GET_PUMP_PROBE] = &get_pump_probe;
flist[F_SET_PUMP_PROBE] = &set_pump_probe;
flist[F_GET_ANALOG_PULSING] = &get_analog_pulsing;
flist[F_SET_ANALOG_PULSING] = &set_analog_pulsing;
flist[F_GET_DIGITAL_PULSING] = &get_digital_pulsing;
flist[F_SET_DIGITAL_PULSING] = &set_digital_pulsing;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -4143,65 +4139,15 @@ int digital_io_delay(int file_des) {
return Server_SendResult(file_des, INT32, NULL, 0);
}
int copy_detector_server(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
char args[2][MAX_STR_LENGTH];
char retvals[MAX_STR_LENGTH] = {0};
memset(args, 0, sizeof(args));
memset(retvals, 0, sizeof(retvals));
if (receiveData(file_des, args, sizeof(args), OTHER) < 0)
return printSocketReadError();
#ifdef VIRTUAL
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
char *sname = args[0];
char *hostname = args[1];
LOG(logINFOBLUE, ("Copying server %s from host %s\n", sname, hostname));
char cmd[MAX_STR_LENGTH] = {0};
#ifdef BLACKFIN_DEFINED
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, "copy detector server");
#endif
// tftp server
if (ret == OK) {
if (snprintf(cmd, MAX_STR_LENGTH, "tftp %s -r %s -g", hostname,
sname) >= MAX_STR_LENGTH) {
ret = FAIL;
strcpy(mess, "Could not copy detector server. Command to copy "
"server too long\n");
LOG(logERROR, (mess));
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
ret = FAIL;
snprintf(mess, MAX_STR_LENGTH,
"Could not copy detector server (tftp). %s\n",
retvals);
// LOG(logERROR, (mess)); already printed in executecommand
} else {
LOG(logINFO, ("\tServer copied\n"));
}
}
if (ret == OK) {
ret = setupDetectorServer(mess, sname);
}
}
#endif
return Server_SendResult(file_des, OTHER, retvals, sizeof(retvals));
}
int reboot_controller(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
#ifdef EIGERD
functionNotImplemented();
#elif VIRTUAL
ret = GOODBYE;
#elif defined(MYTHEN3D) || defined(GOTTHARD2D)
if (getHardwareVersionNumber() == 0) {
ret = FAIL;
strcpy(mess, "Old board version, reboot by yourself please!\n");
@ -4209,20 +4155,11 @@ int reboot_controller(int file_des) {
Server_SendResult(file_des, INT32, NULL, 0);
return GOODBYE;
}
#ifdef VIRTUAL
ret = GOODBYE;
ret = REBOOT;
#else
ret = REBOOT;
#endif
#elif EIGERD
functionNotImplemented();
#else
#ifdef VIRTUAL
ret = GOODBYE;
#else
ret = REBOOT;
#endif
#endif
Server_SendResult(file_des, INT32, NULL, 0);
return ret;
}
@ -4751,7 +4688,7 @@ int get_read_n_rows(int file_des) {
}
void calculate_and_set_position() {
if (maxydet == -1 || detectorId == -1) {
if (maxYMods == -1 || moduleIndex == -1) {
ret = FAIL;
sprintf(mess,
"Could not set detector position (did not get multi size).\n");
@ -4760,21 +4697,20 @@ void calculate_and_set_position() {
}
// calculating new position
int modulePorts[2] = {1, 1};
int pos[2] = {0, 0};
int portGeometry[2] = {1, 1};
// position does change for eiger and jungfrau (2 interfaces)
#if defined(EIGERD)
modulePorts[1] = getNumberofUDPInterfaces(); // horz
portGeometry[X] = getNumberofUDPInterfaces(); // horz
#elif defined(JUNGFRAUD)
modulePorts[0] = getNumberofUDPInterfaces(); // vert
portGeometry[Y] = getNumberofUDPInterfaces(); // vert
#endif
int maxy = maxydet * modulePorts[0];
int pos[2] = {0, 0};
// row
pos[0] = (detectorId % maxy);
// col for horiz. udp ports
pos[1] = (detectorId / maxy) * modulePorts[1];
LOG(logDEBUG, ("Setting Positions (%d,%d)\n", pos[0], pos[1]));
LOG(logDEBUG1, ("moduleIndex:%d maxymods:%d portGeo.x:%d portgeo.y:%d\n",
moduleIndex, maxYMods, portGeometry[X], portGeometry[Y]));
pos[Y] = (moduleIndex % maxYMods) * portGeometry[Y];
pos[X] = (moduleIndex / maxYMods) * portGeometry[X];
LOG(logINFO, ("Setting Positions (%d,%d) #(col, row)\n", pos[X], pos[Y]));
if (setDetectorPosition(pos) == FAIL) {
ret = FAIL;
sprintf(mess, "Could not set detector position.\n");
@ -4786,8 +4722,8 @@ void calculate_and_set_position() {
if (udpDetails[0].srcmac == 0) {
char dmac[MAC_ADDRESS_SIZE];
memset(dmac, 0, MAC_ADDRESS_SIZE);
sprintf(dmac, "aa:bb:cc:dd:%02x:%02x", pos[0] & 0xFF,
pos[1] & 0xFF);
sprintf(dmac, "aa:bb:cc:dd:%02x:%02x", pos[X] & 0xFF,
pos[Y] & 0xFF);
LOG(logINFO, ("Udp source mac address created: %s\n", dmac));
unsigned char a[6];
sscanf(dmac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &a[0], &a[1], &a[2],
@ -4806,8 +4742,8 @@ void calculate_and_set_position() {
if (udpDetails[0].srcmac2 == 0) {
char dmac2[MAC_ADDRESS_SIZE];
memset(dmac2, 0, MAC_ADDRESS_SIZE);
sprintf(dmac2, "aa:bb:cc:dd:%02x:%02x", (pos[0] + 1) & 0xFF,
pos[1] & 0xFF);
sprintf(dmac2, "aa:bb:cc:dd:%02x:%02x", (pos[X] + 1) & 0xFF,
pos[Y] & 0xFF);
LOG(logINFO, ("Udp source mac address2 created: %s\n", dmac2));
unsigned char a[6];
sscanf(dmac2, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &a[0], &a[1],
@ -4835,15 +4771,16 @@ int set_detector_position(int file_des) {
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting detector positions: [%u, %u]\n", args[0], args[1]));
LOG(logDEBUG, ("Setting detector positions: [maxy:%u, modIndex:%u]\n",
args[0], args[1]));
// only set
if (Server_VerifyLock() == OK) {
// if in update mode, there is no need to do this (also detector not set
// up)
if (!updateFlag && check_detector_idle("configure mac") == OK) {
maxydet = args[0];
detectorId = args[1];
maxYMods = args[0];
moduleIndex = args[1];
calculate_and_set_position();
}
}
@ -8297,33 +8234,35 @@ int set_gain_caps(int file_des) {
return printSocketReadError();
LOG(logDEBUG1, ("Setting gain caps to: %u\n", arg));
int retval = -1;
#ifndef MYTHEN3D
functionNotImplemented();
#else
if (Server_VerifyLock() == OK) {
setGainCaps(arg);
retval = getChipStatusRegister(); // TODO! fix
LOG(logDEBUG1, ("gain caps retval: %u\n", retval));
ret = setGainCaps(arg);
if (ret == FAIL) {
strcpy(mess, "Could not set gain caps.\n");
LOG(logERROR, (mess));
} else {
int retval = getGainCaps();
validate(&ret, mess, (int)arg, (int)retval, "set gain caps", DEC);
LOG(logDEBUG1, ("gain caps retval: %u\n", retval));
}
}
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_gain_caps(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logINFO, ("Getting gain caps\n"));
LOG(logDEBUG1, ("Getting gain caps\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
if (Server_VerifyLock() == OK) {
retval = getGainCaps();
LOG(logDEBUG1, ("Gain caps: %u\n", retval));
}
retval = getGainCaps();
LOG(logDEBUG1, ("Gain caps: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
@ -9449,10 +9388,18 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) {
if (receiveData(file_des, &forceDeleteNormalFile,
sizeof(forceDeleteNormalFile), INT32) < 0)
return printSocketReadError();
LOG(logINFO,
("\tForce Delete Normal File flag? %s\n", (forceDeleteNormalFile ? "Y" : "N")));
LOG(logINFO, ("\tForce Delete Normal File flag? %s\n",
(forceDeleteNormalFile ? "Y" : "N")));
#endif
// ensure the name is not the same as the linked name
if (!strcmp(serverName, LINKED_SERVER_NAME)) {
ret = FAIL;
strcpy(mess, "Server name is the same as the symbolic link. Please "
"use a different server name\n");
LOG(logERROR, (mess));
}
// in same folder as current process (will also work for virtual then
// with write permissions)
{
@ -9477,7 +9424,8 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) {
checksum, serverName);
#else
receive_program_via_blackfin(file_des, index, functionType,
filesize, checksum, serverName, forceDeleteNormalFile);
filesize, checksum, serverName,
forceDeleteNormalFile);
#endif
}
@ -9493,7 +9441,8 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) {
void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
char *functionType, uint64_t filesize,
char *checksum, char *serverName, int forceDeleteNormalFile) {
char *checksum, char *serverName,
int forceDeleteNormalFile) {
#if !defined(JUNGFRAUD) && !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && \
!defined(GOTTHARDD)
@ -9595,6 +9544,8 @@ void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
totalsize, forceDeleteNormalFile);
break;
case PROGRAM_SERVER:
// a fail here is not a show stopper (just for memory)
deleteOldServers(mess, serverName, "update detector server");
ret = moveBinaryFile(mess, serverName, TEMP_PROG_FILE_NAME,
"update detector server");
if (ret == OK) {
@ -9821,4 +9772,246 @@ int set_top(int file_des) {
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_polarity(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
enum polarity retval = POSITIVE;
LOG(logDEBUG1, ("Getting negativepolarity\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// get only
retval = getNegativePolarity() ? NEGATIVE : POSITIVE;
LOG(logDEBUG1, ("negative polarity retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_polarity(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
enum polarity arg = POSITIVE;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Setting negative polarity: %u\n", (int)arg));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
switch (arg) {
case POSITIVE:
ret = setNegativePolarity(0);
break;
case NEGATIVE:
ret = setNegativePolarity(1);
break;
default:
modeNotImplemented("Polarity index", (int)arg);
break;
}
if (ret == FAIL) {
sprintf(mess, "Could not set polarity\n");
LOG(logERROR, (mess));
} else {
enum polarity retval = getNegativePolarity() ? NEGATIVE : POSITIVE;
validate(&ret, mess, (int)arg, (int)retval, "set polarity", DEC);
LOG(logDEBUG1, ("negative polarity retval: %u\n", retval));
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_interpolation(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logDEBUG1, ("Getting interpolation\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// get only
retval = getInterpolation();
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_interpolation(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting interpolation: %u\n", arg));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setInterpolation(arg);
if (ret == FAIL) {
if (arg)
sprintf(mess, "Could not set interpolation or enable all "
"counters for it.\n");
else
sprintf(mess, "Could not set interpolation\n");
LOG(logERROR, (mess));
} else {
int retval = getInterpolation();
validate(&ret, mess, (int)arg, (int)retval, "set interpolation",
DEC);
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_pump_probe(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logDEBUG1, ("Getting pump probe\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// get only
retval = getPumpProbe();
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_pump_probe(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting pump probe: %u\n", arg));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setPumpProbe(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set pump probe\n");
LOG(logERROR, (mess));
} else {
int retval = getPumpProbe();
validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC);
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_analog_pulsing(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logDEBUG1, ("Getting analog pulsing\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// get only
retval = getAnalogPulsing();
LOG(logDEBUG1, ("analog pulsing retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_analog_pulsing(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting analog pulsing: %u\n", arg));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setAnalogPulsing(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set analog pulsing\n");
LOG(logERROR, (mess));
} else {
int retval = getAnalogPulsing();
validate(&ret, mess, (int)arg, (int)retval, "set analog pulsing",
DEC);
LOG(logDEBUG1, ("analog pulsing retval: %u\n", retval));
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_digital_pulsing(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logDEBUG1, ("Getting digital pulsing\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// get only
retval = getDigitalPulsing();
LOG(logDEBUG1, ("digital pulsing retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_digital_pulsing(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting digital pulsing: %u\n", arg));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setDigitalPulsing(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set digital pulsing\n");
LOG(logERROR, (mess));
} else {
int retval = getDigitalPulsing();
validate(&ret, mess, (int)arg, (int)retval, "set digital pulsing",
DEC);
LOG(logDEBUG1, ("digital pulsing retval: %u\n", retval));
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}

View File

@ -17,6 +17,8 @@ add_library(slsDetectorObject OBJECT
target_include_directories(slsDetectorObject PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
${SLS_INTERNAL_RAPIDJSON_DIR}
)
target_link_libraries(slsDetectorObject

View File

@ -1472,6 +1472,36 @@ class Detector {
Result<int> getGainCaps(Positions pos = {});
/** [Mythen3] */
Result<defs::polarity> getPolarity(Positions pos = {}) const;
/** [Mythen3] */
void setPolarity(defs::polarity value, Positions pos = {});
/** [Mythen3] */
Result<bool> getInterpolation(Positions pos = {}) const;
/** [Mythen3] Also enables all counters */
void setInterpolation(bool value, Positions pos = {});
/** [Mythen3] */
Result<bool> getPumpProbe(Positions pos = {}) const;
/** [Mythen3] */
void setPumpProbe(bool value, Positions pos = {});
/** [Mythen3] */
Result<bool> getAnalogPulsing(Positions pos = {}) const;
/** [Mythen3] */
void setAnalogPulsing(bool value, Positions pos = {});
/** [Mythen3] */
Result<bool> getDigitalPulsing(Positions pos = {}) const;
/** [Mythen3] */
void setDigitalPulsing(bool value, Positions pos = {});
///@}
/** @name CTB / Moench Specific */
@ -1614,12 +1644,11 @@ class Detector {
/** [CTB] Default is enabled. */
void setLEDEnable(bool enable, Positions pos = {});
void setDacNames(const std::vector<std::string> names);
std::vector<std::string> getDacNames() const;
defs::dacIndex getDacIndex(const std::string& name);
defs::dacIndex getDacIndex(const std::string &name);
std::string getDacName(defs::dacIndex i);
///@}
@ -1766,23 +1795,11 @@ class Detector {
/** [Jungfrau][CTB][Moench] Advanced user Function! */
void resetFPGA(Positions pos = {});
/** [[deprecated ("Replaced by updateDetectorServer, which does not require
* tftp")]] [Jungfrau][Eiger][Gotthard][CTB][Moench][Mythen3][Gotthard2]
* Advanced user Function! \n
* Copy detector server fname from tftp folder of hostname to detector. Also
* creates a symbolic link to a shorter name (without vx.x.x). Then the
* detector controller reboots (except eiger) \n
* [Jungfrau][Gotthard][CTB][Moench] Also changes respawn server (to the
* link), which is effective after a reboot.
*/
void copyDetectorServer(const std::string &fname,
const std::string &hostname, Positions pos = {});
/** [Jungfrau][Eiger][Ctb][Moench][Mythen3][Gotthard2] Copies detector
* server via TCP (without tftp).\nMakes a symbolic link with a shorter
* name (without vx.x.x).\nThen, detector controller reboots (except
* Eiger).\n[Jungfrau][Ctb][Moench]Also changes respawn server to the
* link, which is effective after a reboot.
* Eiger).\n[Jungfrau][Ctb][Moench] Also deletes old server binary and
* changes respawn server to the link, which is effective after a reboot.
*/
void updateDetectorServer(const std::string &fname, Positions pos = {});
@ -1797,19 +1814,6 @@ class Detector {
* Function! */
void rebootController(Positions pos = {});
/** [[deprecated ("Replaced by overloaded updateDetectorServer, which does
* not require tftp and has one less argument")]] Advanced user Function!\n
* [Jungfrau][Gotthard][CTB][Moench] Updates the firmware, detector server,
* make a soft link and then reboots detector controller. \n
* [Mythen3][Gotthard2] Will require a script to start up the shorter named
* server link at start up \n sname is name of detector server binary found
* on tftp folder of host pc \n hostname is name of pc to tftp from \n fname
* is programming file name with full path to it
*/
void updateFirmwareAndServer(const std::string &sname,
const std::string &hostname,
const std::string &fname, Positions pos = {});
/**
* Advanced user Function!\n [Jungfrau][Gotthard][CTB][Moench] Updates the
* firmware, detector server, make a soft link and then reboots detector

View File

@ -1056,7 +1056,18 @@ std::string CmdProxy::TemperatureValues(int action) {
std::string CmdProxy::Dac(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
if (args.size() == 0) {
os << GetHelpDac(std::to_string(0)) << '\n';
} else {
os << args[0] << ' ' << GetHelpDac(args[0]) << '\n';
}
return os.str();
}
auto type = det->getDetectorType().squash();
// dac indices only for ctb
if (args.size() > 0 && action != defs::HELP_ACTION) {
if (is_int(args[0]) && type != defs::CHIPTESTBOARD) {
@ -1066,13 +1077,7 @@ std::string CmdProxy::Dac(int action) {
}
}
if (action == defs::HELP_ACTION) {
if (args.size() == 0) {
os << GetHelpDac(std::to_string(0)) << '\n';
} else {
os << args[0] << ' ' << GetHelpDac(args[0]) << '\n';
}
} else if (action == defs::GET_ACTION) {
if (action == defs::GET_ACTION) {
if (args.empty())
WrongNumberOfParameters(1); // This prints slightly wrong
@ -2911,35 +2916,6 @@ std::string CmdProxy::ProgramFpga(int action) {
return os.str();
}
std::string CmdProxy::CopyDetectorServer(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
LOG(logWARNING) << "Deprecated! Replaced by updatedetectorserver that "
"requires no tftp.\n";
os << "[server_name (in tftp folder)] "
"[pc_host_name]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
"Gotthard2] Copies detector server via TFTP from pc. Ensure that "
"server is in the pc's tftp folder. Makes a symbolic link with a "
"shorter name (without vx.x.x). Then, detector controller "
"reboots (except "
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
"to the link, which is effective after a reboot."
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get");
} else if (action == defs::PUT_ACTION) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
det->copyDetectorServer(args[0], args[1], std::vector<int>{det_id});
os << "successful\n";
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::UpdateDetectorServer(int action) {
std::ostringstream os;
os << cmd << ' ';
@ -2996,23 +2972,21 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "\n\tUsing tftp: Deprecated!! [server_name"
" (in tftp folder)] [pc_host_name] [fname.pof (incl full path)]"
"\n\tWithout tftp: Recommended [server_name (incl fullpath)] "
os << "\n\tWithout tftp: [server_name (incl fullpath)] "
"[fname.pof (incl full path)] "
"This does not use tftp."
"\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
"firmware, detector server, creates the symbolic link and then "
"firmware, detector server, deletes old server, creates the symbolic link and then "
"reboots detector controller. \n\t\t[Mythen3][Gotthard2] will "
"require a script to start up the shorter named server link at "
"start up. \n\t\tsname is full path name of detector server "
"start up. \n\t\tserver_name is full path name of detector server "
"binary"
"\n\t\tfname is full path of programming file"
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get");
} else if (action == defs::PUT_ACTION) {
if (args.size() != 3 && args.size() != 2) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
@ -3021,17 +2995,8 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
args[fpos].find(".rbf") == std::string::npos) {
throw sls::RuntimeError("Programming file must be a pof/rbf file.");
}
if (args.size() == 3) {
LOG(logWARNING)
<< "Deprecated! Recommend to use same command without tftp (no "
"pc name) and using full path to the server binary";
det->updateFirmwareAndServer(args[0], args[1], args[2],
det->updateFirmwareAndServer(args[0], args[1],
std::vector<int>{det_id});
} else {
det->updateFirmwareAndServer(args[0], args[1],
std::vector<int>{det_id});
}
os << "successful\n";
} else {
throw sls::RuntimeError("Unknown action");

View File

@ -743,7 +743,11 @@ class CmdProxy {
/* Pattern */
/* Moench */
/* Advanced */
{"copydetectorserver", "updatedetectorserver"},
/* Insignificant */
{"nframes", "framecounter"},
{"now", "runtime"},
@ -992,6 +996,11 @@ class CmdProxy {
{"gatedelay2", &CmdProxy::GateDelay},
{"gatedelay3", &CmdProxy::GateDelay},
{"gaincaps", &CmdProxy::GainCaps},
{"polarity", &CmdProxy::polarity},
{"interpolation", &CmdProxy::interpolation},
{"pumpprobe", &CmdProxy::pumpprobe},
{"apulse", &CmdProxy::apulse},
{"dpulse", &CmdProxy::dpulse},
/* CTB/ Moench Specific */
{"samples", &CmdProxy::Samples},
@ -1062,7 +1071,6 @@ class CmdProxy {
/* Advanced */
{"programfpga", &CmdProxy::ProgramFpga},
{"resetfpga", &CmdProxy::resetfpga},
{"copydetectorserver", &CmdProxy::CopyDetectorServer},
{"updatedetectorserver", &CmdProxy::UpdateDetectorServer},
{"updatekernel", &CmdProxy::UpdateKernel},
{"rebootcontroller", &CmdProxy::rebootcontroller},
@ -1189,7 +1197,6 @@ class CmdProxy {
std::string JsonParameter(int action);
/* Advanced */
std::string ProgramFpga(int action);
std::string CopyDetectorServer(int action);
std::string UpdateDetectorServer(int action);
std::string UpdateKernel(int action);
std::string UpdateFirmwareAndDetectorServer(int action);
@ -2032,6 +2039,31 @@ class CmdProxy {
"[n_gates]\n\t[Mythen3] Number of external gates in gating "
"or trigger_gating mode (external gating).");
INTEGER_COMMAND_VEC_ID(polarity, getPolarity, setPolarity,
StringTo<defs::polarity>,
"[pos|neg]\n\t[Mythen3] Sets negative or positive "
"polarity. Default is positive");
INTEGER_COMMAND_VEC_ID(interpolation, getInterpolation, setInterpolation,
StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables "
"interpolation. Default is disabled. Enabling also "
"enables all counters. ");
INTEGER_COMMAND_VEC_ID(pumpprobe, getPumpProbe, setPumpProbe, StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables pump probe "
"mode. Default is disabled");
INTEGER_COMMAND_VEC_ID(apulse, getAnalogPulsing, setAnalogPulsing,
StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables analog "
"pulsing. Default is disabled");
INTEGER_COMMAND_VEC_ID(dpulse, getDigitalPulsing, setDigitalPulsing,
StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables digital "
"pulsing. Default is disabled");
/* CTB/ Moench Specific */
INTEGER_COMMAND_VEC_ID(

View File

@ -5,9 +5,9 @@
#include "CmdParser.h"
#include "CmdProxy.h"
#include "CtbConfig.h"
#include "DetectorImpl.h"
#include "Module.h"
#include "CtbConfig.h"
#include "sls/Pattern.h"
#include "sls/container_utils.h"
#include "sls/file_utils.h"
@ -26,8 +26,8 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
// single module
if (moduleIndex >= 0) {
SharedMemory<sharedModule> moduleShm(detectorIndex, moduleIndex);
if (moduleShm.IsExisting()) {
moduleShm.RemoveSharedMemory();
if (moduleShm.exists()) {
moduleShm.removeSharedMemory();
}
return;
}
@ -36,21 +36,21 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
int numDetectors = 0;
if (detectorShm.IsExisting()) {
detectorShm.OpenSharedMemory();
if (detectorShm.exists()) {
detectorShm.openSharedMemory();
numDetectors = detectorShm()->numberOfModules;
detectorShm.RemoveSharedMemory();
detectorShm.removeSharedMemory();
}
for (int i = 0; i < numDetectors; ++i) {
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
moduleShm.RemoveSharedMemory();
moduleShm.removeSharedMemory();
}
// Ctb configuration
SharedMemory<CtbConfig> ctbShm(detectorIndex, -1, CtbConfig::shm_tag());
if (ctbShm.IsExisting())
ctbShm.RemoveSharedMemory();
if (ctbShm.exists())
ctbShm.removeSharedMemory();
}
using defs = slsDetectorDefs;
@ -781,24 +781,7 @@ void Detector::startReceiver() { pimpl->Parallel(&Module::startReceiver, {}); }
void Detector::stopReceiver() { pimpl->Parallel(&Module::stopReceiver, {}); }
void Detector::startDetector(Positions pos) {
auto detector_type = getDetectorType(pos).squash();
if (detector_type == defs::MYTHEN3 && size() > 1) {
std::vector<int> slaves(pos);
auto is_master = getMaster(pos);
int masterPosition = -1;
for (unsigned int i = 0; i < is_master.size(); ++i) {
if (is_master[i]) {
masterPosition = i;
slaves.erase(slaves.begin() + i);
}
}
pimpl->Parallel(&Module::startAcquisition, pos);
if (masterPosition != -1) {
pimpl->Parallel(&Module::startAcquisition, {masterPosition});
}
} else {
pimpl->Parallel(&Module::startAcquisition, pos);
}
pimpl->startAcquisition(false, pos);
}
void Detector::startDetectorReadout() {
@ -1875,6 +1858,46 @@ Result<int> Detector::getGainCaps(Positions pos) {
return pimpl->Parallel(&Module::getGainCaps, pos);
}
Result<defs::polarity> Detector::getPolarity(Positions pos) const {
return pimpl->Parallel(&Module::getPolarity, pos);
}
void Detector::setPolarity(defs::polarity value, Positions pos) {
pimpl->Parallel(&Module::setPolarity, pos, value);
}
Result<bool> Detector::getInterpolation(Positions pos) const {
return pimpl->Parallel(&Module::getInterpolation, pos);
}
void Detector::setInterpolation(bool value, Positions pos) {
pimpl->Parallel(&Module::setInterpolation, pos, value);
}
Result<bool> Detector::getPumpProbe(Positions pos) const {
return pimpl->Parallel(&Module::getPumpProbe, pos);
}
void Detector::setPumpProbe(bool value, Positions pos) {
pimpl->Parallel(&Module::setPumpProbe, pos, value);
}
Result<bool> Detector::getAnalogPulsing(Positions pos) const {
return pimpl->Parallel(&Module::getAnalogPulsing, pos);
}
void Detector::setAnalogPulsing(bool value, Positions pos) {
pimpl->Parallel(&Module::setAnalogPulsing, pos, value);
}
Result<bool> Detector::getDigitalPulsing(Positions pos) const {
return pimpl->Parallel(&Module::getDigitalPulsing, pos);
}
void Detector::setDigitalPulsing(bool value, Positions pos) {
pimpl->Parallel(&Module::setDigitalPulsing, pos, value);
}
// CTB/ Moench Specific
Result<int> Detector::getNumberOfAnalogSamples(Positions pos) const {
@ -2242,15 +2265,6 @@ void Detector::resetFPGA(Positions pos) {
pimpl->Parallel(&Module::resetFPGA, pos);
}
void Detector::copyDetectorServer(const std::string &fname,
const std::string &hostname, Positions pos) {
LOG(logINFO) << "Updating Detector Server (via tftp)...";
pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname);
if (getDetectorType().squash() != defs::EIGER) {
rebootController(pos);
}
}
void Detector::updateDetectorServer(const std::string &fname, Positions pos) {
LOG(logINFO) << "Updating Detector Server (no tftp)...";
std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server");
@ -2272,16 +2286,6 @@ void Detector::rebootController(Positions pos) {
pimpl->Parallel(&Module::rebootController, pos);
}
void Detector::updateFirmwareAndServer(const std::string &sname,
const std::string &hostname,
const std::string &fname,
Positions pos) {
LOG(logINFO) << "Updating Firmware and Detector Server (with tftp)...";
LOG(logINFO) << "Updating Detector Server (via tftp)...";
pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname);
programFPGA(fname, false, pos);
}
void Detector::updateFirmwareAndServer(const std::string &sname,
const std::string &fname,
Positions pos) {

View File

@ -46,8 +46,8 @@ void DetectorImpl::setupDetector(bool verify, bool update) {
updateUserdetails();
}
if (ctb_shm.IsExisting())
ctb_shm.OpenSharedMemory();
if (ctb_shm.exists())
ctb_shm.openSharedMemory();
}
void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
@ -58,8 +58,8 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
// single
if (detPos >= 0) {
SharedMemory<sharedModule> moduleShm(detectorIndex, detPos);
if (moduleShm.IsExisting()) {
moduleShm.RemoveSharedMemory();
if (moduleShm.exists()) {
moduleShm.removeSharedMemory();
}
return;
}
@ -68,20 +68,20 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
int numModules = 0;
if (detectorShm.IsExisting()) {
detectorShm.OpenSharedMemory();
if (detectorShm.exists()) {
detectorShm.openSharedMemory();
numModules = detectorShm()->numberOfModules;
detectorShm.RemoveSharedMemory();
detectorShm.removeSharedMemory();
}
for (int i = 0; i < numModules; ++i) {
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
moduleShm.RemoveSharedMemory();
moduleShm.removeSharedMemory();
}
SharedMemory<CtbConfig> ctbShm(detectorIndex, -1, CtbConfig::shm_tag());
if (ctbShm.IsExisting())
ctbShm.RemoveSharedMemory();
if (ctbShm.exists())
ctbShm.removeSharedMemory();
}
void DetectorImpl::freeSharedMemory() {
@ -92,11 +92,11 @@ void DetectorImpl::freeSharedMemory() {
modules.clear();
// clear detector shm
shm.RemoveSharedMemory();
shm.removeSharedMemory();
client_downstream = false;
if (ctb_shm.IsExisting())
ctb_shm.RemoveSharedMemory();
if (ctb_shm.exists())
ctb_shm.removeSharedMemory();
}
std::string DetectorImpl::getUserDetails() {
@ -140,11 +140,11 @@ void DetectorImpl::setInitialChecks(const bool value) {
}
void DetectorImpl::initSharedMemory(bool verify) {
if (!shm.IsExisting()) {
shm.CreateSharedMemory();
if (!shm.exists()) {
shm.createSharedMemory();
initializeDetectorStructure();
} else {
shm.OpenSharedMemory();
shm.openSharedMemory();
if (verify && shm()->shmversion != DETECTOR_SHMVERSION) {
LOG(logERROR) << "Detector shared memory (" << detectorIndex
<< ") version mismatch "
@ -155,6 +155,8 @@ void DetectorImpl::initSharedMemory(bool verify) {
throw SharedMemoryError("Shared memory version mismatch!");
}
}
// std::cout <<
}
void DetectorImpl::initializeDetectorStructure() {
@ -261,10 +263,10 @@ void DetectorImpl::setHostname(const std::vector<std::string> &name) {
// if needed, CTB dac names are only on detector level
if (shm()->detType == defs::CHIPTESTBOARD) {
if (ctb_shm.IsExisting())
ctb_shm.OpenSharedMemory();
if (ctb_shm.exists())
ctb_shm.openSharedMemory();
else
ctb_shm.CreateSharedMemory();
ctb_shm.createSharedMemory();
}
}
@ -600,14 +602,12 @@ void DetectorImpl::readFrameFromReceiver() {
currentSubFrameIndex = zHeader.expLength;
coordY = zHeader.row;
coordX = zHeader.column;
if (eiger) {
coordY = (nY - 1) - coordY;
}
flipRows = zHeader.flipRows;
if (zHeader.completeImage == 0) {
completeImage = false;
}
LOG(logDEBUG1)
<< zmqSocket[isocket]->GetPortNumber() << " "
<< "Header Info:"
"\n\tcurrentFileName: "
<< currentFileName << "\n\tcurrentAcquisitionIndex: "
@ -1124,25 +1124,7 @@ int DetectorImpl::acquire() {
// start and read all
try {
if (detector_type == defs::MYTHEN3 && modules.size() > 1) {
// Multi module mythen
std::vector<int> master;
std::vector<int> slaves;
auto is_master = Parallel(&Module::isMaster, {});
slaves.reserve(modules.size() - 1); // check this one!!
for (size_t i = 0; i < modules.size(); ++i) {
if (is_master[i])
master.push_back(i);
else
slaves.push_back(i);
}
Parallel(&Module::startAcquisition, slaves);
Parallel(&Module::startAndReadAll, master);
} else {
// Normal acquire
Parallel(&Module::startAndReadAll, {});
}
startAcquisition(true, {});
} catch (...) {
if (receiver)
Parallel(&Module::stopReceiver, {});
@ -1191,6 +1173,44 @@ int DetectorImpl::acquire() {
return OK;
}
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
std::vector<int> master;
std::vector<int> slaves;
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
// could be all slaves in positions
slaves.reserve(positions.size());
auto is_master = Parallel(&Module::isMaster, positions);
for (size_t i : positions) {
if (is_master[i])
master.push_back(i);
else
slaves.push_back(i);
}
if (!slaves.empty()) {
Parallel(&Module::startAcquisition, slaves);
}
if (!master.empty()) {
if (blocking) {
Parallel(&Module::startAndReadAll, master);
} else {
Parallel(&Module::startAcquisition, master);
}
}
} else {
if (blocking) {
Parallel(&Module::startAndReadAll, positions);
} else {
Parallel(&Module::startAcquisition, positions);
}
}
}
void DetectorImpl::printProgress(double progress) {
// spaces for python printout
std::cout << " " << std::fixed << std::setprecision(2) << std::setw(6)
@ -1286,8 +1306,13 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
throw RuntimeError("Programming file must be an rbf file.");
}
break;
default:
case EIGER:
case GOTTHARD:
throw RuntimeError("programfpga not implemented for this detector");
default:
throw RuntimeError(
"Unknown detector type. Did the 'hostname' command execute "
"successfully? Or use update mode in the detector server side.");
}
LOG(logINFO) << "This can take awhile. Please be patient.";

View File

@ -278,6 +278,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/
int acquire();
/** also takes care of master and slave for multi module mythen */
void startAcquisition(bool blocking, std::vector<int> positions);
/**
* Combines data from all readouts and gives it to the gui
* or just gives progress of acquisition by polling receivers

View File

@ -33,11 +33,11 @@ Module::Module(detectorType type, int det_id, int module_index, bool verify)
: moduleIndex(module_index), shm(det_id, module_index) {
// ensure shared memory was not created before
if (shm.IsExisting()) {
if (shm.exists()) {
LOG(logWARNING) << "This shared memory should have been "
"deleted before! "
<< shm.GetName() << ". Freeing it again";
shm.RemoveSharedMemory();
<< shm.getName() << ". Freeing it again";
shm.removeSharedMemory();
}
initSharedMemory(type, det_id, verify);
@ -55,8 +55,8 @@ Module::Module(int det_id, int module_index, bool verify)
Module::~Module() = default;
void Module::freeSharedMemory() {
if (shm.IsExisting()) {
shm.RemoveSharedMemory();
if (shm.exists()) {
shm.removeSharedMemory();
}
}
@ -407,12 +407,18 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
// check dacs
out_of_range = false;
for (auto dac : {M_VTRIM, M_VTH1, M_VTH2, M_VTH3}) {
if (myMod.dacs[dac] < 600) {
myMod.dacs[dac] = 600;
for (int i = 0; i != myMod.ndac; ++i) {
int dacMin = 0;
int dacMax = 2800;
if (i == M_VTH1 || i == M_VTH2 || i == M_VTH3) {
dacMin = 200;
dacMax = 2400;
}
if (myMod.dacs[i] < dacMin) {
myMod.dacs[i] = dacMin;
out_of_range = true;
} else if (myMod.dacs[dac] > 2400) {
myMod.dacs[dac] = 2400;
} else if (myMod.dacs[i] > dacMax) {
myMod.dacs[i] = dacMax;
out_of_range = true;
}
}
@ -2256,11 +2262,52 @@ int Module::getChipStatusRegister() const {
}
void Module::setGainCaps(int caps) {
sendToDetector<int>(F_SET_GAIN_CAPS, caps);
sendToDetector(F_SET_GAIN_CAPS, caps, nullptr);
}
int Module::getGainCaps() { return sendToDetector<int>(F_GET_GAIN_CAPS); }
defs::polarity Module::getPolarity() const {
return sendToDetector<defs::polarity>(F_GET_POLARITY);
}
void Module::setPolarity(const defs::polarity value) {
sendToDetector(F_SET_POLARITY, static_cast<int>(value), nullptr);
}
bool Module::getInterpolation() const {
return sendToDetector<int>(F_GET_INTERPOLATION);
}
void Module::setInterpolation(const bool enable) {
sendToDetector(F_SET_INTERPOLATION, static_cast<int>(enable), nullptr);
setCounterMask(getCounterMask());
}
bool Module::getPumpProbe() const {
return sendToDetector<int>(F_GET_PUMP_PROBE);
}
void Module::setPumpProbe(const bool enable) {
sendToDetector(F_SET_PUMP_PROBE, static_cast<int>(enable), nullptr);
}
bool Module::getAnalogPulsing() const {
return sendToDetector<int>(F_GET_ANALOG_PULSING);
}
void Module::setAnalogPulsing(const bool enable) {
sendToDetector(F_SET_ANALOG_PULSING, static_cast<int>(enable), nullptr);
}
bool Module::getDigitalPulsing() const {
return sendToDetector<int>(F_GET_DIGITAL_PULSING);
}
void Module::setDigitalPulsing(const bool enable) {
sendToDetector(F_SET_DIGITAL_PULSING, static_cast<int>(enable), nullptr);
}
// CTB / Moench Specific
int Module::getNumberOfAnalogSamples() const {
return sendToDetector<int>(F_GET_NUM_ANALOG_SAMPLES);
@ -2611,28 +2658,6 @@ void Module::programFPGA(std::vector<char> buffer,
void Module::resetFPGA() { sendToDetector(F_RESET_FPGA); }
void Module::copyDetectorServer(const std::string &fname,
const std::string &hostname) {
char args[2][MAX_STR_LENGTH]{};
sls::strcpy_safe(args[0], fname.c_str());
sls::strcpy_safe(args[1], hostname.c_str());
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): Sending detector server " << args[0] << " from host "
<< args[1];
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_COPY_DET_SERVER);
client.Send(args);
if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw DetectorError(os.str());
}
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): Detector server copied";
}
void Module::updateDetectorServer(std::vector<char> buffer,
const std::string &serverName) {
switch (shm()->detType) {
@ -3171,20 +3196,20 @@ Ret Module::sendToReceiver(int fnum, const Arg &args) {
slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
bool verify) {
if (!shm.IsExisting()) {
throw SharedMemoryError("Shared memory " + shm.GetName() +
if (!shm.exists()) {
throw SharedMemoryError("Shared memory " + shm.getName() +
"does not exist.\n Corrupted Multi Shared "
"memory. Please free shared memory.");
}
shm.OpenSharedMemory();
shm.openSharedMemory();
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex
<< ":)version mismatch (expected 0x" << std::hex << MODULE_SHMVERSION
<< " but got 0x" << shm()->shmversion << ")" << std::dec
<< ". Clear Shared memory to continue.";
shm.UnmapSharedMemory();
shm.unmapSharedMemory();
throw SharedMemoryError(ss.str());
}
return shm()->detType;
@ -3192,11 +3217,11 @@ slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
void Module::initSharedMemory(detectorType type, int det_id, bool verify) {
shm = SharedMemory<sharedModule>(det_id, moduleIndex);
if (!shm.IsExisting()) {
shm.CreateSharedMemory();
if (!shm.exists()) {
shm.createSharedMemory();
initializeModuleStructure(type);
} else {
shm.OpenSharedMemory();
shm.openSharedMemory();
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex

View File

@ -466,6 +466,16 @@ class Module : public virtual slsDetectorDefs {
int getChipStatusRegister() const;
void setGainCaps(int caps);
int getGainCaps();
defs::polarity getPolarity() const;
void setPolarity(const defs::polarity enable);
bool getInterpolation() const;
void setInterpolation(const bool enable);
bool getPumpProbe() const;
void setPumpProbe(const bool enable);
bool getAnalogPulsing() const;
void setAnalogPulsing(const bool enable);
bool getDigitalPulsing() const;
void setDigitalPulsing(const bool enable);
/**************************************************
* *
@ -548,8 +558,6 @@ class Module : public virtual slsDetectorDefs {
void programFPGA(std::vector<char> buffer,
const bool forceDeleteNormalFile);
void resetFPGA();
void copyDetectorServer(const std::string &fname,
const std::string &hostname);
void updateDetectorServer(std::vector<char> buffer,
const std::string &serverName);
void updateKernel(std::vector<char> buffer);

View File

@ -13,7 +13,8 @@
#include "sls/logger.h"
#include "sls/sls_detector_exceptions.h"
#include "stdlib.h"
// #include "stdlib.h"
#include <cstdlib>
#include <cerrno> // errno
#include <cstring> // strerror
#include <fcntl.h> // O_CREAT, O_TRUNC..
@ -33,268 +34,178 @@
namespace sls {
template <typename T> class SharedMemory {
static constexpr int NAME_MAX_LENGTH = 255;
std::string name;
T *shared_struct{};
public:
//moduleid of -1 creates a detector only shared memory
SharedMemory(int detectorId, int moduleIndex, const std::string& tag = "") {
name = ConstructSharedMemoryName(detectorId, moduleIndex, tag);
// moduleid of -1 creates a detector only shared memory
SharedMemory(int detectorId, int moduleIndex, const std::string &tag = "") {
name = constructSharedMemoryName(detectorId, moduleIndex, tag);
}
/**
* Delete the copy constructor and copy assignment since we don't want two
* objects managing the same resource
*/
// Disable copy, since we refer to a unique location
SharedMemory(const SharedMemory &) = delete;
SharedMemory &operator=(const SharedMemory &other) = delete;
// Move constructor
SharedMemory(SharedMemory &&other)
: name(other.name), fd(other.fd), shmSize(other.shmSize),
shared_struct(other.shared_struct) {
other.fd = -1;
: name(other.name), shared_struct(other.shared_struct) {
other.shared_struct = nullptr;
other.shmSize = 0;
}
// Move assignment
SharedMemory &operator=(SharedMemory &&other) {
name = other.name;
if (fd) {
close(fd);
}
fd = other.fd;
other.fd = -1;
if (shared_struct != nullptr) {
UnmapSharedMemory();
}
if (shared_struct != nullptr)
unmapSharedMemory();
shared_struct = other.shared_struct;
other.shared_struct = nullptr;
shmSize = other.shmSize;
other.shmSize = 0;
return *this;
}
~SharedMemory() {
if (fd >= 0)
close(fd);
if (shared_struct) {
UnmapSharedMemory();
}
if (shared_struct)
unmapSharedMemory();
}
/**
* Verify if it exists
* @return true if exists, else false
*/
bool IsExisting() {
bool ret = true;
T *operator()() { return shared_struct; }
const T *operator()() const { return shared_struct; }
std::string getName() const { return name; }
bool exists() {
int tempfd = shm_open(name.c_str(), O_RDWR, 0);
if ((tempfd < 0) && (errno == ENOENT)) {
ret = false;
return false;
}
close(tempfd);
return ret;
return true;
}
std::string GetName() const { return name; }
size_t size() const { return shmSize; }
/**
* Create Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryError exception on failure to create, ftruncate or
* map
*/
void CreateSharedMemory() {
fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR,
S_IRUSR | S_IWUSR);
void createSharedMemory() {
int fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR,
S_IRUSR | S_IWUSR);
if (fd < 0) {
std::string msg =
"Create shared memory " + name + " failed: " + strerror(errno);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
if (ftruncate(fd, sizeof(T)) < 0) {
std::string msg = "Create shared memory " + name +
" failed at ftruncate: " + strerror(errno);
LOG(logERROR) << msg;
close(fd);
RemoveSharedMemory();
removeSharedMemory();
throw SharedMemoryError(msg);
}
shared_struct = MapSharedMemory();
new (shared_struct) T{};
shared_struct = mapSharedMemory(fd);
new (shared_struct) T{};
LOG(logINFO) << "Shared memory created " << name;
}
/**
* Open existing Shared memory and call MapSharedMemory to map it to an
* address throws a SharedMemoryError exception on failure to open or map
*/
void OpenSharedMemory() {
fd = shm_open(name.c_str(), O_RDWR, 0);
void openSharedMemory() {
int fd = shm_open(name.c_str(), O_RDWR, 0);
if (fd < 0) {
std::string msg = "Open existing shared memory " + name +
" failed: " + strerror(errno);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
shared_struct = MapSharedMemory();
checkSize(fd);
shared_struct = mapSharedMemory(fd);
}
/**
* Unmap shared memory from an address
* throws a SharedMemoryError exception on failure
*/
void UnmapSharedMemory() {
void unmapSharedMemory() {
if (shared_struct != nullptr) {
if (munmap(shared_struct, shmSize) < 0) {
if (munmap(shared_struct, sizeof(T)) < 0) {
std::string msg = "Unmapping shared memory " + name +
" failed: " + strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
}
shared_struct = nullptr;
}
}
/**
* Remove existing Shared memory
*/
void RemoveSharedMemory() {
UnmapSharedMemory();
void removeSharedMemory() {
unmapSharedMemory();
if (shm_unlink(name.c_str()) < 0) {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
std::string msg =
"Free Shared Memory " + name + " Failed: " + strerror(errno);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
LOG(logINFO) << "Shared memory deleted " << name;
}
/**
* Maximum length of name as from man pages
*/
static const int NAME_MAX_LENGTH = 255;
/**
*Using the call operator to access the pointer
*/
T *operator()() { return shared_struct; }
/**
*Using the call operator to access the pointer, const overload
*/
const T *operator()() const { return shared_struct; }
private:
/**
* Create Shared memory name
* throws exception if name created is longer than required 255(manpages)
* @param detectorId detector id
* @param moduleIndex module id, -1 if a detector shared memory
* @returns shared memory name
*/
std::string ConstructSharedMemoryName(int detectorId, int moduleIndex, const std::string& tag) {
std::string constructSharedMemoryName(int detectorId, int moduleIndex,
const std::string &tag) {
// using environment path
std::string sEnvPath;
// using environment variable
std::string slsdetname;
char *envpath = getenv(SHM_ENV_NAME);
if (envpath != nullptr) {
sEnvPath.assign(envpath);
sEnvPath.insert(0, "_");
slsdetname = envpath;
slsdetname.insert(0, "_");
}
std::stringstream ss;
if (moduleIndex < 0){
ss << SHM_DETECTOR_PREFIX << detectorId << sEnvPath;
if (moduleIndex < 0) {
ss << SHM_DETECTOR_PREFIX << detectorId << slsdetname;
if (!tag.empty())
ss << "_" << tag;
}
else
} else {
ss << SHM_DETECTOR_PREFIX << detectorId << SHM_MODULE_PREFIX
<< moduleIndex << sEnvPath;
<< moduleIndex << slsdetname;
}
std::string temp = ss.str();
if (temp.length() > NAME_MAX_LENGTH) {
std::string shm_name = ss.str();
if (shm_name.length() > NAME_MAX_LENGTH) {
std::string msg =
"Shared memory initialization failed. " + temp + " has " +
std::to_string(temp.length()) + " characters. \n" +
"Shared memory initialization failed. " + shm_name + " has " +
std::to_string(shm_name.length()) + " characters. \n" +
"Maximum is " + std::to_string(NAME_MAX_LENGTH) +
". Change the environment variable " + SHM_ENV_NAME;
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
return temp;
return shm_name;
}
/**
* Map shared memory to an address
* throws a SharedMemoryException exception on failure
*/
T *MapSharedMemory() {
// from the Linux manual:
// After the mmap() call has returned, the file descriptor, fd, can
// be closed immediately without invalidating the mapping.
T *mapSharedMemory(int fd) {
void *addr =
mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (addr == MAP_FAILED) {
std::string msg =
"Mapping shared memory " + name + " failed: " + strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
}
shmSize = sizeof(T);
close(fd);
return (T *)addr;
return static_cast<T *>(addr);
}
/**
* Verify if existing shared memory size matches expected size
* @param expectedSize expected size of shared memory, replaced with smaller
* size if size does not match
* @return 0 for success, 1 for fail
*/
int VerifySizeMatch(size_t expectedSize) {
void checkSize(int fd) {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
std::string msg = "Could not verify existing shared memory " +
name + " size match " +
"(could not fstat): " + strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
}
// size does not match
auto sz = static_cast<size_t>(sb.st_size);
if (sz != expectedSize) {
std::string msg = "Existing shared memory " + name +
" size does not match" + "Expected " +
std::to_string(expectedSize) + ", found " +
std::to_string(sz);
LOG(logERROR) << msg;
auto actual_size = static_cast<size_t>(sb.st_size);
auto expected_size = sizeof(T);
if (actual_size != expected_size) {
std::string msg =
"Existing shared memory " + name + " size does not match. " +
"Expected " + std::to_string(expected_size) + ", found " +
std::to_string(actual_size) +
". Detector software mismatch? Try freeing shared memory.";
throw SharedMemoryError(msg);
return 1;
}
return 0;
}
std::string name;
int fd{-1};
size_t shmSize{0};
T *shared_struct{nullptr};
};
} // namespace sls

View File

@ -462,4 +462,152 @@ TEST_CASE("gatedelay3", "[.cmd]") {
} else {
REQUIRE_THROWS(proxy.Call("gatedelay3", {}, -1, GET));
}
}
TEST_CASE("polarity", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getPolarity();
{
std::ostringstream oss;
proxy.Call("polarity", {"pos"}, -1, PUT, oss);
REQUIRE(oss.str() == "polarity pos\n");
}
{
std::ostringstream oss;
proxy.Call("polarity", {"neg"}, -1, PUT, oss);
REQUIRE(oss.str() == "polarity neg\n");
}
{
std::ostringstream oss;
proxy.Call("polarity", {}, -1, GET, oss);
REQUIRE(oss.str() == "polarity neg\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPolarity(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("polarity", {}, -1, GET));
}
}
TEST_CASE("interpolation", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getInterpolation();
auto mask = det.getCounterMask();
{
proxy.Call("counters", {"0", "1"}, -1, PUT);
std::ostringstream oss;
proxy.Call("interpolation", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 1\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
7);
}
{
proxy.Call("counters", {"0", "1"}, -1, PUT);
std::ostringstream oss;
proxy.Call("interpolation", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 0\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
3);
}
{
std::ostringstream oss;
proxy.Call("interpolation", {}, -1, GET, oss);
REQUIRE(oss.str() == "interpolation 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setCounterMask(mask[i], {i});
det.setInterpolation(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("interpolation", {}, -1, GET));
}
}
TEST_CASE("pumpprobe", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getPumpProbe();
{
std::ostringstream oss;
proxy.Call("pumpprobe", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 1\n");
}
{
std::ostringstream oss;
proxy.Call("pumpprobe", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 0\n");
}
{
std::ostringstream oss;
proxy.Call("pumpprobe", {}, -1, GET, oss);
REQUIRE(oss.str() == "pumpprobe 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPumpProbe(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("pumpprobe", {}, -1, GET));
}
}
TEST_CASE("apulse", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getAnalogPulsing();
{
std::ostringstream oss;
proxy.Call("apulse", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "apulse 1\n");
}
{
std::ostringstream oss;
proxy.Call("apulse", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "apulse 0\n");
}
{
std::ostringstream oss;
proxy.Call("apulse", {}, -1, GET, oss);
REQUIRE(oss.str() == "apulse 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setAnalogPulsing(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("apulse", {}, -1, GET));
}
}
TEST_CASE("dpulse", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getDigitalPulsing();
{
std::ostringstream oss;
proxy.Call("dpulse", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "dpulse 1\n");
}
{
std::ostringstream oss;
proxy.Call("dpulse", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "dpulse 0\n");
}
{
std::ostringstream oss;
proxy.Call("dpulse", {}, -1, GET, oss);
REQUIRE(oss.str() == "dpulse 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setDigitalPulsing(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("dpulse", {}, -1, GET));
}
}

View File

@ -16,6 +16,17 @@ using sls::Detector;
using test::GET;
using test::PUT;
TEST_CASE("Calling help doesn't throw or cause segfault"){
//Dont add [.cmd] tag this should run with normal tests
CmdProxy proxy(nullptr);
auto commands = proxy.GetProxyCommands();
std::ostringstream os;
for (const auto &cmd : commands)
REQUIRE_NOTHROW(proxy.Call(cmd, {}, -1, slsDetectorDefs::HELP_ACTION, os));
}
TEST_CASE("Unknown command", "[.cmd]") {
Detector det;
@ -2776,25 +2787,6 @@ TEST_CASE("resetfpga", "[.cmd]") {
}
}
TEST_CASE("copydetectorserver", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
det_type == defs::MOENCH || det_type == defs::MYTHEN3 ||
det_type == defs::GOTTHARD2) {
// TODO: send real server?
// std::ostringstream oss;
// proxy.Call("copydetectorserver",{"jungfrauDetectorServerv4.0.1.0",
// "pc13784"}, -1, PUT, oss);
// REQUIRE(oss.str() == "copydetectorserver successful\n");
REQUIRE_THROWS(proxy.Call("copydetectorserver", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("copydetectorserver", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("copydetectorserver", {}, -1, PUT));
}
}
TEST_CASE("updatekernel", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);

View File

@ -32,8 +32,8 @@ TEST_CASE("Is shm fixed pattern shm compatible") {
// Set shm version to 0
sls::SharedMemory<sls::sharedModule> shm(0, 0);
REQUIRE(shm.IsExisting() == true);
shm.OpenSharedMemory();
REQUIRE(shm.exists() == true);
shm.openSharedMemory();
shm()->shmversion = 0;
// Should fail since version is set to 0

View File

@ -20,8 +20,8 @@ constexpr int shm_id = 10;
TEST_CASE("Create SharedMemory read and write", "[detector]") {
SharedMemory<Data> shm(shm_id, -1);
shm.CreateSharedMemory();
CHECK(shm.GetName() == std::string("/slsDetectorPackage_detector_") +
shm.createSharedMemory();
CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(shm_id));
shm()->x = 3;
@ -32,25 +32,25 @@ TEST_CASE("Create SharedMemory read and write", "[detector]") {
CHECK(shm()->y == 5.7);
CHECK(std::string(shm()->mess) == "Some string");
shm.UnmapSharedMemory();
shm.RemoveSharedMemory();
shm.unmapSharedMemory();
shm.removeSharedMemory();
CHECK(shm.IsExisting() == false);
CHECK(shm.exists() == false);
}
TEST_CASE("Open existing SharedMemory and read", "[detector]") {
{
SharedMemory<double> shm(shm_id, -1);
shm.CreateSharedMemory();
shm.createSharedMemory();
*shm() = 5.3;
}
SharedMemory<double> shm2(shm_id, -1);
shm2.OpenSharedMemory();
shm2.openSharedMemory();
CHECK(*shm2() == 5.3);
shm2.RemoveSharedMemory();
shm2.removeSharedMemory();
}
TEST_CASE("Creating a second shared memory with the same name throws",
@ -59,24 +59,24 @@ TEST_CASE("Creating a second shared memory with the same name throws",
SharedMemory<double> shm0(shm_id, -1);
SharedMemory<double> shm1(shm_id, -1);
shm0.CreateSharedMemory();
CHECK_THROWS(shm1.CreateSharedMemory());
shm0.RemoveSharedMemory();
shm0.createSharedMemory();
CHECK_THROWS(shm1.createSharedMemory());
shm0.removeSharedMemory();
}
TEST_CASE("Open two shared memories to the same place", "[detector]") {
// Create the first shared memory
SharedMemory<Data> shm(shm_id, -1);
shm.CreateSharedMemory();
shm.createSharedMemory();
shm()->x = 5;
CHECK(shm()->x == 5);
// Open the second shared memory with the same name
SharedMemory<Data> shm2(shm_id, -1);
shm2.OpenSharedMemory();
shm2.openSharedMemory();
CHECK(shm2()->x == 5);
CHECK(shm.GetName() == shm2.GetName());
CHECK(shm.getName() == shm2.getName());
// Check that they still point to the same place
shm2()->x = 7;
@ -84,31 +84,28 @@ TEST_CASE("Open two shared memories to the same place", "[detector]") {
// Remove only needs to be done once since they refer
// to the same memory
shm2.RemoveSharedMemory();
CHECK(shm.IsExisting() == false);
CHECK(shm2.IsExisting() == false);
shm2.removeSharedMemory();
CHECK(shm.exists() == false);
CHECK(shm2.exists() == false);
}
TEST_CASE("Move SharedMemory", "[detector]") {
SharedMemory<Data> shm(shm_id, -1);
CHECK(shm.GetName() == std::string("/slsDetectorPackage_detector_") +
CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(shm_id));
shm.CreateSharedMemory();
shm.createSharedMemory();
shm()->x = 9;
CHECK(shm.size() == sizeof(Data));
SharedMemory<Data> shm2(shm_id + 1, -1);
shm2 = std::move(shm); // shm is now a moved from object!
CHECK(shm2()->x == 9);
CHECK(shm() == nullptr);
CHECK(shm.size() == 0);
CHECK(shm2.GetName() == std::string("/slsDetectorPackage_detector_") +
CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(shm_id));
shm2.RemoveSharedMemory();
shm2.removeSharedMemory();
}
TEST_CASE("Create several shared memories", "[detector]") {
@ -117,27 +114,27 @@ TEST_CASE("Create several shared memories", "[detector]") {
v.reserve(N);
for (int i = 0; i != N; ++i) {
v.emplace_back(shm_id + i, -1);
CHECK(v[i].IsExisting() == false);
v[i].CreateSharedMemory();
CHECK(v[i].exists() == false);
v[i].createSharedMemory();
*v[i]() = i;
CHECK(*v[i]() == i);
}
for (int i = 0; i != N; ++i) {
CHECK(*v[i]() == i);
CHECK(v[i].GetName() == std::string("/slsDetectorPackage_detector_") +
CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(i + shm_id));
}
for (int i = 0; i != N; ++i) {
v[i].RemoveSharedMemory();
CHECK(v[i].IsExisting() == false);
v[i].removeSharedMemory();
CHECK(v[i].exists() == false);
}
}
TEST_CASE("Create create a shared memory with a tag"){
SharedMemory<int> shm(0, -1, "ctbdacs");
REQUIRE(shm.GetName() == "/slsDetectorPackage_detector_0_ctbdacs");
REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs");
}
@ -152,7 +149,7 @@ TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set"){
setenv(SHM_ENV_NAME, "myprefix", 1);
SharedMemory<int> shm(0, -1, "ctbdacs");
REQUIRE(shm.GetName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs");
REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs");
// Clean up after us
if (old_slsdetname.empty())
@ -162,3 +159,17 @@ TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set"){
}
TEST_CASE("map int64 to int32 throws"){
SharedMemory<int32_t> shm(shm_id, -1);
shm.createSharedMemory();
*shm() = 7;
SharedMemory<int64_t> shm2(shm_id, -1);
REQUIRE_THROWS(shm2.openSharedMemory());
shm.removeSharedMemory();
}

View File

@ -6,7 +6,6 @@ set(SOURCES
src/Receiver.cpp
src/File.cpp
src/BinaryDataFile.cpp
src/BinaryMasterFile.cpp
src/ThreadObject.cpp
src/Listener.cpp
src/DataProcessor.cpp
@ -14,6 +13,7 @@ set(SOURCES
src/Fifo.cpp
src/Arping.cpp
src/MasterAttributes.cpp
src/MasterFileUtility.cpp
)
set(PUBLICHEADERS
@ -28,8 +28,6 @@ if (SLS_USE_HDF5)
)
list (APPEND SOURCES
src/HDF5DataFile.cpp
src/HDF5MasterFile.cpp
src/HDF5VirtualFile.cpp
)
endif (SLS_USE_HDF5)
@ -42,6 +40,8 @@ add_library(slsReceiverObject OBJECT
target_include_directories(slsReceiverObject PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
${SLS_INTERNAL_RAPIDJSON_DIR}
)
target_link_libraries(slsReceiverObject

View File

@ -39,52 +39,50 @@ class Receiver : private virtual slsDetectorDefs {
int64_t getReceiverVersion();
/**
* Call back for start acquisition
* callback arguments are
* filepath
* filename
* fileindex
* datasize
*
* return value is undefined at the moment
* we write depending on file write enable
* users get data to write depending on call backs registered
* Start Acquisition Call back (slsMultiReceiver writes data if file write enabled)
* if registerCallBackRawDataReady or registerCallBackRawDataModifyReady registered,
* users get data
* callback arguments are:
* - file path
* - file name prefix
* - file index
* - image size in bytes
*/
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
uint64_t, uint32_t,
void *),
void registerCallBackStartAcquisition(int (*func)(const std::string &, const std::string &,
uint64_t, size_t, void *),
void *arg);
/**
* Call back for acquisition finished
* callback argument is
* total frames caught
* callback argument is:
* - total frames caught
*/
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
void *arg);
/**
* Call back for raw data
* args to raw data ready callback are
* sls_receiver_header frame metadata,
* dataPointer is the pointer to the data,
* dataSize in bytes is the size of the data in bytes.
* args to raw data ready callback are:
* - sls_receiver_header frame metadata,
* - pointer to data
* - image size in bytes
*/
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
void *),
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
char *, size_t, void *),
void *arg);
/**
* Call back for raw data (modified)
* args to raw data ready callback are
* sls_receiver_header frame metadata,
* dataPointer is the pointer to the data,
* revDatasize is the reference of data size in bytes.
* args to raw data ready callback are:
* - sls_receiver_header frame metadata,
* - pointer to data
* - revDatasize is the reference of data size in bytes.
* Can be modified to the new size to be written/streamed. (only smaller
* value).
* value allowed).
*/
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *),
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
char *, size_t &,
void *),
void *arg);
private:

View File

@ -72,7 +72,7 @@ void BinaryDataFile::WriteToFile(char *buffer, const int buffersize,
++subFileIndex_;
CreateFile();
}
numFramesInFile_++;
++numFramesInFile_;
// write to file
int ret = 0;

View File

@ -1,60 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "BinaryMasterFile.h"
#include "MasterAttributes.h"
BinaryMasterFile::BinaryMasterFile() : File(BINARY) {}
BinaryMasterFile::~BinaryMasterFile() { CloseFile(); }
void BinaryMasterFile::CloseFile() {
if (fd_) {
fclose(fd_);
}
fd_ = nullptr;
}
void BinaryMasterFile::CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr) {
// create file name
std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_master"
<< "_" << fileIndex << ".raw";
fileName_ = os.str();
// create file
if (!overWriteEnable) {
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) {
fd_ = nullptr;
throw sls::RuntimeError("Could not create binary master file " +
fileName_);
}
} else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) {
fd_ = nullptr;
throw sls::RuntimeError(
"Could not create/overwrite binary master file " + fileName_);
}
if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName_;
}
attr->WriteMasterBinaryAttributes(fd_);
CloseFile();
}
void BinaryMasterFile::UpdateMasterFile(MasterAttributes *attr,
bool silentMode) {
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "a"))) {
fd_ = nullptr;
throw sls::RuntimeError("Could not append binary master file " +
fileName_);
}
attr->WriteFinalBinaryAttributes(fd_);
CloseFile();
if (!silentMode) {
LOG(logINFO) << "Updated Master File";
}
}

View File

@ -1,25 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "File.h"
#include "MasterAttributes.h"
class BinaryMasterFile : private virtual slsDetectorDefs, public File {
public:
BinaryMasterFile();
~BinaryMasterFile();
void CloseFile() override;
void CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr) override;
void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override;
private:
FILE *fd_{nullptr};
std::string fileName_;
};

View File

@ -55,7 +55,7 @@ int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; }
/***callback functions***/
void ClientInterface::registerCallBackStartAcquisition(
int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
int (*func)(const std::string &, const std::string &, uint64_t, size_t, void *),
void *arg) {
startAcquisitionCallBack = func;
pStartAcquisition = arg;
@ -69,13 +69,13 @@ void ClientInterface::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
}
void ClientInterface::registerCallBackRawDataReady(
void (*func)(char *, char *, uint32_t, void *), void *arg) {
void (*func)(sls_receiver_header *, char *, size_t, void *), void *arg) {
rawDataReadyCallBack = func;
pRawDataReady = arg;
}
void ClientInterface::registerCallBackRawDataModifyReady(
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
void (*func)(sls_receiver_header *, char *, size_t &, void *), void *arg) {
rawDataModifyReadyCallBack = func;
pRawDataReady = arg;
}

View File

@ -30,25 +30,24 @@ class ClientInterface : private virtual slsDetectorDefs {
int64_t getReceiverVersion();
//***callback functions***
/** params: filepath, filename, fileindex, datasize */
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
uint64_t, uint32_t,
void *),
/** params: file path, file name, file index, image size */
void registerCallBackStartAcquisition(int (*func)(const std::string &, const std::string &,
uint64_t, size_t, void *),
void *arg);
/** params: total frames caught */
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
void *arg);
/** params: sls_receiver_header frame metadata, dataPointer, dataSize */
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
void *),
/** params: sls_receiver_header pointer, pointer to data, image size */
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
char *, size_t, void *),
void *arg);
/** params: sls_receiver_header frame metadata, dataPointer, modified size
*/
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *),
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
char *, size_t &,
void *),
void *arg);
private:
@ -180,13 +179,14 @@ class ClientInterface : private virtual slsDetectorDefs {
//***callback parameters***
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
uint32_t, void *) = nullptr;
int (*startAcquisitionCallBack)(const std::string &, const std::string &, uint64_t, size_t,
void *) = nullptr;
void *pStartAcquisition{nullptr};
void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr;
void *pAcquisitionFinished{nullptr};
void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr;
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
void (*rawDataReadyCallBack)(sls_receiver_header *, char *, size_t,
void *) = nullptr;
void (*rawDataModifyReadyCallBack)(sls_receiver_header *, char *, size_t &,
void *) = nullptr;
void *pRawDataReady{nullptr};

View File

@ -9,14 +9,12 @@
#include "DataProcessor.h"
#include "BinaryDataFile.h"
#include "BinaryMasterFile.h"
#include "Fifo.h"
#include "GeneralData.h"
#include "MasterAttributes.h"
#include "MasterFileUtility.h"
#ifdef HDF5C
#include "HDF5DataFile.h"
#include "HDF5MasterFile.h"
#include "HDF5VirtualFile.h"
#endif
#include "DataStreamer.h"
#include "sls/container_utils.h"
@ -44,14 +42,10 @@ DataProcessor::DataProcessor(int index, detectorType detectorType, Fifo *fifo,
ctbAnalogDataBytes_(ctbAnalogDataBytes), firstStreamerFrame_(false) {
LOG(logDEBUG) << "DataProcessor " << index << " created";
memset((void *)&timerbegin_, 0, sizeof(timespec));
}
DataProcessor::~DataProcessor() { DeleteFiles(); }
/** getters */
bool DataProcessor::GetStartedFlag() const { return startedFlag_; }
void DataProcessor::SetFifo(Fifo *fifo) { fifo_ = fifo; }
@ -68,10 +62,8 @@ void DataProcessor::ResetParametersforNewAcquisition() {
void DataProcessor::RecordFirstIndex(uint64_t fnum) {
// listen to this fnum, later +1
currentFrameIndex_ = fnum;
startedFlag_ = true;
firstIndex_ = fnum;
LOG(logDEBUG1) << index << " First Index:" << firstIndex_;
}
@ -82,53 +74,26 @@ void DataProcessor::SetGeneralData(GeneralData *generalData) {
void DataProcessor::CloseFiles() {
if (dataFile_)
dataFile_->CloseFile();
if (masterFile_)
masterFile_->CloseFile();
#ifdef HDF5C
if (virtualFile_)
virtualFile_->CloseFile();
#endif
}
void DataProcessor::DeleteFiles() {
CloseFiles();
if (dataFile_) {
delete dataFile_;
dataFile_ = nullptr;
}
if (masterFile_) {
delete masterFile_;
masterFile_ = nullptr;
}
#ifdef HDF5C
if (virtualFile_) {
delete virtualFile_;
virtualFile_ = nullptr;
}
#endif
delete dataFile_;
dataFile_ = nullptr;
}
void DataProcessor::SetupFileWriter(const bool filewriteEnable,
const bool masterFilewriteEnable,
const fileFormat fileFormatType,
const int modulePos, std::mutex *hdf5Lib) {
std::mutex *hdf5LibMutex) {
DeleteFiles();
if (filewriteEnable) {
switch (fileFormatType) {
#ifdef HDF5C
case HDF5:
dataFile_ = new HDF5DataFile(index, hdf5Lib);
if (modulePos == 0 && index == 0) {
if (masterFilewriteEnable) {
masterFile_ = new HDF5MasterFile(hdf5Lib);
}
}
dataFile_ = new HDF5DataFile(index, hdf5LibMutex);
break;
#endif
case BINARY:
dataFile_ = new BinaryDataFile(index);
if (modulePos == 0 && index == 0 && masterFilewriteEnable) {
masterFile_ = new BinaryMasterFile();
}
break;
default:
throw sls::RuntimeError(
@ -138,23 +103,17 @@ void DataProcessor::SetupFileWriter(const bool filewriteEnable,
}
void DataProcessor::CreateFirstFiles(
MasterAttributes *attr, const std::string filePath,
const std::string fileNamePrefix, const uint64_t fileIndex,
const bool overWriteEnable, const bool silentMode, const int modulePos,
const int numUnitsPerReadout, const uint32_t udpPortNumber,
const uint32_t maxFramesPerFile, const uint64_t numImages,
const uint32_t dynamicRange, const bool detectorDataStream) {
const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout,
const uint32_t udpPortNumber, const uint32_t maxFramesPerFile,
const uint64_t numImages, const uint32_t dynamicRange,
const bool detectorDataStream) {
if (dataFile_ == nullptr) {
throw sls::RuntimeError("file object not contstructed");
}
CloseFiles();
// master file write enabled
if (masterFile_) {
masterFile_->CreateMasterFile(filePath, fileNamePrefix, fileIndex,
overWriteEnable, silentMode, attr);
}
// deactivated (half module/ single port), dont write file
if ((!*activated_) || (!detectorDataStream)) {
return;
@ -189,21 +148,17 @@ uint32_t DataProcessor::GetFilesInAcquisition() const {
return dataFile_->GetFilesInAcquisition();
}
void DataProcessor::CreateVirtualFile(
const std::string filePath, const std::string fileNamePrefix,
std::array<std::string, 2> DataProcessor::CreateVirtualFile(
const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint64_t numImages,
const uint32_t dynamicRange, const int numModX, const int numModY,
std::mutex *hdf5Lib) {
const int numModX, const int numModY, const uint32_t dynamicRange,
std::mutex *hdf5LibMutex) {
if (virtualFile_) {
delete virtualFile_;
}
bool gotthard25um =
((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) &&
(numModX * numModY) == 2);
virtualFile_ = new HDF5VirtualFile(hdf5Lib, gotthard25um);
// maxframesperfile = 0 for infinite files
uint32_t framesPerFile =
@ -213,76 +168,66 @@ void DataProcessor::CreateVirtualFile(
// files (they exist anyway) assumption2: virtual file max frame index
// is from R0 P0 (difference from others when missing frames or for a
// stop acquisition)
virtualFile_->CreateVirtualFile(
return masterFileUtility::CreateVirtualHDF5File(
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
modulePos, numUnitsPerReadout, framesPerFile, numImages,
generalData_->nPixelsX, generalData_->nPixelsY, dynamicRange,
numFramesCaught_, numModX, numModY, dataFile_->GetPDataType(),
dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes());
dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes(),
hdf5LibMutex, gotthard25um);
}
void DataProcessor::LinkDataInMasterFile(const bool silentMode) {
std::string fname, datasetName;
if (virtualFile_) {
auto res = virtualFile_->GetFileAndDatasetName();
fname = res[0];
datasetName = res[1];
} else {
void DataProcessor::LinkFileInMaster(const std::string &masterFileName,
const std::string &virtualFileName,
const std::string &virtualDatasetName,
const bool silentMode,
std::mutex *hdf5LibMutex) {
std::string fname{virtualFileName}, datasetName{virtualDatasetName};
// if no virtual file, link data file
if (virtualFileName.empty()) {
auto res = dataFile_->GetFileAndDatasetName();
fname = res[0];
datasetName = res[1];
}
// link in master
masterFile_->LinkDataFile(fname, datasetName,
dataFile_->GetParameterNames(), silentMode);
masterFileUtility::LinkHDF5FileInMaster(masterFileName, fname, datasetName,
dataFile_->GetParameterNames(),
silentMode, hdf5LibMutex);
}
#endif
void DataProcessor::UpdateMasterFile(bool silentMode) {
if (masterFile_) {
// final attributes
std::unique_ptr<MasterAttributes> masterAttributes;
switch (detectorType_) {
case GOTTHARD:
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
break;
case JUNGFRAU:
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
break;
case EIGER:
masterAttributes = sls::make_unique<EigerMasterAttributes>();
break;
case MYTHEN3:
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
break;
case GOTTHARD2:
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
break;
case MOENCH:
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
break;
case CHIPTESTBOARD:
masterAttributes = sls::make_unique<CtbMasterAttributes>();
break;
default:
throw sls::RuntimeError(
"Unknown detector type to set up master file attributes");
}
masterAttributes->framesInFile = numFramesCaught_;
masterFile_->UpdateMasterFile(masterAttributes.get(), silentMode);
std::string DataProcessor::CreateMasterFile(
const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, bool silentMode,
const fileFormat fileFormatType, MasterAttributes *attr,
std::mutex *hdf5LibMutex) {
attr->framesInFile = numFramesCaught_;
std::unique_ptr<File> masterFile{nullptr};
switch (fileFormatType) {
#ifdef HDF5C
case HDF5:
return masterFileUtility::CreateMasterHDF5File(
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
attr, hdf5LibMutex);
#endif
case BINARY:
return masterFileUtility::CreateMasterBinaryFile(
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
attr);
default:
throw sls::RuntimeError("Unknown file format (compile with hdf5 flags");
}
}
void DataProcessor::ThreadExecution() {
char *buffer = nullptr;
fifo_->PopAddress(buffer);
LOG(logDEBUG5) << "DataProcessor " << index
<< ", "
"pop 0x"
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
LOG(logDEBUG5) << "DataProcessor " << index << ", " << std::hex
<< static_cast<void *>(buffer) << std::dec << ":" << buffer;
// check dummy
auto numBytes = (uint32_t)(*((uint32_t *)buffer));
auto numBytes = *reinterpret_cast<uint32_t *>(buffer);
LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer);
@ -327,7 +272,7 @@ void DataProcessor::StopProcessing(char *buf) {
uint64_t DataProcessor::ProcessAnImage(char *buf) {
auto *rheader = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
auto *rheader = reinterpret_cast<sls_receiver_header *>(buf + FIFO_HEADER_NUMBYTES);
sls_detector_header header = rheader->detHeader;
uint64_t fnum = header.frameNumber;
currentFrameIndex_ = fnum;
@ -361,16 +306,17 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
try {
// normal call back
if (rawDataReadyCallBack != nullptr) {
rawDataReadyCallBack((char *)rheader,
std::size_t dsize = *reinterpret_cast<uint32_t *>(buf);
rawDataReadyCallBack(rheader,
buf + FIFO_HEADER_NUMBYTES +
sizeof(sls_receiver_header),
(uint32_t)(*((uint32_t *)buf)), pRawDataReady);
dsize, pRawDataReady);
}
// call back with modified size
else if (rawDataModifyReadyCallBack != nullptr) {
auto revsize = (uint32_t)(*((uint32_t *)buf));
rawDataModifyReadyCallBack((char *)rheader,
std::size_t revsize = *reinterpret_cast<uint32_t *>(buf);
rawDataModifyReadyCallBack(rheader,
buf + FIFO_HEADER_NUMBYTES +
sizeof(sls_receiver_header),
revsize, pRawDataReady);
@ -414,14 +360,15 @@ bool DataProcessor::CheckTimer() {
struct timespec end;
clock_gettime(CLOCK_REALTIME, &end);
LOG(logDEBUG1) << index << " Timer elapsed time:"
<< ((end.tv_sec - timerbegin_.tv_sec) +
(end.tv_nsec - timerbegin_.tv_nsec) / 1000000000.0)
auto elapsed_s = (end.tv_sec - timerbegin_.tv_sec) +
(end.tv_nsec - timerbegin_.tv_nsec) / 1e9;
double timer_s = *streamingTimerInMs_ / 1e3;
LOG(logDEBUG1) << index << " Timer elapsed time:" << elapsed_s
<< " seconds";
// still less than streaming timer, keep waiting
if (((end.tv_sec - timerbegin_.tv_sec) +
(end.tv_nsec - timerbegin_.tv_nsec) / 1000000000.0) <
((double)*streamingTimerInMs_ / 1000.00))
if (elapsed_s < timer_s)
return false;
// restart timer
@ -438,15 +385,14 @@ bool DataProcessor::CheckCount() {
return false;
}
void DataProcessor::registerCallBackRawDataReady(void (*func)(char *, char *,
uint32_t, void *),
void *arg) {
void DataProcessor::registerCallBackRawDataReady(
void (*func)(sls_receiver_header *, char *, size_t, void *), void *arg) {
rawDataReadyCallBack = func;
pRawDataReady = arg;
}
void DataProcessor::registerCallBackRawDataModifyReady(
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
void (*func)(sls_receiver_header *, char *, size_t &, void *), void *arg) {
rawDataModifyReadyCallBack = func;
pRawDataReady = arg;
}
@ -455,7 +401,8 @@ void DataProcessor::PadMissingPackets(char *buf) {
LOG(logDEBUG) << index << ": Padding Missing Packets";
uint32_t pperFrame = generalData_->packetsPerFrame;
auto *header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
auto *header =
reinterpret_cast<sls_receiver_header *>(buf + FIFO_HEADER_NUMBYTES);
uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
sls_bitset pmask = header->packetsMask;
@ -528,7 +475,7 @@ void DataProcessor::RearrangeDbitData(char *buf) {
// ceil as numResult8Bits could be decimal
const int numResult8Bits =
ceil((double)(numSamples * (*ctbDbitList_).size()) / 8.00);
ceil((numSamples * (*ctbDbitList_).size()) / 8.00);
std::vector<uint8_t> result(numResult8Bits);
uint8_t *dest = &result[0];
@ -544,7 +491,7 @@ void DataProcessor::RearrangeDbitData(char *buf) {
}
// loop through the frame digital data
for (auto ptr = source; ptr < (source + numSamples);) {
for (auto *ptr = source; ptr < (source + numSamples);) {
// get selected bit from each 8 bit
uint8_t bit = (*ptr++ >> bi) & 1;
*dest |= bit << bitoffset;

View File

@ -45,12 +45,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
void CloseFiles();
void DeleteFiles();
void SetupFileWriter(const bool filewriteEnable,
const bool masterFilewriteEnable,
const fileFormat fileFormatType, const int modulePos,
std::mutex *hdf5Lib);
const fileFormat fileFormatType,
std::mutex *hdf5LibMutex);
void CreateFirstFiles(MasterAttributes *attr, const std::string filePath,
const std::string fileNamePrefix,
void CreateFirstFiles(const std::string &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos,
const int numUnitsPerReadout,
@ -60,40 +59,36 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
const bool detectorDataStream);
#ifdef HDF5C
uint32_t GetFilesInAcquisition() const;
void CreateVirtualFile(const std::string filePath,
const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos,
const int numUnitsPerReadout,
const uint32_t maxFramesPerFile,
const uint64_t numImages,
const uint32_t dynamicRange, const int numModX,
const int numModY, std::mutex *hdf5Lib);
void LinkDataInMasterFile(const bool silentMode);
std::array<std::string, 2> CreateVirtualFile(
const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos,
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
const uint64_t numImages, const int numModX, const int numModY,
const uint32_t dynamicRange, std::mutex *hdf5LibMutex);
void LinkFileInMaster(const std::string &masterFileName,
const std::string &virtualFileName,
const std::string &virtualDatasetName,
const bool silentMode, std::mutex *hdf5LibMutex);
#endif
void UpdateMasterFile(bool silentMode);
/**
* Call back for raw data
* args to raw data ready callback are
* sls_receiver_header frame metadata
* dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes.
*/
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
void *),
std::string CreateMasterFile(const std::string &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable, bool silentMode,
const fileFormat fileFormatType,
MasterAttributes *attr,
std::mutex *hdf5LibMutex);
/** params: sls_receiver_header pointer, pointer to data, image size */
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
char *, size_t, void *),
void *arg);
/**
* Call back for raw data (modified)
* args to raw data ready callback are
* sls_receiver_header frame metadata
* dataPointer is the pointer to the data
* revDatasize is the reference of data size in bytes.
* Can be modified to the new size to be written/streamed. (only smaller
* value).
*/
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *),
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
char *, size_t &,
void *),
void *arg);
private:
@ -160,7 +155,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
uint32_t *streamingTimerInMs_;
uint32_t *streamingStartFnum_;
uint32_t currentFreqCount_{0};
struct timespec timerbegin_;
struct timespec timerbegin_{};
bool *framePadding_;
std::vector<int> *ctbDbitList_;
int *ctbDbitOffset_;
@ -179,10 +174,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
bool firstStreamerFrame_{false};
File *dataFile_{nullptr};
File *masterFile_{nullptr};
#ifdef HDF5C
File *virtualFile_{nullptr};
#endif
// call back
/**
@ -192,7 +183,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes.
*/
void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr;
void (*rawDataReadyCallBack)(sls_receiver_header *, char *, size_t,
void *) = nullptr;
/**
* Call back for raw data (modified)
@ -202,7 +194,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* revDatasize is the reference of data size in bytes. Can be modified to
* the new size to be written/streamed. (only smaller value).
*/
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
void (*rawDataModifyReadyCallBack)(sls_receiver_header *, char *, size_t &,
void *) = nullptr;
void *pRawDataReady{nullptr};

View File

@ -17,12 +17,11 @@
const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi,
bool fr, slsDetectorDefs::xy nm, bool *qe,
bool fr, slsDetectorDefs::xy np, bool *qe,
uint64_t *tot)
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), roi(r),
fileIndex(fi), flipRows(fr), quadEnable(qe), totalNumFrames(tot) {
numMods.x = nm.x;
numMods.y = nm.y;
fileIndex(fi), flipRows(fr), numPorts(np), quadEnable(qe),
totalNumFrames(tot) {
LOG(logDEBUG) << "DataStreamer " << ind << " created";
}
@ -63,10 +62,7 @@ void DataStreamer::RecordFirstIndex(uint64_t fnum, char *buf) {
void DataStreamer::SetGeneralData(GeneralData *g) { generalData = g; }
void DataStreamer::SetNumberofModules(xy nm) {
numMods.x = nm.x;
numMods.y = nm.y;
}
void DataStreamer::SetNumberofPorts(xy np) { numPorts = np; }
void DataStreamer::SetFlipRows(bool fd) { flipRows = fd; }
@ -220,8 +216,8 @@ int DataStreamer::SendHeader(sls_receiver_header *rheader, uint32_t size,
zHeader.dynamicRange = *dynamicRange;
zHeader.fileIndex = *fileIndex;
zHeader.ndetx = numMods.x;
zHeader.ndety = numMods.y;
zHeader.ndetx = numPorts.x;
zHeader.ndety = numPorts.y;
zHeader.npixelsx = nx;
zHeader.npixelsy = ny;
zHeader.imageSize = size;

View File

@ -33,12 +33,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param r roi
* @param fi pointer to file index
* @param fr flip rows
* @param nm number of modules in each dimension
* @param nm number of ports in each dimension
* @param qe pointer to quad Enable
* @param tot pointer to total number of frames
*/
DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi, bool fr,
xy nm, bool *qe, uint64_t *tot);
xy np, bool *qe, uint64_t *tot);
/**
* Destructor
@ -46,39 +46,11 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
*/
~DataStreamer();
/**
* Set Fifo pointer to the one given
* @param f address of Fifo pointer
*/
void SetFifo(Fifo *f);
/**
* Reset parameters for new acquisition
*/
void ResetParametersforNewAcquisition(const std::string &fname);
/**
* Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer
*/
void SetGeneralData(GeneralData *g);
/**
* Set number of detectors
* @param nm number of modules/ports in both dimensions
*/
void SetNumberofModules(xy nm);
/**
* Set Flipped rows
* @param fd flip rows enable
*/
void SetNumberofPorts(xy np);
void SetFlipRows(bool fd);
/**
* Set additional json header
* @param json additional json header
*/
void
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
@ -143,34 +115,16 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
int SendHeader(sls_receiver_header *rheader, uint32_t size = 0,
uint32_t nx = 0, uint32_t ny = 0, bool dummy = true);
/** type of thread */
static const std::string TypeName;
/** GeneralData (Detector Data) object */
const GeneralData *generalData{nullptr};
/** Fifo structure */
Fifo *fifo;
/** ZMQ Socket - Receiver to Client */
ZmqSocket *zmqSocket{nullptr};
/** Pointer to dynamic range */
uint32_t *dynamicRange;
/** ROI */
ROI *roi;
/** adc Configured */
int adcConfigured{-1};
/** Pointer to file index */
uint64_t *fileIndex;
/** flip rows */
bool flipRows;
/** additional json header */
std::map<std::string, std::string> additionalJsonHeader;
/** Used by streamer thread to update local copy (reduce number of locks
@ -189,18 +143,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** Frame Number of First Frame */
uint64_t firstIndex{0};
/* File name to stream */
std::string fileNametoStream;
/** Complete buffer used for roi, eg. shortGotthard */
char *completeBuffer{nullptr};
/** Number of Modules in X and Y dimension */
xy numMods{1, 1};
/** Quad Enable */
xy numPorts{1, 1};
bool *quadEnable;
/** Total number of frames */
uint64_t *totalNumFrames;
};

View File

@ -60,20 +60,6 @@ class File : private virtual slsDetectorDefs {
return std::vector<DataType>{};
};
virtual void CreateVirtualFile(
const std::string filePath, const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos,
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
const uint64_t numImages, const uint32_t nPixelsX,
const uint32_t nPixelsY, const uint32_t dynamicRange,
const uint64_t numImagesCaught, const int numModX, const int numModY,
const DataType dataType, const std::vector<std::string> parameterNames,
const std::vector<DataType> parameterDataTypes) {
LOG(logERROR) << "This is a generic function CreateVirtualFile that "
"should be overloaded by a derived class";
}
virtual void CreateFirstHDF5DataFile(
const std::string filePath, const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
@ -85,13 +71,6 @@ class File : private virtual slsDetectorDefs {
LOG(logERROR) << "This is a generic function CreateFirstDataFile that "
"should be overloaded by a derived class";
};
virtual void LinkDataFile(std::string dataFilename, std::string dataSetname,
const std::vector<std::string> parameterNames,
const bool silentMode) {
LOG(logERROR) << "This is a generic function LinkDataFile that "
"should be overloaded by a derived class";
};
#endif
virtual void CreateFirstBinaryDataFile(
const std::string filePath, const std::string fileNamePrefix,
@ -103,27 +82,9 @@ class File : private virtual slsDetectorDefs {
"should be overloaded by a derived class";
};
virtual void CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr) {
LOG(logERROR) << "This is a generic function CreateMasterFile that "
"should be overloaded by a derived class";
};
virtual void WriteToFile(char *buffer, const int buffersize,
const uint64_t currentFrameNumber,
const uint32_t numPacketsCaught) {
LOG(logERROR) << "This is a generic function WriteToFile that "
"should be overloaded by a derived class";
};
virtual void UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
LOG(logERROR) << "This is a generic function UpdateMasterFile that "
"should be overloaded by a derived class";
};
const uint32_t numPacketsCaught) = 0;
protected:
slsDetectorDefs::fileFormat format_;

View File

@ -62,6 +62,7 @@ class GeneralData {
uint32_t adcEnableMaskOneGiga{BIT32_MASK};
uint32_t adcEnableMaskTenGiga{BIT32_MASK};
slsDetectorDefs::ROI roi{};
uint32_t counterMask{0};
GeneralData(){};
virtual ~GeneralData(){};
@ -122,8 +123,8 @@ class GeneralData {
ThrowGenericError("SetNumberofInterfaces");
};
virtual void SetNumberofCounters(const int n) {
ThrowGenericError("SetNumberofCounters");
virtual void SetCounterMask(const int n) {
ThrowGenericError("setCounterMask");
};
virtual int GetNumberOfAnalogDatabytes() {
@ -359,13 +360,12 @@ class JungfrauData : public GeneralData {
class Mythen3Data : public GeneralData {
private:
int ncounters;
int ncounters{0};
const int NCHAN = 1280;
public:
Mythen3Data() {
myDetectorType = slsDetectorDefs::MYTHEN3;
ncounters = 3;
nPixelsY = 1;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE;
@ -376,6 +376,7 @@ class Mythen3Data : public GeneralData {
defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
dynamicRange = 32;
tengigaEnable = true;
SetCounterMask(0x7);
UpdateImageSize();
};
@ -389,7 +390,13 @@ class Mythen3Data : public GeneralData {
UpdateImageSize();
};
virtual void SetNumberofCounters(const int n) {
virtual void SetCounterMask(const int mask) {
int n = __builtin_popcount(mask);
if (n < 1 || n > 3) {
throw sls::RuntimeError("Invalid number of counters " +
std::to_string(n) + ". Expected 1-3.");
}
counterMask = mask;
ncounters = n;
UpdateImageSize();
};

View File

@ -128,7 +128,7 @@ void HDF5DataFile::CreateFirstHDF5DataFile(
}
void HDF5DataFile::CreateFile() {
numFramesInFile_ = 0;
numFilesInAcquisition_++;
std::ostringstream os;
@ -237,7 +237,7 @@ void HDF5DataFile::WriteToFile(char *buffer, const int buffersize,
++subFileIndex_;
CreateFile();
}
numFramesInFile_++;
++numFramesInFile_;
// extend dataset (when receiver start followed by many status starts
// (jungfrau)))

View File

@ -1,162 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "HDF5MasterFile.h"
#include "MasterAttributes.h"
HDF5MasterFile::HDF5MasterFile(std::mutex *hdf5Lib)
: File(HDF5), hdf5Lib_(hdf5Lib) {}
HDF5MasterFile::~HDF5MasterFile() { CloseFile(); }
void HDF5MasterFile::CloseFile() {
std::lock_guard<std::mutex> lock(*hdf5Lib_);
try {
Exception::dontPrint(); // to handle errors
if (fd_) {
fd_->close();
delete fd_;
fd_ = nullptr;
}
} catch (const Exception &error) {
LOG(logERROR) << "Could not close master HDF5 handles";
error.printErrorStack();
}
}
void HDF5MasterFile::LinkDataFile(std::string dataFilename,
std::string dataSetname,
const std::vector<std::string> parameterNames,
const bool silentMode) {
std::lock_guard<std::mutex> lock(*hdf5Lib_);
try {
Exception::dontPrint(); // to handle errors
FileAccPropList flist;
flist.setFcloseDegree(H5F_CLOSE_STRONG);
// open master file
H5File masterfd(fileName_.c_str(), H5F_ACC_RDWR,
FileCreatPropList::DEFAULT, flist);
// open data file
H5File fd(dataFilename.c_str(), H5F_ACC_RDONLY,
FileCreatPropList::DEFAULT, flist);
// create link for data dataset
DataSet dset = fd.openDataSet(dataSetname.c_str());
std::string linkname = std::string("/entry/data/") + dataSetname;
if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(),
masterfd.getLocId(), linkname.c_str(),
H5P_DEFAULT, H5P_DEFAULT) < 0) {
throw sls::RuntimeError(
"Could not create link to data dataset in master");
}
// create link for parameter datasets
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
DataSet pDset = fd.openDataSet(parameterNames[i].c_str());
linkname = std::string("/entry/data/") + parameterNames[i];
if (H5Lcreate_external(dataFilename.c_str(),
parameterNames[i].c_str(),
masterfd.getLocId(), linkname.c_str(),
H5P_DEFAULT, H5P_DEFAULT) < 0) {
throw sls::RuntimeError(
"Could not create link to parameter dataset in master");
}
}
fd.close();
masterfd.close();
} catch (const Exception &error) {
error.printErrorStack();
CloseFile();
throw sls::RuntimeError("Could not link in master hdf5 file");
}
if (!silentMode) {
LOG(logINFO) << "Linked in Master File: " << dataFilename;
}
}
void HDF5MasterFile::CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr) {
std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_master"
<< "_" << fileIndex << ".h5";
fileName_ = os.str();
std::lock_guard<std::mutex> lock(*hdf5Lib_);
try {
Exception::dontPrint(); // to handle errors
FileAccPropList flist;
flist.setFcloseDegree(H5F_CLOSE_STRONG);
fd_ = nullptr;
if (!(overWriteEnable))
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL,
FileCreatPropList::DEFAULT, flist);
else
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC,
FileCreatPropList::DEFAULT, flist);
// attributes - version
double dValue = HDF5_WRITER_VERSION;
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
Attribute attribute = fd_->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
// Create a group in the file
Group group1(fd_->createGroup("entry"));
Group group2(group1.createGroup("data"));
Group group3(group1.createGroup("instrument"));
Group group4(group3.createGroup("beam"));
Group group5(group3.createGroup("detector"));
Group group6(group1.createGroup("sample"));
// TODO find a way to get complete group link
attrGroupName_ = "/entry/instrument/detector";
attr->WriteMasterHDF5Attributes(fd_, &group5);
fd_->close();
} catch (const Exception &error) {
error.printErrorStack();
CloseFile();
throw sls::RuntimeError(
"Could not create/overwrite master HDF5 handles");
}
if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName_;
}
}
void HDF5MasterFile::UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
std::lock_guard<std::mutex> lock(*hdf5Lib_);
try {
Exception::dontPrint(); // to handle errors
FileAccPropList flist;
flist.setFcloseDegree(H5F_CLOSE_STRONG);
fd_ = new H5File(fileName_.c_str(), H5F_ACC_RDWR,
FileCreatPropList::DEFAULT, flist);
Group group = fd_->openGroup(attrGroupName_.c_str());
attr->WriteFinalHDF5Attributes(fd_, &group);
fd_->close();
} catch (const Exception &error) {
error.printErrorStack();
CloseFile();
throw sls::RuntimeError(
"Could not create/overwrite master HDF5 handles");
}
if (!silentMode) {
LOG(logINFO) << "Updated Master File";
}
}

View File

@ -1,31 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "File.h"
#include <mutex>
class HDF5MasterFile : private virtual slsDetectorDefs, public File {
public:
HDF5MasterFile(std::mutex *hdf5Lib);
~HDF5MasterFile();
void CloseFile() override;
void LinkDataFile(std::string dataFilename, std::string dataSetname,
const std::vector<std::string> parameterNames,
const bool silentMode) override;
void CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr) override;
void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override;
private:
std::mutex *hdf5Lib_;
H5File *fd_{nullptr};
std::string fileName_;
std::string attrGroupName_;
};

View File

@ -1,211 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "HDF5VirtualFile.h"
#include "receiver_defs.h"
#include <iomanip>
HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5Lib, bool g25)
: File(HDF5), hdf5Lib_(hdf5Lib), gotthard25um(g25) {}
HDF5VirtualFile::~HDF5VirtualFile() { CloseFile(); }
std::array<std::string, 2> HDF5VirtualFile::GetFileAndDatasetName() const {
return std::array<std::string, 2>{fileName_, dataSetName_};
}
void HDF5VirtualFile::CloseFile() {
std::lock_guard<std::mutex> lock(*hdf5Lib_);
try {
Exception::dontPrint(); // to handle errors
if (fd_) {
fd_->close();
delete fd_;
fd_ = nullptr;
}
} catch (const Exception &error) {
LOG(logERROR) << "Could not close virtual HDF5 handles of index";
error.printErrorStack();
}
}
void HDF5VirtualFile::CreateVirtualFile(
const std::string filePath, const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint64_t numImages,
const uint32_t nPixelsX, const uint32_t nPixelsY,
const uint32_t dynamicRange, const uint64_t numImagesCaught,
const int numModX, const int numModY, const DataType dataType,
const std::vector<std::string> parameterNames,
const std::vector<DataType> parameterDataTypes) {
// virtual file name
std::ostringstream osfn;
osfn << filePath << "/" << fileNamePrefix << "_virtual"
<< "_" << fileIndex << ".h5";
fileName_ = osfn.str();
unsigned int paraSize = parameterNames.size();
uint64_t numModZ = numModX;
uint32_t nDimy = nPixelsY;
uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
std::lock_guard<std::mutex> lock(*hdf5Lib_);
try {
Exception::dontPrint(); // to handle errors
// file
FileAccPropList fapl;
fapl.setFcloseDegree(H5F_CLOSE_STRONG);
fd_ = nullptr;
if (!overWriteEnable)
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL,
FileCreatPropList::DEFAULT, fapl);
else
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC,
FileCreatPropList::DEFAULT, fapl);
// attributes - version
double dValue = HDF5_WRITER_VERSION;
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
Attribute attribute = fd_->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
// virtual dataspace
hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy,
numModZ * nDimz};
DataSpace vdsDataSpace(3, vdsDims, nullptr);
hsize_t vdsDimsPara[2] = {numImagesCaught,
(unsigned int)numModY * numModZ};
DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr);
// property list (fill value and datatype)
int fill_value = -1;
DSetCreatPropList plist;
plist.setFillValue(dataType, &fill_value);
// property list for parameters (datatype)
std::vector<DSetCreatPropList> plistPara(paraSize);
// hyperslab (files)
int numFiles = numImagesCaught / maxFramesPerFile;
if (numImagesCaught % maxFramesPerFile)
++numFiles;
uint64_t framesSaved = 0;
for (int iFile = 0; iFile < numFiles; ++iFile) {
uint64_t nDimx =
((numImagesCaught - framesSaved) > maxFramesPerFile)
? maxFramesPerFile
: (numImagesCaught - framesSaved);
hsize_t startLocation[3] = {framesSaved, 0, 0};
hsize_t strideBetweenBlocks[3] = {1, 1, 1};
hsize_t numBlocks[3] = {nDimx, nDimy, nDimz};
hsize_t blockSize[3] = {1, 1, 1};
hsize_t startLocationPara[2] = {framesSaved, 0};
hsize_t strideBetweenBlocksPara[3] = {1, 1};
hsize_t numBlocksPara[2] = {1, 1};
hsize_t blockSizePara[3] = {nDimx, 1};
// interleaving for g2
if (gotthard25um) {
strideBetweenBlocks[2] = 2;
}
for (unsigned int iReadout = 0; iReadout < numModY * numModZ;
++iReadout) {
// interleaving for g2 (startLocation is 0 and 1)
if (gotthard25um) {
startLocation[2] = iReadout;
}
vdsDataSpace.selectHyperslab(H5S_SELECT_SET, numBlocks,
startLocation, strideBetweenBlocks,
blockSize);
vdsDataSpacePara.selectHyperslab(
H5S_SELECT_SET, numBlocksPara, startLocationPara,
strideBetweenBlocksPara, blockSizePara);
// source file name
std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_d"
<< (modulePos * numUnitsPerReadout + iReadout) << "_f"
<< iFile << '_' << fileIndex << ".h5";
std::string srcFileName = os.str();
LOG(logDEBUG1) << srcFileName;
// find relative path
std::string relative_srcFileName = srcFileName;
{
size_t p = srcFileName.rfind('/', srcFileName.length());
if (p != std::string::npos)
relative_srcFileName = (srcFileName.substr(
p + 1, srcFileName.length() - p));
}
// source dataset name
std::ostringstream osfn;
osfn << "/data";
if (numImages > 1)
osfn << "_f" << std::setfill('0') << std::setw(12) << iFile;
std::string srcDatasetName = osfn.str();
// source dataspace
hsize_t srcDims[3] = {nDimx, nDimy, nDimz};
hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz};
DataSpace srcDataSpace(3, srcDims, srcDimsMax);
hsize_t srcDimsPara[1] = {nDimx};
hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED};
DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara);
// mapping of property list
plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(),
srcDatasetName.c_str(), srcDataSpace);
for (unsigned int p = 0; p < paraSize; ++p) {
plistPara[p].setVirtual(
vdsDataSpacePara, relative_srcFileName.c_str(),
parameterNames[p].c_str(), srcDataSpacePara);
}
// H5Sclose(srcDataspace);
// H5Sclose(srcDataspace_para);
if (!gotthard25um) {
startLocation[2] += nDimz;
if (startLocation[2] >= (numModZ * nDimz)) {
startLocation[2] = 0;
startLocation[1] += nDimy;
}
}
startLocationPara[1]++;
}
framesSaved += nDimx;
}
// datasets
dataSetName_ = "data";
DataSet vdsDataSet(fd_->createDataSet(dataSetName_.c_str(), dataType,
vdsDataSpace, plist));
for (unsigned int p = 0; p < paraSize; ++p) {
DataSet vdsDataSetPara(fd_->createDataSet(
parameterNames[p].c_str(), parameterDataTypes[p],
vdsDataSpacePara, plistPara[p]));
}
fd_->close();
} catch (const Exception &error) {
error.printErrorStack();
CloseFile();
throw sls::RuntimeError(
"Could not create/overwrite virtual HDF5 handles");
}
if (!silentMode) {
LOG(logINFO) << "Virtual File: " << fileName_;
}
}

View File

@ -1,34 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "File.h"
#include <mutex>
class HDF5VirtualFile : private virtual slsDetectorDefs, public File {
public:
HDF5VirtualFile(std::mutex *hdf5Lib, bool g25);
~HDF5VirtualFile();
std::array<std::string, 2> GetFileAndDatasetName() const override;
void CloseFile() override;
void CreateVirtualFile(
const std::string filePath, const std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos,
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
const uint64_t numImages, const uint32_t nPixelsX,
const uint32_t nPixelsY, const uint32_t dynamicRange,
const uint64_t numImagesCaught, const int numModX, const int numModY,
const DataType dataType, const std::vector<std::string> parameterNames,
const std::vector<DataType> parameterDataTypes) override;
private:
std::mutex *hdf5Lib_;
H5File *fd_{nullptr};
std::string fileName_;
std::string dataSetName_;
bool gotthard25um;
};

View File

@ -153,10 +153,20 @@ void Implementation::setDetectorType(const detectorType d) {
default:
break;
}
numUDPInterfaces = generalData->numUDPInterfaces;
fifoDepth = generalData->defaultFifoDepth;
udpSocketBufferSize = generalData->defaultUdpSocketBufferSize;
framesPerFile = generalData->maxFramesPerFile;
fifoDepth = generalData->defaultFifoDepth;
numUDPInterfaces = generalData->numUDPInterfaces;
udpSocketBufferSize = generalData->defaultUdpSocketBufferSize;
dynamicRange = generalData->dynamicRange;
tengigaEnable = generalData->tengigaEnable;
numberOfAnalogSamples = generalData->nAnalogSamples;
numberOfDigitalSamples = generalData->nDigitalSamples;
readoutType = generalData->readoutType;
adcEnableMaskOneGiga = generalData->adcEnableMaskOneGiga;
adcEnableMaskTenGiga = generalData->adcEnableMaskTenGiga;
roi = generalData->roi;
counterMask = generalData->counterMask;
SetLocalNetworkParameters();
SetupFifoStructure();
@ -207,7 +217,7 @@ slsDetectorDefs::xy Implementation::GetPortGeometry() {
xy portGeometry{1, 1};
if (detType == EIGER)
portGeometry.x = numUDPInterfaces;
else // (jungfrau and gotthard2)
else if (detType == JUNGFRAU)
portGeometry.y = numUDPInterfaces;
return portGeometry;
}
@ -216,18 +226,18 @@ void Implementation::setDetectorSize(const slsDetectorDefs::xy size) {
xy portGeometry = GetPortGeometry();
std::string log_message = "Detector Size (ports): (";
numModules.x = portGeometry.x * size.x;
numModules.y = portGeometry.y * size.y;
xy nm{numModules.x, numModules.y};
numModules = size;
numPorts.x = portGeometry.x * size.x;
numPorts.y = portGeometry.y * size.y;
if (quadEnable) {
nm.x = 1;
nm.y = 2;
numPorts.x = 1;
numPorts.y = 2;
}
for (const auto &it : dataStreamer) {
it->SetNumberofModules(nm);
it->SetNumberofPorts(numPorts);
}
LOG(logINFO) << "Detector Size (ports): " << sls::ToString(numModules);
LOG(logINFO) << "Detector Size (ports): " << sls::ToString(numPorts);
}
int Implementation::getModulePositionId() const { return modulePos; }
@ -240,15 +250,20 @@ void Implementation::setModulePositionId(const int id) {
xy portGeometry = GetPortGeometry();
streamingPort = DEFAULT_ZMQ_RX_PORTNO + modulePos * portGeometry.x;
for (const auto &it : dataProcessor)
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
fileFormatType, modulePos, &hdf5Lib);
assert(numModules.y != 0);
for (unsigned int i = 0; i < listener.size(); ++i) {
uint16_t row = 0, col = 0;
row = (modulePos % numModules.y) * portGeometry.y;
col = (modulePos / numModules.y) * portGeometry.x + i;
col = (modulePos / numModules.y) * portGeometry.x;
if (portGeometry.y == 2) {
row += i;
}
if (portGeometry.x == 2) {
col += i;
}
LOG(logDEBUG1) << i << ":numModules:" << numModules.x << ","
<< numModules.y << " portGeometry:" << portGeometry.x
<< "," << portGeometry.y;
listener[i]->SetHardCodedPosition(row, col);
}
}
@ -372,8 +387,7 @@ void Implementation::setFileFormat(const fileFormat f) {
throw sls::RuntimeError("Unknown file format");
}
for (const auto &it : dataProcessor)
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
fileFormatType, modulePos, &hdf5Lib);
it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5LibMutex);
}
LOG(logINFO) << "File Format: " << sls::ToString(fileFormatType);
@ -409,8 +423,7 @@ void Implementation::setFileWriteEnable(const bool b) {
if (fileWriteEnable != b) {
fileWriteEnable = b;
for (const auto &it : dataProcessor)
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
fileFormatType, modulePos, &hdf5Lib);
it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5LibMutex);
}
LOG(logINFO) << "File Write Enable: "
<< (fileWriteEnable ? "enabled" : "disabled");
@ -423,9 +436,6 @@ bool Implementation::getMasterFileWriteEnable() const {
void Implementation::setMasterFileWriteEnable(const bool b) {
if (masterFileWriteEnable != b) {
masterFileWriteEnable = b;
for (const auto &it : dataProcessor)
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
fileFormatType, modulePos, &hdf5Lib);
}
LOG(logINFO) << "Master File Write Enable: "
<< (masterFileWriteEnable ? "enabled" : "disabled");
@ -531,9 +541,9 @@ void Implementation::startReceiver() {
// callbacks
if (startAcquisitionCallBack) {
try {
startAcquisitionCallBack(filePath, fileName, fileIndex,
(generalData->imageSize) +
(generalData->fifoBufferHeaderSize),
std::size_t imageSize =
static_cast<uint32_t>(generalData->imageSize);
startAcquisitionCallBack(filePath, fileName, fileIndex, imageSize,
pStartAcquisition);
} catch (const std::exception &e) {
throw sls::RuntimeError("Start Acquisition Callback Error: " +
@ -584,29 +594,9 @@ void Implementation::stopReceiver() {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
#ifdef HDF5C
if (fileWriteEnable && fileFormatType == HDF5) {
if (modulePos == 0) {
// more than 1 file, create virtual file
if (dataProcessor[0]->GetFilesInAcquisition() > 1 ||
(numModules.x * numModules.y) > 1) {
dataProcessor[0]->CreateVirtualFile(
filePath, fileName, fileIndex, overwriteEnable, silentMode,
modulePos, numUDPInterfaces, framesPerFile,
numberOfTotalFrames, dynamicRange, numModules.x,
numModules.y, &hdf5Lib);
}
// link file in master
dataProcessor[0]->LinkDataInMasterFile(silentMode);
}
}
#endif
if (fileWriteEnable && masterFileWriteEnable && modulePos == 0) {
try {
dataProcessor[0]->UpdateMasterFile(silentMode);
} catch (...) {
; // ignore it and just print it
}
if (fileWriteEnable && modulePos == 0) {
// master and virtual file (hdf5)
StartMasterWriter();
}
// wait for the processes (dataStreamer) to be done
@ -753,100 +743,12 @@ void Implementation::CreateUDPSockets() {
}
void Implementation::SetupWriter() {
// master file
std::unique_ptr<MasterAttributes> masterAttributes;
if (masterFileWriteEnable && modulePos == 0) {
switch (detType) {
case GOTTHARD:
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
break;
case JUNGFRAU:
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
break;
case EIGER:
masterAttributes = sls::make_unique<EigerMasterAttributes>();
break;
case MYTHEN3:
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
break;
case GOTTHARD2:
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
break;
case MOENCH:
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
break;
case CHIPTESTBOARD:
masterAttributes = sls::make_unique<CtbMasterAttributes>();
break;
default:
throw sls::RuntimeError(
"Unknown detector type to set up master file attributes");
}
masterAttributes->detType = detType;
masterAttributes->timingMode = timingMode;
xy nm{numModules.x, numModules.y};
if (quadEnable) {
nm.x = 1;
nm.y = 2;
}
masterAttributes->geometry = xy(nm.x, nm.y);
masterAttributes->imageSize = generalData->imageSize;
masterAttributes->nPixels =
xy(generalData->nPixelsX, generalData->nPixelsY);
masterAttributes->maxFramesPerFile = framesPerFile;
masterAttributes->frameDiscardMode = frameDiscardMode;
masterAttributes->framePadding = framePadding;
masterAttributes->scanParams = scanParams;
masterAttributes->totalFrames = numberOfTotalFrames;
masterAttributes->exptime = acquisitionTime;
masterAttributes->period = acquisitionPeriod;
masterAttributes->burstMode = burstMode;
masterAttributes->numUDPInterfaces = numUDPInterfaces;
masterAttributes->dynamicRange = dynamicRange;
masterAttributes->tenGiga = tengigaEnable;
masterAttributes->thresholdEnergyeV = thresholdEnergyeV;
masterAttributes->thresholdAllEnergyeV = thresholdAllEnergyeV;
masterAttributes->subExptime = subExpTime;
masterAttributes->subPeriod = subPeriod;
masterAttributes->quad = quadEnable;
masterAttributes->readNRows = readNRows;
masterAttributes->ratecorr = rateCorrections;
masterAttributes->adcmask =
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
masterAttributes->analog =
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL)
? 1
: 0;
masterAttributes->analogSamples = numberOfAnalogSamples;
masterAttributes->digital =
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL)
? 1
: 0;
masterAttributes->digitalSamples = numberOfDigitalSamples;
masterAttributes->dbitoffset = ctbDbitOffset;
masterAttributes->dbitlist = 0;
for (auto &i : ctbDbitList) {
masterAttributes->dbitlist |= (1 << i);
}
masterAttributes->roi = roi;
masterAttributes->counterMask = counterMask;
masterAttributes->exptime1 = acquisitionTime1;
masterAttributes->exptime2 = acquisitionTime2;
masterAttributes->exptime3 = acquisitionTime3;
masterAttributes->gateDelay1 = gateDelay1;
masterAttributes->gateDelay2 = gateDelay2;
masterAttributes->gateDelay3 = gateDelay3;
masterAttributes->gates = numberOfGates;
masterAttributes->additionalJsonHeader = additionalJsonHeader;
}
try {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->CreateFirstFiles(
masterAttributes.get(), filePath, fileName, fileIndex,
overwriteEnable, silentMode, modulePos, numUDPInterfaces,
udpPortNum[i], framesPerFile, numberOfTotalFrames, dynamicRange,
detectorDataStream[i]);
filePath, fileName, fileIndex, overwriteEnable, silentMode,
modulePos, numUDPInterfaces, udpPortNum[i], framesPerFile,
numberOfTotalFrames, dynamicRange, detectorDataStream[i]);
}
} catch (const sls::RuntimeError &e) {
shutDownUDPSockets();
@ -856,6 +758,95 @@ void Implementation::SetupWriter() {
}
}
void Implementation::StartMasterWriter() {
try {
std::string masterFileName;
// master file
if (masterFileWriteEnable) {
MasterAttributes masterAttributes;
masterAttributes.detType = detType;
masterAttributes.timingMode = timingMode;
masterAttributes.geometry = numPorts;
masterAttributes.imageSize = generalData->imageSize;
masterAttributes.nPixels =
xy(generalData->nPixelsX, generalData->nPixelsY);
masterAttributes.maxFramesPerFile = framesPerFile;
masterAttributes.frameDiscardMode = frameDiscardMode;
masterAttributes.framePadding = framePadding;
masterAttributes.scanParams = scanParams;
masterAttributes.totalFrames = numberOfTotalFrames;
masterAttributes.exptime = acquisitionTime;
masterAttributes.period = acquisitionPeriod;
masterAttributes.burstMode = burstMode;
masterAttributes.numUDPInterfaces = numUDPInterfaces;
masterAttributes.dynamicRange = dynamicRange;
masterAttributes.tenGiga = tengigaEnable;
masterAttributes.thresholdEnergyeV = thresholdEnergyeV;
masterAttributes.thresholdAllEnergyeV = thresholdAllEnergyeV;
masterAttributes.subExptime = subExpTime;
masterAttributes.subPeriod = subPeriod;
masterAttributes.quad = quadEnable;
masterAttributes.readNRows = readNRows;
masterAttributes.ratecorr = rateCorrections;
masterAttributes.adcmask =
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
masterAttributes.analog = (readoutType == ANALOG_ONLY ||
readoutType == ANALOG_AND_DIGITAL)
? 1
: 0;
masterAttributes.analogSamples = numberOfAnalogSamples;
masterAttributes.digital = (readoutType == DIGITAL_ONLY ||
readoutType == ANALOG_AND_DIGITAL)
? 1
: 0;
masterAttributes.digitalSamples = numberOfDigitalSamples;
masterAttributes.dbitoffset = ctbDbitOffset;
masterAttributes.dbitlist = 0;
for (auto &i : ctbDbitList) {
masterAttributes.dbitlist |= (1 << i);
}
masterAttributes.roi = roi;
masterAttributes.counterMask = counterMask;
masterAttributes.exptimeArray[0] = acquisitionTime1;
masterAttributes.exptimeArray[1] = acquisitionTime2;
masterAttributes.exptimeArray[2] = acquisitionTime3;
masterAttributes.gateDelayArray[0] = gateDelay1;
masterAttributes.gateDelayArray[1] = gateDelay2;
masterAttributes.gateDelayArray[2] = gateDelay3;
masterAttributes.gates = numberOfGates;
masterAttributes.additionalJsonHeader = additionalJsonHeader;
// create master file
masterFileName = dataProcessor[0]->CreateMasterFile(
filePath, fileName, fileIndex, overwriteEnable, silentMode,
fileFormatType, &masterAttributes, &hdf5LibMutex);
}
#ifdef HDF5C
if (fileFormatType == HDF5) {
std::array<std::string, 2> virtualFileAndDatasetNames;
// create virtual hdf5 file (if multiple files)
if (dataProcessor[0]->GetFilesInAcquisition() > 1 ||
(numPorts.x * numPorts.y) > 1) {
virtualFileAndDatasetNames =
dataProcessor[0]->CreateVirtualFile(
filePath, fileName, fileIndex, overwriteEnable,
silentMode, modulePos, numUDPInterfaces, framesPerFile,
numberOfTotalFrames, numPorts.x, numPorts.y,
dynamicRange, &hdf5LibMutex);
}
// link file in master
if (masterFileWriteEnable) {
dataProcessor[0]->LinkFileInMaster(
masterFileName, virtualFileAndDatasetNames[0],
virtualFileAndDatasetNames[1], silentMode, &hdf5LibMutex);
}
}
#endif
} catch (...) {
; // ignore it and just print it
}
}
void Implementation::StartRunning() {
// set running mask and post semaphore to start the inner loop in execution
@ -891,12 +882,6 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
}
if (numUDPInterfaces != n) {
// reduce number of detectors to size with 1 interface
xy portGeometry = GetPortGeometry();
numModules.x /= portGeometry.x;
numModules.y /= portGeometry.y;
// clear all threads and fifos
listener.clear();
dataProcessor.clear();
@ -945,15 +930,12 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
if (dataStreamEnable) {
try {
bool flip = flipRows;
xy nm{numModules.x, numModules.y};
if (quadEnable) {
flip = (i == 1 ? true : false);
nm.x = 1;
nm.y = 2;
}
dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, flip,
nm, &quadEnable, &numberOfTotalFrames));
numPorts, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(
&numUDPInterfaces, streamingPort, streamingSrcIP,
@ -1075,15 +1057,12 @@ void Implementation::setDataStreamEnable(const bool enable) {
for (int i = 0; i < numUDPInterfaces; ++i) {
try {
bool flip = flipRows;
xy nm{numModules.x, numModules.y};
if (quadEnable) {
flip = (i == 1 ? true : false);
nm.x = 1;
nm.y = 2;
}
dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, flip,
nm, &quadEnable, &numberOfTotalFrames));
numPorts, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(
&numUDPInterfaces, streamingPort, streamingSrcIP,
@ -1417,14 +1396,8 @@ uint32_t Implementation::getCounterMask() const { return counterMask; }
void Implementation::setCounterMask(const uint32_t i) {
if (counterMask != i) {
int ncounters = __builtin_popcount(i);
if (ncounters < 1 || ncounters > 3) {
throw sls::RuntimeError("Invalid number of counters " +
std::to_string(ncounters) +
". Expected 1-3.");
}
generalData->SetCounterMask(i);
counterMask = i;
generalData->SetNumberofCounters(ncounters);
SetupFifoStructure();
}
LOG(logINFO) << "Counter mask: " << sls::ToStringHex(counterMask);
@ -1517,18 +1490,12 @@ bool Implementation::getQuad() const { return quadEnable; }
void Implementation::setQuad(const bool b) {
if (quadEnable != b) {
quadEnable = b;
setDetectorSize(numModules);
if (!quadEnable) {
xy nm{numModules.x, numModules.y};
for (const auto &it : dataStreamer) {
it->SetNumberofModules(nm);
it->SetFlipRows(flipRows);
}
} else {
xy nm{1, 2};
for (const auto &it : dataStreamer) {
it->SetNumberofModules(nm);
}
if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlipRows(false);
dataStreamer[1]->SetFlipRows(true);
@ -1649,7 +1616,8 @@ void Implementation::setDbitOffset(const int s) { ctbDbitOffset = s; }
* *
* ************************************************/
void Implementation::registerCallBackStartAcquisition(
int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
int (*func)(const std::string &, const std::string &, uint64_t, size_t,
void *),
void *arg) {
startAcquisitionCallBack = func;
pStartAcquisition = arg;
@ -1663,7 +1631,7 @@ void Implementation::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
}
void Implementation::registerCallBackRawDataReady(
void (*func)(char *, char *, uint32_t, void *), void *arg) {
void (*func)(sls_receiver_header *, char *, size_t, void *), void *arg) {
rawDataReadyCallBack = func;
pRawDataReady = arg;
for (const auto &it : dataProcessor)
@ -1671,7 +1639,7 @@ void Implementation::registerCallBackRawDataReady(
}
void Implementation::registerCallBackRawDataModifyReady(
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
void (*func)(sls_receiver_header *, char *, size_t &, void *), void *arg) {
rawDataModifyReadyCallBack = func;
pRawDataReady = arg;
for (const auto &it : dataProcessor)

View File

@ -252,17 +252,21 @@ class Implementation : private virtual slsDetectorDefs {
* Callbacks *
* *
* ************************************************/
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
uint64_t, uint32_t,
void *),
/** params: file path, file name, file index, image size */
void registerCallBackStartAcquisition(int (*func)(const std::string &, const std::string &,
uint64_t, size_t, void *),
void *arg);
/** params: total frames caught */
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
void *arg);
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
void *),
/** params: sls_receiver_header pointer, pointer to data, image size */
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
char *, size_t, void *),
void *arg);
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *),
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
char *, size_t &,
void *),
void *arg);
private:
@ -274,6 +278,7 @@ class Implementation : private virtual slsDetectorDefs {
void ResetParametersforNewAcquisition();
void CreateUDPSockets();
void SetupWriter();
void StartMasterWriter();
void StartRunning();
/**************************************************
@ -285,6 +290,7 @@ class Implementation : private virtual slsDetectorDefs {
// config parameters
detectorType detType{GENERIC};
xy numModules{1, 1};
xy numPorts{1, 1};
int modulePos{0};
std::string detHostname;
bool silentMode{false};
@ -368,13 +374,14 @@ class Implementation : private virtual slsDetectorDefs {
int ctbDbitOffset{0};
// callbacks
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
uint32_t, void *){nullptr};
int (*startAcquisitionCallBack)(const std::string &, const std::string &, uint64_t, size_t,
void *){nullptr};
void *pStartAcquisition{nullptr};
void (*acquisitionFinishedCallBack)(uint64_t, void *){nullptr};
void *pAcquisitionFinished{nullptr};
void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *){nullptr};
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
void (*rawDataReadyCallBack)(sls_receiver_header *, char *, size_t,
void *){nullptr};
void (*rawDataModifyReadyCallBack)(sls_receiver_header *, char *, size_t &,
void *){nullptr};
void *pRawDataReady{nullptr};
@ -386,5 +393,6 @@ class Implementation : private virtual slsDetectorDefs {
std::vector<std::unique_ptr<Fifo>> fifo;
Arping arping;
std::mutex hdf5Lib;
// mutex shared across all hdf5 virtual, master and data files
std::mutex hdf5LibMutex;
};

View File

@ -210,6 +210,8 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int s) {
void Listener::SetHardCodedPosition(uint16_t r, uint16_t c) {
row = r;
column = c;
LOG(logDEBUG1) << "Setting hardcoded position [" << index
<< "] (row: " << row << ", col: " << column << ")";
}
void Listener::ThreadExecution() {

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,9 @@
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
#include <rapidjson/stringbuffer.h>
#include <rapidjson/prettywriter.h>
#ifdef HDF5C
#include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE
@ -53,94 +56,92 @@ class MasterAttributes {
uint64_t dbitlist{0};
slsDetectorDefs::ROI roi{};
uint32_t counterMask{0};
ns exptime1{0};
ns exptime2{0};
ns exptime3{0};
ns gateDelay1{0};
ns gateDelay2{0};
ns gateDelay3{0};
std::array<ns, 3> exptimeArray{};
std::array<ns, 3> gateDelayArray{};
uint32_t gates;
std::map<std::string, std::string> additionalJsonHeader;
// Final Attributes (after acquisition)
uint64_t framesInFile{0};
MasterAttributes() = default;
virtual ~MasterAttributes() = default;
virtual void WriteMasterBinaryAttributes(FILE *fd);
std::string GetBinaryMasterAttributes();
void WriteBinaryAttributes(FILE *fd, std::string message);
void WriteFinalBinaryAttributes(FILE *fd);
~MasterAttributes() = default;
void GetBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
virtual void WriteMasterHDF5Attributes(H5File *fd, Group *group);
void WriteHDF5Attributes(H5File *fd, Group *group);
#endif
void
GetCommonBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void
GetFinalBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteCommonHDF5Attributes(H5File *fd, Group *group);
void WriteFinalHDF5Attributes(H5File *fd, Group *group);
void WriteHDF5Exptime(H5File *fd, Group *group);
void WriteHDF5Period(H5File *fd, Group *group);
void WriteHDF5DynamicRange(H5File *fd, Group *group);
void WriteHDF5TenGiga(H5File *fd, Group *group);
void WriteHDF5ROI(H5File *fd, Group *group);
void WriteHDF5NumUDPInterfaces(H5File *fd, Group *group);
void WriteHDF5ReadNRows(H5File *fd, Group *group);
void WriteHDF5ThresholdEnergy(H5File *fd, Group *group);
void WriteHDF5ThresholdEnergies(H5File *fd, Group *group);
void WriteHDF5SubExpTime(H5File *fd, Group *group);
void WriteHDF5SubPeriod(H5File *fd, Group *group);
void WriteHDF5SubQuad(H5File *fd, Group *group);
void WriteHDF5RateCorrections(H5File *fd, Group *group);
void WriteHDF5CounterMask(H5File *fd, Group *group);
void WriteHDF5ExptimeArray(H5File *fd, Group *group);
void WriteHDF5GateDelayArray(H5File *fd, Group *group);
void WriteHDF5Gates(H5File *fd, Group *group);
void WriteHDF5BurstMode(H5File *fd, Group *group);
void WriteHDF5AdcMask(H5File *fd, Group *group);
void WriteHDF5AnalogFlag(H5File *fd, Group *group);
void WriteHDF5AnalogSamples(H5File *fd, Group *group);
void WriteHDF5DigitalFlag(H5File *fd, Group *group);
void WriteHDF5DigitalSamples(H5File *fd, Group *group);
void WriteHDF5DbitOffset(H5File *fd, Group *group);
void WriteHDF5DbitList(H5File *fd, Group *group);
#endif
};
class GotthardMasterAttributes : public MasterAttributes {
public:
GotthardMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void
GetGotthardBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteGotthardHDF5Attributes(H5File *fd, Group *group);
#endif
};
class JungfrauMasterAttributes : public MasterAttributes {
public:
JungfrauMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void
GetJungfrauBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteJungfrauHDF5Attributes(H5File *fd, Group *group);
#endif
};
class EigerMasterAttributes : public MasterAttributes {
public:
EigerMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void
GetEigerBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteEigerHDF5Attributes(H5File *fd, Group *group);
#endif
};
class Mythen3MasterAttributes : public MasterAttributes {
public:
Mythen3MasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void
GetMythen3BinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteMythen3HDF5Attributes(H5File *fd, Group *group);
#endif
};
class Gotthard2MasterAttributes : public MasterAttributes {
public:
Gotthard2MasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void
GetGotthard2BinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteGotthard2HDF5Attributes(H5File *fd, Group *group);
#endif
};
class MoenchMasterAttributes : public MasterAttributes {
public:
MoenchMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void
GetMoenchBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteMoenchHDF5Attributes(H5File *fd, Group *group);
#endif
};
class CtbMasterAttributes : public MasterAttributes {
public:
CtbMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override;
void GetCtbBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
void WriteCtbHDF5Attributes(H5File *fd, Group *group);
#endif
};

View File

@ -0,0 +1,351 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "MasterFileUtility.h"
#include "sls/container_utils.h"
#include <iomanip>
namespace masterFileUtility {
std::string CreateMasterBinaryFile(const std::string &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr) {
std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_master"
<< "_" << fileIndex << ".json";
std::string fileName = os.str();
std::string mode = "w";
if (!overWriteEnable)
mode = "wx";
FILE *fd = fopen(fileName.c_str(), mode.c_str());
if(!fd) {
throw sls::RuntimeError("Could not create/overwrite binary master file " +
fileName);
}
rapidjson::StringBuffer s;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(s);
attr->GetBinaryAttributes(&writer);
if (fwrite(s.GetString(), 1, strlen(s.GetString()), fd) !=
strlen(s.GetString())) {
throw sls::RuntimeError(
"Master binary file incorrect number of bytes written to file");
}
if (fd) {
fclose(fd);
}
if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName;
}
return fileName;
}
#ifdef HDF5C
void LinkHDF5FileInMaster(const std::string &masterFileName,
const std::string &dataFilename,
const std::string &dataSetname,
const std::vector<std::string> parameterNames,
const bool silentMode, std::mutex *hdf5LibMutex) {
std::lock_guard<std::mutex> lock(*hdf5LibMutex);
std::unique_ptr<H5File> fd{nullptr};
try {
Exception::dontPrint(); // to handle errors
FileAccPropList flist;
flist.setFcloseDegree(H5F_CLOSE_STRONG);
// open master file
H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR,
FileCreatPropList::DEFAULT, flist);
// open data file
fd = sls::make_unique<H5File>(dataFilename.c_str(), H5F_ACC_RDONLY,
FileCreatPropList::DEFAULT, flist);
// create link for data dataset
DataSet dset = fd->openDataSet(dataSetname.c_str());
std::string linkname = std::string("/entry/data/") + dataSetname;
if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(),
masterfd.getLocId(), linkname.c_str(),
H5P_DEFAULT, H5P_DEFAULT) < 0) {
throw sls::RuntimeError(
"Could not create link to data dataset in master");
}
// create link for parameter datasets
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
DataSet pDset = fd->openDataSet(parameterNames[i].c_str());
linkname = std::string("/entry/data/") + parameterNames[i];
if (H5Lcreate_external(dataFilename.c_str(),
parameterNames[i].c_str(),
masterfd.getLocId(), linkname.c_str(),
H5P_DEFAULT, H5P_DEFAULT) < 0) {
throw sls::RuntimeError(
"Could not create link to parameter dataset in master");
}
}
fd->close();
masterfd.close();
} catch (const Exception &error) {
error.printErrorStack();
if (fd != nullptr)
fd->close();
throw sls::RuntimeError("Could not link in master hdf5 file");
}
if (!silentMode) {
LOG(logINFO) << "Linked in Master File: " << dataFilename;
}
}
std::string CreateMasterHDF5File(const std::string &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode, MasterAttributes *attr,
std::mutex *hdf5LibMutex) {
std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_master"
<< "_" << fileIndex << ".h5";
std::string fileName = os.str();
std::lock_guard<std::mutex> lock(*hdf5LibMutex);
std::unique_ptr<H5File> fd{nullptr};
try {
Exception::dontPrint(); // to handle errors
FileAccPropList flist;
flist.setFcloseDegree(H5F_CLOSE_STRONG);
unsigned int createFlags = H5F_ACC_EXCL;
if (overWriteEnable) {
createFlags = H5F_ACC_TRUNC;
}
fd = sls::make_unique<H5File>(fileName.c_str(), createFlags,
FileCreatPropList::DEFAULT, flist);
// attributes - version
double dValue = HDF5_WRITER_VERSION;
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
Attribute attribute = fd->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
// Create a group in the file
Group group1(fd->createGroup("entry"));
Group group2(group1.createGroup("data"));
Group group3(group1.createGroup("instrument"));
Group group4(group3.createGroup("beam"));
Group group5(group3.createGroup("detector"));
Group group6(group1.createGroup("sample"));
attr->WriteHDF5Attributes(fd.get(), &group5);
fd->close();
} catch (const Exception &error) {
error.printErrorStack();
if (fd != nullptr)
fd->close();
throw sls::RuntimeError(
"Could not create/overwrite master HDF5 handles");
}
if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName;
}
return fileName;
}
std::array<std::string, 2> CreateVirtualHDF5File(
const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint64_t numImages,
const uint32_t nPixelsX, const uint32_t nPixelsY,
const uint32_t dynamicRange, const uint64_t numImagesCaught,
const int numModX, const int numModY, const DataType dataType,
const std::vector<std::string> parameterNames,
const std::vector<DataType> parameterDataTypes, std::mutex *hdf5LibMutex,
bool gotthard25um) {
// virtual file name
std::ostringstream osfn;
osfn << filePath << "/" << fileNamePrefix << "_virtual"
<< "_" << fileIndex << ".h5";
std::string fileName = osfn.str();
std::string dataSetName = "data";
unsigned int paraSize = parameterNames.size();
uint64_t numModZ = numModX;
uint32_t nDimy = nPixelsY;
uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
std::lock_guard<std::mutex> lock(*hdf5LibMutex);
std::unique_ptr<H5File> fd{nullptr};
try {
Exception::dontPrint(); // to handle errors
// file
FileAccPropList fapl;
fapl.setFcloseDegree(H5F_CLOSE_STRONG);
if (!overWriteEnable)
fd = sls::make_unique<H5File>(fileName.c_str(), H5F_ACC_EXCL,
FileCreatPropList::DEFAULT, fapl);
else
fd = sls::make_unique<H5File>(fileName.c_str(), H5F_ACC_TRUNC,
FileCreatPropList::DEFAULT, fapl);
// attributes - version
double dValue = HDF5_WRITER_VERSION;
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
Attribute attribute = fd->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
// virtual dataspace
hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy,
numModZ * nDimz};
DataSpace vdsDataSpace(3, vdsDims, nullptr);
hsize_t vdsDimsPara[2] = {numImagesCaught,
(unsigned int)numModY * numModZ};
DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr);
// property list (fill value and datatype)
int fill_value = -1;
DSetCreatPropList plist;
plist.setFillValue(dataType, &fill_value);
// property list for parameters (datatype)
std::vector<DSetCreatPropList> plistPara(paraSize);
// hyperslab (files)
int numFiles = numImagesCaught / maxFramesPerFile;
if (numImagesCaught % maxFramesPerFile)
++numFiles;
uint64_t framesSaved = 0;
for (int iFile = 0; iFile < numFiles; ++iFile) {
uint64_t nDimx =
((numImagesCaught - framesSaved) > maxFramesPerFile)
? maxFramesPerFile
: (numImagesCaught - framesSaved);
hsize_t startLocation[3] = {framesSaved, 0, 0};
hsize_t strideBetweenBlocks[3] = {1, 1, 1};
hsize_t numBlocks[3] = {nDimx, nDimy, nDimz};
hsize_t blockSize[3] = {1, 1, 1};
hsize_t startLocationPara[2] = {framesSaved, 0};
hsize_t strideBetweenBlocksPara[3] = {1, 1};
hsize_t numBlocksPara[2] = {1, 1};
hsize_t blockSizePara[3] = {nDimx, 1};
// interleaving for g2
if (gotthard25um) {
strideBetweenBlocks[2] = 2;
}
for (unsigned int iReadout = 0; iReadout < numModY * numModZ;
++iReadout) {
// interleaving for g2 (startLocation is 0 and 1)
if (gotthard25um) {
startLocation[2] = iReadout;
}
vdsDataSpace.selectHyperslab(H5S_SELECT_SET, numBlocks,
startLocation, strideBetweenBlocks,
blockSize);
vdsDataSpacePara.selectHyperslab(
H5S_SELECT_SET, numBlocksPara, startLocationPara,
strideBetweenBlocksPara, blockSizePara);
// source file name
std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_d"
<< (modulePos * numUnitsPerReadout + iReadout) << "_f"
<< iFile << '_' << fileIndex << ".h5";
std::string srcFileName = os.str();
LOG(logDEBUG1) << srcFileName;
// find relative path
std::string relative_srcFileName = srcFileName;
{
size_t p = srcFileName.rfind('/', srcFileName.length());
if (p != std::string::npos)
relative_srcFileName = (srcFileName.substr(
p + 1, srcFileName.length() - p));
}
// source dataset name
std::ostringstream osfn;
osfn << "/data";
if (numImages > 1)
osfn << "_f" << std::setfill('0') << std::setw(12) << iFile;
std::string srcDatasetName = osfn.str();
// source dataspace
hsize_t srcDims[3] = {nDimx, nDimy, nDimz};
hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz};
DataSpace srcDataSpace(3, srcDims, srcDimsMax);
hsize_t srcDimsPara[1] = {nDimx};
hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED};
DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara);
// mapping of property list
plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(),
srcDatasetName.c_str(), srcDataSpace);
for (unsigned int p = 0; p < paraSize; ++p) {
plistPara[p].setVirtual(
vdsDataSpacePara, relative_srcFileName.c_str(),
parameterNames[p].c_str(), srcDataSpacePara);
}
// H5Sclose(srcDataspace);
// H5Sclose(srcDataspace_para);
if (!gotthard25um) {
startLocation[2] += nDimz;
if (startLocation[2] >= (numModZ * nDimz)) {
startLocation[2] = 0;
startLocation[1] += nDimy;
}
}
startLocationPara[1]++;
}
framesSaved += nDimx;
}
// datasets
DataSet vdsDataSet(fd->createDataSet(dataSetName.c_str(), dataType,
vdsDataSpace, plist));
for (unsigned int p = 0; p < paraSize; ++p) {
DataSet vdsDataSetPara(fd->createDataSet(
parameterNames[p].c_str(), parameterDataTypes[p],
vdsDataSpacePara, plistPara[p]));
}
fd->close();
} catch (const Exception &error) {
error.printErrorStack();
if (fd) {
fd->close();
}
throw sls::RuntimeError(
"Could not create/overwrite virtual HDF5 handles");
}
if (!silentMode) {
LOG(logINFO) << "Virtual File: " << fileName;
}
return std::array<std::string, 2>{fileName, dataSetName};
}
#endif
} // namespace masterFileUtility

View File

@ -0,0 +1,50 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "MasterAttributes.h"
#ifdef HDF5C
#include "H5Cpp.h"
#include <mutex>
#ifndef H5_NO_NAMESPACE
using namespace H5;
#endif
#endif
namespace masterFileUtility {
std::string CreateMasterBinaryFile(const std::string &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode,
MasterAttributes *attr);
#ifdef HDF5C
void LinkHDF5FileInMaster(const std::string &masterFileName,
const std::string &dataFilename,
const std::string &dataSetname,
const std::vector<std::string> parameterNames,
const bool silentMode, std::mutex *hdf5LibMutex);
std::string CreateMasterHDF5File(const std::string &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode, MasterAttributes *attr,
std::mutex *hdf5LibMutex);
std::array<std::string, 2> CreateVirtualHDF5File(
const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint64_t numImages,
const uint32_t nPixelsX, const uint32_t nPixelsY,
const uint32_t dynamicRange, const uint64_t numImagesCaught,
const int numModX, const int numModY, const DataType dataType,
const std::vector<std::string> parameterNames,
const std::vector<DataType> parameterDataTypes, std::mutex *hdf5LibMutex,
bool gotthard25um);
#endif
} // namespace masterFileUtility

View File

@ -47,83 +47,62 @@ void printHelp() {
}
/**
* Start Acquisition Call back
* slsReceiver writes data if file write enabled.
* Users get data to write using call back if registerCallBackRawDataReady is
* registered.
* @param filepath file path
* @param filename file name
* @param fileindex file index
* @param datasize data size in bytes
* @param p pointer to object
* \returns ignored
* Start Acquisition Call back (slsMultiReceiver writes data if file write
* enabled) if registerCallBackRawDataReady or
* registerCallBackRawDataModifyReady registered, users get data
*/
int StartAcq(std::string filepath, std::string filename, uint64_t fileindex,
uint32_t datasize, void *p) {
LOG(logINFOBLUE) << "#### StartAcq: filepath:" << filepath
<< " filename:" << filename << " fileindex:" << fileindex
<< " datasize:" << datasize << " ####";
int StartAcq(const std::string &filePath, const std::string &fileName,
uint64_t fileIndex, size_t imageSize, void *objectPointer) {
LOG(logINFOBLUE) << "#### StartAcq: filePath:" << filePath
<< " fileName:" << fileName << " fileIndex:" << fileIndex
<< " imageSize:" << imageSize << " ####";
return 0;
}
/**
* Acquisition Finished Call back
* @param frames Number of frames caught
* @param p pointer to object
*/
void AcquisitionFinished(uint64_t frames, void *p) {
LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames
<< " ####";
/** Acquisition Finished Call back */
void AcquisitionFinished(uint64_t framesCaught, void *objectPointer) {
LOG(logINFOBLUE) << "#### AcquisitionFinished: framesCaught:"
<< framesCaught << " ####";
}
/**
* Get Receiver Data Call back
* Prints in different colors(for each receiver process) the different headers
* for each image call back.
* @param metadata sls_receiver_header metadata
* @param datapointer pointer to data
* @param datasize data size in bytes.
* @param p pointer to object
*/
void GetData(char *metadata, char *datapointer, uint32_t datasize, void *p) {
slsDetectorDefs::sls_receiver_header *header =
(slsDetectorDefs::sls_receiver_header *)metadata;
void GetData(slsDetectorDefs::sls_receiver_header *header, char *dataPointer,
size_t imageSize, void *objectPointer) {
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR(
detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
"#### %d GetData: ####\n"
"#### %d %d GetData: ####\n"
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
"\t\ttimestamp: %lu\t\tmodId: %u\t\t"
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
//"\t\tpacketsMask:%s"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
detectorHeader.row, (long unsigned int)detectorHeader.frameNumber,
detectorHeader.expLength, detectorHeader.packetNumber,
(long unsigned int)detectorHeader.bunchId,
"\t\tfirstbytedata: 0x%x\t\tdatsize: %zu\n\n",
detectorHeader.column, detectorHeader.row,
(long unsigned int)detectorHeader.frameNumber, detectorHeader.expLength,
detectorHeader.packetNumber, (long unsigned int)detectorHeader.bunchId,
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version,
// header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t *)(datapointer)))), datasize);
((uint8_t)(*((uint8_t *)(dataPointer)))), imageSize);
}
/**
* Get Receiver Data Call back (modified)
* Prints in different colors(for each receiver process) the different headers
* for each image call back.
* @param metadata sls_receiver_header metadata
* @param datapointer pointer to data
* @param revDatasize new data size in bytes after the callback.
* @param modifiedImageSize new data size in bytes after the callback.
* This will be the size written/streamed. (only smaller value is allowed).
* @param p pointer to object
*/
void GetData(char *metadata, char *datapointer, uint32_t &revDatasize,
void *p) {
slsDetectorDefs::sls_receiver_header *header =
(slsDetectorDefs::sls_receiver_header *)metadata;
void GetData(slsDetectorDefs::sls_receiver_header *header, char *dataPointer,
size_t &modifiedImageSize, void *objectPointer) {
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR(
@ -135,7 +114,7 @@ void GetData(char *metadata, char *datapointer, uint32_t &revDatasize,
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
//"\t\tpacketsMask:%s"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
"\t\tfirstbytedata: 0x%x\t\tdatsize: %zu\n\n",
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
detectorHeader.expLength, detectorHeader.packetNumber,
(long long unsigned int)detectorHeader.bunchId,
@ -144,10 +123,10 @@ void GetData(char *metadata, char *datapointer, uint32_t &revDatasize,
detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version,
// header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t *)(datapointer)))), revDatasize);
((uint8_t)(*((uint8_t *)(dataPointer)))), modifiedImageSize);
// if data is modified, eg ROI and size is reduced
revDatasize = 26000;
modifiedImageSize = 26000;
}
/**

View File

@ -129,7 +129,7 @@ int64_t Receiver::getReceiverVersion() {
}
void Receiver::registerCallBackStartAcquisition(
int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
int (*func)(const std::string &, const std::string &, uint64_t, size_t, void *),
void *arg) {
tcpipInterface->registerCallBackStartAcquisition(func, arg);
}
@ -140,14 +140,13 @@ void Receiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
tcpipInterface->registerCallBackAcquisitionFinished(func, arg);
}
void Receiver::registerCallBackRawDataReady(void (*func)(char *, char *,
uint32_t, void *),
void *arg) {
void Receiver::registerCallBackRawDataReady(
void (*func)(sls_receiver_header *, char *, size_t, void *), void *arg) {
tcpipInterface->registerCallBackRawDataReady(func, arg);
}
void Receiver::registerCallBackRawDataModifyReady(
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
void (*func)(sls_receiver_header *, char *, size_t &, void *), void *arg) {
tcpipInterface->registerCallBackRawDataModifyReady(func, arg);
}

View File

@ -18,7 +18,7 @@
// versions
#define HDF5_WRITER_VERSION (6.4) // 1 decimal places
#define BINARY_WRITER_VERSION (6.4) // 1 decimal places
#define BINARY_WRITER_VERSION (7.0) // 1 decimal places
#define MAX_FRAMES_PER_FILE 20000
#define SHORT_MAX_FRAMES_PER_FILE 100000

View File

@ -34,6 +34,8 @@ set(PUBLICHEADERS
if(SLS_DEVEL_HEADERS)
set(PUBLICHEADERS
${PUBLICHEADERS}
include/sls/ansi.h
include/sls/logger.h
include/sls/file_utils.h
include/sls/sls_detector_funcs.h
include/sls/ClientSocket.h
@ -46,7 +48,7 @@ if(SLS_DEVEL_HEADERS)
include/sls/versionAPI.h
include/sls/ZmqSocket.h
include/sls/bit_utils.h
include/sls/mdf5.h
include/sls/md5.h
include/sls/md5_helper.h
)
endif()
@ -75,13 +77,16 @@ target_include_directories(slsSupportObject
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
${SLS_INTERNAL_RAPIDJSON_DIR}
)
message(STATUS "RAPID: ${SLS_INTERNAL_RAPIDJSON_DIR}")
target_link_libraries(slsSupportObject
PUBLIC
slsProjectOptions
libzmq
rapidjson
PRIVATE
slsProjectWarnings
md5sls

View File

@ -43,6 +43,7 @@ std::string ToString(const defs::portPosition s);
std::string ToString(const defs::streamingInterface s);
std::string ToString(const defs::vetoAlgorithm s);
std::string ToString(const defs::gainMode s);
std::string ToString(const defs::polarity s);
std::string ToString(const slsDetectorDefs::xy &coord);
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
@ -313,6 +314,7 @@ template <> defs::portPosition StringTo(const std::string &s);
template <> defs::streamingInterface StringTo(const std::string &s);
template <> defs::vetoAlgorithm StringTo(const std::string &s);
template <> defs::gainMode StringTo(const std::string &s);
template <> defs::polarity StringTo(const std::string &s);
template <> uint32_t StringTo(const std::string &s);
template <> uint64_t StringTo(const std::string &s);

View File

@ -28,9 +28,9 @@ struct zmqHeader {
uint32_t jsonversion{0};
uint32_t dynamicRange{0};
uint64_t fileIndex{0};
/** number of detectors in x axis */
/** number of detectors/port in x axis */
uint32_t ndetx{0};
/** number of detectors in y axis */
/** number of detectors/port in y axis */
uint32_t ndety{0};
/** number of pixels/channels in x axis for this zmq socket */
uint32_t npixelsx{0};

View File

@ -438,6 +438,8 @@ enum streamingInterface {
FIX_G0
};
enum polarity { POSITIVE, NEGATIVE };
#ifdef __cplusplus
/** scan structure */

View File

@ -111,7 +111,6 @@ enum detFuncs {
F_SOFTWARE_TRIGGER,
F_LED,
F_DIGITAL_IO_DELAY,
F_COPY_DET_SERVER,
F_REBOOT_CONTROLLER,
F_SET_ADC_ENABLE_MASK,
F_GET_ADC_ENABLE_MASK,
@ -261,9 +260,19 @@ enum detFuncs {
F_SET_MASTER,
F_GET_TOP,
F_SET_TOP,
F_GET_POLARITY,
F_SET_POLARITY,
F_GET_INTERPOLATION,
F_SET_INTERPOLATION,
F_GET_PUMP_PROBE,
F_SET_PUMP_PROBE,
F_GET_ANALOG_PULSING,
F_SET_ANALOG_PULSING,
F_GET_DIGITAL_PULSING,
F_SET_DIGITAL_PULSING,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
RECEIVER_ENUM_START = 512, /**< detector function should not exceed this
(detector server should not compile anyway) */
F_EXEC_RECEIVER_COMMAND,
@ -477,7 +486,6 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SOFTWARE_TRIGGER: return "F_SOFTWARE_TRIGGER";
case F_LED: return "F_LED";
case F_DIGITAL_IO_DELAY: return "F_DIGITAL_IO_DELAY";
case F_COPY_DET_SERVER: return "F_COPY_DET_SERVER";
case F_REBOOT_CONTROLLER: return "F_REBOOT_CONTROLLER";
case F_SET_ADC_ENABLE_MASK: return "F_SET_ADC_ENABLE_MASK";
case F_GET_ADC_ENABLE_MASK: return "F_GET_ADC_ENABLE_MASK";
@ -625,6 +633,16 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_MASTER: return "F_SET_MASTER";
case F_GET_TOP: return "F_GET_TOP";
case F_SET_TOP: return "F_SET_TOP";
case F_GET_POLARITY: return "F_GET_POLARITY";
case F_SET_POLARITY: return "F_SET_POLARITY";
case F_GET_INTERPOLATION: return "F_GET_INTERPOLATION";
case F_SET_INTERPOLATION: return "F_SET_INTERPOLATION";
case F_GET_PUMP_PROBE: return "F_GET_PUMP_PROBE";
case F_SET_PUMP_PROBE: return "F_SET_PUMP_PROBE";
case F_GET_ANALOG_PULSING: return "F_GET_ANALOG_PULSING";
case F_SET_ANALOG_PULSING: return "F_SET_ANALOG_PULSING";
case F_GET_DIGITAL_PULSING: return "F_GET_DIGITAL_PULSING";
case F_SET_DIGITAL_PULSING: return "F_SET_DIGITAL_PULSING";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";

View File

@ -2,14 +2,14 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package
/** API versions */
#define GITBRANCH "developer"
#define APILIB 0x211125
#define APIRECEIVER 0x211124
#define APIGUI 0x211124
#define APILIB 0x220408
#define APIRECEIVER 0x220408
#define APIGUI 0x220328
#define APIEIGER 0x220324
#define APICTB 0x220328
#define APIGOTTHARD 0x220328
#define APIGOTTHARD2 0x220328
#define APIJUNGFRAU 0x220328
#define APIMYTHEN3 0x220328
#define APIMOENCH 0x220328
#define APICTB 0x220428
#define APIGOTTHARD 0x220428
#define APIGOTTHARD2 0x220428
#define APIJUNGFRAU 0x220428
#define APIMOENCH 0x220427
#define APIEIGER 0x220428
#define APIMYTHEN3 0x220510

View File

@ -642,6 +642,17 @@ std::string ToString(const defs::gainMode s) {
}
}
std::string ToString(const defs::polarity s) {
switch (s) {
case defs::POSITIVE:
return std::string("pos");
case defs::NEGATIVE:
return std::string("neg");
default:
return std::string("Unknown");
}
}
const std::string &ToString(const std::string &s) { return s; }
template <> defs::detectorType StringTo(const std::string &s) {
@ -1055,6 +1066,14 @@ template <> defs::gainMode StringTo(const std::string &s) {
throw sls::RuntimeError("Unknown gain mode " + s);
}
template <> defs::polarity StringTo(const std::string &s) {
if (s == "pos")
return defs::POSITIVE;
if (s == "neg")
return defs::NEGATIVE;
throw sls::RuntimeError("Unknown polarity mode " + s);
}
template <> uint32_t StringTo(const std::string &s) {
int base = s.find("0x") != std::string::npos ? 16 : 10;
return std::stoul(s, nullptr, base);

View File

@ -6,7 +6,7 @@
#include <chrono>
#include <thread>
TEST_CASE("Time 1s restart then time 2s") {
TEST_CASE("Time 1s restart then time 2s", "[.timer]") {
auto sleep_duration = std::chrono::seconds(1);
auto t = sls::Timer();
std::this_thread::sleep_for(sleep_duration);
@ -17,7 +17,7 @@ TEST_CASE("Time 1s restart then time 2s") {
REQUIRE(t.elapsed_s() == Approx(2).epsilon(0.01));
}
TEST_CASE("Return ms") {
TEST_CASE("Return ms", "[.timer]") {
auto sleep_duration = std::chrono::milliseconds(1300);
auto t = sls::Timer();
std::this_thread::sleep_for(sleep_duration);