- retarget theme.py to Catppuccin Latte (light) + Mocha (dark)
- route on-fill text through accent_text (Mocha's light pastels need dark text);
fixes unreadable buttons
- transport buttons: labelled + sized (Play/Pause/Skip/End were cramped glyphs)
- top-bar ☾/☀ theme toggle: live rebuild of views, backend kept, persisted to
QSettings (wiring split into persistent vs view-facing for safe re-wire)
- beam-path pipeline signature: continuous rail, green completed segment, mauve
focal bloom on the active station
- palette-ize stray colours (slider grooves, alert tints, state LED hues, legend)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When there is no server (base_url is None), seed fake samples, a synthetic live
status (incl. a real SampleGeometryModel so bookmark/click projections work),
and a fake camera frame, so Manual mount -> pipeline/motors/bookmarks can be
tested without a backend. Gated to no-server; never affects real runs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- each bookmark has an inline-editable label (rename signal)
- bookmarks persist per-sample via QSettings (keyed by sample db_id): saved on
add/remove/rename, reloaded when the same sample is remounted (and across
GUI restarts)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mark smargon positions during data collection (numbered markers on the camera,
projected via smargon_to_picture and tracked through rotation). Per-bookmark:
Go (move_smargon + set_omega) and Collect (rotation scan with start = bookmark,
i.e. launch data collection from that point). Cleared on unmount.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stop enabling/displaying the per-frame focus metric; also lightens the camera
thread's per-frame work.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- replace CSV-polling smargon trace with a live QtCharts dialog (deltaX/Y/Z +
distance from a reference, fed by the status stream); launch from camera strip
- camera live feed uses fast (nearest) scaling instead of smooth — smooth
rescaling every frame caused lag at low frame rates / long exposures
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Staff alignment view (3rd mode, staff only): beam location / beamstop /
align CoR / flux measurement procedures; camera+spectrum + alignment motors
- Motors: compact SMARGON with editable Chi/Phi + Focus(Z) jog; staff-only ABR
(GMX/GMY/GMZ) moved under SMARGON; energy removed (now staff-tools only)
- Inline camera Exp/Gain by the sample camera
- Prediction-metrics dialog from the prediction stream
- shared _wire_motors; guest overlay also covers the staff camera
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- camera: ML detection boxes+polygons (per-class colours), state-coloured beam
centre marker, focus readout
- camera controls in tab strip: gain/exposure (samcam_settings), autofocus,
screenshot-to-DB
- Gonio/Beamline tabs wired to axis IP video via VideoThread
- precondition gate (ring/shutter/hutch + 1h snooze) on scans; hutch-PSS mount
block; sample-missing modal
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Commit 071b4ab made mount() return SUCCESS as soon as it saw the intermediate
TELL "state"/Busy event, before the later "Gripper detection" event is read,
so an empty-gripper mount completed silently with no MountingFailed/pop-up.
check_command_ok blocks (wait_not_busy) until the mount sequence finishes, so
after it returns the robot's own record is authoritative: if get_mounted_sample()
is None the gripper was empty -> return NO_PIN_IN_GRIPPER, which the mounting
service maps to MountingFailed("No Pin in Gripper"). Covers manual and automation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix the GUI pop-up path and add personnel-safety-system (PSS) gating so
door-open / beam-down / shutter-closed conditions are surfaced and acted on.
- exception pop-ups: connect the previously-orphaned http_error signal;
failed user operations now raise a modal dialog, background/polling errors
a non-modal banner.
- PSS device (devices/pss_state.py) reading EH1-PSYS PROHIBITED-STATE /
ALARM-STATE; new critical DoorSafetyError + DOOR_SAFETY_ERROR code.
- mounting service blocks mount/unmount when the hutch is not prohibited or
an alarm is active; /status now publishes pss_prohibited / pss_alarm.
- GUI blocks manual mount/unmount and the automation Run button immediately
(pop-up) on door-open, and shows a warning banner while an alarm is active.
- centralise per-action precondition checks (ring current, safety shutter,
hutch door) into one combined "continue?" dialog with a session-global
"don't ask again for 1 hour" snooze, applied to all data-collection buttons.
- live automation pauses and auto-resumes on bad conditions (beam, shutter,
door, robot) with continue-now / stop overrides, gated by a default-on
"Pause on bad conditions" checkbox replacing the dead CHECK_ENABLED constant.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add DbOverrideLineEdit: a numeric field holding both a database value and
the user's value, driven by a per-tab Database/User-values toggle. The
user's value persists across samples, can be reverted to the database
value, and recovered again - replacing the clunky per-field checkboxes.
Fix the dtz<->resolution coupling so editing one updates the other in both
Database and User modes (previously it broke whenever a value was
overridden). Wire resolution, detector distance, transmission, exposure,
rotation total/image angle and the raster grid element size through the
new widget; other panels are untouched.
Add tests covering persist/revert/recover, the toggle's downstream emit,
the dtz/resolution coupling in both modes, and cross-sample persistence.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>