123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- ''' Constants and classes for matlab 5 read and write
- See also mio5_utils.pyx where these same constants arise as c enums.
- If you make changes in this file, don't forget to change mio5_utils.pyx
- '''
- import numpy as np
- from ._miobase import convert_dtypes
- __all__ = [
- 'MDTYPES', 'MatlabFunction', 'MatlabObject', 'MatlabOpaque',
- 'NP_TO_MTYPES', 'NP_TO_MXTYPES', 'OPAQUE_DTYPE', 'codecs_template',
- 'mat_struct', 'mclass_dtypes_template', 'mclass_info', 'mdtypes_template',
- 'miCOMPRESSED', 'miDOUBLE', 'miINT16', 'miINT32', 'miINT64', 'miINT8',
- 'miMATRIX', 'miSINGLE', 'miUINT16', 'miUINT32', 'miUINT64', 'miUINT8',
- 'miUTF16', 'miUTF32', 'miUTF8', 'mxCELL_CLASS', 'mxCHAR_CLASS',
- 'mxDOUBLE_CLASS', 'mxFUNCTION_CLASS', 'mxINT16_CLASS', 'mxINT32_CLASS',
- 'mxINT64_CLASS', 'mxINT8_CLASS', 'mxOBJECT_CLASS',
- 'mxOBJECT_CLASS_FROM_MATRIX_H', 'mxOPAQUE_CLASS', 'mxSINGLE_CLASS',
- 'mxSPARSE_CLASS', 'mxSTRUCT_CLASS', 'mxUINT16_CLASS', 'mxUINT32_CLASS',
- 'mxUINT64_CLASS', 'mxUINT8_CLASS'
- ]
- miINT8 = 1
- miUINT8 = 2
- miINT16 = 3
- miUINT16 = 4
- miINT32 = 5
- miUINT32 = 6
- miSINGLE = 7
- miDOUBLE = 9
- miINT64 = 12
- miUINT64 = 13
- miMATRIX = 14
- miCOMPRESSED = 15
- miUTF8 = 16
- miUTF16 = 17
- miUTF32 = 18
- mxCELL_CLASS = 1
- mxSTRUCT_CLASS = 2
- # The March 2008 edition of "Matlab 7 MAT-File Format" says that
- # mxOBJECT_CLASS = 3, whereas matrix.h says that mxLOGICAL = 3.
- # Matlab 2008a appears to save logicals as type 9, so we assume that
- # the document is correct. See type 18, below.
- mxOBJECT_CLASS = 3
- mxCHAR_CLASS = 4
- mxSPARSE_CLASS = 5
- mxDOUBLE_CLASS = 6
- mxSINGLE_CLASS = 7
- mxINT8_CLASS = 8
- mxUINT8_CLASS = 9
- mxINT16_CLASS = 10
- mxUINT16_CLASS = 11
- mxINT32_CLASS = 12
- mxUINT32_CLASS = 13
- # The following are not in the March 2008 edition of "Matlab 7
- # MAT-File Format," but were guessed from matrix.h.
- mxINT64_CLASS = 14
- mxUINT64_CLASS = 15
- mxFUNCTION_CLASS = 16
- # Not doing anything with these at the moment.
- mxOPAQUE_CLASS = 17 # This appears to be a function workspace
- # Thread 'saving/loading symbol table of annymous functions', octave-maintainers, April-May 2007
- # https://lists.gnu.org/archive/html/octave-maintainers/2007-04/msg00031.html
- # https://lists.gnu.org/archive/html/octave-maintainers/2007-05/msg00032.html
- # (Was/Deprecated: https://www-old.cae.wisc.edu/pipermail/octave-maintainers/2007-May/002824.html)
- mxOBJECT_CLASS_FROM_MATRIX_H = 18
- mdtypes_template = {
- miINT8: 'i1',
- miUINT8: 'u1',
- miINT16: 'i2',
- miUINT16: 'u2',
- miINT32: 'i4',
- miUINT32: 'u4',
- miSINGLE: 'f4',
- miDOUBLE: 'f8',
- miINT64: 'i8',
- miUINT64: 'u8',
- miUTF8: 'u1',
- miUTF16: 'u2',
- miUTF32: 'u4',
- 'file_header': [('description', 'S116'),
- ('subsystem_offset', 'i8'),
- ('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'),
- ('nzmax', 'u4')],
- 'U1': 'U1',
- }
- mclass_dtypes_template = {
- mxINT8_CLASS: 'i1',
- mxUINT8_CLASS: 'u1',
- mxINT16_CLASS: 'i2',
- mxUINT16_CLASS: 'u2',
- mxINT32_CLASS: 'i4',
- mxUINT32_CLASS: 'u4',
- mxINT64_CLASS: 'i8',
- mxUINT64_CLASS: 'u8',
- mxSINGLE_CLASS: 'f4',
- mxDOUBLE_CLASS: 'f8',
- }
- mclass_info = {
- mxINT8_CLASS: 'int8',
- mxUINT8_CLASS: 'uint8',
- mxINT16_CLASS: 'int16',
- mxUINT16_CLASS: 'uint16',
- mxINT32_CLASS: 'int32',
- mxUINT32_CLASS: 'uint32',
- mxINT64_CLASS: 'int64',
- mxUINT64_CLASS: 'uint64',
- mxSINGLE_CLASS: 'single',
- mxDOUBLE_CLASS: 'double',
- mxCELL_CLASS: 'cell',
- mxSTRUCT_CLASS: 'struct',
- mxOBJECT_CLASS: 'object',
- mxCHAR_CLASS: 'char',
- mxSPARSE_CLASS: 'sparse',
- mxFUNCTION_CLASS: 'function',
- mxOPAQUE_CLASS: 'opaque',
- }
- NP_TO_MTYPES = {
- 'f8': miDOUBLE,
- 'c32': miDOUBLE,
- 'c24': miDOUBLE,
- 'c16': miDOUBLE,
- 'f4': miSINGLE,
- 'c8': miSINGLE,
- 'i8': miINT64,
- 'i4': miINT32,
- 'i2': miINT16,
- 'i1': miINT8,
- 'u8': miUINT64,
- 'u4': miUINT32,
- 'u2': miUINT16,
- 'u1': miUINT8,
- 'S1': miUINT8,
- 'U1': miUTF16,
- 'b1': miUINT8, # not standard but seems MATLAB uses this (gh-4022)
- }
- NP_TO_MXTYPES = {
- 'f8': mxDOUBLE_CLASS,
- 'c32': mxDOUBLE_CLASS,
- 'c24': mxDOUBLE_CLASS,
- 'c16': mxDOUBLE_CLASS,
- 'f4': mxSINGLE_CLASS,
- 'c8': mxSINGLE_CLASS,
- 'i8': mxINT64_CLASS,
- 'i4': mxINT32_CLASS,
- 'i2': mxINT16_CLASS,
- 'i1': mxINT8_CLASS,
- 'u8': mxUINT64_CLASS,
- 'u4': mxUINT32_CLASS,
- 'u2': mxUINT16_CLASS,
- 'u1': mxUINT8_CLASS,
- 'S1': mxUINT8_CLASS,
- 'b1': mxUINT8_CLASS, # not standard but seems MATLAB uses this
- }
- ''' Before release v7.1 (release 14) matlab (TM) used the system
- default character encoding scheme padded out to 16-bits. Release 14
- and later use Unicode. When saving character data, R14 checks if it
- can be encoded in 7-bit ascii, and saves in that format if so.'''
- codecs_template = {
- miUTF8: {'codec': 'utf_8', 'width': 1},
- miUTF16: {'codec': 'utf_16', 'width': 2},
- miUTF32: {'codec': 'utf_32','width': 4},
- }
- def _convert_codecs(template, byte_order):
- ''' Convert codec template mapping to byte order
- Set codecs not on this system to None
- Parameters
- ----------
- template : mapping
- key, value are respectively codec name, and root name for codec
- (without byte order suffix)
- byte_order : {'<', '>'}
- code for little or big endian
- Returns
- -------
- codecs : dict
- key, value are name, codec (as in .encode(codec))
- '''
- codecs = {}
- postfix = byte_order == '<' and '_le' or '_be'
- for k, v in template.items():
- codec = v['codec']
- try:
- " ".encode(codec)
- except LookupError:
- codecs[k] = None
- continue
- if v['width'] > 1:
- codec += postfix
- codecs[k] = codec
- return codecs.copy()
- MDTYPES = {}
- for _bytecode in '<>':
- _def = {'dtypes': convert_dtypes(mdtypes_template, _bytecode),
- 'classes': convert_dtypes(mclass_dtypes_template, _bytecode),
- 'codecs': _convert_codecs(codecs_template, _bytecode)}
- MDTYPES[_bytecode] = _def
- class mat_struct:
- """Placeholder for holding read data from structs.
- We use instances of this class when the user passes False as a value to the
- ``struct_as_record`` parameter of the :func:`scipy.io.loadmat` function.
- """
- pass
- class MatlabObject(np.ndarray):
- """Subclass of ndarray to signal this is a matlab object.
- This is a simple subclass of :class:`numpy.ndarray` meant to be used
- by :func:`scipy.io.loadmat` and should not be instantiated directly.
- """
- def __new__(cls, input_array, classname=None):
- # Input array is an already formed ndarray instance
- # We first cast to be our class type
- obj = np.asarray(input_array).view(cls)
- # add the new attribute to the created instance
- obj.classname = classname
- # Finally, we must return the newly created object:
- return obj
- def __array_finalize__(self,obj):
- # reset the attribute from passed original object
- self.classname = getattr(obj, 'classname', None)
- # We do not need to return anything
- class MatlabFunction(np.ndarray):
- """Subclass for a MATLAB function.
- This is a simple subclass of :class:`numpy.ndarray` meant to be used
- by :func:`scipy.io.loadmat` and should not be directly instantiated.
- """
- def __new__(cls, input_array):
- obj = np.asarray(input_array).view(cls)
- return obj
- class MatlabOpaque(np.ndarray):
- """Subclass for a MATLAB opaque matrix.
- This is a simple subclass of :class:`numpy.ndarray` meant to be used
- by :func:`scipy.io.loadmat` and should not be directly instantiated.
- """
- def __new__(cls, input_array):
- obj = np.asarray(input_array).view(cls)
- return obj
- OPAQUE_DTYPE = np.dtype(
- [('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')])
|