def test_read_locs(): """Test reading EEGLAB locs.""" pos = read_montage(locs_montage_fname).pos expected = [[0., 9.99779165e-01, -2.10157875e-02], [3.08738197e-01, 7.27341573e-01, -6.12907052e-01], [-5.67059636e-01, 6.77066318e-01, 4.69067752e-01], [0., 7.14575231e-01, 6.99558616e-01]] assert_allclose(pos[:4], expected, atol=1e-7)
def test_set_montage(): """Test setting a montage.""" raw = read_raw_fif(fif_fname) mon = read_montage('mgh60') orig_pos = np.array([ch['loc'][:3] for ch in raw.info['chs'] if ch['ch_name'].startswith('EEG')]) raw.set_montage(mon) new_pos = np.array([ch['loc'][:3] for ch in raw.info['chs'] if ch['ch_name'].startswith('EEG')]) assert_true((orig_pos != new_pos).all()) r0 = _fit_sphere(new_pos)[1] assert_allclose(r0, [0., -0.016, 0.], atol=1e-3)
def test_set_montage(): """Test setting a montage.""" raw = read_raw_fif(fif_fname) orig_pos = np.array([ch['loc'][:3] for ch in raw.info['chs'] if ch['ch_name'].startswith('EEG')]) raw.set_montage('mgh60') # test loading with string argument new_pos = np.array([ch['loc'][:3] for ch in raw.info['chs'] if ch['ch_name'].startswith('EEG')]) assert ((orig_pos != new_pos).all()) r0 = _fit_sphere(new_pos)[1] assert_allclose(r0, [0., -0.016, 0.], atol=1e-3) # mgh70 has no 61/62/63/64 (these are EOG/ECG) mon = read_montage('mgh70') assert 'EEG061' not in mon.ch_names assert 'EEG074' in mon.ch_names
def test_set_montage(): """Test setting a montage.""" raw = read_raw_fif(fif_fname) orig_pos = np.array([ch['loc'][:3] for ch in raw.info['chs'] if ch['ch_name'].startswith('EEG')]) raw.set_montage('mgh60') # test loading with string argument new_pos = np.array([ch['loc'][:3] for ch in raw.info['chs'] if ch['ch_name'].startswith('EEG')]) assert_true((orig_pos != new_pos).all()) r0 = _fit_sphere(new_pos)[1] assert_allclose(r0, [0., -0.016, 0.], atol=1e-3) # mgh70 has no 61/62/63/64 (these are EOG/ECG) mon = read_montage('mgh70') assert 'EEG061' not in mon.ch_names assert 'EEG074' in mon.ch_names
def test_make_info(): """Test some create_info properties """ n_ch = 1 info = create_info(n_ch, 1000., 'eeg') assert_equal(sorted(info.keys()), sorted(RAW_INFO_FIELDS)) coil_types = set([ch['coil_type'] for ch in info['chs']]) assert_true(FIFF.FIFFV_COIL_EEG in coil_types) assert_raises(TypeError, create_info, ch_names='Test Ch', sfreq=1000) assert_raises(ValueError, create_info, ch_names=['Test Ch'], sfreq=-1000) assert_raises(ValueError, create_info, ch_names=['Test Ch'], sfreq=1000, ch_types=['eeg', 'eeg']) assert_raises(TypeError, create_info, ch_names=[np.array([1])], sfreq=1000) assert_raises(TypeError, create_info, ch_names=['Test Ch'], sfreq=1000, ch_types=np.array([1])) assert_raises(KeyError, create_info, ch_names=['Test Ch'], sfreq=1000, ch_types='awesome') assert_raises(TypeError, create_info, ['Test Ch'], sfreq=1000, ch_types=None, montage=np.array([1])) m = read_montage('biosemi32') info = create_info(ch_names=m.ch_names, sfreq=1000., ch_types='eeg', montage=m) ch_pos = [ch['loc'][:3] for ch in info['chs']] assert_array_equal(ch_pos, m.pos) names = ['nasion', 'lpa', 'rpa', '1', '2', '3', '4', '5'] d = read_dig_montage(hsp_fname, None, elp_fname, names, unit='m', transform=False) info = create_info(ch_names=m.ch_names, sfreq=1000., ch_types='eeg', montage=d) idents = [p['ident'] for p in info['dig']] assert_true(FIFF.FIFFV_POINT_NASION in idents) info = create_info(ch_names=m.ch_names, sfreq=1000., ch_types='eeg', montage=[d, m]) ch_pos = [ch['loc'][:3] for ch in info['chs']] assert_array_equal(ch_pos, m.pos) idents = [p['ident'] for p in info['dig']] assert_true(FIFF.FIFFV_POINT_NASION in idents) info = create_info(ch_names=m.ch_names, sfreq=1000., ch_types='eeg', montage=[d, 'biosemi32']) ch_pos = [ch['loc'][:3] for ch in info['chs']] assert_array_equal(ch_pos, m.pos) idents = [p['ident'] for p in info['dig']] assert_true(FIFF.FIFFV_POINT_NASION in idents)
def test_make_info(): """Test some create_info properties.""" n_ch = 1 info = create_info(n_ch, 1000.0, "eeg") assert_equal(sorted(info.keys()), sorted(RAW_INFO_FIELDS)) coil_types = set([ch["coil_type"] for ch in info["chs"]]) assert_true(FIFF.FIFFV_COIL_EEG in coil_types) assert_raises(TypeError, create_info, ch_names="Test Ch", sfreq=1000) assert_raises(ValueError, create_info, ch_names=["Test Ch"], sfreq=-1000) assert_raises(ValueError, create_info, ch_names=["Test Ch"], sfreq=1000, ch_types=["eeg", "eeg"]) assert_raises(TypeError, create_info, ch_names=[np.array([1])], sfreq=1000) assert_raises(TypeError, create_info, ch_names=["Test Ch"], sfreq=1000, ch_types=np.array([1])) assert_raises(KeyError, create_info, ch_names=["Test Ch"], sfreq=1000, ch_types="awesome") assert_raises(TypeError, create_info, ["Test Ch"], sfreq=1000, ch_types=None, montage=np.array([1])) m = read_montage("biosemi32") info = create_info(ch_names=m.ch_names, sfreq=1000.0, ch_types="eeg", montage=m) ch_pos = [ch["loc"][:3] for ch in info["chs"]] assert_array_equal(ch_pos, m.pos) names = ["nasion", "lpa", "rpa", "1", "2", "3", "4", "5"] d = read_dig_montage(hsp_fname, None, elp_fname, names, unit="m", transform=False) info = create_info(ch_names=m.ch_names, sfreq=1000.0, ch_types="eeg", montage=d) idents = [p["ident"] for p in info["dig"]] assert_true(FIFF.FIFFV_POINT_NASION in idents) info = create_info(ch_names=m.ch_names, sfreq=1000.0, ch_types="eeg", montage=[d, m]) ch_pos = [ch["loc"][:3] for ch in info["chs"]] assert_array_equal(ch_pos, m.pos) idents = [p["ident"] for p in info["dig"]] assert_true(FIFF.FIFFV_POINT_NASION in idents) info = create_info(ch_names=m.ch_names, sfreq=1000.0, ch_types="eeg", montage=[d, "biosemi32"]) ch_pos = [ch["loc"][:3] for ch in info["chs"]] assert_array_equal(ch_pos, m.pos) idents = [p["ident"] for p in info["dig"]] assert_true(FIFF.FIFFV_POINT_NASION in idents)
def test_montage(): """Test making montages.""" tempdir = _TempDir() inputs = dict( sfp='FidNz 0 9.071585155 -2.359754454\n' 'FidT9 -6.711765 0.040402876 -3.251600355\n' 'very_very_very_long_name -5.831241498 -4.494821698 4.955347697\n' 'Cz 0 0 8.899186843', csd='// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501 '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501 'E31 90.000 -11.000 1.000 0.0000 0.9816 -0.1908 0.00000000000000000\n' # noqa: E501 'E61 158.000 -17.200 1.000 -0.8857 0.3579 -0.2957 -0.00000000000000022', # noqa: E501 mm_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' # noqa:E501 'NumberPositions= 68\n' 'Positions\n' '-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n' '0.0083 86.8110 -39.9830\n' '-86.0761 -24.9897 -67.9860\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', m_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n' 'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' # noqa:E501 '.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n' '.08 -.02 -.04\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', txt='Site Theta Phi\n' 'Fp1 -92 -72\n' 'Fp2 92 72\n' 'very_very_very_long_name -92 72\n' 'O2 92 -90\n', elp='346\n' 'EEG\t F3\t -62.027\t -50.053\t 85\n' 'EEG\t Fz\t 45.608\t 90\t 85\n' 'EEG\t F4\t 62.01\t 50.103\t 85\n' 'EEG\t FCz\t 68.01\t 58.103\t 85\n', hpts='eeg Fp1 -95.0 -3. -3.\n' 'eeg AF7 -1 -1 -3\n' 'eeg A3 -2 -2 2\n' 'eeg A 0 0 0', ) # Get actual positions and save them for checking # csd comes from the string above, all others come from commit 2fa35d4 poss = dict( sfp=[[0.0, 9.07159, -2.35975], [-6.71176, 0.0404, -3.2516], [-5.83124, -4.49482, 4.95535], [0.0, 0.0, 8.89919]], mm_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.08681, -0.03998], [-0.08608, -0.02499, -0.06799]], m_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.00868, -0.03998], [0.08, -0.02, -0.04]], txt=[[-26.25044, 80.79056, -2.96646], [26.25044, 80.79056, -2.96646], [-26.25044, -80.79056, -2.96646], [0.0, -84.94822, -2.96646]], elp=[[-48.20043, 57.55106, 39.86971], [0.0, 60.73848, 59.4629], [48.1426, 57.58403, 39.89198], [41.64599, 66.91489, 31.8278]], hpts=[[-95, -3, -3], [-1, -1., -3.], [-2, -2, 2.], [0, 0, 0]], ) for key, text in inputs.items(): kind = key.split('_')[-1] fname = op.join(tempdir, 'test.' + kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if kind in ('sfp', 'txt'): assert_true('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 4) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (4, 3)) assert_equal(montage.kind, 'test') if kind == 'csd': dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) poss['csd'] = np.c_[table['x'], table['y'], table['z']] if kind == 'elc': # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis( np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) assert_array_almost_equal(poss[key], montage.pos, 4, err_msg=key) # Test reading in different letter case. ch_names = ["F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3", "CPZ", "CP4", "P3", "PZ", "P4", "O1", "OZ", "O2"] montage = read_montage('standard_1020', ch_names=ch_names) assert_array_equal(ch_names, montage.ch_names) # test transform input_strs = [""" eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """, """ Fp1 -95.0 -31.0 -3.0 AF7 -81 -59 -3 AF3 -87 -41 28 nasion -91 0 -42 lpa 0 -91 -42 rpa 0 91 -42 """] all_fiducials = [['2', '1', '3'], ['nasion', 'lpa', 'rpa']] kinds = ['test_fid.hpts', 'test_fid.sfp'] for kind, fiducials, input_str in zip(kinds, all_fiducials, input_strs): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, kind), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index(fiducials[0]) assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index(fiducials[1]) assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index(fiducials[2]) assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, kind) montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info( montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray( data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1) # Channel names can be treated case insensitive with warnings.catch_warnings(record=True) as w: info = create_info(['FP1', 'af7', 'AF3'], 1e3, ['eeg'] * 3) _set_montage(info, montage) assert_true(len(w) == 0) # Unless there is a collision in names with warnings.catch_warnings(record=True) as w: info = create_info(['FP1', 'Fp1', 'AF3'], 1e3, ['eeg'] * 3) _set_montage(info, montage) assert_true(len(w) == 1) with warnings.catch_warnings(record=True) as w: montage.ch_names = ['FP1', 'Fp1', 'AF3'] info = create_info(['fp1', 'AF3'], 1e3, ['eeg', 'eeg']) _set_montage(info, montage) assert_true(len(w) == 1)
def test_montage(): """Test making montages.""" tempdir = _TempDir() inputs = dict( sfp='FidNz 0 9.071585155 -2.359754454\n' 'FidT9 -6.711765 0.040402876 -3.251600355\n' 'very_very_very_long_name -5.831241498 -4.494821698 4.955347697\n' 'Cz 0 0 8.899186843', csd= '// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501 '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501 'E31 90.000 -11.000 1.000 0.0000 0.9816 -0.1908 0.00000000000000000\n' # noqa: E501 'E61 158.000 -17.200 1.000 -0.8857 0.3579 -0.2957 -0.00000000000000022', # noqa: E501 mm_elc= '# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' # noqa:E501 'NumberPositions= 68\n' 'Positions\n' '-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n' '0.0083 86.8110 -39.9830\n' '-86.0761 -24.9897 -67.9860\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', m_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n' 'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' # noqa:E501 '.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n' '.08 -.02 -.04\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', txt='Site Theta Phi\n' 'Fp1 -92 -72\n' 'Fp2 92 72\n' 'very_very_very_long_name -92 72\n' 'O2 92 -90\n', elp='346\n' 'EEG\t F3\t -62.027\t -50.053\t 85\n' 'EEG\t Fz\t 45.608\t 90\t 85\n' 'EEG\t F4\t 62.01\t 50.103\t 85\n' 'EEG\t FCz\t 68.01\t 58.103\t 85\n', hpts='eeg Fp1 -95.0 -3. -3.\n' 'eeg AF7 -1 -1 -3\n' 'eeg A3 -2 -2 2\n' 'eeg A 0 0 0', bvef='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' '<!-- Generated by EasyCap Configurator 19.05.2014 -->\n' '<Electrodes defaults="false">\n' ' <Electrode>\n' ' <Name>Fp1</Name>\n' ' <Theta>-90</Theta>\n' ' <Phi>-72</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>1</Number>\n' ' </Electrode>\n' ' <Electrode>\n' ' <Name>Fz</Name>\n' ' <Theta>45</Theta>\n' ' <Phi>90</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>2</Number>\n' ' </Electrode>\n' ' <Electrode>\n' ' <Name>F3</Name>\n' ' <Theta>-60</Theta>\n' ' <Phi>-51</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>3</Number>\n' ' </Electrode>\n' ' <Electrode>\n' ' <Name>F7</Name>\n' ' <Theta>-90</Theta>\n' ' <Phi>-36</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>4</Number>\n' ' </Electrode>\n' '</Electrodes>', ) # Get actual positions and save them for checking # csd comes from the string above, all others come from commit 2fa35d4 poss = dict( sfp=[[0.0, 9.07159, -2.35975], [-6.71176, 0.0404, -3.2516], [-5.83124, -4.49482, 4.95535], [0.0, 0.0, 8.89919]], mm_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.08681, -0.03998], [-0.08608, -0.02499, -0.06799]], m_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.00868, -0.03998], [0.08, -0.02, -0.04]], txt=[[-26.25044, 80.79056, -2.96646], [26.25044, 80.79056, -2.96646], [-26.25044, -80.79056, -2.96646], [0.0, -84.94822, -2.96646]], elp=[[-48.20043, 57.55106, 39.86971], [0.0, 60.73848, 59.4629], [48.1426, 57.58403, 39.89198], [41.64599, 66.91489, 31.8278]], hpts=[[-95, -3, -3], [-1, -1., -3.], [-2, -2, 2.], [0, 0, 0]], bvef=[[-26.266444, 80.839803, 5.204748e-15], [3.680313e-15, 60.104076, 60.104076], [-46.325632, 57.207392, 42.500000], [-68.766444, 49.961746, 5.204748e-15]], ) for key, text in inputs.items(): kind = key.split('_')[-1] fname = op.join(tempdir, 'test.' + kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if kind in ('sfp', 'txt'): assert ('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 4) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (4, 3)) assert_equal(montage.kind, 'test') if kind == 'csd': dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) poss['csd'] = np.c_[table['x'], table['y'], table['z']] if kind == 'elc': # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis( np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) assert_array_almost_equal(poss[key], montage.pos, 4, err_msg=key) # Test reading in different letter case. ch_names = [ "F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3", "CPZ", "CP4", "P3", "PZ", "P4", "O1", "OZ", "O2" ] montage = read_montage('standard_1020', ch_names=ch_names) assert_array_equal(ch_names, montage.ch_names) # test transform input_strs = [ """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """, """ Fp1 -95.0 -31.0 -3.0 AF7 -81 -59 -3 AF3 -87 -41 28 FidNz -91 0 -42 FidT9 0 -91 -42 FidT10 0 91 -42 """ ] # sfp files seem to have Nz, T9, and T10 as fiducials: # https://github.com/mne-tools/mne-python/pull/4482#issuecomment-321980611 kinds = ['test_fid.hpts', 'test_fid.sfp'] for kind, input_str in zip(kinds, input_strs): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, kind), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) assert_array_equal(montage.nasion[[0, 2]], [0, 0]) assert_array_equal(montage.lpa[[1, 2]], [0, 0]) assert_array_equal(montage.rpa[[1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, kind) montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray(data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) # test return type as well as set montage assert (isinstance(evoked.set_montage(montage), type(evoked))) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in montage info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) with pytest.warns(RuntimeWarning, match='position specified'): _set_montage(info, montage) # Channel names can be treated case insensitive info = create_info(['FP1', 'af7', 'AF3'], 1e3, ['eeg'] * 3) _set_montage(info, montage) # Unless there is a collision in names info = create_info(['FP1', 'Fp1', 'AF3'], 1e3, ['eeg'] * 3) assert (info['dig'] is None) with pytest.warns(RuntimeWarning, match='position specified'): _set_montage(info, montage) assert len(info['dig']) == 5 # 2 EEG w/pos, 3 fiducials montage.ch_names = ['FP1', 'Fp1', 'AF3'] info = create_info(['fp1', 'AF3'], 1e3, ['eeg', 'eeg']) assert (info['dig'] is None) with pytest.warns(RuntimeWarning, match='position specified'): _set_montage(info, montage, set_dig=False) assert (info['dig'] is None) # test get_pos2d method montage = read_montage("standard_1020") c3 = montage.get_pos2d()[montage.ch_names.index("C3")] c4 = montage.get_pos2d()[montage.ch_names.index("C4")] fz = montage.get_pos2d()[montage.ch_names.index("Fz")] oz = montage.get_pos2d()[montage.ch_names.index("Oz")] f1 = montage.get_pos2d()[montage.ch_names.index("F1")] assert (c3[0] < 0) # left hemisphere assert (c4[0] > 0) # right hemisphere assert (fz[1] > 0) # frontal assert (oz[1] < 0) # occipital assert_allclose(fz[0], 0, atol=1e-2) # midline assert_allclose(oz[0], 0, atol=1e-2) # midline assert (f1[0] < 0 and f1[1] > 0) # left frontal # test get_builtin_montages function montages = get_builtin_montages() assert (len(montages) > 0) # MNE should always ship with montages assert ("standard_1020" in montages) # 10/20 montage assert ("standard_1005" in montages) # 10/05 montage
def test_montage(): """Test making montages.""" tempdir = _TempDir() # no pep8 input_str = [ 'FidNz 0.00000 10.56381 -2.05108\nFidT9 -7.82694 0.45386 -3.76056\n' 'very_very_very_long_name 7.82694 0.45386 -3.76056\nDmy 7.0 0.0 1.0', '// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501 '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501 'E2 44.600 -0.880 1.000 0.7119 0.7021 -0.0154 0.00000000000000000\n' # noqa: E501 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501 'E4 52.700 12.000 1.000 0.7084 0.7504 0.1508 0.00000000000000000', # noqa: E501; dummy line '# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' 'NumberPositions= 68\nPositions\n-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n0.0083 86.8110 -39.9830\n' '85 -20 -48\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', '# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n' 'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' '.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n' '.08 -.02 -.04\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', 'Site Theta Phi\nFp1 -92 -72\nFp2 92 72\n' 'very_very_very_long_name -60 -51\n' 'dummy -60 -52\n', '346\n' 'EEG\t F3\t -62.027\t -50.053\t 85\n' 'EEG\t Fz\t 45.608\t 90\t 85\n' 'EEG\t F4\t 62.01\t 50.103\t 85\n' 'EEG\t FCz\t 68.01\t 58.103\t 85\n', 'eeg Fp1 -95.0 -3. -3.\neeg AF7 -1 -1 -3\neeg A3 -2 -2 2\neeg A 0 0 0' ] kinds = [ 'test.sfp', 'test.csd', 'test_mm.elc', 'test_m.elc', 'test.txt', 'test.elp', 'test.hpts' ] for kind, text in zip(kinds, input_str): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if ".sfp" in kind or ".txt" in kind: assert_true('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 4) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (4, 3)) assert_equal(montage.kind, op.splitext(kind)[0]) if kind.endswith('csd'): dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) pos2 = np.c_[table['x'], table['y'], table['z']] assert_array_almost_equal(pos2[:-1, :], montage.pos[:-1, :], 4) if kind.endswith('elc'): # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis( np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) # Test reading in different letter case. ch_names = [ "F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3", "CPZ", "CP4", "P3", "PZ", "P4", "O1", "OZ", "O2" ] montage = read_montage('standard_1020', ch_names=ch_names) assert_array_equal(ch_names, montage.ch_names) # test transform input_str = """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """ kind = 'test_fid.hpts' fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, 'test_fid.hpts'), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index('2') assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index('1') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index('3') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, 'test_fid.hpts') montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray(data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in the montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1)
def test_montage(): """Test making montages""" tempdir = _TempDir() # no pep8 input_str = [ 'FidNz 0.00000 10.56381 -2.05108\nFidT9 -7.82694 0.45386 -3.76056\n' 'very_very_very_long_name 7.82694 0.45386 -3.76056', '// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa 'E2 44.600 -0.880 1.000 0.7119 0.7021 -0.0154 0.00000000000000000\n' # noqa 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000', # noqa '# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' 'NumberPositions= 68\nPositions\n-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n0.0083 86.8110 -39.9830\n' 'Labels\nLPA\nRPA\nNz\n', '# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n' 'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' '.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n' 'Labels\nLPA\nRPA\nNz\n', 'Site Theta Phi\nFp1 -92 -72\nFp2 92 72\n' 'very_very_very_long_name -60 -51\n', '346\n' 'EEG\t F3\t -62.027\t -50.053\t 85\n' 'EEG\t Fz\t 45.608\t 90\t 85\n' 'EEG\t F4\t 62.01\t 50.103\t 85\n', 'eeg Fp1 -95.0 -31.0 -3.0\neeg AF7 -81 -59 -3\neeg AF3 -87 -41 28\n' ] kinds = ['test.sfp', 'test.csd', 'test_mm.elc', 'test_m.elc', 'test.txt', 'test.elp', 'test.hpts'] for kind, text in zip(kinds, input_str): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if ".sfp" in kind or ".txt" in kind: assert_true('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 3) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (3, 3)) assert_equal(montage.kind, op.splitext(kind)[0]) if kind.endswith('csd'): dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) pos2 = np.c_[table['x'], table['y'], table['z']] assert_array_almost_equal(pos2, montage.pos, 4) if kind.endswith('elc'): # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis( np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) # test transform input_str = """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """ kind = 'test_fid.hpts' fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, 'test_fid.hpts'), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index('2') assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index('1') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index('3') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, 'test_fid.hpts') montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info( montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray( data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in the montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1)
def test_montage(): """Test making montages""" tempdir = _TempDir() # no pep8 input_str = [ """FidNz 0.00000 10.56381 -2.05108 FidT9 -7.82694 0.45386 -3.76056 FidT10 7.82694 0.45386 -3.76056""", """// MatLab Sphere coordinates [degrees] Cartesian coordinates // Label Theta Phi Radius X Y Z off sphere surface E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011 E2 44.600 -0.880 1.000 0.7119 0.7021 -0.0154 0.00000000000000000 E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000""", # noqa """# ASA electrode file ReferenceLabel avg UnitPosition mm NumberPositions= 68 Positions -86.0761 -19.9897 -47.9860 85.7939 -20.0093 -48.0310 0.0083 86.8110 -39.9830 Labels LPA RPA Nz """, """Site Theta Phi Fp1 -92 -72 Fp2 92 72 F3 -60 -51 """, """346 EEG F3 -62.027 -50.053 85 EEG Fz 45.608 90 85 EEG F4 62.01 50.103 85 """, """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 """ ] kinds = [ 'test.sfp', 'test.csd', 'test.elc', 'test.txt', 'test.elp', 'test.hpts' ] for kind, text in zip(kinds, input_str): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) assert_equal(len(montage.ch_names), 3) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (3, 3)) assert_equal(montage.kind, op.splitext(kind)[0]) if kind.endswith('csd'): dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) pos2 = np.c_[table['x'], table['y'], table['z']] assert_array_almost_equal(pos2, montage.pos, 4) # test transform input_str = """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """ kind = 'test_fid.hpts' fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, 'test_fid.hpts'), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index('2') assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index('1') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index('3') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, 'test_fid.hpts') montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray(data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names'])
def test_montage(): """Test making montages.""" tempdir = _TempDir() inputs = dict( sfp='FidNz 0 9.071585155 -2.359754454\n' 'FidT9 -6.711765 0.040402876 -3.251600355\n' 'very_very_very_long_name -5.831241498 -4.494821698 4.955347697\n' 'Cz 0 0 8.899186843', csd='// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501 '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501 'E31 90.000 -11.000 1.000 0.0000 0.9816 -0.1908 0.00000000000000000\n' # noqa: E501 'E61 158.000 -17.200 1.000 -0.8857 0.3579 -0.2957 -0.00000000000000022', # noqa: E501 mm_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' # noqa:E501 'NumberPositions= 68\n' 'Positions\n' '-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n' '0.0083 86.8110 -39.9830\n' '-86.0761 -24.9897 -67.9860\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', m_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n' 'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' # noqa:E501 '.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n' '.08 -.02 -.04\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', txt='Site Theta Phi\n' 'Fp1 -92 -72\n' 'Fp2 92 72\n' 'very_very_very_long_name -92 72\n' 'O2 92 -90\n', elp='346\n' 'EEG\t F3\t -62.027\t -50.053\t 85\n' 'EEG\t Fz\t 45.608\t 90\t 85\n' 'EEG\t F4\t 62.01\t 50.103\t 85\n' 'EEG\t FCz\t 68.01\t 58.103\t 85\n', hpts='eeg Fp1 -95.0 -3. -3.\n' 'eeg AF7 -1 -1 -3\n' 'eeg A3 -2 -2 2\n' 'eeg A 0 0 0', bvef='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' '<!-- Generated by EasyCap Configurator 19.05.2014 -->\n' '<Electrodes defaults="false">\n' ' <Electrode>\n' ' <Name>Fp1</Name>\n' ' <Theta>-90</Theta>\n' ' <Phi>-72</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>1</Number>\n' ' </Electrode>\n' ' <Electrode>\n' ' <Name>Fz</Name>\n' ' <Theta>45</Theta>\n' ' <Phi>90</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>2</Number>\n' ' </Electrode>\n' ' <Electrode>\n' ' <Name>F3</Name>\n' ' <Theta>-60</Theta>\n' ' <Phi>-51</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>3</Number>\n' ' </Electrode>\n' ' <Electrode>\n' ' <Name>F7</Name>\n' ' <Theta>-90</Theta>\n' ' <Phi>-36</Phi>\n' ' <Radius>1</Radius>\n' ' <Number>4</Number>\n' ' </Electrode>\n' '</Electrodes>', ) # Get actual positions and save them for checking # csd comes from the string above, all others come from commit 2fa35d4 poss = dict( sfp=[[0.0, 9.07159, -2.35975], [-6.71176, 0.0404, -3.2516], [-5.83124, -4.49482, 4.95535], [0.0, 0.0, 8.89919]], mm_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.08681, -0.03998], [-0.08608, -0.02499, -0.06799]], m_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.00868, -0.03998], [0.08, -0.02, -0.04]], txt=[[-26.25044, 80.79056, -2.96646], [26.25044, 80.79056, -2.96646], [-26.25044, -80.79056, -2.96646], [0.0, -84.94822, -2.96646]], elp=[[-48.20043, 57.55106, 39.86971], [0.0, 60.73848, 59.4629], [48.1426, 57.58403, 39.89198], [41.64599, 66.91489, 31.8278]], hpts=[[-95, -3, -3], [-1, -1., -3.], [-2, -2, 2.], [0, 0, 0]], bvef=[[-26.266444, 80.839803, 5.204748e-15], [3.680313e-15, 60.104076, 60.104076], [-46.325632, 57.207392, 42.500000], [-68.766444, 49.961746, 5.204748e-15]], ) for key, text in inputs.items(): kind = key.split('_')[-1] fname = op.join(tempdir, 'test.' + kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if kind in ('sfp', 'txt'): assert ('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 4) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (4, 3)) assert_equal(montage.kind, 'test') if kind == 'csd': dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) poss['csd'] = np.c_[table['x'], table['y'], table['z']] if kind == 'elc': # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis( np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) assert_array_almost_equal(poss[key], montage.pos, 4, err_msg=key) # Test reading in different letter case. ch_names = ["F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3", "CPZ", "CP4", "P3", "PZ", "P4", "O1", "OZ", "O2"] montage = read_montage('standard_1020', ch_names=ch_names) assert_array_equal(ch_names, montage.ch_names) # test transform input_strs = [""" eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """, """ Fp1 -95.0 -31.0 -3.0 AF7 -81 -59 -3 AF3 -87 -41 28 FidNz -91 0 -42 FidT9 0 -91 -42 FidT10 0 91 -42 """] # sfp files seem to have Nz, T9, and T10 as fiducials: # https://github.com/mne-tools/mne-python/pull/4482#issuecomment-321980611 kinds = ['test_fid.hpts', 'test_fid.sfp'] for kind, input_str in zip(kinds, input_strs): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, kind), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) assert_array_equal(montage.nasion[[0, 2]], [0, 0]) assert_array_equal(montage.lpa[[1, 2]], [0, 0]) assert_array_equal(montage.rpa[[1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, kind) montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info( montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray( data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) # test return type as well as set montage assert (isinstance(evoked.set_montage(montage), type(evoked))) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in montage info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) with pytest.warns(RuntimeWarning, match='position specified'): _set_montage(info, montage) # Channel names can be treated case insensitive info = create_info(['FP1', 'af7', 'AF3'], 1e3, ['eeg'] * 3) _set_montage(info, montage) # Unless there is a collision in names info = create_info(['FP1', 'Fp1', 'AF3'], 1e3, ['eeg'] * 3) assert (info['dig'] is None) with pytest.warns(RuntimeWarning, match='position specified'): _set_montage(info, montage) assert len(info['dig']) == 5 # 2 EEG w/pos, 3 fiducials montage.ch_names = ['FP1', 'Fp1', 'AF3'] info = create_info(['fp1', 'AF3'], 1e3, ['eeg', 'eeg']) assert (info['dig'] is None) with pytest.warns(RuntimeWarning, match='position specified'): _set_montage(info, montage, set_dig=False) assert (info['dig'] is None) # test get_pos2d method montage = read_montage("standard_1020") c3 = montage.get_pos2d()[montage.ch_names.index("C3")] c4 = montage.get_pos2d()[montage.ch_names.index("C4")] fz = montage.get_pos2d()[montage.ch_names.index("Fz")] oz = montage.get_pos2d()[montage.ch_names.index("Oz")] f1 = montage.get_pos2d()[montage.ch_names.index("F1")] assert (c3[0] < 0) # left hemisphere assert (c4[0] > 0) # right hemisphere assert (fz[1] > 0) # frontal assert (oz[1] < 0) # occipital assert_allclose(fz[0], 0, atol=1e-2) # midline assert_allclose(oz[0], 0, atol=1e-2) # midline assert (f1[0] < 0 and f1[1] > 0) # left frontal # test get_builtin_montages function montages = get_builtin_montages() assert (len(montages) > 0) # MNE should always ship with montages assert ("standard_1020" in montages) # 10/20 montage assert ("standard_1005" in montages) # 10/05 montage
def test_montage(): """Test making montages""" tempdir = _TempDir() # no pep8 input_str = [ 'FidNz 0.00000 10.56381 -2.05108\nFidT9 -7.82694 0.45386 -3.76056\n' 'very_very_very_long_name 7.82694 0.45386 -3.76056', '// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa 'E2 44.600 -0.880 1.000 0.7119 0.7021 -0.0154 0.00000000000000000\n' # noqa 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000', # noqa '# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' 'NumberPositions= 68\nPositions\n-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n0.0083 86.8110 -39.9830\n' 'Labels\nLPA\nRPA\nNz\n', 'Site Theta Phi\nFp1 -92 -72\nFp2 92 72\n' 'very_very_very_long_name -60 -51\n', '346\n' 'EEG F3 -62.027 -50.053 85\n' 'EEG Fz 45.608 90 85\n' 'EEG F4 62.01 50.103 85\n', 'eeg Fp1 -95.0 -31.0 -3.0\neeg AF7 -81 -59 -3\neeg AF3 -87 -41 28\n' ] kinds = ['test.sfp', 'test.csd', 'test.elc', 'test.txt', 'test.elp', 'test.hpts'] for kind, text in zip(kinds, input_str): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if ".sfp" in kind or ".txt" in kind: assert_true('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 3) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (3, 3)) assert_equal(montage.kind, op.splitext(kind)[0]) if kind.endswith('csd'): dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) pos2 = np.c_[table['x'], table['y'], table['z']] assert_array_almost_equal(pos2, montage.pos, 4) # test transform input_str = """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """ kind = 'test_fid.hpts' fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, 'test_fid.hpts'), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index('2') assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index('1') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index('3') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, 'test_fid.hpts') montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info( montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray( data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in the montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1)
def test_montage(): """Test making montages""" tempdir = _TempDir() # no pep8 input_str = ["""FidNz 0.00000 10.56381 -2.05108 FidT9 -7.82694 0.45386 -3.76056 FidT10 7.82694 0.45386 -3.76056""", """// MatLab Sphere coordinates [degrees] Cartesian coordinates // Label Theta Phi Radius X Y Z off sphere surface E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011 E2 44.600 -0.880 1.000 0.7119 0.7021 -0.0154 0.00000000000000000 E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000""", # noqa """# ASA electrode file ReferenceLabel avg UnitPosition mm NumberPositions= 68 Positions -86.0761 -19.9897 -47.9860 85.7939 -20.0093 -48.0310 0.0083 86.8110 -39.9830 Labels LPA RPA Nz """, """Site Theta Phi Fp1 -92 -72 Fp2 92 72 F3 -60 -51 """, """346 EEG F3 -62.027 -50.053 85 EEG Fz 45.608 90 85 EEG F4 62.01 50.103 85 """, """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 """] kinds = ['test.sfp', 'test.csd', 'test.elc', 'test.txt', 'test.elp', 'test.hpts'] for kind, text in zip(kinds, input_str): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) assert_equal(len(montage.ch_names), 3) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (3, 3)) assert_equal(montage.kind, op.splitext(kind)[0]) if kind.endswith('csd'): dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) pos2 = np.c_[table['x'], table['y'], table['z']] assert_array_almost_equal(pos2, montage.pos, 4) # test transform input_str = """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """ kind = 'test_fid.hpts' fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, 'test_fid.hpts'), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index('2') assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index('1') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index('3') assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, 'test_fid.hpts') montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info( montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray( data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in the montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1)
def test_montage(): """Test making montages.""" tempdir = _TempDir() inputs = dict( sfp="FidNz 0 9.071585155 -2.359754454\n" "FidT9 -6.711765 0.040402876 -3.251600355\n" "very_very_very_long_name -5.831241498 -4.494821698 4.955347697\n" "Cz 0 0 8.899186843", csd="// MatLab Sphere coordinates [degrees] Cartesian coordinates\n" # noqa: E501 "// Label Theta Phi Radius X Y Z off sphere surface\n" # noqa: E501 "E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n" # noqa: E501 "E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n" # noqa: E501 "E31 90.000 -11.000 1.000 0.0000 0.9816 -0.1908 0.00000000000000000\n" # noqa: E501 "E61 158.000 -17.200 1.000 -0.8857 0.3579 -0.2957 -0.00000000000000022", # noqa: E501 mm_elc="# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n" # noqa:E501 "NumberPositions= 68\n" "Positions\n" "-86.0761 -19.9897 -47.9860\n" "85.7939 -20.0093 -48.0310\n" "0.0083 86.8110 -39.9830\n" "-86.0761 -24.9897 -67.9860\n" "Labels\nLPA\nRPA\nNz\nDummy\n", m_elc="# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n" "NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n" # noqa:E501 ".0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n" ".08 -.02 -.04\n" "Labels\nLPA\nRPA\nNz\nDummy\n", txt="Site Theta Phi\n" "Fp1 -92 -72\n" "Fp2 92 72\n" "very_very_very_long_name -92 72\n" "O2 92 -90\n", elp="346\n" "EEG\t F3\t -62.027\t -50.053\t 85\n" "EEG\t Fz\t 45.608\t 90\t 85\n" "EEG\t F4\t 62.01\t 50.103\t 85\n" "EEG\t FCz\t 68.01\t 58.103\t 85\n", hpts="eeg Fp1 -95.0 -3. -3.\n" "eeg AF7 -1 -1 -3\n" "eeg A3 -2 -2 2\n" "eeg A 0 0 0", ) # Get actual positions and save them for checking # csd comes from the string above, all others come from commit 2fa35d4 poss = dict( sfp=[[0.0, 9.07159, -2.35975], [-6.71176, 0.0404, -3.2516], [-5.83124, -4.49482, 4.95535], [0.0, 0.0, 8.89919]], mm_elc=[ [-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.08681, -0.03998], [-0.08608, -0.02499, -0.06799], ], m_elc=[ [-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.00868, -0.03998], [0.08, -0.02, -0.04], ], txt=[ [-26.25044, 80.79056, -2.96646], [26.25044, 80.79056, -2.96646], [-26.25044, -80.79056, -2.96646], [0.0, -84.94822, -2.96646], ], elp=[ [-48.20043, 57.55106, 39.86971], [0.0, 60.73848, 59.4629], [48.1426, 57.58403, 39.89198], [41.64599, 66.91489, 31.8278], ], hpts=[[-95, -3, -3], [-1, -1.0, -3.0], [-2, -2, 2.0], [0, 0, 0]], ) for key, text in inputs.items(): kind = key.split("_")[-1] fname = op.join(tempdir, "test." + kind) with open(fname, "w") as fid: fid.write(text) montage = read_montage(fname) if kind in ("sfp", "txt"): assert_true("very_very_very_long_name" in montage.ch_names) assert_equal(len(montage.ch_names), 4) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (4, 3)) assert_equal(montage.kind, "test") if kind == "csd": dtype = [ ("label", "S4"), ("theta", "f8"), ("phi", "f8"), ("radius", "f8"), ("x", "f8"), ("y", "f8"), ("z", "f8"), ("off_sph", "f8"), ] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) poss["csd"] = np.c_[table["x"], table["y"], table["z"]] if kind == "elc": # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis(np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) assert_array_almost_equal(poss[key], montage.pos, 4, err_msg=key) # Test reading in different letter case. ch_names = [ "F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3", "CPZ", "CP4", "P3", "PZ", "P4", "O1", "OZ", "O2", ] montage = read_montage("standard_1020", ch_names=ch_names) assert_array_equal(ch_names, montage.ch_names) # test transform input_str = """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """ fname = op.join(tempdir, "test_fid.hpts") with open(fname, "w") as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, "test_fid.hpts"), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index("2") assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index("1") assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index("3") assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, "test_fid.hpts") montage = read_montage(montage_fname, unit="mm") assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ["eeg"] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c["loc"][:3] for c in info["chs"]]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info["ch_names"]) info = create_info(montage.ch_names, 1e3, ["eeg"] * len(montage.ch_names)) evoked = EvokedArray(data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c["loc"][:3] for c in evoked.info["chs"]]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info["ch_names"]) # Warning should be raised when some EEG are not specified in the montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ["foo", "bar"], 1e3, ["eeg"] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1)
def test_montage(): """Test making montages.""" tempdir = _TempDir() inputs = dict( sfp='FidNz 0 9.071585155 -2.359754454\n' 'FidT9 -6.711765 0.040402876 -3.251600355\n' 'very_very_very_long_name -5.831241498 -4.494821698 4.955347697\n' 'Cz 0 0 8.899186843', csd= '// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501 '// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501 'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501 'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501 'E31 90.000 -11.000 1.000 0.0000 0.9816 -0.1908 0.00000000000000000\n' # noqa: E501 'E61 158.000 -17.200 1.000 -0.8857 0.3579 -0.2957 -0.00000000000000022', # noqa: E501 mm_elc= '# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' # noqa:E501 'NumberPositions= 68\n' 'Positions\n' '-86.0761 -19.9897 -47.9860\n' '85.7939 -20.0093 -48.0310\n' '0.0083 86.8110 -39.9830\n' '-86.0761 -24.9897 -67.9860\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', m_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n' 'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' # noqa:E501 '.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n' '.08 -.02 -.04\n' 'Labels\nLPA\nRPA\nNz\nDummy\n', txt='Site Theta Phi\n' 'Fp1 -92 -72\n' 'Fp2 92 72\n' 'very_very_very_long_name -92 72\n' 'O2 92 -90\n', elp='346\n' 'EEG\t F3\t -62.027\t -50.053\t 85\n' 'EEG\t Fz\t 45.608\t 90\t 85\n' 'EEG\t F4\t 62.01\t 50.103\t 85\n' 'EEG\t FCz\t 68.01\t 58.103\t 85\n', hpts='eeg Fp1 -95.0 -3. -3.\n' 'eeg AF7 -1 -1 -3\n' 'eeg A3 -2 -2 2\n' 'eeg A 0 0 0', ) # Get actual positions and save them for checking # csd comes from the string above, all others come from commit 2fa35d4 poss = dict( sfp=[[0.0, 9.07159, -2.35975], [-6.71176, 0.0404, -3.2516], [-5.83124, -4.49482, 4.95535], [0.0, 0.0, 8.89919]], mm_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.08681, -0.03998], [-0.08608, -0.02499, -0.06799]], m_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803], [1e-05, 0.00868, -0.03998], [0.08, -0.02, -0.04]], txt=[[-26.25044, 80.79056, -2.96646], [26.25044, 80.79056, -2.96646], [-26.25044, -80.79056, -2.96646], [0.0, -84.94822, -2.96646]], elp=[[-48.20043, 57.55106, 39.86971], [0.0, 60.73848, 59.4629], [48.1426, 57.58403, 39.89198], [41.64599, 66.91489, 31.8278]], hpts=[[-95, -3, -3], [-1, -1., -3.], [-2, -2, 2.], [0, 0, 0]], ) for key, text in inputs.items(): kind = key.split('_')[-1] fname = op.join(tempdir, 'test.' + kind) with open(fname, 'w') as fid: fid.write(text) montage = read_montage(fname) if kind in ('sfp', 'txt'): assert_true('very_very_very_long_name' in montage.ch_names) assert_equal(len(montage.ch_names), 4) assert_equal(len(montage.ch_names), len(montage.pos)) assert_equal(montage.pos.shape, (4, 3)) assert_equal(montage.kind, 'test') if kind == 'csd': dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'), ('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('off_sph', 'f8')] try: table = np.loadtxt(fname, skip_header=2, dtype=dtype) except TypeError: table = np.loadtxt(fname, skiprows=2, dtype=dtype) poss['csd'] = np.c_[table['x'], table['y'], table['z']] if kind == 'elc': # Make sure points are reasonable distance from geometric centroid centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0] distance_from_centroid = np.apply_along_axis( np.linalg.norm, 1, montage.pos - centroid) assert_array_less(distance_from_centroid, 0.2) assert_array_less(0.01, distance_from_centroid) assert_array_almost_equal(poss[key], montage.pos, 4, err_msg=key) # Test reading in different letter case. ch_names = [ "F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3", "CPZ", "CP4", "P3", "PZ", "P4", "O1", "OZ", "O2" ] montage = read_montage('standard_1020', ch_names=ch_names) assert_array_equal(ch_names, montage.ch_names) # test transform input_strs = [ """ eeg Fp1 -95.0 -31.0 -3.0 eeg AF7 -81 -59 -3 eeg AF3 -87 -41 28 cardinal 2 -91 0 -42 cardinal 1 0 -91 -42 cardinal 3 0 91 -42 """, """ Fp1 -95.0 -31.0 -3.0 AF7 -81 -59 -3 AF3 -87 -41 28 nasion -91 0 -42 lpa 0 -91 -42 rpa 0 91 -42 """ ] all_fiducials = [['2', '1', '3'], ['nasion', 'lpa', 'rpa']] kinds = ['test_fid.hpts', 'test_fid.sfp'] for kind, fiducials, input_str in zip(kinds, all_fiducials, input_strs): fname = op.join(tempdir, kind) with open(fname, 'w') as fid: fid.write(input_str) montage = read_montage(op.join(tempdir, kind), transform=True) # check coordinate transformation pos = np.array([-95.0, -31.0, -3.0]) nasion = np.array([-91, 0, -42]) lpa = np.array([0, -91, -42]) rpa = np.array([0, 91, -42]) fids = np.vstack((nasion, lpa, rpa)) trans = get_ras_to_neuromag_trans(fids[0], fids[1], fids[2]) pos = apply_trans(trans, pos) assert_array_equal(montage.pos[0], pos) idx = montage.ch_names.index(fiducials[0]) assert_array_equal(montage.pos[idx, [0, 2]], [0, 0]) idx = montage.ch_names.index(fiducials[1]) assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) idx = montage.ch_names.index(fiducials[2]) assert_array_equal(montage.pos[idx, [1, 2]], [0, 0]) pos = np.array([-95.0, -31.0, -3.0]) montage_fname = op.join(tempdir, kind) montage = read_montage(montage_fname, unit='mm') assert_array_equal(montage.pos[0], pos * 1e-3) # test with last info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) _set_montage(info, montage) pos2 = np.array([c['loc'][:3] for c in info['chs']]) assert_array_equal(pos2, montage.pos) assert_equal(montage.ch_names, info['ch_names']) info = create_info(montage.ch_names, 1e3, ['eeg'] * len(montage.ch_names)) evoked = EvokedArray(data=np.zeros((len(montage.ch_names), 1)), info=info, tmin=0) evoked.set_montage(montage) pos3 = np.array([c['loc'][:3] for c in evoked.info['chs']]) assert_array_equal(pos3, montage.pos) assert_equal(montage.ch_names, evoked.info['ch_names']) # Warning should be raised when some EEG are not specified in montage with warnings.catch_warnings(record=True) as w: info = create_info(montage.ch_names + ['foo', 'bar'], 1e3, ['eeg'] * (len(montage.ch_names) + 2)) _set_montage(info, montage) assert_true(len(w) == 1)