spatialdata icon indicating copy to clipboard operation
spatialdata copied to clipboard

Implement, and document in a notebook, an helper function for accessing levels of multiscale images

Open LucaMarconato opened this issue 2 years ago • 6 comments

Asked by @berombau.

One public function similar to this is here https://github.com/scverse/spatialdata/blob/4c6c1e9613310acc8844ff186a66084e8d5b85e4/src/spatialdata/_utils.py#L170.

  • [ ] We could make the function accept an int argument instead.
  • [ ] We definitely need to make the function more visible and make an example with it.

LucaMarconato avatar Sep 19 '23 12:09 LucaMarconato

I'd like a simple accessor to the data array (ideally as property/method on the class) that is the same for all allowed elements in SpatialData.images. You may not know (or care) whether you get a SpatialImage or MultiscaleSpatialImage, and don't want to clutter your code with if/else. I would think apart from viewer applications, the highest resolution level is most often what users need to access. Currently, I am using:

def get_spatial_image_array(image: Union[SpatialImage, xr.DataArray, MultiscaleSpatialImage, datatree.DataTree]) -> xr.DataArray:
    from spatialdata._utils import iterate_pyramid_levels
    # Check for both MultiscaleSpatialImage and DataTree because operations on the former implicitly convert it (e.g. transpose).
    if isinstance(image, (MultiscaleSpatialImage, datatree.DataTree)):
        return next(iterate_pyramid_levels(image))
    else:
        return image

aeisenbarth avatar Oct 18 '23 18:10 aeisenbarth

That's a good point, thanks @aeisenbarth.

@thewtex @giovp I think that maybe such a functionality could be implemented upstream, what are your thoughts on this?

LucaMarconato avatar Oct 18 '23 23:10 LucaMarconato

Yes, agreed -- seems appropriate for a MultiscaleSpatialImage method.

thewtex avatar Oct 20 '23 01:10 thewtex

I just noticed that some operations on (Multiscale)SpatialImage which are inherited from the parent class return an instance of the parent class (DataArray, DataTree). In that case, such a method would not be available.

I'm not sure whether due to this a pure function is favorable over a method, or whether (Multiscale)SpatialImage would need to override other inherited methods (transpose etc.) to return an instance of the subclass.

Also, now that SpatialData.images can contain SpatialImage, DataArray, MultiscaleSpatialImage, DataTree, it would be nice to have a common type and interface of shared methods/properties.

aeisenbarth avatar Oct 20 '23 08:10 aeisenbarth

Besides that, there should be a convenient function to get a SpatialImage from a MultiscaleSpatialImage (in package multiscale_spatial_image ?).

Something wrapping this code:

SpatialImage(get_spatial_image_array(multiscale_image))

aeisenbarth avatar Oct 20 '23 09:10 aeisenbarth

Hi @aeisenbarth thanks for the comments. We reported the behaviors that you mentioned in this issue: https://github.com/spatial-image/multiscale-spatial-image/issues/80

Giovanni made two PRs https://github.com/spatial-image/spatial-image/pull/22, https://github.com/spatial-image/multiscale-spatial-image/pull/81 which go in the direction of a solution (@giovp can you maybe comment on this please?).

Please note that the PRs have been merged already but we haven't adapted spatialdata yet; we would like to do this next week.

LucaMarconato avatar Oct 20 '23 22:10 LucaMarconato