Skip to content

Commit 27d1c59

Browse files
zubarapre-commit-ci[bot]larsonerdrammock
authored
mne-tools#11608, buggfix and docstring update (mne-tools#12066)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Larson <larson.eric.d@gmail.com> Co-authored-by: Daniel McCloy <dan@mccloy.info>
1 parent 5a83eae commit 27d1c59

File tree

4 files changed

+39
-19
lines changed

4 files changed

+39
-19
lines changed

doc/changes/devel.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Bugs
4444
- Fix bugs with :func:`mne.preprocessing.realign_raw` where the start of ``other`` was incorrectly cropped; and onsets and durations in ``other.annotations`` were left unsynced with the resampled data (:gh:`11950` by :newcontrib:`Qian Chu`)
4545
- Fix bug where ``encoding`` argument was ignored when reading annotations from an EDF file (:gh:`11958` by :newcontrib:`Andrew Gilbert`)
4646
- Mark tests ``test_adjacency_matches_ft`` and ``test_fetch_uncompressed_file`` as network tests (:gh:`12041` by :newcontrib:`Maksym Balatsko`)
47+
- Fix bug with :func:`mne.channels.read_ch_adjacency` (:gh:`11608` by :newcontrib:`Ivan Zubarev`)
4748
- Fix bugs with saving splits for :class:`~mne.Epochs` (:gh:`11876` by `Dmitrii Altukhov`_)
4849
- Fix bug with multi-plot 3D rendering where only one plot was updated (:gh:`11896` by `Eric Larson`_)
4950
- Fix bug where subject birthdays were not correctly read by :func:`mne.io.read_raw_snirf` (:gh:`11912` by `Eric Larson`_)

mne/channels/channels.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,8 +1340,7 @@ def read_ch_adjacency(fname, picks=None):
13401340
You can retrieve the names of all
13411341
built-in channel adjacencies via
13421342
:func:`mne.channels.get_builtin_ch_adjacencies`.
1343-
%(picks_all)s
1344-
Picks must match the template.
1343+
%(picks_all_notypes)s
13451344
13461345
Returns
13471346
-------
@@ -1401,20 +1400,15 @@ def read_ch_adjacency(fname, picks=None):
14011400

14021401
nb = loadmat(fname)["neighbours"]
14031402
ch_names = _recursive_flatten(nb["label"], str)
1404-
picks = _picks_to_idx(len(ch_names), picks)
1403+
temp_info = create_info(ch_names, 1.0)
1404+
picks = _picks_to_idx(temp_info, picks, none="all")
14051405
neighbors = [_recursive_flatten(c, str) for c in nb["neighblabel"].flatten()]
14061406
assert len(ch_names) == len(neighbors)
14071407
adjacency = _ch_neighbor_adjacency(ch_names, neighbors)
14081408
# picking before constructing matrix is buggy
14091409
adjacency = adjacency[picks][:, picks]
14101410
ch_names = [ch_names[p] for p in picks]
14111411

1412-
# make sure MEG channel names contain space after "MEG"
1413-
for idx, ch_name in enumerate(ch_names):
1414-
if ch_name.startswith("MEG") and not ch_name[3] == " ":
1415-
ch_name = ch_name.replace("MEG", "MEG ")
1416-
ch_names[idx] = ch_name
1417-
14181412
return adjacency, ch_names
14191413

14201414

mne/channels/tests/test_channels.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,25 @@ def test_get_builtin_ch_adjacencies():
243243
assert len(name_and_description) == 2
244244

245245

246+
@pytest.mark.parametrize("name", get_builtin_ch_adjacencies())
247+
@pytest.mark.parametrize("picks", ["pick-slice", "pick-arange", "pick-names"])
248+
def test_read_builtin_ch_adjacency_picks(name, picks):
249+
"""Test picking channel subsets when reading builtin adjacency matrices."""
250+
ch_adjacency, ch_names = read_ch_adjacency(name)
251+
assert_equal(ch_adjacency.shape[0], len(ch_names))
252+
subset_names = ch_names[::2]
253+
if picks == "pick-slice":
254+
subset = slice(None, None, 2)
255+
elif picks == "pick-arange":
256+
subset = np.arange(0, len(ch_names), 2)
257+
else:
258+
assert picks == "pick-names"
259+
subset = subset_names
260+
261+
ch_subset_adjacency, ch_subset_names = read_ch_adjacency(name, subset)
262+
assert_array_equal(ch_subset_names, subset_names)
263+
264+
246265
def test_read_ch_adjacency(tmp_path):
247266
"""Test reading channel adjacency templates."""
248267
a = partial(np.array, dtype="<U7")
@@ -262,6 +281,7 @@ def test_read_ch_adjacency(tmp_path):
262281
savemat(mat_fname, mat, oned_as="row")
263282

264283
ch_adjacency, ch_names = read_ch_adjacency(mat_fname)
284+
265285
x = ch_adjacency
266286
assert_equal(x.shape[0], len(ch_names))
267287
assert_equal(x.shape, (3, 3))
@@ -328,11 +348,6 @@ def test_read_ch_adjacency(tmp_path):
328348
savemat(mat_fname, mat, oned_as="row")
329349
pytest.raises(ValueError, read_ch_adjacency, mat_fname)
330350

331-
# Try reading all built-in FieldTrip neighbors
332-
for name in get_builtin_ch_adjacencies():
333-
ch_adjacency, ch_names = read_ch_adjacency(name)
334-
assert_equal(ch_adjacency.shape[0], len(ch_names))
335-
336351

337352
def _download_ft_neighbors(target_dir):
338353
"""Download the known neighbors from FieldTrip."""

mne/utils/docs.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3358,11 +3358,16 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
33583358
_picks_header = f"picks : {_picks_types}"
33593359
_picks_desc = "Channels to include."
33603360
_picks_int = "Slices and lists of integers will be interpreted as channel " "indices."
3361-
_picks_str = """In lists, channel *type* strings
3362-
(e.g., ``['meg', 'eeg']``) will pick channels of those
3363-
types, channel *name* strings (e.g., ``['MEG0111', 'MEG2623']``
3364-
will pick the given channels. Can also be the string values
3365-
"all" to pick all channels, or "data" to pick :term:`data channels`.
3361+
_picks_str_types = """channel *type* strings (e.g., ``['meg', 'eeg']``) will
3362+
pick channels of those types,"""
3363+
_picks_str_names = """channel *name* strings (e.g., ``['MEG0111', 'MEG2623']``
3364+
will pick the given channels."""
3365+
_picks_str_values = """Can also be the string values "all" to pick
3366+
all channels, or "data" to pick :term:`data channels`."""
3367+
_picks_str = f"""In lists, {_picks_str_types} {_picks_str_names}
3368+
{_picks_str_values}
3369+
None (default) will pick"""
3370+
_picks_str_notypes = f"""In lists, {_picks_str_names}
33663371
None (default) will pick"""
33673372
_reminder = (
33683373
"Note that channels in ``info['bads']`` *will be included* if "
@@ -3373,13 +3378,18 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
33733378
noref = f"(excluding reference MEG channels). {reminder}"
33743379
picks_base = f"""{_picks_header}
33753380
{_picks_desc} {_picks_int} {_picks_str}"""
3381+
picks_base_notypes = f"""picks : list of int | list of str | slice | None
3382+
{_picks_desc} {_picks_int} {_picks_str_notypes}"""
33763383
docdict["picks_all"] = _reflow_param_docstring(f"{picks_base} all channels. {reminder}")
33773384
docdict["picks_all_data"] = _reflow_param_docstring(
33783385
f"{picks_base} all data channels. {reminder}"
33793386
)
33803387
docdict["picks_all_data_noref"] = _reflow_param_docstring(
33813388
f"{picks_base} all data channels {noref}"
33823389
)
3390+
docdict["picks_all_notypes"] = _reflow_param_docstring(
3391+
f"{picks_base_notypes} all channels. {reminder}"
3392+
)
33833393
docdict["picks_base"] = _reflow_param_docstring(picks_base)
33843394
docdict["picks_good_data"] = _reflow_param_docstring(
33853395
f"{picks_base} good data channels. {reminder}"

0 commit comments

Comments
 (0)