39 Commits

Author SHA1 Message Date
gac-x06da
1cd8760a13 BEC demo examples from Klaus 2025-01-21 15:42:37 +01:00
434ddad89a added license 2024-10-01 10:21:41 +02:00
e32642526f build: pandas and matplotlib added as dependencies 2024-08-14 15:50:35 +02:00
f22487a45b Merge branch 'features/updating-naming-convention' into 'main'
Updating naming convention

See merge request bec/pxiii_bec!15
2024-07-09 10:34:42 +02:00
ace0303301 Naming convention updates for OP 2024-07-08 15:42:03 +02:00
8c4ade4034 Naming convention updates for OP 2024-07-08 15:23:50 +02:00
a799321f98 Merge branch 'fix/bec-widgets-auto-update-import' into 'main'
fix(auto_updates): import from bec_widgets cli autoupdates fixed

See merge request bec/pxiii_bec!14
2024-07-08 14:42:57 +02:00
989dc4be36 fix(auto_updates): import from bec_widgets cli autoupdates fixed 2024-07-08 14:20:21 +02:00
12803b4b6f Merge branch 'fix/epics_ca_addr_list' into 'main'
Changed EPICS_CA_ADDR_LIST to PX III

See merge request bec/pxiii_bec!13
2024-06-23 11:09:53 +02:00
gac-x06da
1834e6f55d Klaus changed EPICS_CA_ADDR_LIST to PX III 2024-06-21 11:07:39 +02:00
5c4a0f92bc Merge branch 'feat/db-hide-compact-config' into 'main'
Hiding compact config from tests

See merge request bec/pxiii_bec!11
2024-06-07 16:22:57 +02:00
b9f0574876 Hiding compact config from tests 2024-06-07 16:15:21 +02:00
f0da85e930 Added keithley diodes in ES 2024-06-07 15:28:22 +02:00
8bb7d2332c All devices load for now 2024-06-07 15:07:14 +02:00
ci_update_bot
6b32ee6ee9 docs: Update device list 2024-06-07 10:04:44 +00:00
84eb0c74c6 Preliminary DB generator from ophyd_devices 2024-06-07 12:02:52 +02:00
824706d1d8 Merge branch 'fix_imports' into 'main'
fix: adapt import to refactoring in bec_lib

See merge request bec/pxiii_bec!10
2024-05-15 18:58:04 +02:00
7cd2a4d44c fix: adapt import to refactoring in bec_lib 2024-05-15 15:10:54 +02:00
2a1180cc90 ci: added child pipeline var 2024-05-13 16:39:31 +02:00
a32d0821ed ci: added ci file 2024-05-07 12:59:02 +02:00
a6f8d6936e Merge branch 'fix/pre_startup' into 'main'
fix: added get config for PX-III

See merge request bec/pxiii_bec!9
2024-04-29 17:29:27 +02:00
fa52c5eee1 fix: added get config for PX-III 2024-04-29 14:00:38 +02:00
1448c6b82a Merge branch 'feature/update_script' into 'main'
feat: added auto updates for bec figures

See merge request bec/pxiii-bec!7
2024-04-24 07:28:17 +02:00
f768808776 Merge branch 'fix/file_writer' into 'main'
fix: added file writer entry point

See merge request bec/pxiii-bec!8
2024-04-23 19:09:17 +02:00
265c09d746 fix: added file writer entry point 2024-04-23 18:27:08 +02:00
cae8614cb5 feat: added auto updates for bec figures 2024-04-23 13:25:08 +02:00
be5c35a938 build: fixed ds plugin name 2024-04-23 09:56:38 +02:00
2d18332e23 Merge branch 'build/plugin_update' into 'main'
build: updated to new plugin structure

See merge request bec/pxiii-bec!6
2024-04-23 08:08:21 +02:00
b9d471361a build: added CA startup entrypoint 2024-04-22 19:33:01 +02:00
ce4d57c597 build: updated to new plugin structure 2024-04-22 19:18:27 +02:00
e81c8b1484 Merge branch 'doc-pmodule-update' into 'master'
doc: psi-python311/2024.02 is now stable

See merge request bec/pxiii-bec!5
2024-03-13 21:30:26 +01:00
1a84335bbb doc: psi-python311/2024.02 is now stable 2024-03-12 13:33:24 +01:00
e87598bc7e Merge branch 'drop-python39' into 'master'
ci: drop python/3.9

See merge request bec/pxiii-bec!4
2024-03-05 22:39:41 +01:00
106f3bed6e ci: drop python/3.9 2024-03-05 12:59:22 +01:00
1de99e47d6 Merge branch 'python39' into 'master'
transition to python/3.9

See merge request bec/pxiii-bec!3
2023-12-12 21:16:36 +01:00
0cdb8e3ca6 refactor: update to psi-python39/2021.11 in deploy script 2023-12-12 16:51:58 +01:00
3887cdb835 build: require python3.9 2023-12-12 16:36:33 +01:00
d89ba54768 Merge branch 'fix-imports' into 'master'
fix: update imports

See merge request bec/pxiii-bec!2
2023-12-08 12:45:36 +01:00
04b08b9d21 fix: update imports 2023-12-08 12:37:37 +01:00
38 changed files with 945 additions and 316 deletions

7
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,7 @@
include:
- project: bec/awi_utils
file: /templates/plugin-repo-template.yml
inputs:
name: "pxiii"
target: "pxiii_bec"
branch: $CHILD_PIPELINE_BRANCH

28
LICENSE Normal file
View File

@@ -0,0 +1,28 @@
BSD 3-Clause License
Copyright (c) 2024, Paul Scherrer Institute
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1 +0,0 @@
from .bec_client import *

View File

@@ -1 +0,0 @@
from .plugins import *

View File

@@ -1,245 +0,0 @@
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)

View File

@@ -1 +0,0 @@

View File

@@ -1,25 +0,0 @@
"""
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}/<path_to_my_config_file.yaml>"
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)

View File

@@ -4,7 +4,7 @@
BEAMLINE_REPO=gitlab.psi.ch:bec/pxiii-bec.git
git clone git@$BEAMLINE_REPO
module add psi-python38/2020.11
module add psi-python311/2024.02
# start redis
docker run --network=host --name redis-bec -d redis
@@ -27,4 +27,3 @@ pip install -e ./pxiii-bec
# start the BEC server
bec-server start --config ./pxiii-bec/deployment/bec-server-config.yaml

View File

@@ -16,31 +16,30 @@ parse the --session argument, add the following lines to the script:
if args.session == "my_session":
print("Loading my_session session")
from bec_plugins.bec_client.plugins.my_session import *
from bec_plugins.bec_ipython_client.plugins.my_session import *
else:
print("Loading default session")
from bec_plugins.bec_client.plugins.default_session import *
from bec_plugins.bec_ipython_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
from bec_lib import bec_logger
logger = bec_logger.logger
logger.info("Using the PXIII startup script.")
logger.info("Using the PX-III startup script.")
parser = argparse.ArgumentParser()
parser.add_argument("--session", help="Session name", type=str, default="cSAXS")
args = parser.parse_args()
# pylint: disable=import-error
_args = _main_dict["args"]
# SETUP BEAMLINE INFO
from bec_client.plugins.SLS.sls_info import OperatorInfo, SLSInfo
_session_name = "PX-III"
if _args.session.lower() == "alignment":
# load the alignment session
_session_name = "Alignment"
logger.success("Alignment session loaded.")
bec._beamline_mixin._bl_info_register(SLSInfo)
bec._beamline_mixin._bl_info_register(OperatorInfo)
# SETUP PROMPTS
bec._ip.prompts.username = "PXIII"
bec._ip.prompts.username = _session_name
bec._ip.prompts.status = 1

View File

@@ -0,0 +1,23 @@
"""
Pre-startup script for BEC client. This script is executed before the BEC client
is started. It can be used to add additional command line arguments.
"""
from bec_lib.service_config import ServiceConfig
def extend_command_line_args(parser):
"""
Extend the command line arguments of the BEC client.
"""
parser.add_argument("--session", help="Session name", type=str, default="PX-III")
return parser
def get_config() -> ServiceConfig:
"""
Create and return the service configuration.
"""
return ServiceConfig(redis={"host": "x06da-bec-001", "port": 6379})

View File

@@ -0,0 +1 @@
from .auto_updates import PlotUpdate

View File

@@ -0,0 +1,26 @@
from bec_widgets.cli.auto_updates import AutoUpdates, ScanInfo
class PlotUpdate(AutoUpdates):
# def simple_line_scan(self, info: ScanInfo) -> None:
# """
# Simple line scan.
# """
# dev_x = info.scan_report_devices[0]
# dev_y = self.get_selected_device(info.monitored_devices, self.figure.selected_device)
# if not dev_y:
# return
# self.figure.clear_all()
# plt = self.figure.plot(dev_x, dev_y)
# plt.set(title=f"PXIII: Scan {info.scan_number}", x_label=dev_x, y_label=dev_y)
def handler(self, info: ScanInfo) -> None:
# EXAMPLES:
# if info.scan_name == "line_scan" and info.scan_report_devices:
# self.simple_line_scan(info)
# return
# if info.scan_name == "grid_scan" and info.scan_report_devices:
# self.run_grid_scan_update(info)
# return
super().handler(info)

View File

View File

View File

@@ -0,0 +1,11 @@
import os
def setup_epics_ca():
os.environ["EPICS_CA_AUTO_ADDR_LIST"] = "NO"
os.environ["EPICS_CA_ADDR_LIST"] = "129.129.110.255"
os.environ["PYTHONIOENCODING"] = "latin1"
def run():
setup_epics_ca()

View File

@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
"""
Created on Wed Aug 31 10:27:18 2022
Database migration from a sensible format to the BEC YAML file format
@author: mohacsi_i
"""
import yaml
import yaml.representer
def MigrateYamlFile(filein, fileout):
""" Migrates an absolutely minimal YAML config file to the format
required by the BEC (i.e. adding default fields).
"""
fp = open(filein, "r")
lut = yaml.load(fp, Loader=yaml.Loader)
# Allocate empty database
db = dict()
for k,v in lut.items():
new = v
# Adding defaults
if 'onFailure' not in new:
new['onFailure'] = "buffer"
if 'enabled' not in new:
new['enabled'] = True
if 'readoutPriority' not in new:
new['readoutPriority'] = "monitored"
if 'readOnly' not in new:
new['readOnly'] = bool(new['deviceClass'] in ('ophyd.EpicsSignalRO'))
if 'softwareTrigger' not in new:
new['softwareTrigger'] = False
if new['deviceClass'] == "ophyd.EpicsSignalRO":
if "read_pv" not in new['deviceConfig']:
new["deviceConfig"]["read_pv"] = new["deviceConfig"]["prefix"]
del new["deviceConfig"]["prefix"]
db[k] = new
with open(fileout, 'w') as stream:
yaml.dump(db, stream, default_flow_style=None, sort_keys=False)
# Automatically start simulation if directly invoked
if __name__ == "__main__":
MigrateYamlFile("./x06da_compact.lmay", "x06da_device_config.yaml")

View File

View File

@@ -0,0 +1,199 @@
# OP before mono
slh_trxr:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-SLH:TRXR'
slh_trxw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-SLH:TRXW'
fi1_try:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-FI1:TRY'
# DCCM crystal 1
dccm_pitch1:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-DCCM:PITCH1'
dccm_energy1:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-DCCM:ENERGY1'
dccm_diode:
deviceClass: ophyd.EpicsSignalRO
deviceConfig:
prefix: 'X06DA-OP-XPM1:BOT:READOUT'
# DCCM crystal 2
dccm_pitch2:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-DCCM:PITCH2'
dccm_energy2:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-DCCM:ENERGY2'
dccm_xbpm:
deviceClass: ophyd.EpicsSignalRO
deviceConfig:
prefix: 'X06DA-OP-XBPM1:SumAll:MeanValue_RBV'
# DCCM common
dccm_energy:
description: Monochromator energy using ECMC virtual motors
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-DCCM:_ENERGY'
dccm_eoffset:
description: Monochromator energy offset for ECMC virtual motors
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-OP-DCCM:_EOFFSET'
# Secondary source XBPM
ssxbpm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSBPM1:TRX'
ssxbpm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSBPM1:TRY'
ssslit_trxr:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSSH1:TRXR'
ssslit_trxw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSSH1:TRXW'
ssslit_tryt:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSSV1:TRYT'
ssslit_tryb:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSSV1:TRYB'
ssxi1_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSXI1:TRX'
ssxi1_try:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES-SSXI1:TRY'
# Vertical focusing mirror
vfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRXU'
enabled: false
vfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRXD'
enabled: false
vfm_tryuw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRYUW'
vfm_tryr:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRYR'
vfm_trydw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRYDW'
vfm_pitch:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:PITCH'
vfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:YAW'
enabled: false
vfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:ROLL'
enabled: false
vfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRX'
enabled: false
vfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-VFM:TRY'
# Horizontal focusing mirror
hfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRXU'
enabled: false
hfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRXD'
enabled: false
hfm_tryur:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRYUR'
hfm_tryw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRYW'
hfm_trydr:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRYDR'
hfm_pitch:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:PITCH'
enabled: false
hfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:YAW'
enabled: false
hfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:ROLL'
enabled: false
hfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRX'
enabled: false
hfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig:
prefix: 'X06DA-ES1-HFM:TRY'
# Exposure box signals
xbox_diode:
deviceClass: ophyd.EpicsSignalRO
deviceConfig:
prefix: 'X06DA-ES-DI1:READOUT'
bstop_diode:
deviceClass: ophyd.EpicsSignalRO
deviceConfig:
prefix: 'X06DA-ES-BS:READOUT'

View File

@@ -0,0 +1,331 @@
slh_trxr:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
slh_trxw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
fi1_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-FI1:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_pitch1:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:PITCH1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_energy1:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:ENERGY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_diode:
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XPM1:BOT:READOUT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_pitch2:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:PITCH2'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_energy2:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:ENERGY2'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_energy:
description: Monochromator energy using ECMC virtual motors
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:_ENERGY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_eoffset:
description: Monochromator energy offset between crystals using ECMC virtual motors
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:_EOFFSET'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_xbpm:
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XBPM1:SumAll:MeanValue_RBV'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
ssxbpm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRX'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_trxr:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_trxw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_tryt:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_tryb:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYB'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxi1_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSXI1:TRX'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxi1_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSXI1:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRXU'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRXD'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_tryuw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRYUW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_tryr:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRYR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trydw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRYDW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_pitch:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:PITCH'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:YAW'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:ROLL'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRX'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-VFM:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRXU'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRXD'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_tryur:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRYUR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_tryw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRYW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trydr:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRYDR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_pitch:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:PITCH'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:YAW'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:ROLL'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRX'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES1-HFM:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_diode:
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DI1:READOUT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
bstop_diode:
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-BS:READOUT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false

View File

View File

@@ -0,0 +1,5 @@
// This file was autogenerated. Do not edit it manually.
## Device List
### pxiii_bec
| Device | Documentation | Module |
| :----- | :------------- | :------ |

View File

View File

@@ -0,0 +1 @@
from .my_test_scan import MyScan

View File

@@ -0,0 +1,10 @@
from bec_server.scan_server.scans import LineScan
class MyScan(LineScan):
scan_name = "test_scan"
def _calculate_positions(self):
return super()._calculate_positions()

80
pyproject.toml Normal file
View File

@@ -0,0 +1,80 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "pxiii_bec"
version = "0.0.0"
description = "Custom device implementations based on the ophyd hardware abstraction layer"
requires-python = ">=3.10"
classifiers = [
"Development Status :: 3 - Alpha",
"Programming Language :: Python :: 3",
"Topic :: Scientific/Engineering",
]
dependencies = [
"bec_ipython_client",
"bec_lib",
"bec_server",
"ophyd_devices",
"std_daq_client",
"rich",
"pyepics",
"pandas~=2.0",
"matplotlib",
]
[project.optional-dependencies]
dev = [
"black",
"isort",
"coverage",
"pylint",
"pytest",
"pytest-random-order",
"pytest-redis",
]
[project.entry-points."bec"]
plugin_bec = "pxiii_bec"
[project.entry-points."bec.deployment.device_server"]
plugin_ds_startup = "pxiii_bec.deployment.device_server.startup:run"
[project.entry-points."bec.file_writer"]
plugin_file_writer = "pxiii_bec.file_writer"
[project.entry-points."bec.scans"]
plugin_scans = "pxiii_bec.scans"
[project.entry-points."bec.ipython_client_startup"]
plugin_ipython_client_pre = "pxiii_bec.bec_ipython_client.startup.pre_startup"
plugin_ipython_client_post = "pxiii_bec.bec_ipython_client.startup"
[project.entry-points."bec.widgets.auto_updates"]
plugin_widgets_update = "pxiii_bec.bec_widgets.auto_updates:PlotUpdate"
[tool.hatch.build.targets.wheel]
include = ["*"]
[tool.isort]
profile = "black"
line_length = 100
multi_line_output = 3
include_trailing_comma = true
[tool.black]
line-length = 100
skip-magic-trailing-comma = true
[tool.pylint.basic]
# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs = [
".*scanID.*",
".*RID.*",
".*pointID.*",
".*ID.*",
".*_2D.*",
".*_1D.*",
]

View File

@@ -1,21 +0,0 @@
[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 = .

View File

@@ -1,7 +0,0 @@
from setuptools import setup
if __name__ == "__main__":
setup(
install_requires=[],
extras_require={"dev": ["pytest", "pytest-random-order", "coverage"]},
)

View File

@@ -0,0 +1,31 @@
# Getting Started with Testing using pytest
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
It can be install via
``` bash
pip install pytest
```
in your *python environment*.
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
## Introduction
Tests in this package should be stored in the `tests` directory.
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
To run all tests, navigate to the directory of the plugin from the command line, and run the command
``` bash
pytest -v --random-order ./tests
```
Note, the python environment needs to be active.
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
## Test examples
Writing tests can be quite specific for the given function.
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).

View File

@@ -0,0 +1,31 @@
# Getting Started with Testing using pytest
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
It can be install via
``` bash
pip install pytest
```
in your *python environment*.
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
## Introduction
Tests in this package should be stored in the `tests` directory.
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
To run all tests, navigate to the directory of the plugin from the command line, and run the command
``` bash
pytest -v --random-order ./tests
```
Note, the python environment needs to be active.
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
## Test examples
Writing tests can be quite specific for the given function.
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).

View File

@@ -0,0 +1,31 @@
# Getting Started with Testing using pytest
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
It can be install via
``` bash
pip install pytest
```
in your *python environment*.
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
## Introduction
Tests in this package should be stored in the `tests` directory.
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
To run all tests, navigate to the directory of the plugin from the command line, and run the command
``` bash
pytest -v --random-order ./tests
```
Note, the python environment needs to be active.
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
## Test examples
Writing tests can be quite specific for the given function.
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).

View File

@@ -0,0 +1,31 @@
# Getting Started with Testing using pytest
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
It can be install via
``` bash
pip install pytest
```
in your *python environment*.
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
## Introduction
Tests in this package should be stored in the `tests` directory.
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
To run all tests, navigate to the directory of the plugin from the command line, and run the command
``` bash
pytest -v --random-order ./tests
```
Note, the python environment needs to be active.
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
## Test examples
Writing tests can be quite specific for the given function.
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).

View File

@@ -0,0 +1,31 @@
# Getting Started with Testing using pytest
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
It can be install via
``` bash
pip install pytest
```
in your *python environment*.
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
## Introduction
Tests in this package should be stored in the `tests` directory.
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
To run all tests, navigate to the directory of the plugin from the command line, and run the command
``` bash
pytest -v --random-order ./tests
```
Note, the python environment needs to be active.
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
## Test examples
Writing tests can be quite specific for the given function.
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).