Summer 26 Features: ROI padding, progress logging, scaled montage - #431
Open
animmosmith wants to merge 10 commits into
Open
Summer 26 Features: ROI padding, progress logging, scaled montage#431animmosmith wants to merge 10 commits into
animmosmith wants to merge 10 commits into
Conversation
This was referenced Aug 20, 2026
animmosmith
force-pushed
the
summer26-features
branch
3 times, most recently
from
August 20, 2026 22:19
473a479 to
1170153
Compare
This was referenced Aug 20, 2026
animmosmith
force-pushed
the
summer26-features
branch
from
August 20, 2026 22:54
4356c27 to
56d4bec
Compare
… sizes Fixes #407. make_montage() always fills the same fixed rectangular canvas regardless of how much data went into it, making visual density comparisons across datasets with different sample sizes (e.g. depth bins with different numbers of raw images) misleading - every montage looks equally "full." make_montage_scaled() packs particles largest-first within a circular boundary whose area (not radius - area scales with sqrt(rel_scale) as the radius) is controlled by rel_scale. Setting rel_scale proportional to each dataset's relative sample size and placing the resulting montages side by side gives a fair visual comparison: half the raw images means half the circle area to fill. Also outputs grayscale rather than RGB, since particles from monochrome instruments don't need three channels, and it makes montage_plot()'s existing cmap='grey' argument actually take effect. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Prompted by Emlyn's review comment questioning the roifiles selection here. Truncating to the max_particles largest particles (or evenly subsampling, as gen_roifiles() does for the older make_montage) both misrepresent the true relative abundance of particle sizes - a scaled montage's whole purpose is a fair visual comparison, so it should reflect the real size distribution, not an artificially selected subset. Every exported particle is now attempted, largest first; particles that can't find a free spot are skipped as before, but now a warning is logged summarising how many were skipped once the montage is complete, since that means msize needs to be increased (not rel_scale, which exists specifically to preserve relative comparisons and would be distorted by nudging it to fit one particular montage).
Closes #416: adds an opt-in Pipeline.enable_progress_tracking(total_files, log_interval) that logs percent complete/elapsed/ETA every log_interval calls to run(). No effect unless called. With multiple chunks (pyopia process --num-chunks), each chunk's Pipeline instance tracks its own progress independently - this rides on the existing per-process logger, so it's automatically safe under the queue-based multiprocess logging already in place.
Closes #418. bbox_expansion already lets a particle's bounding box be expanded before its ROI is cropped, but that expansion is fractional - it scales with each particle's own size. There was no way to add a fixed, consistent pixel margin regardless of particle size, e.g. to guarantee a small non-particle border around every ROI fed to the classifier (which is run on this same cropped ROI as the exported file), or for visual inspection/montage context. Adds a new pad_bbox() helper (fixed-pixel analogue of the existing expand_bbox()) and a pad parameter threaded through the same chain bbox_expansion already uses: extract_roi -> extract_particles -> statextract -> CalculateStats. pad is applied on top of bbox_expansion, so either, both, or neither can be used. Clamped to image bounds the same way.
Adds a new pipeline-compatible class ImageToDisc to pyopia.io that saves processed pipeline images (raw, background, corrected, segmented, etc.) to an output folder. Supports configurable image keys, scale factor for downsizing, collage mode (all images in one file vs separate files), and image format selection. Co-authored-by: nepstad <152277+nepstad@users.noreply.github.com>
- Keep original image dtypes until conversion is needed (avoid premature float64 conversion) - Move matplotlib/skimage imports from __call__ to the specific methods that need them - Move test-level matplotlib import to module level Co-authored-by: nepstad <152277+nepstad@users.noreply.github.com>
Co-authored-by: nepstad <152277+nepstad@users.noreply.github.com>
Adds documentation in two locations: - toml_config.ipynb: Comprehensive section with configuration options table, examples for separate images and collage mode, and pipeline placement guidance - processing_raw_data.ipynb: Practical section explaining when and how to use ImageToDisc for quality control and visual inspection Co-authored-by: nepstad <152277+nepstad@users.noreply.github.com>
…klog Reimplements #390 (open 3+ weeks with no response) with the configurability suggested in review there: replaces the unbounded queue.Queue with a deque(maxlen=queue_size), so when processing falls behind acquisition, old images get dropped instead of an ever-growing backlog. The worker now pops from the right (most recently queued) so a backlog is worked off newest-first, staying close to realtime rather than grinding through stale images. queue_size defaults to 10 (matching #390's original fixed value) and is configurable via `pyopia process-realtime --queue-size`, the same way --watch-folder already is - the right value depends on acquisition rate vs. processing throughput, which is hardware/instrument-dependent.
animmosmith
force-pushed
the
summer26-features
branch
from
August 21, 2026 07:04
56d4bec to
8c324a3
Compare
animmosmith
added a commit
that referenced
this pull request
Aug 22, 2026
Wires pyopia.statistics.make_montage_scaled (#407) into the CLI, mirroring the existing make-montage command's structure (load_stats/steps_from_xstats, same output-filename handling). Exposes rel_scale, the parameter that makes density comparisons across differently-sized datasets fair - see the function's own docstring for why. Not "Closes #407" - that issue closes via #431's own commit; this is follow-on CLI wiring for the same feature, not the feature itself.
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.
Combined feature PR for the Summer 26 Features milestone. Built on top of
summer26-housekeepingso it can be reviewed/merged after that one lands.Each bullet below links to the specific commit that makes that change, so you can review them individually rather than as one combined diff.
pad_bbox()), complementing the existingbbox_expansion, threaded throughextract_roi/extract_particles/statextract/CalculateStats. (9e17ad0)Pipelineviaenable_progress_tracking(total_files, log_interval)- logs percent complete/elapsed/ETA everylog_intervalcalls torun(). No effect unless called; safe under multi-chunk processing since each chunk'sPipelinetracks its own progress independently. (5439189)make_montage_scaled()) for fair density comparison across sample sizes (26fdad7), with a follow-up refinement so it attempts every particle instead of truncating (0a74f5c).pyopia.io.ImageToDisc, a pipeline-compatible step for exporting intermediate images (raw, background, corrected, segmented) to disk for visualisation and manual review - configurable image keys, scale factor, collage vs. separate-file output, and image format (3f91d60), with follow-up memory-efficiency and cleanup commits from review (693e835,d73bde0) and notebook docs (d099aa0). 7 new tests.deque(maxlen=queue_size)instead of an unboundedqueue.Queue) so a backlog gets worked off newest-first and old images are dropped once processing falls behind acquisition, instead of growing forever.queue_sizeis configurable viapyopia process-realtime --queue-size(default 10, matching prior behaviour). (8c324a3)Test plan
flake8 pyopiacleanuv run pytest -m "not slow"- 43 passed