File: eeg.py

package info (click to toggle)
python-mne 1.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 131,492 kB
  • sloc: python: 213,302; javascript: 12,910; sh: 447; makefile: 144
file content (108 lines) | stat: -rw-r--r-- 3,810 bytes parent folder | download
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
"""Read .eeg files."""

# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.

from os import listdir
from os.path import join

import numpy as np

from ..._fiff.constants import FIFF
from ...transforms import apply_trans
from ...utils import logger, warn
from .res4 import _make_ctf_name

_cardinal_dict = dict(
    nasion=FIFF.FIFFV_POINT_NASION,
    lpa=FIFF.FIFFV_POINT_LPA,
    left=FIFF.FIFFV_POINT_LPA,
    rpa=FIFF.FIFFV_POINT_RPA,
    right=FIFF.FIFFV_POINT_RPA,
)


def _read_eeg(directory):
    """Read the .eeg file."""
    # Missing file is ok
    fname, found = _make_ctf_name(directory, "eeg", raise_error=False)
    if not found:
        logger.info("    Separate EEG position data file not present.")
        return
    eeg = dict(
        labels=list(),
        kinds=list(),
        ids=list(),
        rr=list(),
        np=0,
        assign_to_chs=True,
        coord_frame=FIFF.FIFFV_MNE_COORD_CTF_HEAD,
    )
    with open(fname, "rb") as fid:
        for line in fid:
            line = line.strip()
            if len(line) > 0:
                parts = line.decode("utf-8").split()
                if len(parts) != 5:
                    raise RuntimeError(f"Illegal data in EEG position file: {line}")
                r = np.array([float(p) for p in parts[2:]]) / 100.0
                if (r * r).sum() > 1e-4:
                    label = parts[1]
                    eeg["labels"].append(label)
                    eeg["rr"].append(r)
                    id_ = _cardinal_dict.get(label.lower(), int(parts[0]))
                    if label.lower() in _cardinal_dict:
                        kind = FIFF.FIFFV_POINT_CARDINAL
                    else:
                        kind = FIFF.FIFFV_POINT_EXTRA
                    eeg["ids"].append(id_)
                    eeg["kinds"].append(kind)
                    eeg["np"] += 1
    logger.info("    Separate EEG position data file read.")
    return eeg


def _read_pos(directory, transformations):
    """Read the .pos file and return eeg positions as dig extra points."""
    fname = [join(directory, f) for f in listdir(directory) if f.endswith(".pos")]
    if len(fname) < 1:
        return list()
    elif len(fname) > 1:
        warn("    Found multiple pos files. Extra digitizer points not added.")
        return list()
    logger.info(f"    Reading digitizer points from {fname}...")
    if transformations["t_ctf_head_head"] is None:
        warn("    No transformation found. Extra digitizer points not added.")
        return list()
    fname = fname[0]
    digs = list()
    i = 2000
    with open(fname) as fid:
        for line in fid:
            line = line.strip()
            if len(line) > 0:
                parts = line.split()
                # The lines can have 4 or 5 parts. First part is for the id,
                # which can be an int or a string. The last three are for xyz
                # coordinates. The extra part is for additional info
                # (e.g. 'Pz', 'Cz') which is ignored.
                if len(parts) not in [4, 5]:
                    continue
                try:
                    ident = int(parts[0]) + 1000
                except ValueError:  # if id is not an int
                    ident = i
                    i += 1
                dig = dict(
                    kind=FIFF.FIFFV_POINT_EXTRA,
                    ident=ident,
                    r=list(),
                    coord_frame=FIFF.FIFFV_COORD_HEAD,
                )
                r = np.array([float(p) for p in parts[-3:]]) / 100.0  # cm to m
                if (r * r).sum() > 1e-4:
                    r = apply_trans(transformations["t_ctf_head_head"], r)
                    dig["r"] = r
                    digs.append(dig)
    return digs