GUI: updated features to smart_rotation_panel.py

This commit is contained in:
2025-10-10 17:14:47 +02:00
parent 4e6e7fbaf6
commit be0d9382d6
+111 -80
View File
@@ -3,19 +3,22 @@ import math
from PySide6.QtCore import Slot, Qt, Signal
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QFrame, QPushButton, QSpacerItem, QSizePolicy
from aaredaqlib.models import DAQStatusModel
from aaredaqlib.models import DAQStatusModel, SimpleScanParameters
from aaredaqlib.rotation_scan import RotationScanRequest
from aaregui.panels.rotation_data_collection import add_data_to_path
from aaregui.widgets.number_line_edit import NumberLineEdit
class SimpleRotationSettingsPanel(QWidget):
rotation_scan = Signal(RotationScanRequest)
viewer_track_online = Signal()
parameters_changed = Signal(SimpleScanParameters)
def __init__(self, parent=None):
super().__init__(parent)
self.n_images = 1
self.xtal_size_dose_rate_MGy_s = None
self.xtal_x = None
self.xtal_y = None
@@ -24,14 +27,12 @@ class SimpleRotationSettingsPanel(QWidget):
self.dose_rate_MGy_s = None
self._filename = ""
self.dtz = 120
self.n_images = None
self.transmission = 1.0
self.image_time_s = None
self.image_angle = 0.2
self.image_time_s = 0.1
self.__d = None
self._temperature = 100
self.__omega = 0
self._wilson_b = 0
self._wilson_b = None
self.parameters = SimpleScanParameters()
self._layout = QGridLayout(self)
@@ -44,73 +45,75 @@ class SimpleRotationSettingsPanel(QWidget):
self._layout.addWidget(QLabel("Å", parent=self), 0, 4)
self.visible_res_enter.newValue.connect(self.set_visible_resolution)
# Angular range (entry)
self._layout.addWidget(QLabel("Total angle", parent=self), 1, 0)
self.angular_range_enter = NumberLineEdit(
5.0, 1000.0, decimals=3, default=210.0, parent=self
)
self._layout.addWidget(self.angular_range_enter, 1, 1, 1, 3)
self._layout.addWidget(QLabel("Start angle", parent=self), 1, 0)
self.start_angle_enter = NumberLineEdit(-720, 720.0, 0.0, decimals=3, parent=self)
self._layout.addWidget(self.start_angle_enter, 1, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 1, 4)
self.visible_res_enter.newValue.connect(self.set_visible_resolution)
# Calculated labels
self._layout.addWidget(QLabel("Target resolution", parent=self), 2, 0)
self.target_res_label = QLabel("--", parent=self)
self.target_res_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_res_label, 2, 1, 1, 3)
self._layout.addWidget(QLabel("Å", parent=self), 2, 4)
self._layout.addWidget(QLabel("Image angle", parent=self), 3, 0)
self.image_angle_label = QLabel("--", parent=self)
self.image_angle_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.image_angle_label, 3, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 3, 4)
self._layout.addWidget(QLabel("Image time", parent=self), 4, 0)
self.image_time_label = QLabel("--", parent=self)
self.image_time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.image_time_label, 4, 1, 1, 3)
self._layout.addWidget(QLabel("s", parent=self), 4, 4)
self._layout.addWidget(QLabel("Transmission", parent=self), 5, 0)
self.transmission_label = QLabel("--", parent=self)
self.transmission_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.transmission_label, 5, 1, 1, 3)
self._layout.addWidget(QLabel("%", parent=self), 5, 4)
self._layout.addWidget(QLabel("Detector distance", parent=self), 6, 0)
self.dtz_label = QLabel(f"--", parent=self)
self.dtz_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.dtz_label, 6, 1, 1, 3)
self._layout.addWidget(QLabel("mm", parent=self), 6, 4)
self._layout.addWidget(QLabel("Target Dose", parent=self), 7, 0)
self.target_dose_label = QLabel(f"--", parent=self)
self.target_dose_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_dose_label, 7, 1, 1, 3)
self._layout.addWidget(QLabel("MGy", parent=self), 7, 4)
self._layout.addWidget(QLabel("Calculated Dose Rate", parent=self), 8, 0)
self.calculated_dose_rate_label = QLabel(f"--", parent=self)
self.calculated_dose_rate_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.calculated_dose_rate_label, 8, 1, 1, 3)
self._layout.addWidget(QLabel("MGy S^-1", parent=self), 8, 4)
self._layout.addWidget(QLabel("Temperature", parent=self), 9, 0)
self.temp_enter = NumberLineEdit(80, 330, decimals=2, default=100.0, parent=self)
self._layout.addWidget(self.temp_enter, 9, 1, 1, 3)
self._layout.addWidget(QLabel("K", parent=self), 9, 4)
self.temp_enter.newValue.connect(self.set_temperature)
self._layout.addWidget(QLabel("Start angle", parent=self), 10, 0)
self.start_angle = NumberLineEdit(-720, 720.0, 0.0, decimals=3, parent=self)
self._layout.addWidget(self.start_angle, 10, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 10, 4)
self.omega_button = QPushButton("Ω")
self.omega_button.setFixedWidth(20)
self.omega_button.clicked.connect(self.update_omega_start)
self._layout.addWidget(self.omega_button, 10, 5)
self._layout.addWidget(self.omega_button, 1, 5)
# Angular range (entry)
self._layout.addWidget(QLabel("Total angle", parent=self), 2, 0)
self.angular_range_enter = NumberLineEdit(
5.0, 1000.0, decimals=3, default=360.0, parent=self
)
self._layout.addWidget(self.angular_range_enter, 2, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 2, 4)
self.visible_res_enter.newValue.connect(self.set_total_angle)
self._layout.addWidget(QLabel("Image angle", parent=self), 3, 0)
self.image_angle_enter = NumberLineEdit(
0.001, 1.000, decimals=3, default=0.2, parent=self
)
self._layout.addWidget(self.image_angle_enter, 3, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 3, 4)
self.image_angle_enter.newValue.connect(self.set_image_angle)
self._layout.addWidget(QLabel("Temperature", parent=self), 4, 0)
self.temp_enter = NumberLineEdit(80, 330, decimals=2, default=100.0, parent=self)
self._layout.addWidget(self.temp_enter, 4, 1, 1, 3)
self._layout.addWidget(QLabel("K", parent=self), 4, 4)
self.temp_enter.newValue.connect(self.set_temperature)
# Calculated labels
self._layout.addWidget(QLabel("Target resolution", parent=self), 5, 0)
self.target_res_label = QLabel("--", parent=self)
self.target_res_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_res_label, 5, 1, 1, 3)
self._layout.addWidget(QLabel("Å", parent=self), 5, 4)
self._layout.addWidget(QLabel("Image time", parent=self), 6, 0)
self.image_time_label = QLabel("--", parent=self)
self.image_time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.image_time_label, 6, 1, 1, 3)
self._layout.addWidget(QLabel("s", parent=self), 6, 4)
self._layout.addWidget(QLabel("Transmission", parent=self), 7, 0)
self.transmission_label = QLabel("--", parent=self)
self.transmission_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.transmission_label, 7, 1, 1, 3)
self._layout.addWidget(QLabel("%", parent=self), 7, 4)
self._layout.addWidget(QLabel("Detector distance", parent=self), 8, 0)
self.dtz_label = QLabel(f"--", parent=self)
self.dtz_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.dtz_label, 8, 1, 1, 3)
self._layout.addWidget(QLabel("mm", parent=self), 8, 4)
self._layout.addWidget(QLabel("Target Dose", parent=self), 9, 0)
self.target_dose_label = QLabel(f"--", parent=self)
self.target_dose_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_dose_label, 9, 1, 1, 3)
self._layout.addWidget(QLabel("MGy", parent=self), 9, 4)
self._layout.addWidget(QLabel("Calculated Dose Rate", parent=self), 10, 0)
self.calculated_dose_rate_label = QLabel(f"--", parent=self)
self.calculated_dose_rate_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.calculated_dose_rate_label, 10, 1, 1, 3)
self._layout.addWidget(QLabel("MGy S^-1", parent=self), 10, 4)
self._layout.addWidget(QLabel("Wilson B Factor", parent=self), 11, 0)
self.wilson_b_label = QLabel(f"--", parent=self)
@@ -178,7 +181,12 @@ class SimpleRotationSettingsPanel(QWidget):
@Slot(DAQStatusModel)
def update_daq_status(self, s: DAQStatusModel):
self.__d = s
#TODO only update best_res after raster finished otherwise ask to update. or have toggle to overwrite with user value
#TODO only take best res from flat face scan
#TODO identify flat face!!!!
best_res = s.last_best_res
print("best_res: ", best_res)
self.__omega = s.geom.omega_deg
if best_res is not None:
# clamp to control limits and update field; this will also trigger recalculation
@@ -187,12 +195,14 @@ class SimpleRotationSettingsPanel(QWidget):
self.visible_res_enter.update_value(v)
self.set_visible_resolution(v)
best_b_factor = s.last_best_b_factor
self._wilson_b = s.last_best_b_factor
print("b_factor: ", self._wilson_b)
if best_b_factor is not None:
self.wilson_b_label.setText(f"{best_b_factor:.2f}")
if self._wilson_b is not None:
self.wilson_b_label.setText(f"{self._wilson_b:.2f}")
xtal_size = s.crystal_size
print("crystal_size: ", xtal_size)
if xtal_size is not None:
# clamp to control limits and update field; this will also trigger recalculation
self.xtal_x = xtal_size.x
@@ -211,12 +221,21 @@ class SimpleRotationSettingsPanel(QWidget):
self.wavelength_label.setText("<b>N/A</b>")
else:
self.wavelength_label.setText(f"<b>{s.diffraction.wavelength_angstrom:.3f}</b>")
self.update_calculated_labels()
@Slot(float)
def set_visible_resolution(self, v: float):
self.update_calculated_labels()
@Slot(float)
def set_total_angle(self, v: float):
self.update_calculated_labels()
@Slot(float)
def set_image_angle(self, v: float):
self.update_calculated_labels()
@Slot(float)
def set_temperature(self, v: float):
self.update_calculated_labels()
@@ -227,7 +246,7 @@ class SimpleRotationSettingsPanel(QWidget):
@Slot()
def update_omega_start(self):
self.start_angle.update_value(self.__omega)
self.start_angle_enter.update_value(self.__omega)
def update_calculated_labels(self):
if self.__d is None:
@@ -238,9 +257,12 @@ class SimpleRotationSettingsPanel(QWidget):
#TODO read resolution estiamtion from jfjoch
total_angle = self.angular_range_enter.value
d_vis = self.visible_res_enter.value
image_angle = self.image_angle_enter.value
if d_vis == 0.0:
d_vis = 1.3
d_tar = 1/(1/d_vis + 0.1)
self.target_res_label.setText(f"{d_tar:.2f}")
#self.wilson_b_label.setText("--")
Kdose = 2000 / (self.__d.diffraction.wavelength_angstrom**2)
@@ -271,10 +293,9 @@ class SimpleRotationSettingsPanel(QWidget):
total_time_s = self.target_dose_MGy / self.dose_rate_MGy_s
self.calculated_dose_label.setText(f"{self.xtal_size_dose_rate_MGy_s*total_time_s:.2f}")
self.image_angle = 0.2
self.image_angle_label.setText(f"{self.image_angle:.3f}")
self.n_images = total_angle / self.image_angle
if image_angle == 0.0:
image_angle = 0.001
self.n_images = round(total_angle / image_angle)
self.image_time_s = total_time_s / self.n_images
if self.image_time_s < 0.01:
self.transmission = self.image_time_s / 0.01
@@ -295,13 +316,23 @@ class SimpleRotationSettingsPanel(QWidget):
else:
self.dtz_label.setText(f"{self.dtz:.2f}")
self.parameters = SimpleScanParameters(
dtz=int(round(self.dtz)),
exp_time_s=self.image_time_s,
start_omega_deg=self.start_angle_enter.value,
incr_omega_deg=image_angle,
steps=self.n_images,
transmission=self.transmission
)
self.parameters_changed.emit(self.parameters)
@Slot()
def run_measurement(self):
r = RotationScanRequest(
file_prefix=self._filename,
start_omega_deg=0,#,self.start_angle.value,
file_prefix=str(add_data_to_path(self._filename)),
start_omega_deg=self.start_angle_enter.value,
steps=self.n_images,
incr_omega_deg=self.image_angle,
incr_omega_deg=self.image_angle_enter.value,
dtz=self.dtz,
transmission=self.transmission,
screening=False,