def test_channel_specificity(monkeypatch, tmp_path, fold_files): raw = read_raw_nirx(fname_nirx_15_3_short, preload=True) raw.pick(range(2)) kwargs = dict() n_want = 6 if fold_files is list: kwargs = dict(fold_files=[foldfile]) elif fold_files is str: kwargs = dict(fold_files=tmp_path) n_want *= 2 else: assert fold_files is None monkeypatch.setenv('MNE_NIRS_FOLD_PATH', str(tmp_path)) assert len(kwargs) == 0 with pytest.raises(FileNotFoundError, match=r'fold_files\[0\] does.*'): fold_channel_specificity(raw) n_want *= 2 copyfile(foldfile, tmp_path / '10-10.xls') copyfile(foldfile, tmp_path / '10-5.xls') res = fold_channel_specificity(raw, **kwargs) assert len(res) == 2 assert res[0].shape == (n_want, 14) montage = make_standard_montage( 'standard_1005', head_size=0.09700884729534559) fids = read_fiducials( Path(mne.__file__).parent / 'data' / 'fsaverage' / 'fsaverage-fiducials.fif')[0] for f in fids: f['coord_frame'] = montage.dig[0]['coord_frame'] montage.dig[:3] = fids S, D = raw.ch_names[0].split()[0].split('_') assert S == 'S1' and D == 'D2' montage.rename_channels({'PO8': S, 'P6': D}) # not in the tables! # taken from standard_1020.elc s_mri = np.array([55.6666, -97.6251, 2.7300]) / 1000. d_mri = np.array([67.8877, -75.9043, 28.0910]) / 1000. trans = mne.transforms._get_trans('fsaverage', 'mri', 'head')[0] ch_pos = montage.get_positions()['ch_pos'] assert_allclose(ch_pos[S], s_mri, atol=1e-6) assert_allclose(ch_pos[D], d_mri, atol=1e-6) raw.set_montage(montage) montage = transform_to_head(montage) s_head = mne.transforms.apply_trans(trans, s_mri) d_head = mne.transforms.apply_trans(trans, d_mri) assert_allclose(montage._get_ch_pos()['S1'], s_head, atol=1e-6) assert_allclose(montage._get_ch_pos()['D2'], d_head, atol=1e-6) for ch in raw.info['chs']: assert_allclose(ch['loc'][3:6], s_head, atol=1e-6) assert_allclose(ch['loc'][6:9], d_head, atol=1e-6) res_1 = fold_channel_specificity(raw, **kwargs)[0] assert res_1.shape == (0, 14) # TODO: This is wrong, should be P08 not P08h, and distance should be 0 mm! with pytest.warns(RuntimeWarning, match='.*PO8h?/P6.*TP8/T8.*'): res_1 = fold_channel_specificity(raw, interpolate=True, **kwargs)[0] montage.rename_channels({S: D, D: S}) # reversed with pytest.warns(RuntimeWarning, match='.*PO8h?/P6.*TP8/T8.*'): res_2 = fold_channel_specificity(raw, interpolate=True, **kwargs)[0] # We should check the whole thing, but this is probably good enough assert (res_1['Specificity'] == res_2['Specificity']).all()
def test_get_mni_fiducials(): """Test get_mni_fiducials.""" fids, coord_frame = read_fiducials(fid_fname) assert coord_frame == FIFF.FIFFV_COORD_MRI assert [f['ident'] for f in fids] == list(range(1, 4)) fids = np.array([f['r'] for f in fids]) fids_est = get_mni_fiducials('sample', subjects_dir) fids_est = np.array([f['r'] for f in fids_est]) dists = np.linalg.norm(fids - fids_est, axis=-1) * 1000. # -> mm assert (dists < 8).all(), dists
def test_fiducials_io(tmpdir): """Test fiducials i/o.""" pts, coord_frame = read_fiducials(fiducials_fname) assert pts[0]['coord_frame'] == FIFF.FIFFV_COORD_MRI assert pts[0]['ident'] == FIFF.FIFFV_POINT_CARDINAL temp_fname = tmpdir.join('test.fif') write_fiducials(temp_fname, pts, coord_frame) pts_1, coord_frame_1 = read_fiducials(temp_fname) assert coord_frame == coord_frame_1 for pt, pt_1 in zip(pts, pts_1): assert pt['kind'] == pt_1['kind'] assert pt['ident'] == pt_1['ident'] assert pt['coord_frame'] == pt_1['coord_frame'] assert_array_equal(pt['r'], pt_1['r']) # test safeguards pts[0]['coord_frame'] += 1 pytest.raises(ValueError, write_fiducials, temp_fname, pts, coord_frame)
def test_fiducials_io(): """Test fiducials i/o""" pts, coord_frame = read_fiducials(fiducials_fname) assert_equal(pts[0]['coord_frame'], FIFF.FIFFV_COORD_MRI) assert_equal(pts[0]['ident'], FIFF.FIFFV_POINT_CARDINAL) temp_fname = op.join(tempdir, 'test.fif') write_fiducials(temp_fname, pts, coord_frame) pts_1, coord_frame_1 = read_fiducials(temp_fname) assert_equal(coord_frame, coord_frame_1) for pt, pt_1 in zip(pts, pts_1): assert_equal(pt['kind'], pt_1['kind']) assert_equal(pt['ident'], pt_1['ident']) assert_equal(pt['coord_frame'], pt_1['coord_frame']) assert_array_equal(pt['r'], pt_1['r']) # test safeguards pts[0]['coord_frame'] += 1 assert_raises(ValueError, write_fiducials, temp_fname, pts, coord_frame)
def test_fiducials_io(): """Test fiducials i/o.""" tempdir = _TempDir() pts, coord_frame = read_fiducials(fiducials_fname) assert pts[0]['coord_frame'] == FIFF.FIFFV_COORD_MRI assert pts[0]['ident'] == FIFF.FIFFV_POINT_CARDINAL temp_fname = op.join(tempdir, 'test.fif') write_fiducials(temp_fname, pts, coord_frame) pts_1, coord_frame_1 = read_fiducials(temp_fname) assert coord_frame == coord_frame_1 for pt, pt_1 in zip(pts, pts_1): assert pt['kind'] == pt_1['kind'] assert pt['ident'] == pt_1['ident'] assert pt['coord_frame'] == pt_1['coord_frame'] assert_array_equal(pt['r'], pt_1['r']) # test safeguards pts[0]['coord_frame'] += 1 pytest.raises(ValueError, write_fiducials, temp_fname, pts, coord_frame)
def test_fiducials_io(): """Test fiducials i/o.""" tempdir = _TempDir() pts, coord_frame = read_fiducials(fiducials_fname) assert_equal(pts[0]["coord_frame"], FIFF.FIFFV_COORD_MRI) assert_equal(pts[0]["ident"], FIFF.FIFFV_POINT_CARDINAL) temp_fname = op.join(tempdir, "test.fif") write_fiducials(temp_fname, pts, coord_frame) pts_1, coord_frame_1 = read_fiducials(temp_fname) assert_equal(coord_frame, coord_frame_1) for pt, pt_1 in zip(pts, pts_1): assert_equal(pt["kind"], pt_1["kind"]) assert_equal(pt["ident"], pt_1["ident"]) assert_equal(pt["coord_frame"], pt_1["coord_frame"]) assert_array_equal(pt["r"], pt_1["r"]) # test safeguards pts[0]["coord_frame"] += 1 assert_raises(ValueError, write_fiducials, temp_fname, pts, coord_frame)
def test_fiducials_io(tmp_path): """Test fiducials i/o.""" pts, coord_frame = read_fiducials(fiducials_fname) assert pts[0]['coord_frame'] == FIFF.FIFFV_COORD_MRI assert pts[0]['ident'] == FIFF.FIFFV_POINT_CARDINAL temp_fname = tmp_path / 'test.fif' write_fiducials(temp_fname, pts, coord_frame) pts_1, coord_frame_1 = read_fiducials(temp_fname) assert coord_frame == coord_frame_1 for pt, pt_1 in zip(pts, pts_1): assert pt['kind'] == pt_1['kind'] assert pt['ident'] == pt_1['ident'] assert pt['coord_frame'] == pt_1['coord_frame'] assert_array_equal(pt['r'], pt_1['r']) assert isinstance(pt, DigPoint) assert isinstance(pt_1, DigPoint) # test safeguards pts[0]['coord_frame'] += 1 with pytest.raises(ValueError, match='coord_frame entries that are incom'): write_fiducials(temp_fname, pts, coord_frame, overwrite=True)
def test_fiducials(): """Test handling of fiducials.""" # Eventually the code used here should be unified with montage.py, but for # now it uses code in odd places for fname in (fif_fname, ctf_fif_fname): fids, coord_frame = read_fiducials(fname) points = _fiducial_coords(fids, coord_frame) assert points.shape == (3, 3) # Fids assert_allclose(points[:, 2], 0., atol=1e-6) assert_allclose(points[::2, 1], 0., atol=1e-6) assert points[2, 0] > 0 # RPA assert points[0, 0] < 0 # LPA # Nasion assert_allclose(points[1, 0], 0., atol=1e-6) assert points[1, 1] > 0
def _get_landmarks_from_fiducials_file(*, bids_path, fname, fs_subject, fs_subjects_dir): """Get anatomical landmarks from fiducials file, in MRI voxel space.""" # avoid dicrular imports from mne_bids.write import ( _get_t1w_mgh, _mri_landmarks_to_mri_voxels, _get_fid_coords ) digpoints, coord_frame = read_fiducials(fname) # All of this should be guaranteed, but better be safe than sorry! assert coord_frame == FIFF.FIFFV_COORD_MRI assert digpoints[0]['ident'] == FIFF.FIFFV_POINT_LPA assert digpoints[1]['ident'] == FIFF.FIFFV_POINT_NASION assert digpoints[2]['ident'] == FIFF.FIFFV_POINT_RPA montage_loaded = make_dig_montage( lpa=digpoints[0]['r'], nasion=digpoints[1]['r'], rpa=digpoints[2]['r'], coord_frame='mri' ) landmark_coords_mri, _ = _get_fid_coords(dig_points=montage_loaded.dig) landmark_coords_mri = np.asarray( (landmark_coords_mri['lpa'], landmark_coords_mri['nasion'], landmark_coords_mri['rpa']) ) t1w_mgh = _get_t1w_mgh(fs_subject, fs_subjects_dir) landmark_coords_voxels = _mri_landmarks_to_mri_voxels( mri_landmarks=landmark_coords_mri * 1000, # in mm t1_mgh=t1w_mgh ) montage_voxels = make_dig_montage( lpa=landmark_coords_voxels[0], nasion=landmark_coords_voxels[1], rpa=landmark_coords_voxels[2], coord_frame='mri_voxel' ) return montage_voxels
def test_coreg_class_init(drop_point_kind): """Test that Coregistration can be instantiated with various digs.""" fiducials, _ = read_fiducials(fid_fname) info = read_info(raw_fname) dig_list = [] eeg_chans = [] for pt in info['dig']: if pt['kind'] != drop_point_kind: dig_list.append(pt) if pt['kind'] == FIFF.FIFFV_POINT_EEG: eeg_chans.append(f"EEG {pt['ident']:03d}") this_info = info.copy() this_info.set_montage(DigMontage(dig=dig_list, ch_names=eeg_chans), on_missing='ignore') Coregistration(this_info, subject='sample', subjects_dir=subjects_dir, fiducials=fiducials)
def test_coreg_class_gui_match(): """Test that using Coregistration matches mne coreg.""" fiducials, _ = read_fiducials(fid_fname) info = read_info(raw_fname) coreg = Coregistration(info, subject='sample', subjects_dir=subjects_dir, fiducials=fiducials) assert_allclose(coreg.trans['trans'], np.eye(4), atol=1e-6) # mne coreg -s sample -d subjects -f MEG/sample/sample_audvis_trunc_raw.fif # then "Fit Fid.", Save... to get trans, read_trans: want_trans = [ [9.99428809e-01, 2.94733196e-02, 1.65350307e-02, -8.76054692e-04], [-1.92420650e-02, 8.98512006e-01, -4.38526988e-01, 9.39774036e-04], [-2.77817696e-02, 4.37958330e-01, 8.98565888e-01, -8.29207990e-03], [0, 0, 0, 1] ] coreg.set_fid_match('matched') coreg.fit_fiducials(verbose=True) assert_allclose(coreg.trans['trans'], want_trans, atol=1e-6) # Set ICP iterations to one, click "Fit ICP" want_trans = [ [9.99512792e-01, 2.80128177e-02, 1.37659665e-02, 6.08855276e-04], [-1.91694051e-02, 8.98992002e-01, -4.37545270e-01, 9.66848747e-04], [-2.46323701e-02, 4.37068194e-01, 8.99091005e-01, -1.44129358e-02], [0, 0, 0, 1] ] coreg.fit_icp(1, verbose=True) assert_allclose(coreg.trans['trans'], want_trans, atol=1e-6) # Set ICP iterations to 20, click "Fit ICP" with catch_logging() as log: coreg.fit_icp(20, verbose=True) log = log.getvalue() want_trans = [ [9.97582495e-01, 2.12266613e-02, 6.61706254e-02, -5.07694029e-04], [1.81089472e-02, 8.39900672e-01, -5.42437911e-01, 7.81218382e-03], [-6.70908988e-02, 5.42324841e-01, 8.37485850e-01, -2.50057746e-02], [0, 0, 0, 1] ] assert_allclose(coreg.trans['trans'], want_trans, atol=1e-6) assert 'ICP 19' in log assert 'ICP 20' not in log # converged on 19 # Change to uniform scale mode, "Fit Fiducials" in scale UI coreg.set_scale_mode('uniform') coreg.fit_fiducials() want_scale = [0.975] * 3 want_trans = [ [9.99428809e-01, 2.94733196e-02, 1.65350307e-02, -9.25998494e-04], [-1.92420650e-02, 8.98512006e-01, -4.38526988e-01, -1.03350170e-03], [-2.77817696e-02, 4.37958330e-01, 8.98565888e-01, -9.03170835e-03], [0, 0, 0, 1] ] assert_allclose(coreg.scale, want_scale, atol=5e-4) assert_allclose(coreg.trans['trans'], want_trans, atol=1e-6) # Click "Fit ICP" in scale UI with catch_logging() as log: coreg.fit_icp(20, verbose=True) log = log.getvalue() assert 'ICP 18' in log assert 'ICP 19' not in log want_scale = [1.036] * 3 want_trans = [ [9.98992383e-01, 1.72388796e-02, 4.14364934e-02, 6.19427126e-04], [6.80460501e-03, 8.54430079e-01, -5.19521892e-01, 5.58008114e-03], [-4.43605632e-02, 5.19280374e-01, 8.53451848e-01, -2.03358755e-02], [0, 0, 0, 1] ] assert_allclose(coreg.scale, want_scale, atol=5e-4) assert_allclose(coreg.trans['trans'], want_trans, atol=1e-6) # Change scale mode to 3-axis, click "Fit ICP" in scale UI coreg.set_scale_mode('3-axis') with catch_logging() as log: coreg.fit_icp(20, verbose=True) log = log.getvalue() assert 'ICP 7' in log assert 'ICP 8' not in log want_scale = [1.025, 1.010, 1.121] want_trans = [ [9.98387098e-01, 2.04762165e-02, 5.29526398e-02, 4.97257097e-05], [1.13287698e-02, 8.42087150e-01, -5.39222538e-01, 7.09863892e-03], [-5.56319728e-02, 5.38952649e-01, 8.40496957e-01, -1.46372067e-02], [0, 0, 0, 1] ] assert_allclose(coreg.scale, want_scale, atol=5e-4) assert_allclose(coreg.trans['trans'], want_trans, atol=1e-6)
def test_coregistration(scale_mode, ref_scale, grow_hair, fiducials, fid_match): """Test automated coregistration.""" subject = 'sample' if fiducials is None: fiducials, coord_frame = read_fiducials(fid_fname) assert coord_frame == FIFF.FIFFV_COORD_MRI info = read_info(raw_fname) for d in info['dig']: d['r'] = d['r'] * ref_scale trans = read_trans(trans_fname) coreg = Coregistration(info, subject=subject, subjects_dir=subjects_dir, fiducials=fiducials) assert np.allclose(coreg._last_parameters, coreg._parameters) coreg.set_fid_match(fid_match) default_params = list(coreg._default_parameters) coreg.set_rotation(default_params[:3]) coreg.set_translation(default_params[3:6]) coreg.set_scale(default_params[6:9]) coreg.set_grow_hair(grow_hair) coreg.set_scale_mode(scale_mode) # Identity transform errs_id = coreg.compute_dig_mri_distances() is_scaled = ref_scale != [1., 1., 1.] id_max = 0.03 if is_scaled and scale_mode == '3-axis' else 0.02 assert 0.005 < np.median(errs_id) < id_max # Fiducial transform + scale coreg.fit_fiducials(verbose=True) assert coreg._extra_points_filter is None coreg.omit_head_shape_points(distance=0.02) assert coreg._extra_points_filter is not None errs_fid = coreg.compute_dig_mri_distances() assert_array_less(0, errs_fid) if is_scaled or scale_mode is not None: fid_max = 0.05 fid_med = 0.02 else: fid_max = 0.03 fid_med = 0.01 assert_array_less(errs_fid, fid_max) assert 0.001 < np.median(errs_fid) < fid_med assert not np.allclose(coreg._parameters, default_params) coreg.omit_head_shape_points(distance=-1) coreg.omit_head_shape_points(distance=5. / 1000) assert coreg._extra_points_filter is not None # ICP transform + scale coreg.fit_icp(verbose=True) assert isinstance(coreg.trans, Transform) errs_icp = coreg.compute_dig_mri_distances() assert_array_less(0, errs_icp) if is_scaled or scale_mode == '3-axis': icp_max = 0.015 else: icp_max = 0.01 assert_array_less(errs_icp, icp_max) assert 0.001 < np.median(errs_icp) < 0.004 assert np.rad2deg( _angle_between_quats(rot_to_quat(coreg.trans['trans'][:3, :3]), rot_to_quat(trans['trans'][:3, :3]))) < 13 if scale_mode is None: atol = 1e-7 else: atol = 0.35 assert_allclose(coreg._scale, ref_scale, atol=atol) coreg.reset() assert_allclose(coreg._parameters, default_params)
from mne.io import read_raw_ctf, read_info, read_fiducials from mne.coreg import _fiducial_coords, fit_matched_points from mne.transforms import read_trans, write_trans, Transform if len(sys.argv) != 2: print("usage: {} subject".format(sys.argv[0])) sys.exit(1) subject = sys.argv[1] try: FShome = os.environ['FREESURFER_HOME'] except KeyError: print("You must set the FREESURFER_HOME environment variable!") sys.exit(1) try: Subjdir = os.environ['SUBJECTS_DIR'] except KeyError: Subjdir = op.join(FShome, "subjects") print("Note: Using the default SUBJECTS_DIR:", Subjdir) name = op.join(Subjdir, subject, "bem", "{}-fiducials.fif".format(subject)) pts, cframe = read_fiducials(name) fids = _fiducial_coords(pts) print(fids) name = op.join(Subjdir, subject, "bem", "{}-trans.fif".format(subject)) t = read_trans(name) print(t)
if len(sys.argv) != 3: print("usage: {} subject $ds".format(sys.argv[0])) sys.exit(1) subject = sys.argv[1] dsname = sys.argv[2] try: FShome = os.environ['FREESURFER_HOME'] except KeyError: print("You must set the FREESURFER_HOME environment variable!") sys.exit(1) try: Subjdir = os.environ['SUBJECTS_DIR'] except KeyError: Subjdir = op.join(FShome, "subjects") print("Note: Using the default SUBJECTS_DIR:", Subjdir) name = op.join(Subjdir, subject, "bem", "{}-fiducials.fif".format(subject)) fids = read_fiducials(name) fidc = _fiducial_coords(fids[0]) raw = read_raw_ctf(dsname, clean_names = True, preload = False) fidd = _fiducial_coords(raw.info['dig']) xform = fit_matched_points(fidd, fidc, weights = [1, 10, 1]) t = Transform(FIFF.FIFFV_COORD_HEAD, FIFF.FIFFV_COORD_MRI, xform) name = op.join(Subjdir, subject, "bem", "{}-trans.fif".format(subject)) write_trans(name, t)