"""Omega speed cap (500 deg/s) and per-beamline min image time on the rotation panel. Why: the image angle and the image time are each fine on their own - it is the pair that can ask the goniometer to turn too fast. So the cap is a read-out plus a gate on the Run button, and only the per-beamline minimum image time is a limit of the field itself. """ import pytest from aarecommon.math.diffraction_geometry import DiffractionGeometry from aarecommon.models.models import BeamlineStateEnum from PySide6.QtWidgets import QMessageBox from aare.gui.panels.rotation_data_collection import RotationDataCollectionPanel def _panel(monkeypatch, beamline): # mx_beamline() reads the env on every call, so set it before construction monkeypatch.setenv("BEAMLINE", beamline) diffraction = DiffractionGeometry( energy_keV=12.0, dtz_mm=150.0, pixel_size_mm=0.075, beam_center_pxl=(1000.0, 1000.0), detector_size_pxl=(2000, 2000), detector_description="Eiger 16M", detector_serial_number="123", poni_rot1_rad=0.0, poni_rot2_rad=0.0, ) return RotationDataCollectionPanel(diffraction=diffraction) def _runnable(panel, monkeypatch): panel._beamline_state = BeamlineStateEnum.SampleAlignment monkeypatch.setattr(panel, "check_before_run", lambda scan_kind: True) return panel def _commit(field, text): field.setText(text) field.on_editing_finished() def _accepts(field, text) -> bool: field.setText(text) return field.hasAcceptableInput() @pytest.mark.parametrize( "beamline,too_short,ok", [("X06DA", "0.0010", "0.0012"), ("X10SA", "0.0050", "0.0090")] ) def test_min_image_time_per_beamline(qapp, monkeypatch, beamline, too_short, ok): panel = _panel(monkeypatch, beamline) for field in (panel.image_time_enter, panel.screening_image_time_enter): assert not _accepts(field, too_short) assert _accepts(field, ok) def test_speed_readout_follows_the_pair(qapp, monkeypatch): panel = _panel(monkeypatch, "X06DA") _commit(panel.image_angle, "1.000") _commit(panel.image_time_enter, "0.1000") assert panel.omega_speed.text() == "10.0" assert not panel.omega_speed.styleSheet() # within the cap _commit(panel.image_time_enter, "0.0012") # 833 deg/s assert panel.omega_speed.text() == "833.3" assert panel.omega_speed.styleSheet() # marked red def test_run_blocked_above_the_speed_cap(qapp, monkeypatch): panel = _runnable(_panel(monkeypatch, "X06DA"), monkeypatch) boxes = [] monkeypatch.setattr(QMessageBox, "critical", lambda *a, **k: boxes.append(a)) emitted = [] panel.rotation_scan.connect(emitted.append) _commit(panel.image_angle, "1.000") _commit(panel.image_time_enter, "0.0012") # 833 deg/s, over the cap panel.run_measurement() assert emitted == [] assert len(boxes) == 1 _commit(panel.image_time_enter, "0.0100") # 100 deg/s panel.run_measurement() assert len(emitted) == 1 def test_run_blocked_while_field_red(qapp, monkeypatch): panel = _panel(monkeypatch, "X06DA") boxes = [] monkeypatch.setattr(QMessageBox, "critical", lambda *a, **k: boxes.append(a)) emitted = [] panel.rotation_scan.connect(emitted.append) panel._beamline_state = BeamlineStateEnum.SampleAlignment panel.image_time_enter.setText("0.0010") # below 1/900 s, stays red panel.run_measurement() assert emitted == [] assert len(boxes) == 1