diff --git a/src/aare/gui/models/user_sample_model.py b/src/aare/gui/models/user_sample_model.py index 0d25a5ce..78699887 100644 --- a/src/aare/gui/models/user_sample_model.py +++ b/src/aare/gui/models/user_sample_model.py @@ -43,7 +43,19 @@ def get_entry(sample: SampleShortInfo, column: int): return sample.screening_count elif column == 10: return sample.rotation_count + # Data-collection params straight from the AareDB spreadsheet (filled by + # spreadsheetupdater). Nullable: samples without params show blank. elif column == 11: + return sample.aaredb_params.oscillation if sample.aaredb_params else None + elif column == 12: + return sample.aaredb_params.exposure if sample.aaredb_params else None + elif column == 13: + return sample.aaredb_params.totalangle if sample.aaredb_params else None + elif column == 14: + # Model holds a 0-1 fraction; users think in spreadsheet percent. + t = sample.aaredb_params.transmission if sample.aaredb_params else None + return None if t is None else round(t * 100, 1) + elif column == 15: return sample.comment return "" @@ -74,6 +86,10 @@ class UserSampleSpreadsheet(QAbstractTableModel): # collected, so Screening sits left of Rotation. "Screening count", "Rotation count", + "Oscillation (°)", + "Exposure (s)", + "Total range (°)", + "Transmission (%)", "Comment", ] self.current_sample = current_sample @@ -261,10 +277,16 @@ class UserSampleSpreadsheet(QAbstractTableModel): ), # Reverse for descending order ) else: - # Sort the samples based on the specified column and order + # Sort the samples based on the specified column and order. + # Nullable columns (params, comment): None sorts last, never + # compared against a real value (None < float raises). + def _key(row): + v = get_entry(row, self._sort_col) + return (v is None, "" if v is None else v) + self._sorted_samples = sorted( filtered, - key=lambda row: get_entry(row, self._sort_col), + key=_key, reverse=( self._sort_order == Qt.SortOrder.DescendingOrder ), # Reverse for descending order diff --git a/tests/unit/gui/test_models.py b/tests/unit/gui/test_models.py index 95c634bc..e36b10df 100644 --- a/tests/unit/gui/test_models.py +++ b/tests/unit/gui/test_models.py @@ -263,3 +263,28 @@ def test_mime_data_round_trips_for_chip_drops(status_model): samples = SampleShortInfoList.model_validate_json(payload.text()) assert len(samples.s) == 2 assert samples.s[0].db_id == model.get_id(0).db_id + + +def test_spreadsheet_param_columns(status_model): + from aarecommon.models.models import DataCollectionParameters + + model = status_model + hdr = model.header + osc, exp, tot, trans = ( + hdr.index("Oscillation (°)"), + hdr.index("Exposure (s)"), + hdr.index("Total range (°)"), + hdr.index("Transmission (%)"), + ) + model.get_id(_row_of(model, 1)).aaredb_params = DataCollectionParameters( + oscillation=0.1, exposure=0.01, totalangle=360, transmission=0.125 + ) + row = _row_of(model, 1) + d = lambda c: model.data(model.index(row, c), Qt.ItemDataRole.DisplayRole) + assert (d(osc), d(exp), d(tot), d(trans)) == (0.1, 0.01, 360, 12.5) + # No params -> blank, and sorting a mostly-None column must not raise; + # the real value sorts first. + assert model.data(model.index(_row_of(model, 2), osc), Qt.ItemDataRole.DisplayRole) is None + model.sort(osc, Qt.SortOrder.AscendingOrder) + assert model.get_id(0).db_id == 1 + assert model.headerData(hdr.index("Comment"), Qt.Orientation.Horizontal, 0) == "Comment"