liana.mt.lric.__call__

Contents

liana.mt.lric.__call__#

lric.__call__(adata, resource=None, resource_name=None, interactions=None, groupby=None, spatial_key='spatial', max_radius=200, radius_step=20, annulus_steps=1, extend_first_annulus=True, cell_types=None, min_cells=None, groupby_pairs=None, nz_prop=0.05, expr_prop=0.05, complex_sep='_', lr_sep='^', transform_fn=None, use_raw=False, layer=None, pair_chunk=None, key_added='lric', inplace=True, verbose=False)#

Ligand-Receptor Interaction Correlation (LRIC).

Computes an expression-weighted cross-PCF g(r): each cell’s contribution at distance r is weighted by its ligand and receptor expression, so g(r) > 1 flags ligand- and receptor-expressing cells that are spatially co-enriched beyond cell-type co-localisation alone — candidate ligand-receptor interactions that are both proximal and co-expressed.

When groupby is None (default), all cells are treated as potential senders and receivers (self-pairs excluded), providing a global screen for LR pairs with strong spatial co-enrichment signal.

When groupby is a column name in adata.obs, the LRIC is computed for every directed sender→receiver cell-type pair, and each interaction is additionally decomposed into an architecture-only (g_pcf) and an expression-only (g_expr) component.

Parameters:
adata AnnData

Annotated data object.

resource DataFrame | None (default: None)

A pandas dataframe with [ligand, receptor] columns. If provided will overrule the resource requested via resource_name

resource_name str | None (default: None)

Name of the resource to be used for ligand-receptor inference. See li.rs.show_resources() for available resources.

interactions list[tuple[str, str]] | None (default: None)

List of tuples with ligand-receptor pairs [(ligand, receptor), ...] to be used for the analysis. If passed, it will overrule the resource requested via resource and resource_name.

groupby str | None (default: None)

Column in adata.obs used to define cell types. None runs the cell-type-agnostic mode across all cells.

spatial_key str (default: 'spatial')

Key in adata.obsm that contains the spatial coordinates.

max_radius float (default: 200)

Inner edge of the last (widest) annulus bin; the outer edge extends to max_radius + annulus_steps * radius_step.

radius_step float (default: 20)

Step between successive annulus inner edges.

annulus_steps int (default: 1)

Ring width of each annulus, in units of radius_step (width = annulus_steps * radius_step). 1 (default) gives disjoint annuli that tile the range without gaps or overlap; > 1 gives overlapping annuli – a annulus_steps-wide moving window over the same tiles, i.e. a smoothed g(r).

extend_first_annulus bool (default: True)

If True (default), extend the first annulus inward to start at radius 0 (spanning [0, (1 + annulus_steps) * radius_step)) rather than at radius_step. Cell centroids cannot lie closer than ~one cell diameter, so the innermost band is otherwise a thin, near-empty, high-variance bin; extending it folds genuine cell-cell contact pairs into the first bin instead of discarding them. False keeps the first annulus at [radius_step, (1 + annulus_steps) * radius_step). In LRIC this specifically preserves juxtacrine (direct-contact) ligand-receptor signal in the first bin.

cell_types Sequence[str] | None (default: None)

Subset of cell types to consider. Defaults to all types in adata.obs[groupby]. Only relevant when groupby is set. Restricts which pairs are emitted, not which cells are used: the null conditions on the point pattern of the whole slide, so a selection leaves every curve it does emit unchanged.

min_cells int | None (default: None)

Minimum cells (per cell identity if grouped by groupby) to be considered for downstream analysis. Default None derives the threshold from slide composition instead of using a fixed count: cell types making up no more than 1% of all cells are dropped. Unlike cell_types, this one does remove cells, so it shifts the null slightly – pass min_cells=0 to keep the full slide.

groupby_pairs DataFrame | None (default: None)

A DataFrame with columns source and target to be used to subset the possible combinations of interacting cell types. If None, all possible combinations are used. Only relevant when groupby is set. Restricts the directed sender->receiver combinations that are emitted to those listed. Like cell_types, it filters the output only.

nz_prop float (default: 0.05)

Minimum proportion of all observations (cells/spots) with a non-zero value for a variable to be kept. Unlike expr_prop, it is computed across all observations, irrespective of any grouping. Set to 0 to return unfiltered results. Only relevant when groupby is None (agnostic mode). Interactions below the threshold are set to NaN.

expr_prop float (default: 0.05)

Minimum expression proportion for the ligands and receptors (+ their subunits) within each cell-type group. Set to 0 to return unfiltered results. Only relevant when groupby is set; computed within each cell type. Interactions below the threshold are set to NaN.

complex_sep str | None (default: '_')

Separator used to identify multi-subunit complexes in the resource (e.g. "_" splits "ITGAV_ITGB3" into its subunits and adds the minimum-subunit expression as a new column in adata.var). Set to None to skip complex handling.

lr_sep str (default: '^')

Separator to use when joining ligand and receptor names into interactions.

transform_fn Callable[[ndarray], ndarray] | None (default: None)

Expression transform applied to ligand and receptor matrices, defaulting to mean-normalisation to 1 (_linear_transform).

use_raw bool (default: False)

Whether to use the .raw attribute of adata. Defaults to False (uses .X). Must resolve to non-negative expression; scaled or centred data is rejected, as the weights are expression relative to a mean.

layer str | None (default: None)

Layer in anndata.AnnData.layers to use. If None, use anndata.AnnData.X. Same requirement as use_raw: non-negative expression only.

pair_chunk int | None (default: None)

Deprecated since 2.1 and ignored. The weighted numerator is now accumulated without materialising per-chunk temporaries, so there is nothing to tune.

key_added str (default: 'lric')

Key under which the results will be stored in adata.uns if inplace is True.

inplace bool (default: True)

Whether to store results in place, or else to return them.

verbose bool | None (default: False)

Verbosity flag. False, the default, hides progress and info messages but still warns about data-altering conditions; True shows both; None silences everything, warnings included.

Raises:

ValueError – If the resolved expression matrix carries negative values.

Return type:

DataFrame | None

Returns:

A long-format pandas.DataFrame (liana’s liana_res convention) with one row per interaction x radius bin, returned if inplace=False, else None (stored in adata.uns[key_added]).

Agnostic mode columns: ligand_complex, receptor_complex, interaction ("ligand<lr_sep>receptor"), radius (the annulus’ inner edge) and g.

Pairwise mode additionally carries source / target (the sender and receiver cell types) and the g_expr / g_pcf decomposition, where g_pcf is shared by all LR pairs of a given source ->``target``.

Interactions masked by nz_prop / expr_prop are kept as NaN rows.

Examples

Cell-type-agnostic LRIC across all cells:

>>> import liana as li
>>> adata = li.ds.generate_toy_spatial()
>>> li.mt.lric(adata, resource_name="consensus", key_added="lric")
>>> list(adata.uns["lric"].columns)
['ligand_complex', 'receptor_complex', 'interaction', 'radius', 'g']

The cell-type pairwise variant additionally decomposes each interaction into architecture (g_pcf) and expression (g_expr) components:

>>> adata.obs["cell_type"] = adata.obs["bulk_labels"]
>>> li.mt.lric(adata, resource_name="consensus", groupby="cell_type", key_added="lric_ct")

Rank the interactions with liana.mt.get_lric_auc() – its output feeds straight into liana.pl.dotplot() – and draw a single g(r) profile with liana.pl.lric_lineplot().