scverse / spatialdata

An open and interoperable data framework for spatial omics data
https://spatialdata.scverse.org/
BSD 3-Clause "New" or "Revised" License
174 stars 34 forks source link

Cannot aggregate Labels2DModel by ShapesModel #546

Open GuoshengMa opened 3 weeks ago

GuoshengMa commented 3 weeks ago

Hi @LucaMarconato ! I got an error when I use aggregate() to aggregate a label layer by a shape layer.

Here is my code:

image

image

image

The label layer in codex_sdata was created by code below:

segmentation = iio.imread(data_dir / '3-D2_segmentation_borders.tiff')
labels = { 'labels': sd.models.Labels2DModel.parse(segmentation, dims=("y", "x")) }
sdata = sd.SpatialData(table=table, labels=labels, images=images)

In addition, following the conclusion of last Thursday's community meeting, I sent you an email with the subject 'Inquiry Regarding CODEX Data and High-Resolution Visium Image Alignment.' It contained attachments with the test data and scripts I provided. I wanted to confirm whether you received that email?

LucaMarconato commented 3 weeks ago

Hi, answering the last question first thanks for your patience with the issue regarding the other issue. I just answered your email with the solution.

Regarding the current problem, currently we do not support aggregating vector data by raster data and vice versa. This could be done by either "vectorizing" the segmentation mask either by rasterizing the shapes. In your case, I would suggest doing the first.

A first approximation, if you do not need the precise shape of the cell, is to consider the cells as circles. In the notebook that I sent you by email I do so, so you can use that code already. (To be more precise, in the notebook I consider circles with arbitrary radii, but if you want to construct the circles from the labels you can follow the directions in my answer here https://github.com/scverse/spatialdata/discussions/472).

Finally, if you want to be more precise and construct the exact polygons from the raster segmentation mask you can check out the approach used by SOPA https://gustaveroussy.github.io/sopa/ with the function sopa.segmentation.shapes.geometrize.