Compare commits

..

6 Commits

Author SHA1 Message Date
4b04e7a35d fix: alarm handler signature for flomni scan
All checks were successful
CI for csaxs_bec / test (push) Successful in 2m27s
CI for csaxs_bec / test (pull_request) Successful in 2m19s
2026-03-13 09:34:32 +01:00
00c45b2bcf fix(gui): submit button do not block if fails
All checks were successful
CI for csaxs_bec / test (pull_request) Successful in 1m56s
CI for csaxs_bec / test (push) Successful in 1m59s
2026-03-12 23:42:20 +01:00
138b2668b3 fix(gui): cleanup adjusted 2026-03-12 23:42:20 +01:00
31eb00bd97 fix(gui): wrong api calls 2026-03-12 23:42:20 +01:00
x12sa
53e7593b8e fixed centering routine fsamx movements
All checks were successful
CI for csaxs_bec / test (push) Successful in 1m56s
2026-03-12 22:31:56 +01:00
x12sa
8c7e1cf060 fixes during first round of testing flomni with Ana
Some checks failed
CI for csaxs_bec / test (pull_request) Successful in 1m55s
CI for csaxs_bec / test (push) Has been cancelled
2026-03-12 13:48:24 +01:00
7 changed files with 153 additions and 136 deletions

View File

@@ -84,6 +84,15 @@ class FlomniInitStagesMixin:
else:
return
sensor_voltage_target = dev.ftransy.user_parameter.get("sensor_voltage")
sensor_voltage = float(dev.ftransy.controller.socket_put_and_receive("MG@AN[1]").strip())
if not np.isclose(sensor_voltage, sensor_voltage_target, 0.25):
print(f"Sensor voltage of the gripper is {sensor_voltage}, while target from config is {sensor_voltage_target}")
print("Verify that the value is acceptable and update config file. Reload config and start again.")
return
print("Starting to drive ftransy to +y limit")
self.drive_axis_to_limit(dev.ftransy, "forward")
dev.ftransy.limits = [-100, 0]
@@ -414,6 +423,7 @@ class FlomniSampleTransferMixin:
raise FlomniError("Ftray is not at the 'IN' position. Aborting.")
def ftransfer_flomni_stage_in(self):
time.sleep(1)
sample_in_position = dev.flomni_samples.is_sample_slot_used(0)
#bool(float(dev.flomni_samples.sample_placed.sample0.get()))
if not sample_in_position:
@@ -428,7 +438,7 @@ class FlomniSampleTransferMixin:
umv(dev.fsamx, fsamx_in)
dev.fsamx.limits = [fsamx_in - 0.4, fsamx_in + 0.4]
self.flomnigui_idle()
#self.flomnigui_idle()
def laser_tracker_show_all(self):
dev.rtx.controller.laser_tracker_show_all()
@@ -586,6 +596,8 @@ class FlomniSampleTransferMixin:
if sample_in_position:
raise FlomniError(f"The planned put position [{position}] already has a sample.")
self.flomnigui_show_cameras()
self.ftransfer_gripper_move(position)
self.ftransfer_controller_enable_mount_mode()
@@ -611,7 +623,7 @@ class FlomniSampleTransferMixin:
self.ftransfer_controller_disable_mount_mode()
self.ensure_gripper_up()
sample_name = dev.flomni_samples.sample_in_gripper.get()
sample_name = dev.flomni_samples.sample_in_gripper_name.get()
self.flomni_modify_storage_non_interactive(100, 0, "-")
self.flomni_modify_storage_non_interactive(position, 1, sample_name)
@@ -1844,6 +1856,9 @@ class Flomni(
)
def tomo_scan_projection(self, angle: float):
dev.rtx.controller.laser_tracker_check_signalstrength()
scans = builtins.__dict__.get("scans")
# additional_correction = self.align.compute_additional_correction(angle)

View File

@@ -17,17 +17,10 @@ class flomniGuiToolsError(Exception):
class flomniGuiTools:
GUI_RPC_TIMEOUT = 20
def __init__(self):
self.text_box = None
self.progressbar = None
self.flomni_window = None
self.xeyegui = None
self.pdf_viewer = None
self.idle_text_box = None
self.camera_gripper_image = None
self.camera_overview_image = None
def set_client(self, client):
self.client = client
@@ -35,10 +28,9 @@ class flomniGuiTools:
def flomnigui_show_gui(self):
if "flomni" in self.gui.windows:
self.flomni_window = self.gui.windows["flomni"]
self.gui.flomni.raise_window()
else:
self.flomni_window = self.gui.new("flomni", timeout=self.GUI_RPC_TIMEOUT)
self.gui.new("flomni")
def flomnigui_stop_gui(self):
self.gui.flomni.hide()
@@ -48,11 +40,9 @@ class flomniGuiTools:
def flomnigui_show_xeyealign(self):
self.flomnigui_show_gui()
if self._flomnigui_is_missing("xeyegui"):
if self._flomnigui_check_attribute_not_exists("xeyegui"):
self.flomnigui_remove_all_docks()
self.xeyegui = self.gui.flomni.new(
"XRayEye", object_name="xrayeye", timeout=self.GUI_RPC_TIMEOUT
)
self.xeyegui = self.gui.flomni.new("XRayEye", object_name="xrayeye")
# start live
if not dev.cam_xeye.live_mode_enabled.get():
dev.cam_xeye.live_mode_enabled.put(True)
@@ -60,52 +50,49 @@ class flomniGuiTools:
def flomnigui_show_xeyealign_fittab(self):
self.flomnigui_show_gui()
if self._flomnigui_is_missing("xeyegui"):
if self._flomnigui_check_attribute_not_exists("xeyegui"):
self.flomnigui_remove_all_docks()
self.xeyegui = self.gui.flomni.new(
"XRayEye", object_name="xrayeye", timeout=self.GUI_RPC_TIMEOUT
)
self.xeyegui = self.gui.flomni.new("XRayEye")
self.xeyegui.switch_tab("fit")
def _flomnigui_check_attribute_not_exists(self, attribute_name):
if hasattr(self.gui, "flomni"):
if hasattr(self.gui.flomni, attribute_name):
return False
if attribute_name == "xeyegui":
if hasattr(self.gui.flomni, "xrayeye"):
return False
if attribute_name == "progressbar":
if hasattr(self.gui.flomni, "RingProgressBar"):
return False
if attribute_name == "cam_flomni_gripper" or attribute_name == "cam_flomni_overview":
if hasattr(self.gui.flomni, "Image") or hasattr(self.gui.flomni, "Image_0"):
return False
return True
def _flomnigui_is_missing(self, attribute_name):
widget = getattr(self, attribute_name, None)
if widget is None:
return True
if hasattr(widget, "_is_deleted") and widget._is_deleted():
return True
return False
def flomnigui_show_cameras(self):
self.flomnigui_show_gui()
if self._flomnigui_is_missing("camera_gripper_image") or self._flomnigui_is_missing(
"camera_overview_image"
):
if self._flomnigui_check_attribute_not_exists(
"cam_flomni_gripper"
) or self._flomnigui_check_attribute_not_exists("cam_flomni_overview"):
self.flomnigui_remove_all_docks()
self.camera_gripper_image = self.gui.flomni.new("Image")
camera_gripper_image = self.gui.flomni.new("Image")
if self._flomnicam_check_device_exists(dev.cam_flomni_gripper):
self.camera_gripper_image.image(device="cam_flomni_gripper", signal="preview")
self.camera_gripper_image.lock_aspect_ratio = True
self.camera_gripper_image.enable_fps_monitor = True
self.camera_gripper_image.enable_toolbar = False
self.camera_gripper_image.outer_axes = False
self.camera_gripper_image.inner_axes = False
camera_gripper_image.image(device="cam_flomni_gripper", signal="preview")
camera_gripper_image.lock_aspect_ratio = True
camera_gripper_image.enable_fps_monitor = True
camera_gripper_image.enable_toolbar = False
camera_gripper_image.outer_axes = False
camera_gripper_image.inner_axes = False
dev.cam_flomni_gripper.start_live_mode()
else:
print("Cannot open camera_gripper. Device does not exist.")
self.camera_overview_image = self.gui.flomni.new("Image")
camera_overview_image = self.gui.flomni.new("Image")
if self._flomnicam_check_device_exists(dev.cam_flomni_overview):
self.camera_overview_image.image(device="cam_flomni_overview", signal="preview")
self.camera_overview_image.lock_aspect_ratio = True
self.camera_overview_image.enable_fps_monitor = True
self.camera_overview_image.enable_toolbar = False
self.camera_overview_image.outer_axes = False
self.camera_overview_image.inner_axes = False
camera_overview_image.image(device="cam_flomni_overview", signal="preview")
camera_overview_image.lock_aspect_ratio = True
camera_overview_image.enable_fps_monitor = True
camera_overview_image.enable_toolbar = False
camera_overview_image.outer_axes = False
camera_overview_image.inner_axes = False
dev.cam_flomni_overview.start_live_mode()
else:
print("Cannot open camera_overview. Device does not exist.")
@@ -114,21 +101,15 @@ class flomniGuiTools:
# dev.cam_flomni_overview.stop_live_mode()
# dev.cam_flomni_gripper.stop_live_mode()
# dev.cam_xeye.live_mode = False
if "flomni" in self.gui.windows:
self.gui.flomni.delete_all(timeout=self.GUI_RPC_TIMEOUT)
self.gui.flomni.delete_all()
self.progressbar = None
self.text_box = None
self.xeyegui = None
self.pdf_viewer = None
self.idle_text_box = None
self.camera_gripper_image = None
self.camera_overview_image = None
def flomnigui_idle(self):
self.flomnigui_show_gui()
if self._flomnigui_is_missing("idle_text_box"):
if self._flomnigui_check_attribute_not_exists("idle_text_box"):
self.flomnigui_remove_all_docks()
self.idle_text_box = self.gui.flomni.new("TextBox")
idle_text_box = self.gui.flomni.new("TextBox")
text = (
"<pre>"
+ "██████╗ ███████╗ ██████╗ ███████╗██╗ ██████╗ ███╗ ███╗███╗ ██╗██╗\n"
@@ -139,7 +120,7 @@ class flomniGuiTools:
+ "╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝\n"
+ "</pre>"
)
self.idle_text_box.set_html_text(text)
idle_text_box.set_html_text(text)
def flomnigui_docs(self, filename: str | None = None):
import csaxs_bec
@@ -183,7 +164,7 @@ class flomniGuiTools:
# --- GUI handling (active existence check) ----------------------------
self.flomnigui_show_gui()
if self._flomnigui_is_missing("pdf_viewer"):
if self._flomnigui_check_attribute_not_exists("PdfViewerWidget"):
self.flomnigui_remove_all_docks()
self.pdf_viewer = self.gui.flomni.new(widget="PdfViewerWidget")
@@ -201,7 +182,7 @@ class flomniGuiTools:
def flomnigui_show_progress(self):
self.flomnigui_show_gui()
if self._flomnigui_is_missing("progressbar"):
if self._flomnigui_check_attribute_not_exists("progressbar"):
self.flomnigui_remove_all_docks()
# Add a new dock with a RingProgressBar widget
self.progressbar = self.gui.flomni.new("RingProgressBar")

View File

@@ -49,6 +49,8 @@ class XrayEyeAlign:
self._xray_fov_xy = [0, 0]
def update_frame(self, keep_shutter_open=False):
if self.flomni._flomnigui_check_attribute_not_exists("xeyegui"):
self.flomni.flomnigui_show_xeyealign()
if not dev.cam_xeye.live_mode_enabled.get():
dev.cam_xeye.live_mode_enabled.put(True)
@@ -245,7 +247,13 @@ class XrayEyeAlign:
)
print("Check the fit in the GUI...")
print("Then LOAD ALIGNMENT PARAMETERS by running flomni.read_alignment_offset()\n")
time.sleep(5)
print("Automatically loading new alignment parameters from xray eye alignment.\n")
self.flomni.read_alignment_offset()
print("You are ready to remove the xray eye and start ptychography scans.")
def write_output(self):
file = os.path.expanduser("~/Data10/specES1/internal/xrayeye_alignmentvalues")
@@ -266,7 +274,7 @@ class XrayEyeAlign:
fovx_x = (k - 1) * 45
fovx_list.append([fovx_x, fovx_offset * 1000]) # Append the data to the list
print(f"Writing to file new alignment: number {k}, value x {fovx_offset}")
print(f"Alignment number {k}, value x {fovx_offset}")
alignment_values_file.write(f"{fovx_x}\t{fovx_offset * 1000}\n")
# Now build final numpy array:

View File

@@ -38,14 +38,12 @@ class XRayEye(RPCBase):
None
"""
@rpc_timeout(20)
@rpc_call
def on_live_view_enabled(self, enabled: "bool"):
"""
None
"""
@rpc_timeout(20)
@rpc_call
def on_motors_enable(self, x_enable: "bool", y_enable: "bool"):
"""
@@ -56,7 +54,6 @@ class XRayEye(RPCBase):
y_enable(bool): enable y motor controls
"""
@rpc_timeout(20)
@rpc_call
def enable_submit_button(self, enable: "bool"):
"""
@@ -93,14 +90,12 @@ class XRayEye(RPCBase):
None
"""
@rpc_timeout(20)
@rpc_call
def switch_tab(self, tab: "str"):
"""
None
"""
@rpc_timeout(20)
@rpc_call
def submit_fit_array(self, fit_array):
"""

View File

@@ -4,7 +4,6 @@ from bec_lib import bec_logger
from bec_lib.endpoints import MessageEndpoints
from bec_qthemes import material_icon
from bec_widgets import BECWidget, SafeProperty, SafeSlot
from bec_widgets.utils.rpc_decorator import rpc_timeout
from bec_widgets.widgets.plots.image.image import Image
from bec_widgets.widgets.plots.waveform.waveform import Waveform
from bec_widgets.widgets.plots.image.setting_widgets.image_roi_tree import ROIPropertyTree
@@ -26,7 +25,6 @@ from qtpy.QtWidgets import (
QTextEdit,
QTabWidget,
)
import time
logger = bec_logger.logger
CAMERA = ("cam_xeye", "image")
@@ -147,6 +145,7 @@ class XRayEye(BECWidget, QWidget):
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent, **kwargs)
self._connected_motor = None
self.get_bec_shortcuts()
self._init_ui()
@@ -358,16 +357,16 @@ class XRayEye(BECWidget, QWidget):
self.on_tomo_angle_readback, MessageEndpoints.device_readback(motor)
)
logger.info(f"Successfully connected to {motor}")
self._connected_motor = motor
################################################################################
# Properties ported from the original OmnyAlignment, can be adjusted as needed
################################################################################
@SafeProperty(str)
def user_message(self):
return self.message_line_edit.text()
return self.message_line_edit.toPlainText()
@user_message.setter
@rpc_timeout(20)
def user_message(self, message: str):
self.message_line_edit.setText(message)
@@ -376,7 +375,6 @@ class XRayEye(BECWidget, QWidget):
return self.sample_name_line_edit.text()
@sample_name.setter
@rpc_timeout(20)
def sample_name(self, message: str):
self.sample_name_line_edit.setText(message)
@@ -397,7 +395,6 @@ class XRayEye(BECWidget, QWidget):
################################################################################
@SafeSlot(str)
@rpc_timeout(20)
def switch_tab(self, tab: str):
if tab == "fit":
self.tab_widget.setCurrentIndex(1)
@@ -415,7 +412,6 @@ class XRayEye(BECWidget, QWidget):
return roi.get_coordinates()
@SafeSlot(bool)
@rpc_timeout(20)
def on_live_view_enabled(self, enabled: bool):
logger.info(f"Live view is enabled: {enabled}")
self.live_preview_toggle.blockSignals(True)
@@ -464,7 +460,6 @@ class XRayEye(BECWidget, QWidget):
self.shutter_toggle.blockSignals(False)
@SafeSlot(bool, bool)
@rpc_timeout(20)
def on_motors_enable(self, x_enable: bool, y_enable: bool):
"""
Enable/Disable motor controls
@@ -477,7 +472,6 @@ class XRayEye(BECWidget, QWidget):
self.motor_control_2d.enable_controls_ver(y_enable)
@SafeSlot(bool)
@rpc_timeout(20)
def enable_submit_button(self, enable: bool):
"""
Enable/disable submit button.
@@ -515,7 +509,6 @@ class XRayEye(BECWidget, QWidget):
print(f"meta: {meta}")
@SafeSlot()
@rpc_timeout(20)
def submit_fit_array(self, fit_array):
self.tab_widget.setCurrentIndex(1)
# self.fix_x.title = " got fit array"
@@ -528,44 +521,50 @@ class XRayEye(BECWidget, QWidget):
@SafeSlot()
def submit(self):
"""Execute submit action by submit button."""
print("submit pushed")
self.submit_button.blockSignals(True)
if self.roi_manager.single_active_roi is None:
logger.warning("No active ROI")
return
roi_coordinates = self.roi_manager.single_active_roi.get_coordinates()
roi_center_x = roi_coordinates["center_x"]
roi_center_y = roi_coordinates["center_y"]
# Case of rectangular ROI
if isinstance(self.roi_manager.single_active_roi, RectangularROI):
roi_width = roi_coordinates["width"]
roi_height = roi_coordinates["height"]
elif isinstance(self.roi_manager.single_active_roi, CircularROI):
roi_width = roi_coordinates["diameter"]
roi_height = roi_coordinates["radius"]
else:
logger.warning("Unsupported ROI type for submit action.")
return
try:
if self.roi_manager.single_active_roi is None:
logger.warning("No active ROI")
return
roi_coordinates = self.roi_manager.single_active_roi.get_coordinates()
roi_center_x = roi_coordinates["center_x"]
roi_center_y = roi_coordinates["center_y"]
# Case of rectangular ROI
if isinstance(self.roi_manager.single_active_roi, RectangularROI):
roi_width = roi_coordinates["width"]
roi_height = roi_coordinates["height"]
elif isinstance(self.roi_manager.single_active_roi, CircularROI):
roi_width = roi_coordinates["diameter"]
roi_height = roi_coordinates["radius"]
else:
logger.warning("Unsupported ROI type for submit action.")
return
print(
f"current roi: x:{roi_center_x}, y:{roi_center_y}, w:{roi_width},h:{roi_height}"
) # TODO remove when will be not needed for debugging
# submit roi coordinates
step = int(self.dev.omny_xray_gui.step.read().get("omny_xray_gui_step").get("value"))
# submit roi coordinates
step = int(self.dev.omny_xray_gui.step.read().get("omny_xray_gui_step").get("value"))
xval_x = getattr(self.dev.omny_xray_gui, f"xval_x_{step}").set(roi_center_x)
xval_y = getattr(self.dev.omny_xray_gui, f"yval_y_{step}").set(roi_center_y)
width_x = getattr(self.dev.omny_xray_gui, f"width_x_{step}").set(roi_width)
width_y = getattr(self.dev.omny_xray_gui, f"width_y_{step}").set(roi_height)
self.dev.omny_xray_gui.submit.set(1)
print("submit done")
self.submit_button.blockSignals(False)
getattr(self.dev.omny_xray_gui, f"xval_x_{step}").set(roi_center_x)
getattr(self.dev.omny_xray_gui, f"yval_y_{step}").set(roi_center_y)
getattr(self.dev.omny_xray_gui, f"width_x_{step}").set(roi_width)
getattr(self.dev.omny_xray_gui, f"width_y_{step}").set(roi_height)
self.dev.omny_xray_gui.submit.set(1)
finally:
self.submit_button.blockSignals(False)
def cleanup(self):
"""Cleanup connections on widget close -> disconnect slots and stop live mode of camera."""
if self._connected_motor is not None:
self.bec_dispatcher.disconnect_slot(
self.on_tomo_angle_readback, MessageEndpoints.device_readback(self._connected_motor)
)
self.bec_dispatcher.disconnect_slot(
self.device_updates, MessageEndpoints.device_readback("omny_xray_gui")
self.getting_shutter_status, MessageEndpoints.device_readback("omnyfsh")
)
self.bec_dispatcher.disconnect_slot(
self.getting_camera_status, MessageEndpoints.device_read_configuration(CAMERA[0])
)
getattr(self.dev, CAMERA[0]).stop_live_mode()
super().cleanup()

View File

@@ -175,7 +175,10 @@ class RtFlomniController(Controller):
self.set_device_read_write("fopty", False)
def move_samx_to_scan_region(self, fovx: float, cenx: float):
#new routine not using fovx anymore
self.device_manager.devices.rtx.obj.move(cenx, wait=True)
time.sleep(0.05)
#at cenx we expect the PID to be close to zero for a good fsamx position
if self.rt_pid_voltage is None:
rtx = self.device_manager.devices.rtx
self.rt_pid_voltage = rtx.user_parameter.get("rt_pid_voltage")
@@ -184,31 +187,39 @@ class RtFlomniController(Controller):
"rt_pid_voltage not set in rtx user parameters. Please run feedback_enable_with_reset first."
)
logger.info(f"Using PID voltage from rtx user parameter: {self.rt_pid_voltage}")
expected_voltage = self.rt_pid_voltage + fovx / 2 * 7 / 100
logger.info(f"Expected PID voltage: {expected_voltage}")
expected_voltage = self.rt_pid_voltage
#logger.info(f"Expected PID voltage: {expected_voltage}")
logger.info(f"Current PID voltage: {self.get_pid_x()}")
wait_on_exit = False
while True:
if np.abs(self.get_pid_x() - expected_voltage) < 1:
break
wait_on_exit = True
self.socket_put("v0")
#we allow 2V range from center, this corresponds to 30 microns
if np.abs(self.get_pid_x() - expected_voltage) < 2:
logger.info("No correction of fsamx needed")
else:
fsamx = self.device_manager.devices.fsamx
fsamx.read_only = False
fsamx.obj.controller.socket_put_confirmed("axspeed[4]=0.1*stppermm[4]")
fsamx.obj.pid_x_correction -= (self.get_pid_x() - expected_voltage) * 0.007
logger.info(f"Correcting fsamx by {fsamx.obj.pid_x_correction}")
fsamx_in = fsamx.user_parameter.get("in")
fsamx.obj.move(fsamx_in + cenx / 1000 + fsamx.obj.pid_x_correction, wait=True)
fsamx.read_only = True
time.sleep(0.1)
self.laser_tracker_on()
time.sleep(0.01)
while True:
#when we correct, then to 1 V, within 15 microns
if np.abs(self.get_pid_x() - expected_voltage) < 1:
logger.info("No further correction needed")
break
wait_on_exit = True
#disable FZP piezo feedback
self.socket_put("v0")
fsamx.read_only = False
logger.info(f"Current PID voltage: {self.get_pid_x()}")
#here we accumulate the correction
fsamx.obj.pid_x_correction -= (self.get_pid_x() - expected_voltage) * 0.006
fsamx_in = fsamx.user_parameter.get("in")
logger.info(f"Moving fsamx to {cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction}, PID portion of that {fsamx.obj.pid_x_correction}")
fsamx.obj.move(fsamx_in + cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction, wait=True)
fsamx.read_only = True
time.sleep(0.1)
self.laser_tracker_on()
time.sleep(0.01)
if wait_on_exit:
time.sleep(1)
#enable fast FZP feedback again
self.socket_put("v1")
@threadlocked

View File

@@ -24,9 +24,11 @@ import time
import numpy as np
from bec_lib import bec_logger, messages
from bec_lib.alarm_handler import Alarms
from bec_lib.endpoints import MessageEndpoints
from bec_server.scan_server.errors import ScanAbortion
from bec_server.scan_server.scans import SyncFlyScanBase
from csaxs_bec.devices.epics.delay_generator_csaxs.delay_generator_csaxs import TRIGGERSOURCE
logger = bec_logger.logger
@@ -52,7 +54,7 @@ class FlomniFermatScan(SyncFlyScanBase):
angle: float = None,
corridor_size: float = 3,
parameter: dict = None,
frames_per_trigger:int=1,
frames_per_trigger: int = 1,
**kwargs,
):
"""
@@ -76,7 +78,9 @@ class FlomniFermatScan(SyncFlyScanBase):
>>> scans.flomni_fermat_scan(fovx=20, fovy=25, cenx=0.02, ceny=0, zshift=0, angle=0, step=0.5, exp_time=0.01, frames_per_trigger=1)
"""
super().__init__(parameter=parameter, exp_time=exp_time, frames_per_trigger=frames_per_trigger, **kwargs)
super().__init__(
parameter=parameter, exp_time=exp_time, frames_per_trigger=frames_per_trigger, **kwargs
)
self.show_live_table = False
self.axis = []
self.fovx = fovx
@@ -153,9 +157,11 @@ class FlomniFermatScan(SyncFlyScanBase):
yield from self.stubs.send_rpc_and_wait("rty", "set", self.positions[0][1])
def _prepare_setup_part2(self):
# Prepare DDG1 to use
yield from self.stubs.send_rpc_and_wait("ddg1", "set_trigger", TRIGGERSOURCE.EXT_RISING_EDGE.value)
# Prepare DDG1 to use
yield from self.stubs.send_rpc_and_wait(
"ddg1", "set_trigger", TRIGGERSOURCE.EXT_RISING_EDGE.value
)
if self.flomni_rotation_status:
self.flomni_rotation_status.wait()
@@ -174,15 +180,15 @@ class FlomniFermatScan(SyncFlyScanBase):
tracker_signal_status = yield from self.stubs.send_rpc_and_wait(
"rtx", "controller.laser_tracker_check_signalstrength"
)
#self.device_manager.connector.send_client_info(tracker_signal_status)
# self.device_manager.connector.send_client_info(tracker_signal_status)
if tracker_signal_status == "low":
self.device_manager.connector.raise_alarm(
severity=0,
alarm_type="LaserTrackerSignalStrength",
source={"device": "rtx", "reason": "low signal strength", "method": "_prepare_setup_part2"},
metadata={},
msg="Signal strength of the laser tracker is low, sufficient to continue. Realignment recommended!",
error_info = messages.ErrorInfo(
error_message="Signal strength of the laser tracker is low, but sufficient to continue. Realignment recommended!",
compact_error_message="Low signal strength of the laser tracker. Realignment recommended!",
exception_type="LaserTrackerSignalStrengthLow",
device="rtx",
)
self.device_manager.connector.raise_alarm(severity=Alarms.WARNING, info=error_info)
elif tracker_signal_status == "toolow":
raise ScanAbortion(
"Signal strength of the laser tracker is too low for scanning. Realignment required!"
@@ -313,7 +319,9 @@ class FlomniFermatScan(SyncFlyScanBase):
logger.warning("No positions found to return to start")
def cleanup(self):
yield from self.stubs.send_rpc_and_wait("ddg1", "set_trigger", TRIGGERSOURCE.SINGLE_SHOT.value)
yield from self.stubs.send_rpc_and_wait(
"ddg1", "set_trigger", TRIGGERSOURCE.SINGLE_SHOT.value
)
yield from super().cleanup()
def run(self):