feat(napari): add registration panel#216
Open
sdiebolt wants to merge 77 commits into
Open
Conversation
Add a napari-native progress reporter that streams the resampled moving image into a live Image layer, complementing the existing matplotlib plotter. - register_volume gains a progress_plotter factory argument; when show_progress=True, the factory is used in place of the matplotlib default. The matplotlib path is unchanged. - New NapariVolumeProgress plotter + NapariProgressBridge (Qt signal bridge) live in confusius._napari._registration._progress. The bridge routes per-iteration resampled arrays from the worker thread to the GUI thread via a queued connection, so the layer can be mutated safely. - RegistrationPanel._setup_volume_progress wires the panel: the fixed layer is tinted red, the moving layer is tinted cyan and hidden, and the preview is seeded with the moving image resampled onto the fixed grid (identity transform) so the first frame is a meaningful unaligned view. Iterations overwrite the preview in place. On teardown, the moving layer stays hidden and the preview is removed so the final result layer replaces it without leaving duplicates.
Add a per-iteration optimizer-metric curve to the registration progress overlay so users can watch convergence alongside the red/cyan resampled preview. - NapariProgressBridge gains a metric_updated(float) signal; the worker-side NapariVolumeProgress.update() emits the current metric value on every iteration (gated on plot_metric so the matplotlib path stays unchanged). - New RegistrationMetricPlotter widget in confusius._napari._registration._metric_plotter renders the curve in a bottom-docked matplotlib canvas with a navigation toolbar. Rapid iteration events are coalesced through a 16 ms QTimer so the canvas redraws at most once per frame. - RegistrationPanel._ensure_metric_plotter lazily creates and docks the widget (mirroring SignalPanel's lazy-dock pattern, including the HiDPI click-offset workaround). The plotter is reused across runs and reset per run; the dock is kept after teardown so the user can inspect the final convergence trace. - Tests cover the buffer, the 16 ms redraw throttling, the plot_metric=False suppression, and the panel-level dock creation + bridge wiring.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Clicking abort during within-scan (volumewise) registration froze the GUI on Windows and never actually cancelled the remaining work. After the abort event was set, every remaining frame was still dispatched through register_volume, which only skips SimpleITK's Execute() — the one step that releases the GIL. The leftover pure-Python/numpy setup and a wasted resample, multiplied across joblib threads, monopolised the GIL and starved the Qt main thread (worse on Windows, where GIL hand-off to a waiting thread is far less fair than on Linux), so the GUI only unfroze once all frames had been computed. - Short-circuit _register_one before calling register_volume once aborted, returning the original frame with a zero-iteration "aborted" diagnostic. - Stop dispatching new frames to joblib once the abort event is set. - Fill aborted/un-started frames with the data minimum (background) instead of the unregistered input, so the partial result shows which frames were skipped, matching the live preview.
Rename the volumewise 'Ref. time' label to 'Reference volume' to match its spinbox behaviour (clamped to the moving layer's time dimension) and update the related tooltip and docs copy. Constrain the width of the reference-volume, learning-rate, and iterations spinboxes so they don't stretch and align with the rest of the form fields. In the signals panel, regroup the y min/max spinboxes on a single row and tighten their width.
…sforms Rename the remaining noun-style transform helpers to imperative verb phrases for consistency with the project convention: - affine_transform_from_payload -> get_affine_transform_from_payload - bspline_transform_from_payload -> get_bspline_transform_from_payload - output_grid_from_payload -> get_output_grid_from_payload - _affine_payload_from_layer -> _get_affine_payload_from_layer - _spatial_manual_affine_from_layer -> _get_spatial_manual_affine_from_layer Merge _transforms.py into _panel_transform_helpers.py. The split was arbitrary: all transform-payload TypedDicts, construction, deserialization, and I/O helpers, plus the layer-specific helpers, are used exclusively by the napari registration panel. The merged module removes a cross-import and an unneeded module boundary.
Rename the remaining noun-style panel utility helpers to imperative verb phrases for consistency with the project convention: - _default_dims_for_ndim -> get_default_dims_for_ndim - _layer_supports_registration_source -> is_registration_source_layer - _image_display_kwargs_from_layer -> get_image_display_kwargs_from_layer - _should_reset_gamma -> gamma_needs_reset Rename _parse_sequence to parse_comma_separated_ints to make the input format and parsed type explicit, and complete its one-line docstring with full Parameters and Returns sections. Add missing Parameters and Returns sections to is_registration_source_layer.
Add the leading underscore back to the five recently renamed panel utility helpers to keep the file consistent with its existing private naming convention: - get_default_dims_for_ndim -> _get_default_dims_for_ndim - is_registration_source_layer -> _is_registration_source_layer - get_image_display_kwargs_from_layer -> _get_image_display_kwargs_from_layer - gamma_needs_reset -> _gamma_needs_reset - parse_comma_separated_ints -> _parse_comma_separated_ints The functions remain module-internal to the napari registration module; only their call sites in _panel.py needed updating.
Move the transform payload and panel-specific transform helpers out of _panel.py and the previous _panel_transform_helpers.py into a single _panel_transforms.py module, with docstrings completed in the process. - Hoist UI callbacks (save, load, apply, refresh transform controls) into panel-level lambdas so the panel only owns wiring. - Update the napari registration panel tests to call the new module-level helpers.
…ot defaulting to oneline
- drop trailing ":" from form labels (signals, video, save panels) - align the signals source dropdowns in one grid column - let the y-limit spin boxes share the full row width instead of a 96px cap; Ignored size policy keeps the issue #183 overflow away
# Conflicts: # docs/images/gui/generate.py # src/confusius/_napari/_signals/_panel.py # src/confusius/_napari/_time_overlay.py # src/confusius/_napari/_tour.py # src/confusius/_napari/_widget.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds a new napari Registration tab for between-scan and within-scan workflows. It supports live previews and progress reporting, cooperative aborts with partial results, transform save/load/apply flows (including manual napari transforms and B-spline control-point grids via Zarr), and the registration parameter controls needed to run the existing ConfUSIus registration backends from the GUI.
Closes #210.
Closes #213.