[Scipy-svn] r2200 - trunk/Lib/io

scipy-svn at scipy.org scipy-svn at scipy.org
Mon Sep 18 02:34:49 CDT 2006


Author: stefan
Date: 2006-09-18 02:34:13 -0500 (Mon, 18 Sep 2006)
New Revision: 2200

Modified:
   trunk/Lib/io/bytestream.py
   trunk/Lib/io/mio4.py
   trunk/Lib/io/mio5.py
   trunk/Lib/io/miobase.py
Log:
Code cleanup, minor bugfixes in mio (by Matthew Brett).


Modified: trunk/Lib/io/bytestream.py
===================================================================
--- trunk/Lib/io/bytestream.py	2006-09-15 20:24:08 UTC (rev 2199)
+++ trunk/Lib/io/bytestream.py	2006-09-18 07:34:13 UTC (rev 2200)
@@ -57,7 +57,7 @@
         if num_bytes < 0:
             num_bytes = self.array_len
         if self.pos >= self.array_len:
-            return []
+            return array([], dtype=uint8)
         next_pos = min(self.pos + num_bytes, self.array_len)
         res = self.bytes[self.pos:next_pos]
         self.pos = next_pos

Modified: trunk/Lib/io/mio4.py
===================================================================
--- trunk/Lib/io/mio4.py	2006-09-15 20:24:08 UTC (rev 2199)
+++ trunk/Lib/io/mio4.py	2006-09-18 07:34:13 UTC (rev 2200)
@@ -53,9 +53,31 @@
     }
 
 class Mat4Header(object):
-    ''' Place holder for Mat4 header '''
-    pass
+    ''' Place holder for Mat4 header
 
+        Defines:
+        next_position - start position of next matrix
+        name
+        dims - shape of matrix as stored (see sparse reader)
+        dtype - numpy dtype of matrix
+        mclass - matlab code for class of matrix
+        is_char    - True if these are char data
+        is_numeric - True if these are numeric data
+        is_complex - True if data are complex
+        original_dtype - data type in matlab workspace
+    '''
+    def __init__(self):
+        self.next_position = None
+        self.name = ''
+        self.dims = ()
+        self.dtype = None
+        self.mclass = None
+        self.is_char = None
+        self.is_numeric = None
+        self.is_complex = None
+        self.original_dtype = None
+        
+
 class Mat4ArrayReader(MatArrayReader):
     ''' Class for reading Mat4 arrays
     '''
@@ -70,15 +92,6 @@
         
     def read_header(self):
         ''' Read and return Mat4 matrix header
-
-        Defines:
-        next_position - start position of next matrix
-        name
-        dtype - numpy dtype of matrix
-        mclass - matlab code for class of matrix
-        dims - shape of matrix as stored (see sparse reader)
-        is_complex - True if data are complex
-        is_char    - True if these are char data
         '''
         header = Mat4Header()
         data = self.read_array(self.dtypes['header'])
@@ -93,9 +106,6 @@
             raise ValueError, 'O in MOPT integer should be 0, wrong format?'
         header.dtype = self.dtypes[P]
         header.mclass = T
-        header.is_char = None
-        header.is_numeric = None
-        header.original_dtype = None
         header.dims = (data['mrows'], data['ncols'])
         header.is_complex = data['imagf'] == 1
         remaining_bytes = header.dtype.itemsize * product(header.dims)
@@ -124,6 +134,7 @@
 class Mat4FullGetter(Mat4MatrixGetter):
     def get_raw_array(self):
         self.header.is_numeric = True
+        self.header.original_dtype = dtype(float64)
         if self.header.is_complex:
             # avoid array copy to save memory
             res = self.read_hdr_array(copy=False)
@@ -160,6 +171,7 @@
     value is again 0
     '''
     def get_raw_array(self):
+        self.header.original_dtype = dtype(float64)
         res = self.read_hdr_array()
         tmp = res[:-1,:]
         dims = res[-1,0:2]

Modified: trunk/Lib/io/mio5.py
===================================================================
--- trunk/Lib/io/mio5.py	2006-09-15 20:24:08 UTC (rev 2199)
+++ trunk/Lib/io/mio5.py	2006-09-18 07:34:13 UTC (rev 2200)
@@ -139,15 +139,40 @@
     pass
 
 class Mat5Header(object):
-    ''' Placeholder for Mat5 header '''
-    pass
+    ''' Placeholder for Mat5 header
 
+    Defines:
+    next_position - start position of next matrix
+    name
+    dtype - numpy dtype of matrix
+    mclass - matlab code for class of matrix
+    dims - shape of matrix as stored (see sparse reader)
+    is_complex - True if data are complex
+    is_char    - True if these are char data
+    is_global  - is a global variable in matlab workspace
+    is_numeric - is basic numeric matrix
+    original_dtype - data type when saved from matlab
+    '''
+    def __init__(self):
+        self.next_position = None
+        self.is_empty = False
+        self.flags = None
+        self.is_complex = False
+        self.is_global = False
+        self.is_logical = False
+        self.mclass = 0
+        self.is_numeric = None
+        self.original_dtype = None
+        self.is_char = None
+        self.dims = ()
+        self.name = ''
+
 class Mat5ArrayFlags(object):
     ''' Place holder for array flags '''
     pass
 
 
-class Mat5Arrayreader(MatArrayReader):
+class Mat5ArrayReader(MatArrayReader):
     ''' Class to get Mat5 arrays
 
     Provides element reader functions, header reader, matrix reader
@@ -155,7 +180,7 @@
     '''
 
     def __init__(self, mat_stream, dtypes, processor_func, codecs, class_dtypes):
-        super(Mat5Arrayreader, self).__init__(mat_stream,
+        super(Mat5ArrayReader, self).__init__(mat_stream,
                                               dtypes,
                                               processor_func,
                                               )
@@ -173,10 +198,10 @@
             tag.byte_count = byte_count
             tag.mdtype = tag.mdtype & 0xFFFF
             tag.skip = 4 - byte_count
-            return tag
-        tag.byte_count = self.read_array(
-            self.dtypes['tag_byte_count'])
-        tag.skip = tag.byte_count % 8 and 8 - tag.byte_count % 8
+        else: # standard tag format
+            tag.byte_count = self.read_array(
+                self.dtypes['tag_byte_count'])
+            tag.skip = tag.byte_count % 8 and 8 - tag.byte_count % 8
         return tag
     
     def read_element(self, copy=True):
@@ -203,34 +228,26 @@
 
     def read_header(self, tag):
         ''' Read header from Mat5 matrix
-        
-        Defines:
-        next_position - start position of next matrix
-        name
-        dtype - numpy dtype of matrix
-        mclass - matlab code for class of matrix
-        dims - shape of matrix as stored (see sparse reader)
-        is_complex - True if data are complex
-        is_char    - True if these are char data
-        is_global  - is a global variable in matlab workspace
-        is_numeric - is basic numeric matrix
-        original_dtype - data type when saved from matlab
         '''
         if not tag.mdtype == miMATRIX:
             raise TypeError, \
                   'Expecting miMATRIX type here, got %d' %  tag.mdtype
         header = Mat5Header()
+        # Note - there is no skip value for the miMATRIX type; the
+        # number of bytes field in the tag points to the next variable
+        # in the file. This is always aligned to 8 byte boundaries
+        # (except for the miCOMPRESSED type)
         header.next_position = (self.mat_stream.pos +
-                                tag.byte_count +
-                                tag.skip)
+                                tag.byte_count)
+        # Apparently an empty miMATRIX can contain no bytes
+        header.is_empty = tag.byte_count == 0
+        if header.is_empty:
+            return header
         header.flags = self.read_array_flags()
         header.is_complex = header.flags.is_complex
         header.is_global = header.flags.is_global
         header.is_logical = header.flags.is_logical
         header.mclass = header.flags.mclass
-        header.is_numeric = None
-        header.original_dtype = None
-        header.is_char = None
         header.dims = self.read_element()
         header.name = self.read_element().tostring()
         return header
@@ -250,11 +267,13 @@
         ''' Returns reader for next matrix '''
         tag = self.read_tag()
         if tag.mdtype == miCOMPRESSED:
-            return Mat5ZArrayreader(self, tag).matrix_getter_factory()
+            return Mat5ZArrayReader(self, tag).matrix_getter_factory()
         header = self.read_header(tag)
         return self.header_to_getter(header)
     
     def header_to_getter(self, header):
+        if header.is_empty:
+            return Mat5EmptyMatrixGetter(self, header)
         mc = header.mclass
         if mc in mx_numbers:
             return Mat5NumericMatrixGetter(self, header)
@@ -271,7 +290,7 @@
         raise TypeError, 'No reader for class code %s' % mc
 
 
-class Mat5ZArrayreader(Mat5Arrayreader):
+class Mat5ZArrayReader(Mat5ArrayReader):
     ''' Getter for compressed arrays
 
     Reads and uncompresses gzipped stream on init, providing wrapper
@@ -282,9 +301,7 @@
     def __init__(self, array_reader, tag):
         '''Reads and uncompresses gzipped stream'''
         data = array_reader.read_bytes(tag.byte_count)
-        if tag.skip:
-            array_reader.mat_stream.seek(tag.skip, 1)
-        super(Mat5ZArrayreader, self).__init__(
+        super(Mat5ZArrayReader, self).__init__(
             ByteStream(zlib.decompress(data.tostring())),
             array_reader.dtypes,
             array_reader.processor_func,
@@ -295,7 +312,7 @@
     def header_to_getter(self, header):
         ''' Set next_position to current position in parent stream '''
         header.next_position = self.next_position
-        return super(Mat5ZArrayreader, self).header_to_getter(header)
+        return super(Mat5ZArrayReader, self).header_to_getter(header)
         
 
 class Mat5MatrixGetter(MatMatrixGetter):
@@ -316,8 +333,14 @@
     
     def read_element(self, *args, **kwargs):
         return self.array_reader.read_element(*args, **kwargs)
+    
 
+class Mat5EmptyMatrixGetter(Mat5MatrixGetter):
+    ''' Dummy class to return empty array for empty matrix '''
+    def get_raw_array(self):
+        return array([[]])
 
+
 class Mat5NumericMatrixGetter(Mat5MatrixGetter):
     def get_raw_array(self):
         self.header.is_numeric = True
@@ -455,7 +478,7 @@
                  uint16_codec=None
                  ):
         self.codecs = {}
-        self._array_reader = Mat5Arrayreader(
+        self._array_reader = Mat5ArrayReader(
             mat_stream,
             None,
             None,

Modified: trunk/Lib/io/miobase.py
===================================================================
--- trunk/Lib/io/miobase.py	2006-09-15 20:24:08 UTC (rev 2199)
+++ trunk/Lib/io/miobase.py	2006-09-18 07:34:13 UTC (rev 2200)
@@ -76,6 +76,8 @@
         a_dtype is assumed to be correct endianness
         '''
         num_bytes = a_dtype.itemsize * product(a_shape)
+        if not num_bytes:
+            return array([], dtype=a_dtype)
         data = self.read_bytes(num_bytes)
         arr = ndarray(shape=a_shape,
                       dtype=a_dtype,



More information about the Scipy-svn mailing list