def test_magnetic_dipole(): """Test basic magnetic dipole forward calculation.""" trans = Transform('mri', 'head') info = read_info(fname_raw) picks = pick_types(info, meg=True, eeg=False, exclude=[]) info = pick_info(info, picks[:12]) coils = _create_meg_coils(info['chs'], 'normal', trans) # magnetic dipole at device origin r0 = np.array([0., 13., -6.]) for ch, coil in zip(info['chs'], coils): rr = (ch['loc'][:3] + r0) / 2. far_fwd = _magnetic_dipole_field_vec(r0[np.newaxis, :], [coil]) near_fwd = _magnetic_dipole_field_vec(rr[np.newaxis, :], [coil]) ratio = 8. if ch['ch_name'][-1] == '1' else 16. # grad vs mag assert_allclose(np.median(near_fwd / far_fwd), ratio, atol=1e-1)
def test_fit_sphere_to_headshape(): """Test fitting a sphere to digitization points.""" # Create points of various kinds rad = 0.09 big_rad = 0.12 center = np.array([0.0005, -0.01, 0.04]) dev_trans = np.array([0., -0.005, -0.01]) dev_center = center - dev_trans dig = [ # Left auricular {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_LPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([-1.0, 0.0, 0.0])}, # Nasion {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_NASION, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([0.0, 1.0, 0.0])}, # Right auricular {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_RPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([1.0, 0.0, 0.0])}, # Top of the head (extra point) {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EXTRA, 'ident': 0, 'r': np.array([0.0, 0.0, 1.0])}, # EEG points # Fz {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'ident': 0, 'r': np.array([0, .72, .69])}, # F3 {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'ident': 1, 'r': np.array([-.55, .67, .50])}, # F4 {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'ident': 2, 'r': np.array([.55, .67, .50])}, # Cz {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'ident': 3, 'r': np.array([0.0, 0.0, 1.0])}, # Pz {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'ident': 4, 'r': np.array([0, -.72, .69])}, ] for d in dig: d['r'] *= rad d['r'] += center # Device to head transformation (rotate .2 rad over X-axis) dev_head_t = Transform('meg', 'head', translation(*(dev_trans))) info = Info(dig=dig, dev_head_t=dev_head_t) # Degenerate conditions pytest.raises(ValueError, fit_sphere_to_headshape, info, dig_kinds=(FIFF.FIFFV_POINT_HPI,)) pytest.raises(ValueError, fit_sphere_to_headshape, info, dig_kinds='foo', units='m') info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_DEVICE pytest.raises(RuntimeError, fit_sphere_to_headshape, info, units='m') info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_HEAD # # Test with 4 points that match a perfect sphere dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) with pytest.warns(RuntimeWarning, match='Only .* head digitization'): r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units='m') kwargs = dict(rtol=1e-3, atol=1e-5) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with all points dig_kinds = ('cardinal', FIFF.FIFFV_POINT_EXTRA, 'eeg') kwargs = dict(rtol=1e-3, atol=1e-3) with pytest.warns(RuntimeWarning, match='Only .* head digitization'): r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units='m') assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with some noisy EEG points only. dig_kinds = 'eeg' with pytest.warns(RuntimeWarning, match='Only .* head digitization'): r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units='m') kwargs = dict(rtol=1e-3, atol=1e-2) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, center, **kwargs) # Test big size dig_kinds = ('cardinal', 'extra') info_big = deepcopy(info) for d in info_big['dig']: d['r'] -= center d['r'] *= big_rad / rad d['r'] += center with pytest.warns(RuntimeWarning, match='Estimated head size'): r, oh, od = fit_sphere_to_headshape(info_big, dig_kinds=dig_kinds, units='mm') assert_allclose(oh, center * 1000, atol=1e-3) assert_allclose(r, big_rad * 1000, atol=1e-3) del info_big # Test offcenter dig_kinds = ('cardinal', 'extra') info_shift = deepcopy(info) shift_center = np.array([0., -0.03, 0.]) for d in info_shift['dig']: d['r'] -= center d['r'] += shift_center with pytest.warns(RuntimeWarning, match='from head frame origin'): r, oh, od = fit_sphere_to_headshape( info_shift, dig_kinds=dig_kinds, units='m') assert_allclose(oh, shift_center, atol=1e-6) assert_allclose(r, rad, atol=1e-6) # Test "auto" mode (default) # Should try "extra", fail, and go on to EEG with pytest.warns(RuntimeWarning, match='Only .* head digitization'): r, oh, od = fit_sphere_to_headshape(info, units='m') kwargs = dict(rtol=1e-3, atol=1e-3) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) with pytest.warns(RuntimeWarning, match='Only .* head digitization'): r2, oh2, od2 = fit_sphere_to_headshape(info, units='m') assert_allclose(r, r2, atol=1e-7) assert_allclose(oh, oh2, atol=1e-7) assert_allclose(od, od2, atol=1e-7) # this one should pass, 1 EXTRA point and 3 EEG (but the fit is terrible) info = Info(dig=dig[:7], dev_head_t=dev_head_t) with pytest.warns(RuntimeWarning, match='Only .* head digitization'): r, oh, od = fit_sphere_to_headshape(info, units='m') # this one should fail, 1 EXTRA point and 3 EEG (but the fit is terrible) info = Info(dig=dig[:6], dev_head_t=dev_head_t) pytest.raises(ValueError, fit_sphere_to_headshape, info, units='m') pytest.raises(TypeError, fit_sphere_to_headshape, 1, units='m')
def test_fit_sphere_to_headshape(): """Test fitting a sphere to digitization points""" # Create points of various kinds rad = 90. # mm center = np.array([0.5, -10., 40.]) # mm dev_trans = np.array([0., -0.005, -10.]) dev_center = center - dev_trans dig = [ # Left auricular { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_LPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([-1.0, 0.0, 0.0]) }, # Nasion { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_NASION, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([0.0, 1.0, 0.0]) }, # Right auricular { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_RPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([1.0, 0.0, 0.0]) }, # Top of the head (extra point) { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EXTRA, 'r': np.array([0.0, 0.0, 1.0]) }, # EEG points # Fz { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0, .72, .69]) }, # F3 { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([-.55, .67, .50]) }, # F4 { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([.55, .67, .50]) }, # Cz { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0.0, 0.0, 1.0]) }, # Pz { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0, -.72, .69]) }, ] for d in dig: d['r'] *= rad / 1000. d['r'] += center / 1000. # Device to head transformation (rotate .2 rad over X-axis) dev_head_t = Transform('meg', 'head', translation(*(dev_trans / 1000.))) info = {'dig': dig, 'dev_head_t': dev_head_t} # Degenerate conditions assert_raises(ValueError, fit_sphere_to_headshape, info, dig_kinds=(FIFF.FIFFV_POINT_HPI, )) info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_DEVICE assert_raises(RuntimeError, fit_sphere_to_headshape, info) info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_HEAD # # Test with 4 points that match a perfect sphere dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds) kwargs = dict(rtol=1e-3, atol=1e-2) # in mm assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with all points dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA, FIFF.FIFFV_POINT_EXTRA) r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with some noisy EEG points only. dig_kinds = (FIFF.FIFFV_POINT_EEG, ) r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds) kwargs = dict(rtol=1e-3, atol=10.) # in mm assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, center, **kwargs) dig = [dict(coord_frame=FIFF.FIFFV_COORD_DEVICE, )]
def test_fit_sphere_to_headshape(): """Test fitting a sphere to digitization points""" # Create points of various kinds rad = 0.09 big_rad = 0.12 center = np.array([0.0005, -0.01, 0.04]) dev_trans = np.array([0., -0.005, -0.01]) dev_center = center - dev_trans dig = [ # Left auricular { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_LPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([-1.0, 0.0, 0.0]) }, # Nasion { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_NASION, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([0.0, 1.0, 0.0]) }, # Right auricular { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_RPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([1.0, 0.0, 0.0]) }, # Top of the head (extra point) { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EXTRA, 'r': np.array([0.0, 0.0, 1.0]) }, # EEG points # Fz { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0, .72, .69]) }, # F3 { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([-.55, .67, .50]) }, # F4 { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([.55, .67, .50]) }, # Cz { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0.0, 0.0, 1.0]) }, # Pz { 'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0, -.72, .69]) }, ] for d in dig: d['r'] *= rad d['r'] += center # Device to head transformation (rotate .2 rad over X-axis) dev_head_t = Transform('meg', 'head', translation(*(dev_trans))) info = {'dig': dig, 'dev_head_t': dev_head_t} # Degenerate conditions with warnings.catch_warnings(record=True) as w: assert_raises(ValueError, fit_sphere_to_headshape, info, dig_kinds=(FIFF.FIFFV_POINT_HPI, )) assert_equal(len(w), 1) assert_true(w[0].category == DeprecationWarning) assert_raises(ValueError, fit_sphere_to_headshape, info, dig_kinds='foo', units='m') info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_DEVICE assert_raises(RuntimeError, fit_sphere_to_headshape, info, units='m') info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_HEAD # # Test with 4 points that match a perfect sphere dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) with warnings.catch_warnings(record=True): # not enough points r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units='m') kwargs = dict(rtol=1e-3, atol=1e-5) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with all points dig_kinds = ('cardinal', FIFF.FIFFV_POINT_EXTRA, 'eeg') kwargs = dict(rtol=1e-3, atol=1e-3) with warnings.catch_warnings(record=True): # not enough points r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units='m') assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with some noisy EEG points only. dig_kinds = 'eeg' with warnings.catch_warnings(record=True): # not enough points r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units='m') kwargs = dict(rtol=1e-3, atol=1e-2) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, center, **kwargs) # Test big size dig_kinds = ('cardinal', 'extra') info_big = deepcopy(info) for d in info_big['dig']: d['r'] -= center d['r'] *= big_rad / rad d['r'] += center with warnings.catch_warnings(record=True): # fit with catch_logging() as log_file: r, oh, od = fit_sphere_to_headshape(info_big, dig_kinds=dig_kinds, verbose='warning', units='mm') log_file = log_file.getvalue().strip() assert_equal(len(log_file.split('\n')), 2) assert_true('Estimated head size' in log_file) assert_allclose(oh, center * 1000, atol=1e-3) assert_allclose(r, big_rad * 1000, atol=1e-3) del info_big # Test offcenter dig_kinds = ('cardinal', 'extra') info_shift = deepcopy(info) shift_center = np.array([0., -0.03, 0.]) for d in info_shift['dig']: d['r'] -= center d['r'] += shift_center with warnings.catch_warnings(record=True): with catch_logging() as log_file: r, oh, od = fit_sphere_to_headshape(info_shift, dig_kinds=dig_kinds, verbose='warning', units='m') log_file = log_file.getvalue().strip() assert_equal(len(log_file.split('\n')), 2) assert_true('from head frame origin' in log_file) assert_allclose(oh, shift_center, atol=1e-6) assert_allclose(r, rad, atol=1e-6) # Test "auto" mode (default) # Should try "extra", fail, and go on to EEG with warnings.catch_warnings(record=True): # not enough points r, oh, od = fit_sphere_to_headshape(info, units='m') kwargs = dict(rtol=1e-3, atol=1e-3) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) with warnings.catch_warnings(record=True): # not enough points r2, oh2, od2 = fit_sphere_to_headshape(info, units='m') assert_allclose(r, r2, atol=1e-7) assert_allclose(oh, oh2, atol=1e-7) assert_allclose(od, od2, atol=1e-7) # this one should pass, 1 EXTRA point and 3 EEG (but the fit is terrible) info = {'dig': dig[:7], 'dev_head_t': dev_head_t} with warnings.catch_warnings(record=True): # bad fit r, oh, od = fit_sphere_to_headshape(info, units='m') # this one should fail, 1 EXTRA point and 3 EEG (but the fit is terrible) info = {'dig': dig[:6], 'dev_head_t': dev_head_t} assert_raises(ValueError, fit_sphere_to_headshape, info, units='m')
def test_fit_sphere_to_headshape(): """Test fitting a sphere to digitization points""" # Create points of various kinds rad = 90. # mm big_rad = 120. center = np.array([0.5, -10., 40.]) # mm dev_trans = np.array([0., -0.005, -10.]) dev_center = center - dev_trans dig = [ # Left auricular {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_LPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([-1.0, 0.0, 0.0])}, # Nasion {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_NASION, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([0.0, 1.0, 0.0])}, # Right auricular {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'ident': FIFF.FIFFV_POINT_RPA, 'kind': FIFF.FIFFV_POINT_CARDINAL, 'r': np.array([1.0, 0.0, 0.0])}, # Top of the head (extra point) {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EXTRA, 'r': np.array([0.0, 0.0, 1.0])}, # EEG points # Fz {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0, .72, .69])}, # F3 {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([-.55, .67, .50])}, # F4 {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([.55, .67, .50])}, # Cz {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0.0, 0.0, 1.0])}, # Pz {'coord_frame': FIFF.FIFFV_COORD_HEAD, 'kind': FIFF.FIFFV_POINT_EEG, 'r': np.array([0, -.72, .69])}, ] for d in dig: d['r'] *= rad / 1000. d['r'] += center / 1000. # Device to head transformation (rotate .2 rad over X-axis) dev_head_t = Transform('meg', 'head', translation(*(dev_trans / 1000.))) info = {'dig': dig, 'dev_head_t': dev_head_t} # Degenerate conditions assert_raises(ValueError, fit_sphere_to_headshape, info, dig_kinds=(FIFF.FIFFV_POINT_HPI,)) info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_DEVICE assert_raises(RuntimeError, fit_sphere_to_headshape, info) info['dig'][0]['coord_frame'] = FIFF.FIFFV_COORD_HEAD # # Test with 4 points that match a perfect sphere dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds) kwargs = dict(rtol=1e-3, atol=1e-2) # in mm assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with all points dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA, FIFF.FIFFV_POINT_EEG) kwargs = dict(rtol=1e-3, atol=1.) # in mm r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) # Test with some noisy EEG points only. dig_kinds = (FIFF.FIFFV_POINT_EEG,) r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds) kwargs = dict(rtol=1e-3, atol=10.) # in mm assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, center, **kwargs) # Test big size dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) info_big = deepcopy(info) for d in info_big['dig']: d['r'] -= center / 1000. d['r'] *= big_rad / rad d['r'] += center / 1000. with warnings.catch_warnings(record=True): # fit with catch_logging() as log_file: r, oh, od = fit_sphere_to_headshape(info_big, dig_kinds=dig_kinds, verbose='warning') log_file = log_file.getvalue().strip() assert_equal(len(log_file.split('\n')), 1) assert_true(log_file.startswith('Estimated head size')) assert_allclose(oh, center, atol=1e-3) assert_allclose(r, big_rad, atol=1e-3) del info_big # Test offcenter dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) info_shift = deepcopy(info) shift_center = np.array([0., -30, 0.]) for d in info_shift['dig']: d['r'] -= center / 1000. d['r'] += shift_center / 1000. with warnings.catch_warnings(record=True): with catch_logging() as log_file: r, oh, od = fit_sphere_to_headshape( info_shift, dig_kinds=dig_kinds, verbose='warning') log_file = log_file.getvalue().strip() assert_equal(len(log_file.split('\n')), 1) assert_true('from head frame origin' in log_file) assert_allclose(oh, shift_center, atol=1e-3) assert_allclose(r, rad, atol=1e-3)