tlambert03 / nd2

Full-featured nd2 (Nikon NIS Elements) file reader for python. Outputs to numpy, dask, and xarray. Exhaustive metadata extraction
https://tlambert03.github.io/nd2
BSD 3-Clause "New" or "Revised" License
52 stars 15 forks source link

feat: add `write_tiff` export to OME-TIFF, include full metadata as StructuredAnnotation #216

Closed tlambert03 closed 6 months ago

tlambert03 commented 6 months ago

closes #215 and adds an export to ome-tiff

import nd2

with nd2.ND2File('your.nd2') as f:
    f.write_tiff('output.ome.tif')
codecov[bot] commented 6 months ago

Codecov Report

Attention: Patch coverage is 98.60140% with 2 lines in your changes are missing coverage. Please review.

Project coverage is 95.27%. Comparing base (256ef22) to head (cffe615).

Files Patch % Lines
src/nd2/tiff.py 96.66% 2 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #216 +/- ## ========================================== + Coverage 95.17% 95.27% +0.09% ========================================== Files 17 18 +1 Lines 2362 2433 +71 ========================================== + Hits 2248 2318 +70 - Misses 114 115 +1 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codspeed-hq[bot] commented 6 months ago

CodSpeed Performance Report

Merging #216 will not alter performance

Comparing update-ome (cffe615) with main (256ef22)

Summary

✅ 13 untouched benchmarks

tlambert03 commented 6 months ago

@phisanti, not sure if you get these github pings. But this is at a state where you might want to try it out:

pip install git+https://github.com/tlambert03/nd2.git@update-ome

then

import nd2

with nd2.ND2File('your.nd2') as f:
    f.write_tiff('output.ome.tif')
tlambert03 commented 6 months ago

ah: one feature i still need to implement is exporting multi-position ND acquisitions to multi-series tiff

tlambert03 commented 6 months ago

@cgohlke, if I could borrow a moment of your time, i would greatly appreciate your feedback on the nd2_to_tiff implementation in tiff.py in the PR. Mostly curious to know whether I've missed any performance or metadata considerations, and whether I've used the tifffile API as optimally as I could. I would also like to know if you have tips on what I would need to change to implement multi-series files, for nd2 files that have multiple stage positions (i believe 6D is the highest nd2 will ever go though)

tlambert03 commented 6 months ago

I would also like to know if you have tips on what I would need to change to implement multi-series files, for nd2 files that have multiple stage positions (i believe 6D is the highest nd2 will ever go though)

to clarify, I specifically mean the best way to do this while using a data iterator rather than reading the full position into memory, while also considering that as I iterate through frames in the nd2 file, different stage positions will likely not be contiguous

cgohlke commented 6 months ago

The use of the iterator looks correct to me as long as it returns frames of same shape and dtype.

To write a second series, call tif.write(...) again.

Christoph suggests encode("ascii"): Did I? TIFF strings must be ASCII 7-bit, which is enforced by tifffile. In order to write OME-XML, encode it as UTF8. Encoded bytes are not checked by tifffile.

tlambert03 commented 6 months ago

The use of the iterator looks correct to me as long as it returns frames of same shape and dtype. To write a second series, call tif.write(...) again.

thanks!

Did I? TIFF strings must be ASCII 7-bit, which is enforced by tifffile. In order to write OME-XML, encode it as UTF8. Encoded bytes are not checked by tifffile.

oops, I'm sorry that indeed wasn't you! that was someone else on imagesc (sorry, got mixed up in all the various posts I was searching). Ok great, then it sounds like I shouldn't do anything special on the ome_types side to make sure the output is ascii-encodable?