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
31 changes: 0 additions & 31 deletions .github/workflows/python-publish.yml

This file was deleted.

1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ API and Bug Fixes:
* ``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 needs to deduplicates in a quadratic loop.
* Removed ``UndefinedException`` from ``resistance_matrix``.

1.5.0 (2026-11-01)
------------------
Expand Down
3 changes: 2 additions & 1 deletion docs/release_notes/1.5.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ and aligned to other the LR data.
``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 needs to deduplicates in a quadratic loop.
* ``get_edges`` no longer needs to deduplicates in a quadratic loop.
* Removed ``UndefinedException`` from ``resistance_matrix``.
38 changes: 21 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,39 @@ dependencies = [
"anndata>=0.12.2",
"bokeh>=3.7.0,<4.0",
"click>=8.2.0,<9.0",
"dask>=2025.12.0",
"geopandas>=1.0.0,<2.0",
"h5py>=3.11",
"igraph>=1.0.0",
"imageio>=2.37.0,<3.0",
"leidenalg>=0.11.0",
"matplotlib>=3.11,<4.0",
"natsort",
"networkx>=3.0",
"numba>=0.64.0",
"numpy>=2.4.0",
"openpyxl>=3.1",
"pandas>=2.3.0",
"pillow>=13.0.0,<14.0",
"pooch[progress]>=1.8.1",
"requests>=2.32.4",
"scanpy>=1.12.0",
"scikit-image>=0.25.0",
"pandas>=2.3.0",
"imageio>=2.37.0,<3.0",
"scipy>=1.17.1,<2.0",
"scikit-learn>=1.8.0,<2.0",
"scikit-misc>=0.5.1",
"zarr>=3.1.6,<4.0",
"dask>=2025.12.0",
"scipy>=1.17.1,<2.0",
"shapely>=2.0.6,<3.0",
"spatialdata>=0.7.3",
"spatialdata-io>=0.6.0",
"spatialdata-plot>=0.3.0",
"statsmodels>=0.14.5",
"torch>=2.5.0",
"torchvision>=0.20.0",
"geopandas>=1.0.0,<2.0",
"shapely>=2.0.6,<3.0",
"pooch[progress]>=1.8.1",
"requests>=2.32.4",
"tifffile>=2026.5.2",
"tqdm",
"umap-learn>=0.5.12",
"openpyxl>=3.1",
"tifffile>=2026.5.2",
"xarray>=2024.10.0",
"zarr>=3.1.6,<4.0",
]

keywords = ["stlearn"]
Expand All @@ -65,7 +71,9 @@ dev = [
"black>=26.10",
"ruff>=0.17.3",
"mypy>=2.0",
"pytest>=7.0",
"pytest>=8.0",
"pytest-cov>=5",
"psutil>=5.9",
"tox>=4.0",
"ghp-import>=2.1.0",
"sphinx>=4.0",
Expand Down Expand Up @@ -123,12 +131,8 @@ select = [
"RUF", # ruff-specific rules
]
ignore = [
"E722", # bare except — you've already accepted these
"F811", # redefinition — accepted
"N803", "N806", # naming: lowercase args/vars — too invasive to fix
"N818", # exception naming
"PD011", # .values vs .to_numpy() — too noisy, mostly false positives
"B008", # function calls in default args — used by typer/click
"PD011", # .values vs .to_numpy()
"SIM108", # ternary suggestions can hurt readability
]

Expand Down
21 changes: 6 additions & 15 deletions stlearn/spatial/trajectory/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,18 +296,6 @@ def laplacian_matrix(A, normalized=False):
return L


# """
# **********
# Exceptions
# **********
# Custom exceptions for NetComp.
# """


class UndefinedException(Exception):
"""Raised when matrix to be returned is undefined"""


# """
# **********
# Resistance
Expand All @@ -329,6 +317,11 @@ def resistance_matrix(A, check_connected=True):
-------
R : NumPy matrix
Matrix of pairwise resistances between nodes.
Raises
------
ValueError
If check_connected is True and the graph is not connected, since the
resistance matrix is undefined in that case.
Notes
-----
Uses formula for resistance matrix R in terms of Moore-Penrose of
Expand Down Expand Up @@ -358,9 +351,7 @@ def resistance_matrix(A, check_connected=True):
else:
G = nx.from_numpy_array(A)
if not nx.is_connected(G):
raise UndefinedException(
"Graph is not connected. Resistance matrix is undefined."
)
raise ValueError("Graph is not connected. Resistance matrix is undefined.")
L = laplacian_matrix(A)
with contextlib.suppress(AttributeError):
L = L.todense()
Expand Down
4 changes: 2 additions & 2 deletions stlearn/tl/cci/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ def run_cci(
cols_present = np.all(
[cell_type in adata.uns[uns_key] for cell_type in all_set],
)
rows_present = np.all(adata.uns[uns_key].index.values == adata.obs_names.values)
rows_present = adata.uns[uns_key].index.equals(adata.obs_names)
msg = f"Cell type scores misformatted in adata.uns[{uns_key}]:\n"
if not cols_present or not rows_present:
if not cols_present:
Expand Down Expand Up @@ -578,7 +578,7 @@ def run_cci(
count_col = "n_spots_sig" if sig_spots else "n_spots"
col = "lr_sig_scores" if sig_spots else "lr_scores"
best_lr_indices = np.flatnonzero(lr_summary[count_col].to_numpy() > min_spots)
best_lrs = lr_summary.index.values[best_lr_indices]
best_lrs = lr_summary.index.to_numpy()[best_lr_indices]
lr_genes = genes_of(best_lrs)
if len(lr_genes) == 0:
raise ValueError(
Expand Down
4 changes: 2 additions & 2 deletions stlearn/tl/cci/gridding.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def grid(
grid_expr = pd.DataFrame(
grid_expr,
index=[f"grid_{i}" for i in range(n_squares)],
columns=adata.var_names.values.astype(str),
columns=adata.var_names.to_numpy().astype(str),
)
grid_data = AnnData(grid_expr)
grid_data.obs["imagecol"] = grid_coords[:, 0]
Expand All @@ -184,7 +184,7 @@ def grid(
if use_label is not None and cell_info is not None and cell_set is not None:
grid_data.uns[use_label] = pd.DataFrame(
cell_info,
index=grid_data.obs_names.values.astype(str),
index=grid_data.obs_names.to_numpy().astype(str),
columns=cell_set,
)
max_indices = np.apply_along_axis(np.argmax, 1, cell_info)
Expand Down
2 changes: 1 addition & 1 deletion stlearn/tl/cci/het.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def get_data_for_counting(adata, use_label, mix_mode, all_set):
col_order = [cols.index(cell_type) for cell_type in all_set]
cell_data = cell_props.iloc[:, col_order].to_numpy(dtype=np.float64)
else:
cell_labels = adata.obs.loc[:, obs_key].values
cell_labels = adata.obs[obs_key].to_numpy().astype(str)
cell_data = np.zeros((len(cell_labels), len(all_set)), dtype=np.float64)
for i, cell_type in enumerate(all_set):
cell_data[:, i] = (
Expand Down
2 changes: 1 addition & 1 deletion stlearn/tl/cci/ligand_receptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def __init__(self, frame: pd.DataFrame, *, species: str, source: str = "DataFram
examples = frame.loc[with_underscore, ["ligand", "receptor"]].head(3)
raise ValueError(
f"Gene symbols in {source} contain '_', which separates ligand from "
f"receptor in 'L_R' pair names; e.g. {examples.values.tolist()}",
f"receptor in 'L_R' pair names; e.g. {examples.to_numpy().tolist()}",
)
frame = _merge_repeats(frame)
self._set(frame, species.lower(), _labels(frame))
Expand Down
2 changes: 1 addition & 1 deletion stlearn/tl/cci/perm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def get_lr_features(lr_expr: pd.DataFrame | AnnData, lrs: LRPairs, quantiles):
# Column by column below, so CSC; dense stays as it is.
expr = sparse.csc_matrix(expr) if sparse.issparse(expr) else np.asarray(expr)
else:
genes, expr = lr_expr.columns.values, lr_expr.values
genes, expr = lr_expr.columns.to_numpy(), lr_expr.to_numpy()

# Determining indices of LR pairs #
l_indices, r_indices = [], []
Expand Down
4 changes: 2 additions & 2 deletions stlearn/tl/cci/permutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ def perform_spot_testing(
lr_feats = get_lr_features(adata[:, lr_genes], lrs, quantiles)
l_quants = lr_feats.loc[
names, [col for col in lr_feats.columns if "L_" in col]
].values
].to_numpy()
r_quants = lr_feats.loc[
names, [col for col in lr_feats.columns if "R_" in col]
].values
].to_numpy()
candidate_quants = gene_quantiles(
adata, genes, quantiles, expression=scorer.columns
)
Expand Down
Loading