initial commit
This commit is contained in:
108
mne/io/ctf/eeg.py
Normal file
108
mne/io/ctf/eeg.py
Normal file
@@ -0,0 +1,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
|
||||
Reference in New Issue
Block a user