From 57245e255cc8f95655bb2933e0969910705f42f0 Mon Sep 17 00:00:00 2001 From: Klaus Wakonig Date: Mon, 10 Jul 2023 10:59:38 +0200 Subject: [PATCH] init --- .gitignore | 177 +++++++++++++ bec_plugins/__init__.py | 1 + bec_plugins/bec_client/__init__.py | 1 + bec_plugins/bec_client/hli/__init__.py | 0 bec_plugins/bec_client/hli/spec_hli.py | 245 ++++++++++++++++++ bec_plugins/bec_client/plugins/__init__.py | 1 + bec_plugins/bec_client/startup/__init__.py | 0 .../bec_client/startup/post_startup.py | 46 ++++ bec_plugins/bec_client/startup/pre_startup.py | 25 ++ bec_plugins/scan_server/__init__.py | 0 deployment/autodeploy_versions | 11 + deployment/bec-server-config.yaml | 18 ++ deployment/deploy.sh | 28 ++ setup.cfg | 21 ++ setup.py | 7 + 15 files changed, 581 insertions(+) create mode 100644 .gitignore create mode 100644 bec_plugins/__init__.py create mode 100644 bec_plugins/bec_client/__init__.py create mode 100644 bec_plugins/bec_client/hli/__init__.py create mode 100644 bec_plugins/bec_client/hli/spec_hli.py create mode 100644 bec_plugins/bec_client/plugins/__init__.py create mode 100644 bec_plugins/bec_client/startup/__init__.py create mode 100644 bec_plugins/bec_client/startup/post_startup.py create mode 100644 bec_plugins/bec_client/startup/pre_startup.py create mode 100644 bec_plugins/scan_server/__init__.py create mode 100644 deployment/autodeploy_versions create mode 100644 deployment/bec-server-config.yaml create mode 100755 deployment/deploy.sh create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74235c6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,177 @@ +**/*_venv +**/.idea +*.log +**/__pycache__ +**/.DS_Store +**/out +**/.vscode +**/.pytest_cache +**/*.egg* + +# file writer data +**.h5 + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/**/_build/ +docs/**/autodoc/ +docs/**/_autosummary/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +**.prof + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/bec_plugins/__init__.py b/bec_plugins/__init__.py new file mode 100644 index 0000000..c8ba5d1 --- /dev/null +++ b/bec_plugins/__init__.py @@ -0,0 +1 @@ +from .bec_client import * diff --git a/bec_plugins/bec_client/__init__.py b/bec_plugins/bec_client/__init__.py new file mode 100644 index 0000000..ba24808 --- /dev/null +++ b/bec_plugins/bec_client/__init__.py @@ -0,0 +1 @@ +from .plugins import * diff --git a/bec_plugins/bec_client/hli/__init__.py b/bec_plugins/bec_client/hli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bec_plugins/bec_client/hli/spec_hli.py b/bec_plugins/bec_client/hli/spec_hli.py new file mode 100644 index 0000000..5d699c2 --- /dev/null +++ b/bec_plugins/bec_client/hli/spec_hli.py @@ -0,0 +1,245 @@ +from bec_client.scan_manager import ScanReport +from bec_utils.devicemanager import Device + +# pylint:disable=undefined-variable +# pylint: disable=too-many-arguments + + +def dscan( + motor1: Device, m1_from: float, m1_to: float, steps: int, exp_time: float, **kwargs +) -> ScanReport: + """Relative line scan with one device. + + Args: + motor1 (Device): Device that should be scanned. + m1_from (float): Start position relative to the current position. + m1_to (float): End position relative to the current position. + steps (int): Number of steps. + exp_time (float): Exposure time. + + Returns: + ScanReport: Status object. + + Examples: + >>> dscan(dev.motor1, -5, 5, 10, 0.1) + """ + return scans.line_scan( + motor1, m1_from, m1_to, steps=steps, exp_time=exp_time, relative=True, **kwargs + ) + + +def d2scan( + motor1: Device, + m1_from: float, + m1_to: float, + motor2: Device, + m2_from: float, + m2_to: float, + steps: int, + exp_time: float, + **kwargs +) -> ScanReport: + """Relative line scan with two devices. + + Args: + motor1 (Device): First device that should be scanned. + m1_from (float): Start position of the first device relative to its current position. + m1_to (float): End position of the first device relative to its current position. + motor2 (Device): Second device that should be scanned. + m2_from (float): Start position of the second device relative to its current position. + m2_to (float): End position of the second device relative to its current position. + steps (int): Number of steps. + exp_time (float): Exposure time + + Returns: + ScanReport: Status object. + + Examples: + >>> d2scan(dev.motor1, -5, 5, dev.motor2, -8, 8, 10, 0.1) + """ + return scans.line_scan( + motor1, + m1_from, + m1_to, + motor2, + m2_from, + m2_to, + steps=steps, + exp_time=exp_time, + relative=True, + **kwargs + ) + + +def ascan(motor1, m1_from, m1_to, steps, exp_time, **kwargs): + """Absolute line scan with one device. + + Args: + motor1 (Device): Device that should be scanned. + m1_from (float): Start position. + m1_to (float): End position. + steps (int): Number of steps. + exp_time (float): Exposure time. + + Returns: + ScanReport: Status object. + + Examples: + >>> ascan(dev.motor1, -5, 5, 10, 0.1) + """ + return scans.line_scan( + motor1, m1_from, m1_to, steps=steps, exp_time=exp_time, relative=False, **kwargs + ) + + +def a2scan(motor1, m1_from, m1_to, motor2, m2_from, m2_to, steps, exp_time, **kwargs): + """Absolute line scan with two devices. + + Args: + motor1 (Device): First device that should be scanned. + m1_from (float): Start position of the first device. + m1_to (float): End position of the first device. + motor2 (Device): Second device that should be scanned. + m2_from (float): Start position of the second device. + m2_to (float): End position of the second device. + steps (int): Number of steps. + exp_time (float): Exposure time + + Returns: + ScanReport: Status object. + + Examples: + >>> a2scan(dev.motor1, -5, 5, dev.motor2, -8, 8, 10, 0.1) + """ + return scans.line_scan( + motor1, + m1_from, + m1_to, + motor2, + m2_from, + m2_to, + steps=steps, + exp_time=exp_time, + relative=False, + **kwargs + ) + + +def dmesh(motor1, m1_from, m1_to, m1_steps, motor2, m2_from, m2_to, m2_steps, exp_time, **kwargs): + """Relative mesh scan (grid scan) with two devices. + + Args: + motor1 (Device): First device that should be scanned. + m1_from (float): Start position of the first device relative to its current position. + m1_to (float): End position of the first device relative to its current position. + m1_steps (int): Number of steps for motor1. + motor2 (Device): Second device that should be scanned. + m2_from (float): Start position of the second device relative to its current position. + m2_to (float): End position of the second device relative to its current position. + m2_steps (int): Number of steps for motor2. + exp_time (float): Exposure time + + Returns: + ScanReport: Status object. + + Examples: + >>> dmesh(dev.motor1, -5, 5, 10, dev.motor2, -8, 8, 10, 0.1) + """ + return scans.grid_scan( + motor1, + m1_from, + m1_to, + m1_steps, + motor2, + m2_from, + m2_to, + m2_steps, + exp_time=exp_time, + relative=True, + ) + + +def amesh(motor1, m1_from, m1_to, m1_steps, motor2, m2_from, m2_to, m2_steps, exp_time, **kwargs): + """Absolute mesh scan (grid scan) with two devices. + + Args: + motor1 (Device): First device that should be scanned. + m1_from (float): Start position of the first device. + m1_to (float): End position of the first device. + m1_steps (int): Number of steps for motor1. + motor2 (Device): Second device that should be scanned. + m2_from (float): Start position of the second device. + m2_to (float): End position of the second device. + m2_steps (int): Number of steps for motor2. + exp_time (float): Exposure time + + Returns: + ScanReport: Status object. + + Examples: + >>> amesh(dev.motor1, -5, 5, 10, dev.motor2, -8, 8, 10, 0.1) + """ + return scans.grid_scan( + motor1, + m1_from, + m1_to, + m1_steps, + motor2, + m2_from, + m2_to, + m2_steps, + exp_time=exp_time, + relative=False, + ) + + +def umv(*args) -> ScanReport: + """Updated absolute move (i.e. blocking) for one or more devices. + + Returns: + ScanReport: Status object. + + Examples: + >>> umv(dev.samx, 1) + >>> umv(dev.samx, 1, dev.samy, 2) + """ + return scans.umv(*args, relative=False) + + +def umvr(*args) -> ScanReport: + """Updated relative move (i.e. blocking) for one or more devices. + + Returns: + ScanReport: Status object. + + Examples: + >>> umvr(dev.samx, 1) + >>> umvr(dev.samx, 1, dev.samy, 2) + """ + return scans.umv(*args, relative=True) + + +def mv(*args) -> ScanReport: + """Absolute move for one or more devices. + + Returns: + ScanReport: Status object. + + Examples: + >>> mv(dev.samx, 1) + >>> mv(dev.samx, 1, dev.samy, 2) + """ + return scans.mv(*args, relative=False) + + +def mvr(*args) -> ScanReport: + """Relative move for one or more devices. + + Returns: + ScanReport: Status object. + + Examples: + >>> mvr(dev.samx, 1) + >>> mvr(dev.samx, 1, dev.samy, 2) + """ + return scans.mv(*args, relative=True) diff --git a/bec_plugins/bec_client/plugins/__init__.py b/bec_plugins/bec_client/plugins/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/bec_plugins/bec_client/plugins/__init__.py @@ -0,0 +1 @@ + diff --git a/bec_plugins/bec_client/startup/__init__.py b/bec_plugins/bec_client/startup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bec_plugins/bec_client/startup/post_startup.py b/bec_plugins/bec_client/startup/post_startup.py new file mode 100644 index 0000000..b12600d --- /dev/null +++ b/bec_plugins/bec_client/startup/post_startup.py @@ -0,0 +1,46 @@ +""" +Post startup script for the BEC client. This script is executed after the +IPython shell is started. It is used to load the beamline specific +information and to setup the prompts. + +The script is executed in the global namespace of the IPython shell. This +means that all variables defined here are available in the shell. + +If needed, bec command-line arguments can be parsed here. For example, to +parse the --session argument, add the following lines to the script: + + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("--session", help="Session name", type=str, default="my_default_session") + args = parser.parse_args() + + if args.session == "my_session": + print("Loading my_session session") + from bec_plugins.bec_client.plugins.my_session import * + else: + print("Loading default session") + from bec_plugins.bec_client.plugins.default_session import * +""" + +# pylint: disable=invalid-name, unused-import, import-error, undefined-variable, unused-variable, unused-argument, no-name-in-module +import argparse + +from bec_lib.core import bec_logger + +logger = bec_logger.logger + +logger.info("Using the PXIII startup script.") + +parser = argparse.ArgumentParser() +parser.add_argument("--session", help="Session name", type=str, default="cSAXS") +args = parser.parse_args() + +# SETUP BEAMLINE INFO +from bec_client.plugins.SLS.sls_info import OperatorInfo, SLSInfo + +bec._beamline_mixin._bl_info_register(SLSInfo) +bec._beamline_mixin._bl_info_register(OperatorInfo) + +# SETUP PROMPTS +bec._ip.prompts.username = "PXIII" +bec._ip.prompts.status = 1 diff --git a/bec_plugins/bec_client/startup/pre_startup.py b/bec_plugins/bec_client/startup/pre_startup.py new file mode 100644 index 0000000..dcfa194 --- /dev/null +++ b/bec_plugins/bec_client/startup/pre_startup.py @@ -0,0 +1,25 @@ +""" +Pre-startup script for BEC client. This script is executed before the BEC client +is started. It can be used to set up the BEC client configuration. The script is +executed in the global namespace of the BEC client. This means that all +variables defined here are available in the BEC client. + +To set up the BEC client configuration, use the ServiceConfig class. For example, +to set the configuration file path, add the following lines to the script: + + import pathlib + from bec_lib.core import ServiceConfig + + current_path = pathlib.Path(__file__).parent.resolve() + CONFIG_PATH = f"{current_path}/" + + config = ServiceConfig(CONFIG_PATH) + +If this startup script defined a ServiceConfig object, the BEC client will use +it to configure itself. Otherwise, the BEC client will use the default config. +""" + +# example: +# current_path = pathlib.Path(__file__).parent.resolve() +# CONFIG_PATH = f"{current_path}/../../../bec_config.yaml" +# config = ServiceConfig(CONFIG_PATH) diff --git a/bec_plugins/scan_server/__init__.py b/bec_plugins/scan_server/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/deployment/autodeploy_versions b/deployment/autodeploy_versions new file mode 100644 index 0000000..44c018c --- /dev/null +++ b/deployment/autodeploy_versions @@ -0,0 +1,11 @@ +# This file is used to select the BEC and Ophyd Devices version for the auto deployment process. +# Do not edit this file unless you know what you are doing! + +# The version can be a git tag, branch or commit hash. + +# BEC version to use +BEC_AUTODEPLOY_VERSION="master" + +# ophyd_devices version to use +OPHYD_DEVICES_AUTODEPLOY_VERSION="master" + diff --git a/deployment/bec-server-config.yaml b/deployment/bec-server-config.yaml new file mode 100644 index 0000000..7c0c7e7 --- /dev/null +++ b/deployment/bec-server-config.yaml @@ -0,0 +1,18 @@ +redis: + host: localhost + port: 6379 +mongodb: + host: localhost + port: 27017 +scibec: + host: http://[::1] + port: 3030 + beamline: "PXIII" +service_config: + general: + reset_queue_on_cancel: True + enforce_ACLs: False + file_writer: + plugin: default_NeXus_format + base_path: ./ + diff --git a/deployment/deploy.sh b/deployment/deploy.sh new file mode 100755 index 0000000..eb3e95e --- /dev/null +++ b/deployment/deploy.sh @@ -0,0 +1,28 @@ +# deployment script to be translated to Ansible + +# can be removed once we have the autodeployment in place +BEAMLINE_REPO=gitlab.psi.ch:bec/pxiii-bec.git +git clone git@$BEAMLINE_REPO + +module add psi-python38/2020.11 + +# start redis +docker run --network=host --name redis-bec -d redis +# alternative: +# conda install -y redis; redis-server & + + +# get the target versions for ophyd_devices and BEC +source ./pxiii-bec/deployment/autodeploy_versions + +git clone -b $OPHYD_DEVICES_AUTODEPLOY_VERSION https://gitlab.psi.ch/bec/ophyd_devices.git +git clone -b $BEC_AUTODEPLOY_VERSION https://gitlab.psi.ch/bec/bec.git + +# install BEC +cd bec +source ./bin/install_bec_dev.sh + +cd ../ +# start the BEC server +bec-server start --config ./pxiii-bec/deployment/bec-server-config.yaml + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..bf71b83 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,21 @@ +[metadata] +name = bec_plugins +description = BEC plugins to modify the behaviour of services within the BEC framework +long_description = file: README.md +long_description_content_type = text/markdown +url = https://gitlab.psi.ch/bec/bec +project_urls = + Bug Tracker = https://gitlab.psi.ch/bec/bec/issues +classifiers = + Programming Language :: Python :: 3 + Development Status :: 3 - Alpha + Topic :: Scientific/Engineering + +[options] +package_dir = + = . +packages = find: +python_requires = >=3.8 + +[options.packages.find] +where = . diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4ee4437 --- /dev/null +++ b/setup.py @@ -0,0 +1,7 @@ +from setuptools import setup + +if __name__ == "__main__": + setup( + install_requires=[], + extras_require={"dev": ["pytest", "pytest-random-order", "coverage"]}, + )