Reading plates#
Behind every profile there are images and segmentations.
read_plate() reads one plate of them into a SpatialData object: fields of view as Images, the CellProfiler objects as Labels, the wells as Shapes, and the well- and cell-level measurements as Tables that annotate them.
It reads two layouts and tells them apart by the contents of the directory you point it at:
a Cell Painting Gallery source [Weisbart et al., 2024], the
images/andworkspace/trees of an accession;a CellProfiler export, the folder the
ExportForSpatialDatamodule writes out of a pipeline run.
This tutorial uses a synthetic plate, so nothing has to be downloaded first.
import matplotlib.pyplot as plt
import numpy as np
import mantispy as mt
sdata = mt.ds.blobs(n_wells=4, n_sites=4)
sdata
SpatialData object
├── Images
│ ├── 'BLOBS01_A01_s1_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A01_s2_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A01_s3_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A01_s4_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A02_s1_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A02_s2_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A02_s3_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A02_s4_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A03_s1_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A03_s2_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A03_s3_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A03_s4_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A04_s1_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A04_s2_image': DataArray[cyx] (5, 64, 64)
│ ├── 'BLOBS01_A04_s3_image': DataArray[cyx] (5, 64, 64)
│ └── 'BLOBS01_A04_s4_image': DataArray[cyx] (5, 64, 64)
├── Labels
│ ├── 'BLOBS01_A01_s1_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s1_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s1_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s2_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s2_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s2_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s3_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s3_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s3_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s4_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s4_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A01_s4_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s1_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s1_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s1_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s2_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s2_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s2_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s3_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s3_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s3_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s4_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s4_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A02_s4_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s1_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s1_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s1_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s2_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s2_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s2_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s3_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s3_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s3_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s4_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s4_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A03_s4_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s1_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s1_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s1_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s2_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s2_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s2_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s3_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s3_cytoplasm': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s3_nuclei': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s4_cells': DataArray[yx] (64, 64)
│ ├── 'BLOBS01_A04_s4_cytoplasm': DataArray[yx] (64, 64)
│ └── 'BLOBS01_A04_s4_nuclei': DataArray[yx] (64, 64)
├── Shapes
│ └── 'BLOBS01_wells': GeoDataFrame shape: (96, 2) (2D shapes)
└── Tables
├── 'cells': AnnData (192, 19)
└── 'wells': AnnData (4, 19)
with coordinate systems:
▸ 'BLOBS01', with elements:
BLOBS01_A01_s1_image (Images), BLOBS01_A01_s2_image (Images), BLOBS01_A01_s3_image (Images), BLOBS01_A01_s4_image (Images), BLOBS01_A02_s1_image (Images), BLOBS01_A02_s2_image (Images), BLOBS01_A02_s3_image (Images), BLOBS01_A02_s4_image (Images), BLOBS01_A03_s1_image (Images), BLOBS01_A03_s2_image (Images), BLOBS01_A03_s3_image (Images), BLOBS01_A03_s4_image (Images), BLOBS01_A04_s1_image (Images), BLOBS01_A04_s2_image (Images), BLOBS01_A04_s3_image (Images), BLOBS01_A04_s4_image (Images), BLOBS01_A01_s1_cells (Labels), BLOBS01_A01_s1_cytoplasm (Labels), BLOBS01_A01_s1_nuclei (Labels), BLOBS01_A01_s2_cells (Labels), BLOBS01_A01_s2_cytoplasm (Labels), BLOBS01_A01_s2_nuclei (Labels), BLOBS01_A01_s3_cells (Labels), BLOBS01_A01_s3_cytoplasm (Labels), BLOBS01_A01_s3_nuclei (Labels), BLOBS01_A01_s4_cells (Labels), BLOBS01_A01_s4_cytoplasm (Labels), BLOBS01_A01_s4_nuclei (Labels), BLOBS01_A02_s1_cells (Labels), BLOBS01_A02_s1_cytoplasm (Labels), BLOBS01_A02_s1_nuclei (Labels), BLOBS01_A02_s2_cells (Labels), BLOBS01_A02_s2_cytoplasm (Labels), BLOBS01_A02_s2_nuclei (Labels), BLOBS01_A02_s3_cells (Labels), BLOBS01_A02_s3_cytoplasm (Labels), BLOBS01_A02_s3_nuclei (Labels), BLOBS01_A02_s4_cells (Labels), BLOBS01_A02_s4_cytoplasm (Labels), BLOBS01_A02_s4_nuclei (Labels), BLOBS01_A03_s1_cells (Labels), BLOBS01_A03_s1_cytoplasm (Labels), BLOBS01_A03_s1_nuclei (Labels), BLOBS01_A03_s2_cells (Labels), BLOBS01_A03_s2_cytoplasm (Labels), BLOBS01_A03_s2_nuclei (Labels), BLOBS01_A03_s3_cells (Labels), BLOBS01_A03_s3_cytoplasm (Labels), BLOBS01_A03_s3_nuclei (Labels), BLOBS01_A03_s4_cells (Labels), BLOBS01_A03_s4_cytoplasm (Labels), BLOBS01_A03_s4_nuclei (Labels), BLOBS01_A04_s1_cells (Labels), BLOBS01_A04_s1_cytoplasm (Labels), BLOBS01_A04_s1_nuclei (Labels), BLOBS01_A04_s2_cells (Labels), BLOBS01_A04_s2_cytoplasm (Labels), BLOBS01_A04_s2_nuclei (Labels), BLOBS01_A04_s3_cells (Labels), BLOBS01_A04_s3_cytoplasm (Labels), BLOBS01_A04_s3_nuclei (Labels), BLOBS01_A04_s4_cells (Labels), BLOBS01_A04_s4_cytoplasm (Labels), BLOBS01_A04_s4_nuclei (Labels), BLOBS01_wells (Shapes)
▸ 'BLOBS01_A01', with elements:
BLOBS01_A01_s1_image (Images), BLOBS01_A01_s2_image (Images), BLOBS01_A01_s3_image (Images), BLOBS01_A01_s4_image (Images), BLOBS01_A01_s1_cells (Labels), BLOBS01_A01_s1_cytoplasm (Labels), BLOBS01_A01_s1_nuclei (Labels), BLOBS01_A01_s2_cells (Labels), BLOBS01_A01_s2_cytoplasm (Labels), BLOBS01_A01_s2_nuclei (Labels), BLOBS01_A01_s3_cells (Labels), BLOBS01_A01_s3_cytoplasm (Labels), BLOBS01_A01_s3_nuclei (Labels), BLOBS01_A01_s4_cells (Labels), BLOBS01_A01_s4_cytoplasm (Labels), BLOBS01_A01_s4_nuclei (Labels)
▸ 'BLOBS01_A01_s1', with elements:
BLOBS01_A01_s1_image (Images), BLOBS01_A01_s1_cells (Labels), BLOBS01_A01_s1_cytoplasm (Labels), BLOBS01_A01_s1_nuclei (Labels)
▸ 'BLOBS01_A01_s2', with elements:
BLOBS01_A01_s2_image (Images), BLOBS01_A01_s2_cells (Labels), BLOBS01_A01_s2_cytoplasm (Labels), BLOBS01_A01_s2_nuclei (Labels)
▸ 'BLOBS01_A01_s3', with elements:
BLOBS01_A01_s3_image (Images), BLOBS01_A01_s3_cells (Labels), BLOBS01_A01_s3_cytoplasm (Labels), BLOBS01_A01_s3_nuclei (Labels)
▸ 'BLOBS01_A01_s4', with elements:
BLOBS01_A01_s4_image (Images), BLOBS01_A01_s4_cells (Labels), BLOBS01_A01_s4_cytoplasm (Labels), BLOBS01_A01_s4_nuclei (Labels)
▸ 'BLOBS01_A02', with elements:
BLOBS01_A02_s1_image (Images), BLOBS01_A02_s2_image (Images), BLOBS01_A02_s3_image (Images), BLOBS01_A02_s4_image (Images), BLOBS01_A02_s1_cells (Labels), BLOBS01_A02_s1_cytoplasm (Labels), BLOBS01_A02_s1_nuclei (Labels), BLOBS01_A02_s2_cells (Labels), BLOBS01_A02_s2_cytoplasm (Labels), BLOBS01_A02_s2_nuclei (Labels), BLOBS01_A02_s3_cells (Labels), BLOBS01_A02_s3_cytoplasm (Labels), BLOBS01_A02_s3_nuclei (Labels), BLOBS01_A02_s4_cells (Labels), BLOBS01_A02_s4_cytoplasm (Labels), BLOBS01_A02_s4_nuclei (Labels)
▸ 'BLOBS01_A02_s1', with elements:
BLOBS01_A02_s1_image (Images), BLOBS01_A02_s1_cells (Labels), BLOBS01_A02_s1_cytoplasm (Labels), BLOBS01_A02_s1_nuclei (Labels)
▸ 'BLOBS01_A02_s2', with elements:
BLOBS01_A02_s2_image (Images), BLOBS01_A02_s2_cells (Labels), BLOBS01_A02_s2_cytoplasm (Labels), BLOBS01_A02_s2_nuclei (Labels)
▸ 'BLOBS01_A02_s3', with elements:
BLOBS01_A02_s3_image (Images), BLOBS01_A02_s3_cells (Labels), BLOBS01_A02_s3_cytoplasm (Labels), BLOBS01_A02_s3_nuclei (Labels)
▸ 'BLOBS01_A02_s4', with elements:
BLOBS01_A02_s4_image (Images), BLOBS01_A02_s4_cells (Labels), BLOBS01_A02_s4_cytoplasm (Labels), BLOBS01_A02_s4_nuclei (Labels)
▸ 'BLOBS01_A03', with elements:
BLOBS01_A03_s1_image (Images), BLOBS01_A03_s2_image (Images), BLOBS01_A03_s3_image (Images), BLOBS01_A03_s4_image (Images), BLOBS01_A03_s1_cells (Labels), BLOBS01_A03_s1_cytoplasm (Labels), BLOBS01_A03_s1_nuclei (Labels), BLOBS01_A03_s2_cells (Labels), BLOBS01_A03_s2_cytoplasm (Labels), BLOBS01_A03_s2_nuclei (Labels), BLOBS01_A03_s3_cells (Labels), BLOBS01_A03_s3_cytoplasm (Labels), BLOBS01_A03_s3_nuclei (Labels), BLOBS01_A03_s4_cells (Labels), BLOBS01_A03_s4_cytoplasm (Labels), BLOBS01_A03_s4_nuclei (Labels)
▸ 'BLOBS01_A03_s1', with elements:
BLOBS01_A03_s1_image (Images), BLOBS01_A03_s1_cells (Labels), BLOBS01_A03_s1_cytoplasm (Labels), BLOBS01_A03_s1_nuclei (Labels)
▸ 'BLOBS01_A03_s2', with elements:
BLOBS01_A03_s2_image (Images), BLOBS01_A03_s2_cells (Labels), BLOBS01_A03_s2_cytoplasm (Labels), BLOBS01_A03_s2_nuclei (Labels)
▸ 'BLOBS01_A03_s3', with elements:
BLOBS01_A03_s3_image (Images), BLOBS01_A03_s3_cells (Labels), BLOBS01_A03_s3_cytoplasm (Labels), BLOBS01_A03_s3_nuclei (Labels)
▸ 'BLOBS01_A03_s4', with elements:
BLOBS01_A03_s4_image (Images), BLOBS01_A03_s4_cells (Labels), BLOBS01_A03_s4_cytoplasm (Labels), BLOBS01_A03_s4_nuclei (Labels)
▸ 'BLOBS01_A04', with elements:
BLOBS01_A04_s1_image (Images), BLOBS01_A04_s2_image (Images), BLOBS01_A04_s3_image (Images), BLOBS01_A04_s4_image (Images), BLOBS01_A04_s1_cells (Labels), BLOBS01_A04_s1_cytoplasm (Labels), BLOBS01_A04_s1_nuclei (Labels), BLOBS01_A04_s2_cells (Labels), BLOBS01_A04_s2_cytoplasm (Labels), BLOBS01_A04_s2_nuclei (Labels), BLOBS01_A04_s3_cells (Labels), BLOBS01_A04_s3_cytoplasm (Labels), BLOBS01_A04_s3_nuclei (Labels), BLOBS01_A04_s4_cells (Labels), BLOBS01_A04_s4_cytoplasm (Labels), BLOBS01_A04_s4_nuclei (Labels)
▸ 'BLOBS01_A04_s1', with elements:
BLOBS01_A04_s1_image (Images), BLOBS01_A04_s1_cells (Labels), BLOBS01_A04_s1_cytoplasm (Labels), BLOBS01_A04_s1_nuclei (Labels)
▸ 'BLOBS01_A04_s2', with elements:
BLOBS01_A04_s2_image (Images), BLOBS01_A04_s2_cells (Labels), BLOBS01_A04_s2_cytoplasm (Labels), BLOBS01_A04_s2_nuclei (Labels)
▸ 'BLOBS01_A04_s3', with elements:
BLOBS01_A04_s3_image (Images), BLOBS01_A04_s3_cells (Labels), BLOBS01_A04_s3_cytoplasm (Labels), BLOBS01_A04_s3_nuclei (Labels)
▸ 'BLOBS01_A04_s4', with elements:
BLOBS01_A04_s4_image (Images), BLOBS01_A04_s4_cells (Labels), BLOBS01_A04_s4_cytoplasm (Labels), BLOBS01_A04_s4_nuclei (Labels)
Coordinate systems#
Every element sits in three coordinate systems: its own field, its well, and the plate. This lays the fields of a well out as a mosaic and the wells as a plate map, with nothing resampled.
sorted(sdata.coordinate_systems)[:6]
['BLOBS01',
'BLOBS01_A01',
'BLOBS01_A01_s1',
'BLOBS01_A01_s2',
'BLOBS01_A01_s3',
'BLOBS01_A01_s4']
Rendering a well in its own frame puts its four fields where the microscope stage found them:
from spatialdata.transformations import get_transformation
fig, ax = plt.subplots(figsize=(4, 4))
for name, image in sdata.images.items():
if "_A01_" not in name:
continue
offset = get_transformation(image, "BLOBS01_A01").to_affine_matrix(input_axes=("y", "x"), output_axes=("y", "x"))
y, x = offset[0, 2], offset[1, 2]
ax.imshow(np.asarray(image.sel(c="DNA")), extent=(x, x + 64, y + 64, y), cmap="gray")
ax.set(xlim=(0, 128), ylim=(128, 0), title="well A01, four fields")
plt.show()
Images and labels#
The image of a field carries one channel per stain, named. The labels carry CellProfiler object numbers, so the rows of the cell table join straight onto them.
image = sdata["BLOBS01_A01_s1_image"]
list(image.coords["c"].values)
[np.str_('DNA'),
np.str_('RNA'),
np.str_('AGP'),
np.str_('ER'),
np.str_('Mito')]
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
axes[0].imshow(np.asarray(image.sel(c="DNA")), cmap="gray")
axes[0].set_title("DNA")
for ax, name in zip(axes[1:], ("cells", "nuclei", "cytoplasm"), strict=True):
ax.imshow(np.asarray(sdata[f"BLOBS01_A01_s1_{name}"]), cmap="tab20")
ax.set_title(name)
for ax in axes:
ax.set_axis_off()
plt.show()
Cytoplasm is the cell mask minus the nucleus mask, as CellProfiler defines it.
The tables#
cells holds one row per segmented object and wells one row per well.
Both are ordinary AnnData objects.
Their var is annotated with what each feature name encodes, as read_profiles() annotates a profile read from disk.
cells = sdata.tables["cells"]
cells
AnnData object with n_obs × n_vars = 192 × 19
obs: 'Metadata_Plate', 'Metadata_Well', 'Metadata_Site', 'Metadata_ObjectNumber', 'region'
var: 'object', 'feature_group', 'feature', 'channel', 'scale', 'angle', 'gray_levels', 'radial_bin', 'params', 'is_feature'
uns: 'mantispy', 'spatialdata_attrs'
layers: None (.X)
cells.var
| object | feature_group | feature | channel | scale | angle | gray_levels | radial_bin | params | is_feature | |
|---|---|---|---|---|---|---|---|---|---|---|
| Cells_AreaShape_Area | Cells | AreaShape | Area | NaN | NaN | NaN | NaN | NaN | NaN | True |
| Cells_Intensity_MeanIntensity_DNA | Cells | Intensity | MeanIntensity | DNA | NaN | NaN | NaN | NaN | NaN | True |
| Cells_Intensity_MeanIntensity_RNA | Cells | Intensity | MeanIntensity | RNA | NaN | NaN | NaN | NaN | NaN | True |
| Cells_Intensity_MeanIntensity_AGP | Cells | Intensity | MeanIntensity | AGP | NaN | NaN | NaN | NaN | NaN | True |
| Cells_Intensity_MeanIntensity_ER | Cells | Intensity | MeanIntensity | ER | NaN | NaN | NaN | NaN | NaN | True |
| Cells_Intensity_MeanIntensity_Mito | Cells | Intensity | MeanIntensity | Mito | NaN | NaN | NaN | NaN | NaN | True |
| Nuclei_AreaShape_Area | Nuclei | AreaShape | Area | NaN | NaN | NaN | NaN | NaN | NaN | True |
| Nuclei_Intensity_MeanIntensity_DNA | Nuclei | Intensity | MeanIntensity | DNA | NaN | NaN | NaN | NaN | NaN | True |
| Nuclei_Intensity_MeanIntensity_RNA | Nuclei | Intensity | MeanIntensity | RNA | NaN | NaN | NaN | NaN | NaN | True |
| Nuclei_Intensity_MeanIntensity_AGP | Nuclei | Intensity | MeanIntensity | AGP | NaN | NaN | NaN | NaN | NaN | True |
| Nuclei_Intensity_MeanIntensity_ER | Nuclei | Intensity | MeanIntensity | ER | NaN | NaN | NaN | NaN | NaN | True |
| Nuclei_Intensity_MeanIntensity_Mito | Nuclei | Intensity | MeanIntensity | Mito | NaN | NaN | NaN | NaN | NaN | True |
| Cytoplasm_AreaShape_Area | Cytoplasm | AreaShape | Area | NaN | NaN | NaN | NaN | NaN | NaN | True |
| Cytoplasm_Intensity_MeanIntensity_DNA | Cytoplasm | Intensity | MeanIntensity | DNA | NaN | NaN | NaN | NaN | NaN | True |
| Cytoplasm_Intensity_MeanIntensity_RNA | Cytoplasm | Intensity | MeanIntensity | RNA | NaN | NaN | NaN | NaN | NaN | True |
| Cytoplasm_Intensity_MeanIntensity_AGP | Cytoplasm | Intensity | MeanIntensity | AGP | NaN | NaN | NaN | NaN | NaN | True |
| Cytoplasm_Intensity_MeanIntensity_ER | Cytoplasm | Intensity | MeanIntensity | ER | NaN | NaN | NaN | NaN | NaN | True |
| Cytoplasm_Intensity_MeanIntensity_Mito | Cytoplasm | Intensity | MeanIntensity | Mito | NaN | NaN | NaN | NaN | NaN | True |
| Cells_Correlation_Correlation_DNA_RNA | Cells | Correlation | Correlation | DNA|RNA | NaN | NaN | NaN | NaN | NaN | True |
region names the Labels element each row annotates, and Metadata_ObjectNumber the label value inside it:
cells.obs.head()
| Metadata_Plate | Metadata_Well | Metadata_Site | Metadata_ObjectNumber | region | |
|---|---|---|---|---|---|
| BLOBS01_A01_s1_cells:1 | BLOBS01 | A01 | 1 | 1 | BLOBS01_A01_s1_cells |
| BLOBS01_A01_s1_cells:2 | BLOBS01 | A01 | 1 | 2 | BLOBS01_A01_s1_cells |
| BLOBS01_A01_s1_cells:3 | BLOBS01 | A01 | 1 | 3 | BLOBS01_A01_s1_cells |
| BLOBS01_A01_s1_cells:4 | BLOBS01 | A01 | 1 | 4 | BLOBS01_A01_s1_cells |
| BLOBS01_A01_s1_cells:5 | BLOBS01 | A01 | 1 | 5 | BLOBS01_A01_s1_cells |
Reading a real plate#
A gallery source needs the accession directory, the batch and the plate barcode:
sdata = mt.io.read_plate(
"cpg0000-jump-pilot/source_4",
"BR00116991",
batch="2020_11_04_CPJUMP1",
wells=["A01"],
)
wells defaults to every well whose images are present, so a partial download reads back as itself.
The gallery publishes one-pixel object outlines rather than segmentation masks, so the Labels are reconstructed from them.
A component is accepted only when exactly one object centroid falls in it and its area is close to the area CellProfiler measured.
Rows whose object was not reconstructed are dropped.
Every label therefore stands for one object.
Where a source recorded no stage coordinates, or no pixel size to convert them with, each field sits in its own frame.
read_plate() then keeps that layout instead of inventing one, and leaves out the well shapes and the plate frame they would have lived in.
A plate straight out of a pipeline run needs only its folder:
sdata = mt.io.read_plate("run_export/Plate1")
Nothing is reconstructed on that path.
The ExportForSpatialData module writes real label arrays, a per-cell table already joined across compartments, and a manifest in the table’s uns listing what it wrote.
The reader builds only what the manifest names, so a folder that was moved still reads.
Arrays a failed cycle never wrote are skipped, together with the rows that annotate them.
Two plates#
Element names carry the plate barcode, so two plates concatenate without renaming:
import spatialdata as sd
other = mt.ds.blobs(n_wells=4, n_sites=4, plate="BLOBS02", seed=1)
merged = sd.concatenate([sdata, other], concatenate_tables=True)
merged.tables["wells"].obs.groupby("Metadata_Plate", observed=True).size()
Metadata_Plate
BLOBS01 4
BLOBS02 4
dtype: int64