saeyslab / napari-sparrow

Other
17 stars 0 forks source link

Cannot add shapes layer to sdata from numpy array #182

Open julienmortier opened 5 months ago

julienmortier commented 5 months ago

When I want to add a shapes layer to an sdata directly from a numpy array, it does not work (see error below).

mask_nucleus = io.imread(os.path.join(segmentation_folder_path, 'segmentation_mask_nucleus.tiff'))
sdata = sp.sh._add_shapes_layer(sdata, input=mask_nucleus, output_layer="nucleus_boundaries", transformation=None, overwrite=True)
{
    "name": "ValueError",
    "message": "Unsupported input type.",
    "stack": "---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[12], line 2
      1 mask_nucleus = io.imread(os.path.join(segmentation_folder_path, 'segmentation_mask_nucleus.tiff'))
----> 2 sdata = sp.sh._add_shapes_layer(sdata, input=mask_nucleus, output_layer=\"nucleus_boundaries\", transformation=None, overwrite=True)

File ~\\Documents\
apari-sparrow\\src\\sparrow\\shape\\_shape.py:23, in _add_shapes_layer(sdata, input, output_layer, transformation, overwrite)
     15 def _add_shapes_layer(
     16     sdata: SpatialData,
     17     input: Union[Array, GeoDataFrame],
   (...)
     20     overwrite: bool = False,
     21 ) -> SpatialData:
     22     manager = ShapesLayerManager()
---> 23     sdata = manager.add_shapes(
     24         sdata,
     25         input=input,
     26         output_layer=output_layer,
     27         transformation=transformation,
     28         overwrite=overwrite,
     29     )
     31     return sdata

File ~\\Documents\
apari-sparrow\\src\\sparrow\\shape\\_manager.py:42, in ShapesLayerManager.add_shapes(self, sdata, input, output_layer, transformation, overwrite)
     34 if transformation is not None and not isinstance(
     35     transformation, (Translation, Identity)
     36 ):
     37     raise ValueError(
     38         f\"Currently only transformations of type Translation are supported, \"
     39         f\"while provided transformation is of type {type(transformation)}\"
     40     )
---> 42 polygons = self.get_polygons_from_input(input)
     44 if transformation is not None:
     45     polygons = self.set_transformation(polygons, transformation)

File c:\\Users\\julienm\\miniconda3\\envs\
apari-sparrow\\lib\\functools.py:926, in singledispatchmethod.__get__.<locals>._method(*args, **kwargs)
    924 def _method(*args, **kwargs):
    925     method = self.dispatcher.dispatch(args[0].__class__)
--> 926     return method.__get__(obj, cls)(*args, **kwargs)

File ~\\Documents\
apari-sparrow\\src\\sparrow\\shape\\_manager.py:130, in ShapesLayerManager.get_polygons_from_input(self, input)
    128 @singledispatchmethod
    129 def get_polygons_from_input(self, input: Any) -> GeoDataFrame:
--> 130     raise ValueError(\"Unsupported input type.\")

ValueError: Unsupported input type."
}
julienmortier commented 5 months ago

However, when I first add it as a labels layer, then it does work. So there is a workaround, but I assume the desired behavior would be that you can just add it directly in the shapes layer, right?

mask_nucleus = io.imread(os.path.join(segmentation_folder_path, 'segmentation_mask_nucleus.tiff'))
sdata = sp.im._add_label_layer(sdata, arr=mask_nucleus, chunks=1024, output_layer="nucleus", overwrite=True)
sdata = sp.sh._add_shapes_layer(sdata, input=sdata['nucleus'].data, output_layer="nucleus_boundaries", transformation=None, overwrite=True)
ArneDefauw commented 5 months ago

_add_shapes_layer only accepts dask arrays and GeoDataFrame. So you first need to convert the numpy array to a dask array, e.g.:


import numpy as np
import dask.array as da

# Create a NumPy array (for example purposes)
numpy_array = np.random.rand(1000, 1000)

# Convert the NumPy array to a Dask array
# You can specify the 'chunks' size according to your needs
dask_array = da.from_array(numpy_array, chunks=(250, 250))

I can change this, so it also accepts numpy arrays

julienmortier commented 5 months ago

Ah, I see, that makes sense. I think it would indeed be useful if it would also accept numpy arrays.