Esempio n. 1
0
def test_auto_topomap_coords():
    """Test mapping of coordinates in 3D space to 2D"""
    info = Raw(fif_fname).info.copy()
    picks = pick_types(info, meg=False, eeg=True, eog=False, stim=False)

    # Remove extra digitization point, so EEG digitization points match up
    # with the EEG channels
    del info['dig'][85]

    # Remove head origin from channel locations, so mapping with digitization
    # points yields the same result
    dig_kinds = (FIFF.FIFFV_POINT_CARDINAL,
                 FIFF.FIFFV_POINT_EEG,
                 FIFF.FIFFV_POINT_EXTRA)
    _, origin_head, _ = fit_sphere_to_headshape(info, dig_kinds)
    origin_head /= 1000.  # to meters
    for ch in info['chs']:
        ch['loc'][:3] -= origin_head

    # Use channel locations
    l0 = _auto_topomap_coords(info, picks)

    # Remove electrode position information, use digitization points from now
    # on.
    for ch in info['chs']:
        ch['loc'] = np.zeros(12)

    l1 = _auto_topomap_coords(info, picks)
    assert_allclose(l1, l0)

    # Test plotting mag topomap without channel locations: it should fail
    mag_picks = pick_types(info, meg='mag')
    assert_raises(ValueError, _auto_topomap_coords, info, mag_picks)

    # Test function with too many EEG digitization points: it should fail
    info['dig'].append({'r': [1, 2, 3], 'kind': FIFF.FIFFV_POINT_EEG})
    assert_raises(ValueError, _auto_topomap_coords, info, picks)

    # Test function with too little EEG digitization points: it should fail
    info['dig'] = info['dig'][:-2]
    assert_raises(ValueError, _auto_topomap_coords, info, picks)

    # Electrode positions must be unique
    info['dig'].append(info['dig'][-1])
    assert_raises(ValueError, _auto_topomap_coords, info, picks)

    # Test function without EEG digitization points: it should fail
    info['dig'] = [d for d in info['dig'] if d['kind'] != FIFF.FIFFV_POINT_EEG]
    assert_raises(RuntimeError, _auto_topomap_coords, info, picks)

    # Test function without any digitization points, it should fail
    info['dig'] = None
    assert_raises(RuntimeError, _auto_topomap_coords, info, picks)
    info['dig'] = []
    assert_raises(RuntimeError, _auto_topomap_coords, info, picks)
Esempio n. 2
0
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 = 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')
Esempio n. 3
0
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, )]
Esempio n. 5
0
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')
Esempio n. 6
0
def test_fit_sphere_to_headshape():
    """Test fitting a sphere to digitization points"""
    # Create points of various kinds
    dig = [
        # Left auricular
        {
            'coord_frame': FIFF.FIFFV_COORD_DEVICE,
            '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_DEVICE,
            '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_DEVICE,
            '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_DEVICE,
            'kind': FIFF.FIFFV_POINT_EXTRA,
            'r': np.array([0.0, 0.0, 1.0])
        },

        # EEG points
        # Fz
        {
            'coord_frame': FIFF.FIFFV_COORD_DEVICE,
            'kind': FIFF.FIFFV_POINT_EEG,
            'r': np.array([0, .72, .69])
        },
        # F3
        {
            'coord_frame': FIFF.FIFFV_COORD_DEVICE,
            'kind': FIFF.FIFFV_POINT_EEG,
            'r': np.array([-.55, .67, .50])
        },
        # F4
        {
            'coord_frame': FIFF.FIFFV_COORD_DEVICE,
            'kind': FIFF.FIFFV_POINT_EEG,
            'r': np.array([.55, .67, .50])
        },
        # Cz
        {
            'coord_frame': FIFF.FIFFV_COORD_DEVICE,
            'kind': FIFF.FIFFV_POINT_EEG,
            'r': np.array([0.0, 0.0, 1.0])
        },
        # Pz
        {
            'coord_frame': FIFF.FIFFV_COORD_DEVICE,
            'kind': FIFF.FIFFV_POINT_EEG,
            'r': np.array([0, -.72, .69])
        },
    ]

    # Device to head transformation (rotate .2 rad over X-axis)
    dev_head_t = {
        'from': FIFF.FIFFV_COORD_DEVICE,
        'to': FIFF.FIFFV_COORD_HEAD,
        'trans': rotation(x=0.2),
    }

    info = {'dig': dig, 'dev_head_t': dev_head_t}

    #  # 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)
    assert_almost_equal(r / 1000, 1.0, decimal=10)
    assert_almost_equal(oh / 1000, [0.0, 0.0, 0.0], decimal=10)
    assert_almost_equal(od / 1000, [0.0, 0.0, 0.0], decimal=10)

    # Test with all points. Digitization points are no longer perfect, so
    # allow for a wider margin of error.
    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_almost_equal(r / 1000, 1.0, decimal=3)
    assert_almost_equal(oh / 1000, [0.0, 0.0, 0.0], decimal=3)
    assert_almost_equal(od / 1000, [0.0, 0.0, 0.0], decimal=3)

    # 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)
    assert_almost_equal(r / 1000, 1.0, decimal=2)
    assert_almost_equal(oh / 1000, [0.0, 0.0, 0.0], decimal=2)
    assert_almost_equal(od / 1000, [0.0, 0.0, 0.0], decimal=2)
Esempio n. 7
0
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 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 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)
Esempio n. 8
0
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)
Esempio n. 9
0
def test_fit_sphere_to_headshape():
    """ Test fitting a sphere to digitization points. """
    # Create points of various kinds
    dig = [
        # Left auricular
        {'coord_frame': FIFF.FIFFV_COORD_DEVICE,
         '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_DEVICE,
         '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_DEVICE,
         '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_DEVICE,
         'kind': FIFF.FIFFV_POINT_EXTRA,
         'r': np.array([0.0, 0.0, 1.0])},

        # EEG points
        # Fz
        {'coord_frame': FIFF.FIFFV_COORD_DEVICE,
         'kind': FIFF.FIFFV_POINT_EEG,
         'r': np.array([0, .72, .69])},
        # F3
        {'coord_frame': FIFF.FIFFV_COORD_DEVICE,
         'kind': FIFF.FIFFV_POINT_EEG,
         'r': np.array([-.55, .67, .50])},
        # F4
        {'coord_frame': FIFF.FIFFV_COORD_DEVICE,
         'kind': FIFF.FIFFV_POINT_EEG,
         'r': np.array([.55, .67, .50])},
        # Cz
        {'coord_frame': FIFF.FIFFV_COORD_DEVICE,
         'kind': FIFF.FIFFV_POINT_EEG,
         'r': np.array([0.0, 0.0, 1.0])},
        # Pz
        {'coord_frame': FIFF.FIFFV_COORD_DEVICE,
         'kind': FIFF.FIFFV_POINT_EEG,
         'r': np.array([0, -.72, .69])},
    ]

    # Device to head transformation (rotate .2 rad over X-axis)
    dev_head_t = {
        'from': FIFF.FIFFV_COORD_DEVICE,
        'to': FIFF.FIFFV_COORD_HEAD,
        'trans': rotation(x=0.2),
    }

    info = {'dig': dig, 'dev_head_t': dev_head_t}

    #  # 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,
                                        verbose=logging.ERROR)
    assert_almost_equal(r / 1000, 1.0, decimal=10)
    assert_almost_equal(oh / 1000, [0.0, 0.0, 0.0], decimal=10)
    assert_almost_equal(od / 1000, [0.0, 0.0, 0.0], decimal=10)

    # Test with all points. Digitization points are no longer perfect, so
    # allow for a wider margin of error.
    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,
                                        verbose=logging.ERROR)
    assert_almost_equal(r / 1000, 1.0, decimal=3)
    assert_almost_equal(oh / 1000, [0.0, 0.0, 0.0], decimal=3)
    assert_almost_equal(od / 1000, [0.0, 0.0, 0.0], decimal=3)

    # 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,
                                        verbose=logging.ERROR)
    assert_almost_equal(r / 1000, 1.0, decimal=2)
    assert_almost_equal(oh / 1000, [0.0, 0.0, 0.0], decimal=2)
    assert_almost_equal(od / 1000, [0.0, 0.0, 0.0], decimal=2)
Esempio n. 10
0
def test_fit_sphere_to_headshape():
    """Test fitting a sphere to digitization points"""
    # Create points of various kinds
    rad = 90.0  # mm
    big_rad = 120.0
    center = np.array([0.5, -10.0, 40.0])  # mm
    dev_trans = np.array([0.0, -0.005, -10.0])
    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, 0.72, 0.69])},
        # F3
        {"coord_frame": FIFF.FIFFV_COORD_HEAD, "kind": FIFF.FIFFV_POINT_EEG, "r": np.array([-0.55, 0.67, 0.50])},
        # F4
        {"coord_frame": FIFF.FIFFV_COORD_HEAD, "kind": FIFF.FIFFV_POINT_EEG, "r": np.array([0.55, 0.67, 0.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, -0.72, 0.69])},
    ]
    for d in dig:
        d["r"] *= rad / 1000.0
        d["r"] += center / 1000.0

    # Device to head transformation (rotate .2 rad over X-axis)
    dev_head_t = Transform("meg", "head", translation(*(dev_trans / 1000.0)))

    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.0)  # 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.0)  # 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.0
        d["r"] *= big_rad / rad
        d["r"] += center / 1000.0
    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.0, -30, 0.0])
    for d in info_shift["dig"]:
        d["r"] -= center / 1000.0
        d["r"] += shift_center / 1000.0
    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)
Esempio n. 11
0
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')
Esempio n. 12
0
                fnum_raw = "%02d" % ii_raw
                mfp["input_file"] = raw_fname

                if len(session_input_files) > 1:
                    output_name_base = output_folder + "/" + session + "-" + fnum_raw
                else:
                    output_name_base = output_folder + "/" + session

                if not "empt" in session.lower():  #### TYPO IN ONE SESSION NAME: emptRy!!
                    # change this to test existence of initial HPI measurement...
                    mfp["output_file"] = output_name_base + mf_fname_suffix + ".fif"
                    mfp["mv_hp"] = output_name_base + mf_fname_suffix + ".pos"
                    mfp["logfile"] = output_name_base + mf_fname_suffix + ".log"
                    if radius_head is None:  # only needed once per study (same HPI digs)
                        raw = Raw(raw_fname)
                        radius_head, origin_head, origin_devive = fit_sphere_to_headshape(raw.info, verbose=VERBOSE)
                        raw.close()
                    mfp["origin_head"] = origin_head
                    mfp["radius_head"] = radius_head

                else:
                    mfp["output_file"] = output_name_base + mf_fname_suffix + ".fif"
                    mfp["mv_hp"] = None
                    mfp["logfile"] = output_name_base + mf_fname_suffix + ".log"
                    mfp["movecomp"] = False
                    mfp["hpicons"] = False
                    mfp["origin_head"] = False  # Must be False, if None, will try to estimate it!
                    mfp["radius_head"] = False

                # Since both session_input and session_output_files are lists, they
                # will now remain ordered 1-to-1
Esempio n. 13
0
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, )]
Esempio n. 14
0
                mfp['input_file'] = raw_fname

                if len(session_input_files) > 1:
                    output_name_base = output_folder + '/' + session + '-' + fnum_raw
                else:
                    output_name_base = output_folder + '/' + session

                if not 'empt' in session.lower(
                ):  #### TYPO IN ONE SESSION NAME: emptRy!!
                    # change this to test existence of initial HPI measurement...
                    mfp['output_file'] = output_name_base + mf_fname_suffix + '.fif'
                    mfp['mv_hp'] = output_name_base + mf_fname_suffix + '.pos'
                    mfp['logfile'] = output_name_base + mf_fname_suffix + '.log'
                    if radius_head is None:  # only needed once per study (same HPI digs)
                        raw = Raw(raw_fname)
                        radius_head, origin_head, origin_devive = fit_sphere_to_headshape(
                            raw.info, verbose=VERBOSE)
                        raw.close()
                    mfp['origin_head'] = origin_head
                    mfp['radius_head'] = radius_head

                else:
                    mfp['output_file'] = output_name_base + mf_fname_suffix + '.fif'
                    mfp['mv_hp'] = None
                    mfp['logfile'] = output_name_base + mf_fname_suffix + '.log'
                    mfp['movecomp'] = False
                    mfp['hpicons'] = False
                    mfp['origin_head'] = False  # Must be False, if None, will try to estimate it!
                    mfp['radius_head'] = False

                # Since both session_input and session_output_files are lists, they
                # will now remain ordered 1-to-1