Skip to content

spatialSimilarityLookup

spatialSimilarityLookup

spatialSimilarityLookup(
    data,
    roiColumn,
    xCoordinate="X_centroid",
    yCoordinate="Y_centroid",
    zCoordinate=None,
    similarityThreshold=0.5,
    roiSubset=None,
    method="radius",
    radius=30,
    knn=10,
    imageId="imageid",
    layer="raw",
    log=True,
    subset=None,
    label="spatialSimilarityLookup",
    reuseSimilarityMatrix=None,
    verbose=True,
    outputDir=None,
    streamData=False,
    n_jobs=-1,
    sdataTable=None,
)

Find regions whose neighbourhood resembles a reference ROI.

The neighbourhood-weighted expression (spatial lag) is computed for every cell, the median lag vector of the reference ROI becomes the query, and every cell is scored by its Euclidean similarity to that query. Cells scoring at or above similarityThreshold are labelled as matching.

Draw the reference ROI first — with sp.helpers.addROI_omero or sp.pl.addRoiScatter — and pass the column it wrote as roiColumn. Cells labelled 'Other' are treated as outside every ROI.

Scores land in layers[label], and one boolean obs column per ROI is written as label + "_" + <roi name>. The similarity kernel is Numba-compiled and the per-image work runs through joblib.

Parameters:

Name Type Description Default
data (AnnData | SpatialData | str, required)

The cell table. An AnnData, a path to an .h5ad file, a SpatialData object, or a path to a .zarr SpatialData store.

required
roiColumn (str, required)

Column in obs naming the ROI each cell belongs to. The value 'Other' marks cells outside every ROI.

required
xCoordinate str

Column in obs holding x positions.

'X_centroid'
yCoordinate str

Column in obs holding y positions.

'Y_centroid'
zCoordinate str

Column in obs holding z positions. Leave as None for 2D data; set it and the neighbourhood search becomes three-dimensional.

None
similarityThreshold float

Score at or above which a cell counts as a match. Higher is stricter.

0.5
roiSubset str | list

Use only these ROIs as queries. Defaults to every value of roiColumn except 'Other'.

None
method str

How neighbourhoods are defined. 'radius' takes every cell within radius pixels; 'knn' takes the knn nearest cells regardless of distance.

'radius'
radius float

Neighbourhood radius in the units of the coordinate columns, normally pixels. Used when method='radius'.

30
knn int

Number of nearest neighbours. Used when method='knn'.

10
imageId str

Column in obs holding image identifiers. Neighbourhoods never cross images.

'imageid'
layer str

Which matrix the spatial lag is computed from. 'raw' uses .raw.X, None uses .X.

'raw'
log bool

Apply log1p before computing the lag.

True
subset str

Process only this image.

None
label str

Key for the outputs: layers[label] for the scores, and obs[label + "_<roi>"] for the per-ROI matches.

'spatialSimilarityLookup'
reuseSimilarityMatrix str

Name of a layer holding scores from a previous run. Supplying it skips the spatial-lag computation, which is the expensive part — use it to re-threshold without recomputing.

None
n_jobs int

Workers for the per-image computation, passed to joblib.Parallel. The default -1 uses every core.

-1
verbose bool

Print progress messages.

True
outputDir str

Directory to write the updated object to. With None the object is returned instead.

None
streamData bool

Run out of core against an .h5ad path with CAP-AnnData, reading only the sections this function needs and writing back only what it changes. Requires data to be a path; the file is updated in place and None is returned.

False
sdataTable str

Which SpatialData table to work on. Ignored for AnnData input, and optional when the store has exactly one table.

None

Returns:

Name Type Description
adata AnnData | SpatialData | None

The updated object with layers[label] holding the similarity scores and one obs[label + "_<roi>"] column per ROI. None in streaming mode.

Raises:

Type Description
ValueError

When no cells overlap between the result and roiSubset — usually a mismatched subset, imageId, or roiColumn.

Example
# Draw a reference region, then look for it everywhere.
adata = sp.pl.addRoiScatter(adata, marker="ECAD", roiName="tumour", label="roi")
adata = sp.tl.spatialSimilarityLookup(
    adata, roiColumn="roi", radius=30, similarityThreshold=0.5
)
sp.pl.spatialScatterPlot(adata, colorBy="spatialSimilarityLookup_tumour", s=3)

# Try a stricter threshold without recomputing the spatial lag.
adata = sp.tl.spatialSimilarityLookup(
    adata,
    roiColumn="roi",
    similarityThreshold=0.8,
    reuseSimilarityMatrix="spatialSimilarityLookup",
    label="strictLookup",
)