mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-22 14:38:14 +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
|
||||
.*
|
||||
build
|
||||
docs/
|
||||
RELEASE.txt
|
||||
Testing/
|
||||
|
||||
|
@ -129,7 +129,7 @@ set(CMAKE_INSTALL_RPATH "$ORIGIN")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
|
||||
find_package(Doxygen)
|
||||
|
||||
find_package(ZeroMQ 4 REQUIRED)
|
||||
|
||||
if (SLS_USE_TESTS)
|
||||
@ -182,24 +182,11 @@ configure_file( .clang-tidy
|
||||
)
|
||||
|
||||
|
||||
if (DOXYGEN_FOUND)
|
||||
# set input and output files
|
||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/Doxyfile.in)
|
||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||
add_subdirectory(sample)
|
||||
|
||||
add_subdirectory(docs)
|
||||
|
||||
# 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)
|
||||
|
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
|
||||
# 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-
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# (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
|
||||
# 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
|
||||
# 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.
|
||||
# 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
|
||||
# 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)
|
||||
for th in threshold:
|
||||
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
|
||||
@ -30,7 +30,7 @@ and closes is afterwards.
|
||||
with xrf_shutter_open(box, 'Fe'):
|
||||
for th in threshold:
|
||||
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
|
||||
# )
|
||||
|
||||
target_sources(tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-integrationMulti.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-integrationDectector.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-eigerIntegration.cpp
|
||||
)
|
||||
# target_sources(tests PRIVATE
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/test-integrationMulti.cpp
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/test-integrationDectector.cpp
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/test-eigerIntegration.cpp
|
||||
# )
|
||||
|
||||
# if(SLS_USE_TESTS)
|
||||
# set(TEST_SOURCES
|
||||
@ -32,18 +32,7 @@ target_sources(tests PRIVATE
|
||||
# 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()
|
||||
|
||||
|
@ -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
|
||||
slsProjectOptions
|
||||
slsProjectWarnings
|
||||
slsDetectorShared
|
||||
slsReceiverShared
|
||||
slsSupportLib
|
||||
|
@ -36,7 +36,9 @@ class get_pybind_include(object):
|
||||
ext_modules = [
|
||||
Extension(
|
||||
'_sls_detector',
|
||||
['src/main.cpp'],
|
||||
['src/main.cpp',
|
||||
'src/enums.cpp',
|
||||
'src/experimental.cpp'],
|
||||
include_dirs=[
|
||||
# Path to pybind11 headers
|
||||
get_pybind_include(),
|
||||
|
@ -4,3 +4,6 @@ from .experimental import ExperimentalDetector
|
||||
from .jungfrau import Jungfrau
|
||||
from .jungfrau_ctb import JungfrauCTB
|
||||
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 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):
|
||||
def __init__(self):
|
||||
super().__init__(0)
|
||||
self.online = True
|
||||
"""
|
||||
This class is the base for detector specific
|
||||
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 "sls_detector_defs.h"
|
||||
|
||||
class Detector {
|
||||
class DetectorPythonInterface {
|
||||
public:
|
||||
Detector(int i) : det(i), multi_detector_id(i) {
|
||||
DetectorPythonInterface(int i) : det(i), multi_detector_id(i) {
|
||||
// Disable output from std::cout
|
||||
// std::cout.setstate(std::ios_base::failbit);
|
||||
}
|
||||
@ -352,7 +352,7 @@ class Detector {
|
||||
void checkDetectorVersionCompatibility() {
|
||||
det.checkDetectorVersionCompatibility();
|
||||
}
|
||||
bool checkReceiverVersionCompatibility() {
|
||||
void checkReceiverVersionCompatibility() {
|
||||
det.checkReceiverVersionCompatibility();
|
||||
}
|
||||
|
||||
@ -695,7 +695,7 @@ class Detector {
|
||||
int multi_detector_id = 0;
|
||||
};
|
||||
|
||||
void Detector::setFileFormat(const std::string &format) {
|
||||
void DetectorPythonInterface::setFileFormat(const std::string &format) {
|
||||
if (format == "binary") {
|
||||
det.setFileFormat(slsDetectorDefs::fileFormat::BINARY);
|
||||
} 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 =
|
||||
det.setFileFormat(slsDetectorDefs::fileFormat::GET_FILE_FORMAT, -1);
|
||||
switch (format) {
|
||||
@ -717,7 +717,7 @@ std::string Detector::getFileFormat() {
|
||||
}
|
||||
|
||||
slsDetectorDefs::networkParameter
|
||||
Detector::networkNameToEnum(std::string par_name) {
|
||||
DetectorPythonInterface::networkNameToEnum(std::string par_name) {
|
||||
|
||||
if (par_name == "detectormac") {
|
||||
return slsDetectorDefs::networkParameter::DETECTOR_MAC;
|
||||
@ -761,9 +761,9 @@ Detector::networkNameToEnum(std::string par_name) {
|
||||
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
|
||||
slsDetectorDefs::dacIndex dac = slsDetectorDefs::dacIndex::E_SvP;
|
||||
|
||||
@ -918,7 +918,7 @@ slsDetectorDefs::dacIndex Detector::dacNameToEnum(std::string dac_name) {
|
||||
// overflow of single subframes */
|
||||
// };
|
||||
|
||||
std::vector<std::string> Detector::getReadoutFlags() {
|
||||
std::vector<std::string> DetectorPythonInterface::getReadoutFlags() {
|
||||
std::vector<std::string> flags;
|
||||
auto r = det.setReadOutFlags();
|
||||
if (r & slsDetectorDefs::readOutFlags::STORE_IN_RAM)
|
||||
@ -953,7 +953,7 @@ std::vector<std::string> Detector::getReadoutFlags() {
|
||||
}
|
||||
|
||||
// note singular
|
||||
void Detector::setReadoutFlag(const std::string flag_name) {
|
||||
void DetectorPythonInterface::setReadoutFlag(const std::string flag_name) {
|
||||
if (flag_name == "none")
|
||||
det.setReadOutFlags(slsDetectorDefs::readOutFlags::NORMAL_READOUT);
|
||||
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");
|
||||
}
|
||||
|
||||
std::vector<double> Detector::getRateCorrection() {
|
||||
std::vector<double> DetectorPythonInterface::getRateCorrection() {
|
||||
std::vector<double> rate_corr;
|
||||
for (int i = 0; i < det.getNumberOfDetectors(); ++i) {
|
||||
rate_corr.push_back(det.getRateCorrection(i));
|
||||
@ -996,7 +996,7 @@ std::vector<double> Detector::getRateCorrection() {
|
||||
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 pulsePixel(int n=0,int x=0,int y=0);
|
||||
|
||||
@ -1008,7 +1008,7 @@ void Detector::pulseAllPixels(int n) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
void Detector::pulseDiagonal(int n) {
|
||||
void DetectorPythonInterface::pulseDiagonal(int n) {
|
||||
// int pulsePixelNMove(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/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
#include "Detector.h"
|
||||
#include "DetectorPythonInterface.h"
|
||||
#include "Result.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;
|
||||
|
||||
void init_enums(py::module &);
|
||||
void init_experimental(py::module &);
|
||||
PYBIND11_MODULE(_sls_detector, m) {
|
||||
m.doc() = R"pbdoc(
|
||||
C/C++ API
|
||||
@ -18,7 +37,10 @@ PYBIND11_MODULE(_sls_detector, m) {
|
||||
|
||||
)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
|
||||
are used by the python classes Eiger and Jungfrau and normally it is better
|
||||
to use them than to directly access functions here.
|
||||
@ -43,298 +65,283 @@ PYBIND11_MODULE(_sls_detector, m) {
|
||||
|
||||
)pbdoc");
|
||||
DetectorApi.def(py::init<int>())
|
||||
.def("freeSharedMemory", &Detector::freeSharedMemory)
|
||||
.def("getMultiDetectorId", &Detector::getMultiDetectorId)
|
||||
.def("acq", &Detector::acquire)
|
||||
.def("getAcquiringFlag", &Detector::getAcquiringFlag)
|
||||
.def("setAcquiringFlag", &Detector::setAcquiringFlag)
|
||||
.def("freeSharedMemory", &DetectorPythonInterface::freeSharedMemory)
|
||||
.def("getMultiDetectorId", &DetectorPythonInterface::getMultiDetectorId)
|
||||
.def("acq", &DetectorPythonInterface::acquire)
|
||||
.def("getAcquiringFlag", &DetectorPythonInterface::getAcquiringFlag)
|
||||
.def("setAcquiringFlag", &DetectorPythonInterface::setAcquiringFlag)
|
||||
|
||||
.def("setAllTrimbits", &Detector::setAllTrimbits)
|
||||
.def("getAllTrimbits", &Detector::getAllTrimbits)
|
||||
.def("setCounterBit", &Detector::setCounterBit)
|
||||
.def("getCounterBit", &Detector::getCounterBit)
|
||||
.def("setAllTrimbits", &DetectorPythonInterface::setAllTrimbits)
|
||||
.def("getAllTrimbits", &DetectorPythonInterface::getAllTrimbits)
|
||||
.def("setCounterBit", &DetectorPythonInterface::setCounterBit)
|
||||
.def("getCounterBit", &DetectorPythonInterface::getCounterBit)
|
||||
|
||||
.def("getAdc", &Detector::getAdc)
|
||||
.def("getDac", &Detector::getDac)
|
||||
.def("getDac_mV", &Detector::getDac_mV)
|
||||
.def("setDac", &Detector::setDac)
|
||||
.def("setDac_mV", &Detector::setDac_mV)
|
||||
.def("getDacFromIndex", &Detector::getDacFromIndex)
|
||||
.def("setDacFromIndex", &Detector::setDacFromIndex)
|
||||
.def("getAdc", &DetectorPythonInterface::getAdc)
|
||||
.def("getDac", &DetectorPythonInterface::getDac)
|
||||
.def("getDac_mV", &DetectorPythonInterface::getDac_mV)
|
||||
.def("setDac", &DetectorPythonInterface::setDac)
|
||||
.def("setDac_mV", &DetectorPythonInterface::setDac_mV)
|
||||
.def("getDacFromIndex", &DetectorPythonInterface::getDacFromIndex)
|
||||
.def("setDacFromIndex", &DetectorPythonInterface::setDacFromIndex)
|
||||
|
||||
.def("getDbitPipeline", &Detector::getDbitPipeline)
|
||||
.def("setDbitPipeline", &Detector::setDbitPipeline)
|
||||
.def("getDbitPhase", &Detector::getDbitPhase)
|
||||
.def("setDbitPhase", &Detector::setDbitPhase)
|
||||
.def("getDbitClock", &Detector::getDbitClock)
|
||||
.def("setDbitClock", &Detector::setDbitClock)
|
||||
.def("getDbitPipeline", &DetectorPythonInterface::getDbitPipeline)
|
||||
.def("setDbitPipeline", &DetectorPythonInterface::setDbitPipeline)
|
||||
.def("getDbitPhase", &DetectorPythonInterface::getDbitPhase)
|
||||
.def("setDbitPhase", &DetectorPythonInterface::setDbitPhase)
|
||||
.def("getDbitClock", &DetectorPythonInterface::getDbitClock)
|
||||
.def("setDbitClock", &DetectorPythonInterface::setDbitClock)
|
||||
|
||||
.def("setThresholdEnergy", &Detector::setThresholdEnergy)
|
||||
.def("getThresholdEnergy", &Detector::getThresholdEnergy)
|
||||
.def("setThresholdEnergy", &DetectorPythonInterface::setThresholdEnergy)
|
||||
.def("getThresholdEnergy", &DetectorPythonInterface::getThresholdEnergy)
|
||||
|
||||
.def("getSettings", &Detector::getSettings)
|
||||
.def("setSettings", &Detector::setSettings)
|
||||
.def("getSettingsDir", &Detector::getSettingsDir)
|
||||
.def("setSettingsDir", &Detector::setSettingsDir)
|
||||
.def("getSettings", &DetectorPythonInterface::getSettings)
|
||||
.def("setSettings", &DetectorPythonInterface::setSettings)
|
||||
.def("getSettingsDir", &DetectorPythonInterface::getSettingsDir)
|
||||
.def("setSettingsDir", &DetectorPythonInterface::setSettingsDir)
|
||||
|
||||
.def("loadTrimbitFile", &Detector::loadTrimbitFile)
|
||||
.def("setTrimEnergies", &Detector::setTrimEnergies)
|
||||
.def("getTrimEnergies", &Detector::getTrimEnergies)
|
||||
.def("loadTrimbitFile", &DetectorPythonInterface::loadTrimbitFile)
|
||||
.def("setTrimEnergies", &DetectorPythonInterface::setTrimEnergies)
|
||||
.def("getTrimEnergies", &DetectorPythonInterface::getTrimEnergies)
|
||||
|
||||
.def("pulseChip", &Detector::pulseChip)
|
||||
.def("pulseAllPixels", &Detector::pulseAllPixels)
|
||||
.def("pulseDiagonal", &Detector::pulseDiagonal)
|
||||
.def("getRunStatus", &Detector::getRunStatus)
|
||||
.def("readConfigurationFile", &Detector::readConfigurationFile)
|
||||
.def("readParametersFile", &Detector::readParametersFile)
|
||||
.def("checkOnline", &Detector::checkOnline)
|
||||
.def("setReadoutClockSpeed", &Detector::setReadoutClockSpeed)
|
||||
.def("getReadoutClockSpeed", &Detector::getReadoutClockSpeed)
|
||||
.def("getSyncClkSpeed", &Detector::getSyncClkSpeed)
|
||||
.def("getHostname", &Detector::getHostname)
|
||||
.def("setHostname", &Detector::setHostname)
|
||||
.def("pulseChip", &DetectorPythonInterface::pulseChip)
|
||||
.def("pulseAllPixels", &DetectorPythonInterface::pulseAllPixels)
|
||||
.def("pulseDiagonal", &DetectorPythonInterface::pulseDiagonal)
|
||||
.def("getRunStatus", &DetectorPythonInterface::getRunStatus)
|
||||
.def("readConfigurationFile",
|
||||
&DetectorPythonInterface::readConfigurationFile)
|
||||
.def("readParametersFile", &DetectorPythonInterface::readParametersFile)
|
||||
.def("checkOnline", &DetectorPythonInterface::checkOnline)
|
||||
.def("setReadoutClockSpeed",
|
||||
&DetectorPythonInterface::setReadoutClockSpeed)
|
||||
.def("getReadoutClockSpeed",
|
||||
&DetectorPythonInterface::getReadoutClockSpeed)
|
||||
.def("getSyncClkSpeed", &DetectorPythonInterface::getSyncClkSpeed)
|
||||
.def("getHostname", &DetectorPythonInterface::getHostname)
|
||||
.def("setHostname", &DetectorPythonInterface::setHostname)
|
||||
|
||||
.def("getReceiverPort", &Detector::getReceiverPort)
|
||||
.def("setReceiverPort", &Detector::setReceiverPort)
|
||||
.def("getReceiverPort", &DetectorPythonInterface::getReceiverPort)
|
||||
.def("setReceiverPort", &DetectorPythonInterface::setReceiverPort)
|
||||
|
||||
.def("isChipPowered", &Detector::isChipPowered)
|
||||
.def("powerChip", &Detector::powerChip)
|
||||
.def("isChipPowered", &DetectorPythonInterface::isChipPowered)
|
||||
.def("powerChip", &DetectorPythonInterface::powerChip)
|
||||
|
||||
.def("readRegister", &Detector::readRegister)
|
||||
.def("writeRegister", &Detector::writeRegister)
|
||||
.def("writeAdcRegister", &Detector::writeAdcRegister)
|
||||
.def("setBitInRegister", &Detector::setBitInRegister)
|
||||
.def("clearBitInRegister", &Detector::clearBitInRegister)
|
||||
.def("readRegister", &DetectorPythonInterface::readRegister)
|
||||
.def("writeRegister", &DetectorPythonInterface::writeRegister)
|
||||
.def("writeAdcRegister", &DetectorPythonInterface::writeAdcRegister)
|
||||
.def("setBitInRegister", &DetectorPythonInterface::setBitInRegister)
|
||||
.def("clearBitInRegister", &DetectorPythonInterface::clearBitInRegister)
|
||||
|
||||
.def("setDynamicRange", &Detector::setDynamicRange)
|
||||
.def("getDynamicRange", &Detector::getDynamicRange)
|
||||
.def("getFirmwareVersion", &Detector::getFirmwareVersion)
|
||||
.def("getServerVersion", &Detector::getServerVersion)
|
||||
.def("getClientVersion", &Detector::getClientVersion)
|
||||
.def("getReceiverVersion", &Detector::getReceiverVersion)
|
||||
.def("getDetectorNumber", &Detector::getDetectorNumber)
|
||||
.def("getRateCorrection", &Detector::getRateCorrection)
|
||||
.def("setRateCorrection", &Detector::setRateCorrection)
|
||||
.def("setDynamicRange", &DetectorPythonInterface::setDynamicRange)
|
||||
.def("getDynamicRange", &DetectorPythonInterface::getDynamicRange)
|
||||
.def("getFirmwareVersion", &DetectorPythonInterface::getFirmwareVersion)
|
||||
.def("getServerVersion", &DetectorPythonInterface::getServerVersion)
|
||||
.def("getClientVersion", &DetectorPythonInterface::getClientVersion)
|
||||
.def("getReceiverVersion", &DetectorPythonInterface::getReceiverVersion)
|
||||
.def("getDetectorNumber", &DetectorPythonInterface::getDetectorNumber)
|
||||
.def("getRateCorrection", &DetectorPythonInterface::getRateCorrection)
|
||||
.def("setRateCorrection", &DetectorPythonInterface::setRateCorrection)
|
||||
|
||||
.def("startAcquisition", &Detector::startAcquisition)
|
||||
.def("stopAcquisition", &Detector::stopAcquisition)
|
||||
.def("startReceiver", &Detector::startReceiver)
|
||||
.def("stopReceiver", &Detector::stopReceiver)
|
||||
.def("startAcquisition", &DetectorPythonInterface::startAcquisition)
|
||||
.def("stopAcquisition", &DetectorPythonInterface::stopAcquisition)
|
||||
.def("startReceiver", &DetectorPythonInterface::startReceiver)
|
||||
.def("stopReceiver", &DetectorPythonInterface::stopReceiver)
|
||||
|
||||
.def("getFilePath",
|
||||
(std::string(Detector::*)()) & Detector::getFilePath,
|
||||
(std::string(DetectorPythonInterface::*)()) &
|
||||
DetectorPythonInterface::getFilePath,
|
||||
"Using multiSlsDetector")
|
||||
.def("getFilePath",
|
||||
(std::string(Detector::*)(int)) & Detector::getFilePath,
|
||||
(std::string(DetectorPythonInterface::*)(int)) &
|
||||
DetectorPythonInterface::getFilePath,
|
||||
"File path for individual detector")
|
||||
.def("setFilePath",
|
||||
(void (Detector::*)(std::string)) & Detector::setFilePath)
|
||||
.def("setFilePath",
|
||||
(void (Detector::*)(std::string, int)) & Detector::setFilePath)
|
||||
.def("setFilePath", (void (DetectorPythonInterface::*)(std::string)) &
|
||||
DetectorPythonInterface::setFilePath)
|
||||
|
||||
.def("setFileName", &Detector::setFileName)
|
||||
.def("getFileName", &Detector::getFileName)
|
||||
.def("setFileIndex", &Detector::setFileIndex)
|
||||
.def("getFileIndex", &Detector::getFileIndex)
|
||||
.def("setFileName", &DetectorPythonInterface::setFileName)
|
||||
.def("getFileName", &DetectorPythonInterface::getFileName)
|
||||
.def("setFileIndex", &DetectorPythonInterface::setFileIndex)
|
||||
.def("getFileIndex", &DetectorPythonInterface::getFileIndex)
|
||||
|
||||
.def("setExposureTime", &Detector::setExposureTime)
|
||||
.def("getExposureTime", &Detector::getExposureTime)
|
||||
.def("setSubExposureTime", &Detector::setSubExposureTime)
|
||||
.def("getSubExposureTime", &Detector::getSubExposureTime)
|
||||
.def("setPeriod", &Detector::setPeriod)
|
||||
.def("getPeriod", &Detector::getPeriod)
|
||||
.def("setSubExposureDeadTime", &Detector::setSubExposureDeadTime)
|
||||
.def("getSubExposureDeadTime", &Detector::getSubExposureDeadTime)
|
||||
.def("setExposureTime", &DetectorPythonInterface::setExposureTime)
|
||||
.def("getExposureTime", &DetectorPythonInterface::getExposureTime)
|
||||
.def("setSubExposureTime", &DetectorPythonInterface::setSubExposureTime)
|
||||
.def("getSubExposureTime", &DetectorPythonInterface::getSubExposureTime)
|
||||
.def("setPeriod", &DetectorPythonInterface::setPeriod)
|
||||
.def("getPeriod", &DetectorPythonInterface::getPeriod)
|
||||
.def("setSubExposureDeadTime", &DetectorPythonInterface::setSubExposureDeadTime)
|
||||
.def("getSubExposureDeadTime", &DetectorPythonInterface::getSubExposureDeadTime)
|
||||
|
||||
.def("getCycles", &Detector::getCycles)
|
||||
.def("setCycles", &Detector::setCycles)
|
||||
.def("getNumberOfGates", &Detector::getNumberOfGates)
|
||||
.def("setNumberOfGates", &Detector::setNumberOfGates)
|
||||
.def("getDelay", &Detector::getDelay)
|
||||
.def("setDelay", &Detector::setDelay)
|
||||
.def("getCycles", &DetectorPythonInterface::getCycles)
|
||||
.def("setCycles", &DetectorPythonInterface::setCycles)
|
||||
.def("getNumberOfGates", &DetectorPythonInterface::getNumberOfGates)
|
||||
.def("setNumberOfGates", &DetectorPythonInterface::setNumberOfGates)
|
||||
.def("getDelay", &DetectorPythonInterface::getDelay)
|
||||
.def("setDelay", &DetectorPythonInterface::setDelay)
|
||||
|
||||
.def("setStoragecellStart", &Detector::setStoragecellStart)
|
||||
.def("getStoragecellStart", &Detector::getStoragecellStart)
|
||||
.def("setNumberOfStorageCells", &Detector::setNumberOfStorageCells)
|
||||
.def("getNumberOfStorageCells", &Detector::getNumberOfStorageCells)
|
||||
.def("setStoragecellStart", &DetectorPythonInterface::setStoragecellStart)
|
||||
.def("getStoragecellStart", &DetectorPythonInterface::getStoragecellStart)
|
||||
.def("setNumberOfStorageCells", &DetectorPythonInterface::setNumberOfStorageCells)
|
||||
.def("getNumberOfStorageCells", &DetectorPythonInterface::getNumberOfStorageCells)
|
||||
|
||||
.def("getTimingMode", &Detector::getTimingMode)
|
||||
.def("setTimingMode", &Detector::setTimingMode)
|
||||
.def("getTimingMode", &DetectorPythonInterface::getTimingMode)
|
||||
.def("setTimingMode", &DetectorPythonInterface::setTimingMode)
|
||||
|
||||
.def("getDetectorType", &Detector::getDetectorType)
|
||||
.def("getDetectorType", &DetectorPythonInterface::getDetectorType)
|
||||
|
||||
.def("setThresholdTemperature", &Detector::setThresholdTemperature)
|
||||
.def("getThresholdTemperature", &Detector::getThresholdTemperature)
|
||||
.def("setTemperatureControl", &Detector::setTemperatureControl)
|
||||
.def("getTemperatureControl", &Detector::getTemperatureControl)
|
||||
.def("getTemperatureEvent", &Detector::getTemperatureEvent)
|
||||
.def("resetTemperatureEvent", &Detector::resetTemperatureEvent)
|
||||
.def("setThresholdTemperature", &DetectorPythonInterface::setThresholdTemperature)
|
||||
.def("getThresholdTemperature", &DetectorPythonInterface::getThresholdTemperature)
|
||||
.def("setTemperatureControl", &DetectorPythonInterface::setTemperatureControl)
|
||||
.def("getTemperatureControl", &DetectorPythonInterface::getTemperatureControl)
|
||||
.def("getTemperatureEvent", &DetectorPythonInterface::getTemperatureEvent)
|
||||
.def("resetTemperatureEvent", &DetectorPythonInterface::resetTemperatureEvent)
|
||||
|
||||
.def("getRxDataStreamStatus", &Detector::getRxDataStreamStatus)
|
||||
.def("setRxDataStreamStatus", &Detector::setRxDataStreamStatus)
|
||||
.def("getRxDataStreamStatus", &DetectorPythonInterface::getRxDataStreamStatus)
|
||||
.def("setRxDataStreamStatus", &DetectorPythonInterface::setRxDataStreamStatus)
|
||||
|
||||
// Network stuff
|
||||
.def("getReceiverHostname", &Detector::getReceiverHostname,
|
||||
.def("getReceiverHostname",
|
||||
&DetectorPythonInterface::getReceiverHostname,
|
||||
py::arg("det_id") = -1)
|
||||
.def("setReceiverHostname", &Detector::setReceiverHostname,
|
||||
py::arg("hostname"), py::arg("det_id") = -1)
|
||||
.def("getReceiverStreamingPort", &Detector::getReceiverStreamingPort)
|
||||
.def("setReceiverStreamingPort", &Detector::setReceiverStreamingPort)
|
||||
.def("getReceiverUDPPort", &Detector::getReceiverUDPPort)
|
||||
.def("getReceiverUDPPort2", &Detector::getReceiverUDPPort2)
|
||||
.def("setReceiverUDPPort", &Detector::setReceiverUDPPort)
|
||||
.def("setReceiverUDPPort2", &Detector::setReceiverUDPPort2)
|
||||
.def("setReceiverUDPIP", &Detector::setReceiverUDPIP)
|
||||
.def("getReceiverUDPIP", &Detector::getReceiverUDPIP)
|
||||
.def("getReceiverUDPMAC", &Detector::getReceiverUDPMAC)
|
||||
.def("setReceiverUDPMAC", &Detector::setReceiverUDPMAC)
|
||||
.def("setReceiverHostname",
|
||||
&DetectorPythonInterface::setReceiverHostname, py::arg("hostname"),
|
||||
py::arg("det_id") = -1)
|
||||
.def("getReceiverStreamingPort",
|
||||
&DetectorPythonInterface::getReceiverStreamingPort)
|
||||
.def("setReceiverStreamingPort",
|
||||
&DetectorPythonInterface::setReceiverStreamingPort)
|
||||
.def("getReceiverUDPPort", &DetectorPythonInterface::getReceiverUDPPort)
|
||||
.def("getReceiverUDPPort2",
|
||||
&DetectorPythonInterface::getReceiverUDPPort2)
|
||||
.def("setReceiverUDPPort", &DetectorPythonInterface::setReceiverUDPPort)
|
||||
.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("setReceiverPort", &Detector::setReceiverPort)
|
||||
.def("getReceiverPort", &DetectorPythonInterface::getReceiverPort)
|
||||
.def("setReceiverPort", &DetectorPythonInterface::setReceiverPort)
|
||||
|
||||
.def("configureNetworkParameters",
|
||||
&Detector::configureNetworkParameters)
|
||||
.def("getDelayFrame", &Detector::getDelayFrame)
|
||||
.def("setDelayFrame", &Detector::setDelayFrame)
|
||||
.def("getDelayLeft", &Detector::getDelayLeft)
|
||||
.def("setDelayLeft", &Detector::setDelayLeft)
|
||||
.def("getDelayRight", &Detector::getDelayRight)
|
||||
.def("setDelayRight", &Detector::setDelayRight)
|
||||
.def("getLastClientIP", &Detector::getLastClientIP)
|
||||
.def("getReceiverLastClientIP", &Detector::getReceiverLastClientIP)
|
||||
&DetectorPythonInterface::configureNetworkParameters)
|
||||
.def("getDelayFrame", &DetectorPythonInterface::getDelayFrame)
|
||||
.def("setDelayFrame", &DetectorPythonInterface::setDelayFrame)
|
||||
.def("getDelayLeft", &DetectorPythonInterface::getDelayLeft)
|
||||
.def("setDelayLeft", &DetectorPythonInterface::setDelayLeft)
|
||||
.def("getDelayRight", &DetectorPythonInterface::getDelayRight)
|
||||
.def("setDelayRight", &DetectorPythonInterface::setDelayRight)
|
||||
.def("getLastClientIP", &DetectorPythonInterface::getLastClientIP)
|
||||
.def("getReceiverLastClientIP",
|
||||
&DetectorPythonInterface::getReceiverLastClientIP)
|
||||
|
||||
.def("setFramesPerFile", &Detector::setFramesPerFile)
|
||||
.def("getFramesPerFile", &Detector::getFramesPerFile)
|
||||
.def("setReceiverFifoDepth", &Detector::setReceiverFifoDepth)
|
||||
.def("getReceiverFifoDepth", &Detector::getReceiverFifoDepth)
|
||||
.def("setFramesPerFile", &DetectorPythonInterface::setFramesPerFile)
|
||||
.def("getFramesPerFile", &DetectorPythonInterface::getFramesPerFile)
|
||||
.def("setReceiverFifoDepth",
|
||||
&DetectorPythonInterface::setReceiverFifoDepth)
|
||||
.def("getReceiverFifoDepth",
|
||||
&DetectorPythonInterface::getReceiverFifoDepth)
|
||||
|
||||
.def("getReceiverFrameDiscardPolicy",
|
||||
&Detector::getReceiverFrameDiscardPolicy)
|
||||
&DetectorPythonInterface::getReceiverFrameDiscardPolicy)
|
||||
.def("setReceiverFramesDiscardPolicy",
|
||||
&Detector::setReceiverFramesDiscardPolicy)
|
||||
.def("setPartialFramesPadding", &Detector::setPartialFramesPadding)
|
||||
.def("getPartialFramesPadding", &Detector::getPartialFramesPadding)
|
||||
&DetectorPythonInterface::setReceiverFramesDiscardPolicy)
|
||||
.def("setPartialFramesPadding",
|
||||
&DetectorPythonInterface::setPartialFramesPadding)
|
||||
.def("getPartialFramesPadding",
|
||||
&DetectorPythonInterface::getPartialFramesPadding)
|
||||
|
||||
.def("getUserDetails", &Detector::getUserDetails)
|
||||
.def("getUserDetails", &DetectorPythonInterface::getUserDetails)
|
||||
.def("checkDetectorVersionCompatibility",
|
||||
&Detector::checkDetectorVersionCompatibility)
|
||||
&DetectorPythonInterface::checkDetectorVersionCompatibility)
|
||||
.def("checkReceiverVersionCompatibility",
|
||||
&Detector::checkReceiverVersionCompatibility)
|
||||
.def("getMeasuredPeriod", &Detector::getMeasuredPeriod)
|
||||
.def("getMeasuredSubPeriod", &Detector::getMeasuredSubPeriod)
|
||||
&DetectorPythonInterface::checkReceiverVersionCompatibility)
|
||||
.def("getMeasuredPeriod", &DetectorPythonInterface::getMeasuredPeriod)
|
||||
.def("getMeasuredSubPeriod",
|
||||
&DetectorPythonInterface::getMeasuredSubPeriod)
|
||||
|
||||
.def("setFileWrite", &Detector::setFileWrite)
|
||||
.def("getFileWrite", &Detector::getFileWrite)
|
||||
.def("setFileOverWrite", &Detector::setFileOverWrite)
|
||||
.def("getFileOverWrite", &Detector::getFileOverWrite)
|
||||
.def("getDacVthreshold", &Detector::getDacVthreshold)
|
||||
.def("setDacVthreshold", &Detector::setDacVthreshold)
|
||||
.def("setNumberOfFrames", &Detector::setNumberOfFrames)
|
||||
.def("getNumberOfFrames", &Detector::getNumberOfFrames)
|
||||
.def("setFileWrite", &DetectorPythonInterface::setFileWrite)
|
||||
.def("getFileWrite", &DetectorPythonInterface::getFileWrite)
|
||||
.def("setFileOverWrite", &DetectorPythonInterface::setFileOverWrite)
|
||||
.def("getFileOverWrite", &DetectorPythonInterface::getFileOverWrite)
|
||||
.def("getDacVthreshold", &DetectorPythonInterface::getDacVthreshold)
|
||||
.def("setDacVthreshold", &DetectorPythonInterface::setDacVthreshold)
|
||||
.def("setNumberOfFrames", &DetectorPythonInterface::setNumberOfFrames)
|
||||
.def("getNumberOfFrames", &DetectorPythonInterface::getNumberOfFrames)
|
||||
|
||||
// Overloaded calls
|
||||
.def("getFramesCaughtByReceiver",
|
||||
(int (Detector::*)()) & Detector::getFramesCaughtByReceiver)
|
||||
(int (DetectorPythonInterface::*)()) &
|
||||
DetectorPythonInterface::getFramesCaughtByReceiver)
|
||||
.def("getFramesCaughtByReceiver",
|
||||
(int (Detector::*)(int)) & Detector::getFramesCaughtByReceiver)
|
||||
(int (DetectorPythonInterface::*)(int)) &
|
||||
DetectorPythonInterface::getFramesCaughtByReceiver)
|
||||
|
||||
.def("resetFramesCaught", &Detector::resetFramesCaught)
|
||||
.def("resetFramesCaught", &DetectorPythonInterface::resetFramesCaught)
|
||||
.def("getReceiverCurrentFrameIndex",
|
||||
&Detector::getReceiverCurrentFrameIndex)
|
||||
.def("getGapPixels", &Detector::getGapPixels)
|
||||
.def("setGapPixels", &Detector::setGapPixels)
|
||||
.def("getFlippedDataX", &Detector::getFlippedDataX)
|
||||
.def("getFlippedDataY", &Detector::getFlippedDataY)
|
||||
.def("setFlippedDataX", &Detector::setFlippedDataX)
|
||||
.def("setFlippedDataY", &Detector::setFlippedDataY)
|
||||
&DetectorPythonInterface::getReceiverCurrentFrameIndex)
|
||||
.def("getGapPixels", &DetectorPythonInterface::getGapPixels)
|
||||
.def("setGapPixels", &DetectorPythonInterface::setGapPixels)
|
||||
.def("getFlippedDataX", &DetectorPythonInterface::getFlippedDataX)
|
||||
.def("getFlippedDataY", &DetectorPythonInterface::getFlippedDataY)
|
||||
.def("setFlippedDataX", &DetectorPythonInterface::setFlippedDataX)
|
||||
.def("setFlippedDataY", &DetectorPythonInterface::setFlippedDataY)
|
||||
|
||||
.def("getServerLock", &Detector::getServerLock)
|
||||
.def("setServerLock", &Detector::setServerLock)
|
||||
.def("getReceiverLock", &Detector::getReceiverLock)
|
||||
.def("setReceiverLock", &Detector::setReceiverLock)
|
||||
.def("getServerLock", &DetectorPythonInterface::getServerLock)
|
||||
.def("setServerLock", &DetectorPythonInterface::setServerLock)
|
||||
.def("getReceiverLock", &DetectorPythonInterface::getReceiverLock)
|
||||
.def("setReceiverLock", &DetectorPythonInterface::setReceiverLock)
|
||||
|
||||
.def("getReadoutFlags", &Detector::getReadoutFlags)
|
||||
.def("setReadoutFlag", &Detector::setReadoutFlag)
|
||||
.def("getReadoutFlags", &DetectorPythonInterface::getReadoutFlags)
|
||||
.def("setReadoutFlag", &DetectorPythonInterface::setReadoutFlag)
|
||||
|
||||
.def("setFileFormat", &Detector::setFileFormat)
|
||||
.def("getFileFormat", &Detector::getFileFormat)
|
||||
.def("setFileFormat", &DetectorPythonInterface::setFileFormat)
|
||||
.def("getFileFormat", &DetectorPythonInterface::getFileFormat)
|
||||
|
||||
.def("getActive", &Detector::getActive)
|
||||
.def("setActive", &Detector::setActive)
|
||||
.def("getActive", &DetectorPythonInterface::getActive)
|
||||
.def("setActive", &DetectorPythonInterface::setActive)
|
||||
|
||||
.def("getTenGigabitEthernet", &Detector::getTenGigabitEthernet)
|
||||
.def("setTenGigabitEthernet", &Detector::setTenGigabitEthernet)
|
||||
.def("getTenGigabitEthernet",
|
||||
&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)
|
||||
.def("setPatternLoops", &Detector::setPatternLoops, py::arg("level"),
|
||||
py::arg("start"), py::arg("stop"), py::arg("n"),
|
||||
.def("setPatternWord", &DetectorPythonInterface::setPatternWord,
|
||||
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)
|
||||
.def("setPatternWord", &Detector::setPatternWord, py::arg("addr"),
|
||||
py::arg("word"), py::arg("det_id") = -1)
|
||||
.def("getPatternWord", &Detector::getPatternWord, py::arg("addr"),
|
||||
.def("setPatternClockControl",
|
||||
&DetectorPythonInterface::setPatternClockControl, py::arg("word"),
|
||||
py::arg("det_id") = -1)
|
||||
|
||||
.def("setPatternIOControl", &Detector::setPatternIOControl,
|
||||
py::arg("word"), py::arg("det_id") = -1)
|
||||
.def("setPatternClockControl", &Detector::setPatternClockControl,
|
||||
py::arg("word"), py::arg("det_id") = -1)
|
||||
|
||||
.def("setPatternWaitAddr", &Detector::setPatternWaitAddr,
|
||||
.def("setPatternWaitAddr", &DetectorPythonInterface::setPatternWaitAddr,
|
||||
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)
|
||||
|
||||
.def("setPatternWaitTime", &Detector::setPatternWaitTime,
|
||||
.def("setPatternWaitTime", &DetectorPythonInterface::setPatternWaitTime,
|
||||
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)
|
||||
|
||||
.def("getImageSize", &Detector::getImageSize)
|
||||
.def("setImageSize", &Detector::setImageSize)
|
||||
.def("getNumberOfDetectors", &Detector::getNumberOfDetectors)
|
||||
.def("getDetectorGeometry", &Detector::getDetectorGeometry);
|
||||
.def("getImageSize", &DetectorPythonInterface::getImageSize)
|
||||
.def("setImageSize", &DetectorPythonInterface::setImageSize)
|
||||
.def("getNumberOfDetectors",
|
||||
&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");
|
||||
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/slsDetectorCommand.cpp
|
||||
src/slsDetector.cpp
|
||||
src/Detector.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
@ -39,6 +40,8 @@ set(PUBLICHEADERS
|
||||
include/slsDetectorUsers.h
|
||||
include/detectorData.h
|
||||
include/multiSlsDetector.h
|
||||
include/Detector.h
|
||||
include/Result.h
|
||||
)
|
||||
set_target_properties(slsDetectorShared PROPERTIES
|
||||
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 "sls_detector_defs.h"
|
||||
|
||||
|
||||
class slsDetector;
|
||||
class ZmqSocket;
|
||||
class detectorData;
|
||||
@ -20,6 +19,9 @@ class detectorData;
|
||||
#define SHORT_STRING_LENGTH 50
|
||||
#define DATE_LENGTH 30
|
||||
|
||||
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
/**
|
||||
* @short structure allocated in shared memory to store detector settings
|
||||
* for IPC and cache
|
||||
@ -98,8 +100,7 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* one
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
explicit multiSlsDetector(int multi_id = 0,
|
||||
bool verify = true,
|
||||
explicit multiSlsDetector(int multi_id = 0, bool verify = true,
|
||||
bool update = true);
|
||||
|
||||
/**
|
||||
@ -107,6 +108,101 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
*/
|
||||
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
|
||||
* Called by constructor/ set hostname / read config file
|
||||
@ -114,14 +210,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* one
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
void setupMultiDetector(bool verify = true,
|
||||
bool update = true);
|
||||
void setupMultiDetector(bool verify = true, bool update = true);
|
||||
|
||||
/**
|
||||
* 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>
|
||||
std::vector<RT> serialCall(RT (slsDetector::*somefunc)(CT...),
|
||||
typename NonDeduced<CT>::type... Args);
|
||||
@ -149,13 +243,13 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
std::vector<RT> parallelCall(RT (slsDetector::*somefunc)(CT...) const,
|
||||
typename NonDeduced<CT>::type... Args) const;
|
||||
|
||||
template <typename... CT>
|
||||
void parallelCall(void (slsDetector::*somefunc)(CT...),
|
||||
typename NonDeduced<CT>::type... Args);
|
||||
|
||||
template <typename... CT>
|
||||
void parallelCall(void (slsDetector::*somefunc)(CT...), typename NonDeduced<CT>::type... Args);
|
||||
|
||||
template <typename... CT>
|
||||
void parallelCall(void (slsDetector::*somefunc)(CT...) const, typename NonDeduced<CT>::type... Args) const;
|
||||
|
||||
void parallelCall(void (slsDetector::*somefunc)(CT...) const,
|
||||
typename NonDeduced<CT>::type... Args) const;
|
||||
|
||||
/**
|
||||
* Decodes which detector and the corresponding channel numbers for it
|
||||
@ -210,6 +304,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int64_t getId(idMode mode, int detPos = -1);
|
||||
|
||||
int getMultiId()const{return multiId;}
|
||||
|
||||
/**
|
||||
* Get Client Software version
|
||||
* @returns client software version
|
||||
@ -761,7 +857,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @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
|
||||
@ -898,12 +995,14 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
* @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
|
||||
@ -928,7 +1027,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the detector IP address (bottom half)
|
||||
@ -944,13 +1044,15 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* Validates and sets the receiver.
|
||||
* Also updates the receiver with all the shared memory parameters significant for the receiver
|
||||
* Also configures the detector to the receiver as UDP destination
|
||||
* Also updates the receiver with all the shared memory parameters
|
||||
* significant for the receiver Also configures the detector to the receiver
|
||||
* as UDP destination
|
||||
* @param receiver receiver hostname or IP address
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @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
|
||||
@ -975,7 +1077,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the receiver UDP IP address (bottom half)
|
||||
@ -1005,7 +1108,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the receiver UDP MAC address (bottom half)
|
||||
@ -1043,14 +1147,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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
|
||||
* @returns the receiver UDP port 2 of same interface
|
||||
*/
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the number of interfaces
|
||||
@ -1058,14 +1164,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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
|
||||
* @returns the number of interfaces
|
||||
*/
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the interface selected
|
||||
@ -1073,7 +1181,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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
|
||||
* @returns the interface selected
|
||||
*/
|
||||
@ -1091,7 +1200,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @returns the client zmq port
|
||||
*/
|
||||
@ -1109,7 +1219,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @returns the receiver zmq port
|
||||
*/
|
||||
@ -1127,7 +1238,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @returns the client zmq ip
|
||||
*/
|
||||
@ -1145,7 +1257,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* streaming ip
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the receiver zmq ip
|
||||
*/
|
||||
@ -1159,7 +1272,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @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
|
||||
@ -1167,7 +1281,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @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
|
||||
@ -1177,14 +1292,17 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 value additional json header parameter value (cannot be empty)
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns the additional json header parameter value,
|
||||
* 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
|
||||
@ -1193,21 +1311,26 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* @returns the additional json header parameter value,
|
||||
* 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 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)
|
||||
* @param value frameModeType (-1 gets)
|
||||
* @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);
|
||||
|
||||
@ -1215,7 +1338,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* Sets the detector mode in processor (Moench only)
|
||||
* @param value detectorModetype (-1 gets)
|
||||
* @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);
|
||||
|
||||
@ -1225,7 +1349,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @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
|
||||
@ -1565,7 +1690,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 hostname name of pc to tftp from
|
||||
* @param fname programming file name
|
||||
@ -1589,7 +1715,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int setAutoComparatorDisableMode(int ival = -1, int detPos = -1);
|
||||
|
||||
|
||||
/**
|
||||
* Set Rate correction ( Eiger)
|
||||
* @param t dead time in ns - if 0 disable correction,
|
||||
@ -1942,7 +2067,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
/**
|
||||
* Writes a pattern word (CTB/ Moench)
|
||||
* @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
|
||||
* @returns actual value
|
||||
*/
|
||||
@ -1956,7 +2082,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
* @param n number of loops for level 0-2, -1 gets
|
||||
* @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)
|
||||
@ -1999,14 +2126,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
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 detPos -1 for all detectors in list or specific detector position
|
||||
*/
|
||||
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
|
||||
* @returns mask of bits selected
|
||||
*/
|
||||
@ -2132,8 +2261,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
*/
|
||||
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
|
||||
@ -2205,7 +2332,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int64_t secondsToNanoSeconds(double t);
|
||||
|
||||
|
||||
/** Multi detector Id */
|
||||
const int multiId{0};
|
||||
|
||||
@ -2260,4 +2386,3 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
||||
void *pCallbackArg{nullptr};
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "CmdLineParser.h"
|
||||
#include "CmdProxy.h"
|
||||
#include "Detector.h"
|
||||
#include "container_utils.h"
|
||||
#include "multiSlsDetector.h"
|
||||
#include "slsDetectorCommand.h"
|
||||
@ -109,7 +110,12 @@ class multiSlsDetectorClient {
|
||||
// returns an empty string If the command is not in CmdProxy but
|
||||
// deprecated the new command is returned
|
||||
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(),
|
||||
parser.detector_id(), action_);
|
||||
if (cmd.empty()) {
|
||||
|
@ -629,7 +629,7 @@ class slsDetector : public virtual slsDetectorDefs {
|
||||
* Set starting frame number for the next acquisition
|
||||
* @param val starting frame number
|
||||
*/
|
||||
void setStartingFrameNumber(const uint64_t value);
|
||||
void setStartingFrameNumber(uint64_t value);
|
||||
|
||||
/**
|
||||
* 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";
|
||||
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;
|
||||
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-multiSlsDetector.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 "multiSlsDetector.h"
|
||||
#include "multiSlsDetectorClient.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include <sstream>
|
||||
@ -396,3 +397,39 @@ TEST_CASE("rx_checkversion", "[.cmd]") {
|
||||
multiSlsDetectorClient("rx_checkversion", GET, nullptr, oss);
|
||||
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/ServerInterface2.cpp
|
||||
src/network_utils.cpp
|
||||
src/ToString.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
@ -29,6 +30,9 @@ set(PUBLICHEADERS
|
||||
include/ServerInterface2.h
|
||||
include/network_utils.h
|
||||
include/FixedCapacityContainer.h
|
||||
include/ToString.h
|
||||
include/TimeHelper.h
|
||||
include/TypeTraits.h
|
||||
)
|
||||
|
||||
add_library(slsSupportLib SHARED
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
@ -7,12 +8,48 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Result.h"
|
||||
#include "TimeHelper.h"
|
||||
#include "ToString.h"
|
||||
#include "container_utils.h"
|
||||
#include "logger.h"
|
||||
#include "slsDetectorCommand.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "sls_detector_exceptions.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 {
|
||||
|
||||
template <typename T> class CmdProxy {
|
||||
@ -20,9 +57,8 @@ template <typename T> class CmdProxy {
|
||||
explicit CmdProxy(T *detectorPtr) : det(detectorPtr) {}
|
||||
|
||||
std::string Call(const std::string &command,
|
||||
const std::vector<std::string> &arguments,
|
||||
int detector_id,
|
||||
int action=-1) {
|
||||
const std::vector<std::string> &arguments, int detector_id,
|
||||
int action = -1, std::ostream &os = std::cout) {
|
||||
cmd = command;
|
||||
args = arguments;
|
||||
det_id = detector_id;
|
||||
@ -31,7 +67,7 @@ template <typename T> class CmdProxy {
|
||||
|
||||
auto it = functions.find(cmd);
|
||||
if (it != functions.end()) {
|
||||
std::cout << ((*this).*(it->second))(action);
|
||||
os << ((*this).*(it->second))(action);
|
||||
return {};
|
||||
} else {
|
||||
return cmd;
|
||||
@ -53,17 +89,47 @@ template <typename T> class CmdProxy {
|
||||
|
||||
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:
|
||||
T *det;
|
||||
std::string cmd;
|
||||
std::vector<std::string> args;
|
||||
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 StringMap = std::map<std::string, std::string>;
|
||||
|
||||
// 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"},
|
||||
{"r_padding", "rx_padding"},
|
||||
@ -92,10 +158,10 @@ template <typename T> class CmdProxy {
|
||||
}
|
||||
|
||||
// Mapped functions
|
||||
|
||||
std::string ListCommands(int 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) {
|
||||
auto commands = slsDetectorCommand(nullptr).getAllCommands();
|
||||
@ -127,6 +193,22 @@ template <typename T> class CmdProxy {
|
||||
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
|
||||
|
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 <vector>
|
||||
|
||||
#include "TypeTraits.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
// 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]);
|
||||
}
|
||||
|
||||
template <typename T> bool allEqual(const std::vector<T> &container) {
|
||||
if (container.empty())
|
||||
/** Compare elements in a Container to see if they are all equal */
|
||||
template <typename Container> bool allEqual(const Container &c) {
|
||||
if (!c.empty() &&
|
||||
std::all_of(begin(c), end(c),
|
||||
[c](const typename Container::value_type &element) {
|
||||
return element == c.front();
|
||||
}))
|
||||
return true;
|
||||
return false;
|
||||
const auto &first = container[0];
|
||||
return std::all_of(container.cbegin(), container.cend(),
|
||||
[first](const T &element) { return element == first; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare elements but with specified tolerance, useful
|
||||
* for floating point values.
|
||||
*/
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
|
||||
allEqualWithTol(const std::vector<T> &container, const T tol) {
|
||||
@ -120,6 +129,22 @@ minusOneIfDifferent(const std::vector<std::array<T,size>> &container) {
|
||||
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
|
||||
|
@ -1,14 +1,6 @@
|
||||
#pragma once
|
||||
/************************************************
|
||||
* @file sls_detector_exceptions.h
|
||||
* @short exceptions defined
|
||||
***********************************************/
|
||||
/**
|
||||
*@short exceptions defined
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sls {
|
||||
|
||||
@ -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
|
||||
Templated on array size to ensure no access after buffer limits.
|
||||
*/
|
||||
template <size_t array_size>
|
||||
void removeChar(char (&str)[array_size], char ch) {
|
||||
template <size_t array_size> void removeChar(char (&str)[array_size], char ch) {
|
||||
int count = 0;
|
||||
for (int i = 0; str[i]; i++) {
|
||||
if (str[i] != ch)
|
||||
@ -62,7 +61,8 @@ Concatenate strings using + if the strings are different
|
||||
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>
|
||||
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);
|
||||
|
||||
// remove the end of the string starting with the first aplhabetic character
|
||||
// return the end
|
||||
std::string RemoveUnit(std::string &str);
|
||||
}; // 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<MacAddr> &);
|
||||
|
@ -7,4 +7,5 @@ target_sources(tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-sls_detector_defs.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Sockets.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