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 plot_smooth(parameters, frequency_band, subject): corr_file = get_path(parameters, 'corr_tsv', frequency_band=frequency_band, subject=subject) if corr_file is None: return results = read_tsv(corr_file) traces = [ dict( x=results['Kernel'], y=results['Rsquared'], marker=dict(color='black', ), ), ] layout = go.Layout( xaxis=dict( dtick=4, range=(0, parameters['fmri']['at_elec']['kernel_end']), ), yaxis=dict( dtick=0.02, rangemode='tozero', ), ) fig = go.Figure( data=traces, layout=layout, ) return fig
def headmotions(parameters): fmri_dir = parameters['paths']['output'] / 'workflow' / 'fmri' freq = parameters['ieeg']['ecog_compare']['frequency_bands'][-1] summary_tsv = get_path(parameters, 'summary_tsv', frequency_band=freq) summary = read_tsv(summary_tsv) figs = {} for mc_name in ('abs', 'rel'): mc_type = f'prefiltered_func_data_mcf_{mc_name}_mean.rms' mc = [] for summ in summary: fmri_subj_dir = fmri_dir / f'_subject_{summ["subject"]}' mc_file = next(fmri_subj_dir.rglob(mc_type)) mc.append(genfromtxt(mc_file)) mc = array(mc) for value_type in ('r2_at_peak', 'size_at_peak'): traces = [ go.Scatter( x=mc, y=summary[value_type], mode='markers', marker=dict(color='black', ), ) ] layout = merge( LAYOUT, dict( margin=dict(t=30, ), height=230, width=200, showlegend=False, title=dict(text=mc_name + ' motion / ' + value_type.split('_')[0], ), xaxis=dict( rangemode='tozero', title=dict(text='head motions (mm)', ), ), yaxis=dict( rangemode='tozero', title=dict(text=value_type.split('_')[0], ), ), ), ) fig = go.Figure( data=traces, layout=layout, ) name = mc_type[:-4] + '_' + value_type figs[name] = fig return figs
def simulate_all(ROOT_DIR): simulate_bids(ROOT_DIR) elec = read_tsv(data_elec) simulate_ieeg(ROOT_DIR, task_ieeg, elec) simulate_electrodes(ROOT_DIR, elec_ct) simulate_bold(ROOT_DIR, task_fmri) simulate_anat(ROOT_DIR, task_anat, data_t1) simulate_bold_prf(ROOT_DIR, task_fmri_prf) simulate_ieeg_prf(ROOT_DIR, task_ieeg_prf)
def compute_corr_ecog_fmri_allfreq(fmri_file, ecog_file, min_n_sign_elec, pvalue, output_dir): output_dir.mkdir(exist_ok=True, parents=True) with ecog_file.open('rb') as f: ecog_stats = load(f) fmri_vals = read_tsv(fmri_file) fmri_idx = isin(fmri_vals['channel'], (ecog_stats.chan[0])) fmri_vals = fmri_vals[fmri_idx] assert_array_equal(fmri_vals['channel'], ecog_stats.chan[0]) threshold = norm.ppf(1 - pvalue / 2) kernel_sizes = fmri_vals.dtype.names[1:] n_freq = ecog_stats.freq[0].shape[0] rsquared = empty(( n_freq, len(kernel_sizes), )) slope = empty(( n_freq, len(kernel_sizes), )) pvalue = empty(( n_freq, len(kernel_sizes), )) for i_k, kernel in enumerate(kernel_sizes): for i_f in range(n_freq): x = ecog_stats.data[0][:, i_f] y = fmri_vals[kernel] rsquared[i_f, i_k], slope[i_f, i_k], pvalue[i_f, i_k] = compute_rsquared_pvalue( x, y, threshold, min_n_sign_elec) axes = { 'kernels': kernel_sizes, 'freq': ecog_stats.freq[0], } out_file = output_dir / 'corr_ecog_fmri_allfreq.pkl' with out_file.open('wb') as f: dump([rsquared, slope, pvalue, axes], f) return out_file
def _write_events(events_input, events_output): """ TODO ---- EVENTS should be in PARAMETERS """ EVENTS = ( 'move', 'verbgen', 'music', ) tsv = read_tsv(events_input) with events_output.open('w') as f: for event in tsv: if event['trial_type'] in EVENTS: f.write(f'{event["onset"]}\t{event["duration"]}\t1\n')
def _compute_summary(in_files, output_dir): summary_file = output_dir / 'summary_per_subject.tsv' with summary_file.open('w') as f: f.write(f'subject\tsession\ttask\tacquisition\tsize_at_peak\tr2_at_peak\tslope_at_peak\tintercept_at_peak\tsize_at_concave\tr2_at_concave\tdiff_r2\n') for corr_file in in_files: corr_tsv = read_tsv(corr_file) size_max, r2_max, slope, intercept = corr_tsv[argmax(corr_tsv['Rsquared'])] deriv = gradient(gradient(corr_tsv['Rsquared'])) size_deriv, r2_deriv, *dummy = corr_tsv[argmin(deriv)] file_info = file_Core(corr_file) f.write(f'{file_info.subject}\t{file_info.session}\t{file_info.task}\t{file_info.acquisition}\t{size_max}\t{r2_max}\t{slope}\t{intercept}\t{size_deriv}\t{r2_deriv}\t{r2_max - r2_deriv}\n')
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 plot_surface(parameters, frequency_band, subject, surf): elec_file = get_path(parameters, 'elec', subject=subject) ieeg_file = get_path(parameters, 'ieeg_tsv', frequency_band=frequency_band, subject=subject) fmri_file = get_path(parameters, 'fmri_nii', subject=subject) if elec_file is None or ieeg_file is None or fmri_file is None: return freesurfer_dir = parameters['paths'][ 'freesurfer_subjects_dir'] / f'sub-{subject}' compare_ieeg = read_tsv(ieeg_file) fs = Freesurfer(freesurfer_dir) electrodes = Electrodes(elec_file) elec = electrodes.electrodes.tsv all_elec = [] labels = [] for chan in compare_ieeg: i_chan = where(elec['name'] == chan['channel'])[0] all_elec.append(elec[i_chan]) labels.append(f"{chan['channel']} = {chan['measure']:0.3f}") elec = concatenate(all_elec) if mean(elec['x']) > 0: right_or_left = 1 hemi = 'rh' else: right_or_left = -1 hemi = 'lh' fs = Freesurfer(freesurfer_dir) pial = getattr(fs.read_brain(), hemi) vert = pial.vert + fs.surface_ras_shift if subject in surf: fmri_vals = surf[subject] else: print(f'Computing surf for {subject}') fmri_vals = project_mri_to_surf( fmri_file, vert, parameters['plot']['surface']['kernel']) surf[subject] = fmri_vals colorscale = 'balance' traces = [ go.Scatter3d( x=elec['x'], y=elec['y'], z=elec['z'], text=labels, mode='markers', hoverinfo='text', marker=dict( size=5, color=compare_ieeg['measure'], colorscale=colorscale, showscale=True, cmid=0, colorbar=dict( title='electrodes', titleside="top", ticks="outside", ticklabelposition="outside", x=0, ), ), ), go.Mesh3d( x=vert[:, 0], y=vert[:, 1], z=vert[:, 2], i=pial.tri[:, 0], j=pial.tri[:, 1], k=pial.tri[:, 2], intensity=fmri_vals, cmid=0, colorscale='Balance', hoverinfo='skip', flatshading=False, colorbar=dict( title='fmri', titleside="top", ticks="outside", ticklabelposition="outside", x=1, ), lighting=dict( ambient=0.18, diffuse=1, fresnel=0.1, specular=1, roughness=0.1, ), lightposition=dict( x=0, y=0, z=-1, ), ), ] fig = go.Figure( data=traces, layout=go.Layout(scene=dict( xaxis=AXIS, yaxis=AXIS, zaxis=AXIS, camera=dict( eye=dict( x=right_or_left, y=0, z=0, ), projection=dict(type='orthographic', ), ), ), ), ) return to_div(fig)
def plot_histogram(parameters, frequency_band): summary_tsv = get_path(parameters, 'summary_tsv', frequency_band=frequency_band) if summary_tsv is None: return summary = read_tsv(summary_tsv) figs = [] for value_type in ('r2_at_peak', 'size_at_peak', 'size_at_concave'): if value_type in ('size_at_peak', 'size_at_concave'): bin_size = 1 dtick = 4 max_val = parameters['fmri']['at_elec']['kernel_end'] elif value_type == 'r2_at_peak': bin_size = .1 dtick = 0.2 max_val = 1 if SHIFT == 'middle': xbins = dict( start=bin_size / -2, end=max_val + bin_size / 2, size=bin_size, ) else: xbins = dict( start=0, end=max_val + bin_size, size=bin_size, ) values = summary[value_type] traces = [ go.Histogram( x=values, xbins=xbins, marker=dict( color='black', ), ), ] layout = go.Layout( barmode='stack', showlegend=False, xaxis=dict( range=(0, max_val + bin_size / 2), dtick=dtick, ), yaxis=dict( dtick=1, ), ) fig = go.Figure( data=traces, layout=layout, ) figs.append(fig) return figs
def read_shape(one_tsv): results = read_tsv(one_tsv) k = [float(x['Kernel']) for x in results] rsquared = [float(x['Rsquared']) for x in results] return polyfit(k, rsquared, 2)[0], k[argmax(rsquared)], max(rsquared)
def timeseries_fmri(parameters): fmri_dir = parameters['paths']['output'] / 'workflow' / 'fmri' subject = parameters['plot']['subject'] subject = 'delft' fmri_subj_dir = fmri_dir / f'_subject_{subject}' regressor_file = next(fmri_subj_dir.rglob('design.mat')) thresh_file = next(fmri_subj_dir.rglob('thresh_zstat1.nii.gz')) timeseries_file = next(fmri_subj_dir.rglob('filtered_func_data.nii.gz')) subj_dir = parameters['paths']['input'] / f'sub-{subject}' events_fmri_file = next(subj_dir.glob('ses-*/func/*_events.tsv')) events = read_tsv(events_fmri_file) thresh = nload(thresh_file).get_fdata() i_vox = thresh >= THRESH timeseries = nload(timeseries_file).get_fdata() fmri = timeseries[i_vox] t_fmri = arange(timeseries.shape[3]) * TR regressor = genfromtxt(regressor_file, skip_header=5) traces = [ go.Scatter( x=t_fmri, y=fmri.mean(axis=0), line=dict(color='black', ), ), go.Scatter( x=t_fmri, y=regressor, yaxis='y2', ), ] layout = merge( LAYOUT, dict( height=100, width=450, showlegend=False, xaxis=dict( tick0=0, dtick=30, range=(0, 270), ), yaxis=dict(), yaxis2=dict( overlaying='y', side='right', visible=False, ), shapes=event_shapes(events), ), ) fig = go.Figure( data=traces, layout=layout, ) return fig
def timeseries_ieeg(parameters): ieeg_dir = parameters['paths']['output'] / 'workflow' / 'ieeg' subject = parameters['plot']['subject'] freq = parameters['ieeg']['ecog_compare']['frequency_bands'][-1] ieeg_subj_dir = ieeg_dir / f'_subject_{subject}' ieeg_compare_file = next( ieeg_subj_dir.glob( f'_frequency_{freq[0]}.{freq[1]}/ecog_compare/sub-*_compare.tsv')) ieeg0_file = next(ieeg_subj_dir.rglob('*_task-motoractive_*_ieeg.pkl')) ieeg1_file = next(ieeg_subj_dir.rglob('*_task-motorbaseline_*_ieeg.pkl')) subj_dir = parameters['paths']['input'] / f'sub-{subject}' events_ieeg_file = next(subj_dir.glob('ses-*/ieeg/*_events.tsv')) dat0 = compute_quick_spectrogram(ieeg0_file, freq) dat1 = compute_quick_spectrogram(ieeg1_file, freq) dat = dat0._copy() dat.data = concat([dat0.data, dat1.data]) dat.axis['time'] = concat([dat0.time, dat1.time]) dat.axis['chan'] = concat([dat0.chan, dat1.chan]) dat = concatenate(dat, axis='time') ieeg_compare = read_tsv(ieeg_compare_file) chans = ieeg_compare['channel'][ieeg_compare['measure'] > 10] x0 = math(select(dat, chan=chans), operator_name='mean', axis='chan') t = dat.time[0] x = x0(trial=0) i_t = argsort(t) events = read_tsv(events_ieeg_file) i_start = where(events['trial_type'] == 'rest')[0][0] offset = events['onset'][i_start] events['onset'] -= offset traces = [ go.Scatter(x=t[i_t] - offset, y=x[i_t], line=dict(color='black', )), ] layout = merge( LAYOUT, dict( height=100, width=450, xaxis=dict( tick0=0, dtick=30, range=(0, 330), ), yaxis=dict( dtick=0.1, range=(0, 0.4), ), shapes=event_shapes(events), ), ) fig = go.Figure(data=traces, layout=layout) return fig
def plot_freq_comparison(parameters): freqA = parameters['ieeg']['ecog_compare']['frequency_bands'][ parameters['plot']['compare']['freqA']] freqB = parameters['ieeg']['ecog_compare']['frequency_bands'][ parameters['plot']['compare']['freqB']] actA = read_tsv(get_path(parameters, 'summary_tsv', frequency_band=freqA)) actB = read_tsv(get_path(parameters, 'summary_tsv', frequency_band=freqB)) max_r = max(r_[actA['r2_at_peak'], actB['r2_at_peak']]) result = ttest_rel(actA['r2_at_peak'], actB['r2_at_peak']) traces = [ go.Scatter( x=actA['r2_at_peak'], y=actB['r2_at_peak'], text=actA['subject'], mode='markers', marker=dict(color='black', ), ) ] figs = [] fig = go.Figure( data=traces, layout=go.Layout( height=500, width=500, title=dict( text= f'R<sup>2</sub> values (paired t-test, <i>p</i> = {result.pvalue:0.03f})' ), xaxis=dict( title=dict(text=axis_label(freqA), ), tick0=0, dtick=0.1, range=[0, max_r + 0.1], ), yaxis=dict( title=dict(text=axis_label(freqB), ), tick0=0, dtick=0.1, range=[0, max_r + 0.1], ), shapes=[ dict(type='line', layer='below', x0=0, x1=max_r + 0.1, y0=0, y1=max_r + 0.1, line=dict(color='gray', )) ])) figs.append(fig) for param in ('size_at_peak', 'size_at_concave'): fig = _plot_compare_size(actA, actB, param, parameters, freqA, freqB) figs.append(fig) param = 'slope_at_peak' min_r = min(r_[actA[param], actB[param]]) max_r = max(r_[actA[param], actB[param]]) diff_act = mean(actA[param] - actB[param]) result = ttest_rel(actA[param], actB[param]) regr = linregress(actA['slope_at_peak'], actB['slope_at_peak']) traces = [ go.Scatter( x=actA[param], y=actB[param], text=actA['subject'], mode='markers', marker=dict(color='black', ), ) ] fig = go.Figure( data=traces, layout=go.Layout( height=500, width=500, title=dict( text= f'Difference [{freqA[0]}-{freqA[1]}] Hz - [{freqB[0]}-{freqB[1]}] Hz = {diff_act:0.2f}<br />paired t-test, <i>p</i> = {result.pvalue:0.03f}<br />regression slope = {regr.slope:0.3f} <i>p</i> = {regr.pvalue:0.03f}' ), xaxis=dict( title=dict(text=axis_label(freqA), ), tick0=0, dtick=0.2, range=[min_r - 0.1, max_r + 0.1], ), yaxis=dict( title=dict(text=axis_label(freqB), ), tick0=0, dtick=0.2, range=[min_r - 0.1, max_r + 0.1], scaleanchor="x", scaleratio=1, ), shapes=[ dict(type='line', layer='below', x1=-min_r - 0.1, x0=-max_r - 0.1, y1=min_r + 0.1, y0=max_r + 0.1, line=dict(color='gray', )), dict(type='line', layer='below', x0=0, x1=1, y0=0, y1=0, xref='paper', line=dict( width=2, color='gray', )), dict(type='line', layer='below', x0=0, x1=0, y0=0, y1=1, yref='paper', line=dict( width=2, color='gray', )), ])) figs.append(fig) return figs
def plot_brain_regions(parameters, ieeg_file, region_type): """ region_type can be one of: 'aparc.a2009s', 'aparc.DKTatlas', 'BA_exvivo', 'BA_exvivo.thresh', """ brainregions_file = name(parameters, 'brainregions', ieeg_file) electrodes = read_tsv(brainregions_file) pial = load('pial', parameters, ieeg_file) annot = load(region_type, parameters, ieeg_file) colors = [] labels = [] for elec in electrodes: region = elec[region_type] labels.append(f'{elec["chan"]} = {region}') colors.append(annot['regions']['colors'][region]) # to normalize plotly n_regions = len(annot['regions']['names']) right_or_left = sign((electrodes['x'] > 0).sum() / electrodes.shape[0] - .5) traces = [ go.Mesh3d( x=pial.vert[:, 0], y=pial.vert[:, 1], z=pial.vert[:, 2], i=pial.tri[:, 0], j=pial.tri[:, 1], k=pial.tri[:, 2], intensity=annot['regions']['values'] / n_regions, colorscale=annot['regions']['colorscale'], hoverinfo='skip', showscale=False, flatshading=False, lighting=dict( ambient=0.18, diffuse=1, fresnel=0.1, specular=1, roughness=0.1, ), lightposition=dict( x=0, y=0, z=-1, ), ), go.Scatter3d( x=electrodes['x'], y=electrodes['y'], z=electrodes['z'], text=labels, mode='markers', hoverinfo='text', marker=dict( size=5, color=colors, ), ) ] fig = go.Figure( data=traces, layout=go.Layout(scene=dict( xaxis=AXIS, yaxis=AXIS, zaxis=AXIS, camera=dict( eye=dict( x=right_or_left, y=0, z=0.5, ), projection=dict(type='orthographic', ), ), ), ), ) return fig