[ismrmrd] 160/177: merge from pyismrmrd:
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:02:14 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag v1.1.0.beta.1
in repository ismrmrd.
commit 412c90147e22550b52d406cf1719f0ec6cad7fef
Author: Ghislain Antony Vaillant <ghisvail at gmail.com>
Date: Fri Oct 24 15:07:46 2014 +0100
merge from pyismrmrd:
* add NDArray class
* add transparent dtype management
* add link with c-error management
---
bindings/python/cismrmrd.pxd | 13 +++
bindings/python/ismrmrd.pyx | 206 ++++++++++++++++++++++++++++++++++++++-----
2 files changed, 199 insertions(+), 20 deletions(-)
diff --git a/bindings/python/cismrmrd.pxd b/bindings/python/cismrmrd.pxd
index ec82fa8..2925aea 100644
--- a/bindings/python/cismrmrd.pxd
+++ b/bindings/python/cismrmrd.pxd
@@ -11,6 +11,19 @@ cdef extern from "ismrmrd/ismrmrd.h":
ISMRMRD_POSITION_LENGTH = 3
ISMRMRD_DIRECTION_LENGTH = 3
+ ctypedef enum ISMRMRD_ErrorCodes:
+ ISMRMRD_BEGINERROR
+ ISMRMRD_NOERROR
+ ISMRMRD_MEMORYERROR
+ ISMRMRD_FILEERROR
+ ISMRMRD_TYPEERROR
+ ISMRMRD_RUNTIMEERROR
+ ISMRMRD_HDF5ERROR
+ ISMRMRD_ENDERROR
+
+ cdef bint ismrmrd_pop_error(char**, int*, char**, int*, char**)
+ char* ismrmrd_strerror(int)
+
ctypedef struct ISMRMRD_EncodingCounters:
uint16_t kspace_encode_step_1 # e.g. phase encoding line number
uint16_t kspace_encode_step_2 # e.g. partition encodning number
diff --git a/bindings/python/ismrmrd.pyx b/bindings/python/ismrmrd.pyx
index fae6e6f..0b484bc 100644
--- a/bindings/python/ismrmrd.pyx
+++ b/bindings/python/ismrmrd.pyx
@@ -8,17 +8,39 @@ cimport numpy
numpy.import_array()
# conversion table between ISMRMRD and Numpy dtypes
-cdef dict ismrmrd_to_numpy_dtypes_dict = {
+cdef dict ismrmrd_to_numpy_typenums_dict = {
cismrmrd.ISMRMRD_USHORT: numpy.NPY_UINT16,
cismrmrd.ISMRMRD_SHORT: numpy.NPY_INT16,
cismrmrd.ISMRMRD_UINT: numpy.NPY_UINT32,
cismrmrd.ISMRMRD_INT: numpy.NPY_INT32,
- cismrmrd.ISMRMRD_FLOAT: numpy.NPY_FLOAT64,
- cismrmrd.ISMRMRD_DOUBLE: numpy.NPY_FLOAT128,
+ cismrmrd.ISMRMRD_FLOAT: numpy.NPY_FLOAT32,
+ cismrmrd.ISMRMRD_DOUBLE: numpy.NPY_FLOAT64,
cismrmrd.ISMRMRD_CXFLOAT: numpy.NPY_COMPLEX64,
cismrmrd.ISMRMRD_CXDOUBLE: numpy.NPY_COMPLEX128,
}
+cdef dict numpy_dtype_to_ismrmrd_typenum = {
+ numpy.uint16: cismrmrd.ISMRMRD_USHORT,
+ numpy.int16: cismrmrd.ISMRMRD_SHORT,
+ numpy.uint32: cismrmrd.ISMRMRD_UINT,
+ numpy.int32: cismrmrd.ISMRMRD_INT,
+ numpy.float32: cismrmrd.ISMRMRD_FLOAT,
+ numpy.float64: cismrmrd.ISMRMRD_DOUBLE,
+ numpy.complex64: cismrmrd.ISMRMRD_CXFLOAT,
+ numpy.complex128: cismrmrd.ISMRMRD_CXDOUBLE,
+}
+
+cdef dict ismrmrd_typenum_to_numpy_dtype = {
+ cismrmrd.ISMRMRD_USHORT: numpy.uint16,
+ cismrmrd.ISMRMRD_SHORT: numpy.int16,
+ cismrmrd.ISMRMRD_UINT: numpy.uint32,
+ cismrmrd.ISMRMRD_INT: numpy.int32,
+ cismrmrd.ISMRMRD_FLOAT: numpy.float32,
+ cismrmrd.ISMRMRD_DOUBLE: numpy.float64,
+ cismrmrd.ISMRMRD_CXFLOAT: numpy.complex64,
+ cismrmrd.ISMRMRD_CXDOUBLE: numpy.complex128,
+}
+
# expose acquisition flags to Python namespace
# TODO: encapsulate that to a class and let set_flag / clear_flag be the
# only interface
@@ -61,6 +83,23 @@ ACQ_USER7 = cismrmrd.ISMRMRD_ACQ_USER7
ACQ_USER8 = cismrmrd.ISMRMRD_ACQ_USER8
+cdef bytes build_exception_string():
+ cdef char *pfile = NULL
+ cdef char *pfunc = NULL
+ cdef char *pmsg = NULL
+ cdef int line=0, code=0
+ cdef bytes err_string
+ if(cismrmrd.ismrmrd_pop_error(&pfile, &line, &pfunc, &code, &pmsg)):
+ err_string = "ISMRMRD {0} in {1} ({2}:{3})".format(
+ <bytes> cismrmrd.ismrmrd_strerror(code),
+ <bytes> pfunc,
+ <bytes> pfile,
+ line,
+ <bytes> pmsg,
+ )
+ return err_string
+
+
cdef class EncodingCounters:
cdef cismrmrd.ISMRMRD_EncodingCounters *thisptr
@@ -135,6 +174,9 @@ cdef class AcquisitionHeader:
def __cinit__(self):
self.thisptr = <cismrmrd.ISMRMRD_AcquisitionHeader*>calloc(1, sizeof(cismrmrd.ISMRMRD_AcquisitionHeader))
+ errno = cismrmrd.ismrmrd_init_acquisition_header(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
def __dealloc__(self):
free(self.thisptr)
@@ -293,17 +335,23 @@ cdef class Acquisition:
def __cinit__(self, AcquisitionHeader head=None):
self.thisptr = <cismrmrd.ISMRMRD_Acquisition*>calloc(1, sizeof(cismrmrd.ISMRMRD_Acquisition))
- cismrmrd.ismrmrd_init_acquisition(self.thisptr)
+ errno = cismrmrd.ismrmrd_init_acquisition(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
if head is not None:
self.head = head
def __dealloc__(self):
- cismrmrd.ismrmrd_cleanup_acquisition(self.thisptr)
+ errno = cismrmrd.ismrmrd_cleanup_acquisition(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
free(self.thisptr)
def __copy__(self):
cdef Acquisition acopy = Acquisition()
- cismrmrd.ismrmrd_copy_acquisition(acopy.thisptr, self.thisptr)
+ errno = cismrmrd.ismrmrd_copy_acquisition(acopy.thisptr, self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
return acopy
property head:
@@ -313,7 +361,9 @@ cdef class Acquisition:
return head
def __set__(self, AcquisitionHeader head):
head.copy_to(&self.thisptr.head)
- cismrmrd.ismrmrd_make_consistent_acquisition(self.thisptr)
+ errno = cismrmrd.ismrmrd_make_consistent_acquisition(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
property data:
def __get__(self):
@@ -323,6 +373,8 @@ cdef class Acquisition:
# careful here, thisptr is a R-W view
return numpy.PyArray_SimpleNewFromData(2, shape_data,
numpy.NPY_COMPLEX64, <void *>(self.thisptr.data))
+ def __set__(self, val):
+ self.data.ravel()[:] = numpy.asarray(val).ravel()[:]
property traj:
def __get__(self):
@@ -334,6 +386,8 @@ cdef class Acquisition:
# which is arguably better than returning a NoneType.
return numpy.PyArray_SimpleNewFromData(2, shape_traj,
numpy.NPY_FLOAT32, <void *>(self.thisptr.traj))
+ def __set__(self, val):
+ self.data.ravel()[:] = numpy.asarray(val).ravel()[:]
cdef class ImageHeader:
@@ -342,6 +396,9 @@ cdef class ImageHeader:
def __cinit__(self):
self.thisptr = <cismrmrd.ISMRMRD_ImageHeader*>calloc(1, sizeof(cismrmrd.ISMRMRD_ImageHeader))
+ errno = cismrmrd.ismrmrd_init_image_header(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
def __dealloc__(self):
free(self.thisptr)
@@ -502,17 +559,23 @@ cdef class Image:
def __cinit__(self, ImageHeader head=None):
self.thisptr = <cismrmrd.ISMRMRD_Image*>calloc(1, sizeof(cismrmrd.ISMRMRD_Image))
- cismrmrd.ismrmrd_init_image(self.thisptr)
+ errno = cismrmrd.ismrmrd_init_image(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
if head is not None:
self.head = head
def __dealloc__(self):
- cismrmrd.ismrmrd_cleanup_image(self.thisptr)
+ errno = cismrmrd.ismrmrd_cleanup_image(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
free(self.thisptr)
def __copy__(self):
cdef Image acopy = Image()
- cismrmrd.ismrmrd_copy_image(acopy.thisptr, self.thisptr)
+ errno = cismrmrd.ismrmrd_copy_image(acopy.thisptr, self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
return acopy
property head:
@@ -522,7 +585,9 @@ cdef class Image:
return head
def __set__(self, ImageHeader head):
head.copy_to(&self.thisptr.head)
- cismrmrd.ismrmrd_make_consistent_image(self.thisptr)
+ errno = cismrmrd.ismrmrd_make_consistent_image(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
property attribute_string:
def __get__(self): return self.thisptr.attribute_string
@@ -532,9 +597,79 @@ cdef class Image:
cdef numpy.npy_intp shape_data[3]
for idim in range(3):
shape_data[idim] = self.head.matrix_size[idim]
- cdef int typenum = ismrmrd_to_numpy_dtypes_dict[self.head.data_type]
+ cdef int typenum = ismrmrd_to_numpy_typenums_dict[self.head.data_type]
return numpy.PyArray_SimpleNewFromData(3, shape_data,
typenum, <void *>(self.thisptr.data))
+ def __set__(self, val):
+ self.data.ravel()[:] = numpy.asarray(val).ravel()[:]
+
+
+cdef class NDArray:
+
+ cdef cismrmrd.ISMRMRD_NDArray *thisptr
+
+ def __cinit__(self, shape=None, dtype=None):
+ self.thisptr = <cismrmrd.ISMRMRD_NDArray*>calloc(1, sizeof(cismrmrd.ISMRMRD_NDArray))
+ errno = cismrmrd.ismrmrd_init_ndarray(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
+ # default dtype is numpy.dtype(None), normally float64
+ self.dtype = dtype
+ # shape remain optional
+ if shape is not None:
+ self.shape = shape
+
+ def __dealloc__(self):
+ errno = cismrmrd.ismrmrd_cleanup_ndarray(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
+ free(self.thisptr)
+
+ def __copy__(self):
+ cdef NDArray acopy = NDArray()
+ errno = cismrmrd.ismrmrd_copy_ndarray(acopy.thisptr, self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
+ return acopy
+
+ property version:
+ def __get__(self): return self.thisptr.version
+
+ property dtype:
+ def __get__(self):
+ return numpy.dtype(ismrmrd_typenum_to_numpy_dtype[self.thisptr.data_type])
+ def __set__(self, val):
+ numpy_dtype = numpy.dtype(val)
+ self.thisptr.data_type = numpy_dtype_to_ismrmrd_typenum[numpy_dtype.type]
+ errno = cismrmrd.ismrmrd_make_consistent_ndarray(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
+
+ property ndim:
+ def __get__(self): return self.thisptr.ndim
+ def __set__(self, val): self.thisptr.ndim = val
+
+ property shape:
+ def __get__(self):
+ return [self.thisptr.dims[i] for i in range(self.ndim)]
+ def __set__(self, val):
+ self.ndim = len(val)
+ for idim in range(self.ndim):
+ self.thisptr.dims[idim] = val[idim]
+ errno = cismrmrd.ismrmrd_make_consistent_ndarray(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
+
+ property data:
+ def __get__(self):
+ cdef numpy.npy_intp shape_data[cismrmrd.ISMRMRD_NDARRAY_MAXDIM]
+ for idim in range(self.ndim):
+ shape_data[idim] = self.shape[idim]
+ cdef int typenum = ismrmrd_to_numpy_typenums_dict[self.thisptr.data_type]
+ return numpy.PyArray_SimpleNewFromData(self.ndim, shape_data,
+ typenum, <void *>(self.thisptr.data))
+ def __set__(self, val):
+ self.data.ravel()[:] = numpy.asarray(val).ravel()[:]
cdef class Dataset:
@@ -544,7 +679,9 @@ cdef class Dataset:
def __cinit__(self, const char *filename, const char *groupname):
self.thisptr = <cismrmrd.ISMRMRD_Dataset*>calloc(1, sizeof(cismrmrd.ISMRMRD_Dataset))
- cismrmrd.ismrmrd_init_dataset(self.thisptr, filename, groupname)
+ errno = cismrmrd.ismrmrd_init_dataset(self.thisptr, filename, groupname)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
self.is_open = False
def __dealloc__(self):
@@ -553,12 +690,16 @@ cdef class Dataset:
def open(self, create_if_needed=True):
if not self.is_open:
- cismrmrd.ismrmrd_open_dataset(self.thisptr, create_if_needed)
+ errno = cismrmrd.ismrmrd_open_dataset(self.thisptr, create_if_needed)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
self.is_open = True
def close(self):
if self.is_open:
- cismrmrd.ismrmrd_close_dataset(self.thisptr)
+ errno = cismrmrd.ismrmrd_close_dataset(self.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
self.is_open = False
property filename:
@@ -571,17 +712,23 @@ cdef class Dataset:
def __get__(self): return self.thisptr.fileid
def write_header(self, xmlstring):
- cismrmrd.ismrmrd_write_header(self.thisptr, xmlstring)
+ errno = cismrmrd.ismrmrd_write_header(self.thisptr, xmlstring)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
def read_header(self):
return cismrmrd.ismrmrd_read_header(self.thisptr)
def append_acquisition(self, Acquisition acq):
- return cismrmrd.ismrmrd_append_acquisition(self.thisptr, acq.thisptr)
+ errno = cismrmrd.ismrmrd_append_acquisition(self.thisptr, acq.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
def read_acquisition(self, index):
cdef Acquisition acq = Acquisition()
- cismrmrd.ismrmrd_read_acquisition(self.thisptr, index, acq.thisptr)
+ errno = cismrmrd.ismrmrd_read_acquisition(self.thisptr, index, acq.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
return acq
@property
@@ -589,12 +736,31 @@ cdef class Dataset:
return cismrmrd.ismrmrd_get_number_of_acquisitions(self.thisptr)
def append_image(self, varname, Image img):
- return cismrmrd.ismrmrd_append_image(self.thisptr, varname, img.thisptr)
+ errno = cismrmrd.ismrmrd_append_image(self.thisptr, varname, img.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
def read_image(self, varname, index):
cdef Image img = Image()
- cismrmrd.ismrmrd_read_image(self.thisptr, varname, index, img.thisptr)
+ errno = cismrmrd.ismrmrd_read_image(self.thisptr, varname, index, img.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
return img
def number_of_images(self, varname):
return cismrmrd.ismrmrd_get_number_of_images(self.thisptr, varname)
+
+ def append_array(self, varname, NDArray arr):
+ errno = cismrmrd.ismrmrd_append_array(self.thisptr, varname, arr.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string().decode('UTF-8'))
+
+ def read_array(self, varname, index):
+ cdef NDArray arr = NDArray()
+ errno = cismrmrd.ismrmrd_read_array(self.thisptr, varname, index, arr.thisptr)
+ if errno != cismrmrd.ISMRMRD_NOERROR:
+ raise RuntimeError(build_exception_string())
+ return arr
+
+ def number_of_arrays(self, varname):
+ return cismrmrd.ismrmrd_get_number_of_arrays(self.thisptr, varname)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ismrmrd.git
More information about the debian-science-commits
mailing list