def test_read_correct_inputs(): """Test that inputs of read functions are correct.""" bids_path = 'sub-01_ses-01_meg.fif' with pytest.raises(RuntimeError, match='"bids_path" must be a ' 'BIDSPath object'): read_raw_bids(bids_path) with pytest.raises(RuntimeError, match='"bids_path" must be a ' 'BIDSPath object'): get_head_mri_trans(bids_path)
def test_get_head_mri_trans(): """Test getting a trans object from BIDS data.""" import nibabel as nib event_id = {'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3, 'Visual/Right': 4, 'Smiley': 5, 'Button': 32} events_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_trunc_raw-eve.fif') # Drop unknown events. events = mne.read_events(events_fname) events = events[events[:, 2] != 0] # Write it to BIDS raw = _read_raw_fif(raw_fname) bids_root = _TempDir() bids_path = _bids_path.copy().update(root=bids_root) write_raw_bids(raw, bids_path, events_data=events, event_id=event_id, overwrite=False) # We cannot recover trans, if no MRI has yet been written with pytest.raises(RuntimeError): estimated_trans = get_head_mri_trans(bids_path=bids_path) # Write some MRI data and supply a `trans` so that a sidecar gets written trans = mne.read_trans(raw_fname.replace('_raw.fif', '-trans.fif')) # Get the T1 weighted MRI data file ... test write_anat with a nibabel # image instead of a file path t1w_mgh = op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz') t1w_mgh = nib.load(t1w_mgh) t1w_bidspath = BIDSPath(subject=subject_id, session=session_id, acquisition=acq, root=bids_root) t1w_bidspath = write_anat(t1w_mgh, bids_path=t1w_bidspath, raw=raw, trans=trans, verbose=True) anat_dir = t1w_bidspath.directory # Try to get trans back through fitting points estimated_trans = get_head_mri_trans(bids_path=bids_path) assert trans['from'] == estimated_trans['from'] assert trans['to'] == estimated_trans['to'] assert_almost_equal(trans['trans'], estimated_trans['trans']) print(trans) print(estimated_trans) # provoke an error by introducing NaNs into MEG coords with pytest.raises(RuntimeError, match='AnatomicalLandmarkCoordinates'): raw.info['dig'][0]['r'] = np.ones(3) * np.nan sh.rmtree(anat_dir) bids_path = write_anat(t1w_mgh, bids_path=t1w_bidspath, raw=raw, trans=trans, verbose=True) estimated_trans = get_head_mri_trans(bids_path=bids_path)
def test_get_head_mri_trans_ctf(): """Test getting a trans object from BIDS data in CTF.""" import nibabel as nib ctf_data_path = op.join(testing.data_path(), 'CTF') raw_ctf_fname = op.join(ctf_data_path, 'testdata_ctf.ds') raw_ctf = mne.io.read_raw_ctf(raw_ctf_fname) bids_root = _TempDir() write_raw_bids(raw_ctf, bids_basename, bids_root, overwrite=False) # Take a fake trans trans = mne.read_trans(raw_fname.replace('_raw.fif', '-trans.fif')) # Get the T1 weighted MRI data file ... test write_anat with a nibabel # image instead of a file path t1w_mgh = op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz') t1w_mgh = nib.load(t1w_mgh) write_anat(bids_root, subject_id, t1w_mgh, session_id, acq, raw=raw_ctf, trans=trans) # Try to get trans back through fitting points estimated_trans = get_head_mri_trans(bids_basename=bids_basename, bids_root=bids_root) assert_almost_equal(trans['trans'], estimated_trans['trans'])
def test_get_head_mri_trans_ctf(fname): """Test getting a trans object from BIDS data in CTF.""" import nibabel as nib ctf_data_path = op.join(testing.data_path(), 'CTF') raw_ctf_fname = op.join(ctf_data_path, fname) raw_ctf = _read_raw_ctf(raw_ctf_fname, clean_names=True) bids_root = _TempDir() bids_path = _bids_path.copy().update(root=bids_root) write_raw_bids(raw_ctf, bids_path, overwrite=False) # Take a fake trans trans = mne.read_trans(raw_fname.replace('_raw.fif', '-trans.fif')) # Get the T1 weighted MRI data file ... test write_anat with a nibabel # image instead of a file path t1w_mgh = op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz') t1w_mgh = nib.load(t1w_mgh) t1w_bids_path = BIDSPath(subject=subject_id, session=session_id, acquisition=acq, root=bids_root) write_anat(t1w_mgh, bids_path=t1w_bids_path, raw=raw_ctf, trans=trans) # Try to get trans back through fitting points estimated_trans = get_head_mri_trans(bids_path=bids_path, extra_params=dict(clean_names=True)) assert_almost_equal(trans['trans'], estimated_trans['trans'])
def test_get_head_mri_trans(tmpdir): """Test getting a trans object from BIDS data.""" import nibabel as nib event_id = { 'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3, 'Visual/Right': 4, 'Smiley': 5, 'Button': 32 } events_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_trunc_raw-eve.fif') subjects_dir = op.join(data_path, 'subjects') # Drop unknown events. events = mne.read_events(events_fname) events = events[events[:, 2] != 0] # Write it to BIDS raw = _read_raw_fif(raw_fname) bids_path = _bids_path.copy().update(root=tmpdir) write_raw_bids(raw, bids_path, events_data=events, event_id=event_id, overwrite=False) # We cannot recover trans if no MRI has yet been written with pytest.raises(RuntimeError, match='Did not find any T1w'): estimated_trans = get_head_mri_trans(bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) # Write some MRI data and supply a `trans` so that a sidecar gets written trans = mne.read_trans(raw_fname.replace('_raw.fif', '-trans.fif')) # Get the T1 weighted MRI data file ... test write_anat with a nibabel # image instead of a file path t1w_mgh = op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz') t1w_mgh = nib.load(t1w_mgh) landmarks = get_anat_landmarks(t1w_mgh, raw.info, trans, fs_subject='sample', fs_subjects_dir=subjects_dir) t1w_bids_path = write_anat(t1w_mgh, bids_path=bids_path, landmarks=landmarks, verbose=True) anat_dir = bids_path.directory # Try to get trans back through fitting points estimated_trans = get_head_mri_trans(bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert trans['from'] == estimated_trans['from'] assert trans['to'] == estimated_trans['to'] assert_almost_equal(trans['trans'], estimated_trans['trans']) # provoke an error by introducing NaNs into MEG coords raw.info['dig'][0]['r'] = np.full(3, np.nan) sh.rmtree(anat_dir) bad_landmarks = get_anat_landmarks(t1w_mgh, raw.info, trans, 'sample', op.join(data_path, 'subjects')) write_anat(t1w_mgh, bids_path=t1w_bids_path, landmarks=bad_landmarks) with pytest.raises(RuntimeError, match='AnatomicalLandmarkCoordinates'): estimated_trans = get_head_mri_trans(bids_path=t1w_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) # test we are permissive for different casings of landmark names in the # sidecar, and also accept "nasion" instead of just "NAS" raw = _read_raw_fif(raw_fname) write_raw_bids(raw, bids_path, events_data=events, event_id=event_id, overwrite=True) # overwrite with new acq t1w_bids_path = write_anat(t1w_mgh, bids_path=bids_path, landmarks=landmarks, overwrite=True) t1w_json_fpath = t1w_bids_path.copy().update(extension='.json').fpath with t1w_json_fpath.open('r', encoding='utf-8') as f: t1w_json = json.load(f) coords = t1w_json['AnatomicalLandmarkCoordinates'] coords['lpa'] = coords['LPA'] coords['Rpa'] = coords['RPA'] coords['Nasion'] = coords['NAS'] del coords['LPA'], coords['RPA'], coords['NAS'] _write_json(t1w_json_fpath, t1w_json, overwrite=True) estimated_trans = get_head_mri_trans(bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert_almost_equal(trans['trans'], estimated_trans['trans']) # Test t1_bids_path parameter # # Case 1: different BIDS roots meg_bids_path = _bids_path.copy().update(root=tmpdir / 'meg_root') t1_bids_path = _bids_path.copy().update(root=tmpdir / 'mri_root') raw = _read_raw_fif(raw_fname) write_raw_bids(raw, bids_path=meg_bids_path) landmarks = get_anat_landmarks(t1w_mgh, raw.info, trans, fs_subject='sample', fs_subjects_dir=subjects_dir) write_anat(t1w_mgh, bids_path=t1_bids_path, landmarks=landmarks) read_trans = get_head_mri_trans(bids_path=meg_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert np.allclose(trans['trans'], read_trans['trans']) # Case 2: different sessions raw = _read_raw_fif(raw_fname) meg_bids_path = _bids_path.copy().update(root=tmpdir / 'session_test', session='01') t1_bids_path = meg_bids_path.copy().update(session='02') write_raw_bids(raw, bids_path=meg_bids_path) write_anat(t1w_mgh, bids_path=t1_bids_path, landmarks=landmarks) read_trans = get_head_mri_trans(bids_path=meg_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert np.allclose(trans['trans'], read_trans['trans']) # Test that incorrect subject directory throws error with pytest.raises(ValueError, match='Could not find'): estimated_trans = get_head_mri_trans(bids_path=bids_path, fs_subject='bad', fs_subjects_dir=subjects_dir)
def test_get_head_mri_trans(): """Test getting a trans object from BIDS data.""" import nibabel as nib event_id = { 'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3, 'Visual/Right': 4, 'Smiley': 5, 'Button': 32 } events_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_trunc_raw-eve.fif') # Write it to BIDS raw = mne.io.read_raw_fif(raw_fname) bids_root = _TempDir() with pytest.warns(UserWarning, match='No line frequency'): write_raw_bids(raw, bids_basename, bids_root, events_data=events_fname, event_id=event_id, overwrite=False) # We cannot recover trans, if no MRI has yet been written with pytest.raises(RuntimeError): bids_fname = bids_basename + '_meg.fif' estimated_trans = get_head_mri_trans(bids_fname, bids_root) # Write some MRI data and supply a `trans` so that a sidecar gets written trans = mne.read_trans(raw_fname.replace('_raw.fif', '-trans.fif')) # Get the T1 weighted MRI data file ... test write_anat with a nibabel # image instead of a file path t1w_mgh = op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz') t1w_mgh = nib.load(t1w_mgh) anat_dir = write_anat(bids_root, subject_id, t1w_mgh, session_id, acq, raw=raw, trans=trans, verbose=True) # Try to get trans back through fitting points estimated_trans = get_head_mri_trans(bids_fname, bids_root) assert trans['from'] == estimated_trans['from'] assert trans['to'] == estimated_trans['to'] assert_almost_equal(trans['trans'], estimated_trans['trans']) print(trans) print(estimated_trans) # Passing a path instead of a name works well bids_fpath = op.join(bids_root, 'sub-{}'.format(subject_id), 'ses-{}'.format(session_id), 'meg', bids_basename + '_meg.fif') estimated_trans = get_head_mri_trans(bids_fpath, bids_root) # provoke an error by pointing introducing NaNs into MEG coords with pytest.raises(RuntimeError, match='AnatomicalLandmarkCoordinates'): raw.info['dig'][0]['r'] = np.ones(3) * np.nan sh.rmtree(anat_dir) write_anat(bids_root, subject_id, t1w_mgh, session_id, acq, raw=raw, trans=trans, verbose=True) estimated_trans = get_head_mri_trans(bids_fname, bids_root)
def test_get_head_mri_trans(tmp_path): """Test getting a trans object from BIDS data.""" import nibabel as nib event_id = {'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3, 'Visual/Right': 4, 'Smiley': 5, 'Button': 32} events_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_trunc_raw-eve.fif') subjects_dir = op.join(data_path, 'subjects') # Drop unknown events. events = mne.read_events(events_fname) events = events[events[:, 2] != 0] # Write it to BIDS raw = _read_raw_fif(raw_fname) bids_path = _bids_path.copy().update( root=tmp_path, datatype='meg', suffix='meg' ) write_raw_bids(raw, bids_path, events_data=events, event_id=event_id, overwrite=False) # We cannot recover trans if no MRI has yet been written with pytest.raises(FileNotFoundError, match='Did not find'): estimated_trans = get_head_mri_trans( bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) # Write some MRI data and supply a `trans` so that a sidecar gets written trans = mne.read_trans(raw_fname.replace('_raw.fif', '-trans.fif')) # Get the T1 weighted MRI data file ... test write_anat with a nibabel # image instead of a file path t1w_mgh = op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz') t1w_mgh = nib.load(t1w_mgh) landmarks = get_anat_landmarks( t1w_mgh, raw.info, trans, fs_subject='sample', fs_subjects_dir=subjects_dir) t1w_bids_path = bids_path.copy().update( datatype='anat', suffix='T1w' ) t1w_bids_path = write_anat( t1w_mgh, bids_path=t1w_bids_path, landmarks=landmarks, verbose=True ) anat_dir = t1w_bids_path.directory # Try to get trans back through fitting points estimated_trans = get_head_mri_trans( bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert trans['from'] == estimated_trans['from'] assert trans['to'] == estimated_trans['to'] assert_almost_equal(trans['trans'], estimated_trans['trans']) # provoke an error by introducing NaNs into MEG coords raw.info['dig'][0]['r'] = np.full(3, np.nan) sh.rmtree(anat_dir) bad_landmarks = get_anat_landmarks(t1w_mgh, raw.info, trans, 'sample', op.join(data_path, 'subjects')) write_anat(t1w_mgh, bids_path=t1w_bids_path, landmarks=bad_landmarks) with pytest.raises(RuntimeError, match='AnatomicalLandmarkCoordinates'): estimated_trans = get_head_mri_trans(bids_path=t1w_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) # test raw with no fiducials to provoke error t1w_bids_path = write_anat( # put back t1w_mgh, bids_path=t1w_bids_path, landmarks=landmarks, overwrite=True ) montage = raw.get_montage() montage.remove_fiducials() raw_test = raw.copy() raw_test.set_montage(montage) raw_test.save(bids_path.fpath, overwrite=True) with pytest.raises(RuntimeError, match='Could not extract fiducial'): get_head_mri_trans(bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) # test we are permissive for different casings of landmark names in the # sidecar, and also accept "nasion" instead of just "NAS" raw = _read_raw_fif(raw_fname) write_raw_bids(raw, bids_path, events_data=events, event_id=event_id, overwrite=True) # overwrite with new acq t1w_bids_path = write_anat( t1w_mgh, bids_path=t1w_bids_path, landmarks=landmarks, overwrite=True ) t1w_json_fpath = t1w_bids_path.copy().update(extension='.json').fpath with t1w_json_fpath.open('r', encoding='utf-8') as f: t1w_json = json.load(f) coords = t1w_json['AnatomicalLandmarkCoordinates'] coords['lpa'] = coords['LPA'] coords['Rpa'] = coords['RPA'] coords['Nasion'] = coords['NAS'] del coords['LPA'], coords['RPA'], coords['NAS'] _write_json(t1w_json_fpath, t1w_json, overwrite=True) estimated_trans = get_head_mri_trans( bids_path=bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert_almost_equal(trans['trans'], estimated_trans['trans']) # Test t1_bids_path parameter # # Case 1: different BIDS roots meg_bids_path = _bids_path.copy().update( root=tmp_path / 'meg_root', datatype='meg', suffix='meg' ) t1_bids_path = _bids_path.copy().update( root=tmp_path / 'mri_root', task=None, run=None ) raw = _read_raw_fif(raw_fname) write_raw_bids(raw, bids_path=meg_bids_path) landmarks = get_anat_landmarks( t1w_mgh, raw.info, trans, fs_subject='sample', fs_subjects_dir=subjects_dir) write_anat(t1w_mgh, bids_path=t1_bids_path, landmarks=landmarks) read_trans = get_head_mri_trans( bids_path=meg_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert np.allclose(trans['trans'], read_trans['trans']) # Case 2: different sessions raw = _read_raw_fif(raw_fname) meg_bids_path = _bids_path.copy().update( root=tmp_path / 'session_test', session='01', datatype='meg', suffix='meg' ) t1_bids_path = meg_bids_path.copy().update( session='02', task=None, run=None, datatype='anat', suffix='T1w' ) write_raw_bids(raw, bids_path=meg_bids_path) write_anat(t1w_mgh, bids_path=t1_bids_path, landmarks=landmarks) read_trans = get_head_mri_trans( bids_path=meg_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir) assert np.allclose(trans['trans'], read_trans['trans']) # Test that incorrect subject directory throws error with pytest.raises(ValueError, match='Could not find'): estimated_trans = get_head_mri_trans( bids_path=bids_path, fs_subject='bad', fs_subjects_dir=subjects_dir) # Case 3: write with suffix for kind landmarks2 = landmarks.copy() landmarks2.dig[0]['r'] *= -1 landmarks2.save(tmp_path / 'landmarks2.fif') landmarks2 = tmp_path / 'landmarks2.fif' write_anat(t1w_mgh, bids_path=t1_bids_path, overwrite=True, deface=True, landmarks={"coreg": landmarks, "deface": landmarks2}) read_trans1 = get_head_mri_trans( bids_path=meg_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir, kind="coreg") assert np.allclose(trans['trans'], read_trans1['trans']) read_trans2 = get_head_mri_trans( bids_path=meg_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir, kind="deface") assert not np.allclose(trans['trans'], read_trans2['trans']) # Test we're respecting existing suffix & data type # The following path is supposed to mimic a derivative generated by the # MNE-BIDS-Pipeline. # # XXX We MAY want to revise this once the BIDS-Pipeline produces more # BIDS-compatible output, e.g. including `channels.tsv` files for written # Raw data etc. raw = _read_raw_fif(raw_fname) deriv_root = tmp_path / 'derivatives' / 'mne-bids-pipeline' electrophys_path = ( deriv_root / 'sub-01' / 'eeg' / 'sub-01_task-av_proc-filt_raw.fif' ) electrophys_path.parent.mkdir(parents=True) raw.save(electrophys_path) electrophys_bids_path = BIDSPath( subject='01', task='av', datatype='eeg', processing='filt', suffix='raw', extension='.fif', root=deriv_root, check=False ) t1_bids_path = _bids_path.copy().update( root=tmp_path / 'mri_root', task=None, run=None ) with pytest.warns(RuntimeWarning, match='Did not find any channels.tsv'): get_head_mri_trans( bids_path=electrophys_bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir ) # bids_path without datatype is deprecated bids_path = electrophys_bids_path.copy().update(datatype=None) with pytest.raises(FileNotFoundError): # defaut location is all wrong! with pytest.warns(DeprecationWarning, match='no datatype'): get_head_mri_trans( bids_path=bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir ) # bids_path without suffix is deprecated bids_path = electrophys_bids_path.copy().update(suffix=None) with pytest.raises(FileNotFoundError): # defaut location is all wrong! with pytest.warns(DeprecationWarning, match='no datatype'): get_head_mri_trans( bids_path=bids_path, t1_bids_path=t1_bids_path, fs_subject='sample', fs_subjects_dir=subjects_dir ) # Should fail for an unsupported coordinate frame raw = _read_raw_fif(raw_fname) bids_root = tmp_path / 'unsupported_coord_frame' bids_path = BIDSPath( subject='01', task='av', datatype='meg', suffix='meg', extension='.fif', root=bids_root ) t1_bids_path = _bids_path.copy().update( root=tmp_path / 'mri_root', task=None, run=None ) write_raw_bids(raw=raw, bids_path=bids_path, verbose=False)