[ismrmrd] 159/177: merge single diff of pyismrmrd as of commit time

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 4c0f3fb1e9e621501391cb0da730386e133d080e
Author: Ghislain Antony Vaillant <ghisvail at gmail.com>
Date:   Thu Oct 23 18:40:04 2014 +0100

    merge single diff of pyismrmrd as of commit time
---
 bindings/python/cismrmrd.pxd |  63 +++++++--
 bindings/python/ismrmrd.pyx  | 306 +++++++++++++++++++++++++++++++++++--------
 bindings/python/setup.py     |   4 +-
 3 files changed, 306 insertions(+), 67 deletions(-)

diff --git a/bindings/python/cismrmrd.pxd b/bindings/python/cismrmrd.pxd
index 063ccb5..ec82fa8 100644
--- a/bindings/python/cismrmrd.pxd
+++ b/bindings/python/cismrmrd.pxd
@@ -23,6 +23,45 @@ cdef extern from "ismrmrd/ismrmrd.h":
         uint16_t segment               # e.g. segment number for segmented acquisition
         uint16_t user[ISMRMRD_USER_INTS]   # Free user parameters
 
+    cdef enum ISMRMRD_AcquisitionFlags:
+        ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP1
+        ISMRMRD_ACQ_LAST_IN_ENCODE_STEP1
+        ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP2
+        ISMRMRD_ACQ_LAST_IN_ENCODE_STEP2
+        ISMRMRD_ACQ_FIRST_IN_AVERAGE
+        ISMRMRD_ACQ_LAST_IN_AVERAGE
+        ISMRMRD_ACQ_FIRST_IN_SLICE
+        ISMRMRD_ACQ_LAST_IN_SLICE
+        ISMRMRD_ACQ_FIRST_IN_CONTRAST
+        ISMRMRD_ACQ_LAST_IN_CONTRAST
+        ISMRMRD_ACQ_FIRST_IN_PHASE
+        ISMRMRD_ACQ_LAST_IN_PHASE
+        ISMRMRD_ACQ_FIRST_IN_REPETITION
+        ISMRMRD_ACQ_LAST_IN_REPETITION
+        ISMRMRD_ACQ_FIRST_IN_SET
+        ISMRMRD_ACQ_LAST_IN_SET
+        ISMRMRD_ACQ_FIRST_IN_SEGMENT
+        ISMRMRD_ACQ_LAST_IN_SEGMENT
+        ISMRMRD_ACQ_IS_NOISE_MEASUREMENT
+        ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION
+        ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING
+        ISMRMRD_ACQ_IS_REVERSE
+        ISMRMRD_ACQ_IS_NAVIGATION_DATA
+        ISMRMRD_ACQ_IS_PHASECORR_DATA
+        ISMRMRD_ACQ_LAST_IN_MEASUREMENT
+        ISMRMRD_ACQ_IS_HPFEEDBACK_DATA
+        ISMRMRD_ACQ_IS_DUMMYSCAN_DATA
+        ISMRMRD_ACQ_IS_RTFEEDBACK_DATA
+        ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA
+        ISMRMRD_ACQ_USER1
+        ISMRMRD_ACQ_USER2
+        ISMRMRD_ACQ_USER3
+        ISMRMRD_ACQ_USER4
+        ISMRMRD_ACQ_USER5
+        ISMRMRD_ACQ_USER6
+        ISMRMRD_ACQ_USER7
+        ISMRMRD_ACQ_USER8
+
     ctypedef struct ISMRMRD_AcquisitionHeader:
         uint16_t version   # First unsigned int indicates the version
         uint64_t flags     # bit field with flags
@@ -96,6 +135,7 @@ cdef extern from "ismrmrd/ismrmrd.h":
 
     ctypedef struct ISMRMRD_ImageHeader:
         uint16_t version    # First unsigned int indicates the version
+        uint16_t data_type  # e.g. unsigned short, float, complex float, etc.
         uint64_t flags      # bit field with flags
         uint32_t measurement_uid    # Unique ID for the measurement
         uint16_t matrix_size[3]     # Pixels in the 3 spatial dimensions
@@ -114,7 +154,6 @@ cdef extern from "ismrmrd/ismrmrd.h":
         uint16_t set        # e.g. flow encodning set
         uint32_t acquisition_time_stamp # Acquisition clock
         uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS] # Physiology time stamps, e.g. ecg, breating, etc.
-        uint16_t image_data_type    # e.g. unsigned short, float, complex float, etc.
         uint16_t image_type     # e.g. magnitude, phase, complex, real, imag, etc.
         uint16_t image_index    # e.g. image number in series of images
         uint16_t image_series_index             # e.g. series number
@@ -181,15 +220,19 @@ cdef extern from "ismrmrd/dataset.h":
     cdef char *ismrmrd_read_header(const ISMRMRD_Dataset *)
     cdef int ismrmrd_write_header(ISMRMRD_Dataset *, const char *)
     cdef uint32_t ismrmrd_get_number_of_acquisitions(const ISMRMRD_Dataset*)
-    cdef int ismrmrd_append_acquisition(ISMRMRD_Dataset *, const ISMRMRD_Acquisition *)
-    cdef int ismrmrd_read_acquisition(const ISMRMRD_Dataset *, uint32_t , ISMRMRD_Acquisition *)
-    cdef uint32_t ismrmrd_get_number_of_images(const ISMRMRD_Dataset *, const char *)
+    cdef int ismrmrd_append_acquisition(ISMRMRD_Dataset *,
+            const ISMRMRD_Acquisition *)
+    cdef int ismrmrd_read_acquisition(const ISMRMRD_Dataset *, uint32_t,
+            ISMRMRD_Acquisition *)
+    cdef uint32_t ismrmrd_get_number_of_images(const ISMRMRD_Dataset *,
+            const char *)
     cdef int ismrmrd_append_image(ISMRMRD_Dataset *, const char *,
-                         const int, const ISMRMRD_Image *)
+            const ISMRMRD_Image *)
     cdef int ismrmrd_read_image(const ISMRMRD_Dataset *, const char *,
-                       const uint32_t, ISMRMRD_Image *)
-    cdef uint32_t ismrmrd_get_number_of_arrays(const ISMRMRD_Dataset *, const char *)
-    cdef int ismrmrd_append_array(ISMRMRD_Dataset *dset, const char *varname,
-                            const int block_mode, const ISMRMRD_NDArray *)
+            const uint32_t, ISMRMRD_Image *)
+    cdef uint32_t ismrmrd_get_number_of_arrays(const ISMRMRD_Dataset *,
+            const char *)
+    cdef int ismrmrd_append_array(ISMRMRD_Dataset *dset, const char *,
+            const ISMRMRD_NDArray *)
     cdef int ismrmrd_read_array(const ISMRMRD_Dataset *, const char *,
-                        const uint32_t, ISMRMRD_NDArray *)
+            const uint32_t, ISMRMRD_NDArray *)
diff --git a/bindings/python/ismrmrd.pyx b/bindings/python/ismrmrd.pyx
index 0d60efe..fae6e6f 100644
--- a/bindings/python/ismrmrd.pyx
+++ b/bindings/python/ismrmrd.pyx
@@ -2,26 +2,85 @@ cimport cismrmrd
 from libc.stdlib cimport calloc, free
 from libc.string cimport memcpy
 
-#### Helper functions
+# required for PyArray* functions and dtypes
+import numpy
+cimport numpy
+numpy.import_array()
+
+# conversion table between ISMRMRD and Numpy dtypes
+cdef dict ismrmrd_to_numpy_dtypes_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_CXFLOAT:   numpy.NPY_COMPLEX64,
+    cismrmrd.ISMRMRD_CXDOUBLE:  numpy.NPY_COMPLEX128,
+}
+
+# expose acquisition flags to Python namespace
+# TODO: encapsulate that to a class and let set_flag / clear_flag be the 
+# only interface
+ACQ_FIRST_IN_ENCODE_STEP1 = cismrmrd.ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP1
+ACQ_LAST_IN_ENCODE_STEP1 = cismrmrd.ISMRMRD_ACQ_LAST_IN_ENCODE_STEP1
+ACQ_FIRST_IN_ENCODE_STEP2 = cismrmrd.ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP2
+ACQ_LAST_IN_ENCODE_STEP2 = cismrmrd.ISMRMRD_ACQ_LAST_IN_ENCODE_STEP2
+ACQ_FIRST_IN_AVERAGE = cismrmrd.ISMRMRD_ACQ_FIRST_IN_AVERAGE
+ACQ_LAST_IN_AVERAGE = cismrmrd.ISMRMRD_ACQ_LAST_IN_AVERAGE
+ACQ_FIRST_IN_SLICE = cismrmrd.ISMRMRD_ACQ_FIRST_IN_SLICE
+ACQ_LAST_IN_SLICE = cismrmrd.ISMRMRD_ACQ_LAST_IN_SLICE
+ACQ_FIRST_IN_CONTRAST = cismrmrd.ISMRMRD_ACQ_FIRST_IN_CONTRAST
+ACQ_LAST_IN_CONTRAST = cismrmrd.ISMRMRD_ACQ_LAST_IN_CONTRAST
+ACQ_FIRST_IN_PHASE = cismrmrd.ISMRMRD_ACQ_FIRST_IN_PHASE
+ACQ_LAST_IN_PHASE = cismrmrd.ISMRMRD_ACQ_LAST_IN_PHASE
+ACQ_FIRST_IN_REPETITION = cismrmrd.ISMRMRD_ACQ_FIRST_IN_REPETITION
+ACQ_LAST_IN_REPETITION = cismrmrd.ISMRMRD_ACQ_LAST_IN_REPETITION
+ACQ_FIRST_IN_SET = cismrmrd.ISMRMRD_ACQ_FIRST_IN_SET
+ACQ_LAST_IN_SET = cismrmrd.ISMRMRD_ACQ_LAST_IN_SET
+ACQ_FIRST_IN_SEGMENT = cismrmrd.ISMRMRD_ACQ_FIRST_IN_SEGMENT
+ACQ_LAST_IN_SEGMENT = cismrmrd.ISMRMRD_ACQ_LAST_IN_SEGMENT
+ACQ_IS_NOISE_MEASUREMENT = cismrmrd.ISMRMRD_ACQ_IS_NOISE_MEASUREMENT
+ACQ_IS_PARALLEL_CALIBRATION = cismrmrd.ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION
+ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING = cismrmrd.ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING
+ACQ_IS_REVERSE = cismrmrd.ISMRMRD_ACQ_IS_REVERSE
+ACQ_IS_NAVIGATION_DATA = cismrmrd.ISMRMRD_ACQ_IS_NAVIGATION_DATA
+ACQ_IS_PHASECORR_DATA = cismrmrd.ISMRMRD_ACQ_IS_PHASECORR_DATA
+ACQ_LAST_IN_MEASUREMENT = cismrmrd.ISMRMRD_ACQ_LAST_IN_MEASUREMENT
+ACQ_IS_HPFEEDBACK_DATA = cismrmrd.ISMRMRD_ACQ_IS_HPFEEDBACK_DATA
+ACQ_IS_DUMMYSCAN_DATA = cismrmrd.ISMRMRD_ACQ_IS_DUMMYSCAN_DATA
+ACQ_IS_RTFEEDBACK_DATA = cismrmrd.ISMRMRD_ACQ_IS_RTFEEDBACK_DATA
+ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA = cismrmrd.ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA
+ACQ_USER1 = cismrmrd.ISMRMRD_ACQ_USER1
+ACQ_USER2 = cismrmrd.ISMRMRD_ACQ_USER2
+ACQ_USER3 = cismrmrd.ISMRMRD_ACQ_USER3
+ACQ_USER4 = cismrmrd.ISMRMRD_ACQ_USER4
+ACQ_USER5 = cismrmrd.ISMRMRD_ACQ_USER5
+ACQ_USER6 = cismrmrd.ISMRMRD_ACQ_USER6
+ACQ_USER7 = cismrmrd.ISMRMRD_ACQ_USER7
+ACQ_USER8 = cismrmrd.ISMRMRD_ACQ_USER8
 
-cdef AcquisitionHeader_from_struct(cismrmrd.ISMRMRD_AcquisitionHeader *other):
-    head = AcquisitionHeader()
-    memcpy(head.this, other, sizeof(cismrmrd.ISMRMRD_AcquisitionHeader))
-    return head
 
-cdef ImageHeader_from_struct(cismrmrd.ISMRMRD_ImageHeader *other):
-    head = ImageHeader()
-    memcpy(head.this, other, sizeof(cismrmrd.ISMRMRD_ImageHeader))
-    return head
+cdef class EncodingCounters:
 
-####
+    cdef cismrmrd.ISMRMRD_EncodingCounters *thisptr
+
+    def __cinit__(self, other = None):
+        self.thisptr = <cismrmrd.ISMRMRD_EncodingCounters*>calloc(1, sizeof(cismrmrd.ISMRMRD_EncodingCounters))
 
-cdef class EncodingCounters:
-    cdef cismrmrd.ISMRMRD_EncodingCounters *this
-    def __cinit__(self):
-        self.this = <cismrmrd.ISMRMRD_EncodingCounters*>calloc(1, sizeof(cismrmrd.ISMRMRD_EncodingCounters))
     def __dealloc__(self):
-        free(self.this)
+        free(self.thisptr)
+
+    def __copy__(self):
+        cdef EncodingCounters acopy = EncodingCounters()
+        acopy.copy_from(self.thisptr)
+        return acopy
+
+    cdef copy_from(self, cismrmrd.ISMRMRD_EncodingCounters *ptr):
+        memcpy(self.thisptr, ptr, sizeof(cismrmrd.ISMRMRD_EncodingCounters))
+
+    cdef copy_to(self, cismrmrd.ISMRMRD_EncodingCounters *ptr):
+        memcpy(ptr, self.thisptr, sizeof(cismrmrd.ISMRMRD_EncodingCounters))
 
     property kspace_encode_step_1:
         def __get__(self): return self.thisptr.kspace_encode_step_1
@@ -69,16 +128,31 @@ cdef class EncodingCounters:
             for i in range(cismrmrd.ISMRMRD_USER_INTS):
                 self.thisptr.user[i] = vals[i]
 
+
 cdef class AcquisitionHeader:
-    cdef cismrmrd.ISMRMRD_AcquisitionHeader *this
+
+    cdef cismrmrd.ISMRMRD_AcquisitionHeader *thisptr
+
     def __cinit__(self):
-        self.this = <cismrmrd.ISMRMRD_AcquisitionHeader*>calloc(1, sizeof(cismrmrd.ISMRMRD_AcquisitionHeader))
+        self.thisptr = <cismrmrd.ISMRMRD_AcquisitionHeader*>calloc(1, sizeof(cismrmrd.ISMRMRD_AcquisitionHeader))
+
     def __dealloc__(self):
-        free(self.this)
+        free(self.thisptr)
+
+    def __copy__(self):
+        cdef AcquisitionHeader acopy = AcquisitionHeader()
+        acopy.copy_from(self.thisptr)
+        return acopy
+
+    cdef copy_from(self, cismrmrd.ISMRMRD_AcquisitionHeader *ptr):
+        memcpy(self.thisptr, ptr, sizeof(cismrmrd.ISMRMRD_AcquisitionHeader))
+
+    cdef copy_to(self, cismrmrd.ISMRMRD_AcquisitionHeader *ptr):
+        memcpy(ptr, self.thisptr, sizeof(cismrmrd.ISMRMRD_AcquisitionHeader))
 
     property version:
-        def __get__(self): return self.this.version
-        def __set__(self, val): self.this.version = val
+        def __get__(self): return self.thisptr.version
+        def __set__(self, val): self.thisptr.version = val
 
     property flags:
         def __get__(self): return self.thisptr.flags
@@ -189,8 +263,12 @@ cdef class AcquisitionHeader:
                 self.thisptr.patient_table_position[i] = val[i]
 
     property idx:
-        def __get__(self): return self.idx
-        def __set__(self, val): pass    # FIXME (does nothing)
+        def __get__(self):
+            cdef EncodingCounters idx = EncodingCounters()
+            idx.copy_from(&self.thisptr.idx)
+            return idx
+        def __set__(self, EncodingCounters val):
+            val.copy_to(&self.thisptr.idx)
 
     property user_int:
         def __get__(self):
@@ -208,31 +286,85 @@ cdef class AcquisitionHeader:
             for i in range(cismrmrd.ISMRMRD_USER_FLOATS):
                 self.thisptr.user_float[i] = val[i]
 
+
 cdef class Acquisition:
-    cdef cismrmrd.ISMRMRD_Acquisition *this
-    def __cinit__(self):
-        self.this = <cismrmrd.ISMRMRD_Acquisition*>cismrmrd.ismrmrd_create_acquisition()
+
+    cdef cismrmrd.ISMRMRD_Acquisition *thisptr
+
+    def __cinit__(self, AcquisitionHeader head=None):
+        self.thisptr = <cismrmrd.ISMRMRD_Acquisition*>calloc(1, sizeof(cismrmrd.ISMRMRD_Acquisition))
+        cismrmrd.ismrmrd_init_acquisition(self.thisptr)
+        if head is not None:
+            self.head = head 
+
     def __dealloc__(self):
-        cismrmrd.ismrmrd_free_acquisition(self.this)
+        cismrmrd.ismrmrd_cleanup_acquisition(self.thisptr)
+        free(self.thisptr)
+
+    def __copy__(self):
+        cdef Acquisition acopy = Acquisition()
+        cismrmrd.ismrmrd_copy_acquisition(acopy.thisptr, self.thisptr)
+        return acopy
 
     property head:
-        def __get__(self): return AcquisitionHeader_from_struct(&self.this.head)
+        def __get__(self):
+            cdef AcquisitionHeader head = AcquisitionHeader()
+            head.copy_from(&self.thisptr.head)
+            return head
+        def __set__(self, AcquisitionHeader head):
+            head.copy_to(&self.thisptr.head)
+            cismrmrd.ismrmrd_make_consistent_acquisition(self.thisptr)
+
     property data:
         def __get__(self):
-            size = cismrmrd.ismrmrd_size_of_acquisition_data(self.this)
-            return None     # FIXME: return NumPy array or Cython Typed MemoryView
+            cdef numpy.npy_intp shape_data[2]
+            shape_data[0] = self.head.active_channels
+            shape_data[1] = self.head.number_of_samples
+            # careful here, thisptr is a R-W view
+            return numpy.PyArray_SimpleNewFromData(2, shape_data,
+                    numpy.NPY_COMPLEX64, <void *>(self.thisptr.data))
+
+    property traj:
+        def __get__(self):
+            cdef numpy.npy_intp shape_traj[2]
+            shape_traj[0] = self.head.number_of_samples
+            shape_traj[1] = self.head.trajectory_dimensions
+            # careful here, thisptr is a R-W view
+            # if traj ptr is empty, then will return an empty array
+            # which is arguably better than returning a NoneType.
+            return numpy.PyArray_SimpleNewFromData(2, shape_traj,
+                    numpy.NPY_FLOAT32, <void *>(self.thisptr.traj))
+
 
 cdef class ImageHeader:
-    cdef cismrmrd.ISMRMRD_ImageHeader *this
+
+    cdef cismrmrd.ISMRMRD_ImageHeader *thisptr
+
     def __cinit__(self):
-        self.this = <cismrmrd.ISMRMRD_ImageHeader*>calloc(1, sizeof(cismrmrd.ISMRMRD_ImageHeader))
+        self.thisptr = <cismrmrd.ISMRMRD_ImageHeader*>calloc(1, sizeof(cismrmrd.ISMRMRD_ImageHeader))
+
     def __dealloc__(self):
-        free(self.this)
+        free(self.thisptr)
+
+    def __copy__(self):
+        cdef ImageHeader acopy = ImageHeader()
+        acopy.copy_from(self.thisptr)
+        return acopy
+
+    cdef copy_from(self, cismrmrd.ISMRMRD_ImageHeader *ptr):
+        memcpy(self.thisptr, ptr, sizeof(cismrmrd.ISMRMRD_ImageHeader))
+
+    cdef copy_to(self, cismrmrd.ISMRMRD_ImageHeader *ptr):
+        memcpy(ptr, self.thisptr, sizeof(cismrmrd.ISMRMRD_ImageHeader))
 
     property version:
         def __get__(self): return self.thisptr.version
         def __set__(self, val): self.thisptr.version = val
 
+    property data_type:
+        def __get__(self): return self.thisptr.data_type
+        def __set__(self, val): self.thisptr.data_type = val
+
     property flags:
         def __get__(self): return self.thisptr.flags
         def __set__(self, val): self.thisptr.flags = val
@@ -335,10 +467,6 @@ cdef class ImageHeader:
             for i in range(cismrmrd.ISMRMRD_PHYS_STAMPS):
                 self.thisptr.physiology_time_stamp[i] = val[i]
 
-    property image_data_type:
-        def __get__(self): return self.thisptr.image_data_type
-        def __set__(self, val): self.thisptr.image_data_type = val
-
     property image_type:
         def __get__(self): return self.thisptr.image_type
         def __set__(self, val): self.thisptr.image_type = val
@@ -367,40 +495,106 @@ cdef class ImageHeader:
             for i in range(cismrmrd.ISMRMRD_USER_FLOATS):
                 self.thisptr.user_int[i] = val[i]
 
+
 cdef class Image:
-    cdef cismrmrd.ISMRMRD_Image *this
-    def __cinit__(self):
-        self.this = <cismrmrd.ISMRMRD_Image*>cismrmrd.ismrmrd_create_image()
+
+    cdef cismrmrd.ISMRMRD_Image *thisptr
+
+    def __cinit__(self, ImageHeader head=None):
+        self.thisptr = <cismrmrd.ISMRMRD_Image*>calloc(1, sizeof(cismrmrd.ISMRMRD_Image))
+        cismrmrd.ismrmrd_init_image(self.thisptr)
+        if head is not None:
+            self.head = head
+
     def __dealloc__(self):
-        cismrmrd.ismrmrd_free_image(self.this)
+        cismrmrd.ismrmrd_cleanup_image(self.thisptr)
+        free(self.thisptr)
+
+    def __copy__(self):
+        cdef Image acopy = Image()
+        cismrmrd.ismrmrd_copy_image(acopy.thisptr, self.thisptr)
+        return acopy
 
     property head:
-        def __get__(self): return ImageHeader_from_struct(&self.this.head)
+        def __get__(self):
+            cdef ImageHeader head = ImageHeader()
+            head.copy_from(&self.thisptr.head)
+            return head
+        def __set__(self, ImageHeader head):
+            head.copy_to(&self.thisptr.head)
+            cismrmrd.ismrmrd_make_consistent_image(self.thisptr)
+        
     property attribute_string:
-        def __get__(self): return self.this.attribute_string
+        def __get__(self): return self.thisptr.attribute_string
+        
     property data:
         def __get__(self):
-            size = cismrmrd.ismrmrd_size_of_image_data(self.this)
-            return None     # FIXME: return NumPy array or Cython Typed MemoryView
+            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]
+            return numpy.PyArray_SimpleNewFromData(3, shape_data,
+                    typenum, <void *>(self.thisptr.data))
+
 
 cdef class Dataset:
-    cdef cismrmrd.ISMRMRD_Dataset *this
-    def __cinit__(self, const char *filename, const char *groupname, bint create_if_needed):
-        self.this = <cismrmrd.ISMRMRD_Dataset*>calloc(1, sizeof(cismrmrd.ISMRMRD_Dataset))
-        cismrmrd.ismrmrd_init_dataset(self.this, filename, groupname)
-        cismrmrd.ismrmrd_open_dataset(self.this, create_if_needed)
+
+    cdef cismrmrd.ISMRMRD_Dataset *thisptr
+    cdef bint is_open
+
+    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)
+        self.is_open = False
+
     def __dealloc__(self):
-        cismrmrd.ismrmrd_close_dataset(self.this)
-        free(self.this)
+        self.close()
+        free(self.thisptr)
+
+    def open(self, create_if_needed=True):
+        if not self.is_open:
+            cismrmrd.ismrmrd_open_dataset(self.thisptr, create_if_needed)
+            self.is_open = True
+        
+    def close(self):
+        if self.is_open:
+            cismrmrd.ismrmrd_close_dataset(self.thisptr)
+            self.is_open = False
 
     property filename:
-        def __get__(self): return self.this.filename
+        def __get__(self): return self.thisptr.filename
+
     property groupname:
-        def __get__(self): return self.this.filename
+        def __get__(self): return self.thisptr.filename
+
     property fileid:
-        def __get__(self): return self.this.fileid
+        def __get__(self): return self.thisptr.fileid
 
     def write_header(self, xmlstring):
-        cismrmrd.ismrmrd_write_header(self.this, xmlstring)
+        cismrmrd.ismrmrd_write_header(self.thisptr, xmlstring)
+
     def read_header(self):
-        return cismrmrd.ismrmrd_read_header(self.this)
+        return cismrmrd.ismrmrd_read_header(self.thisptr)
+
+    def append_acquisition(self, Acquisition acq):
+        return cismrmrd.ismrmrd_append_acquisition(self.thisptr, acq.thisptr)
+
+    def read_acquisition(self, index):
+        cdef Acquisition acq = Acquisition()
+        cismrmrd.ismrmrd_read_acquisition(self.thisptr, index, acq.thisptr)
+        return acq
+
+    @property
+    def number_of_acquisitions(self):
+        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)
+
+    def read_image(self, varname, index):
+        cdef Image img = Image()
+        cismrmrd.ismrmrd_read_image(self.thisptr, varname, index, img.thisptr)
+        return img
+
+    def number_of_images(self, varname):
+        return cismrmrd.ismrmrd_get_number_of_images(self.thisptr, varname)
diff --git a/bindings/python/setup.py b/bindings/python/setup.py
index 1343673..a1c20ed 100644
--- a/bindings/python/setup.py
+++ b/bindings/python/setup.py
@@ -2,13 +2,15 @@ import os
 from distutils.core import setup
 from distutils.extension import Extension
 from Cython.Distutils import build_ext
+import numpy
 
 ismrmrd_home = os.environ['ISMRMRD_HOME']
 
 ext = Extension(
     "ismrmrd",
     ["cismrmrd.pxd", "ismrmrd.pyx"],
-    include_dirs=[os.path.join(ismrmrd_home, 'include')],
+    include_dirs=[os.path.join(ismrmrd_home, 'include'),
+                  numpy.get_include()],
     library_dirs=[os.path.join(ismrmrd_home, 'lib')],
     libraries=["ismrmrd"],
     extra_link_args=[],

-- 
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