Skip to content

G6: domain-blind viewers - #1178

Merged
trissim merged 8 commits into
mainfrom
refactor/G6-domain-blind-viewers
Oct 10, 2026
Merged

trissim merged 8 commits into
mainfrom
refactor/G6-domain-blind-viewers

Conversation

@trissim

@trissim trissim commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Surface G6 (receipt: docs/refactor/consolidation-20261009/G6-domain-blind-viewers.md). The napari and Fiji viewers no longer use OpenHCS's axis family. They lay out any stream from the axes that the stream declares.

Wire and layout

  • The display config now carries declared_axes (DeclaredAxis: name, label, roles, value kind). Each viewer validates component_modes and component_order against the payload's own axes. The exact-set rejection in config.py is deleted. No viewer module reads AxisFamily.active() (guarded).
  • Each viewer has a ViewerSlotFamily. NapariSlots are layer and stack. FijiSlots put colour in C, stack in Z, time in T, and anything else in FRAME, plus a window slot; axes that share a slot combine in declared order. NapariDimensionMode and FijiDimensionMode are derived from these families, keeping their member names so saved configs still load. The per-role field defaults also come from the slot family.
  • The napari WELL→LAYER and fractional-Z cases now ask the declared axes for their role. Labels come from Axis.label, which the microscopy family sets to Ch, Z and T. ViewerAxisLabelStrategy is deleted. A named channel label now reads Ch 1: DNA (before: Ch1: DNA).
  • The viewer decodes NapariDisplaySettings / FijiDisplaySettings, so openhcs.core.config is never imported in the viewer process.

Control: there is now one ViewerControlAction family. Each viewer inherits the lifecycle actions (shutdown, force-shutdown, clear-state, process-launch, settle) over a ViewerServerPort.

  • Bug fixed: Fiji used to answer unknown messages with SUCCESS. Now one shared action answers ERROR, so navigate, viewport and measure sent to Fiji fail visibly.
  • Both viewers advertise pong capabilities derived from the registry.
  • The FijiUnsupported* plans are deleted.

Identity: each viewer is one ViewerFamily class (NapariViewer, FijiViewer) that owns its backend, config key, title, display settings (and so its slot family) and visualizer.

  • ViewerType is now a boundary enum derived from that registry.
  • Deleted: ViewerDeclarationABC and the forwarding properties on StreamingConfig and its mixin.
  • start_viewer/stop_viewer are written once, in ManagedViewerLifecycleMixin.

Import cut: ExecutionConnectionProjection is renamed ExecutionConnectionFields and moved next to ExecutionConnectionSpec. The napari server now loads 75 openhcs modules instead of 203, with no microscopes, orchestrator or config (guarded).

Lockstep library PRs (not tagged; the lead releases): OpenHCSDev/ZMQRuntime#27 (0.5.0, deletes the flat ViewerComponentMode), OpenHCSDev/PolyStore#33 (0.4.0, receivers take window and layer components; requires zmqruntime 0.5) and OpenHCSDev/PyQT-reactive#17 (0.3.29, accepts zmqruntime <0.6). The pins are bumped here, and the submodule pointers point at those branches' commits.

Durable state: NapariVariableSizeHandling moved to openhcs.runtime.viewer_display. None of the owner's saved files reference it (checked by the lead), so no cutover tool is needed.

Rule 1b: Authority, admission and receipt names in the viewer modules are renamed (for example ViewerComponentCoordinateAuthority → ViewerComponentCoordinates and admit_settlement → request_settlement).

Tests: 37 viewer test files ran under -n 2 against a clean origin/main worktree. This branch introduces no failures beyond the baseline's 99. test_completed_shapes_publish_full_inventory_and_declared_domain fails only in the full-file run and passes alone; the same file fails 47 times on the baseline. A further 58 related files (agent, MCP, GUI, config, demos) show the same failures as the baseline after the fixes. New: guards (6), a witness in which a viewer under microscopy decodes a RemoteSensing stream and a family-level control test.

G6 · PR #1178 · guards 6/6 · production −1778 +1643 · tests −578 +886

🤖 Generated with Claude Code

trissim and others added 3 commits October 10, 2026 03:55
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ExecutionConnectionProjection (renamed ExecutionConnectionFields: it carries
a connection, nothing is projected) moves beside ExecutionConnectionSpec, so
agent/dto/viewer.py no longer pulls zmq_execution_client, the orchestrator and
the microscope handlers into the napari server (203 -> 75 openhcs modules).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…family, ViewerFamily

- The display-config wire section carries the stream's DeclaredAxis list
  (name, label, roles, value kind). Viewers lay a stream out and validate it
  against its own declarations; no viewer module reads AxisFamily.active().
  The exact-set rejection and from_display_payload copies in config.py are
  deleted; the viewer decodes NapariDisplaySettings/FijiDisplaySettings and no
  longer imports openhcs.core.config.
- Each viewer owns a ViewerSlotFamily (NapariSlots: layer/stack; FijiSlots:
  window, C, Z, T by role, FRAME otherwise). NapariDimensionMode and
  FijiDimensionMode are views derived from them, and the per-role config
  defaults derive from the slot families. Partition and stack special cases in
  napari are role queries on the declared axes. Labels come from Axis.label.
- One ViewerControlAction family: every viewer inherits shutdown,
  force-shutdown, clear-state, process-launch and settle over a
  ViewerServerPort; unknown messages answer ERROR (Fiji answered SUCCESS);
  pong capabilities derive from the registry for both viewers. The
  FijiUnsupported* plans are deleted.
- One ViewerFamily class per viewer (NapariViewer, FijiViewer) owns wire
  name, backend, display settings and visualizer; ViewerType is the boundary
  enum derived from the registry; ViewerDeclarationABC and the StreamingConfig
  forwarding properties are deleted. start_viewer/stop_viewer live once in
  ManagedViewerLifecycleMixin.
- Lockstep: zmqruntime 0.4.2 (flat ViewerComponentMode deleted) and PolyStore
  0.3.5 (receivers take window/layer components).
- Rule 1b renames in the viewer modules (Authority/admission/receipt names).
- Guards in tests/unit/test_g6_viewer_guards.py; one-shot cutover tool for the
  moved NapariVariableSizeHandling import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 10, 2026 07:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

… the cutover tool

The owner's files do not reference NapariVariableSizeHandling, so the
one-shot import cutover is not needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
trissim and others added 4 commits October 10, 2026 13:06
…ies; absorb napari 0.9.2 slicing API

- zmqruntime 0.5.0 (079a1c41d), PolyStore 0.4.0 (f6af43a9b), python-introspect
  0.2.5 (4bb7d132d); minimum versions raised.
- Axis keeps G6's label beside G4's metadata declarations; the installed demo
  takes main's typed viewer payload check.
- napari 0.9.2 removed Layer._make_slice_input and _indices_view: native frame
  completion uses _slicing_state.make_slice_input (B2's fix, #1182) and the
  displayed-subject projection reads _view_indices.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… payload spatial rank; napari tests read _view_indices

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions

The viewer took axis labels only from merged value-name metadata, so a stream
without value names showed raw axis names. The display batch now declares the
route's axes on the viewer's name metadata. The official30 test reads
ViewerType members by value and their config key through the family.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orts NapariVariableSizeHandling from viewer_display

FijiSlots.Channel collided with the microscopy member name the kernel guard
forbids; the slots are HyperstackChannel/Slice/Frame and the form-choice enum
members derive from the slot wire values (unchanged CHANNEL/SLICE/FRAME).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@trissim
trissim merged commit 0bcfcf3 into main Oct 10, 2026
1 of 38 checks passed
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.

2 participants