From 1fe3c7f4e5e4c18c323b97bec49da32846b280e9 Mon Sep 17 00:00:00 2001 From: Dawn Date: Mon, 14 Sep 2026 10:29:12 +0200 Subject: [PATCH] refactor: transmission is a per-mode setting, placed in its section The shared "Rotation transmission" row sat in the top rows of BOTH the Gridscan and Rotation tabs, where it read as one setting for everything (and as nonsense in the Gridscan tab). Now each tab places its own row: Gridscan keeps "Transmission" with the shared resolution/distance rows, and the Rotation tab moves "Rotation transmission" below the Screening block and its Run button, as the first row of the Rotation section - next to the fields it actually applies to. Screening keeps its separate "Screening transmission". No behavior change: same field, same spreadsheet/user-value handling, only the label and the placement. Co-Authored-By: Claude Fable 5 --- src/aare/gui/panels/raster_data_collection.py | 3 ++ .../gui/panels/rotation_data_collection.py | 21 +++++++---- src/aare/gui/panels/scan_settings_panel.py | 7 +++- .../unit/gui/test_data_collection_settings.py | 37 +++++++++++++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/aare/gui/panels/raster_data_collection.py b/src/aare/gui/panels/raster_data_collection.py index bbbe74b4..9aee838a 100644 --- a/src/aare/gui/panels/raster_data_collection.py +++ b/src/aare/gui/panels/raster_data_collection.py @@ -30,6 +30,9 @@ class RasterDataCollectionPanel(ScanSettingsPanel): diffraction=diffraction, default_dtz=raster_mgr.active_grid.dtz, default_transmission=raster_mgr.active_grid.transmission, + # Plain "Transmission": the tab IS the gridscan, and the longer + # "Gridscan transmission" clips in the label column. + transmission_label="Transmission", parent=parent, ) diff --git a/src/aare/gui/panels/rotation_data_collection.py b/src/aare/gui/panels/rotation_data_collection.py index 2b4783a7..114c4fab 100644 --- a/src/aare/gui/panels/rotation_data_collection.py +++ b/src/aare/gui/panels/rotation_data_collection.py @@ -61,6 +61,11 @@ class RotationDataCollectionPanel(ScanSettingsPanel): "daq.data_collection_settings.default_rotation_settings.transmission", default_transmission, ), + # Row 11 = first row under the "Rotation" header: the rotation + # transmission belongs next to the rotation fields, not at the + # top of the tab where it read as applying to screening too. + transmission_row=11, + transmission_label="Rotation transmission", ) self._filename = "" @@ -151,13 +156,13 @@ class RotationDataCollectionPanel(ScanSettingsPanel): self.total_angle = NumberLineEdit( 0, 9999.0, self._default_total_angle, decimals=3, parent=self, track_pending=True ) - self._add_row(11, "Total angle", self.total_angle, "°") + self._add_row(12, "Total angle", self.total_angle, "°") self._add_database_field(self.total_angle, self._on_total_angle_committed) self.image_angle = NumberLineEdit( 0, 10.0, self._default_image_angle, decimals=3, parent=self, track_pending=True ) - self._add_row(12, "Image angle", self.image_angle, "°") + self._add_row(13, "Image angle", self.image_angle, "°") self._add_database_field(self.image_angle, self._on_image_angle_committed) self.image_time_enter = NumberLineEdit( @@ -168,27 +173,27 @@ class RotationDataCollectionPanel(ScanSettingsPanel): parent=self, track_pending=True, ) - self._add_row(13, "Image time", self.image_time_enter, "s") + self._add_row(14, "Image time", self.image_time_enter, "s") self._add_database_field(self.image_time_enter, self._on_exp_time_committed) self.omega_speed = QLabel("-") - self._add_row(14, "Rotation speed", self.omega_speed, "°/s") + self._add_row(15, "Rotation speed", self.omega_speed, "°/s") self.total_time = QLabel(f"{self._total_time} min 0 s") - self._add_row(15, "Total measurement time", self.total_time) + self._add_row(16, "Total measurement time", self.total_time) self.dose = QLabel(f"{self._dose_mgy}") - self._add_row(16, "Dose", self.dose, "MGy") + self._add_row(17, "Dose", self.dose, "MGy") self.measurement_button = QPushButton("Run rotation") self.measurement_button.setStyleSheet(f"color: {GO_TEXT};") self.measurement_button.clicked.connect(self.run_measurement) - self._layout.addWidget(self.measurement_button, 17, 0, 1, 6) + self._layout.addWidget(self.measurement_button, 18, 0, 1, 6) # Per-tab Abort (DataCollectionSettings wires it to the DAQ cancel). self.abort_button = QPushButton("Abort measurement") self.abort_button.setStyleSheet(f"color: {ABORT_TEXT};") - self._layout.addWidget(self.abort_button, 18, 0, 1, 6) + self._layout.addWidget(self.abort_button, 19, 0, 1, 6) # every field exists now: fill in the speed and measurement time self._values_changed() diff --git a/src/aare/gui/panels/scan_settings_panel.py b/src/aare/gui/panels/scan_settings_panel.py index 17d369c0..a60c3fc4 100644 --- a/src/aare/gui/panels/scan_settings_panel.py +++ b/src/aare/gui/panels/scan_settings_panel.py @@ -125,6 +125,8 @@ class ScanSettingsPanel(QWidget): diffraction: DiffractionGeometry, default_dtz: float = 200.0, default_transmission: float = 1.0, + transmission_row: int = 2, + transmission_label: str = "Transmission", parent=None, ): super().__init__(parent) @@ -186,10 +188,13 @@ class ScanSettingsPanel(QWidget): self._add_row(1, "Detector distance", self.dtz_enter, "mm") self._add_database_field(self.dtz_enter, self._on_dtz_committed) + # Placed where the subclass says: transmission is a per-mode setting + # (user request), so each tab puts its own row next to its section + # instead of a shared top-level "Rotation transmission" for all tabs. self.transmission_enter = NumberLineEdit( 0, 1.0, default=default_transmission, decimals=4, parent=self, track_pending=True ) - self._add_row(2, "Rotation transmission", self.transmission_enter) + self._add_row(transmission_row, transmission_label, self.transmission_enter) self._add_database_field(self.transmission_enter, self._on_transmission_committed) # -- grid rows ---------------------------------------------------------- diff --git a/tests/unit/gui/test_data_collection_settings.py b/tests/unit/gui/test_data_collection_settings.py index d821e942..1d2ca541 100644 --- a/tests/unit/gui/test_data_collection_settings.py +++ b/tests/unit/gui/test_data_collection_settings.py @@ -20,6 +20,7 @@ from aarecommon.models.models import ( SampleShortInfo, ) from PySide6.QtCore import Qt +from PySide6.QtWidgets import QLabel from aare.gui.panels.data_collection_settings import DataCollectionSettings from aare.gui.panels.raster_data_collection import RasterDataCollectionPanel @@ -448,3 +449,39 @@ def test_energy_spin_motor_move_semantics(settings_panel, daq_status_factory): settings_panel._energy_state.update_actual(12.3995) assert box.property("movestate") == "" + + +def _grid_widget(grid, row: int, col: int): + item = grid.itemAtPosition(row, col) + assert item is not None + widget = item.widget() + assert widget is not None + return widget + + +def test_transmission_rows_are_per_mode(panel, qapp, diffraction): + # Rotation tab: the rotation transmission moved out of the shared top + # rows into the Rotation section (row 11, right under the header), below + # the Screening block and its Run button (row 9). + grid = panel._layout + label = _grid_widget(grid, 11, 0) + assert isinstance(label, QLabel) + assert label.text() == "Rotation transmission" + assert _grid_widget(grid, 11, 1) is panel.transmission_enter + assert _grid_widget(grid, 9, 0) is panel.screening_button + + # Gridscan tab keeps its own transmission in the top rows, without the + # misleading "Rotation" prefix. + geom = SampleGeometryModel( + beam_location_pxl=Coordinate(x=500, y=500), + pixel_in_mm=0.001, + aerotech=Coordinate(), + aerotech_meas=Coordinate(), + smargon=SmargonCoordinate(sh_mm=Coordinate(), phi_deg=0.0, chi_deg=0.0), + omega_deg=0.0, + beam_size_mm=Coordinate(x=0.01, y=0.01), + ) + raster = RasterDataCollectionPanel(RasterGridManager(geom), diffraction) + raster_label = _grid_widget(raster._layout, 2, 0) + assert isinstance(raster_label, QLabel) + assert raster_label.text() == "Transmission"