|
9 | 9 | except ImportError: # scipy < 1.8 |
10 | 10 | from scipy.io.matlab.mio5 import MatlabFunction |
11 | 11 | from scipy.io.matlab.mio5_params import MatlabOpaque |
12 | | -from scipy.io import loadmat, whosmat |
| 12 | +from scipy.io import loadmat |
13 | 13 |
|
14 | | -from ...utils import _import_pymatreader_funcs, _soft_import, warn |
| 14 | +from ...fixes import _whosmat |
| 15 | +from ...utils import _import_pymatreader_funcs, warn |
15 | 16 |
|
16 | 17 |
|
17 | 18 | def _todict_from_np_struct(data): # taken from pymatreader.utils |
@@ -83,106 +84,6 @@ def _scipy_reader(file_name, variable_names=None, uint16_codec=None): |
83 | 84 | return _check_for_scipy_mat_struct(mat_data) |
84 | 85 |
|
85 | 86 |
|
86 | | -def _whosmat_hdf5(fname: str): |
87 | | - """List variables in a MATLAB v7.3 (HDF5) .mat file without loading data. |
88 | | -
|
89 | | - This function provides similar functionality to :func:`scipy.io.whosmat` but |
90 | | - for MATLAB v7.3 files stored in HDF5 format, which are not supported by SciPy. |
91 | | -
|
92 | | - Parameters |
93 | | - ---------- |
94 | | - fname : str | PathLike |
95 | | - Path to the MATLAB v7.3 (.mat) file. |
96 | | -
|
97 | | - Returns |
98 | | - ------- |
99 | | - variables : list of tuple |
100 | | - A list of (name, shape, class) tuples for each variable in the file. |
101 | | - The name is a string, shape is a tuple of ints, and class is a string |
102 | | - indicating the MATLAB data type (e.g., 'double', 'int32', 'struct'). |
103 | | -
|
104 | | - Notes |
105 | | - ----- |
106 | | - This function only works with MATLAB v7.3 (HDF5) files. For earlier versions, |
107 | | - use :func:`scipy.io.whosmat` instead. |
108 | | -
|
109 | | - See Also |
110 | | - -------- |
111 | | - scipy.io.whosmat : List variables in classic MATLAB files. |
112 | | - """ |
113 | | - h5py = _soft_import("h5py", purpose="MATLAB v7.3 I/O", strict=False) |
114 | | - if h5py is False: |
115 | | - raise ModuleNotFoundError( |
116 | | - "h5py is required to inspect MATLAB v7.3 files preload=`False` " |
117 | | - "Please install h5py to use this functionality." |
118 | | - ) |
119 | | - |
120 | | - variables = [] |
121 | | - |
122 | | - with h5py.File(str(fname), "r") as f: |
123 | | - for name in f.keys(): |
124 | | - node = f[name] |
125 | | - |
126 | | - # Extract shape from HDF5 object |
127 | | - if isinstance(node, h5py.Dataset): |
128 | | - shape = tuple(int(x) for x in node.shape) |
129 | | - else: |
130 | | - shape = () |
131 | | - for attr_key in ( |
132 | | - "MATLAB_shape", |
133 | | - "MATLAB_Size", |
134 | | - "MATLAB_size", |
135 | | - "dims", |
136 | | - "MATLAB_dims", |
137 | | - ): |
138 | | - shp = node.attrs.get(attr_key) |
139 | | - if shp is not None: |
140 | | - try: |
141 | | - shape = tuple(int(x) for x in shp) |
142 | | - break |
143 | | - except Exception: |
144 | | - pass |
145 | | - if not shape and "size" in node: |
146 | | - try: |
147 | | - shape = tuple(int(x) for x in node["size"][()]) |
148 | | - except Exception: |
149 | | - pass |
150 | | - |
151 | | - # Infer MATLAB class from HDF5 object |
152 | | - mcls = node.attrs.get("MATLAB_class", "").lower() |
153 | | - if mcls: |
154 | | - matlab_class = "char" if mcls == "string" else mcls |
155 | | - elif isinstance(node, h5py.Dataset): |
156 | | - dt = node.dtype |
157 | | - # Handle complex numbers stored as {real, imag} struct |
158 | | - if getattr(dt, "names", None) and {"real", "imag"} <= set(dt.names): |
159 | | - matlab_class = ( |
160 | | - "double" if dt["real"].base.itemsize == 8 else "single" |
161 | | - ) |
162 | | - # Map NumPy dtype to MATLAB class |
163 | | - elif (kind := dt.kind) == "f": |
164 | | - matlab_class = "double" if dt.itemsize == 8 else "single" |
165 | | - elif kind == "i": |
166 | | - matlab_class = f"int{8 * dt.itemsize}" |
167 | | - elif kind == "u": |
168 | | - matlab_class = f"uint{8 * dt.itemsize}" |
169 | | - elif kind == "b": |
170 | | - matlab_class = "logical" |
171 | | - elif kind in ("S", "U", "O"): |
172 | | - matlab_class = "char" |
173 | | - else: |
174 | | - matlab_class = "unknown" |
175 | | - # Check for sparse matrix structure |
176 | | - elif {"ir", "jc", "data"}.issubset(set(node.keys())): |
177 | | - matlab_class = "sparse" |
178 | | - else: |
179 | | - matlab_class = "unknown" |
180 | | - |
181 | | - variables.append((name, shape, matlab_class)) |
182 | | - |
183 | | - return variables |
184 | | - |
185 | | - |
186 | 87 | def _readmat(fname, uint16_codec=None, *, preload=False): |
187 | 88 | try: |
188 | 89 | read_mat = _import_pymatreader_funcs("EEGLAB I/O") |
@@ -220,18 +121,11 @@ def _readmat(fname, uint16_codec=None, *, preload=False): |
220 | 121 | # checking the variables in the .set file |
221 | 122 | # to decide how to handle 'data' variable |
222 | 123 | try: |
223 | | - variables = whosmat(str(fname)) |
224 | | - except NotImplementedError: |
225 | | - try: |
226 | | - variables = _whosmat_hdf5(str(fname)) |
227 | | - except ModuleNotFoundError: |
228 | | - warn( |
229 | | - "pymatreader is required to preload=`False` for " |
230 | | - "Matlab files v7.3 files with HDF5 support. " |
231 | | - "Setting preload=True." |
232 | | - ) |
233 | | - preload = True |
234 | | - return read_mat(fname, uint16_codec=uint16_codec) |
| 124 | + variables = _whosmat(str(fname)) |
| 125 | + except Exception: |
| 126 | + warn("Could not inspect .set file variables. Setting preload=True.") |
| 127 | + preload = True |
| 128 | + return read_mat(fname, uint16_codec=uint16_codec) |
235 | 129 |
|
236 | 130 | is_possible_not_loaded = False |
237 | 131 |
|
|
0 commit comments