diff --git a/gui/src/aaregui/panels/raster_data_collection.py b/gui/src/aaregui/panels/raster_data_collection.py index 4af10dd6..2c36593a 100644 --- a/gui/src/aaregui/panels/raster_data_collection.py +++ b/gui/src/aaregui/panels/raster_data_collection.py @@ -217,20 +217,10 @@ class RasterDataCollectionPanel(ScanSettingsPanel): @Slot() def _on_evaluate_clicked(self): - p = self.parent() - if hasattr(p, "file_path_panel"): - reply = p.file_path_panel.file_path_error_box("raster") - logger.debug(f"reply from file path panel: {reply}") - if not reply: - return - self.evaluate_grid.emit() + if self.check_before_run(scan_kind = "raster"): + self.evaluate_grid.emit() @Slot() def _on_evaluate_auto_clicked(self): - p = self.parent() - if hasattr(p, "file_path_panel"): - reply = p.file_path_panel.file_path_error_box("raster") - logger.debug(f"reply from file path panel: {reply}") - if not reply: - return - self.evaluate_grid_auto.emit() \ No newline at end of file + if self.check_before_run(scan_kind = "raster"): + self.evaluate_grid_auto.emit() \ No newline at end of file diff --git a/gui/src/aaregui/panels/rotation_data_collection.py b/gui/src/aaregui/panels/rotation_data_collection.py index e42696f0..645eae51 100644 --- a/gui/src/aaregui/panels/rotation_data_collection.py +++ b/gui/src/aaregui/panels/rotation_data_collection.py @@ -128,15 +128,9 @@ class RotationDataCollectionPanel(ScanSettingsPanel): @Slot() def run_screening(self): - p = self.parent() - logger.debug("make box") - if hasattr(p, "file_path_panel"): - logger.debug("should make box") - reply = p.file_path_panel.file_path_error_box("screening") - logger.debug(f"reply from file path panel: {reply}") - if not reply: - return - logger.debug("no box") + if not self.check_before_run(scan_kind = "screening"): + logger.error("Cannot run measurement because of check") + return screening_settings = self.screening_type.currentData() r = RotationScanRequest( file_prefix=str(add_screening_to_path(self._filename)), @@ -153,12 +147,9 @@ class RotationDataCollectionPanel(ScanSettingsPanel): @Slot() def run_measurement(self): - p = self.parent() - if hasattr(p, "file_path_panel"): - reply = p.file_path_panel.file_path_error_box("rotation") - logger.debug(f"reply from file path panel: {reply}") - if not reply: - return + if not self.check_before_run(scan_kind = "rotation"): + logger.error("Cannot run measurement because of check") + return r = RotationScanRequest( file_prefix=str(add_data_to_path(self._filename)), start_omega_deg=self.start_angle.value, diff --git a/gui/src/aaregui/panels/sample_queue_panel.py b/gui/src/aaregui/panels/sample_queue_panel.py index 30c590ee..a3147966 100644 --- a/gui/src/aaregui/panels/sample_queue_panel.py +++ b/gui/src/aaregui/panels/sample_queue_panel.py @@ -5,6 +5,8 @@ from PySide6.QtGui import QKeySequence, QShortcut from aaredaqlib.models import SampleShortInfoList, SampleShortInfo from aaregui.models.sample_queue_model import SampleQueueSpreadsheet +from aaregui.widgets.message_box import ring_current_low_check, experiment_hutch_shutter_check, LOW_CURRENT_THRESHOLD, \ + ring_current_auto_check from aaregui.widgets.title_label import TitleLabel from aaredaqlib.models import DAQStatusModel @@ -23,6 +25,7 @@ class SampleQueuePanel(QFrame): self.__set_to_pause = False self._current_db_id: int | None = None self.ring_current = None + self._experiment_shutter_state = None self.setFrameShape(QFrame.Shape.StyledPanel) self.setFrameShadow(QFrame.Shadow.Raised) @@ -92,28 +95,23 @@ class SampleQueuePanel(QFrame): sample = self.table_model.samples[row] self.table_model.remove_sample(sample.db_id) - def __ring_current_low_check(self) -> bool: - if self.ring_current is not None and self.ring_current < 100: - logger.debug(f"Ring current too low {self.ring_current}") + def ring_current_check(self): + if not ring_current_low_check(self, self.ring_current): self.table_model.set_running(False) self.set_to_pause = True self.__pause = True self.play_button.setText("▶ Run") - reply = QMessageBox.question(self, "Ring current too low", f"Ring current is too low: {self.ring_current} mA. Do you wish to continue?", - QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, - QMessageBox.StandardButton.No) - if reply == QMessageBox.StandardButton.Yes: - return True - else: - return False - logger.debug(f"Ring current: {self.ring_current}") + return False return True def run(self): - if not self.__ring_current_low_check(): + if not self.ring_current_check(): logger.debug("low ring current, skipping") return + elif not experiment_hutch_shutter_check(parent=self, shutter_state=self._experiment_shutter_state): + logger.debug("experiment shutter closed, user chose to skip") + elif self.__pause: if len(self.table_model.samples) > 0: self.table_model.set_running(True) @@ -135,15 +133,34 @@ class SampleQueuePanel(QFrame): @Slot(DAQStatusModel) def update_daq_status(self, s: DAQStatusModel): self.ring_current = s.bl.ring_current_mA + self._experiment_shutter_state = s.bl.exp_shutter_open @Slot(int, bool) def automated_scan_done(self, db_id: int, success: bool): if self._current_db_id is not None and db_id != self._current_db_id: return - if not self.__ring_current_low_check(): - self.unmount.emit() - return + def current_ok() -> bool: + return (self.ring_current is not None) and (self.ring_current >= LOW_CURRENT_THRESHOLD) + + if self.ring_current is None or (self.ring_current < LOW_CURRENT_THRESHOLD): + # Pause UI state + self.table_model.set_running(False) + self.__pause = True + self.play_button.setText("▶ Run") + + # This dialog will auto-accept when current_ok() returns True. + # No user button press is required to continue. + if ring_current_auto_check(self, self.ring_current, current_ok): + logger.debug("Ring current recovered or user chose to continue," + "resuming automation") + self.table_model.set_running(True) + self.__pause = False + self.play_button.setText("⏸ Pause") + else: + logger.debug("No beam, or user quit, ending automation") + self.unmount.emit() + return if success: self.table_model.remove_sample(db_id) diff --git a/gui/src/aaregui/panels/scan_settings_panel.py b/gui/src/aaregui/panels/scan_settings_panel.py index cd39bb15..11f9abd9 100644 --- a/gui/src/aaregui/panels/scan_settings_panel.py +++ b/gui/src/aaregui/panels/scan_settings_panel.py @@ -1,9 +1,10 @@ from PySide6.QtCore import Slot, Signal -from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QFrame, QPushButton +from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QFrame, QPushButton, QMessageBox from aaredaqlib.diffraction_geometry import DiffractionGeometry from aaredaqlib.logger_config import setup_logger from aaredaqlib.models import DAQStatusModel +from aaregui.widgets.message_box import ring_current_low_check, experiment_hutch_shutter_check from aaregui.widgets.number_line_edit import NumberLineEdit logger = setup_logger("aareGUI") @@ -33,6 +34,8 @@ class ScanSettingsPanel(QWidget): self._sample_cell_parameters = None self._sample_pdb_id = None self._target_dose = None + self._ring_current = None + self._experiment_shutter_state = None self._layout = QGridLayout(self) @@ -64,14 +67,14 @@ class ScanSettingsPanel(QWidget): self.reload_params_button.clicked.connect(self.reload_parameters) self.reload_params_button.setVisible(False) # Child classes should make it visible - @Slot(DAQStatusModel) def update_daq_status(self, s: DAQStatusModel): self.dtz_enter.update_limits(s.bl.dtz_min, s.bl.dtz_max) self.high_res_enter.update_limits(self.__diffraction.resolution_angstrom(s.bl.dtz_min), self.__diffraction.resolution_angstrom(s.bl.dtz_max)) self.__diffraction = s.diffraction - + self._ring_current = s.bl.ring_current_mA + self._experiment_shutter_state = s.bl.exp_shutter_open can_edit = (not s.busy) and (s.session.session.name == "OwnedByYou") # Lock/unlock base NumberLineEdits self.high_res_enter.setReadOnly(not can_edit) @@ -211,3 +214,19 @@ class ScanSettingsPanel(QWidget): List of tuples: (parameter_name, widget, converter_function or None) """ return [] + + def check_before_run (self, scan_kind: str): + if not ring_current_low_check(self, self._ring_current): + logger.warning("Low ring current, User chose to not to continue scan") + return False + if not experiment_hutch_shutter_check(self, self._experiment_shutter_state): + logger.warning("experiment shutter closed, user chose to not to continue scan") + return False + p = self.parent() + if hasattr(p, "file_path_panel"): + reply = p.file_path_panel.file_path_error_box(scan_kind=scan_kind) + logger.debug(f"reply from file path panel: {reply}") + if not reply: + logger.warning("Error with file path.") + return False + return True \ No newline at end of file