Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle downsampling to_multiscales with channel dimension #125

Closed
will-moore opened this issue Dec 18, 2024 · 6 comments
Closed

Handle downsampling to_multiscales with channel dimension #125

will-moore opened this issue Dec 18, 2024 · 6 comments

Comments

@will-moore
Copy link

I was trying to downsample data that has a 'c' dimension...

# 4D data...
data = np.random.randint(0, 256, 16777216).reshape((2, 128, 256, 256))

# This works - downsamples in x,y,z
image = nz.to_ngff_image(data, dims=['t', 'z', 'y', 'x'])
multiscales = nz.to_multiscales(image, scale_factors=[2, 4], chunks=64)
nz.to_ngff_zarr('example_4d_2time.ome.zarr', multiscales)

# This fails since 'c' dimension isn't handled
image = nz.to_ngff_image(data, dims=['c', 'z', 'y', 'x'])
multiscales = nz.to_multiscales(image, scale_factors=[2, 4], chunks=64)
nz.to_ngff_zarr('example_4d_2ch.ome.zarr', multiscales)

# 5D data - also fails
data = np.random.randint(0, 256, 16777216).reshape((4, 2, 128, 128, 128))
image = nz.to_ngff_image(data, dims=['t', 'c', 'z', 'y', 'x'])
multiscales = nz.to_multiscales(image, scale_factors=[2, 4], chunks=64)
nz.to_ngff_zarr('example_4d_2ch_4time.ome.zarr', multiscales)

I was trying to fix _downsample_itkwasm and made some progress with the 4D channel example above but the 5D example was too much for me!

I was also wondering about future support of n-dimensional data, since OME-Zarr will soon allow any number of dimensions?

I was trying an approach of slicing 5 dimensions down to just 3 dimensions before downsampling, but this would need more work to handle n-dimensions:
e.g.

                 for d_index, dim_name in enumerate(previous_image.dims):
                        if dim_name in ('x', 'y', 'z'):
                            d_size = previous_image.data.shape[d_index]
                            indices.append(np.s_[0:d_size:])
                        elif dim_name == 'c':
                            indices.append(channel)
                        elif dim_name == 't':
                            indices.append(timepoint)

                    data_3d = previous_image.data[tuple(indices)]

Thanks!

@cudmore
Copy link

cudmore commented Dec 20, 2024

Came here to report the 4D issue with a 'channel' dimension 'c'. Tried out ngff-zarr because I saw your post in the ome-zarr-py issues!

My 2-channel 4D image has shape (2, 70, 1024, 1024).

@will-moore, do you have some example code that fixes the 4D case with dims=['c', 'z', 'y', 'x']).

The trace I get includes the warning Size and sigma must have the same length. Size: 4 Sigma: 3..

Traceback (most recent call last):
  File "/Users/cudmore/Sites/MapManagerCore/sandbox/ome_zarr/exportOmeZarr.py", line 177, in <module>
    tryNgff()
  File "/Users/cudmore/Sites/MapManagerCore/sandbox/ome_zarr/exportOmeZarr.py", line 154, in tryNgff
    multiscales = nz.to_multiscales(image,
                  ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/ngff_zarr/to_multiscales.py", line 327, in to_multiscales
    images = _downsample_itkwasm(
             ^^^^^^^^^^^^^^^^^^^^
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/ngff_zarr/methods/_itkwasm.py", line 188, in _downsample_itkwasm
    kernel_radius = gaussian_kernel_radius(
                    ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/itkwasm_downsample/gaussian_kernel_radius.py", line 34, in gaussian_kernel_radius
    output = func(size=size, sigma=sigma, max_kernel_width=max_kernel_width, max_kernel_error=max_kernel_error)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/itkwasm_downsample_wasi/gaussian_kernel_radius.py", line 81, in gaussian_kernel_radius
    outputs = _pipeline.run(args, pipeline_outputs, pipeline_inputs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/itkwasm/pipeline.py", line 626, in run
    ri.delayed_exit(return_code)
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/itkwasm/pipeline.py", line 157, in delayed_exit
    func(self._store, return_code)
  File "/Users/cudmore/opt/miniconda3/envs/pmm-env/lib/python3.11/site-packages/wasmtime/_func.py", line 103, in __call__
    raise WasmtimeError._from_ptr(error)
wasmtime._error.ExitTrap: error while executing at wasm backtrace:
    0: 0x42487 - <unknown>!<wasm function 562>
    1: 0x8d420 - <unknown>!<wasm function 1059>
note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information

Caused by:
    Exited with i32 exit status 1

@thewtex
Copy link
Owner

thewtex commented Dec 23, 2024

@will-moore @cudmore thanks for the report! Please test #126

I was also wondering about future support of n-dimensional data, since OME-Zarr will soon allow any number of dimensions?

If there are real use cases that we do not support, we can add tests/implementations for them.

I wrote the tests against the generated data. I tried to verify on real data with napari,

ome_zarr download https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457539.zarr
napari --plugin napari-ome-zarr ./13457539.zarr

But I just get blackness:

image

What am I doing wrong?

CC @joshmoore

@will-moore
Copy link
Author

I tried:

$ ome_zarr view ./13457539.zarr

This opens the image in ome-ngff-validator which tells me Error: Dimension separator must be / for version 0.4, which I think is a bug in the download (see ome/ome-zarr-py#231).
I think that napari via ome-zarr-py is strictly using the / dimension separator for v0.4 data which is why it's not finding the right chunks.
However, you can use the ome-ngff-validator to view the image in itk-vtk viewer etc which is not so strict.

@will-moore
Copy link
Author

The download issue is fixed with the PR at ome/ome-zarr-py#419 (review)

ome_zarr download https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457539.zarr
napari --plugin napari-ome-zarr ./13457539.zarr

Screenshot 2025-01-06 at 15 37 58

@will-moore
Copy link
Author

@cudmore The branch at #126 fixes this issue, if you want to give it a try?

@thewtex
Copy link
Owner

thewtex commented Jan 8, 2025

@will-moore @cudmore #126 has been pushed to PyPI in ngff-zarr 0.11.0 -- further testing is appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants