Spaces:
Running
Running
| # Authors: The MNE-Python contributors. | |
| # License: BSD-3-Clause | |
| # Copyright the MNE-Python contributors. | |
| from ..utils import logger | |
| from .constants import FIFF | |
| from .tag import find_tag, has_tag | |
| from .write import ( | |
| end_block, | |
| start_block, | |
| write_float_matrix, | |
| write_int, | |
| write_name_list, | |
| ) | |
| def _transpose_named_matrix(mat): | |
| """Transpose mat inplace (no copy).""" | |
| mat["nrow"], mat["ncol"] = mat["ncol"], mat["nrow"] | |
| mat["row_names"], mat["col_names"] = mat["col_names"], mat["row_names"] | |
| mat["data"] = mat["data"].T | |
| def _read_named_matrix(fid, node, matkind, indent=" ", transpose=False): | |
| """Read named matrix from the given node. | |
| Parameters | |
| ---------- | |
| fid : file | |
| The opened file descriptor. | |
| node : dict | |
| The node in the tree. | |
| matkind : int | |
| The type of matrix. | |
| transpose : bool | |
| If True, transpose the matrix. Default is False. | |
| %(verbose)s | |
| Returns | |
| ------- | |
| mat: dict | |
| The matrix data | |
| """ | |
| # Descend one level if necessary | |
| if node["block"] != FIFF.FIFFB_MNE_NAMED_MATRIX: | |
| for k in range(node["nchild"]): | |
| if node["children"][k]["block"] == FIFF.FIFFB_MNE_NAMED_MATRIX: | |
| if has_tag(node["children"][k], matkind): | |
| node = node["children"][k] | |
| break | |
| else: | |
| logger.info( | |
| f"{indent}Desired named matrix (kind = {matkind}) not available" | |
| ) | |
| return None | |
| else: | |
| if not has_tag(node, matkind): | |
| logger.info( | |
| f"{indent}Desired named matrix (kind = {matkind}) not available" | |
| ) | |
| return None | |
| # Read everything we need | |
| tag = find_tag(fid, node, matkind) | |
| if tag is None: | |
| raise ValueError("Matrix data missing") | |
| else: | |
| data = tag.data | |
| nrow, ncol = data.shape | |
| tag = find_tag(fid, node, FIFF.FIFF_MNE_NROW) | |
| if tag is not None and tag.data != nrow: | |
| raise ValueError( | |
| "Number of rows in matrix data and FIFF_MNE_NROW tag do not match" | |
| ) | |
| tag = find_tag(fid, node, FIFF.FIFF_MNE_NCOL) | |
| if tag is not None and tag.data != ncol: | |
| raise ValueError( | |
| "Number of columns in matrix data and FIFF_MNE_NCOL tag do not match" | |
| ) | |
| tag = find_tag(fid, node, FIFF.FIFF_MNE_ROW_NAMES) | |
| row_names = tag.data.split(":") if tag is not None else [] | |
| tag = find_tag(fid, node, FIFF.FIFF_MNE_COL_NAMES) | |
| col_names = tag.data.split(":") if tag is not None else [] | |
| mat = dict( | |
| nrow=nrow, ncol=ncol, row_names=row_names, col_names=col_names, data=data | |
| ) | |
| if transpose: | |
| _transpose_named_matrix(mat) | |
| return mat | |
| def write_named_matrix(fid, kind, mat): | |
| """Write named matrix from the given node. | |
| Parameters | |
| ---------- | |
| fid : file | |
| The opened file descriptor. | |
| kind : int | |
| The kind of the matrix. | |
| matkind : int | |
| The type of matrix. | |
| """ | |
| # let's save ourselves from disaster | |
| n_tot = mat["nrow"] * mat["ncol"] | |
| if mat["data"].size != n_tot: | |
| ratio = n_tot / float(mat["data"].size) | |
| if n_tot < mat["data"].size and ratio > 0: | |
| ratio = 1 / ratio | |
| raise ValueError( | |
| f"Cannot write matrix: row ({mat['nrow']}) and column ({mat['ncol']}) " | |
| f"total element ({n_tot}) mismatch with data size ({mat['data'].size}), " | |
| f"appears to be off by a factor of {ratio:g}x" | |
| ) | |
| start_block(fid, FIFF.FIFFB_MNE_NAMED_MATRIX) | |
| write_int(fid, FIFF.FIFF_MNE_NROW, mat["nrow"]) | |
| write_int(fid, FIFF.FIFF_MNE_NCOL, mat["ncol"]) | |
| if len(mat["row_names"]) > 0: | |
| # let's prevent unintentional stupidity | |
| if len(mat["row_names"]) != mat["nrow"]: | |
| raise ValueError('len(mat["row_names"]) != mat["nrow"]') | |
| write_name_list(fid, FIFF.FIFF_MNE_ROW_NAMES, mat["row_names"]) | |
| if len(mat["col_names"]) > 0: | |
| # let's prevent unintentional stupidity | |
| if len(mat["col_names"]) != mat["ncol"]: | |
| raise ValueError('len(mat["col_names"]) != mat["ncol"]') | |
| write_name_list(fid, FIFF.FIFF_MNE_COL_NAMES, mat["col_names"]) | |
| write_float_matrix(fid, kind, mat["data"]) | |
| end_block(fid, FIFF.FIFFB_MNE_NAMED_MATRIX) | |