Skip to content

Commit 4b02dbf

Browse files
committed
exercise the protein specific code
1 parent 6822307 commit 4b02dbf

3 files changed

Lines changed: 58 additions & 3 deletions

File tree

.github/workflows/prepare_test_data.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ jobs:
3535
# 10x Genomics Xenium 3.0.0 (5K) Mouse ileum, nuclear expansion
3636
curl -O https://cf.10xgenomics.com/samples/xenium/3.0.0/Xenium_Prime_Mouse_Ileum_tiny/Xenium_Prime_Mouse_Ileum_tiny_outs.zip
3737
38+
# 10x Genomics Xenium 4.0.0 (v1) Human ovary, nuclear expansion
39+
curl -O https://cf.10xgenomics.com/samples/xenium/4.0.0/Xenium_V1_Human_Ovary_tiny/Xenium_V1_Human_Ovary_tiny_outs.zip
40+
41+
# 10x Genomics Xenium 4.0.0 (v1) Human ovary, multimodal cell segmentation
42+
curl -O https://cf.10xgenomics.com/samples/xenium/4.0.0/Xenium_V1_MultiCellSeg_Human_Ovary_tiny/Xenium_V1_MultiCellSeg_Human_Ovary_tiny_outs.zip
43+
3844
# 10x Genomics Xenium 4.0.0 (v1+Protein) Human kidney, multimodal cell segmentation
3945
curl -O https://cf.10xgenomics.com/samples/xenium/4.0.0/Xenium_V1_Protein_Human_Kidney_tiny/Xenium_V1_Protein_Human_Kidney_tiny_outs.zip
4046

src/spatialdata_io/readers/xenium.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def xenium(
6868
aligned_images: bool = True,
6969
cells_table: bool = True,
7070
n_jobs: int = 1,
71+
gex_only: bool | None = True,
7172
imread_kwargs: Mapping[str, Any] = MappingProxyType({}),
7273
image_models_kwargs: Mapping[str, Any] = MappingProxyType({}),
7374
labels_models_kwargs: Mapping[str, Any] = MappingProxyType({}),
@@ -121,6 +122,8 @@ def xenium(
121122
Whether to read the cell annotations in the `AnnData` table.
122123
n_jobs
123124
Number of jobs to use for parallel processing.
125+
gex_only
126+
Whether to load only the "Gene Expression" feature type.
124127
imread_kwargs
125128
Keyword arguments to pass to the image reader.
126129
image_models_kwargs
@@ -186,7 +189,7 @@ def xenium(
186189
cells_table = True
187190

188191
if cells_table:
189-
return_values = _get_tables_and_circles(path, cells_as_circles, specs)
192+
return_values = _get_tables_and_circles(path, cells_as_circles, specs, gex_only)
190193
if cells_as_circles:
191194
table, circles = return_values
192195
else:
@@ -561,9 +564,9 @@ def _get_points(path: Path, specs: dict[str, Any]) -> Table:
561564

562565

563566
def _get_tables_and_circles(
564-
path: Path, cells_as_circles: bool, specs: dict[str, Any]
567+
path: Path, cells_as_circles: bool, specs: dict[str, Any], gex_only: bool
565568
) -> AnnData | tuple[AnnData, AnnData]:
566-
adata = _read_10x_h5(path / XeniumKeys.CELL_FEATURE_MATRIX_FILE)
569+
adata = _read_10x_h5(path / XeniumKeys.CELL_FEATURE_MATRIX_FILE, gex_only=gex_only)
567570
metadata = pd.read_parquet(path / XeniumKeys.CELL_METADATA_FILE)
568571
np.testing.assert_array_equal(metadata.cell_id.astype(str), adata.obs_names.values)
569572
circ = metadata[[XeniumKeys.CELL_X, XeniumKeys.CELL_Y]].to_numpy()

tests/test_xenium.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,49 @@ def test_cli_xenium(runner: CliRunner, dataset: str) -> None:
188188
)
189189
assert result.exit_code == 0, result.output
190190
_ = read_zarr(output_zarr)
191+
192+
@skip_if_below_python_version()
193+
@pytest.mark.parametrize(
194+
("dataset", "gex_only",),
195+
[("Xenium_V1_human_Lung_2fov_outs", False),
196+
("Xenium_V1_human_Lung_2fov_outs", True),
197+
("Xenium_V1_Human_Ovary_tiny_outs", False),
198+
("Xenium_V1_Human_Ovary_tiny_outs", True),
199+
("Xenium_V1_MultiCellSeg_Human_Ovary_tiny_outs", False),
200+
("Xenium_V1_MultiCellSeg_Human_Ovary_tiny_outs", True),
201+
("Xenium_V1_Protein_Human_Kidney_tiny_outs", False),
202+
("Xenium_V1_Protein_Human_Kidney_tiny_outs", True)
203+
]
204+
)
205+
def test_xenium_other_feature_types(dataset: str, gex_only: bool) -> None:
206+
f = Path("./data") / dataset
207+
assert f.is_dir()
208+
sdata = xenium(f, cells_as_circles=False, gex_only=gex_only)
209+
if gex_only:
210+
assert set(sdata["table"].var["feature_types"]) == {"Gene Expression"}
211+
elif dataset == "Xenium_V1_human_Lung_2fov_outs":
212+
assert set(sdata["table"].var["feature_types"]) == {"Deprecated Codeword",
213+
"Gene Expression",
214+
"Negative Control Codeword",
215+
"Negative Control Probe",
216+
"Unassigned Codeword"}
217+
elif dataset in {"Xenium_V1_Human_Ovary_tiny_outs", "Xenium_V1_MultiCellSeg_Human_Ovary_tiny_outs"}:
218+
assert set(sdata["table"].var["feature_types"]) == {"Gene Expression",
219+
"Genomic Control",
220+
"Negative Control Codeword",
221+
"Negative Control Probe",
222+
"Unassigned Codeword"}
223+
elif dataset == "Xenium_V1_Protein_Human_Kidney_tiny_outs":
224+
assert set(sdata["table"].var["feature_types"]) == {"Gene Expression",
225+
"Genomic Control",
226+
"Negative Control Codeword",
227+
"Negative Control Probe",
228+
"Protein Expression",
229+
"Unassigned Codeword"}
230+
# Protein feature
231+
assert np.allclose(sdata["table"].X[0:3, sdata["table"].var_names.str.match("VISTA")].toarray().squeeze(), [0.7, 1.2, 0.0])
232+
# RNA feature
233+
assert np.allclose(sdata["table"].X[[6,7,24], sdata["table"].var_names.str.match("ACTG2")].squeeze(), [1, 0, 2])
234+
235+
else:
236+
assert ValueError(f"Unexpected dataset {dataset}")

0 commit comments

Comments
 (0)