Skip to content

Releases: alxndrkalinin/cubic

v0.8.0a2 — Wiener-Butterworth back projector for fast RL deconvolution

19 Jun 05:37

Choose a tag to compare

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 of BackProjector.m: traditional, gaussian, butterworth, wiener, wiener-butterworth.
  • backprojector toggle on richardson_lucy_xp, threaded through decon_xpy, richardson_lucy_iter, and deconv_iter_num_finder. Faithful unmatched RL update (no H^T1, no correction<0 clip, 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, full pytest (397 passed) green.

Full Changelog: v0.8.0a1...v0.8.0a2

v0.8.0a1 — Cellpose v4 DINO model support

15 Jun 21:44
6dbf90e

Choose a tag to compare

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 now segment_cellpose; segment_cpsam is kept as a deprecated alias (slated for removal after 0.8).
  • Tunable tile size: segment_cellpose exposes a bsize parameter (defaults to 256 for the SAM backbone, 384 for DINO), centralized in _resolve_bsize with cellpose's SAM→256 guard and non-positive-bsize validation.

Packaging

  • Require cellpose>=4.2.0 (the release that first ships cpsam_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

12 Jun 16:45

Choose a tag to compare

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 regionprops extra_properties forwarding.
  • 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), with compute_ssim_elements, an RI-factor solver (bracket + bisection on dS/dα), and image_processing helpers
  • alpha_min / alpha_max kwargs for MicroSSIM (#41)
  • pcc (Pearson correlation coefficient)
  • normalize='min_max' for psnr/nrmse; spatial_dims for 5-D SSIM inputs
  • return_iou passthrough in average_precision

Feature extraction

  • Device-agnostic GLCM texture features
  • extra_properties forwarded through regionprops / 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.isin for numpy ≥2.2 (#43)
  • average_precision counts distinct labels
  • crop_corner correctness 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)

11 Jun 05:29

Choose a tag to compare

Fixes

  • GPU masked SSIM: move the erosion footprint onto the mask's device before morphology.erosion. morphology.square/cube receive only an int, so the device-agnostic proxy returned a host footprint; cuCIM's erosion rejected 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

05 Jun 20:39

Choose a tag to compare

v0.7.0a12 Pre-release
Pre-release

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). Matches skimage.feature.graycoprops to ≤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_table extra_properties passthrough: forward user-defined func(regionmask, intensity) callables to skimage/cucim.
  • Fix: regionprops_table now preserves requested property/column order deterministically (was hash-seed-dependent across process workers).

Full diff: #49

v0.7.0a11

04 Jun 00:50

Choose a tag to compare

v0.7.0a11 Pre-release
Pre-release

Pre-release.

Features

  • average_precision(..., return_iou=True) — expose the object-overlap IoU matrix that average_precision already computes internally (via compute_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_matches gains @overload signatures so the (matches) vs (matches, iou) return is statically typed. Default return_iou=False preserves the existing 4-tuple contract.

v0.7.0a10

02 Jun 22:57

Choose a tag to compare

v0.7.0a10 Pre-release
Pre-release

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.ipynb now auto-downloads both files via pooch with sha256 verification on first run — no manual download step. Adds scripts/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

01 Jun 23:38

Choose a tag to compare

v0.7.0a9 Pre-release
Pre-release

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 removed np.in1d to np.isin for NumPy ≥ 2.2 compatibility (#43).
  • cleanup_segmentation: handle empty FOVs without asserting, and migrate off the deprecated skimage min_size= parameter with backend-aware dispatch for cucim (#44).
  • FSC/FRC resolution: return NaN instead 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 v4 CellposeModel (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() for plt.imshow on CuPy arrays.
  • 3D resolution notebook: refresh outputs with post-mean-center FSC values.

v0.7.0a7 — expose MicroSSIM alpha_min/alpha_max kwargs

26 May 20:55
908a22f

Choose a tag to compare

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 skip fit() 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_factor invariant: 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_DEFAULT re-exports
  • MicroSSIM(*, 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_factor tests covering bracket boundaries, degenerate caps, cap-probe behavior, and 2D/3D propagation
  • 3 new MicroSSIM tests + 3 new MicroMS3IM tests covering inheritance of caps, pinned-α scoring without fit(), and eager validation

PR: #41

v0.7.0a6 — torch CUDA → cupy zero-copy fix

23 May 00:45

Choose a tag to compare

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 availablecupy.asarray zero-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).