def test_read_dig_polhemus_isotrak_eeg(isotrak_eeg): """Test reading Polhemus IsoTrak EEG positions.""" N_CHANNELS = 5 _SEED = 42 EXPECTED_FID_IN_POLHEMUS = { 'nasion': np.array([1.1056e-01, -5.4210e-19, 0]), 'lpa': np.array([-2.1075e-04, 8.0793e-02, -7.5894e-19]), 'rpa': np.array([2.1075e-04, -8.0793e-02, -2.8731e-18]), } ch_names = ['eeg {:01d}'.format(ii) for ii in range(N_CHANNELS)] EXPECTED_CH_POS = dict(zip( ch_names, np.random.RandomState(_SEED).randn(N_CHANNELS, 3))) montage = read_dig_polhemus_isotrak(fname=isotrak_eeg, ch_names=ch_names) assert repr(montage) == ( '<DigMontage | ' '0 extras (headshape), 0 HPIs, 3 fiducials, 5 channels>' ) fiducials, fid_coordframe = _get_fid_coords(montage.dig) assert fid_coordframe == FIFF.FIFFV_COORD_UNKNOWN for kk, val in fiducials.items(): assert_array_equal(val, EXPECTED_FID_IN_POLHEMUS[kk]) for kk, dig_point in zip(montage.ch_names, _get_dig_eeg(montage.dig)): assert_array_equal(dig_point['r'], EXPECTED_CH_POS[kk]) assert dig_point['coord_frame'] == FIFF.FIFFV_COORD_UNKNOWN
def test_read_dig_captrak(tmpdir): """Test reading a captrak montage file.""" EXPECTED_CH_NAMES_OLD = [ 'AF3', 'AF4', 'AF7', 'AF8', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'CP1', 'CP2', 'CP3', 'CP4', 'CP5', 'CP6', 'CPz', 'Cz', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'FC1', 'FC2', 'FC3', 'FC4', 'FC5', 'FC6', 'FT10', 'FT7', 'FT8', 'FT9', 'Fp1', 'Fp2', 'Fz', 'GND', 'O1', 'O2', 'Oz', 'P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'PO10', 'PO3', 'PO4', 'PO7', 'PO8', 'PO9', 'POz', 'Pz', 'REF', 'T7', 'T8', 'TP10', 'TP7', 'TP8', 'TP9' ] EXPECTED_CH_NAMES = [ 'T7', 'FC5', 'F7', 'C5', 'FT7', 'FT9', 'TP7', 'TP9', 'P7', 'CP5', 'PO7', 'C3', 'CP3', 'P5', 'P3', 'PO3', 'PO9', 'O1', 'Oz', 'POz', 'O2', 'PO4', 'P1', 'Pz', 'P2', 'CP2', 'CP1', 'CPz', 'Cz', 'C1', 'FC1', 'FC3', 'REF', 'F3', 'F1', 'Fz', 'F5', 'AF7', 'AF3', 'Fp1', 'GND', 'F2', 'AF4', 'Fp2', 'F4', 'F8', 'F6', 'AF8', 'FC2', 'FC6', 'FC4', 'C2', 'C4', 'P4', 'CP4', 'PO8', 'P8', 'P6', 'CP6', 'PO10', 'TP10', 'TP8', 'FT10', 'T8', 'C6', 'FT8' ] assert set(EXPECTED_CH_NAMES) == set(EXPECTED_CH_NAMES_OLD) montage = read_dig_captrak( fname=op.join(data_path, 'montage', 'captrak_coords.bvct')) # XXX: remove with 0.22 once captrCK is deprecated with pytest.warns(DeprecationWarning, match='read_dig_captrack is deprecated'): montage2 = read_dig_captrack( fname=op.join(data_path, 'montage', 'captrak_coords.bvct')) assert repr(montage) == repr(montage2) assert montage.ch_names == EXPECTED_CH_NAMES assert repr(montage) == ( '<DigMontage | ' '0 extras (headshape), 0 HPIs, 3 fiducials, 66 channels>') montage = transform_to_head(montage) # transform_to_head has to be tested _check_roundtrip(montage=montage, fname=str(tmpdir.join('bvct_test.fif'))) fid, _ = _get_fid_coords(montage.dig) assert_allclose( actual=np.array([fid.nasion, fid.lpa, fid.rpa]), desired=[[0, 0.11309, 0], [-0.09189, 0, 0], [0.09240, 0, 0]], atol=1e-5, ) raw_bv = read_raw_brainvision(bv_raw_fname) raw_bv.set_channel_types({"HEOG": 'eog', "VEOG": 'eog', "ECG": 'ecg'}) raw_bv.set_montage(montage) test_raw_bv = read_raw_fif(bv_fif_fname) # compare after set_montage using chs loc. for actual, expected in zip(raw_bv.info['chs'], test_raw_bv.info['chs']): assert_allclose(actual['loc'][:3], expected['loc'][:3]) if actual['kind'] == FIFF.FIFFV_EEG_CH: assert_allclose(actual['loc'][3:6], [-0.005103, 0.05395, 0.144622], rtol=1e-04)
def test_standard_montages_have_fids(kind): """Test standard montage are all in unknown coord (have fids).""" montage = make_standard_montage(kind) fids, coord_frame = _get_fid_coords(montage.dig) for k, v in fids.items(): assert v is not None, k for d in montage.dig: assert d['coord_frame'] == FIFF.FIFFV_COORD_UNKNOWN
def test_egi_dig_montage(): """Test EGI MFF XML dig montage support.""" dig_montage = read_dig_egi(egi_dig_montage_fname) fid, coord = _get_fid_coords(dig_montage.dig) assert coord == FIFF.FIFFV_COORD_UNKNOWN assert_allclose( actual=np.array([fid[key] for key in ['nasion', 'lpa', 'rpa']]), desired=[ [0., 10.564, -2.051], # noqa [-8.592, 0.498, -4.128], # noqa [8.592, 0.498, -4.128] ], # noqa ) # Test accuracy and embedding within raw object raw_egi = read_raw_egi(egi_raw_fname, channel_naming='EEG %03d') raw_egi.set_montage(dig_montage) test_raw_egi = read_raw_fif(egi_fif_fname) assert_equal(len(raw_egi.ch_names), len(test_raw_egi.ch_names)) for ch_raw, ch_test_raw in zip(raw_egi.info['chs'], test_raw_egi.info['chs']): assert_equal(ch_raw['ch_name'], ch_test_raw['ch_name']) assert_equal(ch_raw['coord_frame'], FIFF.FIFFV_COORD_HEAD) assert_allclose(ch_raw['loc'], ch_test_raw['loc'], atol=1e-7) assert_dig_allclose(raw_egi.info, test_raw_egi.info) dig_montage_in_head = transform_to_head(dig_montage.copy()) fid, coord = _get_fid_coords(dig_montage_in_head.dig) assert coord == FIFF.FIFFV_COORD_HEAD assert_allclose( actual=np.array([fid[key] for key in ['nasion', 'lpa', 'rpa']]), desired=[[0., 10.278, 0.], [-8.592, 0., 0.], [8.592, 0., 0.]], atol=1e-4, ) # test round-trip IO temp_dir = _TempDir() fname_temp = op.join(temp_dir, 'egi_test.fif') _check_roundtrip(dig_montage_in_head, fname_temp) # XXX: write forces head
def test_standard_montages_have_fids(kind): """Test standard montage are all in unknown coord (have fids).""" montage = make_standard_montage(kind) fids, coord_frame = _get_fid_coords(montage.dig) for k, v in fids.items(): assert v is not None, k for d in montage.dig: if kind.startswith(('artinis', 'standard', 'mgh')): want = FIFF.FIFFV_COORD_MRI else: want = FIFF.FIFFV_COORD_UNKNOWN assert d['coord_frame'] == want
def test_read_dig_polhemus_isotrak_elp(): """Test reading Polhemus IsoTrak ELP file.""" EXPECTED_FID_IN_POLHEMUS = { 'nasion': np.array([1.1056e-01, -5.4210e-19, 0]), 'lpa': np.array([-2.1075e-04, 8.0793e-02, -7.5894e-19]), 'rpa': np.array([2.1075e-04, -8.0793e-02, -2.8731e-18]), } montage = read_dig_polhemus_isotrak(fname=op.join(kit_dir, 'test.elp'), ch_names=None) assert repr(montage) == ( '<DigMontage | ' '0 extras (headshape), 5 HPIs, 3 fiducials, 0 channels>') fiducials, fid_coordframe = _get_fid_coords(montage.dig) assert fid_coordframe == FIFF.FIFFV_COORD_UNKNOWN for kk, val in fiducials.items(): assert_array_equal(val, EXPECTED_FID_IN_POLHEMUS[kk])
def test_read_dig_montage_using_polhemus_fastscan(): """Test FastScan.""" N_EEG_CH = 10 my_electrode_positions = read_polhemus_fastscan( op.join(kit_dir, 'test_elp.txt') ) montage = make_dig_montage( # EEG_CH ch_pos=dict(zip(ascii_lowercase[:N_EEG_CH], np.random.RandomState(0).rand(N_EEG_CH, 3))), # NO NAMED points nasion=my_electrode_positions[0], lpa=my_electrode_positions[1], rpa=my_electrode_positions[2], hpi=my_electrode_positions[3:], hsp=read_polhemus_fastscan(op.join(kit_dir, 'test_hsp.txt')), # Other defaults coord_frame='unknown' ) assert repr(montage) == ( '<DigMontage | ' '500 extras (headshape), 5 HPIs, 3 fiducials, 10 channels>' ) # XXX: is this wrong? extra is not in headspace, is it? assert set([d['coord_frame'] for d in montage.dig]) == { FIFF.FIFFV_COORD_UNKNOWN } # XXX: so far we build everything in 'unknown' EXPECTED_FID_IN_POLHEMUS = { 'nasion': [0.001393, 0.0131613, -0.0046967], 'lpa': [-0.0624997, -0.0737271, 0.07996], 'rpa': [-0.0748957, 0.0873785, 0.0811943], } fiducials, fid_coordframe = _get_fid_coords(montage.dig) assert fid_coordframe == FIFF.FIFFV_COORD_UNKNOWN for kk, val in fiducials.items(): assert_allclose(val, EXPECTED_FID_IN_POLHEMUS[kk])
def test_transform_to_head_and_compute_dev_head_t(): """Test transform_to_head and compute_dev_head_t.""" EXPECTED_DEV_HEAD_T = \ [[-3.72201691e-02, -9.98212167e-01, -4.67667497e-02, -7.31583414e-04], [8.98064989e-01, -5.39382685e-02, 4.36543170e-01, 1.60134431e-02], [-4.38285221e-01, -2.57513699e-02, 8.98466990e-01, 6.13035748e-02], [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]] EXPECTED_FID_IN_POLHEMUS = { 'nasion': np.array([0.001393, 0.0131613, -0.0046967]), 'lpa': np.array([-0.0624997, -0.0737271, 0.07996]), 'rpa': np.array([-0.0748957, 0.0873785, 0.0811943]), } EXPECTED_FID_IN_HEAD = { 'nasion': np.array([-8.94466792e-18, 1.10559624e-01, -3.85185989e-34]), 'lpa': np.array([-8.10816716e-02, 6.56321671e-18, 0]), 'rpa': np.array([8.05048781e-02, -6.47441364e-18, 0]), } hpi_dev = np.array( [[ 2.13951493e-02, 8.47444056e-02, -5.65431188e-02], # noqa [ 2.10299433e-02, -8.03141101e-02, -6.34420259e-02], # noqa [ 1.05916829e-01, 8.18485672e-05, 1.19928083e-02], # noqa [ 9.26595105e-02, 4.64804385e-02, 8.45141253e-03], # noqa [ 9.42554419e-02, -4.35206589e-02, 8.78999363e-03]] # noqa ) hpi_polhemus = np.array( [[-0.0595004, -0.0704836, 0.075893 ], # noqa [-0.0646373, 0.0838228, 0.0762123], # noqa [-0.0135035, 0.0072522, -0.0268405], # noqa [-0.0202967, -0.0351498, -0.0129305], # noqa [-0.0277519, 0.0452628, -0.0222407]] # noqa ) montage_polhemus = make_dig_montage( **EXPECTED_FID_IN_POLHEMUS, hpi=hpi_polhemus, coord_frame='unknown' ) montage_meg = make_dig_montage(hpi=hpi_dev, coord_frame='meg') # Test regular worflow to get dev_head_t montage = montage_polhemus + montage_meg fids, _ = _get_fid_coords(montage.dig) for kk in fids: assert_allclose(fids[kk], EXPECTED_FID_IN_POLHEMUS[kk], atol=1e-5) with pytest.raises(ValueError, match='set to head coordinate system'): _ = compute_dev_head_t(montage) montage = transform_to_head(montage) fids, _ = _get_fid_coords(montage.dig) for kk in fids: assert_allclose(fids[kk], EXPECTED_FID_IN_HEAD[kk], atol=1e-5) dev_head_t = compute_dev_head_t(montage) assert_allclose(dev_head_t['trans'], EXPECTED_DEV_HEAD_T, atol=1e-7) # Test errors when number of HPI points do not match EXPECTED_ERR_MSG = 'Device-to-Head .*Got 0 .*device and 5 points in head' with pytest.raises(ValueError, match=EXPECTED_ERR_MSG): _ = compute_dev_head_t(transform_to_head(montage_polhemus)) EXPECTED_ERR_MSG = 'Device-to-Head .*Got 5 .*device and 0 points in head' with pytest.raises(ValueError, match=EXPECTED_ERR_MSG): _ = compute_dev_head_t(transform_to_head( montage_meg + make_dig_montage(**EXPECTED_FID_IN_POLHEMUS) )) EXPECTED_ERR_MSG = 'Device-to-Head .*Got 3 .*device and 5 points in head' with pytest.raises(ValueError, match=EXPECTED_ERR_MSG): _ = compute_dev_head_t(transform_to_head( DigMontage(dig=_format_dig_points(montage_meg.dig[:3])) + montage_polhemus ))