mio5_params.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. ''' Constants and classes for matlab 5 read and write
  2. See also mio5_utils.pyx where these same constants arise as c enums.
  3. If you make changes in this file, don't forget to change mio5_utils.pyx
  4. '''
  5. from __future__ import division, print_function, absolute_import
  6. import numpy as np
  7. from .miobase import convert_dtypes
  8. miINT8 = 1
  9. miUINT8 = 2
  10. miINT16 = 3
  11. miUINT16 = 4
  12. miINT32 = 5
  13. miUINT32 = 6
  14. miSINGLE = 7
  15. miDOUBLE = 9
  16. miINT64 = 12
  17. miUINT64 = 13
  18. miMATRIX = 14
  19. miCOMPRESSED = 15
  20. miUTF8 = 16
  21. miUTF16 = 17
  22. miUTF32 = 18
  23. mxCELL_CLASS = 1
  24. mxSTRUCT_CLASS = 2
  25. # The March 2008 edition of "Matlab 7 MAT-File Format" says that
  26. # mxOBJECT_CLASS = 3, whereas matrix.h says that mxLOGICAL = 3.
  27. # Matlab 2008a appears to save logicals as type 9, so we assume that
  28. # the document is correct. See type 18, below.
  29. mxOBJECT_CLASS = 3
  30. mxCHAR_CLASS = 4
  31. mxSPARSE_CLASS = 5
  32. mxDOUBLE_CLASS = 6
  33. mxSINGLE_CLASS = 7
  34. mxINT8_CLASS = 8
  35. mxUINT8_CLASS = 9
  36. mxINT16_CLASS = 10
  37. mxUINT16_CLASS = 11
  38. mxINT32_CLASS = 12
  39. mxUINT32_CLASS = 13
  40. # The following are not in the March 2008 edition of "Matlab 7
  41. # MAT-File Format," but were guessed from matrix.h.
  42. mxINT64_CLASS = 14
  43. mxUINT64_CLASS = 15
  44. mxFUNCTION_CLASS = 16
  45. # Not doing anything with these at the moment.
  46. mxOPAQUE_CLASS = 17 # This appears to be a function workspace
  47. # Thread 'saveing/loading symbol table of annymous functions', octave-maintainers, April-May 2007
  48. # https://lists.gnu.org/archive/html/octave-maintainers/2007-04/msg00031.html
  49. # https://lists.gnu.org/archive/html/octave-maintainers/2007-05/msg00032.html
  50. # (Was/Deprecated: https://www-old.cae.wisc.edu/pipermail/octave-maintainers/2007-May/002824.html)
  51. mxOBJECT_CLASS_FROM_MATRIX_H = 18
  52. mdtypes_template = {
  53. miINT8: 'i1',
  54. miUINT8: 'u1',
  55. miINT16: 'i2',
  56. miUINT16: 'u2',
  57. miINT32: 'i4',
  58. miUINT32: 'u4',
  59. miSINGLE: 'f4',
  60. miDOUBLE: 'f8',
  61. miINT64: 'i8',
  62. miUINT64: 'u8',
  63. miUTF8: 'u1',
  64. miUTF16: 'u2',
  65. miUTF32: 'u4',
  66. 'file_header': [('description', 'S116'),
  67. ('subsystem_offset', 'i8'),
  68. ('version', 'u2'),
  69. ('endian_test', 'S2')],
  70. 'tag_full': [('mdtype', 'u4'), ('byte_count', 'u4')],
  71. 'tag_smalldata':[('byte_count_mdtype', 'u4'), ('data', 'S4')],
  72. 'array_flags': [('data_type', 'u4'),
  73. ('byte_count', 'u4'),
  74. ('flags_class','u4'),
  75. ('nzmax', 'u4')],
  76. 'U1': 'U1',
  77. }
  78. mclass_dtypes_template = {
  79. mxINT8_CLASS: 'i1',
  80. mxUINT8_CLASS: 'u1',
  81. mxINT16_CLASS: 'i2',
  82. mxUINT16_CLASS: 'u2',
  83. mxINT32_CLASS: 'i4',
  84. mxUINT32_CLASS: 'u4',
  85. mxINT64_CLASS: 'i8',
  86. mxUINT64_CLASS: 'u8',
  87. mxSINGLE_CLASS: 'f4',
  88. mxDOUBLE_CLASS: 'f8',
  89. }
  90. mclass_info = {
  91. mxINT8_CLASS: 'int8',
  92. mxUINT8_CLASS: 'uint8',
  93. mxINT16_CLASS: 'int16',
  94. mxUINT16_CLASS: 'uint16',
  95. mxINT32_CLASS: 'int32',
  96. mxUINT32_CLASS: 'uint32',
  97. mxINT64_CLASS: 'int64',
  98. mxUINT64_CLASS: 'uint64',
  99. mxSINGLE_CLASS: 'single',
  100. mxDOUBLE_CLASS: 'double',
  101. mxCELL_CLASS: 'cell',
  102. mxSTRUCT_CLASS: 'struct',
  103. mxOBJECT_CLASS: 'object',
  104. mxCHAR_CLASS: 'char',
  105. mxSPARSE_CLASS: 'sparse',
  106. mxFUNCTION_CLASS: 'function',
  107. mxOPAQUE_CLASS: 'opaque',
  108. }
  109. NP_TO_MTYPES = {
  110. 'f8': miDOUBLE,
  111. 'c32': miDOUBLE,
  112. 'c24': miDOUBLE,
  113. 'c16': miDOUBLE,
  114. 'f4': miSINGLE,
  115. 'c8': miSINGLE,
  116. 'i8': miINT64,
  117. 'i4': miINT32,
  118. 'i2': miINT16,
  119. 'i1': miINT8,
  120. 'u8': miUINT64,
  121. 'u4': miUINT32,
  122. 'u2': miUINT16,
  123. 'u1': miUINT8,
  124. 'S1': miUINT8,
  125. 'U1': miUTF16,
  126. 'b1': miUINT8, # not standard but seems MATLAB uses this (gh-4022)
  127. }
  128. NP_TO_MXTYPES = {
  129. 'f8': mxDOUBLE_CLASS,
  130. 'c32': mxDOUBLE_CLASS,
  131. 'c24': mxDOUBLE_CLASS,
  132. 'c16': mxDOUBLE_CLASS,
  133. 'f4': mxSINGLE_CLASS,
  134. 'c8': mxSINGLE_CLASS,
  135. 'i8': mxINT64_CLASS,
  136. 'i4': mxINT32_CLASS,
  137. 'i2': mxINT16_CLASS,
  138. 'i1': mxINT8_CLASS,
  139. 'u8': mxUINT64_CLASS,
  140. 'u4': mxUINT32_CLASS,
  141. 'u2': mxUINT16_CLASS,
  142. 'u1': mxUINT8_CLASS,
  143. 'S1': mxUINT8_CLASS,
  144. 'b1': mxUINT8_CLASS, # not standard but seems MATLAB uses this
  145. }
  146. ''' Before release v7.1 (release 14) matlab (TM) used the system
  147. default character encoding scheme padded out to 16-bits. Release 14
  148. and later use Unicode. When saving character data, R14 checks if it
  149. can be encoded in 7-bit ascii, and saves in that format if so.'''
  150. codecs_template = {
  151. miUTF8: {'codec': 'utf_8', 'width': 1},
  152. miUTF16: {'codec': 'utf_16', 'width': 2},
  153. miUTF32: {'codec': 'utf_32','width': 4},
  154. }
  155. def _convert_codecs(template, byte_order):
  156. ''' Convert codec template mapping to byte order
  157. Set codecs not on this system to None
  158. Parameters
  159. ----------
  160. template : mapping
  161. key, value are respectively codec name, and root name for codec
  162. (without byte order suffix)
  163. byte_order : {'<', '>'}
  164. code for little or big endian
  165. Returns
  166. -------
  167. codecs : dict
  168. key, value are name, codec (as in .encode(codec))
  169. '''
  170. codecs = {}
  171. postfix = byte_order == '<' and '_le' or '_be'
  172. for k, v in template.items():
  173. codec = v['codec']
  174. try:
  175. " ".encode(codec)
  176. except LookupError:
  177. codecs[k] = None
  178. continue
  179. if v['width'] > 1:
  180. codec += postfix
  181. codecs[k] = codec
  182. return codecs.copy()
  183. MDTYPES = {}
  184. for _bytecode in '<>':
  185. _def = {'dtypes': convert_dtypes(mdtypes_template, _bytecode),
  186. 'classes': convert_dtypes(mclass_dtypes_template, _bytecode),
  187. 'codecs': _convert_codecs(codecs_template, _bytecode)}
  188. MDTYPES[_bytecode] = _def
  189. class mat_struct(object):
  190. ''' Placeholder for holding read data from structs
  191. We use instances of this class when the user passes False as a value to the
  192. ``struct_as_record`` parameter of the :func:`scipy.io.matlab.loadmat`
  193. function.
  194. '''
  195. pass
  196. class MatlabObject(np.ndarray):
  197. ''' ndarray Subclass to contain matlab object '''
  198. def __new__(cls, input_array, classname=None):
  199. # Input array is an already formed ndarray instance
  200. # We first cast to be our class type
  201. obj = np.asarray(input_array).view(cls)
  202. # add the new attribute to the created instance
  203. obj.classname = classname
  204. # Finally, we must return the newly created object:
  205. return obj
  206. def __array_finalize__(self,obj):
  207. # reset the attribute from passed original object
  208. self.classname = getattr(obj, 'classname', None)
  209. # We do not need to return anything
  210. class MatlabFunction(np.ndarray):
  211. ''' Subclass to signal this is a matlab function '''
  212. def __new__(cls, input_array):
  213. obj = np.asarray(input_array).view(cls)
  214. return obj
  215. class MatlabOpaque(np.ndarray):
  216. ''' Subclass to signal this is a matlab opaque matrix '''
  217. def __new__(cls, input_array):
  218. obj = np.asarray(input_array).view(cls)
  219. return obj
  220. OPAQUE_DTYPE = np.dtype(
  221. [('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')])