Compare commits

..

5 Commits

Author SHA1 Message Date
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 623 additions and 586 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

@@ -57,15 +57,22 @@ class flomniGuiTools:
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_show_cameras(self):
self.flomnigui_show_gui()
if self._flomnigui_check_attribute_not_exists(
"camera_gripper"
) or self._flomnigui_check_attribute_not_exists("camera_overview"):
"cam_flomni_gripper"
) or self._flomnigui_check_attribute_not_exists("cam_flomni_overview"):
self.flomnigui_remove_all_docks()
camera_gripper_image = self.gui.flomni.new("Image")
if self._flomnicam_check_device_exists(dev.cam_flomni_gripper):

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

@@ -25,7 +25,6 @@ from qtpy.QtWidgets import (
QTextEdit,
QTabWidget,
)
import time
logger = bec_logger.logger
CAMERA = ("cam_xeye", "image")
@@ -146,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()
@@ -357,13 +357,14 @@ 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
def user_message(self, message: str):
@@ -520,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()

File diff suppressed because it is too large Load Diff

View File

@@ -10,8 +10,8 @@
endstation:
- !include ./bl_endstation.yaml
# detectors:
# - !include ./bl_detectors.yaml
detectors:
- !include ./bl_detectors.yaml
#sastt:
# - !include ./sastt.yaml

View File

@@ -288,7 +288,7 @@ fosax:
limits:
- 10.2
- 10.6
port: 3332
port: 3334
sign: -1
enabled: true
onFailure: buffer
@@ -307,7 +307,7 @@ fosay:
limits:
- -3.1
- -2.9
port: 3332
port: 3334
sign: -1
enabled: true
onFailure: buffer
@@ -325,7 +325,7 @@ fosaz:
limits:
- -6
- -4
port: 3332
port: 3334
sign: 1
enabled: true
onFailure: buffer
@@ -429,20 +429,20 @@ cam_xeye:
readOnly: false
readoutPriority: async
cam_ids_rgb:
description: Camera flOMNI Xray eye ID203
deviceClass: csaxs_bec.devices.ids_cameras.ids_camera.IDSCamera
deviceConfig:
camera_id: 2
bits_per_pixel: 24
num_rotation_90: 2
transpose: true
force_monochrome: false
m_n_colormode: 1
enabled: true
onFailure: buffer
readOnly: false
readoutPriority: async
# cam_ids_rgb:
# description: Camera flOMNI Xray eye ID203
# deviceClass: csaxs_bec.devices.ids_cameras.ids_camera.IDSCamera
# deviceConfig:
# camera_id: 203
# bits_per_pixel: 24
# num_rotation_90: 2
# transpose: false
# force_monochrome: false
# m_n_colormode: 1
# enabled: true
# onFailure: buffer
# readOnly: false
# readoutPriority: async
# ############################################################
@@ -490,21 +490,21 @@ calculated_signal:
############################################################
#################### OMNY Pandabox #########################
# ############################################################
# omny_panda:
# readoutPriority: async
# deviceClass: csaxs_bec.devices.panda_box.panda_box_omny.PandaBoxOMNY
# deviceConfig:
# host: omny-panda.psi.ch
# signal_alias:
# FMC_IN.VAL1.Min: cap_voltage_fzp_y_min
# FMC_IN.VAL1.Max: cap_voltage_fzp_y_max
# FMC_IN.VAL1.Mean: cap_voltage_fzp_y_mean
# FMC_IN.VAL2.Min: cap_voltage_fzp_x_min
# FMC_IN.VAL2.Max: cap_voltage_fzp_x_max
# FMC_IN.VAL2.Mean: cap_voltage_fzp_x_mean
# deviceTags:
# - detector
# enabled: true
# readOnly: false
# softwareTrigger: false
############################################################
omny_panda:
readoutPriority: async
deviceClass: csaxs_bec.devices.panda_box.panda_box_omny.PandaBoxOMNY
deviceConfig:
host: omny-panda.psi.ch
signal_alias:
FMC_IN.VAL1.Min: cap_voltage_fzp_y_min
FMC_IN.VAL1.Max: cap_voltage_fzp_y_max
FMC_IN.VAL1.Mean: cap_voltage_fzp_y_mean
FMC_IN.VAL2.Min: cap_voltage_fzp_x_min
FMC_IN.VAL2.Max: cap_voltage_fzp_x_max
FMC_IN.VAL2.Mean: cap_voltage_fzp_x_mean
deviceTags:
- detector
enabled: true
readOnly: false
softwareTrigger: false