Example #1
0
def reg_single_channel_wrap(model,
                            subs=cfg.subs,
                            bands=cfg.bands,
                            alpha=cfg.alpha,
                            name=''):

    # load data
    df = cf.load_df(f"reg_{model['tag']}", bands=bands, subs=subs)
    # filter out not significant
    df = df.query(f'p<{alpha}')

    time_start = time.time()
    for i in range(len(df)):
        cf.display_progress(
            f"{df.iloc[i]['sub']} {df.iloc[i]['ch_name']} {df.iloc[i]['band']}",
            i, len(df), time_start)
        for predictor in model['predictors_stepwise']:
            if df.iloc[i]['p' + predictor] < alpha and df.iloc[i][
                    'r2' + predictor] > 0:
                band = cfg.bands[[b['name'] for b in cfg.bands
                                  ].index(df.iloc[i]['band'])]
                reg_single_channel(df.iloc[i]['sub'],
                                   df.iloc[i]['ch_name'],
                                   band,
                                   model,
                                   plot=False)
    cf.concatenate_pdfs(cf.check_path(
        ['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]),
                        'temp',
                        f"single_channel_reg-{model['tag']}{name}.pdf",
                        remove=True)
Example #2
0
def electrode_positions(subs=cfg.subs):
    """ Make one figure per channel with the position of the channel
        Concatenate for each subject
    """

    print("\n======== electrode positions ======================================\n")

    FiguresPath =cf.check_path(['..','Figures' , 'overview' + cfg.out ])

    # iterate over subjects
    for sub in subs:

        cf.print_d(f'Electrode positions for {sub}')

        # load subject params
        SP = cf.sub_params(sub)

        for iCh, ChName in enumerate(SP['ChNames']):

            fig, ax = plt.subplots(1,1,figsize=(6,2))    
            pl.clear_axes(np.array([ax]))    
            fig.suptitle(f"{sub} {ChName}")

            pl.channel_position_plot(ax,SP['coords'],iCh)

            fig_name = os.path.join(FiguresPath,f"elec_positions_{sub}_{ChName}_temp.pdf")
            fig.savefig(fig_name, format='pdf') 
            plt.close()

        cf.concatenate_pdfs(FiguresPath,'temp',f"elec_positions_{sub}.pdf", remove=True)
Example #3
0
def subject_overview(subs = cfg.subs, bands = cfg.bands, EpochsSetups = cfg.EpochsSetups,
                        avg = True, TrialWise = True, key = None, picks = 'good'):
    """ Make one figure per channel with
    channel position and one evoked plot per band

    Parameters
    ----------
    key :  str
        metadata key to plot separate traces by metadata value
    """

    print("\n======== subject overview =========================================\n")

    # iterate over subjects
    for sub in subs:
        # load subject params
        SP = cf.sub_params(sub)

        # preload raw data for all bands
        epochs = []
        iterator =  product(enumerate(bands),enumerate(EpochsSetups))
        for i, ((iBand, band),(iEp, EpochsSetup)) in enumerate(iterator): 
            cf.print_d(f"{sub}, loading {band['name']} epochs...")
            # get list of channels
            PicksList = cf.get_picks(SP, picks, band = band)
            if PicksList == []: continue
            # epochs (phase epochs are complex and cannot be resampled)
            try: epochs += [cf.load_epochs(sub, band, EpochsSetup, picks = PicksList).resample(100)]
            except: epochs += [cf.load_epochs(sub, band, EpochsSetup, picks = PicksList)]

        # iterate over channels, one figure per channel
        TimeStart = time.time()
        for iCh, ChName in enumerate(PicksList): 
            cf.display_progress(f"{sub}, {ChName}", iCh, len(PicksList),TimeStart) 
    
            channel_overview(sub, ChName, bands, EpochsSetups, EpochsList=epochs, key=key, plot = False, save = True, temp=True)
            
        # concatenate figures subject wise
        FileName = f"{sub}_band-{band['name']}_{picks}_overview.pdf"
        FiguresPath = cf.check_path(['..', 'Figures', 'overview' + cfg.out])
        cf.concatenate_pdfs(FiguresPath, 'temp', FileName, remove = True)

    # concatenate for all subjects
    FileName = f"band-{band['name']}_{picks}_overview.pdf"
    FiguresPath = cf.check_path(['..', 'Figures', 'overview' + cfg.out])
    cf.concatenate_pdfs(FiguresPath, 'sub', FileName, remove = False)
Example #4
0
def rejection_figure(SP, kept, stats, thresholds, save=True, plot=False):
    """ Make rejection summary figure for single subject
        
    """

    #create figure
    fig, ax = plt.subplots(2, 1, figsize=(7, 7))
    fig.suptitle(
        f"{SP['sub']}, rejected {np.sum(~kept)}/{len(kept)}, {int(100*np.sum(~kept)/len(kept))}%",
        fontsize=15)

    # rejected channel positions
    pl.brain_plot(ax[0],
                  SP['ChInfo']['coords'],
                  1. * (~kept),
                  mask=kept,
                  mode='symmetric',
                  interval=[0, 1])

    # scatter with rejection summary
    pl.scatter_plot(ax[1],
                    stats[0],
                    stats[1],
                    stats[2],
                    colorbar='s',
                    mask=kept,
                    ylabel='std(dVdt)',
                    xlabel='std(V)',
                    vlines=thresholds[0],
                    hlines=thresholds[1])

    # save figure
    FigName = os.path.join(cf.check_path([SP['FiguresPath'], 'rejection']),
                           f"{SP['sub']}.pdf")
    if save: fig.savefig(FigName, format='pdf', dpi=100)
    if plot: plt.show()
    else: plt.close()
Example #5
0
def reg_maps(model,
             predictors=[''],
             subs=cfg.subs,
             bands=cfg.bands,
             alpha=cfg.alpha,
             filter_tag='',
             fdr=False,
             plot=True,
             save=True,
             concat=True,
             time=True):
    """ Plot brain maps for variables (p_value, r2, ...) 
        stored in files for each band

    Parameters
    ----------
    alpha : float
        level of significance (leave out p>alpha)
    subs : list of str
        list of subjects to include f.e. [sub-01, sub-02]
    bands : list of dict
        list of bands to include   

    """

    print(f"\nBand comparison brain map for reg {model['tag']}")

    if predictors == 'all': predictors = [''] + model['predictors']

    # load data
    df = cf.load_df(f"reg_{model['tag']}", bands=bands, subs=subs)
    # get total number of channels
    L = len(df[df['band'] == bands[0]['name']])
    # filter out regressions with negative score
    df = df.query(f'r2>0  and p<{alpha}')

    if time:
        conditions, keys = [], []
        for p in predictors:
            conditions += 2 * ['p' + p]
            keys += ['r2' + p, 't' + p]
    else:
        conditions = ['p' + p for p in predictors]
        keys = ['r2' + p for p in predictors]

    # loop over figures
    for i, (k, c) in enumerate(zip(keys, conditions)):

        print(i, k)
        fig, ax = plt.subplots(len(bands),
                               2,
                               figsize=(12, 3 * len(bands)),
                               gridspec_kw={'width_ratios': [3, 1]})
        if len(bands) == 1: ax = np.array([ax])
        fig.suptitle(fr"reg {model['tag']}, {k}, {c} $\leq {alpha}$",
                     fontsize=20)

        for i_band, band in enumerate(bands):
            df_band = df[df['band'] == band['name']]

            if len(df_band) == 0: continue
            # extract data to plot
            x = df_band[k]
            coords = np.array([c for c in df_band['coords'].values])
            pl.brain_plot(ax[i_band, 0],
                          coords,
                          x,
                          ylabel=band['name'],
                          mask=(df_band[c] > alpha),
                          colorbar='' + (i_band == (len(bands) - 1)) * k,
                          mode='interval',
                          interval=[max(0, np.min(df[k])),
                                    np.max(df[k])])

            s = df_band[df_band[c] < alpha][k]
            x = np.linspace(0, np.max(df[k]), 20)
            h, x = np.histogram(s, bins=x, density=False)
            ax[i_band, 1].bar(x[:-1] + .5 * (x[1] - x[0]),
                              h,
                              width=.8 * (x[1] - x[0]))
            ax[i_band, 1].set_xlabel(k)
            ax[i_band, 1].spines['right'].set_visible(False)
            ax[i_band, 1].spines['top'].set_visible(False)
            ax[i_band, 1].tick_params(axis='both',
                                      which='both',
                                      size=0,
                                      labelsize=9)
            if k != 'r2': L = len(df)
            ax[i_band,
               1].set_title(f"{np.sum(h)}/{L}  {int(100*np.sum(h)/L)}%")

        fig.subplots_adjust(left=0.1, right=0.9, hspace=0.5)
        if save:
            fig_name = os.path.join(
                cf.check_path(
                    ['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]),
                f"brain_map_reg_{model['tag']}_{str(i).zfill(2)}{'_temp'*concat}.pdf"
            )
            fig.savefig(fig_name, format='pdf', dpi=100)
        if plot: plt.show()
        else: plt.close()
    if save and concat:
        cf.concatenate_pdfs(cf.check_path(
            ['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]),
                            'temp',
                            f"brain_map_reg-{model['tag']}.pdf",
                            remove=True)
Example #6
0
def reg_statistics(model,
                   predictors=[''],
                   subs=cfg.subs,
                   bands=cfg.bands,
                   alpha=cfg.alpha,
                   filter_tag='',
                   plot=True,
                   save=True):

    # load data
    df = cf.load_df(f"reg_{model['tag']}", bands=bands, subs=subs)

    L = len(df)
    # filter out regressions with negative score
    df = df.query(f'r2>0  and p<{alpha}')

    if predictors == 'all': predictors = [''] + model['predictors']
    keys = ['p' + p for p in predictors]
    conditions = ['r2' + p for p in predictors]

    fig, ax = plt.subplots(len(keys),
                           3,
                           figsize=(12, 3 * len(keys)),
                           gridspec_kw={'width_ratios': [1, 2, 0.5]})
    if len(keys) == 1: ax = np.array([ax])

    fig.suptitle(f"Regression stats summary", fontsize=15)

    colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(bands)))

    for i, (k, c) in enumerate(zip(keys, conditions)):

        # scatter r2 vs p -------------------------------------------------------------
        for i_band, band in enumerate(bands):
            ax[i, 0].scatter(df[df['band'] == band['name']][k],
                             df[df['band'] == band['name']][c],
                             c=[colors[i_band]],
                             alpha=0.3)
        ax[i, 0].set_xlabel(k)
        ax[i, 0].set_ylabel(c)
        ax[i, 0].axvline(alpha, color='k', linewidth=0.5)
        ax[i, 0].axhline(0, color='k', linewidth=0.5)
        ax[i, 0].spines['right'].set_visible(False)
        ax[i, 0].spines['top'].set_visible(False)
        ax[i, 0].tick_params(axis='both', which='both', size=0, labelsize=9)

        # number of significant channels ----------------------------------------------
        n = []

        for sub in subs:

            # load subject params
            dp = cf.sub_params(sub)

            # significant channels for subjec-band pair
            n_sub = []

            # iterate over bands -----------------------------------------------
            for i_band, band in enumerate(bands):
                n_sub += [
                    np.sum(
                        np.array(df[(df['sub'] == sub) &
                                    (df['band'] == band['name'])][k]) < alpha)
                ]
            # go to next band --------------------------------------------------
            n += [n_sub]
            # go to next subject ======================================================

        n = np.array(n).T

        # width and positions of bars
        width = 0.8 / len(bands)
        x = np.arange(len(subs))

        colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(bands)))

        for i_band, band in enumerate(bands):
            ax[i, 1].bar(x + i_band * width,
                         n[i_band],
                         width,
                         color=colors[i_band])
            ax[i, 2].bar(i_band * width,
                         np.sum(n[i_band]),
                         width,
                         label=band['name'],
                         color=colors[i_band])

        ax[i, 1].set_ylabel("# significant channels")
        ax[i, 1].set_xticks(np.arange(len(subs)) + 0.4)
        ax[i, 1].set_xticklabels(subs, rotation=45)
        ax[i, 1].spines['right'].set_visible(False)
        ax[i, 1].spines['top'].set_visible(False)
        ax[i, 1].tick_params(axis='both', which='both', size=0, labelsize=9)

        ax[i, 2].set_xticks([0.4])
        ax[i, 2].set_xlim([-0.2, 1])
        ax[i, 2].set_xticklabels(['Total'])
        ax[i, 2].spines['right'].set_visible(False)
        ax[i, 2].spines['top'].set_visible(False)
        ax[i, 2].tick_params(axis='both', which='both', size=0, labelsize=9)

        if i > 0: L = len(df)
        ax[i, 2].set_title(f"{np.sum(n)}/{L}  {int(100*np.sum(n)/L)}%")

    ax[0, 2].legend(frameon=False, loc=(1, 0.2), fontsize=9)
    fig.subplots_adjust(left=0.1, right=0.9, wspace=0.3, hspace=0.5)

    # save figure
    fig_name = os.path.join(
        cf.check_path(['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]),
        f"stats_reg_{model['tag']}.pdf")
    if save: fig.savefig(fig_name, format='pdf', dpi=100)
    if plot: plt.show()
    else: plt.close()
Example #7
0
def spike_detection(sub, ch_name, tw):

    dp = cf.sub_params(sub)

    # load epochs
    filename = os.path.join(dp['derivatives_path'], f'{sub}_raw.fif')
    raw = mne.io.read_raw_fif(filename, preload=True).crop(tmin=tw[0],
                                                           tmax=tw[1])

    amp = np.array([raw.get_data(picks=ch_name)])
    t = np.linspace(tw[0], tw[1], amp.shape[-1])

    # compute wavelets
    f = np.arange(5, 150, 2)
    power = np.squeeze(
        mne.time_frequency.tfr_array_morlet(amp,
                                            sp.srate,
                                            f,
                                            n_cycles=f / 2.,
                                            output='power')[0])
    power = power / power.std(axis=-1)[:, np.newaxis]  #*f[:,np.newaxis]
    amp = np.squeeze(amp)

    timewindowsize = 0.1  # s
    d = int(timewindowsize * sp.srate)
    C = []
    for i in range(len(t) - d):
        cf.print_d(f"{i/(len(t) - d)}")
        corr = np.corrcoef(power[:, i:i + d])
        corr = corr[np.triu_indices_from(corr, k=1)]
        C += [corr]

    C = np.array(C).T

    fig, ax = plt.subplots(4, 1, figsize=(6, 6))
    fig.suptitle(f'{sub} {ch_name}')

    coords = dp['coords'][dp['ch_names'].index(ch_name)]
    pl.channel_position_plot(ax[0], [coords], 0)

    pl.trace_plot(ax[1],
                  t,
                  amp,
                  xlims=[tw[0] + 0.5, tw[1] - 0.5],
                  ylabel='V (uV)')

    pl.imshow_plot(ax[2],
                   power,
                   title='',
                   ylabel='f (Hz)',
                   xlims=[tw[0] + 0.5, tw[1] - 0.5],
                   ylims=f,
                   colorbar='power (std)')

    pl.trace_plot(ax[3],
                  t[:-d],
                  C,
                  xlims=[tw[0] + 0.5, tw[1] - 0.5],
                  ylabel='correlation',
                  xlabel='t (s)',
                  plot_std=True,
                  plot_p595=True,
                  mode='avg')

    fig_name = os.path.join(cf.check_path(['..', 'Figures', 'spikes']),
                            f'{sub}_{ch_name}_{int(tw[0])}.pdf')
    fig.savefig(fig_name, format='pdf')
    plt.close()
Example #8
0
def num_significant_channels(key,
                             test,
                             tag,
                             split=None,
                             alpha=sp.alpha,
                             subs=sp.subject_list,
                             bands=sp.bands):
    """ Make a bar plot with number of significant channels
        per subject per band for some test or regression

    Parameters
    ----------
    key : str
        name of the column to extract
    test : str
        name of the test/regression that works as a label for files
        queries : dict
        generated with cf.compose_queries, contains mne queries, file tag, queries list
    split : int or str
        if int divide the time window into 'split' chunks and run one test in each
        if string separate epochs by values of metadata column 'split',
        f.ex. split = 'w_position' run the test for each word position
    alpha : float
        level of significance (leave out p>alpha)
    subs : list of str
        list of subjects to include f.e. [sub-01, sub-02]
    bands : list of dict
        list of bands to include   
    """

    print(f"\n{test} {tag} summary figure")

    df = cf.load_df(test + '_' + tag)

    if split == None: labels = ['']  # no split
    elif isinstance(split, int):
        labels = list(np.unique(df['tw'].to_numpy()))  # split by time windows
    elif isinstance(split, str):
        labels = list(np.unique(df[split].to_numpy()))  # split by conditions

    num_plots = len(labels)

    fig, ax = plt.subplots(num_plots,
                           1,
                           figsize=(len(subs), 3 * num_plots),
                           sharex=True)
    fig.suptitle(fr"{test} {tag}, {key} $\leq {alpha}$")

    if split == None: ax = np.array([ax])

    # loop over plots
    for i_plot, label in enumerate(labels):

        # number of significant channels
        n = []

        for sub in subs:

            # load subject params
            dp = cf.sub_params(sub)

            # significant channels for subjec-band pair
            n_sub = []

            # iterate over bands -----------------------------------------------
            for i_band, band in enumerate(bands):
                if split == None:
                    n_sub += [
                        np.sum(
                            np.array(df[(df['sub'] == sub) & (
                                df['band'] == band['name'])][key]) < alpha)
                    ]
                    title = ''
                elif isinstance(split, int):
                    n_sub += [
                        np.sum(
                            np.array(df[
                                (df['sub'] == sub)
                                & (df['band'] == band['name'])
                                & ([x == label for x in df['tw'].to_numpy()])]
                                     [key]) < alpha)
                    ]
                    title = str(label) + ' s'
                elif isinstance(split, str):
                    n_sub += [
                        np.sum(
                            np.array(df[(df['sub'] == sub)
                                        & (df['band'] == band['name'])
                                        & (df[split] == label)][key]) < alpha)
                    ]
                    title = f"{split} = {label}"
                # go to next band --------------------------------------------------
            n += [n_sub]
            # go to next subject ======================================================

        n = np.array(n).T

        # width and positions of bars
        width = 0.8 / len(bands)
        x = np.arange(len(subs))

        colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(bands)))

        for i_band, band in enumerate(bands):
            ax[i_plot].bar(x + i_band * width,
                           n[i_band],
                           width,
                           label=band['name'],
                           color=colors[i_band])

        ax[i_plot].set_ylabel("# significant channels")
        ax[i_plot].set_title(title)
        ax[i_plot].set_xticks(np.arange(len(subs)) + 0.4)
        ax[i_plot].set_xticklabels(subs)
        ax[i_plot].spines['right'].set_visible(False)
        ax[i_plot].spines['top'].set_visible(False)
        ax[i_plot].tick_params(axis='both', which='both', size=0, labelsize=9)

    ax[i_plot].legend(frameon=False, loc=(1, 0.2), fontsize=9)
    fig.subplots_adjust(right=0.8)

    # save figure
    fig_name = os.path.join(cf.check_path(['..', 'Figures', test + sp.out]),
                            f"summary_{test}_{tag}_{key}.pdf")
    fig.savefig(fig_name, format='pdf', dpi=100)
    if sp.plot: plt.show()
    plt.close()
Example #9
0
def band_comparison_matrix(key,
                           file_tag,
                           path,
                           title='',
                           label='',
                           subs=sp.subject_list,
                           bands=sp.bands,
                           log10=False):
    """ Compare variables (p_value, r2, ...) between bands 
        with scatter plots

    Parameters
    ----------
    key : str
        name of the column to extract
    file_tag : str
        name of the figure will be brain_map_{file_tag}.pdf
    subs : list of str
        list of subjects to include f.e. [sub-01, sub-02]
    bands : list of dict
        list of bands to include   

    """

    print(f'\nBand comparison matrix for {file_tag}')

    if len(bands) == 1: sys.exit('At least 2 bands needed only 1 was passed')

    df = cf.load_df(file_tag, subs=subs, bands=bands)

    # fig 2: comparison accros bands ---------------------------------------------------------------------
    fig, ax = plt.subplots(len(bands) - 1,
                           len(bands) - 1,
                           figsize=(2.5 * (len(bands) - 1),
                                    2.5 * (len(bands) - 1)))
    fig.suptitle(title, fontsize=20)
    clear_axes(ax)

    for i, band in enumerate(bands[:-1]):

        # data for first band
        x = df[df['band'] == band['name']][key]
        if log10: x = -np.log10(x)

        ax[-1, i].set_xlabel(band['name'])
        ax[i, 0].set_ylabel(bands[i + 1]['name'])

        # comparison across bands
        for j in range(i, len(bands) - 1):
            y = df[df['band'] == bands[j + 1]['name']][key]
            if log10: y = -np.log10(y)

            ax[j, i].scatter(x, y)
            #ax[j,i].hist2d(x,y,bins=np.linspace(min(x.min(),y.min()),max(x.max(),y.max()),10),cmap='Reds')

            # draw diagonal line
            ax[j, i].axis('equal')
            ax[j, i].plot([0, 1], [0, 1], 'k--', transform=ax[j, i].transAxes)
            ax[j, i].spines['left'].set_visible(True)
            ax[j, i].spines['bottom'].set_visible(True)
            #ax[i,j].set_xlim([0,np.log10(sp.n_permutations)])
            #ax[i,j].set_ylim([0,np.log10(sp.n_permutations)])
            #ax[i,j].set_xticks([0,1,2])
            #ax[i,j].set_yticks([0,1,2])

    fig.subplots_adjust(left=0.05,
                        bottom=0.05,
                        right=0.95,
                        top=0.95,
                        wspace=0.3,
                        hspace=0.3)

    # save figure
    fig_name = os.path.join(cf.check_path(path), f"matrix_{file_tag}.pdf")
    fig.savefig(fig_name, format='pdf', dpi=100)
    if sp.plot: plt.show()
    plt.close()
Example #10
0
def ttest(EpochsSetups,
          EOIlabel,
          split=None,
          subs=cfg.subs,
          bands=cfg.bands,
          picks='good',
          alpha=cfg.alpha,
          paired=False,
          PopMean=0,
          alternative='greater',
          Bonferroni=False,
          fdr=True,
          figure=True):
    """ Run ttest on epochs looping over subjects and bands

    Use split to run tests on different subsets of the data
        
    Parameters
    ----------
    EpochsSetups : list of dict
    split : str or None
        separate epochs by values of metadata column 'split',
        f.ex. split = 'w_position' run the test independently for each word position
    subs : list of str
        subject list
    bands : list of dict

    Outputs
    -------
   
    """
    print(
        f"\n======== t-test ==================================================\n  {EOIlabel}\n"
    )

    from scipy.stats import ttest_ind, ttest_1samp

    # ITERATE SUBJECT LIST AND BAND LIST =======================================
    TimeStart = time.time()
    iterator = list(product(enumerate(bands), enumerate(subs)))
    for i, ((iBand, band), (iSub, sub)) in enumerate(iterator):

        cf.display_progress(f"{sub} {band['name']}", i, len(iterator),
                            TimeStart)

        # load subject params
        SP = cf.sub_params(sub)

        if 'EOI' in picks and SP['ChInfo'][f"{picks}-{band['name']}"] == []:
            continue

        # colect data
        samples, values = get_samples(sub,
                                      band,
                                      EpochsSetups,
                                      split=split,
                                      picks=picks,
                                      paired=paired,
                                      avg=True)

        # perform tests
        pValues = []
        # ---- 2 sample test --------
        if len(samples[0]) == 2:
            for s1, s2 in samples:
                # s1 = [n_observations (i.e. n_epochs), n_channels]
                pValues += [
                    ttest_ind(s1 - PopMean,
                              s2,
                              equal_var=False,
                              alternative=alternative)[1]
                ]

        # ---- 1 sample test --------
        if len(samples[0]) == 1:
            for s1 in samples:
                pValues += [
                    ttest_1samp(s1[0],
                                PopMean,
                                axis=0,
                                alternative=alternative)[1]
                ]
        pValues = np.array(pValues)

        # Bonferroni correction
        if split != None and Bonferroni: pValues *= len(samples)
        # fdr correction
        if fdr:
            pValues = mne.stats.fdr_correction(
                pValues[:], cfg.alpha)[1].reshape(pValues.shape)
        RejectedNull = np.sum(pValues < alpha, axis=0)
        # boolean with True for significant chs
        SignificantMask = (RejectedNull > 0)
        # List of significant ch names
        SignificantList = [
            ch for j, ch in enumerate(cf.get_picks(SP, picks=picks, band=band))
            if SignificantMask[j]
        ]

        # save to ChInfoFile
        SP['ChInfo'][f"{EOIlabel}-{band['name']}"] = SignificantList
        json.dump(SP['ChInfo'], open(SP['ChInfoFile'], 'w'))

        print(
            f"\r{sub} {band['name']} {len(SignificantList)}/{len(SignificantMask)} significant channels"
        )

        if figure:
            ttest_figure_signle_sub(SP, band, EpochsSetups, split, samples,
                                    values, SignificantMask, SignificantList,
                                    PopMean, pValues, picks, alpha)

        # concatenate for each band
        if figure and iSub == len(subs) - 1:
            #ttest_figure_all_subs()
            # concatenate figures
            FiguresPath = cf.check_path(['..', 'Figures', 'ttest' + cfg.out])
            FigureName = f"ttest-{EOIlabel}_band-{band['name']}.pdf"
            cf.concatenate_pdfs(FiguresPath,
                                f'sub*temp',
                                FigureName,
                                remove=True)
Example #11
0
def contrast(key1,
             key2,
             test1,
             test2,
             model1,
             model2,
             alpha=sp.alpha,
             subs=sp.subject_list,
             bands=sp.bands,
             plot=True,
             save=True):
    """ Plot brain maps for variables (p_value, r2, ...) 
        stored in files for each band

    Parameters
    ----------
    key : str
        name of the column to extract
    test : str
        name of the test/regression that works as a label for files
    model1, model2 : dict
        contains mne queries, file tag
    alpha : float
        level of significance (leave out p>alpha)
    subs : list of str
        list of subjects to include f.e. [sub-01, sub-02]
    bands : list of dict
        list of bands to include   

    """

    print(f"\nContrast {test1} {model1['tag']} {test2} {model2['tag']}")

    df1 = cf.load_df(f"{test1}_{model1['tag']}", subs=subs, bands=bands)
    df2 = cf.load_df(f"{test2}_{model2['tag']}", subs=subs, bands=bands)

    fig, ax = plt.subplots(len(bands), 1, figsize=(10, 3 * len(bands)))
    if len(bands) == 1: ax = np.array([ax])

    fig.suptitle(
        fr"{test1} {key1} {model1['tag']} vs {test2} {key3} {model2['tag']}, $p \leq {alpha}$",
        fontsize=20)

    for i_band, band in enumerate(bands):

        df1_band = df1[df1['band'] == band['name']]
        df2_band = df2[df2['band'] == band['name']]

        mask1 = df1_band[key].values < alpha
        mask2 = df2_band[key].values < alpha

        # for regression results filter significant channels
        if test == 'reg':
            mask1 *= (df1_band['r2'].values > 0) * (df1_band['p'].values <
                                                    alpha)
            mask2 *= (df2_band['r2'].values > 0) * (df2_band['p'].values <
                                                    alpha)

        x = 1. * mask1 + 2 * mask2

        cb = ''
        if i_band == len(bands) - 1:
            cb = [model1['tag'], model2['tag'], 'both']

        pl.brain_plot(ax[i_band],
                      cf.eval_coords(df1_band['coords']),
                      x,
                      ylabel=band['name'],
                      mask=(x < 0.5),
                      mode='contrast',
                      colorbar=cb)

    #fig.subplots_adjust(left=0.05, bottom=0.05, right=0.9, top=0.9, wspace=0.3, hspace=0.3)

    # save figure
    if save:
        fig_name = os.path.join(
            cf.check_path(['..', 'Figures', test1 + sp.out]),
            f"contrast_{test1}-{model1['tag']}_{test2}-{model2['tag']}.pdf")
        fig.savefig(fig_name, format='pdf', dpi=100)
    if plot: plt.show()
    else: plt.close()
Example #12
0
def band_comparison_brain(key,
                          test,
                          file_tag,
                          split=None,
                          alpha=sp.alpha,
                          subs=sp.subject_list,
                          bands=sp.bands):
    """ Plot brain maps for variables (p_value, r2, ...) 
        stored in files for each band

    Parameters
    ----------
    key : str
        name of the column to extract
    test : str
        name of the test/regression that works as a label for files
    queries : dict
        generated with cf.compose_queries, contains mne queries, file tag, queries list
    split : int or str
        if int divide the time window into 'split' chunks and run one test in each
        if string separate epochs by values of metadata column 'split',
        f.ex. split = 'w_position' run the test for each word position
    alpha : float
        level of significance (leave out p>alpha)
    subs : list of str
        list of subjects to include f.e. [sub-01, sub-02]
    bands : list of dict
        list of bands to include   

    """

    print(f"\nBand comparison brain map for {test} {file_tag}")

    df = cf.load_df(f"{test}-{file_tag}", subs=subs, bands=bands)

    if split == None: labels = ['']  # no split
    elif isinstance(split, int):
        labels = list(np.unique(df['tw'].to_numpy()))  # split by time windows
    elif isinstance(split, str):
        labels = list(np.unique(df[split].to_numpy()))  # split by conditions

    num_plots = len(labels)

    # threshold is given in units of p, has to be transformed
    if key[0] == 'p': alpha = -np.log10(alpha)

    if len(sp.bands) == 1: ax = ax[np.newaxis, :]

    # loop over plots
    for i_plot, label in enumerate(labels):

        fig, ax = plt.subplots(len(bands), 1, figsize=(10, 3 * len(bands)))

        fig.suptitle(fr"{test} {file_tag}, $p \leq {alpha}$", fontsize=20)

        for i_band, band in enumerate(bands):
            # filter df by band and split
            if split == None:
                df_band = df[df['band'] == band['name']]
                title = ''
                figtag = ''
            elif isinstance(split, int):
                df_band = df[(df['band'] == band['name'])
                             & ([x == label for x in df['tw'].to_numpy()])]
                title = '' + (str(label) + ' s') * (i_band == 0)
                figtag = f'_tw{i_plot}'
            elif isinstance(split, str):
                df_band = df[(df['band'] == band['name'])
                             & (df[split] == label)]
                title = '' + f"{split} = {label}" * (i_band == 0)
                figtag = f"_{split}-{label}"

            # extract data to plot
            x = df_band[key]

            # for p values
            if key[0] == 'p':
                # transform p values and threshold
                x = -np.log10(x)
                cbar_label = r'-log$_{10}(p)$'

            # get channel positions
            coords = np.array([c for c in df_band['coords']])

            pl.brain_plot(ax[i_band],
                          coords,
                          np.clip(x, alpha, 3),
                          title=title,
                          ylabel=band['name'],
                          colorbar='' +
                          (i_band == (len(bands) - 1)) * cbar_label,
                          mask=(x < alpha),
                          mode='interval',
                          interval=[alpha, 3])

        #fig.subplots_adjust(left=0.05, bottom=0.05, right=0.9, top=0.9, wspace=0.3, hspace=0.3)

        # save figure
        fig_name = os.path.join(
            cf.check_path(['..', 'Figures', test + sp.out]),
            f"brain_map_{test}_{file_tag}{figtag}.pdf")
        fig.savefig(fig_name, format='pdf', dpi=100)
        if sp.plot: plt.show()
        plt.close()
Example #13
0
def channel_overview(sub, ChName, bands, EpochsSetups, EpochsList=None, 
                     key=None, plot = True, save = False, temp=False):
    """ Same as subject overview but for one single channel
    

    Parameters
    ----------
    key :  str
        metadata key to plot separate traces by metadata value
    """

    # load subject params
    SP = cf.sub_params(sub)
    #if ChName not in SP['ChNames']: sys.exit(f"{sub} {ChName} not found  (o_0) ")

    # make figure
    fig, ax = plt.subplots(3,len(EpochsSetups),figsize=(5*len(EpochsSetups),4.5))  
         
    # add extra dimension if missing
    if len(EpochsSetups) == 1: ax = np.array([ax]).T

    title = f"{sub} {ChName}"
    if 'sample' in EpochsSetups[0].keys(): title += f"\nsample: {EpochsSetups[0]['sample']}"
    fig.suptitle(title)

    # plot channel cosition
    pl.channel_position_plot(ax[0,0],cf.get_coords(SP,picks=[ChName]))   
    pl.clear_axes(ax[0,:])   


    # LOOP OVER BANDS AND EPOCH SETUPS -----------------------------------------
    iterator =  product(enumerate(bands),enumerate(EpochsSetups))
    for i, ((iBand, band),(iEp, EpochsSetup)) in enumerate(iterator): 

        if EpochsList == None: epochs = cf.load_epochs(sub,band,EpochsSetup)
        else: epochs = EpochsList[iEp].copy()
        epochs = epochs.pick_channels([ChName])

 
        xticks = [x*SP['soa'] for x in EpochsSetup['xticks']]

        # avg PLOT -----------------------------------------------------------
        if band['method'] in [None,'filter']: ylabel = f"{band['name']} band\n"*(iEp==0) + f"\nV (z-scored)"
        elif band['method'] in ['complex']: ylabel = f"{band['name']} band\n"*(iEp==0) + f"\nITC"
        else: ylabel = f"{band['name']} power\n"*(iEp==0) + f"\ndB (z-scored)"

        # OPTION 1: plot all epochs together ----------------------------------
        if key == None:
            x = np.squeeze(epochs.get_data(picks=ChName))
            
            # plot avg trace
            pl.trace_plot(ax[2,iEp], epochs.times, x, ylabel = ylabel, 
                            vlines = [SP['soa']*x for x in EpochsSetup['xticks']], plot_sem = True)

        # OPTION 2: separate epochs by condition -------------------------------
        else:
            conditions=list(set(epochs.metadata[key]))
            conditions.sort()
            if isinstance(conditions[0],str):
                queries = [f"{key} =='{c}'" for c in conditions]
            elif len(conditions)>10: 
                conditions = np.linspace(min(conditions),max(conditions),5)
                queries = [f"{key} >={conditions[i]} and {key} <{conditions[i+1]}" for i in range(len(conditions)-1)]
            else:
                 queries = [f"{key} =={c}" for c in conditions]
            colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(conditions)))
            for i_q, query in enumerate(queries):
                x = np.squeeze(epochs.copy()[query].get_data(picks=ChName))
                # plot avg trace per condition
                pl.trace_plot(ax[2,iEp], epochs.times, x,  ylabel = '' + band['name']*(iEp==0), 
                   vlines = xticks, plot_sem = True, color=colors[i_q],label = conditions[i_q])

            # make legend
            if iEp==len(EpochsSetups)-1 and key!=None:
                ax[-1,-1].legend(frameon=False,title=key,loc=(1,0.2),fontsize = 7)  # 



        # TrialWise PLOT -----------------------------------------------------------
        if band['method'] in [None,'filter']: ylabel, cb = f"{band['name']} band", f"V (z-scored)"
        elif band['method'] in ['complex']: ylabel, cb =f"{band['name']} band", r"$\theta$"
        else: ylabel, cb = f"{band['name']} power", f"dB (z-scored)"

        try: order = EpochsSetup['order']
        except: order = key
        if order!=None:
            values = epochs.metadata[order].values
            idx =np.argsort(values)
            yticks = [j for j, x in enumerate(np.diff(values[idx])!=0) if x]
            yticklabels = [str(values[idx][y]) for y in yticks]
            ylabel=(iEp==0)*ylabel + f"\n\n{order}"
        else: 
            idx = []
            yticks = []
            yticklabels = []
            ylabel=(iEp==0)*ylabel + f"\n\nepoch"

        m = np.squeeze(epochs.copy().get_data(picks=ChName))
        if isinstance(m[0,0],complex): 
            m = np.angle(m)
            vmin, vmax = -np.pi, np.pi
        else:
            m = (m-m.mean())/m.std()
            vmin = np.percentile(m,15)
            vmax = np.percentile(m,85)

        pl.imshow_plot(ax[1,iEp], m,vmin=vmin,vmax=vmax, ylabel = ylabel, xlims  = epochs.times,
                                title = EpochsSetup['name'], yticks = yticks, yticklabels = yticklabels, vlines = xticks, colorbar = cb,cmap='jet',order=idx)


    ax[-1,0].set_xlabel('t (s)')
    fig.subplots_adjust(wspace=0.3, hspace=0.3)

    if save: 
        FiguresPath = cf.check_path(['..','Figures' , 'overview' + cfg.out ])
        fig_name = os.path.join(FiguresPath,f"{sub}_{ChName}{'_temp'*temp}.pdf")
        fig.savefig(fig_name, format='pdf') 
    if plot: plt.show()
    else: plt.close()  
Example #14
0
def metadata_overview(features, query=None, subs=cfg.subs, key=None, plot_subs = True, plot = True, save = True):

    
    print("\n======== metadata overview ========================================\n")

    
    # colect metadata 
    metadata_list = []
    for sub in cfg.subs: 
        SP = cf.sub_params(sub)
        sub_metadata = pd.read_csv(SP['metadata_file'])
        if query!=None: sub_metadata=sub_metadata.query(query)
        metadata_list += [sub_metadata]

    # make figure
    fig, ax = plt.subplots(1+len(subs)*plot_subs,len(features),figsize=(2*len(features),2*(1+len(subs)*plot_subs)))  
                           
    # add extra dimension if missing
    if not plot_subs: ax = np.array([ax])

    fig.suptitle(f"Metadata")

    metadata_list = [pd.concat(metadata_list)] + metadata_list*plot_subs
    labels = ['All subjects'] + subs*plot_subs


    iterator =  product(enumerate(metadata_list),enumerate(features))
    for (i_m, metadata),(i_f, feature) in iterator: 


        # OPTION 1: plot all epochs together
        if key == None:
            # plot all subs together
            data = metadata[feature].values
            x = np.arange(data.min()-1.5,data.max()+2)
            h, _ = np.histogram(data,x,density=True)
            pl.trace_plot(ax[i_m,i_f], x[:-1]+0.5, h, ylabel = '' + labels[i_m]*(i_f==0), title = '' + feature*(i_m==len(metadata_list)-1))
            ax[i_m,i_f].set_xticks(np.arange(data.min(),data.max()+2))

        
        # OPTION 2: separate epochs by condition
        else:
            conditions=list(set(metadata[key]))
            conditions.sort()
            queries = [f"{key} =='{c}'" for c in conditions]
            colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(conditions)))
            for i_q, query in enumerate(queries):
                data = metadata[feature].values
                x = np.arange(data.min()-1.5,data.max()+2)
                data_query = metadata.query(query)[feature].values
                h, _ = np.histogram(data_query,x,density=True)
                pl.trace_plot(ax[i_m,i_f], x[:-1]+0.5, h,  ylabel = '' + labels[i_m]*(i_f==0), xlabel = '' + feature*(i_m==len(metadata_list)-1) ,color=colors[i_q],label = conditions[i_q])               
            ax[i_m,i_f].set_xticks(np.arange(data.min(),data.max()+2))
    ax[0,-1].legend(frameon=False,loc=(0.5,0.5))


    fig.subplots_adjust(top=0.8,bottom=0.2,wspace=0.3, hspace=0.3)
    if save: 
        FiguresPath =cf.check_path(['..','Figures' , 'overview'+ cfg.out])
        fig_name = os.path.join(FiguresPath,f"metadata.pdf")
        fig.savefig(fig_name, format='pdf') 
    if plot: plt.show()
    else: plt.close()
Example #15
0
def reg_single_channel(sub,
                       ch_name,
                       band,
                       model,
                       alpha=cfg.alpha,
                       plot=True,
                       save=True,
                       temp=True,
                       n=4):

    # load subject params
    dp = cf.sub_params(sub)

    # load epochs
    all_epochs = cf.load_epochs(sub, band, model['ep_setup'],
                                picks=[ch_name]).decimate(5)
    epochs = all_epochs[model['query']]

    # regression
    scores, ps = stepwise_regression(epochs, model['predictors'],
                                     model['predictors_stepwise'])

    predictors = model['predictors_stepwise']

    # FIGURE --------------------------------------------------------
    fig, ax = plt.subplots(len(predictors) + 1,
                           3,
                           figsize=(15, 3 * (len(predictors) + 1)))
    fig.suptitle(f"{sub} {ch_name} {band['name']}\n{model['query']}",
                 fontsize=15)

    # ch_position
    pl.channel_position_plot(ax[0, 2], cf.get_coords(epochs, picks=[ch_name]))

    # channel summary
    pl.channel_summary_plot(ax[0, 1], sub, ch_name, model['tag'],
                            model['predictors'])

    t_sig = pl.score_plot(
        ax[0, 0],
        scores,
        ps,
        epochs.times,
        model['predictors_stepwise'],
        vlines=[dp['soa'] * x for x in model['ep_setup']['xticks']],
        xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']])
    ax[1, 0].set_title(model['query'])

    if np.sum(np.array([len(t_sig[pr]) == 2 for pr in predictors])) == 0:
        plt.close()
        return

    for i_p, predictor in enumerate(predictors):

        predictor_values = epochs.metadata[predictor].values
        N = min(n, len(set(predictor_values)))
        predictor_thresholds = np.linspace(np.nanmin(predictor_values),
                                           np.nanmax(predictor_values), N + 1)
        #predictor_thresholds = np.percentile(predictor_values, np.linspace(0,100,N+1))
        colors = plt.get_cmap('autumn')(np.linspace(0., 1., N))

        for i in range(N):

            y = np.squeeze(epochs[
                f'{predictor}>={predictor_thresholds[i]} and {predictor}<={predictor_thresholds[i+1]}']
                           .get_data(picks=ch_name))
            label = f"({round(predictor_thresholds[i])},{round(predictor_thresholds[i+1])})"

            pl.trace_plot(
                ax[i_p + 1, 0],
                epochs.times,
                y,
                ylabel='zscored power',
                title=predictor,
                xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']],
                vlines=[dp['soa'] * x for x in model['ep_setup']['xticks']],
                color=colors[i],
                label=label,
                legend=True,
                plot_sem=True,
                xlabel='t (s)')

        if len(t_sig[predictor]) == 2:
            ax[i_p + 1, 0].axvspan(t_sig[predictor][0] - cfg.smooth * 0.5,
                                   t_sig[predictor][1] + cfg.smooth * 0.5,
                                   color='gray',
                                   alpha=0.3,
                                   lw=0)
            pl.response_plot(ax[i_p + 1, 1],
                             ch_name,
                             all_epochs.copy(),
                             predictor,
                             tmin=t_sig[predictor][0] - cfg.smooth * 0.5,
                             tmax=t_sig[predictor][1] + cfg.smooth * 0.5)
        else:
            pl.clear_axes(np.array([ax[i_p + 1, 1]]))

        values = all_epochs.metadata[predictor].values
        order = np.argsort(values)
        yticks = [j for j, x in enumerate(np.diff(values[order]) != 0) if x]
        yticklabels = [str(values[order][idx]) for idx in yticks]

        m = np.squeeze(all_epochs.copy().get_data(picks=ch_name))
        m = (m - m.mean()) / m.std()
        vmin = np.percentile(m, 15)
        vmax = np.percentile(m, 85)

        pl.imshow_plot(ax[i_p + 1, 2],
                       m,
                       vmin=vmin,
                       vmax=vmax,
                       ylabel=predictor,
                       xlims=all_epochs.times,
                       yticks=yticks,
                       yticklabels=yticklabels,
                       colorbar='z-score',
                       cmap='RdBu_r',
                       order=order)

    fig.subplots_adjust(left=0.1,
                        bottom=0.1,
                        right=0.9,
                        top=0.9,
                        wspace=0.3,
                        hspace=0.4)
    if save:
        fig_name = os.path.join(
            cf.check_path(['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]),
            f"{sub}_{ch_name}_{band['name']}_temp.pdf")
        fig.savefig(fig_name, format='pdf', dpi=100)
    if plot: plt.show()
    else: plt.close()
Example #16
0
def band_comparison_lateralization(key,
                                   test,
                                   tag,
                                   split=None,
                                   alpha=sp.alpha,
                                   subs=sp.subject_list,
                                   bands=sp.bands):
    """ Bar plots for proportion of significant channels on
        left right axis and frontal occipital axis

    Parameters
    ----------
    key : str
        name of the column to extract
    test : str
        name of the test/regression that works as a label for files
    tag : str
        test tag
    alpha : float
        level of significance (leave out p>alpha)
    subs : list of str
        list of subjects to include f.e. [sub-01, sub-02]
    bands : list of dict
        list of bands to include   

    """

    print(f"\nLateralization figure for {test} {tag}")

    df = cf.load_df(f"{test}_{tag}", subs=subs, bands=bands)

    if split == None: labels = ['']  # no split
    elif isinstance(split, int):
        labels = list(np.unique(df['tw'].to_numpy()))  # split by time windows
    elif isinstance(split, str):
        labels = list(np.unique(df[split].to_numpy()))  # split by conditions

    num_plots = len(labels)

    if len(sp.bands) == 1: ax = ax[np.newaxis, :]

    # loop over plots
    for i_plot, label in enumerate(labels):

        fig, ax = plt.subplots(len(bands), 2, figsize=(5, 3 * len(bands)))

        fig.suptitle(fr"{test} {tag}, $p \leq {alpha}$", fontsize=20)

        # for axis limits
        x, y = 0, 0

        for i_band, band in enumerate(bands):
            # filter df by band and split
            if split == None:
                df_band = df[df['band'] == band['name']]
                title = ''
                figtag = ''
            elif isinstance(split, int):
                df_band = df[(df['band'] == band['name'])
                             & ([x == label for x in df['tw'].to_numpy()])]
                title = '' + (str(label) + ' s') * (i_band == 0)
                figtag = f'_tw{i_plot}'
            elif isinstance(split, str):
                df_band = df[(df['band'] == band['name'])
                             & (df[split] == label)]
                title = '' + f"{split} = {label}" * (i_band == 0)
                figtag = f"_{split}-{label}"

            df_sig = df_band[df_band[key] <= alpha]

            # get channel positions
            coords_all = np.array([c for c in df_band['coords']])
            coords_sig = np.array([c for c in df_sig['coords']])

            # skip if there aren't significant channels
            if len(coords_sig.shape) != 2: continue

            # left rigth
            h_all, bins = np.histogram(coords_all[:, 0], bins=6, density=False)
            h_sig, bins = np.histogram(coords_sig[:, 0],
                                       bins=bins,
                                       density=False)

            width = (bins[1] - bins[0])

            ax[i_band, 0].bar(bins[:-1] + width / 2,
                              h_sig / h_all,
                              width=width * 0.9,
                              color='firebrick')
            ax[i_band, 0].set_xticks([bins[0], bins[-1]])
            ax[i_band, 0].set_xticklabels(['L', 'R'])
            #ax[i_band,0].set_ylim([0,1])
            ax[i_band, 0].spines['right'].set_visible(False)
            ax[i_band, 0].spines['top'].set_visible(False)
            ax[i_band, 0].tick_params(axis='both',
                                      which='both',
                                      size=0,
                                      labelsize=9)

            y = max(y, np.max(h_sig / h_all))

            # frontal occipital
            h_all, bins = np.histogram(coords_all[:, 1], bins=6, density=False)
            h_sig, bins = np.histogram(coords_sig[:, 1],
                                       bins=bins,
                                       density=False)

            width = (bins[1] - bins[0])

            ax[i_band, 1].barh(bins[:-1] + width / 2,
                               h_sig / h_all,
                               height=width * 0.9,
                               color='firebrick')
            ax[i_band, 1].set_yticks([bins[0], bins[-1]])
            ax[i_band, 1].set_yticklabels(['O', 'F'])
            #ax[i_band,1].set_xlim([0,1])
            ax[i_band, 1].spines['right'].set_visible(False)
            ax[i_band, 1].spines['top'].set_visible(False)
            ax[i_band, 1].tick_params(axis='both',
                                      which='both',
                                      size=0,
                                      labelsize=9)

            x = max(x, np.max(h_sig / h_all))

        for i_band in range(len(bands)):
            ax[i_band, 0].set_ylim([0, y])
            ax[i_band, 1].set_xlim([0, x])

        fig.subplots_adjust(left=0.1,
                            bottom=0.15,
                            right=0.95,
                            top=0.85,
                            wspace=0.4,
                            hspace=0.4)

        # save figure
        fig_name = os.path.join(
            cf.check_path(['..', 'Figures', f"{test}_{tag}" + sp.out]),
            f"lateralization_{test}_{tag}_{key}.pdf")
        fig.savefig(fig_name, format='pdf', dpi=100)
        if sp.plot: plt.show()
        plt.close()
Example #17
0
def reg_single_channel2(sub,
                        ch_name,
                        band_name,
                        model,
                        extra_band,
                        predictor2,
                        predictors='all',
                        alpha=cfg.alpha,
                        plot=True,
                        save=False,
                        temp=False,
                        n=4,
                        twsize=cfg.tws):

    # load subject params
    dp = cf.sub_params(sub)

    if predictors == 'all': predictors = model['predictors']
    ep_setup = model['ep_setup']

    # raw file
    mneraw_file = os.path.join(dp['derivatives_path'],
                               f"{sub}_band-{band_name}_raw.fif")
    raw = mne.io.read_raw_fif(mneraw_file, preload=True)
    all_epochs = cf.load_epochs(dp,
                                raw.copy().pick_channels([ch_name]),
                                model['ep_setup'])
    epochs = all_epochs[model['query']]

    # get predictor values
    X = np.array(epochs.metadata[model['predictors']])
    X[np.isinf(X)] = -15.5

    # get responses averaged over time windows
    tmin, tmax = model['ep_setup']['tmin'], model['ep_setup']['tmax'] - twsize
    tws = [[t, t + cfg.tws]
           for t in np.arange(tmin, tmax, (tmax - tmin) / 100.)]
    y = []
    t = []
    for t1, t2 in tws:
        # epoch average
        e = epochs.copy()
        y += [np.squeeze(e.crop(t1, t2).get_data(picks=ch_name).mean(axis=-1))]
        t += [0.5 * (t1 + t2)]
    y = np.swapaxes(np.array([y]).T, -1, -2)

    # compute regressions
    R = regression(X, y, t)

    # FIGURE --------------------------------------------------------

    fig, ax = plt.subplots(len(predictors) + 2,
                           3,
                           figsize=(15, 3 * (len(predictors) + 2)))

    fig.suptitle(
        f"{sub} {ch_name} {band_name}\n{model['predictors']}\n{model['query']}",
        fontsize=15)

    # ch_position
    #pl.clear_axes(ax[0,:])
    pl.channel_position_plot(ax[0, 0],
                             [dp['coords'][dp['ch_names'].index(ch_name)]], 0)

    # channel summary
    pl.channel_summary_plot(ax[0, 1], sub, ch_name, model['tag'],
                            model['predictors'])

    # raster plot
    y = cf.load_epochs(dp,
                       raw.copy().pick_channels([ch_name]),
                       model['ep_setup']).get_data(picks=ch_name)
    #y = (y - np.median(y))/np.subtract(*np.percentile(y, [75, 25]))
    y = (y - np.median(y)) / y.std()
    pl.imshow_plot(
        ax[1, 1],
        y[:, 0, :],
        title='All trials',
        xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']],
        vlines=[dp['soa'] * x for x in ep_setup['xticks']],
        ylabel='epoch',
        colorbar='zscore',
        vmin=-1,
        vmax=1,
        cmap='RdBu_r')

    # score plot
    t_sig = pl.score_plot(
        ax[1, 0],
        R,
        model['predictors'],
        vlines=[dp['soa'] * x for x in ep_setup['xticks']],
        xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']])
    ax[1, 0].set_title(model['query'])

    if np.sum(np.array([len(t_sig[pr]) == 2 for pr in predictors])) == 0:
        plt.close()
        return

    for i_p, predictor in enumerate(predictors):

        predictor_values = epochs.metadata[predictor].values
        predictor_values[np.isinf(predictor_values)] = -15.5
        N = min(n, len(set(predictor_values)))
        predictor_thresholds = np.linspace(np.nanmin(predictor_values),
                                           np.nanmax(predictor_values), N + 1)
        colors = plt.get_cmap('autumn')(np.linspace(0., 1., N))

        for i in range(N):

            y = np.squeeze(epochs[
                f'{predictor}>={predictor_thresholds[i]} and {predictor}<={predictor_thresholds[i+1]}']
                           .get_data(picks=ch_name))
            label = f"({round(predictor_thresholds[i])},{round(predictor_thresholds[i+1])})"

            pl.trace_plot(
                ax[i_p + 2, 0],
                epochs.times,
                y,
                ylabel='zscored power',
                title=predictor,
                xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']],
                vlines=[dp['soa'] * x for x in ep_setup['xticks']],
                color=colors[i],
                label=label,
                legend=True,
                plot_sem=True,
                xlabel='t (s)')

        if len(t_sig[predictor]) == 2:
            ax[i_p + 2, 0].axvspan(t_sig[predictor][0],
                                   t_sig[predictor][1],
                                   color='gray',
                                   alpha=0.3,
                                   lw=0)
            pl.response_plot(ax[i_p + 2, 1],
                             ch_name,
                             all_epochs.copy(),
                             predictor,
                             tmin=t_sig[predictor][0],
                             tmax=t_sig[predictor][1])
        else:
            pl.clear_axes(np.array([ax[i_p + 2, 1]]))

    # Third column

    order = np.argsort(
        np.squeeze(epochs.copy().crop(
            t_sig[predictor2][0],
            t_sig[predictor2][1]).get_data(picks=ch_name).mean(axis=-1)))

    # raster plot
    y = epochs.get_data(picks=ch_name)
    y = (y - np.median(y)) / y.std()
    pl.imshow_plot(
        ax[1, 2],
        y[order, 0, :],
        title=f"{band_name} {predictor2} ordered",
        xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']],
        vlines=[dp['soa'] * x for x in ep_setup['xticks']],
        ylabel='epoch',
        colorbar='zscore',
        vmin=-1,
        vmax=1,
        cmap='RdBu_r')

    for i in range(len(extra_band)):
        # raw file
        mneraw_file = os.path.join(dp['derivatives_path'],
                                   f"{sub}_band-{extra_band[i]}_raw.fif")
        raw = mne.io.read_raw_fif(mneraw_file, preload=True)
        all_epochs = cf.load_epochs(dp,
                                    raw.copy().pick_channels([ch_name]),
                                    model['ep_setup'])
        epochs = all_epochs[model['query']]

        # raster plot
        y = epochs.get_data(picks=ch_name)
        y = (y - np.median(y)) / y.std()
        pl.imshow_plot(
            ax[2 + i, 2],
            y[order, 0, :],
            title=f"{extra_band[i]}",
            xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']],
            vlines=[dp['soa'] * x for x in ep_setup['xticks']],
            ylabel='epoch',
            colorbar='zscore',
            vmin=-1,
            vmax=1,
            cmap='RdBu_r')

    pl.clear_axes(np.array(ax[0, 2]))

    fig.subplots_adjust(left=0.1,
                        bottom=0.1,
                        right=0.9,
                        top=0.9,
                        wspace=0.3,
                        hspace=0.4)
    if save:
        #i_band = [band['name'] for band in cfg.bands].index(band_name)
        fig_name = os.path.join(
            cf.check_path(['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]),
            f"{sub}_{ch_name}_{band_name}_temp.pdf")
        fig.savefig(fig_name, format='pdf', dpi=100)
    if plot: plt.show()
    else: plt.close()
Example #18
0
def ttest_figure_signle_sub(SP, band, EpochsSetups, split, samples, values,
                            SignificantMask, SignificantList, PopMean, pValues,
                            picks, alpha):

    # mean and sem across epochs
    # ---- 2 sample test --------
    if len(samples[0]) == 2:
        m = np.array([[s1.mean(axis=0), s2.mean(axis=0)]
                      for s1, s2 in samples])
        s = np.array([[
            s1.std(axis=0) / np.sqrt(len(s1)),
            s2.std(axis=0) / np.sqrt(len(s2))
        ] for s1, s2 in samples])
        x = m[:, 0] - m[:, 1]
        xerr = np.sqrt(0.5) * (s[:, 0] + s[:, 1])
    # ---- 1 sample test --------
    if len(samples[0]) == 1:
        x = np.array([s1[0].mean(axis=0) for s1 in samples])
        xerr = np.array(
            [s1[0].std(axis=0) / np.sqrt(len(s1[0])) for s1 in samples])

    # ---- Make Figure ----------------
    fig, ax = plt.subplots(2,
                           1,
                           figsize=(5, 12),
                           gridspec_kw={'height_ratios': [1, 5]})

    title = f"T-test {SP['sub']} {band['name']} ({np.sum(SignificantMask)}/{len(SignificantMask)})"
    if 'sample' in EpochsSetups[0].keys():
        title += f"\nsample: {EpochsSetups[0]['sample']}"
    fig.suptitle(title)

    # ---- plot glass brain ------------
    coords = np.array([
        SP['ChInfo']['coords'][SP['ChInfo']['ChNames'].index(ch)]
        for ch in cf.get_picks(SP, picks=picks, band=band)
    ])
    pl.channel_position_plot(ax[0], coords, mask=~SignificantMask)

    # ---- scatter plot with mean and std ------
    y = np.arange(len(SignificantMask))
    if split == None:
        ax[1].errorbar(x[0], y, xerr=xerr[0], color='k', fmt='o', alpha=0.1)
        ax[1].errorbar(x[0, SignificantMask],
                       y[SignificantMask],
                       xerr=xerr[0, SignificantMask],
                       color='k',
                       fmt='o')
    else:
        colors = plt.get_cmap('turbo')(np.linspace(0., 1., len(values)))
        for j, v in enumerate(values):
            mask = pValues[j] < alpha
            ax[1].errorbar(x[j],
                           y,
                           xerr=xerr[j],
                           color=colors[j],
                           fmt='o',
                           alpha=0.1)
            ax[1].errorbar(x[j, mask],
                           y[mask],
                           xerr=xerr[j, mask],
                           color=colors[j],
                           fmt='o',
                           label=f"{v}")
        if isinstance(split, list): title = 'time window'
        else: title = split
        ax[1].legend(title=title, frameon=False)

    # ---- decorate axes ------------
    ax[1].set_xlabel(
        f"{EpochsSetups[0]['name']} - {EpochsSetups[1]['name']} dB")
    ax[1].set_ylabel('channel')

    ax[1].set_yticks(
        [j for j in range(len(SignificantMask)) if SignificantMask[j]])
    ax[1].set_yticklabels(SignificantList)

    ax[1].axvline(PopMean, linestyle='-', color='grey', linewidth=0.5)

    ax[1].spines['right'].set_visible(False)
    ax[1].spines['top'].set_visible(False)
    ax[1].tick_params(axis='both', which='both', size=0, labelsize=7)

    # ---- save figure --------------
    FiguresPath = cf.check_path(['..', 'Figures', 'ttest' + cfg.out])
    FigureName = os.path.join(FiguresPath,
                              f"{SP['sub']}_{band['name']}_temp.pdf")
    fig.savefig(FigureName, format='pdf', dpi=100)
    plt.close()