|
|
|
|
@@ -33,46 +33,48 @@ class XRayEye2DControl(BECWidget, QWidget):
|
|
|
|
|
self.get_bec_shortcuts()
|
|
|
|
|
self._step_size = step_size
|
|
|
|
|
self.root_layout = QGridLayout(self)
|
|
|
|
|
self.setStyleSheet("""
|
|
|
|
|
self.setStyleSheet(
|
|
|
|
|
"""
|
|
|
|
|
QToolButton {
|
|
|
|
|
border: 1px solid;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
""")
|
|
|
|
|
"""
|
|
|
|
|
)
|
|
|
|
|
# Up
|
|
|
|
|
self.move_up_button = QToolButton(parent=self)
|
|
|
|
|
self.move_up_button.setIcon(material_icon('keyboard_double_arrow_up'))
|
|
|
|
|
self.move_up_button.setIcon(material_icon("keyboard_double_arrow_up"))
|
|
|
|
|
self.root_layout.addWidget(self.move_up_button, 0, 2)
|
|
|
|
|
# Up tweak button
|
|
|
|
|
self.move_up_tweak_button = QToolButton(parent=self)
|
|
|
|
|
self.move_up_tweak_button.setIcon(material_icon('keyboard_arrow_up'))
|
|
|
|
|
self.move_up_tweak_button.setIcon(material_icon("keyboard_arrow_up"))
|
|
|
|
|
self.root_layout.addWidget(self.move_up_tweak_button, 1, 2)
|
|
|
|
|
|
|
|
|
|
# Left
|
|
|
|
|
self.move_left_button = QToolButton(parent=self)
|
|
|
|
|
self.move_left_button.setIcon(material_icon('keyboard_double_arrow_left'))
|
|
|
|
|
self.move_left_button.setIcon(material_icon("keyboard_double_arrow_left"))
|
|
|
|
|
self.root_layout.addWidget(self.move_left_button, 2, 0)
|
|
|
|
|
# Left tweak button
|
|
|
|
|
self.move_left_tweak_button = QToolButton(parent=self)
|
|
|
|
|
self.move_left_tweak_button.setIcon(material_icon('keyboard_arrow_left'))
|
|
|
|
|
self.move_left_tweak_button.setIcon(material_icon("keyboard_arrow_left"))
|
|
|
|
|
self.root_layout.addWidget(self.move_left_tweak_button, 2, 1)
|
|
|
|
|
|
|
|
|
|
# Right
|
|
|
|
|
self.move_right_button = QToolButton(parent=self)
|
|
|
|
|
self.move_right_button.setIcon(material_icon('keyboard_double_arrow_right'))
|
|
|
|
|
self.move_right_button.setIcon(material_icon("keyboard_double_arrow_right"))
|
|
|
|
|
self.root_layout.addWidget(self.move_right_button, 2, 4)
|
|
|
|
|
# Right tweak button
|
|
|
|
|
self.move_right_tweak_button = QToolButton(parent=self)
|
|
|
|
|
self.move_right_tweak_button.setIcon(material_icon('keyboard_arrow_right'))
|
|
|
|
|
self.move_right_tweak_button.setIcon(material_icon("keyboard_arrow_right"))
|
|
|
|
|
self.root_layout.addWidget(self.move_right_tweak_button, 2, 3)
|
|
|
|
|
|
|
|
|
|
# Down
|
|
|
|
|
self.move_down_button = QToolButton(parent=self)
|
|
|
|
|
self.move_down_button.setIcon(material_icon('keyboard_double_arrow_down'))
|
|
|
|
|
self.move_down_button.setIcon(material_icon("keyboard_double_arrow_down"))
|
|
|
|
|
self.root_layout.addWidget(self.move_down_button, 4, 2)
|
|
|
|
|
# Down tweak button
|
|
|
|
|
self.move_down_tweak_button = QToolButton(parent=self)
|
|
|
|
|
self.move_down_tweak_button.setIcon(material_icon('keyboard_arrow_down'))
|
|
|
|
|
self.move_down_tweak_button.setIcon(material_icon("keyboard_arrow_down"))
|
|
|
|
|
self.root_layout.addWidget(self.move_down_tweak_button, 3, 2)
|
|
|
|
|
|
|
|
|
|
# Connections
|
|
|
|
|
@@ -124,8 +126,15 @@ class XRayEye2DControl(BECWidget, QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class XRayEye(BECWidget, QWidget):
|
|
|
|
|
USER_ACCESS = ["active_roi", "enable_live_view", "enable_live_view.setter", "user_message", "user_message.setter",
|
|
|
|
|
"sample_name", "sample_name.setter", "enable_move_buttons", "enable_move_buttons.setter"]
|
|
|
|
|
USER_ACCESS = [
|
|
|
|
|
"active_roi",
|
|
|
|
|
"user_message",
|
|
|
|
|
"user_message.setter",
|
|
|
|
|
"sample_name",
|
|
|
|
|
"sample_name.setter",
|
|
|
|
|
"enable_move_buttons",
|
|
|
|
|
"enable_move_buttons.setter",
|
|
|
|
|
]
|
|
|
|
|
PLUGIN = True
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent=None, **kwargs):
|
|
|
|
|
@@ -136,7 +145,9 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
self._make_connections()
|
|
|
|
|
|
|
|
|
|
# Connection to redis endpoints
|
|
|
|
|
self.bec_dispatcher.connect_slot(self.device_updates, MessageEndpoints.device_readback("omny_xray_gui"))
|
|
|
|
|
self.bec_dispatcher.connect_slot(
|
|
|
|
|
self.device_updates, MessageEndpoints.device_readback("omny_xray_gui")
|
|
|
|
|
)
|
|
|
|
|
self.connect_motors()
|
|
|
|
|
self.resize(800, 600)
|
|
|
|
|
QTimer.singleShot(0, self._init_gui_trigger)
|
|
|
|
|
@@ -145,7 +156,9 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
self.core_layout = QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
self.image = Image(parent=self)
|
|
|
|
|
self.image.enable_toolbar = False # Disable default toolbar to not allow to user set anything
|
|
|
|
|
self.image.enable_toolbar = (
|
|
|
|
|
False # Disable default toolbar to not allow to user set anything
|
|
|
|
|
)
|
|
|
|
|
self.image.inner_axes = False # Disable inner axes to maximize image area
|
|
|
|
|
self.image.plot_item.vb.invertY(True) # #TODO Invert y axis to match logic of LabView GUI
|
|
|
|
|
|
|
|
|
|
@@ -156,8 +169,9 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
self.control_panel_layout.setSpacing(10)
|
|
|
|
|
|
|
|
|
|
# ROI toolbar + Live toggle (header row)
|
|
|
|
|
self.roi_manager = ROIPropertyTree(parent=self, image_widget=self.image, compact=True,
|
|
|
|
|
compact_orientation="horizontal")
|
|
|
|
|
self.roi_manager = ROIPropertyTree(
|
|
|
|
|
parent=self, image_widget=self.image, compact=True, compact_orientation="horizontal"
|
|
|
|
|
)
|
|
|
|
|
header_row = QHBoxLayout()
|
|
|
|
|
header_row.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
header_row.setSpacing(8)
|
|
|
|
|
@@ -230,7 +244,9 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
|
|
|
|
|
# Make connections
|
|
|
|
|
self.live_preview_toggle.enabled.connect(self.on_live_view_enabled)
|
|
|
|
|
self.step_size.valueChanged.connect(lambda x: self.motor_control_2d.setProperty("step_size", x))
|
|
|
|
|
self.step_size.valueChanged.connect(
|
|
|
|
|
lambda x: self.motor_control_2d.setProperty("step_size", x)
|
|
|
|
|
)
|
|
|
|
|
self.submit_button.clicked.connect(self.submit)
|
|
|
|
|
|
|
|
|
|
def _create_separator(self):
|
|
|
|
|
@@ -248,12 +264,14 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
def connect_motors(self):
|
|
|
|
|
""" Checks one of the possible motors for flomni, omny and lamni setup."""
|
|
|
|
|
possible_motors = ['osamroy', 'lsamrot', 'fsamroy']
|
|
|
|
|
"""Checks one of the possible motors for flomni, omny and lamni setup."""
|
|
|
|
|
possible_motors = ["osamroy", "lsamrot", "fsamroy"]
|
|
|
|
|
|
|
|
|
|
for motor in possible_motors:
|
|
|
|
|
if motor in self.dev:
|
|
|
|
|
self.bec_dispatcher.connect_slot(self.on_tomo_angle_readback, MessageEndpoints.device_readback(motor))
|
|
|
|
|
self.bec_dispatcher.connect_slot(
|
|
|
|
|
self.on_tomo_angle_readback, MessageEndpoints.device_readback(motor)
|
|
|
|
|
)
|
|
|
|
|
logger.info(f"Succesfully connected to {motor}")
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
|
@@ -341,7 +359,7 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
|
|
|
|
|
@SafeSlot(bool, bool)
|
|
|
|
|
def on_tomo_angle_readback(self, data: dict, meta: dict):
|
|
|
|
|
#TODO implement if needed
|
|
|
|
|
# TODO implement if needed
|
|
|
|
|
print(f"data: {data}")
|
|
|
|
|
print(f"meta: {meta}")
|
|
|
|
|
|
|
|
|
|
@@ -355,25 +373,25 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
meta(dict): metadata from device
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
signals = data.get('signals')
|
|
|
|
|
enable_live_preview = signals.get("omny_xray_gui_update_frame_acq").get('value')
|
|
|
|
|
enable_x_motor = signals.get("omny_xray_gui_enable_mv_x").get('value')
|
|
|
|
|
enable_y_motor = signals.get("omny_xray_gui_enable_mv_y").get('value')
|
|
|
|
|
signals = data.get("signals")
|
|
|
|
|
enable_live_preview = signals.get("omny_xray_gui_update_frame_acq").get("value")
|
|
|
|
|
enable_x_motor = signals.get("omny_xray_gui_enable_mv_x").get("value")
|
|
|
|
|
enable_y_motor = signals.get("omny_xray_gui_enable_mv_y").get("value")
|
|
|
|
|
self.on_live_view_enabled(bool(enable_live_preview))
|
|
|
|
|
self.on_motors_enable(bool(enable_x_motor), bool(enable_y_motor))
|
|
|
|
|
|
|
|
|
|
# Signals from epics gui device
|
|
|
|
|
# send message
|
|
|
|
|
user_message = signals.get("omny_xray_gui_send_message").get('value')
|
|
|
|
|
user_message = signals.get("omny_xray_gui_send_message").get("value")
|
|
|
|
|
self.user_message = user_message
|
|
|
|
|
# sample name
|
|
|
|
|
sample_message = signals.get("omny_xray_gui_sample_name").get('value')
|
|
|
|
|
sample_message = signals.get("omny_xray_gui_sample_name").get("value")
|
|
|
|
|
self.sample_name = sample_message
|
|
|
|
|
# enable frame acquisition
|
|
|
|
|
update_frame_acq = signals.get("omny_xray_gui_update_frame_acq").get('value')
|
|
|
|
|
update_frame_acq = signals.get("omny_xray_gui_update_frame_acq").get("value")
|
|
|
|
|
self.on_live_view_enabled(bool(update_frame_acq))
|
|
|
|
|
# enable submit button
|
|
|
|
|
enable_submit_button = signals.get("omny_xray_gui_submit").get('value')
|
|
|
|
|
enable_submit_button = signals.get("omny_xray_gui_submit").get("value")
|
|
|
|
|
self.enable_submit_button(enable_submit_button)
|
|
|
|
|
|
|
|
|
|
@SafeSlot()
|
|
|
|
|
@@ -383,35 +401,40 @@ class XRayEye(BECWidget, QWidget):
|
|
|
|
|
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']
|
|
|
|
|
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']
|
|
|
|
|
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']
|
|
|
|
|
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
|
|
|
|
|
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'))
|
|
|
|
|
step = int(self.dev.omny_xray_gui.step.read().get("omny_xray_gui_step").get("value"))
|
|
|
|
|
|
|
|
|
|
xval_x = getattr(self.dev.omny_xray_gui.xval_x, f"xval_x_{step}").set(roi_center_x)
|
|
|
|
|
xval_y = getattr(self.dev.omny_xray_gui.yval_y, f"yval_y_{step}").set(roi_center_y)
|
|
|
|
|
width_x = getattr(self.dev.omny_xray_gui.width_x, f"width_x_{step}").set(roi_width)
|
|
|
|
|
width_y = getattr(self.dev.omny_xray_gui.width_y, f"width_y_{step}").set(roi_height)
|
|
|
|
|
self.dev.omny_xray_gui.submit.set(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cleanup(self):
|
|
|
|
|
"""Cleanup connections on widget close -> disconnect slots and stop live mode of camera."""
|
|
|
|
|
self.bec_dispatcher.disconnect_slot(self.device_updates, MessageEndpoints.device_readback("omny_xray_gui"))
|
|
|
|
|
getattr(self.dev,CAMERA[0]).live_mode = False
|
|
|
|
|
self.bec_dispatcher.disconnect_slot(
|
|
|
|
|
self.device_updates, MessageEndpoints.device_readback("omny_xray_gui")
|
|
|
|
|
)
|
|
|
|
|
getattr(self.dev, CAMERA[0]).live_mode = False
|
|
|
|
|
super().cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|