Open StefanHMueller opened 6 months ago
@StefanHMueller thanks for reporting this issue and for detailing your workaround 🙏
There are several problems with the current dask_image.imread
implementation. Here's an issue tracking some of them and also the roadmaps towards improving the situation.
I'm glad you've found a workaround that works for you. Also consider using the readers mentioned here.
[]()
Thanks @m-albert . I hadn't see the AICSImageIO readers before. It produces dask arrays with the right shape and does so quickly. This at least solves my problem, even though it would be nice not to depend on yet another package one day. Reading nd2 files of any dimension to dask works for me simply like this:
from aicsimageio import AICSImage
path = 'path_to_file/.nd2'
img = AICSImage(path)
dask_array = img.dask_data
Issue
I use the imread function to load nd2 files recorded on Nikon microscopes that contain multiple series (i.e. multiple fields of view are imaged simultaneously) and multiple color channels as well as multiple frames. The imread function just returns all frames at the first series and the first color channel, i.e. a 5D image with x=512, y=512, c=2, t=5, v=3 is reduced to a dask array with shape (5,512,512) without error or warning. Test data in .nd2 format to reproduce can be found here: https://github.com/Single-molecule-Biophysics-UOW/TIRF_tools/blob/main/test_data/multi_series_multiC_002.nd2
This returns:
This behavior depends on which reader pims uses internally (options are nd2reader or bioformats), but either way dask_image does not handle the output correctly.
Cause
The reason for this behavior is the following: In the imread function the shape of the image is determined using
len(im)
which only returns the number of frames regardless of other dimensions:Workaround
This behavior can be fixed by changing the iteration axis and bundling of axes for the pims reader as follows. I also added some quick and dirty string shuffling to make sure xy are the two last dimensions:
This returns:
As expected the shape as imread determines it is now correct. To actually use this work around I made my own version of the imread function as well as the _read_frame function and inserted those lines just after the
pims.open(...
statements. This works well, but probably is very dependent on the exact file type used and the reader used by pims. Perhaps it would be feasible to implement a warning if imread returns an array with less dimensions than the pims imageSequenceND has axes though?