|
|
|
@@ -0,0 +1,423 @@
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
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.widgets.plots.image.image import Image
|
|
|
|
|
from bec_widgets.widgets.plots.image.setting_widgets.image_roi_tree import ROIPropertyTree
|
|
|
|
|
from bec_widgets.widgets.plots.roi.image_roi import BaseROI, CircularROI, RectangularROI
|
|
|
|
|
from bec_widgets.widgets.utility.toggle.toggle import ToggleSwitch
|
|
|
|
|
from qtpy.QtCore import Qt, QTimer
|
|
|
|
|
from qtpy.QtWidgets import (
|
|
|
|
|
QFrame,
|
|
|
|
|
QGridLayout,
|
|
|
|
|
QHBoxLayout,
|
|
|
|
|
QLabel,
|
|
|
|
|
QLineEdit,
|
|
|
|
|
QPushButton,
|
|
|
|
|
QSizePolicy,
|
|
|
|
|
QSpinBox,
|
|
|
|
|
QToolButton,
|
|
|
|
|
QVBoxLayout,
|
|
|
|
|
QWidget,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
logger = bec_logger.logger
|
|
|
|
|
CAMERA = ("cam_xeye_rgb", "image") #TODO here put correct camera
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class XRayEye2DControl(BECWidget, QWidget):
|
|
|
|
|
def __init__(self, parent=None, step_size: int = 100, *arg, **kwargs):
|
|
|
|
|
super().__init__(parent=parent, *arg, **kwargs)
|
|
|
|
|
self.get_bec_shortcuts()
|
|
|
|
|
self._step_size = step_size
|
|
|
|
|
self.root_layout = QGridLayout(self)
|
|
|
|
|
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.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.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.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.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.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.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.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.root_layout.addWidget(self.move_down_tweak_button, 3, 2)
|
|
|
|
|
|
|
|
|
|
# Connections
|
|
|
|
|
self.move_up_button.clicked.connect(lambda: self.move("up", tweak=False))
|
|
|
|
|
self.move_up_tweak_button.clicked.connect(lambda: self.move("up", tweak=True))
|
|
|
|
|
self.move_down_button.clicked.connect(lambda: self.move("down", tweak=False))
|
|
|
|
|
self.move_down_tweak_button.clicked.connect(lambda: self.move("down", tweak=True))
|
|
|
|
|
self.move_left_button.clicked.connect(lambda: self.move("left", tweak=False))
|
|
|
|
|
self.move_left_tweak_button.clicked.connect(lambda: self.move("left", tweak=True))
|
|
|
|
|
self.move_right_button.clicked.connect(lambda: self.move("right", tweak=False))
|
|
|
|
|
self.move_right_tweak_button.clicked.connect(lambda: self.move("right", tweak=True))
|
|
|
|
|
|
|
|
|
|
@SafeProperty(int)
|
|
|
|
|
def step_size(self) -> int:
|
|
|
|
|
return self._step_size
|
|
|
|
|
|
|
|
|
|
@step_size.setter
|
|
|
|
|
def step_size(self, step_size: int):
|
|
|
|
|
self._step_size = step_size
|
|
|
|
|
|
|
|
|
|
@SafeSlot(bool)
|
|
|
|
|
def enable_controls_hor(self, enable: bool):
|
|
|
|
|
self.move_left_button.setEnabled(enable)
|
|
|
|
|
self.move_left_tweak_button.setEnabled(enable)
|
|
|
|
|
self.move_right_button.setEnabled(enable)
|
|
|
|
|
self.move_right_tweak_button.setEnabled(enable)
|
|
|
|
|
|
|
|
|
|
@SafeSlot(bool)
|
|
|
|
|
def enable_controls_ver(self, enable: bool):
|
|
|
|
|
self.move_up_button.setEnabled(enable)
|
|
|
|
|
self.move_up_tweak_button.setEnabled(enable)
|
|
|
|
|
self.move_down_button.setEnabled(enable)
|
|
|
|
|
self.move_down_tweak_button.setEnabled(enable)
|
|
|
|
|
|
|
|
|
|
def move(self, direction: str, tweak: bool = False):
|
|
|
|
|
step = self._step_size
|
|
|
|
|
if tweak:
|
|
|
|
|
step = int(self._step_size / 5)
|
|
|
|
|
if direction == "up":
|
|
|
|
|
self.dev.omny_xray_gui.mvy.set(step)
|
|
|
|
|
elif direction == "down":
|
|
|
|
|
self.dev.omny_xray_gui.mvy.set(-step)
|
|
|
|
|
elif direction == "left":
|
|
|
|
|
self.dev.omny_xray_gui.mvx.set(-step)
|
|
|
|
|
elif direction == "right":
|
|
|
|
|
self.dev.omny_xray_gui.mvx.set(step)
|
|
|
|
|
else:
|
|
|
|
|
logger.warning(f"Unknown direction {direction} for move command.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"]
|
|
|
|
|
PLUGIN = True
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent=None, **kwargs):
|
|
|
|
|
super().__init__(parent=parent, **kwargs)
|
|
|
|
|
self.get_bec_shortcuts()
|
|
|
|
|
|
|
|
|
|
self._init_ui()
|
|
|
|
|
self._make_connections()
|
|
|
|
|
|
|
|
|
|
# Connection to redis endpoints
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
def _init_ui(self):
|
|
|
|
|
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.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
|
|
|
|
|
|
|
|
|
|
# Control panel on the right: vertical layout inside a fixed-width widget
|
|
|
|
|
self.control_panel = QWidget(parent=self)
|
|
|
|
|
self.control_panel_layout = QVBoxLayout(self.control_panel)
|
|
|
|
|
self.control_panel_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
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")
|
|
|
|
|
header_row = QHBoxLayout()
|
|
|
|
|
header_row.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
header_row.setSpacing(8)
|
|
|
|
|
header_row.addWidget(self.roi_manager, 0)
|
|
|
|
|
header_row.addStretch()
|
|
|
|
|
self.live_preview_label = QLabel("Live Preview", parent=self)
|
|
|
|
|
self.live_preview_toggle = ToggleSwitch(parent=self)
|
|
|
|
|
self.live_preview_toggle.checked = False
|
|
|
|
|
header_row.addWidget(self.live_preview_label, 0, Qt.AlignVCenter)
|
|
|
|
|
header_row.addWidget(self.live_preview_toggle, 0, Qt.AlignVCenter)
|
|
|
|
|
self.control_panel_layout.addLayout(header_row)
|
|
|
|
|
|
|
|
|
|
# separator
|
|
|
|
|
self.control_panel_layout.addWidget(self._create_separator())
|
|
|
|
|
|
|
|
|
|
# 2D Positioner (fixed size)
|
|
|
|
|
self.motor_control_2d = XRayEye2DControl(parent=self)
|
|
|
|
|
self.control_panel_layout.addWidget(self.motor_control_2d, 0, Qt.AlignTop | Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
# separator
|
|
|
|
|
self.control_panel_layout.addWidget(self._create_separator())
|
|
|
|
|
|
|
|
|
|
# Step size label
|
|
|
|
|
step_size_form = QGridLayout()
|
|
|
|
|
# General Step size
|
|
|
|
|
self.step_size = QSpinBox(parent=self)
|
|
|
|
|
self.step_size.setRange(10, 100)
|
|
|
|
|
self.step_size.setSingleStep(10)
|
|
|
|
|
self.step_size.setValue(100)
|
|
|
|
|
# Submit button
|
|
|
|
|
self.submit_button = QPushButton("Submit", parent=self)
|
|
|
|
|
# Add to layout form
|
|
|
|
|
step_size_form.addWidget(QLabel("Horizontal", parent=self), 0, 0)
|
|
|
|
|
step_size_form.addWidget(self.step_size, 0, 1)
|
|
|
|
|
step_size_form.addWidget(QLabel("Vertical", parent=self), 1, 0)
|
|
|
|
|
step_size_form.addWidget(self.submit_button, 2, 0, 1, 2)
|
|
|
|
|
|
|
|
|
|
# Add form to control panel
|
|
|
|
|
self.control_panel_layout.addLayout(step_size_form)
|
|
|
|
|
|
|
|
|
|
# Push form to bottom
|
|
|
|
|
self.control_panel_layout.addStretch()
|
|
|
|
|
|
|
|
|
|
# Sample/Message form (bottom)
|
|
|
|
|
form = QGridLayout()
|
|
|
|
|
self.sample_name_line_edit = QLineEdit(parent=self)
|
|
|
|
|
self.sample_name_line_edit.setReadOnly(True)
|
|
|
|
|
form.addWidget(QLabel("Sample", parent=self), 0, 0)
|
|
|
|
|
form.addWidget(self.sample_name_line_edit, 0, 1)
|
|
|
|
|
self.message_line_edit = QLineEdit(parent=self)
|
|
|
|
|
self.message_line_edit.setReadOnly(True)
|
|
|
|
|
form.addWidget(QLabel("Message", parent=self), 1, 0)
|
|
|
|
|
form.addWidget(self.message_line_edit, 1, 1)
|
|
|
|
|
self.control_panel_layout.addLayout(form)
|
|
|
|
|
|
|
|
|
|
# Fix panel width and allow vertical expansion
|
|
|
|
|
self.control_panel.adjustSize()
|
|
|
|
|
p_hint = self.control_panel.sizeHint()
|
|
|
|
|
self.control_panel.setFixedWidth(p_hint.width())
|
|
|
|
|
self.control_panel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
|
|
|
|
|
|
|
|
|
|
# Core Layout: image (expanding) | control panel (fixed)
|
|
|
|
|
self.core_layout.addWidget(self.image)
|
|
|
|
|
self.core_layout.addWidget(self.control_panel)
|
|
|
|
|
|
|
|
|
|
def _make_connections(self):
|
|
|
|
|
# Fetch initial state
|
|
|
|
|
self.on_live_view_enabled(True)
|
|
|
|
|
self.step_size.setValue(self.motor_control_2d.step_size)
|
|
|
|
|
|
|
|
|
|
# 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.submit_button.clicked.connect(self.submit)
|
|
|
|
|
|
|
|
|
|
def _create_separator(self):
|
|
|
|
|
sep = QFrame(parent=self)
|
|
|
|
|
sep.setFrameShape(QFrame.HLine)
|
|
|
|
|
sep.setFrameShadow(QFrame.Sunken)
|
|
|
|
|
sep.setLineWidth(1)
|
|
|
|
|
return sep
|
|
|
|
|
|
|
|
|
|
def _init_gui_trigger(self):
|
|
|
|
|
self.dev.omny_xray_gui.read()
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
|
# Device Connection logic
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
def connect_motors(self):
|
|
|
|
|
""" 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))
|
|
|
|
|
logger.info(f"Succesfully connected to {motor}")
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
|
# Properties ported from the original OmnyAlignment, can be adjusted as needed
|
|
|
|
|
################################################################################
|
|
|
|
|
@SafeProperty(bool)
|
|
|
|
|
def enable_live_view(self):
|
|
|
|
|
"""Get or set the live view enabled state."""
|
|
|
|
|
return self.live_preview_toggle.checked
|
|
|
|
|
|
|
|
|
|
@enable_live_view.setter
|
|
|
|
|
def enable_live_view(self, enable: bool):
|
|
|
|
|
self.live_preview_toggle.checked = enable
|
|
|
|
|
|
|
|
|
|
@SafeProperty(str)
|
|
|
|
|
def user_message(self):
|
|
|
|
|
return self.message_line_edit.text()
|
|
|
|
|
|
|
|
|
|
@user_message.setter
|
|
|
|
|
def user_message(self, message: str):
|
|
|
|
|
self.message_line_edit.setText(message)
|
|
|
|
|
|
|
|
|
|
@SafeProperty(str)
|
|
|
|
|
def sample_name(self):
|
|
|
|
|
return self.sample_name_line_edit.text()
|
|
|
|
|
|
|
|
|
|
@sample_name.setter
|
|
|
|
|
def sample_name(self, message: str):
|
|
|
|
|
self.sample_name_line_edit.setText(message)
|
|
|
|
|
|
|
|
|
|
@SafeProperty(bool)
|
|
|
|
|
def enable_move_buttons(self):
|
|
|
|
|
return self.motor_control_2d.isEnabled()
|
|
|
|
|
|
|
|
|
|
@enable_move_buttons.setter
|
|
|
|
|
def enable_move_buttons(self, enabled: bool):
|
|
|
|
|
self.motor_control_2d.setEnabled(enabled)
|
|
|
|
|
|
|
|
|
|
def active_roi(self) -> BaseROI | None:
|
|
|
|
|
"""Return the currently active ROI, or None if no ROI is active."""
|
|
|
|
|
return self.roi_manager.single_active_roi
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
|
# Slots ported from the original OmnyAlignment, can be adjusted as needed
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
@SafeSlot()
|
|
|
|
|
def get_roi_coordinates(self) -> dict | None:
|
|
|
|
|
"""Get the coordinates of the currently active ROI."""
|
|
|
|
|
roi = self.roi_manager.single_active_roi
|
|
|
|
|
if roi is None:
|
|
|
|
|
logger.warning("No active ROI")
|
|
|
|
|
return None
|
|
|
|
|
logger.info(f"Active ROI coordinates: {roi.get_coordinates()}")
|
|
|
|
|
return roi.get_coordinates()
|
|
|
|
|
|
|
|
|
|
@SafeSlot(bool)
|
|
|
|
|
def on_live_view_enabled(self, enabled: bool):
|
|
|
|
|
logger.info(f"Live view is enabled: {enabled}")
|
|
|
|
|
self.live_preview_toggle.blockSignals(True)
|
|
|
|
|
if enabled:
|
|
|
|
|
self.live_preview_toggle.checked = enabled
|
|
|
|
|
self.image.image(CAMERA)
|
|
|
|
|
self.live_preview_toggle.blockSignals(False)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.image.disconnect_monitor(CAMERA)
|
|
|
|
|
self.live_preview_toggle.checked = enabled
|
|
|
|
|
self.live_preview_toggle.blockSignals(False)
|
|
|
|
|
|
|
|
|
|
@SafeSlot(bool, bool)
|
|
|
|
|
def on_motors_enable(self, x_enable: bool, y_enable: bool):
|
|
|
|
|
self.motor_control_2d.enable_controls_hor(x_enable)
|
|
|
|
|
self.motor_control_2d.enable_controls_ver(y_enable)
|
|
|
|
|
|
|
|
|
|
@SafeSlot(str)
|
|
|
|
|
def set_message(self, msg: str):
|
|
|
|
|
self.message_line_edit.setText(msg)
|
|
|
|
|
|
|
|
|
|
@SafeSlot(str)
|
|
|
|
|
def set_sample_name(self, msg: str):
|
|
|
|
|
self.sample_name_line_edit.setText(msg)
|
|
|
|
|
|
|
|
|
|
@SafeSlot(int)
|
|
|
|
|
def enable_submit_button(self, enable: int):
|
|
|
|
|
"""If -1 disable else enable"""
|
|
|
|
|
if enable == -1:
|
|
|
|
|
self.submit_button.setEnabled(False)
|
|
|
|
|
else:
|
|
|
|
|
self.submit_button.setEnabled(True)
|
|
|
|
|
|
|
|
|
|
@SafeSlot(bool, bool)
|
|
|
|
|
def on_tomo_angle_readback(self, data: dict, meta: dict):
|
|
|
|
|
print(f"data: {data}")
|
|
|
|
|
print(f"meta: {meta}")
|
|
|
|
|
|
|
|
|
|
@SafeSlot(dict, dict)
|
|
|
|
|
def device_updates(self, data: dict, meta: dict):
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
send_message = signals.get("omny_xray_gui_send_message").get('value')
|
|
|
|
|
self.set_message(send_message)
|
|
|
|
|
# sample name
|
|
|
|
|
sample_message = signals.get("omny_xray_gui_sample_name").get('value')
|
|
|
|
|
self.set_sample_name(sample_message)
|
|
|
|
|
# enable frame acquisition
|
|
|
|
|
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')
|
|
|
|
|
self.enable_submit_button(enable_submit_button)
|
|
|
|
|
|
|
|
|
|
@SafeSlot()
|
|
|
|
|
def submit(self):
|
|
|
|
|
"""Execute submit action by submit button."""
|
|
|
|
|
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: {roi_center_x},{roi_center_y}, {roi_width},{roi_height}")
|
|
|
|
|
# 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.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):
|
|
|
|
|
self.bec_dispatcher.disconnect_slot(self.device_updates, MessageEndpoints.device_readback("omny_xray_gui"))
|
|
|
|
|
getattr(self.dev,CAMERA).live_mode = False
|
|
|
|
|
super().cleanup()
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
from qtpy.QtWidgets import QApplication
|
|
|
|
|
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
|
|
|
|
|
win = XRayEye()
|
|
|
|
|
|
|
|
|
|
win.resize(1000, 800)
|
|
|
|
|
win.show()
|
|
|
|
|
sys.exit(app.exec_())
|