Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion mne/channels/_standard_montage_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,15 @@ def _read_elc(fname, head_size):
break

# Read positions
new_style = False
pos = []
for line in fid:
if "Labels\n" in line:
break
if ":" in line:
# Of the 'new' format: `E01 : 5.288 -3.658 119.693`
pos.append(list(map(float, line.split(":")[1].split())))
new_style = True
else:
# Of the 'old' format: `5.288 -3.658 119.693`
pos.append(list(map(float, line.split())))
Expand All @@ -281,7 +283,13 @@ def _read_elc(fname, head_size):
for line in fid:
if not line or not set(line) - {" "}:
break
ch_names_.extend(line.strip(" ").strip("\n").split())
if new_style:
# Not sure how this format would deal with spaces in channel labels,
# but none of my test files had this, so let's wait until it comes up.
parsed = line.strip(" ").strip("\n").split()
else:
parsed = [line.strip(" ").strip("\n")]
ch_names_.extend(parsed)

pos = np.array(pos) * scale
if head_size is not None:
Expand Down
6 changes: 5 additions & 1 deletion mne/channels/montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -1537,7 +1537,10 @@ def _read_eeglab_locations(fname):
return ch_names, pos


def read_custom_montage(fname, head_size=HEAD_SIZE_DEFAULT, coord_frame=None):
@verbose
def read_custom_montage(
fname, head_size=HEAD_SIZE_DEFAULT, coord_frame=None, *, verbose=None
):
"""Read a montage from a file.

Parameters
Expand All @@ -1558,6 +1561,7 @@ def read_custom_montage(fname, head_size=HEAD_SIZE_DEFAULT, coord_frame=None):
for most readers but ``"head"`` for EEGLAB.

.. versionadded:: 0.20
%(verbose)s

Returns
-------
Expand Down
56 changes: 55 additions & 1 deletion mne/channels/tests/test_montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,42 @@ def test_documented():
None,
id="new ASA electrode (elc)",
),
pytest.param(
partial(read_custom_montage, head_size=None),
(
"ReferenceLabel\n"
"avg\n"
"UnitPosition mm\n"
"NumberPositions= 6\n"
"Positions\n"
"-69.2574 10.5895 -25.0009\n"
"3.3791 94.6594 32.2592\n"
"77.2856 12.0537 -30.2488\n"
"4.6147 121.8858 8.6370\n"
"-31.3669 54.0269 94.9191\n"
"-8.7495 56.5653 99.6655\n"
"Labels\n"
"LPA\n"
"Nz\n"
"RPA\n"
"EEG 000\n"
"EEG 001\n"
"EEG 002\n"
),
make_dig_montage(
ch_pos={
"EEG 000": [0.004615, 0.121886, 0.008637],
"EEG 001": [-0.031367, 0.054027, 0.094919],
"EEG 002": [-0.00875, 0.056565, 0.099665],
},
nasion=[0.003379, 0.094659, 0.032259],
lpa=[-0.069257, 0.010589, -0.025001],
rpa=[0.077286, 0.012054, -0.030249],
),
"elc",
None,
id="another old ASA electrode (elc)",
),
pytest.param(
partial(read_custom_montage, head_size=1),
(
Expand Down Expand Up @@ -545,8 +581,26 @@ def test_montage_readers(reader, file_content, expected_dig, ext, warning, tmp_p
actual_ch_pos = dig_montage._get_ch_pos()
expected_ch_pos = expected_dig._get_ch_pos()
for kk in actual_ch_pos:
assert_allclose(actual_ch_pos[kk], expected_ch_pos[kk], atol=1e-5)
assert_allclose(actual_ch_pos[kk], expected_ch_pos[kk], atol=1e-5, err_msg=kk)
assert len(dig_montage.dig) == len(expected_dig.dig)
for key in ("nasion", "lpa", "rpa"):
expected = [
d
for d in expected_dig.dig
if d["kind"] == FIFF.FIFFV_POINT_CARDINAL
and d["ident"] == getattr(FIFF, f"FIFFV_POINT_{key.upper()}")
]
got = [
d
for d in dig_montage.dig
if d["kind"] == FIFF.FIFFV_POINT_CARDINAL
and d["ident"] == getattr(FIFF, f"FIFFV_POINT_{key.upper()}")
]
assert len(expected) in (0, 1), key
assert len(got) in (0, 1), key
assert len(expected) == len(got)
if len(expected):
assert_allclose(got[0]["r"], expected[0]["r"], atol=1e-5, err_msg=key)
for d1, d2 in zip(dig_montage.dig, expected_dig.dig):
assert d1["coord_frame"] == d2["coord_frame"]
for key in ("coord_frame", "ident", "kind"):
Expand Down
4 changes: 2 additions & 2 deletions tutorials/inverse/70_eeg_mri_coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
EEG source localization given electrode locations on an MRI
===========================================================

This tutorial explains how to compute the forward operator from EEG data when
the electrodes are in MRI voxel coordinates.
This tutorial explains how to compute the forward operator from EEG data when the
electrodes are in MRI voxel coordinates.
"""

# Authors: Eric Larson <larson.eric.d@gmail.com>
Expand Down