Releases: alxndrkalinin/cubic
v0.8.0a2 — Wiener-Butterworth back projector for fast RL deconvolution
Adds an unmatched Wiener-Butterworth (WB) back projector to Richardson-Lucy deconvolution (Guo et al. 2020, Nat. Biotechnol. 38:1337), converging in ~1–2 iterations instead of 10–50. The matched path is byte-for-byte unchanged by default.
Highlights
create_backprojector(cubic.preprocessing) — device-agnostic NumPy/CuPy port ofBackProjector.m:traditional,gaussian,butterworth,wiener,wiener-butterworth.backprojectortoggle onrichardson_lucy_xp, threaded throughdecon_xpy,richardson_lucy_iter, anddeconv_iter_num_finder. Faithful unmatched RL update (noH^T1, nocorrection<0clip, estimate floored at 1e-3, both projectors sum-normalized); circulant only.- Example notebook
deconvolution_wb_backprojector_3d.ipynb(+ paired script + README row).
Validation
- Matched path byte-exact vs pre-change on CPU/GPU; CPU/GPU parity for the WB path ≤ 4e-8.
- On real astrocyte data (A40 GPU): WB@2 reaches matched@~10 quality with sharper absolute FSC resolution.
ruff,ruff format,mypy, fullpytest(397 passed) green.
Full Changelog: v0.8.0a1...v0.8.0a2
v0.8.0a1 — Cellpose v4 DINO model support
Features
- Cellpose v4 DINO models: the GPU-resident segmentation path now supports all four Cellpose v4 models — the SAM backbones (
cpsam,cpsam_v2) and the DINOv3 backbones (cpdino,cpdino-vitb). The canonical entry point is nowsegment_cellpose;segment_cpsamis kept as a deprecated alias (slated for removal after 0.8). - Tunable tile size:
segment_cellposeexposes absizeparameter (defaults to 256 for the SAM backbone, 384 for DINO), centralized in_resolve_bsizewith cellpose's SAM→256 guard and non-positive-bsizevalidation.
Packaging
- Require
cellpose>=4.2.0(the release that first shipscpsam_v2/cpdino). - The DINO backbones additionally require
dinov3, which is published only on GitHub:pip install git+https://github.com/facebookresearch/dinov3.
Notes
- Resident masks match stock
CellposeModel.eval(AP@0.5 ≥ 0.95) for all four models in 2D and 3D.
Full changes in #51.
v0.7.0
First stable release of the 0.7 series, consolidating work from 13 alpha pre-releases (v0.7.0a1–a13). 79 commits since v0.6.0.
Highlights
- Expanded
cubic.metrics— a full device-agnostic metrics suite: resolution (FRC/FSC/DCR, band-limited), image quality (PSNR, SSIM, MS-SSIM, MicroSSIM/MicroMS3IM), and Pearson correlation (PCC). - GPU-resident Cellpose-SAM segmentation with the v4 API.
- Device-agnostic GLCM texture features and
regionpropsextra_propertiesforwarding. - torch interop in the device layer — zero-copy CUDA↔CuPy bridging.
New features
Metrics — resolution
- DCR, histogram FSC, and band-limited metrics (#32)
- Binomial splitting for single-image FRC/FSC (#40)
Metrics — image quality
- MicroSSIM / MicroMS3IM port and a general-purpose
ms_ssim(Wang 2003, torchmetrics-compatible), withcompute_ssim_elements, an RI-factor solver (bracket + bisection on dS/dα), andimage_processinghelpers alpha_min/alpha_maxkwargs for MicroSSIM (#41)pcc(Pearson correlation coefficient)normalize='min_max'forpsnr/nrmse;spatial_dimsfor 5-D SSIM inputsreturn_ioupassthrough inaverage_precision
Feature extraction
- Device-agnostic GLCM texture features
extra_propertiesforwarded throughregionprops/regionprops_table
Segmentation
- GPU-resident Cellpose-SAM eval + v4 API migration (#46)
Device layer & examples
- torch tensors recognized in
asnumpy/get_device; CUDA tensors route to CuPy (zero-copy) - Shared device-routing helpers across the scipy/skimage proxies; proxies now scan all args for device
- Segmentation & feature-extraction example notebooks (#33); Zenodo + pooch auto-download for example data (#48)
Notable fixes
- SSIM mask footprint moved to the mask's device for cuCIM erosion (GPU per-cell SSIM)
- FSC/FRC: mean-center before Hamming window (#42); return NaN when the curve never legitimately crosses threshold (#45); honor
use_max_nyquist - Segmentation: handle empty FOVs, migrate off deprecated skimage
min_size=(#44);np.isinfor numpy ≥2.2 (#43) average_precisioncounts distinct labelscrop_cornercorrectness for single-axis and bottom-right crops- Rank-agnostic deconvolution slicing with a faithful observer path
- GLCM: float64 counts, empty-pair directions on CuPy, distance validation
Install
```bash
pip install cubic==0.7.0
```
Full changelog: v0.6.0...v0.7.0
v0.7.0a13 — fix GPU masked SSIM (cuCIM erosion footprint device)
Fixes
- GPU masked SSIM: move the erosion footprint onto the mask's device before
morphology.erosion.morphology.square/cubereceive only an int, so the device-agnostic proxy returned a host footprint; cuCIM'serosionrejected a NumPy footprint paired with a GPU mask (footprint must be either an ndarray or Sequence). Per-cell SSIM now runs on GPU. (1cd5f08)
Full changelog: v0.7.0a12...v0.7.0a13
v0.7.0a12
Alpha release adding device-agnostic texture features for the dynacell CP feature track.
Highlights
cubic.feature.glcm_features(new): device-agnostic Haralick GLCM texture features for 2D(H, W)and 3D(D, H, W)images (NumPy + CuPy). Matchesskimage.feature.graycopropsto ≤1e-9 on the seven properties (contrast, dissimilarity, homogeneity, ASM, energy, correlation, entropy), with per-image scale-invariant quantization, an optional foreground mask, and robust handling of empty-pair directions on CuPy.regionprops/regionprops_tableextra_propertiespassthrough: forward user-definedfunc(regionmask, intensity)callables to skimage/cucim.- Fix:
regionprops_tablenow preserves requested property/column order deterministically (was hash-seed-dependent across process workers).
Full diff: #49
v0.7.0a11
Pre-release.
Features
average_precision(..., return_iou=True)— expose the object-overlap IoU matrix thataverage_precisionalready computes internally (viacompute_matches) as an optional fifth return element. Lets a caller that also needs a Dice/overlap metric reuse the single overlap pass instead of recomputing it.compute_matchesgains@overloadsignatures so the(matches)vs(matches, iou)return is statically typed. Defaultreturn_iou=Falsepreserves the existing 4-tuple contract.
v0.7.0a10
Pre-release.
Examples / data
- Deconvolution example data moved to Zenodo (#48). The dead Google Drive links for the 3D astrocyte stack and theoretical PSF are replaced by a CC-BY-4.0 Zenodo deposit (10.5281/zenodo.20514102).
deconvolution_iterations_3d.ipynbnow auto-downloads both files viapoochwith sha256 verification on first run — no manual download step. Addsscripts/zenodo_upload.py+ metadata for republishing future example datasets. - Re-executed the deconvolution notebook from a clean GPU kernel; all reported resolution values unchanged (PSNR iter 35, SSIM iter 37, FSC iter 41, DCR XY 919→785 nm / Z 974→874 nm).
Closes #47.
v0.7.0a9
Pre-release.
Fixes
- FRC/FSC preprocessing: mean-center images before the Hamming window and before cube-padding to remove the DC × window artifact at low frequencies (#42).
clear_border: switch from removednp.in1dtonp.isinfor NumPy ≥ 2.2 compatibility (#43).cleanup_segmentation: handle empty FOVs without asserting, and migrate off the deprecated skimagemin_size=parameter with backend-aware dispatch for cucim (#44).- FSC/FRC resolution: return
NaNinstead of a spurious value (e.g. Nyquist or wildly large numbers from unbounded spline extrapolation) when the correlation curve never legitimately crosses the threshold (#45).
Features
- GPU-resident Cellpose-SAM evaluation (
segment_cpsam): migrate the Cellpose wrapper to the v4CellposeModel(SAM) API, add a GPU-resident eval that avoids host round-trips, port tile-norm + sharpen normalization to the GPU path, fall back to CPU flow-QC on very large masks, and add 3D + stitch parity tests (#46).
Examples
- 2D resolution notebook: use
asnumpy()forplt.imshowon CuPy arrays. - 3D resolution notebook: refresh outputs with post-mean-center FSC values.
v0.7.0a7 — expose MicroSSIM alpha_min/alpha_max kwargs
What's new
Feature: configurable bracket caps for MicroSSIM's RI-factor solver
MicroSSIM (and the inherited MicroMS3IM) now expose alpha_min / alpha_max as keyword-only kwargs on the constructor and on the get_ri_factor / get_global_ri_factor solver entry points. Defaults are bumped from the old hardcoded [1e-3, 1e3] to [1e-6, 1e6] (re-exported as ALPHA_MIN_DEFAULT / ALPHA_MAX_DEFAULT), so heavily up- or down-scaled predictions whose optimum α sits outside the old window now fit cleanly instead of raising on the bracket walk.
Use cases:
MicroSSIM(alpha_max=1e8)— lift the cap further when fitting against extreme dynamic-range mismatches.MicroMS3IM(ri_factor=α, offset_gt=..., offset_pred=..., max_val=...)— pin α from an external per-(model, organelle) calibration and skipfit()entirely; ideal for reusing one calibrated α across many evaluation calls.
Robustness
- Eager validation:
alpha_min ∈ (0, 1),alpha_max > 1, both finite — checked at construction, before any per-slice element work. - Bracket cap probe: the doubling/halving schedule probes the cap itself once before raising, so a sign change in
(last_power_of_2, alpha_max](e.g.(524288, 1e6]with the default) is not silently missed. - Bit-exact pinned-
ri_factorinvariant: identical params + inputs through identical code path produce identical floats (regression test asserts==, not< 1e-12).
API additions
cubic.metrics.microssim.ALPHA_MIN_DEFAULT/ALPHA_MAX_DEFAULTre-exportsMicroSSIM(*, alpha_min, alpha_max)get_ri_factor(elements, *, alpha_min, alpha_max)get_global_ri_factor(gt, pred, *, alpha_min, alpha_max)
Tests
- 16 new
ri_factortests covering bracket boundaries, degenerate caps, cap-probe behavior, and 2D/3D propagation - 3 new
MicroSSIMtests + 3 newMicroMS3IMtests covering inheritance of caps, pinned-α scoring withoutfit(), and eager validation
PR: #41
v0.7.0a6 — torch CUDA → cupy zero-copy fix
What's new
Fix: torch CUDA tensors now stay on GPU through cubic metrics
Previously, cubic.metrics.{pcc, ssim, psnr, nrmse} called with a torch.cuda.FloatTensor would materialize the tensor on host via .detach().cpu().numpy(), then run on CPU — a pointless GPU→CPU transfer when CuPy is available.
Now _canonicalize_torch checks the tensor's device:
- torch CUDA tensor + CuPy available →
cupy.asarrayzero-copy view via__cuda_array_interface__. Computation stays on GPU and routes to cuCIM for SSIM, cuCIM/cupy for PSNR/NRMSE, and cupy duck-typed math for PCC. - torch CPU tensor / no CuPy → host NumPy (unchanged).
Verified zero-copy: the cupy view shares the GPU pointer with the torch tensor's storage. The no-mutation contract (cubic metrics never write to inputs) makes this safe.
Tests
- New:
test_torch_cuda_tensor_routes_to_cupy_not_numpy— asserts the routing and zero-copy GPU pointer. - All previous 275 tests still pass (cellpose failure is pre-existing, unrelated API mismatch).