Feature/live refresh + sim#1
Merged
maragall merged 2 commits intomaragall:mainfrom Mar 20, 2026
Merged
Conversation
maragall
pushed a commit
that referenced
this pull request
Jan 22, 2026
* Display channel names instead of numeric indices - Extract channel names from OME metadata or filenames - Store channel names in xarray attrs for later use - Add _update_channel_labels() method to update NDV's internal _lut_controllers with actual channel names - Use QTimer delay to ensure NDV initialization completes before updating labels 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments for channel name display - Keep xarray coords numeric instead of string channel names to avoid luts/coords type mismatch (addresses comments #2 and #3) - Replace fixed 500ms QTimer delay with retry mechanism that polls for _lut_controllers readiness with bounded retries (addresses comment #4) - Add documentation noting _lut_controllers is a private API that may change in future ndv versions (addresses comment #1) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 2) - Fix single-TIFF path to use numeric coords instead of string channel names, consistent with OME-TIFF path (comment #1) - Add generation counter to cancel stale retry callbacks when viewer is replaced by a new dataset load (comment #2) - Add hasattr check for synchronize() method with debug logging when missing (comment #3) - Remove placeholder issue URL, keep explanation about private API (comment #4) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add comment explaining synchronize() purpose 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 4) - Fix misleading "all axes" comments to accurately describe which axes use numeric indices vs actual values (comments #3, #5) - Preserve partial channel names from OME metadata instead of discarding all when count doesn't match n_c (comment #4) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 5) - Initialize _channel_label_generation in __init__ for clarity instead of relying on getattr defaults (comment #5) - Add debug logging when channel label update succeeds (comment #6) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 6) - Rename 'channels' to 'channel_names' in single-TIFF path for consistency with OME-TIFF path (comment #1) - Initialize _pending_channel_label_retries in __init__ alongside _channel_label_generation for consistency (comment #3) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add unit tests for channel name display feature Test coverage includes: - OME-TIFF channel name extraction and fallback logic - Single-TIFF channel name extraction from filenames - Retry mechanism with generation counter - Channel label update on NDV controllers - Integration tests for end-to-end behavior 25 tests, all passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 7) - Clarify that numeric coordinates convention applies to both OME-TIFF and single-TIFF paths (comment #5) - Document graceful failure mode if private _lut_controllers API changes (comment #9) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 8) - Change timeout log from debug to warning for user visibility (comment #2) - Add pytest install note to tests/README.md (comment #3) - Remove unused pytest import (comment #8) - Remove unused ch2 variable (comment #6) - Remove unnecessary pending_retries assignment (comment #7) - Add explanatory comments to except clauses (comments #9, #10, #11) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review comments (round 9) - Fix debug log to track actual updated names instead of slicing list (handles controller gaps correctly) (comment #15) - Remove unnecessary getattr for _pending_channel_label_retries since it's now initialized in __init__ (comment #21) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix channel labels not updating during in-place refresh During live acquisition, if _try_inplace_ndv_update succeeds, the code returned early without scheduling channel label updates. This caused channel labels to show numeric indices instead of names (e.g., "DAPI", "GFP") after in-place data swaps. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix CI: black formatting and skip downsampling tests when unavailable - Apply black formatting to ndviewer_light.py and test_channel_names.py - Add pytest skipif marker to test_downsampling_wrapper.py to skip tests when Downsampling3DXarrayWrapper is not available (requires scipy) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add scipy to CI environment for 3D downsampling tests scipy.ndimage.zoom is used by Downsampling3DXarrayWrapper for resampling large 3D volumes to fit within OpenGL texture limits. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Remove accidentally committed IDE config files - Remove .claude/agents/ directory (IDE-specific configuration) - Remove .coverage file (test artifact) - Add both to .gitignore to prevent future commits 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Replace line number references with method names in tests Line numbers drift as code evolves, making references misleading. Method names are more stable and searchable with IDE navigation. Updated: - test_channel_names.py: All inline comments now reference method names - tests/README.md: Documentation uses method names instead of line numbers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix README: "three main areas" → "five main areas" The test file has five test classes, not three. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Change synchronize() fallback log from debug to warning If synchronize() method doesn't exist on LUT controller, channel labels may not appear in the UI. A warning is more appropriate than debug level. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Use _ = for intentionally unused ET.SubElement return value Makes explicit that the return value is intentionally unused. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Extract constants and helper for channel label update retry - Add CHANNEL_LABEL_UPDATE_MAX_RETRIES (20) constant - Add CHANNEL_LABEL_UPDATE_RETRY_DELAY_MS (100) constant - Extract _initiate_channel_label_update() helper method to DRY up duplicated code between _store_data_from_loader and _set_ndv_data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
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 pull request adds live dataset refresh support to the
ndviewer_light.pyviewer and introduces a new script,simulate_live_acquisition.py, for simulating ongoing acquisitions on disk. The main focus is on enabling the viewer to automatically detect and display new data as it appears, which is particularly useful for live imaging experiments.The most important changes are:
Live refresh and dataset monitoring in the viewer (
ndviewer_light.py):QTimerto check for new timepoints or fields of view in the dataset folder, enabling the viewer to automatically refresh and display new data during ongoing acquisitions. This includes robust detection of changes and efficient in-place updates to minimize flicker. [1] [2] [3]Color mapping adjustment:
'darkred'to'magenta'for better visual distinction.Simulation tool for live acquisition:
simulate_live_acquisition.py, which generates a "single_tiff" style dataset on disk, simulating the gradual appearance of new timepoints and FOVs. The script can also launch the viewer automatically, allowing for end-to-end testing of live refresh functionality.