5 Commits

Author SHA1 Message Date
x06da 640459f1b5 Automatic backup triggered by new deployment
CI for pxiii_bec / test (push) Successful in 28s
2026-05-22 09:25:50 +02:00
wyzula_j 8a023aff5a fix(bec-widgets): migration of scripts to V3
CI for pxiii_bec / test (pull_request) Successful in 32s
CI for pxiii_bec / test (push) Successful in 29s
2026-03-05 13:59:55 +01:00
perl_d f5a6b20eb8 Update repo with template version v1.2.8
CI for pxiii_bec / test (pull_request) Successful in 32s
CI for pxiii_bec / test (push) Successful in 1m21s
2026-02-27 15:49:26 +01:00
perl_d 624da08a27 Update repo with template version v1.2.7
CI for pxiii_bec / test (push) Failing after 0s
CI for pxiii_bec / test (pull_request) Failing after 0s
2026-02-27 12:11:40 +01:00
appel_c eb5a9c89ca feat: update repo with copier template for gitea migration 2025-09-11 17:02:57 +02:00
22 changed files with 3622 additions and 831 deletions
+1 -1
View File
@@ -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: pxiii_bec
+102
View File
@@ -0,0 +1,102 @@
name: CI for pxiii_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/pxiii_bec
ref: "${{ inputs.BEC_PLUGIN_REPO_BRANCH || github.head_ref || github.sha }}"
path: ./pxiii_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 ./pxiii_bec
- name: Run Pytest with Coverage
id: coverage
run: pytest --random-order --cov=./pxiii_bec --cov-config=./pxiii_bec/pyproject.toml --cov-branch --cov-report=xml --no-cov-on-fail ./pxiii_bec/tests/ || test $? -eq 5
+62
View File
@@ -0,0 +1,62 @@
name: Create template upgrade PR for pxiii_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\"
}"
-7
View File
@@ -1,7 +0,0 @@
include:
- file: /templates/plugin-repo-template.yml
inputs:
name: pxiii_bec
target: pxiii_bec
branch: $CHILD_PIPELINE_BRANCH
project: bec/awi_utils
@@ -1,10 +1,14 @@
"""
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.
is started. It can be used to add additional command line arguments.
"""
import os
from bec_lib.service_config import ServiceConfig
import pxiii_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": "x06da-bec-001", "port": 6379})
deployment_path = os.path.dirname(os.path.dirname(os.path.dirname(pxiii_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})
+62
View File
@@ -0,0 +1,62 @@
import csv
import json
INPUT_CSV = "pxiii-devices-new.csv"
OUTPUT_YAML = "pxiii-devices-new.yaml"
def str_to_bool(val):
return str(val).strip().lower() in ["yes", "true", "1"]
with open(INPUT_CSV, newline="") as csvfile:
reader = csv.DictReader(csvfile)
with open(OUTPUT_YAML, "w") as yamlfile:
for row in reader:
include = row["include"]
name = row["name"]
desc = row["description"]
device_class = row["deviceClass"]
pv = row["PV"]
readout_priority = row["readoutPriority"]
tag = row["tag"]
read_only = str_to_bool(row["readOnly"])
user_param = row.get("userParameter", "").strip()
if str(include).strip().lower() != "yes":
continue
yamlfile.write(f"{name}:\n")
yamlfile.write(f" description: {desc}\n")
yamlfile.write(f" deviceClass: ophyd.Epics{device_class}\n")
if device_class == "Motor":
yamlfile.write(f" deviceConfig: {{prefix: '{pv}'}}\n")
else:
yamlfile.write(
f" deviceConfig: {{read_pv: '{pv}', auto_monitor: true}}\n"
)
yamlfile.write(" onFailure: buffer\n")
yamlfile.write(" enabled: True\n")
yamlfile.write(f" readoutPriority: {readout_priority}\n")
yamlfile.write(" deviceTags:\n")
yamlfile.write(f" - {tag}\n")
yamlfile.write(f" readOnly: {read_only}\n")
yamlfile.write(" softwareTrigger: false\n")
# Only add userParameter for Motors if present
# if device_class == "Motor" and user_param:
if user_param:
try:
parsed = json.loads(user_param)
yamlfile.write(" userParameter:\n")
for k, v in parsed.items():
yamlfile.write(f" {k}: {v}\n")
except json.JSONDecodeError:
yamlfile.write(f" userParameter: {user_param}\n")
yamlfile.write("\n")
print(f"YAML written to {OUTPUT_YAML}")
@@ -0,0 +1,143 @@
name,description,deviceClass,PV,readoutPriority,tag,readOnly,include,userParameter,
sls_current,SLS current,SignalRO,ARS07-DPCT-0100:CURR,monitored,SLS,yes,no,,
fe_sl_xr,FE Slit X Ring,Motor,X06DA-FE-SLDI:TRXR,baseline,fe,no,yes,,
fe_sl_yt,FE Slit Y top,Motor,X06DA-FE-SLDI:TRYT,baseline,fe,no,yes,,
fe_sl_xw,FE Slit X Wall,Motor,X06DA-FE-SLDI:TRXW,baseline,fe,no,yes,,
fe_sl_yb,FE SlitY Bottom,Motor,X06DA-FE-SLDI:TRYB,baseline,fe,no,yes,,
fe_sl_xcen,FE Slit X Centre,Motor,X06DA-FE-SLDI:CENTERX,baseline,fe,no,yes,,
fe_sl_xsize,FE Slit X Size,Motor,X06DA-FE-SLDI:SIZEX,baseline,fe,no,yes,,
fe_sl_ycen,FE Slit Y Centre,Motor,X06DA-FE-SLDI:CENTERY,baseline,fe,no,yes,,
fe_sl_ysize,FE Slit Y Size,Motor,X06DA-FE-SLDI:SIZEY,baseline,fe,no,yes,,
fe_cm_xu,FE Coll Mirror Upstream X,Motor,X06DA-FE-MI1:TRXU,baseline,fe_cm,no,yes,,
fe_cm_xd,FE Coll Mirror Downstream X,Motor,X06DA-FE-MI1:TRXD,baseline,fe_cm,no,yes,,
fe_cm_yur,FE Coll Mirror Upstream Ring Y,Motor,X06DA-FE-MI1:TRYUR,baseline,fe_cm,no,yes,,
fe_cm_yw,FE Coll Mirror Wall Y,Motor,X06DA-FE-MI1:TRYUW,baseline,fe_cm,no,yes,,
fe_cm_ydr,FE Coll Mirror Downstream Y,Motor,X06DA-FE-MI1:TRYD,baseline,fe_cm,no,yes,,
fe_cm_b1,FE Coll Mirror Bender,Motor,X06DA-FE-MI1:BEND1,baseline,fe_cm,no,yes,,
fe_cm_yaw,FE Coll Mirror Yaw,Motor,X06DA-FE-MI1:YAW,baseline,fe_cm,no,yes,,
fe_cm_roll,FE Coll Mirror Roll,Motor,X06DA-FE-MI1:ROLL,baseline,fe_cm,no,yes,,
fe_cm_pitch,FE Coll Mirror Pitch,Motor,X06DA-FE-MI1:PITCH,baseline,fe_cm,no,yes,,
fe_cm_x,FE Coll Mirror X,Motor,X06DA-FE-MI1:TRX,baseline,fe_cm,no,yes,,
fe_cm_y,FE Coll Mirror Y ,Motor,X06DA-FE-MI1:TRY,baseline,fe_cm,no,yes,,
bsf_bpm1,BSF BPM Signal 1,SignalRO,X06DA-OP-BSFBPM:SIGNAL1,monitored,bpm,yes,no,,
bsf_bpm2,BSF BPM Signal 2,SignalRO,X06DA-OP-BSFBPM:SIGNAL2,monitored,bpm,yes,no,,
bsf_bpm3,BSF BPM Signal 3,SignalRO,X06DA-OP-BSFBPM:SIGNAL3,monitored,bpm,yes,no,,
bsf_bpm4,BSF BPM Signal 4,SignalRO,X06DA-OP-BSFBPM:SIGNAL4,monitored,bpm,yes,no,,
bsf_bpmsum,BSF BPM Summed,SignalRO,X06DA-OP-BSFBPM:SUM,monitored,bpm,yes,no,,
bsf_sl_xw,BSF slit outboard,Motor,X06DA-OP-BSFSLH:TRXW,monitored,bsf,no,yes,,
bsf_sl_xr,BSF slit inboard,Motor,X06DA-OP-BSFSLH:TRXR,baseline,bsf,no,yes,,
bsf_sl_xcen,BSF X centre,Motor,X06DA-OP-BSFSLH:CENTER,baseline,bsf,no,yes,,
bsf_sl_xsize,BSF X size,Motor,X06DA-OP-BSFSLH:SIZE,baseline,bsf,no,yes,,
bsf_f1_y,BSF Filter 1 Y,Motor,X06DA-OP-BSFFI1:TRY,baseline,bsf,no,yes,,
dccm_theta1,DCCM theta1,Motor,X06DA-OP-DCCM:ROTX-CR1,baseline,dccm,no,yes,,
dccm_theta2,DCCM theta2,Motor,X06DA-OP-DCCM:ROTX-CR2,baseline,dccm,no,yes,,
dccm_rotz,DCCM Crystal 2 rotz ,Motor,X06DA-OP-DCCM:ROTZ-CR2,baseline,dccm,no,yes,,
dccm_energy,DCCM energy,Motor,X06DA-OP-DCCM:ENERGY,baseline,dccm,no,yes,,
dccm_diode_t,Top diode between mono crystals,SignalRO,X06DA-OP-DCCMXBPM1T:READOUT,monitored,dccm,no,yes,,
dccm_diode_b,Bottom diode between mono crystals,SignalRO,X06DA-OP-DCCMXBPM1B:READOUT,monitored,dccm,no,yes,,
dccm_xbpm1,XBPM after mono ch1,SignalRO,X06DA-OP-DCCMXBPM2:Current1:MeanValue_RBV,monitored,dccm,no,yes,,
dccm_xbpm2,XBPM after mono ch2,SignalRO,X06DA-OP-DCCMXBPM2:Current2:MeanValue_RBV,monitored,dccm,no,yes,,
dccm_xbpm3,XBPM after mono ch3,SignalRO,X06DA-OP-DCCMXBPM2:Current3:MeanValue_RBV,monitored,dccm,no,yes,,
dccm_xbpm4,XBPM after mono ch4,SignalRO,X06DA-OP-DCCMXBPM2:Current4:MeanValue_RBV,monitored,dccm,no,yes,,
dccm_xbpmsum,XBPM after mono summed,SignalRO,X06DA-OP-DCCMXBPM2:SumAll:MeanValue_RBV,monitored,dccm,no,yes,,
dccm_di_y,DCCM diode Y,Motor,X06DA-OP-DCCMXBPM1:TRY,baseline,dccm,no,yes,,
dccm_xbpm_y,DCCM XBPM Y,Motor,X06DA-OP-DCCMXBPM2:TRY,baseline,dccm,no,yes,,
ss_bpm1,SS BPM Signal 1,SignalRO,X06DA-ES-SSBPM:Current1:MeanValue_RBV,monitored,bpm,yes,yes,,
ss_bpm2,SS BPM Signal 2,SignalRO,X06DA-ES-SSBPM:Current2:MeanValue_RBV,monitored,bpm,yes,yes,,
ss_bpm3,SS BPM Signal 3,SignalRO,X06DA-ES-SSBPM:Current3:MeanValue_RBV,monitored,bpm,yes,yes,,
ss_bpm4,SS BPM Signal 4,SignalRO,X06DA-ES-SSBPM:Current4:MeanValue_RBV,monitored,bpm,yes,yes,,
ss_bpmsum,SS BPM Summed,SignalRO,X06DA-ES-SSBPM:SumAll:MeanValue_RBV,monitored,bpm,yes,yes,,
ss_bpm_x,SS BPM X,Motor,X06DA-ES-SSBPM:TRX,baseline,ss,no,yes,,
ss_bpm_y,SS BPM Y,Motor,X06DA-ES-SSBPM:TRY,baseline,ss,no,yes,,
ss_sl_xw,SS slit wall,Motor,X06DA-ES-SSSLH:TRXW,baseline,ss,no,yes,,
ss_sl_xr,SS slit ring,Motor,X06DA-ES-SSSLH:TRXR,baseline,ss,no,yes,,
ss_sl_xcen,SS slit X centre,Motor,X06DA-ES-SSSLH:CENTER,baseline,ss,no,yes,,
ss_sl_xsize,SS slit X size,Motor,X06DA-ES-SSSLH:SIZE,baseline,ss,no,yes,,
ss_sl_yt,SS slit top,Motor,X06DA-ES-SSSLV:TRYT,baseline,ss,no,yes,,
ss_sl_yb,SS slit bottom,Motor,X06DA-ES-SSSLV:TRYB,baseline,ss,no,yes,,
ss_sl_ycen,SS slit Y centre,Motor,X06DA-ES-SSSLV:CENTER,baseline,ss,no,yes,,
ss_sl_ysize,SS slit Y size,Motor,X06DA-ES-SSSLV:SIZE,baseline,ss,no,yes,,
ss_xi_x,SS X-ray eye X,Motor,X06DA-ES-SSXI:TRX,baseline,ss,no,yes,,
ss_xi_y,SS X-ray eye Y,Motor,X06DA-ES-SSXI:TRY,baseline,ss,no,yes,,
ss_xicam_x,ss cam X,SignalRO,X06DA-ES-SSCAM:Stats5:CentroidX_RBV,baseline,ss,yes,yes,,
ss_xicam_y,ss cam Y,SignalRO,X06DA-ES-SSCAM:Stats5:CentroidY_RBV,baseline,ss,yes,yes,,
ss_xicam_max,ss cam max value,SignalRO,X06DA-ES-SSCAM:Stats5:MaxValue_RBV,monitored,ss,yes,yes,,
ss_xicam_exp,ss camera exposure,Signal,X06DA-ES-SSCAM:cam1:AcquireTime,baseline,ss,no,yes,,
ss_xicam_gain,ss camera gain,Signal,X06DA-ES-SSCAM:cam1:Gain,baseline,ss,no,yes,,
ss_xicam_xsig,ss camera x sigma,Signal,X06DA-ES-SSCAM:Stats5:SigmaX_RBV,baseline,ss,yes,yes,,
ss_xicam_ysig,ss camera y sigma,Signal,X06DA-ES-SSCAM:Stats5:SigmaY_RBV,baseline,ss,yes,yes,,
vfm_xu,VFM Upstream X,Motor,X06DA-ES-VFM:TRXU,baseline,vfm,no,yes,,
vfm_xd,VFM Downstream X,Motor,X06DA-ES-VFM:TRXD,baseline,vfm,no,yes,,
vfm_yur,VFM Upstream Ring Y,Motor,X06DA-ES-VFM:TRYUR,baseline,vfm,no,yes,,
vfm_yw,VFM Wall Y,Motor,X06DA-ES-VFM:TRYW,baseline,vfm,no,yes,,
vfm_ydr,VFM Downstream Ring Y,Motor,X06DA-ES-VFM:TRYDR,baseline,vfm,no,yes,,
vfm_bu,VFM Upstream Bender,Motor,X06DA-ES-VFM:BNDU,baseline,vfm,no,yes,,
vfm_bd,VFM Downstream Bender,Motor,X06DA-ES-VFM:BNDD,baseline,vfm,no,yes,,
vfm_yaw,VFM Virtual Yaw,Motor,X06DA-ES-VFM:YAW,baseline,vfm,no,yes,,
vfm_roll,VFM Virtual Roll,Motor,X06DA-ES-VFM:ROLL,baseline,vfm,no,yes,,
vfm_pitch,VFM Virtual Pitch,Motor,X06DA-ES-VFM:PITCH,baseline,vfm,no,yes,,
vfm_x,VFM Virtual X,Motor,X06DA-ES-VFM:TRX,baseline,vfm,no,yes,,
vfm_y,VFM Virtual Y ,Motor,X06DA-ES-VFM:TRY,baseline,vfm,no,yes,,
hfm_xu,HFM Upstream X,Motor,X06DA-ES-HFM:TRXU,baseline,hfm,no,yes,,
hfm_xd,HFM Downstream X,Motor,X06DA-ES-HFM:TRXD,baseline,hfm,no,yes,,
hfm_yuw,HFM Upstream Wall Y,Motor,X06DA-ES-HFM:TRYUW,baseline,hfm,no,yes,,
hfm_yr,HFM Ring Y,Motor,X06DA-ES-HFM:TRYR,baseline,hfm,no,yes,,
hfm_ydw,HFM Downstream Wall Y,Motor,X06DA-ES-HFM:TRYDW,baseline,hfm,no,yes,,
hfm_bu,HFM Upstream Bender,Motor,X06DA-ES-HFM:BNDU,baseline,hfm,no,yes,,
hfm_bd,HFM Downstream Bender,Motor,X06DA-ES-HFM:BNDD,baseline,hfm,no,yes,,
hfm_yaw,HFM Virtual Yaw,Motor,X06DA-ES-HFM:YAW,baseline,hfm,no,yes,,
hfm_roll,HFM Virtual Roll,Motor,X06DA-ES-HFM:ROLL,baseline,hfm,no,yes,,
hfm_pitch,HFM Virtual Pitch,Motor,X06DA-ES-HFM:PITCH,baseline,hfm,no,yes,,
hfm_x,HFM Virtual X,Motor,X06DA-ES-HFM:TRX,baseline,hfm,no,yes,,
hfm_y,HFM Virtual Y ,Motor,X06DA-ES-HFM:TRY,baseline,hfm,no,yes,,
bcu_bpm1,BCU BPM Signal 1 ,SignalRO,X06DA-ES-BCBPM:Current1:MeanValue_RBV,monitored,bpm,yes,no,,
bcu_bpm2,BCU BPM Signal 2,SignalRO,X06DA-ES-BCBPM:Current2:MeanValue_RBV,monitored,bpm,yes,no,,
bcu_bpm3,BCU BPM Signal 3,SignalRO,X06DA-ES-BCBPM:Current3:MeanValue_RBV,monitored,bpm,yes,no,,
bcu_bpm4,BCU BPM Signal 4,SignalRO,X06DA-ES-BCBPM:Current4:MeanValue_RBV,monitored,bpm,yes,no,,
bcu_bpmsum,BCU BPM Summed,SignalRO,X06DA-ES-BCBPM:SumAll:MeanValue_RBV,monitored,bpm,yes,no,,
bcu_bpm_x,BCU BPM X,Motor,X06DA-ES-BCBPM:TRX,baseline,bcu,no,no,,
bcu_bpm_y,BCU BPM Y ,Motor,X06DA-ES-BCBPM:TRY,baseline,bcu,no,no,,
bcu_sl_xw,BCU slit wall,Motor,X06DA-ES-BCSLH:TRXW,baseline,bcu,no,no,,
bcu_sl_xr,BCU slit ring,Motor,X06DA-ES-BCSLH:TRXR,baseline,bcu,no,no,,
bcu_sl_xcen,BCU slit X centre,Motor,X06DA-ES-BCSLH:CENTER,baseline,bcu,no,no,,
bcu_sl_xsize,BCU slit X size,Motor,X06DA-ES-BCSLH:SIZEX,baseline,bcu,no,no,,
bcu_sl_yt,BCU slit top,Motor,X06DA-ES-BCSLV:TRYT,baseline,bcu,no,no,,
bcu_sl_yb,BCU slit bottom,Motor,X06DA-ES-BCSLV:TRYB,baseline,bcu,no,no,,
bcu_sl_ycen,BCU slit Y centre,Motor,X06DA-ES-BCSLV:CENTER,baseline,bcu,no,no,,
bcu_sl_ysize,BCU slit Y size,Motor,X06DA-ES-BCSLV:SIZE,baseline,bcu,no,no,,
bcu_f1_x,BCU filter 1 X,Motor,X06DA-ES-BCFI1:TRX,baseline,bcu,no,no,,
bcu_f2_x,BCU filter 2 X,Motor,X06DA-ES-BCFI2:TRX,baseline,bcu,no,no,,
bcu_f3_x,BCU filter 3 X,Motor,X06DA-ES-BCFI3:TRX,baseline,bcu,no,no,,
bcu_f4_x,BCU filter 4 X,Motor,X06DA-ES-BCFI4:TRX,baseline,bcu,no,no,,
xrf_pos,XRF det in/out,Signal,X06DA-ES-XRF:POS-SET,baseline,se,no,yes,"{""type"":positioner}",
samcam_x,sample cam X ,SignalRO,X06DA-ES-MS:Stats5:CentroidX_RBV,baseline,scam,yes,yes,,
samcam_xsig,sample cam X sigma,SignalRO,X06DA-ES-MS:Stats5:SigmaX_RBV,monitored,scam,yes,yes,,
samcam_y,sample cam Y ,SignalRO,X06DA-ES-MS:Stats5:CentroidY_RBV,baseline,scam,yes,yes,,
samcam_ysig,sample cam Y sigma,SignalRO,X06DA-ES-MS:Stats5:SigmaY_RBV,monitored,scam,yes,yes,,
samcam_max,sample cam max value,SignalRO,X06DA-ES-MS:Stats5:MaxValue_RBV,monitored,scam,yes,yes,,
samcam_exp,sample cam exp time,Signal,X06DA-ES-MS:cam1:AcquireTime,baseline,scam,no,yes,,
samcam_gain,sample cam gain,Signal,X06DA-ES-MS:cam1:Gain,baseline,scam,no,yes,,
scam_zoom,Sample cam zoom,Motor,X06DA-ES-MS:ZOOM,baseline,scam,no,no,,
fl_bright,Frontlight brightness,Signal,X06DA-ES-FL:SET,baseline,se,no,no,,
coll_x,Collimator X,Motor,X06DA-ES-COL:TRX,baseline,se,no,no,,
coll_y,Collimator Y,Motor,X06DA-ES-COL:TRY,baseline,se,no,no,"{""type"": multi-position, ""in"": 41.5, ""out"": 20.0, ""park"": 0,""tol"":0.05}",
diag_y,Scintillator/diode Y,Motor,X06DA-ES-SCL:TRY,baseline,se,no,no,"{""type"": multi-position, ""scint"": 38.62, ""i1"": 44.0, ""out"": 20.0,""park"": 0,""tol"":0.3}",
diag_z,Scintillator/diode Z,Motor,X06DA-ES-SCL:TRZ,baseline,se,no,no,,
i1,i1 diode reading,SignalRO,X06DA-ES-SCLDI:READOUT,monitored,bpm,yes,no,,
bl_pos,Backlight positioner,Signal,X06DA-ES-BL:POS-SET,baseline,se,no,yes,"{""type"":positioner}",
bl_bright,Backlight brightness,Signal,X06DA-ES-BL:SET,baseline,se,no,yes,,
bs_x,Beamstop X,Motor,X06DA-ES-BS:TRX,baseline,se,no,no,,
bs_y,Beamstop Y,Motor,X06DA-ES-BS:TRY,baseline,se,no,no,,
bs_z,Beamstop Z,Motor,X06DA-ES-BS:TRZ,baseline,se,no,no,"{""type"": guarded, ""min"": 13, ""samp"": 15, ""work_min"": 20, ""safe"": 41, ""max_blin"": 42, ""max_blout"": 70}",
bs_pos,Beamstop positioner,Signal,X06DA-ES-BS:POS-SET,baseline,se,no,yes,"{""type"":positioner}",
gon_x,Goniometer X,Motor,X06DA-ES-DF1:TRX1,baseline,det,no,no,"{""type"": guarded, ""in"": 18.0, ""out"": -10.0, ""safe"": -100,""tol"":0.5}",
gon_y,Goniometer Y,Motor,X06DA-ES-DF1:TRY1,baseline,det,no,no,,
gon_z,Goniometer X,Motor,X06DA-ES-DF1:TRZ1,baseline,det,no,no,,
omega,Omega,Motor,X06DA-ES-DF1:ROTU,baseline,det,no,no,,
cryo_pos,Cryo positioner,Signal,X06DA-ES-CS:POS-SET,baseline,se,no,yes,"{""type"":positioner}",
cryo_x,Cryojet X ,Motor,X06DA-ES-CS:TRX,baseline,se,no,no,,
det_cov,Detector cover,Signal,X06DA-ES-DETCOV:SET,baseline,det,no,yes,"{""type"":positioner}",
det_y,Detector Y,Motor,X06DA-ES-DET:TRY,baseline,det,no,no,,
det_z,Detector Z,Motor,X06DA-ES-DET:TRZ,baseline,det,no,no,,
gonpos,Sample sensor distance,SignalRO,X06DA-ES-DF1:CBOX-USER1,baseline,se,no,no,,
gonvalid,Sample in valid distance,SignalRO,X06DA-ES-DF1:CBOX-CMP1,baseline,se,no,no,,
1 name description deviceClass PV readoutPriority tag readOnly include userParameter
2 sls_current SLS current SignalRO ARS07-DPCT-0100:CURR monitored SLS yes no
3 fe_sl_xr FE Slit X Ring Motor X06DA-FE-SLDI:TRXR baseline fe no yes
4 fe_sl_yt FE Slit Y top Motor X06DA-FE-SLDI:TRYT baseline fe no yes
5 fe_sl_xw FE Slit X Wall Motor X06DA-FE-SLDI:TRXW baseline fe no yes
6 fe_sl_yb FE SlitY Bottom Motor X06DA-FE-SLDI:TRYB baseline fe no yes
7 fe_sl_xcen FE Slit X Centre Motor X06DA-FE-SLDI:CENTERX baseline fe no yes
8 fe_sl_xsize FE Slit X Size Motor X06DA-FE-SLDI:SIZEX baseline fe no yes
9 fe_sl_ycen FE Slit Y Centre Motor X06DA-FE-SLDI:CENTERY baseline fe no yes
10 fe_sl_ysize FE Slit Y Size Motor X06DA-FE-SLDI:SIZEY baseline fe no yes
11 fe_cm_xu FE Coll Mirror Upstream X Motor X06DA-FE-MI1:TRXU baseline fe_cm no yes
12 fe_cm_xd FE Coll Mirror Downstream X Motor X06DA-FE-MI1:TRXD baseline fe_cm no yes
13 fe_cm_yur FE Coll Mirror Upstream Ring Y Motor X06DA-FE-MI1:TRYUR baseline fe_cm no yes
14 fe_cm_yw FE Coll Mirror Wall Y Motor X06DA-FE-MI1:TRYUW baseline fe_cm no yes
15 fe_cm_ydr FE Coll Mirror Downstream Y Motor X06DA-FE-MI1:TRYD baseline fe_cm no yes
16 fe_cm_b1 FE Coll Mirror Bender Motor X06DA-FE-MI1:BEND1 baseline fe_cm no yes
17 fe_cm_yaw FE Coll Mirror Yaw Motor X06DA-FE-MI1:YAW baseline fe_cm no yes
18 fe_cm_roll FE Coll Mirror Roll Motor X06DA-FE-MI1:ROLL baseline fe_cm no yes
19 fe_cm_pitch FE Coll Mirror Pitch Motor X06DA-FE-MI1:PITCH baseline fe_cm no yes
20 fe_cm_x FE Coll Mirror X Motor X06DA-FE-MI1:TRX baseline fe_cm no yes
21 fe_cm_y FE Coll Mirror Y Motor X06DA-FE-MI1:TRY baseline fe_cm no yes
22 bsf_bpm1 BSF BPM Signal 1 SignalRO X06DA-OP-BSFBPM:SIGNAL1 monitored bpm yes no
23 bsf_bpm2 BSF BPM Signal 2 SignalRO X06DA-OP-BSFBPM:SIGNAL2 monitored bpm yes no
24 bsf_bpm3 BSF BPM Signal 3 SignalRO X06DA-OP-BSFBPM:SIGNAL3 monitored bpm yes no
25 bsf_bpm4 BSF BPM Signal 4 SignalRO X06DA-OP-BSFBPM:SIGNAL4 monitored bpm yes no
26 bsf_bpmsum BSF BPM Summed SignalRO X06DA-OP-BSFBPM:SUM monitored bpm yes no
27 bsf_sl_xw BSF slit outboard Motor X06DA-OP-BSFSLH:TRXW monitored bsf no yes
28 bsf_sl_xr BSF slit inboard Motor X06DA-OP-BSFSLH:TRXR baseline bsf no yes
29 bsf_sl_xcen BSF X centre Motor X06DA-OP-BSFSLH:CENTER baseline bsf no yes
30 bsf_sl_xsize BSF X size Motor X06DA-OP-BSFSLH:SIZE baseline bsf no yes
31 bsf_f1_y BSF Filter 1 Y Motor X06DA-OP-BSFFI1:TRY baseline bsf no yes
32 dccm_theta1 DCCM theta1 Motor X06DA-OP-DCCM:ROTX-CR1 baseline dccm no yes
33 dccm_theta2 DCCM theta2 Motor X06DA-OP-DCCM:ROTX-CR2 baseline dccm no yes
34 dccm_rotz DCCM Crystal 2 rotz Motor X06DA-OP-DCCM:ROTZ-CR2 baseline dccm no yes
35 dccm_energy DCCM energy Motor X06DA-OP-DCCM:ENERGY baseline dccm no yes
36 dccm_diode_t Top diode between mono crystals SignalRO X06DA-OP-DCCMXBPM1T:READOUT monitored dccm no yes
37 dccm_diode_b Bottom diode between mono crystals SignalRO X06DA-OP-DCCMXBPM1B:READOUT monitored dccm no yes
38 dccm_xbpm1 XBPM after mono ch1 SignalRO X06DA-OP-DCCMXBPM2:Current1:MeanValue_RBV monitored dccm no yes
39 dccm_xbpm2 XBPM after mono ch2 SignalRO X06DA-OP-DCCMXBPM2:Current2:MeanValue_RBV monitored dccm no yes
40 dccm_xbpm3 XBPM after mono ch3 SignalRO X06DA-OP-DCCMXBPM2:Current3:MeanValue_RBV monitored dccm no yes
41 dccm_xbpm4 XBPM after mono ch4 SignalRO X06DA-OP-DCCMXBPM2:Current4:MeanValue_RBV monitored dccm no yes
42 dccm_xbpmsum XBPM after mono summed SignalRO X06DA-OP-DCCMXBPM2:SumAll:MeanValue_RBV monitored dccm no yes
43 dccm_di_y DCCM diode Y Motor X06DA-OP-DCCMXBPM1:TRY baseline dccm no yes
44 dccm_xbpm_y DCCM XBPM Y Motor X06DA-OP-DCCMXBPM2:TRY baseline dccm no yes
45 ss_bpm1 SS BPM Signal 1 SignalRO X06DA-ES-SSBPM:Current1:MeanValue_RBV monitored bpm yes yes
46 ss_bpm2 SS BPM Signal 2 SignalRO X06DA-ES-SSBPM:Current2:MeanValue_RBV monitored bpm yes yes
47 ss_bpm3 SS BPM Signal 3 SignalRO X06DA-ES-SSBPM:Current3:MeanValue_RBV monitored bpm yes yes
48 ss_bpm4 SS BPM Signal 4 SignalRO X06DA-ES-SSBPM:Current4:MeanValue_RBV monitored bpm yes yes
49 ss_bpmsum SS BPM Summed SignalRO X06DA-ES-SSBPM:SumAll:MeanValue_RBV monitored bpm yes yes
50 ss_bpm_x SS BPM X Motor X06DA-ES-SSBPM:TRX baseline ss no yes
51 ss_bpm_y SS BPM Y Motor X06DA-ES-SSBPM:TRY baseline ss no yes
52 ss_sl_xw SS slit wall Motor X06DA-ES-SSSLH:TRXW baseline ss no yes
53 ss_sl_xr SS slit ring Motor X06DA-ES-SSSLH:TRXR baseline ss no yes
54 ss_sl_xcen SS slit X centre Motor X06DA-ES-SSSLH:CENTER baseline ss no yes
55 ss_sl_xsize SS slit X size Motor X06DA-ES-SSSLH:SIZE baseline ss no yes
56 ss_sl_yt SS slit top Motor X06DA-ES-SSSLV:TRYT baseline ss no yes
57 ss_sl_yb SS slit bottom Motor X06DA-ES-SSSLV:TRYB baseline ss no yes
58 ss_sl_ycen SS slit Y centre Motor X06DA-ES-SSSLV:CENTER baseline ss no yes
59 ss_sl_ysize SS slit Y size Motor X06DA-ES-SSSLV:SIZE baseline ss no yes
60 ss_xi_x SS X-ray eye X Motor X06DA-ES-SSXI:TRX baseline ss no yes
61 ss_xi_y SS X-ray eye Y Motor X06DA-ES-SSXI:TRY baseline ss no yes
62 ss_xicam_x ss cam X SignalRO X06DA-ES-SSCAM:Stats5:CentroidX_RBV baseline ss yes yes
63 ss_xicam_y ss cam Y SignalRO X06DA-ES-SSCAM:Stats5:CentroidY_RBV baseline ss yes yes
64 ss_xicam_max ss cam max value SignalRO X06DA-ES-SSCAM:Stats5:MaxValue_RBV monitored ss yes yes
65 ss_xicam_exp ss camera exposure Signal X06DA-ES-SSCAM:cam1:AcquireTime baseline ss no yes
66 ss_xicam_gain ss camera gain Signal X06DA-ES-SSCAM:cam1:Gain baseline ss no yes
67 ss_xicam_xsig ss camera x sigma Signal X06DA-ES-SSCAM:Stats5:SigmaX_RBV baseline ss yes yes
68 ss_xicam_ysig ss camera y sigma Signal X06DA-ES-SSCAM:Stats5:SigmaY_RBV baseline ss yes yes
69 vfm_xu VFM Upstream X Motor X06DA-ES-VFM:TRXU baseline vfm no yes
70 vfm_xd VFM Downstream X Motor X06DA-ES-VFM:TRXD baseline vfm no yes
71 vfm_yur VFM Upstream Ring Y Motor X06DA-ES-VFM:TRYUR baseline vfm no yes
72 vfm_yw VFM Wall Y Motor X06DA-ES-VFM:TRYW baseline vfm no yes
73 vfm_ydr VFM Downstream Ring Y Motor X06DA-ES-VFM:TRYDR baseline vfm no yes
74 vfm_bu VFM Upstream Bender Motor X06DA-ES-VFM:BNDU baseline vfm no yes
75 vfm_bd VFM Downstream Bender Motor X06DA-ES-VFM:BNDD baseline vfm no yes
76 vfm_yaw VFM Virtual Yaw Motor X06DA-ES-VFM:YAW baseline vfm no yes
77 vfm_roll VFM Virtual Roll Motor X06DA-ES-VFM:ROLL baseline vfm no yes
78 vfm_pitch VFM Virtual Pitch Motor X06DA-ES-VFM:PITCH baseline vfm no yes
79 vfm_x VFM Virtual X Motor X06DA-ES-VFM:TRX baseline vfm no yes
80 vfm_y VFM Virtual Y Motor X06DA-ES-VFM:TRY baseline vfm no yes
81 hfm_xu HFM Upstream X Motor X06DA-ES-HFM:TRXU baseline hfm no yes
82 hfm_xd HFM Downstream X Motor X06DA-ES-HFM:TRXD baseline hfm no yes
83 hfm_yuw HFM Upstream Wall Y Motor X06DA-ES-HFM:TRYUW baseline hfm no yes
84 hfm_yr HFM Ring Y Motor X06DA-ES-HFM:TRYR baseline hfm no yes
85 hfm_ydw HFM Downstream Wall Y Motor X06DA-ES-HFM:TRYDW baseline hfm no yes
86 hfm_bu HFM Upstream Bender Motor X06DA-ES-HFM:BNDU baseline hfm no yes
87 hfm_bd HFM Downstream Bender Motor X06DA-ES-HFM:BNDD baseline hfm no yes
88 hfm_yaw HFM Virtual Yaw Motor X06DA-ES-HFM:YAW baseline hfm no yes
89 hfm_roll HFM Virtual Roll Motor X06DA-ES-HFM:ROLL baseline hfm no yes
90 hfm_pitch HFM Virtual Pitch Motor X06DA-ES-HFM:PITCH baseline hfm no yes
91 hfm_x HFM Virtual X Motor X06DA-ES-HFM:TRX baseline hfm no yes
92 hfm_y HFM Virtual Y Motor X06DA-ES-HFM:TRY baseline hfm no yes
93 bcu_bpm1 BCU BPM Signal 1 SignalRO X06DA-ES-BCBPM:Current1:MeanValue_RBV monitored bpm yes no
94 bcu_bpm2 BCU BPM Signal 2 SignalRO X06DA-ES-BCBPM:Current2:MeanValue_RBV monitored bpm yes no
95 bcu_bpm3 BCU BPM Signal 3 SignalRO X06DA-ES-BCBPM:Current3:MeanValue_RBV monitored bpm yes no
96 bcu_bpm4 BCU BPM Signal 4 SignalRO X06DA-ES-BCBPM:Current4:MeanValue_RBV monitored bpm yes no
97 bcu_bpmsum BCU BPM Summed SignalRO X06DA-ES-BCBPM:SumAll:MeanValue_RBV monitored bpm yes no
98 bcu_bpm_x BCU BPM X Motor X06DA-ES-BCBPM:TRX baseline bcu no no
99 bcu_bpm_y BCU BPM Y Motor X06DA-ES-BCBPM:TRY baseline bcu no no
100 bcu_sl_xw BCU slit wall Motor X06DA-ES-BCSLH:TRXW baseline bcu no no
101 bcu_sl_xr BCU slit ring Motor X06DA-ES-BCSLH:TRXR baseline bcu no no
102 bcu_sl_xcen BCU slit X centre Motor X06DA-ES-BCSLH:CENTER baseline bcu no no
103 bcu_sl_xsize BCU slit X size Motor X06DA-ES-BCSLH:SIZEX baseline bcu no no
104 bcu_sl_yt BCU slit top Motor X06DA-ES-BCSLV:TRYT baseline bcu no no
105 bcu_sl_yb BCU slit bottom Motor X06DA-ES-BCSLV:TRYB baseline bcu no no
106 bcu_sl_ycen BCU slit Y centre Motor X06DA-ES-BCSLV:CENTER baseline bcu no no
107 bcu_sl_ysize BCU slit Y size Motor X06DA-ES-BCSLV:SIZE baseline bcu no no
108 bcu_f1_x BCU filter 1 X Motor X06DA-ES-BCFI1:TRX baseline bcu no no
109 bcu_f2_x BCU filter 2 X Motor X06DA-ES-BCFI2:TRX baseline bcu no no
110 bcu_f3_x BCU filter 3 X Motor X06DA-ES-BCFI3:TRX baseline bcu no no
111 bcu_f4_x BCU filter 4 X Motor X06DA-ES-BCFI4:TRX baseline bcu no no
112 xrf_pos XRF det in/out Signal X06DA-ES-XRF:POS-SET baseline se no yes {"type":positioner}
113 samcam_x sample cam X SignalRO X06DA-ES-MS:Stats5:CentroidX_RBV baseline scam yes yes
114 samcam_xsig sample cam X sigma SignalRO X06DA-ES-MS:Stats5:SigmaX_RBV monitored scam yes yes
115 samcam_y sample cam Y SignalRO X06DA-ES-MS:Stats5:CentroidY_RBV baseline scam yes yes
116 samcam_ysig sample cam Y sigma SignalRO X06DA-ES-MS:Stats5:SigmaY_RBV monitored scam yes yes
117 samcam_max sample cam max value SignalRO X06DA-ES-MS:Stats5:MaxValue_RBV monitored scam yes yes
118 samcam_exp sample cam exp time Signal X06DA-ES-MS:cam1:AcquireTime baseline scam no yes
119 samcam_gain sample cam gain Signal X06DA-ES-MS:cam1:Gain baseline scam no yes
120 scam_zoom Sample cam zoom Motor X06DA-ES-MS:ZOOM baseline scam no no
121 fl_bright Frontlight brightness Signal X06DA-ES-FL:SET baseline se no no
122 coll_x Collimator X Motor X06DA-ES-COL:TRX baseline se no no
123 coll_y Collimator Y Motor X06DA-ES-COL:TRY baseline se no no {"type": multi-position, "in": 41.5, "out": 20.0, "park": 0,"tol":0.05}
124 diag_y Scintillator/diode Y Motor X06DA-ES-SCL:TRY baseline se no no {"type": multi-position, "scint": 38.62, "i1": 44.0, "out": 20.0,"park": 0,"tol":0.3}
125 diag_z Scintillator/diode Z Motor X06DA-ES-SCL:TRZ baseline se no no
126 i1 i1 diode reading SignalRO X06DA-ES-SCLDI:READOUT monitored bpm yes no
127 bl_pos Backlight positioner Signal X06DA-ES-BL:POS-SET baseline se no yes {"type":positioner}
128 bl_bright Backlight brightness Signal X06DA-ES-BL:SET baseline se no yes
129 bs_x Beamstop X Motor X06DA-ES-BS:TRX baseline se no no
130 bs_y Beamstop Y Motor X06DA-ES-BS:TRY baseline se no no
131 bs_z Beamstop Z Motor X06DA-ES-BS:TRZ baseline se no no {"type": guarded, "min": 13, "samp": 15, "work_min": 20, "safe": 41, "max_blin": 42, "max_blout": 70}
132 bs_pos Beamstop positioner Signal X06DA-ES-BS:POS-SET baseline se no yes {"type":positioner}
133 gon_x Goniometer X Motor X06DA-ES-DF1:TRX1 baseline det no no {"type": guarded, "in": 18.0, "out": -10.0, "safe": -100,"tol":0.5}
134 gon_y Goniometer Y Motor X06DA-ES-DF1:TRY1 baseline det no no
135 gon_z Goniometer X Motor X06DA-ES-DF1:TRZ1 baseline det no no
136 omega Omega Motor X06DA-ES-DF1:ROTU baseline det no no
137 cryo_pos Cryo positioner Signal X06DA-ES-CS:POS-SET baseline se no yes {"type":positioner}
138 cryo_x Cryojet X Motor X06DA-ES-CS:TRX baseline se no no
139 det_cov Detector cover Signal X06DA-ES-DETCOV:SET baseline det no yes {"type":positioner}
140 det_y Detector Y Motor X06DA-ES-DET:TRY baseline det no no
141 det_z Detector Z Motor X06DA-ES-DET:TRZ baseline det no no
142 gonpos Sample sensor distance SignalRO X06DA-ES-DF1:CBOX-USER1 baseline se no no
143 gonvalid Sample in valid distance SignalRO X06DA-ES-DF1:CBOX-CMP1 baseline se no no
File diff suppressed because it is too large Load Diff
@@ -1,757 +1,3 @@
sls_current:
description: sls current
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'ARS07-DPCT-0100:CURR', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: true
softwareTrigger: false
vg0_press:
description: VG0 pressure
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-FE-VMCC-0000:PRESSURE', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: true
softwareTrigger: false
abs_press:
description: Absorber pressure
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-FE-ABS1-VMCC-1010:PRESSURE', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: true
softwareTrigger: false
base_config:
- !include ./pxiii-devices-new.yaml
sldi_cenx:
description: FE slit-diaphragm horizontal center
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERX'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
sldi_sizex:
description: FE slit-diaphragm horizontal size
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:SIZEX'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
sldi_ceny:
description: FE slit-diaphragm vertical center
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
sldi_sizey:
description: FE slit-diaphragm vertical size
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:SIZEY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
fecmi_try:
description: FE collimating mirror try
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-MI1:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
fecmi_pitch:
description: FE collimating mirror pitch
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-MI1:PITCH'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
fecmi_bend:
description: FE collimating mirror bend
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-MI1:BEND1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
slh_press:
description: OP slit pressure
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-SLH-VMFR-1010:PRESSURE', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
slh_trxr:
description: OP slit inner blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
slh_trxw:
description: OP slit outer blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
fi1_try:
description: Beam attenuator motion before mono
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-FI1:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_theta1:
description: Monochromator pitch 1
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:THETA1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_diode_top:
description: Top diode between mono crystals
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XPM1:TOP:READOUT', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_diode_bottom:
description: Bottom diode between mono crystals
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XPM1:BOT:READOUT', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_theta2:
description: Monochromator pitch 2
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:THETA2'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_xbpm:
description: XBPM total intensity after monochromator
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XBPM1:SumAll:MeanValue_RBV', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_energy:
description: Monochromator energy
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:ENERGY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_eoffset:
description: Monochromator energy offset
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:EOFFSET'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm_trx:
description: XBPM motion before secondary source
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRX1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm_try:
description: XBPM motion before secondary source
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm:
description: XBPM before secondary source
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-SSBPM1:SumAll:MeanValue_RBV'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
ssslit_trxr:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_trxw:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_tryt:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_tryb:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYB'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxi1_trx:
description: Secondary source diagnostic screen motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSXI1:TRX1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxi1_try:
description: Secondary source diagnostic screen motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSXI1:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRXU'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRXD'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
# vfm_tryuw:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-VFM:TRYUW'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# vfm_tryr:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-VFM:TRYR'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# vfm_trydw:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-VFM:TRYDW'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
vfm_pitch:
description: KB mirror vertical steering
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:PITCH'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:YAW'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:ROLL'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRX'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRXU'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRXD'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
# hfm_tryur:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-HFM:TRYUR'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# hfm_tryw:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-HFM:TRYW'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# hfm_trydr:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-HFM:TRYDR'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
hfm_pitch:
description: KB mirror horizontal steering
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:PITCH'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:YAW'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:ROLL'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRX'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
# xbox_xbpm:
# description: Exposure box XBPM
# deviceClass: ophyd.EpicsSignalRO
# deviceConfig: {read_pv: 'X06DA-ES-XBBPM1:SumAll:MeanValue_RBV'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: true
# softwareTrigger: false
xbox_fil1:
description: Exposure box filter wheel 1
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI1:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_fil2:
description: Exposure box filter wheel 2
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI2:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_fil3:
description: Exposure box filter wheel 3
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI3:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_fil4:
description: Exposure box filter wheel 4
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI4:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_diode:
description: Exposure box diode
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DI1:READOUT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
gonpos:
description: Sample sensor distance
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DF1:CBOX-USER1', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
gonvalid:
description: Sample in valid distance
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DF1:CBOX-CMP1', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
samzoom:
description: Sample microscope zoom
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SAMCAM:ZOOM'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
samcam:
description: Sample camera aggregate device
deviceClass: pxiii_bec.devices.SamCamDetector
deviceConfig: {prefix: 'X06DA-SAMCAM:'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
samstream:
description: Sample camera ZMQ stream
deviceClass: pxiii_bec.devices.StdDaqPreviewDetector
deviceConfig:
url: 'tcp://129.129.110.12:9089'
deviceTags:
- detector
enabled: true
readoutPriority: async
readOnly: false
softwareTrigger: false
# samimg:
# description: Sample camera image from EPICS
# deviceClass: pxiii_bec.devices.NDArrayPreview
# deviceConfig:
# prefix: 'X06DA-SAMCAM:image1:'
# deviceTags:
# - detector
# enabled: true
# readoutPriority: async
# readOnly: false
# softwareTrigger: false
bstop_pneum:
description: Beamstop pneumatic in-out
deviceClass: ophyd.EpicsSignal
deviceConfig: {read_pv: 'X06DA-ES-BS:GET-POS', write_pv: 'X06DA-ES-BS:SET-POS'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_x:
description: Beamstop translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-BS:TRX1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_y:
description: Beamstop translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-BS:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_z:
description: Beamstop translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-BS:TRZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_pneum:
description: Beamstop pneumatic
deviceClass: pxiii_bec.devices.PneumaticValve
deviceConfig: {read_pv: 'X06DA-ES-BS:GET-POS', write_pv: 'X06DA-ES-BS:SET-POS', kind: 'config', auto_monitor: true, put_complete: true}
onFailure: buffer
enabled: true
readoutPriority: baseline
readOnly: false
softwareTrigger: false
bstop_diode:
description: Beamstop diode
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-BS:READOUT', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
frontlight:
description: Microscope frontlight
deviceClass: ophyd.EpicsSignal
deviceConfig: {read_pv: 'X06DA-ES-FL:SET-BRGHT', kind: 'config', put_complete: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
backlight:
description: Backlight reflector
deviceClass: pxiii_bec.devices.PneumaticValve
deviceConfig: {read_pv: 'X06DA-ES-BL:GET-POS', write_pv: 'X06DA-ES-BL:SET-POS', kind: 'config', auto_monitor: true, put_complete: true}
onFailure: buffer
enabled: true
readoutPriority: baseline
readOnly: false
softwareTrigger: false
gmx:
description: ABR horizontal stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:GMX', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
gmy:
description: ABR vertical stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:GMY', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
gmz:
description: ABR axial stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:GMZ', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
omega:
description: ABR rotation stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:OMEGA', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
abr:
description: Aerotech ABR motion system
deviceClass: pxiii_bec.devices.AerotechAbrStage
deviceConfig: {prefix: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
shx:
description: SmarGon X axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: -2, high_limit: 2, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
shy:
description: SmarGon Y axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: -2, high_limit: 2, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
shz:
description: SmarGon Z axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: 10, high_limit: 22, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
chi:
description: SmarGon CHI axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: 0, high_limit: 40, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
phi:
description: SmarGon PHI axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
det_y:
description: Pilatus height
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-DET:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
det_z:
description: Pilatus translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-DET:TRZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
@@ -0,0 +1,757 @@
sls_current:
description: sls current
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'ARS07-DPCT-0100:CURR', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: true
softwareTrigger: false
vg0_press:
description: VG0 pressure
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-FE-VMCC-0000:PRESSURE', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: true
softwareTrigger: false
abs_press:
description: Absorber pressure
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-FE-ABS1-VMCC-1010:PRESSURE', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: true
softwareTrigger: false
sldi_cenx:
description: FE slit-diaphragm horizontal center
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERX'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
sldi_sizex:
description: FE slit-diaphragm horizontal size
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:SIZEX'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
sldi_ceny:
description: FE slit-diaphragm vertical center
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
sldi_sizey:
description: FE slit-diaphragm vertical size
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-SLDI:SIZEY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
fecmi_try:
description: FE collimating mirror try
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-MI1:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
fecmi_pitch:
description: FE collimating mirror pitch
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-MI1:PITCH'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
fecmi_bend:
description: FE collimating mirror bend
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-FE-MI1:BEND1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
deviceTags:
- fe
readOnly: false
softwareTrigger: false
slh_press:
description: OP slit pressure
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-SLH-VMFR-1010:PRESSURE', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
slh_trxr:
description: OP slit inner blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
slh_trxw:
description: OP slit outer blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
fi1_try:
description: Beam attenuator motion before mono
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-FI1:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_theta1:
description: Monochromator pitch 1
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:THETA1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_diode_top:
description: Top diode between mono crystals
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XPM1:TOP:READOUT', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_diode_bottom:
description: Bottom diode between mono crystals
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XPM1:BOT:READOUT', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_theta2:
description: Monochromator pitch 2
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:THETA2'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_xbpm:
description: XBPM total intensity after monochromator
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-OP-XBPM1:SumAll:MeanValue_RBV', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
dccm_energy:
description: Monochromator energy
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:ENERGY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
dccm_eoffset:
description: Monochromator energy offset
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:EOFFSET'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm_trx:
description: XBPM motion before secondary source
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRX1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm_try:
description: XBPM motion before secondary source
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxbpm:
description: XBPM before secondary source
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-SSBPM1:SumAll:MeanValue_RBV'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
ssslit_trxr:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXR'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_trxw:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXW'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_tryt:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssslit_tryb:
description: Secondary source blade motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYB'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxi1_trx:
description: Secondary source diagnostic screen motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSXI1:TRX1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
ssxi1_try:
description: Secondary source diagnostic screen motion
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSXI1:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRXU'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRXD'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
# vfm_tryuw:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-VFM:TRYUW'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# vfm_tryr:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-VFM:TRYR'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# vfm_trydw:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-VFM:TRYDW'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
vfm_pitch:
description: KB mirror vertical steering
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:PITCH'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:YAW'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:ROLL'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRX'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
vfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-VFM:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trxu:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRXU'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trxd:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRXD'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
# hfm_tryur:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-HFM:TRYUR'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# hfm_tryw:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-HFM:TRYW'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
# hfm_trydr:
# deviceClass: ophyd.EpicsMotor
# deviceConfig: {prefix: 'X06DA-ES-HFM:TRYDR'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: false
# softwareTrigger: false
hfm_pitch:
description: KB mirror horizontal steering
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:PITCH'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_yaw:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:YAW'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_roll:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:ROLL'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_trx:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRX'}
enabled: false
onFailure: buffer
readoutPriority: monitored
readOnly: false
softwareTrigger: false
hfm_try:
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-HFM:TRY'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
# xbox_xbpm:
# description: Exposure box XBPM
# deviceClass: ophyd.EpicsSignalRO
# deviceConfig: {read_pv: 'X06DA-ES-XBBPM1:SumAll:MeanValue_RBV'}
# onFailure: buffer
# enabled: true
# readoutPriority: monitored
# readOnly: true
# softwareTrigger: false
xbox_fil1:
description: Exposure box filter wheel 1
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI1:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_fil2:
description: Exposure box filter wheel 2
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI2:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_fil3:
description: Exposure box filter wheel 3
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI3:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_fil4:
description: Exposure box filter wheel 4
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-FI4:ROZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
xbox_diode:
description: Exposure box diode
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DI1:READOUT'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
gonpos:
description: Sample sensor distance
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DF1:CBOX-USER1', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
gonvalid:
description: Sample in valid distance
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-DF1:CBOX-CMP1', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
samzoom:
description: Sample microscope zoom
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SAMCAM:ZOOM'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
samcam:
description: Sample camera aggregate device
deviceClass: pxiii_bec.devices.SamCamDetector
deviceConfig: {prefix: 'X06DA-SAMCAM:'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
samstream:
description: Sample camera ZMQ stream
deviceClass: pxiii_bec.devices.StdDaqPreviewDetector
deviceConfig:
url: 'tcp://129.129.110.12:9089'
deviceTags:
- detector
enabled: true
readoutPriority: async
readOnly: false
softwareTrigger: false
# samimg:
# description: Sample camera image from EPICS
# deviceClass: pxiii_bec.devices.NDArrayPreview
# deviceConfig:
# prefix: 'X06DA-SAMCAM:image1:'
# deviceTags:
# - detector
# enabled: true
# readoutPriority: async
# readOnly: false
# softwareTrigger: false
bstop_pneum:
description: Beamstop pneumatic in-out
deviceClass: ophyd.EpicsSignal
deviceConfig: {read_pv: 'X06DA-ES-BS:GET-POS', write_pv: 'X06DA-ES-BS:SET-POS'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_x:
description: Beamstop translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-BS:TRX1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_y:
description: Beamstop translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-BS:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_z:
description: Beamstop translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-BS:TRZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
bstop_pneum:
description: Beamstop pneumatic
deviceClass: pxiii_bec.devices.PneumaticValve
deviceConfig: {read_pv: 'X06DA-ES-BS:GET-POS', write_pv: 'X06DA-ES-BS:SET-POS', kind: 'config', auto_monitor: true, put_complete: true}
onFailure: buffer
enabled: true
readoutPriority: baseline
readOnly: false
softwareTrigger: false
bstop_diode:
description: Beamstop diode
deviceClass: ophyd.EpicsSignalRO
deviceConfig: {read_pv: 'X06DA-ES-BS:READOUT', auto_monitor: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: true
softwareTrigger: false
frontlight:
description: Microscope frontlight
deviceClass: ophyd.EpicsSignal
deviceConfig: {read_pv: 'X06DA-ES-FL:SET-BRGHT', kind: 'config', put_complete: true}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
backlight:
description: Backlight reflector
deviceClass: pxiii_bec.devices.PneumaticValve
deviceConfig: {read_pv: 'X06DA-ES-BL:GET-POS', write_pv: 'X06DA-ES-BL:SET-POS', kind: 'config', auto_monitor: true, put_complete: true}
onFailure: buffer
enabled: true
readoutPriority: baseline
readOnly: false
softwareTrigger: false
gmx:
description: ABR horizontal stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:GMX', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
gmy:
description: ABR vertical stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:GMY', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
gmz:
description: ABR axial stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:GMZ', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
omega:
description: ABR rotation stage
deviceClass: pxiii_bec.devices.A3200Axis
deviceConfig: {prefix: 'X06DA-ES-DF1:OMEGA', base_pv: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
abr:
description: Aerotech ABR motion system
deviceClass: pxiii_bec.devices.AerotechAbrStage
deviceConfig: {prefix: 'X06DA-ES'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
shx:
description: SmarGon X axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: -2, high_limit: 2, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
shy:
description: SmarGon Y axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: -2, high_limit: 2, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
shz:
description: SmarGon Z axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: 10, high_limit: 22, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
chi:
description: SmarGon CHI axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', low_limit: 0, high_limit: 40, sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
phi:
description: SmarGon PHI axis
deviceClass: pxiii_bec.devices.SmarGonAxisB
deviceConfig: {prefix: 'SCS', sg_url: 'http://x06da-smargopolo.psi.ch:3000'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
det_y:
description: Pilatus height
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-DET:TRY1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
det_z:
description: Pilatus translation
deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-DET:TRZ1'}
onFailure: buffer
enabled: true
readoutPriority: monitored
readOnly: false
softwareTrigger: false
+6
View 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 pxiii_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
View File
+355
View File
@@ -0,0 +1,355 @@
"""Utility functions for calculating energy, wavelength, and Bragg angle."""
from dataclasses import dataclass
import numpy as np
# from pxii_parameters import (EnergyDefaults, CamConversion)
@dataclass(frozen=True)
class Constants:
"""Constants used in energy calculations"""
# # Physical Constants from https://physics.nist.gov/cuu/Constants/index.html
ANGSTROM_CONVERSION = 1e10 # Convert meters to angstrom
PLANCK_CONST_EV = 4.135667696e-15 # eV/Hz
SPEED_OF_LIGHT = 299792458 # m/s
# d-spacings
d_spacing = {120: 3.13481, 298: 3.13562}
def speed_of_light_ang():
"""
Calculate the speed of light in angstroms per second.
Returns:
float: The speed of light converted to angstroms per second.
"""
return Constants.SPEED_OF_LIGHT * Constants.ANGSTROM_CONVERSION
def en_wav_factor():
"""
Calculate the energy wavelength factor.
This function computes a constant factor used to calculate energy
values in relation to wavelength by combining Planck's constant,
in eV/Hz, and the speed of light in angstrom.
Returns:
float: The computed energy wavelength factor.
"""
return Constants.PLANCK_CONST_EV * speed_of_light_ang()
# Helper Functions
def convert_to_degrees(angle_mrad: float) -> float:
"""
Convert an angle from milliradians to degrees.
Args:
angle_mrad: The angle value in milliradians.
Returns:
The angle converted into degrees as a float.
"""
return np.rad2deg(angle_mrad / 1000)
def create_conversion_result(
energy_ev: float, wavelength: float, bragg_angle_mrad: float
) -> dict:
"""
Creates a dictionary containing converted values of energy and angles.
This function takes the energy in electron-volts, the wavelength,
and the Bragg angle in milliradians as input. It computes and
returns a dictionary containing the energy in both electron-volts
and kiloelectron-volts, the wavelength, the Bragg angle in milliradians,
and the Bragg angle converted to degrees.
Args:
energy_ev: Energy value in electron-volts.
wavelength: Wavelength value.
bragg_angle_mrad: Bragg angle in milliradians.
Returns:
dict: A dictionary containing the following keys:
- "energy_kev": Energy value in kiloelectron-volts.
- "energy_ev": Energy value in electron-volts.
- "wavelength": Wavelength value.
- "bragg_angle_mrad": Bragg angle in milliradians.
- "bragg_angle_deg": Bragg angle in degrees.
"""
return {
"energy_kev": energy_ev / 1000,
"energy_ev": energy_ev,
"wavelength": wavelength,
"bragg_angle_mrad": float(bragg_angle_mrad),
"bragg_angle_deg": float(convert_to_degrees(bragg_angle_mrad)),
}
def print_conversion_result(result: dict) -> None:
"""
Prints the energy-related conversion results to the console.
"""
line = (
f"energy: {result['energy_ev']:.6g} eV, energy: {result['energy_kev']:.6g} keV, "
f"wavelength: {result['wavelength']:.4g} Å, "
f"bragg angle: {result['bragg_angle_mrad']:.5g} mrad, {result['bragg_angle_deg']:.4g} deg"
)
print(line)
# Conversion Functions
def calculate_wavelength_from_angle(bragg_angle_mrad: float, temp=120) -> float:
"""
calculate_wavelength_from_angle(bragg_angle_mrad: float) -> float
Arguments:
bragg_angle_mrad: The Bragg angle in milliradians, used to compute the
sine value required for the wavelength calculation.
Returns:
The calculated wavelength as a float value.
"""
d = Constants.d_spacing[temp]
return 2 * d * np.sin(bragg_angle_mrad / 1000)
def calculate_energy_from_wavelength(wavelength: float) -> float:
"""
Calculates the energy of a photon based on its wavelength.
Args:
wavelength: The wavelength of the photon in angstrom.
Returns:
The energy of the photon in eV.
"""
return en_wav_factor() / wavelength
def calculate_wavelength_from_energy(energy_ev: float) -> float:
"""
Calculates the wavelength of a photon from its energy.
Arguments:
energy_ev: float
The energy of the photon in electronvolts (eV).
Returns:
float
The calculated wavelength of the photon in angstrom.
"""
return en_wav_factor() / energy_ev
def calculate_bragg_angle_from_wavelength(wavelength: float, temp=120) -> float:
"""
Calculate the Bragg angle in milliradians for a given wavelength.
Args:
wavelength: The wavelength in angstrom.
Returns:
The Bragg angle in milliradians as a float.
"""
d = Constants.d_spacing[temp]
angle_rad = np.arcsin(wavelength / (2 * d))
return angle_rad * 1000
def convert_input_angle_to_mrad(bragg_angle: float) -> float:
"""
Convert input angle into milliradians (mrad).
This function takes an angle as input and determines its likely unit,
converting it to milliradians (mrad) if necessary. If the input value
is less than 1, it is assumed to be in radians and is converted to
mrad. If the input value falls between predefined minimum and
maximum values for mrad, it is assumed to be in degrees and thus
converted to mrad using the degrees-to-radians conversion factor.
For input values that don't match these scenarios, it assumes
that the input is already in mrad and returns it unchanged.
Arguments:
bragg_angle (float): The input Bragg angle, which can be in
radians, degrees, or milliradians.
Returns:
float: The Bragg angle converted into milliradians (mrad).
"""
if bragg_angle < 1: # Likely the input angle is in radians
return bragg_angle * 1000
if 3 < bragg_angle < 25: # Likely input angle is in degrees
return np.deg2rad(bragg_angle) * 1000
return bragg_angle # Already in mrad
# Core Functions
def validate_energy(energy_ev):
"""
Validates the energy value to ensure it falls within the acceptable range. The function
converts the provided energy from keV to eV if the input value is less than 1/1000 of the
maximum energy value. It then checks whether the energy is within the defined bounds.
If the energy value is outside the acceptable range, the function raises a ValueError.
Args:
energy_ev (float): The energy value in eV or keV to be validated. If this value is
smaller than 1/1000 of the maximum allowed energy (in eV), it will be multiplied
by 1000 to convert it from keV to eV.
Returns:
float: The validated energy value in eV that falls within the acceptable range.
Raises:
ValueError: If the energy value is outside the defined range of
[MIN_ENERGY_EV, MAX_ENERGY_EV].
"""
if energy_ev < EnergyDefaults.max_energy_ev / 1000: # Assuming the input is in keV.
energy_ev *= 1000
if not EnergyDefaults.min_energy_ev <= energy_ev <= EnergyDefaults.max_energy_ev:
raise ValueError(
f"Energy of {energy_ev} eV is outside the valid range "
f"({EnergyDefaults.min_energy_ev} eV to {EnergyDefaults.max_energy_ev} eV)"
)
return energy_ev
def convert_from_bragg(
bragg_angle_mrad: float, temp=120, print_result: bool = False
) -> dict:
"""
Convert the Bragg angle to wavelength and energy, returning the result as a dictionary.
This function converts a given Bragg angle (in milliradians) into the corresponding
wavelength and energy values, and returns them in a dictionary format. The function
also supports optional printing of the calculated results.
Args:
bragg_angle_mrad (float): The Bragg angle in milliradians to be converted.
print_result (bool): Whether to print the conversion result. Defaults to False.
Returns:
dict: A dictionary containing the following keys:
- 'energy_ev': Energy in electronvolts.
- 'wavelength': Wavelength corresponding to the input angle.
- 'bragg_angle_mrad': Input Bragg angle in milliradians.
"""
bragg_angle_mrad = convert_input_angle_to_mrad(bragg_angle_mrad)
wavelength = float(calculate_wavelength_from_angle(bragg_angle_mrad, temp=temp))
energy_ev = float(calculate_energy_from_wavelength(wavelength))
result = create_conversion_result(energy_ev, wavelength, bragg_angle_mrad)
if print_result:
print_conversion_result(result)
return result
def convert_from_energy(energy_ev: float, temp=120, print_result: bool = False) -> dict:
"""
Convert energy in electron volts (eV) to wavelength and Bragg angle in milliradians
(mrad). This method validates the given energy, calculates corresponding properties,
and optionally prints the result.
Args:
energy_ev: Energy value in electron volts (float) to be converted.
print_result: Flag indicating whether to print the resulting
conversion details (bool). Defaults to False.
Returns:
A dictionary containing the following key-value pairs:
- "energy_ev" (float): Validated energy in eV.
- "wavelength" (float): Calculated wavelength in meters.
- "bragg_angle_mrad" (float): Calculated Bragg angle in mrad.
"""
energy_ev = validate_energy(energy_ev)
wavelength = calculate_wavelength_from_energy(energy_ev)
bragg_angle_mrad = float(
calculate_bragg_angle_from_wavelength(wavelength, temp=temp)
)
result = create_conversion_result(energy_ev, wavelength, bragg_angle_mrad)
if print_result:
print_conversion_result(result)
return result
def convert_from_wavelength(
wavelength: float,
temp: float = 120,
print_result: bool = False,
) -> dict:
"""
Convert a given wavelength value into corresponding energy, Bragg angle, and
generate a result dictionary.
The function processes a wavelength value, checks its validity against a
permitted range, calculates corresponding energy and Bragg angle, and
formats the results into a dictionary. Optionally, the function can print
the result.
Parameters:
wavelength: float
The input wavelength value in Angstroms to be converted. Should
fall within the permitted wavelength range.
print_result: bool
Optional flag indicating whether to print the conversion result.
Default is False.
Returns:
dict
A dictionary containing the energy (electron-volts), wavelength
(Angstroms), and Bragg angle (milliradians). If the wavelength is
outside of the permitted range, returns None.
"""
energy_ev = calculate_energy_from_wavelength(wavelength)
bragg_angle_mrad = float(
calculate_bragg_angle_from_wavelength(wavelength, temp=temp)
)
result = create_conversion_result(energy_ev, wavelength, bragg_angle_mrad)
if print_result:
print_conversion_result(result)
return result
def calc_perp_position(
energy_ev: float,
print_result: bool = False,
) -> float:
"""
Calculate the perpendicular motor position based on provided energy in electron-volts (eV).
This function computes the perpendicular motor position using the given energy value in
electron-volts. The calculation is based on the Bragg angle derived from the energy. An optional
parameter allows printing the result during execution.
Parameters:
energy_ev (float): The energy value in electron-volts used for the calculation.
print_result (bool): Flag to determine whether to print the computed perpendicular offset.
Default is False.
Returns:
float: The computed perpendicular position.
Raises:
None
"""
result = convert_from_energy(energy_ev, print_result=False)
bragg_angle_rad = result["bragg_angle_mrad"] / 1000
perp_offset = float(EnergyDefaults.beam_offset / (2 * np.cos(bragg_angle_rad))) - 3
if print_result:
print(f"Perp = {perp_offset: .4f}")
return perp_offset
def calc_scam_microns(pixels, zoom=1000):
"""Convert pixels to microns for the sample camera"""
return float(pixels / (CamConversion.a * np.exp(CamConversion.b * zoom)))
def calc_bsccam_microns(pixels):
"""Convert pixels to microns for the BSC camera"""
return pixels*20
+252
View File
@@ -0,0 +1,252 @@
"""Get data from an h5 file or BEC history and perform fitting."""
import numpy as np
from lmfit.models import (
GaussianModel,
LorentzianModel,
VoigtModel,
ConstantModel,
LinearModel,
)
from scipy.ndimage import gaussian_filter1d
import h5py
import matplotlib.pyplot as plt
def create_fit_parameters(
deriv: bool = False,
model: str = "Voigt",
baseline: str = "Linear",
smoothing: None = None,
):
"""Store the fit parameters in a dictionary."""
# map input model to lmfit model name
model_mappings = {
"Gaussian": GaussianModel,
"Lorentzian": LorentzianModel,
"Voigt": VoigtModel,
"Constant": ConstantModel,
"Linear": LinearModel,
}
return {
"deriv": deriv,
"model": model_mappings[model],
"baseline": model_mappings[baseline],
"smoothing": smoothing,
}
def get_data_from_h5(signal_name: str = "lu_bpmsum"):
"""Get data from an h5 file."""
with h5py.File("scan_676.h5", "r") as f:
entry = f["entry"]["collection"]
y_data = entry["devices"][signal_name][signal_name]["value"][:]
motor_data = entry["metadata"]["bec"]
motor_name = motor_data["scan_motors"][0].decode()
scan_number = motor_data["scan_number"][()]
x_data = entry["devices"][motor_name][motor_name]["value"][:]
return {
"x_data": x_data,
"y_data": y_data,
"signal_name": signal_name,
"motor_name": motor_name,
"scan_number": str(scan_number),
}
def get_data_from_history(
history_index: int,
signal_name: str = "lu_bpmsum",
):
"""Read data from the BEC history and return the X and Y data as arrays."""
scan = bec.history[history_index]
md = scan.metadata["bec"]
motor_name = md["scan_report_devices"][0].decode()
scan_number = md["scan_number"]
x_data = scan.devices[motor_name][motor_name].read()["value"]
y_data = scan.devices[signal_name][signal_name].read()["value"]
return {
"signal_name": signal_name,
"x_data": x_data,
"y_data": y_data,
"motor_name": motor_name,
"scan_number": scan_number,
}
def process_data(data, fit_params):
"""
Process the signal data for fitting based on derivative or smoothing.
"""
smoothing, deriv = fit_params["smoothing"], fit_params["deriv"]
signal_name = data["signal_name"]
y_data = data["y_data"]
if deriv:
if smoothing:
y_smooth = gaussian_filter1d(y_data, smoothing)
fitting_data = np.gradient(y_smooth)
signal_name = f"Derivative of smoothed {signal_name}"
else:
fitting_data = np.gradient(y_data)
signal_name = f"Derivative of {signal_name}"
elif smoothing and smoothing > 0.01:
fitting_data = gaussian_filter1d(y_data, smoothing)
signal_name = f"Smoothed {signal_name}"
else:
fitting_data = y_data
updated_data = {
"y_to_fit": fitting_data,
"signal_name": signal_name,
}
data.update(updated_data)
return data
def fit(data, fit_params):
"""Fit a signal to a model and return the fitting results."""
# Create the model
peak_model = fit_params["model"](prefix="peak_")
baseline_model = fit_params["baseline"](prefix="base_")
full_model = peak_model + baseline_model
# Prepare data
processed_data = process_data(data, fit_params)
params = full_model.make_params()
y_min = np.min(processed_data["y_to_fit"])
# Configure baseline parameters
if fit_params["baseline"] == ConstantModel:
params["base_c"].set(value=y_min)
elif fit_params["baseline"] == LinearModel:
params["base_intercept"].set(value=y_min)
params["base_slope"].set(value=0)
# Add peak-specific parameters
params.update(
peak_model.guess(processed_data["y_to_fit"], x=processed_data["x_data"])
)
# Perform the fitting
lmfit_result = full_model.fit(
processed_data["y_to_fit"], params, x=processed_data["x_data"]
)
# Find the X that gives the max Y
max_index = np.argmax(processed_data["y_to_fit"])
x_max = processed_data["x_data"][max_index]
# Generate data for a smoothed fit curve
fit_xdata = np.linspace(np.min(data["x_data"]), np.max(data["x_data"]), 500)
fit_ydata = lmfit_result.eval(x=fit_xdata, params=lmfit_result.params)
# Collect results
return {
"model": fit_params["model"].__name__,
"fwhm": lmfit_result.params["peak_fwhm"].value,
"centre": lmfit_result.best_values["peak_center"],
"height": lmfit_result.params["peak_height"].value,
"chi_sq": lmfit_result.chisqr,
"lmfit_result": lmfit_result,
"x_max": x_max,
"fit_xdata": fit_xdata,
"fit_ydata": fit_ydata,
}
def plot_fitted_data(data, fit_result):
"""Plot the original data and the fitted model."""
plt.plot(data["x_data"], data["y_to_fit"], label="Data")
plt.plot(fit_result['fit_xdata'], fit_result['fit_ydata'], label="Fit")
plt.xlabel(data["motor_name"])
plt.ylabel(data["signal_name"])
plt.title(f"Scan {data['scan_number']}, fitted with {fit_result['model']}")
plt.grid(True)
plt.legend()
plt.show()
def select_bec_window(dock_area_name="Fitting"):
"""Check to see if the fitting results dock is already open and re-create it if not"""
open_docks = bec.gui.windows
if open_docks.get(dock_area_name) is None:
dock_area = bec.gui.new(dock_area_name)
# wf = dock_area.new("Plot").new(bec.gui.available_widgets.Waveform)
wf = dock_area.new(widget='Waveform', object_name='Plot')
text_box = dock_area.new(widget='TextBox', object_name="Results", where="bottom")
else:
wf = bec.gui.Fitting.Plot
text_box = bec.gui.Fitting.Results
return wf, text_box
def plot_live_data_bec(
motor_name,
signal_name,
window_name="Fitting"
):
"""
Plotting live data for motor and signal using BEC.
This function plots live data from a specified motor and signal.
It clears the current plot window, sets its title, labels the axes
with the provided motor and signal names, and initializes live plotting
on the given signal against the motor.
Args:
motor_name (str): The name of the motor to be used as the x-axis.
signal_name (str): The name of the signal to be used as the y-axis.
Returns:
None
"""
wf, text_box = select_bec_window(window_name)
text_box.set_plain_text("Plotting live data")
wf.clear_all()
wf.title = "Scan: Live scan"
wf.x_label = motor_name
wf.y_label = signal_name
wf.plot(device_x=motor_name, device_y=signal_name)
def plot_fitted_data_bec(
data,
fit_result,
):
"""
Plot fitted data and display fitting parameters in the specified window.
This function selects a BEC window and plots the original data along with the
fitted function. Additionally, it displays the fitting results in a text
box within the same window for better visualization of the fit results.
Parameters:
data : dict
Dictionary containing the original dataset, where 'x_data' and 'y_to_fit'
hold the independent variable and the dependent variable, respectively,
'scan_number' represents the scan number, 'motor_name' and 'signal_name'
provide axis labels.
fit_result : dict
Dictionary containing the results of the fit, including parameters such
as 'centre', 'fwhm', 'height', and the fitted model stored under
'lmfit_result', with its 'best_fit' attribute representing the fitted data.
"""
wf, text_box = select_bec_window()
fit_text = (
f"Fit parameters: Centre = {fit_result['centre']:.4f}, "
f"FWHM = {fit_result['fwhm']:.3f}, "
f"Height = {fit_result['height']:.4f}\n"
f"Model = {fit_result['model']}\n"
f"Chi sq = {fit_result['chi_sq']:.3g}"
)
text_box.set_plain_text(fit_text)
wf.clear_all()
wf.title = f"Scan: {data['scan_number']}"
wf.x_label = data["motor_name"]
wf.y_label = data["signal_name"]
wf.plot(x=data["x_data"], y=data["y_to_fit"], label="Data")
wf.plot(x=fit_result["fit_xdata"], y=fit_result["fit_ydata"], label="Fit")
# wf.Fit.set(symbol_size = 0)
wf.get_curve('Fit').set(symbol_size=0)
+312
View File
@@ -0,0 +1,312 @@
"""Use the methods in mx_basics to perform:
1) a go_to_peak scan, that scans a motor, finds the peak position and moves to peak
2) fits data from a bec history file
"""
from dataclasses import dataclass
import numpy as np
# from pxiii_parameters import FitDefaults, BPMScans, MirrorConfig
# from mx_basics import (
# create_fit_parameters,
# get_data_from_history,
# fit,
# plot_fitted_data_bec,
# plot_live_data_bec,
# )
# Method functions
def calculate_step_size(start: float, stop: float, steps: int) -> float:
"""
Provides the function to calculate the step size for dividing a specified range
into a given number of steps.
Args:
start: The starting value of the range.
stop: The stopping value of the range.
steps: The number of steps to divide the range into. Must be at least 1.
Raises:
ValueError: If the steps value is less than 1.
Returns:
The calculated step size as a float, rounded to three decimal places.
"""
if steps < 1:
raise ValueError("Number of steps must be at least 1.")
return round((stop - start) / steps, 3)
def move_to_position(motor_device, motor_name: str, position: float, data: dict):
"""
Function to move a specified motor device to a given position.
The function verifies if the requested position is within the scan range of the
motor device provided. If the position is outside the range, the motor is
moved to the center of its scan range, an error message is raised, and the
operation is halted. If the position is valid, the motor is moved to the
specified position.
Parameters:
motor_device: The motor device to be moved.
motor_name: str
The name of the motor as a string
position: float
The desired position to move the motor to. Position should be within
the scan range of the motor determined by the provided data.
data: dict
A dictionary containing "x_data", which is used to determine the
scan range of the motor.
Raises:
ValueError: Raised if the specified position is outside the valid scan
range determined by "x_data" in the data dictionary. The motor will
return to the center of its scan range in this case.
"""
motor_min = np.min(data["x_data"])
motor_max = np.max(data["x_data"])
motor_centre = (motor_max + motor_min) / 2
if not motor_min <= position <= motor_max:
scans.umv(motor_device, motor_centre, relative=False)
msg = (
f"Position {position: .2f} is outside the scan range of "
f"{motor_min: .2f} to {motor_max: .2f}. "
f"Returning to centre of scan range {motor_centre: .3f}."
)
raise ValueError(msg)
motor_position = round(position, 4)
scans.umv(motor_device, motor_position, relative=False)
print(f"\n Moving {motor_name} to position {motor_position: .3f}")
def go_to_peak(
motor_device,
signal_device,
start: float,
stop: float,
steps: int,
relative: bool = FitDefaults.RELATIVE_MODE,
plot: bool = True,
settle: float = FitDefaults.SETTLE_TIME,
confirm: bool = True,
gomax: bool = False,
):
"""
Go to the peak of a signal by scanning a motor within a specified range and
identifying the optimal position based on signal peak data.
Parameters:
motor_device: The motor device to be scanned.
signal_device: The signal device to monitor during the scan.
start (float): The starting position of the scan. Ignored if `relative` is True.
stop (float): The ending position of the scan. Ignored if `relative` is True.
steps (int): The number of steps to divide the scan range into.
relative (bool, optional): If True, interpret `start` and `stop` as relative to
the current motor position. Defaults to RELATIVE_MODE constant.
plot (bool, optional): If True, plot the scan data and the fitted results.
Defaults to True.
settle (float, optional): The time in seconds to wait after each step for the
signal to stabilize. Defaults to DEFAULT_SETTLE_TIME constant.
confirm (bool, optional): If True, ask for user confirmation before starting
the scan. Defaults to True.
Raises:
Exception: Raises exceptions potentially raised by dependent functions or
operations such as plotting, fitting, or motor movement.
Returns:
None
"""
motor_name = motor_device.name
signal_name = signal_device.name
# wf.plot(x_name=motor_name, y_name=signal_name)
if plot:
plot_live_data_bec(motor_name, signal_name)
# Validate and calculate step size
step_size = calculate_step_size(start, stop, steps)
# Confirm the scan range
# current_motor_position = motor_device.user_readback.get()
current_motor_position = motor_device.read()[motor_name]["value"]
if confirm:
if relative:
scan_start = current_motor_position + start
scan_end = current_motor_position + stop
print(
f"\nScanning from {scan_start: .6g} to {scan_end: .6g} in "
f"{steps} steps of size {step_size}"
)
print(f"Relative mode = {relative}")
else:
print(
f"\nScanning from {start: .5g} to {stop: .5g} in {steps} steps of size {step_size}"
)
print(f"Relative mode = {relative}")
input("Press Enter to continue...")
# Perform the scan
scan_result = scans.line_scan(
motor_device, start, stop, steps=steps, relative=relative, settling_time=settle
)
motor_data = scan_result.scan.live_data[motor_name][motor_name].val
signal_data = scan_result.scan.live_data[signal_name][signal_name].val
scan_number = "Current"
data = {
"x_data": np.array(motor_data),
"y_data": np.array(signal_data),
"motor_name": motor_name,
"signal_name": signal_name,
"motor_device": motor_device,
"scan_number": scan_number,
}
# Define and fit model to scan data
fit_params = create_fit_parameters(False, FitDefaults.MODEL, FitDefaults.BASELINE)
fit_result = fit(data, fit_params)
# Plot the fitted data if plot = True
if plot:
plot_fitted_data_bec(data, fit_result)
# If gomax is set then move to the maximum value, rather than the fit centre
if gomax:
value = fit_result["x_max"]
print(f"Max position is at {value}")
move_to_position(data["motor_device"], data["motor_name"], fit_result["x_max"], data)
else:
# Safely move the motor to the peak position
move_to_position(data["motor_device"], data["motor_name"], fit_result["centre"], data)
def fit_history(
history_index: int,
signal_name: str,
deriv: bool = False,
model: str = FitDefaults.MODEL,
move_to_peak: bool = False,
):
"""
Retrieve and analyze historical data by fitting a model, optionally moving to
a peak position.
Parameters:
history_index (int): Index of the historical data set to retrieve.
signal_name (str): Name of the signal to fit.
deriv (bool, optional): Whether to include the derivative in the fitting
procedure. Defaults to False.
model (str, optional): Name of the model to use for fitting. Defaults to
DEFAULT_MODEL.
move_to_peak (bool, optional): Whether to move the motor to the peak position
after fitting. Defaults to False.
Raises:
KeyError: If required keys are not found in the retrieved data dictionary.
ValueError: If the fitting process fails or produces invalid results.
Returns:
None
"""
# Retrieve historical data
data = get_data_from_history(history_index, signal_name)
# Define fitting parameters
fit_params = create_fit_parameters(deriv, model, FitDefaults.BASELINE)
# Perform fit and plot the data
fit_result = fit(data, fit_params)
plot_fitted_data_bec(data, fit_result)
# Optionally move the motor to the peak position
if move_to_peak:
move_to_position(data["motor_device"], data["motor_name"], fit_result["centre"], data)
def scan_bpm(bpmname):
"""
Runs a grid scan of a BPM in x and y, and plots each channel
as a heatmap.
Parameters:
bpmname: the name of the bpm to be scanned e.g. "fe"
"""
# Open a dock area and set up the heatmaps
dock_area = bec.gui.new("XBPM_Scan")
wf5 = dock_area.new("Sum").new(bec.gui.available_widgets.Heatmap)
wf1 = dock_area.new("Ch1", relative_to="Sum", position="bottom").new(
bec.gui.available_widgets.Heatmap
)
wf3 = dock_area.new("Ch3", relative_to="Ch1", position="right").new(
bec.gui.available_widgets.Heatmap
)
wf4 = dock_area.new("Ch4", relative_to="Ch3", position="bottom").new(
bec.gui.available_widgets.Heatmap
)
wf2 = dock_area.new("Ch2", relative_to="Ch1", position="bottom").new(
bec.gui.available_widgets.Heatmap
)
wfscan = dock_area.new("ScanControl").new(bec.gui.available_widgets.ScanControl)
cfg = getattr(BPMScans, bpmname)
wf1.x_label = cfg["x_name"]
wf1.y_label = cfg["y_name"]
wf1.plot(x_name=cfg["x_name"], y_name=cfg["y_name"], z_name=cfg["z1_name"], color_map="plasma")
wf2.x_label = cfg["x_name"]
wf2.y_label = cfg["y_name"]
wf2.plot(x_name=cfg["x_name"], y_name=cfg["y_name"], z_name=cfg["z2_name"], color_map="plasma")
wf3.x_label = cfg["x_name"]
wf3.y_label = cfg["y_name"]
wf3.plot(x_name=cfg["x_name"], y_name=cfg["y_name"], z_name=cfg["z3_name"], color_map="plasma")
wf4.x_label = cfg["x_name"]
wf4.y_label = cfg["y_name"]
wf4.plot(x_name=cfg["x_name"], y_name=cfg["y_name"], z_name=cfg["z4_name"], color_map="plasma")
wf5.x_label = cfg["x_name"]
wf5.y_label = cfg["y_name"]
wf5.plot(x_name=cfg["x_name"], y_name=cfg["y_name"], z_name=cfg["z5_name"], color_map="plasma")
# Run the scan
x_mot = cfg["x_device"]
y_mot = cfg["y_device"]
# scans.grid_scan(x_mot, -0.5, 0.5, 20, y_mot, -0.5, 0.5, 20,
# exp_time=0.5, relative=False, snaked=True)
def optimise_kb(mirror):
"""
Runs a grid scan of a the upstream and downstream benders,
and plots a heatmap of the sample camera x or y sigma.
Parameters:
mirror: either "hfm" or :vfm"
"""
# Open a dock area and set up the heatmaps
dock_area = bec.gui.new(mirror)
wf1 = dock_area.new("Heatmap").new(bec.gui.available_widgets.Heatmap)
wfscan = dock_area.new("ScanControl").new(bec.gui.available_widgets.ScanControl)
cfg = getattr(MirrorConfig, mirror)
wf1.x_label = cfg["bu_name"]
wf1.y_label = cfg["bd_name"]
wf1.plot(x_name=cfg["bu_name"], y_name=cfg["bd_name"], z_name=cfg["z_name"], color_map="plasma")
# Run the scan
x_mot = cfg["x_device"]
y_mot = cfg["y_device"]
# scans.grid_scan(x_mot, -0.02, 0.02, 11, y_mot, -0.02, 0.02, 11,
# exp_time=0.5, relative=True, snaked=True)
+246
View File
@@ -0,0 +1,246 @@
"""Script to change energy at PXIII by setting DCCM motors and mirror stripe
Moving DCCM motors - implemented for dccm_theta1 and dccm_theta2
Mirrors - change of mirror stripe is not yet implemented
Plotting optional
"""
import pandas as pd
import numpy as np
# from mx_methods import go_to_peak
# from pxiii_parameters import EnergyDefaults
# from calculator import (
# validate_energy,
# convert_from_bragg,
# convert_from_energy,
# )
def get_current_energy():
"""
Returns the energy in eV from the current bragg angle.
"""
# current_bragg_angle = dev.dccm_theta1.user_readback.get()
current_bragg_angle = -EnergyDefaults.energy.user_readback.get()
current_energy = convert_from_bragg(current_bragg_angle, print_result=False)[
"energy_ev"
]
return current_energy
# Functions below are common to all beamlines
def calculate_energy_difference(current_energy, target_energy):
"""
Calculate the absolute difference in energy between the current energy level
and the target energy level.
"""
return abs(target_energy - current_energy)
def interpolate_column(energy_ev, x_values, y_values):
"""
Perform interpolation for a specific column of data.
This function uses numpy's interpolation method to perform linear
interpolation. It calculates the interpolated y-values corresponding
to the given energy in electron-volts (energy_ev), based on specified
x-values and y-values.
Parameters:
energy_ev (array-like): Array of energy values in electron-volts
at which interpolation is needed.
x_values (array-like): Array of x-values corresponding to known
data points.
y_values (array-like): Array of y-values corresponding to known
data points.
Returns:
numpy.ndarray: Interpolated y-values computed for the energy_ev
input.
"""
return np.interp(energy_ev, x_values, y_values)
# def get_value_from_lut(energy_ev):
# """
# Retrieve interpolated values from a Lookup Table (LUT) based on the provided energy
# in electron volts (eV).
# This function reads a CSV file containing energy lookup data and processes the LUT
# to return interpolated values for specified relevant columns. The interpolation is
# performed for the provided energy value using the LUT's energy and data values.
# Args:
# energy_ev (float): The energy value in electron volts for which the interpolated data is
# required.
# Returns:
# dict: A dictionary where the keys are the relevant column names from the LUT, and the values
# are the interpolated values as floats.
# """
# energy_lookup_data = pd.read_csv(EnergyDefaults.LUT_table)
# column_names = energy_lookup_data.columns.tolist()
# lut_values = energy_lookup_data.values.astype(float).T
# # Filter relevant columns for interpolation
# relevant_columns = {"dccm_pitch"}
# int_values = {}
# for i, col_name in enumerate(column_names):
# if col_name in relevant_columns:
# int_values[col_name] = float(
# interpolate_column(energy_ev, lut_values[0], lut_values[i])
# )
# return int_values
def get_mirror_stripe(energy_ev):
"""
Determines the mirror stripe material based on the energy level provided.
This function evaluates the given energy level in electron volts (eV) and
identifies the material type that corresponds to the specified thresholds
for silicon, rhodium, and, if applicable, platinum.
Args:
energy_ev (float): Energy level in electron volts, used to determine
the corresponding material type.
Returns:
str: A string indicating the material type corresponding to the provided
energy level. Possible values are "silicon", "rhodium", or "platinum".
"""
if energy_ev <= EnergyDefaults.stripe_thresholds["silicon"]:
return "silicon"
if (
EnergyDefaults.stripe_thresholds["silicon"]
< energy_ev
<= EnergyDefaults.stripe_thresholds["rhodium"]
):
return "rhodium"
return "platinum"
def set_mirror_stripe(energy_ev):
"""
Selects and sets the appropriate mirror stripe based on the given energy value
in electron volts (eV). Prints the selected mirror stripe.
Args:
energy_ev (float): The energy value in electron volts used to determine
the appropriate mirror stripe.
Returns:
None
"""
selected_stripe = get_mirror_stripe(energy_ev)
print(f"Selected mirror stripe: {selected_stripe}")
def mono_pitch_scan(plot=True):
"""Scan the monochromator pitch and move to the peak."""
if plot:
print("Scanning monochromator pitch and moving to peak, with plotting.")
go_to_peak(
EnergyDefaults.mono_pitch,
EnergyDefaults.signals["sig1"],
-EnergyDefaults.pitch_scan["halfwidth"],
EnergyDefaults.pitch_scan["halfwidth"],
steps=EnergyDefaults.pitch_scan["steps"],
relative=True,
settle=0.01,
plot=True,
confirm=False,
)
else:
print("Scanning monochromator pitch and moving to peak, without plotting.")
go_to_peak(
EnergyDefaults.mono_pitch,
EnergyDefaults.signals["sig1"],
-EnergyDefaults.pitch_scan["halfwidth"],
EnergyDefaults.pitch_scan["halfwidth"],
steps=EnergyDefaults.pitch_scan["steps"],
relative=True,
settle=0.01,
plot=False,
confirm=False,
)
def get_dccm_motors_positions(energy_ev):
"""
Retrieve the positions of DCCM motors based on given energy value.
The function returns a dictionary containing all
calculated motor positions.
Arguments:
energy_ev (float): The energy value in electron volts for which the
DCCM motor positions are to be calculated.
Returns:
dict: A dictionary containing the calculated DCCM motor positions
including values retrieved from the lookup table, if applicable.
"""
# dccm_motor_values = get_value_from_lut(energy_ev)
th1_angle = -convert_from_energy(energy_ev, print_result=False)["bragg_angle_deg"]
th2_angle = convert_from_energy(energy_ev, temp=298, print_result=False)["bragg_angle_deg"]
# Add a fudge factor to correct theta2 offset 30th Nov 25
th2_fudge = th2_angle + 0.005
# dccm_motor_values.update({"theta1_angle": th1_angle, "theta2_angle": th2_angle})
dccm_motor_values = {"theta1_angle": th1_angle, "theta2_angle": th2_fudge}
return dccm_motor_values
def move_dccm_motors(energy_ev):
"""
Move the DCCM theta1 and theta2 motors to the required positions
for the given energy in eV.
"""
dccm_pos = get_dccm_motors_positions(energy_ev)
print(
f"Moving DCCM theta1: {dccm_pos['theta1_angle']: .5g} deg, theta2: {dccm_pos['theta2_angle']: .5g} deg, "
# f"DCM pitch: {dcm_pos['dcm_pitch']: .5g} mrad, "
)
umv(EnergyDefaults.energy, dccm_pos["theta1_angle"])
umv(EnergyDefaults.mono_pitch, dccm_pos["theta2_angle"])
def bl_energy(energy_ev, plot=True):
"""
Adjusts the beamline's energy to the specified energy in electron volts (eV).
The function validates the target energy, checks the current energy, and makes
adjustments only if the energy difference is significant enough. It performs
necessary operations including changing DCCM motors, updating
the mirror stripe, and scanning to find the optimal DCCM pitch of 2nd crystal..
Args:
energy_ev: Target energy in electron volts to which the beamline should be adjusted.
plot: Boolean flag indicating whether to plot the DCCM pitch scan for finding the peak.
Returns:
None
"""
energy_ev = validate_energy(energy_ev) # Ensure energy is valid.
# Check current energy to avoid unnecessary adjustments.
current_energy = get_current_energy()
energy_diff = calculate_energy_difference(current_energy, energy_ev)
if energy_diff <= EnergyDefaults.min_energy_change:
print(
f"Energy change of {energy_diff:.2f} eV is too small, not changing energy."
)
return
# Step 1: Move and set the DCCM motors.
move_dccm_motors(energy_ev)
# Step 2: Update the mirror stripe.
set_mirror_stripe(energy_ev)
# Step 3: Perform DCCM pitch scan and move to peak.
if plot:
mono_pitch_scan(plot=True)
else:
mono_pitch_scan(plot=False)
+78
View File
@@ -0,0 +1,78 @@
"""File to store beamline parameters and defaults"""
from dataclasses import dataclass
import numpy as np
@dataclass(frozen=True)
class FitDefaults:
"""Default values for fitting routines"""
# Constants for default models, baselines, and parameters
MODEL = "Voigt"
BASELINE = "Linear"
SETTLE_TIME = 0.1
RELATIVE_MODE = True
@dataclass(frozen=True)
class EnergyDefaults:
"""Parameters for PXIII energy changes"""
min_energy_change = 0
min_energy_ev = 4500
max_energy_ev = 16001
signals = {
"sig1": dev.dccm_xbpmsum,
"sig2": dev.ss_bpmsum,
# "sig3": dev.xbox_xbpm,
}
energy = dev.dccm_theta1
mono_pitch = dev.dccm_theta2
# LUT_table = "luts/energy_lut.csv"
stripe_thresholds = {"silicon": 9000, "rhodium": 40000}
pitch_scan = {"halfwidth": 0.01, "steps": 60}
@dataclass(frozen=True)
class CamConversion:
"""Convert pixels to microns for sam cam"""
a = 0.5208
b = 0.002586
@dataclass(frozen=True)
class BPMScans:
"""Define the names of the motors and bpm channels"""
ss = {
"x_name": dev.ss_bpm_x.name,
"y_name": dev.ss_bpm_y.name,
"z1_name": dev.ss_bpm1.name,
"z2_name": dev.ss_bpm2.name,
"z3_name": dev.ss_bpm3.name,
"z4_name": dev.ss_bpm3.name,
"z5_name": dev.ss_bpmsum.name,
"x_device": dev.ss_bpm_x,
"y_device": dev.ss_bpm_y,
}
@dataclass(frozen=True)
class MirrorConfig:
"""Define the names of the mirror channels"""
hfm = {
"bu_name": dev.hfm_bu.name,
"bd_name": dev.hfm_bd.name,
"z_name": dev.samcam_xsig.name,
"x_device": dev.hfm_bu,
"y_device": dev.hfm_bd,
}
vfm = {
"bu_name": dev.vfm_bu.name,
"bd_name": dev.vfm_bd.name,
"z_name": dev.samcam_ysig.name,
"x_device": dev.vfm_bu,
"y_device": dev.vfm_bd,
}
+4 -3
View File
@@ -16,7 +16,8 @@ def alignment_fit_and_plot(
Args:
history_index (int): scan to fetch, e.g. -1 for the most recent scan
device_name (str): the device for which to get the monitoring data
signal_name (str | None): the signal to plot, if different from the device name.
smoothing_sigma (float): the sigma for the Gaussian smoothing filter
"""
# Fetch scan data from the history
# by default, signal = device name, unless otherwise specified
@@ -29,9 +30,9 @@ def alignment_fit_and_plot(
# Create a plot and a text box to display results
dock_area = bec.gui.new()
wf = dock_area.new().new(bec.gui.available_widgets.Waveform)
wf = dock_area.new(bec.gui.available_widgets.Waveform)
wf.title = f"Scan {md['scan_number']}: {md['scan_name']} of {motor_name}"
text = dock_area.new(position="right").new(widget=bec.gui.available_widgets.TextBox)
text = dock_area.new(bec.gui.available_widgets.TextBox, where="right")
# Calculate some processed data and add everything to the plot
wf.plot(data, label="Raw data")
+23 -15
View File
@@ -5,6 +5,18 @@
import time
def _device_name(device):
return device.name if hasattr(device, "name") else str(device)
def _get_or_create_scan_window(name="CurrentScan"):
window = bec.gui.windows.get(name)
if window is None:
return bec.gui.new(name)
window.delete_all()
return window
def rock(steps, exp_time, scan_start=None, scan_end=None, datasource=None, visual=True, **kwargs):
"""Demo step scan with plotting
@@ -26,22 +38,18 @@ def rock(steps, exp_time, scan_start=None, scan_end=None, datasource=None, visua
scan_end = 0.05 / dev.dccm_energy.user_readback.get()
if visual:
# Get or create scan specific window
window = None
for _, val in bec.gui.windows.items():
if val.title == "CurrentScan":
window = val.widget
window.clear_all()
if window is None:
window = bec.gui.new("CurrentScan")
# Get or create scan specific window.
window = _get_or_create_scan_window("CurrentScan")
motor_name = _device_name(motor)
datasource_name = _device_name(datasource)
# Draw a simploe plot in the window
dock = window.add_dock(f"ScanDisplay {motor}")
plt1 = dock.add_widget("BECWaveformWidget")
plt1.plot(x_name=motor, y_name=datasource)
plt1.set_x_label(motor)
plt1.set_y_label(datasource)
plt1.add_dap(motor, datasource, dap="LinearModel")
# Draw a waveform plot in the window.
plt1 = window.new(
bec.gui.available_widgets.Waveform, object_name=f"ScanDisplay_{motor_name}"
)
plt1.plot(device_x=motor_name, device_y=datasource_name, dap="LinearModel")
plt1.x_label = motor_name
plt1.y_label = datasource_name
window.show()
print("Handing over to 'scans.line_scan'")
-30
View File
@@ -1,30 +0,0 @@
def scan_theta2(scan_start, scan_end, stepno, exp):
# Save the motor starting position
start_value = dev.dccm_theta2.read()['dccm_theta2']['value']
print(f"Motor position is {start_value}")
# Run the scan
s = scans.line_scan(dev.dccm_theta2, scan_start, scan_end, steps=stepno, exp_time=exp, relative=True)
# data = s.devices[dccm_xbpm][dccm_xbpm].read()["value"]
# Move motor back to starting position and print XBPM reading
umv(dev.dccm_theta2, start_value)
xbpm_reading = dev.dccm_xbpm.read()['dccm_xbpm']['value']
print(f"Moving dccm_theta2 back to start position of where XBPM Reading is {xbpm_reading}")
end_value = dev.dccm_theta2.read()['dccm_theta2']['value']
print(f"Motor was at {start_value} before the scan, now at {end_value}")
# # Create a plot to display the results
dock_area = bec.gui.new()
wf = dock_area.new().new(bec.gui.available_widgets.Waveform)
wf.title = f"Scan of DCCM_theta2"
wf.plot(x_name='dccm_theta2', y_name='dccm_xbpm')
wf.add_dap_curve(device_label='dccm_xbpm-dccm_xbpm', dap_name='GaussianModel')
print(dap_xbpm.dap_params)
+23 -15
View File
@@ -6,6 +6,18 @@ def bl_check_beam():
return True
def _device_name(device):
return device.name if hasattr(device, "name") else str(device)
def _get_or_create_scan_window(name="CurrentScan"):
window = bec.gui.windows.get(name)
if window is None:
return bec.gui.new(name)
window.delete_all()
return window
def ascan(
motor, scan_start, scan_end, steps, exp_time, plot=None, visual=True, relative=False, **kwargs
):
@@ -23,22 +35,18 @@ def ascan(
raise RuntimeError("Beamline is not in ready state")
if visual:
# Get or create scan specific window
window = None
for _, val in bec.gui.windows.items():
if val.title == "CurrentScan":
window = val.widget
window.clear_all()
if window is None:
window = bec.gui.new("CurrentScan")
# Get or create scan specific window.
window = _get_or_create_scan_window("CurrentScan")
motor_name = _device_name(motor)
plot_name = _device_name(plot)
# Draw a simploe plot in the window
dock = window.add_dock(f"ScanDisplay {motor}")
plt1 = dock.add_widget("BECWaveformWidget")
plt1.plot(x_name=motor, y_name=plot)
plt1.set_x_label(motor)
plt1.set_y_label(plot)
plt1.add_dap(motor, plot, dap="LinearModel")
# Draw a waveform plot in the window.
plt1 = window.new(
bec.gui.available_widgets.Waveform, object_name=f"ScanDisplay_{motor_name}"
)
plt1.plot(device_x=motor_name, device_y=plot_name, dap="LinearModel")
plt1.x_label = motor_name
plt1.y_label = plot_name
window.show()
print("Handing over to 'scans.line_scan'")
+1 -1
View File
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
name = "pxiii_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",