Arcadia-Science / readlif

Leica Image Format (LIF) file reader for Python
GNU General Public License v3.0
32 stars 13 forks source link

Inconsistent treatment of dimensions #13

Closed MaartenBransen closed 3 years ago

MaartenBransen commented 3 years ago

I was wondering why the LifImage class has nz and nt attributes, but not e.g. nx or ny attributes, although it is of course trivial to obtain these from LifImage.dims.

Perhaps it is related to the comment on line 342 of reader.py: # Don't need a try / except block, all images have x and y I am not sure this is necessarily true. Our (Leica) confocal microscope for example can record directly in the xz plane, without scanning along the y direction. I suspect (but I haven't yet checked) it stores these not as nx×1 images but rather as nx×nz images.

I intend to check this soon, and could provide an example file of this, if it would be useful.

nimne commented 3 years ago

Hi Maarten,

I really appreciate the careful look through the code! The truth is, it's a result of "building the plane while flying it". in other words, I wrote this package to solve a very specific problem I had, and then it has been generalized over time as others have found it useful!

I agree that LifImage.dims is the better solution here, and it's where I've added all of the 'new' features. Having a bunch of inconsistent attributes isn't helpful, but I've been hesitant to delete things that might be in use somewhere.

If you can find that example file, that would be great! It's easy enough to change the assumptions here to be consistent without causing any breaking.

I would also be up for cleaning up the API (removing the things like nz and nt) for a potential 1.0.0 release if I can add in the other dimensions in your other issue. The slowest part is the lack of example files, I don't really want to assume anything about how the format should work.

-Nick

MaartenBransen commented 3 years ago

Hi Nick

I agree that dims is a good place to put this stuff in favour of many separate attribute.

# Don't need a try / except block, all images have x and y I am not sure this is necessarily true.

I tested with a file where I scanned in the x-y plane, and as I suspected the code gives an error in _recursive_image_find when it cannot find the information on the y-dimension. The file is attached here with the other example data.

Maarten

Edit: just adding a try/except block for the logical size of the x and y dimensions is enough to make it work, in which case get_frame() returns a 1×nx image. When the data is recorded as x-z-y (so 3D but scanning the xz plane for subsequent y positions, rather than the conventional xy plane for subsequent z order) the data are returned in the incorrect order by get_frame. I assume because it loads subsequent rows intended as being in the xz plane and treats them as being rows in the xy plane.

nimne commented 3 years ago

Thanks for the example files! This is an interesting finding. I would expect that the data block is still organized in the same way (essentially dims 1-10) despite the acquisition order, although this would suggest otherwise.

Does the file load in the correct order in ImageJ / bioformats? I'm hoping I'll have some time to look at this later today.

MaartenBransen commented 3 years ago

Does the file load in the correct order in ImageJ / bioformats?

I'll check this tomorrow.

I checked the metadata for the x-z-y scan, and the order of the y and z dimensions is indeed swapped with respect to a 'normal' x-y-z scan, and so is the byte order of the data block itself it seems. Fortunately the byte-offset / increment between steps along each dimension is included in the metadata. See below.

{'DimID': '1', 'NumberOfElements': '128', 'Origin': '1.376765e-020', 'Length': '3.464866e-005', 'Unit': 'm', 'BitInc': '0', 'BytesInc': '1'},
{'DimID': '3', 'NumberOfElements': '64', 'Origin': '1.192093e-009', 'Length': '1.718785e-005', 'Unit': 'm', 'BitInc': '0', 'BytesInc': '128'},
{'DimID': '2', 'NumberOfElements': '38', 'Origin': '2.000334e-005', 'Length': '9.994533e-006', 'Unit': 'm', 'BitInc': '0', 'BytesInc': '8192'}
MaartenBransen commented 3 years ago

I can confirm that ImageJ/Bioformats loads and displays the data in the right way. It does swap the naming of the y and z directions, but I think that is just the default naming / coordinate system of ImageJ's stack viewer and I don't think that can be changed or is specific to these files. I indicated how the axes should be labeled.

zyx_orientation

nimne commented 3 years ago

After a bit of a pause, I've updated 0.6.1 with get_plane. There is still the issue of inconsistent dimension handling, but until this is (mostly) feature-complete and things get refactored into a 1.0.0 release, they are here to stay. Closing this issue for now.