fix: read the aareDB total angle from the column that exists
CI / lint (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / lint (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
The column is totalangle, not totalrange, so reading it raised AttributeError four times a second in the status loop. Reading a spreadsheet cell now goes through _spreadsheet_float, which treats a missing column, an empty cell and a cell that does not hold a number all as "not set" and logs the column once. aareDB owns these names; the GUI should fall back to its defaults when one moves, not die on the status loop it is read from. Note that the same misspelling is still in daq.py (spreadsheet_params and get_auto_raster_params), where getattr's default hides it: automation has never picked up the total angle from the spreadsheet either. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JHoUkj66jxByS2ypY5h9Mn
This commit is contained in:
@@ -48,9 +48,24 @@ from aare.gui.widgets.number_line_edit import NumberLineEdit
|
||||
logger = setup_logger(LOGGER_NAME)
|
||||
|
||||
|
||||
def _as_float(value: Any) -> float | None:
|
||||
"""Spreadsheet values arrive as numbers or as strings; an empty cell is None."""
|
||||
return None if value is None else float(value)
|
||||
# Columns already reported as unusable, so the status loop says it once.
|
||||
_BAD_COLUMNS: set[str] = set()
|
||||
|
||||
|
||||
def _spreadsheet_float(params: Any, column: str) -> float | None:
|
||||
"""One cell of the sample's spreadsheet row, as a float. An empty cell, a
|
||||
cell that does not hold a number, and a column aareDB does not have all
|
||||
read as None: aareDB owns these names, and a renamed column must not kill
|
||||
the status loop. Each bad column is reported once - pydantic's own message
|
||||
names the column it expected instead."""
|
||||
try:
|
||||
value = getattr(params, column)
|
||||
return None if value is None else float(value)
|
||||
except (AttributeError, TypeError, ValueError) as e:
|
||||
if column not in _BAD_COLUMNS:
|
||||
_BAD_COLUMNS.add(column)
|
||||
logger.error(f"Ignoring the aareDB parameter {column!r}: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -71,16 +86,16 @@ class SampleParameters:
|
||||
params = None if sample is None else sample.aaredb_params
|
||||
if params is None:
|
||||
return cls()
|
||||
transmission = _as_float(params.transmission)
|
||||
transmission = _spreadsheet_float(params, "transmission")
|
||||
if transmission is not None and transmission > 1.0:
|
||||
# aareDB holds transmission either as a fraction or as a percentage
|
||||
transmission = transmission / 100.0
|
||||
return cls(
|
||||
resolution_a=_as_float(params.targetresolution),
|
||||
resolution_a=_spreadsheet_float(params, "targetresolution"),
|
||||
transmission=transmission,
|
||||
total_angle_deg=_as_float(params.totalrange),
|
||||
image_angle_deg=_as_float(params.oscillation),
|
||||
exp_time_s=_as_float(params.exposure),
|
||||
total_angle_deg=_spreadsheet_float(params, "totalangle"),
|
||||
image_angle_deg=_spreadsheet_float(params, "oscillation"),
|
||||
exp_time_s=_spreadsheet_float(params, "exposure"),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ def test_sample_parameters_translate_the_spreadsheet_row():
|
||||
params = types.SimpleNamespace(
|
||||
targetresolution=1.5,
|
||||
transmission=20.0, # percent
|
||||
totalrange="180", # spreadsheet cells can arrive as text
|
||||
totalangle="180", # spreadsheet cells can arrive as text
|
||||
oscillation=0.1,
|
||||
exposure=0.02,
|
||||
)
|
||||
@@ -64,6 +64,14 @@ def test_sample_parameters_are_empty_without_a_sample():
|
||||
assert SampleParameters.from_sample(None) == SampleParameters()
|
||||
|
||||
|
||||
def test_a_column_aaredb_does_not_have_is_ignored():
|
||||
# aareDB owns these names: a renamed column must leave the panel on its
|
||||
# defaults, not break the status loop it is read from.
|
||||
params = types.SimpleNamespace(targetresolution=1.5)
|
||||
sample = cast(Any, types.SimpleNamespace(aaredb_params=params))
|
||||
assert SampleParameters.from_sample(sample) == SampleParameters(resolution_a=1.5)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Rotation panel
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user