Source code for spatialtis.spatial.enrichment

import warnings
from typing import Optional

import numpy as np
import pandas as pd
from anndata import AnnData
from natsort import natsorted
from spatialtis_core import comb_bootstrap

from spatialtis.abc import AnalysisBase
from spatialtis.utils import NeighborsNotFoundError
from spatialtis.typing import Array
from spatialtis.utils import doc
from spatialtis.utils.io import read_neighbors


[docs]@doc class spatial_enrichment(AnalysisBase): """`Profiling markers spatial enrichment <about/implementation.html#profiling-of-markers-co-expression>`_ using permutation test Similar to neighborhood analysis which tells you the relationship between different type of cells. This analysis tells you the spatial relationship between markers. Args: data: {adata} threshold: The expression level to determine whether a marker is positive layer_key: {layer_key} selected_markers: {selected_markers} resample: Number of times to perform resample pval: {pval} order: If False, (Cell_A, Cell_B) and (Cell_B, Cell_A) are the same interaction (Default: False) **kwargs: {analysis_kwargs} .. seealso:: :class:`spatialtis.cell_interaction` """ def __init__( self, data: AnnData, threshold: Optional[float] = None, layer_key: Optional[str] = None, selected_markers: Optional[Array] = None, resample: int = 500, pval: float = 0.01, order: bool = False, **kwargs, ): super().__init__(data, **kwargs) self.params = {"order": order} if not self.neighbors_exists: raise NeighborsNotFoundError("Run `find_neighbors` first before continue.") if (threshold is not None) & (layer_key is None): layer_key = f"gt_{threshold}" data.layers[layer_key] = (data.X.copy() >= threshold).astype(bool) elif (threshold is not None) & (layer_key is not None): warnings.warn( "You specific both threshold and layers_key, " "using user defined layers_key" ) else: layer_key = f"mean_cut" data.layers[layer_key] = (data.X.copy() >= data.X.mean(axis=0)).astype( bool ) if selected_markers is None: markers = self.markers else: markers = natsorted(pd.unique(selected_markers)) results_data = [] for roi_name, roi_data, mks, exp in self.roi_exp_iter( selected_markers=markers, layer_key=layer_key, dtype=np.bool, desc="Spatial enrichment", ): neighbors = read_neighbors(roi_data, self.neighbors_key) labels = roi_data[self.cell_id_key] result = comb_bootstrap( exp, mks, neighbors, labels, pval=pval, order=order, times=resample, ignore_self=False, ) for pairs in result: results_data.append([*roi_name, *pairs]) df = pd.DataFrame( data=results_data, columns=self.exp_obs + ["marker1", "marker2", "value"] ) df = df.pivot_table( values="value", index=self.exp_obs, columns=["marker1", "marker2"] ) self.result = df