Skip to content

Commit bd1dc9c

Browse files
TST: Add regression coverage for OPM topomap grouping via plot_joint() and ICA (#13842)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 4983e96 commit bd1dc9c

4 files changed

Lines changed: 75 additions & 4 deletions

File tree

doc/changes/dev/13842.other.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added regression coverage for colocated triaxial OPM topomap handling in ``plot_joint()`` and ``ICA.plot_components()``, by `Pragnya Khandelwal`_.

mne/conftest.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@
2727

2828
# ruff: noqa: E402
2929
import mne
30-
from mne import Epochs, pick_types, read_events
30+
from mne import Epochs, create_info, make_fixed_length_epochs, pick_types, read_events
31+
from mne._fiff.constants import FIFF
3132
from mne.channels import read_layout
3233
from mne.coreg import create_default_subject
3334
from mne.datasets import testing
3435
from mne.fixes import _compare_version, has_numba
35-
from mne.io import read_raw_ctf, read_raw_fif, read_raw_nirx, read_raw_snirf
36+
from mne.io import RawArray, read_raw_ctf, read_raw_fif, read_raw_nirx, read_raw_snirf
3637
from mne.stats import cluster_level
3738
from mne.utils import (
3839
Bunch,
@@ -546,6 +547,47 @@ def _bias_params(evoked, noise_cov, fwd):
546547
return evoked, fwd, noise_cov, data_cov, want
547548

548549

550+
@pytest.fixture
551+
def triaxial_raw():
552+
"""Create a small triaxial OPM raw for regression tests."""
553+
ch_names = ["OPM001", "OPM002", "OPM003", "OPM004", "OPM005", "OPM006"]
554+
info = create_info(ch_names, 1000.0, ch_types="mag")
555+
positions = np.array(
556+
[
557+
[0.03, 0.00, 0.05],
558+
[0.03, 0.00, 0.05],
559+
[0.03, 0.00, 0.05],
560+
[-0.03, 0.00, 0.05],
561+
[-0.03, 0.00, 0.05],
562+
[-0.03, 0.00, 0.05],
563+
]
564+
)
565+
orientations = np.array(
566+
[
567+
[0.5145, 0.0000, 0.8575],
568+
[0.0000, 1.0000, 0.0000],
569+
[0.0000, 0.0000, 1.0000],
570+
[-0.5145, 0.0000, 0.8575],
571+
[0.0000, 1.0000, 0.0000],
572+
[0.0000, 0.0000, 1.0000],
573+
]
574+
)
575+
with info._unlock():
576+
for idx, ch in enumerate(info["chs"]):
577+
ch["coil_type"] = FIFF.FIFFV_COIL_FIELDLINE_OPM_MAG_GEN1
578+
ch["loc"][:3] = positions[idx]
579+
ch["loc"][9:12] = orientations[idx]
580+
rng = np.random.default_rng(0)
581+
data = rng.standard_normal((len(ch_names), 2000))
582+
return RawArray(data, info, verbose="error")
583+
584+
585+
@pytest.fixture
586+
def triaxial_evoked(triaxial_raw):
587+
"""Create a small triaxial OPM evoked for regression tests."""
588+
return make_fixed_length_epochs(triaxial_raw).average()
589+
590+
549591
@pytest.fixture
550592
def garbage_collect():
551593
"""Garbage collect on exit."""

mne/viz/tests/test_ica.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,3 +574,15 @@ def test_plot_components_opm():
574574
ica.fit(RawArray(evoked.data, evoked.info), picks="mag", verbose="error")
575575
fig = ica.plot_components()
576576
assert len(fig.axes) == 10
577+
578+
579+
@pytest.mark.slowtest
580+
@pytest.mark.filterwarnings(
581+
"ignore:FastICA did not converge.*:sklearn.exceptions.ConvergenceWarning"
582+
)
583+
def test_plot_components_opm_triaxial(triaxial_raw):
584+
"""Test OPM component topomaps with colocated triaxial channels."""
585+
ica = ICA(max_iter=1, random_state=0, n_components=3)
586+
ica.fit(triaxial_raw, picks="mag", verbose="error")
587+
fig = ica.plot_components()
588+
assert len(fig.axes) == 3

mne/viz/tests/test_topo.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
import numpy as np
1111
import pytest
1212

13-
from mne import Epochs, compute_proj_evoked, read_cov, read_events
13+
from mne import (
14+
Epochs,
15+
compute_proj_evoked,
16+
read_cov,
17+
read_events,
18+
)
1419
from mne.channels import read_layout
1520
from mne.io import read_raw_fif
1621
from mne.time_frequency.tfr import AverageTFRArray
@@ -116,7 +121,6 @@ def return_inds(d): # to test function kwarg to zorder arg of evoked.plot
116121
evoked.plot_joint(
117122
ts_args=dict(proj="reconstruct"), topomap_args=dict(proj="reconstruct")
118123
)
119-
plt.close("all")
120124

121125
# test sEEG (gh:8733)
122126
evoked.del_proj().pick("mag") # avoid overlapping positions error
@@ -132,6 +136,18 @@ def return_inds(d): # to test function kwarg to zorder arg of evoked.plot
132136
plt.close("all")
133137

134138

139+
def test_plot_joint_opm_triaxial(triaxial_evoked):
140+
"""Test joint plot with triaxial colocated OPM channels."""
141+
fig = triaxial_evoked.plot_joint(
142+
times=[0.0],
143+
picks="mag",
144+
show=False,
145+
ts_args=dict(time_unit="s"),
146+
topomap_args=dict(time_unit="s", contours=0, res=8, sensors=False),
147+
)
148+
assert len(fig.axes) >= 2
149+
150+
135151
def test_plot_topo():
136152
"""Test plotting of ERP topography."""
137153
# Show topography

0 commit comments

Comments
 (0)