mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-21 11:20:04 +02:00
Api (#48)
* WIP * WIP * WIP * cleaned up multi * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * split up python module * WIP * WIP * WIP * WIP * WIP * ok * fixed bugs from rebase * WIP * fixed broken test * WIP * fixed python * WIP * sphinx help * including new commands * docs * WIP * WIP * more tests * added missing public header * WIP
This commit is contained in:
parent
98ddf154b2
commit
4ceee97c03
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,7 +9,6 @@ bin/
|
|||||||
*.o
|
*.o
|
||||||
.*
|
.*
|
||||||
build
|
build
|
||||||
docs/
|
|
||||||
RELEASE.txt
|
RELEASE.txt
|
||||||
Testing/
|
Testing/
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ set(CMAKE_INSTALL_RPATH "$ORIGIN")
|
|||||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||||
|
|
||||||
|
|
||||||
find_package(Doxygen)
|
|
||||||
find_package(ZeroMQ 4 REQUIRED)
|
find_package(ZeroMQ 4 REQUIRED)
|
||||||
|
|
||||||
if (SLS_USE_TESTS)
|
if (SLS_USE_TESTS)
|
||||||
@ -182,24 +182,11 @@ configure_file( .clang-tidy
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if (DOXYGEN_FOUND)
|
add_subdirectory(sample)
|
||||||
# set input and output files
|
|
||||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/Doxyfile.in)
|
add_subdirectory(docs)
|
||||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
|
||||||
|
|
||||||
# request to configure the file
|
|
||||||
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
|
||||||
message("Doxygen build started")
|
|
||||||
|
|
||||||
# note the option ALL which allows to build the docs together with the application
|
|
||||||
add_custom_target( docs
|
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
COMMENT "Generating API documentation with Doxygen"
|
|
||||||
VERBATIM )
|
|
||||||
else (DOXYGEN_FOUND)
|
|
||||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
|
||||||
endif (DOXYGEN_FOUND)
|
|
||||||
|
|
||||||
|
|
||||||
if(SLS_MASTER_PROJECT)
|
if(SLS_MASTER_PROJECT)
|
||||||
|
11
cmake/FindSphinx.cmake
Normal file
11
cmake/FindSphinx.cmake
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#Look for an executable called sphinx-build
|
||||||
|
find_program(SPHINX_EXECUTABLE
|
||||||
|
NAMES sphinx-build
|
||||||
|
DOC "Path to sphinx-build executable")
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
#Handle standard arguments to find_package like REQUIRED and QUIET
|
||||||
|
find_package_handle_standard_args(Sphinx
|
||||||
|
"Failed to find sphinx-build executable"
|
||||||
|
SPHINX_EXECUTABLE)
|
67
docs/CMakeLists.txt
Normal file
67
docs/CMakeLists.txt
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
find_package(Doxygen)
|
||||||
|
find_package(Sphinx)
|
||||||
|
|
||||||
|
|
||||||
|
if (DOXYGEN_FOUND AND SPHINX_FOUND)
|
||||||
|
|
||||||
|
# #Utility to generate command line documentation
|
||||||
|
add_executable(gendoc src/gendoc.cpp)
|
||||||
|
target_link_libraries(gendoc PRIVATE
|
||||||
|
slsDetectorShared
|
||||||
|
)
|
||||||
|
set_target_properties(gendoc PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Doxygen
|
||||||
|
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
|
||||||
|
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||||
|
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
||||||
|
|
||||||
|
#Sphinx
|
||||||
|
set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
set(SPHINX_SOURCE_FILES
|
||||||
|
src/commandline.rst
|
||||||
|
src/container_utils.rst
|
||||||
|
src/dependencies.rst
|
||||||
|
src/detector.rst
|
||||||
|
src/index.rst
|
||||||
|
src/installation.rst
|
||||||
|
src/pydetector.rst
|
||||||
|
src/pyenums.rst
|
||||||
|
src/pyexamples.rst
|
||||||
|
src/receiver.rst
|
||||||
|
src/result.rst
|
||||||
|
src/type_traits.rst
|
||||||
|
src/ToString.rst
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(filename ${SPHINX_SOURCE_FILES})
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${filename}
|
||||||
|
"${SPHINX_BUILD}/${filename}")
|
||||||
|
endforeach(filename ${SPHINX_SOURCE_FILES})
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
|
||||||
|
"${SPHINX_BUILD}/conf.py"
|
||||||
|
@ONLY)
|
||||||
|
|
||||||
|
add_custom_target(docs
|
||||||
|
gendoc
|
||||||
|
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||||
|
COMMAND ${SPHINX_EXECUTABLE} -a -b html
|
||||||
|
-Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml
|
||||||
|
-c "${SPHINX_BUILD}"
|
||||||
|
${SPHINX_BUILD}/src
|
||||||
|
${SPHINX_BUILD}/html
|
||||||
|
COMMENT "Generating documentation with Sphinx")
|
||||||
|
|
||||||
|
else (DOXYGEN_FOUND AND SPHINX_FOUND)
|
||||||
|
message("Doxygen and Sphinx are needed to build documentation")
|
||||||
|
endif (DOXYGEN_FOUND AND SPHINX_FOUND)
|
@ -58,7 +58,7 @@ PROJECT_LOGO =
|
|||||||
# entered, it will be relative to the location where doxygen was started. If
|
# entered, it will be relative to the location where doxygen was started. If
|
||||||
# left blank the current directory will be used.
|
# left blank the current directory will be used.
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/docs/
|
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@
|
||||||
|
|
||||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
||||||
# directories (in 2 levels) under the output directory of each output format and
|
# directories (in 2 levels) under the output directory of each output format and
|
||||||
@ -791,7 +791,7 @@ WARN_LOGFILE =
|
|||||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = @CMAKE_CURRENT_SOURCE_DIR@
|
INPUT = @PROJECT_SOURCE_DIR@
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
@ -890,7 +890,7 @@ EXCLUDE_SYMLINKS = NO
|
|||||||
# Note that the wildcards are matched against the file with absolute path, so to
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
# exclude all test directories for example use the pattern */test/*
|
# exclude all test directories for example use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_PATTERNS = */tests/* */python */manual */rapidjson */catch */integrationTests *README* */slsDetectorGui/*
|
EXCLUDE_PATTERNS = */docs/* */tests/* */python/* */manual */slsDetectorServers/* */libs/* */integrationTests *README* */slsDetectorGui/* */ctbGui/* */slsDetectorCalibration/*
|
||||||
|
|
||||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||||
@ -1104,7 +1104,7 @@ IGNORE_PREFIX =
|
|||||||
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
|
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_HTML = YES
|
GENERATE_HTML = NO
|
||||||
|
|
||||||
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
|
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
|
||||||
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
@ -1936,7 +1936,7 @@ MAN_LINKS = NO
|
|||||||
# captures the structure of the code including all documentation.
|
# captures the structure of the code including all documentation.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_XML = NO
|
GENERATE_XML = YES
|
||||||
|
|
||||||
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
|
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
|
||||||
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
62
docs/conf.py.in
Normal file
62
docs/conf.py.in
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# This file only contains a selection of the most common options. For a full
|
||||||
|
# list see the documentation:
|
||||||
|
# http://www.sphinx-doc.org/en/master/config
|
||||||
|
|
||||||
|
# -- Path setup --------------------------------------------------------------
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
#
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
# sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
sys.path.insert(0, os.path.abspath('../bin/'))
|
||||||
|
#sys.path.insert(0, '/home/l_frojdh/sls/build/bin')
|
||||||
|
#sys.path.insert(0, @CMAKE_CURRENT_BINARY_DIR@)
|
||||||
|
print(sys.path)
|
||||||
|
|
||||||
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
|
project = 'slsDetectorPackage'
|
||||||
|
copyright = '2019, PSD Detector Group'
|
||||||
|
author = 'PSD Detector Group'
|
||||||
|
version = '@PROJECT_VERSION@'
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
# ones.
|
||||||
|
extensions = ['breathe',
|
||||||
|
'sphinx_rtd_theme',
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.napoleon',
|
||||||
|
]
|
||||||
|
|
||||||
|
breathe_default_project = "slsDetectorPackage"
|
||||||
|
napoleon_use_ivar = True
|
||||||
|
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
#
|
||||||
|
html_theme = "sphinx_rtd_theme"
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
#html_static_path = ['_static']
|
6
docs/src/ToString.rst
Normal file
6
docs/src/ToString.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ToString
|
||||||
|
==============
|
||||||
|
|
||||||
|
String conversion
|
||||||
|
|
||||||
|
.. doxygenfile:: ToString.h
|
16
docs/src/commandline.rst
Normal file
16
docs/src/commandline.rst
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Command line interface
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Commands can be uses either with sls_detector_get or sls_detector_put
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
sls_detector_get vrf
|
||||||
|
|
||||||
|
Commands
|
||||||
|
-----------
|
||||||
|
|
||||||
|
.. include:: ../commands.rst
|
14
docs/src/container_utils.rst
Normal file
14
docs/src/container_utils.rst
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
ContainerUtils
|
||||||
|
==================
|
||||||
|
|
||||||
|
Helper functions to handle standard container compliant
|
||||||
|
containers. Supports array, vector, sls::Result etc.
|
||||||
|
|
||||||
|
While not a part of the public API we aim not to change this
|
||||||
|
interface too much. However, we don't give the same strong
|
||||||
|
guarantees as for Detector etc.
|
||||||
|
|
||||||
|
Any reoccurring container operation should probably be added to
|
||||||
|
this file.
|
||||||
|
|
||||||
|
.. doxygenfile:: container_utils.h
|
53
docs/src/dependencies.rst
Normal file
53
docs/src/dependencies.rst
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Dependencies
|
||||||
|
=========================
|
||||||
|
|
||||||
|
While we value few dependencies some libraries are required in
|
||||||
|
order to not have to reinvent the wheel. Due to the state of package
|
||||||
|
management in C++ we decided to bundle some of them with our source
|
||||||
|
code. These are found in the libs/ directory.
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
Core
|
||||||
|
-----------------------
|
||||||
|
To use the basic building blocks, meaning sls_detector_get/put and
|
||||||
|
the shared libraries these are needed:
|
||||||
|
|
||||||
|
* Linux, preferably recent kernel (currently no cross platform support)
|
||||||
|
* CMake > 3.9
|
||||||
|
* C++11 compatible compiler. (We test with gcc and clang)
|
||||||
|
* ZeroMQ version 4
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
GUI
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The GUI is currently using Qt4 but watch out for an upgrade to 5.
|
||||||
|
|
||||||
|
* Qt 4.8
|
||||||
|
* Qwt 6
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
Python bindings
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* Python > 3.6
|
||||||
|
* pybind11 (packaged in libs/)
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
Documentation
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The documentation that you are reading now is built with
|
||||||
|
|
||||||
|
* Doxygen (to extract C++ classes etc.)
|
||||||
|
* Breathe (Sphinx plugin to handle doxygen xml)
|
||||||
|
* Sphinx
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
Packaged in libs/
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* catch2 (unit testing)
|
||||||
|
* rapidjson (streaming from receiver)
|
||||||
|
* pybind11 (python bindings)
|
16
docs/src/detector.rst
Normal file
16
docs/src/detector.rst
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Detector
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
The sls::Detector is the new public API to control
|
||||||
|
detectors from C++. This API is also used internally
|
||||||
|
for the Python bindings and the command line interface.
|
||||||
|
If a receiver has been configured this is also controlled
|
||||||
|
through this class.
|
||||||
|
|
||||||
|
Most, if not all, functions are called in parallel
|
||||||
|
and the return value is a thin std::vector wrapper
|
||||||
|
containing results from all modules. (Result<T>)
|
||||||
|
|
||||||
|
.. doxygenclass:: sls::Detector
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
56
docs/src/gendoc.cpp
Normal file
56
docs/src/gendoc.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Utility program to generate input files for the command line
|
||||||
|
* documentation. Uses the string returned from sls_detector_help cmd
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#include "CmdProxy.h"
|
||||||
|
#include "Detector.h"
|
||||||
|
#include "sls_detector_defs.h"
|
||||||
|
|
||||||
|
std::string replace_all(const std::string &src, const std::string &from,
|
||||||
|
const std::string &to) {
|
||||||
|
|
||||||
|
std::string results;
|
||||||
|
std::string::const_iterator end = src.end();
|
||||||
|
std::string::const_iterator current = src.begin();
|
||||||
|
std::string::const_iterator next =
|
||||||
|
std::search(current, end, from.begin(), from.end());
|
||||||
|
while (next != end) {
|
||||||
|
results.append(current, next);
|
||||||
|
results.append(to);
|
||||||
|
current = next + from.size();
|
||||||
|
next = std::search(current, end, from.begin(), from.end());
|
||||||
|
}
|
||||||
|
results.append(current, next);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
std::cout << "Generating command line documentation!\n";
|
||||||
|
|
||||||
|
sls::CmdProxy<sls::Detector> proxy(nullptr);
|
||||||
|
auto commands = proxy.GetProxyCommands();
|
||||||
|
|
||||||
|
std::ofstream fs("commands.rst");
|
||||||
|
fs << ".. glossary::\n";
|
||||||
|
|
||||||
|
for (const auto &cmd : commands) {
|
||||||
|
std::ostringstream os;
|
||||||
|
proxy.Call(cmd, {}, -1, slsDetectorDefs::HELP_ACTION, os);
|
||||||
|
|
||||||
|
auto tmp = os.str().erase(0, cmd.size());
|
||||||
|
auto usage = tmp.substr(0, tmp.find_first_of('\n'));
|
||||||
|
tmp.erase(0, usage.size());
|
||||||
|
auto help = replace_all(tmp, "\n\t", "\n\t\t");
|
||||||
|
fs << '\t' << cmd << usage << help << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
50
docs/src/index.rst
Normal file
50
docs/src/index.rst
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
.. slsDetectorPackage documentation master file, created by
|
||||||
|
sphinx-quickstart on Mon Jul 29 17:38:15 2019.
|
||||||
|
You can adapt this file completely to your liking, but it should at least
|
||||||
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
|
Welcome to slsDetectorPackage's documentation!
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
:caption: Installation:
|
||||||
|
|
||||||
|
installation
|
||||||
|
dependencies
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: C++ API
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
detector
|
||||||
|
result
|
||||||
|
receiver
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Python API
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
pydetector
|
||||||
|
pyenums
|
||||||
|
pyexamples
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Command line
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
commandline
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Developer
|
||||||
|
|
||||||
|
container_utils
|
||||||
|
type_traits
|
||||||
|
ToString
|
||||||
|
|
||||||
|
.. Indices and tables
|
||||||
|
.. ==================
|
||||||
|
|
||||||
|
.. * :ref:`genindex`
|
||||||
|
.. * :ref:`modindex`
|
||||||
|
.. * :ref:`search`
|
5
docs/src/installation.rst
Normal file
5
docs/src/installation.rst
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
Installation
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
get the source etc.
|
9
docs/src/pydetector.rst
Normal file
9
docs/src/pydetector.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Detector
|
||||||
|
=====================================================
|
||||||
|
|
||||||
|
.. py:currentmodule:: sls_detector
|
||||||
|
|
||||||
|
.. autoclass:: ExperimentalDetector
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
12
docs/src/pyenums.rst
Normal file
12
docs/src/pyenums.rst
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Enums
|
||||||
|
===========
|
||||||
|
|
||||||
|
These enums are defined in slsDetectorDefs in the C++ package and
|
||||||
|
exposed to Python through pybind11.
|
||||||
|
|
||||||
|
.. py:currentmodule:: sls_detector
|
||||||
|
|
||||||
|
.. autoclass:: runStatus
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
@ -18,7 +18,7 @@ file writing etc.
|
|||||||
threshold = range(0, 2000, 200)
|
threshold = range(0, 2000, 200)
|
||||||
for th in threshold:
|
for th in threshold:
|
||||||
d.vthreshold = th
|
d.vthreshold = th
|
||||||
d.acq()
|
d.acquire()
|
||||||
|
|
||||||
|
|
||||||
If we want to control the shutter of for example, the big X-ray box we can add
|
If we want to control the shutter of for example, the big X-ray box we can add
|
||||||
@ -30,7 +30,7 @@ and closes is afterwards.
|
|||||||
with xrf_shutter_open(box, 'Fe'):
|
with xrf_shutter_open(box, 'Fe'):
|
||||||
for th in threshold:
|
for th in threshold:
|
||||||
d.vthreshold = th
|
d.vthreshold = th
|
||||||
d.acq()
|
d.acquire()
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
6
docs/src/receiver.rst
Normal file
6
docs/src/receiver.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Receiver
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
.. doxygenclass:: slsReceiver
|
||||||
|
:members:
|
||||||
|
.. :undoc-members:
|
4
docs/src/result.rst
Normal file
4
docs/src/result.rst
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Result
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
.. doxygenfile:: Result.h
|
7
docs/src/type_traits.rst
Normal file
7
docs/src/type_traits.rst
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
TypeTraits
|
||||||
|
==============
|
||||||
|
|
||||||
|
Template meta functions in the same spirit as type_traits
|
||||||
|
from the standard library.
|
||||||
|
|
||||||
|
.. doxygenfile:: TypeTraits.h
|
@ -7,11 +7,11 @@
|
|||||||
# ${PROJECT_SOURCE_DIR}/catch
|
# ${PROJECT_SOURCE_DIR}/catch
|
||||||
# )
|
# )
|
||||||
|
|
||||||
target_sources(tests PRIVATE
|
# target_sources(tests PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-integrationMulti.cpp
|
# ${CMAKE_CURRENT_SOURCE_DIR}/test-integrationMulti.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-integrationDectector.cpp
|
# ${CMAKE_CURRENT_SOURCE_DIR}/test-integrationDectector.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-eigerIntegration.cpp
|
# ${CMAKE_CURRENT_SOURCE_DIR}/test-eigerIntegration.cpp
|
||||||
)
|
# )
|
||||||
|
|
||||||
# if(SLS_USE_TESTS)
|
# if(SLS_USE_TESTS)
|
||||||
# set(TEST_SOURCES
|
# set(TEST_SOURCES
|
||||||
@ -32,18 +32,7 @@ target_sources(tests PRIVATE
|
|||||||
# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# add_executable(a src/a.cpp)
|
|
||||||
# target_link_libraries(a
|
|
||||||
# slsProjectOptions
|
|
||||||
# slsProjectWarnings
|
|
||||||
# slsDetectorShared
|
|
||||||
# slsSupportLib
|
|
||||||
# pthread
|
|
||||||
# rt
|
|
||||||
# )
|
|
||||||
# set_target_properties(a PROPERTIES
|
|
||||||
# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
|
||||||
# )
|
|
||||||
|
|
||||||
# endif()
|
# endif()
|
||||||
|
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
|
|
||||||
#include "catch.hpp"
|
|
||||||
|
|
||||||
#include "ClientSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "logger.h"
|
|
||||||
#include "network_utils.h"
|
|
||||||
#include "slsDetector.h"
|
|
||||||
#include "sls_detector_defs.h"
|
|
||||||
#include "sls_detector_exceptions.h"
|
|
||||||
#include "sls_detector_funcs.h"
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <string>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "network_utils.h"
|
|
||||||
|
|
||||||
using namespace sls;
|
|
||||||
using ROI = slsDetectorDefs::ROI;
|
|
||||||
|
|
||||||
// Easy printing of an ROI
|
|
||||||
std::ostream &operator<<(std::ostream &out, const ROI &r) {
|
|
||||||
return out << "xmin: " << std::setw(5) << r.xmin
|
|
||||||
<< " xmax: " << std::setw(5) << r.xmax
|
|
||||||
<< " ymin: " << std::setw(5) << r.ymin
|
|
||||||
<< " ymax: " << std::setw(5) << r.ymax;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
std::cout << "nullptr: " << sizeof(nullptr) << "\n";
|
|
||||||
// int ret[]{0,0,0};
|
|
||||||
// for (auto i: ret)
|
|
||||||
// std::cout << i << "\n";
|
|
||||||
// uint32_t imageSize = 101;
|
|
||||||
// uint32_t packetSize = 100;
|
|
||||||
// std::cout << "a: " << std::ceil((double)imageSize / (double)packetSize) <<'\n';
|
|
||||||
// std::cout << "b: " << imageSize / packetSize <<'\n';
|
|
||||||
// std::cout << "c: " << static_cast<double>(imageSize / packetSize) << '\n';
|
|
||||||
// std::cout << "c: " << (imageSize + packetSize-1) / packetSize << '\n';
|
|
||||||
|
|
||||||
// slsDetectorDefs::ROI roilimits[5];
|
|
||||||
// roilimits[0].xmin = 5;
|
|
||||||
// roilimits[0].xmax = 12;
|
|
||||||
// roilimits[0].ymin = 5;
|
|
||||||
// roilimits[0].ymax = 15;
|
|
||||||
|
|
||||||
// roilimits[1].xmin = 0;
|
|
||||||
// roilimits[1].xmax = 3;
|
|
||||||
// roilimits[1].ymin = 20;
|
|
||||||
// roilimits[1].ymax = 25;
|
|
||||||
|
|
||||||
// roilimits[2].xmin = 500;
|
|
||||||
// roilimits[2].xmax = 600;
|
|
||||||
// roilimits[2].ymin = 100;
|
|
||||||
// roilimits[2].ymax = 200;
|
|
||||||
|
|
||||||
// roilimits[3].xmin = 300;
|
|
||||||
// roilimits[3].xmax = 500;
|
|
||||||
// roilimits[3].ymin = 800;
|
|
||||||
// roilimits[3].ymax = 900;
|
|
||||||
|
|
||||||
// roilimits[4].xmin = 1000;
|
|
||||||
// roilimits[4].xmax = 2000;
|
|
||||||
// roilimits[4].ymin = 300;
|
|
||||||
// roilimits[4].ymax = 500;
|
|
||||||
|
|
||||||
// std::cout << "Before sorting:\n";
|
|
||||||
// for (auto r : roilimits) {
|
|
||||||
// std::cout << r << '\n';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// std::sort(std::begin(roilimits), std::end(roilimits),
|
|
||||||
// [](ROI a, ROI b) { return a.xmin < b.xmin; });
|
|
||||||
|
|
||||||
// std::cout << "After sorting: \n";
|
|
||||||
// for (auto r : roilimits) {
|
|
||||||
// std::cout << r << '\n';
|
|
||||||
// }
|
|
||||||
}
|
|
@ -1,11 +1,13 @@
|
|||||||
|
|
||||||
pybind11_add_module(_sls_detector src/main.cpp)
|
pybind11_add_module(_sls_detector
|
||||||
|
src/main.cpp
|
||||||
|
src/enums.cpp
|
||||||
|
src/experimental.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(_sls_detector PUBLIC
|
target_link_libraries(_sls_detector PUBLIC
|
||||||
slsProjectOptions
|
|
||||||
slsProjectWarnings
|
|
||||||
slsDetectorShared
|
slsDetectorShared
|
||||||
slsReceiverShared
|
slsReceiverShared
|
||||||
slsSupportLib
|
slsSupportLib
|
||||||
|
@ -36,7 +36,9 @@ class get_pybind_include(object):
|
|||||||
ext_modules = [
|
ext_modules = [
|
||||||
Extension(
|
Extension(
|
||||||
'_sls_detector',
|
'_sls_detector',
|
||||||
['src/main.cpp'],
|
['src/main.cpp',
|
||||||
|
'src/enums.cpp',
|
||||||
|
'src/experimental.cpp'],
|
||||||
include_dirs=[
|
include_dirs=[
|
||||||
# Path to pybind11 headers
|
# Path to pybind11 headers
|
||||||
get_pybind_include(),
|
get_pybind_include(),
|
||||||
|
@ -4,3 +4,6 @@ from .experimental import ExperimentalDetector
|
|||||||
from .jungfrau import Jungfrau
|
from .jungfrau import Jungfrau
|
||||||
from .jungfrau_ctb import JungfrauCTB
|
from .jungfrau_ctb import JungfrauCTB
|
||||||
from _sls_detector import DetectorApi
|
from _sls_detector import DetectorApi
|
||||||
|
|
||||||
|
import _sls_detector
|
||||||
|
runStatus = _sls_detector.slsDetectorDefs.runStatus
|
||||||
|
@ -1,9 +1,180 @@
|
|||||||
|
|
||||||
from _sls_detector import multiDetectorApi
|
from _sls_detector import multiDetectorApi
|
||||||
|
from _sls_detector import slsDetectorDefs
|
||||||
|
|
||||||
|
runStatus = slsDetectorDefs.runStatus
|
||||||
|
from .utils import element_if_equal, all_equal
|
||||||
|
import datetime as dt
|
||||||
|
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def freeze(cls):
|
||||||
|
cls.__frozen = False
|
||||||
|
|
||||||
|
def frozensetattr(self, key, value):
|
||||||
|
if self.__frozen and not hasattr(self, key):
|
||||||
|
raise AttributeError(
|
||||||
|
"Class {} is frozen. Cannot set {} = {}".format(
|
||||||
|
cls.__name__, key, value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
object.__setattr__(self, key, value)
|
||||||
|
|
||||||
|
def init_decorator(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(self, *args, **kwargs):
|
||||||
|
func(self, *args, **kwargs)
|
||||||
|
self.__frozen = True
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
cls.__setattr__ = frozensetattr
|
||||||
|
cls.__init__ = init_decorator(cls.__init__)
|
||||||
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
@freeze
|
||||||
class ExperimentalDetector(multiDetectorApi):
|
class ExperimentalDetector(multiDetectorApi):
|
||||||
def __init__(self):
|
"""
|
||||||
super().__init__(0)
|
This class is the base for detector specific
|
||||||
self.online = True
|
interfaces. Most functions exists in two versions
|
||||||
|
like the getExptime() function that uses the
|
||||||
|
C++ API directly and the simplified exptime property.
|
||||||
|
"""
|
||||||
|
def __init__(self, multi_id = 0):
|
||||||
|
"""
|
||||||
|
multi_id refers to the shared memory id of the
|
||||||
|
slsDetectorPackage. Default value is 0.
|
||||||
|
"""
|
||||||
|
super().__init__(multi_id)
|
||||||
|
|
||||||
|
# Acq
|
||||||
|
@property
|
||||||
|
def rx_status(self):
|
||||||
|
"""
|
||||||
|
Read the status of the receiver
|
||||||
|
"""
|
||||||
|
return element_if_equal(self.getReceiverStatus())
|
||||||
|
|
||||||
|
@rx_status.setter
|
||||||
|
def rx_status(self, status_str):
|
||||||
|
if status_str == "start":
|
||||||
|
self.startReceiver()
|
||||||
|
elif status_str == "stop":
|
||||||
|
self.stopReceiver()
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("Unknown argument to rx_status")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def busy(self):
|
||||||
|
"""
|
||||||
|
Checks if the detector is acquiring. Can also be set but should only be used if the acquire fails and
|
||||||
|
leaves the detector with busy == True
|
||||||
|
|
||||||
|
.. note ::
|
||||||
|
|
||||||
|
Only works when the measurement is launched using acquire, not with status start!
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
bool
|
||||||
|
:py:obj:`True` if the detector is acquiring otherwise :py:obj:`False`
|
||||||
|
|
||||||
|
Examples
|
||||||
|
----------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
d.busy
|
||||||
|
>> True
|
||||||
|
|
||||||
|
#If the detector is stuck reset by:
|
||||||
|
d.busy = False
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.getAcquiringFlag()
|
||||||
|
|
||||||
|
@busy.setter
|
||||||
|
def busy(self, value):
|
||||||
|
self.setAcquiringFlag(value)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
@property
|
||||||
|
def startingfnum(self):
|
||||||
|
return element_if_equal(self.getStartingFrameNumber())
|
||||||
|
|
||||||
|
@startingfnum.setter
|
||||||
|
def startingfnum(self, value):
|
||||||
|
self.setStartingFrameNumber(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config(self):
|
||||||
|
return NotImplementedError("config is set only")
|
||||||
|
|
||||||
|
@config.setter
|
||||||
|
def config(self, fname):
|
||||||
|
self.setConfig(fname)
|
||||||
|
|
||||||
|
# File
|
||||||
|
@property
|
||||||
|
def fname(self):
|
||||||
|
return element_if_equal(self.getFileName())
|
||||||
|
|
||||||
|
@fname.setter
|
||||||
|
def fname(self, file_name):
|
||||||
|
self.setFileName(file_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fpath(self):
|
||||||
|
return element_if_equal(self.getFilePath())
|
||||||
|
|
||||||
|
@fpath.setter
|
||||||
|
def fpath(self, path):
|
||||||
|
self.setFilePath(path)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fwrite(self):
|
||||||
|
return element_if_equal(self.getFileWrite())
|
||||||
|
|
||||||
|
@fwrite.setter
|
||||||
|
def fwrite(self, value):
|
||||||
|
self.setFileWrite(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def foverwrite(self):
|
||||||
|
return element_if_equal(self.getFileOverWrite())
|
||||||
|
|
||||||
|
@foverwrite.setter
|
||||||
|
def foverwrite(self, value):
|
||||||
|
self.setFileOverWrite(value)
|
||||||
|
|
||||||
|
# Time
|
||||||
|
@property
|
||||||
|
def exptime(self):
|
||||||
|
res = self.getExptime()
|
||||||
|
return element_if_equal([it.total_seconds() for it in res])
|
||||||
|
|
||||||
|
@exptime.setter
|
||||||
|
def exptime(self, t):
|
||||||
|
self.setExptime(dt.timedelta(seconds=t))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subexptime(self):
|
||||||
|
res = self.getSubExptime()
|
||||||
|
return element_if_equal([it.total_seconds() for it in res])
|
||||||
|
|
||||||
|
@subexptime.setter
|
||||||
|
def subexptime(self, t):
|
||||||
|
self.setSubExptime(dt.timedelta(seconds=t))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def period(self):
|
||||||
|
res = self.getPeriod()
|
||||||
|
return element_if_equal([it.total_seconds() for it in res])
|
||||||
|
|
||||||
|
@period.setter
|
||||||
|
def period(self, t):
|
||||||
|
self.setPeriod(dt.timedelta(seconds=t))
|
||||||
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
|||||||
#include "slsDetector.h"
|
#include "slsDetector.h"
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
|
|
||||||
class Detector {
|
class DetectorPythonInterface {
|
||||||
public:
|
public:
|
||||||
Detector(int i) : det(i), multi_detector_id(i) {
|
DetectorPythonInterface(int i) : det(i), multi_detector_id(i) {
|
||||||
// Disable output from std::cout
|
// Disable output from std::cout
|
||||||
// std::cout.setstate(std::ios_base::failbit);
|
// std::cout.setstate(std::ios_base::failbit);
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ class Detector {
|
|||||||
void checkDetectorVersionCompatibility() {
|
void checkDetectorVersionCompatibility() {
|
||||||
det.checkDetectorVersionCompatibility();
|
det.checkDetectorVersionCompatibility();
|
||||||
}
|
}
|
||||||
bool checkReceiverVersionCompatibility() {
|
void checkReceiverVersionCompatibility() {
|
||||||
det.checkReceiverVersionCompatibility();
|
det.checkReceiverVersionCompatibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +695,7 @@ class Detector {
|
|||||||
int multi_detector_id = 0;
|
int multi_detector_id = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Detector::setFileFormat(const std::string &format) {
|
void DetectorPythonInterface::setFileFormat(const std::string &format) {
|
||||||
if (format == "binary") {
|
if (format == "binary") {
|
||||||
det.setFileFormat(slsDetectorDefs::fileFormat::BINARY);
|
det.setFileFormat(slsDetectorDefs::fileFormat::BINARY);
|
||||||
} else if (format == "hdf5") {
|
} else if (format == "hdf5") {
|
||||||
@ -703,7 +703,7 @@ void Detector::setFileFormat(const std::string &format) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Detector::getFileFormat() {
|
std::string DetectorPythonInterface::getFileFormat() {
|
||||||
auto format =
|
auto format =
|
||||||
det.setFileFormat(slsDetectorDefs::fileFormat::GET_FILE_FORMAT, -1);
|
det.setFileFormat(slsDetectorDefs::fileFormat::GET_FILE_FORMAT, -1);
|
||||||
switch (format) {
|
switch (format) {
|
||||||
@ -717,7 +717,7 @@ std::string Detector::getFileFormat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
slsDetectorDefs::networkParameter
|
slsDetectorDefs::networkParameter
|
||||||
Detector::networkNameToEnum(std::string par_name) {
|
DetectorPythonInterface::networkNameToEnum(std::string par_name) {
|
||||||
|
|
||||||
if (par_name == "detectormac") {
|
if (par_name == "detectormac") {
|
||||||
return slsDetectorDefs::networkParameter::DETECTOR_MAC;
|
return slsDetectorDefs::networkParameter::DETECTOR_MAC;
|
||||||
@ -761,9 +761,9 @@ Detector::networkNameToEnum(std::string par_name) {
|
|||||||
throw std::runtime_error("Could not decode network parameter");
|
throw std::runtime_error("Could not decode network parameter");
|
||||||
};
|
};
|
||||||
|
|
||||||
// slsDetectorDefs::fileFormat Detector::file///
|
// slsDetectorDefs::fileFormat DetectorPythonInterface::file///
|
||||||
|
|
||||||
slsDetectorDefs::dacIndex Detector::dacNameToEnum(std::string dac_name) {
|
slsDetectorDefs::dacIndex DetectorPythonInterface::dacNameToEnum(std::string dac_name) {
|
||||||
// to avoid uninitialised
|
// to avoid uninitialised
|
||||||
slsDetectorDefs::dacIndex dac = slsDetectorDefs::dacIndex::E_SvP;
|
slsDetectorDefs::dacIndex dac = slsDetectorDefs::dacIndex::E_SvP;
|
||||||
|
|
||||||
@ -918,7 +918,7 @@ slsDetectorDefs::dacIndex Detector::dacNameToEnum(std::string dac_name) {
|
|||||||
// overflow of single subframes */
|
// overflow of single subframes */
|
||||||
// };
|
// };
|
||||||
|
|
||||||
std::vector<std::string> Detector::getReadoutFlags() {
|
std::vector<std::string> DetectorPythonInterface::getReadoutFlags() {
|
||||||
std::vector<std::string> flags;
|
std::vector<std::string> flags;
|
||||||
auto r = det.setReadOutFlags();
|
auto r = det.setReadOutFlags();
|
||||||
if (r & slsDetectorDefs::readOutFlags::STORE_IN_RAM)
|
if (r & slsDetectorDefs::readOutFlags::STORE_IN_RAM)
|
||||||
@ -953,7 +953,7 @@ std::vector<std::string> Detector::getReadoutFlags() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// note singular
|
// note singular
|
||||||
void Detector::setReadoutFlag(const std::string flag_name) {
|
void DetectorPythonInterface::setReadoutFlag(const std::string flag_name) {
|
||||||
if (flag_name == "none")
|
if (flag_name == "none")
|
||||||
det.setReadOutFlags(slsDetectorDefs::readOutFlags::NORMAL_READOUT);
|
det.setReadOutFlags(slsDetectorDefs::readOutFlags::NORMAL_READOUT);
|
||||||
else if (flag_name == "storeinram")
|
else if (flag_name == "storeinram")
|
||||||
@ -988,7 +988,7 @@ void Detector::setReadoutFlag(const std::string flag_name) {
|
|||||||
throw std::runtime_error("Flag name not recognized");
|
throw std::runtime_error("Flag name not recognized");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> Detector::getRateCorrection() {
|
std::vector<double> DetectorPythonInterface::getRateCorrection() {
|
||||||
std::vector<double> rate_corr;
|
std::vector<double> rate_corr;
|
||||||
for (int i = 0; i < det.getNumberOfDetectors(); ++i) {
|
for (int i = 0; i < det.getNumberOfDetectors(); ++i) {
|
||||||
rate_corr.push_back(det.getRateCorrection(i));
|
rate_corr.push_back(det.getRateCorrection(i));
|
||||||
@ -996,7 +996,7 @@ std::vector<double> Detector::getRateCorrection() {
|
|||||||
return rate_corr;
|
return rate_corr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Detector::pulseAllPixels(int n) {
|
void DetectorPythonInterface::pulseAllPixels(int n) {
|
||||||
// int pulsePixelNMove(int n=0,int x=0,int y=0);
|
// int pulsePixelNMove(int n=0,int x=0,int y=0);
|
||||||
// int pulsePixel(int n=0,int x=0,int y=0);
|
// int pulsePixel(int n=0,int x=0,int y=0);
|
||||||
|
|
||||||
@ -1008,7 +1008,7 @@ void Detector::pulseAllPixels(int n) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void Detector::pulseDiagonal(int n) {
|
void DetectorPythonInterface::pulseDiagonal(int n) {
|
||||||
// int pulsePixelNMove(int n=0,int x=0,int y=0);
|
// int pulsePixelNMove(int n=0,int x=0,int y=0);
|
||||||
// int pulsePixel(int n=0,int x=0,int y=0);
|
// int pulsePixel(int n=0,int x=0,int y=0);
|
||||||
|
|
19
python/src/enums.cpp
Normal file
19
python/src/enums.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <pybind11/chrono.h>
|
||||||
|
#include <pybind11/operators.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
|
#include "sls_detector_defs.h"
|
||||||
|
namespace py = pybind11;
|
||||||
|
void init_enums(py::module &m) {
|
||||||
|
py::class_<slsDetectorDefs> Defs(m, "slsDetectorDefs");
|
||||||
|
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")
|
||||||
|
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
|
||||||
|
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
|
||||||
|
.value("WAITING", slsDetectorDefs::runStatus::WAITING)
|
||||||
|
.value("RUN_FINISHED", slsDetectorDefs::runStatus::RUN_FINISHED)
|
||||||
|
.value("TRANSMITTING", slsDetectorDefs::runStatus::TRANSMITTING)
|
||||||
|
.value("RUNNING", slsDetectorDefs::runStatus::RUNNING)
|
||||||
|
.value("STOPPED", slsDetectorDefs::runStatus::STOPPED)
|
||||||
|
.export_values();
|
||||||
|
}
|
70
python/src/experimental.cpp
Normal file
70
python/src/experimental.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <pybind11/chrono.h>
|
||||||
|
#include <pybind11/operators.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
|
#include "Detector.h"
|
||||||
|
#include "sls_detector_defs.h"
|
||||||
|
#include "typecaster.h"
|
||||||
|
namespace py = pybind11;
|
||||||
|
void init_experimental(py::module &m) {
|
||||||
|
// Experimental API to use the multi directly and inherit from to reduce
|
||||||
|
// code duplication need to investigate how to handle documentation
|
||||||
|
using sls::Detector;
|
||||||
|
using sls::Positions;
|
||||||
|
py::class_<Detector> multiDetectorApi(m, "multiDetectorApi");
|
||||||
|
multiDetectorApi
|
||||||
|
.def(py::init<int>())
|
||||||
|
|
||||||
|
// Acq related
|
||||||
|
.def("acquire", &Detector::acquire)
|
||||||
|
.def("startReceiver", &Detector::startReceiver, py::arg() = Positions{})
|
||||||
|
.def("stopReceiver", &Detector::stopReceiver, py::arg() = Positions{})
|
||||||
|
.def("getAcquiringFlag", &Detector::getAcquiringFlag)
|
||||||
|
.def("setAcquiringFlag", &Detector::setAcquiringFlag)
|
||||||
|
.def("getReceiverStatus", &Detector::getReceiverStatus,
|
||||||
|
py::arg() = Positions{})
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
.def("free", &Detector::freeSharedMemory)
|
||||||
|
.def("setConfig", &Detector::setConfig)
|
||||||
|
.def("getHostname", &Detector::getHostname, py::arg() = Positions{})
|
||||||
|
|
||||||
|
// Bits and registers
|
||||||
|
.def("setBit", &Detector::setBit, py::arg(), py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("clearBit", &Detector::clearBit, py::arg(), py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getRegister", &Detector::getRegister, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
|
||||||
|
.def("getStartingFrameNumber", &Detector::getStartingFrameNumber,
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("setStartingFrameNumber", &Detector::setStartingFrameNumber,
|
||||||
|
py::arg(), py::arg() = Positions{})
|
||||||
|
|
||||||
|
// File
|
||||||
|
.def("getFileName", &Detector::getFileName)
|
||||||
|
.def("setFileName", &Detector::setFileName, py::arg())
|
||||||
|
.def("getFilePath", &Detector::getFilePath)
|
||||||
|
.def("setFilePath", &Detector::setFilePath, py::arg())
|
||||||
|
.def("setFileWrite", &Detector::setFileWrite, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getFileWrite", &Detector::getFileWrite, py::arg() = Positions{})
|
||||||
|
.def("setFileOverWrite", &Detector::setFileOverWrite, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getFileOverWrite", &Detector::getFileOverWrite,
|
||||||
|
py::arg() = Positions{})
|
||||||
|
|
||||||
|
// Time
|
||||||
|
.def("setExptime", &Detector::setExptime, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getExptime", &Detector::getExptime, py::arg() = Positions{})
|
||||||
|
.def("setPeriod", &Detector::setPeriod, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getPeriod", &Detector::getPeriod, py::arg() = Positions{})
|
||||||
|
.def("setSubExptime", &Detector::setSubExptime, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getSubExptime", &Detector::getSubExptime,
|
||||||
|
py::arg() = Positions{});
|
||||||
|
}
|
@ -1,12 +1,31 @@
|
|||||||
|
#include <pybind11/chrono.h>
|
||||||
#include <pybind11/operators.h>
|
#include <pybind11/operators.h>
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
#include "Detector.h"
|
#include "Detector.h"
|
||||||
|
#include "DetectorPythonInterface.h"
|
||||||
|
#include "Result.h"
|
||||||
#include "mythenFileIO.h"
|
#include "mythenFileIO.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "typecaster.h"
|
||||||
|
|
||||||
|
// // Add type_typecaster to pybind for our wrapper type
|
||||||
|
// namespace pybind11 {
|
||||||
|
// namespace detail {
|
||||||
|
// template <typename Type, typename Alloc>
|
||||||
|
// struct type_caster<sls::Result<Type, Alloc>>
|
||||||
|
// : list_caster<sls::Result<Type, Alloc>, Type> {};
|
||||||
|
// } // namespace detail
|
||||||
|
// } // namespace pybind11
|
||||||
|
|
||||||
|
using ds = std::chrono::duration<double>;
|
||||||
|
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
|
void init_enums(py::module &);
|
||||||
|
void init_experimental(py::module &);
|
||||||
PYBIND11_MODULE(_sls_detector, m) {
|
PYBIND11_MODULE(_sls_detector, m) {
|
||||||
m.doc() = R"pbdoc(
|
m.doc() = R"pbdoc(
|
||||||
C/C++ API
|
C/C++ API
|
||||||
@ -18,7 +37,10 @@ PYBIND11_MODULE(_sls_detector, m) {
|
|||||||
|
|
||||||
)pbdoc";
|
)pbdoc";
|
||||||
|
|
||||||
py::class_<Detector> DetectorApi(m, "DetectorApi", R"pbdoc(
|
init_enums(m);
|
||||||
|
init_experimental(m);
|
||||||
|
|
||||||
|
py::class_<DetectorPythonInterface> DetectorApi(m, "DetectorApi", R"pbdoc(
|
||||||
Interface to the multiSlsDetector class through Detector.h These functions
|
Interface to the multiSlsDetector class through Detector.h These functions
|
||||||
are used by the python classes Eiger and Jungfrau and normally it is better
|
are used by the python classes Eiger and Jungfrau and normally it is better
|
||||||
to use them than to directly access functions here.
|
to use them than to directly access functions here.
|
||||||
@ -43,298 +65,283 @@ PYBIND11_MODULE(_sls_detector, m) {
|
|||||||
|
|
||||||
)pbdoc");
|
)pbdoc");
|
||||||
DetectorApi.def(py::init<int>())
|
DetectorApi.def(py::init<int>())
|
||||||
.def("freeSharedMemory", &Detector::freeSharedMemory)
|
.def("freeSharedMemory", &DetectorPythonInterface::freeSharedMemory)
|
||||||
.def("getMultiDetectorId", &Detector::getMultiDetectorId)
|
.def("getMultiDetectorId", &DetectorPythonInterface::getMultiDetectorId)
|
||||||
.def("acq", &Detector::acquire)
|
.def("acq", &DetectorPythonInterface::acquire)
|
||||||
.def("getAcquiringFlag", &Detector::getAcquiringFlag)
|
.def("getAcquiringFlag", &DetectorPythonInterface::getAcquiringFlag)
|
||||||
.def("setAcquiringFlag", &Detector::setAcquiringFlag)
|
.def("setAcquiringFlag", &DetectorPythonInterface::setAcquiringFlag)
|
||||||
|
|
||||||
.def("setAllTrimbits", &Detector::setAllTrimbits)
|
.def("setAllTrimbits", &DetectorPythonInterface::setAllTrimbits)
|
||||||
.def("getAllTrimbits", &Detector::getAllTrimbits)
|
.def("getAllTrimbits", &DetectorPythonInterface::getAllTrimbits)
|
||||||
.def("setCounterBit", &Detector::setCounterBit)
|
.def("setCounterBit", &DetectorPythonInterface::setCounterBit)
|
||||||
.def("getCounterBit", &Detector::getCounterBit)
|
.def("getCounterBit", &DetectorPythonInterface::getCounterBit)
|
||||||
|
|
||||||
.def("getAdc", &Detector::getAdc)
|
.def("getAdc", &DetectorPythonInterface::getAdc)
|
||||||
.def("getDac", &Detector::getDac)
|
.def("getDac", &DetectorPythonInterface::getDac)
|
||||||
.def("getDac_mV", &Detector::getDac_mV)
|
.def("getDac_mV", &DetectorPythonInterface::getDac_mV)
|
||||||
.def("setDac", &Detector::setDac)
|
.def("setDac", &DetectorPythonInterface::setDac)
|
||||||
.def("setDac_mV", &Detector::setDac_mV)
|
.def("setDac_mV", &DetectorPythonInterface::setDac_mV)
|
||||||
.def("getDacFromIndex", &Detector::getDacFromIndex)
|
.def("getDacFromIndex", &DetectorPythonInterface::getDacFromIndex)
|
||||||
.def("setDacFromIndex", &Detector::setDacFromIndex)
|
.def("setDacFromIndex", &DetectorPythonInterface::setDacFromIndex)
|
||||||
|
|
||||||
.def("getDbitPipeline", &Detector::getDbitPipeline)
|
.def("getDbitPipeline", &DetectorPythonInterface::getDbitPipeline)
|
||||||
.def("setDbitPipeline", &Detector::setDbitPipeline)
|
.def("setDbitPipeline", &DetectorPythonInterface::setDbitPipeline)
|
||||||
.def("getDbitPhase", &Detector::getDbitPhase)
|
.def("getDbitPhase", &DetectorPythonInterface::getDbitPhase)
|
||||||
.def("setDbitPhase", &Detector::setDbitPhase)
|
.def("setDbitPhase", &DetectorPythonInterface::setDbitPhase)
|
||||||
.def("getDbitClock", &Detector::getDbitClock)
|
.def("getDbitClock", &DetectorPythonInterface::getDbitClock)
|
||||||
.def("setDbitClock", &Detector::setDbitClock)
|
.def("setDbitClock", &DetectorPythonInterface::setDbitClock)
|
||||||
|
|
||||||
.def("setThresholdEnergy", &Detector::setThresholdEnergy)
|
.def("setThresholdEnergy", &DetectorPythonInterface::setThresholdEnergy)
|
||||||
.def("getThresholdEnergy", &Detector::getThresholdEnergy)
|
.def("getThresholdEnergy", &DetectorPythonInterface::getThresholdEnergy)
|
||||||
|
|
||||||
.def("getSettings", &Detector::getSettings)
|
.def("getSettings", &DetectorPythonInterface::getSettings)
|
||||||
.def("setSettings", &Detector::setSettings)
|
.def("setSettings", &DetectorPythonInterface::setSettings)
|
||||||
.def("getSettingsDir", &Detector::getSettingsDir)
|
.def("getSettingsDir", &DetectorPythonInterface::getSettingsDir)
|
||||||
.def("setSettingsDir", &Detector::setSettingsDir)
|
.def("setSettingsDir", &DetectorPythonInterface::setSettingsDir)
|
||||||
|
|
||||||
.def("loadTrimbitFile", &Detector::loadTrimbitFile)
|
.def("loadTrimbitFile", &DetectorPythonInterface::loadTrimbitFile)
|
||||||
.def("setTrimEnergies", &Detector::setTrimEnergies)
|
.def("setTrimEnergies", &DetectorPythonInterface::setTrimEnergies)
|
||||||
.def("getTrimEnergies", &Detector::getTrimEnergies)
|
.def("getTrimEnergies", &DetectorPythonInterface::getTrimEnergies)
|
||||||
|
|
||||||
.def("pulseChip", &Detector::pulseChip)
|
.def("pulseChip", &DetectorPythonInterface::pulseChip)
|
||||||
.def("pulseAllPixels", &Detector::pulseAllPixels)
|
.def("pulseAllPixels", &DetectorPythonInterface::pulseAllPixels)
|
||||||
.def("pulseDiagonal", &Detector::pulseDiagonal)
|
.def("pulseDiagonal", &DetectorPythonInterface::pulseDiagonal)
|
||||||
.def("getRunStatus", &Detector::getRunStatus)
|
.def("getRunStatus", &DetectorPythonInterface::getRunStatus)
|
||||||
.def("readConfigurationFile", &Detector::readConfigurationFile)
|
.def("readConfigurationFile",
|
||||||
.def("readParametersFile", &Detector::readParametersFile)
|
&DetectorPythonInterface::readConfigurationFile)
|
||||||
.def("checkOnline", &Detector::checkOnline)
|
.def("readParametersFile", &DetectorPythonInterface::readParametersFile)
|
||||||
.def("setReadoutClockSpeed", &Detector::setReadoutClockSpeed)
|
.def("checkOnline", &DetectorPythonInterface::checkOnline)
|
||||||
.def("getReadoutClockSpeed", &Detector::getReadoutClockSpeed)
|
.def("setReadoutClockSpeed",
|
||||||
.def("getSyncClkSpeed", &Detector::getSyncClkSpeed)
|
&DetectorPythonInterface::setReadoutClockSpeed)
|
||||||
.def("getHostname", &Detector::getHostname)
|
.def("getReadoutClockSpeed",
|
||||||
.def("setHostname", &Detector::setHostname)
|
&DetectorPythonInterface::getReadoutClockSpeed)
|
||||||
|
.def("getSyncClkSpeed", &DetectorPythonInterface::getSyncClkSpeed)
|
||||||
|
.def("getHostname", &DetectorPythonInterface::getHostname)
|
||||||
|
.def("setHostname", &DetectorPythonInterface::setHostname)
|
||||||
|
|
||||||
.def("getReceiverPort", &Detector::getReceiverPort)
|
.def("getReceiverPort", &DetectorPythonInterface::getReceiverPort)
|
||||||
.def("setReceiverPort", &Detector::setReceiverPort)
|
.def("setReceiverPort", &DetectorPythonInterface::setReceiverPort)
|
||||||
|
|
||||||
.def("isChipPowered", &Detector::isChipPowered)
|
.def("isChipPowered", &DetectorPythonInterface::isChipPowered)
|
||||||
.def("powerChip", &Detector::powerChip)
|
.def("powerChip", &DetectorPythonInterface::powerChip)
|
||||||
|
|
||||||
.def("readRegister", &Detector::readRegister)
|
.def("readRegister", &DetectorPythonInterface::readRegister)
|
||||||
.def("writeRegister", &Detector::writeRegister)
|
.def("writeRegister", &DetectorPythonInterface::writeRegister)
|
||||||
.def("writeAdcRegister", &Detector::writeAdcRegister)
|
.def("writeAdcRegister", &DetectorPythonInterface::writeAdcRegister)
|
||||||
.def("setBitInRegister", &Detector::setBitInRegister)
|
.def("setBitInRegister", &DetectorPythonInterface::setBitInRegister)
|
||||||
.def("clearBitInRegister", &Detector::clearBitInRegister)
|
.def("clearBitInRegister", &DetectorPythonInterface::clearBitInRegister)
|
||||||
|
|
||||||
.def("setDynamicRange", &Detector::setDynamicRange)
|
.def("setDynamicRange", &DetectorPythonInterface::setDynamicRange)
|
||||||
.def("getDynamicRange", &Detector::getDynamicRange)
|
.def("getDynamicRange", &DetectorPythonInterface::getDynamicRange)
|
||||||
.def("getFirmwareVersion", &Detector::getFirmwareVersion)
|
.def("getFirmwareVersion", &DetectorPythonInterface::getFirmwareVersion)
|
||||||
.def("getServerVersion", &Detector::getServerVersion)
|
.def("getServerVersion", &DetectorPythonInterface::getServerVersion)
|
||||||
.def("getClientVersion", &Detector::getClientVersion)
|
.def("getClientVersion", &DetectorPythonInterface::getClientVersion)
|
||||||
.def("getReceiverVersion", &Detector::getReceiverVersion)
|
.def("getReceiverVersion", &DetectorPythonInterface::getReceiverVersion)
|
||||||
.def("getDetectorNumber", &Detector::getDetectorNumber)
|
.def("getDetectorNumber", &DetectorPythonInterface::getDetectorNumber)
|
||||||
.def("getRateCorrection", &Detector::getRateCorrection)
|
.def("getRateCorrection", &DetectorPythonInterface::getRateCorrection)
|
||||||
.def("setRateCorrection", &Detector::setRateCorrection)
|
.def("setRateCorrection", &DetectorPythonInterface::setRateCorrection)
|
||||||
|
|
||||||
.def("startAcquisition", &Detector::startAcquisition)
|
.def("startAcquisition", &DetectorPythonInterface::startAcquisition)
|
||||||
.def("stopAcquisition", &Detector::stopAcquisition)
|
.def("stopAcquisition", &DetectorPythonInterface::stopAcquisition)
|
||||||
.def("startReceiver", &Detector::startReceiver)
|
.def("startReceiver", &DetectorPythonInterface::startReceiver)
|
||||||
.def("stopReceiver", &Detector::stopReceiver)
|
.def("stopReceiver", &DetectorPythonInterface::stopReceiver)
|
||||||
|
|
||||||
.def("getFilePath",
|
.def("getFilePath",
|
||||||
(std::string(Detector::*)()) & Detector::getFilePath,
|
(std::string(DetectorPythonInterface::*)()) &
|
||||||
|
DetectorPythonInterface::getFilePath,
|
||||||
"Using multiSlsDetector")
|
"Using multiSlsDetector")
|
||||||
.def("getFilePath",
|
.def("getFilePath",
|
||||||
(std::string(Detector::*)(int)) & Detector::getFilePath,
|
(std::string(DetectorPythonInterface::*)(int)) &
|
||||||
|
DetectorPythonInterface::getFilePath,
|
||||||
"File path for individual detector")
|
"File path for individual detector")
|
||||||
.def("setFilePath",
|
.def("setFilePath", (void (DetectorPythonInterface::*)(std::string)) &
|
||||||
(void (Detector::*)(std::string)) & Detector::setFilePath)
|
DetectorPythonInterface::setFilePath)
|
||||||
.def("setFilePath",
|
|
||||||
(void (Detector::*)(std::string, int)) & Detector::setFilePath)
|
|
||||||
|
|
||||||
.def("setFileName", &Detector::setFileName)
|
.def("setFileName", &DetectorPythonInterface::setFileName)
|
||||||
.def("getFileName", &Detector::getFileName)
|
.def("getFileName", &DetectorPythonInterface::getFileName)
|
||||||
.def("setFileIndex", &Detector::setFileIndex)
|
.def("setFileIndex", &DetectorPythonInterface::setFileIndex)
|
||||||
.def("getFileIndex", &Detector::getFileIndex)
|
.def("getFileIndex", &DetectorPythonInterface::getFileIndex)
|
||||||
|
|
||||||
.def("setExposureTime", &Detector::setExposureTime)
|
.def("setExposureTime", &DetectorPythonInterface::setExposureTime)
|
||||||
.def("getExposureTime", &Detector::getExposureTime)
|
.def("getExposureTime", &DetectorPythonInterface::getExposureTime)
|
||||||
.def("setSubExposureTime", &Detector::setSubExposureTime)
|
.def("setSubExposureTime", &DetectorPythonInterface::setSubExposureTime)
|
||||||
.def("getSubExposureTime", &Detector::getSubExposureTime)
|
.def("getSubExposureTime", &DetectorPythonInterface::getSubExposureTime)
|
||||||
.def("setPeriod", &Detector::setPeriod)
|
.def("setPeriod", &DetectorPythonInterface::setPeriod)
|
||||||
.def("getPeriod", &Detector::getPeriod)
|
.def("getPeriod", &DetectorPythonInterface::getPeriod)
|
||||||
.def("setSubExposureDeadTime", &Detector::setSubExposureDeadTime)
|
.def("setSubExposureDeadTime", &DetectorPythonInterface::setSubExposureDeadTime)
|
||||||
.def("getSubExposureDeadTime", &Detector::getSubExposureDeadTime)
|
.def("getSubExposureDeadTime", &DetectorPythonInterface::getSubExposureDeadTime)
|
||||||
|
|
||||||
.def("getCycles", &Detector::getCycles)
|
.def("getCycles", &DetectorPythonInterface::getCycles)
|
||||||
.def("setCycles", &Detector::setCycles)
|
.def("setCycles", &DetectorPythonInterface::setCycles)
|
||||||
.def("getNumberOfGates", &Detector::getNumberOfGates)
|
.def("getNumberOfGates", &DetectorPythonInterface::getNumberOfGates)
|
||||||
.def("setNumberOfGates", &Detector::setNumberOfGates)
|
.def("setNumberOfGates", &DetectorPythonInterface::setNumberOfGates)
|
||||||
.def("getDelay", &Detector::getDelay)
|
.def("getDelay", &DetectorPythonInterface::getDelay)
|
||||||
.def("setDelay", &Detector::setDelay)
|
.def("setDelay", &DetectorPythonInterface::setDelay)
|
||||||
|
|
||||||
.def("setStoragecellStart", &Detector::setStoragecellStart)
|
.def("setStoragecellStart", &DetectorPythonInterface::setStoragecellStart)
|
||||||
.def("getStoragecellStart", &Detector::getStoragecellStart)
|
.def("getStoragecellStart", &DetectorPythonInterface::getStoragecellStart)
|
||||||
.def("setNumberOfStorageCells", &Detector::setNumberOfStorageCells)
|
.def("setNumberOfStorageCells", &DetectorPythonInterface::setNumberOfStorageCells)
|
||||||
.def("getNumberOfStorageCells", &Detector::getNumberOfStorageCells)
|
.def("getNumberOfStorageCells", &DetectorPythonInterface::getNumberOfStorageCells)
|
||||||
|
|
||||||
.def("getTimingMode", &Detector::getTimingMode)
|
.def("getTimingMode", &DetectorPythonInterface::getTimingMode)
|
||||||
.def("setTimingMode", &Detector::setTimingMode)
|
.def("setTimingMode", &DetectorPythonInterface::setTimingMode)
|
||||||
|
|
||||||
.def("getDetectorType", &Detector::getDetectorType)
|
.def("getDetectorType", &DetectorPythonInterface::getDetectorType)
|
||||||
|
|
||||||
.def("setThresholdTemperature", &Detector::setThresholdTemperature)
|
.def("setThresholdTemperature", &DetectorPythonInterface::setThresholdTemperature)
|
||||||
.def("getThresholdTemperature", &Detector::getThresholdTemperature)
|
.def("getThresholdTemperature", &DetectorPythonInterface::getThresholdTemperature)
|
||||||
.def("setTemperatureControl", &Detector::setTemperatureControl)
|
.def("setTemperatureControl", &DetectorPythonInterface::setTemperatureControl)
|
||||||
.def("getTemperatureControl", &Detector::getTemperatureControl)
|
.def("getTemperatureControl", &DetectorPythonInterface::getTemperatureControl)
|
||||||
.def("getTemperatureEvent", &Detector::getTemperatureEvent)
|
.def("getTemperatureEvent", &DetectorPythonInterface::getTemperatureEvent)
|
||||||
.def("resetTemperatureEvent", &Detector::resetTemperatureEvent)
|
.def("resetTemperatureEvent", &DetectorPythonInterface::resetTemperatureEvent)
|
||||||
|
|
||||||
.def("getRxDataStreamStatus", &Detector::getRxDataStreamStatus)
|
.def("getRxDataStreamStatus", &DetectorPythonInterface::getRxDataStreamStatus)
|
||||||
.def("setRxDataStreamStatus", &Detector::setRxDataStreamStatus)
|
.def("setRxDataStreamStatus", &DetectorPythonInterface::setRxDataStreamStatus)
|
||||||
|
|
||||||
// Network stuff
|
// Network stuff
|
||||||
.def("getReceiverHostname", &Detector::getReceiverHostname,
|
.def("getReceiverHostname",
|
||||||
|
&DetectorPythonInterface::getReceiverHostname,
|
||||||
py::arg("det_id") = -1)
|
py::arg("det_id") = -1)
|
||||||
.def("setReceiverHostname", &Detector::setReceiverHostname,
|
.def("setReceiverHostname",
|
||||||
py::arg("hostname"), py::arg("det_id") = -1)
|
&DetectorPythonInterface::setReceiverHostname, py::arg("hostname"),
|
||||||
.def("getReceiverStreamingPort", &Detector::getReceiverStreamingPort)
|
py::arg("det_id") = -1)
|
||||||
.def("setReceiverStreamingPort", &Detector::setReceiverStreamingPort)
|
.def("getReceiverStreamingPort",
|
||||||
.def("getReceiverUDPPort", &Detector::getReceiverUDPPort)
|
&DetectorPythonInterface::getReceiverStreamingPort)
|
||||||
.def("getReceiverUDPPort2", &Detector::getReceiverUDPPort2)
|
.def("setReceiverStreamingPort",
|
||||||
.def("setReceiverUDPPort", &Detector::setReceiverUDPPort)
|
&DetectorPythonInterface::setReceiverStreamingPort)
|
||||||
.def("setReceiverUDPPort2", &Detector::setReceiverUDPPort2)
|
.def("getReceiverUDPPort", &DetectorPythonInterface::getReceiverUDPPort)
|
||||||
.def("setReceiverUDPIP", &Detector::setReceiverUDPIP)
|
.def("getReceiverUDPPort2",
|
||||||
.def("getReceiverUDPIP", &Detector::getReceiverUDPIP)
|
&DetectorPythonInterface::getReceiverUDPPort2)
|
||||||
.def("getReceiverUDPMAC", &Detector::getReceiverUDPMAC)
|
.def("setReceiverUDPPort", &DetectorPythonInterface::setReceiverUDPPort)
|
||||||
.def("setReceiverUDPMAC", &Detector::setReceiverUDPMAC)
|
.def("setReceiverUDPPort2",
|
||||||
|
&DetectorPythonInterface::setReceiverUDPPort2)
|
||||||
|
.def("setReceiverUDPIP", &DetectorPythonInterface::setReceiverUDPIP)
|
||||||
|
.def("getReceiverUDPIP", &DetectorPythonInterface::getReceiverUDPIP)
|
||||||
|
.def("getReceiverUDPMAC", &DetectorPythonInterface::getReceiverUDPMAC)
|
||||||
|
.def("setReceiverUDPMAC", &DetectorPythonInterface::setReceiverUDPMAC)
|
||||||
|
|
||||||
.def("getReceiverPort", &Detector::getReceiverPort)
|
.def("getReceiverPort", &DetectorPythonInterface::getReceiverPort)
|
||||||
.def("setReceiverPort", &Detector::setReceiverPort)
|
.def("setReceiverPort", &DetectorPythonInterface::setReceiverPort)
|
||||||
|
|
||||||
.def("configureNetworkParameters",
|
.def("configureNetworkParameters",
|
||||||
&Detector::configureNetworkParameters)
|
&DetectorPythonInterface::configureNetworkParameters)
|
||||||
.def("getDelayFrame", &Detector::getDelayFrame)
|
.def("getDelayFrame", &DetectorPythonInterface::getDelayFrame)
|
||||||
.def("setDelayFrame", &Detector::setDelayFrame)
|
.def("setDelayFrame", &DetectorPythonInterface::setDelayFrame)
|
||||||
.def("getDelayLeft", &Detector::getDelayLeft)
|
.def("getDelayLeft", &DetectorPythonInterface::getDelayLeft)
|
||||||
.def("setDelayLeft", &Detector::setDelayLeft)
|
.def("setDelayLeft", &DetectorPythonInterface::setDelayLeft)
|
||||||
.def("getDelayRight", &Detector::getDelayRight)
|
.def("getDelayRight", &DetectorPythonInterface::getDelayRight)
|
||||||
.def("setDelayRight", &Detector::setDelayRight)
|
.def("setDelayRight", &DetectorPythonInterface::setDelayRight)
|
||||||
.def("getLastClientIP", &Detector::getLastClientIP)
|
.def("getLastClientIP", &DetectorPythonInterface::getLastClientIP)
|
||||||
.def("getReceiverLastClientIP", &Detector::getReceiverLastClientIP)
|
.def("getReceiverLastClientIP",
|
||||||
|
&DetectorPythonInterface::getReceiverLastClientIP)
|
||||||
|
|
||||||
.def("setFramesPerFile", &Detector::setFramesPerFile)
|
.def("setFramesPerFile", &DetectorPythonInterface::setFramesPerFile)
|
||||||
.def("getFramesPerFile", &Detector::getFramesPerFile)
|
.def("getFramesPerFile", &DetectorPythonInterface::getFramesPerFile)
|
||||||
.def("setReceiverFifoDepth", &Detector::setReceiverFifoDepth)
|
.def("setReceiverFifoDepth",
|
||||||
.def("getReceiverFifoDepth", &Detector::getReceiverFifoDepth)
|
&DetectorPythonInterface::setReceiverFifoDepth)
|
||||||
|
.def("getReceiverFifoDepth",
|
||||||
|
&DetectorPythonInterface::getReceiverFifoDepth)
|
||||||
|
|
||||||
.def("getReceiverFrameDiscardPolicy",
|
.def("getReceiverFrameDiscardPolicy",
|
||||||
&Detector::getReceiverFrameDiscardPolicy)
|
&DetectorPythonInterface::getReceiverFrameDiscardPolicy)
|
||||||
.def("setReceiverFramesDiscardPolicy",
|
.def("setReceiverFramesDiscardPolicy",
|
||||||
&Detector::setReceiverFramesDiscardPolicy)
|
&DetectorPythonInterface::setReceiverFramesDiscardPolicy)
|
||||||
.def("setPartialFramesPadding", &Detector::setPartialFramesPadding)
|
.def("setPartialFramesPadding",
|
||||||
.def("getPartialFramesPadding", &Detector::getPartialFramesPadding)
|
&DetectorPythonInterface::setPartialFramesPadding)
|
||||||
|
.def("getPartialFramesPadding",
|
||||||
|
&DetectorPythonInterface::getPartialFramesPadding)
|
||||||
|
|
||||||
.def("getUserDetails", &Detector::getUserDetails)
|
.def("getUserDetails", &DetectorPythonInterface::getUserDetails)
|
||||||
.def("checkDetectorVersionCompatibility",
|
.def("checkDetectorVersionCompatibility",
|
||||||
&Detector::checkDetectorVersionCompatibility)
|
&DetectorPythonInterface::checkDetectorVersionCompatibility)
|
||||||
.def("checkReceiverVersionCompatibility",
|
.def("checkReceiverVersionCompatibility",
|
||||||
&Detector::checkReceiverVersionCompatibility)
|
&DetectorPythonInterface::checkReceiverVersionCompatibility)
|
||||||
.def("getMeasuredPeriod", &Detector::getMeasuredPeriod)
|
.def("getMeasuredPeriod", &DetectorPythonInterface::getMeasuredPeriod)
|
||||||
.def("getMeasuredSubPeriod", &Detector::getMeasuredSubPeriod)
|
.def("getMeasuredSubPeriod",
|
||||||
|
&DetectorPythonInterface::getMeasuredSubPeriod)
|
||||||
|
|
||||||
.def("setFileWrite", &Detector::setFileWrite)
|
.def("setFileWrite", &DetectorPythonInterface::setFileWrite)
|
||||||
.def("getFileWrite", &Detector::getFileWrite)
|
.def("getFileWrite", &DetectorPythonInterface::getFileWrite)
|
||||||
.def("setFileOverWrite", &Detector::setFileOverWrite)
|
.def("setFileOverWrite", &DetectorPythonInterface::setFileOverWrite)
|
||||||
.def("getFileOverWrite", &Detector::getFileOverWrite)
|
.def("getFileOverWrite", &DetectorPythonInterface::getFileOverWrite)
|
||||||
.def("getDacVthreshold", &Detector::getDacVthreshold)
|
.def("getDacVthreshold", &DetectorPythonInterface::getDacVthreshold)
|
||||||
.def("setDacVthreshold", &Detector::setDacVthreshold)
|
.def("setDacVthreshold", &DetectorPythonInterface::setDacVthreshold)
|
||||||
.def("setNumberOfFrames", &Detector::setNumberOfFrames)
|
.def("setNumberOfFrames", &DetectorPythonInterface::setNumberOfFrames)
|
||||||
.def("getNumberOfFrames", &Detector::getNumberOfFrames)
|
.def("getNumberOfFrames", &DetectorPythonInterface::getNumberOfFrames)
|
||||||
|
|
||||||
// Overloaded calls
|
// Overloaded calls
|
||||||
.def("getFramesCaughtByReceiver",
|
.def("getFramesCaughtByReceiver",
|
||||||
(int (Detector::*)()) & Detector::getFramesCaughtByReceiver)
|
(int (DetectorPythonInterface::*)()) &
|
||||||
|
DetectorPythonInterface::getFramesCaughtByReceiver)
|
||||||
.def("getFramesCaughtByReceiver",
|
.def("getFramesCaughtByReceiver",
|
||||||
(int (Detector::*)(int)) & Detector::getFramesCaughtByReceiver)
|
(int (DetectorPythonInterface::*)(int)) &
|
||||||
|
DetectorPythonInterface::getFramesCaughtByReceiver)
|
||||||
|
|
||||||
.def("resetFramesCaught", &Detector::resetFramesCaught)
|
.def("resetFramesCaught", &DetectorPythonInterface::resetFramesCaught)
|
||||||
.def("getReceiverCurrentFrameIndex",
|
.def("getReceiverCurrentFrameIndex",
|
||||||
&Detector::getReceiverCurrentFrameIndex)
|
&DetectorPythonInterface::getReceiverCurrentFrameIndex)
|
||||||
.def("getGapPixels", &Detector::getGapPixels)
|
.def("getGapPixels", &DetectorPythonInterface::getGapPixels)
|
||||||
.def("setGapPixels", &Detector::setGapPixels)
|
.def("setGapPixels", &DetectorPythonInterface::setGapPixels)
|
||||||
.def("getFlippedDataX", &Detector::getFlippedDataX)
|
.def("getFlippedDataX", &DetectorPythonInterface::getFlippedDataX)
|
||||||
.def("getFlippedDataY", &Detector::getFlippedDataY)
|
.def("getFlippedDataY", &DetectorPythonInterface::getFlippedDataY)
|
||||||
.def("setFlippedDataX", &Detector::setFlippedDataX)
|
.def("setFlippedDataX", &DetectorPythonInterface::setFlippedDataX)
|
||||||
.def("setFlippedDataY", &Detector::setFlippedDataY)
|
.def("setFlippedDataY", &DetectorPythonInterface::setFlippedDataY)
|
||||||
|
|
||||||
.def("getServerLock", &Detector::getServerLock)
|
.def("getServerLock", &DetectorPythonInterface::getServerLock)
|
||||||
.def("setServerLock", &Detector::setServerLock)
|
.def("setServerLock", &DetectorPythonInterface::setServerLock)
|
||||||
.def("getReceiverLock", &Detector::getReceiverLock)
|
.def("getReceiverLock", &DetectorPythonInterface::getReceiverLock)
|
||||||
.def("setReceiverLock", &Detector::setReceiverLock)
|
.def("setReceiverLock", &DetectorPythonInterface::setReceiverLock)
|
||||||
|
|
||||||
.def("getReadoutFlags", &Detector::getReadoutFlags)
|
.def("getReadoutFlags", &DetectorPythonInterface::getReadoutFlags)
|
||||||
.def("setReadoutFlag", &Detector::setReadoutFlag)
|
.def("setReadoutFlag", &DetectorPythonInterface::setReadoutFlag)
|
||||||
|
|
||||||
.def("setFileFormat", &Detector::setFileFormat)
|
.def("setFileFormat", &DetectorPythonInterface::setFileFormat)
|
||||||
.def("getFileFormat", &Detector::getFileFormat)
|
.def("getFileFormat", &DetectorPythonInterface::getFileFormat)
|
||||||
|
|
||||||
.def("getActive", &Detector::getActive)
|
.def("getActive", &DetectorPythonInterface::getActive)
|
||||||
.def("setActive", &Detector::setActive)
|
.def("setActive", &DetectorPythonInterface::setActive)
|
||||||
|
|
||||||
.def("getTenGigabitEthernet", &Detector::getTenGigabitEthernet)
|
.def("getTenGigabitEthernet",
|
||||||
.def("setTenGigabitEthernet", &Detector::setTenGigabitEthernet)
|
&DetectorPythonInterface::getTenGigabitEthernet)
|
||||||
|
.def("setTenGigabitEthernet",
|
||||||
|
&DetectorPythonInterface::setTenGigabitEthernet)
|
||||||
|
|
||||||
.def("getPatternLoops", &Detector::getPatternLoops, py::arg("level"),
|
.def("getPatternLoops", &DetectorPythonInterface::getPatternLoops,
|
||||||
|
py::arg("level"), py::arg("det_id") = -1)
|
||||||
|
.def("setPatternLoops", &DetectorPythonInterface::setPatternLoops,
|
||||||
|
py::arg("level"), py::arg("start"), py::arg("stop"), py::arg("n"),
|
||||||
py::arg("det_id") = -1)
|
py::arg("det_id") = -1)
|
||||||
.def("setPatternLoops", &Detector::setPatternLoops, py::arg("level"),
|
.def("setPatternWord", &DetectorPythonInterface::setPatternWord,
|
||||||
py::arg("start"), py::arg("stop"), py::arg("n"),
|
py::arg("addr"), py::arg("word"), py::arg("det_id") = -1)
|
||||||
|
.def("getPatternWord", &DetectorPythonInterface::getPatternWord,
|
||||||
|
py::arg("addr"), py::arg("det_id") = -1)
|
||||||
|
|
||||||
|
.def("setPatternIOControl",
|
||||||
|
&DetectorPythonInterface::setPatternIOControl, py::arg("word"),
|
||||||
py::arg("det_id") = -1)
|
py::arg("det_id") = -1)
|
||||||
.def("setPatternWord", &Detector::setPatternWord, py::arg("addr"),
|
.def("setPatternClockControl",
|
||||||
py::arg("word"), py::arg("det_id") = -1)
|
&DetectorPythonInterface::setPatternClockControl, py::arg("word"),
|
||||||
.def("getPatternWord", &Detector::getPatternWord, py::arg("addr"),
|
|
||||||
py::arg("det_id") = -1)
|
py::arg("det_id") = -1)
|
||||||
|
|
||||||
.def("setPatternIOControl", &Detector::setPatternIOControl,
|
.def("setPatternWaitAddr", &DetectorPythonInterface::setPatternWaitAddr,
|
||||||
py::arg("word"), py::arg("det_id") = -1)
|
|
||||||
.def("setPatternClockControl", &Detector::setPatternClockControl,
|
|
||||||
py::arg("word"), py::arg("det_id") = -1)
|
|
||||||
|
|
||||||
.def("setPatternWaitAddr", &Detector::setPatternWaitAddr,
|
|
||||||
py::arg("level"), py::arg("addr"), py::arg("det_id") = -1)
|
py::arg("level"), py::arg("addr"), py::arg("det_id") = -1)
|
||||||
.def("getPatternWaitAddr", &Detector::getPatternWaitAddr,
|
.def("getPatternWaitAddr", &DetectorPythonInterface::getPatternWaitAddr,
|
||||||
py::arg("level"), py::arg("det_id") = -1)
|
py::arg("level"), py::arg("det_id") = -1)
|
||||||
|
|
||||||
.def("setPatternWaitTime", &Detector::setPatternWaitTime,
|
.def("setPatternWaitTime", &DetectorPythonInterface::setPatternWaitTime,
|
||||||
py::arg("level"), py::arg("duration"), py::arg("det_id") = -1)
|
py::arg("level"), py::arg("duration"), py::arg("det_id") = -1)
|
||||||
|
|
||||||
.def("getPatternWaitTime", &Detector::getPatternWaitTime,
|
.def("getPatternWaitTime", &DetectorPythonInterface::getPatternWaitTime,
|
||||||
py::arg("level"), py::arg("det_id") = -1)
|
py::arg("level"), py::arg("det_id") = -1)
|
||||||
|
|
||||||
.def("getImageSize", &Detector::getImageSize)
|
.def("getImageSize", &DetectorPythonInterface::getImageSize)
|
||||||
.def("setImageSize", &Detector::setImageSize)
|
.def("setImageSize", &DetectorPythonInterface::setImageSize)
|
||||||
.def("getNumberOfDetectors", &Detector::getNumberOfDetectors)
|
.def("getNumberOfDetectors",
|
||||||
.def("getDetectorGeometry", &Detector::getDetectorGeometry);
|
&DetectorPythonInterface::getNumberOfDetectors)
|
||||||
|
.def("getDetectorGeometry",
|
||||||
|
&DetectorPythonInterface::getDetectorGeometry);
|
||||||
|
|
||||||
// Experimental API to use the multi directly and inherit from to reduce
|
|
||||||
// code duplication need to investigate how to handle documentation
|
|
||||||
py::class_<multiSlsDetector> multiDetectorApi(m, "multiDetectorApi");
|
|
||||||
multiDetectorApi.def(py::init<int>())
|
|
||||||
.def("acquire", &multiSlsDetector::acquire)
|
|
||||||
|
|
||||||
.def_property("exptime",
|
|
||||||
py::cpp_function(&multiSlsDetector::setExposureTime,
|
|
||||||
py::arg(), py::arg() = -1, py::arg() = 0,
|
|
||||||
py::arg("det_id") = -1),
|
|
||||||
py::cpp_function(&multiSlsDetector::setExposureTime,
|
|
||||||
py::arg(), py::arg() = -1, py::arg() = 0,
|
|
||||||
py::arg("det_id") = -1))
|
|
||||||
.def("getExposureTime", &multiSlsDetector::setExposureTime, py::arg()=-1,
|
|
||||||
py::arg() = 0, py::arg("det_id") = -1)
|
|
||||||
.def_property_readonly(
|
|
||||||
"hostname", py::cpp_function(&multiSlsDetector::getHostname,
|
|
||||||
py::arg(), py::arg("det_id") = -1))
|
|
||||||
.def_property("busy",
|
|
||||||
py::cpp_function(&multiSlsDetector::getAcquiringFlag),
|
|
||||||
py::cpp_function(&multiSlsDetector::setAcquiringFlag))
|
|
||||||
.def_property_readonly(
|
|
||||||
"rx_tcpport", py::cpp_function(&multiSlsDetector::getReceiverPort))
|
|
||||||
.def_property_readonly(
|
|
||||||
"detectornumber",
|
|
||||||
py::cpp_function(&multiSlsDetector::getDetectorNumber))
|
|
||||||
.def_property("rx_udpip",
|
|
||||||
py::cpp_function(&multiSlsDetector::getReceiverUDPIP,
|
|
||||||
py::arg(), py::arg("det_id") = -1),
|
|
||||||
py::cpp_function(&multiSlsDetector::setReceiverUDPIP,
|
|
||||||
py::arg(), py::arg("ip"),
|
|
||||||
py::arg("det_id") = -1))
|
|
||||||
.def("_getReceiverUDPIP", &multiSlsDetector::getReceiverUDPIP)
|
|
||||||
.def("_setReceiverUDPIP", &multiSlsDetector::setReceiverUDPIP)
|
|
||||||
.def("getPatternLoops", &multiSlsDetector::getPatternLoops,
|
|
||||||
py::arg("level"), py::arg("det_id") = -1)
|
|
||||||
.def("setPatternLoops", &multiSlsDetector::setPatternLoops)
|
|
||||||
.def("setPatternWord", &multiSlsDetector::setPatternWord,
|
|
||||||
py::arg("addr"), py::arg("word"), py::arg("det_id") = -1);
|
|
||||||
|
|
||||||
py::module io = m.def_submodule("io", "Submodule for io");
|
py::module io = m.def_submodule("io", "Submodule for io");
|
||||||
io.def("read_my302_file", &read_my302_file, "some");
|
io.def("read_my302_file", &read_my302_file, "some");
|
||||||
|
11
python/src/typecaster.h
Normal file
11
python/src/typecaster.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include "Result.h"
|
||||||
|
// Add type_typecaster to pybind for our wrapper type
|
||||||
|
namespace pybind11 {
|
||||||
|
namespace detail {
|
||||||
|
template <typename Type, typename Alloc>
|
||||||
|
struct type_caster<sls::Result<Type, Alloc>>
|
||||||
|
: list_caster<sls::Result<Type, Alloc>, Type> {};
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace pybind11
|
21
sample/CMakeLists.txt
Normal file
21
sample/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
add_executable(a api.cpp)
|
||||||
|
target_link_libraries(a
|
||||||
|
slsDetectorShared
|
||||||
|
slsSupportLib
|
||||||
|
pthread
|
||||||
|
rt
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(a PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(result useResult.cpp)
|
||||||
|
target_link_libraries(result
|
||||||
|
slsDetectorShared
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(result PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
|
)
|
67
sample/api.cpp
Normal file
67
sample/api.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "Detector.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const std::chrono::nanoseconds &t) {
|
||||||
|
os << t.count() << "ns";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename _ = void>
|
||||||
|
struct is_container : std::false_type {};
|
||||||
|
|
||||||
|
template <typename... Ts> struct is_container_helper {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_container<
|
||||||
|
T, typename std::conditional<
|
||||||
|
false,
|
||||||
|
is_container_helper<typename T::value_type, typename T::size_type,
|
||||||
|
typename T::iterator, typename T::const_iterator,
|
||||||
|
decltype(std::declval<T>().size()),
|
||||||
|
decltype(std::declval<T>().begin()),
|
||||||
|
decltype(std::declval<T>().end()),
|
||||||
|
decltype(std::declval<T>().cbegin()),
|
||||||
|
decltype(std::declval<T>().cend()),
|
||||||
|
decltype(std::declval<T>().empty())>,
|
||||||
|
void>::type> : public std::true_type {};
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
auto operator<<(std::ostream &os, const Container &con) ->
|
||||||
|
typename std::enable_if<is_container<Container>::value,
|
||||||
|
std::ostream &>::type {
|
||||||
|
if (con.empty())
|
||||||
|
return os << "[]";
|
||||||
|
auto it = con.cbegin();
|
||||||
|
os << '[' << *it++;
|
||||||
|
while (it != con.cend())
|
||||||
|
os << ", " << *it++;
|
||||||
|
return os << ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
using sls::Detector;
|
||||||
|
using std::chrono::nanoseconds;
|
||||||
|
using std::chrono::seconds;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Detector d;
|
||||||
|
d.setConfig("/home/l_frojdh/virtual.config");
|
||||||
|
|
||||||
|
// d.setExptime(nanoseconds(500)); // set exptime of all modules
|
||||||
|
// auto t0 = d.getExptime();
|
||||||
|
// std::cout << "exptime: " << t0 << '\n';
|
||||||
|
|
||||||
|
// d.setExptime(seconds(1), {1}); // set exptime of module one
|
||||||
|
// auto t1 = d.getExptime({1,3,5}); // get exptime of module 1, 3 and 5
|
||||||
|
// std::cout << "exptime: " <<t1 << '\n';
|
||||||
|
|
||||||
|
std::cout << "Period: " << d.getPeriod() << '\n';
|
||||||
|
std::cout << "Period: " << d.getPeriod().squash() << '\n';
|
||||||
|
// std::cout << "fname: " << d.getFname() << "\n";
|
||||||
|
|
||||||
|
// std::cout << "fwrite: " << std::boolalpha << d.getFwrite() << '\n';
|
||||||
|
|
||||||
|
// d.freeSharedMemory();
|
||||||
|
|
||||||
|
}
|
55
sample/useResult.cpp
Normal file
55
sample/useResult.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "Result.h"
|
||||||
|
#include "ToString.h"
|
||||||
|
|
||||||
|
auto main() -> int {
|
||||||
|
|
||||||
|
using sls::Result; // declared in namespace sls
|
||||||
|
using sls::ToString;
|
||||||
|
|
||||||
|
std::cout << "Examples on usage of Result<T>\n";
|
||||||
|
|
||||||
|
// Result exposes the underlying constructors of std::vector
|
||||||
|
Result<int> res{1, 2, 3, 4, 5};
|
||||||
|
std::cout << "res: " << res << '\n';
|
||||||
|
|
||||||
|
Result<double> res2(5, 3.7);
|
||||||
|
std::cout << "res2: " << res2 << '\n';
|
||||||
|
|
||||||
|
// and can be converted to and from a vector. However, the
|
||||||
|
// conversion to a vector is not efficient since a copy is made
|
||||||
|
// and should only be done when a vector is needed for further use
|
||||||
|
// in most sense and in standard algorithms Result<T> behaves as a
|
||||||
|
// vector.
|
||||||
|
std::vector<int> vec(5, 5);
|
||||||
|
std::cout << "vec: " << ToString(vec) << "\n";
|
||||||
|
|
||||||
|
Result<int> res3 = vec;
|
||||||
|
std::cout << "res3: " << res3 << '\n';
|
||||||
|
|
||||||
|
std::vector<int> vec2 = res3;
|
||||||
|
std::cout << "vec2: " << ToString(vec2) << "\n";
|
||||||
|
|
||||||
|
|
||||||
|
// WARNING this feature is still not decied, its convenient
|
||||||
|
// but might turn out to be a source of bugs...
|
||||||
|
// it is also possible to convert from Result<T> to T
|
||||||
|
int r = res3;
|
||||||
|
std::cout << "r: " << r << '\n';
|
||||||
|
std::cout << "static_cast<int>: " << static_cast<int>(res3) << '\n';
|
||||||
|
std::cout << "static_cast<double>: " << static_cast<double>(res3) << '\n';
|
||||||
|
|
||||||
|
int r2 = res;
|
||||||
|
std::cout << "res: " << res << " converted to int: " << r2 << "\n";
|
||||||
|
|
||||||
|
//Using squash we can also convert to a single value
|
||||||
|
std::cout << "res.squash(): " << res.squash() << '\n';
|
||||||
|
std::cout << "res3.squash(): " << res3.squash() << '\n';
|
||||||
|
|
||||||
|
|
||||||
|
//.squash also takes a default value
|
||||||
|
std::cout << "res.squash(-1): " << res.squash(-1) << '\n';
|
||||||
|
std::cout << "res3.squash(-1): " << res3.squash(-1) << '\n';
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
@ -3,6 +3,7 @@ set(SOURCES
|
|||||||
src/slsDetectorUsers.cpp
|
src/slsDetectorUsers.cpp
|
||||||
src/slsDetectorCommand.cpp
|
src/slsDetectorCommand.cpp
|
||||||
src/slsDetector.cpp
|
src/slsDetector.cpp
|
||||||
|
src/Detector.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
@ -39,6 +40,8 @@ set(PUBLICHEADERS
|
|||||||
include/slsDetectorUsers.h
|
include/slsDetectorUsers.h
|
||||||
include/detectorData.h
|
include/detectorData.h
|
||||||
include/multiSlsDetector.h
|
include/multiSlsDetector.h
|
||||||
|
include/Detector.h
|
||||||
|
include/Result.h
|
||||||
)
|
)
|
||||||
set_target_properties(slsDetectorShared PROPERTIES
|
set_target_properties(slsDetectorShared PROPERTIES
|
||||||
LIBRARY_OUTPUT_NAME SlsDetector
|
LIBRARY_OUTPUT_NAME SlsDetector
|
||||||
|
127
slsDetectorSoftware/include/Detector.h
Normal file
127
slsDetectorSoftware/include/Detector.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Result.h"
|
||||||
|
#include "sls_detector_defs.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class multiSlsDetector;
|
||||||
|
namespace sls {
|
||||||
|
using ns = std::chrono::nanoseconds;
|
||||||
|
using Positions = const std::vector<int> &;
|
||||||
|
using defs = slsDetectorDefs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class Detector
|
||||||
|
*/
|
||||||
|
class Detector {
|
||||||
|
std::unique_ptr<multiSlsDetector> pimpl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @param multi_id multi detector shared memory id
|
||||||
|
*/
|
||||||
|
Detector(int multi_id = 0);
|
||||||
|
~Detector();
|
||||||
|
|
||||||
|
// Acquisition
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking call, starts the receiver and detector. Acquired
|
||||||
|
* the number of frames set.
|
||||||
|
*/
|
||||||
|
void acquire();
|
||||||
|
void startReceiver(Positions pos = {});
|
||||||
|
void stopReceiver(Positions pos = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the acquiring flag. When true the detector blocks
|
||||||
|
* any attempt to start a new acquisition.
|
||||||
|
*/
|
||||||
|
bool getAcquiringFlag() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the acquiring flag. This might have to done manually
|
||||||
|
* after an acquisition was aborted.
|
||||||
|
*/
|
||||||
|
void setAcquiringFlag(bool value);
|
||||||
|
|
||||||
|
/** Read back the run status of the receiver */
|
||||||
|
Result<defs::runStatus> getReceiverStatus(Positions pos = {});
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the shared memory of this detector and all modules
|
||||||
|
* belonging to it.
|
||||||
|
*/
|
||||||
|
void freeSharedMemory();
|
||||||
|
void setConfig(const std::string &fname);
|
||||||
|
Result<std::string> getHostname(Positions pos = {}) const;
|
||||||
|
// void setHostname(Positions pos = {});
|
||||||
|
|
||||||
|
Result<uint64_t> getStartingFrameNumber(Positions pos = {}) const;
|
||||||
|
void setStartingFrameNumber(uint64_t value, Positions pos);
|
||||||
|
|
||||||
|
// Bits and registers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears (sets to 0) bit number bitnr in register at addr.
|
||||||
|
* @param addr address of the register
|
||||||
|
* @param bitnr bit number to clear
|
||||||
|
* @param pos detector position
|
||||||
|
*/
|
||||||
|
void clearBit(uint32_t addr, int bitnr, Positions pos = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets bit number bitnr in register at addr to 1
|
||||||
|
* @param addr address of the register
|
||||||
|
* @param bitnr bit number to clear
|
||||||
|
* @param pos detector position
|
||||||
|
*/
|
||||||
|
void setBit(uint32_t addr, int bitnr, Positions pos = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads 32 bit register from detector
|
||||||
|
* @param addr address of the register
|
||||||
|
* @returns value read from register
|
||||||
|
*/
|
||||||
|
Result<uint32_t> getRegister(uint32_t addr, Positions pos = {});
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* *
|
||||||
|
* FILE, anything concerning file writing or *
|
||||||
|
* reading goes here *
|
||||||
|
* *
|
||||||
|
* ************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns receiver file name prefix. The actual file name
|
||||||
|
* contains module id and file index as well.
|
||||||
|
* @param pos detector positions
|
||||||
|
* @returns file name prefix
|
||||||
|
*/
|
||||||
|
Result<std::string> getFileName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the receiver file name prefix
|
||||||
|
* @param fname file name prefix
|
||||||
|
*/
|
||||||
|
void setFileName(const std::string &fname);
|
||||||
|
Result<std::string> getFilePath() const;
|
||||||
|
void setFilePath(const std::string &fname);
|
||||||
|
Result<bool> getFileWrite(Positions pos = {}) const;
|
||||||
|
void setFileWrite(bool value, Positions pos = {});
|
||||||
|
Result<bool> getFileOverWrite(Positions pos = {}) const;
|
||||||
|
void setFileOverWrite(bool value, Positions pos = {});
|
||||||
|
|
||||||
|
// Time
|
||||||
|
Result<ns> getExptime(Positions pos = {}) const;
|
||||||
|
void setExptime(ns t, Positions pos = {});
|
||||||
|
Result<ns> getSubExptime(Positions pos = {}) const;
|
||||||
|
void setSubExptime(ns t, Positions pos = {});
|
||||||
|
Result<ns> getPeriod(Positions pos = {}) const;
|
||||||
|
void setPeriod(ns t, Positions pos = {});
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sls
|
99
slsDetectorSoftware/include/Result.h
Normal file
99
slsDetectorSoftware/include/Result.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file Result.h
|
||||||
|
* Result is a thin wrapper around std::vector and used for returning values
|
||||||
|
* from the detector. Since every module could have a different value, we need
|
||||||
|
* to return a vector instead of just a single value.
|
||||||
|
*
|
||||||
|
* Easy conversions to single values are provided using the squash method.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ToString.h"
|
||||||
|
#include "container_utils.h"
|
||||||
|
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @tparam T type to store in the result
|
||||||
|
* @tparam Allocator for the underlying vector, default
|
||||||
|
*/
|
||||||
|
template <class T, class Allocator = std::allocator<T>> class Result {
|
||||||
|
/** wrapped vector */
|
||||||
|
std::vector<T, Allocator> vec;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Result() = default;
|
||||||
|
Result(std::initializer_list<T> list) : vec(list){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward arguments to the constructor of std::vector
|
||||||
|
* @tparam Args template paramter pack to forward
|
||||||
|
*/
|
||||||
|
template <typename... Args>
|
||||||
|
Result(Args &&... args) : vec(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
|
using value_type = typename std::vector<T>::value_type;
|
||||||
|
using iterator = typename std::vector<T>::iterator;
|
||||||
|
using const_iterator = typename std::vector<T>::const_iterator;
|
||||||
|
using size_type = typename std::vector<T>::size_type;
|
||||||
|
using reference = typename std::vector<T>::reference;
|
||||||
|
using const_reference = typename std::vector<T>::const_reference;
|
||||||
|
|
||||||
|
auto begin() noexcept -> decltype(vec.begin()) { return vec.begin(); }
|
||||||
|
auto begin() const noexcept -> decltype(vec.begin()) { return vec.begin(); }
|
||||||
|
auto cbegin() const noexcept -> decltype(vec.cbegin()) {
|
||||||
|
return vec.cbegin();
|
||||||
|
}
|
||||||
|
auto end() noexcept -> decltype(vec.end()) { return vec.end(); }
|
||||||
|
auto end() const noexcept -> decltype(vec.end()) { return vec.end(); }
|
||||||
|
auto cend() const noexcept -> decltype(vec.cend()) { return vec.cend(); }
|
||||||
|
auto size() const noexcept -> decltype(vec.size()) { return vec.size(); }
|
||||||
|
auto empty() const noexcept -> decltype(vec.empty()) { return vec.empty(); }
|
||||||
|
auto front() -> decltype(vec.front()) { return vec.front(); }
|
||||||
|
auto front() const -> decltype(vec.front()) { return vec.front(); }
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
auto push_back(V value) -> decltype(vec.push_back(value)) {
|
||||||
|
vec.push_back(std::forward<V>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator[](size_type pos) -> decltype(vec[pos]) { return vec[pos]; }
|
||||||
|
const_reference operator[](size_type pos) const { return vec[pos]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If all elements are equal it returns the front value
|
||||||
|
* otherwise a default constructed T
|
||||||
|
*/
|
||||||
|
T squash() const { return Squash(vec); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If all elements are equal return the front value, otherwise
|
||||||
|
* return the supplied default value
|
||||||
|
*/
|
||||||
|
T squash(T default_value) const { return Squash(vec, default_value); }
|
||||||
|
|
||||||
|
/** Test whether all elements of the result are equal */
|
||||||
|
bool equal() const noexcept { return allEqual(vec); }
|
||||||
|
|
||||||
|
/** Convert Result<T> to std::vector<T> */
|
||||||
|
operator std::vector<T>() { return vec; }
|
||||||
|
|
||||||
|
/** Convert Result<T> to T using squash() */
|
||||||
|
operator T() { return squash(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* operator << overload to print Result, uses ToString for the conversion
|
||||||
|
* @tparam T type stored in the Result
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
std::ostream &operator<<(std::ostream &os, const Result<T> &res) {
|
||||||
|
return os << ToString(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sls
|
@ -4,7 +4,6 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
|
|
||||||
|
|
||||||
class slsDetector;
|
class slsDetector;
|
||||||
class ZmqSocket;
|
class ZmqSocket;
|
||||||
class detectorData;
|
class detectorData;
|
||||||
@ -20,14 +19,17 @@ class detectorData;
|
|||||||
#define SHORT_STRING_LENGTH 50
|
#define SHORT_STRING_LENGTH 50
|
||||||
#define DATE_LENGTH 30
|
#define DATE_LENGTH 30
|
||||||
|
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <numeric>
|
||||||
/**
|
/**
|
||||||
* @short structure allocated in shared memory to store detector settings
|
* @short structure allocated in shared memory to store detector settings
|
||||||
* for IPC and cache
|
* for IPC and cache
|
||||||
*/
|
*/
|
||||||
struct sharedMultiSlsDetector {
|
struct sharedMultiSlsDetector {
|
||||||
|
|
||||||
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
|
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
|
||||||
* ------*/
|
* ------*/
|
||||||
|
|
||||||
/** shared memory version */
|
/** shared memory version */
|
||||||
int shmversion;
|
int shmversion;
|
||||||
@ -45,7 +47,7 @@ struct sharedMultiSlsDetector {
|
|||||||
int numberOfDetectors;
|
int numberOfDetectors;
|
||||||
|
|
||||||
/** END OF FIXED PATTERN
|
/** END OF FIXED PATTERN
|
||||||
* -----------------------------------------------*/
|
* -----------------------------------------------*/
|
||||||
|
|
||||||
/** Number of detectors operated at once */
|
/** Number of detectors operated at once */
|
||||||
int numberOfDetector[2];
|
int numberOfDetector[2];
|
||||||
@ -72,11 +74,11 @@ struct sharedMultiSlsDetector {
|
|||||||
int maxNumberOfChannel[2];
|
int maxNumberOfChannel[2];
|
||||||
|
|
||||||
/** max number of channels including gap pixels for all detectors in
|
/** max number of channels including gap pixels for all detectors in
|
||||||
* one dimension*/
|
* one dimension*/
|
||||||
int maxNumberOfChannelInclGapPixels[2];
|
int maxNumberOfChannelInclGapPixels[2];
|
||||||
|
|
||||||
/** max number of channels allowed for the complete set of detectors in
|
/** max number of channels allowed for the complete set of detectors in
|
||||||
* one dimension */
|
* one dimension */
|
||||||
int maxNumberOfChannelsPerDetector[2];
|
int maxNumberOfChannelsPerDetector[2];
|
||||||
|
|
||||||
/** timer values */
|
/** timer values */
|
||||||
@ -98,8 +100,7 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* one
|
* one
|
||||||
* @param update true to update last user pid, date etc
|
* @param update true to update last user pid, date etc
|
||||||
*/
|
*/
|
||||||
explicit multiSlsDetector(int multi_id = 0,
|
explicit multiSlsDetector(int multi_id = 0, bool verify = true,
|
||||||
bool verify = true,
|
|
||||||
bool update = true);
|
bool update = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +108,101 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
virtual ~multiSlsDetector();
|
virtual ~multiSlsDetector();
|
||||||
|
|
||||||
|
template <class CT> struct NonDeduced { using type = CT; };
|
||||||
|
template <typename RT, typename... CT>
|
||||||
|
std::vector<RT> Parallel(RT (slsDetector::*somefunc)(CT...),
|
||||||
|
std::vector<int> positions,
|
||||||
|
typename NonDeduced<CT>::type... Args) {
|
||||||
|
|
||||||
|
if (positions.empty() || (positions.size() == 1 && positions[0] == -1 )) {
|
||||||
|
positions.resize(detectors.size());
|
||||||
|
std::iota(begin(positions), end(positions), 0);
|
||||||
|
}
|
||||||
|
std::vector<std::future<RT>> futures;
|
||||||
|
futures.reserve(positions.size());
|
||||||
|
for (size_t i : positions) {
|
||||||
|
if (i >= detectors.size())
|
||||||
|
throw sls::RuntimeError("Detector out of range");
|
||||||
|
futures.push_back(std::async(std::launch::async, somefunc,
|
||||||
|
detectors[i].get(), Args...));
|
||||||
|
}
|
||||||
|
std::vector<RT> result;
|
||||||
|
result.reserve(positions.size());
|
||||||
|
for (auto &i : futures) {
|
||||||
|
result.push_back(i.get());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename RT, typename... CT>
|
||||||
|
std::vector<RT> Parallel(RT (slsDetector::*somefunc)(CT...) const,
|
||||||
|
std::vector<int> positions,
|
||||||
|
typename NonDeduced<CT>::type... Args) const{
|
||||||
|
|
||||||
|
if (positions.empty() || (positions.size() == 1 && positions[0] == -1 )) {
|
||||||
|
positions.resize(detectors.size());
|
||||||
|
std::iota(begin(positions), end(positions), 0);
|
||||||
|
}
|
||||||
|
std::vector<std::future<RT>> futures;
|
||||||
|
futures.reserve(positions.size());
|
||||||
|
for (size_t i : positions) {
|
||||||
|
if (i >= detectors.size())
|
||||||
|
throw sls::RuntimeError("Detector out of range");
|
||||||
|
futures.push_back(std::async(std::launch::async, somefunc,
|
||||||
|
detectors[i].get(), Args...));
|
||||||
|
}
|
||||||
|
std::vector<RT> result;
|
||||||
|
result.reserve(positions.size());
|
||||||
|
for (auto &i : futures) {
|
||||||
|
result.push_back(i.get());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... CT>
|
||||||
|
void Parallel(void (slsDetector::*somefunc)(CT...),
|
||||||
|
std::vector<int> positions,
|
||||||
|
typename NonDeduced<CT>::type... Args) {
|
||||||
|
|
||||||
|
if (positions.empty() || (positions.size() == 1 && positions[0] == -1 )) {
|
||||||
|
positions.resize(detectors.size());
|
||||||
|
std::iota(begin(positions), end(positions), 0);
|
||||||
|
}
|
||||||
|
std::vector<std::future<void>> futures;
|
||||||
|
futures.reserve(positions.size());
|
||||||
|
for (size_t i : positions) {
|
||||||
|
if (i >= detectors.size())
|
||||||
|
throw sls::RuntimeError("Detector out of range");
|
||||||
|
futures.push_back(std::async(std::launch::async, somefunc,
|
||||||
|
detectors[i].get(), Args...));
|
||||||
|
}
|
||||||
|
for (auto &i : futures) {
|
||||||
|
i.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... CT>
|
||||||
|
void Parallel(void (slsDetector::*somefunc)(CT...) const,
|
||||||
|
std::vector<int> positions,
|
||||||
|
typename NonDeduced<CT>::type... Args) const{
|
||||||
|
|
||||||
|
if (positions.empty() || (positions.size() == 1 && positions[0] == -1 )) {
|
||||||
|
positions.resize(detectors.size());
|
||||||
|
std::iota(begin(positions), end(positions), 0);
|
||||||
|
}
|
||||||
|
std::vector<std::future<void>> futures;
|
||||||
|
futures.reserve(positions.size());
|
||||||
|
for (size_t i : positions) {
|
||||||
|
if (i >= detectors.size())
|
||||||
|
throw sls::RuntimeError("Detector out of range");
|
||||||
|
futures.push_back(std::async(std::launch::async, somefunc,
|
||||||
|
detectors[i].get(), Args...));
|
||||||
|
}
|
||||||
|
for (auto &i : futures) {
|
||||||
|
i.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates/open shared memory, initializes detector structure and members
|
* Creates/open shared memory, initializes detector structure and members
|
||||||
* Called by constructor/ set hostname / read config file
|
* Called by constructor/ set hostname / read config file
|
||||||
@ -114,14 +210,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* one
|
* one
|
||||||
* @param update true to update last user pid, date etc
|
* @param update true to update last user pid, date etc
|
||||||
*/
|
*/
|
||||||
void setupMultiDetector(bool verify = true,
|
void setupMultiDetector(bool verify = true, bool update = true);
|
||||||
bool update = true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loop through the detectors serially and return the result as a vector
|
* Loop through the detectors serially and return the result as a vector
|
||||||
*/
|
*/
|
||||||
template <class CT>
|
|
||||||
struct NonDeduced { using type = CT; };
|
|
||||||
template <typename RT, typename... CT>
|
template <typename RT, typename... CT>
|
||||||
std::vector<RT> serialCall(RT (slsDetector::*somefunc)(CT...),
|
std::vector<RT> serialCall(RT (slsDetector::*somefunc)(CT...),
|
||||||
typename NonDeduced<CT>::type... Args);
|
typename NonDeduced<CT>::type... Args);
|
||||||
@ -149,13 +243,13 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
std::vector<RT> parallelCall(RT (slsDetector::*somefunc)(CT...) const,
|
std::vector<RT> parallelCall(RT (slsDetector::*somefunc)(CT...) const,
|
||||||
typename NonDeduced<CT>::type... Args) const;
|
typename NonDeduced<CT>::type... Args) const;
|
||||||
|
|
||||||
|
template <typename... CT>
|
||||||
|
void parallelCall(void (slsDetector::*somefunc)(CT...),
|
||||||
|
typename NonDeduced<CT>::type... Args);
|
||||||
|
|
||||||
template <typename... CT>
|
template <typename... CT>
|
||||||
void parallelCall(void (slsDetector::*somefunc)(CT...), typename NonDeduced<CT>::type... Args);
|
void parallelCall(void (slsDetector::*somefunc)(CT...) const,
|
||||||
|
typename NonDeduced<CT>::type... Args) const;
|
||||||
template <typename... CT>
|
|
||||||
void parallelCall(void (slsDetector::*somefunc)(CT...) const, typename NonDeduced<CT>::type... Args) const;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes which detector and the corresponding channel numbers for it
|
* Decodes which detector and the corresponding channel numbers for it
|
||||||
@ -210,22 +304,24 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
int64_t getId(idMode mode, int detPos = -1);
|
int64_t getId(idMode mode, int detPos = -1);
|
||||||
|
|
||||||
/**
|
int getMultiId()const{return multiId;}
|
||||||
* Get Client Software version
|
|
||||||
* @returns client software version
|
/**
|
||||||
*/
|
* Get Client Software version
|
||||||
|
* @returns client software version
|
||||||
|
*/
|
||||||
int64_t getClientSoftwareVersion() const;
|
int64_t getClientSoftwareVersion() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Receiver software version
|
* Get Receiver software version
|
||||||
* @return receiver software version
|
* @return receiver software version
|
||||||
*/
|
*/
|
||||||
int64_t getReceiverSoftwareVersion(int detPos = -1);
|
int64_t getReceiverSoftwareVersion(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Detector Number
|
* Get Detector Number
|
||||||
* @returns vector of detector number
|
* @returns vector of detector number
|
||||||
*/
|
*/
|
||||||
std::vector<int64_t> getDetectorNumber();
|
std::vector<int64_t> getDetectorNumber();
|
||||||
/**
|
/**
|
||||||
* Free shared memory from the command line
|
* Free shared memory from the command line
|
||||||
@ -621,7 +717,7 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
void setStartingFrameNumber(const uint64_t value, int detPos = -1);
|
void setStartingFrameNumber(const uint64_t value, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get starting frame number for the next acquisition
|
* Get starting frame number for the next acquisition
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns starting frame number
|
* @returns starting frame number
|
||||||
@ -761,7 +857,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns value of speed set
|
* @returns value of speed set
|
||||||
*/
|
*/
|
||||||
int setSpeed(speedVariable index, int value = -1, int mode = 0, int detPos = -1);
|
int setSpeed(speedVariable index, int value = -1, int mode = 0,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set/get dynamic range and updates the number of dataBytes
|
* Set/get dynamic range and updates the number of dataBytes
|
||||||
@ -780,9 +877,9 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
int getDataBytes(int detPos = -1);
|
int getDataBytes(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of detectors in the multi structure*/
|
* Returns the number of detectors in the multi structure*/
|
||||||
size_t size() const{ return detectors.size();}
|
size_t size() const { return detectors.size(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set/get dacs value
|
* Set/get dacs value
|
||||||
@ -898,12 +995,14 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
std::string getDetectorMAC(int detPos = -1);
|
std::string getDetectorMAC(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the format of the detector MAC address (bottom half) and sets it (Jungfrau only)
|
* Validates the format of the detector MAC address (bottom half) and sets
|
||||||
|
* it (Jungfrau only)
|
||||||
* @param detectorMAC detector MAC address (bottom half)
|
* @param detectorMAC detector MAC address (bottom half)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the detector MAC address (bottom half)
|
* @returns the detector MAC address (bottom half)
|
||||||
*/
|
*/
|
||||||
std::string setDetectorMAC2(const std::string &detectorMAC, int detPos = -1);
|
std::string setDetectorMAC2(const std::string &detectorMAC,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the detector MAC address (bottom half) Jungfrau only
|
* Returns the detector MAC address (bottom half) Jungfrau only
|
||||||
@ -928,7 +1027,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
std::string getDetectorIP(int detPos = -1) const;
|
std::string getDetectorIP(int detPos = -1) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the format of the detector IP address (bottom half) and sets it (Jungfrau only)
|
* Validates the format of the detector IP address (bottom half) and sets it
|
||||||
|
* (Jungfrau only)
|
||||||
* @param detectorIP detector IP address (bottom half)
|
* @param detectorIP detector IP address (bottom half)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the detector IP address (bottom half)
|
* @returns the detector IP address (bottom half)
|
||||||
@ -944,13 +1044,15 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and sets the receiver.
|
* Validates and sets the receiver.
|
||||||
* Also updates the receiver with all the shared memory parameters significant for the receiver
|
* Also updates the receiver with all the shared memory parameters
|
||||||
* Also configures the detector to the receiver as UDP destination
|
* significant for the receiver Also configures the detector to the receiver
|
||||||
|
* as UDP destination
|
||||||
* @param receiver receiver hostname or IP address
|
* @param receiver receiver hostname or IP address
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the receiver IP address from shared memory
|
* @returns the receiver IP address from shared memory
|
||||||
*/
|
*/
|
||||||
std::string setReceiverHostname(const std::string &receiver, int detPos = -1);
|
std::string setReceiverHostname(const std::string &receiver,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the receiver IP address
|
* Returns the receiver IP address
|
||||||
@ -975,7 +1077,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
std::string getReceiverUDPIP(int detPos = -1) const;
|
std::string getReceiverUDPIP(int detPos = -1) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the format of the receiver UDP IP address (bottom half) and sets it(Jungfrau only)
|
* Validates the format of the receiver UDP IP address (bottom half) and
|
||||||
|
* sets it(Jungfrau only)
|
||||||
* @param udpip receiver UDP IP address (bottom half)
|
* @param udpip receiver UDP IP address (bottom half)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the receiver UDP IP address (bottom half)
|
* @returns the receiver UDP IP address (bottom half)
|
||||||
@ -1005,7 +1108,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
std::string getReceiverUDPMAC(int detPos = -1) const;
|
std::string getReceiverUDPMAC(int detPos = -1) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the format of the receiver UDP MAC address (bottom half) and sets it (Jungfrau only)
|
* Validates the format of the receiver UDP MAC address (bottom half) and
|
||||||
|
* sets it (Jungfrau only)
|
||||||
* @param udpmac receiver UDP MAC address (bottom half)
|
* @param udpmac receiver UDP MAC address (bottom half)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the receiver UDP MAC address (bottom half)
|
* @returns the receiver UDP MAC address (bottom half)
|
||||||
@ -1043,14 +1147,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
int setReceiverUDPPort2(int udpport, int detPos = -1);
|
int setReceiverUDPPort2(int udpport, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the receiver UDP port 2 of same interface (Eiger and Jungfrau only)
|
* Returns the receiver UDP port 2 of same interface (Eiger and Jungfrau
|
||||||
|
* only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the receiver UDP port 2 of same interface
|
* @returns the receiver UDP port 2 of same interface
|
||||||
*/
|
*/
|
||||||
int getReceiverUDPPort2(int detPos = -1) const;
|
int getReceiverUDPPort2(int detPos = -1) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the number of UDP interfaces to stream data from detector (Jungfrau only)
|
* Sets the number of UDP interfaces to stream data from detector (Jungfrau
|
||||||
|
* only)
|
||||||
* @param n number of interfaces. Options 1 or 2.
|
* @param n number of interfaces. Options 1 or 2.
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the number of interfaces
|
* @returns the number of interfaces
|
||||||
@ -1058,14 +1164,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
int setNumberofUDPInterfaces(int n, int detPos = -1);
|
int setNumberofUDPInterfaces(int n, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of UDP interfaces to stream data from detector (Jungfrau only)
|
* Returns the number of UDP interfaces to stream data from detector
|
||||||
|
* (Jungfrau only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the number of interfaces
|
* @returns the number of interfaces
|
||||||
*/
|
*/
|
||||||
int getNumberofUDPInterfaces(int detPos = -1) const;
|
int getNumberofUDPInterfaces(int detPos = -1) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the UDP interfaces to stream data from detector. Effective only when number of interfaces is 1. (Jungfrau only)
|
* Selects the UDP interfaces to stream data from detector. Effective only
|
||||||
|
* when number of interfaces is 1. (Jungfrau only)
|
||||||
* @param n selected interface. Options 1 or 2.
|
* @param n selected interface. Options 1 or 2.
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the interface selected
|
* @returns the interface selected
|
||||||
@ -1073,7 +1181,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
int selectUDPInterface(int n, int detPos = -1);
|
int selectUDPInterface(int n, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the UDP interfaces to stream data from detector. Effective only when number of interfaces is 1. (Jungfrau only)
|
* Returns the UDP interfaces to stream data from detector. Effective only
|
||||||
|
* when number of interfaces is 1. (Jungfrau only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the interface selected
|
* @returns the interface selected
|
||||||
*/
|
*/
|
||||||
@ -1090,11 +1199,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
void setClientDataStreamingInPort(int i = -1, int detPos = -1);
|
void setClientDataStreamingInPort(int i = -1, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the client zmq port
|
* Returns the client zmq port
|
||||||
* If detPos is -1(multi module), port returns client streaming port of first module
|
* If detPos is -1(multi module), port returns client streaming port of
|
||||||
|
* first module
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the client zmq port
|
* @returns the client zmq port
|
||||||
*/
|
*/
|
||||||
int getClientStreamingPort(int detPos = -1);
|
int getClientStreamingPort(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1108,11 +1218,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
void setReceiverDataStreamingOutPort(int i = -1, int detPos = -1);
|
void setReceiverDataStreamingOutPort(int i = -1, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the receiver zmq port
|
* Returns the receiver zmq port
|
||||||
* If detPos is -1(multi module), port returns receiver streaming port of first module
|
* If detPos is -1(multi module), port returns receiver streaming port of
|
||||||
|
* first module
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the receiver zmq port
|
* @returns the receiver zmq port
|
||||||
*/
|
*/
|
||||||
int getReceiverStreamingPort(int detPos = -1);
|
int getReceiverStreamingPort(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1126,11 +1237,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
int detPos = -1);
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the client zmq ip
|
* Returns the client zmq ip
|
||||||
* If detPos is -1(multi module), ip returns concatenation of all client streaming ip
|
* If detPos is -1(multi module), ip returns concatenation of all client
|
||||||
|
* streaming ip
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the client zmq ip
|
* @returns the client zmq ip
|
||||||
*/
|
*/
|
||||||
std::string getClientStreamingIP(int detPos = -1);
|
std::string getClientStreamingIP(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1144,11 +1256,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
int detPos = -1);
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the receiver zmq ip
|
* Returns the receiver zmq ip
|
||||||
* If detPos is -1(multi module), ip returns concatenation of all receiver streaming ip
|
* If detPos is -1(multi module), ip returns concatenation of all receiver
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* streaming ip
|
||||||
* @returns the receiver zmq ip
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
* @returns the receiver zmq ip
|
||||||
|
*/
|
||||||
std::string getReceiverStreamingIP(int detPos = -1);
|
std::string getReceiverStreamingIP(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1159,7 +1272,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns transmission delay
|
* @returns transmission delay
|
||||||
*/
|
*/
|
||||||
int setDetectorNetworkParameter(networkParameter index, int delay, int detPos = -1);
|
int setDetectorNetworkParameter(networkParameter index, int delay,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the additional json header
|
* Sets the additional json header
|
||||||
@ -1167,7 +1281,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns additional json header, default is empty
|
* @returns additional json header, default is empty
|
||||||
*/
|
*/
|
||||||
std::string setAdditionalJsonHeader(const std::string &jsonheader, int detPos = -1);
|
std::string setAdditionalJsonHeader(const std::string &jsonheader,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the additional json header
|
* Returns the additional json header
|
||||||
@ -1177,14 +1292,17 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
std::string getAdditionalJsonHeader(int detPos = -1);
|
std::string getAdditionalJsonHeader(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value for the additional json header parameter if found, else append it
|
* Sets the value for the additional json header parameter if found, else
|
||||||
|
* append it
|
||||||
* @param key additional json header parameter
|
* @param key additional json header parameter
|
||||||
* @param value additional json header parameter value (cannot be empty)
|
* @param value additional json header parameter value (cannot be empty)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns the additional json header parameter value,
|
* @returns the additional json header parameter value,
|
||||||
* empty if no parameter found in additional json header
|
* empty if no parameter found in additional json header
|
||||||
*/
|
*/
|
||||||
std::string setAdditionalJsonParameter(const std::string &key, const std::string &value, int detPos = -1);
|
std::string setAdditionalJsonParameter(const std::string &key,
|
||||||
|
const std::string &value,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the additional json header parameter value
|
* Returns the additional json header parameter value
|
||||||
@ -1193,21 +1311,26 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @returns the additional json header parameter value,
|
* @returns the additional json header parameter value,
|
||||||
* empty if no parameter found in additional json header
|
* empty if no parameter found in additional json header
|
||||||
*/
|
*/
|
||||||
std::string getAdditionalJsonParameter(const std::string &key, int detPos = -1);
|
std::string getAdditionalJsonParameter(const std::string &key,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the detector minimum/maximum energy threshold in processor (for Moench only)
|
* Sets the detector minimum/maximum energy threshold in processor (for
|
||||||
|
* Moench only)
|
||||||
* @param index 0 for emin, antyhing else for emax
|
* @param index 0 for emin, antyhing else for emax
|
||||||
* @param v value to set (-1 gets)
|
* @param v value to set (-1 gets)
|
||||||
* @returns detector minimum/maximum energy threshold (-1 for not found or error in computing json parameter value)
|
* @returns detector minimum/maximum energy threshold (-1 for not found or
|
||||||
|
* error in computing json parameter value)
|
||||||
*/
|
*/
|
||||||
int setDetectorMinMaxEnergyThreshold(const int index, int value, int detPos = -1);
|
int setDetectorMinMaxEnergyThreshold(const int index, int value,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the frame mode in processor (Moench only)
|
* Sets the frame mode in processor (Moench only)
|
||||||
* @param value frameModeType (-1 gets)
|
* @param value frameModeType (-1 gets)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns frame mode (-1 for not found or error in computing json parameter value)
|
* @returns frame mode (-1 for not found or error in computing json
|
||||||
|
* parameter value)
|
||||||
*/
|
*/
|
||||||
int setFrameMode(frameModeType value, int detPos = -1);
|
int setFrameMode(frameModeType value, int detPos = -1);
|
||||||
|
|
||||||
@ -1215,7 +1338,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* Sets the detector mode in processor (Moench only)
|
* Sets the detector mode in processor (Moench only)
|
||||||
* @param value detectorModetype (-1 gets)
|
* @param value detectorModetype (-1 gets)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns detector mode (-1 for not found or error in computing json parameter value)
|
* @returns detector mode (-1 for not found or error in computing json
|
||||||
|
* parameter value)
|
||||||
*/
|
*/
|
||||||
int setDetectorMode(detectorModeType value, int detPos = -1);
|
int setDetectorMode(detectorModeType value, int detPos = -1);
|
||||||
|
|
||||||
@ -1225,7 +1349,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns receiver udp socket buffer size
|
* @returns receiver udp socket buffer size
|
||||||
*/
|
*/
|
||||||
int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1, int detPos = -1);
|
int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the receiver UDP socket buffer size
|
* Returns the receiver UDP socket buffer size
|
||||||
@ -1324,77 +1449,77 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
void setADCEnableMask(uint32_t mask, int detPos = -1);
|
void setADCEnableMask(uint32_t mask, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ADC Enable Mask (CTB, Moench)
|
* Get ADC Enable Mask (CTB, Moench)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns ADC Enable mask
|
* @returns ADC Enable mask
|
||||||
*/
|
*/
|
||||||
uint32_t getADCEnableMask(int detPos = -1);
|
uint32_t getADCEnableMask(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set ADC invert register (CTB, Moench)
|
* Set ADC invert register (CTB, Moench)
|
||||||
* @param value ADC invert value
|
* @param value ADC invert value
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setADCInvert(uint32_t value, int detPos = -1);
|
void setADCInvert(uint32_t value, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ADC invert register (CTB, Moench)
|
* Get ADC invert register (CTB, Moench)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns ADC invert value
|
* @returns ADC invert value
|
||||||
*/
|
*/
|
||||||
uint32_t getADCInvert(int detPos = -1);
|
uint32_t getADCInvert(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set external sampling source (CTB only)
|
* Set external sampling source (CTB only)
|
||||||
* @param value external sampling source (Option: 0-63)
|
* @param value external sampling source (Option: 0-63)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setExternalSamplingSource(int value, int detPos = -1);
|
void setExternalSamplingSource(int value, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get external sampling source (CTB only)
|
* Get external sampling source (CTB only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns external sampling source
|
* @returns external sampling source
|
||||||
*/
|
*/
|
||||||
int getExternalSamplingSource(int detPos = -1);
|
int getExternalSamplingSource(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set external sampling enable (CTB only)
|
* Set external sampling enable (CTB only)
|
||||||
* @param value external sampling source (Option: 0-63)
|
* @param value external sampling source (Option: 0-63)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setExternalSampling(bool value, int detPos = -1);
|
void setExternalSampling(bool value, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get external sampling source (CTB only)
|
* Get external sampling source (CTB only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns external sampling enable
|
* @returns external sampling enable
|
||||||
*/
|
*/
|
||||||
int getExternalSampling(int detPos = -1);
|
int getExternalSampling(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set external sampling enable (CTB only)
|
* Set external sampling enable (CTB only)
|
||||||
* @param list external sampling source (Option: 0-63)
|
* @param list external sampling source (Option: 0-63)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setReceiverDbitList(std::vector<int> list, int detPos = -1);
|
void setReceiverDbitList(std::vector<int> list, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get external sampling source (CTB only)
|
* Get external sampling source (CTB only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns external sampling enable
|
* @returns external sampling enable
|
||||||
*/
|
*/
|
||||||
std::vector<int> getReceiverDbitList(int detPos = -1);
|
std::vector<int> getReceiverDbitList(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set digital data offset in bytes (CTB only)
|
* Set digital data offset in bytes (CTB only)
|
||||||
* @param value digital data offset in bytes
|
* @param value digital data offset in bytes
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setReceiverDbitOffset(int value, int detPos = -1);
|
void setReceiverDbitOffset(int value, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get digital data offset in bytes (CTB only)
|
* Get digital data offset in bytes (CTB only)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns digital data offset in bytes
|
* @returns digital data offset in bytes
|
||||||
@ -1565,7 +1690,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
void rebootController(int detPos = -1);
|
void rebootController(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the firmware, detector server and then reboots detector controller blackfin. (Not Eiger)
|
* Updates the firmware, detector server and then reboots detector
|
||||||
|
* controller blackfin. (Not Eiger)
|
||||||
* @param sname name of detector server binary
|
* @param sname name of detector server binary
|
||||||
* @param hostname name of pc to tftp from
|
* @param hostname name of pc to tftp from
|
||||||
* @param fname programming file name
|
* @param fname programming file name
|
||||||
@ -1589,7 +1715,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
int setAutoComparatorDisableMode(int ival = -1, int detPos = -1);
|
int setAutoComparatorDisableMode(int ival = -1, int detPos = -1);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Rate correction ( Eiger)
|
* Set Rate correction ( Eiger)
|
||||||
* @param t dead time in ns - if 0 disable correction,
|
* @param t dead time in ns - if 0 disable correction,
|
||||||
@ -1600,17 +1725,17 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
void setRateCorrection(int64_t t = 0, int detPos = -1);
|
void setRateCorrection(int64_t t = 0, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get rate correction ( Eiger)
|
* Get rate correction ( Eiger)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns 0 if rate correction disabled, > 0 otherwise (ns)
|
* @returns 0 if rate correction disabled, > 0 otherwise (ns)
|
||||||
*/
|
*/
|
||||||
int64_t getRateCorrection(int detPos = -1);
|
int64_t getRateCorrection(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints receiver configuration
|
* Prints receiver configuration
|
||||||
* @param level print level
|
* @param level print level
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void printReceiverConfiguration(TLogLevel level = logINFO, int detPos = -1);
|
void printReceiverConfiguration(TLogLevel level = logINFO, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1824,8 +1949,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @returns file write enable
|
* @returns file write enable
|
||||||
*/
|
*/
|
||||||
int getFileWrite(int detPos = -1) const;
|
int getFileWrite(int detPos = -1) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets/Gets receiver master file write enable
|
* Sets/Gets receiver master file write enable
|
||||||
* @param value 1 or 0 to set/reset master file write enable
|
* @param value 1 or 0 to set/reset master file write enable
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
@ -1923,26 +2048,27 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
int setPattern(const std::string &fname, int detPos = -1);
|
int setPattern(const std::string &fname, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets pattern IO control (CTB/ Moench)
|
* Sets pattern IO control (CTB/ Moench)
|
||||||
* @param word 64bit word to be written, -1 gets
|
* @param word 64bit word to be written, -1 gets
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns actual value
|
* @returns actual value
|
||||||
*/
|
*/
|
||||||
uint64_t setPatternIOControl(uint64_t word = -1, int detPos = -1);
|
uint64_t setPatternIOControl(uint64_t word = -1, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets pattern clock control (CTB/ Moench)
|
* Sets pattern clock control (CTB/ Moench)
|
||||||
* @param word 64bit word to be written, -1 gets
|
* @param word 64bit word to be written, -1 gets
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns actual value
|
* @returns actual value
|
||||||
*/
|
*/
|
||||||
uint64_t setPatternClockControl(uint64_t word = -1, int detPos = -1);
|
uint64_t setPatternClockControl(uint64_t word = -1, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a pattern word (CTB/ Moench)
|
* Writes a pattern word (CTB/ Moench)
|
||||||
* @param addr address of the word
|
* @param addr address of the word
|
||||||
* @param word 64bit word to be written, -1 reads the addr (same as executing the pattern)
|
* @param word 64bit word to be written, -1 reads the addr (same as
|
||||||
|
* executing the pattern)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns actual value
|
* @returns actual value
|
||||||
*/
|
*/
|
||||||
@ -1956,15 +2082,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
* @param n number of loops for level 0-2, -1 gets
|
* @param n number of loops for level 0-2, -1 gets
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setPatternLoops(int level, int start = -1, int stop = -1, int n = -1, int detPos = -1);
|
void setPatternLoops(int level, int start = -1, int stop = -1, int n = -1,
|
||||||
|
int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pattern loop limits (CTB/ Moench)
|
* Gets the pattern loop limits (CTB/ Moench)
|
||||||
* @param level -1 complete pattern, 0,1,2, loop level
|
* @param level -1 complete pattern, 0,1,2, loop level
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns array of start address, stop address and number of loops
|
* @returns array of start address, stop address and number of loops
|
||||||
*/
|
*/
|
||||||
std::array<int, 3> getPatternLoops(int level, int detPos = -1);
|
std::array<int, 3> getPatternLoops(int level, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the wait address (CTB/ Moench)
|
* Sets the wait address (CTB/ Moench)
|
||||||
@ -1999,14 +2126,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
uint64_t getPatternMask(int detPos = -1);
|
uint64_t getPatternMask(int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the bits that the mask will be applied to for every pattern (CTB/ Moench)
|
* Selects the bits that the mask will be applied to for every pattern (CTB/
|
||||||
|
* Moench)
|
||||||
* @param mask mask to select bits
|
* @param mask mask to select bits
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
*/
|
*/
|
||||||
void setPatternBitMask(uint64_t mask, int detPos = -1);
|
void setPatternBitMask(uint64_t mask, int detPos = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the bits that the mask will be applied to for every pattern (CTB/ Moench)
|
* Gets the bits that the mask will be applied to for every pattern (CTB/
|
||||||
|
* Moench)
|
||||||
* @param detPos -1 for all detectors in list or specific detector position
|
* @param detPos -1 for all detectors in list or specific detector position
|
||||||
* @returns mask of bits selected
|
* @returns mask of bits selected
|
||||||
*/
|
*/
|
||||||
@ -2132,16 +2261,14 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
void addSlsDetector(const std::string &hostname);
|
void addSlsDetector(const std::string &hostname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add gap pixels to the image (only for Eiger in 4 bit mode)
|
||||||
/**
|
* @param image pointer to image without gap pixels
|
||||||
* add gap pixels to the image (only for Eiger in 4 bit mode)
|
* @param gpImage poiner to image with gap pixels, if NULL, allocated
|
||||||
* @param image pointer to image without gap pixels
|
* inside function
|
||||||
* @param gpImage poiner to image with gap pixels, if NULL, allocated
|
* @returns number of data bytes of image with gap pixels
|
||||||
* inside function
|
*/
|
||||||
* @returns number of data bytes of image with gap pixels
|
int processImageWithGapPixels(char *image, char *&gpImage);
|
||||||
*/
|
|
||||||
int processImageWithGapPixels(char *image, char *&gpImage);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set total progress (total number of frames/images in an acquisition)
|
* Set total progress (total number of frames/images in an acquisition)
|
||||||
@ -2197,14 +2324,13 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
std::vector<char> readPofFile(const std::string &fname);
|
std::vector<char> readPofFile(const std::string &fname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a double holding time in seconds to an int64_t with nano seconds
|
* Convert a double holding time in seconds to an int64_t with nano seconds
|
||||||
* Used for conversion when sending time to detector
|
* Used for conversion when sending time to detector
|
||||||
* @param t time in seconds
|
* @param t time in seconds
|
||||||
* @returns time in nano seconds
|
* @returns time in nano seconds
|
||||||
*/
|
*/
|
||||||
int64_t secondsToNanoSeconds(double t);
|
int64_t secondsToNanoSeconds(double t);
|
||||||
|
|
||||||
|
|
||||||
/** Multi detector Id */
|
/** Multi detector Id */
|
||||||
const int multiId{0};
|
const int multiId{0};
|
||||||
@ -2260,4 +2386,3 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
|||||||
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
||||||
void *pCallbackArg{nullptr};
|
void *pCallbackArg{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "CmdLineParser.h"
|
#include "CmdLineParser.h"
|
||||||
#include "CmdProxy.h"
|
#include "CmdProxy.h"
|
||||||
|
#include "Detector.h"
|
||||||
#include "container_utils.h"
|
#include "container_utils.h"
|
||||||
#include "multiSlsDetector.h"
|
#include "multiSlsDetector.h"
|
||||||
#include "slsDetectorCommand.h"
|
#include "slsDetectorCommand.h"
|
||||||
@ -109,7 +110,12 @@ class multiSlsDetectorClient {
|
|||||||
// returns an empty string If the command is not in CmdProxy but
|
// returns an empty string If the command is not in CmdProxy but
|
||||||
// deprecated the new command is returned
|
// deprecated the new command is returned
|
||||||
if (action_ != slsDetectorDefs::READOUT_ACTION) {
|
if (action_ != slsDetectorDefs::READOUT_ACTION) {
|
||||||
sls::CmdProxy<multiSlsDetector> proxy(detPtr);
|
int multi_id = 0;
|
||||||
|
if (detPtr != nullptr)
|
||||||
|
multi_id = detPtr->getMultiId();
|
||||||
|
sls::Detector d(multi_id);
|
||||||
|
sls::CmdProxy<sls::Detector> proxy(&d);
|
||||||
|
// sls::CmdProxy<multiSlsDetector> proxy(detPtr);
|
||||||
auto cmd = proxy.Call(parser.command(), parser.arguments(),
|
auto cmd = proxy.Call(parser.command(), parser.arguments(),
|
||||||
parser.detector_id(), action_);
|
parser.detector_id(), action_);
|
||||||
if (cmd.empty()) {
|
if (cmd.empty()) {
|
||||||
|
@ -629,7 +629,7 @@ class slsDetector : public virtual slsDetectorDefs {
|
|||||||
* Set starting frame number for the next acquisition
|
* Set starting frame number for the next acquisition
|
||||||
* @param val starting frame number
|
* @param val starting frame number
|
||||||
*/
|
*/
|
||||||
void setStartingFrameNumber(const uint64_t value);
|
void setStartingFrameNumber(uint64_t value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get starting frame number for the next acquisition
|
* Get starting frame number for the next acquisition
|
||||||
|
129
slsDetectorSoftware/src/Detector.cpp
Normal file
129
slsDetectorSoftware/src/Detector.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#include "Detector.h"
|
||||||
|
#include "container_utils.h"
|
||||||
|
#include "multiSlsDetector.h"
|
||||||
|
#include "slsDetector.h"
|
||||||
|
#include "sls_detector_defs.h"
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
using defs = slsDetectorDefs;
|
||||||
|
|
||||||
|
Detector::Detector(int multi_id)
|
||||||
|
: pimpl(sls::make_unique<multiSlsDetector>(multi_id)) {}
|
||||||
|
Detector::~Detector() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Acquisition
|
||||||
|
void Detector::acquire() { pimpl->acquire(); }
|
||||||
|
|
||||||
|
void Detector::startReceiver(Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::startReceiver, pos);
|
||||||
|
}
|
||||||
|
void Detector::stopReceiver(Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::stopReceiver, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<defs::runStatus> Detector::getReceiverStatus(Positions pos) {
|
||||||
|
return pimpl->Parallel(&slsDetector::getReceiverStatus, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Detector::getAcquiringFlag() const{
|
||||||
|
return pimpl->getAcquiringFlag();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setAcquiringFlag(bool value){
|
||||||
|
pimpl->setAcquiringFlag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
Result<std::string> Detector::getHostname(Positions pos) const {
|
||||||
|
return pimpl->Parallel(&slsDetector::getHostname, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); }
|
||||||
|
|
||||||
|
|
||||||
|
void Detector::setConfig(const std::string &fname) {
|
||||||
|
pimpl->readConfigurationFile(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::clearBit(uint32_t addr, int bitnr, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::clearBit, pos, addr, bitnr);
|
||||||
|
}
|
||||||
|
void Detector::setBit(uint32_t addr, int bitnr, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setBit, pos, addr, bitnr);
|
||||||
|
}
|
||||||
|
Result<uint32_t> Detector::getRegister(uint32_t addr, Positions pos) {
|
||||||
|
return pimpl->Parallel(&slsDetector::readRegister, pos, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<ns> Detector::getExptime(Positions pos) const {
|
||||||
|
auto r = pimpl->Parallel(&slsDetector::setTimer, pos,
|
||||||
|
defs::ACQUISITION_TIME, -1);
|
||||||
|
return Result<ns>(begin(r), end(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<uint64_t> Detector::getStartingFrameNumber(Positions pos) const {
|
||||||
|
return pimpl->Parallel(&slsDetector::getStartingFrameNumber, pos);
|
||||||
|
}
|
||||||
|
void Detector::setStartingFrameNumber(uint64_t value, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setStartingFrameNumber, pos, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setExptime(ns t, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setTimer, pos, defs::ACQUISITION_TIME,
|
||||||
|
t.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<ns> Detector::getSubExptime(Positions pos) const {
|
||||||
|
auto r = pimpl->Parallel(&slsDetector::setTimer, pos,
|
||||||
|
defs::SUBFRAME_ACQUISITION_TIME, -1);
|
||||||
|
return Result<ns>(begin(r), end(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setSubExptime(ns t, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setTimer, pos,
|
||||||
|
defs::SUBFRAME_ACQUISITION_TIME, t.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<ns> Detector::getPeriod(Positions pos) const {
|
||||||
|
auto r =
|
||||||
|
pimpl->Parallel(&slsDetector::setTimer, pos, defs::FRAME_PERIOD, -1);
|
||||||
|
return Result<ns>(begin(r), end(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setPeriod(ns t, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setTimer, pos, defs::FRAME_PERIOD, t.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
// File
|
||||||
|
void Detector::setFileName(const std::string &fname) {
|
||||||
|
pimpl->Parallel(&slsDetector::setFileName, Positions{}, fname);
|
||||||
|
}
|
||||||
|
Result<std::string> Detector::getFileName() const {
|
||||||
|
return pimpl->Parallel(&slsDetector::setFileName, Positions{}, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setFilePath(const std::string &fpath) {
|
||||||
|
pimpl->Parallel(&slsDetector::setFilePath, Positions{}, fpath);
|
||||||
|
}
|
||||||
|
Result<std::string> Detector::getFilePath() const {
|
||||||
|
return pimpl->Parallel(&slsDetector::getFilePath, Positions{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setFileWrite(bool value, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setFileWrite, Positions{}, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<bool> Detector::getFileWrite(Positions pos) const {
|
||||||
|
return pimpl->Parallel(&slsDetector::getFileWrite, Positions{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Detector::setFileOverWrite(bool value, Positions pos) {
|
||||||
|
pimpl->Parallel(&slsDetector::setFileOverWrite, Positions{}, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<bool> Detector::getFileOverWrite(Positions pos) const {
|
||||||
|
return pimpl->Parallel(&slsDetector::getFileOverWrite, Positions{});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sls
|
@ -4457,3 +4457,9 @@ std::vector<char> multiSlsDetector::readPofFile(const std::string &fname) {
|
|||||||
FILE_LOG(logINFO) << "Read file into memory";
|
FILE_LOG(logINFO) << "Read file into memory";
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1382,7 +1382,7 @@ void slsDetector::configureMAC() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void slsDetector::setStartingFrameNumber(const uint64_t value) {
|
void slsDetector::setStartingFrameNumber(uint64_t value) {
|
||||||
FILE_LOG(logDEBUG1) << "Setting starting frame number to " << value;
|
FILE_LOG(logDEBUG1) << "Setting starting frame number to " << value;
|
||||||
sendToDetector(F_SET_STARTING_FRAME_NUMBER, value, nullptr);
|
sendToDetector(F_SET_STARTING_FRAME_NUMBER, value, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,5 @@ target_sources(tests PRIVATE
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetector.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetector.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetectorClient.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetectorClient.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
|
||||||
)
|
)
|
75
slsDetectorSoftware/tests/test-Result.cpp
Normal file
75
slsDetectorSoftware/tests/test-Result.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "Result.h"
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
using sls::Result;
|
||||||
|
|
||||||
|
TEST_CASE("Default construction", "[detector][n2]") {
|
||||||
|
Result<int> res;
|
||||||
|
REQUIRE(res.size() == 0);
|
||||||
|
REQUIRE(res.empty() == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Initializer list construction", "[n2]") {
|
||||||
|
Result<int> res{1, 2, 5};
|
||||||
|
REQUIRE(res.empty() == false);
|
||||||
|
REQUIRE(res.size() == 3);
|
||||||
|
REQUIRE(res[0] == 1);
|
||||||
|
REQUIRE(res[1] == 2);
|
||||||
|
REQUIRE(res[2] == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Construct with value and number", "[n2]") {
|
||||||
|
Result<int> res(5, 7);
|
||||||
|
REQUIRE(res.size() == 5);
|
||||||
|
REQUIRE(res[0] == 7);
|
||||||
|
REQUIRE(res[1] == 7);
|
||||||
|
REQUIRE(res[2] == 7);
|
||||||
|
REQUIRE(res[3] == 7);
|
||||||
|
REQUIRE(res[4] == 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Squash empty", "[n2]") {
|
||||||
|
Result<double> res;
|
||||||
|
REQUIRE(res.squash() == 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Squash gives either value or default constructed value", "[n2]") {
|
||||||
|
Result<int> res{3, 3, 3};
|
||||||
|
REQUIRE(res.squash() == 3);
|
||||||
|
|
||||||
|
res.push_back(5);
|
||||||
|
REQUIRE(res.squash() == 0);
|
||||||
|
REQUIRE(res.squash(-1) == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Updating an element", "[n2]") {
|
||||||
|
|
||||||
|
Result<int> res{1, 2, 3};
|
||||||
|
REQUIRE(res[0] == 1);
|
||||||
|
REQUIRE(res[1] == 2);
|
||||||
|
REQUIRE(res[2] == 3);
|
||||||
|
|
||||||
|
res[0] = 5;
|
||||||
|
REQUIRE(res[0] == 5);
|
||||||
|
REQUIRE(res[1] == 2);
|
||||||
|
REQUIRE(res[2] == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("equal", "[n2]"){
|
||||||
|
Result<float> res;
|
||||||
|
|
||||||
|
// There are no elements to compare
|
||||||
|
REQUIRE(res.equal() == false);
|
||||||
|
|
||||||
|
//all (the one) elements are equal
|
||||||
|
res.push_back(1.2);
|
||||||
|
REQUIRE(res.equal() == true);
|
||||||
|
|
||||||
|
res.push_back(1.2);
|
||||||
|
REQUIRE(res.equal() == true);
|
||||||
|
|
||||||
|
res.push_back(1.3);
|
||||||
|
REQUIRE(res.equal() == false);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
#include "multiSlsDetector.h"
|
||||||
#include "multiSlsDetectorClient.h"
|
#include "multiSlsDetectorClient.h"
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -108,7 +109,7 @@ TEST_CASE("enablefoverwrite", "[.cmd]") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//EIGER ONLY
|
// EIGER ONLY
|
||||||
// TEST_CASE("activatecmd", "[.cmd]") {
|
// TEST_CASE("activatecmd", "[.cmd]") {
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@ -395,4 +396,40 @@ TEST_CASE("rx_checkversion", "[.cmd]") {
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
multiSlsDetectorClient("rx_checkversion", GET, nullptr, oss);
|
multiSlsDetectorClient("rx_checkversion", GET, nullptr, oss);
|
||||||
REQUIRE(oss.str() == "rx_checkversion compatible\n");
|
REQUIRE(oss.str() == "rx_checkversion compatible\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("exptime", "[.cmd]") {
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
multiSlsDetectorClient("exptime 0.05", PUT, nullptr, oss);
|
||||||
|
REQUIRE(oss.str() == "exptime 0.050000000\n");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
multiSlsDetectorClient("exptime", GET, nullptr, oss);
|
||||||
|
REQUIRE(oss.str() == "exptime 0.050000000\n");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
multiSlsDetectorClient("exptime 1", PUT, nullptr, oss);
|
||||||
|
REQUIRE(oss.str() == "exptime 1.000000000\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST_CASE("exptime2", "[.cmd]") {
|
||||||
|
// {
|
||||||
|
// std::ostringstream oss;
|
||||||
|
// multiSlsDetectorClient("exptime2 0.05", PUT, nullptr, oss);
|
||||||
|
// REQUIRE(oss.str() == "exptime2 0.05s\n");
|
||||||
|
// }
|
||||||
|
// {
|
||||||
|
// std::ostringstream oss;
|
||||||
|
// multiSlsDetectorClient("exptime2", GET, nullptr, oss);
|
||||||
|
// REQUIRE(oss.str() == "exptime2 0.05s\n");
|
||||||
|
// }
|
||||||
|
// {
|
||||||
|
// std::ostringstream oss;
|
||||||
|
// multiSlsDetectorClient("exptime2 1", PUT, nullptr, oss);
|
||||||
|
// REQUIRE(oss.str() == "exptime2 1s\n");
|
||||||
|
// }
|
||||||
|
// }
|
@ -7,6 +7,7 @@ set(SOURCES
|
|||||||
src/ServerSocket.cpp
|
src/ServerSocket.cpp
|
||||||
src/ServerInterface2.cpp
|
src/ServerInterface2.cpp
|
||||||
src/network_utils.cpp
|
src/network_utils.cpp
|
||||||
|
src/ToString.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
@ -29,6 +30,9 @@ set(PUBLICHEADERS
|
|||||||
include/ServerInterface2.h
|
include/ServerInterface2.h
|
||||||
include/network_utils.h
|
include/network_utils.h
|
||||||
include/FixedCapacityContainer.h
|
include/FixedCapacityContainer.h
|
||||||
|
include/ToString.h
|
||||||
|
include/TimeHelper.h
|
||||||
|
include/TypeTraits.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(slsSupportLib SHARED
|
add_library(slsSupportLib SHARED
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -7,12 +8,48 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Result.h"
|
||||||
|
#include "TimeHelper.h"
|
||||||
|
#include "ToString.h"
|
||||||
|
#include "container_utils.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "slsDetectorCommand.h"
|
#include "slsDetectorCommand.h"
|
||||||
#include "sls_detector_exceptions.h"
|
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
|
#include "sls_detector_exceptions.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
|
||||||
|
#define TIME_COMMAND(GETFCN, SETFCN, HLPSTR) \
|
||||||
|
std::ostringstream os; \
|
||||||
|
os << cmd << ' '; \
|
||||||
|
if (action == slsDetectorDefs::HELP_ACTION) \
|
||||||
|
os << HLPSTR << '\n'; \
|
||||||
|
else if (action == slsDetectorDefs::GET_ACTION) { \
|
||||||
|
auto t = det->GETFCN({det_id}); \
|
||||||
|
if (args.size() == 0) { \
|
||||||
|
os << OutString(t) << '\n'; \
|
||||||
|
} else if (args.size() == 1) { \
|
||||||
|
os << OutString(t, args[0]) << '\n'; \
|
||||||
|
} else { \
|
||||||
|
WrongNumberOfParameters(2); \
|
||||||
|
} \
|
||||||
|
} else if (action == slsDetectorDefs::PUT_ACTION) { \
|
||||||
|
if (args.size() == 1) { \
|
||||||
|
std::string time_str(args[0]); \
|
||||||
|
std::string unit = RemoveUnit(time_str); \
|
||||||
|
auto t = StringTo<time::ns>(time_str, unit); \
|
||||||
|
det->SETFCN(t, {det_id}); \
|
||||||
|
} else if (args.size() == 2) { \
|
||||||
|
auto t = StringTo<time::ns>(args[0], args[1]); \
|
||||||
|
det->SETFCN(t, {det_id}); \
|
||||||
|
} else { \
|
||||||
|
WrongNumberOfParameters(2); \
|
||||||
|
} \
|
||||||
|
os << ToString(args) << '\n'; \
|
||||||
|
} else { \
|
||||||
|
throw sls::RuntimeError("Unknown action"); \
|
||||||
|
} \
|
||||||
|
return os.str();
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
|
|
||||||
template <typename T> class CmdProxy {
|
template <typename T> class CmdProxy {
|
||||||
@ -20,9 +57,8 @@ template <typename T> class CmdProxy {
|
|||||||
explicit CmdProxy(T *detectorPtr) : det(detectorPtr) {}
|
explicit CmdProxy(T *detectorPtr) : det(detectorPtr) {}
|
||||||
|
|
||||||
std::string Call(const std::string &command,
|
std::string Call(const std::string &command,
|
||||||
const std::vector<std::string> &arguments,
|
const std::vector<std::string> &arguments, int detector_id,
|
||||||
int detector_id,
|
int action = -1, std::ostream &os = std::cout) {
|
||||||
int action=-1) {
|
|
||||||
cmd = command;
|
cmd = command;
|
||||||
args = arguments;
|
args = arguments;
|
||||||
det_id = detector_id;
|
det_id = detector_id;
|
||||||
@ -31,7 +67,7 @@ template <typename T> class CmdProxy {
|
|||||||
|
|
||||||
auto it = functions.find(cmd);
|
auto it = functions.find(cmd);
|
||||||
if (it != functions.end()) {
|
if (it != functions.end()) {
|
||||||
std::cout << ((*this).*(it->second))(action);
|
os << ((*this).*(it->second))(action);
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
return cmd;
|
return cmd;
|
||||||
@ -53,17 +89,47 @@ template <typename T> class CmdProxy {
|
|||||||
|
|
||||||
size_t GetFunctionMapSize() const noexcept { return functions.size(); };
|
size_t GetFunctionMapSize() const noexcept { return functions.size(); };
|
||||||
|
|
||||||
|
std::vector<std::string> GetAllCommands() {
|
||||||
|
auto commands = slsDetectorCommand(nullptr).getAllCommands();
|
||||||
|
for (const auto &it : functions)
|
||||||
|
commands.emplace_back(it.first);
|
||||||
|
std::sort(begin(commands), end(commands));
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
std::vector<std::string> GetProxyCommands() {
|
||||||
|
std::vector<std::string> commands;
|
||||||
|
for (const auto &it : functions)
|
||||||
|
commands.emplace_back(it.first);
|
||||||
|
std::sort(begin(commands), end(commands));
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T *det;
|
T *det;
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
int det_id{-1};
|
int det_id{-1};
|
||||||
|
|
||||||
|
template <typename V> std::string OutString(const V &value) {
|
||||||
|
if (value.equal())
|
||||||
|
return ToString(value.front());
|
||||||
|
return ToString(value);
|
||||||
|
}
|
||||||
|
template <typename V>
|
||||||
|
std::string OutString(const V &value, const std::string &unit) {
|
||||||
|
if (value.equal())
|
||||||
|
return ToString(value.front(), unit);
|
||||||
|
return ToString(value, unit);
|
||||||
|
}
|
||||||
|
|
||||||
using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>;
|
using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>;
|
||||||
using StringMap = std::map<std::string, std::string>;
|
using StringMap = std::map<std::string, std::string>;
|
||||||
|
|
||||||
// Initialize maps for translating name and function
|
// Initialize maps for translating name and function
|
||||||
FunctionMap functions{{"list", &CmdProxy::ListCommands}};
|
FunctionMap functions{{"list", &CmdProxy::ListCommands},
|
||||||
|
{"exptime2", &CmdProxy::Exptime},
|
||||||
|
{"period2", &CmdProxy::Period},
|
||||||
|
{"subexptime2", &CmdProxy::SubExptime}};
|
||||||
|
|
||||||
StringMap depreciated_functions{{"r_readfreq", "rx_readfreq"},
|
StringMap depreciated_functions{{"r_readfreq", "rx_readfreq"},
|
||||||
{"r_padding", "rx_padding"},
|
{"r_padding", "rx_padding"},
|
||||||
@ -92,10 +158,10 @@ template <typename T> class CmdProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mapped functions
|
// Mapped functions
|
||||||
|
|
||||||
std::string ListCommands(int action) {
|
std::string ListCommands(int action) {
|
||||||
if (action==slsDetectorDefs::HELP_ACTION)
|
if (action == slsDetectorDefs::HELP_ACTION)
|
||||||
return "list - lists all available commands, list deprecated - list deprecated commands\n";
|
return "list\n\tlists all available commands, list deprecated - "
|
||||||
|
"list deprecated commands\n";
|
||||||
|
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
auto commands = slsDetectorCommand(nullptr).getAllCommands();
|
auto commands = slsDetectorCommand(nullptr).getAllCommands();
|
||||||
@ -127,6 +193,22 @@ template <typename T> class CmdProxy {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Period(int action) {
|
||||||
|
TIME_COMMAND(
|
||||||
|
getPeriod, setPeriod,
|
||||||
|
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the period");
|
||||||
|
}
|
||||||
|
std::string Exptime(int action) {
|
||||||
|
TIME_COMMAND(
|
||||||
|
getExptime, setExptime,
|
||||||
|
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the exposure time");
|
||||||
|
}
|
||||||
|
std::string SubExptime(int action) {
|
||||||
|
TIME_COMMAND(getSubExptime, setSubExptime,
|
||||||
|
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the "
|
||||||
|
"exposure time of EIGER subframes");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sls
|
} // namespace sls
|
||||||
|
19
slsSupportLib/include/TimeHelper.h
Normal file
19
slsSupportLib/include/TimeHelper.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "TypeTraits.h"
|
||||||
|
namespace sls {
|
||||||
|
namespace time {
|
||||||
|
using ns = std::chrono::nanoseconds;
|
||||||
|
using us = std::chrono::microseconds;
|
||||||
|
using ms = std::chrono::milliseconds;
|
||||||
|
using s = std::chrono::seconds;
|
||||||
|
|
||||||
|
//Absolute value of std::chrono::duration
|
||||||
|
template <class Rep, class Period>
|
||||||
|
constexpr std::chrono::duration<Rep, Period> abs(std::chrono::duration<Rep, Period> d) {
|
||||||
|
return d >= d.zero() ? d : -d;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace time
|
||||||
|
} // namespace sls
|
140
slsSupportLib/include/ToString.h
Normal file
140
slsSupportLib/include/ToString.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file ToString.h
|
||||||
|
*
|
||||||
|
* Conversion from various types to std::string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TimeHelper.h"
|
||||||
|
#include "TypeTraits.h"
|
||||||
|
#include "sls_detector_exceptions.h"
|
||||||
|
#include "string_utils.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
std::string ToString(const std::vector<std::string> &vec,
|
||||||
|
const char delimiter = ' ');
|
||||||
|
|
||||||
|
/** Convert std::chrono::duration with specified output unit */
|
||||||
|
template <typename T, typename Rep = double>
|
||||||
|
typename std::enable_if<is_duration<T>::value, std::string>::type
|
||||||
|
ToString(T t, const std::string &unit) {
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
std::ostringstream os;
|
||||||
|
if (unit == "ns")
|
||||||
|
os << duration_cast<duration<Rep, std::nano>>(t).count() << unit;
|
||||||
|
else if (unit == "us")
|
||||||
|
os << duration_cast<duration<Rep, std::micro>>(t).count() << unit;
|
||||||
|
else if (unit == "ms")
|
||||||
|
os << duration_cast<duration<Rep, std::milli>>(t).count() << unit;
|
||||||
|
else if (unit == "s")
|
||||||
|
os << duration_cast<duration<Rep>>(t).count() << unit;
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Unknown unit: " + unit);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert std::chrono::duration automatically selecting the unit */
|
||||||
|
template <typename From>
|
||||||
|
typename std::enable_if<is_duration<From>::value, std::string>::type
|
||||||
|
ToString(From t) {
|
||||||
|
auto tns = std::chrono::duration_cast<std::chrono::nanoseconds>(t);
|
||||||
|
if (time::abs(tns) < std::chrono::microseconds(1)) {
|
||||||
|
return ToString(tns, "ns");
|
||||||
|
} else if (time::abs(tns) < std::chrono::milliseconds(1)) {
|
||||||
|
return ToString(tns, "us");
|
||||||
|
} else if (time::abs(tns) < std::chrono::milliseconds(99)) {
|
||||||
|
return ToString(tns, "ms");
|
||||||
|
} else {
|
||||||
|
return ToString(tns, "s");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Conversion of floating point values, removes trailing zeros*/
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_floating_point<T>::value, std::string>::type
|
||||||
|
ToString(const T &value) {
|
||||||
|
auto s = std::to_string(value);
|
||||||
|
s.erase(s.find_last_not_of('0') + 1u, std::string::npos);
|
||||||
|
s.erase(s.find_last_not_of('.') + 1u, std::string::npos);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Conversion of integer types, do not remove trailing zeros */
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_integral<T>::value, std::string>::type
|
||||||
|
ToString(const T &value) {
|
||||||
|
return std::to_string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** For a container loop over all elements and call ToString */
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<is_container<T>::value, std::string>::type
|
||||||
|
ToString(const T &container) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << '[';
|
||||||
|
if (!container.empty()) {
|
||||||
|
auto it = container.cbegin();
|
||||||
|
os << ToString(*it++);
|
||||||
|
while (it != container.cend())
|
||||||
|
os << ", " << ToString(*it++);
|
||||||
|
}
|
||||||
|
os << ']';
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Container and specified unit, call ToString(value, unit) */
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<is_container<T>::value, std::string>::type
|
||||||
|
ToString(const T &container, const std::string &unit) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << '[';
|
||||||
|
if (!container.empty()) {
|
||||||
|
auto it = container.cbegin();
|
||||||
|
os << ToString(*it++, unit);
|
||||||
|
while (it != container.cend())
|
||||||
|
os << ", " << ToString(*it++, unit);
|
||||||
|
}
|
||||||
|
os << ']';
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T StringTo(const std::string &t, const std::string &unit) {
|
||||||
|
double tval{0};
|
||||||
|
try {
|
||||||
|
tval = std::stod(t);
|
||||||
|
} catch (const std::invalid_argument &e) {
|
||||||
|
throw sls::RuntimeError("Could not convert string to time");
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
if (unit == "ns") {
|
||||||
|
return duration_cast<T>(duration<double, std::nano>(tval));
|
||||||
|
} else if (unit == "us") {
|
||||||
|
return duration_cast<T>(duration<double, std::micro>(tval));
|
||||||
|
} else if (unit == "ms") {
|
||||||
|
return duration_cast<T>(duration<double, std::milli>(tval));
|
||||||
|
} else if (unit == "s" || unit.empty()) {
|
||||||
|
return duration_cast<T>(std::chrono::duration<double>(tval));
|
||||||
|
} else {
|
||||||
|
throw sls::RuntimeError(
|
||||||
|
"Invalid unit in conversion from string to std::chrono::duration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T StringTo(std::string t) {
|
||||||
|
auto unit = RemoveUnit(t);
|
||||||
|
return StringTo<T>(t, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sls
|
48
slsSupportLib/include/TypeTraits.h
Normal file
48
slsSupportLib/include/TypeTraits.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type trait to check if atemplate parameter is a std::chrono::duration
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename T, typename _ = void>
|
||||||
|
struct is_duration : std::false_type {};
|
||||||
|
|
||||||
|
template <typename... Ts> struct is_duration_helper {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_duration<T,
|
||||||
|
typename std::conditional<
|
||||||
|
false,
|
||||||
|
is_duration_helper<typename T::rep, typename T::period,
|
||||||
|
decltype(std::declval<T>().min()),
|
||||||
|
decltype(std::declval<T>().max()),
|
||||||
|
decltype(std::declval<T>().zero())>,
|
||||||
|
void>::type> : public std::true_type {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type trait to evaluate if template parameter is
|
||||||
|
* complying with a standard container
|
||||||
|
*/
|
||||||
|
template <typename T, typename _ = void>
|
||||||
|
struct is_container : std::false_type {};
|
||||||
|
|
||||||
|
template <typename... Ts> struct is_container_helper {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_container<
|
||||||
|
T, typename std::conditional<
|
||||||
|
false,
|
||||||
|
is_container_helper<typename T::value_type, typename T::size_type,
|
||||||
|
typename T::iterator, typename T::const_iterator,
|
||||||
|
decltype(std::declval<T>().size()),
|
||||||
|
decltype(std::declval<T>().begin()),
|
||||||
|
decltype(std::declval<T>().end()),
|
||||||
|
decltype(std::declval<T>().cbegin()),
|
||||||
|
decltype(std::declval<T>().cend()),
|
||||||
|
decltype(std::declval<T>().empty())>,
|
||||||
|
void>::type> : public std::true_type {};
|
||||||
|
|
||||||
|
} // namespace sls
|
@ -9,6 +9,8 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "TypeTraits.h"
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
|
|
||||||
// C++11 make_unique implementation for exception safety
|
// C++11 make_unique implementation for exception safety
|
||||||
@ -26,14 +28,21 @@ make_unique(std::size_t n) {
|
|||||||
return std::unique_ptr<T>(new RT[n]);
|
return std::unique_ptr<T>(new RT[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool allEqual(const std::vector<T> &container) {
|
/** Compare elements in a Container to see if they are all equal */
|
||||||
if (container.empty())
|
template <typename Container> bool allEqual(const Container &c) {
|
||||||
return false;
|
if (!c.empty() &&
|
||||||
const auto &first = container[0];
|
std::all_of(begin(c), end(c),
|
||||||
return std::all_of(container.cbegin(), container.cend(),
|
[c](const typename Container::value_type &element) {
|
||||||
[first](const T &element) { return element == first; });
|
return element == c.front();
|
||||||
|
}))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare elements but with specified tolerance, useful
|
||||||
|
* for floating point values.
|
||||||
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
|
typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
|
||||||
allEqualWithTol(const std::vector<T> &container, const T tol) {
|
allEqualWithTol(const std::vector<T> &container, const T tol) {
|
||||||
@ -111,15 +120,31 @@ minusOneIfDifferent(const std::vector<std::vector<T>> &container) {
|
|||||||
|
|
||||||
template <typename T, size_t size>
|
template <typename T, size_t size>
|
||||||
std::array<T, size>
|
std::array<T, size>
|
||||||
minusOneIfDifferent(const std::vector<std::array<T,size>> &container) {
|
minusOneIfDifferent(const std::vector<std::array<T, size>> &container) {
|
||||||
if (allEqual(container))
|
if (allEqual(container))
|
||||||
return container.front();
|
return container.front();
|
||||||
|
|
||||||
std::array<T,size> arr;
|
std::array<T, size> arr;
|
||||||
arr.fill(static_cast<T>(-1));
|
arr.fill(static_cast<T>(-1));
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the first value if all values are equal
|
||||||
|
* otherwise return default_value. If no default
|
||||||
|
* value is supplied it will be default constructed
|
||||||
|
*/
|
||||||
|
template <typename Container>
|
||||||
|
typename Container::value_type
|
||||||
|
Squash(const Container &c, typename Container::value_type default_value = {}) {
|
||||||
|
if (!c.empty() &&
|
||||||
|
std::all_of(begin(c), end(c),
|
||||||
|
[c](const typename Container::value_type &element) {
|
||||||
|
return element == c.front();
|
||||||
|
}))
|
||||||
|
return c.front();
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace sls
|
} // namespace sls
|
||||||
|
@ -1,14 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************
|
|
||||||
* @file sls_detector_exceptions.h
|
|
||||||
* @short exceptions defined
|
|
||||||
***********************************************/
|
|
||||||
/**
|
|
||||||
*@short exceptions defined
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
|
|
||||||
/* Implementation of a safe string copy function for setting fields in
|
/* Implementation of a safe string copy function for setting fields in
|
||||||
for example the multi sls detector. It tries to copy the size of the
|
for example the multi sls detector. It tries to copy the size of the
|
||||||
destination from the source, stopping on '\0'.
|
destination from the source, stopping on '\0'.
|
||||||
|
|
||||||
Warning this will truncate the source string and should be used with care.
|
Warning this will truncate the source string and should be used with care.
|
||||||
Still this is better than strcpy and a buffer overflow...
|
Still this is better than strcpy and a buffer overflow...
|
||||||
*/
|
*/
|
||||||
template <size_t array_size>
|
template <size_t array_size>
|
||||||
void strcpy_safe(char (&destination)[array_size], const char *source) {
|
void strcpy_safe(char (&destination)[array_size], const char *source) {
|
||||||
assert(array_size > strlen(source));
|
assert(array_size > strlen(source));
|
||||||
strncpy(destination, source, array_size-1);
|
strncpy(destination, source, array_size - 1);
|
||||||
destination[array_size - 1] = '\0';
|
destination[array_size - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t array_size>
|
template <size_t array_size>
|
||||||
void strcpy_safe(char (&destination)[array_size], const std::string& source) {
|
void strcpy_safe(char (&destination)[array_size], const std::string &source) {
|
||||||
assert(array_size > source.size());
|
assert(array_size > source.size());
|
||||||
strncpy(destination, source.c_str(), array_size-1);
|
strncpy(destination, source.c_str(), array_size - 1);
|
||||||
destination[array_size - 1] = '\0';
|
destination[array_size - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,8 +32,7 @@ void strcpy_safe(char (&destination)[array_size], const std::string& source) {
|
|||||||
Removes all occurrences of the specified char from a c string
|
Removes all occurrences of the specified char from a c string
|
||||||
Templated on array size to ensure no access after buffer limits.
|
Templated on array size to ensure no access after buffer limits.
|
||||||
*/
|
*/
|
||||||
template <size_t array_size>
|
template <size_t array_size> void removeChar(char (&str)[array_size], char ch) {
|
||||||
void removeChar(char (&str)[array_size], char ch) {
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; str[i]; i++) {
|
for (int i = 0; str[i]; i++) {
|
||||||
if (str[i] != ch)
|
if (str[i] != ch)
|
||||||
@ -44,7 +43,7 @@ void removeChar(char (&str)[array_size], char ch) {
|
|||||||
str[count] = '\0';
|
str[count] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Split a string using the specified delimeter and return a vector of strings.
|
Split a string using the specified delimeter and return a vector of strings.
|
||||||
TODO! Look into switching to absl or a string_view based implementation. Current
|
TODO! Look into switching to absl or a string_view based implementation. Current
|
||||||
implementation should not be used in a performance critical place.
|
implementation should not be used in a performance critical place.
|
||||||
@ -62,9 +61,10 @@ Concatenate strings using + if the strings are different
|
|||||||
std::string concatenateIfDifferent(const std::vector<std::string> &container);
|
std::string concatenateIfDifferent(const std::vector<std::string> &container);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Concatenate vector of things with str method using + if the strings are different
|
Concatenate vector of things with str method using + if the strings are
|
||||||
|
different
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template <typename T>
|
||||||
std::string concatenateIfDifferent(const std::vector<T> &container);
|
std::string concatenateIfDifferent(const std::vector<T> &container);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -72,4 +72,7 @@ Convert an ip address string to a string in hex format. (removing dots)
|
|||||||
*/
|
*/
|
||||||
std::string stringIpToHex(const std::string &ip);
|
std::string stringIpToHex(const std::string &ip);
|
||||||
|
|
||||||
|
// remove the end of the string starting with the first aplhabetic character
|
||||||
|
// return the end
|
||||||
|
std::string RemoveUnit(std::string &str);
|
||||||
}; // namespace sls
|
}; // namespace sls
|
||||||
|
18
slsSupportLib/src/ToString.cpp
Normal file
18
slsSupportLib/src/ToString.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "ToString.h"
|
||||||
|
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
std::string ToString(const std::vector<std::string> &vec,
|
||||||
|
const char delimiter) {
|
||||||
|
std::ostringstream os;
|
||||||
|
if (vec.empty())
|
||||||
|
return os.str();
|
||||||
|
auto it = vec.cbegin();
|
||||||
|
os << *it++;
|
||||||
|
if (vec.size() > 1) {
|
||||||
|
while (it != vec.cend())
|
||||||
|
os << delimiter << *it++;
|
||||||
|
}
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
} // namespace sls
|
@ -47,6 +47,18 @@ std::string concatenateIfDifferent(const std::vector<T> &container) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string RemoveUnit(std::string &str) {
|
||||||
|
auto it = str.begin();
|
||||||
|
while (it != str.end()) {
|
||||||
|
if (std::isalpha(*it))
|
||||||
|
break;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
auto pos = it - str.begin();
|
||||||
|
auto unit = str.substr(pos);
|
||||||
|
str.erase(it, end(str));
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
template std::string concatenateIfDifferent(const std::vector<IpAddr> &);
|
template std::string concatenateIfDifferent(const std::vector<IpAddr> &);
|
||||||
template std::string concatenateIfDifferent(const std::vector<MacAddr> &);
|
template std::string concatenateIfDifferent(const std::vector<MacAddr> &);
|
||||||
|
@ -7,4 +7,5 @@ target_sources(tests PRIVATE
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-sls_detector_defs.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-sls_detector_defs.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Sockets.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-Sockets.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-FixedCapacityContainer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-FixedCapacityContainer.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/test-ToString.cpp
|
||||||
)
|
)
|
85
slsSupportLib/tests/test-ToString.cpp
Normal file
85
slsSupportLib/tests/test-ToString.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "TimeHelper.h"
|
||||||
|
#include "ToString.h"
|
||||||
|
#include "catch.hpp"
|
||||||
|
#include <vector>
|
||||||
|
using namespace sls;
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Integer conversions", "[support][now]"){
|
||||||
|
REQUIRE(ToString(0) == "0");
|
||||||
|
REQUIRE(ToString(1) == "1");
|
||||||
|
REQUIRE(ToString(-1) == "-1");
|
||||||
|
REQUIRE(ToString(100) == "100");
|
||||||
|
REQUIRE(ToString(589633100) == "589633100");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("floating point conversions", "[support][now]"){
|
||||||
|
REQUIRE(ToString(0.) == "0");
|
||||||
|
REQUIRE(ToString(1.) == "1");
|
||||||
|
REQUIRE(ToString(-1.) == "-1");
|
||||||
|
REQUIRE(ToString(100.) == "100");
|
||||||
|
REQUIRE(ToString(589633100.) == "589633100");
|
||||||
|
REQUIRE(ToString(2.35) == "2.35");
|
||||||
|
REQUIRE(ToString(2.3500) == "2.35");
|
||||||
|
REQUIRE(ToString(2.35010) == "2.3501");
|
||||||
|
REQUIRE(ToString(5000) == "5000");
|
||||||
|
REQUIRE(ToString(5E15) == "5000000000000000");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("conversion from duration to string", "[support][now]") {
|
||||||
|
REQUIRE(ToString(time::ns(150)) == "150ns");
|
||||||
|
REQUIRE(ToString(time::ms(783)) == "0.783s");
|
||||||
|
REQUIRE(ToString(time::ms(783), "ms") == "783ms");
|
||||||
|
REQUIRE(ToString(time::us(0)) == "0ns"); // Defaults to the lowest unit
|
||||||
|
REQUIRE(ToString(time::us(0), "s") == "0s");
|
||||||
|
REQUIRE(ToString(time::s(-1)) == "-1s");
|
||||||
|
REQUIRE(ToString(time::us(-100)) == "-100us");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("string to std::chrono::duration", "[support][now]") {
|
||||||
|
REQUIRE(StringTo<time::ns>("150", "ns") == time::ns(150));
|
||||||
|
REQUIRE(StringTo<time::ns>("150ns") == time::ns(150));
|
||||||
|
REQUIRE(StringTo<time::ns>("150s") == time::s(150));
|
||||||
|
REQUIRE(StringTo<time::s>("3 s") == time::s(3));
|
||||||
|
|
||||||
|
REQUIRE_THROWS(StringTo<time::ns>("5xs"));
|
||||||
|
REQUIRE_THROWS(StringTo<time::ns>("asvn"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Convert vector of time", "[support][now]"){
|
||||||
|
std::vector<time::ns> vec{time::ns(150), time::us(10), time::ns(600)};
|
||||||
|
REQUIRE(ToString(vec) == "[150ns, 10us, 600ns]");
|
||||||
|
REQUIRE(ToString(vec, "ns") == "[150ns, 10000ns, 600ns]");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Vector of int", "[support][now]"){
|
||||||
|
std::vector<int> vec;
|
||||||
|
REQUIRE(ToString(vec) == "[]");
|
||||||
|
|
||||||
|
vec.push_back(1);
|
||||||
|
REQUIRE(ToString(vec) == "[1]");
|
||||||
|
|
||||||
|
vec.push_back(172);
|
||||||
|
REQUIRE(ToString(vec) == "[1, 172]");
|
||||||
|
|
||||||
|
vec.push_back(5000);
|
||||||
|
REQUIRE(ToString(vec) == "[1, 172, 5000]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Vector of double", "[support][now]"){
|
||||||
|
std::vector<double> vec;
|
||||||
|
REQUIRE(ToString(vec) == "[]");
|
||||||
|
|
||||||
|
vec.push_back(1.3);
|
||||||
|
REQUIRE(ToString(vec) == "[1.3]");
|
||||||
|
|
||||||
|
vec.push_back(5669.325);
|
||||||
|
REQUIRE(ToString(vec) == "[1.3, 5669.325]");
|
||||||
|
|
||||||
|
vec.push_back(-5669.325005);
|
||||||
|
REQUIRE(ToString(vec) == "[1.3, 5669.325, -5669.325005]");
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user