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
53 stars 15 forks source link

bug: Lim_FileGetAttributes failing in certain linux environments #118

Closed tlambert03 closed 1 year ago

tlambert03 commented 1 year ago

Originally posted by @manthey in https://github.com/tlambert03/nd2/issues/114#issuecomment-1343355668

Description

I try to open the nd2 file downloaded from here: https://downloads.openmicroscopy.org/images/ND2/aryeh/b16_pdtB+y50__crop.nd2 It fails with TypeError: <lambda>() missing 6 required positional arguments: 'bitsPerComponentInMemory', 'bitsPerComponentSignificant', 'componentCount', 'heightPx', 'pixelDataType', and 'sequenceCount'.

As one more interesting clue to failing to read some nd2 files in some environments and not others: When I use stock Ubuntu python 3.8 or python 3.9 installed from the deadsnakes ppa, I get the failure to read attributes. If I use pyenv to compile python 3.9 locally, that reads the nd2 file successfully. The only difference I have noticed is that using LD_TRACE_LOADED_OBJECTS=1 shows that the system/deadsnakes pythons both pull in libexpat, whereas the pyenv python does not.

manthey commented 1 year ago

Here is a way to reproduce this with docker:

This Dockerfile works:

FROM python:3.9-slim

COPY b16_pdtB+y50__crop.nd2 .

RUN python3 -m pip install virtualenv
RUN python3 -m virtualenv /venv
RUN /venv/bin/pip install nd2

RUN /venv/bin/python -c 'import nd2;print(nd2.ND2File("b16_pdtB+y50__crop.nd2").sizes)'

The output is:

<string>:1: UserWarning: ND2File file not closed before garbage collection. Please use `with ND2File(...):` context or call `.close()`.
{'T': 57, 'P': 12, 'Y': 1200, 'X': 1600}

This Dockerfile fails:

FROM ubuntu:20.04

RUN apt-get update && apt-get install -y python3-pip

COPY b16_pdtB+y50__crop.nd2 .

RUN python3 -m pip install virtualenv
RUN python3 -m virtualenv /venv
RUN /venv/bin/pip install nd2

RUN /venv/bin/python -c 'import nd2;print(nd2.ND2File("b16_pdtB+y50__crop.nd2").sizes)'

The output is:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/venv/lib/python3.8/site-packages/nd2/nd2file.py", line 98, in __init__
    self._rdr = get_reader(
  File "/venv/lib/python3.8/site-packages/nd2/_util.py", line 68, in get_reader
    return ND2Reader(
  File "src/nd2/_sdk/latest.pyx", line 48, in nd2._sdk.latest.ND2Reader.__cinit__
  File "src/nd2/_sdk/latest.pyx", line 79, in nd2._sdk.latest.ND2Reader.open
  File "src/nd2/_sdk/latest.pyx", line 115, in nd2._sdk.latest.ND2Reader.attributes.__get__
TypeError: __new__() missing 6 required positional arguments: 'bitsPerComponentInMemory', 'bitsPerComponentSignificant', 'componentCount', 'heightPx', 'pixelDataType', and 'sequenceCount'
tlambert03 commented 1 year ago

Thanks so much! I do think you're onto something with expat by the way. I sent a question to the group that makes the sdk. It might be a legitimate compilation oversight in the distributed sdk.

This docker file is very handy, thanks again for your time

tlambert03 commented 1 year ago

with #135, we now no longer depend on any C code (libexpat is irrelevant now). So I'm going to optimistically close this

manthey commented 1 year ago

Excellent.