22# License: BSD-3-Clause
33# Copyright the MNE-Python contributors.
44
5-
5+ import matplotlib . pyplot as plt
66import numpy as np
77import pytest
88from numpy .testing import assert_allclose , assert_equal
1717subjects_dir = data_path / "subjects"
1818fname_dip = data_path / "MEG" / "sample" / "sample_audvis_trunc_set1.dip"
1919fname_evokeds = data_path / "MEG" / "sample" / "sample_audvis_trunc-ave.fif"
20+ fname_trans = data_path / "MEG" / "sample" / "sample_audvis_trunc-trans.fif"
2021
2122
2223def _gui_with_two_dipoles ():
2324 """Create a dipolefit GUI and add two dipoles to it."""
2425 from mne .gui import dipolefit
2526
2627 g = dipolefit (fname_evokeds )
27- dip = mne .read_dipole (fname_dip )[[0 , 1 ]]
28- g .add_dipole (dip , name = ["rh1 " , "rh2 " ])
28+ dip = mne .read_dipole (fname_dip )[[12 , 15 ]] # 80ms and 90ms
29+ g .add_dipole (dip , name = ["rh " , "lh " ])
2930 return g
3031
3132
@@ -37,8 +38,9 @@ def test_dipolefit_gui_basic(renderer_interactive_pyvistaqt):
3738
3839 # Test basic interface elements.
3940 g = dipolefit (fname_evokeds )
40- assert g ._evoked .comment == "Left Auditory" # MNE-Sample data should be loaded
41- assert g ._current_time == g ._evoked .times [84 ] # time of max GFP
41+ evoked = g ._evoked
42+ assert evoked .comment == "Left Auditory" # MNE-Sample data should be loaded
43+ assert g ._current_time == evoked .times [84 ] # time of max GFP
4244
4345 # Test fitting a single dipole.
4446 assert len (g ._dipoles ) == len (g .dipoles ) == 0
@@ -48,28 +50,38 @@ def test_dipolefit_gui_basic(renderer_interactive_pyvistaqt):
4850 assert dip .name == "Left Auditory"
4951 assert len (dip .times ) == 1
5052 assert_equal (dip .times , g ._current_time )
51- assert_allclose (dip .amplitude , 6.152221e-08 , rtol = 1e-4 )
52- assert_allclose (dip .pos , [[0.04568744 , 0.00753845 , 0.06737837 ]], atol = 1e-5 )
53- assert_allclose (dip .ori , [[0.45720003 , - 0.72124413 , - 0.52036049 ]], atol = 1e-5 )
5453 old_dip1_timecourse = g ._dipoles [0 ]["timecourse" ]
5554
55+ # Check the position of the fitted dipole against the pre-computed dipole in the
56+ # testing dataset. The pre-computed dipole only needs to give us the general area
57+ # in which we expect the fitted dipole and does not have to be a perfect match.
58+ ref_dip = mne .read_dipole (fname_dip )
59+ ref_dip_t = ref_dip [[np .argmin (np .abs (ref_dip .times - g ._current_time ))]]
60+ assert_allclose (dip .pos , ref_dip_t .pos , atol = 0.012 ) # somewhat near the reference
61+
5662 # Test fitting a second dipole with a subset of channels at a different time.
5763 g ._on_sensor_data () # open sensor selection window
58- picks = read_vectorview_selection ("Left" , info = g . _evoked .info )
64+ picks = read_vectorview_selection ("Left" , info = evoked .info )
5965 ui_events .publish (g ._fig_sensors , ui_events .ChannelsSelect (picks ))
6066 assert sorted (g ._fig_sensors .lasso .selection ) == sorted (picks )
61- ui_events .publish (g ._fig , ui_events .TimeChange (0.1 )) # change time
62- assert g ._current_time == 0.1
67+ ui_events .publish (g ._fig , ui_events .TimeChange (0.09 )) # change time
68+ assert g ._current_time == 0.09
6369 g ._on_fit_dipole ()
6470 assert len (g ._dipoles ) == len (g .dipoles ) == 2
6571 dip2 = g .dipoles [1 ]
66- assert_equal (dip2 .times , g ._evoked .times [np .searchsorted (g ._evoked .times , 0.1 ) - 1 ])
67- assert_allclose (dip2 .amplitude , 4.422736e-08 , rtol = 1e-4 )
68- assert_allclose (dip2 .pos , [[- 0.05893074 , - 0.00202937 , 0.05113064 ]], atol = 1e-5 )
69- assert_allclose (dip2 .ori , [[0.3017588 , - 0.88550684 , - 0.35329769 ]], atol = 1e-5 )
72+
73+ # The selected time of 0.09 is not actually in evoked.times, find the closest value
74+ # that is (0.08990784...). That should be the time recorded in the dipole object.
75+ closest_time = evoked .times [np .argmin (np .abs (evoked .times - g ._current_time ))]
76+ assert dip2 .times [0 ] == closest_time
77+
78+ # Check that the general area of the second dipole is now in the left hemisphere.
79+ ref_dip_t = ref_dip [[np .argmin (np .abs (ref_dip .times - g ._current_time ))]]
80+ assert_allclose (dip2 .pos , ref_dip_t .pos , atol = 0.012 ) # somewhat near the reference
81+
7082 # Adding the second dipole should have affected the timecourse of the first.
7183 new_dip1_timecourse = g ._dipoles [0 ]["timecourse" ]
72- assert not np .allclose (old_dip1_timecourse , new_dip1_timecourse )
84+ assert not np .allclose (old_dip1_timecourse , new_dip1_timecourse , atol = 1e-10 )
7385
7486 # Test differences between the two dipoles
7587 assert list (g ._dipoles .keys ()) == [0 , 1 ]
@@ -78,12 +90,6 @@ def test_dipolefit_gui_basic(renderer_interactive_pyvistaqt):
7890 assert dip2_dict ["dip" ] is dip2
7991 assert dip1_dict ["num" ] == 0
8092 assert dip2_dict ["num" ] == 1
81- assert_allclose (
82- dip1_dict ["helmet_pos" ], [0.10320071 , 0.00946581 , 0.07516293 ], atol = 1e-5
83- )
84- assert_allclose (
85- dip2_dict ["helmet_pos" ], [- 0.11462019 , - 0.00727073 , 0.04561434 ], atol = 1e-5
86- )
8793 assert dip1_dict ["color" ] == _get_color_list ()[0 ]
8894 assert dip2_dict ["color" ] == _get_color_list ()[1 ]
8995
@@ -92,7 +98,9 @@ def test_dipolefit_gui_basic(renderer_interactive_pyvistaqt):
9298 old_timecourses = np .vstack ((dip1_dict ["timecourse" ], dip2_dict ["timecourse" ]))
9399 g ._on_select_method ("Single dipole" )
94100 new_timecourses = np .vstack ((dip1_dict ["timecourse" ], dip2_dict ["timecourse" ]))
95- assert not np .allclose (old_timecourses , new_timecourses )
101+ assert not np .allclose (old_timecourses , new_timecourses , atol = 1e-10 )
102+
103+ plt .close (g ._fig_sensors )
96104 g ._fig ._renderer .close ()
97105
98106
@@ -176,7 +184,7 @@ def test_dipolefit_gui_save_load(tmpdir, renderer_interactive_pyvistaqt):
176184 g .add_dipole (dip_from_file )
177185 g .add_dipole (mne .read_dipole (tmpdir / "test.bdip" ))
178186 assert len (g .dipoles ) == 6
179- assert [d .name for d in g .dipoles ] == ["rh1 " , "rh2 " , "rh1 " , "rh2 " , "dip4" , "dip5" ]
187+ assert [d .name for d in g .dipoles ] == ["rh " , "lh " , "rh " , "lh " , "dip4" , "dip5" ]
180188 assert_allclose (
181189 np .vstack ([d .pos for d in g .dipoles [:2 ]]), dip_from_file .pos , atol = 0
182190 )
0 commit comments