def summary_fig(contrasts, CURVES, Ntot):

    fig, AX = ge.figure(axes=(4, 1), figsize=(1., 1.))

    AX[0].axis('off')

    if len(CURVES) > 1:
        ge.plot(contrasts,
                np.mean(np.array(CURVES), axis=0),
                sy=np.std(np.array(CURVES), axis=0),
                ax=AX[1])
    else:
        AX[1].axis('off')
    ge.set_plot(AX[1], xlabel='contrast', ylabel='$\delta$ dF/F')

    AX[2].axis('off')

    ge.annotate(AX[2],
                'n=%i/%i resp. cells' % (len(CURVES), Ntot), (0.5, .0),
                ha='center',
                va='top')

    frac_resp = len(CURVES) / Ntot
    data = np.array([100 * frac_resp, 100 * (1 - frac_resp)])
    ge.pie(data,
           COLORS=[plt.cm.tab10(2), plt.cm.tab10(3)],
           pie_labels=['  %.1f%%' % (100 * d / data.sum()) for d in data],
           ext_labels=['', ''],
           ax=AX[3])

    return fig
예제 #2
0
    def plot_FOV(self):

        if self.fovMap.currentText() == 'black_to_green':
            cmap = ge.get_linear_colormap('k', ge.green)
        elif self.fovMap.currentText() == 'white_to_green':
            cmap = ge.get_linear_colormap('w', 'darkgreen')
        elif self.fovMap.currentText() == 'grey':
            cmap = ge.get_linear_colormap('w', 'darkgrey')
        else:
            cmap = ge.viridis

        self.fig, ax = ge.figure(figsize=(2., 4.),
                                 bottom=0,
                                 top=0,
                                 right=0.,
                                 left=0.)
        self.data.show_CaImaging_FOV(\
                                    self.fovType.currentText(),
                                    NL=float(self.fovNL.value()), cmap=cmap, ax=ax)
        ge.annotate(ax,
                    self.fovLabel.text(), (.99, .99),
                    ha='right',
                    va='top',
                    color='white')
        ge.show()
예제 #3
0
def population_analysis(FILES,
                        min_time_minutes=2,
                        exclude_subjects=[],
                        ax=None,
                        running_speed_threshold=0.1):

    times, fracs_running, subjects = [], [], []
    if ax is None:
        fig, ax = ge.figure(figsize=(5, 1), top=5)
    else:
        fig = None

    for f in FILES:

        data = MultimodalData(f)
        if (data.nwbfile is not None) and ('Running-Speed'
                                           in data.nwbfile.acquisition):
            speed = data.nwbfile.acquisition['Running-Speed'].data[:]
            max_time = len(
                speed) / data.nwbfile.acquisition['Running-Speed'].rate
            if (max_time > 60 * min_time_minutes) and (
                    data.metadata['subject_ID'] not in exclude_subjects):
                times.append(max_time)
                fracs_running.append(
                    100 * np.sum(speed > running_speed_threshold) / len(speed))
                subjects.append(data.metadata['subject_ID'])

    i = -1
    for c, s in enumerate(np.unique(subjects)):
        s_cond = np.array(subjects) == s
        ax.bar(np.arange(1 + i, i + 1 + np.sum(s_cond)),
               np.array(fracs_running)[s_cond] + 1,
               width=.75,
               color=plt.cm.tab10(c % 10))
        i += np.sum(s_cond) + 1
    ax.bar([i + 2], [np.mean(fracs_running)],
           yerr=[np.std(fracs_running)],
           width=1.5,
           color='grey')
    ge.annotate(ax,
                'frac. running:\n%.1f+/-%.1f %%' %
                (np.mean(fracs_running), np.std(fracs_running)),
                (i + 3, np.mean(fracs_running)),
                xycoords='data')
    ge.set_plot(ax,
                xticks=[],
                xlabel='\nrecording',
                ylabel='       frac. running (%)')
    ymax, i = ax.get_ylim()[1], -1
    for c, s in enumerate(np.unique(subjects)):
        s_cond = np.array(subjects) == s
        ge.annotate(ax,
                    s, (1 + i, ymax),
                    rotation=90,
                    color=plt.cm.tab10(c % 10),
                    xycoords='data',
                    size='x-small')
        i += np.sum(s_cond) + 1
    return fig, ax
def summary_fig(results):

    other_keys = []
    for key in results:
        if (key not in [
                'Ntot', 'significant', 'x-center', 'y-center', 'value'
        ]) and ('-bins' not in key):
            other_keys.append(key)

    fig, AX = ge.figure(axes=(2 + len(other_keys), 1),
                        right=2,
                        figsize=(1., 1.1))

    if ('x-center' in results) and ('y-center' in results):
        ge.hist2d(results['x-center'],
                  results['y-center'],
                  bins=(results['x-center-bins'], results['y-center-bins']),
                  ax=AX[0],
                  xlabel='x-center ($^{o}$)',
                  ylabel='y-center ($^{o}$)',
                  title='max. resp.')
    elif ('x-center' in results):
        ge.hist(results['x-center'],
                bins=results['x-center-bins'],
                ax=AX[0],
                xlabel='x-center ($^{o}$)')
    elif ('y-center' in results):
        ge.hist(results['y-center'],
                bins=results['y-center-bins'],
                ax=AX[0],
                xlabel='y-center ($^{o}$)')
    else:
        AX[0].axis('off')

    for i, key in enumerate(other_keys):
        ge.hist(results[key],
                bins=results[key + '-bins'],
                ax=AX[i + 1],
                xlabel=key,
                title='max resp')
        AX[i + 1].set_xlabel(key, fontsize=8)

    ge.annotate(AX[-1],
                'n=%i/%i resp. cells' %
                (np.sum(results['significant']), results['Ntot']), (0.5, .0),
                ha='center',
                va='top')

    frac_resp = np.sum(results['significant']) / results['Ntot']
    data = np.array([100 * frac_resp, 100 * (1 - frac_resp)])
    ge.pie(data,
           COLORS=[plt.cm.tab10(2), plt.cm.tab10(3)],
           pie_labels=['  %.1f%%' % (100 * d / data.sum()) for d in data],
           ext_labels=['', ''],
           ax=AX[-1])

    return fig
예제 #5
0
    def plot_raw_data(self):

        self.fig, ax = ge.figure(axes_extents=[[[6, 4]]],
                                 bottom=0.1,
                                 right=3.,
                                 top=0.5)

        Tbar = 1  # by default
        if (self.xmin.text() == '') or (self.xmax.text() == ''):
            tlim = [0, 20]
        else:
            tlim = [float(self.xmin.text()), float(self.xmax.text())]

        if self.xbar.text() != '':
            Tbar = float(self.xbar.text())

        settings = {}
        for mod in self.modalities:
            if getattr(self, mod + 'Plot').value() > 0:
                settings[mod] = dict(fig_fraction=getattr(self, mod +
                                                          'Plot').value())

        for key in ['CaImaging', 'CaImagingSum']:
            if (key in settings) and (self.sqbox.text() in [
                    'dF/F', 'Fluorescence', 'Neuropil', 'Deconvolved'
            ]):
                settings[key]['subquantity'] = self.sqbox.text()

        if 'CaImaging' in settings:
            settings['CaImaging']['roiIndices'] = self.roiIndices

        self.data.plot_raw_data(tlim, settings=settings, Tbar=Tbar, ax=ax)

        if self.annot.isChecked():
            ge.annotate(
                self.fig,
                "%s, %s, %s, %s" %
                (self.data.metadata['subject_ID'],
                 self.data.protocols[self.pbox.currentIndex() - 1][:20],
                 self.data.metadata['filename'].split('\\')[-2],
                 self.data.metadata['filename'].split('\\')[-1]), (1, 1),
                color='k',
                ha='right',
                va='top',
                size='x-small')

        ge.show()
예제 #6
0
    def __init__(self, figsize=(.5,1.), wspace=0.4, top=2.):

        pattern = [[2,1],[2,1],[2,1],[2,1], # patches
                   [1,1], # -- space --
                   [3,1], # looming
                   [1,1], # -- space --
                   [2,1],[2,1],[2,1],[2,1], # patches
                   [1,1], # -- space --
                   [2,1],[2,1],[2,1],[2,1]]

        self.fig, self.AX = ge.figure(axes_extents=[pattern], figsize=(.5,1.),
                                      wspace=wspace, top=top, reshape_axes=False)

        for iax in [4,6,11]:
            self.AX[0][iax].axis('off')

        ge.annotate(self.AX[0][1], 'static-patches\n\n', (1,1), ha='center')
        ge.annotate(self.AX[0][5], 'looming-stim\n\n', (.5,1), ha='center')
        ge.annotate(self.AX[0][8], 'drifting-gratings\n\n', (1,1), ha='center')
        ge.annotate(self.AX[0][13], 'moving-dots\n\n', (1,1), ha='center')
def make_proportion_fig(data, rois_of_interest_contour,
                        rois_of_interest_motion,
                        rois_of_interest_contour_only):

    fig, ax = ge.figure(figsize=(1.2, 1), top=1, bottom=2)
    n = 0
    ticks = []
    for key in list(rois_of_interest_contour.keys())[::2]:
        ax.bar([n], [100. * len(rois_of_interest_contour[key]) / data.nROIs],
               color=ge.blue)
        ticks.append(key)
        n += 1
    print(list(rois_of_interest_motion.keys())[::2])
    for key in list(rois_of_interest_motion.keys())[::2]:
        ax.bar([n], [100. * len(rois_of_interest_motion[key]) / data.nROIs],
               color=ge.orange)
        ticks.append(key)
        n += 1
    for key in rois_of_interest_contour_only:
        ax.bar([n],
               [100. * len(rois_of_interest_contour_only[key]) / data.nROIs],
               color=ge.blue)
        ticks.append(key)
        n += 1
    ge.annotate(ax, 'contour', (0, .95), size='small', color=ge.blue)
    ge.annotate(ax,
                'motion', (0.5, .95),
                size='small',
                color=ge.orange,
                ha='center')
    ge.annotate(ax,
                'contour\nonly', (1, .95),
                size='small',
                color=ge.blue,
                ha='right',
                va='top')
    ge.set_plot(ax,
                xticks=np.arange(n),
                xticks_labels=ticks,
                xticks_rotation=90,
                ylabel='responsive ROI (%)     ')
    return fig, ax
예제 #8
0
    def plot_row_column_of_quantity(self):

        single_cond = self.build_single_conditions()
        COL_CONDS = self.build_column_conditions()
        ROW_CONDS = self.build_row_conditions()
        COLOR_CONDS = self.build_color_conditions()

        if (len(COLOR_CONDS) > 1) and (self.color.text() != ''):
            COLORS = [
                getattr(ge, self.color.text())((c % 10) / 10.)
                for c in np.arange(len(COLOR_CONDS))
            ]
        elif (len(COLOR_CONDS) > 1):
            COLORS = [
                ge.tab10((c % 10) / 10.) for c in np.arange(len(COLOR_CONDS))
            ]
        elif self.color.text() != '':
            COLORS = [getattr(ge, self.color.text())]
        else:
            COLORS = ['k']

        if self.fig_presets.currentText() == 'raw-traces-preset':
            fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)),
                                reshape_axes=False,
                                top=0.4,
                                bottom=0.4,
                                left=0.7,
                                right=0.7,
                                wspace=0.5,
                                hspace=0.5)
        else:
            fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)),
                                reshape_axes=False)

        self.ylim = [np.inf, -np.inf]
        for irow, row_cond in enumerate(ROW_CONDS):
            for icol, col_cond in enumerate(COL_CONDS):
                for icolor, color_cond in enumerate(COLOR_CONDS):
                    cond = np.array(
                        single_cond & col_cond & row_cond
                        & color_cond)[:self.EPISODES['resp'].shape[0]]
                    if self.EPISODES['resp'][cond, :].shape[0] > 0:
                        my = self.EPISODES['resp'][cond, :].mean(axis=0)
                        if self.withSTDbox.isChecked():
                            sy = self.EPISODES['resp'][cond, :].std(axis=0)
                            ge.plot(self.EPISODES['t'],
                                    my,
                                    sy=sy,
                                    ax=AX[irow][icol],
                                    color=COLORS[icolor],
                                    lw=1)
                            self.ylim = [
                                min([self.ylim[0],
                                     np.min(my - sy)]),
                                max([self.ylim[1],
                                     np.max(my + sy)])
                            ]
                        else:
                            AX[irow][icol].plot(self.EPISODES['t'],
                                                my,
                                                color=COLORS[icolor],
                                                lw=1)
                            self.ylim = [
                                min([self.ylim[0], np.min(my)]),
                                max([self.ylim[1], np.max(my)])
                            ]

                    if self.screen.isChecked() and not (self.parent.visual_stim
                                                        is not None):
                        print('initializing stim [...]')
                        self.parent.load_VisualStim()
                    if self.screen.isChecked():
                        inset = ge.inset(AX[irow][icol], [.8, .9, .3, .25])
                        self.parent.visual_stim.show_frame(\
                                    self.EPISODES['index_from_start'][cond][0],
                                    ax=inset, parent=self.parent, enhance=True, label=None)

        if self.withStatTest.isChecked():
            for irow, row_cond in enumerate(ROW_CONDS):
                for icol, col_cond in enumerate(COL_CONDS):
                    for icolor, color_cond in enumerate(COLOR_CONDS):

                        cond = np.array(
                            single_cond & col_cond & row_cond
                            & color_cond)[:self.EPISODES['resp'].shape[0]]
                        test = stat_test_for_evoked_responses(
                            self.EPISODES,
                            cond,
                            interval_pre=[self.t0pre, self.t1pre],
                            interval_post=[self.t0post, self.t1post],
                            test='wilcoxon')

                        AX[irow][icol].plot([self.t0pre, self.t1pre],
                                            self.ylim[0] * np.ones(2),
                                            'k-',
                                            lw=2)
                        AX[irow][icol].plot([self.t0post, self.t1post],
                                            self.ylim[0] * np.ones(2),
                                            'k-',
                                            lw=2)
                        ps, size = pval_to_star(test)
                        AX[irow][icol].annotate(
                            ps,
                            ((self.t1pre + self.t0post) / 2., self.ylim[0]),
                            va='top',
                            ha='center',
                            size=size,
                            xycoords='data')

        if (self.ymin.text() != '') and (self.ymax.text() != ''):
            self.ylim = [float(self.ymin.text()), float(self.ymax.text())]
        if (self.xmin.text() != '') and (self.xmax.text() != ''):
            self.xlim = [float(self.xmin.text()), float(self.xmax.text())]
        else:
            self.xlim = [self.EPISODES['t'][0], self.EPISODES['t'][-1]]

        for irow, row_cond in enumerate(ROW_CONDS):
            for icol, col_cond in enumerate(COL_CONDS):
                ge.set_plot(AX[irow][icol],
                            spines=(['left', 'bottom']
                                    if self.axis.isChecked() else []),
                            ylim=self.ylim,
                            xlim=self.xlim,
                            xlabel=(self.xbarlabel.text()
                                    if self.axis.isChecked() else ''),
                            ylabel=(self.ybarlabel.text()
                                    if self.axis.isChecked() else ''))

                if self.stim.isChecked():
                    AX[irow][icol].fill_between(
                        [0, np.mean(self.EPISODES['time_duration'])],
                        self.ylim[0] * np.ones(2),
                        self.ylim[1] * np.ones(2),
                        color='grey',
                        alpha=.2,
                        lw=0)

        if not self.axis.isChecked():
            ge.draw_bar_scales(AX[0][0],
                               Xbar=(0. if self.xbar.text() == '' else float(
                                   self.xbar.text())),
                               Xbar_label=self.xbarlabel.text(),
                               Ybar=(0. if self.ybar.text() == '' else float(
                                   self.ybar.text())),
                               Ybar_label=self.ybarlabel.text(),
                               Xbar_fraction=0.1,
                               Xbar_label_format='%.1f',
                               Ybar_fraction=0.2,
                               Ybar_label_format='%.1f',
                               loc='top-left')

        if self.label.text() != '':
            ge.annotate(fig, ' '+self.label.text()+\
                        (1+int(self.nlabel.text()))*'\n', (0,0), color=COLORS[0],
                        ha='left', va='bottom')

        if self.annot.isChecked():
            S = ''
            if hasattr(self, 'roiPick'):
                S += 'roi #%s' % self.roiPick.text()
            for i, key in enumerate(self.varied_parameters.keys()):
                if 'single-value' in getattr(self,
                                             '%s_plot' % key).currentText():
                    S += ', %s=%.2f' % (key, getattr(
                        self, '%s_values' % key).currentText())
            ge.annotate(fig, S, (0, 0), color='k', ha='left', va='bottom')

        return fig, AX
def analysis_pdf(datafile, Nmax=1000000):

    data = MultimodalData(datafile)

    stim_duration = data.metadata['Protocol-1-presentation-duration']
    interval_post = [1. / 2. * stim_duration, stim_duration]
    interval_pre = [interval_post[0] - interval_post[1], 0]

    try:
        # find the protocol with the many-standards
        iprotocol_MS = np.argwhere([('many-standards' in p)
                                    for p in data.protocols])[0][0]
        # find the protocol with the oddball-1
        iprotocol_O1 = np.argwhere([('oddball-1' in p)
                                    for p in data.protocols])[0][0]
        # find the protocol with the oddball-2
        iprotocol_O2 = np.argwhere([('oddball-2' in p)
                                    for p in data.protocols])[0][0]

        # mismatch negativity angles
        MM_angles = [
            data.metadata['Protocol-%i-angle-redundant (deg)' %
                          (1 + iprotocol_O1)],
            data.metadata['Protocol-%i-angle-deviant (deg)' %
                          (1 + iprotocol_O1)]
        ]
        #
        DATA = {'stim_duration': stim_duration}
        DATA[str(int(MM_angles[0]))] = {
            'iprotocol_control': iprotocol_MS,
            'control': [],
            'redundant': [],
            'deviant': [],
            'responsive': []
        }
        DATA[str(int(MM_angles[1]))] = {
            'iprotocol_control': iprotocol_MS,
            'control': [],
            'redundant': [],
            'deviant': [],
            'responsive': []
        }
        DATA[str(
            int(data.metadata[
                'Protocol-%i-angle-redundant (deg)' %
                (1 + iprotocol_O1)]))]['iprotocol_redundant'] = iprotocol_O1
        DATA[str(
            int(data.metadata[
                'Protocol-%i-angle-deviant (deg)' %
                (1 + iprotocol_O1)]))]['iprotocol_deviant'] = iprotocol_O1
        DATA[str(
            int(data.metadata[
                'Protocol-%i-angle-redundant (deg)' %
                (1 + iprotocol_O2)]))]['iprotocol_redundant'] = iprotocol_O2
        DATA[str(
            int(data.metadata[
                'Protocol-%i-angle-deviant (deg)' %
                (1 + iprotocol_O2)]))]['iprotocol_deviant'] = iprotocol_O2

        # find the angle for the redundant and deviant conditions
        print(data.metadata['Protocol-3-angle-redundant (deg)'],
              data.metadata['Protocol-3-angle-deviant (deg)'])

        Nresp, Nresp_selective, SIs = 0, 0, []

        pdf_OS = PdfPages(
            os.path.join(
                summary_pdf_folder(datafile),
                '%s-orientation_selectivity.pdf' %
                data.protocols[iprotocol_MS]))
        pdf_MSO = PdfPages(
            os.path.join(
                summary_pdf_folder(datafile),
                '%s-mismatch_selective_only.pdf' %
                data.protocols[iprotocol_MS]))
        pdf_MA = PdfPages(
            os.path.join(summary_pdf_folder(datafile),
                         '%s-mismatch_all.pdf' % data.protocols[iprotocol_MS]))

        for roi in np.arange(data.iscell.sum())[:Nmax]:

            print('   - MMN analysis for ROI #%i / %i' %
                  (roi + 1, data.iscell.sum()))
            ## ORIENTATION SELECTIVITY ANALYSIS
            fig, SI, responsive, responsive_angles = ODS.OS_ROI_analysis(
                data,
                roiIndex=roi,
                iprotocol=iprotocol_MS,
                stat_test_props=dict(interval_pre=interval_pre,
                                     interval_post=interval_post,
                                     test='wilcoxon',
                                     positive=True),
                with_responsive_angles=True)
            pdf_OS.savefig()  # saves the current figure into a pdf page
            plt.close()

            if responsive:
                Nresp += 1
                SIs.append(SI)

            EPISODES = EpisodeResponse(
                data,
                protocol_id=None,  # means all
                quantity='CaImaging',
                subquantity='dF/F',
                roiIndex=roi)

            fig, AX = ge.figure(axes=(2, 1), wspace=3., right=10.)
            responsive_for_at_least_one = False
            ge.annotate(fig, 'ROI #%i' % (roi + 1), (0.02, 0.98), va='top')

            for angle, ax in zip(MM_angles, AX):

                DATA[str(int(angle))]['responsive'].append(
                    False)  # False by default

                ge.title(ax, '$\\theta$=%.1f$^{o}$' % angle)
                for ik, key, color in zip(range(3),
                                          ['control', 'redundant', 'deviant'],
                                          ['k', ge.blue, ge.red]):
                    cond = data.get_stimulus_conditions([
                        np.array(DATA[str(int(angle))]['iprotocol_%s' % key]),
                        np.array([float(angle)])
                    ], ['protocol_id', 'angle'], None)[0]
                    ge.plot(EPISODES.t,
                            EPISODES.resp[cond, :].mean(axis=0),
                            sy=EPISODES.resp[cond, :].std(axis=0),
                            color=color,
                            ax=ax,
                            no_set=True)
                    ge.annotate(ax,
                                ik * '\n' + '%s, n=%i' % (key, np.sum(cond)),
                                (0.98, 1.),
                                color=color,
                                va='top',
                                size='small')

                    # storing for population analysis:
                    DATA[str(int(angle))][key].append(
                        EPISODES.resp[cond, :].mean(axis=0))
                    if angle in responsive_angles:
                        responsive_for_at_least_one = True
                        DATA[str(int(
                            angle))]['responsive'][-1] = True  # shift to True

                ge.set_plot(ax, xlabel='time (s)', ylabel='dF/F')

            pdf_MA.savefig()
            if responsive_for_at_least_one:
                pdf_MSO.savefig()
            plt.close()

        for angle in MM_angles:
            fig, AX = modulation_summary_panel(EPISODES.t,
                                               DATA[str(int(angle))],
                                               title='$\\theta$=%.1f$^{o}$' %
                                               angle)
            pdf_MA.savefig()
            plt.close()
            fig, AX = modulation_summary_panel(EPISODES.t,
                                               DATA[str(int(angle))],
                                               title='$\\theta$=%.1f$^{o}$' %
                                               angle,
                                               responsive_only=True)
            pdf_MSO.savefig()
            plt.close()

        # orientation selectivity summary
        ODS.summary_fig(Nresp,
                        data.iscell.sum(),
                        SIs,
                        label='Orient. Select. Index')
        pdf_OS.savefig()  # saves the current figure into a pdf page
        plt.close()

        # modulation summary

        for pdf in [pdf_OS, pdf_MSO, pdf_MA]:
            pdf.close()

        print('[ok] mismatch negativity analysis saved in: "%s" ' %
              summary_pdf_folder(datafile))

    except BaseException as be:
        print('\n', be)
        print('---------------------------------------')
        print(' /!\ Pb with mismatch negativity analysis /!\  ')
예제 #10
0
    def plot_trial_average(
            self,
            # episodes props
            protocol_id=0,
            quantity='Photodiode-Signal',
            subquantity='dF/F',
            roiIndex=0,
            dt_sampling=1,  # ms
            interpolation='linear',
            baseline_substraction=False,
            prestim_duration=None,
            condition=None,
            COL_CONDS=None,
            column_keys=[],
            column_key='',
            ROW_CONDS=None,
            row_keys=[],
            row_key='',
            COLOR_CONDS=None,
            color_keys=[],
            color_key='',
            fig_preset='',
            xbar=0.,
            xbarlabel='',
            ybar=0.,
            ybarlabel='',
            with_std=True,
            with_screen_inset=False,
            with_stim=True,
            with_axis=False,
            with_stat_test=False,
            stat_test_props={},
            color='k',
            label='',
            ylim=None,
            xlim=None,
            fig=None,
            AX=None,
            verbose=False):

        # ----- building episodes ------
        self.roiIndices = [roiIndex]
        self.CaImaging_key = subquantity
        self.EPISODES = build_episodes(
            self,
            protocol_id=protocol_id,
            quantity=quantity,
            prestim_duration=prestim_duration,
            dt_sampling=dt_sampling,
            baseline_substraction=baseline_substraction,
            verbose=verbose)  # this sets "self.Pcond"

        if with_screen_inset and (self.visual_stim is None):
            print('initializing stim [...]')
            self.init_visual_stim()

        if condition is None:
            condition = np.ones(np.sum(self.Pcond), dtype=bool)
        elif len(condition) == len(self.Pcond):
            condition = condition[self.Pcond]

        # ----- building episodes ------

        if column_key != '':
            COL_CONDS = self.build_conditions([
                np.sort(
                    np.unique(
                        self.nwbfile.stimulus[column_key].data[self.Pcond]))
            ], [column_key])
        elif column_keys != '':
            COL_CONDS = self.build_conditions([
                np.sort(np.unique(self.nwbfile.stimulus[key].data[self.Pcond]))
                for key in column_keys
            ], column_keys)
        elif (COL_CONDS is None):
            COL_CONDS = [np.ones(np.sum(self.Pcond), dtype=bool)]

        if row_key != '':
            ROW_CONDS = self.build_conditions([
                np.sort(
                    np.unique(self.nwbfile.stimulus[row_key].data[self.Pcond]))
            ], [row_key])
        elif row_keys != '':
            ROW_CONDS = self.build_conditions([
                np.sort(np.unique(self.nwbfile.stimulus[key].data[self.Pcond]))
                for key in row_keys
            ], row_keys)
        elif (ROW_CONDS is None):
            ROW_CONDS = [np.ones(np.sum(self.Pcond), dtype=bool)]

        if COLOR_CONDS is None:
            COLOR_CONDS = [np.ones(np.sum(self.Pcond), dtype=bool)]

        # if (len(COLOR_CONDS)>1) and (self.color.text()!=''):
        #     COLORS = [getattr(ge, self.color.text())((c%10)/10.) for c in np.arange(len(COLOR_CONDS))]
        # elif (len(COLOR_CONDS)>1):
        #     COLORS = [ge.tab10((c%10)/10.) for c in np.arange(len(COLOR_CONDS))]
        # elif self.color.text()!='':
        #     COLORS = [getattr(ge, self.color.text())]
        # else:
        COLORS = [color]

        if (fig is None) and (AX is None) and (fig_preset
                                               == 'raw-traces-preset'):
            fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)),
                                reshape_axes=False,
                                top=0.4,
                                bottom=0.4,
                                left=0.7,
                                right=0.7,
                                wspace=0.5,
                                hspace=0.5)
        elif (fig is None) and (AX is None):
            fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)),
                                reshape_axes=False)

        self.ylim = [np.inf, -np.inf]
        for irow, row_cond in enumerate(ROW_CONDS):
            for icol, col_cond in enumerate(COL_CONDS):
                for icolor, color_cond in enumerate(COLOR_CONDS):
                    cond = np.array(
                        condition & col_cond & row_cond
                        & color_cond)[:self.EPISODES['resp'].shape[0]]

                    if self.EPISODES['resp'][cond, :].shape[0] > 0:
                        my = self.EPISODES['resp'][cond, :].mean(axis=0)
                        if with_std:
                            sy = self.EPISODES['resp'][cond, :].std(axis=0)
                            ge.plot(self.EPISODES['t'],
                                    my,
                                    sy=sy,
                                    ax=AX[irow][icol],
                                    color=COLORS[icolor],
                                    lw=1)
                            self.ylim = [
                                min([self.ylim[0],
                                     np.min(my - sy)]),
                                max([self.ylim[1],
                                     np.max(my + sy)])
                            ]
                        else:
                            AX[irow][icol].plot(self.EPISODES['t'],
                                                my,
                                                color=COLORS[icolor],
                                                lw=1)
                            self.ylim = [
                                min([self.ylim[0], np.min(my)]),
                                max([self.ylim[1], np.max(my)])
                            ]

                    if with_screen_inset:
                        inset = ge.inset(AX[irow][icol], [.8, .9, .3, .25])
                        self.visual_stim.show_frame(\
                                    self.EPISODES['index_from_start'][cond][0],
                                    ax=inset, enhance=True, label=None)

        if with_stat_test:
            for irow, row_cond in enumerate(ROW_CONDS):
                for icol, col_cond in enumerate(COL_CONDS):
                    for icolor, color_cond in enumerate(COLOR_CONDS):

                        cond = np.array(
                            single_cond & col_cond & row_cond
                            & color_cond)[:self.EPISODES['resp'].shape[0]]
                        test = stat_test_for_evoked_responses(
                            self.EPISODES, cond, **stat_test_props)
                        AX[irow][icol].plot(stat_test_props['interval_pre'],
                                            self.ylim[0] * np.ones(2),
                                            'k-',
                                            lw=1)
                        AX[irow][icol].plot(stat_test_props['interval_post'],
                                            self.ylim[0] * np.ones(2),
                                            'k-',
                                            lw=1)
                        ps, size = pval_to_star(test)
                        AX[irow][icol].annotate(
                            ps, ((stat_test_props['interval_post'][0] +
                                  stat_test_props['interval_pre'][1]) / 2.,
                                 self.ylim[0]),
                            va='top',
                            ha='center',
                            size=size,
                            xycoords='data')

        if xlim is None:
            self.xlim = [self.EPISODES['t'][0], self.EPISODES['t'][-1]]
        else:
            self.xlim = xlim

        if ylim is not None:
            self.ylim = ylim

        for irow, row_cond in enumerate(ROW_CONDS):
            for icol, col_cond in enumerate(COL_CONDS):
                ge.set_plot(
                    AX[irow][icol],
                    spines=(['left', 'bottom'] if with_axis else []),
                    # xlabel=(self.xbarlabel.text() if with_axis else ''),
                    # ylabel=(self.ybarlabel.text() if with_axis else ''),
                    ylim=self.ylim,
                    xlim=self.xlim)

                if with_stim:
                    AX[irow][icol].fill_between(
                        [0, np.mean(self.EPISODES['time_duration'])],
                        self.ylim[0] * np.ones(2),
                        self.ylim[1] * np.ones(2),
                        color='grey',
                        alpha=.2,
                        lw=0)

        if not with_axis:
            ge.draw_bar_scales(AX[0][0],
                               Xbar=xbar,
                               Xbar_label=xbarlabel,
                               Ybar=ybar,
                               Ybar_label=ybarlabel,
                               Xbar_fraction=0.1,
                               Xbar_label_format='%.1f',
                               Ybar_fraction=0.2,
                               Ybar_label_format='%.1f',
                               loc='top-left')

        if label != '':
            ge.annotate(fig,
                        label, (0, 0),
                        color=color,
                        ha='left',
                        va='bottom')

        # if self.annot.isChecked():
        #     S=''
        #     if hasattr(self, 'roiPick'):
        #         S+='roi #%s' % self.roiPick.text()
        #     for i, key in enumerate(self.varied_parameters.keys()):
        #         if 'single-value' in getattr(self, '%s_plot' % key).currentText():
        #             S += ', %s=%.2f' % (key, getattr(self, '%s_values' % key).currentText())
        #     ge.annotate(fig, S, (0,0), color='k', ha='left', va='bottom')

        return fig, AX
예제 #11
0
def analysis_fig(data, running_speed_threshold=0.1):

    MODALITIES, QUANTITIES, TIMES, UNITS, COLORS = find_modalities(data)
    n = len(MODALITIES) + int(len(MODALITIES) * (len(MODALITIES) - 1) / 2)

    plt.style.use('ggplot')

    fig, AX = plt.subplots(n, 5, figsize=(11.4, 2.5 * n))
    if n == 1:
        AX = [AX]
    plt.subplots_adjust(left=0.06,
                        right=0.98,
                        bottom=0.3 / n,
                        top=0.9,
                        wspace=.5,
                        hspace=.6)

    for i, mod, quant, times, unit, color in zip(range(len(TIMES)), MODALITIES,
                                                 QUANTITIES, TIMES, UNITS,
                                                 COLORS):
        AX[i][0].set_title(mod, fontsize=10, color=color)

        quantity = (quant.data[:] if times is None else quant)

        if mod == 'GazeMovement':
            nsamples = data.nwbfile.processing['Pupil'].data_interfaces[
                'cx'].num_samples
            subsampling = np.max([1, int(nsamples / 1000)])
            cx = data.nwbfile.processing['Pupil'].data_interfaces[
                'cx'].data[:][::subsampling]
            cy = data.nwbfile.processing['Pupil'].data_interfaces[
                'cy'].data[:][::subsampling]
            ge.scatter(cx - np.mean(cx),
                       cy - np.mean(cy),
                       ax=AX[i][0],
                       color=color,
                       ms=1,
                       lw=0.05)
            ge.set_plot(AX[i][0], xlabel='x (mm)', ylabel='y (mm)')
            AX[i][0].axis('equal')
        else:
            AX[i][0].axis('off')

        if mod == 'Running-Speed':
            inset = AX[i][0].inset_axes([0.2, 0.2, 0.6, 0.6])
            frac_running = np.sum(
                quantity > running_speed_threshold) / len(quantity)
            D = np.array([100 * frac_running, 100 * (1 - frac_running)])
            ge.pie(
                [100 * frac_running, 100 * (1 - frac_running)],
                ax=inset,
                # pie_labels = ['%.1f%%\n' % (100*d/D.sum()) for d in D],
                COLORS=[color, 'lightgrey'],
                ext_labels=[
                    'run \n%.1f%% ' % (100 * frac_running),
                    ' rest \n%.1f%% ' % (100 * (1 - frac_running))
                ])
            ge.annotate(AX[0][0],
                        'thresh=%.1fcm/s' % running_speed_threshold, (0.5, 0),
                        ha='center',
                        va='top')

        AX[i][1].hist(quantity,
                      bins=10,
                      weights=100 * np.ones(len(quantity)) / len(quantity),
                      color=color)
        AX[i][1].set_xlabel(unit, fontsize=10)
        AX[i][1].set_ylabel('occurence (%)', fontsize=10)

        quantity = (quant.data[:] if times is None else quant)
        AX[i][2].hist(quantity,
                      bins=10,
                      weights=100 * np.ones(len(quantity)) / len(quantity),
                      log=True,
                      color=color)
        AX[i][2].set_xlabel(unit, fontsize=10)
        AX[i][2].set_ylabel('occurence (%)', fontsize=10)

        CC, ts = autocorrel_on_NWB_quantity(
            Q1=(quant if times is None else None),
            q1=(quantity if times is not None else None),
            t_q1=times,
            tmax=180)
        AX[i][3].plot(ts / 60., CC, '-', color=color, lw=2)
        AX[i][3].set_xlabel('time (min)', fontsize=9)
        AX[i][3].set_ylabel('auto correl.', fontsize=9)

        CC, ts = autocorrel_on_NWB_quantity(
            Q1=(quant if times is None else None),
            q1=(quantity if times is not None else None),
            t_q1=times,
            tmax=20)
        AX[i][4].plot(ts, CC, '-', color=color, lw=2)
        AX[i][4].set_xlabel('time (s)', fontsize=9)
        AX[i][4].set_ylabel('auto correl.', fontsize=9)

    for i1 in range(len(UNITS)):

        m1, q1, times1, unit1 = MODALITIES[i1], QUANTITIES[i1], TIMES[
            i1], UNITS[i1]

        for i2 in range(i1 + 1, len(UNITS)):

            i += 1

            m2, q2, times2, unit2 = MODALITIES[i2], QUANTITIES[i2], TIMES[
                i2], UNITS[i2]

            AX[i][0].set_title(m1 + ' vs ' + m2 + 10 * ' ', fontsize=10)
            if times1 is None:
                Q1, qq1 = q1, None
            else:
                Q1, qq1 = None, q1
            if times2 is None:
                Q2, qq2 = q2, None
            else:
                Q2, qq2 = None, q2

            hist, be1, be2 = hist2D_on_NWB_quantity(Q1=Q1,
                                                    Q2=Q2,
                                                    q1=qq1,
                                                    t_q1=times1,
                                                    q2=qq2,
                                                    t_q2=times2,
                                                    bins=40)

            hist = np.log(np.clip(hist, np.min(hist[hist > 0]), np.max(hist)))
            ge.matrix(hist,
                      x=be1,
                      y=be2,
                      colormap=plt.cm.binary,
                      ax=AX[i][0],
                      aspect='auto')
            AX[i][0].grid(False)
            AX[i][0].set_xlabel(unit2, fontsize=8)
            AX[i][0].set_ylabel(unit1, fontsize=8)
            ge.annotate(AX[i][0],
                        '  log distrib.', (0, 1),
                        va='top',
                        size='x-small')

            mean_q1, var_q1, mean_q2, var_q2 = crosshistogram_on_NWB_quantity(
                Q1=Q1,
                Q2=Q2,
                q1=qq1,
                t_q1=times1,
                q2=qq2,
                t_q2=times2,
                Npoints=30)

            AX[i][1].errorbar(mean_q1,
                              mean_q2,
                              xerr=var_q1,
                              yerr=var_q2,
                              color='k')
            AX[i][1].set_xlabel(unit1, fontsize=10)
            AX[i][1].set_ylabel(unit2, fontsize=10)

            mean_q1, var_q1, mean_q2, var_q2 = crosshistogram_on_NWB_quantity(
                Q1=Q2,
                Q2=Q1,
                q1=qq2,
                t_q1=times2,
                q2=qq1,
                t_q2=times1,
                Npoints=30)

            AX[i][2].errorbar(mean_q1,
                              mean_q2,
                              xerr=var_q1,
                              yerr=var_q2,
                              color='k')
            AX[i][2].set_xlabel(unit2, fontsize=10)
            AX[i][2].set_ylabel(unit1, fontsize=10)


            CCF, tshift = crosscorrel_on_NWB_quantity(Q1=Q2, Q2=Q1,
                            q1=qq2, t_q1=times2, q2=qq1, t_q2=times1,\
                                                      tmax=180)
            AX[i][3].plot(tshift / 60, CCF, 'k-')
            AX[i][3].set_xlabel('time (min)', fontsize=10)
            AX[i][3].set_ylabel('cross correl.', fontsize=10)

            CCF, tshift = crosscorrel_on_NWB_quantity(Q1=Q2, Q2=Q1,
                                        q1=qq2, t_q1=times2, q2=qq1, t_q2=times1,\
                                        tmax=20)
            AX[i][4].plot(tshift, CCF, 'k-')
            AX[i][4].set_xlabel('time (s)', fontsize=10)
            AX[i][4].set_ylabel('cross correl.', fontsize=10)

    return fig
def OS_ROI_analysis(FullData,
                    roiIndex=0,
                    iprotocol=0,
                    subprotocol_id=0,
                    verbose=False,
                    response_significance_threshold=0.01,
                    with_responsive_angles=False,
                    stat_test_props=dict(interval_pre=[-2, 0],
                                         interval_post=[1, 3],
                                         test='wilcoxon',
                                         positive=True)):
    """
    orientation selectivity ROI analysis
    """

    EPISODES = EpisodeResponse(FullData,
                               protocol_id=iprotocol,
                               quantity='CaImaging',
                               subquantity='dF/F',
                               roiIndex=roiIndex)

    fig, AX = FullData.plot_trial_average(
        EPISODES=EPISODES,
        quantity='CaImaging',
        subquantity='dF/F',
        roiIndex=roiIndex,
        column_key='angle',
        ybar=1.,
        ybarlabel='1dF/F',
        xbar=1.,
        xbarlabel='1s',
        fig_preset='raw-traces-preset+right-space',
        with_annotation=True,
        with_stat_test=True,
        stat_test_props=stat_test_props,
        verbose=verbose)

    ax = ge.inset(fig, (0.88, 0.4, 0.1, 0.4))
    angles, y, sy, responsive_angles = [], [], [], []
    responsive = False

    for i, angle in enumerate(EPISODES.varied_parameters['angle']):

        stats = EPISODES.stat_test_for_evoked_responses(
            episode_cond=EPISODES.find_episode_cond('angle', i),
            **stat_test_props)

        angles.append(angle)
        y.append(np.mean(stats.y))  # means "post"
        sy.append(np.std(stats.y))  # std "post"

        if stats.significant(threshold=response_significance_threshold):
            responsive = True
            responsive_angles.append(angle)

    ge.plot(angles,
            np.array(y),
            sy=np.array(sy),
            ax=ax,
            axes_args=dict(ylabel='<post dF/F>         ',
                           xlabel='angle ($^{o}$)',
                           xticks=angles,
                           size='small'),
            m='o',
            ms=2,
            lw=1)

    SI = orientation_selectivity_index(angles, y)
    ge.annotate(fig,
                'SI=%.2f ' % SI, (1, 0.97),
                va='top',
                ha='right',
                xycoords='figure fraction',
                weight='bold',
                fontsize=8,
                color=('k' if responsive else 'lightgray'))
    ge.annotate(fig, ('responsive' if responsive else 'unresponsive'),
                (0.78, 0.98),
                ha='left',
                va='top',
                xycoords='figure fraction',
                weight='bold',
                fontsize=8,
                color=(plt.cm.tab10(2) if responsive else plt.cm.tab10(3)))

    if with_responsive_angles:
        return fig, SI, responsive, responsive_angles
    else:
        return fig, SI, responsive
예제 #13
0
    def plot_row_column_of_quantity(self):

        self.Pcond = self.data.get_protocol_cond(self.pbox.currentIndex() - 1)
        single_cond = self.build_single_conditions()
        COL_CONDS = self.build_column_conditions()
        ROW_CONDS = self.build_row_conditions()
        COLOR_CONDS = self.build_color_conditions()

        if (len(COLOR_CONDS) > 1) and (self.color.text() != ''):
            COLORS = [
                getattr(ge, self.color.text())((c % 10) / 10.)
                for c in np.arange(len(COLOR_CONDS))
            ]
        elif (len(COLOR_CONDS) > 1):
            COLORS = [
                ge.tab10((c % 10) / 10.) for c in np.arange(len(COLOR_CONDS))
            ]
        elif self.color.text() != '':
            COLORS = [getattr(ge, self.color.text())]
        else:
            COLORS = ['k']

        fig, AX = ge.figure(
            axes=(len(COL_CONDS), len(ROW_CONDS)),
            **dv_tools.FIGURE_PRESETS[self.fig_presets.currentText()])

        self.ylim = [np.inf, -np.inf]
        for irow, row_cond in enumerate(ROW_CONDS):
            for icol, col_cond in enumerate(COL_CONDS):
                for icolor, color_cond in enumerate(COLOR_CONDS):
                    cond = np.array(single_cond & col_cond & row_cond
                                    & color_cond)[:self.EPISODES.resp.shape[0]]
                    if self.EPISODES.resp[cond, :].shape[0] > 0:
                        my = self.EPISODES.resp[cond, :].mean(axis=0)
                        if self.withSTDbox.isChecked():
                            sy = self.EPISODES.resp[cond, :].std(axis=0)
                            ge.plot(self.EPISODES.t,
                                    my,
                                    sy=sy,
                                    ax=AX[irow][icol],
                                    color=COLORS[icolor],
                                    lw=1)
                            self.ylim = [
                                min([self.ylim[0],
                                     np.min(my - sy)]),
                                max([self.ylim[1],
                                     np.max(my + sy)])
                            ]
                        else:
                            AX[irow][icol].plot(self.EPISODES.t,
                                                my,
                                                color=COLORS[icolor],
                                                lw=1)
                            self.ylim = [
                                min([self.ylim[0], np.min(my)]),
                                max([self.ylim[1], np.max(my)])
                            ]

                        if self.annot.isChecked():
                            # column label
                            if (len(COL_CONDS) > 1) and (irow == 0) and (icolor
                                                                         == 0):
                                s = ''
                                for i, key in enumerate(
                                        self.varied_parameters.keys()):
                                    if 'column' in getattr(
                                            self,
                                            '%s_plot' % key).currentText():
                                        s += format_key_value(
                                            key,
                                            getattr(self.EPISODES,
                                                    key)[cond][0]
                                        ) + 4 * ' '  # should have a unique value
                                ge.annotate(AX[irow][icol],
                                            s, (1, 1),
                                            ha='right',
                                            va='bottom')
                            # row label
                            if (len(ROW_CONDS) > 1) and (icol == 0) and (icolor
                                                                         == 0):
                                s = ''
                                for i, key in enumerate(
                                        self.varied_parameters.keys()):
                                    if 'row' in getattr(self, '%s_plot' %
                                                        key).currentText():
                                        s += format_key_value(
                                            key,
                                            getattr(self.EPISODES,
                                                    key)[cond][0]
                                        ) + 4 * ' '  # should have a unique value
                                ge.annotate(AX[irow][icol],
                                            s, (0, 0),
                                            ha='right',
                                            va='bottom',
                                            rotation=90)
                            # n per cond
                            ge.annotate(AX[irow][icol],
                                        ' n=%i' % np.sum(cond) + '\n' * icolor,
                                        (.99, 0),
                                        color=COLORS[icolor],
                                        size='xx-small',
                                        ha='left',
                                        va='bottom')

                    if self.screen.isChecked() and not (self.data.visual_stim
                                                        is not None):
                        print('initializing stim [...]')
                        self.data.init_visual_stim()

                    if self.screen.isChecked():
                        inset = ge.inset(AX[irow][icol], [.8, .9, .3, .25])
                        self.data.visual_stim.show_frame(\
                                                         self.EPISODES.index_from_start[cond][0],
                                                         ax=inset, enhance=True, label=None)

        if self.withStatTest.isChecked():
            for irow, row_cond in enumerate(ROW_CONDS):
                for icol, col_cond in enumerate(COL_CONDS):
                    for icolor, color_cond in enumerate(COLOR_CONDS):

                        cond = np.array(
                            single_cond & col_cond & row_cond
                            & color_cond)[:self.EPISODES.resp.shape[0]]
                        results = self.EPISODES.stat_test_for_evoked_responses(
                            episode_cond=cond,
                            interval_pre=[self.t0pre, self.t1pre],
                            interval_post=[self.t0post, self.t1post],
                            test='wilcoxon')
                        ps, size = results.pval_annot()
                        AX[irow][icol].annotate(
                            ps,
                            ((self.t1pre + self.t0post) / 2., self.ylim[0]),
                            va='top',
                            ha='center',
                            size=size,
                            xycoords='data')
                        AX[irow][icol].plot([self.t0pre, self.t1pre],
                                            self.ylim[0] * np.ones(2),
                                            'k-',
                                            lw=2)
                        AX[irow][icol].plot([self.t0post, self.t1post],
                                            self.ylim[0] * np.ones(2),
                                            'k-',
                                            lw=2)

        # color label
        if self.annot.isChecked() and (len(COLOR_CONDS) > 1):
            for icolor, color_cond in enumerate(COLOR_CONDS):
                cond = np.array(single_cond
                                & color_cond)[:self.EPISODES.resp.shape[0]]
                for i, key in enumerate(self.varied_parameters.keys()):
                    if 'color' in getattr(self, '%s_plot' % key).currentText():
                        s = format_key_value(
                            key,
                            getattr(self.EPISODES, key)[cond][0])
                        ge.annotate(fig,
                                    s,
                                    (1. - icolor / (len(COLOR_CONDS) + 2), 0),
                                    color=COLORS[icolor],
                                    ha='right',
                                    va='bottom')

        if (self.ymin.text() != '') and (self.ymax.text() != ''):
            self.ylim = [float(self.ymin.text()), float(self.ymax.text())]
        if (self.xmin.text() != '') and (self.xmax.text() != ''):
            self.xlim = [float(self.xmin.text()), float(self.xmax.text())]
        else:
            self.xlim = [self.EPISODES.t[0], self.EPISODES.t[-1]]

        for irow, row_cond in enumerate(ROW_CONDS):
            for icol, col_cond in enumerate(COL_CONDS):
                ge.set_plot(AX[irow][icol],
                            spines=(['left', 'bottom']
                                    if self.axis.isChecked() else []),
                            ylim=self.ylim,
                            xlim=self.xlim,
                            xlabel=(self.xbarlabel.text()
                                    if self.axis.isChecked() else ''),
                            ylabel=(self.ybarlabel.text()
                                    if self.axis.isChecked() else ''))

                if self.stim.isChecked():
                    AX[irow][icol].fill_between(
                        [0, np.mean(self.EPISODES.time_duration)],
                        self.ylim[0] * np.ones(2),
                        self.ylim[1] * np.ones(2),
                        color='grey',
                        alpha=.2,
                        lw=0)

        if not self.axis.isChecked():
            ge.draw_bar_scales(AX[0][0],
                               Xbar=(0. if self.xbar.text() == '' else float(
                                   self.xbar.text())),
                               Xbar_label=self.xbarlabel.text(),
                               Ybar=(0. if self.ybar.text() == '' else float(
                                   self.ybar.text())),
                               Ybar_label=self.ybarlabel.text() + ' ',
                               Xbar_fraction=0.1,
                               Xbar_label_format='%.1f',
                               Ybar_fraction=0.2,
                               Ybar_label_format='%.1f',
                               loc='top-left')

        if self.label.text() != '':
            ge.annotate(fig, ' '+self.label.text()+\
                        (1+int(self.nlabel.text()))*'\n', (0,0), color=COLORS[0],
                        ha='left', va='bottom')

        if self.annot.isChecked():
            S = ''
            if hasattr(self, 'roiPick'):
                S += 'roi #%s, ' % self.roiPick.text()
            for i, key in enumerate(self.varied_parameters.keys()):
                if 'single-value' in getattr(self,
                                             '%s_plot' % key).currentText():
                    S += '%s=%s, ' % (key, getattr(
                        self, '%s_values' % key).currentText())
            ge.annotate(fig, S, (0, 0), color='k', ha='left', va='bottom')

        if self.annot.isChecked():
            ge.annotate(
                fig,
                "%s, %s, %s, %s" %
                (self.data.metadata['subject_ID'],
                 self.data.protocols[self.pbox.currentIndex() - 1][:20],
                 self.data.metadata['filename'].split('\\')[-2],
                 self.data.metadata['filename'].split('\\')[-1]), (0, 1),
                color='k',
                ha='left',
                va='top',
                size='x-small')

        return fig, AX
예제 #14
0
def ROI_analysis(FullData,
                 roiIndex=0,
                 iprotocol=0,
                 verbose=False,
                 response_significance_threshold=0.01,
                 radius_threshold_for_center=20.,
                 with_responsive_angles=False,
                 stat_test_props=dict(interval_pre=[-2, 0],
                                      interval_post=[1, 3],
                                      test='wilcoxon',
                                      positive=True),
                 Npanels=4):
    """
    direction selectivity ROI analysis
    """

    EPISODES = EpisodeResponse(FullData,
                               protocol_id=iprotocol,
                               quantity='CaImaging',
                               subquantity='dF/F',
                               roiIndex=roiIndex)

    ROW_KEYS, ROW_VALUES, ROW_INDICES, Nfigs, ROW_BINS = [], [], [], 1, []
    for key in ['x-center', 'y-center', 'contrast']:
        if key in EPISODES.varied_parameters:
            ROW_KEYS.append(key)
            ROW_VALUES.append(EPISODES.varied_parameters[key])
            ROW_INDICES.append(np.arange(len(EPISODES.varied_parameters[key])))
            Nfigs *= len(EPISODES.varied_parameters[key])
            x = np.unique(EPISODES.varied_parameters[key])
            ROW_BINS.append(
                np.concatenate([[x[0] - .5 * (x[1] - x[0])],
                                .5 * (x[1:] + x[:-1]),
                                [x[-1] + .5 * (x[-1] - x[-2])]]))

    fig, AX = FullData.plot_trial_average(EPISODES=EPISODES,
                                          protocol_id=iprotocol,
                                          quantity='CaImaging',
                                          subquantity='dF/F',
                                          roiIndex=roiIndex,
                                          column_key='radius',
                                          row_keys=ROW_KEYS,
                                          color_key='angle',
                                          ybar=1.,
                                          ybarlabel='1dF/F',
                                          xbar=1.,
                                          xbarlabel='1s',
                                          fig_preset='raw-traces-preset',
                                          with_annotation=True,
                                          with_std=False,
                                          with_stat_test=True,
                                          stat_test_props=stat_test_props,
                                          verbose=verbose)

    # now computing the size-response curve for all conditions
    if 'angle' in EPISODES.varied_parameters:

        ROW_KEYS.append('angle')
        ROW_VALUES.append(EPISODES.varied_parameters['angle'])
        ROW_INDICES.append(np.arange(len(EPISODES.varied_parameters['angle'])))
        Nfigs *= len(EPISODES.varied_parameters['angle'])
        x = np.unique(EPISODES.varied_parameters['angle'])
        ROW_BINS.append(
            np.concatenate([[x[0] - .5 * (x[1] - x[0])], .5 * (x[1:] + x[:-1]),
                            [x[-1] + .5 * (x[-1] - x[-2])]]))

    fig2, AX = ge.figure(axes=(Npanels, int(Nfigs / Npanels)), hspace=1.5)

    full_resp = {'value': [], 'significant': [], 'radius': []}
    for key, bins in zip(ROW_KEYS, ROW_BINS):
        full_resp[key] = []
        full_resp[key + '-bins'] = bins

    iax, ylims = 0, [10, -10]
    max_response_level, max_response_curve, imax_response_curve = 0, None, -1
    for indices in itertools.product(*ROW_INDICES):

        title = ''
        for key, index in zip(ROW_KEYS, indices):
            title += format_key_value(
                key, EPISODES.varied_parameters[key]
                [index]) + ', '  # should have a unique value
        ge.title(ge.flat(AX)[iax], title, size='small')

        resp, radii, significants = [0], [0], [False]
        for ia, radius in enumerate(EPISODES.varied_parameters['radius']):

            # stat test "pre" vs "post"
            stats = EPISODES.stat_test_for_evoked_responses(
                episode_cond=EPISODES.find_episode_cond(
                    ROW_KEYS + ['radius'],
                    list(indices) + [ia]),
                **stat_test_props)

            resp.append(np.mean(stats.y - stats.x))  # "post"-"pre"
            radii.append(radius)

            ge.annotate(ge.flat(AX)[iax],
                        '    ' + stats.pval_annot()[0], (radius, resp[-1]),
                        size='x-small',
                        rotation=90,
                        ha='center',
                        xycoords='data')

            significants.append(
                stats.significant(threshold=response_significance_threshold))

            # store all in full resp
            for key, index in zip(ROW_KEYS, indices):
                full_resp[key].append(EPISODES.varied_parameters[key][index])
            full_resp['radius'].append(radius)
            full_resp['value'].append(np.mean(stats.y - stats.x))
            full_resp['significant'].append(
                stats.significant(threshold=response_significance_threshold))

        # check if max resp
        center_cond = np.array(significants) & (np.array(radii) <
                                                radius_threshold_for_center)
        if np.sum(center_cond) and (np.max(np.array(resp)[center_cond]) >
                                    max_response_level):
            max_response_level = np.max(np.array(resp)[center_cond])
            max_response_curve = np.array(resp)
            imax_response_curve = iax

        ylims = [
            np.min([np.min(resp), ylims[0]]),
            np.max([np.max(resp), ylims[1]])
        ]
        ge.flat(AX)[iax].plot(radii, resp, 'ko-', ms=4)
        iax += 1

    for iax, ax in enumerate(ge.flat(AX)):
        ge.set_plot(ax,
                    ylim=[
                        ylims[0] - .05 * (ylims[1] - ylims[0]),
                        ylims[1] + .05 * (ylims[1] - ylims[0])
                    ],
                    ylabel=('$\delta$ dF/F' if (iax % Npanels == 0) else ''),
                    xlabel=('size ($^{o}$)' if
                            (int(iax / Npanels) == (int(Nfigs / Npanels) -
                                                    1)) else ''))
        ax.fill_between([0, radius_threshold_for_center],
                        ylims[0] * np.ones(2),
                        ylims[1] * np.ones(2),
                        color='k',
                        alpha=0.05,
                        lw=0)

        if iax == imax_response_curve:
            ax.fill_between(radii,
                            ylims[0] * np.ones(len(radii)),
                            ylims[1] * np.ones(len(radii)),
                            color='k',
                            alpha=0.1,
                            lw=0)

    x = np.unique(EPISODES.varied_parameters['radius'])
    full_resp['radius-bins'] = np.concatenate([[x[0] - .5 * (x[1] - x[0])],
                                               .5 * (x[1:] + x[:-1]),
                                               [x[-1] + .5 * (x[-1] - x[-2])]])

    for key in full_resp:
        full_resp[key] = np.array(full_resp[key])

    return fig, fig2, radii, max_response_curve, imax_response_curve, full_resp
def DS_ROI_analysis(FullData,
                    roiIndex=0,
                    iprotocol=0,
                    verbose=False,
                    response_significance_threshold=0.01,
                    with_responsive_angles=False,
                    fig=None,
                    AX=None,
                    CaImaging_options=dict(quantity='CaImaging',
                                           subquantity='dF/F'),
                    stat_test_props=dict(interval_pre=[-2, 0],
                                         interval_post=[1, 3],
                                         test='wilcoxon'),
                    inset_coords=(0.92, 0.4, 0.07, 0.4)):
    """
    direction selectivity ROI analysis
    """

    EPISODES = EpisodeResponse(FullData,
                               protocol_id=iprotocol,
                               roiIndex=roiIndex,
                               verbose=verbose,
                               **CaImaging_options)

    fig, AX = FullData.plot_trial_average(
        EPISODES=EPISODES,
        protocol_id=iprotocol,
        roiIndex=roiIndex,
        column_key='angle',
        ybar=1.,
        ybarlabel='1dF/F',
        xbar=1.,
        xbarlabel='1s',
        fig=fig,
        AX=AX,
        no_set=False,
        fig_preset='raw-traces-preset+right-space',
        with_annotation=True,
        with_stat_test=True,
        stat_test_props=stat_test_props,
        verbose=verbose,
        **CaImaging_options)

    ax = ge.inset(fig, inset_coords)
    angles, y, sy, responsive_angles = [], [], [], []
    responsive = False
    for i, angle in enumerate(EPISODES.varied_parameters['angle']):
        means_pre = EPISODES.compute_stats_over_repeated_trials(
            'angle',
            i,
            interval_cond=EPISODES.compute_interval_cond(
                stat_test_props['interval_pre']),
            quantity='mean')
        means_post = EPISODES.compute_stats_over_repeated_trials(
            'angle',
            i,
            interval_cond=EPISODES.compute_interval_cond(
                stat_test_props['interval_post']),
            quantity='mean')

        stats = EPISODES.stat_test_for_evoked_responses(
            episode_cond=EPISODES.find_episode_cond('angle', i),
            **stat_test_props)

        angles.append(angle)
        y.append(np.mean(means_post))
        sy.append(np.std(means_post))

        if stats.significant(response_significance_threshold):
            responsive = True
            responsive_angles.append(angle)

    ge.plot(angles,
            np.array(y),
            sy=np.array(sy),
            ax=ax,
            axes_args=dict(ylabel='<post dF/F>         ',
                           xlabel='angle ($^{o}$)',
                           xticks=np.array(angles)[::int(len(angles) / 4)],
                           size='small'),
            m='o',
            ms=2,
            lw=1)

    SI = orientation_selectivity_index(angles, y)
    ge.annotate(ax,
                'SI=%.2f\n ' % SI, (1, 1),
                ha='right',
                weight='bold',
                fontsize=8,
                color=('k' if responsive else 'lightgray'))
    ge.annotate(ax, ('responsive' if responsive else 'unresponsive'), (0., 1),
                ha='left',
                weight='bold',
                fontsize=8,
                color=(plt.cm.tab10(2) if responsive else plt.cm.tab10(3)))

    if with_responsive_angles:
        return fig, SI, responsive, responsive_angles
    else:
        return fig, SI, responsive
예제 #16
0
def analysis_fig(data, roiIndex=0):

    MODALITIES, QUANTITIES, TIMES, UNITS, COLORS = find_modalities(data)

    plt.style.use('ggplot')

    fig, AX = plt.subplots(2 + len(MODALITIES),
                           5,
                           figsize=(11.4, 2.3 * (2 + len(MODALITIES))))

    plt.subplots_adjust(left=0.05,
                        right=0.98,
                        bottom=0.3 / (2 + len(MODALITIES)),
                        top=0.94,
                        wspace=.5,
                        hspace=.5)
    if len(MODALITIES) == 0:
        AX = [AX]
    index = np.arange(len(data.iscell))[data.iscell][roiIndex]

    AX[0][0].annotate('ROI#%i' % (roiIndex + 1), (0.5, 0.5),
                      weight='bold',
                      fontsize=10,
                      va='center',
                      ha='center')
    AX[0][0].axis('off')
    AX[0][-1].axis('off')

    data.show_CaImaging_FOV(key='meanImgE',
                            cmap='viridis',
                            ax=AX[0][1],
                            roiIndex=roiIndex)
    data.show_CaImaging_FOV(key='meanImgE',
                            cmap='viridis',
                            ax=AX[0][2],
                            roiIndex=roiIndex,
                            with_roi_zoom=True)
    try:
        data.show_CaImaging_FOV(key='meanImg_chan2',
                                cmap='viridis',
                                ax=AX[0][3],
                                roiIndex=roiIndex,
                                NL=3,
                                with_roi_zoom=True)
        AX[0][3].annotate('red cell: %s' %
                          ('yes' if bool(data.redcell[index]) else 'no'),
                          (0.5, 0.),
                          xycoords='axes fraction',
                          fontsize=8,
                          va='top',
                          ha='center')
    except KeyError:
        AX[0][3].axis('off')
        AX[0][3].annotate('no red channel', (0.5, 0.5),
                          xycoords='axes fraction',
                          fontsize=9,
                          va='center',
                          ha='center')

    AX[1][0].hist(data.Fluorescence.data[index, :],
                  bins=30,
                  weights=100 * np.ones(len(data.dFoF[index, :])) /
                  len(data.dFoF[index, :]))
    AX[1][0].set_xlabel('Fluo. (a.u.)', fontsize=10)

    AX[1][1].hist(data.dFoF[index, :],
                  bins=30,
                  weights=100 * np.ones(len(data.dFoF[index, :])) /
                  len(data.dFoF[index, :]))
    AX[1][1].set_xlabel('dF/F', fontsize=10)

    AX[1][2].hist(data.dFoF[index, :],
                  log=True,
                  bins=30,
                  weights=100 * np.ones(len(data.dFoF[index, :])) /
                  len(data.dFoF[index, :]))
    AX[1][2].set_xlabel('dF/F', fontsize=10)
    for ax in AX[1][:3]:
        ax.set_ylabel('occurence (%)', fontsize=10)

    CC, ts = autocorrel_on_NWB_quantity(Q1=None,
                                        q1=data.dFoF[index, :],
                                        t_q1=data.Neuropil.timestamps[:],
                                        tmax=180)
    AX[1][3].plot(ts / 60., CC, '-', lw=2)
    AX[1][3].set_xlabel('time (min)', fontsize=10)
    AX[1][3].set_ylabel('auto correl.', fontsize=10)

    CC, ts = autocorrel_on_NWB_quantity(Q1=None,
                                        q1=data.dFoF[index, :],
                                        t_q1=data.Neuropil.timestamps[:],
                                        tmax=10)
    AX[1][4].plot(ts, CC, '-', lw=2)
    AX[1][4].set_xlabel('time (s)', fontsize=10)
    AX[1][4].set_ylabel('auto correl.', fontsize=10)

    for i, mod, quant, times, unit, color in zip(range(len(TIMES)), MODALITIES,
                                                 QUANTITIES, TIMES, UNITS,
                                                 COLORS):

        AX[2 + i][0].set_title(mod, fontsize=10, color=color)

        if times is None:
            Q, qq = quant, None
        else:
            Q, qq = None, quant

        try:
            hist, be1, be2 = hist2D_on_NWB_quantity(
                Q1=Q,
                Q2=None,
                q1=qq,
                t_q1=times,
                q2=data.dFoF[index, :],
                t_q2=data.Neuropil.timestamps[:],
                bins=(np.linspace(data.dFoF[index, :].min(),
                                  data.dFoF[index, :].max(), 50), 50))
            hist = np.log(np.clip(hist, np.min(hist[hist > 0]), np.max(hist)))
            ge.matrix(hist,
                      x=be1,
                      y=be2,
                      colormap=plt.cm.binary,
                      ax=AX[2 + i][0],
                      aspect='auto')
            AX[2 + i][0].grid(False)
            AX[2 + i][0].set_ylabel(unit, fontsize=8)
            AX[2 + i][0].set_xlabel('dF/F', fontsize=8)
            ge.annotate(AX[2 + i][0],
                        '  log distrib.', (0, 1),
                        va='top',
                        size='x-small')

            mean_q1, var_q1, mean_q2, var_q2 = crosshistogram_on_NWB_quantity(
                Q1=Q,
                Q2=None,
                q1=qq,
                t_q1=times,
                q2=data.dFoF[index, :],
                t_q2=data.Neuropil.timestamps[:],
                Npoints=30)

            AX[2 + i][1].errorbar(mean_q1,
                                  mean_q2,
                                  xerr=var_q1,
                                  yerr=var_q2,
                                  color=color)
            AX[2 + i][1].set_xlabel(unit, fontsize=10)
            AX[2 + i][1].set_ylabel('dF/F', fontsize=10)

            mean_q1, var_q1, mean_q2, var_q2 = crosshistogram_on_NWB_quantity(
                Q2=Q,
                Q1=None,
                q2=qq,
                t_q2=times,
                q1=data.dFoF[index, :],
                t_q1=data.Neuropil.timestamps[:],
                Npoints=30)

            AX[2 + i][2].errorbar(mean_q1,
                                  mean_q2,
                                  xerr=var_q1,
                                  yerr=var_q2,
                                  color=color)
            AX[2 + i][2].set_ylabel(unit, fontsize=10)
            AX[2 + i][2].set_xlabel('dF/F', fontsize=10)

            CCF, tshift = crosscorrel_on_NWB_quantity(
                Q1=Q,
                Q2=None,
                q1=qq,
                t_q1=times,
                q2=data.dFoF[index, :],
                t_q2=data.Neuropil.timestamps[:],
                tmax=180)
            AX[2 + i][3].plot(tshift / 60, CCF, '-', color=color)
            AX[2 + i][3].set_xlabel('time (min)', fontsize=10)
            AX[2 + i][3].set_ylabel('cross correl.', fontsize=10)

            CCF, tshift = crosscorrel_on_NWB_quantity(
                Q1=Q,
                Q2=None,
                q1=qq,
                t_q1=times,
                q2=data.dFoF[index, :],
                t_q2=data.Neuropil.timestamps[:],
                tmax=20)
            AX[2 + i][4].plot(tshift, CCF, '-', color=color)
            AX[2 + i][4].set_xlabel('time (s)', fontsize=10)
            AX[2 + i][4].set_ylabel('cross correl.', fontsize=10)
        except BaseException as be:
            print(mod, ' -->', be)

    return fig
예제 #17
0
def ROI_analysis(FullData,
                 roiIndex=0,
                 iprotocol_center=0,
                 iprotocol_surround=1,
                 verbose=False,
                 response_significance_threshold=0.01,
                 radius_threshold_for_center=20.,
                 with_responsive_angles = False,
                 stat_test_props=dict(interval_pre=[-2,0], interval_post=[1,3],
                                      test='wilcoxon', positive=True),
                 Npanels=4):
    """
    ROI analysis for secondary RF
    """

    EPISODES_CENTER = EpisodeResponse(FullData,
                                      protocol_id=iprotocol_center,
                                      quantity='CaImaging', subquantity='dF/F',
                                      prestim_duration=2.,
                                      roiIndex = roiIndex)

    EPISODES_SURROUND = EpisodeResponse(FullData,
                                        protocol_id=iprotocol_surround,
                                        quantity='CaImaging', subquantity='dF/F',
                                        prestim_duration=2.,
                                        roiIndex = roiIndex)
    

    FIGS = []
    
    for iangle, angle in enumerate(EPISODES_CENTER.varied_parameters['angle']):
    
        fig, AX = FullData.plot_trial_average(EPISODES=EPISODES_CENTER,
                                              condition=EPISODES_CENTER.find_episode_cond('angle', iangle),
                                              protocol_id=iprotocol_center,
                                              quantity='CaImaging', subquantity='dF/F',
                                              roiIndex = roiIndex,
                                              column_key='x-center', row_key='y-center',
                                              ybar=1., ybarlabel='1dF/F',
                                              xbar=1., xbarlabel='1s',
                                              fig_preset='raw-traces-preset',
                                              with_std=False,
                                              with_annotation=True,
                                              verbose=verbose, color=ge.blue)
        ge.annotate(fig, 'center ', (0.5, 0), color=ge.blue, ha='right')

        FullData.plot_trial_average(EPISODES=EPISODES_SURROUND,
                                    condition=EPISODES_SURROUND.find_episode_cond('angle', iangle),
                                    protocol_id=iprotocol_surround,
                                    quantity='CaImaging', subquantity='dF/F',
                                    roiIndex = roiIndex,
                                    column_key='x-center', row_key='y-center',
                                    with_std=False, with_stim=False,
                                    verbose=verbose, AX=AX, color=ge.red)
        ge.annotate(fig, ' surround', (0.5, 0), color=ge.red)
        ge.annotate(fig, format_key_value('angle', angle)+'  ', (1., 0), ha='right')

        # just for the axis extent
        _, AX2 = FullData.plot_trial_average(EPISODES=EPISODES_SURROUND,
                                    condition=EPISODES_SURROUND.find_episode_cond('angle', iangle),
                                    protocol_id=iprotocol_surround,
                                    quantity='CaImaging', subquantity='dF/F',
                                    roiIndex = roiIndex,
                                    column_key='x-center', row_key='y-center')
        
        ylims = [0,1]
        for ax, ax2 in zip(ge.flat(AX), ge.flat(AX2)):
            ylims = [np.min([ylims[0], ax.get_ylim()[0], ax2.get_ylim()[0]]),
                     np.max([ylims[1], ax.get_ylim()[1], ax2.get_ylim()[1]])]
        for ax in ge.flat(AX):
            ax.set_ylim(ylims)

        FIGS.append(fig)

    # fig2, AX = ge.figure(axes=(Npanels, int(Nfigs/Npanels)), hspace=1.5)

    # full_resp = {'value':[], 'significant':[], 'radius':[]}
    # for key, bins in zip(ROW_KEYS, ROW_BINS):
    #     full_resp[key] = []
    #     full_resp[key+'-bins'] = bins
    
    # iax, ylims = 0, [10, -10]
    # max_response_level, max_response_curve, imax_response_curve = 0, None, -1
    # for indices in itertools.product(*ROW_INDICES):

    #     title = ''
    #     for key, index in zip(ROW_KEYS, indices):
    #         title+=format_key_value(key, EPISODES.varied_parameters[key][index])+', ' # should have a unique value
    #     ge.title(ge.flat(AX)[iax], title, size='small')
        
    #     resp, radii, significants = [0], [0], [False]
    #     for ia, radius in enumerate(EPISODES.varied_parameters['radius']):
            
    #         # stat test "pre" vs "post"
    #         stats = EPISODES.stat_test_for_evoked_responses(episode_cond=EPISODES.find_episode_cond(ROW_KEYS+['radius'], list(indices)+[ia]),
    #                                                         **stat_test_props)
            
    #         resp.append(np.mean(stats.y-stats.x)) # "post"-"pre"
    #         radii.append(radius)
            
    #         ge.annotate(ge.flat(AX)[iax], '    '+stats.pval_annot()[0], (radius, resp[-1]),
    #                     size='x-small', rotation=90, ha='center', xycoords='data')

    #         significants.append(stats.significant(threshold=response_significance_threshold))

    #         # store all in full resp
    #         for key, index in zip(ROW_KEYS, indices):
    #             full_resp[key].append(EPISODES.varied_parameters[key][index])
    #         full_resp['radius'].append(radius)
    #         full_resp['value'].append(np.mean(stats.y-stats.x))
    #         full_resp['significant'].append(stats.significant(threshold=response_significance_threshold))

    #     # check if max resp
    #     center_cond = np.array(significants) & (np.array(radii)<radius_threshold_for_center)
    #     if np.sum(center_cond) and (np.max(np.array(resp)[center_cond])>max_response_level):
    #         max_response_level = np.max(np.array(resp)[center_cond])
    #         max_response_curve = np.array(resp)
    #         imax_response_curve = iax
            
    #     ylims = [np.min([np.min(resp), ylims[0]]), np.max([np.max(resp), ylims[1]])]
    #     ge.flat(AX)[iax].plot(radii, resp, 'ko-', ms=4)
    #     iax += 1
        
    # for iax, ax in enumerate(ge.flat(AX)):
    #     ge.set_plot(ax, ylim=[ylims[0]-.05*(ylims[1]-ylims[0]), ylims[1]+.05*(ylims[1]-ylims[0])],
    #                 ylabel=('$\delta$ dF/F' if (iax%Npanels==0) else ''),
    #                 xlabel=('size ($^{o}$)' if (int(iax/Npanels)==(int(Nfigs/Npanels)-1)) else ''))
    #     ax.fill_between([0, radius_threshold_for_center], ylims[0]*np.ones(2), ylims[1]*np.ones(2), color='k', alpha=0.05, lw=0)
        
    #     if iax==imax_response_curve:
    #         ax.fill_between(radii, ylims[0]*np.ones(len(radii)), ylims[1]*np.ones(len(radii)), color='k', alpha=0.1, lw=0)
            
    # x = np.unique(EPISODES.varied_parameters['radius'])
    # full_resp['radius-bins'] = np.concatenate([[x[0]-.5*(x[1]-x[0])], .5*(x[1:]+x[:-1]), [x[-1]+.5*(x[-1]-x[-2])]])

    # for key in full_resp:
    #     full_resp[key] = np.array(full_resp[key])
    
    # return fig, fig2, radii, max_response_curve, imax_response_curve, full_resp
    # return fig, None, None, None, None, None
    return FIGS
def modulation_summary_panel(t,
                             data,
                             title='',
                             pre_interval=[-1, 0],
                             post_interval=[1, 2],
                             responsive_only=False):

    if responsive_only:
        fig, AX = ge.figure(axes=(4, 1), wspace=2)
        valid_cells = np.array(data['responsive'])
        # pie plot for responsiveness
        AX[0].pie([
            100 * np.sum(valid_cells) / len(valid_cells), 100 *
            (1 - np.sum(valid_cells) / len(valid_cells))
        ],
                  explode=(0, 0.1),
                  colors=[plt.cm.tab10(2), plt.cm.tab10(3)],
                  labels=['resp.  ', '  unresp.'],
                  autopct='%1.1f%%',
                  shadow=True,
                  startangle=90)

        iax = 1
    else:
        fig, AX = ge.figure(axes=(3, 1), wspace=2)
        iax = 0
        valid_cells = np.ones(len(data['control']), dtype=bool)

    ge.annotate(fig,
                '%s, n=%i ROIs' % (title, np.sum(valid_cells)), (0.05, 0.98),
                va='top')

    pre_cond = (t > pre_interval[0]) & (t < pre_interval[1])
    post_cond = (t > post_interval[0]) & (t < post_interval[1])

    evoked_levels = {}
    if np.sum(valid_cells) > 1:
        for ik, key, color in zip(range(3),
                                  ['redundant', 'control', 'deviant'],
                                  [ge.blue, 'k', ge.red]):
            y = np.array(data[key])[valid_cells, :]
            ge.plot(t,
                    y.mean(axis=0),
                    sy=y.std(axis=0),
                    color=color,
                    ax=AX[iax],
                    no_set=True)
            y_bsl = y - np.mean(y[:, pre_cond], axis=1).reshape(
                (np.sum(valid_cells), 1))
            ge.plot(t,
                    y_bsl.mean(axis=0),
                    sy=y_bsl.std(axis=0),
                    color=color,
                    ax=AX[iax + 1],
                    no_set=True)
            # bar plot
            evoked_levels[key] = np.mean(y_bsl[:, post_cond], axis=1)
            AX[iax + 2].bar([ik],
                            np.mean(evoked_levels[key]),
                            yerr=np.std(evoked_levels[key]),
                            lw=2,
                            color=color)

        # adaptation effect (control vs redundant conditions)
        test = ttest_rel(evoked_levels['redundant'], evoked_levels['control'])
        AX[iax + 2].plot([0, 1],
                         AX[iax + 2].get_ylim()[1] * np.ones(2),
                         'k-',
                         lw=1)
        ge.annotate(AX[iax + 2],
                    ge.from_pval_to_star(test.pvalue),
                    (0.5, AX[iax + 2].get_ylim()[1]),
                    ha='center',
                    xycoords='data')

        # surprise effect (control vs deviant conditions)
        test = ttest_rel(evoked_levels['deviant'], evoked_levels['control'])
        AX[iax + 2].plot([1, 2],
                         AX[iax + 2].get_ylim()[1] * np.ones(2),
                         'k-',
                         lw=1)
        ge.annotate(AX[iax + 2],
                    ge.from_pval_to_star(test.pvalue),
                    (1.5, AX[iax + 2].get_ylim()[1]),
                    ha='center',
                    xycoords='data')

        # pre / post intervals
        ylim1 = AX[iax].get_ylim()[0]
        AX[iax].plot(pre_interval, ylim1 * np.ones(2), lw=1, color='dimgrey')
        AX[iax].plot(post_interval, ylim1 * np.ones(2), lw=1, color='dimgrey')

        ge.set_plot(AX[iax], xlabel='time (s)', ylabel='dF/F')
        ge.set_plot(AX[iax + 1], xlabel='time (s)', ylabel='$\Delta$ dF/F')
        ge.title(AX[iax + 1], 'baseline corrected', size='x-small')
        ge.set_plot(AX[iax + 2],
                    xlabel='',
                    ylabel='evoked $\Delta$ dF/F',
                    xticks=[0, 1, 2],
                    xticks_labels=['red.', 'ctrl', 'dev.'],
                    xticks_rotation=70)

    return fig, AX
def interaction_fig(responses,
                    static_patch_label='...',
                    moving_dots_label='...',
                    mixed_label='...',
                    random=False,
                    Ybar=0.2,
                    Ybar_label='0.2dF/F',
                    tmin=-3):

    fig, AX = ge.figure(axes=(3, 1),
                        figsize=(1., 1),
                        wspace=0.5,
                        right=8,
                        top=2)

    ax = ge.inset(fig, [.9, .4, .07, .5])
    ax.bar([0], [responses['linear-integral']], color=ge.red)
    ax.bar([1], [responses['mixed-integral']], color='k')
    ge.set_plot(ax, ['left'], ylabel='integ. (resp.s)')

    # static-patch
    cond = responses['t_contour'] > tmin / 2.
    AX[0].plot(responses['t_contour'][cond],
               responses['contour'][cond],
               color='k')
    ge.set_plot(AX[0], [], title=static_patch_label)

    # mv Dots
    cond = responses['t_motion'] > tmin
    AX[1].plot(responses['t_motion'][cond],
               responses['motion' if not random else 'random'][cond],
               color='k')
    ge.set_plot(AX[1], [], title=moving_dots_label)

    # mixed
    interaction_panel(
        responses,
        ax=AX[2],
        title=mixed_label,
        mixed_key='mixed' if not random else 'mixed-random',
        linear_key='linear' if not random else 'linear-random',
        with_episodes_highlights=
        False,  # only after that we have set common lims
        tmin=tmin)

    ge.set_common_ylims(AX)
    ge.set_common_xlims(AX)

    AX[0].fill_between([0, responses['patch-duration']],
                       AX[0].get_ylim()[0] * np.ones(2),
                       AX[0].get_ylim()[1] * np.ones(2),
                       color=ge.blue,
                       alpha=.3,
                       lw=0)
    AX[1].fill_between([0, responses['mvDot-duration']],
                       AX[1].get_ylim()[0] * np.ones(2),
                       AX[1].get_ylim()[1] * np.ones(2),
                       color=ge.orange,
                       alpha=.1,
                       lw=0)

    AX[2].plot(
        responses['delay'] + np.arange(2) * responses['integral_window'],
        AX[2].get_ylim()[1] * np.ones(2), 'k-')
    AX[2].fill_between(responses['delay'] +
                       np.arange(2) * responses['patch-duration'],
                       AX[2].get_ylim()[0] * np.ones(2),
                       AX[2].get_ylim()[1] * np.ones(2),
                       color=ge.blue,
                       alpha=.3,
                       lw=0)
    AX[2].fill_between([0, responses['mvDot-duration']],
                       AX[2].get_ylim()[0] * np.ones(2),
                       AX[2].get_ylim()[1] * np.ones(2),
                       color=ge.orange,
                       alpha=.1,
                       lw=0)

    for ax in AX:
        ge.draw_bar_scales(ax,
                           Xbar=1,
                           Xbar_label='1s',
                           Ybar=Ybar,
                           Ybar_label=Ybar_label)
    ge.annotate(fig, ' n=%iROIs' % responses['nROIs'], (0.02, 0.02))
    return fig, AX, ax
def analysis_pdf(datafile,
                 iprotocol=0,
                 stat_test_props=dict(interval_pre=[-2, 0],
                                      interval_post=[1, 3],
                                      test='wilcoxon',
                                      positive=True),
                 response_significance_threshold=0.05,
                 quantity='dFoF',
                 verbose=True,
                 Nmax=1000000):

    data = Data(datafile, metadata_only=True)

    print('   - computing episodes [...]')
    EPISODES = EpisodeResponse(datafile,
                               protocol_id=iprotocol,
                               quantities=['dFoF'])

    pdf_filename = os.path.join(
        summary_pdf_folder(datafile),
        '%s-spatial_selectivity.pdf' % data.protocols[iprotocol])

    results = {'Ntot': EPISODES.data.nROIs, 'significant': []}

    fig, AX = ge.figure(axes=(3, 1))

    with PdfPages(pdf_filename) as pdf:

        print(
            '   - spatial-selectivity analysis for summed ROI fluo (n=%i rois)'
            % EPISODES.data.nROIs)

        fig, AX = EPISODES.plot_trial_average(
            quantity=quantity,
            roiIndices='all',
            roiIndex=None,
            column_key='x-center',
            row_key='y-center',  # color_key='angle',
            ybar=0.2,
            ybarlabel='0.2dF/F',
            xbar=1.,
            xbarlabel='1s',
            with_annotation=True,
            with_std=True,
            with_stat_test=True,
            stat_test_props=stat_test_props,
            with_screen_inset=True,
            verbose=verbose)
        pdf.savefig(fig)
        plt.close(fig)  # Add figure to pdf and close

        for roi in np.arange(EPISODES.data.nROIs)[:Nmax]:

            print('   - spatial-selectivity analysis for ROI #%i / %i' %
                  (roi + 1, EPISODES.data.nROIs))

            resp = EPISODES.compute_summary_data(
                stat_test_props,
                exclude_keys=['repeat'],
                response_args=dict(roiIndex=roi),
                response_significance_threshold=response_significance_threshold
            )

            fig, AX = EPISODES.plot_trial_average(
                quantity=quantity,
                roiIndex=roi,
                column_key='x-center',
                row_key='y-center',
                color_key='angle',
                ybar=0.2,
                ybarlabel='0.2dF/F',
                xbar=1.,
                xbarlabel='1s',
                with_annotation=True,
                with_std=False,
                with_stat_test=True,
                stat_test_props=stat_test_props,
                with_screen_inset=True,
                verbose=verbose)
            pdf.savefig(fig)
            plt.close(fig)  # Add figure to pdf and close

            significant_cond, label = (
                resp['significant'] == True), '  -> max resp.: '
            if np.sum(significant_cond) > 0:
                imax = np.argmax(resp['value'][significant_cond])
                for key in resp:
                    if ('-bins' not in key):
                        if (key not in results):
                            results[key] = []  # initialize if not done
                        results[key].append(resp[key][significant_cond][imax])
                        label += format_key_value(
                            key, resp[key][significant_cond]
                            [imax]) + ', '  # should have a unique value
                        print(label)
                ge.annotate(
                    fig, label + '\n\n', (0, 0),
                    size='x-small')  #, ha='right', va='top'), rotation=90)
            else:
                ge.annotate(
                    fig,
                    label + ' N/A (no significant resp.)\n\n', (0, 0),
                    size='x-small')  #, ha='right', va='top', rotation=90)

        # the adding the bins
        for key in resp:
            if ('-bins' in key):
                results[key] = resp[key]

        fig = summary_fig(results)
        pdf.savefig(fig)  # saves the current figure into a pdf page
        plt.close(fig)

    print('[ok] spatial-selectivity analysis saved as: "%s" ' % pdf_filename)
예제 #21
0
def population_tuning_fig(full_resp):

    Ncells = len(np.unique(full_resp['roi']))
    Neps = len(full_resp['roi']) / Ncells
    angles = np.unique(full_resp['angle_from_pref'])

    fig, AX = ge.figure(axes=(3, 1), figsize=(1.5, 1.5))

    for ax in AX:
        ge.annotate(ax,
                    'n=%i resp. cells (%.0f%% of rois)' %
                    (Ncells, 100. * Ncells / full_resp['Nroi_tot']), (1, 1),
                    va='top',
                    ha='right')

    ge.plot(angles,
            np.mean(full_resp['per_cell_post'], axis=0),
            sy=np.std(full_resp['per_cell_post'], axis=0),
            color='grey',
            ms=2,
            m='o',
            ax=AX[0],
            no_set=True,
            lw=1)
    ge.set_plot(AX[0],
                xlabel='angle ($^{o}$) w.r.t. pref. orient.',
                ylabel='post level (dF/F)',
                xticks=[0, 90, 180, 270])

    ge.plot(angles,
            np.mean(full_resp['per_cell'], axis=0),
            sy=np.std(full_resp['per_cell'], axis=0),
            color='grey',
            ms=2,
            m='o',
            ax=AX[1],
            no_set=True,
            lw=1)
    ge.set_plot(AX[1],
                xlabel='angle ($^{o}$) w.r.t. pref. orient.',
                ylabel='evoked resp. ($\delta$ dF/F)',
                xticks=[0, 90, 180, 270])

    ge.plot(angles,
            np.mean(full_resp['per_cell'].T /
                    np.max(full_resp['per_cell'], axis=1).T,
                    axis=1),
            sy=np.std(full_resp['per_cell'].T /
                      np.max(full_resp['per_cell'], axis=1).T,
                      axis=1),
            color='grey',
            ms=2,
            m='o',
            ax=AX[2],
            no_set=True,
            lw=1)
    ge.set_plot(AX[2],
                xlabel='angle ($^{o}$) w.r.t. pref. orient.',
                ylabel='norm. resp ($\delta$ dF/F)',
                yticks=[0, 0.5, 1],
                xticks=[0, 90, 180, 270])

    return fig
예제 #22
0
def tuning_modulation_fig(curves, full_resp=None):

    # running vs still --- raw evoked response
    fig, ax = ge.figure(figsize=(1.5, 1.5), right=6)
    ge.plot(curves['angles'],
            curves['all'],
            label='all',
            color='grey',
            ax=ax,
            no_set=True,
            lw=2,
            alpha=.5)
    ge.plot(curves['angles'],
            curves['running_mean'],
            color=ge.orange,
            ms=4,
            m='o',
            ax=ax,
            lw=2,
            label='running',
            no_set=True)
    ge.plot(curves['angles'],
            curves['still_mean'],
            color=ge.blue,
            ms=4,
            m='o',
            ax=ax,
            lw=2,
            label='still',
            no_set=True)
    ge.legend(ax, ncol=3, loc=(.3, 1.))
    ge.set_plot(ax,
                xlabel='angle ($^{o}$) w.r.t. pref. orient.',
                ylabel='evoked resp, ($\delta$ dF/F)   ',
                xticks=[0, 90, 180, 270])

    if (full_resp is not None) and ('speed_level'
                                    in full_resp) and ('pupil_level'
                                                       in full_resp):
        inset = ge.inset(fig, [.8, .5, .16, .28])
        ge.scatter(full_resp['pupil_level'][full_resp['running_cond']],
                   full_resp['speed_level'][full_resp['running_cond']],
                   ax=inset,
                   no_set=True,
                   color=ge.orange)
        ge.scatter(full_resp['pupil_level'][~full_resp['running_cond']],
                   full_resp['speed_level'][~full_resp['running_cond']],
                   ax=inset,
                   no_set=True,
                   color=ge.blue)
        ge.annotate(ax,
                    'n=%i cells\n' % full_resp['Ncells'], (0., 1.),
                    ha='center')
        ge.set_plot(inset,
                    xlabel='pupil size (mm)',
                    ylabel='run. speed (cm/s)     ',
                    title='episodes (n=%i)   ' % full_resp['Neps'])
        ge.annotate(inset,
                    'n=%i' %
                    (np.sum(full_resp['running_cond']) / full_resp['Ncells']),
                    (0., 1.),
                    va='top',
                    color=ge.orange)
        ge.annotate(inset,
                    '\nn=%i' %
                    (np.sum(~full_resp['running_cond']) / full_resp['Ncells']),
                    (0., 1.),
                    va='top',
                    color=ge.blue)

    if len(curves['constricted_mean']) > 0:
        # constricted vs dilated --- raw evoked response
        fig2, ax = ge.figure(figsize=(1.5, 1.5), right=6)
        ge.plot(curves['angles'],
                curves['all'],
                label='all',
                color='grey',
                ax=ax,
                no_set=True,
                lw=2,
                alpha=.5)
        ge.plot(curves['angles'],
                curves['constricted_mean'],
                color=ge.green,
                ms=4,
                m='o',
                ax=ax,
                lw=2,
                label='constricted',
                no_set=True)
        ge.plot(curves['angles'],
                curves['dilated_mean'],
                color=ge.purple,
                ms=4,
                m='o',
                ax=ax,
                lw=2,
                label='dilated',
                no_set=True)
        ge.legend(ax, ncol=3, loc=(.1, 1.))
        ge.set_plot(ax,
                    xlabel='angle ($^{o}$) w.r.t. pref. orient.',
                    ylabel='evoked resp, ($\delta$ dF/F)   ',
                    xticks=[0, 90, 180, 270])

        if (full_resp is not None) and ('speed_level'
                                        in full_resp) and ('pupil_level'
                                                           in full_resp):
            inset2 = ge.inset(fig2, [.8, .5, .16, .28])
            ge.scatter(full_resp['pupil_level'][full_resp['dilated_cond']],
                       full_resp['speed_level'][full_resp['dilated_cond']],
                       ax=inset2,
                       no_set=True,
                       color=ge.purple)
            ge.scatter(full_resp['pupil_level'][full_resp['constricted_cond']],
                       full_resp['speed_level'][full_resp['constricted_cond']],
                       ax=inset2,
                       no_set=True,
                       color=ge.green)
            ge.annotate(ax,
                        'n=%i cells\n' % len(np.unique(full_resp['roi'])),
                        (0., 1.),
                        ha='right')
            ge.set_plot(inset2,
                        xlabel='pupil size (mm)',
                        ylabel='run. speed (cm/s)     ',
                        ylim=inset.get_ylim(),
                        title='episodes (n=%i)   ' % full_resp['Neps'])
            ge.annotate(
                inset2,
                'n=%i' %
                (np.sum(full_resp['constricted_cond']) / full_resp['Ncells']),
                (0., 1.),
                va='top',
                color=ge.green)
            ge.annotate(
                inset2,
                '\nn=%i' %
                (np.sum(full_resp['dilated_cond']) / full_resp['Ncells']),
                (0., 1.),
                va='top',
                color=ge.purple)
    else:
        fig2 = None

    return fig, fig2