liana.mt.cross_pcf.__call__

liana.mt.cross_pcf.__call__#

cross_pcf.__call__(adata, groupby, spatial_key='spatial', cell_types=None, min_cells=None, max_radius=200, radius_step=20, annulus_steps=1, extend_first_annulus=True, groupby_pairs=None, key_added='cross_pcf', inplace=True, verbose=False)#

Cross pair-correlation function (cross-PCF) between cell types.

Computes the distance-resolved cross-PCF g(r) for every combination of cell types present in adata.obs[groupby], normalised against the empirical any-cell-type pair count within this tissue (a random-labelling null).

Parameters:
adata AnnData

Annotated data object.

groupby str

Key to be used for grouping.

spatial_key str (default: 'spatial')

Key in adata.obsm that contains the spatial coordinates.

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

Subset of cell types to consider. Defaults to all types in adata.obs[groupby].

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.

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).

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. Restricts the cell-type combinations that are emitted to those listed; matched regardless of orientation, as g(r) is symmetric. Cell types referenced by groupby_pairs are also folded into cell_types.

key_added str (default: 'cross_pcf')

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 (default: False)

Verbosity flag.

Return type:

DataFrame | None

Returns:

A long-format pandas.DataFrame (liana’s liana_res convention) with one row per cell-type pair x radius bin and columns source, target, interaction ("source^target"), radius (the annulus’ inner edge) and g. Returned if inplace=False, else None (stored in adata.uns[key_added]).

Notes

g(r) is symmetric in source/target, so each unordered pair is emitted once, with source before target in sorted cell-type order. Self-pairs are excluded.

CrossPCF and LRIC share the same binning: half-open [inner, outer) tiles read off a single edge list, with distance-0 pairs between distinct cells counted in the contact band. Pairwise LRIC’s g_pcf therefore equals cross_pcf exactly.

Examples

>>> import liana as li
>>> adata = li.ds.generate_toy_spatial()
>>> adata.obs["cell_type"] = adata.obs["bulk_labels"]
>>> li.mt.cross_pcf(adata, groupby="cell_type", key_added="cross_pcf")
>>> list(adata.uns["cross_pcf"].columns)
['source', 'target', 'interaction', 'radius', 'g']

Rank the pairs with liana.mt.get_lric_auc() and draw one with liana.pl.lric_lineplot().