From 7e1857f5c5543cf0001fb7a83ba9e45da73619b6 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Tue, 30 Sep 2025 17:14:09 +0200 Subject: [PATCH] AUTOMATION PARAMETERS: simple/smart rotation panel added --- .../panels/data_collection_settings.py | 7 +- .../aaregui/panels/smart_rotation_panel.py | 108 ++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 gui/src/aaregui/panels/smart_rotation_panel.py diff --git a/gui/src/aaregui/panels/data_collection_settings.py b/gui/src/aaregui/panels/data_collection_settings.py index c9ca73c2..6e6b305f 100644 --- a/gui/src/aaregui/panels/data_collection_settings.py +++ b/gui/src/aaregui/panels/data_collection_settings.py @@ -16,6 +16,7 @@ from aaredaqlib.sample_geometry import SampleGeometryModel from aaregui.panels.file_path_panel import FilePathPanel from aaregui.panels.raster_data_collection import RasterDataCollectionPanel from aaregui.panels.rotation_data_collection import RotationDataCollectionPanel +from aaregui.panels.smart_rotation_panel import SimpleRotationSettingsPanel from aaregui.scan_logic.raster_grid_manager import RasterGridManager from aaregui.widgets.title_label import TitleLabel @@ -45,8 +46,11 @@ class DataCollectionSettings(QFrame): self.screening = RotationDataCollectionPanel(parent=self, diffraction=diffraction) self.__tab_widget.addTab(self.screening, "Rotation") - v_layout.addWidget(self.__tab_widget) + self.simple = SimpleRotationSettingsPanel(parent=self) + self.__tab_widget.addTab(self.simple, "Simple") + + v_layout.addWidget(self.__tab_widget) v_layout.addStretch() abort_button = QPushButton("Abort measurement", parent=self) @@ -72,6 +76,7 @@ class DataCollectionSettings(QFrame): def update_daq_status(self, s: DAQStatusModel): self.raster.update_daq_status(s) self.screening.update_daq_status(s) + self.simple.update_daq_status(s) if s.sample is not None and s.sample.db_id != self.__sample_id: self.__sample_id = s.sample.db_id self.__tab_widget.setCurrentIndex(0) diff --git a/gui/src/aaregui/panels/smart_rotation_panel.py b/gui/src/aaregui/panels/smart_rotation_panel.py new file mode 100644 index 00000000..bcd718a3 --- /dev/null +++ b/gui/src/aaregui/panels/smart_rotation_panel.py @@ -0,0 +1,108 @@ +from PySide6.QtCore import Slot, Qt +from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QFrame, QPushButton + +from aaredaqlib.models import DAQStatusModel +from aaregui.widgets.number_line_edit import NumberLineEdit + + +class SimpleRotationSettingsPanel(QWidget): + + def __init__(self, parent=None): + super().__init__(parent) + self.__d = None + + self._layout = QGridLayout(self) + self._layout.setContentsMargins(4, 4, 4, 4) + self._layout.setHorizontalSpacing(6) + self._layout.setVerticalSpacing(4) + # Visible resolution (entry) + self._layout.addWidget(QLabel("Visible resolution", parent=self), 0, 0) + self.visible_res_enter = NumberLineEdit( + 0.8, 10.0, decimals=2, default=2.0, parent=self + ) + self._layout.addWidget(self.visible_res_enter, 0, 1, 1, 3) + 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("°", 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("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) + + # Run rotation button + self.run_rotation_button = QPushButton("Run rotation", parent=self) + self.run_rotation_button.setStyleSheet("color: rgb(78, 154, 6);") + self._layout.addWidget(self.run_rotation_button, 7, 0, 1, 6) + @Slot(DAQStatusModel) + def update_daq_status(self, s: DAQStatusModel): + self.__d = s + self.update_calculated_labels() + + @Slot(float) + def set_visible_resolution(self, v: float): + self.update_calculated_labels() + + + def update_calculated_labels(self): + if self.__d is None: + return + flux = 2.5e11 + + total_angle = self.angular_range_enter.value + d_vis = self.visible_res_enter.value + d_tar = 1/(1/d_vis + 0.1) + self.target_res_label.setText(f"{d_tar}") + + Kdose = 2000 / (self.__d.diffraction.wavelength_angstrom**2) + dose_rate_MGy_s = (flux / (self.__d.geom.beam_size_mm.x * 1000 * self.__d.geom.beam_size_mm.y * 1000 * Kdose)) / 1e6 + target_dose_MGy = 10 * d_tar / 2.0 + total_time_s = target_dose_MGy / dose_rate_MGy_s + image_angle = 0.2 + self.image_angle_label.setText(f"{image_angle:.3f}") + nimages = total_angle / image_angle + image_time_s = total_time_s / nimages + if image_time_s < 0.01: + transmission = image_time_s / 0.01 + image_time_s = 0.01 + else: + transmission = 1.0 + + dtz = self.__d.diffraction.calc_dtz_mm(d_tar) + + self.transmission_label.setText(f"{transmission * 100:.1f}%") + self.image_time_label.setText(f"{image_time_s:.4f}") + self.dtz_label.setText(f"{dtz:.2f}")