feat: show spreadsheet params in sample list
Add Oscillation, Exposure, Total range and Transmission columns to the dewar sample table, read from SampleShortInfo.aaredb_params (already filled by spreadsheetupdater from AareDB, so no server change). Transmission is shown as percent like the user spreadsheet. The new columns are nullable, so the header sort key now puts None last instead of raising on None < float. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user