squidpy.experimental.im.make_stitched_labels

squidpy.experimental.im.make_stitched_labels(sdata, labels_key, qc_table_key=None, labels_key_added=None, table_key_added=None, write_table=True, merge_strategy='sum', join_labels=False, join_close_radius=3, inplace=True)[source]

Materialise a stitched labels element from an assign_stitch_groups result.

Reads the stitch_group_id mapping in the QC table, builds a lazy int->int LUT, and registers a new labels element where each stitched group shares a single ID. The original labels element is not modified.

Optionally also writes a companion AnnData (write_table=True) with one row per unique stitch_group_id – unstitched cells keep their row unchanged, stitched groups (size 2-4) collapse via merge_strategy.

Parameters:
  • sdata (SpatialData) – SpatialData with a labels element and a QC table that has been processed by squidpy.experimental.tl.assign_stitch_groups().

  • labels_key (str) – Key in sdata.labels of the original labels element.

  • qc_table_key (str | None) – Key of the QC table. Defaults to "{labels_key}_qc".

  • labels_key_added (str | None) – Key for the new labels element. Defaults to "{labels_key}_stitched". Existing element at this key is overwritten with a warning.

  • table_key_added (str | None) – Key for the optional collapsed AnnData (one row per unique stitch_group_id). Defaults to "{labels_key_added}_table" (must differ from the labels element key – SpatialData requires unique names across element types).

  • write_table (bool) – If True, also write the collapsed AnnData to sdata.tables[table_key_added].

  • merge_strategy (str | Callable[[Series], object]) –

    How to aggregate genuine numeric user feature columns in .obs and all of .X across the 2-4 pieces of each stitched cell. String options: "sum" (default, for additive features like area / intensity), "min", "max", "mean", "median", "first". Callable: receives a pandas.Series (one column of one group’s members) and returns a scalar; applied column-wise to .obs and .X.

    merge_strategy does not apply to the columns below, which are handled automatically (so a stray "sum" can’t corrupt them):

    • Group-invariant columns (stitch_group_id, is_stitched, n_pieces, stitch_confidence, region) and any non-numeric column -> first member’s value.

    • centroid_y / centroid_x -> mean of the pieces’ centroids.

    • QC cut-artifact scores (cut_score, smoothed_cut_score, max_straight_edge_ratio, cardinal_alignment_score, nhood_outlier_fraction, is_outlier) -> max (worst piece).

  • join_labels (bool) – If True, morphologically close the gap between pieces of each stitched group, so a group that the basic remap leaves as several components sharing an ID becomes a single connected component. Only background pixels inside each group’s closed hull are filled; other cells are never overwritten. This stays lazy on dask input (a per-block dask.array.map_overlap() pass, never materialising the whole image). Closing bridges seams up to 2 * join_close_radius px wide; pieces separated by a wider gap stay disconnected – raise join_close_radius for those. Default False preserves the original gap pixels.

  • join_close_radius (int) – Radius (px) of the disk structuring element used when join_labels=True. Default 3 matches the closing radius used during scoring; raise it if pieces remain disconnected after joining.

  • inplace (bool) – If True (default), write the new labels element (and table when write_table=True) into sdata. If False, return the materialised objects in a dict {"labels": ..., "table": ...} without mutating sdata; "table" is None when write_table=False.

Return type:

dict[str, object] | None