def write_bids(data, filename, markers=[]): write_brainvision(data, filename, markers) _write_ieeg_json( replace_extension(filename, '.json')) _write_ieeg_channels( replace_underscore(filename, 'channels.tsv'), data) _write_ieeg_events( replace_underscore(filename, 'events.tsv'), markers)
def simulate_ieeg(root, ieeg_task, elec): bids_mkdir(root, ieeg_task) chan_names = [x['name'] for x in elec] ieeg_file = ieeg_task.get_filename(root) create_ieeg_data(ieeg_file, chan_names) create_ieeg_info(replace_extension(ieeg_file, '.json')) create_channels(replace_underscore(ieeg_file, 'channels.tsv'), elec) create_events(replace_underscore(ieeg_file, 'events.tsv')) return iEEG(ieeg_file)
def compute_corr_ecog_fmri(fmri_file, ecog_file, output_dir, PVALUE): output_dir.mkdir(exist_ok=True, parents=True) fmri_tsv = read_tsv(fmri_file) ecog_tsv = read_tsv(ecog_file) fmri_tsv = select_channels(fmri_tsv, ecog_tsv) kernel_sizes = fmri_tsv.dtype.names[1:] results_tsv = output_dir / replace_underscore(ecog_file.stem, 'bold_r2.tsv') with results_tsv.open('w') as f: f.write('Kernel\tRsquared\tSlope\tIntercept\n') for kernel in kernel_sizes: try: r2, slope, intercept = compute_rsquared( ecog_tsv['measure'], fmri_tsv[kernel], ecog_tsv['pvalue'], PVALUE) except Exception: r2 = slope = intercept = NaN f.write(f'{float(kernel):.2f}\t{r2}\t{slope}\t{intercept}\n') return results_tsv, fmri_file, ecog_file
def calc_fmri_at_elec(measure_nii, electrodes_file, distance, kernels, graymatter, output_dir): """ Calculate the (weighted) average of fMRI values at electrode locations """ electrodes = Electrodes(electrodes_file) img = nload(str(measure_nii)) mri = img.get_data() mri[mri == 0] = NaN labels = electrodes.electrodes.get(map_lambda=lambda x: x['name']) chan_xyz = array(electrodes.get_xyz()) nd = array(list(ndindex(mri.shape))) ndi = from_mrifile_to_chan(img, nd) if graymatter: gm_mri = nload(str(graymatter)).get_data().astype(bool) mri[~gm_mri] = NaN lg.debug( f'Computing fMRI values for {measure_nii.name} at {len(labels)} electrodes and {len(kernels)} "{distance}" kernels' ) fmri_vals, n_voxels = compute_kernels(kernels, chan_xyz, mri, ndi, distance) fmri_vals_tsv = output_dir / replace_underscore(measure_nii.name, 'compare.tsv') n_voxels_tsv = output_dir / replace_underscore(measure_nii.name, 'nvoxels.tsv') with fmri_vals_tsv.open('w') as f: f.write('channel\t' + '\t'.join(str(one_k) for one_k in kernels) + '\n') for one_label, val_at_elec in zip(labels, fmri_vals): f.write(one_label + '\t' + '\t'.join(str(one_val) for one_val in val_at_elec) + '\n') with n_voxels_tsv.open('w') as f: f.write('channel\t' + '\t'.join(str(one_k) for one_k in kernels) + '\n') for one_label, val_at_elec in zip(labels, n_voxels): f.write(one_label + '\t' + '\t'.join(str(one_val) for one_val in val_at_elec) + '\n') return fmri_vals_tsv, n_voxels_tsv
def simulate_bold_prf(bids_dir, task_prf): prf_file = task_prf.get_filename(bids_dir) prf_file.parent.mkdir(exist_ok=True, parents=True) bars = generate_bars() stimulus = generate_stimulus(bars) model = generate_model(stimulus, spm_hrf) X = -2 Y = 2 SIGMA = 2 BETA = 1 BASELINE = 0 dat = model.generate_prediction(X, Y, SIGMA, BETA, BASELINE) create_bold(prf_file, task_prf.task, 11143, dat) tsv_file = replace_underscore(prf_file, 'events.tsv') create_prf_events(tsv_file, bars.shape[2], TR)
def simulate_bold(root, task_fmri): bids_mkdir(root, task_fmri) fmri_file = task_fmri.get_filename(root) SHIFT = 3 x = r_[ones(SHIFT), ones(16) * 5, ones(16), ones(16) * 5, ones(16), ones(16) * 5, ones(16 - SHIFT)] create_bold(fmri_file, task_fmri.task, 11129, x) create_events(replace_underscore(fmri_file, 'events.tsv')) return Task(fmri_file)
def prepare_design(func, anat, output_dir): """You should set remove_unnecessary_outputs to False, otherwise it removes the events.tsv file """ task = Task(func) events_fsl = output_dir / task.events.filename.name _write_events(task.events.filename, events_fsl) # collect info img = niload(str(task.filename)) n_vols = img.header.get_data_shape()[3] tr = img.header['pixdim'][4] # Not sure it it's reliable with DESIGN_TEMPLATE.open('r') as f: design = f.read() feat_dir = output_dir / replace_extension( Path(task.filename).name, '.feat') design_values = { 'XXX_OUTPUTDIR': str(feat_dir), 'XXX_NPTS': str(n_vols), 'XXX_TR': str(tr), 'XXX_FEAT_FILE': str(task.filename), 'XXX_HIGHRES_FILE': str(anat), 'XXX_EV1': 'active', 'XXX_TSVFILE': str(events_fsl), } for pattern, value in design_values.items(): design = design.replace(pattern, value) subj_design = output_dir / replace_underscore( Path(task.filename).name, 'design.fsf') with subj_design.open('w') as f: f.write(design) return subj_design
def vol2surf(in_vol, feat_path, freesurfer_dir, hemi, surface, surf_fwhm): out_surf = replace_underscore(in_vol.filename, in_vol.modality + 'surf' + hemi + '.mgh') mri_nonan = mri_nan2zero(in_vol.filename) cmd = [ 'mri_vol2surf', '--src', str(mri_nonan), '--srcreg', str(feat_path / 'reg/freesurfer/anat2exf.register.dat'), '--trgsubject', 'sub-' + in_vol.subject, # freesurfer subject '--hemi', hemi, '--out', str(out_surf), '--surf', surface, '--surf-fwhm', str(surf_fwhm), ] p = Popen(cmd, env={ **ENVIRON, 'SUBJECTS_DIR': str(freesurfer_dir) }, stdout=PIPE, stderr=PIPE) info = { "surf": out_surf, "hemi": hemi, "subject": 'sub-' + in_vol.subject, "mri_nonan": mri_nonan, } return p, info
def assign_regions(elec, freesurfer): bids_dir = find_root(elec.filename) elec.acquisition += 'regions' tsv_electrodes = elec.get_filename(bids_dir) with tsv_electrodes.open('w') as f: f.write('name\tx\ty\tz\ttype\tsize\tmaterial\tregion\n' ) # TODO: region is not in BEP010 for _tsv in elec.electrodes.tsv: xyz = array([float(_tsv['x']), float(_tsv['y']), float(_tsv['z'])]) region = freesurfer.find_brain_region( xyz, exclude_regions=('White', 'WM', 'Unknown'))[0] f.write( f'{_tsv["name"]}\t{_tsv["x"]}\t{_tsv["y"]}\t{_tsv["z"]}\t{_tsv["type"]}\t{_tsv["size"]}\t{_tsv["material"]}\t{region}\n' ) elec.coordframe.json[ 'iEEGCoordinateProcessingDescription'] += '; Assign brain regions' # TODO: better description + remove None new_json = replace_underscore(tsv_electrodes, 'coordsystem.json') with new_json.open('w') as f: dump(elec.coordframe.json, f, indent=2) return Electrodes(tsv_electrodes)
def simulate_electrodes(root, elec_obj, electrodes_file=None): bids_mkdir(root, elec_obj) if electrodes_file is None: electrodes_file = data_elec output_file = elec_obj.get_filename(root) copyfile(electrodes_file, output_file) coordsystem_file = replace_underscore(output_file, 'coordsystem.json') COORDSYSTEM = { "iEEGCoordinateSystem": 'T1w', "iEEGCoordinateUnits": 'mm', "iEEGCoordinateProcessingDescription": "none", "IntendedFor": "/sub-bert/ses-day01/anat/sub-bert_ses-day01_acq-wholebrain_T1w.nii.gz", "AssociatedImageCoordinateSystem": "T1w", "AssociatedImageCoordinateUnits": "mm", } with coordsystem_file.open('w') as f: dump(COORDSYSTEM, f, indent=' ') return Electrodes(output_file)
def simulate_ieeg_prf(bids_dir, task_prf): prf_file = task_prf.get_filename(bids_dir) bars = generate_bars() stimulus = generate_stimulus(bars) model = generate_model(stimulus, nohrf) dat = generate_population_data(model, N_CHAN) chan = _make_chan_name(n_chan=N_CHAN) data = Data(data=dat, s_freq=S_FREQ, chan=chan, time=arange(dat[0].shape[0]) / S_FREQ) data.start_time = fake_time data.export(prf_file, 'bids') tsv_file = replace_underscore(prf_file, 'events.tsv') create_prf_events(tsv_file, bars.shape[2], DUR) stimuli_dir = bids_dir / 'stimuli' stimuli_dir.mkdir(exist_ok=True, parents=True) bar_file = stimuli_dir / STIM_FILE save(bar_file, bars)
def xmain(bids_dir, analysis_dir, freesurfer_dir, output_dir, acquisition='clinical', measure_modality="", measure_column=""): """ plot electrodes onto the brain surface, Parameters ---------- bids_dir : path analysis_dir : path freesurfer_dir : path output_dir : path acquisition : str acquisition type of the electrode files measure_modality : str modality measure_column : str column """ img_dir = output_dir / ELECSURF_DIR rmtree(img_dir, ignore_errors=True) img_dir.mkdir(exist_ok=True, parents=True) for electrode_path in find_in_bids(bids_dir, generator=True, acquisition=acquisition, modality='electrodes', extension='.tsv'): lg.debug(f'Reading electrodes from {electrode_path}') elec = Electrodes(electrode_path) fs = Freesurfer(freesurfer_dir / ('sub-' + elec.subject)) labels = None if measure_modality != "": try: ecog_file = find_in_bids(analysis_dir, subject=elec.subject, modality=measure_modality, extension='.tsv') except FileNotFoundError as err: lg.warning(err) continue lg.debug(f'Reading {measure_column} from {ecog_file}') ecog_tsv = read_tsv(ecog_file) labels = [x['name'] for x in elec.electrodes.tsv] labels, vals = read_channels(ecog_tsv, labels, measure_column) else: vals = None v = plot_electrodes(elec, fs, labels, vals) png_file = img_dir / replace_underscore(elec.get_filename(), 'surfaceplot.png') lg.debug(f'Saving electrode plot on {png_file}') v.save(png_file) v.close()
def test_replace_underscore(): assert replace_underscore('file_mod.txt', 'dat.txt') == 'file_dat.txt'
def project_electrodes(elec, freesurfer, analysis_dir): elec.acquisition += 'projected' bids_root = find_root(elec.filename) tsv_electrodes = elec.get_filename(bids_root) elec_realigned = {} HEMI = { 'L': 'lh', 'R': 'rh', } groups = {x['group'] for x in elec.electrodes.tsv} for group in groups: print(group) anat_dir = analysis_dir / ('sub-' + elec.subject) / 'anat' anat_dir.mkdir(exist_ok=True, parents=True) labels = [ x['name'] for x in elec.electrodes.tsv if x['group'] == group ] hemi = [ x['hemisphere'] for x in elec.electrodes.tsv if x['group'] == group ][0] elec_type = [ x['type'] for x in elec.electrodes.tsv if x['group'] == group ][0] if not elec_type == 'surface': print(f'not realigning {group} because its type is {elec_type}') for _elec in elec.electrodes_tsv: if _elec['group'] == group: elec_realigned[_elec['label']] = (float(_elec['x']), float(_elec['y']), float(_elec['z'])) anat_file = anat_dir / (HEMI[hemi] + '.smooth') if not anat_file.exists(): surf = getattr(freesurfer.read_brain('pial'), HEMI[hemi]) fill_surface(surf.surf_file, anat_file) xyz = array([(float(x['x']), float(x['y']), float(x['z'])) for x in elec.electrodes.tsv if x['group'] == group]) xyz -= freesurfer.surface_ras_shift xyz_realigned = snap_elec_to_surf(xyz, anat_file) for label, xyz_ in zip(labels, xyz_realigned): elec_realigned[label] = xyz_ + freesurfer.surface_ras_shift with tsv_electrodes.open('w') as f: f.write('name\tgroup\tx\ty\tz\tsize\ttype\tmaterial\themisphere\n') for _elec in elec.electrodes.tsv: label = _elec['name'] xyz = "\t".join(f'{x:f}' for x in elec_realigned[label]) one_chans = [x for x in elec.electrodes.tsv if x['name'] == label][0] group = one_chans['group'] elec_type = one_chans['type'] size = one_chans['size'] material = one_chans['material'] hemisphere = one_chans['hemisphere'] f.write( f'{label}\t{group}\t{xyz}\t{size}\t{elec_type}\t{material}\t{hemisphere}\n' ) elec.coordframe.json[ 'iEEGCoordinateProcessingDescription'] += '; Dijkstra et al.' # TODO: better description + remove None new_json = replace_underscore(tsv_electrodes, 'coordsystem.json') with new_json.open('w') as f: dump(elec.coordframe.json, f, indent=2) return Electrodes(tsv_electrodes)