Skip to content

fix(navigation): keep planned-coordinate grid fixed during acquisition#563

Open
Alpaca233 wants to merge 1 commit into
Cephla-Lab:masterfrom
Alpaca233:fix/live-scan-grid-follows-during-acquisition
Open

fix(navigation): keep planned-coordinate grid fixed during acquisition#563
Alpaca233 wants to merge 1 commit into
Cephla-Lab:masterfrom
Alpaca233:fix/live-scan-grid-follows-during-acquisition

Conversation

@Alpaca233

Copy link
Copy Markdown
Collaborator

Problem

During acquisition, the orange grid of planned FOV coordinates in the navigation viewer follows the current stage position instead of staying fixed on the well plate. It tends to appear by the 2nd–3rd acquisition, especially after switching between Current Position and Manual XY modes and changing magnification.

Root cause

The orange "live scan grid" is a positioning preview (WellplateMultiPointWidget.update_live_coordinatesset_live_scan_coordinates) wired to MovementUpdater.position_after_move only while manually navigating. It is supposed to be disconnected for the duration of an acquisition (HighContentScreeningGui.toggleAcquisitionStart). Two defects defeat that:

  1. toggle_live_scan_grid(on=True) connected the signal unconditionally. PyQt removes only one connection per disconnect(), so any double-enable left a dangling connection that the single acquisition-start disconnect could not clear. Duplicates accumulate across acquisitions — which is why it shows up by the 2nd–3rd run.
  2. update_live_coordinates never checked whether an acquisition was running, so a surviving connection redrew the grid on every stage move.

Fix

  • Make toggle_live_scan_grid idempotent (returns early if already in the requested state) so duplicate connections can never form.
  • Make update_live_coordinates a no-op while acquisition_in_progress() — defense in depth that directly enforces the invariant.

The current-position FOV box uses a separate position_after_move connection, so it still tracks the stage during acquisition; only the planned grid is pinned.

Tests

tests/control/test_live_scan_grid.py:

  • test_live_scan_grid_does_not_follow_stage_during_acquisition — the grid stays put during acquisition, and still follows during manual navigation.
  • test_toggle_live_scan_grid_is_idempotent — a redundant enable leaves no dangling connection after a single disable.

Both fail before the fix and pass after. Existing GUI tests still pass.

🤖 Generated with Claude Code

The orange "live scan grid" (planned-coordinate overlay) re-centers on the
current stage position via WellplateMultiPointWidget.update_live_coordinates,
which is wired to MovementUpdater.position_after_move only while manually
navigating. It is meant to be disconnected for the duration of an acquisition.

Two defects let it follow the stage during a scan:

1. toggle_live_scan_grid(on=True) connected the signal unconditionally. PyQt
   removes only one connection per disconnect(), so any double-enable left a
   dangling connection that the single acquisition-start disconnect could not
   clear. Duplicates accumulated across acquisitions, so the grid started
   chasing the stage by the 2nd-3rd run.

2. update_live_coordinates never checked whether an acquisition was running,
   so a surviving connection redrew the grid on every stage move.

Fix: make toggle_live_scan_grid idempotent (so duplicate connections can never
form) and make update_live_coordinates a no-op while acquisition_in_progress().
The current-position FOV box uses a separate connection, so it still tracks the
stage; only the planned grid is pinned.

Adds regression tests covering both invariants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant