Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@
History
=======

1.5.1 (2026-11-07)
------------------
* ``st.tl.cci.run`` now uses a spots-by-spots, sparse graph:
``adata.obsp["spot_neighbours"]``. It replaces the comma-joined strings
``adata.obsm["spot_neighbours"]`` and ``adata.obsm["spot_neigh_bcs"]``.
* With ``use_label``, ``run`` counts cell types over the same graph instead of
searching the neighbours a second time (``het.count`` takes it as ``neighbours=``).
* ``st.tl.cache.write_subset_h5ad`` takes ``obsp_keys``, and
``merge_h5ad_into_adata`` copies ``obsp``, so a cached CCI run keeps its neighbours.

API and Bug Fixes:

* ``stlearn.tl.cci.neighbours.calc_neighbours`` returns that sparse matrix instead
of a numba ``List``. ``neighbourhood_matrix`` and
``neighbourhoods_from_barcodes`` are removed.
* ``LRScorer`` takes a sparse matrix. ``get_scores``, ``adjacency`` and
``flatten_neighbours`` are removed from ``stlearn.tl.cci.scoring``.
* ``st.tl.cci.run_cci`` and ``get_edges`` read the stored graph directly;
``stlearn.tl.cci.neighbours.get_neighbourhoods`` and the edge helpers in
``stlearn.tl.cci.edges`` are removed. ``get_interaction_matrix`` and
``get_interaction_pvals`` take the graph's CSR arrays (``neigh_indptr``,
``neigh_indices``) instead of a numba ``List``.
* ``get_edges`` no longer deduplicates edges with a quadratic loop: the arrow
plots on large neighbourhoods are seconds faster.

1.5.0 (2026-11-01)
------------------
This release contains changes in cell-cell interaction (CCI) mainly
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

TUTORIALS_URL = (
"https://github.com/GenomicsMachineLearning/stLearn-tutorials/releases/download/V1.5.0/tutorials.zip"
"https://github.com/GenomicsMachineLearning/stLearn-tutorials/releases/download/V1.5.1/tutorials.zip"
)


Expand Down
2 changes: 2 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ undissociated tissue sample.
Latest Additions
----------------

.. include:: release_notes/1.5.1.rst

.. include:: release_notes/1.5.0.rst

.. include:: release_notes/1.4.1.rst
Expand Down
24 changes: 24 additions & 0 deletions docs/release_notes/1.5.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
1.5.1 (2026-11-07)
~~~~~~~~~~~~~~~~~~

.. rubric:: Features

* ``st.tl.cci.run`` now uses a spots-by-spots, sparse graph:
``adata.obsp["spot_neighbours"]``. It replaces the comma-joined strings
``adata.obsm["spot_neighbours"]`` and ``adata.obsm["spot_neigh_bcs"]``.
* With ``use_label``, ``run`` counts cell types over the same graph instead of
searching the neighbours a second time (``het.count`` takes it as ``neighbours=``).
* ``st.tl.cache.write_subset_h5ad`` takes ``obsp_keys``, and
``merge_h5ad_into_adata`` copies ``obsp``, so a cached CCI run keeps its neighbours.
* ``stlearn.tl.cci.neighbours.calc_neighbours`` returns that sparse matrix instead
of a numba ``List``. ``neighbourhood_matrix`` and
``neighbourhoods_from_barcodes`` are removed.
* ``LRScorer`` takes a sparse matrix. ``get_scores``, ``adjacency`` and
``flatten_neighbours`` are removed from ``stlearn.tl.cci.scoring``.
* ``st.tl.cci.run_cci`` and ``get_edges`` read the stored graph directly;
``stlearn.tl.cci.neighbours.get_neighbourhoods`` and the edge helpers in
``stlearn.tl.cci.edges`` are removed. ``get_interaction_matrix`` and
``get_interaction_pvals`` take the graph's CSR arrays (``neigh_indptr``,
``neigh_indices``) instead of a numba ``List``.
* ``get_edges`` no longer deduplicates edges with a quadratic loop: the arrow
plots on large neighbourhoods are seconds faster.
2 changes: 2 additions & 0 deletions docs/release_notes/index.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Release Notes
===================================================

.. include:: 1.5.1.rst

.. include:: 1.5.0.rst

.. include:: 1.4.1.rst
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "stlearn"
version = "1.5.0"
version = "1.5.1"
authors = [
{ name = "Genomics and Machine Learning Lab", email = "andrew.newman@uq.edu.au" },
]
Expand Down
2 changes: 1 addition & 1 deletion stlearn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

__author__ = """Genomics and Machine Learning Lab"""
__email__ = "andrew.newman@uq.edu.au"
__version__ = "1.5.0"
__version__ = "1.5.1"

from . import add, datasets, em, io, pl, pp, spatial, tl, types, utils
from ._settings import settings
Expand Down
16 changes: 14 additions & 2 deletions stlearn/tl/cache/anndata.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import pandas as pd


def write_subset_h5ad(adata, filename, obsm_keys=None, uns_keys=None):
"""Write only specific obsm and uns components to H5AD"""
def write_subset_h5ad(adata, filename, obsm_keys=None, uns_keys=None, obsp_keys=None):
"""Write only specific obsm, obsp and uns components to H5AD"""

# Create a minimal AnnData object with the same structure
minimal_adata = ad.AnnData(
Expand Down Expand Up @@ -32,6 +32,14 @@ def write_subset_h5ad(adata, filename, obsm_keys=None, uns_keys=None):
else:
print(f"Warning: uns['{key}'] not found")

if obsp_keys:
for key in obsp_keys:
if key in adata.obsp:
minimal_adata.obsp[key] = adata.obsp[key]
print(f"Added obsp['{key}'] with {adata.obsp[key].nnz} entries")
else:
print(f"Warning: obsp['{key}'] not found")

minimal_adata.write_h5ad(filename, compression="gzip", compression_opts=9)
print(f"Wrote subset to {filename}")

Expand All @@ -48,4 +56,8 @@ def merge_h5ad_into_adata(adata_main, h5ad_file):
adata_main.uns[key] = value
print(f"Added uns['{key}']")

for key, value in adata_subset.obsp.items():
adata_main.obsp[key] = value
print(f"Added obsp['{key}'] with {value.nnz} entries")

return adata_main
Loading
Loading