spatialdata icon indicating copy to clipboard operation
spatialdata copied to clipboard

spatialdata.transform MultiscaleSpatialImage raises KeyError

Open aeisenbarth opened this issue 1 year ago • 0 comments

The implementation of transform for MultiscaleSpatialImage is not covered by tests. This is a problem because (Multiscale)SpatialImage are structurally and implementationwise significantly different.

For scale1 and greater, the key is supposed to have a dictionary of a transformation matrix from the downscaling operation:

            scale = _get_scale(xdata.attrs["transform"])

But the key does not exist and I also cannot see it anywhere else in the DataTree.

See this test case in https://github.com/scverse/spatialdata/pull/379: https://github.com/scverse/spatialdata/blob/7690b49c595b8e996696d5ab4357d0332d42f851/tests/transformations/test_transformations.py#L870-L876

__________ test_keep_numerical_coordinates_c[blobs_multiscale_image] ___________

image_name = 'blobs_multiscale_image'

    @pytest.mark.parametrize("image_name", ["blobs_multiscale_image"])
    def test_keep_numerical_coordinates_c(image_name):
        c_coords = range(3)
        sdata = blobs(n_channels=len(c_coords))
        t = get_transformation(sdata.images[image_name])
>       t_blobs = transform(sdata.images[image_name], t)

test_transformations.py:876: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
…/functools.py:888: in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

data = DataTree('None', parent=None)
├── DataTree('scale0')
│       Dimensions:  (c: 3, y: 512, x: 512)
│       Coordinates:
...0.0
        Data variables:
            image    (c, y, x) float64 dask.array<chunksize=(3, 128, 128), meta=np.ndarray>
transformation = Sequence 
    Scale (y, x)
        [1. 1.]
    Identity 
maintain_positioning = False

    @transform.register(MultiscaleSpatialImage)
    def _(
        data: MultiscaleSpatialImage, transformation: BaseTransformation, maintain_positioning: bool = False
    ) -> MultiscaleSpatialImage:
        schema = get_model(data)
        from spatialdata.models import (
            Image2DModel,
            Image3DModel,
            Labels2DModel,
            Labels3DModel,
        )
        from spatialdata.transformations import get_transformation, set_transformation
        from spatialdata.transformations.transformations import Sequence
    
        # labels need to be preserved after the resizing of the image
        if schema in (Labels2DModel, Labels3DModel):
            # TODO: this should work, test better
            kwargs = {"prefilter": False}
        elif schema in (Image2DModel, Image3DModel):
            kwargs = {}
        else:
            raise ValueError(f"MultiscaleSpatialImage with schema {schema} not supported")
    
        get_axes_names(data)
        transformed_dict = {}
        for k, v in data.items():
            assert len(v) == 1
            xdata = v.values().__iter__().__next__()
    
            composed: BaseTransformation
            if k == "scale0":
                composed = transformation
            else:
>               scale = _get_scale(xdata.attrs["transform"])
E               KeyError: 'transform'

aeisenbarth avatar Oct 20 '23 09:10 aeisenbarth