Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ismrmrd/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
IMTYPE_REAL = 3
IMTYPE_IMAG = 4
IMTYPE_COMPLEX = 5
IMTYPE_RGB = 6

# Image flags
IMAGE_IS_NAVIGATION_DATA = 1
Expand Down
16 changes: 15 additions & 1 deletion ismrmrd/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,21 @@ def has_acquisitions(self):
class File(Folder):

def __init__(self, filename, mode='a'):
self.__file = h5py.File(filename, mode,driver='stdio')
"""Open an ISMRMRD File.

Parameters
----------
filename : str
Path to the HDF5 file.
mode : str, optional
h5py file-open mode. Defaults to ``'a'`` (read/write, create if
needed). Pass ``'r'`` for read-only access without touching the
file's modification time. Valid values are the same as for
:func:`h5py.File`: ``'r'``, ``'r+'``, ``'w'``, ``'w-'``/``'x'``,
and ``'a'``. See
https://docs.h5py.org/en/stable/high/file.html for details.
"""
self.__file = h5py.File(filename, mode, driver='stdio')
super().__init__(self.__file)

def __enter__(self):
Expand Down
32 changes: 27 additions & 5 deletions ismrmrd/hdf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,34 @@ def fileinfo(fname):


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):
"""Open an ISMRMRD Dataset backed by an HDF5 file.

Parameters
----------
filename : str
Path to the HDF5 file.
dataset_name : str, optional
Name of the dataset group inside the file.
create_if_needed : bool, optional
When True (default) the file is opened in append mode ('a'),
creating it if it does not exist. When False the file must
already exist and is opened in read/write mode ('r+').
mode : str, optional
Explicit h5py file-open mode. When provided, overrides the
behaviour implied by *create_if_needed*. Valid values are the
same as for :func:`h5py.File`: ``'r'``, ``'r+'``, ``'w'``,
``'w-'``/``'x'``, and ``'a'``. See
https://docs.h5py.org/en/stable/high/file.html for details.
"""
# 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)

self._dataset_name = dataset_name

Expand Down
6 changes: 6 additions & 0 deletions ismrmrd/waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ def from_array(data, **kwargs):

channels, nsamples = data.shape

uint16_max = np.iinfo(np.uint16).max
if nsamples > uint16_max:
raise ValueError(f"Array has {nsamples} samples, which is greater than the maximum of {uint16_max}")
if channels > uint16_max:
raise ValueError(f"Array has {channels} channels, which is greater than the maximum of {uint16_max}")

array_data = {
'version': 1,
'channels': channels,
Expand Down
16 changes: 16 additions & 0 deletions tests/test_hdf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,19 @@ def test_read_and_write_waveforms_to_hdf5():

def test_waveform_hdf5_size():
assert ismrmrd.hdf5.waveform_header_dtype.itemsize == 40


def test_dataset_read_only_mode():
filename = os.path.join(temp_dir, 'read_only.h5')

dataset = ismrmrd.Dataset(filename)
dataset.append_acquisition(create_random_acquisition())
dataset.close()

ro_dataset = ismrmrd.Dataset(filename, create_if_needed=False, mode='r')
assert ro_dataset.number_of_acquisitions() == 1
ro_dataset.close()

with pytest.raises(Exception):
ro_dataset2 = ismrmrd.Dataset(filename, create_if_needed=False, mode='r')
ro_dataset2.append_acquisition(create_random_acquisition())
14 changes: 14 additions & 0 deletions tests/test_waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ def test_initialization_with_illegal_header_value():
ismrmrd.Waveform.from_array(common.create_random_waveform_data(), version='Bad version')


def test_from_array_raises_on_too_many_samples():
uint16_max = np.iinfo(np.uint16).max
data = np.zeros((1, uint16_max + 1), dtype=np.uint32)
with pytest.raises(ValueError):
ismrmrd.Waveform.from_array(data)


def test_from_array_raises_on_too_many_channels():
uint16_max = np.iinfo(np.uint16).max
data = np.zeros((uint16_max + 1, 1), dtype=np.uint32)
with pytest.raises(ValueError):
ismrmrd.Waveform.from_array(data)


def test_serialize_and_deserialize():
waveform = common.create_random_waveform()

Expand Down
Loading