From c50794939b11cbbc484c55fec54409e8474361d8 Mon Sep 17 00:00:00 2001 From: "Alexandre M. S" Date: Sat, 23 Nov 2013 23:46:17 +0100 Subject: [PATCH 1/2] WIP: Save SpatialImages into HDF5 files. First commit: functions to save a Nifti1Image into a HDF5 file group and retrieve it back. --- nibabel/hdfloadsave.py | 102 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 nibabel/hdfloadsave.py diff --git a/nibabel/hdfloadsave.py b/nibabel/hdfloadsave.py new file mode 100644 index 0000000000..10b29db7aa --- /dev/null +++ b/nibabel/hdfloadsave.py @@ -0,0 +1,102 @@ +# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- +# vi: set ft=python sts=4 ts=4 sw=4 et: +### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## +# +# See COPYING file distributed along with the NiBabel package for the +# copyright and license terms. +# +### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## + +import numpy as np +import h5py + +from .nifti1 import Nifti1Image, Nifti1Header + +#from .spm2analyze import Spm2AnalyzeImage +#from .nifti1 import Nifti1Image, Nifti1Pair, Nifti1Header, header_dtype as ni1_hdr_dtype +#from .nifti2 import Nifti2Image, Nifti2Pair +#from .minc1 import Minc1Image +#from .minc2 import Minc2Image +#from .freesurfer import MGHImage + +def nifti1img_to_hdf(fname, spatial_img, h5path='/img', append=True): + """ + Saves a Nifti1Image into an HDF5 file. + + fname: string + Output HDF5 file path + + spatial_img: nibabel SpatialImage + Image to be saved + + h5path: string + HDF5 group path where the image data will be saved. + Datasets will be created inside the given group path: + 'data', 'extra', 'affine', the header information will + be set as attributes of the 'data' dataset. + + append: bool + True if you don't want to erase the content of the file + if it already exists, False otherwise. + """ + mode = 'w' + if append: + mode = 'r+' + + f = h5py.File(fname, mode) + + h5img = f.create_group(h5path) + h5img['data'] = spatial_img.get_data() + h5img['extra'] = spatial_img.get_extra() + h5img['affine'] = spatial_img.get_affine() + + hdr = spatial_img.get_header() + for k in hdr.keys(): + h5img['data'].attrs[k] = hdr[k] + + f.close() + + +def hdfgroup_to_nifti1image(fname, h5path): + """ + Returns a nibabel Nifti1Image from an HDF5 group datasets + + @param fname: string + HDF5 file path + + @param h5path: + HDF5 group path in fname + + @return: nibabel Nifti1Image + """ + f = h5py.File(fname, 'r') + + h5img = f[h5path] + data = h5img['data'].value + extra = h5img['extra'].value + affine = h5img['affine'].value + + header = get_nifti1hdr_from_h5attrs(h5img['data'].attrs) + + f.close() + + img = Nifti1Image(data, affine, header=header, extra=extra) + + return img + + +def get_nifti1hdr_from_h5attrs(h5attrs): + """ + Transforms an H5py Attributes set to a dict. + Converts unicode string keys into standard strings + and each value into a numpy array. + + @param h5attrs: H5py Attributes + + @return: dict + """ + hdr = Nifti1Header() + for k in h5attrs.keys(): + hdr[str(k)] = np.array(h5attrs[k]) + + return hdr \ No newline at end of file From c99264943e8468f9d13abdb8c24664a2d9e3df95 Mon Sep 17 00:00:00 2001 From: "Alexandre M. S" Date: Thu, 28 Nov 2013 09:42:04 +0100 Subject: [PATCH 2/2] WIP: Save SpatialImages into HDF5 files. Using a "with" statement to open the hdf files. To access the dataset values ".values" is old, changed to [()]. --- nibabel/hdfloadsave.py | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/nibabel/hdfloadsave.py b/nibabel/hdfloadsave.py index 10b29db7aa..8bf3c9dc29 100644 --- a/nibabel/hdfloadsave.py +++ b/nibabel/hdfloadsave.py @@ -38,23 +38,28 @@ def nifti1img_to_hdf(fname, spatial_img, h5path='/img', append=True): append: bool True if you don't want to erase the content of the file if it already exists, False otherwise. + + @note: + HDF5 open modes + >>> 'r' Readonly, file must exist + >>> 'r+' Read/write, file must exist + >>> 'w' Create file, truncate if exists + >>> 'w-' Create file, fail if exists + >>> 'a' Read/write if exists, create otherwise (default) """ mode = 'w' if append: - mode = 'r+' - - f = h5py.File(fname, mode) - - h5img = f.create_group(h5path) - h5img['data'] = spatial_img.get_data() - h5img['extra'] = spatial_img.get_extra() - h5img['affine'] = spatial_img.get_affine() + mode = 'a' - hdr = spatial_img.get_header() - for k in hdr.keys(): - h5img['data'].attrs[k] = hdr[k] + with h5py.File(fname, mode) as f: + h5img = f.create_group(h5path) + h5img['data'] = spatial_img.get_data() + h5img['extra'] = spatial_img.get_extra() + h5img['affine'] = spatial_img.get_affine() - f.close() + hdr = spatial_img.get_header() + for k in hdr.keys(): + h5img['data'].attrs[k] = hdr[k] def hdfgroup_to_nifti1image(fname, h5path): @@ -69,16 +74,13 @@ def hdfgroup_to_nifti1image(fname, h5path): @return: nibabel Nifti1Image """ - f = h5py.File(fname, 'r') - - h5img = f[h5path] - data = h5img['data'].value - extra = h5img['extra'].value - affine = h5img['affine'].value - - header = get_nifti1hdr_from_h5attrs(h5img['data'].attrs) + with h5py.File(fname, 'r') as f: + h5img = f[h5path] + data = h5img['data'][()] + extra = h5img['extra'][()] + affine = h5img['affine'][()] - f.close() + header = get_nifti1hdr_from_h5attrs(h5img['data'].attrs) img = Nifti1Image(data, affine, header=header, extra=extra)