Allow read-only h5 access, define IMTYPE_RGB, explicit error on too-large Waveforms#87
Allow read-only h5 access, define IMTYPE_RGB, explicit error on too-large Waveforms#87kspaceKelvin wants to merge 6 commits into
Conversation
kspaceKelvin
commented
Jan 21, 2026
- Issue Opening and closing MRD file via File interface updates file modified time #78 is resolved by allowing file mode to be specified when opening an HDF5 file
- An enum for IMTYPE_RGB is added as described in https://ismrmrd.readthedocs.io/en/latest/mrd_image_data.html#data-types
- An explicit TypeError is raised if attempting to create a Waveform that exceeds the maximum size
As described in tefra/xsdata#1128
| IMTYPE_REAL = 3 | ||
| IMTYPE_IMAG = 4 | ||
| IMTYPE_COMPLEX = 5 | ||
| IMTYPE_RGB = 6 |
There was a problem hiding this comment.
I don't see where this is defined in the C++ implementation?
What does RGB mean for each of the possible ISMRMRD image types? i.e. How is RGB decoded from a 32-bit complex float? How many bits for each RGB channel if the image is 32-bit vs 16-bit?
There was a problem hiding this comment.
I see this in the docs now (https://ismrmrd.readthedocs.io/en/latest/mrd_image_data.html#image-types).
But I still don't understand. How long has this been documented without actually being implemented in ISMRMRD or ismrmrd-python?
|
|
||
| class Dataset(object): | ||
| def __init__(self, filename, dataset_name="dataset", create_if_needed=True): | ||
| def __init__(self, filename, dataset_name="dataset", create_if_needed=True, mode=None): |
There was a problem hiding this comment.
We should document the valid arguments for mode: https://docs.h5py.org/en/stable/high/file.html#opening-creating-files
| channels, nsamples = data.shape | ||
|
|
||
| if nsamples > np.iinfo(np.uint16).max: | ||
| raise TypeError(f"Array has {nsamples} samples, which is greater than the maximum of {np.iinfo(np.uint16).max}") |
There was a problem hiding this comment.
This is a ValueError not a TypeError.
|
I'm happy to make the suggested changes and merge this 👍 |
There was a problem hiding this comment.
Pull request overview
This PR updates the Python ISMRMRD helpers to (1) support more explicit control over how HDF5 files are opened, (2) expose the missing IMTYPE_RGB image type constant, and (3) fail fast when constructing Waveforms that exceed header representable sizes.
Changes:
- Add an optional
modeparameter toismrmrd.hdf5.Datasetto control theh5py.File(...)open mode. - Define
IMTYPE_RGB = 6inismrmrd.constants. - Add an explicit error in
Waveform.from_arraywhennumber_of_samplesexceeds theuint16maximum.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
ismrmrd/waveform.py |
Adds a size guard when building Waveforms from numpy arrays. |
ismrmrd/hdf5.py |
Extends Dataset to accept an explicit HDF5 open mode. |
ismrmrd/constants.py |
Adds the missing IMTYPE_RGB constant. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| channels, nsamples = data.shape | ||
|
|
||
| if nsamples > np.iinfo(np.uint16).max: | ||
| raise TypeError(f"Array has {nsamples} samples, which is greater than the maximum of {np.iinfo(np.uint16).max}") | ||
|
|
| if nsamples > np.iinfo(np.uint16).max: | ||
| raise TypeError(f"Array has {nsamples} samples, which is greater than the maximum of {np.iinfo(np.uint16).max}") | ||
|
|
| def __init__(self, filename, dataset_name="dataset", create_if_needed=True, mode=None): | ||
| # Open the file | ||
| if create_if_needed: | ||
| self._file = h5py.File(filename, 'a') | ||
| else: | ||
| self._file = h5py.File(filename, 'r+') | ||
| if mode is None: | ||
| if create_if_needed: | ||
| mode = 'a' | ||
| else: | ||
| mode = 'r+' | ||
|
|
||
| self._file = h5py.File(filename, mode) |
| def __init__(self, filename, dataset_name="dataset", create_if_needed=True, mode=None): | ||
| # Open the file | ||
| if create_if_needed: | ||
| self._file = h5py.File(filename, 'a') | ||
| else: | ||
| self._file = h5py.File(filename, 'r+') | ||
| if mode is None: | ||
| if create_if_needed: | ||
| mode = 'a' | ||
| else: | ||
| mode = 'r+' | ||
|
|
||
| self._file = h5py.File(filename, mode) |