[7f9fb8]: / mne / _fiff / matrix.py

Download this file

138 lines (118 with data), 4.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# 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)