-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ngff zarr): add multi channel support #480
Conversation
Instead of |
Works on oeway's astronaut now. Some fishy stuff with the x chunk index to shift down x rows:
|
4a11f39
to
54457d8
Compare
Thanks for working on this! Looking forward it! FYI: I am currently making a browser file system that can handle large files backed by indexeddb. Would be nice to test using pyodide/jupyterlite + zarr-python to read in-browser large files, then pipe the data as a zarr store to itk-vtk-viewer! |
src/IO/ImageDataFromChunks.worker.js
Outdated
} | ||
|
||
const chunkSize = Object.fromEntries(info.chunkSize) | ||
const chunkStrides = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The chunk strides for each dimension will be based on the input MultiscaleSpatialImage dims
and their order: maybe a slice
here on the dims
array starting on the dim
index and a reduce
based on the chunkSize
.
ced60eb
to
0822171
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🦖 🌮 🎉
Looks awesome!
Steps for optimization noted inline that I think we should add before merging.
src/IO/ImageDataFromChunks.worker.js
Outdated
for (let cc = itStart.c; cc < itEnd.c; cc++) { | ||
for (let zz = itStart.z; zz < itEnd.z; zz++) { | ||
for (let yy = itStart.y; yy < itEnd.y; yy++) { | ||
for (let xx = itStart.x; xx < itEnd.x; xx++) { | ||
pixelArray[ | ||
cc + | ||
xx * pixelStrides.x + | ||
yy * pixelStrides.y + | ||
zz * pixelStrides.z | ||
] = | ||
chunk[ | ||
// subtract x * chunkSize.x from xx to start at beginning of chunk despite itStart.x | ||
(xx - x * chunkSize.x) * chunkStrides.x + | ||
(yy - y * chunkSize.y) * chunkStrides.y + | ||
(zz - z * chunkSize.z) * chunkStrides.z + | ||
(cc - c * chunkSize.c) * chunkStrides.c | ||
] | ||
} // column | ||
} // row | ||
} // slice | ||
} // component | ||
} // chunk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimizations to add to this critical piece:
[ ] 1. Three versions of the loop based on the dim order. a) tczyx, b) tzyxc c) other. a) for most OME-NGFF, b for the interleaved channel c) in the wild, e.g. it is also common to have tzcyz. c) can be like it is now. a) and b) will further be optimized in the following steps.
[ ] 2. For the conditions where we can use them in the inner-most loop, use .subarray
and .set
for getting and setting the contiguous region.
[ ] 3. Cache the offsets in the intermediate loops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added caching of offsets. Do we have any example images of non tczyx
dim ordering we would like to support? I have not tested any...
Also, webpack dev server dishes out test/data/input
Looking good. Can we base and add tests for the new datasets? |
Added tests for a selection of the working images. Some issues:
|
152d4fe
to
761e8b7
Compare
For the first two, we should fix the data generator. Could you please create issues on the multi-scale-spatial-image repository, and assign it to me? For the endianness issue, we should transform an chunk array from big to little before loading into the itk.Image. Could you please look for a JS library to do that and apply when required? |
Chrome --no-sandbox Thread --dockered flag through Karma to toggle some tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good.
['f8', 'getFloat64'], | ||
]) | ||
|
||
export const ElementGetter = (dtype, buffer) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For efficiency, let's have this operate over the chunk TypedArray instead of the element
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where to do this optimization? Current in worker flow: Dataview(chunkBuffer).getX(index, endiness) -> IJKTypedArray.
b10d70c
to
0e2b82d
Compare
Implemented the above with guidance from the old code. Good speedup with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turbo-tacular!~ 🚀 👨🎤
Please take a look at a comment inline, follow-up as needed, and merge this puppy. 🥺
src/IO/ZarrMultiscaleSpatialImage.js
Outdated
dataset, | ||
}) => { | ||
const dims = | ||
pixelArrayAttrs?._ARRAY_DIMENSIONS ?? // xarray |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just change the order here -- first try / trust axes
, then _ARRAY_DIMENSIONS
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems that many NGFFs don't have a foo.zarr/s0/.zattrs where _ARRAY_DIMENSIONS
lives. To avoid 404s the code is not fetching the scale level .zattrs
, so no _ARRAY_DIMENSIONS
to fall back to.
🎉 This PR is included in version 12.3.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Hi @oeway CI was given some ❤️ , v12.3.0 is now out with these improvements, please give it a whirl! |
Somehow these hacks work for all the datasets I've loaded except for the 2 lowest resolution scales in oeway's astronaut where the chunks span components.