From 3e278a68a2504e80f3e7092bfaa6dd0575b53bed Mon Sep 17 00:00:00 2001 From: x12sa Date: Fri, 16 Jan 2026 13:38:45 +0100 Subject: [PATCH] moved axis mapping to config file --- .../plugins/cSAXS/smaract.py | 402 +++++++++--------- csaxs_bec/device_configs/smaract_test.yaml | 47 ++ 2 files changed, 256 insertions(+), 193 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/cSAXS/smaract.py b/csaxs_bec/bec_ipython_client/plugins/cSAXS/smaract.py index 553149f..c6774f5 100644 --- a/csaxs_bec/bec_ipython_client/plugins/cSAXS/smaract.py +++ b/csaxs_bec/bec_ipython_client/plugins/cSAXS/smaract.py @@ -1,60 +1,112 @@ + import builtins import time -#from pathlib import Path from bec_lib import bec_logger - # Logger initialization logger = bec_logger.logger -if builtins.__dict__.get("bec") is not None: - bec = builtins.__dict__.get("bec") - dev = builtins.__dict__.get("dev") - umv = builtins.__dict__.get("umv") - umvr = builtins.__dict__.get("umvr") +# Pull BEC globals if present +bec = builtins.__dict__.get("bec") +dev = builtins.__dict__.get("dev") +umv = builtins.__dict__.get("umv") +umvr = builtins.__dict__.get("umvr") + class cSAXSInitSmaractStagesError(Exception): pass class cSAXSInitSmaractStages: - # Class-level mappings for axes and devices - AXIS_MAP = {c: i for i, c in enumerate("ABCDEFGHIJKLMNOPQRSTUVWXYZ")} - - devices = { - "xbpm3x": "A", - "xbpm3y": "B", - "sl3trxi": "C", - "sl3trxo": "D", - "sl3trxb": "E", - "sl3trxt": "F", - "fast_shutter_n1_x": "H", - "fast_shutter_o1_x": "G", - "fast_shutter_o2_x": "F", - "filter_array_1_x": "B", - "filter_array_2_x": "C", - "filter_array_3_x": "D", - "filter_array_4_x": "E", - "sl4trxi": "G", - "sl4trxo": "H", - "sl4trxb": "I", - "sl4trxt": "A", - "sl5trxi": "C", - "sl5trxo": "D", - "sl5trxb": "E", - "sl5trxt": "F", - "xbimtrx": "A", - "xbimtry": "B", - } + """ + Runtime SmarAct utilities for referencing and moving to initial positions. + + This class no longer relies on static mappings. Instead, it: + - discovers available devices from `list(dev.keys())` + - reads the numeric channel/axis from each device's `user_parameter['bl_smar_stage']` + - reads `init_position` from `user_parameter['init_position']` + """ def __init__(self, client) -> None: self.client = client - - def smaract_reference_stages(self, force=False, devices_to_reference=None): + # ------------------------------ + # Internal helpers (runtime-based) + # ------------------------------ + def _yesno(self, question: str, default: str = "y") -> bool: """ - Reference SmarAct stages. + Use OMNYTools.yesno if available; otherwise default to 'yes' (or fallback to input()). + """ + try: + if hasattr(self, "OMNYTools") and hasattr(self.OMNYTools, "yesno"): + return self.OMNYTools.yesno(question, default) + except Exception: + pass + + # Fallback: default answer without interaction + # (Safe default: 'y' proceeds; adjust if you want interactive input) + logger.info(f"[cSAXS] (yesno fallback) {question} -> default '{default}'") + return (default or "y").lower().startswith("y") + + def _get_user_param_safe(self, device_name: str, key: str): + """ + Safe access to device user parameters from current BEC session. + """ + try: + return dev[device_name].user_parameter.get(key) + except Exception: + return None + + def _iter_session_devices(self): + """ + Yield device names available in current BEC session. + """ + if dev is None: + return + for name in list(dev.keys()): + yield name + + def _build_session_axis_map(self, selection: set | None = None) -> dict: + """ + Build runtime axis map {device_name: channel} for devices that define 'bl_smar_stage'. + If 'selection' is provided, restrict to names in selection. + """ + axis_map = {} + missing = [] + for name in self._iter_session_devices() or []: + if selection is not None and name not in selection: + continue + ch = self._get_user_param_safe(name, "bl_smar_stage") + if ch is None: + missing.append(name) + continue + try: + axis_map[name] = int(ch) + except Exception: + missing.append(name) + + if missing and selection is None: + logger.info( + "[cSAXS] Devices without 'bl_smar_stage' (ignored): " + ", ".join(sorted(missing)) + ) + return axis_map + + def _get_device_object(self, device_name: str): + """ + Return the live device object from BEC 'dev'. + """ + try: + return getattr(dev, device_name) + except Exception: + return None + + # ------------------------------ + # Public API + # ------------------------------ + def smaract_reference_stages(self, force: bool = False, devices_to_reference=None): + """ + Reference SmarAct stages using runtime discovery. Parameters ---------- @@ -62,22 +114,21 @@ class cSAXSInitSmaractStages: If True, re-reference ALL selected stages. If False (default), only reference stages that are currently NOT referenced. - devices_to_reference : iterable of str, optional + devices_to_reference : iterable of str or str, optional If provided, only these devices will be considered for referencing. - If None (default), all stages in `self.devices` are candidates. + If None, all devices in the current session that define 'bl_smar_stage' are considered. Behavior -------- + - Runtime-based: reads axis channel from user_parameter['bl_smar_stage']. - If devices_to_reference is given → restrict referencing to those. - If force=False → skip devices already referenced. - If force=True → re-reference selected devices always. - Only newly referenced devices are passed to - smaract_components_to_initial_position() afterwards. - + smaract_components_to_initial_position(devices_to_move=[...]) afterwards. Examples -------- - Reference only stages that are NOT referenced yet (default) csaxs.smaract_reference_stages() @@ -107,39 +158,32 @@ class cSAXSInitSmaractStages: Check referencing status of all stages csaxs.smaract_check_all_referenced() - - - """ - # Normalize selection if isinstance(devices_to_reference, str): devices_to_reference = [devices_to_reference] + selection = set(devices_to_reference) if devices_to_reference else None - selection = ( - set(devices_to_reference) - if devices_to_reference is not None - else set(self.devices.keys()) - ) + # Build axis map for selected devices (or all devices present) + axis_map = self._build_session_axis_map(selection=selection) + if selection: + unknown = sorted(list(selection - set(axis_map.keys()))) + if unknown: + print(f"Unknown devices requested or missing 'bl_smar_stage' (ignored): {unknown}") - unknown = selection - set(self.devices.keys()) - if unknown: - print(f"Unknown devices requested and ignored: {sorted(unknown)}") - selection = selection.intersection(self.devices.keys()) newly_referenced = [] already_referenced = [] failed = [] + to_verify = [] # devices that need a final verification print("\nStarting SmarAct referencing...\n") - for dev_name in sorted(selection): - axis_letter = self.devices[dev_name] - ch = self.AXIS_MAP[axis_letter] + for dev_name in sorted(axis_map.keys()): + ch = axis_map[dev_name] + d = self._get_device_object(dev_name) - try: - d = getattr(dev, dev_name) - except AttributeError: + if d is None: print(f"{dev_name}: device not accessible, skipping.") failed.append(dev_name) continue @@ -153,22 +197,33 @@ class cSAXSInitSmaractStages: already_referenced.append(dev_name) continue - # Perform referencing - print(f"{dev_name}: referencing axis {ch}...") + # Start referencing + print(f"{dev_name}: referencing axis...") d.controller.set_closed_loop_move_speed(ch, 1) d.controller.find_reference_mark(ch, 0, 1000, 1) time.sleep(0.1) - # Verify + # Add to list for final verification + to_verify.append((dev_name, ch, d)) + + except Exception as e: + print(f"Error referencing {dev_name} (axis {ch}): {e}") + failed.append(dev_name) + + time.sleep(1.0) + + print("\nVerifying referencing state...\n") + + for dev_name, ch, d in to_verify: + try: if d.controller.axis_is_referenced(ch): print(f"{dev_name}: successfully referenced.") newly_referenced.append(dev_name) else: print(f"{dev_name}: referencing FAILED.") failed.append(dev_name) - except Exception as e: - print(f"Error referencing {dev_name} (axis {ch}): {e}") + print(f"{dev_name}: verification error: {e}") failed.append(dev_name) # --- Summary --- @@ -181,47 +236,42 @@ class cSAXSInitSmaractStages: # --- Move newly referenced only --- if newly_referenced: print("Moving newly referenced stages to initial positions...") - self.smaract_components_to_initial_position( - devices_to_move=newly_referenced - ) + self.smaract_components_to_initial_position(devices_to_move=newly_referenced) else: print("No newly referenced stages.") - def smaract_check_all_referenced(self): """ - Check if all SmarAct axes are referenced. + Check reference state for all SmarAct devices that define 'bl_smar_stage'. """ - for dev_name, axis_letter in self.devices.items(): - ch = self.AXIS_MAP[axis_letter] - + axis_map = self._build_session_axis_map(selection=None) + for dev_name in sorted(axis_map.keys()): + ch = axis_map[dev_name] + d = self._get_device_object(dev_name) + if d is None: + print(f"{dev_name}: device not accessible or unsupported.") + continue try: - d = getattr(dev, dev_name) if d.controller.axis_is_referenced(ch): print(f"{dev_name} (axis {ch}) is referenced.") else: print(f"{dev_name} (axis {ch}) is NOT referenced.") - except AttributeError: - print(f"{dev_name}: device not accessible or unsupported.") except Exception as e: print(f"Error checking {dev_name} (axis {ch}): {e}") - - def smaract_components_to_initial_position( - self, - devices_to_move=None, - ): + def smaract_components_to_initial_position(self, devices_to_move=None): """ Move selected (or all) SmarAct-based components to their configured init_position. Parameters ---------- - devices_to_move : iterable of str, optional + devices_to_move : iterable of str or str, optional Specific device names to move (e.g. ["xbpm3x", "sl3trxi"]). - If None, all known SmarAct devices defined in `self.devices` are considered. + If None, all devices in the current session that define 'bl_smar_stage' are considered. Behavior -------- + - Runtime-based: uses user_parameter['bl_smar_stage'] (numeric channel) and 'init_position'. - Only axes that are referenced will be moved. - Unreferenced axes are skipped with a WARNING; the operation continues. - Devices missing `init_position` are skipped and listed. @@ -232,108 +282,75 @@ class cSAXSInitSmaractStages: devices_to_move = [devices_to_move] selection = set(devices_to_move) if devices_to_move else None - planned_moves = [] - not_referenced = [] - missing_params = [] - inaccessible_devices = [] + # Resolve axis map based on selection + axis_map = self._build_session_axis_map(selection=selection) unknown_requested = [] - - # If a selection is provided, pre-check for unknown device names - if selection is not None: - known = set(self.devices.keys()) - unknown_requested = sorted(list(selection - known)) + if selection: + unknown_requested = sorted(list(selection - set(axis_map.keys()))) if unknown_requested: - bec_logger.logger.warning( - "[cSAXS] The following requested devices are unknown and will be ignored: " + logger.warning( + "[cSAXS] Requested devices unknown or missing 'bl_smar_stage': " + ", ".join(unknown_requested) ) # First confirmation: intent - scope_desc = ( - "all SmarAct-based components" - if selection is None - else "the selected SmarAct-based components" - ) - if not self.OMNYTools.yesno( + scope_desc = "all SmarAct-based components" if selection is None else "the selected SmarAct-based components" + if not self._yesno( f"Do you want to move {scope_desc} to the init position as defined in the config file?", "y", ): return - # --- Pre-check phase --- - for dev_name, axis_letter in self.devices.items(): - # If a selection is provided, only consider those in the selection - if selection is not None and dev_name not in selection: - continue + planned_moves = [] + not_referenced = [] + missing_params = [] + inaccessible_devices = [] - try: - d = getattr(dev, dev_name) - except AttributeError: - bec_logger.logger.warning( - f"[cSAXS] Device {dev_name} not accessible, skipping." - ) + # --- Pre-check phase --- + for dev_name in sorted(axis_map.keys()): + d = self._get_device_object(dev_name) + if d is None: + logger.warning(f"[cSAXS] Device {dev_name} not accessible, skipping.") inaccessible_devices.append(dev_name) continue - # Resolve channel - ch = self.AXIS_MAP.get(axis_letter, None) - if ch is None: - bec_logger.logger.warning( - f"[cSAXS] Axis map has no entry for letter '{axis_letter}' " - f"(device {dev_name}); skipping." - ) - continue - + ch = axis_map[dev_name] try: # Reference check if not d.controller.axis_is_referenced(ch): not_referenced.append(dev_name) continue - # Fetch init_position - init_pos = self.OMNYTools._get_user_param_safe( - dev_name, - "init_position", - ) - + # Fetch init_position (from user parameters) + init_pos = self._get_user_param_safe(dev_name, "init_position") if init_pos is None: missing_params.append(dev_name) continue - planned_moves.append((dev_name, init_pos)) + planned_moves.append((dev_name, float(init_pos))) except Exception as exc: - bec_logger.logger.error( - f"[cSAXS] Error during pre-check for {dev_name}: {exc}" - ) + logger.error(f"[cSAXS] Error during pre-check for {dev_name}: {exc}") if not planned_moves: # Nothing to move—still summarize why. header = "\nNo motions planned. Summary of issues:" lines = [] if not_referenced: - lines.append( - " - Not referenced: " + ", ".join(sorted(not_referenced)) - ) + lines.append(" - Not referenced: " + ", ".join(sorted(not_referenced))) if missing_params: - lines.append( - " - Missing init_position: " + ", ".join(sorted(missing_params)) - ) + lines.append(" - Missing init_position: " + ", ".join(sorted(missing_params))) if inaccessible_devices: - lines.append( - " - Not accessible: " + ", ".join(sorted(inaccessible_devices)) - ) + lines.append(" - Not accessible: " + ", ".join(sorted(inaccessible_devices))) if unknown_requested: - lines.append( - " - Unknown requested: " + ", ".join(sorted(unknown_requested)) - ) + lines.append(" - Unknown requested: " + ", ".join(sorted(unknown_requested))) if not lines: lines.append(" - (No eligible devices or nothing to do.)") print(header) for line in lines: print(line) - bec_logger.logger.warning("[cSAXS] Nothing to do.") + logger.warning("[cSAXS] Nothing to do.") return # --- Summary table --- @@ -342,7 +359,7 @@ class cSAXSInitSmaractStages: print(f"{'Device':<35} {'Init position':>20}") print("-" * 60) for dev_name, init_pos in planned_moves: - print(f"{dev_name:<35} {init_pos:>20}") + print(f"{dev_name:<35} {init_pos:>20.6g}") print("-" * 60) # Notes / diagnostics @@ -353,79 +370,78 @@ class cSAXSInitSmaractStages: print("\nNote: The following requested devices are unknown and were ignored:") print(", ".join(unknown_requested)) if not_referenced: - print( - "\nNote: The following devices are NOT referenced and will be skipped:" - ) + print("\nNote: The following devices are NOT referenced and will be skipped:") print(", ".join(sorted(not_referenced))) if missing_params: - print( - "\nNote: The following devices have no init_position defined and will be skipped:" - ) + print("\nNote: The following devices have no init_position defined and will be skipped:") print(", ".join(sorted(missing_params))) if inaccessible_devices: - print( - "\nNote: The following devices were not accessible and will be skipped:" - ) + print("\nNote: The following devices were not accessible and will be skipped:") print(", ".join(sorted(inaccessible_devices))) # Second confirmation: execution - if not self.OMNYTools.yesno( - "Proceed with the motions listed above?", - "y", - ): - bec_logger.logger.info( - "[cSAXS] Motion to initial position aborted by user." - ) + if not self._yesno("Proceed with the motions listed above?", "y"): + logger.info("[cSAXS] Motion to initial position aborted by user.") return - # --- Execution phase (SIMULTANEOUS MOTION) --- + if umv is None: + logger.error("[cSAXS] 'umv' is not available in this session.") + return + # Build a flat argument list: [dev1, pos1, dev2, pos2, ...] move_args = [] for dev_name, init_pos in planned_moves: - try: - d = getattr(dev, dev_name) - move_args.append(d) - move_args.append(init_pos) - bec_logger.logger.info( - f"[cSAXS] Preparing move: {dev_name} -> {init_pos}" - ) - except Exception as exc: - bec_logger.logger.error( - f"[cSAXS] Could not access {dev_name}: {exc}" - ) + d = self._get_device_object(dev_name) + if d is None: + logger.error(f"[cSAXS] Could not access {dev_name}, skipping.") + continue + move_args.append(d) + move_args.append(init_pos) + logger.info(f"[cSAXS] Preparing move: {dev_name} -> {init_pos}") if not move_args: - bec_logger.logger.warning( - "[cSAXS] No valid devices left for simultaneous motion." - ) + logger.warning("[cSAXS] No valid devices left for simultaneous motion.") return - # Now trigger simultaneous move + # Trigger simultaneous move try: - bec_logger.logger.info( - f"[cSAXS] Starting simultaneous motion of {len(planned_moves)} devices." - ) - umv(*move_args) # <-- simultaneous move + logger.info(f"[cSAXS] Starting simultaneous motion of {len(planned_moves)} devices.") + umv(*move_args) # simultaneous move except Exception as exc: - bec_logger.logger.error( - f"[cSAXS] Simultaneous motion failed: {exc}" - ) + logger.error(f"[cSAXS] Simultaneous motion failed: {exc}") return - bec_logger.logger.info( - "[cSAXS] Simultaneous SmarAct motion to initial positions completed." - ) + logger.info("[cSAXS] Simultaneous SmarAct motion to initial positions completed.") + # Final warning summary about unreferenced devices + if not_referenced: + logger.warning( + "[cSAXS] Some stages were NOT moved because they are not referenced:\n" + + ", ".join(sorted(not_referenced)) + + "\nPlease reference these axes and re-run if needed." + ) class cSAXSSmaract: - def __init__(self, client) -> None: self.client = client - def fshn1in(self): - # Fetch in position - in_pos = self.OMNYTools._get_user_param_safe("fast_shutter_n1_x","in") - umv(dev.fast_shutter_n1_x,in_pos) + def _get_user_param_safe(self, device_name: str, key: str): + try: + return dev[device_name].user_parameter.get(key) + except Exception: + return None + def fshn1in(self): + """ + Move fast shutter n1 to its 'in' position defined in user parameters. + """ + in_pos = self._get_user_param_safe("fast_shutter_n1_x", "in") + if in_pos is None: + logger.error("[cSAXS] No 'in' position defined for fast_shutter_n1_x.") + return + if umv is None: + logger.error("[cSAXS] 'umv' is not available in this session.") + return + umv(dev.fast_shutter_n1_x, in_pos) diff --git a/csaxs_bec/device_configs/smaract_test.yaml b/csaxs_bec/device_configs/smaract_test.yaml index 0f0baae..02f0383 100644 --- a/csaxs_bec/device_configs/smaract_test.yaml +++ b/csaxs_bec/device_configs/smaract_test.yaml @@ -1,3 +1,4 @@ + ################## XBOX 1 ES ##################### xbpm3x: description: X-ray beam position x monitor 1 in ESbox1 @@ -18,6 +19,8 @@ xbpm3x: readoutPriority: baseline userParameter: init_position: -22.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 0 xbpm3y: description: X-ray beam position y monitor 1 in ESbox1 @@ -38,6 +41,8 @@ xbpm3y: readoutPriority: baseline userParameter: init_position: -2 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 1 sl3trxi: description: ESbox1 slit 3 inner blade movement @@ -58,6 +63,8 @@ sl3trxi: readoutPriority: baseline userParameter: init_position: -5.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 2 sl3trxo: description: ESbox1 slit 3 outer blade movement @@ -78,6 +85,8 @@ sl3trxo: readoutPriority: baseline userParameter: init_position: 6 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 3 sl3trxb: description: ESbox1 slit 3 bottom blade movement @@ -98,6 +107,8 @@ sl3trxb: readoutPriority: baseline userParameter: init_position: -5.8 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 4 sl3trxt: description: ESbox1 slit 3 top blade movement @@ -118,6 +129,8 @@ sl3trxt: readoutPriority: baseline userParameter: init_position: 5.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 5 fast_shutter_n1_x: description: ESbox1 New fast shutter 1 x movment @@ -139,6 +152,8 @@ fast_shutter_n1_x: userParameter: init_position: -7 in: 0 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 7 fast_shutter_o1_x: description: ESbox1 Old fast shutter 1 x movment @@ -159,6 +174,8 @@ fast_shutter_o1_x: readoutPriority: baseline userParameter: init_position: -15.8 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 6 fast_shutter_o2_x: description: ESbox1 Old fast shutter 2 x movment @@ -179,6 +196,8 @@ fast_shutter_o2_x: readoutPriority: baseline userParameter: init_position: -15.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 5 filter_array_1_x: description: ESbox1 Filter Array 1 x movment @@ -199,6 +218,8 @@ filter_array_1_x: readoutPriority: baseline userParameter: init_position: 25 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 1 filter_array_2_x: description: ESbox1 Filter Array 2 x movment @@ -219,6 +240,8 @@ filter_array_2_x: readoutPriority: baseline userParameter: init_position: 25.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 2 filter_array_3_x: description: ESbox1 Filter Array 3 x movment @@ -239,6 +262,8 @@ filter_array_3_x: readoutPriority: baseline userParameter: init_position: 25.8 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 3 filter_array_4_x: description: ESbox1 Filter Array 4 x movment @@ -259,6 +284,8 @@ filter_array_4_x: readoutPriority: baseline userParameter: init_position: 25 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 4 sl4trxi: description: ESbox1 slit 4 inner blade movement @@ -279,6 +306,8 @@ sl4trxi: readoutPriority: baseline userParameter: init_position: -5.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 6 sl4trxo: description: ESbox1 slit 4 outer blade movement @@ -299,6 +328,8 @@ sl4trxo: readoutPriority: baseline userParameter: init_position: 6 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 7 sl4trxb: description: ESbox1 slit 4 bottom blade movement @@ -319,6 +350,8 @@ sl4trxb: readoutPriority: baseline userParameter: init_position: -5.8 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 8 sl4trxt: description: ESbox1 slit 4 top blade movement @@ -339,6 +372,8 @@ sl4trxt: readoutPriority: baseline userParameter: init_position: 5.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 0 ################## XBOX 2 ES ##################### @@ -361,6 +396,8 @@ sl5trxi: readoutPriority: baseline userParameter: init_position: -6 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 2 sl5trxo: description: ESbox2 slit 5 outer blade movement @@ -381,6 +418,8 @@ sl5trxo: readoutPriority: baseline userParameter: init_position: 5.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 3 sl5trxb: description: ESbox2 slit 5 bottom blade movement @@ -401,6 +440,8 @@ sl5trxb: readoutPriority: baseline userParameter: init_position: -5.5 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 4 sl5trxt: description: ESbox1 slit 5 top blade movement @@ -421,6 +462,8 @@ sl5trxt: readoutPriority: baseline userParameter: init_position: 6 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 5 xbimtrx: description: ESbox2 beam intensity monitor x movement @@ -441,6 +484,8 @@ xbimtrx: readoutPriority: baseline userParameter: init_position: -14.7 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 0 xbimtry: description: ESbox2 beam intensity monitor y movement @@ -461,3 +506,5 @@ xbimtry: readoutPriority: baseline userParameter: init_position: 0 + # bl_smar_stage to use csaxs reference method. assign number according to axis channel + bl_smar_stage: 1