Skip to content

0.12.0b4

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 25 Jun 09:57

Release Notes — InSituPy 0.12.0b4

Date: 2026-06-25
PyPI: pip install insitupy-spatial==0.12.0b4
Previous release: 0.12.0b3


Summary

This release is centred on multi-sample analysis workflows. One of the main additions is a
flexible filter layer system (InSituExperiment filters): users can define named sample
subsets — including composite filters that combine multiple base filters with AND/OR logic —
and use them to scope any downstream analysis without modifying the underlying experiment.
Alongside filters, a new cross-sample table workflow (build_table() / .table[...] /
import_from_table()) enables concatenation of cell tables across all samples into a single
AnnData, with results writable back to individual samples and full support for multi-panel
experiments with differing gene sets. Experiment management gains three new methods —
replace(), remove(), and reload() — and each dataset now carries a stable UID that
persists across saves, reloads, and reorders, making filter and merge-back operations robust
to experiment restructuring.

On the analysis side, QC is redesigned around the new qc_summary() method, and the
embedding plots (umap, pca, tsne) gain highlight/dim parameters for
focus-on-subset visualisation, a layer parameter to plot from any AnnData layer, and several
rendering options. The save pipeline received its most thorough hardening to date: atomic
swaps, collect-then-raise error handling, and guards against path-less dataset corruption make
save/saveas reliable even after hard crashes.


New Features

Cross-sample table workflow

  • Added InSituExperiment.build_table() to concatenate cell tables across all samples into a single AnnData, with support for union or inner gene sets across panels.
  • Results are accessible via .table[cells_layer] (bracket accessor) and can be written back to samples with import_from_table().
  • InSituExperimentView.table works on filtered subsets of the experiment.
  • concat_on_disk option builds the table by writing per-sample H5AD files and concatenating them, avoiding peak RAM for large experiments.
  • A build_params.json sidecar tracks the parameters used to build each stored table.

QC redesign

  • New InSituExperiment.qc_summary() method returns a tidy DataFrame of per-sample QC metrics.
  • calculate_mad_thresholds moved to the new insitupy.experimental submodule; the insitupy.pp alias is deprecated with a warning.

Embedding plot enhancements (isp.pl.embedding / umap / pca / tsne)

  • highlight parameter: colour a subset of cells, grey out the rest.
  • dim parameter: inverse of highlight — grey out the specified cells.
  • "Other" legend entry automatically added for dimmed/highlighted background points.
  • layer parameter: plot expression values from any AnnData layer (not just .X).
  • render_mode="matplotlib" for matplotlib-native rendering as an alternative to datashader.
  • point_edge_color, point_edge_width, and rasterized parameters added.
  • nan_color parameter to control colour of NaN values in categorical columns.
  • Scanpy colour palette fallback for categories already coloured in .uns.

Experiment management

  • InSituData.uid — each dataset now has a stable unique identifier that persists across saves and reloads.
  • InSituExperiment.replace(uid, new_data) — replace a dataset in an experiment by UID.
  • InSituExperiment.remove(uid) — remove a dataset from an experiment.
  • InSituExperiment.reload() — reload all datasets from disk without re-reading the experiment.
  • InSituData.read() now auto-loads all available modalities by default.

Filter layer improvements

  • Composite filter layers that combine multiple base filters with AND/OR logic.
  • Improved repr distinguishes base filters from composite filters.

Metadata utilities

  • InSituExperiment.update_metadata() and rename_metadata_column() for in-place metadata edits.
  • unload() to release modality data from memory.
  • concat(mode='move') now supported on subsetted experiments.
  • from_config() accepts a DataFrame directly as metadata input.
  • Experiment metadata stored as metadata.parquet instead of metadata.csv (more robust, preserves dtypes).

napari interactive viewer

  • New GeometriesWidget with colour palettes and geometry registries for managing annotations in the viewer.
  • GeometriesWidget restructured: separate "Show" and "Add" panels, point size preservation.
  • Auto-naming of new geometry layers.
  • Single-layer regions: all region/annotation classes for a given key are merged into one napari layer, with a combined widget.

Shapes and geometry

  • ShapesData gains to_regions() / to_annotations() conversion methods.
  • scale_factor sentinel default with a descriptive ValueError when not set.

Image registration

  • Registration module refactored into a standalone register_images_standalone function; the ImageRegistration class is deprecated.
  • raise_on_insufficient_matches parameter added to control error vs. warning behaviour on low feature matches.

Save/load additions

  • InSituData partial save methods: save_geometries(), save_cells(), save_images().
  • InSituData gains conversion methods between modality types.

Repr improvements

  • InSituData.__repr__ now shows the dataset UID.
  • InSituExperiment.__repr__ now shows loaded modality counts per dataset.

Bug Fixes

Save pipeline hardening (major)

  • saveas() now uses a true atomic swap: moves old data aside to a backup before renaming the staging directory in; restores the backup if the swap fails. Previously, a crash during the swap could destroy both old and new copies.
  • InSituExperiment.save() now uses a collect-then-raise pattern: all datasets are attempted before raising, and a RuntimeError lists every failing UID. Experiment-level files are skipped on any failure.
  • InSituExperiment.save() no longer corrupts a path-less dataset's _path on failure; the pre-pass validates before assigning.
  • Path-less datasets (added via .add() without a prior save) are auto-assigned a free data-NNN slot and written via saveas() on the first save() call.
  • InSituExperimentView.save_filters() now merges filter masks back to parent samples by UID rather than positional index, preventing wrong-sample writes after a parent reorder.
  • saveas() recovers an orphaned .__ispy_bak__ backup left by a previous crash instead of silently deleting it.
  • InSituExperimentView save methods no longer mutate the parent experiment's filter state.

Memory and I/O

  • Prevented OOM when saving large lazy transcript datasets.
  • Fixed a pandas 2.x Copy-on-Write MemoryError in transcript cropping (_crop_transcripts now uses DataFrame.take()).
  • Fixed regions extending past image boundaries causing crop failures.
  • Fixed empty rows appearing in metadata.csv on Windows.

Interactive viewer

  • Fixed IndexError race condition in TranscriptViewerWidget.
  • Fixed .uns colour order being lost when switching to cells/labels display mode.
  • Fixed point annotation colour channel mismatch in geometry layers.
  • Fixed stale-key and uid-guard issues in interactive widgets; added "(all)" key option.
  • Fixed sync-order bug in geometry colour legend updates.

Other

  • Fixed H&E image registration crash and memory leak in registration QC.
  • Fixed circular import in containers/io.py.
  • Fixed MultiCellData.__getitem__ raising IndexError instead of KeyError for missing layer names.
  • Fixed best image pyramid level selection in quantify_signal when pixel sizes differ.
  • Corrected inverted unload() string normalisation and leiden flavour handling.

Dependency Changes

  • scipy pinned to >=1.14,<1.17 (1.17 introduced a breaking change).
  • zarr minimum bumped to 3.2.1.
  • Python minimum updated to >=3.11.0 (was >=3.10).
  • anndata added as an explicit dependency (>=0.12.0).

Documentation

  • New save/load tutorial (docs/tutorials/00_io/) covering full and partial saves, reload patterns, and when to use each method.
  • New cross-sample table tutorial with architecture diagram.
  • New filter workflow tutorial documenting base and composite filter layers.
  • MCP server tutorial (MCP_TUTORIAL.md) updated: Claude Code global config option added, ChatGPT section labelled as untested with feedback link, tool count corrected to 22, tools/mcp_server/README.md rewritten with uvx as the recommended path.

Internal / Refactoring

  • Geometry layers in napari migrated to the napari features API.
  • _concatenate_samples and _transfer_to_samples extracted as reusable helpers.
  • _clear_modality helper introduced, consolidating deleter and unload logic.
  • Transcript cropping intermediate code cleaned up after performance work.
  • Ruff linting applied and violations fixed across the codebase.
  • GitHub Actions release workflow now auto-detects pre-release tags (a, b, rc) and marks the GitHub Release accordingly.

Full Changelog: 0.12.0b3...0.12.0b4