feat: migrate optics-hutch SmarAct stages to MCS2, align cross-controller compat
CI for csaxs_bec / test (pull_request) Successful in 3m48s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 2m7s

- Switch xbpm2x/xbpm2y/polrot/poly/scinx in bl_optics_hutch.yaml from the
  legacy MCS1 controller to the new MCS2 controller (mcs2-00029056.psi.ch),
  re-enabling polrot/poly with corrected axis assignments from the updated
  wiring table to avoid colliding with xbpm2x/xbpm2y on the same channel.
- Remove mcs2_config_test.yaml now that MCS2 is live on real stages.
- Give Mcs2Controller.find_reference_mark an unused hold_time parameter so
  shared call sites (smaract.py, flomni.py, omny.py, lamni_optics_mixin.py)
  that pass MCS1-style (axis, direction, holdTime, autoZero) args work
  unchanged against MCS2 devices too.
- Rename smaract_show_all/mcs2_show_all to a common show_all on both
  controllers, and have each list describe() from every registered MCS1 and
  MCS2 controller instead of only its own type.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UfjGm8MQrhCV8VaC9Tf4qx
This commit was merged in pull request #287.
This commit is contained in:
x12sa
2026-07-30 12:04:10 +02:00
co-authored by Claude Sonnet 5
parent a65ab6cbdd
commit 771ee01a57
4 changed files with 78 additions and 82 deletions
+58 -58
View File
@@ -192,14 +192,14 @@ ccm_energy:
xbpm2x:
description: X-ray beam position monitor 1 in OPbox
deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
deviceClass: csaxs_bec.devices.mcs2.mcs2_ophyd.Mcs2Motor
deviceConfig:
axis_Id: A
host: x12sa-eb-smaract-mcs-03.psi.ch
host: mcs2-00029056.psi.ch
limits:
- -200
- 200
port: 5000
port: 55551
sign: 1
enabled: true
onFailure: retry
@@ -216,14 +216,14 @@ xbpm2x:
xbpm2y:
description: X-ray beam position monitor 1 in OPbox
deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
deviceClass: csaxs_bec.devices.mcs2.mcs2_ophyd.Mcs2Motor
deviceConfig:
axis_Id: B
host: x12sa-eb-smaract-mcs-03.psi.ch
host: mcs2-00029056.psi.ch
limits:
- -200
- 200
port: 5000
port: 55551
sign: 1
enabled: true
onFailure: retry
@@ -237,16 +237,39 @@ xbpm2y:
deviceTags:
- bl_optics_hutch
scinx:
description: scintillator in OPbox
deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
polrot:
description: rotation of crytal of the polarizer
deviceClass: csaxs_bec.devices.mcs2.mcs2_ophyd.Mcs2Motor
deviceConfig:
axis_Id: C
host: x12sa-eb-smaract-mcs-03.psi.ch
host: mcs2-00029056.psi.ch
limits:
- -200
- 200
port: 5000
port: 55551
sign: 1
enabled: true
onFailure: retry
readOnly: false
readoutPriority: baseline
connectionTimeout: 20
userParameter:
in_position: -1.0
# bl_smar_stage to use csaxs reference method. assign number according to axis channel
bl_smar_stage: 2
deviceTags:
- bl_optics_hutch
poly:
description: polarizer holder in OPbox
deviceClass: csaxs_bec.devices.mcs2.mcs2_ophyd.Mcs2Motor
deviceConfig:
axis_Id: D
host: mcs2-00029056.psi.ch
limits:
- -200
- 200
port: 55551
sign: 1
enabled: true
onFailure: retry
@@ -256,56 +279,33 @@ scinx:
userParameter:
# bl_smar_stage to use csaxs reference method. assign number according to axis channel
init_position: -23
bl_smar_stage: 2
in_position: -12.5
bl_smar_stage: 3
deviceTags:
- bl_optics_hutch
# poly:
# description: polarizer holder in OPbox
# deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
# deviceConfig:
# axis_Id: B
# host: x12sa-eb-smaract-mcs-03.psi.ch
# limits:
# - -200
# - 200
# port: 5000
# sign: 1
# enabled: true
# onFailure: retry
# readOnly: false
# readoutPriority: baseline
# connectionTimeout: 20
# userParameter:
# # bl_smar_stage to use csaxs reference method. assign number according to axis channel
# init_position: -23
# bl_smar_stage: 1
# deviceTags:
# - bl_optics_hutch
# polrot:
# description: rotation of crytal of the polarizer
# deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
# deviceConfig:
# axis_Id: A
# host: x12sa-eb-smaract-mcs-03.psi.ch
# limits:
# - -200
# - 200
# port: 5000
# sign: 1
# enabled: true
# onFailure: retry
# readOnly: false
# readoutPriority: baseline
# connectionTimeout: 20
# userParameter:
# in_position: -1.0
# # bl_smar_stage to use csaxs reference method. assign number according to axis channel
# bl_smar_stage: 0
# deviceTags:
# - bl_optics_hutch
scinx:
description: scintillator in OPbox
deviceClass: csaxs_bec.devices.mcs2.mcs2_ophyd.Mcs2Motor
deviceConfig:
axis_Id: E
host: mcs2-00029056.psi.ch
limits:
- -200
- 200
port: 55551
sign: 1
enabled: true
onFailure: retry
readOnly: false
readoutPriority: baseline
connectionTimeout: 20
userParameter:
# bl_smar_stage to use csaxs reference method. assign number according to axis channel
init_position: -23
bl_smar_stage: 4
in_position: -12.5
deviceTags:
- bl_optics_hutch
# dmm1_trx_readback_example: # This is the same template as for i.e. bpm4i
# description: 'This is an example of a read-only Epics signal'
@@ -1,18 +0,0 @@
mcs2test:
description: "Single-axis MCS2 test config (MCS2-C-0008, channel A)"
deviceClass: csaxs_bec.devices.mcs2.mcs2_ophyd.Mcs2Motor
deviceConfig:
axis_Id: A
host: <mcs2-controller-hostname-or-ip>
port: 55551
limits:
- -5
- 5
sign: 1
enabled: true
onFailure: raise
readoutPriority: baseline
readOnly: false
softwareTrigger: false
deviceTags:
- test_config
+13 -3
View File
@@ -91,7 +91,7 @@ class Mcs2Controller(Controller):
USER_ACCESS = [
"query",
"command",
"mcs2_show_all",
"show_all",
"move_open_loop_steps",
"find_reference_mark",
"describe",
@@ -315,6 +315,7 @@ class Mcs2Controller(Controller):
self,
axis_Id_numeric: int,
direction: int = 0,
hold_time: int | None = None,
autoZero: int = 1,
velocity: float = 1.0,
acceleration: float = 10.0,
@@ -324,6 +325,11 @@ class Mcs2Controller(Controller):
Args:
axis_Id_numeric (int): Axis number.
direction (int): 0 = start/forward direction, 1 = reverse direction.
hold_time: Unused. Accepted only for positional compatibility with
SmaractController.find_reference_mark's (axis, direction, holdTime,
autoZero) signature, so shared call sites like
``find_reference_mark(ch, 0, 1000, 1)`` work unchanged against both
controller types. The MCS2 has no hold-time concept for referencing.
autoZero (int): If truthy, the position is set to zero once the reference
mark is found.
velocity (float): Referencing velocity in mm/s.
@@ -437,7 +443,11 @@ class Mcs2Controller(Controller):
t.add_row([None for _ in t.field_names])
print(t)
def mcs2_show_all(self) -> None:
def show_all(self) -> None:
"""Print the describe() table for every registered SmarAct controller,
MCS1 (SmaractController) and MCS2 (Mcs2Controller) alike."""
from csaxs_bec.devices.smaract.smaract_controller import SmaractController
for controller in self._controller_instances.values():
if isinstance(controller, Mcs2Controller):
if isinstance(controller, (SmaractController, Mcs2Controller)):
controller.describe()
@@ -60,7 +60,7 @@ class SmaractController(Controller):
_initialized = False
USER_ACCESS = [
"socket_put_and_receive",
"smaract_show_all",
"show_all",
"move_open_loop_steps",
"find_reference_mark",
"describe",
@@ -442,9 +442,13 @@ class SmaractController(Controller):
t.add_row([None for t in t.field_names])
print(t)
def smaract_show_all(self) -> None:
def show_all(self) -> None:
"""Print the describe() table for every registered SmarAct controller,
MCS1 (SmaractController) and MCS2 (Mcs2Controller) alike."""
from csaxs_bec.devices.mcs2.mcs2_controller import Mcs2Controller
for controller in self._controller_instances.values():
if isinstance(controller, SmaractController):
if isinstance(controller, (SmaractController, Mcs2Controller)):
controller.describe()
@axis_checked