bec-server 2.4.2__tar.gz → 2.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bec_server-2.6.0/.gitignore +180 -0
- bec_server-2.6.0/PKG-INFO +32 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/devices/devicemanager.py +3 -31
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer/__init__.py +1 -1
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer/cli/launch.py +0 -3
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer/file_writer.py +12 -105
- bec_server-2.6.0/bec_server/file_writer_plugins/__init__.py +1 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_manager.py +11 -30
- bec_server-2.6.0/pyproject.toml +62 -0
- bec_server-2.6.0/tests/tests_bec_server_utils/test_main.py +68 -0
- bec_server-2.6.0/tests/tests_bec_server_utils/test_service_handler.py +64 -0
- bec_server-2.6.0/tests/tests_bec_server_utils/test_tmux_launch.py +47 -0
- bec_server-2.6.0/tests/tests_data_processing/conftest.py +12 -0
- bec_server-2.6.0/tests/tests_data_processing/test_dap_cli_launch.py +40 -0
- bec_server-2.6.0/tests/tests_data_processing/test_dap_server.py +13 -0
- bec_server-2.6.0/tests/tests_data_processing/test_dap_service_manager.py +115 -0
- bec_server-2.6.0/tests/tests_data_processing/test_lmfit1d_service.py +164 -0
- bec_server-2.6.0/tests/tests_device_server/conftest.py +24 -0
- bec_server-2.6.0/tests/tests_device_server/test_config_handler.py +109 -0
- bec_server-2.6.0/tests/tests_device_server/test_device_manager_ds.py +174 -0
- bec_server-2.6.0/tests/tests_device_server/test_device_serializer.py +45 -0
- bec_server-2.6.0/tests/tests_device_server/test_device_server.py +814 -0
- bec_server-2.6.0/tests/tests_device_server/test_device_server_cli_launch.py +32 -0
- bec_server-2.6.0/tests/tests_device_server/test_rpc_mixin.py +255 -0
- bec_server-2.6.0/tests/tests_file_writer/conftest.py +12 -0
- bec_server-2.6.0/tests/tests_file_writer/test_file_writer.py +165 -0
- bec_server-2.6.0/tests/tests_file_writer/test_file_writer_cli_launch.py +32 -0
- bec_server-2.6.0/tests/tests_file_writer/test_file_writer_manager.py +284 -0
- bec_server-2.6.0/tests/tests_scan_bundler/conftest.py +51 -0
- bec_server-2.6.0/tests/tests_scan_bundler/test_bec_emitter.py +65 -0
- bec_server-2.6.0/tests/tests_scan_bundler/test_bluesky_emitter.py +78 -0
- bec_server-2.6.0/tests/tests_scan_bundler/test_emitter.py +104 -0
- bec_server-2.6.0/tests/tests_scan_bundler/test_scan_bundler.py +664 -0
- bec_server-2.6.0/tests/tests_scan_bundler/test_scan_bundler_cli_launch.py +32 -0
- bec_server-2.6.0/tests/tests_scan_server/conftest.py +12 -0
- bec_server-2.6.0/tests/tests_scan_server/test_flomni_fermat_scan.py +61 -0
- bec_server-2.6.0/tests/tests_scan_server/test_path_optimization.py +230 -0
- bec_server-2.6.0/tests/tests_scan_server/test_scan_guard.py +307 -0
- bec_server-2.6.0/tests/tests_scan_server/test_scan_server_cli_launch.py +32 -0
- bec_server-2.6.0/tests/tests_scan_server/test_scan_server_queue.py +696 -0
- bec_server-2.6.0/tests/tests_scan_server/test_scan_stubs.py +123 -0
- bec_server-2.6.0/tests/tests_scan_server/test_scan_worker.py +1520 -0
- bec_server-2.6.0/tests/tests_scan_server/test_scans.py +2703 -0
- bec_server-2.6.0/tests/tests_scan_server/utils.py +118 -0
- bec_server-2.6.0/tests/tests_scihub/conftest.py +12 -0
- bec_server-2.6.0/tests/tests_scihub/test_repeated_timer.py +32 -0
- bec_server-2.6.0/tests/tests_scihub/test_scibec_config_handler.py +352 -0
- bec_server-2.6.0/tests/tests_scihub/test_scibec_connector.py +151 -0
- bec_server-2.6.0/tests/tests_scihub/test_scibec_metadata_handler.py +213 -0
- bec_server-2.6.0/tests/tests_scihub/test_scihub_cli_launch.py +32 -0
- bec_server-2.6.0/tests/tests_scihub/test_scilog_connector.py +40 -0
- bec-server-2.4.2/PKG-INFO +0 -12
- bec-server-2.4.2/bec_server/file_writer_plugins/__init__.py +0 -2
- bec-server-2.4.2/bec_server.egg-info/PKG-INFO +0 -12
- bec-server-2.4.2/bec_server.egg-info/SOURCES.txt +0 -78
- bec-server-2.4.2/bec_server.egg-info/dependency_links.txt +0 -1
- bec-server-2.4.2/bec_server.egg-info/entry_points.txt +0 -8
- bec-server-2.4.2/bec_server.egg-info/requires.txt +0 -24
- bec-server-2.4.2/bec_server.egg-info/top_level.txt +0 -1
- bec-server-2.4.2/setup.cfg +0 -26
- bec-server-2.4.2/setup.py +0 -52
- {bec-server-2.4.2 → bec_server-2.6.0}/README.md +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/bec_server_utils/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/bec_server_utils/launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/bec_server_utils/service_handler.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/bec_server_utils/subprocess_launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/bec_server_utils/tmux_launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/cli/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/cli/launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/dap_server.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/dap_service.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/dap_service_manager.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/data_processing/lmfit1d_service.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/cli/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/cli/launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/device_server.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/devices/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/devices/config_update_handler.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/devices/device_serializer.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/device_server/rpc_mixin.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer/cli/__init__.py +0 -0
- {bec-server-2.4.2/bec_server/file_writer_plugins → bec_server-2.6.0/bec_server/file_writer}/default_writer.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer/file_writer_manager.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer/merged_dicts.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/file_writer_plugins/cSAXS.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/bec_emitter.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/bluesky_emitter.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/cli/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/cli/launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/emitter.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_bundler/scan_bundler.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/cli/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/cli/launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/device_validation.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/errors.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/path_optimization.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_assembler.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_guard.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_plugins/LamNIFermatScan.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_plugins/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_plugins/flomni_fermat_scan.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_plugins/otf_scan.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_plugins/owis_grid.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_plugins/sgalil_grid.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_queue.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_server.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_stubs.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scan_worker.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scan_server/scans.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/cli/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/cli/launch.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/repeated_timer.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scibec/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scibec/config_handler.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scibec/scibec_connector.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scibec/scibec_metadata_handler.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scihub.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scilog/__init__.py +0 -0
- {bec-server-2.4.2 → bec_server-2.6.0}/bec_server/scihub/scilog/scilog.py +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
**/*_venv
|
|
2
|
+
**/.idea
|
|
3
|
+
*.log
|
|
4
|
+
**/__pycache__
|
|
5
|
+
**/.DS_Store
|
|
6
|
+
**/out
|
|
7
|
+
**/.vscode
|
|
8
|
+
**/.pytest_cache
|
|
9
|
+
**/*.egg*
|
|
10
|
+
|
|
11
|
+
# recovery_config files
|
|
12
|
+
recovery_config_*
|
|
13
|
+
|
|
14
|
+
# file writer data
|
|
15
|
+
**.h5
|
|
16
|
+
|
|
17
|
+
# Byte-compiled / optimized / DLL files
|
|
18
|
+
__pycache__/
|
|
19
|
+
*.py[cod]
|
|
20
|
+
*$py.class
|
|
21
|
+
|
|
22
|
+
# C extensions
|
|
23
|
+
*.so
|
|
24
|
+
|
|
25
|
+
# Distribution / packaging
|
|
26
|
+
.Python
|
|
27
|
+
build/
|
|
28
|
+
develop-eggs/
|
|
29
|
+
dist/
|
|
30
|
+
downloads/
|
|
31
|
+
eggs/
|
|
32
|
+
.eggs/
|
|
33
|
+
lib/
|
|
34
|
+
lib64/
|
|
35
|
+
parts/
|
|
36
|
+
sdist/
|
|
37
|
+
var/
|
|
38
|
+
wheels/
|
|
39
|
+
share/python-wheels/
|
|
40
|
+
*.egg-info/
|
|
41
|
+
.installed.cfg
|
|
42
|
+
*.egg
|
|
43
|
+
MANIFEST
|
|
44
|
+
|
|
45
|
+
# PyInstaller
|
|
46
|
+
# Usually these files are written by a python script from a template
|
|
47
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
48
|
+
*.manifest
|
|
49
|
+
*.spec
|
|
50
|
+
|
|
51
|
+
# Installer logs
|
|
52
|
+
pip-log.txt
|
|
53
|
+
pip-delete-this-directory.txt
|
|
54
|
+
|
|
55
|
+
# Unit test / coverage reports
|
|
56
|
+
htmlcov/
|
|
57
|
+
.tox/
|
|
58
|
+
.nox/
|
|
59
|
+
.coverage
|
|
60
|
+
.coverage.*
|
|
61
|
+
.cache
|
|
62
|
+
nosetests.xml
|
|
63
|
+
coverage.xml
|
|
64
|
+
*.cover
|
|
65
|
+
*.py,cover
|
|
66
|
+
.hypothesis/
|
|
67
|
+
.pytest_cache/
|
|
68
|
+
cover/
|
|
69
|
+
|
|
70
|
+
# Translations
|
|
71
|
+
*.mo
|
|
72
|
+
*.pot
|
|
73
|
+
|
|
74
|
+
# Django stuff:
|
|
75
|
+
*.log
|
|
76
|
+
local_settings.py
|
|
77
|
+
db.sqlite3
|
|
78
|
+
db.sqlite3-journal
|
|
79
|
+
|
|
80
|
+
# Flask stuff:
|
|
81
|
+
instance/
|
|
82
|
+
.webassets-cache
|
|
83
|
+
|
|
84
|
+
# Scrapy stuff:
|
|
85
|
+
.scrapy
|
|
86
|
+
|
|
87
|
+
# Sphinx documentation
|
|
88
|
+
docs/**/_build/
|
|
89
|
+
docs/**/autodoc/
|
|
90
|
+
docs/**/_autosummary/
|
|
91
|
+
|
|
92
|
+
# PyBuilder
|
|
93
|
+
.pybuilder/
|
|
94
|
+
target/
|
|
95
|
+
|
|
96
|
+
# Jupyter Notebook
|
|
97
|
+
.ipynb_checkpoints
|
|
98
|
+
|
|
99
|
+
# IPython
|
|
100
|
+
profile_default/
|
|
101
|
+
ipython_config.py
|
|
102
|
+
|
|
103
|
+
**.prof
|
|
104
|
+
|
|
105
|
+
# pyenv
|
|
106
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
107
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
108
|
+
# .python-version
|
|
109
|
+
|
|
110
|
+
# pipenv
|
|
111
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
112
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
113
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
114
|
+
# install all needed dependencies.
|
|
115
|
+
#Pipfile.lock
|
|
116
|
+
|
|
117
|
+
# poetry
|
|
118
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
119
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
120
|
+
# commonly ignored for libraries.
|
|
121
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
122
|
+
#poetry.lock
|
|
123
|
+
|
|
124
|
+
# pdm
|
|
125
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
126
|
+
#pdm.lock
|
|
127
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
128
|
+
# in version control.
|
|
129
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
130
|
+
.pdm.toml
|
|
131
|
+
|
|
132
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
133
|
+
__pypackages__/
|
|
134
|
+
|
|
135
|
+
# Celery stuff
|
|
136
|
+
celerybeat-schedule
|
|
137
|
+
celerybeat.pid
|
|
138
|
+
|
|
139
|
+
# SageMath parsed files
|
|
140
|
+
*.sage.py
|
|
141
|
+
|
|
142
|
+
# Environments
|
|
143
|
+
.env
|
|
144
|
+
.venv
|
|
145
|
+
env/
|
|
146
|
+
venv/
|
|
147
|
+
ENV/
|
|
148
|
+
env.bak/
|
|
149
|
+
venv.bak/
|
|
150
|
+
|
|
151
|
+
# Spyder project settings
|
|
152
|
+
.spyderproject
|
|
153
|
+
.spyproject
|
|
154
|
+
|
|
155
|
+
# Rope project settings
|
|
156
|
+
.ropeproject
|
|
157
|
+
|
|
158
|
+
# mkdocs documentation
|
|
159
|
+
/site
|
|
160
|
+
|
|
161
|
+
# mypy
|
|
162
|
+
.mypy_cache/
|
|
163
|
+
.dmypy.json
|
|
164
|
+
dmypy.json
|
|
165
|
+
|
|
166
|
+
# Pyre type checker
|
|
167
|
+
.pyre/
|
|
168
|
+
|
|
169
|
+
# pytype static type analyzer
|
|
170
|
+
.pytype/
|
|
171
|
+
|
|
172
|
+
# Cython debug symbols
|
|
173
|
+
cython_debug/
|
|
174
|
+
|
|
175
|
+
# PyCharm
|
|
176
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
177
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
178
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
179
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
180
|
+
#.idea/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: bec-server
|
|
3
|
+
Version: 2.6.0
|
|
4
|
+
Summary: BEC server
|
|
5
|
+
Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec/issues
|
|
6
|
+
Project-URL: Homepage, https://gitlab.psi.ch/bec/bec
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Requires-Dist: bec-lib
|
|
12
|
+
Requires-Dist: cytoolz
|
|
13
|
+
Requires-Dist: h5py
|
|
14
|
+
Requires-Dist: libtmux
|
|
15
|
+
Requires-Dist: lmfit
|
|
16
|
+
Requires-Dist: msgpack
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: ophyd
|
|
19
|
+
Requires-Dist: ophyd-devices
|
|
20
|
+
Requires-Dist: py-scibec
|
|
21
|
+
Requires-Dist: pydantic
|
|
22
|
+
Requires-Dist: python-dotenv
|
|
23
|
+
Requires-Dist: pyyaml
|
|
24
|
+
Requires-Dist: rich
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: black; extra == 'dev'
|
|
27
|
+
Requires-Dist: coverage; extra == 'dev'
|
|
28
|
+
Requires-Dist: isort; extra == 'dev'
|
|
29
|
+
Requires-Dist: pylint; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-random-order; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-timeout; extra == 'dev'
|
|
@@ -13,7 +13,6 @@ from functools import reduce
|
|
|
13
13
|
|
|
14
14
|
import numpy as np
|
|
15
15
|
import ophyd
|
|
16
|
-
import ophyd.sim as ops
|
|
17
16
|
import ophyd_devices as opd
|
|
18
17
|
from ophyd.ophydobj import OphydObject
|
|
19
18
|
from ophyd.signal import EpicsSignalBase
|
|
@@ -27,16 +26,11 @@ from bec_lib import (
|
|
|
27
26
|
MessageEndpoints,
|
|
28
27
|
bec_logger,
|
|
29
28
|
messages,
|
|
29
|
+
plugin_helper,
|
|
30
30
|
)
|
|
31
31
|
from bec_server.device_server.devices.config_update_handler import ConfigUpdateHandler
|
|
32
32
|
from bec_server.device_server.devices.device_serializer import get_device_info
|
|
33
33
|
|
|
34
|
-
try:
|
|
35
|
-
from bec_plugins import devices as plugin_devices
|
|
36
|
-
except ImportError:
|
|
37
|
-
plugin_devices = None
|
|
38
|
-
|
|
39
|
-
|
|
40
34
|
logger = bec_logger.logger
|
|
41
35
|
|
|
42
36
|
|
|
@@ -118,30 +112,8 @@ class DeviceManagerDS(DeviceManagerBase):
|
|
|
118
112
|
|
|
119
113
|
@staticmethod
|
|
120
114
|
def _get_device_class(dev_type: str) -> type:
|
|
121
|
-
"""
|
|
122
|
-
|
|
123
|
-
The class is looked after in ophyd devices[.module][.submodule] first, if it is not
|
|
124
|
-
present plugin_devices, ophyd, ophyd_devices.sim are searched too
|
|
125
|
-
|
|
126
|
-
Args:
|
|
127
|
-
dev_type (str): device type string
|
|
128
|
-
|
|
129
|
-
Returns:
|
|
130
|
-
type: class object
|
|
131
|
-
"""
|
|
132
|
-
submodule, _, class_name = dev_type.rpartition(":")
|
|
133
|
-
if submodule:
|
|
134
|
-
submodule = f".{submodule.replace(':', '.')}"
|
|
135
|
-
for parent_module in (opd, plugin_devices, ophyd, ops):
|
|
136
|
-
try:
|
|
137
|
-
module = __import__(f"{parent_module.__name__}{submodule}", fromlist=[""])
|
|
138
|
-
except ModuleNotFoundError:
|
|
139
|
-
continue
|
|
140
|
-
else:
|
|
141
|
-
break
|
|
142
|
-
else:
|
|
143
|
-
raise TypeError(f"Unknown device class {dev_type}")
|
|
144
|
-
return getattr(module, class_name)
|
|
115
|
+
"""Get the device class from the device type"""
|
|
116
|
+
return plugin_helper.get_plugin_class(dev_type, [opd, ophyd])
|
|
145
117
|
|
|
146
118
|
def _load_session(self, *_args, **_kwargs):
|
|
147
119
|
delayed_init = []
|
|
@@ -23,9 +23,6 @@ def main():
|
|
|
23
23
|
config = ServiceConfig(config_path)
|
|
24
24
|
|
|
25
25
|
file_writer_manager = file_writer.FileWriterManager(config, RedisConnector)
|
|
26
|
-
file_writer_manager.file_writer.configure(
|
|
27
|
-
layout_file=os.path.abspath("./layout_cSAXS_NXsas.xml")
|
|
28
|
-
)
|
|
29
26
|
try:
|
|
30
27
|
event = threading.Event()
|
|
31
28
|
logger.success("Started FileWriter")
|
|
@@ -8,11 +8,10 @@ import traceback
|
|
|
8
8
|
import typing
|
|
9
9
|
|
|
10
10
|
import h5py
|
|
11
|
-
import xmltodict
|
|
12
11
|
|
|
13
|
-
import
|
|
14
|
-
from bec_lib import MessageEndpoints, bec_logger, messages
|
|
12
|
+
from bec_lib import MessageEndpoints, bec_logger, messages, plugin_helper
|
|
15
13
|
|
|
14
|
+
from .default_writer import NeXus_format as default_NeXus_format
|
|
16
15
|
from .merged_dicts import merge_dicts
|
|
17
16
|
|
|
18
17
|
logger = bec_logger.logger
|
|
@@ -49,107 +48,6 @@ class FileWriter(abc.ABC):
|
|
|
49
48
|
return device_storage
|
|
50
49
|
|
|
51
50
|
|
|
52
|
-
class XMLWriter:
|
|
53
|
-
@staticmethod
|
|
54
|
-
def get_type(type_string: str):
|
|
55
|
-
if type_string == "float":
|
|
56
|
-
return float
|
|
57
|
-
if type_string == "string":
|
|
58
|
-
return str
|
|
59
|
-
if type_string == "int":
|
|
60
|
-
return int
|
|
61
|
-
raise NeXusLayoutError(f"Unsupported data type {type_string}.")
|
|
62
|
-
|
|
63
|
-
def get_value(self, value, entry, source, data_type):
|
|
64
|
-
if source == "constant":
|
|
65
|
-
if data_type:
|
|
66
|
-
return self.get_type(data_type)(value)
|
|
67
|
-
return value
|
|
68
|
-
return entry
|
|
69
|
-
|
|
70
|
-
def add_group(self, container, val):
|
|
71
|
-
name = val.pop("@name")
|
|
72
|
-
group = container.create_group(name)
|
|
73
|
-
self.add_content(group, val)
|
|
74
|
-
|
|
75
|
-
def add_dataset(self, container, val):
|
|
76
|
-
name = val.pop("@name")
|
|
77
|
-
source = val.pop("@source")
|
|
78
|
-
value = val.pop("@value", None)
|
|
79
|
-
data_type = val.pop("@type", None)
|
|
80
|
-
entry = val.pop("@entry", None)
|
|
81
|
-
|
|
82
|
-
data = self.get_value(value=value, entry=entry, source=source, data_type=data_type)
|
|
83
|
-
if data is None:
|
|
84
|
-
return
|
|
85
|
-
dataset = container.create_dataset(name, data=data)
|
|
86
|
-
self.add_content(dataset, val)
|
|
87
|
-
return
|
|
88
|
-
|
|
89
|
-
def add_attribute(self, container, val):
|
|
90
|
-
name = val.pop("@name")
|
|
91
|
-
source = val.pop("@source")
|
|
92
|
-
value = val.pop("@value", None)
|
|
93
|
-
data_type = val.pop("@type", None)
|
|
94
|
-
entry = val.pop("@entry", None)
|
|
95
|
-
|
|
96
|
-
data = self.get_value(value=value, entry=entry, source=source, data_type=data_type)
|
|
97
|
-
setattr(container.attrs, name, data)
|
|
98
|
-
|
|
99
|
-
def add_hardlink(self, container, val):
|
|
100
|
-
pass
|
|
101
|
-
|
|
102
|
-
def add_softlink(self, container, val):
|
|
103
|
-
pass
|
|
104
|
-
|
|
105
|
-
def add_content(self, container, layout):
|
|
106
|
-
for key, values in layout.items():
|
|
107
|
-
if not isinstance(values, list):
|
|
108
|
-
values = [values]
|
|
109
|
-
for val in values:
|
|
110
|
-
if key == "group":
|
|
111
|
-
self.add_group(container, val)
|
|
112
|
-
elif key == "hdf5_layout":
|
|
113
|
-
self.add_base_entry(container, val)
|
|
114
|
-
elif key == "attribute":
|
|
115
|
-
self.add_attribute(container, val)
|
|
116
|
-
elif key == "dataset":
|
|
117
|
-
self.add_dataset(container, val)
|
|
118
|
-
elif key == "hardlink":
|
|
119
|
-
self.add_hardlink(container, val)
|
|
120
|
-
elif key == "softlink":
|
|
121
|
-
self.add_softlink(container, val)
|
|
122
|
-
else:
|
|
123
|
-
pass
|
|
124
|
-
# raise NeXusLayoutError()
|
|
125
|
-
|
|
126
|
-
def add_base_entry(self, container, val):
|
|
127
|
-
self.add_group(container, val["group"])
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
class NeXusFileXMLWriter(FileWriter, XMLWriter):
|
|
131
|
-
def configure(self, layout_file, **kwargs):
|
|
132
|
-
self.layout_file = layout_file
|
|
133
|
-
with open(self.layout_file, "br") as f:
|
|
134
|
-
self.layout = xmltodict.parse(f)
|
|
135
|
-
|
|
136
|
-
def get_value(self, value, entry, source, data_type):
|
|
137
|
-
if source == "constant":
|
|
138
|
-
if data_type:
|
|
139
|
-
return self.get_type(data_type)(value)
|
|
140
|
-
return value
|
|
141
|
-
if source == "bec":
|
|
142
|
-
return self.data.get(entry)
|
|
143
|
-
return entry
|
|
144
|
-
|
|
145
|
-
def write(self, file_path: str, data):
|
|
146
|
-
print(f"writing file to {file_path}")
|
|
147
|
-
self.data = self._create_device_data_storage(data)
|
|
148
|
-
|
|
149
|
-
with h5py.File(file_path, "w") as file:
|
|
150
|
-
self.add_content(file, self.layout)
|
|
151
|
-
|
|
152
|
-
|
|
153
51
|
class HDF5Storage:
|
|
154
52
|
"""
|
|
155
53
|
The HDF5Storage class is a container used by the HDF5 writer plugins to store data in the correct NeXus format.
|
|
@@ -310,7 +208,16 @@ class NexusFileWriter(FileWriter):
|
|
|
310
208
|
).isoformat()
|
|
311
209
|
if data.end_time is not None:
|
|
312
210
|
device_storage["end_time"] = datetime.datetime.fromtimestamp(data.end_time).isoformat()
|
|
313
|
-
|
|
211
|
+
|
|
212
|
+
requested_plugin = self.file_writer_manager.file_writer_config.get("plugin")
|
|
213
|
+
if requested_plugin == "default_NeXus_format":
|
|
214
|
+
writer_format = default_NeXus_format
|
|
215
|
+
else:
|
|
216
|
+
plugins = plugin_helper.get_file_writer_plugins()
|
|
217
|
+
if requested_plugin not in plugins:
|
|
218
|
+
logger.error(f"Plugin {requested_plugin} not found. Using default plugin.")
|
|
219
|
+
writer_format = default_NeXus_format
|
|
220
|
+
|
|
314
221
|
for file_ref in data.file_references.values():
|
|
315
222
|
rel_path = os.path.relpath(file_ref["path"], os.path.dirname(file_path))
|
|
316
223
|
file_ref["path"] = rel_path
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .cSAXS import NeXus_format as cSAXS_NeXus_format
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import glob
|
|
2
|
-
import importlib
|
|
3
|
-
import importlib.util
|
|
4
1
|
import inspect
|
|
5
|
-
import os
|
|
6
|
-
from pathlib import Path
|
|
7
2
|
|
|
8
|
-
from bec_lib import MessageEndpoints, bec_logger
|
|
3
|
+
from bec_lib import MessageEndpoints, bec_logger, plugin_helper
|
|
9
4
|
from bec_lib.messages import AvailableResourceMessage
|
|
10
5
|
from bec_lib.signature_serializer import signature_to_dict
|
|
11
6
|
|
|
@@ -15,7 +10,6 @@ logger = bec_logger.logger
|
|
|
15
10
|
|
|
16
11
|
|
|
17
12
|
class ScanManager:
|
|
18
|
-
DEFAULT_PLUGIN_PATH = Path(os.path.dirname(os.path.abspath(__file__)) + "/../../").resolve()
|
|
19
13
|
|
|
20
14
|
def __init__(self, *, parent):
|
|
21
15
|
"""
|
|
@@ -31,30 +25,17 @@ class ScanManager:
|
|
|
31
25
|
|
|
32
26
|
def load_plugins(self):
|
|
33
27
|
"""load scan plugins"""
|
|
34
|
-
|
|
35
|
-
if not
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
for file in files:
|
|
43
|
-
if file.endswith("__init__.py"):
|
|
28
|
+
plugins = plugin_helper.get_scan_plugins()
|
|
29
|
+
if not plugins:
|
|
30
|
+
return
|
|
31
|
+
for name, cls in plugins.items():
|
|
32
|
+
if not issubclass(cls, ScanServerScans.RequestBase):
|
|
33
|
+
logger.error(
|
|
34
|
+
f"Plugin {name} is not a valid scan plugin as it does not inherit from RequestBase. Skipping."
|
|
35
|
+
)
|
|
44
36
|
continue
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
module_spec.loader.exec_module(plugin_module)
|
|
48
|
-
module_members = inspect.getmembers(plugin_module)
|
|
49
|
-
for name, cls in module_members:
|
|
50
|
-
if not inspect.isclass(cls):
|
|
51
|
-
continue
|
|
52
|
-
# ignore imported classes
|
|
53
|
-
if cls.__module__ != "scan_plugins":
|
|
54
|
-
continue
|
|
55
|
-
if issubclass(cls, ScanServerScans.RequestBase):
|
|
56
|
-
self._plugins[name] = cls
|
|
57
|
-
logger.info(f"Loading scan plugin {name}")
|
|
37
|
+
self._plugins[name] = cls
|
|
38
|
+
logger.info(f"Loading scan plugin {name}")
|
|
58
39
|
|
|
59
40
|
def update_available_scans(self):
|
|
60
41
|
"""load all scans and plugin scans"""
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "bec-server"
|
|
7
|
+
version = "2.6.0"
|
|
8
|
+
description = "BEC server"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Topic :: Scientific/Engineering",
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"bec-lib",
|
|
17
|
+
"cytoolz",
|
|
18
|
+
"h5py",
|
|
19
|
+
"libtmux",
|
|
20
|
+
"lmfit",
|
|
21
|
+
"msgpack",
|
|
22
|
+
"numpy",
|
|
23
|
+
"ophyd",
|
|
24
|
+
"ophyd_devices",
|
|
25
|
+
"pydantic",
|
|
26
|
+
"py-scibec",
|
|
27
|
+
"pyyaml",
|
|
28
|
+
"python-dotenv",
|
|
29
|
+
"rich",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
dev = [
|
|
34
|
+
"black",
|
|
35
|
+
"isort",
|
|
36
|
+
"coverage",
|
|
37
|
+
"pylint",
|
|
38
|
+
"pytest",
|
|
39
|
+
"pytest-random-order",
|
|
40
|
+
"pytest-timeout",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
bec-dap = "bec_server.data_processing:main"
|
|
45
|
+
bec-device-server = "bec_server.device_server:main"
|
|
46
|
+
bec-file-writer = "bec_server.file_writer:main"
|
|
47
|
+
bec-scan-server = "bec_server.scan_server:main"
|
|
48
|
+
bec-scan-bundler = "bec_server.scan_bundler:main"
|
|
49
|
+
bec-scihub = "bec_server.scihub:main"
|
|
50
|
+
bec-server = "bec_server:main"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
[project.urls]
|
|
54
|
+
"Bug Tracker" = "https://gitlab.psi.ch/bec/bec/issues"
|
|
55
|
+
Homepage = "https://gitlab.psi.ch/bec/bec"
|
|
56
|
+
|
|
57
|
+
[tool.hatch.build.targets.wheel]
|
|
58
|
+
include = ["*"]
|
|
59
|
+
|
|
60
|
+
[tool.black]
|
|
61
|
+
line-length = 100
|
|
62
|
+
skip-magic-trailing-comma = true
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from unittest import mock
|
|
2
|
+
|
|
3
|
+
from bec_server.bec_server_utils.launch import main
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_main_start():
|
|
7
|
+
with mock.patch("bec_server.bec_server_utils.launch.ServiceHandler") as mock_service_handler:
|
|
8
|
+
with mock.patch("bec_server.bec_server_utils.launch.argparse") as mock_argparse:
|
|
9
|
+
mock_argparse.ArgumentParser().parse_args.return_value = mock.MagicMock(
|
|
10
|
+
command="start", config=None
|
|
11
|
+
)
|
|
12
|
+
main()
|
|
13
|
+
mock_service_handler.assert_called_once_with(
|
|
14
|
+
bec_path=mock.ANY, config_path=None, no_tmux=False
|
|
15
|
+
)
|
|
16
|
+
mock_service_handler().start.assert_called_once()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_main_stop():
|
|
20
|
+
with mock.patch("bec_server.bec_server_utils.launch.ServiceHandler") as mock_service_handler:
|
|
21
|
+
with mock.patch("bec_server.bec_server_utils.launch.argparse") as mock_argparse:
|
|
22
|
+
mock_argparse.ArgumentParser().parse_args.return_value = mock.MagicMock(
|
|
23
|
+
command="stop", config=None
|
|
24
|
+
)
|
|
25
|
+
main()
|
|
26
|
+
mock_service_handler.assert_called_once_with(
|
|
27
|
+
bec_path=mock.ANY, config_path=None, no_tmux=False
|
|
28
|
+
)
|
|
29
|
+
mock_service_handler().stop.assert_called_once()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_main_restart():
|
|
33
|
+
with mock.patch("bec_server.bec_server_utils.launch.ServiceHandler") as mock_service_handler:
|
|
34
|
+
with mock.patch("bec_server.bec_server_utils.launch.argparse") as mock_argparse:
|
|
35
|
+
mock_argparse.ArgumentParser().parse_args.return_value = mock.MagicMock(
|
|
36
|
+
command="restart", config=None
|
|
37
|
+
)
|
|
38
|
+
main()
|
|
39
|
+
mock_service_handler.assert_called_once_with(
|
|
40
|
+
bec_path=mock.ANY, config_path=None, no_tmux=False
|
|
41
|
+
)
|
|
42
|
+
mock_service_handler().restart.assert_called_once()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_main_start_with_config():
|
|
46
|
+
with mock.patch("bec_server.bec_server_utils.launch.ServiceHandler") as mock_service_handler:
|
|
47
|
+
with mock.patch("bec_server.bec_server_utils.launch.argparse") as mock_argparse:
|
|
48
|
+
mock_argparse.ArgumentParser().parse_args.return_value = mock.MagicMock(
|
|
49
|
+
command="start", config="/path/to/config"
|
|
50
|
+
)
|
|
51
|
+
main()
|
|
52
|
+
mock_service_handler.assert_called_once_with(
|
|
53
|
+
bec_path=mock.ANY, config_path="/path/to/config", no_tmux=False
|
|
54
|
+
)
|
|
55
|
+
mock_service_handler().start.assert_called_once()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_main_restart_with_config():
|
|
59
|
+
with mock.patch("bec_server.bec_server_utils.launch.ServiceHandler") as mock_service_handler:
|
|
60
|
+
with mock.patch("bec_server.bec_server_utils.launch.argparse") as mock_argparse:
|
|
61
|
+
mock_argparse.ArgumentParser().parse_args.return_value = mock.MagicMock(
|
|
62
|
+
command="restart", config="/path/to/config"
|
|
63
|
+
)
|
|
64
|
+
main()
|
|
65
|
+
mock_service_handler.assert_called_once_with(
|
|
66
|
+
bec_path=mock.ANY, config_path="/path/to/config", no_tmux=False
|
|
67
|
+
)
|
|
68
|
+
mock_service_handler().restart.assert_called_once()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from unittest import mock
|
|
2
|
+
|
|
3
|
+
from bec_server.bec_server_utils.service_handler import ServiceHandler
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_service_handler():
|
|
7
|
+
bec_path = "/path/to/bec"
|
|
8
|
+
config_path = "/path/to/config"
|
|
9
|
+
|
|
10
|
+
with mock.patch("bec_server.bec_server_utils.service_handler.sys") as mock_sys:
|
|
11
|
+
mock_sys.platform = "linux"
|
|
12
|
+
service_handler = ServiceHandler(bec_path, config_path)
|
|
13
|
+
assert service_handler.interface == "tmux"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_service_handler_start():
|
|
17
|
+
bec_path = "/path/to/bec"
|
|
18
|
+
config_path = "/path/to/config"
|
|
19
|
+
|
|
20
|
+
with mock.patch("bec_server.bec_server_utils.service_handler.sys") as mock_sys:
|
|
21
|
+
mock_sys.platform = "linux"
|
|
22
|
+
service_handler = ServiceHandler(bec_path, config_path)
|
|
23
|
+
|
|
24
|
+
with mock.patch(
|
|
25
|
+
"bec_server.bec_server_utils.service_handler.tmux_start"
|
|
26
|
+
) as mock_tmux_start:
|
|
27
|
+
service_handler.start()
|
|
28
|
+
mock_tmux_start.assert_called_once_with(bec_path, config_path, service_handler.SERVICES)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_service_handler_stop():
|
|
32
|
+
with mock.patch("bec_server.bec_server_utils.service_handler.tmux_stop") as mock_tmux_stop:
|
|
33
|
+
service_handler = ServiceHandler("/path/to/bec", "/path/to/config")
|
|
34
|
+
service_handler.stop()
|
|
35
|
+
mock_tmux_stop.assert_called_once()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_service_handler_restart():
|
|
39
|
+
bec_path = "/path/to/bec"
|
|
40
|
+
config_path = "/path/to/config"
|
|
41
|
+
|
|
42
|
+
with mock.patch("bec_server.bec_server_utils.service_handler.sys") as mock_sys:
|
|
43
|
+
mock_sys.platform = "linux"
|
|
44
|
+
service_handler = ServiceHandler(bec_path, config_path)
|
|
45
|
+
|
|
46
|
+
with mock.patch("bec_server.bec_server_utils.service_handler.tmux_stop") as mock_tmux_stop:
|
|
47
|
+
with mock.patch(
|
|
48
|
+
"bec_server.bec_server_utils.service_handler.tmux_start"
|
|
49
|
+
) as mock_tmux_start:
|
|
50
|
+
service_handler.restart()
|
|
51
|
+
mock_tmux_stop.assert_called_once()
|
|
52
|
+
mock_tmux_start.assert_called_once_with(
|
|
53
|
+
bec_path, config_path, service_handler.SERVICES
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_service_handler_services():
|
|
58
|
+
service_handler = ServiceHandler("/path/to/bec", "/path/to/config")
|
|
59
|
+
assert (
|
|
60
|
+
service_handler.SERVICES["scan_server"]["path"].substitute(base_path="/path/to/bec")
|
|
61
|
+
== "/path/to/bec/scan_server"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
assert service_handler.SERVICES["scan_server"]["command"] == "bec-scan-server"
|