-
Notifications
You must be signed in to change notification settings - Fork 534
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
Document NumPyDataLoader for reading .npy and .npz files #6733
Conversation
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.
I think this looks really handy.
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.
Thanks for the contribution 🙏
After addressing a few nitpick and adding a test, this should be good for integration.
Additional, the following documentation should be updated.
See https://github.com/Slicer/Slicer/blob/main/Docs/user_guide/data_loading_and_saving.md#images
402e429
to
9e45525
Compare
Do you know how to auto-select the just loaded file in user interface? That does not happen for .npy files, like it happens for .png and .nrrd files. |
Probably easiest to use this utility to show the images in the background: |
Slicer/Modules/Scripted/DICOMPlugins/DICOMScalarVolumePlugin.py Lines 454 to 457 in 3d62cbf
|
I started to add some more comments, but then I rather made the changes myself:
|
Thanks for the improvements @lassoan. You should have added yourself as a module contributor. In PyTorch, the usual conventions for dimensions are: NCHW for 4D tensors/arrays and NCDHW for 5D. I assume that channel-last convention was taken from ITK, or maybe VTK? How many people rely on this? As this is a new addition, we could only use PyTorch's convention in this reader, if we don't want to change this convention in the rest of Slicer. |
Yes, this is the ITK/VTK memory layout. It is easy enough to reorder axes before writing to file, so documenting the convention is probably enough (as it is already described in the updated User guide page). If it turns out to be an issue then we could add axis order as loading option (and an options widget for choosing this order in the "Add data" window). |
My principal motivation for this PR is desire to easily and conveniently visualize dumps of NCHW 4D tensors. Having an option to load them as "channel last/fastest" would be nice, but I really want PyTorch's convention to be the default. |
Even when reordering the axis for channel to be last, with the updated reader, I get an all-black image of "4 components". Visualizing something (vector norm, component average, or even just the first component) would be more useful than an all-black image. |
Also, we could employ heuristic: the dimensions with largest size could be considered to be spatial. So (10, 4, 368, 640) would be interpreted as 4D image with 4 timepoints and 3D size of 640x368x10 (ijk). Prefer timepoints over components unless size is 3, which can be easily visualized as RGB. |
Of course, all of these complications stem from .npy not having suitable metadata. |
Having we could have My only concern is that if sooner or later users will report that the loader randomly breaks. We experienced this with ITK, as ITK vector image reader has such heuristic, too. We were shocked when after being annoyed by seemingly random load failures for a long time we realized that loading fails for all data sets that have 3 or 4 time points simply because it is interpreted as channel data instead of time sequence. Not much better, but maybe a bit more predictable heuristic could be to decide based on (composite) file extension. For example, Why don't you save the result using pynrrd? You could use nrrd.write("test.nrrd", a, {'kinds': ['RGB-color', 'domain', 'domain']}) How do you load the image into Slicer? Drag-and-drop is pretty tedious and it also shows the loaded image by default (there is no way to update an existing image). You could solve both tedious drag-and-drop and setting axes by using slicerio: np.save("path/to/myfile.npy", someTensor),
nodeID = slicerio.server.file_load("path/to/myfile.npy", "NumpyArrayFile", {'axes': 'NCDHW'})
|
+1 for being more explicit either in the naming convention or in giving the user the ability to specify the load pattern. I agree that heuristics can be painful. |
Assuming the pull-request was unintentionally closed, I am re-opening it so that we further improve and reach consensus. |
Yes - sorry, wrong button! |
@lassoan It would be good if you could take over this PR, or start a new PR. Implementing |
As it could take some time for this reader to get more mature, it would make sense to put it in the Sandbox extension, where it could be updates more easily and more frequently. |
This would be consistent with the existing modules available in SlicerSandbox: ![]() Then, this PR would only update the following files:
|
I will take care of it. |
This commit NumpyDataLoader for reading .npy and .npz files The file may contain an array of dimension between 1 to 5 (axes: time, K, J, I, component). User is responsible for setting the correct IJK to RAS matrix. As suggested in forum discussion https://discourse.slicer.org/t/import-numpy-file-in-as-image-volume/3653/5 Based on: https://github.com/pieper/SlicerDMRI/blob/9565f89d16cd72618cd87f1c9046542450e4937b/Modules/Scripted/NIfTIFile/NIfTIFile.py https://github.com/Slicer/Slicer/blob/9390be6bf76e048e6fd384d8bfd607eba2857b5a/Applications/SlicerApp/Testing/Python/SlicerScriptedFileReaderWriterTest.py Co-authored-by: Andras Lasso <lasso@queensu.ca>
This pull request should be integrated after the following one have been reviewed and integrated: |
Should this PR be merged or closed? |
The reader is avaialable in the Sandbox extension (PerkLab/SlicerSandbox#19), so indeed we can close this pull request. |
As suggested in forum discussion
https://discourse.slicer.org/t/import-numpy-file-in-as-image-volume/3653/5
Based on:
https://github.com/pieper/SlicerDMRI/blob/9565f89d16cd72618cd87f1c9046542450e4937b/Modules/Scripted/NIfTIFile/NIfTIFile.py
https://github.com/Slicer/Slicer/blob/9390be6bf76e048e6fd384d8bfd607eba2857b5a/Applications/SlicerApp/Testing/Python/SlicerScriptedFileReaderWriterTest.py