[Scipy-svn] r4693 - in trunk/scipy/io/matlab: . tests

scipy-svn at scipy.org scipy-svn at scipy.org
Sun Sep 7 03:46:32 EDT 2008


Author: matthew.brett at gmail.com
Date: 2008-09-07 02:46:29 -0500 (Sun, 07 Sep 2008)
New Revision: 4693

Modified:
   trunk/scipy/io/matlab/__init__.py
   trunk/scipy/io/matlab/mio5.py
   trunk/scipy/io/matlab/tests/test_mio.py
Log:
Add modified version of Zachary Pincus patch to support small element format saving

Modified: trunk/scipy/io/matlab/__init__.py
===================================================================
--- trunk/scipy/io/matlab/__init__.py	2008-09-05 18:05:54 UTC (rev 4692)
+++ trunk/scipy/io/matlab/__init__.py	2008-09-07 07:46:29 UTC (rev 4693)
@@ -0,0 +1,5 @@
+# Matlab file read and write utilities
+from mio import loadmat, savemat
+
+from numpy.testing import Tester
+test = Tester().test

Modified: trunk/scipy/io/matlab/mio5.py
===================================================================
--- trunk/scipy/io/matlab/mio5.py	2008-09-05 18:05:54 UTC (rev 4692)
+++ trunk/scipy/io/matlab/mio5.py	2008-09-07 07:46:29 UTC (rev 4693)
@@ -87,6 +87,7 @@
                     ('version', 'u2'),
                     ('endian_test', 'S2')],
     'tag_full': [('mdtype', 'u4'), ('byte_count', 'u4')],
+    'tag_smalldata':[('byte_count_mdtype', 'u4'), ('data', 'S4')],
     'array_flags': [('data_type', 'u4'),
                     ('byte_count', 'u4'),
                     ('flags_class','u4'),
@@ -193,23 +194,28 @@
                          dtype=self.dtypes['tag_full'],
                          buffer=raw_tag)
         mdtype = tag['mdtype'].item()
-
+        # Byte count if this is small data element
         byte_count = mdtype >> 16
         if byte_count: # small data element format
             if byte_count > 4:
                 raise ValueError, 'Too many bytes for sde format'
             mdtype = mdtype & 0xFFFF
-            dt = self.dtypes[mdtype]
-            el_count = byte_count // dt.itemsize
-            return np.ndarray(shape=(el_count,),
-                              dtype=dt,
-                              buffer=raw_tag[4:])
-
-        byte_count = tag['byte_count'].item()
-        if mdtype == miMATRIX:
-            return self.current_getter(byte_count).get_array()
-        elif mdtype in self.codecs: # encoded char data
+            if mdtype == miMATRIX:
+                raise TypeError('Cannot have matrix in SDE format')
+            raw_str = raw_tag[4:byte_count+4]
+        else: # regular element
+            byte_count = tag['byte_count'].item()
+            # Deal with miMATRIX type (cannot pass byte string)
+            if mdtype == miMATRIX:
+                return self.current_getter(byte_count).get_array()
+            # All other types can be read from string
             raw_str = self.mat_stream.read(byte_count)
+            # Seek to next 64-bit boundary
+            mod8 = byte_count % 8
+            if mod8:
+                self.mat_stream.seek(8 - mod8, 1)
+            
+        if mdtype in self.codecs: # encoded char data
             codec = self.codecs[mdtype]
             if not codec:
                 raise TypeError, 'Do not support encoding %d' % mdtype
@@ -219,15 +225,10 @@
             el_count = byte_count // dt.itemsize
             el = np.ndarray(shape=(el_count,),
                             dtype=dt,
-                            buffer=self.mat_stream.read(byte_count))
+                            buffer=raw_str)
             if copy:
                 el = el.copy()
 
-        # Seek to next 64-bit boundary
-        mod8 = byte_count % 8
-        if mod8:
-            self.mat_stream.seek(8 - mod8, 1)
-
         return el
 
     def matrix_getter_factory(self):
@@ -572,18 +573,30 @@
 
     def write_element(self, arr, mdtype=None):
         # write tag, data
-        tag = np.zeros((), mdtypes_template['tag_full'])
         if mdtype is None:
-            tag['mdtype'] = np_to_mtypes[arr.dtype.str[1:]]
+            mdtype = np_to_mtypes[arr.dtype.str[1:]]
+        byte_count = arr.size*arr.itemsize
+        if byte_count <= 4:
+            self.write_smalldata_element(arr, mdtype, byte_count)
         else:
-            tag['mdtype'] = mdtype
+            self.write_regular_element(arr, mdtype, byte_count)
 
-        tag['byte_count'] = arr.size*arr.itemsize
+    def write_smalldata_element(self, arr, mdtype, byte_count):
+        # write tag with embedded data
+        tag = np.zeros((), mdtypes_template['tag_smalldata'])
+        tag['byte_count_mdtype'] = (byte_count << 16) + mdtype
+        # if arr.tostring is < 4, the element will be zero-padded as needed.
+        tag['data'] = arr.tostring(order='F')
+        self.write_dtype(tag)
+
+    def write_regular_element(self, arr, mdtype, byte_count):
+        # write tag, data
+        tag = np.zeros((), mdtypes_template['tag_full'])
+        tag['mdtype'] = mdtype
+        tag['byte_count'] = byte_count
         padding = (8 - tag['byte_count']) % 8
-
         self.write_dtype(tag)
         self.write_bytes(arr)
-
         # pad to next 64-bit boundary
         self.write_bytes(np.zeros((padding,),'u1'))
 
@@ -595,7 +608,7 @@
         ''' Write header for given data options
         mclass      - mat5 matrix class
         is_global   - True if matrix is global
-        is_complex  - True is matrix is complex
+        is_complex  - True if matrix is complex
         is_logical  - True if matrix is logical
         nzmax        - max non zero elements for sparse arrays
         '''

Modified: trunk/scipy/io/matlab/tests/test_mio.py
===================================================================
--- trunk/scipy/io/matlab/tests/test_mio.py	2008-09-05 18:05:54 UTC (rev 4692)
+++ trunk/scipy/io/matlab/tests/test_mio.py	2008-09-07 07:46:29 UTC (rev 4693)
@@ -267,3 +267,5 @@
 
     assert_array_almost_equal(actual['x'].todense(),
                               expected['x'].todense())
+
+    




More information about the Scipy-svn mailing list