Commit Graph
137 Commits
Author SHA1 Message Date
duan_jandClaude Fable 5.1 2d0235071c fix: take the aareDB transmission as the fraction aarecommon >= 0.7 declares
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 (pull_request) Successful in 54s
CI / test (3.12) (pull_request) Successful in 59s
CI / test (3.13) (pull_request) Successful in 58s
CI / test (3.14) (pull_request) Successful in 1m0s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m7s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m9s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m12s
CI / test-with-coverage (pull_request) Successful in 1m32s
CI / coverage-analysis (pull_request) Successful in 21s
CI resolves aarecommon 0.7.3, where DataCollectionParameters.transmission
is a 0-to-1 fraction that rejects anything above 1.0 (the percent sheets
are converted inside AareDB >= 0.83, which main already requires). The
divide-by-100 from the earlier 'percentage' fix therefore failed the
model test on CI and would have turned 20% into 0.2% at the beamline.
Pass the fraction through and pin aarecommon>=0.7.3 so the older int
percentage model can no longer be installed; relock.

Also satisfy the diff typecheck gate: basedpyright only counts instance
variables assigned in __init__, so the Database/User toggle widgets are
created there and _build_source_toggle only lays them out.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:53:26 +02:00
duan_jandClaude Fable 5.1 2df433b33c feat: show AUTO CENTERING in the sample camera view while a loop centering runs
CI / lint (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (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 (3.12) (push) Skipped
CI / lint (pull_request) Failing after 1m2s
CI / test (3.12) (pull_request) Failing after 1m5s
CI / test (3.13) (pull_request) Failing after 1m10s
CI / test (3.14) (pull_request) Failing after 1m19s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Failing after 1m19s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Failing after 1m20s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Failing after 1m25s
CI / test-with-coverage (pull_request) Failing after 1m25s
CI / coverage-analysis (pull_request) Skipped
/status cannot tell an auto centering from a manual alignment move (both
are busy + SampleAlignment, the combo the overlay deliberately hides), so
the DAQ worker emits its own auto_centering flag: True while its own
/alc/center_loop POST is in flight (the endpoint blocks until done) or
while the automation progress reports the Center step running. The
sample camera views pass it to build_busy_overlay_style, which paints a
purple AUTO CENTERING wave text like the ROBOT MOUNTING/COOLING ones.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:35:26 +02:00
leonarski_fandClaude Opus 5 daabf830d7 fix: read the aareDB transmission as the percentage it is
CI / lint (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
DataCollectionParameters.transmission is a StrictInt documented as
"positive, between 0 and 100" (aareDB's own API description of the
spreadsheet payload), while every model that consumes it wants a 0-to-1
fraction. The old "divide by 100 only when above 1.0" guess therefore
turned a spreadsheet asking for 1% into a scan at 100% transmission -
a hundredfold dose on the sample. A fraction cannot be stored in that
column at all: the model rejects 0.2.

The mapping test now builds a real DataCollectionParameters instead of a
stand-in namespace, so a renamed column fails the test rather than the
beamline. That is what let 'totalrange' through.

daq.py's spreadsheet_params and get_auto_raster_params still carry both
the old column name and the same transmission guess.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHoUkj66jxByS2ypY5h9Mn
2026-09-07 16:59:53 +02:00
leonarski_fandClaude Opus 5 85e0609aa4 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
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
2026-09-07 16:54:16 +02:00
leonarski_fandClaude Opus 5 fd4b9b3122 fix: keep user values in the scan panels across sample mounts
CI / lint (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 / test (3.12) (push) Skipped
The panels kept the effective detector distance, resolution and
transmission in their own attributes, and a sample change overwrote those
from the spreadsheet whatever the Database/User toggle said. The fields
went on showing the user's numbers while the scan request carried the
database ones, so a value had to be re-entered after every mount.

The fields are now the only place a value lives. Each setting is worth,
in order: what the user typed while "User values" is selected, what the
mounted sample asks for, the panel default - one rule, ScanSettingsPanel
._setting, that each panel spells out a line at a time. Overrides are per
setting, so a setting the user did not touch keeps following the sample.

Along the way:

* DbOverrideLineEdit is gone; the panels use NumberLineEdit directly, and
  the per-widget database/user bookkeeping is replaced by SampleParameters,
  the one place that knows the aareDB spreadsheet column names.
* The (name, widget, converter) mapping loops with getattr/hasattr are
  replaced by explicit per-field commit slots.
* The omega speed cap no longer drives one field's validator from another
  field's value: it is a read-out plus a check on the pair at Run time.
* _add_row/_add_pair_row build the label/field/unit rows, which also puts
  the Total angle degree sign on its own row instead of the header above.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHoUkj66jxByS2ypY5h9Mn
2026-09-07 16:29:14 +02:00
duan_j 416302224c feat: 900 Hz at 6d and 120 Hz at 10s for data collection. Paint input correspondingly. 2026-09-05 11:04:18 +02:00
duan_j 0696b583b0 test: no need to compare wording
CI / test-with-coverage (pull_request) Successful in 2m23s
CI / lint (pull_request) Successful in 47s
CI / test (3.12) (pull_request) Successful in 58s
CI / test (3.13) (pull_request) Successful in 1m3s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m6s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m6s
CI / test (3.14) (pull_request) Successful in 2m18s
CI / coverage-analysis (pull_request) Successful in 3s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 3m27s
Docs build and publish / docker (push) Successful in 4s
CI / lint (push) Canceled after 34s
CI / test (3.12) (push) Canceled after 34s
CI / test (3.13) (push) Canceled after 29s
CI / test (3.14) (push) Canceled after 29s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 24s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 24s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 19s
CI / test-with-coverage (push) Canceled after 19s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 15s
2026-09-02 09:13:08 +02:00
perl_d 9939df6767 fix: separate detector tilt geometry per beamline 2026-09-01 14:50:54 +02:00
perl_d e027ccbfb1 fix: return beam center in correct format
CI / test (3.12) (pull_request) Successful in 1m1s
CI / test (3.14) (pull_request) Successful in 1m1s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m10s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m16s
CI / test (3.13) (pull_request) Successful in 1m26s
CI / lint (pull_request) Successful in 1m30s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m33s
Docs build and publish / docker (push) Successful in 3s
CI / lint (push) Canceled after 38s
CI / test (3.12) (push) Canceled after 37s
CI / test-with-coverage (push) Canceled after 22s
CI / test (3.13) (push) Canceled after 33s
CI / test (3.14) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 29s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 27s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 23s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 20s
CI / test-with-coverage (pull_request) Successful in 2m45s
CI / coverage-analysis (pull_request) Successful in 7s
2026-08-31 17:57:36 +02:00
perl_d 8797d555a7 feat: add 1D beam center config for 10S
CI / lint (pull_request) Successful in 38s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m4s
CI / test (3.13) (pull_request) Successful in 1m35s
CI / test-with-coverage (pull_request) Successful in 1m39s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m46s
CI / test (3.12) (pull_request) Successful in 2m3s
CI / test (3.14) (pull_request) Successful in 2m24s
CI / coverage-analysis (pull_request) Failing after 4s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 2m32s
Docs build and publish / docker (push) Successful in 8s
CI / lint (push) Canceled after 44s
CI / test (3.14) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 42s
CI / test (3.13) (push) Canceled after 39s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 34s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 29s
CI / test-with-coverage (push) Canceled after 27s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 20s
2026-08-31 17:37:35 +02:00
duan_j a19cbf1081 test: no need to test energy 0 and update tolerance
CI / lint (pull_request) Successful in 53s
CI / test (3.11) (pull_request) Successful in 58s
CI / test (3.13) (pull_request) Successful in 59s
CI / test (3.12) (pull_request) Successful in 1m3s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m12s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m14s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m18s
CI / test-with-coverage (pull_request) Successful in 1m29s
CI / coverage-analysis (pull_request) Successful in 3s
CI / lint (push) Successful in 34s
Docs build and publish / docker (push) Successful in 17s
CI / test (3.11) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 36s
CI / test (3.13) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 31s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 27s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 26s
CI / test-with-coverage (push) Canceled after 22s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 20s
test: update test...
2026-08-24 19:24:29 +02:00
duan_j c71676a29c test: log panel 2026-08-24 19:24:29 +02:00
duan_jandClaude Fable 5 a7bd46c14b test: sample padding pixel so movestate colors survive Linux fonts
x=20 sits on a digit glyph with CI's Linux fonts, so the assert compared
an antialiased glyph blend against the pure background. The padding area
(border 1px + padding 6px) can never contain text on any font.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0147jE48bQUTm9AqNQApT6b2
2026-08-24 19:24:29 +02:00
duan_jandClaude Fable 5 b984a36f7c fix: energy spin movestate colors never rendered
The movestate property sat on the spinbox's inner QLineEdit, which both
themes deliberately paint transparent (QAbstractSpinBox QLineEdit rule)
- the state machine worked but no color ever showed, and the tests only
asserted the property, not the paint. The property now lives on the
spinbox itself with QAbstractSpinBox[movestate=...] added to both
themes' rules, verified by a pixel-sampling regression test that grabs
the rendered widget through the real stylesheet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:24:29 +02:00
duan_jandClaude Fable 5 e1d11aa949 feat: MotorMoveGroup semantics for both Set Energy rows
The energy setpoint applies via the Change Energy button, not Enter, so
it gets the full motor state machine instead of the typing-pending
color: neutral tracks the readback, a user edit stages pending (and is
the only thing that enables the button), the click turns moving, and
readback arrival within tol returns to neutral. New SpinMoveState in
motor_move_group.py adapts the pattern to a QDoubleSpinBox+button pair
(colors ride the movestate QSS via the spin's internal QLineEdit);
replaces the hand-rolled pending-until-click in the exp-config row and
covers the Beamline setup row that had no color at all. The server's
0.0 detector-unavailable energy is kept out of the readback feed so it
cannot clamp the spin to the range minimum.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:24:29 +02:00
duan_jandClaude Fable 5 225d7064c4 feat: bound Set Energy to a 4-20 keV placeholder range
Both Set Energy rows allowed 1-30 keV, an arbitrary spinbox default;
nothing downstream validates the request (daq.change_energy forwards
straight to bec). Shared ENERGY_MIN/MAX_KEV constants now bound both
spins to 4-20 keV with a tooltip flagging the range as pending
Beamline Scientist confirmation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:24:29 +02:00
duan_jandClaude Fable 5 3e7c334abb feat: pending color while typing in Experiment configuration values
Values inside the Experiment configuration banner now show the same
pending color as the motor move boxes while the typed text differs from
the applied value; Enter (or focus-out) commits as before and clears it.
Opt-in via NumberLineEdit(track_pending=True) because MotorMoveGroup
owns the movestate property on its registered boxes; reuses the existing
movestate QSS, so no new styling. The Set Energy spinbox marks pending
until Change Energy is clicked, since its apply gate is the button.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:24:29 +02:00
duan_jandClaude Fable 5 1a9f4d8709 test: Moving state no longer flips to combined view
CI / lint (pull_request) Successful in 38s
CI / test (3.11) (pull_request) Successful in 1m1s
CI / test (3.12) (pull_request) Successful in 1m2s
CI / test (3.13) (pull_request) Successful in 1m1s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m15s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m15s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m20s
CI / test-with-coverage (pull_request) Successful in 1m31s
CI / coverage-analysis (pull_request) Successful in 4s
CI / lint (push) Successful in 31s
Docs build and publish / docker (push) Successful in 17s
CI / test (3.11) (push) Canceled after 38s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 24s
CI / test (3.12) (push) Canceled after 34s
CI / test (3.13) (push) Canceled after 33s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 29s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 28s
CI / test-with-coverage (push) Canceled after 23s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 25s
The fix removed Moving from the motion-watch trigger but the unit test and code comment still described the old behavior, so pre-push failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 13:30:20 +02:00
duan_jandClaude Fable 5 36675e0204 feat: auto-centering row with apply-after-mount, grid button raster-only
Auto Centering moves out of the experiment tabs to its own row between
Manual sample and Exp. Config., with an apply-after-mount checkbox that
re-runs it on every detected sample mount (guarded against firing on GUI
startup). Draw a Grid now only shows on the Raster scan tab.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 19:54:50 +02:00
duan_jandClaude Fable 5 64058ae6c8 feat: fold expanded help cheatsheet when mouse leaves the box
Click is no longer the only way back to the "?" badge: moving the
pointer off the expanded box, or out of the widget entirely, folds it.
Checked before the interaction gate so it works in viewing mode too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 19:54:50 +02:00
duan_j d5c66afba9 fix: combined view only when state is moving or when in robotsampleexchange 2026-08-20 19:54:50 +02:00
duan_jandClaude Fable 5 5f068a6305 feat: hover HUD with pixel coords and grey scale bar on sample camera
Bottom-right corner shows the hovered pixel coordinates with a grey
1-2-5 scale bar above them, derived from geom.pixel_in_mm and the
current zoom. Works in viewing mode (before the interaction gate),
clears on leave, and skips drawing outside the image.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 19:54:50 +02:00
duan_jandClaude Fable 5 8b6ae51ce6 fix: satisfy lint and diff-coverage gates for admin gating
basedpyright requires _admin_tip_anchor to exist after __init__, so the
anchor is created eagerly instead of lazily. Cover the red-tip branch and
the status-bar menu gate; the menu test swaps in a QMenu subclass with a
no-op exec because PySide method lookup ignores class-attr monkeypatches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 19:54:50 +02:00
duan_jandClaude Fable 5 569b024456 feat: admin-gate beam diagnostics states, warn via passive red tip
Beam location, Beamstop alignment and Flux measurement grey out for
non-staff in the state strip and the status-bar transitions menu. All
"not admin" denials now show as an auto-dismissing QToolTip on a
Catppuccin red wash instead of a click-to-close QMessageBox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 19:54:50 +02:00
duan_jandClaude Fable 5 167d78db68 style: collapse multiline _status calls for ruff format
CI / lint (pull_request) Successful in 52s
CI / test (3.11) (pull_request) Successful in 1m1s
CI / test (3.13) (pull_request) Successful in 1m3s
CI / test (3.12) (pull_request) Successful in 1m3s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m11s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m18s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m19s
CI / test-with-coverage (pull_request) Successful in 1m29s
CI / coverage-analysis (pull_request) Successful in 4s
CI / lint (push) Successful in 32s
Docs build and publish / docker (push) Successful in 15s
CI / test (3.11) (push) Canceled after 45s
CI / test (3.12) (push) Canceled after 42s
CI / test (3.13) (push) Canceled after 40s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 37s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 35s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 32s
CI / test-with-coverage (push) Canceled after 30s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 34s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 09:25:14 +02:00
duan_jandClaude Fable 5 7a01a866ef feat: status bar splits passive left / operable right
Operable controls (Fast Shutter, State, p-group, Session) group right
via addPermanentWidget and share one hover affordance - hand cursor +
underline - now owned by ClickableLabel; ValueLabel opts out for the
passive readouts, and the unwired busy label becomes a plain QLabel.
Cryo sits first in the operable group but stays passive: a cryo
operation is planned (TODO in status_bar.py), the placement just
reserves its spot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 09:25:14 +02:00
duan_jandClaude Fable 5 16b61b886b fix: no BEAMLINE BUSY overlay during Sample alignment
Same exception as the motion watch: busy in Sample alignment is the
alignment itself, and the sample motion is watched in these very
views - the curtain hid exactly what the user needed to see. Gated
at both style call sites (sample camera and the Axis views); the
session-driven 'In viewing mode' badge is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 09:25:14 +02:00
duan_jandClaude Fable 5 e9428ca64d test: pin the Sample-alignment motion-watch exception
CI / test (3.11) (pull_request) Successful in 1m12s
CI / test (3.12) (pull_request) Successful in 1m13s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m12s
CI / lint (pull_request) Successful in 1m30s
CI / test (3.13) (pull_request) Successful in 1m25s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m21s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m27s
CI / test-with-coverage (pull_request) Successful in 1m43s
CI / coverage-analysis (pull_request) Successful in 4s
CI / lint (push) Successful in 28s
Docs build and publish / docker (push) Successful in 8s
CI / test (3.11) (push) Canceled after 35s
CI / test (3.12) (push) Canceled after 31s
CI / test (3.13) (push) Canceled after 30s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 26s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 25s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 21s
CI / test-with-coverage (push) Canceled after 20s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 24s
Robot motion switches to the combined view; alignment beginning
switches straight back while busy is still set, and staying busy in
alignment never re-triggers. Piggybacks on the init test's window -
extra MainWindow constructions feed the PySide teardown flake.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 17:00:26 +02:00
duan_jandClaude Fable 5 b58c23d0f6 feat: sample camera starts in scale-to-fit
CI / lint (push) Skipped
CI / test (3.11) (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 / test (3.11) (pull_request) Successful in 1m8s
CI / test (3.12) (pull_request) Successful in 1m11s
CI / test (3.13) (pull_request) Successful in 1m9s
CI / lint (pull_request) Canceled after 1m20s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Canceled after 1m10s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Canceled after 1m7s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Canceled after 1m5s
CI / test-with-coverage (pull_request) Canceled after 1m2s
CI / coverage-analysis (pull_request) Canceled after 0s
_autoscale now defaults on, so the view fits from the first layout
(the constructor's placeholder already carries the camera size and
resizeEvent refits on every resize). update_pixmap additionally
refits when the frame size changes - the real stream resolution can
differ from the placeholder, and only a view resize refit before.
Right-click 'Scale to fit' still toggles back to 1:1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 16:49:30 +02:00
duan_jandClaude Fable 5 344888dac0 feat: Queued chip view shows the actual run order
The queue engine keeps insertion order and Run pops its head, but the
Queued view sorted by the dewar table's header sort - the top row was
not what runs next. set_queued_ids now keeps the order it is fed (the
queue model's order) and the Queued view displays exactly that; header
clicks no longer reorder it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 16:24:09 +02:00
duan_jandClaude Fable 5 8f91f1ed2e feat: fast shutter open/close row in Beamline setup
Status flag on the left (same rich-text scheme as the status bar,
theme-aware via set_theme), Open/Close buttons on the right, wired
to the same daq.open_shutter/close_shutter slots staff-gated in
main_window.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 4a728baf79 feat: clicking the '#' header selects all rows
The status column holds no sortable data, so its header click slot
was free: it now does Ctrl+A, pairing with the Unmeasured chip to
grab everything still to be done in one motion. The sort indicator
is put back afterwards - the click drags it onto '#' even though
the model ignores sorting there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 2909182bb1 fix: measured threshold is rotation count >= 1
Confirmed by Dawn: any rotation data counts as measured; unmeasured
is exactly rotation count 0. The old > 1 rule left single-rotation
samples looking like still-to-do work in the Unmeasured view.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 2a82c598c0 feat: live energy/wavelength readout in Beamline setup
New 'Current energy / lambda' row above the setpoint, fed per DAQ
tick from diffraction.energy_keV; the setpoint row is renamed
'Set Energy (keV)' so 'what is' and 'what to set' are distinct.
Guards energy 0.0 (server's detector-unavailable fallback) because
the wavelength property divides by it. The copied energy row in the
experiment configuration is renamed to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 4175cb8edf feat: add Unmeasured filter chip to the sample table
Complement of Measured (rotation count <= 1): one click shows
everything still to be done, so it can be selected wholesale and
queued. Plain chip like All - unmeasured rows carry no tint, so
there is no legend color to wear; cross-status marks (queued/
flagged) show like in the Measured view.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 fbd40eee90 feat: breathe the pending transition target in the state strip
While Moving, the target state sat solid blue and read as already
reached. An opacity pulse (QGraphicsOpacityEffect + QPropertyAnimation)
marks it as in progress; a stylesheet animation would repolish the
button every frame, which the guarded updates in _apply_highlight
exist to avoid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 c24da7739b refactor: replace Qt overrides with native mechanisms, install app filters once
Per-window installs of the two QApplication-level filters (cursor,
wheel guard) stacked one stale copy per MainWindow; now installed once
per process, parented to the app. closeEvent overrides in the baton
dialogs replaced by finished.connect(timer.stop); keyPressEvent in
VideoGraphicsView replaced by WidgetShortcut QShortcuts; hover
enter/leave overrides in PlayPauseButton replaced by underMouse();
ValueLabel inherits ClickableLabel instead of duplicating its
mousePressEvent. Dead raster-timer branch and a PyQt5-era
event-position fallback deleted; redundant try/except and getattr
guards dropped now that class-level defaults cover pre-init reads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:34:58 +02:00
duan_jandClaude Fable 5 190e728734 fix: install gate event filters after eventFilter's targets exist
CI / lint (pull_request) Successful in 1m13s
CI / test (3.12) (pull_request) Successful in 1m30s
CI / test (3.11) (pull_request) Successful in 1m38s
CI / test (3.13) (pull_request) Successful in 1m40s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m38s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m41s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m51s
CI / test-with-coverage (pull_request) Successful in 2m6s
CI / coverage-analysis (pull_request) Successful in 3s
CI / lint (push) Successful in 31s
Docs build and publish / docker (push) Successful in 15s
CI / test (3.11) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 33s
CI / test (3.13) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 28s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 27s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 23s
CI / test-with-coverage (push) Canceled after 22s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 21s
The locked-banner and Beamline-tab-bar filters were installed mid
__init__, but MainWindow.eventFilter reads sample_lists_tabs, which is
created later - every event delivered in between raised AttributeError
inside the filter ('Error calling Python override of eventFilter()'
spam) and broke widget teardown, cascading errors across CI tests and
wedging the pxiii_bec job. Filters now install late, next to
installEventFilter(self), and the filter guards its attribute reads so
construction/teardown-time events can never raise.

Also fold the staff-gate assertions into test_main_window_init: every
extra MainWindow construction raises the odds of the pre-existing
PySide SystemError flake, so don't build a window just for them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 10:54:20 +02:00
duan_jandClaude Fable 5 aa6c226103 test: cover every changed line in the branch diff
CI / lint (push) Skipped
CI / test (3.11) (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 (pull_request) Successful in 1m17s
CI / test (3.11) (pull_request) Successful in 1m44s
CI / test (3.12) (pull_request) Successful in 1m41s
CI / test (3.13) (pull_request) Successful in 2m1s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m57s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 2m0s
CI / test-with-coverage (pull_request) Successful in 2m26s
CI / coverage-analysis (pull_request) Successful in 3s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Failing after 18m13s
Diff coverage vs main now 100 percent from the gui suite alone:
non-staff locked banners and both gated-tab popups, remote-close
bookkeeping in update_daq_status, smargon staged moves, camera More
link and Alt-wheel axis fallback, number box relimits, energy row
emit, and the gui.main() banner/graceful-exit path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 09:20:44 +02:00
duan_jandClaude Fable 5 16e112f44a test: lift diff coverage over the 80 percent gate
CI / lint (push) Skipped
CI / test (3.11) (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 (pull_request) Successful in 1m3s
CI / test (3.11) (pull_request) Successful in 1m25s
CI / test (3.12) (pull_request) Successful in 1m25s
CI / test (3.13) (pull_request) Successful in 1m24s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m32s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m37s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m41s
CI / test-with-coverage (pull_request) Successful in 2m4s
CI / coverage-analysis (pull_request) Successful in 3s
Promote the illumination panel's __main__ self-check to a real pytest
file so CI counts it, add busy-overlay render checks (status text
paints, video view routes through it), and cover the motor group's
incomplete-entry and below-min Enter paths. Local diff coverage from
the gui suite alone: 82 percent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 08:52:01 +02:00
duan_jandClaude Fable 5 5871c959e2 fix: clear basedpyright diff violations
Rename NumberLineEdit.validator to range_validator: the instance attr
shadowed QLineEdit.validator() and broke type checking at call sites.
Annotate the smargon _move_axes dict and cast the stand-in self in the
prediction subscriber test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 08:52:01 +02:00
duan_jandClaude Fable 5 e18c7feded feat: stage motor entry values, apply moves in one click
CI / lint (push) Skipped
CI / test (3.11) (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
Chi/Phi boxes in the Smargon tab no longer move on Enter: edits stage
the target (orange), the Move button sends all staged axes at once
(green), and boxes return to neutral when the motor reports arrival.
Out-of-range entries stay red and are never sent; limit tips pop as
tooltips. MotorMoveGroup is opt-in per box so other panels can adopt
the same logic later.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 10:56:32 +02:00
duan_jandClaude Fable 5 69178945e5 fix: prevent libzmq abort and per-frame decode errors in prediction subscriber
CI / lint (push) Skipped
CI / test (3.11) (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
Sniff for '{' before JSON-parsing zmq parts: JPEG frames start with 0xff
and raised UnicodeDecodeError on every frame. Stop closing the socket
from the GUI thread in stop(): zmq sockets are not thread-safe and the
concurrent close/recv tripped the signaler.cpp POLLIN assertion (core
dump); run() closes it in its own thread via the 500ms RCVTIMEO.

uv.lock: sync version to 0.8.3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 10:31:57 +02:00
duan_j 9906937525 chore: add test to improve coverage
CI / lint (push) Skipped
CI / test (3.11) (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 / test (3.12) (pull_request) Successful in 1m27s
CI / lint (pull_request) Successful in 1m37s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m25s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m29s
CI / test (3.13) (pull_request) Successful in 1m59s
CI / test-with-coverage (pull_request) Successful in 2m0s
CI / test (3.11) (pull_request) Successful in 2m21s
CI / coverage-analysis (pull_request) Successful in 4s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Canceled after 2m23s
2026-08-11 16:00:58 +02:00
perl_d 8a51eef4f0 feat: lazily init jfj client 2026-08-11 13:02:54 +02:00
duan_jandClaude Fable 5 e77dfb4716 refactor: shared busy-badge renderer for camera and axis video views
draw_busy_badge in busy_overlay renders the title+subtext pill once;
the sample camera and axis video overlays both delegate to it instead
of keeping diverging copies. The axis panel's dot+label status pill and
its per-theme QSS go away with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 10:35:55 +02:00
duan_jandClaude Fable 5 e457236777 feat: merge Automation progress and Console log into one Information dock
The two tabified bottom docks left their switcher tabs stranded at the
window bottom; one Information dock with proper tabs mirrors the Sample
List dock's layout. LogDock becomes the LogPanel widget with mirror
views for the pop-out and a reveal_requested signal so the owner
controls visibility (Ctrl+Shift+L, notifications).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 10:35:55 +02:00
duan_jandClaude Fable 5 7b4764e7ca test: cover the camera overlays, theme migration, layout heal, and splash
Diff coverage vs main was 77%, under the 80% CI gate; the new camera
help/error/badge code and the theme+layout main_window paths were the
uncovered bulk. Locally: 82%.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 10:35:55 +02:00
duan_jandClaude Fable 5 2adf8ff6d5 style: narrow the log pop-out view for the pyright gate
The Optional _popout_view is assert-narrowed once after opening; the
unguarded accesses were the last three diff-gate violations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 10:35:54 +02:00
duan_jandClaude Fable 5 69b6813025 test: cover the sample-status logic, wheel guard, pop-outs, and log mirror
New tests for what the port added: status tint priority and
context-dependent chip filters on the dewar/queue model, the
right-button wheel guard (motor protection), PopoutWindow edge maths,
manual-resize fallback, close-hides behavior and DockTitleBar, the
chip drag-drop relabeling, and the console-log pop-out mirror. The
widgets' __main__ self-checks are superseded by these and removed.
Brings PR diff coverage from 70% to 81% (gate: 80%).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 10:35:54 +02:00