Compare commits
48 Commits
fix_mono_n
...
feat/vario
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efd8842540 | ||
|
|
fd1626fbcd | ||
|
|
062df3171b | ||
|
|
37a268fe7b | ||
|
|
e9e7d84e60 | ||
|
|
1c0c9ad53e | ||
|
|
faeb991b75 | ||
|
|
7377613213 | ||
|
|
d8383d3b73 | ||
|
|
c3bfab2056 | ||
|
|
0261c601ff | ||
|
|
d3dc130f11 | ||
|
|
ed1e5a027f | ||
|
|
df2961ce8e | ||
|
|
e179fc1a07 | ||
| 60d1dfc5af | |||
| 3e2e37908b | |||
| 804a731181 | |||
| 99f6192f37 | |||
| 0a8272685d | |||
| c6ed27966c | |||
| 6a8f6c7988 | |||
| 6bfc8999f7 | |||
| c70088e7bc | |||
| 190eae2c3f | |||
| 1d6caa2291 | |||
| 9b739c852d | |||
| 9d9a2e9681 | |||
|
|
ed759da14f | ||
|
|
158175f545 | ||
|
|
ed9148ed96 | ||
|
|
0a83b59af8 | ||
|
|
a67394a9a2 | ||
|
|
a6f0d01558 | ||
|
|
217a14d03d | ||
|
|
4424f83b8b | ||
|
|
626b0dc8a0 | ||
|
|
1f7fdb89d7 | ||
|
|
ee748d56c4 | ||
|
|
02e6462ea1 | ||
| 2633c8be0a | |||
| 09c3e395de | |||
| 8e5bdd230d | |||
|
|
dd0fe31cb7 | ||
| 442c421d05 | |||
| 85042a7f45 | |||
| 6a1992f605 | |||
| aaf4084517 |
@@ -2,7 +2,7 @@
|
||||
# It is needed to track the repo template version, and editing may break things.
|
||||
# This file will be overwritten by copier on template updates.
|
||||
|
||||
_commit: v1.0.0
|
||||
_commit: v1.2.8
|
||||
_src_path: https://github.com/bec-project/plugin_copier_template.git
|
||||
make_commit: false
|
||||
project_name: debye_bec
|
||||
|
||||
102
.gitea/workflows/ci.yml
Normal file
102
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
name: CI for debye_bec
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
BEC_WIDGETS_BRANCH:
|
||||
description: "Branch of BEC Widgets to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
BEC_CORE_BRANCH:
|
||||
description: "Branch of BEC Core to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
OPHYD_DEVICES_BRANCH:
|
||||
description: "Branch of Ophyd Devices to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
BEC_PLUGIN_REPO_BRANCH:
|
||||
description: "Branch of the BEC Plugin Repository to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
PYTHON_VERSION:
|
||||
description: "Python version to use"
|
||||
required: false
|
||||
type: string
|
||||
default: "3.12"
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
QTWEBENGINE_DISABLE_SANDBOX: 1
|
||||
QT_QPA_PLATFORM: "offscreen"
|
||||
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "${{ inputs.PYTHON_VERSION || '3.12' }}"
|
||||
|
||||
- name: Checkout BEC Plugin Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bec/debye_bec
|
||||
ref: "${{ inputs.BEC_PLUGIN_REPO_BRANCH || github.head_ref || github.sha }}"
|
||||
path: ./debye_bec
|
||||
|
||||
- name: Lint for merge conflicts from template updates
|
||||
shell: bash
|
||||
# Find all Copier conflicts except this line
|
||||
run: '! grep -r "<<<<<<< before updating" | grep -v "grep -r \"<<<<<<< before updating"'
|
||||
|
||||
- name: Checkout BEC Core
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bec/bec
|
||||
ref: "${{ inputs.BEC_CORE_BRANCH || 'main' }}"
|
||||
path: ./bec
|
||||
|
||||
- name: Checkout Ophyd Devices
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bec/ophyd_devices
|
||||
ref: "${{ inputs.OPHYD_DEVICES_BRANCH || 'main' }}"
|
||||
path: ./ophyd_devices
|
||||
|
||||
- name: Checkout BEC Widgets
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bec/bec_widgets
|
||||
ref: "${{ inputs.BEC_WIDGETS_BRANCH || 'main' }}"
|
||||
path: ./bec_widgets
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgl1 libegl1 x11-utils libxkbcommon-x11-0 libdbus-1-3 xvfb
|
||||
sudo apt-get -y install libnss3 libxdamage1 libasound2t64 libatomic1 libxcursor1
|
||||
|
||||
- name: Install Python dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
pip install uv
|
||||
uv pip install --system -e ./ophyd_devices
|
||||
uv pip install --system -e ./bec/bec_lib[dev]
|
||||
uv pip install --system -e ./bec/bec_ipython_client
|
||||
uv pip install --system -e ./bec/bec_server[dev]
|
||||
uv pip install --system -e ./bec_widgets[dev,pyside6]
|
||||
uv pip install --system -e ./debye_bec
|
||||
|
||||
- name: Run Pytest with Coverage
|
||||
id: coverage
|
||||
run: pytest --random-order --cov=./debye_bec --cov-config=./debye_bec/pyproject.toml --cov-branch --cov-report=xml --no-cov-on-fail ./debye_bec/tests/ || test $? -eq 5
|
||||
62
.gitea/workflows/create_update_pr.yml
Normal file
62
.gitea/workflows/create_update_pr.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Create template upgrade PR for debye_bec
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
create_update_branch_and_pr:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
pip install copier PySide6
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Perform update
|
||||
run: |
|
||||
git config --global user.email "bec_ci_staging@psi.ch"
|
||||
git config --global user.name "BEC automated CI"
|
||||
|
||||
branch="chore/update-template-$(python -m uuid)"
|
||||
echo "switching to branch $branch"
|
||||
git checkout -b $branch
|
||||
|
||||
echo "Running copier update..."
|
||||
output="$(copier update --trust --defaults --conflict inline 2>&1)"
|
||||
echo "$output"
|
||||
msg="$(printf '%s\n' "$output" | head -n 1)"
|
||||
|
||||
if ! grep -q "make_commit: true" .copier-answers.yml ; then
|
||||
echo "Autocommit not made, committing..."
|
||||
git add -A
|
||||
git commit -a -m "$msg"
|
||||
fi
|
||||
|
||||
if diff-index --quiet HEAD ; then
|
||||
echo "No changes detected"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git push -u origin $branch
|
||||
curl -X POST "https://gitea.psi.ch/api/v1/repos/${{ gitea.repository }}/pulls" \
|
||||
-H "Authorization: token ${{ secrets.CI_REPO_WRITE }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"title\": \"Template: $(echo $msg)\",
|
||||
\"body\": \"This PR was created by Gitea Actions\",
|
||||
\"head\": \"$(echo $branch)\",
|
||||
\"base\": \"main\"
|
||||
}"
|
||||
@@ -1,7 +0,0 @@
|
||||
include:
|
||||
- file: /templates/plugin-repo-template.yml
|
||||
inputs:
|
||||
name: debye_bec
|
||||
target: debye_bec
|
||||
branch: $CHILD_PIPELINE_BRANCH
|
||||
project: bec/awi_utils
|
||||
@@ -3,8 +3,12 @@ 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.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from bec_lib.service_config import ServiceConfig
|
||||
|
||||
import debye_bec
|
||||
|
||||
|
||||
def extend_command_line_args(parser):
|
||||
"""
|
||||
@@ -18,6 +22,11 @@ def extend_command_line_args(parser):
|
||||
|
||||
def get_config() -> ServiceConfig:
|
||||
"""
|
||||
Create and return the service configuration.
|
||||
Create and return the ServiceConfig for the plugin repository
|
||||
"""
|
||||
return ServiceConfig(redis={"host": "x01da-bec-001", "port": 6379})
|
||||
deployment_path = os.path.dirname(os.path.dirname(os.path.dirname(debye_bec.__file__)))
|
||||
files = os.listdir(deployment_path)
|
||||
if "bec_config.yaml" in files:
|
||||
return ServiceConfig(config_path=os.path.join(deployment_path, "bec_config.yaml"))
|
||||
else:
|
||||
return ServiceConfig(redis={"host": "localhost", "port": 6379})
|
||||
|
||||
34
debye_bec/device_configs/x01da_beam_monitors.yaml
Normal file
34
debye_bec/device_configs/x01da_beam_monitors.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
###################################
|
||||
## Beam Monitors ##
|
||||
###################################
|
||||
|
||||
beam_monitor_1:
|
||||
readoutPriority: async
|
||||
description: Beam monitor 1
|
||||
deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-GIGE01:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
beam_monitor_2:
|
||||
readoutPriority: async
|
||||
description: Beam monitor 2
|
||||
deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-GIGE02:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
xray_eye:
|
||||
readoutPriority: async
|
||||
description: X-ray eye
|
||||
deviceClass: debye_bec.devices.cameras.basler_cam.BaslerCam
|
||||
deviceConfig:
|
||||
prefix: "X01DA-ES-XRAYEYE:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
@@ -1,875 +0,0 @@
|
||||
###################
|
||||
#### FRONT END ####
|
||||
###################
|
||||
|
||||
## Slit Diaphragm -- Physical positioners
|
||||
sldi_trxr:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Slit Diaphragm -- Virtual positioners
|
||||
|
||||
sldi_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_centery:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Collimating Mirror -- Physical Positioners
|
||||
|
||||
cm_trxu:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror X-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRXU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trxd:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror X-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRXD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_tryu:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trydr:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation downstream ring
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYDR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trydw:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation downstream wall
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYDW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_bnd:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror bender
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:BND
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Collimating Mirror -- Virtual Positioners
|
||||
|
||||
cm_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_roty:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_rotz:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Roll
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_xctp:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point X
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:XTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_ytcp:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point Y
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:YTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_ztcp:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point Z
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ZTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_xstripe:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror X Stripe
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:XSTRIPE
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################
|
||||
###### OPTICS #####
|
||||
###################
|
||||
|
||||
## Bragg Monochromator
|
||||
mo1_bragg:
|
||||
readoutPriority: baseline
|
||||
description: Positioner for the Monochromator
|
||||
deviceClass: debye_bec.devices.mo1_bragg.mo1_bragg.Mo1Bragg
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-MO1:BRAGG:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Monochromator -- Physical Positioners
|
||||
|
||||
mo_try:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator Y Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
mo_trx:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator X Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
mo_roty:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Focusing Mirror -- Physical Positioners
|
||||
|
||||
fm_trxu:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror X-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRXU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_trxd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror X-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRXD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryur:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation upstream ring
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYUR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryuw:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation upstream wall
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYUW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_bnd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror bender
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:BND
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Focusing Mirror -- Virtual Positioners
|
||||
|
||||
fm_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_roty:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_rotz:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Roll
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_xctp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point X
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:XTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_ytcp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point Y
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:YTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_ztcp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point Z
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ZTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
# fm_xstripe:
|
||||
# readoutPriority: baseline
|
||||
# description: Focusing Morror X Stripe
|
||||
# deviceClass: ophyd.EpicsMotor
|
||||
# deviceConfig:
|
||||
# prefix: X01DA-OP-FM:XSTRIPE
|
||||
# onFailure: retry
|
||||
# enabled: true
|
||||
# softwareTrigger: false
|
||||
|
||||
## Optics Slits 1 -- Physical positioners
|
||||
|
||||
sl1_trxr:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl1_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl1_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl1_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
bm1_try:
|
||||
readoutPriority: baseline
|
||||
description: Beam Monitor 1 Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-BM1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Optics Slits 1 -- Virtual positioners
|
||||
|
||||
sl1_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl1_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl1_centery:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl1_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL1:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Optics Slits 2 -- Physical positioners
|
||||
|
||||
sl2_trxr:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl2_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl2_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl2_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
bm2_try:
|
||||
readoutPriority: baseline
|
||||
description: Beam Monitor 2 Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-BM2:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Optics Slits 2 -- Virtual positioners
|
||||
|
||||
sl2_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl2_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl2_centery:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sl2_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-SL2:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###############################
|
||||
###### EXPERIMENTAL HUTCH #####
|
||||
###############################
|
||||
|
||||
###########################################
|
||||
## Optical Table -- Physical Positioners ##
|
||||
###########################################
|
||||
|
||||
ot_tryu:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Y-Translation Upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:TRYU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
ot_tryd:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Y-Translation Downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:TRYD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
############################################
|
||||
## Optical Table -- Virtual Positioners ###
|
||||
############################################
|
||||
|
||||
ot_try:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Y-Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
ot_pitch:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
#########################################
|
||||
## Exit Window -- Physical Positioners ##
|
||||
#########################################
|
||||
|
||||
es0wi_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station 0 Exit Window Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-WI:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###############################################
|
||||
## End Station Slits -- Physical Positioners ##
|
||||
###############################################
|
||||
|
||||
es0sl_trxr:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es0sl_trxw:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es0sl_tryb:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es0sl_tryt:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
##############################################
|
||||
## End Station Slits -- Virtual positioners ##
|
||||
##############################################
|
||||
|
||||
es0sl_center:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es0sl_gapx:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es0sl_centery:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es0sl_gapy:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
#########################################################
|
||||
## Pinhole and alignment laser -- Physical Positioners ##
|
||||
#########################################################
|
||||
|
||||
es1pin_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station pinhole and alignment laser Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1pin_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station pinhole and alignment laser X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1pin_rotx:
|
||||
readoutPriority: baseline
|
||||
description: End Station pinhole and alignment laser X-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1pin_roty:
|
||||
readoutPriority: baseline
|
||||
description: End Station pinhole and alignment laser Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
|
||||
################################################
|
||||
## Sample Manipulator -- Physical Positioners ##
|
||||
################################################
|
||||
|
||||
es1man_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1man_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1man_trz:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator Z-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:TRZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1man_roty:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
############################################
|
||||
## Segemented Arc -- Physical Positioners ##
|
||||
############################################
|
||||
|
||||
es1arc_roty:
|
||||
readoutPriority: baseline
|
||||
description: End Station segmented arc Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-ARC:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1det1_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station SDD 1 X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-DET1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1bm1_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station X-ray Eye X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-BM1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es1det2_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station SDD 2 X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-DET2:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
#######################################
|
||||
## Beam Stop -- Physical Positioners ##
|
||||
#######################################
|
||||
|
||||
es2bs_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station beamstop X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-BS:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es2bs_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station beamstop Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-BS:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
##############################################
|
||||
## IC12 Manipulator -- Physical Positioners ##
|
||||
##############################################
|
||||
|
||||
es2ma2_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station ionization chamber 1+2 Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-MA2:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
es2ma2_trz:
|
||||
readoutPriority: baseline
|
||||
description: End Station ionization chamber 1+2 Z-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-MA2:TRZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
#######################################################
|
||||
## XRD Detector Manipulator -- Physical Positioners ##
|
||||
#######################################################
|
||||
|
||||
es2ma3_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station XRD detector Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-MA3:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
449
debye_bec/device_configs/x01da_experimental_hutch.yaml
Normal file
449
debye_bec/device_configs/x01da_experimental_hutch.yaml
Normal file
@@ -0,0 +1,449 @@
|
||||
###################################
|
||||
## Optical Table ##
|
||||
###################################
|
||||
|
||||
ot_tryu:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Y-Translation Upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:TRYU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ot_tryd:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Y-Translation Downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:TRYD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ot_es1_trz:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table ES1 Z-Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-OT:TRZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ot_es2_trz:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table ES2 Z-Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-OT:TRZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ot_try:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Y-Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ot_pitch:
|
||||
readoutPriority: baseline
|
||||
description: Optical Table Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES-OT:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Exit Window ##
|
||||
###################################
|
||||
|
||||
es0wi_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station 0 Exit Window Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-WI:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## ES0 Filter ##
|
||||
###################################
|
||||
|
||||
es0filter:
|
||||
readoutPriority: baseline
|
||||
description: ES0 filter station
|
||||
deviceClass: debye_bec.devices.es0filter.ES0Filter
|
||||
deviceConfig:
|
||||
prefix: "X01DA-ES0-FI:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Slits ES0 ##
|
||||
###################################
|
||||
|
||||
es0sl_trxr:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_trxw:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_tryb:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_tryt:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_center:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_gapx:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_centery:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es0sl_gapy:
|
||||
readoutPriority: baseline
|
||||
description: End Station slits Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES0-SL:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Alignment Laser ##
|
||||
###################################
|
||||
|
||||
es1_alignment_laser:
|
||||
readoutPriority: baseline
|
||||
description: ES1 alignment laser
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES1-LAS:Relay"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Sample Manipulator ##
|
||||
###################################
|
||||
|
||||
es1man_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es1man_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es1man_trz:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator Z-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:TRZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es1man_roty:
|
||||
readoutPriority: baseline
|
||||
description: End Station sample manipulator Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-MAN1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Segmented Arc ##
|
||||
###################################
|
||||
|
||||
es1arc_roty:
|
||||
readoutPriority: baseline
|
||||
description: End Station segmented arc Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-ARC:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es1det1_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station SDD 1 X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-DET1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es1bm1_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station X-ray Eye X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-BM1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es1det2_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station SDD 2 X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-DET2:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## IC1 + IC2 Manipulator ##
|
||||
###################################
|
||||
|
||||
es2ma2_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station ionization chamber 1+2 Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-MA2:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es2ma2_trz:
|
||||
readoutPriority: baseline
|
||||
description: End Station ionization chamber 1+2 Z-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-MA2:TRZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## XRD Detector Manipulator ##
|
||||
###################################
|
||||
|
||||
es2ma3_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station XRD detector Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-MA3:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Hutch Env. Sensors + Light ##
|
||||
###################################
|
||||
|
||||
es_temperature1:
|
||||
readoutPriority: baseline
|
||||
description: ES temperature sensor 1
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH1:TEMP"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_humidity1:
|
||||
readoutPriority: baseline
|
||||
description: ES humidity sensor 1
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH1:HUMIREL"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_pressure1:
|
||||
readoutPriority: baseline
|
||||
description: ES ambient pressure sensor 1
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH1:PRES"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_temperature2:
|
||||
readoutPriority: baseline
|
||||
description: ES temperature sensor 2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH2:TEMP"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_humidity2:
|
||||
readoutPriority: baseline
|
||||
description: ES humidity sensor 2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH2:HUMIREL"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_pressure2:
|
||||
readoutPriority: baseline
|
||||
description: ES ambient pressure sensor 2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH2:PRES"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_light_toggle:
|
||||
readoutPriority: baseline
|
||||
description: ES light toggle
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-EH-LIGHT:TOGGLE"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_gas_sensor_o2:
|
||||
readoutPriority: baseline
|
||||
description: ES Gas Sensor O2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-KIMESSA2:EH-O2"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_gas_sensor_h2s:
|
||||
readoutPriority: baseline
|
||||
description: ES Gas Sensor H2S
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-KIMESSA2:EH-H2S"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_gas_sensor_no2:
|
||||
readoutPriority: baseline
|
||||
description: ES Gas Sensor NO2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-KIMESSA2:EH-NO2"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_gas_sensor_co:
|
||||
readoutPriority: baseline
|
||||
description: ES Gas Sensor CO
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-KIMESSA2:EH-CO"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_gas_sensor_h2:
|
||||
readoutPriority: baseline
|
||||
description: ES Gas Sensor H2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-KIMESSA2:EH-H2"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_gas_sensor_nh3:
|
||||
readoutPriority: baseline
|
||||
description: ES Gas Sensor NH3
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-KIMESSA2:EH-NH3"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
218
debye_bec/device_configs/x01da_frontend.yaml
Normal file
218
debye_bec/device_configs/x01da_frontend.yaml
Normal file
@@ -0,0 +1,218 @@
|
||||
|
||||
###################################
|
||||
## Frontend Slits ##
|
||||
###################################
|
||||
|
||||
sldi_trxr:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_centery:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sldi_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Collimating Mirror ##
|
||||
###################################
|
||||
|
||||
cm_trxu:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror X-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRXU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_trxd:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror X-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRXD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_tryu:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_trydr:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation downstream ring
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYDR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_trydw:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation downstream wall
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYDW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_bnd:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror bender
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:BND
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_roty:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_rotz:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Roll
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_trx:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point X
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:XTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_try:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point Y
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:YTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_ztcp:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point Z
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ZTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
cm_xstripe:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror X Stripe
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:XSTRIPE
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
34
debye_bec/device_configs/x01da_hutch_cameras.yaml
Normal file
34
debye_bec/device_configs/x01da_hutch_cameras.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
###################################
|
||||
## Hutch Cameras ##
|
||||
###################################
|
||||
|
||||
hutch_cam_1:
|
||||
readoutPriority: baseline
|
||||
description: Hutch Camera 1
|
||||
deviceClass: debye_bec.devices.cameras.hutch_cam.HutchCam
|
||||
deviceConfig:
|
||||
prefix: "pcp085420"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
hutch_cam_2:
|
||||
readoutPriority: baseline
|
||||
description: Hutch Camera 2
|
||||
deviceClass: debye_bec.devices.cameras.hutch_cam.HutchCam
|
||||
deviceConfig:
|
||||
prefix: "pcp085436"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
hutch_cam_3:
|
||||
readoutPriority: baseline
|
||||
description: Hutch Camera 3
|
||||
deviceClass: debye_bec.devices.cameras.hutch_cam.HutchCam
|
||||
deviceConfig:
|
||||
prefix: "pcp085435"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
@@ -1,3 +1,8 @@
|
||||
|
||||
###################################
|
||||
## SLS Machine ##
|
||||
###################################
|
||||
|
||||
curr:
|
||||
readoutPriority: baseline
|
||||
description: SLS ring current
|
||||
|
||||
@@ -1,4 +1,41 @@
|
||||
## Optics Slits 1 -- Physical positioners
|
||||
|
||||
###################################
|
||||
## Monochromator ##
|
||||
###################################
|
||||
|
||||
mo_try:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator Y Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
mo_trx:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator X Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
mo_roty:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Optics Slits + Beam Monitor 1 ##
|
||||
###################################
|
||||
|
||||
sl1_trxr:
|
||||
readoutPriority: baseline
|
||||
@@ -12,6 +49,7 @@ sl1_trxr:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl1_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-translation Wall-edge
|
||||
@@ -24,6 +62,7 @@ sl1_trxw:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl1_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 Y-translation Bottom-edge
|
||||
@@ -36,6 +75,7 @@ sl1_tryb:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl1_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-translation Top-edge
|
||||
@@ -48,6 +88,7 @@ sl1_tryt:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
bm1_try:
|
||||
readoutPriority: baseline
|
||||
description: Beam Monitor 1 Y-translation
|
||||
@@ -61,8 +102,6 @@ bm1_try:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
## Optics Slits 1 -- Virtual positioners
|
||||
|
||||
sl1_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-center
|
||||
@@ -75,6 +114,7 @@ sl1_centerx:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl1_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 X-gap
|
||||
@@ -87,6 +127,7 @@ sl1_gapx:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl1_centery:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 Y-center
|
||||
@@ -99,6 +140,7 @@ sl1_centery:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl1_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 1 Y-gap
|
||||
@@ -112,7 +154,128 @@ sl1_gapy:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
## Optics Slits 2 -- Physical positioners
|
||||
###################################
|
||||
## Focusing Mirror ##
|
||||
###################################
|
||||
|
||||
fm_trxu:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror X-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRXU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_trxd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror X-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRXD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryur:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation upstream ring
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYUR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryuw:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation upstream wall
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYUW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_bnd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror bender
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:BND
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
fm_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
fm_roty:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
fm_rotz:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Roll
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
fm_xctp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point X
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:XTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
fm_ytcp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point Y
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:YTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
fm_ztcp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point Z
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ZTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Optics Slits + Beam Monitor 2 ##
|
||||
###################################
|
||||
|
||||
sl2_trxr:
|
||||
readoutPriority: baseline
|
||||
@@ -126,6 +289,7 @@ sl2_trxr:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl2_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-translation Wall-edge
|
||||
@@ -138,6 +302,7 @@ sl2_trxw:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl2_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 Y-translation Bottom-edge
|
||||
@@ -150,6 +315,7 @@ sl2_tryb:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl2_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-translation Top-edge
|
||||
@@ -162,6 +328,7 @@ sl2_tryt:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
bm2_try:
|
||||
readoutPriority: baseline
|
||||
description: Beam Monitor 2 Y-translation
|
||||
@@ -175,8 +342,6 @@ bm2_try:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
## Optics Slits 2 -- Virtual positioners
|
||||
|
||||
sl2_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-center
|
||||
@@ -189,6 +354,7 @@ sl2_centerx:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl2_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 X-gap
|
||||
@@ -201,6 +367,7 @@ sl2_gapx:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl2_centery:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 Y-center
|
||||
@@ -213,6 +380,7 @@ sl2_centery:
|
||||
deviceTags:
|
||||
- optics
|
||||
- slits
|
||||
|
||||
sl2_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Optics slits 2 Y-gap
|
||||
80
debye_bec/device_configs/x01da_standard_config.yaml
Normal file
80
debye_bec/device_configs/x01da_standard_config.yaml
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
###################################
|
||||
## General ##
|
||||
###################################
|
||||
|
||||
## SLS Machine
|
||||
machine_config:
|
||||
- !include ./x01da_machine.yaml
|
||||
|
||||
## Beam Monitors OP + EH
|
||||
beam_monitors_config:
|
||||
- !include ./x01da_beam_monitors.yaml
|
||||
|
||||
###################################
|
||||
## Frontend ##
|
||||
###################################
|
||||
|
||||
## Frontend
|
||||
frontend_config:
|
||||
- !include ./x01da_frontend.yaml
|
||||
|
||||
###################################
|
||||
## Optics Hutch ##
|
||||
###################################
|
||||
|
||||
## Bragg Monochromator
|
||||
mo1_bragg:
|
||||
readoutPriority: monitored
|
||||
description: Positioner for the Monochromator
|
||||
deviceClass: debye_bec.devices.mo1_bragg.mo1_bragg.Mo1Bragg
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-MO1:BRAGG:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
mo1_bragg_angle:
|
||||
readoutPriority: baseline
|
||||
description: Positioner for the Monochromator
|
||||
deviceClass: debye_bec.devices.mo1_bragg.mo1_bragg_angle.Mo1BraggAngle
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-MO1:BRAGG:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Remaining optics hutch
|
||||
optics_config:
|
||||
- !include ./x01da_optics.yaml
|
||||
|
||||
###################################
|
||||
## Experimental Hutch ##
|
||||
###################################
|
||||
|
||||
# ## NIDAQ
|
||||
nidaq:
|
||||
readoutPriority: monitored
|
||||
description: NIDAQ backend for data reading for debye scans
|
||||
deviceClass: debye_bec.devices.nidaq.nidaq.Nidaq
|
||||
deviceConfig:
|
||||
prefix: "X01DA-PC-SCANSERVER:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## XAS (ICx, SDD, ref foils)
|
||||
xas_config:
|
||||
- !include ./x01da_xas.yaml
|
||||
|
||||
## XRD (Pilatus, pinhole, beamstop)
|
||||
#xrd_config:
|
||||
# - !include ./x01da_xrd.yaml
|
||||
|
||||
# Commented out because too slow
|
||||
## Hutch cameras
|
||||
# hutch_cams:
|
||||
# - !include ./x01da_hutch_cameras.yaml
|
||||
|
||||
## Remaining experimental hutch
|
||||
es_config:
|
||||
- !include ./x01da_experimental_hutch.yaml
|
||||
@@ -1,636 +0,0 @@
|
||||
optic_slit_config:
|
||||
- !include ./x01da_optic_slits.yaml
|
||||
machine_config:
|
||||
- !include ./x01da_machine.yaml
|
||||
## Slit Diaphragm -- Physical positioners
|
||||
sldi_trxr:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Ring-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRXR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_trxw:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Wall-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRXW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_tryb:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-translation Bottom-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRYB
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_tryt:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-translation Top-edge
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:TRYT
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Slit Diaphragm -- Virtual positioners
|
||||
|
||||
sldi_centerx:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:CENTERX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_gapx:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm X-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:GAPX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_centery:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-center
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:CENTERY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
sldi_gapy:
|
||||
readoutPriority: baseline
|
||||
description: Front-end slit diaphragm Y-gap
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-SLDI:GAPY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
|
||||
## Collimating Mirror -- Physical Positioners
|
||||
|
||||
cm_trxu:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror X-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRXU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trxd:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror X-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRXD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_tryu:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trydr:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation downstream ring
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYDR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trydw:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror Y-translation downstream wall
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:TRYDW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_bnd:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Mirror bender
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:BND
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Collimating Mirror -- Virtual Positioners
|
||||
|
||||
cm_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_roty:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_rotz:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Roll
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ROTZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_trx:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point X
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:XTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_try:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point Y
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:YTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_ztcp:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror Center Point Z
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:ZTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
cm_xstripe:
|
||||
readoutPriority: baseline
|
||||
description: Collimating Morror X Stripe
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-FE-CM:XSTRIPE
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Bragg Monochromator
|
||||
mo1_bragg:
|
||||
readoutPriority: baseline
|
||||
description: Positioner for the Monochromator
|
||||
deviceClass: debye_bec.devices.mo1_bragg.mo1_bragg.Mo1Bragg
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-MO1:BRAGG:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
mo1_bragg_angle:
|
||||
readoutPriority: baseline
|
||||
description: Positioner for the Monochromator
|
||||
deviceClass: debye_bec.devices.mo1_bragg.mo1_bragg_angle.Mo1BraggAngle
|
||||
deviceConfig:
|
||||
prefix: "X01DA-OP-MO1:BRAGG:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
# NIDAQ
|
||||
nidaq:
|
||||
readoutPriority: monitored
|
||||
description: NIDAQ backend for data reading for debye scans
|
||||
deviceClass: debye_bec.devices.nidaq.nidaq.Nidaq
|
||||
deviceConfig:
|
||||
prefix: "X01DA-PC-SCANSERVER:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Monochromator -- Physical Positioners
|
||||
|
||||
mo_try:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator Y Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
mo_trx:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator X Translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
mo_roty:
|
||||
readoutPriority: baseline
|
||||
description: Monochromator Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-MO1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Focusing Mirror -- Physical Positioners
|
||||
|
||||
fm_trxu:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror X-translation upstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRXU
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_trxd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror X-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRXD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation downstream
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYD
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryur:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation upstream ring
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYUR
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_tryuw:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror Y-translation upstream wall
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:TRYUW
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_bnd:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Mirror bender
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:BND
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Focusing Mirror -- Virtual Positioners
|
||||
|
||||
fm_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Pitch
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_roty:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Yaw
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_rotz:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Roll
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ROTZ
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_xctp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point X
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:XTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_ytcp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point Y
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:YTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
fm_ztcp:
|
||||
readoutPriority: baseline
|
||||
description: Focusing Morror Center Point Z
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-OP-FM:ZTCP
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
# Ionization Chambers
|
||||
|
||||
ic0:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 0
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber0
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
ic1:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 1
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber1
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
ic2:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 2
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber2
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
# ES0 Filter
|
||||
|
||||
es0filter:
|
||||
readoutPriority: baseline
|
||||
description: ES0 filter station
|
||||
deviceClass: debye_bec.devices.es0filter.ES0Filter
|
||||
deviceConfig:
|
||||
prefix: "X01DA-ES0-FI:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
# Reference foil changer
|
||||
|
||||
reffoilchanger:
|
||||
readoutPriority: baseline
|
||||
description: ES2 reference foil changer
|
||||
deviceClass: debye_bec.devices.reffoilchanger.Reffoilchanger
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
# Beam Monitors
|
||||
|
||||
# beam_monitor_1:
|
||||
# readoutPriority: async
|
||||
# description: Beam monitor 1
|
||||
# deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam
|
||||
# deviceConfig:
|
||||
# prefix: "X01DA-OP-GIGE01:"
|
||||
# onFailure: retry
|
||||
# enabled: true
|
||||
# softwareTrigger: false
|
||||
|
||||
# beam_monitor_2:
|
||||
# readoutPriority: async
|
||||
# description: Beam monitor 2
|
||||
# deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam
|
||||
# deviceConfig:
|
||||
# prefix: "X01DA-OP-GIGE02:"
|
||||
# onFailure: retry
|
||||
# enabled: true
|
||||
# softwareTrigger: false
|
||||
|
||||
xray_eye:
|
||||
readoutPriority: async
|
||||
description: X-ray eye
|
||||
deviceClass: debye_bec.devices.cameras.basler_cam.BaslerCam
|
||||
deviceConfig:
|
||||
prefix: "X01DA-ES-XRAYEYE:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
# Pilatus Curtain
|
||||
# pilatus_curtain:
|
||||
# readoutPriority: baseline
|
||||
# description: Pilatus Curtain
|
||||
# deviceClass: debye_bec.devices.pilatus_curtain.PilatusCurtain
|
||||
# deviceConfig:
|
||||
# prefix: "X01DA-ES2-DET3:TRY-"
|
||||
# onFailure: retry
|
||||
# enabled: true
|
||||
# softwareTrigger: false
|
||||
|
||||
|
||||
################################
|
||||
## ES Hutch Sensors and Light ##
|
||||
################################
|
||||
|
||||
es_temperature1:
|
||||
readoutPriority: baseline
|
||||
description: ES temperature sensor 1
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH1:TEMP"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_humidity1:
|
||||
readoutPriority: baseline
|
||||
description: ES humidity sensor 1
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH1:HUMIREL"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_pressure1:
|
||||
readoutPriority: baseline
|
||||
description: ES ambient pressure sensor 1
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH1:PRES"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_temperature2:
|
||||
readoutPriority: baseline
|
||||
description: ES temperature sensor 2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH2:TEMP"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_humidity2:
|
||||
readoutPriority: baseline
|
||||
description: ES humidity sensor 2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH2:HUMIREL"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_pressure2:
|
||||
readoutPriority: baseline
|
||||
description: ES ambient pressure sensor 2
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-PC-I2C:_CH2:PRES"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es_light_toggle:
|
||||
readoutPriority: baseline
|
||||
description: ES light toggle
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-EH-LIGHT:TOGGLE"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
#################
|
||||
## SDD sensors ##
|
||||
#################
|
||||
|
||||
sdd1_temperature:
|
||||
readoutPriority: baseline
|
||||
description: SDD1 temperature sensor
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES1-DET1:Temperature"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sdd1_humidity:
|
||||
readoutPriority: baseline
|
||||
description: SDD1 humidity sensor
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES1-DET1:Humidity"
|
||||
kind: "config"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
#####################
|
||||
## Alignment Laser ##
|
||||
#####################
|
||||
|
||||
es1_alignment_laser:
|
||||
readoutPriority: baseline
|
||||
description: ES1 alignment laser
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES1-LAS:Relay"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
## Pinhole alignment stages -- Physical Positioners
|
||||
|
||||
pin1_trx:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
pin1_try:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
pin1_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole X-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
pin1_roty:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
83
debye_bec/device_configs/x01da_xas.yaml
Normal file
83
debye_bec/device_configs/x01da_xas.yaml
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
###################################
|
||||
## Ionization Chambers ##
|
||||
###################################
|
||||
|
||||
ic0:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 0
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber0
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ic1:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 1
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber1
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ic2:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 2
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber2
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
pips:
|
||||
readoutPriority: baseline
|
||||
description: Pips diode
|
||||
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.Pips
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Reference Foil Changer ##
|
||||
###################################
|
||||
|
||||
reffoilchanger:
|
||||
readoutPriority: baseline
|
||||
description: ES2 reference foil changer
|
||||
deviceClass: debye_bec.devices.reffoilchanger.Reffoilchanger
|
||||
deviceConfig:
|
||||
prefix: "X01DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## SDD Sensors ##
|
||||
###################################
|
||||
|
||||
sdd1_temperature:
|
||||
readoutPriority: baseline
|
||||
description: SDD1 temperature sensor
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES1-DET1:Temperature"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
sdd1_humidity:
|
||||
readoutPriority: baseline
|
||||
description: SDD1 humidity sensor
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES1-DET1:Humidity"
|
||||
kind: "config"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
108
debye_bec/device_configs/x01da_xrd.yaml
Normal file
108
debye_bec/device_configs/x01da_xrd.yaml
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
###################################
|
||||
## Pinhole ##
|
||||
###################################
|
||||
|
||||
pin1_trx:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
pin1_try:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
pin1_rotx:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole X-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:ROTX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
pin1_roty:
|
||||
readoutPriority: baseline
|
||||
description: Pinhole Y-rotation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES1-PIN1:ROTY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
tags: Endstation
|
||||
|
||||
###################################
|
||||
## Beam Stop ##
|
||||
###################################
|
||||
|
||||
es2bs_trx:
|
||||
readoutPriority: baseline
|
||||
description: End Station beamstop X-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-BS:TRX
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
es2bs_try:
|
||||
readoutPriority: baseline
|
||||
description: End Station beamstop Y-translation
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig:
|
||||
prefix: X01DA-ES2-BS:TRY
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Pilatus ##
|
||||
###################################
|
||||
|
||||
pilatus_curtain:
|
||||
readoutPriority: baseline
|
||||
description: Pilatus Curtain
|
||||
deviceClass: debye_bec.devices.pilatus_curtain.PilatusCurtain
|
||||
deviceConfig:
|
||||
prefix: "X01DA-ES2-DET3:TRY-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
pilatus:
|
||||
readoutPriority: baseline
|
||||
description: Pilatus
|
||||
deviceClass: debye_bec.devices.pilatus.pilatus.Pilatus
|
||||
deviceTags:
|
||||
- detector
|
||||
deviceConfig:
|
||||
prefix: "X01DA-ES2-PIL:"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: true
|
||||
|
||||
pilatus_smpl:
|
||||
readoutPriority: baseline
|
||||
description: Sample to pilatus distance
|
||||
deviceClass: ophyd.EpicsSignalRO
|
||||
deviceConfig:
|
||||
read_pv: "X01DA-ES2-DET:SMPLDIST"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ophyd import ADBase
|
||||
from ophyd import ADBase, EpicsSignalRO
|
||||
from ophyd import ADComponent as ADCpt
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd_devices import PreviewSignal
|
||||
@@ -20,6 +20,16 @@ if TYPE_CHECKING: # pragma: no cover
|
||||
class BaslerCamBase(ADBase):
|
||||
"""BaslerCam Base class."""
|
||||
|
||||
cam_detector_state_string = Cpt(EpicsSignalRO, suffix="cam1:DetectorState_RBV", string=True)
|
||||
|
||||
_default_configuration_attrs = [
|
||||
'cam1.acquire_time',
|
||||
'cam1.detector_state',
|
||||
'cam_detector_state_string',
|
||||
'cam1.gain',
|
||||
'cam1.model',
|
||||
]
|
||||
|
||||
cam1 = ADCpt(AravisDetectorCam, "cam1:")
|
||||
image1 = ADCpt(ImagePlugin_V35, "image1:")
|
||||
|
||||
|
||||
79
debye_bec/devices/cameras/hutch_cam.py
Normal file
79
debye_bec/devices/cameras/hutch_cam.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""EH Hutch Cameras"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import cv2
|
||||
import threading
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bec_lib.logger import bec_logger
|
||||
from bec_lib.file_utils import get_full_path
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
from ophyd_devices import DeviceStatus
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from bec_lib.devicemanager import ScanInfo
|
||||
from bec_lib.messages import ScanStatusMessage
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
CAM_USERNAME = "camera_user"
|
||||
CAM_PASSWORD = "camera_user1"
|
||||
CAM_PORT = 554
|
||||
|
||||
class HutchCam(PSIDeviceBase):
|
||||
"""Class for the Hutch Cameras"""
|
||||
|
||||
# image = Cpt(Signal, name='image', kind='config')
|
||||
|
||||
def __init__(self, *, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs):
|
||||
super().__init__(name=name, scan_info=scan_info, **kwargs)
|
||||
|
||||
self.hostname = prefix
|
||||
self.status = None
|
||||
|
||||
# pylint: disable=E1101
|
||||
def on_connected(self) -> None:
|
||||
"""
|
||||
Called after the device is connected and its signals are connected.
|
||||
Default values for signals should be set here.
|
||||
"""
|
||||
rtsp_url = f"rtsp://{CAM_USERNAME}:{CAM_PASSWORD}@{self.hostname}.psi.ch:{CAM_PORT}/rtpstream/config1"
|
||||
cap = cv2.VideoCapture(f"{rtsp_url}?tcp")
|
||||
if not cap.isOpened():
|
||||
logger.error(self, "Connection Failed", "Could not connect to the camera stream.")
|
||||
return
|
||||
cap.release()
|
||||
|
||||
def on_stage(self) -> DeviceStatus:
|
||||
"""Called while staging the device."""
|
||||
|
||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||
file_path = get_full_path(scan_msg, name='hutch_cam_' + self.hostname).removesuffix('h5')
|
||||
|
||||
self.status = DeviceStatus(self)
|
||||
|
||||
thread = threading.Thread(target=self._save_picture, args=(file_path, self.status), daemon=True)
|
||||
thread.start()
|
||||
|
||||
return self.status
|
||||
|
||||
def _save_picture(self, file_path, status):
|
||||
try:
|
||||
logger.info(f'Capture from camera {self.hostname}')
|
||||
rtsp_url = f"rtsp://{CAM_USERNAME}:{CAM_PASSWORD}@{self.hostname}.psi.ch:{CAM_PORT}/rtpstream/config1"
|
||||
cap = cv2.VideoCapture(f"{rtsp_url}?tcp")
|
||||
if not cap.isOpened():
|
||||
logger.error("Connection Failed", "Could not connect to the camera stream.")
|
||||
return
|
||||
logger.info(f'Connection to camera {self.hostname} established')
|
||||
ret, frame = cap.readAsync()
|
||||
cap.release()
|
||||
if not ret:
|
||||
logger.error("Capture Failed", "Failed to capture image from camera.")
|
||||
return
|
||||
cv2.imwrite(file_path + 'png', frame)
|
||||
status.set_finished()
|
||||
logger.info(f'Capture from camera {self.hostname} done')
|
||||
except Exception as e:
|
||||
status.set_exception(e)
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ophyd import ADBase
|
||||
from ophyd import ADBase, EpicsSignalRO
|
||||
from ophyd import ADComponent as ADCpt
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd_devices import PreviewSignal
|
||||
@@ -20,6 +20,16 @@ if TYPE_CHECKING: # pragma: no cover
|
||||
class ProsilicaCamBase(ADBase):
|
||||
"""Base class for Prosilica cameras."""
|
||||
|
||||
cam_detector_state_string = Cpt(EpicsSignalRO, suffix="cam1:DetectorState_RBV", string=True)
|
||||
|
||||
_default_configuration_attrs = [
|
||||
'cam1.acquire_time',
|
||||
'cam1.detector_state',
|
||||
'cam_detector_state_string',
|
||||
'cam1.gain',
|
||||
'cam1.model',
|
||||
]
|
||||
|
||||
cam1 = ADCpt(ProsilicaDetectorCam, "cam1:")
|
||||
image1 = ADCpt(ImagePlugin_V35, "image1:")
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"""Ionization chamber device class"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
@@ -6,8 +8,8 @@ import numpy as np
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device
|
||||
from ophyd import DynamicDeviceComponent as Dcpt
|
||||
from ophyd import EpicsSignal, EpicsSignalRO, EpicsSignalWithRBV, Kind
|
||||
from ophyd.status import DeviceStatus, SubscriptionStatus
|
||||
from ophyd import EpicsSignal, EpicsSignalRO, EpicsSignalWithRBV
|
||||
from ophyd_devices import CompareStatus, DeviceStatus, SubscriptionStatus, TransitionStatus
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
from typeguard import typechecked
|
||||
|
||||
@@ -31,22 +33,24 @@ class EpicsSignalSplit(EpicsSignal):
|
||||
class GasMixSetupControl(Device):
|
||||
"""GasMixSetup Control for Inonization Chamber 0"""
|
||||
|
||||
gas1_req = Cpt(EpicsSignalWithRBV, suffix="Gas1Req", kind="config", doc="Gas 1 requirement")
|
||||
gas1_req = Cpt(EpicsSignalWithRBV, suffix="Gas1Req", kind="omitted", doc="Gas 1 requirement")
|
||||
conc1_req = Cpt(
|
||||
EpicsSignalWithRBV, suffix="Conc1Req", kind="config", doc="Concentration 1 requirement"
|
||||
EpicsSignalWithRBV, suffix="Conc1Req", kind="omitted", doc="Concentration 1 requirement"
|
||||
)
|
||||
gas2_req = Cpt(EpicsSignalWithRBV, suffix="Gas2Req", kind="config", doc="Gas 2 requirement")
|
||||
gas2_req = Cpt(EpicsSignalWithRBV, suffix="Gas2Req", kind="omitted", doc="Gas 2 requirement")
|
||||
conc2_req = Cpt(
|
||||
EpicsSignalWithRBV, suffix="Conc2Req", kind="config", doc="Concentration 2 requirement"
|
||||
EpicsSignalWithRBV, suffix="Conc2Req", kind="omitted", doc="Concentration 2 requirement"
|
||||
)
|
||||
press_req = Cpt(
|
||||
EpicsSignalWithRBV, suffix="PressReq", kind="config", doc="Pressure requirement"
|
||||
EpicsSignalWithRBV, suffix="PressReq", kind="omitted", doc="Pressure requirement"
|
||||
)
|
||||
fill = Cpt(EpicsSignal, suffix="Fill", kind="config", doc="Fill the chamber")
|
||||
status = Cpt(EpicsSignalRO, suffix="Status", kind="config", doc="Status")
|
||||
gas1 = Cpt(EpicsSignalRO, suffix="Gas1", kind="config", doc="Gas 1")
|
||||
gas1_string = Cpt(EpicsSignalRO, suffix="Gas1", kind="config", doc="Gas 1", string=True)
|
||||
conc1 = Cpt(EpicsSignalRO, suffix="Conc1", kind="config", doc="Concentration 1")
|
||||
gas2 = Cpt(EpicsSignalRO, suffix="Gas2", kind="config", doc="Gas 2")
|
||||
gas2_string = Cpt(EpicsSignalRO, suffix="Gas2", kind="config", doc="Gas 2", string=True)
|
||||
conc2 = Cpt(EpicsSignalRO, suffix="Conc2", kind="config", doc="Concentration 2")
|
||||
press = Cpt(EpicsSignalRO, suffix="PressTransm", kind="config", doc="Current Pressure")
|
||||
|
||||
@@ -82,10 +86,25 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||
),
|
||||
"cOnOff_string": (
|
||||
EpicsSignal,
|
||||
(f"ES:AMP5004.cOnOff{num}"),
|
||||
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cGain_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cFilter_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
||||
gmes_status = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||
gmes_status_msg = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES1-IC{num-1}:")
|
||||
hv_en_signals = {
|
||||
"ext_ena": (
|
||||
@@ -102,7 +121,7 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
|
||||
|
||||
@typechecked
|
||||
def set_gain(self, gain: Literal["1e6", "1e7", "5e7", "1e8", "1e9"] | AmplifierGain) -> None:
|
||||
def set_gain(self, gain: Literal["1e6", "1e7", "5e7", "1e8", "1e9"]) -> None:
|
||||
"""Configure the gain setting of the specified channel
|
||||
|
||||
Args:
|
||||
@@ -110,18 +129,10 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
"""
|
||||
|
||||
if self.amp.cOnOff.get() == AmplifierEnable.OFF:
|
||||
status = CompareStatus(self.amp.cOnOff, AmplifierEnable.ON)
|
||||
self.cancel_on_stop(status)
|
||||
self.amp.cOnOff.put(AmplifierEnable.ON)
|
||||
|
||||
# Wait until channel is switched on
|
||||
def _wait_enabled():
|
||||
return self.amp.cOnOff.get() == AmplifierEnable.ON
|
||||
|
||||
if not self.wait_for_condition(
|
||||
_wait_enabled, check_stopped=True, timeout=self.timeout_for_pvwait
|
||||
):
|
||||
raise TimeoutError(
|
||||
f"Enabling channel run into timeout after {self.timeout_for_pvwait} seconds"
|
||||
)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
match gain:
|
||||
case "1e6":
|
||||
@@ -136,29 +147,18 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
self.amp.cGain_ENUM.put(AmplifierGain.G1E9)
|
||||
|
||||
def set_filter(
|
||||
self,
|
||||
value: (
|
||||
Literal["1us", "3us", "10us", "30us", "100us", "300us", "1ms", "3ms"] | AmplifierFilter
|
||||
),
|
||||
self, value: Literal["1us", "3us", "10us", "30us", "100us", "300us", "1ms", "3ms"]
|
||||
) -> None:
|
||||
"""Configure the filter setting of the specified channel
|
||||
|
||||
Args:
|
||||
value (Literal['1us', '3us', '10us', '30us', '100us', '300us', '1ms', '3ms']) : Desired filter
|
||||
value (Literal['1us','3us','10us','30us','100us','300us','1ms','3ms']) :Desired filter
|
||||
"""
|
||||
if self.amp.cOnOff.get() == AmplifierEnable.OFF:
|
||||
status = CompareStatus(self.amp.cOnOff, AmplifierEnable.ON)
|
||||
self.cancel_on_stop(status)
|
||||
self.amp.cOnOff.put(AmplifierEnable.ON)
|
||||
|
||||
# Wait until channel is switched on
|
||||
def _wait_enabled():
|
||||
return self.amp.cOnOff.get() == AmplifierEnable.ON
|
||||
|
||||
if not self.wait_for_condition(
|
||||
_wait_enabled, check_stopped=True, timeout=self.timeout_for_pvwait
|
||||
):
|
||||
raise TimeoutError(
|
||||
f"Enabling channel run into timeout after {self.timeout_for_pvwait} seconds"
|
||||
)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
match value:
|
||||
case "1us":
|
||||
@@ -187,20 +187,16 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
hv (float) : Desired voltage for the 'HV' terminal. Voltage has to be between 0...3000
|
||||
"""
|
||||
|
||||
if not (0 <= hv <= 3000):
|
||||
if not 0 <= hv <= 3000:
|
||||
raise ValueError(f"specified HV {hv} not within range [0 .. 3000]")
|
||||
if not np.isclose(np.abs(hv - self.hv.grid_v.get()), 0, atol=3):
|
||||
raise ValueError(f"Grid {self.hv.grid_v.get()} must not be higher than HV {hv}!")
|
||||
|
||||
if not self.hv_en.ena.get() == 1:
|
||||
|
||||
def check_ch_ena(*, old_value, value, **kwargs):
|
||||
return value == 1
|
||||
|
||||
status = SubscriptionStatus(device=self.hv_en.ena, callback=check_ch_ena)
|
||||
status = CompareStatus(self.hv_en.ena, 1)
|
||||
self.cancel_on_stop(status)
|
||||
self.hv_en.ena.put(1)
|
||||
# Wait after setting ena to 1
|
||||
status.wait(timeout=2)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
# Set current fixed to 3 mA (max)
|
||||
self.hv.hv_i.put(3)
|
||||
@@ -212,23 +208,20 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
enable the high voltage (if external enable is active)!
|
||||
|
||||
Args:
|
||||
grid (float) : Desired voltage for the 'Grid' terminal, Grid Voltage has to be between 0...3000
|
||||
grid (float) : Desired voltage for the 'Grid' terminal,
|
||||
Grid Voltage has to be between 0...3000
|
||||
"""
|
||||
|
||||
if not (0 <= grid <= 3000):
|
||||
if not 0 <= grid <= 3000:
|
||||
raise ValueError(f"specified Grid {grid} not within range [0 .. 3000]")
|
||||
if not np.isclose(np.abs(grid - self.hv.hv_v.get()), 0, atol=3):
|
||||
raise ValueError(f"Grid {grid} must not be higher than HV {self.hv.hv_v.get()}!")
|
||||
|
||||
if not self.hv_en.ena.get() == 1:
|
||||
|
||||
def check_ch_ena(*, old_value, value, **kwargs):
|
||||
return value == 1
|
||||
|
||||
status = SubscriptionStatus(device=self.hv_en.ena, callback=check_ch_ena)
|
||||
status = CompareStatus(self.hv_en.ena, 1)
|
||||
self.cancel_on_stop(status)
|
||||
self.hv_en.ena.put(1)
|
||||
# Wait after setting ena to 1
|
||||
status.wait(timeout=2)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
# Set current fixed to 3 mA (max)
|
||||
self.hv.grid_i.put(3)
|
||||
@@ -244,7 +237,7 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
pressure: float,
|
||||
*,
|
||||
wait: bool = False,
|
||||
) -> DeviceStatus:
|
||||
) -> DeviceStatus | None:
|
||||
"""Fill an ionization chamber with the specified gas mixture.
|
||||
|
||||
Args:
|
||||
@@ -256,13 +249,13 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
wait (bool): If you like to wait for the filling to finish.
|
||||
"""
|
||||
|
||||
if not (0 <= conc1 <= 100):
|
||||
if not 0 <= conc1 <= 100:
|
||||
raise ValueError(f"Concentration 1 {conc1} out of range [0 .. 100 %]")
|
||||
if not (0 <= conc2 <= 100):
|
||||
if not 0 <= conc2 <= 100:
|
||||
raise ValueError(f"Concentration 2 {conc2} out of range [0 .. 100 %]")
|
||||
if not np.isclose((conc1 + conc2), 100, atol=0.1):
|
||||
raise ValueError(f"Conc1 {conc1} and conc2 {conc2} must sum to 100 +- 0.1")
|
||||
if not (0 <= pressure <= 3):
|
||||
if not 0 <= pressure <= 3:
|
||||
raise ValueError(f"Pressure {pressure} out of range [0 .. 3 bar abs]")
|
||||
|
||||
self.gmes.gas1_req.set(gas1).wait(timeout=3)
|
||||
@@ -270,27 +263,13 @@ class IonizationChamber0(PSIDeviceBase):
|
||||
self.gmes.gas2_req.set(gas2).wait(timeout=3)
|
||||
self.gmes.conc2_req.set(conc2).wait(timeout=3)
|
||||
|
||||
status = TransitionStatus(self.gmes.status.get(), [0, 1])
|
||||
self.cancel_on_stop(status)
|
||||
self.gmes.fill.put(1)
|
||||
|
||||
def wait_for_status():
|
||||
return self.gmes.status.get() == 0
|
||||
|
||||
timeout = 3
|
||||
if not self.wait_for_condition(wait_for_status, timeout=timeout, check_stopped=True):
|
||||
raise TimeoutError(
|
||||
f"Ionization chamber filling process did not start after {timeout}s. Last log message {self.gmes_status.get()}"
|
||||
)
|
||||
|
||||
def wait_for_filling_finished():
|
||||
return self.gmes.status.get() == 1
|
||||
|
||||
# Wait until ionization chamber is filled successfully
|
||||
status = self.task_handler.submit_task(
|
||||
task=self.wait_for_condition, task_args=(wait_for_filling_finished, 360, True)
|
||||
)
|
||||
if wait:
|
||||
status.wait()
|
||||
return status
|
||||
status.wait(timeout=360)
|
||||
else:
|
||||
return status
|
||||
|
||||
|
||||
class IonizationChamber1(IonizationChamber0):
|
||||
@@ -313,10 +292,25 @@ class IonizationChamber1(IonizationChamber0):
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||
),
|
||||
"cOnOff_string": (
|
||||
EpicsSignal,
|
||||
(f"ES:AMP5004.cOnOff{num}"),
|
||||
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cGain_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cFilter_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
||||
gmes_status = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||
gmes_status_msg = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES2-IC{num-1}:")
|
||||
hv_en_signals = {
|
||||
"ext_ena": (
|
||||
@@ -349,10 +343,25 @@ class IonizationChamber2(IonizationChamber0):
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||
),
|
||||
"cOnOff_string": (
|
||||
EpicsSignal,
|
||||
(f"ES:AMP5004.cOnOff{num}"),
|
||||
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cGain_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cFilter_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
||||
gmes_status = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||
gmes_status_msg = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES2-IC{num-1}:")
|
||||
hv_en_signals = {
|
||||
"ext_ena": (
|
||||
@@ -363,3 +372,63 @@ class IonizationChamber2(IonizationChamber0):
|
||||
"ena": (EpicsSignal, "ES2-IC12:HV-Ena", {"kind": "config", "doc": "Enable signal of HV"}),
|
||||
}
|
||||
hv_en = Dcpt(hv_en_signals)
|
||||
|
||||
class Pips(IonizationChamber0):
|
||||
"""Pips, prefix should be 'X01DA-'."""
|
||||
|
||||
USER_ACCESS = ["set_gain", "set_filter"]
|
||||
|
||||
num = 4
|
||||
amp_signals = {
|
||||
"cOnOff": (
|
||||
EpicsSignal,
|
||||
(f"ES:AMP5004.cOnOff{num}"),
|
||||
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}"},
|
||||
),
|
||||
"cGain_ENUM": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}"},
|
||||
),
|
||||
"cFilter_ENUM": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||
),
|
||||
"cOnOff_string": (
|
||||
EpicsSignal,
|
||||
(f"ES:AMP5004.cOnOff{num}"),
|
||||
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cGain_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
"cFilter_ENUM_string": (
|
||||
EpicsSignalWithRBV,
|
||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
gmes = None
|
||||
gmes_status_msg = None
|
||||
hv = None
|
||||
hv_en_signals = None
|
||||
hv_en = None
|
||||
|
||||
@typechecked
|
||||
def set_hv(self, *_) -> None:
|
||||
"""Not available for the PIPS"""
|
||||
return None
|
||||
|
||||
@typechecked
|
||||
def set_grid(self, *_) -> None:
|
||||
"""Not available for the PIPS"""
|
||||
return None
|
||||
|
||||
@typechecked
|
||||
def fill(self, *_) -> None:
|
||||
"""Not available for the PIPS"""
|
||||
return None
|
||||
|
||||
@@ -9,16 +9,15 @@ used to ensure that the action is executed completely. This is believed
|
||||
to allow for a more stable execution of the action."""
|
||||
|
||||
import time
|
||||
from typing import Any, Literal
|
||||
from typing import Literal
|
||||
|
||||
from bec_lib.devicemanager import ScanInfo
|
||||
from bec_lib.logger import bec_logger
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import DeviceStatus, Signal, StatusBase
|
||||
from ophyd.status import SubscriptionStatus, WaitTimeoutError
|
||||
from ophyd import DeviceStatus, StatusBase
|
||||
from ophyd.status import WaitTimeoutError
|
||||
from ophyd_devices import CompareStatus, ProgressSignal, TransitionStatus
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
from ophyd_devices.utils.errors import DeviceStopError
|
||||
from pydantic import BaseModel, Field
|
||||
from typeguard import typechecked
|
||||
|
||||
@@ -56,16 +55,18 @@ class ScanParameter(BaseModel):
|
||||
|
||||
scan_time: float | None = Field(None, description="Scan time for a half oscillation")
|
||||
scan_duration: float | None = Field(None, description="Duration of the scan")
|
||||
xrd_enable_low: bool | None = Field(
|
||||
None, description="XRD enabled for low, should be PV trig_ena_lo_enum"
|
||||
break_enable_low: bool | None = Field(
|
||||
None, description="Break enabled for low, should be PV trig_ena_lo_enum"
|
||||
) # trig_enable_low: bool = None
|
||||
xrd_enable_high: bool | None = Field(
|
||||
None, description="XRD enabled for high, should be PV trig_ena_hi_enum"
|
||||
break_enable_high: bool | None = Field(
|
||||
None, description="Break enabled for high, should be PV trig_ena_hi_enum"
|
||||
) # trig_enable_high: bool = None
|
||||
exp_time_low: float | None = Field(None, description="Exposure time low energy/angle")
|
||||
exp_time_high: float | None = Field(None, description="Exposure time high energy/angle")
|
||||
break_time_low: float | None = Field(None, description="Break time low energy/angle")
|
||||
break_time_high: float | None = Field(None, description="Break time high energy/angle")
|
||||
cycle_low: int | None = Field(None, description="Cycle for low energy/angle")
|
||||
cycle_high: int | None = Field(None, description="Cycle for high energy/angle")
|
||||
exp_time: float | None = Field(None, description="XRD trigger period")
|
||||
n_of_trigger: int | None = Field(None, description="Amount of XRD triggers")
|
||||
start: float | None = Field(None, description="Start value for energy/angle")
|
||||
stop: float | None = Field(None, description="Stop value for energy/angle")
|
||||
p_kink: float | None = Field(None, description="P Kink")
|
||||
@@ -140,10 +141,12 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
self.set_trig_settings(
|
||||
enable_low=False,
|
||||
enable_high=False,
|
||||
exp_time_low=0,
|
||||
exp_time_high=0,
|
||||
break_time_low=0,
|
||||
break_time_high=0,
|
||||
cycle_low=0,
|
||||
cycle_high=0,
|
||||
exp_time=0,
|
||||
n_of_trigger=0,
|
||||
)
|
||||
self.set_scan_control_settings(
|
||||
mode=ScanControlMode.SIMPLE, scan_duration=self.scan_parameter.scan_duration
|
||||
@@ -155,12 +158,14 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
scan_time=self.scan_parameter.scan_time,
|
||||
)
|
||||
self.set_trig_settings(
|
||||
enable_low=self.scan_parameter.xrd_enable_low, # enable_low=self.scan_parameter.trig_enable_low,
|
||||
enable_high=self.scan_parameter.xrd_enable_high, # enable_high=self.scan_parameter.trig_enable_high,
|
||||
exp_time_low=self.scan_parameter.exp_time_low,
|
||||
exp_time_high=self.scan_parameter.exp_time_high,
|
||||
enable_low=self.scan_parameter.break_enable_low,
|
||||
enable_high=self.scan_parameter.break_enable_high,
|
||||
break_time_low=self.scan_parameter.break_time_low,
|
||||
break_time_high=self.scan_parameter.break_time_high,
|
||||
cycle_low=self.scan_parameter.cycle_low,
|
||||
cycle_high=self.scan_parameter.cycle_high,
|
||||
exp_time=self.scan_parameter.exp_time,
|
||||
n_of_trigger=self.scan_parameter.n_of_trigger,
|
||||
)
|
||||
self.set_scan_control_settings(
|
||||
mode=ScanControlMode.SIMPLE, scan_duration=self.scan_parameter.scan_duration
|
||||
@@ -176,10 +181,12 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
self.set_trig_settings(
|
||||
enable_low=False,
|
||||
enable_high=False,
|
||||
exp_time_low=0,
|
||||
exp_time_high=0,
|
||||
break_time_low=0,
|
||||
break_time_high=0,
|
||||
cycle_low=0,
|
||||
cycle_high=0,
|
||||
exp_time=0,
|
||||
n_of_trigger=0,
|
||||
)
|
||||
self.set_scan_control_settings(
|
||||
mode=ScanControlMode.ADVANCED, scan_duration=self.scan_parameter.scan_duration
|
||||
@@ -193,12 +200,14 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
e_kink=self.scan_parameter.e_kink,
|
||||
)
|
||||
self.set_trig_settings(
|
||||
enable_low=self.scan_parameter.xrd_enable_low, # enable_low=self.scan_parameter.trig_enable_low,
|
||||
enable_high=self.scan_parameter.xrd_enable_high, # enable_high=self.scan_parameter.trig_enable_high,
|
||||
exp_time_low=self.scan_parameter.exp_time_low,
|
||||
exp_time_high=self.scan_parameter.exp_time_high,
|
||||
enable_low=self.scan_parameter.break_enable_low,
|
||||
enable_high=self.scan_parameter.break_enable_high,
|
||||
break_time_low=self.scan_parameter.break_time_low,
|
||||
break_time_high=self.scan_parameter.break_time_high,
|
||||
cycle_low=self.scan_parameter.cycle_low,
|
||||
cycle_high=self.scan_parameter.cycle_high,
|
||||
exp_time=self.scan_parameter.exp_time,
|
||||
n_of_trigger=self.scan_parameter.n_of_trigger,
|
||||
)
|
||||
self.set_scan_control_settings(
|
||||
mode=ScanControlMode.ADVANCED, scan_duration=self.scan_parameter.scan_duration
|
||||
@@ -213,7 +222,7 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
status = CompareStatus(self.scan_control.scan_msg, ScanControlLoadMessage.SUCCESS)
|
||||
self.cancel_on_stop(status)
|
||||
self.scan_control.scan_load.put(1)
|
||||
# Wait for params to be checked from controller
|
||||
# Wait for params to be checked from controller
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
return None
|
||||
|
||||
@@ -271,7 +280,7 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
self.scan_control.scan_status,
|
||||
transitions=[ScanControlScanStatus.READY, ScanControlScanStatus.RUNNING],
|
||||
strict=True,
|
||||
raise_states=[ScanControlScanStatus.PARAMETER_WRONG],
|
||||
failure_states=[ScanControlScanStatus.PARAMETER_WRONG],
|
||||
)
|
||||
self.cancel_on_stop(status)
|
||||
start_func(1)
|
||||
@@ -311,7 +320,7 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
|
||||
status_list.append(self.scan_settings.s_scan_scantime.set(scan_time))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
|
||||
for s in status_list:
|
||||
s.wait(timeout=self.timeout_for_pvwait)
|
||||
|
||||
@@ -342,7 +351,7 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
status = CompareStatus(self.calculator.calc_done, 1)
|
||||
self.cancel_on_stop(status)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
time.sleep(0.25) #TODO needed still? Needed due to update frequency of softIOC
|
||||
time.sleep(0.25) # TODO needed still? Needed due to update frequency of softIOC
|
||||
if mode == "AngleToEnergy":
|
||||
return self.calculator.calc_energy.get()
|
||||
elif mode == "EnergyToAngle":
|
||||
@@ -391,22 +400,24 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
self,
|
||||
enable_low: bool,
|
||||
enable_high: bool,
|
||||
exp_time_low: int,
|
||||
exp_time_high: int,
|
||||
break_time_low: float,
|
||||
break_time_high: float,
|
||||
cycle_low: int,
|
||||
cycle_high: int,
|
||||
exp_time: float,
|
||||
n_of_trigger: int,
|
||||
) -> None:
|
||||
"""Set TRIG settings for the upcoming scan.
|
||||
|
||||
Args:
|
||||
enable_low (bool): Enable TRIG for low energy/angle
|
||||
enable_high (bool): Enable TRIG for high energy/angle
|
||||
num_trigger_low (int): Number of triggers for low energy/angle
|
||||
num_trigger_high (int): Number of triggers for high energy/angle
|
||||
exp_time_low (int): Exposure time for low energy/angle
|
||||
exp_time_high (int): Exposure time for high energy/angle
|
||||
break_time_low (float): Exposure time for low energy/angle
|
||||
break_time_high (float): Exposure time for high energy/angle
|
||||
cycle_low (int): Cycle for low energy/angle
|
||||
cycle_high (int): Cycle for high energy/angle
|
||||
exp_time (float): Length of 1 trigger period in seconds
|
||||
n_of_trigger (int): Amount of triggers to be fired during brake
|
||||
"""
|
||||
|
||||
status_list = []
|
||||
@@ -417,10 +428,10 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
status_list.append(self.scan_settings.trig_ena_lo_enum.set(int(enable_low)))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
status_list.append(self.scan_settings.trig_time_hi.set(exp_time_high))
|
||||
status_list.append(self.scan_settings.trig_time_hi.set(break_time_high))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
status_list.append(self.scan_settings.trig_time_lo.set(exp_time_low))
|
||||
status_list.append(self.scan_settings.trig_time_lo.set(break_time_low))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
status_list.append(self.scan_settings.trig_every_n_hi.set(cycle_high))
|
||||
@@ -429,10 +440,15 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
status_list.append(self.scan_settings.trig_every_n_lo.set(cycle_low))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
status_list.append(self.trigger_settings.xrd_trig_period.set(exp_time))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
status_list.append(self.trigger_settings.xrd_n_of_trig.set(n_of_trigger))
|
||||
self.cancel_on_stop(status_list[-1])
|
||||
|
||||
for s in status_list:
|
||||
s.wait(timeout=self.timeout_for_pvwait)
|
||||
|
||||
|
||||
def set_scan_control_settings(self, mode: ScanControlMode, scan_duration: float) -> None:
|
||||
"""Set the scan control settings for the upcoming scan.
|
||||
|
||||
@@ -453,7 +469,6 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner):
|
||||
for s in status_list:
|
||||
s.wait(timeout=self.timeout_for_pvwait)
|
||||
|
||||
|
||||
def _update_scan_parameter(self):
|
||||
"""Get the scan_info parameters for the scan."""
|
||||
for key, value in self.scan_info.msg.request_inputs["inputs"].items():
|
||||
|
||||
@@ -139,21 +139,29 @@ class Mo1TriggerSettings(Device):
|
||||
xrd_trig_src_enum = Cpt(EpicsSignalWithRBV, suffix="xrd_trig_src_ENUM", kind="config")
|
||||
xrd_trig_mode_enum = Cpt(EpicsSignalWithRBV, suffix="xrd_trig_mode_ENUM", kind="config")
|
||||
xrd_trig_len = Cpt(EpicsSignalWithRBV, suffix="xrd_trig_len", kind="config")
|
||||
xrd_trig_period = Cpt(EpicsSignalWithRBV, suffix="xrd_trig_period", kind="config")
|
||||
xrd_n_of_trig = Cpt(EpicsSignalWithRBV, suffix="xrd_n_of_trig", kind="config")
|
||||
xrd_trig_req = Cpt(EpicsSignal, suffix="xrd_trig_req", kind="config")
|
||||
|
||||
falcon_trig_src_enum = Cpt(EpicsSignalWithRBV, suffix="falcon_trig_src_ENUM", kind="config")
|
||||
falcon_trig_mode_enum = Cpt(EpicsSignalWithRBV, suffix="falcon_trig_mode_ENUM", kind="config")
|
||||
falcon_trig_len = Cpt(EpicsSignalWithRBV, suffix="falcon_trig_len", kind="config")
|
||||
falcon_trig_period = Cpt(EpicsSignalWithRBV, suffix="falcon_trig_period", kind="config")
|
||||
falcon_n_of_trig = Cpt(EpicsSignalWithRBV, suffix="falcon_n_of_trig", kind="config")
|
||||
falcon_trig_req = Cpt(EpicsSignal, suffix="falcon_trig_req", kind="config")
|
||||
|
||||
univ1_trig_src_enum = Cpt(EpicsSignalWithRBV, suffix="univ1_trig_src_ENUM", kind="config")
|
||||
univ1_trig_mode_enum = Cpt(EpicsSignalWithRBV, suffix="univ1_trig_mode_ENUM", kind="config")
|
||||
univ1_trig_len = Cpt(EpicsSignalWithRBV, suffix="univ1_trig_len", kind="config")
|
||||
univ1_trig_period = Cpt(EpicsSignalWithRBV, suffix="univ1_trig_period", kind="config")
|
||||
univ1_n_of_trig = Cpt(EpicsSignalWithRBV, suffix="univ1_n_of_trig", kind="config")
|
||||
univ1_trig_req = Cpt(EpicsSignal, suffix="univ1_trig_req", kind="config")
|
||||
|
||||
univ2_trig_src_enum = Cpt(EpicsSignalWithRBV, suffix="univ2_trig_src_ENUM", kind="config")
|
||||
univ2_trig_mode_enum = Cpt(EpicsSignalWithRBV, suffix="univ2_trig_mode_ENUM", kind="config")
|
||||
univ2_trig_len = Cpt(EpicsSignalWithRBV, suffix="univ2_trig_len", kind="config")
|
||||
univ2_trig_period = Cpt(EpicsSignalWithRBV, suffix="univ2_trig_period", kind="config")
|
||||
univ2_n_of_trig = Cpt(EpicsSignalWithRBV, suffix="univ2_n_of_trig", kind="config")
|
||||
univ2_trig_req = Cpt(EpicsSignal, suffix="univ2_trig_req", kind="config")
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
from typing import TYPE_CHECKING, Literal, cast
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
from bec_lib.logger import bec_logger
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device, DeviceStatus, EpicsSignal, EpicsSignalRO, Kind, StatusBase
|
||||
from ophyd.status import SubscriptionStatus, WaitTimeoutError
|
||||
from ophyd.status import WaitTimeoutError
|
||||
from ophyd_devices import CompareStatus, ProgressSignal, TransitionStatus
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
from ophyd_devices.sim.sim_signals import SetableSignal
|
||||
@@ -147,6 +146,76 @@ class NidaqControl(Device):
|
||||
doc="EPICS counter input 7",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci8 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI8",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 8",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci9 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI9",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 9",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci10 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI10",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 0",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci11 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI11",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 1",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci12 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI12",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 2",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci13 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI13",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 3",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci14 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI14",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 4",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci15 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI15",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 5",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci16 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI16",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 6",
|
||||
auto_monitor=True,
|
||||
)
|
||||
ci17 = Cpt(
|
||||
EpicsSignalRO,
|
||||
suffix="NIDAQ-CI17",
|
||||
kind=Kind.normal,
|
||||
doc="EPICS counter input 7",
|
||||
auto_monitor=True,
|
||||
)
|
||||
|
||||
di0 = Cpt(
|
||||
EpicsSignalRO,
|
||||
@@ -276,6 +345,36 @@ class NidaqControl(Device):
|
||||
ci7_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7, MEAN"
|
||||
)
|
||||
ci8_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 8, MEAN"
|
||||
)
|
||||
ci9_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 9, MEAN"
|
||||
)
|
||||
ci10_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 10, MEAN"
|
||||
)
|
||||
ci11_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 11, MEAN"
|
||||
)
|
||||
ci12_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 12, MEAN"
|
||||
)
|
||||
ci13_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 13, MEAN"
|
||||
)
|
||||
ci14_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 14, MEAN"
|
||||
)
|
||||
ci15_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 15, MEAN"
|
||||
)
|
||||
ci16_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 16, MEAN"
|
||||
)
|
||||
ci17_mean = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 17, MEAN"
|
||||
)
|
||||
|
||||
ci0_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 0. STD"
|
||||
@@ -301,6 +400,44 @@ class NidaqControl(Device):
|
||||
ci7_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7. STD"
|
||||
)
|
||||
ci8_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 8. STD"
|
||||
)
|
||||
ci9_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 9. STD"
|
||||
)
|
||||
ci10_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 10. STD"
|
||||
)
|
||||
ci11_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 11. STD"
|
||||
)
|
||||
ci12_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 12. STD"
|
||||
)
|
||||
ci13_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 13. STD"
|
||||
)
|
||||
ci14_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 14. STD"
|
||||
)
|
||||
ci15_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 15. STD"
|
||||
)
|
||||
ci16_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 16. STD"
|
||||
)
|
||||
ci17_std_dev = Cpt(
|
||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 17. STD"
|
||||
)
|
||||
|
||||
xas_timestamp = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XAS timestamp")
|
||||
|
||||
xrd_timestamp = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD timestamp")
|
||||
xrd_angle = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD angle")
|
||||
xrd_energy = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD energy")
|
||||
xrd_ai0_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD ai0 mean")
|
||||
xrd_ai0_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD ai0 std dev")
|
||||
|
||||
di0_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 0, MAX")
|
||||
di1_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 1, MAX")
|
||||
@@ -315,16 +452,21 @@ class NidaqControl(Device):
|
||||
### Control PVs ###
|
||||
|
||||
enable_compression = Cpt(EpicsSignal, suffix="NIDAQ-EnableRLE", kind=Kind.config)
|
||||
enable_dead_time_correction = Cpt(EpicsSignal, suffix="NIDAQ-EnableDTC", kind=Kind.config)
|
||||
kickoff_call = Cpt(EpicsSignal, suffix="NIDAQ-Kickoff", kind=Kind.config)
|
||||
stage_call = Cpt(EpicsSignal, suffix="NIDAQ-Stage", kind=Kind.config)
|
||||
state = Cpt(EpicsSignal, suffix="NIDAQ-FSMState", kind=Kind.config, auto_monitor=True)
|
||||
server_status = Cpt(EpicsSignalRO, suffix="NIDAQ-ServerStatus", kind=Kind.config)
|
||||
compression_ratio = Cpt(EpicsSignalRO, suffix="NIDAQ-CompressionRatio", kind=Kind.config)
|
||||
scan_type = Cpt(EpicsSignal, suffix="NIDAQ-ScanType", kind=Kind.config)
|
||||
scan_type_string = Cpt(EpicsSignal, suffix="NIDAQ-ScanType", kind=Kind.config, string=True)
|
||||
sampling_rate = Cpt(EpicsSignal, suffix="NIDAQ-SamplingRateRequested", kind=Kind.config)
|
||||
sampling_rate_string = Cpt(EpicsSignal, suffix="NIDAQ-SamplingRateRequested", kind=Kind.config, string=True)
|
||||
scan_duration = Cpt(EpicsSignal, suffix="NIDAQ-SamplingDuration", kind=Kind.config)
|
||||
readout_range = Cpt(EpicsSignal, suffix="NIDAQ-ReadoutRange", kind=Kind.config)
|
||||
readout_range_string = Cpt(EpicsSignal, suffix="NIDAQ-ReadoutRange", kind=Kind.config, string=True)
|
||||
encoder_factor = Cpt(EpicsSignal, suffix="NIDAQ-EncoderFactor", kind=Kind.config)
|
||||
encoder_factor_string = Cpt(EpicsSignal, suffix="NIDAQ-EncoderFactor", kind=Kind.config, string=True)
|
||||
stop_call = Cpt(EpicsSignal, suffix="NIDAQ-Stop", kind=Kind.config)
|
||||
power = Cpt(EpicsSignal, suffix="NIDAQ-Power", kind=Kind.config)
|
||||
heartbeat = Cpt(EpicsSignal, suffix="NIDAQ-Heartbeat", kind=Kind.config, auto_monitor=True)
|
||||
@@ -352,7 +494,7 @@ class Nidaq(PSIDeviceBase, NidaqControl):
|
||||
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
|
||||
self.scan_info: ScanInfo
|
||||
self.timeout_wait_for_signal = 5 # put 5s firsts
|
||||
self._timeout_wait_for_pv = 3 # 3s timeout for pv calls
|
||||
self._timeout_wait_for_pv = 5 # 5s timeout for pv calls. editted due to timeout issues persisting
|
||||
self.valid_scan_names = [
|
||||
"xas_simple_scan",
|
||||
"xas_simple_scan_with_xrd",
|
||||
@@ -551,7 +693,11 @@ class Nidaq(PSIDeviceBase, NidaqControl):
|
||||
# Stage call to IOC
|
||||
status = CompareStatus(self.state, NidaqState.STAGE)
|
||||
self.cancel_on_stop(status)
|
||||
self.stage_call.set(1).wait(timeout=self._timeout_wait_for_pv)
|
||||
# TODO 11.11.25/HS64
|
||||
# Switched from set to put in the hope to get rid of the rare event where nidaq is stopped at the start of a scan
|
||||
# Problems consistently persisting, testing changing back to set, unconvinced this is the actual cause 14.11.25/AHC
|
||||
# self.stage_call.set(1).wait(timeout=self._timeout_wait_for_pv)
|
||||
self.stage_call.put(1)
|
||||
status.wait(timeout=self.timeout_wait_for_signal)
|
||||
if self.scan_info.msg.scan_name != "nidaq_continuous_scan":
|
||||
status = self.on_kickoff()
|
||||
|
||||
0
debye_bec/devices/pilatus/__init__.py
Normal file
0
debye_bec/devices/pilatus/__init__.py
Normal file
685
debye_bec/devices/pilatus/pilatus.py
Normal file
685
debye_bec/devices/pilatus/pilatus.py
Normal file
@@ -0,0 +1,685 @@
|
||||
"""Pilatus AD integration at Debye beamline."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
from typing import TYPE_CHECKING, Tuple
|
||||
|
||||
import numpy as np
|
||||
from bec_lib.file_utils import get_full_path
|
||||
from bec_lib.logger import bec_logger
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import EpicsSignal, EpicsSignalRO, Kind
|
||||
from ophyd.areadetector.cam import ADBase, PilatusDetectorCam
|
||||
from ophyd.areadetector.plugins import HDF5Plugin_V22 as HDF5Plugin
|
||||
from ophyd.areadetector.plugins import ImagePlugin_V22 as ImagePlugin
|
||||
from ophyd.status import WaitTimeoutError
|
||||
from ophyd_devices import AndStatus, CompareStatus, DeviceStatus, FileEventSignal, PreviewSignal
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from bec_lib.devicemanager import ScanInfo
|
||||
from bec_lib.messages import DevicePreviewMessage, ScanStatusMessage
|
||||
from bec_server.device_server.device_server import DeviceManagerDS
|
||||
|
||||
PILATUS_READOUT_TIME = 0.1 # in s
|
||||
# PILATUS_ACQUIRE_TIME = (
|
||||
# 999999 # This time is the timeout of the detector in operation mode, so it needs to be large.
|
||||
# )
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
# pylint: disable=raise-missing-from
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class DETECTORSTATE(int, enum.Enum):
|
||||
"""Pilatus Detector States from CamServer"""
|
||||
|
||||
UNARMED = 0
|
||||
ARMED = 1
|
||||
|
||||
|
||||
class ACQUIREMODE(int, enum.Enum):
|
||||
"""Pilatus Acquisition Modes"""
|
||||
|
||||
DONE = 0
|
||||
ACQUIRING = 1
|
||||
|
||||
|
||||
class FILEWRITEMODE(int, enum.Enum):
|
||||
"""HDF5 Plugin FileWrite Mode"""
|
||||
|
||||
SINGLE = 0
|
||||
CAPTURE = 1
|
||||
STREAM = 2
|
||||
|
||||
|
||||
class COMPRESSIONALGORITHM(int, enum.Enum):
|
||||
"""HDF5 Plugin Compression Algorithm"""
|
||||
|
||||
NONE = 0
|
||||
NBIT = 1 # Don't use that..
|
||||
SZIP = 2
|
||||
ZLIB = 3
|
||||
|
||||
|
||||
class TRIGGERMODE(int, enum.Enum):
|
||||
"""Pilatus Trigger Modes"""
|
||||
|
||||
INTERNAL = 0
|
||||
EXT_ENABLE = 1
|
||||
EXT_TRIGGER = 2
|
||||
MULT_TRIGGER = 3
|
||||
ALIGNMENT = 4
|
||||
|
||||
|
||||
class MONOTRIGGERSOURCE(int, enum.Enum):
|
||||
""" "Mono XRD trigger source"""
|
||||
|
||||
EPICS = 0
|
||||
INPOS = 1
|
||||
|
||||
|
||||
class MONOTRIGGERMODE(int, enum.Enum):
|
||||
""" "Mono XRD trigger mode"""
|
||||
|
||||
PULSE = 0
|
||||
CONDITION = 1
|
||||
|
||||
def description(self) -> str:
|
||||
"""Return a description of the trigger mode."""
|
||||
descriptions = {
|
||||
TRIGGERMODE.INTERNAL: "Internal trigger mode, images are acquired on internal trigger.",
|
||||
TRIGGERMODE.EXT_ENABLE: "External Enable trigger mode; check manual as details are currently unknown",
|
||||
TRIGGERMODE.EXT_TRIGGER: "External Trigger mode, images are acquired on external trigger signal. All images on single trigger.",
|
||||
TRIGGERMODE.MULT_TRIGGER: "Multiple External Trigger mode, images are acquired on multiple external trigger signals. One image per trigger.",
|
||||
TRIGGERMODE.ALIGNMENT: "Alignment mode, used for beam alignment.",
|
||||
}
|
||||
return descriptions.get(self, "Unknown")
|
||||
|
||||
def __str__(self):
|
||||
return self.description()
|
||||
|
||||
|
||||
class ScanParameter(BaseModel):
|
||||
"""Dataclass to store the scan parameters for the Pilatus.
|
||||
This needs to be in sync with the kwargs of the XRD related scans from Debye, to
|
||||
ensure that the scan parameters are correctly set. Any changes in the scan kwargs,
|
||||
i.e. renaming or adding new parameters, need to be represented here as well."""
|
||||
|
||||
scan_time: float | None = Field(None, description="Scan time for a half oscillation")
|
||||
scan_duration: float | None = Field(None, description="Duration of the scan")
|
||||
break_enable_low: bool | None = Field(
|
||||
None, description="Break enabled for low, should be PV trig_ena_lo_enum"
|
||||
) # trig_enable_low: bool = None
|
||||
break_enable_high: bool | None = Field(
|
||||
None, description="Break enabled for high, should be PV trig_ena_hi_enum"
|
||||
) # trig_enable_high: bool = None
|
||||
break_time_low: float | None = Field(None, description="Break time low energy/angle")
|
||||
break_time_high: float | None = Field(None, description="Break time high energy/angle")
|
||||
cycle_low: int | None = Field(None, description="Cycle for low energy/angle")
|
||||
cycle_high: int | None = Field(None, description="Cycle for high energy/angle")
|
||||
exp_time: float | None = Field(None, description="XRD trigger period")
|
||||
n_of_trigger: int | None = Field(None, description="Amount of XRD triggers")
|
||||
start: float | None = Field(None, description="Start value for energy/angle")
|
||||
stop: float | None = Field(None, description="Stop value for energy/angle")
|
||||
model_config: dict = {"validate_assignment": True}
|
||||
|
||||
|
||||
class Pilatus(PSIDeviceBase, ADBase):
|
||||
"""
|
||||
Pilatus Base integration for Debye.
|
||||
Prefix of the detector is 'X01DA-ES2-PIL:'
|
||||
|
||||
Args:
|
||||
prefix (str) : Prefix for the IOC
|
||||
name (str) : Name of the detector
|
||||
scan_info (ScanInfo | None) : ScanInfo object passed through the device by the device_manager
|
||||
device_manager (DeviceManager | None) : DeviceManager object passed through the device by the device_manager
|
||||
"""
|
||||
|
||||
# USER_ACCESS = ["start_live_mode", "stop_live_mode"]
|
||||
|
||||
cam_gain_menu_string = Cpt(EpicsSignalRO, suffix='cam1:GainMenu', string=True)
|
||||
|
||||
_default_configuration_attrs = [
|
||||
'cam.threshold_energy',
|
||||
'cam.threshold_auto_apply',
|
||||
'cam.gain_menu',
|
||||
'cam_gain_menu_string',
|
||||
'cam.pixel_cut_off',
|
||||
'cam.acquire_time',
|
||||
'cam.num_exposures',
|
||||
'cam.model',
|
||||
]
|
||||
|
||||
cam = Cpt(PilatusDetectorCam, "cam1:")
|
||||
hdf = Cpt(HDF5Plugin, "HDF1:")
|
||||
image1 = Cpt(ImagePlugin, "image1:")
|
||||
filter_number = Cpt(
|
||||
EpicsSignal, "cam1:FileNumber", kind=Kind.omitted, doc="File number for ramdisk"
|
||||
)
|
||||
trigger_shot = Cpt(
|
||||
EpicsSignal,
|
||||
read_pv="X01DA-OP-MO1:BRAGG:xrd_trig_req",
|
||||
write_pv="X01DA-OP-MO1:BRAGG:xrd_trig_req",
|
||||
add_prefix=("a",),
|
||||
kind=Kind.omitted,
|
||||
doc="Trigger PV from MO1 Bragg",
|
||||
)
|
||||
trigger_source = Cpt(
|
||||
EpicsSignal,
|
||||
read_pv="X01DA-OP-MO1:BRAGG:xrd_trig_src_ENUM_RBV",
|
||||
write_pv="X01DA-OP-MO1:BRAGG:xrd_trig_src_ENUM",
|
||||
add_prefix=("a",),
|
||||
kind=Kind.omitted,
|
||||
doc="Trigger Source; PV, 0 : EPICS, 1 : INPOS",
|
||||
)
|
||||
trigger_mode = Cpt(
|
||||
EpicsSignal,
|
||||
read_pv="X01DA-OP-MO1:BRAGG:xrd_trig_mode_ENUM_RBV",
|
||||
write_pv="X01DA-OP-MO1:BRAGG:xrd_trig_mode_ENUM",
|
||||
add_prefix=("a",),
|
||||
kind=Kind.omitted,
|
||||
doc="Trigger Mode; 0 : PULSE, 1 : CONDITION",
|
||||
)
|
||||
trigger_pulse_length = Cpt(
|
||||
EpicsSignal,
|
||||
read_pv="X01DA-OP-MO1:BRAGG:xrd_trig_len_RBV",
|
||||
write_pv="X01DA-OP-MO1:BRAGG:xrd_trig_len",
|
||||
add_prefix=("a",),
|
||||
kind=Kind.omitted,
|
||||
doc="Trigger Period in seconds",
|
||||
)
|
||||
trigger_period = Cpt(
|
||||
EpicsSignal,
|
||||
read_pv="X01DA-OP-MO1:BRAGG:xrd_trig_period_RBV",
|
||||
write_pv="X01DA-OP-MO1:BRAGG:xrd_trig_period",
|
||||
add_prefix=("a",),
|
||||
kind=Kind.omitted,
|
||||
doc="Trigger Pulse Length in seconds",
|
||||
)
|
||||
trigger_n_of = Cpt(
|
||||
EpicsSignal,
|
||||
read_pv="X01DA-OP-MO1:BRAGG:xrd_n_of_trig_RBV",
|
||||
write_pv="X01DA-OP-MO1:BRAGG:xrd_n_of_trig",
|
||||
add_prefix=("a",),
|
||||
kind=Kind.omitted,
|
||||
doc="Number of trigger to generate for each request",
|
||||
)
|
||||
preview = Cpt(
|
||||
PreviewSignal,
|
||||
name="preview",
|
||||
ndim=2,
|
||||
num_rotation_90=3,
|
||||
doc="Preview signal for the Pilatus Detector",
|
||||
)
|
||||
file_event = Cpt(FileEventSignal, name="file_event")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
name: str,
|
||||
prefix: str = "",
|
||||
scan_info: ScanInfo | None = None,
|
||||
device_manager: DeviceManagerDS | None = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
name=name, prefix=prefix, scan_info=scan_info, device_manager=device_manager, **kwargs
|
||||
)
|
||||
self.scan_parameter = ScanParameter()
|
||||
self.device_manager = device_manager
|
||||
self._readout_time = PILATUS_READOUT_TIME
|
||||
self._full_path = ""
|
||||
self._poll_thread = threading.Thread(
|
||||
target=self._poll_array_data, daemon=True, name=f"{self.name}_poll_thread"
|
||||
)
|
||||
self._poll_thread_kill_event = threading.Event()
|
||||
self._poll_rate = 1 # Poll rate in Hz
|
||||
self.xas_xrd_scan_names = ["xas_simple_scan_with_xrd", "xas_advanced_scan_with_xrd"]
|
||||
self.n_images = None
|
||||
# self._live_mode_thread = threading.Thread(
|
||||
# target=self._live_mode_loop, daemon=True, name=f"{self.name}_live_mode_thread"
|
||||
# )
|
||||
# self._live_mode_kill_event = threading.Event()
|
||||
# self._live_mode_run_event = threading.Event()
|
||||
# self._live_mode_stopped_event = threading.Event()
|
||||
# self._live_mode_stopped_event.set() # Initial state is stopped
|
||||
|
||||
########################################
|
||||
# Custom Beamline Methods #
|
||||
########################################
|
||||
|
||||
def _poll_array_data(self):
|
||||
"""Poll the array data for preview updates."""
|
||||
while not self._poll_thread_kill_event.wait(1 / self._poll_rate):
|
||||
try:
|
||||
# logger.info(f"Running poll loop for {self.name}..")
|
||||
value = self.image1.array_data.get()
|
||||
if value is None:
|
||||
continue
|
||||
width = self.image1.array_size.width.get()
|
||||
height = self.image1.array_size.height.get()
|
||||
# Geometry correction for the image
|
||||
data = np.reshape(value, (height, width))
|
||||
last_image: DevicePreviewMessage = self.preview.get()
|
||||
# logger.info(f"Preview image for {self.name} has shape {data.shape}")
|
||||
if last_image is not None:
|
||||
if np.array_equal(data, last_image.data):
|
||||
# No update if image is the same, ~2.5ms on 2400x2400 image (6M)
|
||||
logger.debug(
|
||||
f"Pilatus preview image for {self.name} is the same as last one, not updating."
|
||||
)
|
||||
continue
|
||||
|
||||
logger.debug(f"Setting preview data for {self.name}")
|
||||
self.preview.put(data)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
content = traceback.format_exc()
|
||||
logger.error(
|
||||
f"Error while polling array data for preview of {self.name}: {content}"
|
||||
)
|
||||
|
||||
# def start_live_mode(self, exp_time: float, n_images_max: int = 50000):
|
||||
# """
|
||||
# Start live mode with given exposure time.
|
||||
|
||||
# Args:
|
||||
# exp_time (float) : Exposure time in seconds
|
||||
# n_images_max (int): Maximum number of images to capture during live mode.
|
||||
# Default is 5000. Only reset if needed.
|
||||
# """
|
||||
# if (
|
||||
# self.cam.acquire.get() != ACQUIREMODE.DONE.value
|
||||
# or self.hdf.capture.get() != ACQUIREMODE.DONE.value
|
||||
# ):
|
||||
# logger.warning(f"Can't start live mode, acquisition running on detector {self.name}.")
|
||||
# return
|
||||
# if self._live_mode_run_event.is_set():
|
||||
# logger.warning(f"Live mode is already running on detector {self.name}.")
|
||||
# return
|
||||
|
||||
# # Set relevant PVs
|
||||
# self.cam.array_counter.set(0).wait(5) # Reset array counter
|
||||
# self.cam.num_images.set(n_images_max).wait(5)
|
||||
# logger.info(
|
||||
# f"Setting exposure time to {exp_time} s for live mode on {self.name} with {n_images_max} images."
|
||||
# )
|
||||
# self.cam.acquire_time.set(exp_time - self._readout_time).wait(5)
|
||||
# self.cam.acquire_period.set(exp_time).wait(5)
|
||||
|
||||
# status = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||
# # It should suffice to make sure that self.hdf.capture is not set..
|
||||
# self.cam.acquire.put(1) # Start measurement
|
||||
# try:
|
||||
# status.wait(10)
|
||||
# except WaitTimeoutError:
|
||||
# content = traceback.format_exc()
|
||||
# raise RuntimeError(
|
||||
# f"Live Mode on detector {self.name} did not stop: {content} after 10s."
|
||||
# )
|
||||
# self._live_mode_run_event.set()
|
||||
|
||||
# def _live_mode_loop(self, exp_time: float):
|
||||
# while not self._live_mode_kill_event.is_set():
|
||||
# self._live_mode_run_event.wait()
|
||||
# self._live_mode_stopped_event.clear() # Clear stopped event
|
||||
# time.sleep(self._readout_time) # make sure to wait for the readout_time
|
||||
# n_images = self.cam.array_counter.get()
|
||||
# status = CompareStatus(self.cam.array_counter, n_images + 1)
|
||||
# self.trigger_shot.put(1)
|
||||
# try:
|
||||
# status.wait(60)
|
||||
# except WaitTimeoutError:
|
||||
# logger.warning(
|
||||
# f"Live mode timeout exceeded for {self.name}. Continuing in live_mode_loop"
|
||||
# )
|
||||
# if self._live_mode_run_event.is_set():
|
||||
# self._live_mode_stopped_event.set() # Set stopped event to indicate that live mode loop is stopped
|
||||
|
||||
# def stop_live_mode(self):
|
||||
# """Stop live mode."""
|
||||
# if self._live_mode_stopped_event.is_set():
|
||||
# return
|
||||
# status = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||
# self.cam.acquire.put(0)
|
||||
# self._live_mode_run_event.clear()
|
||||
# if not self._live_mode_stopped_event.wait(10): # Wait until live mode loop is stopped
|
||||
# logger.warning(f"Live mode did not stop in time for {self.name}.")
|
||||
# try:
|
||||
# status.wait(10)
|
||||
# except WaitTimeoutError:
|
||||
# content = traceback.format_exc()
|
||||
# raise RuntimeError(
|
||||
# f"Live Mode on detector {self.name} did not stop: {content} after 10s."
|
||||
# )
|
||||
|
||||
def check_detector_stop_running_acquisition(self) -> AndStatus:
|
||||
"""Check if the detector is still running an acquisition."""
|
||||
status_acquire = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||
status_writing = CompareStatus(self.hdf.capture, ACQUIREMODE.DONE.value)
|
||||
status_cam_server = CompareStatus(self.cam.armed, DETECTORSTATE.UNARMED.value)
|
||||
status = status_acquire & status_writing & status_cam_server
|
||||
return status
|
||||
|
||||
def _calculate_trigger(self, scan_msg: ScanStatusMessage) -> Tuple[float, float]:
|
||||
self._update_scan_parameter()
|
||||
total_osc = 0
|
||||
calc_duration = 0
|
||||
total_trig_lo = 0
|
||||
total_trig_hi = 0
|
||||
# Switching high/low is intended as angle is inverse to energy and settings in BEC are always in energy
|
||||
loc_break_enable_low = self.scan_parameter.break_enable_high
|
||||
loc_break_time_low = self.scan_parameter.break_time_high
|
||||
loc_cycle_low = self.scan_parameter.cycle_high
|
||||
loc_break_enable_high = self.scan_parameter.break_enable_low
|
||||
loc_break_time_high = self.scan_parameter.break_time_low
|
||||
loc_cycle_high = self.scan_parameter.cycle_low
|
||||
|
||||
if not loc_break_enable_low:
|
||||
loc_break_time_low = 0
|
||||
loc_cycle_low = 1
|
||||
if not loc_break_enable_high:
|
||||
loc_break_time_high = 0
|
||||
loc_cycle_high = 1
|
||||
|
||||
total_osc = self.scan_parameter.scan_duration / (
|
||||
self.scan_parameter.scan_time +
|
||||
loc_break_time_low / (2 * loc_cycle_low) +
|
||||
loc_break_time_high / (2 * loc_cycle_high)
|
||||
)
|
||||
total_osc = np.ceil(total_osc)
|
||||
total_osc = total_osc + total_osc % 2 # round up to the next even number
|
||||
|
||||
if loc_break_enable_low:
|
||||
total_trig_lo = np.floor(total_osc / (2 * loc_cycle_low))
|
||||
if loc_break_enable_high:
|
||||
total_trig_hi = np.floor(total_osc / (2 * loc_cycle_high))
|
||||
calc_duration = total_osc * self.scan_parameter.scan_time + total_trig_lo * loc_break_time_low + total_trig_hi * loc_break_time_high
|
||||
|
||||
if calc_duration < self.scan_parameter.scan_duration:
|
||||
# Due to inaccuracy in formula, this can happen, we then need to manually add two oscillations and recalculate the triggers
|
||||
total_osc = total_osc + 2
|
||||
if loc_break_enable_low:
|
||||
total_trig_lo = np.floor(total_osc / (2 * loc_cycle_low))
|
||||
if loc_break_enable_high:
|
||||
total_trig_hi = np.floor(total_osc / (2 * loc_cycle_high))
|
||||
calc_duration = total_osc * self.scan_parameter.scan_time + total_trig_lo * loc_break_time_low + total_trig_hi * loc_break_time_high
|
||||
|
||||
return total_trig_lo, total_trig_hi
|
||||
|
||||
########################################
|
||||
# Beamline Specific Implementations #
|
||||
########################################
|
||||
|
||||
def on_init(self) -> None:
|
||||
"""
|
||||
Called when the device is initialized.
|
||||
|
||||
No signals are connected at this point. If you like to
|
||||
set default values on signals, please use on_connected instead.
|
||||
"""
|
||||
|
||||
def on_connected(self) -> None:
|
||||
"""
|
||||
Called after the device is connected and its signals are connected.
|
||||
Default values for signals should be set here.
|
||||
"""
|
||||
|
||||
status_cam = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||
status_hdf = CompareStatus(self.hdf.capture, ACQUIREMODE.DONE.value)
|
||||
try:
|
||||
status_cam.wait(timeout=5)
|
||||
status_hdf.wait(timeout=5)
|
||||
except WaitTimeoutError:
|
||||
logger.warning(
|
||||
f"Camera device {self.name} was running an acquisition. Stopping acquisition."
|
||||
)
|
||||
self.cam.acquire.put(0)
|
||||
self.hdf.capture.put(0)
|
||||
|
||||
self.cam.trigger_mode.set(TRIGGERMODE.MULT_TRIGGER.value).wait(5)
|
||||
self.cam.image_file_tmot.set(60).wait(5)
|
||||
self.hdf.file_write_mode.set(FILEWRITEMODE.STREAM.value).wait(5)
|
||||
self.hdf.file_template.set("%s%s").wait(5)
|
||||
self.hdf.auto_save.set(1).wait(5)
|
||||
self.hdf.lazy_open.set(1).wait(5)
|
||||
self.hdf.compression.set(COMPRESSIONALGORITHM.NONE.value).wait(5) # To test which to use
|
||||
# Start polling thread...
|
||||
self._poll_thread.start()
|
||||
# Start live mode thread...
|
||||
# self._live_mode_thread.start()
|
||||
|
||||
def on_stage(self) -> DeviceStatus | None:
|
||||
"""
|
||||
Called while staging the device.
|
||||
|
||||
Information about the upcoming scan can be accessed from the scan_info
|
||||
(self.scan_info.msg) object.
|
||||
"""
|
||||
# self.stop_live_mode() # Make sure that live mode is stopped if scan runs
|
||||
|
||||
# If user has activated alignment mode on qt panel, switch back to multitrigger and stop acquisition
|
||||
if self.cam.trigger_mode.get() != TRIGGERMODE.MULT_TRIGGER.value:
|
||||
self.cam.trigger_mode.set(TRIGGERMODE.MULT_TRIGGER.value).wait(5)
|
||||
if self.cam.acquire.get() == ACQUIREMODE.ACQUIRING.value:
|
||||
self.cam.acquire.put(0)
|
||||
status_cam = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||
status_cam.wait(timeout=5)
|
||||
|
||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||
if scan_msg.scan_name in self.xas_xrd_scan_names:
|
||||
self._update_scan_parameter()
|
||||
# Compute number of triggers
|
||||
total_trig_lo, total_trig_hi = self._calculate_trigger(scan_msg)
|
||||
# Set the number of images, we may also set this to a higher values if preferred and stop the acquisition
|
||||
# TODO This logic is prone to errors, as we rely on the scans to nicely resolve to n_images. We should
|
||||
# use here instead a way of settings the n_images independently of the scan parameters to avoid running out of sync
|
||||
# with the complete method. Ideally we comput them in the scan itself.. This is much safer IMO!
|
||||
self.n_images = (total_trig_lo + total_trig_hi) * self.scan_parameter.n_of_trigger
|
||||
exp_time = self.scan_parameter.exp_time
|
||||
self.trigger_source.set(MONOTRIGGERSOURCE.INPOS).wait(5)
|
||||
self.trigger_n_of.set(self.scan_parameter.n_of_trigger).wait(5)
|
||||
|
||||
elif scan_msg.scan_type == "step":
|
||||
self.n_images = scan_msg.num_points * scan_msg.scan_parameters.get(
|
||||
"frames_per_trigger", 1
|
||||
)
|
||||
exp_time = scan_msg.scan_parameters.get("exp_time")
|
||||
self.trigger_source.set(MONOTRIGGERSOURCE.EPICS).wait(5)
|
||||
self.trigger_n_of.set(1).wait(5) # BEC will trigger each acquisition
|
||||
else:
|
||||
# TODO how to deal with fly scans?
|
||||
return None
|
||||
# Common settings
|
||||
self.trigger_mode.set(MONOTRIGGERMODE.PULSE).wait(5)
|
||||
self.trigger_period.set(exp_time).wait(5)
|
||||
self.trigger_pulse_length.set(0.005).wait(
|
||||
5
|
||||
) # Pulse length of 5 ms enough for Pilatus and NIDAQ
|
||||
|
||||
if exp_time - self._readout_time <= 0:
|
||||
raise ValueError(
|
||||
(
|
||||
f"Exposure time {exp_time} is too short ",
|
||||
f"for Pilatus with readout_time {self._readout_time}.",
|
||||
)
|
||||
)
|
||||
detector_exp_time = exp_time - self._readout_time
|
||||
self._full_path = get_full_path(scan_msg, name="pilatus")
|
||||
file_path = "/".join(self._full_path.split("/")[:-1])
|
||||
file_name = self._full_path.split("/")[-1]
|
||||
# Prepare detector and backend
|
||||
self.cam.array_callbacks.set(1).wait(5) # Enable array callbacks
|
||||
self.hdf.enable.set(1).wait(5) # Enable HDF5 plugin
|
||||
# Camera settings
|
||||
self.cam.num_exposures.set(1).wait(5)
|
||||
self.cam.num_images.set(self.n_images).wait(5)
|
||||
self.cam.acquire_time.set(detector_exp_time).wait(5) # let's try this
|
||||
self.cam.acquire_period.set(exp_time).wait(5)
|
||||
self.filter_number.set(0).wait(5)
|
||||
# HDF5 settings
|
||||
logger.debug(
|
||||
f"Setting HDF5 file path to {file_path} and file name to {file_name}. full_path is {self._full_path}"
|
||||
)
|
||||
self.hdf.file_path.set(file_path).wait(5)
|
||||
self.hdf.file_name.set(file_name).wait(5)
|
||||
self.hdf.num_capture.set(self.n_images).wait(5)
|
||||
self.cam.array_counter.set(0).wait(5) # Reset array counter
|
||||
self.file_event.put(
|
||||
file_path=self._full_path,
|
||||
done=False,
|
||||
successful=False,
|
||||
hinted_h5_entries={"data": "/entry/data/data"},
|
||||
)
|
||||
|
||||
def on_unstage(self) -> None:
|
||||
"""Called while unstaging the device."""
|
||||
|
||||
def on_pre_scan(self) -> DeviceStatus | None:
|
||||
"""Called right before the scan starts on all devices automatically."""
|
||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||
if (
|
||||
scan_msg.scan_name in self.xas_xrd_scan_names or scan_msg.scan_type == "step"
|
||||
): # TODO how to deal with fly scans?
|
||||
status_hdf = CompareStatus(self.hdf.capture, ACQUIREMODE.ACQUIRING.value)
|
||||
status_cam = CompareStatus(self.cam.acquire, ACQUIREMODE.ACQUIRING.value)
|
||||
status_cam_server = CompareStatus(self.cam.armed, DETECTORSTATE.ARMED.value)
|
||||
status = status_hdf & status_cam & status_cam_server
|
||||
self.cam.acquire.put(1)
|
||||
self.hdf.capture.put(1)
|
||||
self.cancel_on_stop(status)
|
||||
return status
|
||||
else:
|
||||
return None
|
||||
|
||||
def on_trigger(self) -> DeviceStatus | None:
|
||||
"""Called when the device is triggered."""
|
||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||
if not scan_msg.scan_type == "step":
|
||||
return None
|
||||
start_time = time.time()
|
||||
img_counter = self.hdf.num_captured.get()
|
||||
logger.debug(f"Triggering image with num_captured {img_counter}")
|
||||
status = CompareStatus(self.hdf.num_captured, img_counter + 1)
|
||||
logger.debug(f"Triggering took image {time.time() - start_time:.3f} seconds")
|
||||
self.trigger_shot.put(1)
|
||||
self.cancel_on_stop(status)
|
||||
return status
|
||||
|
||||
def _complete_callback(self, status: DeviceStatus):
|
||||
"""Callback for when the device completes a scan."""
|
||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||
if (
|
||||
scan_msg.scan_name in self.xas_xrd_scan_names or scan_msg.scan_type == "step"
|
||||
): # TODO how to deal with fly scans?
|
||||
if status.success:
|
||||
self.file_event.put(
|
||||
file_path=self._full_path,
|
||||
done=True,
|
||||
successful=True,
|
||||
hinted_h5_entries={"data": "/entry/data/data"},
|
||||
)
|
||||
else:
|
||||
self.file_event.put(
|
||||
file_path=self._full_path,
|
||||
done=True,
|
||||
successful=False,
|
||||
hinted_h5_entries={"data": "/entry/data/data"},
|
||||
)
|
||||
else:
|
||||
return None
|
||||
|
||||
def on_complete(self) -> DeviceStatus | None:
|
||||
"""Called to inquire if a device has completed a scans."""
|
||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||
if (
|
||||
scan_msg.scan_name in self.xas_xrd_scan_names or scan_msg.scan_type == "step"
|
||||
): # TODO how to deal with fly scans?
|
||||
status_hdf = CompareStatus(self.hdf.capture, ACQUIREMODE.DONE.value)
|
||||
status_cam = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||
status_cam_server = CompareStatus(self.cam.armed, DETECTORSTATE.UNARMED.value)
|
||||
if self.scan_info.msg.scan_name in self.xas_xrd_scan_names:
|
||||
# For long scans, it can be that the mono will execute one cycle more,
|
||||
# meaning a few more XRD triggers will be sent
|
||||
status_img_written = CompareStatus(
|
||||
self.hdf.num_captured, self.n_images, operation_success=">="
|
||||
)
|
||||
else:
|
||||
status_img_written = CompareStatus(self.hdf.num_captured, self.n_images)
|
||||
status_img_written = CompareStatus(self.hdf.num_captured, self.n_images)
|
||||
status = status_hdf & status_cam & status_img_written & status_cam_server
|
||||
status.add_callback(self._complete_callback) # Callback that writing was successful
|
||||
self.cancel_on_stop(status)
|
||||
return status
|
||||
else:
|
||||
return None
|
||||
|
||||
def on_kickoff(self) -> None:
|
||||
"""Called to kickoff a device for a fly scan. Has to be called explicitly."""
|
||||
|
||||
def on_stop(self) -> None:
|
||||
"""Called when the device is stopped."""
|
||||
self.cam.acquire.put(0)
|
||||
self.hdf.capture.put(0)
|
||||
|
||||
def on_destroy(self) -> None:
|
||||
"""Called when the device is destroyed. Cleanup resources here."""
|
||||
self._poll_thread_kill_event.set()
|
||||
# TODO do we need to clean the poll thread ourselves?
|
||||
self.on_stop()
|
||||
|
||||
def _update_scan_parameter(self):
|
||||
"""Get the scan_info parameters for the scan."""
|
||||
for key, value in self.scan_info.msg.request_inputs["inputs"].items():
|
||||
if hasattr(self.scan_parameter, key):
|
||||
setattr(self.scan_parameter, key, value)
|
||||
for key, value in self.scan_info.msg.request_inputs["kwargs"].items():
|
||||
if hasattr(self.scan_parameter, key):
|
||||
setattr(self.scan_parameter, key, value)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
pilatus = Pilatus(name="pilatus", prefix="X01DA-ES2-PIL:")
|
||||
logger.info("Calling wait for connection")
|
||||
# pilatus.wait_for_connection(all_signals=True, timeout=20)
|
||||
logger.info("Connecting to pilatus...")
|
||||
pilatus.on_connected()
|
||||
for exp_time, scan_number, n_pnts in zip([0.5, 1.0, 2.0], [1, 2, 3], [30, 20, 10]):
|
||||
logger.info("Sleeping for 5s")
|
||||
time.sleep(5)
|
||||
pilatus.scan_info.msg.num_points = n_pnts
|
||||
pilatus.scan_info.msg.scan_parameters["exp_time"] = exp_time
|
||||
pilatus.scan_info.msg.scan_parameters["frames_per_trigger"] = 1
|
||||
pilatus.scan_info.msg.info["file_components"] = (
|
||||
f"/sls/x01da/data/p22481/raw/data/S00000-00999/S{scan_number:05d}/S{scan_number:05d}",
|
||||
"h5",
|
||||
)
|
||||
pilatus.on_stage()
|
||||
logger.info("Stage done")
|
||||
pilatus.on_pre_scan().wait(timeout=5)
|
||||
logger.info("Pre-scan done")
|
||||
for ii in range(pilatus.scan_info.msg.num_points):
|
||||
# if ii == 0:
|
||||
# time.sleep(1)
|
||||
logger.info(f"Triggering image {ii+1}/{pilatus.scan_info.msg.num_points}")
|
||||
pilatus.on_trigger().wait()
|
||||
p = pilatus.preview.get()
|
||||
if p is not None:
|
||||
p: DevicePreviewMessage
|
||||
logger.warning(
|
||||
f"Preview shape: {p.data.shape}, max: {np.max(p.data)}, min: {np.min(p.data)}, mean: {np.mean(p.data)}"
|
||||
)
|
||||
pilatus.on_complete().wait(timeout=5)
|
||||
logger.info("Complete done")
|
||||
pilatus.on_unstage()
|
||||
logger.info("Unstage done")
|
||||
finally:
|
||||
pilatus.on_destroy()
|
||||
@@ -1,75 +1,100 @@
|
||||
"""ES2 Pilatus Curtain"""
|
||||
|
||||
import time
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device, EpicsSignal, EpicsSignalRO, Kind
|
||||
from ophyd_devices.utils import bec_utils
|
||||
from ophyd import EpicsSignal, EpicsSignalRO
|
||||
from ophyd_devices import CompareStatus, DeviceStatus
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bec_lib.devicemanager import ScanInfo
|
||||
|
||||
|
||||
class GasMixSetup(Device):
|
||||
class PilatusCurtainError(Exception):
|
||||
"""PilatusCurtain specific exception"""
|
||||
|
||||
|
||||
class COVER(int, enum.Enum):
|
||||
"""Pilatus Curtain States"""
|
||||
|
||||
# TODO What are the proper states here? - Probably enums for the states are better.
|
||||
OPEN = 0
|
||||
CLOSED = 0
|
||||
ERROR = 1
|
||||
|
||||
|
||||
class PilatusCurtain(PSIDeviceBase):
|
||||
"""Class for the ES2 Pilatus Curtain"""
|
||||
|
||||
USER_ACCESS = ["open", "close"]
|
||||
|
||||
open_cover = Cpt(EpicsSignal, suffix="OpenCover", kind="config", doc="Open Cover")
|
||||
|
||||
close_cover = Cpt(EpicsSignal, suffix="CloseCover", kind="config", doc="Close Cover")
|
||||
|
||||
cover_is_closed = Cpt(
|
||||
EpicsSignalRO, suffix="CoverIsClosed", kind="config", doc="Cover is closed"
|
||||
)
|
||||
|
||||
cover_is_open = Cpt(EpicsSignalRO, suffix="CoverIsOpen", kind="config", doc="Cover is open")
|
||||
|
||||
cover_is_moving = Cpt(
|
||||
EpicsSignalRO, suffix="CoverIsMoving", kind="config", doc="Cover is moving"
|
||||
)
|
||||
|
||||
cover_error = Cpt(EpicsSignalRO, suffix="CoverError", kind="config", doc="Cover error")
|
||||
|
||||
def __init__(
|
||||
self, prefix="", *, name: str, kind: Kind = None, device_manager=None, parent=None, **kwargs
|
||||
):
|
||||
"""Initialize the Pilatus Curtain.
|
||||
|
||||
Args:
|
||||
prefix (str): EPICS prefix for the device
|
||||
name (str): Name of the device
|
||||
kind (Kind): Kind of the device
|
||||
device_manager (DeviceManager): Device manager instance
|
||||
parent (Device): Parent device
|
||||
kwargs: Additional keyword arguments
|
||||
"""
|
||||
super().__init__(prefix, name=name, kind=kind, parent=parent, **kwargs)
|
||||
self.device_manager = device_manager
|
||||
self.service_cfg = None
|
||||
def __init__(self, *, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs):
|
||||
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
|
||||
|
||||
self.timeout_for_pvwait = 30
|
||||
self.readback.name = self.name
|
||||
# Wait for connection on all components, ensure IOC is connected
|
||||
self.wait_for_connection(all_signals=True, timeout=5)
|
||||
|
||||
if device_manager:
|
||||
self.device_manager = device_manager
|
||||
else:
|
||||
self.device_manager = bec_utils.DMMock()
|
||||
def on_connected(self) -> None:
|
||||
"""
|
||||
Called after the device is connected and its signals are connected.
|
||||
Default values for signals should be set here.
|
||||
"""
|
||||
if self.cover_error.get() == COVER.ERROR:
|
||||
raise PilatusCurtainError("Pilatus Curtain is in an error state!")
|
||||
|
||||
self.connector = self.device_manager.connector
|
||||
def on_stage(self) -> DeviceStatus | None:
|
||||
"""Called while staging the device."""
|
||||
return self.open()
|
||||
|
||||
def open(self) -> None:
|
||||
def on_unstage(self) -> DeviceStatus | None:
|
||||
"""Called while unstaging the device."""
|
||||
# return self.close()
|
||||
|
||||
def on_stop(self) -> DeviceStatus | None:
|
||||
"""Called when the device is stopped."""
|
||||
# return self.close()
|
||||
|
||||
def open(self) -> DeviceStatus | None:
|
||||
"""Open the cover"""
|
||||
if self.cover_is_closed.get() == COVER.CLOSED:
|
||||
self.open_cover.put(1)
|
||||
# TODO timeout ok?
|
||||
status_open = CompareStatus(self.cover_is_open, COVER.OPEN, timeout=5)
|
||||
status_error = CompareStatus(self.cover_error, COVER.ERROR, operation_success="!=")
|
||||
status = status_open & status_error
|
||||
return status
|
||||
else:
|
||||
return None
|
||||
|
||||
self.open_cover.put(1)
|
||||
|
||||
while not self.cover_is_open.get():
|
||||
time.sleep(0.1)
|
||||
if self.cover_error.get():
|
||||
raise TimeoutError("Curtain did not open successfully and is now in an error state")
|
||||
|
||||
def close(self) -> None:
|
||||
def close(self) -> DeviceStatus | None:
|
||||
"""Close the cover"""
|
||||
|
||||
self.close_cover.put(1)
|
||||
|
||||
while not self.cover_is_closed.get():
|
||||
time.sleep(0.1)
|
||||
if self.cover_error.get():
|
||||
raise TimeoutError(
|
||||
"Curtain did not close successfully and is now in an error state"
|
||||
)
|
||||
if self.cover_is_open.get() == COVER.OPEN:
|
||||
self.close_cover.put(1)
|
||||
# TODO timeout ok?
|
||||
status_close = CompareStatus(self.cover_is_closed, COVER.CLOSED, timeout=5)
|
||||
status_error = CompareStatus(self.cover_error, COVER.ERROR, operation_success="!=")
|
||||
status = status_close & status_error
|
||||
return status
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -52,9 +52,15 @@ class Reffoilchanger(PSIDeviceBase):
|
||||
status = Cpt(
|
||||
EpicsSignal, suffix="ES2-REF:SELN-FilterState-ENUM_RBV", kind="config", doc="Status"
|
||||
)
|
||||
status_string = Cpt(
|
||||
EpicsSignal, suffix="ES2-REF:SELN-FilterState-ENUM_RBV", kind="config", doc="Status", string=True
|
||||
)
|
||||
op_mode = Cpt(
|
||||
EpicsSignalWithRBV, suffix="ES2-REF:SELN-OpMode-ENUM", kind="config", doc="Status"
|
||||
)
|
||||
op_mode_string = Cpt(
|
||||
EpicsSignalWithRBV, suffix="ES2-REF:SELN-OpMode-ENUM", kind="config", doc="Status", string=True
|
||||
)
|
||||
ref_set = Cpt(EpicsSignal, suffix="ES2-REF:SELN-SET", kind="config", doc="Requested reference")
|
||||
ref_rb = Cpt(
|
||||
EpicsSignalRO, suffix="ES2-REF:SELN-RB", kind="config", doc="Currently set reference"
|
||||
|
||||
6
debye_bec/macros/README.md
Normal file
6
debye_bec/macros/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Macros
|
||||
|
||||
This directory is intended to store macros which will be loaded automatically when starting BEC.
|
||||
Macros are small functions to make repetitive tasks easier. Functions defined in python files in this directory will be accessible from the BEC console.
|
||||
Please do not put any code outside of function definitions here. If you wish for code to be automatically run when starting BEC, see the startup script at debye_bec/bec_ipython_client/startup/post_startup.py
|
||||
For a guide on writing macros, please see: https://bec.readthedocs.io/en/latest/user/command_line_interface.html#how-to-write-a-macro
|
||||
0
debye_bec/macros/__init__.py
Normal file
0
debye_bec/macros/__init__.py
Normal file
@@ -108,8 +108,9 @@ class XASSimpleScanWithXRD(XASSimpleScan):
|
||||
gui_config = {
|
||||
"Movement Parameters": ["start", "stop"],
|
||||
"Scan Parameters": ["scan_time", "scan_duration"],
|
||||
"Low Energy Range": ["xrd_enable_low", "num_trigger_low", "exp_time_low", "cycle_low"],
|
||||
"High Energy Range": ["xrd_enable_high", "num_trigger_high", "exp_time_high", "cycle_high"],
|
||||
"Low Energy Break": ["break_enable_low", "break_time_low", "cycle_low"],
|
||||
"High Energy Break": ["break_enable_high", "break_time_high", "cycle_high"],
|
||||
"XRD Triggers": ["exp_time", "n_of_trigger"],
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@@ -118,14 +119,14 @@ class XASSimpleScanWithXRD(XASSimpleScan):
|
||||
stop: float,
|
||||
scan_time: float,
|
||||
scan_duration: float,
|
||||
xrd_enable_low: bool,
|
||||
num_trigger_low: int,
|
||||
exp_time_low: float,
|
||||
break_enable_low: bool,
|
||||
break_time_low: float,
|
||||
cycle_low: int,
|
||||
xrd_enable_high: bool,
|
||||
num_trigger_high: int,
|
||||
exp_time_high: float,
|
||||
break_enable_high: bool,
|
||||
break_time_high: float,
|
||||
cycle_high: float,
|
||||
exp_time: float,
|
||||
n_of_trigger: int,
|
||||
motor: DeviceBase = "mo1_bragg",
|
||||
**kwargs,
|
||||
):
|
||||
@@ -138,16 +139,16 @@ class XASSimpleScanWithXRD(XASSimpleScan):
|
||||
stop (float): Stop energy for the scan.
|
||||
scan_time (float): Time for one oscillation .
|
||||
scan_duration (float): Total duration of the scan.
|
||||
xrd_enable_low (bool): Enable XRD triggering for the low energy range.
|
||||
num_trigger_low (int): Number of triggers for the low energy range.
|
||||
exp_time_low (float): Exposure time for the low energy range.
|
||||
break_enable_low (bool): Enable breaks for the low energy range.
|
||||
break_time_low (float): Break time for the low energy range.
|
||||
cycle_low (int): Specify how often the triggers should be considered,
|
||||
every nth cycle for low
|
||||
xrd_enable_high (bool): Enable XRD triggering for the high energy range.
|
||||
num_trigger_high (int): Number of triggers for the high energy range.
|
||||
exp_time_high (float): Exposure time for the high energy range.
|
||||
break_enable_high (bool): Enable breaks for the high energy range.
|
||||
break_time_high (float): Break time for the high energy range.
|
||||
cycle_high (int): Specify how often the triggers should be considered,
|
||||
every nth cycle for high
|
||||
exp_time (float): Length of 1 trigger period in seconds
|
||||
n_of_trigger (int): Amount of triggers to be fired during break
|
||||
motor (DeviceBase, optional): Motor device to be used for the scan.
|
||||
Defaults to "mo1_bragg".
|
||||
|
||||
@@ -162,14 +163,14 @@ class XASSimpleScanWithXRD(XASSimpleScan):
|
||||
motor=motor,
|
||||
**kwargs,
|
||||
)
|
||||
self.xrd_enable_low = xrd_enable_low
|
||||
self.num_trigger_low = num_trigger_low
|
||||
self.exp_time_low = exp_time_low
|
||||
self.break_enable_low = break_enable_low
|
||||
self.break_time_low = break_time_low
|
||||
self.cycle_low = cycle_low
|
||||
self.xrd_enable_high = xrd_enable_high
|
||||
self.num_trigger_high = num_trigger_high
|
||||
self.exp_time_high = exp_time_high
|
||||
self.break_enable_high = break_enable_high
|
||||
self.break_time_high = break_time_high
|
||||
self.cycle_high = cycle_high
|
||||
self.exp_time = exp_time
|
||||
self.n_of_trigger = n_of_trigger
|
||||
|
||||
|
||||
class XASAdvancedScan(XASSimpleScan):
|
||||
@@ -233,8 +234,9 @@ class XASAdvancedScanWithXRD(XASAdvancedScan):
|
||||
"Movement Parameters": ["start", "stop"],
|
||||
"Scan Parameters": ["scan_time", "scan_duration"],
|
||||
"Spline Parameters": ["p_kink", "e_kink"],
|
||||
"Low Energy Range": ["xrd_enable_low", "num_trigger_low", "exp_time_low", "cycle_low"],
|
||||
"High Energy Range": ["xrd_enable_high", "num_trigger_high", "exp_time_high", "cycle_high"],
|
||||
"Low Energy Break": ["break_enable_low", "break_time_low", "cycle_low"],
|
||||
"High Energy Break": ["break_enable_high", "break_time_high", "cycle_high"],
|
||||
"XRD Triggers": ["exp_time", "n_of_trigger"],
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@@ -245,14 +247,14 @@ class XASAdvancedScanWithXRD(XASAdvancedScan):
|
||||
scan_duration: float,
|
||||
p_kink: float,
|
||||
e_kink: float,
|
||||
xrd_enable_low: bool,
|
||||
num_trigger_low: int,
|
||||
exp_time_low: float,
|
||||
break_enable_low: bool,
|
||||
break_time_low: float,
|
||||
cycle_low: int,
|
||||
xrd_enable_high: bool,
|
||||
num_trigger_high: int,
|
||||
exp_time_high: float,
|
||||
break_enable_high: bool,
|
||||
break_time_high: float,
|
||||
cycle_high: float,
|
||||
exp_time: float,
|
||||
n_of_trigger: int,
|
||||
motor: DeviceBase = "mo1_bragg",
|
||||
**kwargs,
|
||||
):
|
||||
@@ -270,16 +272,16 @@ class XASAdvancedScanWithXRD(XASAdvancedScan):
|
||||
scan_duration (float): Total duration of the scan.
|
||||
p_kink (float): Position of kink.
|
||||
e_kink (float): Energy of the kink.
|
||||
xrd_enable_low (bool): Enable XRD triggering for the low energy range.
|
||||
num_trigger_low (int): Number of triggers for the low energy range.
|
||||
exp_time_low (float): Exposure time for the low energy range.
|
||||
break_enable_low (bool): Enable breaks for the low energy range.
|
||||
break_time_low (float): Break time for the low energy range.
|
||||
cycle_low (int): Specify how often the triggers should be considered,
|
||||
every nth cycle for low
|
||||
xrd_enable_high (bool): Enable XRD triggering for the high energy range.
|
||||
num_trigger_high (int): Number of triggers for the high energy range.
|
||||
exp_time_high (float): Exposure time for the high energy range.
|
||||
break_enable_high (bool): Enable breaks for the high energy range.
|
||||
break_time_high (float): Break time for the high energy range.
|
||||
cycle_high (int): Specify how often the triggers should be considered,
|
||||
every nth cycle for high
|
||||
exp_time (float): Length of 1 trigger period in seconds
|
||||
n_of_trigger (int): Amount of triggers to be fired during break
|
||||
motor (DeviceBase, optional): Motor device to be used for the scan.
|
||||
Defaults to "mo1_bragg".
|
||||
|
||||
@@ -298,11 +300,11 @@ class XASAdvancedScanWithXRD(XASAdvancedScan):
|
||||
)
|
||||
self.p_kink = p_kink
|
||||
self.e_kink = e_kink
|
||||
self.xrd_enable_low = xrd_enable_low
|
||||
self.num_trigger_low = num_trigger_low
|
||||
self.exp_time_low = exp_time_low
|
||||
self.break_enable_low = break_enable_low
|
||||
self.break_time_low = break_time_low
|
||||
self.cycle_low = cycle_low
|
||||
self.xrd_enable_high = xrd_enable_high
|
||||
self.num_trigger_high = num_trigger_high
|
||||
self.exp_time_high = exp_time_high
|
||||
self.break_enable_high = break_enable_high
|
||||
self.break_time_high = break_time_high
|
||||
self.cycle_high = cycle_high
|
||||
self.exp_time = exp_time
|
||||
self.n_of_trigger = n_of_trigger
|
||||
|
||||
@@ -28,7 +28,7 @@ class NIDAQWriterService(BECService):
|
||||
def __init__(self, config: ServiceConfig, connector_cls: RedisConnector) -> None:
|
||||
super().__init__(config=config, connector_cls=connector_cls, unique_service=True)
|
||||
self.queue = queue.Queue()
|
||||
config = self._service_config.service_config.get("file_writer")
|
||||
config = self._service_config.config.get("file_writer")
|
||||
self.writer_mixin = FileWriter(service_config=config)
|
||||
self._scan_status_consumer = None
|
||||
self._ni_data_consumer = None
|
||||
|
||||
@@ -6,13 +6,13 @@ build-backend = "hatchling.build"
|
||||
name = "debye_bec"
|
||||
version = "0.0.0"
|
||||
description = "A plugin repository for BEC"
|
||||
requires-python = ">=3.10"
|
||||
requires-python = ">=3.11"
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Topic :: Scientific/Engineering",
|
||||
]
|
||||
dependencies = ["numpy", "scipy", "bec_lib", "h5py", "ophyd_devices"]
|
||||
dependencies = ["numpy", "scipy", "bec_lib", "h5py", "ophyd_devices", "opencv-python==4.11.0.86"]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
|
||||
0
test_commit.yml
Normal file
0
test_commit.yml
Normal file
0
test_commit_2.yml
Normal file
0
test_commit_2.yml
Normal file
0
test_commit_3.yml
Normal file
0
test_commit_3.yml
Normal file
0
test_commit_4
Normal file
0
test_commit_4
Normal file
@@ -74,15 +74,16 @@ def test_egu(mock_bragg):
|
||||
def test_move_succeeds(mock_bragg):
|
||||
dev = mock_bragg
|
||||
dev.move_abs._read_pv.mock_data = 0
|
||||
# Move succeeds
|
||||
with mock.patch.object(dev.motor_is_moving._read_pv, "mock_data", side_effect=[0, 1]):
|
||||
status = dev.move(0.5)
|
||||
# Sleep needed to allow thread to resolive in _move_and_finish, i.e. and the 0.25s sleep inside the function
|
||||
time.sleep(1)
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
assert dev.setpoint.get() == 0.5
|
||||
assert dev.move_abs.get() == 1
|
||||
dev.motor_is_moving._read_pv.mock_data = 0
|
||||
|
||||
status = dev.move(0.5)
|
||||
assert status.done is False
|
||||
dev.motor_is_moving._read_pv.mock_data = 1
|
||||
status.wait(timeout=3) # Callback should within that time
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
assert dev.setpoint.get() == 0.5
|
||||
assert dev.move_abs.get() == 1
|
||||
|
||||
|
||||
def test_stop_move(mock_bragg):
|
||||
@@ -131,10 +132,12 @@ def test_set_trig_settings(mock_bragg):
|
||||
dev.set_trig_settings(
|
||||
enable_low=True,
|
||||
enable_high=False,
|
||||
exp_time_high=0.1,
|
||||
exp_time_low=0.01,
|
||||
break_time_high=0.1,
|
||||
break_time_low=0.01,
|
||||
cycle_low=1,
|
||||
cycle_high=3,
|
||||
exp_time=0.5,
|
||||
n_of_trigger=7,
|
||||
)
|
||||
assert dev.scan_settings.trig_ena_lo_enum.get() == True
|
||||
assert dev.scan_settings.trig_ena_hi_enum.get() == False
|
||||
@@ -142,6 +145,8 @@ def test_set_trig_settings(mock_bragg):
|
||||
assert dev.scan_settings.trig_every_n_hi.get() == 3
|
||||
assert dev.scan_settings.trig_time_lo.get() == 0.01
|
||||
assert dev.scan_settings.trig_time_hi.get() == 0.1
|
||||
assert dev.trigger_settings.xrd_trig_period.get() == 0.5
|
||||
assert dev.trigger_settings.xrd_n_of_trig.get() == 7
|
||||
|
||||
|
||||
def test_set_control_settings(mock_bragg):
|
||||
|
||||
283
tests/tests_devices/test_pilatus.py
Normal file
283
tests/tests_devices/test_pilatus.py
Normal file
@@ -0,0 +1,283 @@
|
||||
# pylint: skip-file
|
||||
import threading
|
||||
from typing import TYPE_CHECKING, Generator
|
||||
from unittest import mock
|
||||
|
||||
import ophyd
|
||||
import pytest
|
||||
from bec_lib.messages import ScanStatusMessage
|
||||
from bec_server.scan_server.scan_worker import ScanWorker
|
||||
from ophyd_devices import CompareStatus, DeviceStatus
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import DeviceStoppedError
|
||||
from ophyd_devices.tests.utils import MockPV, patch_dual_pvs
|
||||
from ophyd_devices.utils.psi_device_base_utils import TaskStatus
|
||||
|
||||
from debye_bec.devices.pilatus.pilatus import (
|
||||
ACQUIREMODE,
|
||||
COMPRESSIONALGORITHM,
|
||||
DETECTORSTATE,
|
||||
FILEWRITEMODE,
|
||||
TRIGGERMODE,
|
||||
Pilatus,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma no cover
|
||||
from bec_lib.messages import FileMessage
|
||||
|
||||
# @pytest.fixture(scope="function")
|
||||
# def scan_worker_mock(scan_server_mock):
|
||||
# scan_server_mock.device_manager.connector = mock.MagicMock()
|
||||
# scan_worker = ScanWorker(parent=scan_server_mock)
|
||||
# yield scan_worker
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="function",
|
||||
params=[
|
||||
(0.1, 1, 1, "line_scan", "step"),
|
||||
(0.2, 2, 2, "time_scan", "step"),
|
||||
(0.5, 5, 5, "xas_advanced_scan", "fly"),
|
||||
],
|
||||
)
|
||||
def mock_scan_info(request, tmpdir):
|
||||
exp_time, frames_per_trigger, num_points, scan_name, scan_type = request.param
|
||||
scan_info = ScanStatusMessage(
|
||||
scan_id="test_id",
|
||||
status="open",
|
||||
scan_type=scan_type,
|
||||
scan_number=1,
|
||||
scan_parameters={
|
||||
"exp_time": exp_time,
|
||||
"frames_per_trigger": frames_per_trigger,
|
||||
"system_config": {},
|
||||
},
|
||||
info={"file_components": (f"{tmpdir}/data/S00000/S000001", "h5")},
|
||||
num_points=num_points,
|
||||
scan_name=scan_name,
|
||||
)
|
||||
yield scan_info
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def pilatus(mock_scan_info) -> Generator[Pilatus, None, None]:
|
||||
name = "pilatus"
|
||||
prefix = "X01DA-OP-MO1:PILATUS:"
|
||||
with mock.patch.object(ophyd, "cl") as mock_cl:
|
||||
mock_cl.get_pv = MockPV
|
||||
mock_cl.thread_class = threading.Thread
|
||||
dev = Pilatus(name=name, prefix=prefix)
|
||||
patch_dual_pvs(dev)
|
||||
# dev.image1 = mock.MagicMock()
|
||||
# with mock.patch.object(dev, "image1"):
|
||||
with mock.patch.object(dev, "task_handler"):
|
||||
dev.scan_info.msg = mock_scan_info
|
||||
try:
|
||||
yield dev
|
||||
finally:
|
||||
try:
|
||||
dev.on_destroy()
|
||||
except ophyd.utils.DestroyedError:
|
||||
pass
|
||||
|
||||
|
||||
# TODO figure out how to test as set calls on the PV below seem to break it..
|
||||
# def test_pilatus_on_connected(pilatus):
|
||||
# """Test the on_connected logic of the Pilatus detector."""
|
||||
# pilatus.cam.acquire._read_pv.mock_data = ACQUIREMODE.DONE.value
|
||||
# pilatus.hdf.capture._read_pv.mock_data = ACQUIREMODE.DONE.value
|
||||
# pilatus.on_connected()
|
||||
# assert pilatus.cam.trigger_mode.get() == TRIGGERMODE.MULT_TRIGGER
|
||||
# assert pilatus.hdf.file_write_mode.get() == FILEWRITEMODE.STREAM
|
||||
# assert pilatus.hdf.file_template.get() == "%s%s"
|
||||
# assert pilatus.hdf.auto_save.get() == 1
|
||||
# assert pilatus.hdf.lazy_open.get() == 1
|
||||
# assert pilatus.hdf.compression.get() == COMPRESSIONALGORITHM.NONE
|
||||
|
||||
|
||||
def test_pilatus_on_stop(pilatus):
|
||||
"""Test the on_stop logic of the Pilatus detector."""
|
||||
pilatus.cam.acquire._read_pv.mock_data = ACQUIREMODE.ACQUIRING.value
|
||||
pilatus.hdf.capture._read_pv.mock_data = ACQUIREMODE.ACQUIRING.value
|
||||
pilatus.on_stop()
|
||||
assert pilatus.cam.acquire.get() == ACQUIREMODE.DONE
|
||||
assert pilatus.hdf.capture.get() == ACQUIREMODE.DONE
|
||||
|
||||
|
||||
def test_pilatus_on_destroy(pilatus):
|
||||
"""Test the on_destroy logic of the Pilatus detector."""
|
||||
with mock.patch.object(pilatus, "on_stop") as mock_on_stop:
|
||||
pilatus.destroy()
|
||||
assert mock_on_stop.call_count == 1
|
||||
assert pilatus._poll_thread_kill_event.is_set()
|
||||
|
||||
|
||||
def test_pilatus_on_failure_callback(pilatus):
|
||||
"""Test the on_failure_callback logic of the Pilatus detector."""
|
||||
|
||||
with mock.patch.object(pilatus, "on_stop") as mock_on_stop:
|
||||
status = DeviceStatus(pilatus)
|
||||
status.set_finished() # Does not trigger 'stop'
|
||||
assert mock_on_stop.call_count == 0
|
||||
status = DeviceStatus(pilatus)
|
||||
status.set_exception(RuntimeError("Test error")) # triggers 'stop'
|
||||
assert mock_on_stop.call_count == 1
|
||||
|
||||
|
||||
def test_pilatus_on_pre_scan(pilatus):
|
||||
"""Test the on_pre_scan logic of the Pilatus detector."""
|
||||
scan_msg = pilatus.scan_info.msg
|
||||
if scan_msg.scan_type != "step" and scan_msg.scan_name not in pilatus.xas_xrd_scan_names:
|
||||
assert pilatus.on_pre_scan() is None
|
||||
return
|
||||
pilatus.cam.acquire._read_pv.mock_data = ACQUIREMODE.DONE.value
|
||||
pilatus.hdf.capture._read_pv.mock_data = ACQUIREMODE.DONE.value
|
||||
pilatus.cam.armed._read_pv.mock_data = DETECTORSTATE.UNARMED.value
|
||||
status = pilatus.on_pre_scan()
|
||||
assert status.done is False
|
||||
pilatus.cam.armed.put(DETECTORSTATE.ARMED.value)
|
||||
status.wait(timeout=5)
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
|
||||
|
||||
def test_pilatus_on_trigger(pilatus):
|
||||
"""test on trigger logic of the Pilatus detector."""
|
||||
scan_msg = pilatus.scan_info.msg
|
||||
if scan_msg.scan_type != "step" and scan_msg.scan_name not in pilatus.xas_xrd_scan_names:
|
||||
status = pilatus.trigger()
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
return None
|
||||
pilatus.hdf.num_captured._read_pv.mock_data = 0
|
||||
pilatus.trigger_shot.put(0)
|
||||
status = pilatus.trigger()
|
||||
assert status.done is False
|
||||
assert pilatus.trigger_shot.get() == 1
|
||||
pilatus.hdf.num_captured._read_pv.mock_data = 1
|
||||
status.wait(timeout=5)
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
|
||||
|
||||
def test_pilatus_on_trigger_cancel_on_stop(pilatus):
|
||||
"""Test that the status of the trigger is cancelled if stop is called"""
|
||||
if pilatus.scan_info.msg.scan_name.startswith("xas"):
|
||||
status = pilatus.trigger()
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
return
|
||||
pilatus.hdf.num_captured._read_pv.mock_data = 0
|
||||
pilatus.trigger_shot.put(0)
|
||||
status = pilatus.trigger()
|
||||
assert status.done is False
|
||||
with pytest.raises(DeviceStoppedError):
|
||||
pilatus.stop()
|
||||
status.wait(timeout=5)
|
||||
|
||||
|
||||
def test_pilatus_on_complete(pilatus: Pilatus):
|
||||
"""Test the on_complete logic of the Pilatus detector."""
|
||||
|
||||
if pilatus.scan_info.msg.scan_name.startswith("xas"):
|
||||
# TODO add test cases for xas scans
|
||||
# status = pilatus.complete()
|
||||
# assert status.done is True
|
||||
# assert status.success is True
|
||||
return
|
||||
# Check in addition that the file event is set properly, once with if it works, and once if not (i.e. when cancelled)
|
||||
for success in [True, False]:
|
||||
if success is True:
|
||||
pilatus.file_event.put(file_path="", done=False, successful=False)
|
||||
pilatus._full_path = "file-path-for-success"
|
||||
else:
|
||||
pilatus.file_event.put(file_path="", done=False, successful=True)
|
||||
pilatus._full_path = "file-path-for-failure"
|
||||
# Set values for relevant PVs
|
||||
pilatus.cam.acquire._read_pv.mock_data = ACQUIREMODE.ACQUIRING.value
|
||||
pilatus.hdf.capture._read_pv.mock_data = ACQUIREMODE.ACQUIRING.value
|
||||
pilatus.cam.armed._read_pv.mock_data = DETECTORSTATE.ARMED.value
|
||||
num_images = pilatus.scan_info.msg.num_points * pilatus.scan_info.msg.scan_parameters.get(
|
||||
"frames_per_trigger", 1
|
||||
)
|
||||
pilatus.hdf.num_captured._read_pv.mock_data = num_images - 1
|
||||
# Call on complete
|
||||
pilatus.n_images = num_images
|
||||
status = pilatus.complete()
|
||||
# Should not be finished
|
||||
assert status.done is False
|
||||
pilatus.cam.acquire.put(ACQUIREMODE.DONE.value)
|
||||
pilatus.hdf.capture.put(ACQUIREMODE.DONE.value)
|
||||
pilatus.cam.armed.put(DETECTORSTATE.UNARMED.value)
|
||||
assert status.done is False
|
||||
if success is True:
|
||||
pilatus.hdf.num_captured._read_pv.mock_data = num_images
|
||||
# Now it should resolve
|
||||
status.wait(timeout=5)
|
||||
assert status.done is True
|
||||
assert status.success is True
|
||||
file_msg: FileMessage = pilatus.file_event.get()
|
||||
assert file_msg.file_path == "file-path-for-success"
|
||||
assert file_msg.done is True
|
||||
assert file_msg.successful is True
|
||||
else:
|
||||
with pytest.raises(DeviceStoppedError):
|
||||
pilatus.stop()
|
||||
status.wait(timeout=5)
|
||||
assert status.done is True
|
||||
assert status.success is False
|
||||
file_msg: FileMessage = pilatus.file_event.get()
|
||||
assert file_msg.file_path == "file-path-for-failure"
|
||||
assert file_msg.done is True
|
||||
assert file_msg.successful is False
|
||||
|
||||
|
||||
# TODO, figure out how to properly test this..
|
||||
# def test_pilatus_on_stage(pilatus):
|
||||
# """Test the on_stage logic of the Pilatus detector."""
|
||||
# # Make sure that no additional logic from stage signals of underlying components is triggered
|
||||
# pilatus.stage_sigs = {}
|
||||
# pilatus.cam.stage_sigs = {}
|
||||
# pilatus.hdf.stage_sigs = {}
|
||||
# if pilatus.scan_info.msg.scan_name.startswith("xas"):
|
||||
# pilatus.on_stage()
|
||||
# return
|
||||
# exp_time = pilatus.scan_info.msg.scan_parameters.get("exp_time", 0.1)
|
||||
# n_images = pilatus.scan_info.msg.num_points * pilatus.scan_info.msg.scan_parameters.get(
|
||||
# "frames_per_trigger", 1
|
||||
# )
|
||||
# if exp_time <= 0.1:
|
||||
# with pytest.raises(ValueError):
|
||||
# pilatus.on_stage()
|
||||
# return
|
||||
# pilatus.filter_number.put(10)
|
||||
# pilatus.cam.array_counter.put(1)
|
||||
# file_components = pilatus.scan_info.msg.info.get("file_components", ("", ""))[0]
|
||||
# base_path = file_components[0].rsplit("/", 1)[0]
|
||||
# file_name = file_components[0].rsplit("/", 1)[1] + "_pilatus.h5"
|
||||
# file_path = os.path.join(base_path, file_name)
|
||||
# pilatus.on_stage()
|
||||
# assert pilatus.cam.array_callbacks.get() == 0
|
||||
# assert pilatus.hdf.enable.get() == 1
|
||||
# assert pilatus.cam.num_exposures.get() == 1
|
||||
# assert pilatus.cam.num_images.get() == n_images
|
||||
# assert pilatus.cam.acquire_time.get() == exp_time - pilatus._readout_time
|
||||
# assert pilatus.cam.acquire_period.get() == exp_time
|
||||
# assert pilatus.filter_number.get() == 0
|
||||
# assert pilatus.hdf.file_path.get() == base_path
|
||||
# assert pilatus.hdf.file_name.get() == file_name
|
||||
# assert pilatus.hdf.num_capture.get() == n_images
|
||||
# assert pilatus.cam.array_counter.get() == 0
|
||||
# file_msg: FileMessage = pilatus.file_event.get()
|
||||
# assert file_msg.file_path == file_path
|
||||
# assert file_msg.done is False
|
||||
# assert file_msg.successful is False
|
||||
|
||||
|
||||
def test_pilatus_on_stage_raises_low_exp_time(pilatus):
|
||||
"""Test that on_stage raises a ValueError if the exposure time is too low."""
|
||||
pilatus.scan_info.msg.scan_parameters["exp_time"] = 0.09
|
||||
scan_msg = pilatus.scan_info.msg
|
||||
if scan_msg.scan_type != "step" and scan_msg.scan_name not in pilatus.xas_xrd_scan_names:
|
||||
return
|
||||
with pytest.raises(ValueError):
|
||||
pilatus.on_stage()
|
||||
@@ -141,17 +141,18 @@ def test_xas_simple_scan_with_xrd(scan_assembler, ScanStubStatusMock):
|
||||
stop=5,
|
||||
scan_time=1,
|
||||
scan_duration=10,
|
||||
xrd_enable_low=True,
|
||||
num_trigger_low=1,
|
||||
exp_time_low=1,
|
||||
break_enable_low=True,
|
||||
break_time_low=1,
|
||||
cycle_low=1,
|
||||
xrd_enable_high=True,
|
||||
num_trigger_high=2,
|
||||
exp_time_high=3,
|
||||
break_enable_high=True,
|
||||
break_time_high=2,
|
||||
exp_time=1,
|
||||
n_of_trigger=1,
|
||||
cycle_high=4,
|
||||
)
|
||||
request.device_manager.add_device("nidaq")
|
||||
reference_commands = get_instructions(request, ScanStubStatusMock)
|
||||
# TODO #64 based on creating this ScanStatusMessage, we should test the logic of stage/kickoff/complete/unstage in Pilatus and mo1Bragg
|
||||
|
||||
assert reference_commands == [
|
||||
None,
|
||||
@@ -339,13 +340,13 @@ def test_xas_advanced_scan_with_xrd(scan_assembler, ScanStubStatusMock):
|
||||
scan_duration=10,
|
||||
p_kink=50,
|
||||
e_kink=8500,
|
||||
xrd_enable_low=True,
|
||||
num_trigger_low=1,
|
||||
exp_time_low=1,
|
||||
break_enable_low=True,
|
||||
break_time_low=1,
|
||||
cycle_low=1,
|
||||
xrd_enable_high=True,
|
||||
num_trigger_high=2,
|
||||
exp_time_high=3,
|
||||
break_enable_high=True,
|
||||
break_time_high=2,
|
||||
exp_time=1,
|
||||
n_of_trigger=1,
|
||||
cycle_high=4,
|
||||
)
|
||||
request.device_manager.add_device("nidaq")
|
||||
|
||||
Reference in New Issue
Block a user