def run_forward(*, cfg, subject, session=None): bids_path = BIDSPath(subject=subject, session=session, task=cfg.task, acquisition=cfg.acq, run=None, recording=cfg.rec, space=cfg.space, extension='.fif', datatype=cfg.datatype, root=cfg.deriv_root, check=False) fname_info = bids_path.copy().update(**cfg.source_info_path_update) fname_trans = bids_path.copy().update(suffix='trans') fname_fwd = bids_path.copy().update(suffix='fwd') if cfg.use_template_mri: src, trans, bem_sol = _prepare_forward_fsaverage(cfg) else: src, trans, bem_sol = _prepare_forward(cfg, bids_path, fname_trans) # Finally, calculate and save the forward solution. msg = 'Calculating forward solution' logger.info( **gen_log_kwargs(message=msg, subject=subject, session=session)) info = mne.io.read_info(fname_info) fwd = mne.make_forward_solution(info, trans=trans, src=src, bem=bem_sol, mindist=cfg.mindist) mne.write_trans(fname_trans, fwd['mri_head_t'], overwrite=True) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def test_io_trans(): """Test reading and writing of trans files """ tempdir = _TempDir() os.mkdir(op.join(tempdir, 'sample')) assert_raises(RuntimeError, _find_trans, 'sample', subjects_dir=tempdir) trans0 = read_trans(fname) fname1 = op.join(tempdir, 'sample', 'test-trans.fif') trans0.save(fname1) assert_true(fname1 == _find_trans('sample', subjects_dir=tempdir)) trans1 = read_trans(fname1) # check all properties assert_true(trans0['from'] == trans1['from']) assert_true(trans0['to'] == trans1['to']) assert_array_equal(trans0['trans'], trans1['trans']) # check reading non -trans.fif files assert_raises(IOError, read_trans, fname_eve) # check warning on bad filenames with warnings.catch_warnings(record=True) as w: fname2 = op.join(tempdir, 'trans-test-bad-name.fif') write_trans(fname2, trans0) assert_naming(w, 'test_transforms.py', 1)
def test_io_trans(): """Test reading and writing of trans files """ tempdir = _TempDir() os.mkdir(op.join(tempdir, "sample")) assert_raises(RuntimeError, _find_trans, "sample", subjects_dir=tempdir) trans0 = read_trans(fname) fname1 = op.join(tempdir, "sample", "test-trans.fif") write_trans(fname1, trans0) assert_true(fname1 == _find_trans("sample", subjects_dir=tempdir)) trans1 = read_trans(fname1) # check all properties assert_true(trans0["from"] == trans1["from"]) assert_true(trans0["to"] == trans1["to"]) assert_array_equal(trans0["trans"], trans1["trans"]) # check reading non -trans.fif files assert_raises(IOError, read_trans, fname_eve) # check warning on bad filenames with warnings.catch_warnings(record=True) as w: fname2 = op.join(tempdir, "trans-test-bad-name.fif") write_trans(fname2, trans0) assert_true(len(w) >= 1)
def run_forward(subject, session=None): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) fname_evoked = op.join(deriv_path, bids_basename + '-ave.fif') fname_trans = op.join(deriv_path, 'sub-{}'.format(subject) + '-trans.fif') fname_fwd = op.join(deriv_path, bids_basename + '-fwd.fif') msg = f'Input: {fname_evoked}, Output: {fname_fwd}' logger.info(gen_log_message(message=msg, step=10, subject=subject, session=session)) # Find the raw data file # XXX : maybe simplify bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=config.get_runs()[0], processing=config.proc, recording=config.rec, space=config.space) trans = get_head_mri_trans(bids_basename=bids_basename, bids_root=config.bids_root) mne.write_trans(fname_trans, trans) src = mne.setup_source_space(subject, spacing=config.spacing, subjects_dir=config.get_fs_subjects_dir(), add_dist=False) evoked = mne.read_evokeds(fname_evoked, condition=0) # Here we only use 3-layers BEM only if EEG is available. if 'eeg' in config.ch_types: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, 0.006, 0.3), subjects_dir=config.get_fs_subjects_dir()) else: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3,), subjects_dir=config.get_fs_subjects_dir()) bem = mne.make_bem_solution(model) fwd = mne.make_forward_solution(evoked.info, trans, src, bem, mindist=config.mindist) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def run_forward(subject, session=None): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) bids_basename = BIDSPath(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, recording=config.rec, space=config.space, prefix=deriv_path, check=False) fname_evoked = bids_basename.copy().update(kind='ave', extension='.fif') fname_trans = bids_basename.copy().update(kind='trans', extension='.fif') fname_fwd = bids_basename.copy().update(kind='fwd', extension='.fif') msg = f'Input: {fname_evoked}, Output: {fname_fwd}' logger.info( gen_log_message(message=msg, step=10, subject=subject, session=session)) # Find the raw data file trans = get_head_mri_trans(bids_basename=(bids_basename.copy().update( run=config.get_runs()[0], prefix=None)), bids_root=config.bids_root) mne.write_trans(fname_trans, trans) src = mne.setup_source_space(subject, spacing=config.spacing, subjects_dir=config.get_fs_subjects_dir(), add_dist=False) evoked = mne.read_evokeds(fname_evoked, condition=0) # Here we only use 3-layers BEM only if EEG is available. if 'eeg' in config.ch_types: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, 0.006, 0.3), subjects_dir=config.get_fs_subjects_dir()) else: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, ), subjects_dir=config.get_fs_subjects_dir()) bem = mne.make_bem_solution(model) fwd = mne.make_forward_solution(evoked.info, trans, src, bem, mindist=config.mindist) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def run_forward(subject, session=None): bids_path = BIDSPath(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, recording=config.rec, space=config.space, extension='.fif', datatype=config.get_datatype(), root=config.deriv_root, check=False) fname_evoked = bids_path.copy().update(suffix='ave') fname_trans = bids_path.copy().update(suffix='trans') fname_fwd = bids_path.copy().update(suffix='fwd') msg = f'Input: {fname_evoked}, Output: {fname_fwd}' logger.info( gen_log_message(message=msg, step=10, subject=subject, session=session)) # Retrieve the head -> MRI transformation matrix from the MRI sidecar file # in the input data, and save it to an MNE "trans" file in the derivatives # folder. trans = get_head_mri_trans(bids_path.copy().update( run=config.get_runs()[0], root=config.bids_root)) mne.write_trans(fname_trans, trans) src = mne.setup_source_space(subject, spacing=config.spacing, subjects_dir=config.get_fs_subjects_dir(), add_dist=False) evoked = mne.read_evokeds(fname_evoked, condition=0) # Here we only use 3-layers BEM only if EEG is available. if 'eeg' in config.ch_types: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, 0.006, 0.3), subjects_dir=config.get_fs_subjects_dir()) else: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, ), subjects_dir=config.get_fs_subjects_dir()) bem = mne.make_bem_solution(model) fwd = mne.make_forward_solution(evoked.info, trans, src, bem, mindist=config.mindist) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def test_io_trans(): """Test reading and writing of trans files """ info0 = read_trans(fname) fname1 = op.join(tempdir, 'test-trans.fif') write_trans(fname1, info0) info1 = read_trans(fname1) # check all properties assert_true(info0['from'] == info1['from']) assert_true(info0['to'] == info1['to']) assert_array_equal(info0['trans'], info1['trans']) for d0, d1 in zip(info0['dig'], info1['dig']): assert_array_equal(d0['r'], d1['r']) for name in ['kind', 'ident', 'coord_frame']: assert_true(d0[name] == d1[name])
def test_io_trans(): """Test reading and writing of trans files.""" tempdir = _TempDir() os.mkdir(op.join(tempdir, 'sample')) pytest.raises(RuntimeError, _find_trans, 'sample', subjects_dir=tempdir) trans0 = read_trans(fname) fname1 = op.join(tempdir, 'sample', 'test-trans.fif') trans0.save(fname1) assert fname1 == _find_trans('sample', subjects_dir=tempdir) trans1 = read_trans(fname1) # check all properties assert trans0 == trans1 # check reading non -trans.fif files pytest.raises(IOError, read_trans, fname_eve) # check warning on bad filenames fname2 = op.join(tempdir, 'trans-test-bad-name.fif') with pytest.warns(RuntimeWarning, match='-trans.fif'): write_trans(fname2, trans0)
def test_io_trans(): """Test reading and writing of trans files """ trans0 = read_trans(fname) fname1 = op.join(tempdir, 'test-trans.fif') write_trans(fname1, trans0) trans1 = read_trans(fname1) # check all properties assert_true(trans0['from'] == trans1['from']) assert_true(trans0['to'] == trans1['to']) assert_array_equal(trans0['trans'], trans1['trans']) # check reading non -trans.fif files assert_raises(IOError, read_trans, fname_eve) # check warning on bad filenames with warnings.catch_warnings(record=True) as w: fname2 = op.join(tempdir, 'trans-test-bad-name.fif') write_trans(fname2, trans0) assert_true(len(w) >= 1)
def save_montage_and_trans(self): montage_fid = self.get_acq_montage() if montage_fid is None: print("Return no montage") return montage_fid.save(f"{self.config['DEFAULT']['subject_dir']}/{self.subject}-montage.fif") self.save_montage_tsv() df_acq = correct_for_movements(self.df_acq).dropna() mri_pts = self.df_montage.loc[df_acq.index.values].values mtg_pts = df_acq.values[:, :3] trans_mat = recover_homogenous_affine_trans(mtg_pts[:3], mri_pts[:3]) # rx, ry, rz, tx, ty, tz, sx, sy, sz x0 = [*mne.transforms.rotation_angles(trans_mat), *trans_mat[:3, 3], 1.0, 1.0, 1.0] n_scale_params = 3 trans = mne.coreg.fit_matched_points(mtg_pts, mri_pts, x0=x0, out='trans', scale=n_scale_params) #, weights=(1.0, 10.0, 1.0)) trans = mne.Transform('head', 'mri', trans) trans_file_name = mne.coreg.trans_fname.format(raw_dir=self.config["DEFAULT"]['subject_dir'], subject=self.subject) mne.write_trans(trans_file_name, trans)
def run_forward(subject, session=None): bids_path = BIDSPath(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, recording=config.rec, space=config.space, extension='.fif', datatype=config.get_datatype(), root=config.deriv_root, check=False) fname_evoked = bids_path.copy().update(suffix='ave') fname_trans = bids_path.copy().update(suffix='trans') fname_fwd = bids_path.copy().update(suffix='fwd') # Generate a head ↔ MRI transformation matrix from the # electrophysiological and MRI sidecar files, and save it to an MNE # "trans" file in the derivatives folder. if config.mri_t1_path_generator is None: t1_bids_path = None else: t1_bids_path = BIDSPath(subject=bids_path.subject, session=bids_path.session, root=config.bids_root) t1_bids_path = config.mri_t1_path_generator(t1_bids_path.copy()) if t1_bids_path.suffix is None: t1_bids_path.update(suffix='T1w') if t1_bids_path.datatype is None: t1_bids_path.update(datatype='anat') msg = 'Estimating head ↔ MRI transform' logger.info( gen_log_message(message=msg, step=10, subject=subject, session=session)) trans = get_head_mri_trans(bids_path.copy().update( run=config.get_runs()[0], root=config.bids_root), t1_bids_path=t1_bids_path) mne.write_trans(fname_trans, trans) fs_subject = config.get_fs_subject(subject) fs_subjects_dir = config.get_fs_subjects_dir() # Create the source space. msg = 'Creating source space' logger.info( gen_log_message(message=msg, step=10, subject=subject, session=session)) src = mne.setup_source_space(subject=fs_subject, subjects_dir=fs_subjects_dir, spacing=config.spacing, add_dist=False, n_jobs=config.N_JOBS) # Calculate the BEM solution. # Here we only use a 3-layers BEM only if EEG is available. msg = 'Calculating BEM solution' logger.info( gen_log_message(message=msg, step=10, subject=subject, session=session)) if 'eeg' in config.ch_types: conductivity = (0.3, 0.006, 0.3) else: conductivity = (0.3, ) bem_model = mne.make_bem_model(subject=fs_subject, subjects_dir=fs_subjects_dir, ico=4, conductivity=conductivity) bem_sol = mne.make_bem_solution(bem_model) # Finally, calculate and save the forward solution. msg = 'Calculating forward solution' logger.info( gen_log_message(message=msg, step=10, subject=subject, session=session)) info = mne.io.read_info(fname_evoked) fwd = mne.make_forward_solution(info, trans=trans, src=src, bem=bem_sol, mindist=config.mindist) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
m_trans, m_rot, m_t = mne.chpi.head_pos_to_trans_rot_t(mean_pos) # convert mean quaternion trans, rot, t = mne.chpi.head_pos_to_trans_rot_t(pos) # convert quaternions hp=np.zeros(trans.shape) # initialize to correct size # compute head origin position in device coordinates in every time point: for k in range(trans.shape[0]): hp[k]=np.matmul(-rot[k,:,:].T, trans[k,:]) HP=np.concatenate((HP,hp),axis=0) #net_trans=np.concatenate((net_trans,trans),axis=0) #net_rot=np.concatenate((net_rot,rot),axis=0) plt.figure() plt.title('Head movement over all files (in mm)') for subplt in range(3): plt.subplot(3,1,subplt+1) plt.plot(1000*HP[:,subplt]) plt.show() print('Mean head position over following files: \n') print(pos_files) print('\nis\n') print(1000*HP.mean(axis=0)) print('Saving the mean transformation to file ' + basepath + 'mean-trans.fif...\n') mean_tr=np.diagflat(np.ones(4)) #mean_tr[0:3,3]=net_trans.mean(axis=0) mean_tr[0:3,3]=m_trans mean_tr[0:3,0:3]=m_rot A=mne.Transform('meg','head',mean_tr) mne.write_trans('mean-trans.fif',A) print('Done!')
def run_forward(subject, session=None): print("Processing subject: %s" % subject) # Construct the search path for the data file. `sub` is mandatory subject_path = op.join('sub-{}'.format(subject)) # `session` is optional if session is not None: subject_path = op.join(subject_path, 'ses-{}'.format(session)) subject_path = op.join(subject_path, config.kind) bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) fpath_deriv = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, subject_path) fname_evoked = \ op.join(fpath_deriv, bids_basename + '-ave.fif') print("Input: ", fname_evoked) fname_trans = \ op.join(fpath_deriv, 'sub-{}'.format(subject) + '-trans.fif') fname_fwd = \ op.join(fpath_deriv, bids_basename + '-fwd.fif') print("Output: ", fname_fwd) # Find the raw data file # XXX : maybe simplify bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=config.runs[0], processing=config.proc, recording=config.rec, space=config.space) data_dir = op.join(config.bids_root, subject_path) search_str = op.join(data_dir, bids_basename) + '_' + config.kind + '*' fnames = sorted(glob.glob(search_str)) fnames = [f for f in fnames if op.splitext(f)[1] in mne_bids_readers] if len(fnames) >= 1: bids_fname = fnames[0] elif len(fnames) == 0: raise ValueError('Could not find input data file matching: ' '"{}"'.format(search_str)) bids_fname = op.basename(bids_fname) mne.gui.coregistration() trans = get_head_mri_trans(bids_fname=bids_fname, bids_root=config.bids_root) mne.write_trans(fname_trans, trans) # create the boundary element model (BEM) once from mne.bem import make_watershed_bem, make_flash_bem if 'eeg' in config.ch_types or config.kind == 'eeg': make_flash_bem(subject, subjects_dir=subjects_dir, overwrite=True) else: mne.bem.make_watershed_bem(subject, subjects_dir=subjects_dir, overwrite=True)
def make_mne_anatomy(subject, subjects_dir, recordings_path=None, hcp_path=op.curdir, outputs=('label', 'mri', 'surf')): """Extract relevant anatomy and create MNE friendly directory layout The function will create the following outputs by default: $subjects_dir/$subject/bem/inner_skull.surf $subjects_dir/$subject/label/* $subjects_dir/$subject/mri/* $subjects_dir/$subject/surf/* $recordings_path/$subject/$subject-head_mri-trans.fif These can then be set as $SUBJECTS_DIR and as MEG directory, consistent with MNE examples. Parameters ---------- subject : str The subject name. subjects_dir : str The path corresponding to MNE/freesurfer SUBJECTS_DIR (to be created) hcp_path : str The path where the HCP files can be found. outputs : {'label', 'mri', 'stats', 'surf', 'touch'} The outputs of the freesrufer pipeline shipped by HCP. Defaults to ('mri', 'surf'), the minimum needed to extract MNE-friendly anatomy files and data. """ if hcp_path == op.curdir: hcp_path = op.realpath(hcp_path) if not op.isabs(subjects_dir): subjects_dir = op.realpath(subjects_dir) this_subjects_dir = op.join(subjects_dir, subject) if not op.isabs(recordings_path): recordings_path = op.realpath(recordings_path) this_recordings_path = op.join(recordings_path, subject) if not op.exists(this_recordings_path): os.makedirs(this_recordings_path) for output in outputs: if not op.exists(op.join(this_subjects_dir, output)): os.makedirs(op.join(this_subjects_dir, output)) if output == 'mri': for suboutput in ['orig', 'transforms']: if not op.exists(op.join(this_subjects_dir, output, suboutput)): os.makedirs(op.join(this_subjects_dir, output, suboutput)) files = get_file_paths(subject=subject, data_type='freesurfer', output=output, hcp_path=hcp_path) for source in files: match = [match for match in re.finditer(subject, source)][-1] split_path = source[:match.span()[1] + 1] target = op.join(this_subjects_dir, source.split(split_path)[-1]) if (not op.isfile(target) and not op.islink(target) and op.exists(source)): # don't link if it's not there. if sys.platform != 'win32': os.symlink(source, target) else: shutil.copyfile(source, target) logger.info('reading extended structural processing ...') # Step 1 ################################################################# # transform head models to expected coordinate system # make hcp trans transforms_fname = get_file_paths(subject=subject, data_type='meg_anatomy', output='transforms', hcp_path=hcp_path) transforms_fname = [ k for k in transforms_fname if k.endswith('transform.txt') ][0] hcp_trans = _read_trans_hcp(fname=transforms_fname, convert_to_meter=False) # get RAS freesurfer trans c_ras_trans_fname = get_file_paths(subject=subject, data_type='freesurfer', output='mri', hcp_path=hcp_path) c_ras_trans_fname = [ k for k in c_ras_trans_fname if k.endswith('c_ras.mat') ][0] logger.info('reading RAS freesurfer transform') # ceci n'est pas un .mat file ... with open(op.join(subjects_dir, c_ras_trans_fname)) as fid: ras_trans = np.array([r.split() for r in fid.read().split('\n') if r], dtype=np.float64) logger.info('Combining RAS transform and coregistration') ras_trans_m = linalg.inv(ras_trans) # and the inversion logger.info('extracting head model') head_model_fname = get_file_paths(subject=subject, data_type='meg_anatomy', output='head_model', hcp_path=hcp_path)[0] pnts, faces = _get_head_model(head_model_fname=head_model_fname) logger.info('coregistring head model to MNE-HCP coordinates') pnts = apply_trans(ras_trans_m.dot(hcp_trans['bti2spm']), pnts) tri_fname = op.join(this_subjects_dir, 'bem', 'inner_skull.surf') if not op.exists(op.dirname(tri_fname)): os.makedirs(op.dirname(tri_fname)) write_surface(tri_fname, pnts, faces) # Step 2 ################################################################# # write corresponding device to MRI transform logger.info('extracting coregistration') # now convert to everything meter too here ras_trans_m[:3, 3] *= 1e-3 bti2spm = hcp_trans['bti2spm'] bti2spm[:3, 3] *= 1e-3 head_mri_t = Transform( # we're lying here for a good purpose 'head', 'mri', np.dot(ras_trans_m, bti2spm)) # it should be 'ctf_head' write_trans( op.join(this_recordings_path, '%s-head_mri-trans.fif' % subject), head_mri_t)
def run_forward(subject, session=None): print("Processing subject: %s" % subject) # Construct the search path for the data file. `sub` is mandatory subject_path = op.join('sub-{}'.format(subject)) # `session` is optional if session is not None: subject_path = op.join(subject_path, 'ses-{}'.format(session)) subject_path = op.join(subject_path, config.kind) bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) fpath_deriv = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, subject_path) fname_evoked = \ op.join(fpath_deriv, bids_basename + '-ave.fif') print("Input: ", fname_evoked) fname_trans = \ op.join(fpath_deriv, 'sub-{}'.format(subject) + '-trans.fif') fname_fwd = \ op.join(fpath_deriv, bids_basename + '-fwd.fif') print("Output: ", fname_fwd) # Find the raw data file # XXX : maybe simplify bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=config.runs[0], processing=config.proc, recording=config.rec, space=config.space) data_dir = op.join(config.bids_root, subject_path) search_str = op.join(data_dir, bids_basename) + '_' + config.kind + '*' fnames = sorted(glob.glob(search_str)) fnames = [f for f in fnames if op.splitext(f)[1] in mne_bids_readers] if len(fnames) >= 1: bids_fname = fnames[0] elif len(fnames) == 0: raise ValueError('Could not find input data file matching: ' '"{}"'.format(search_str)) bids_fname = op.basename(bids_fname) trans = get_head_mri_trans(bids_fname=bids_fname, bids_root=config.bids_root) mne.write_trans(fname_trans, trans) src = mne.setup_source_space(subject, spacing=config.spacing, subjects_dir=config.subjects_dir, add_dist=False) evoked = mne.read_evokeds(fname_evoked, condition=0) # Here we only use 3-layers BEM only if EEG is available. if 'eeg' in config.ch_types or config.kind == 'eeg': model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, 0.006, 0.3), subjects_dir=config.subjects_dir) else: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, ), subjects_dir=config.subjects_dir) bem = mne.make_bem_solution(model) fwd = mne.make_forward_solution(evoked.info, trans, src, bem, mindist=config.mindist) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def make_mne_anatomy(subject, subjects_dir, recordings_path=None, hcp_path=op.curdir, outputs=('label', 'mri', 'surf')): """Extract relevant anatomy and create MNE friendly directory layout The function will create the following outputs by default: $subjects_dir/$subject/bem/inner_skull.surf $subjects_dir/$subject/label/* $subjects_dir/$subject/mri/* $subjects_dir/$subject/surf/* $recordings_path/$subject/$subject-head_mri-trans.fif These can then be set as $SUBJECTS_DIR and as MEG directory, consistent with MNE examples. Parameters ---------- subject : str The subject name. subjects_dir : str The path corresponding to MNE/freesurfer SUBJECTS_DIR (to be created) hcp_path : str The path where the HCP files can be found. outputs : {'label', 'mri', 'stats', 'surf', 'touch'} The outputs of the freesrufer pipeline shipped by HCP. Defaults to ('mri', 'surf'), the minimum needed to extract MNE-friendly anatomy files and data. """ if hcp_path == op.curdir: hcp_path = op.realpath(hcp_path) if not op.isabs(subjects_dir): subjects_dir = op.realpath(subjects_dir) this_subjects_dir = op.join(subjects_dir, subject) if not op.isabs(recordings_path): recordings_path = op.realpath(recordings_path) this_recordings_path = op.join(recordings_path, subject) if not op.exists(this_recordings_path): os.makedirs(this_recordings_path) for output in outputs: if not op.exists(op.join(this_subjects_dir, output)): os.makedirs(op.join(this_subjects_dir, output)) if output == 'mri': for suboutput in ['orig', 'transforms']: if not op.exists( op.join(this_subjects_dir, output, suboutput)): os.makedirs(op.join(this_subjects_dir, output, suboutput)) files = get_file_paths( subject=subject, data_type='freesurfer', output=output, hcp_path=hcp_path) for source in files: match = [match for match in re.finditer(subject, source)][-1] split_path = source[:match.span()[1] + 1] target = op.join(this_subjects_dir, source.split(split_path)[-1]) if (not op.isfile(target) and not op.islink(target) and op.exists(source)): # don't link if it's not there. if sys.platform != 'win32': os.symlink(source, target) else: shutil.copyfile(source, target) logger.info('reading extended structural processing ...') # Step 1 ################################################################# # transform head models to expected coordinate system # make hcp trans transforms_fname = get_file_paths( subject=subject, data_type='meg_anatomy', output='transforms', hcp_path=hcp_path) transforms_fname = [k for k in transforms_fname if k.endswith('transform.txt')][0] hcp_trans = _read_trans_hcp(fname=transforms_fname, convert_to_meter=False) # get RAS freesurfer trans c_ras_trans_fname = get_file_paths( subject=subject, data_type='freesurfer', output='mri', hcp_path=hcp_path) c_ras_trans_fname = [k for k in c_ras_trans_fname if k.endswith('c_ras.mat')][0] logger.info('reading RAS freesurfer transform') # ceci n'est pas un .mat file ... with open(op.join(subjects_dir, c_ras_trans_fname)) as fid: ras_trans = np.array([ r.split() for r in fid.read().split('\n') if r], dtype=np.float64) logger.info('Combining RAS transform and coregistration') ras_trans_m = linalg.inv(ras_trans) # and the inversion logger.info('extracting head model') head_model_fname = get_file_paths( subject=subject, data_type='meg_anatomy', output='head_model', hcp_path=hcp_path)[0] pnts, faces = _get_head_model(head_model_fname=head_model_fname) logger.info('coregistring head model to MNE-HCP coordinates') pnts = apply_trans(ras_trans_m.dot(hcp_trans['bti2spm']), pnts) tri_fname = op.join(this_subjects_dir, 'bem', 'inner_skull.surf') if not op.exists(op.dirname(tri_fname)): os.makedirs(op.dirname(tri_fname)) write_surface(tri_fname, pnts, faces) # Step 2 ################################################################# # write corresponding device to MRI transform logger.info('extracting coregistration') # now convert to everything meter too here ras_trans_m[:3, 3] *= 1e-3 bti2spm = hcp_trans['bti2spm'] bti2spm[:3, 3] *= 1e-3 head_mri_t = Transform( # we're lying here for a good purpose 'head', 'mri', np.dot(ras_trans_m, bti2spm)) # it should be 'ctf_head' write_trans(op.join(this_recordings_path, '%s-head_mri-trans.fif' % subject), head_mri_t)