Skip to content
This repository was archived by the owner on Aug 27, 2025. It is now read-only.

Commit 6648c82

Browse files
xenium tuto WIP
1 parent 36cf6b5 commit 6648c82

1 file changed

Lines changed: 38 additions & 46 deletions

File tree

docs/10x_tutorials/xenium_tuto.ipynb

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -215,46 +215,9 @@
215215
},
216216
{
217217
"cell_type": "code",
218-
"execution_count": 31,
218+
"execution_count": null,
219219
"metadata": {},
220-
"outputs": [
221-
{
222-
"name": "stdout",
223-
"output_type": "stream",
224-
"text": [
225-
"\u001b[34mINFO \u001b[0m `dims` is specified redundantly: found also inside `data`. \n"
226-
]
227-
},
228-
{
229-
"name": "stderr",
230-
"output_type": "stream",
231-
"text": [
232-
"\u001b[36;20m[INFO] (spatialdata_xenium_explorer.core.images)\u001b[0m Adding image image:\n",
233-
"<xarray.SpatialImage 'image' (c: 3, y: 43287, x: 22209)>\n",
234-
"dask.array<rechunk-merge, shape=(3, 43287, 22209), dtype=uint8, chunksize=(1, 4096, 4096), chunktype=numpy.ndarray>\n",
235-
"Coordinates:\n",
236-
" * c (c) <U1 '0' '1' '2'\n",
237-
" * y (y) float64 0.5 1.5 2.5 3.5 ... 4.328e+04 4.329e+04 4.329e+04\n",
238-
" * x (x) float64 0.5 1.5 2.5 3.5 ... 2.221e+04 2.221e+04 2.221e+04\n",
239-
"Attributes:\n",
240-
" transform: {'global': Affine (x, y -> x, y)\\n [1.83698152e-03 6.44010...\n"
241-
]
242-
},
243-
{
244-
"ename": "KeyError",
245-
"evalue": "'Image Xeniumranger_V1_hSkin_Melanoma_Add_on_FFPE_he_image already exists in the dataset.'",
246-
"output_type": "error",
247-
"traceback": [
248-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
249-
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
250-
"Cell \u001b[0;32mIn[31], line 6\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;66;03m# where you exported the alignment file\u001b[39;00m\n\u001b[1;32m 4\u001b[0m alignment_matrix_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mXeniumranger_V1_hSkin_Melanoma_Add_on_FFPE_he_imagealignment.csv\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m----> 6\u001b[0m \u001b[43mspatialdata_xenium_explorer\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43malign\u001b[49m\u001b[43m(\u001b[49m\u001b[43msdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mh_and_e\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43malignment_matrix_path\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mimage_key\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mimage_key\u001b[49m\u001b[43m)\u001b[49m\n",
251-
"File \u001b[0;32m~/dev/spatialdata_xenium_explorer/spatialdata_xenium_explorer/core/images.py:243\u001b[0m, in \u001b[0;36malign\u001b[0;34m(sdata, image, transformation_matrix_path, image_key, image_models_kwargs, overwrite)\u001b[0m\n\u001b[1;32m 234\u001b[0m image \u001b[38;5;241m=\u001b[39m Image2DModel\u001b[38;5;241m.\u001b[39mparse(\n\u001b[1;32m 235\u001b[0m image,\n\u001b[1;32m 236\u001b[0m dims\u001b[38;5;241m=\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mc\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124my\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 239\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mimage_models_kwargs,\n\u001b[1;32m 240\u001b[0m )\n\u001b[1;32m 242\u001b[0m log\u001b[38;5;241m.\u001b[39minfo(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAdding image \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mimage\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m:\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mimage\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 243\u001b[0m \u001b[43msdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd_image\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mimage\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moverwrite\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moverwrite\u001b[49m\u001b[43m)\u001b[49m\n",
252-
"File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/spatialdata-xenium-explorer-yAxRBYoR-py3.9/lib/python3.9/site-packages/spatialdata/_core/spatialdata.py:710\u001b[0m, in \u001b[0;36mSpatialData.add_image\u001b[0;34m(self, name, image, storage_options, overwrite)\u001b[0m\n\u001b[1;32m 708\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_add_image_in_memory(name\u001b[38;5;241m=\u001b[39mname, image\u001b[38;5;241m=\u001b[39mimage, overwrite\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m 709\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 710\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_add_image_in_memory\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mimage\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mimage\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moverwrite\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moverwrite\u001b[49m\u001b[43m)\u001b[49m\n",
253-
"File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/spatialdata-xenium-explorer-yAxRBYoR-py3.9/lib/python3.9/site-packages/spatialdata/_core/spatialdata.py:288\u001b[0m, in \u001b[0;36mSpatialData._add_image_in_memory\u001b[0;34m(self, name, image, overwrite)\u001b[0m\n\u001b[1;32m 284\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_validate_unique_element_names(\n\u001b[1;32m 285\u001b[0m \u001b[38;5;28mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlabels\u001b[38;5;241m.\u001b[39mkeys()) \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpoints\u001b[38;5;241m.\u001b[39mkeys()) \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mshapes\u001b[38;5;241m.\u001b[39mkeys()) \u001b[38;5;241m+\u001b[39m [name]\n\u001b[1;32m 286\u001b[0m )\n\u001b[1;32m 287\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_images \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m overwrite:\n\u001b[0;32m--> 288\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mImage \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m already exists in the dataset.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 289\u001b[0m ndim \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlen\u001b[39m(get_axes_names(image))\n\u001b[1;32m 290\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m3\u001b[39m:\n",
254-
"\u001b[0;31mKeyError\u001b[0m: 'Image Xeniumranger_V1_hSkin_Melanoma_Add_on_FFPE_he_image already exists in the dataset.'"
255-
]
256-
}
257-
],
220+
"outputs": [],
258221
"source": [
259222
"image_key = \"morphology_mip\"\n",
260223
"\n",
@@ -306,7 +269,9 @@
306269
"cell_type": "markdown",
307270
"metadata": {},
308271
"source": [
309-
"### Alignment from `SpatialData` to the Xenium Explorer"
272+
"### Alignment from `SpatialData` to the Xenium Explorer\n",
273+
"\n",
274+
"Now, we suppose you have already aligned your H&E image using `SpatialData`. Here, we detail how use the transformation inside the Xenium Explorer."
310275
]
311276
},
312277
{
@@ -319,6 +284,13 @@
319284
"import numpy as np"
320285
]
321286
},
287+
{
288+
"cell_type": "markdown",
289+
"metadata": {},
290+
"source": [
291+
"First, we get the transformation from the H&E image to the global coordinate system:"
292+
]
293+
},
322294
{
323295
"cell_type": "code",
324296
"execution_count": 29,
@@ -330,13 +302,22 @@
330302
"transformation = get_transformation(spatial_element, to_coordinate_system=\"global\")"
331303
]
332304
},
305+
{
306+
"cell_type": "markdown",
307+
"metadata": {},
308+
"source": [
309+
"If it is an affine transformation, we can create a `.csv` file representing the transformation:"
310+
]
311+
},
333312
{
334313
"cell_type": "code",
335314
"execution_count": 30,
336315
"metadata": {},
337316
"outputs": [],
338317
"source": [
339-
"assert isinstance(transformation, Affine), \"The Xenium Explorer only supports Affine transformations\"\n",
318+
"assert isinstance(\n",
319+
" transformation, Affine\n",
320+
"), \"The Xenium Explorer only supports Affine transformations\"\n",
340321
"\n",
341322
"np.savetxt(\"alignment_matrix.csv\", transformation.matrix, delimiter=\",\")"
342323
]
@@ -356,7 +337,13 @@
356337
"source": [
357338
"# 4. Update the cells on the Explorer\n",
358339
"\n",
359-
"### Update the cell categories"
340+
"### Update the cell categories\n",
341+
"\n",
342+
"Here, we run some Leiden clustering with `scanpy`. Then, we will update the Xenium Explorer files to display the spot clusters.\n",
343+
"\n",
344+
"More generally, you can add new cell categories, i.e. a column of `sdata.table.obs`, and the Xenium Explorer will show it after the instructions below.\n",
345+
"\n",
346+
"> Note that we only display categorical columns. If a column from `sdata.table.obs` contains continuous numerical values (e.g., `3.13, 7.89, ...`), it will not be transformed into a categorical variable, and therefore not shown in the Xenium Explorer. In this case, we recommend using `spatiadata_plot` as shown above."
360347
]
361348
},
362349
{
@@ -424,7 +411,7 @@
424411
"source": [
425412
"### Update a new segmentation\n",
426413
"\n",
427-
"In the case where you performed your own segmentation, you may want to update the explorer with your new cells.\n",
414+
"In the case where you performed your own segmentation, you may want to update the explorer with your new cells. You'll also need to update `sdata.table` to contain the transcript counts associated to your new cells.\n",
428415
"\n",
429416
"> Note that `mode=\"-it\"` signifies to create all files except the image and transcript file. Indeed, the two latter files doesn't need to be updated, they will remain the same."
430417
]
@@ -445,9 +432,14 @@
445432
"outputs": [],
446433
"source": [
447434
"# this is the key related to your new cell boundaries, i.e. sdata[shapes_key] is a pandas GeoDataFrame\n",
448-
"shapes_key = \"new_shapes\"\n",
449-
"\n",
450-
"spatialdata.aggregate(...)"
435+
"shapes_key = \"new_shapes\""
436+
]
437+
},
438+
{
439+
"cell_type": "markdown",
440+
"metadata": {},
441+
"source": [
442+
"Now, update all the files related to your new cells:"
451443
]
452444
},
453445
{

0 commit comments

Comments
 (0)