Skip to content

OIR: resolve pixel block paths through the Location mapping - #4470

Open
PEEKPerformer wants to merge 1 commit into
ome:developfrom
PEEKPerformer:oir-mapped-location-fix
Open

PEEKPerformer wants to merge 1 commit into
ome:developfrom
PEEKPerformer:oir-mapped-location-fix

Conversation

@PEEKPerformer

Copy link
Copy Markdown
Contributor

Opening an .oir file through a mapped location, for example as an entry in a zip file opened by the existing ZipReader, initializes fine and reports correct metadata, but every pixel read then fails with FileNotFoundException. initFile labels each pixel block with current.getAbsolutePath(), which resolves a mapped ID against the working directory and produces a path that does not exist. The metadata pass succeeds because its stream is opened from currentId, which resolves through the Location mapping; copyPixelBlock later reopens block.file directly and misses the mapping.

The fix keeps the mapped ID as the pixel block label when currentId is mapped, so pixel blocks reopen through the same mapping. For unmapped files the label is exactly the same string as before.

To reproduce with any .oir file, no special data needed:

zip sample.zip sample.oir
bfconvert sample.zip out.ome.tiff

Tested with the public file Olympus-OIR/imagesc-105684/1202-interval_10sec_sequence_frame.oir from downloads.openmicroscopy.org:

  • Before: showinf -nopix sample.zip works, bfconvert sample.zip throws FileNotFoundException from OIRReader.copyPixelBlock.
  • After: the conversion completes, and the output pixels are byte-identical to converting the .oir directly (verified with numpy over both OME-TIFFs, 8 timepoints x 2 channels x 512x512 uint16).
  • Direct (unmapped) reads are unchanged: full showinf output and -omexml-only output for the same file are identical between a build without and with this change, after normalizing run-specific timestamps and UUIDs.
  • In-memory reading (Location.mapFile with a ByteArrayHandle, the ReadWriteInMemory pattern) previously failed the same way for .oir and now works; the first plane read back from memory is byte-identical to the converted output.
  • ant test passes.

One related limitation is intentionally out of scope: multi-file .oir datasets discover their companion parts via directory listing, which cannot see mapped entries, so a zip containing a multi-part acquisition would still only read the main file. Self-contained .oir files, which isSingleFile defines as anything under 1 GB, work with this change, and the zip-wrapped files that motivated it are all in that category.

Context: this came out of the zip-wrapped .poir/.mpoir discussion in #4465. A .poir reader that delegates to OIRReader through mapped locations, which is how ZipReader composes readers today, needs this fix whether the reader lives in core or externally. It is also useful on its own, since it makes zipped and in-memory .oir work with the readers that already exist.

When an .oir file is opened through a mapped location, e.g. as an
entry in a zip file opened by ZipReader, initFile labels each pixel
block with a CWD-absolutized path that does not exist on disk.
Metadata parsing succeeds because the stream is opened from currentId,
which resolves through the Location mapping, but every subsequent
openBytes call reopens block.file directly and throws
FileNotFoundException.

Keep the mapped ID as the pixel block label when currentId is mapped,
so that copyPixelBlock reopens blocks through the same mapping. For
unmapped files the label is unchanged.

To reproduce with any .oir file:

    zip sample.zip sample.oir
    bfconvert sample.zip out.ome.tiff

Before this change the conversion fails with FileNotFoundException;
after it, output pixels are identical to converting the .oir directly.
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

Successfully merging this pull request may close these issues.

1 participant