예제 #1
0
    def __init__(self,
                 data,
                 X=None,
                 quantity='CaImaging',
                 subquantity='Fluorescence',
                 n_components=-1):
        """
        input has convention: (Nfeatures, Nsamples) , e.g. (Ncells, Ntimesamples)
        """

        # initialize quantity
        if (X is None) and (quantity == 'CaImaging'):
            X = Ca_imaging_tools.compute_CaImaging_trace(
                data, subquantity, range(data.iscell.sum()))
            self.t = data.Neuropil.timestamps[:]

        self.Nfeatures, self.Nsamples = X.shape  # HERE !!

        self.means, self.stds = np.mean(X, axis=1), np.std(X, axis=1)

        if n_components < 0:
            n_components = self.Nfeatures
        self.components = 1 + np.arange(n_components)

        # initialize PCA from scikit-learn
        super().__init__(n_components=n_components)

        # rescale
        self.X = X.T / self.stds - self.means

        # perform PCA
        self.fit(self.X)

        # get the component projections
        self.Xinv = self.fit_transform(self.X)
예제 #2
0
 def add_CaImagingSum(self,
                      tlim,
                      ax,
                      fig_fraction_start=0.,
                      fig_fraction=1.,
                      color='green',
                      quantity='CaImaging',
                      subquantity='Fluorescence',
                      subsampling=1,
                      name='Sum [Ca]'):
     i1 = convert_time_to_index(tlim[0], self.Neuropil, axis=1)
     i2 = convert_time_to_index(tlim[1], self.Neuropil, axis=1)
     tt = np.array(self.Neuropil.timestamps[:])[np.arange(
         i1, i2)][::subsampling]
     y = compute_CaImaging_trace(self, subquantity,
                                 np.arange(np.sum(self.iscell))).sum(
                                     axis=0)[np.arange(i1,
                                                       i2)][::subsampling]
     ax.plot(tt, (y - y.min()) / (y.max() - y.min()) * fig_fraction +
             fig_fraction_start,
             color=color)
     ax.annotate(name, (tlim[0], fig_fraction / 2. + fig_fraction_start),
                 color=color,
                 fontsize=8,
                 ha='right')
예제 #3
0
    def add_CaImaging(self,
                      tlim,
                      ax,
                      fig_fraction_start=0.,
                      fig_fraction=1.,
                      color='green',
                      quantity='CaImaging',
                      subquantity='Fluorescence',
                      roiIndices='all',
                      vicinity_factor=1,
                      subsampling=1,
                      name='[Ca] imaging'):
        if (type(roiIndices) == str) and roiIndices == 'all':
            roiIndices = np.arange(np.sum(self.iscell))
        if color == 'tab':
            COLORS = [plt.cm.tab10(n % 10) for n in range(len(roiIndices))]
        else:
            COLORS = [str(color) for n in range(len(roiIndices))]

        dF = compute_CaImaging_trace(self, subquantity,
                                     roiIndices)  # validROI indices inside !!
        i1 = convert_time_to_index(tlim[0], self.Neuropil, axis=1)
        i2 = convert_time_to_index(tlim[1], self.Neuropil, axis=1)
        tt = np.array(self.Neuropil.timestamps[:])[np.arange(
            i1, i2)][::subsampling]
        if vicinity_factor > 1:
            ymax_factor = fig_fraction * (1 - 1. / vicinity_factor)
        else:
            ymax_factor = fig_fraction / len(roiIndices)
        for n, ir in zip(range(len(roiIndices))[::-1], roiIndices[::-1]):
            y = dF[n, np.arange(i1, i2)][::subsampling]
            ypos = n * fig_fraction / len(
                roiIndices) / vicinity_factor + fig_fraction_start
            if subquantity in ['dF/F', 'dFoF']:
                ax.plot(tt, y / 2. * ymax_factor + ypos, color=COLORS[n], lw=1)
                ax.plot(tlim[0] * np.ones(2),
                        np.arange(2) / 2. * ymax_factor + ypos,
                        color=COLORS[n],
                        lw=1)
            elif y.max() > y.min():
                rescaled_y = (y - y.min()) / (y.max() - y.min())
                ax.plot(tt,
                        rescaled_y * ymax_factor + ypos,
                        color=COLORS[n],
                        lw=1)

            ax.annotate('ROI#%i' % (ir + 1), (tlim[1], ypos),
                        color=COLORS[n],
                        fontsize=8)
        if subquantity in ['dF/F', 'dFoF']:
            ax.annotate('1$\Delta$F/F', (tlim[0], fig_fraction_start),
                        ha='right',
                        rotation=90,
                        color='k',
                        fontsize=9)
        ax.annotate(name, (tlim[0], fig_fraction / 2. + fig_fraction_start),
                    color=color,
                    fontsize=8,
                    ha='right')
예제 #4
0
def ROI_analysis(FullData,
                 roiIndex=0,
                 subquantity='Deconvolved',
                 metrics='mean',
                 iprotocol=0,
                 verbose=False):

    dF = compute_CaImaging_trace(FullData, subquantity, [roiIndex]).sum(axis=0)
    t = FullData.Fluorescence.timestamps[:]
    Nall = FullData.nwbfile.stimulus['time_start_realigned'].num_samples

    # compute protcol cond
    Pcond = FullData.get_protocol_cond(iprotocol)[:Nall]

    # do REVERSE CORRELATION analysis
    full_img, cum_weight = np.zeros(FullData.visual_stim.screen['resolution'],
                                    dtype=float).T, 0

    for i in np.arange(Nall)[Pcond]:
        tstart = FullData.nwbfile.stimulus['time_start_realigned'].data[i]
        tstop = FullData.nwbfile.stimulus['time_stop_realigned'].data[i]
        cond = (t > tstart) & (t < tstop)
        weight = np.inf
        if metrics == 'mean':
            weight = np.mean(dF[cond])
        elif np.sum(cond) > 0 and (metrics == 'max'):
            weight = np.max(dF[cond])
        if np.isfinite(weight):
            full_img += weight * 2 * (FullData.visual_stim.get_image(i) - .5)
            cum_weight += weight
        else:
            print(
                'For episode #%i in t=(%.1f, %.1f), pb in estimating the weight !'
                % (i, tstart, tstop))

    full_img /= cum_weight

    # GAUSSIAN FILTERING
    # img = gaussian_filter(full_img, (10,10))

    fig, ax = ge.figure(figsize=(1.7, 1.7))

    ax.imshow(full_img,
              cmap=plt.cm.PiYG,
              interpolation=None,
              origin='lower',
              aspect='equal',
              extent=[
                  FullData.visual_stim.x.min(),
                  FullData.visual_stim.x.max(),
                  FullData.visual_stim.z.min(),
                  FullData.visual_stim.z.max()
              ],
              vmin=-np.max(np.abs(full_img)),
              vmax=np.max(np.abs(full_img)))

    ge.set_plot(ax,
                xlabel='x ($^{o}$)',
                ylabel='y ($^{o}$)',
                title='roi #%i' % (roiIndex + 1))

    return fig
예제 #5
0
def build_episodes(
        self,
        parent=None,
        protocol_id=0,
        quantity='Photodiode-Signal',
        prestim_duration=None,  # to force the prestim window otherwise, half the value in between episodes
        dt_sampling=1,  # ms
        interpolation='linear',
        baseline_substraction=False,
        verbose=True):

    EPISODES = {'dt_sampling': dt_sampling, 'quantity': quantity, 'resp': []}

    parent = (parent if parent is not None else self)

    # choosing protocol (if multiprotocol)
    if ('protocol_id' in parent.nwbfile.stimulus) and (len(
            np.unique(parent.nwbfile.stimulus['protocol_id'].data[:])) > 1):
        Pcond = (parent.nwbfile.stimulus['protocol_id'].data[:] == protocol_id)
    else:
        Pcond = np.ones(parent.nwbfile.stimulus['time_start'].data.shape[0],
                        dtype=bool)
    # limiting to available episodes
    Pcond[np.arange(len(Pcond)) >=
          parent.nwbfile.stimulus['time_start_realigned'].num_samples] = False

    if verbose:
        print(
            'Number of episodes over the whole recording: %i/%i (with protocol condition)'
            % (np.sum(Pcond), len(Pcond)))

    # find the parameter(s) varied within that specific protocol
    EPISODES['varied_parameters'] = {}
    for key in parent.nwbfile.stimulus.keys():
        if key not in [
                'frame_run_type', 'index', 'protocol_id', 'time_duration',
                'time_start', 'time_start_realigned', 'time_stop',
                'time_stop_realigned'
        ]:
            unique = np.unique(parent.nwbfile.stimulus[key].data[Pcond])
            if len(unique) > 1:
                EPISODES['varied_parameters'][key] = unique
    # for the parent class
    self.varied_parameters = EPISODES[
        'varied_parameters']  # adding this as a shortcut
    self.Pcond = Pcond  # protocol condition

    # new sampling
    if (prestim_duration is None) and ('interstim' in parent.nwbfile.stimulus):
        prestim_duration = np.min(parent.nwbfile.stimulus['interstim'].data[:]
                                  ) / 2.  # half the stim duration
    elif prestim_duration is None:
        prestim_duration = 1
    ipre = int(prestim_duration / dt_sampling * 1e3)

    duration = parent.nwbfile.stimulus['time_stop'].data[Pcond][
        0] - parent.nwbfile.stimulus['time_start'].data[Pcond][0]
    idur = int(duration / dt_sampling / 1e-3)
    EPISODES['t'] = np.arange(-ipre + 1, idur + ipre - 1) * dt_sampling * 1e-3

    if quantity == 'CaImaging':
        tfull = parent.Neuropil.timestamps[:]
        valfull = compute_CaImaging_trace(
            parent, parent.CaImaging_key,
            parent.roiIndices).sum(axis=0)  # valid ROI indices inside
    else:
        try:
            tfull = np.arange(
                parent.nwbfile.acquisition[quantity].data.shape[0]
            ) / parent.nwbfile.acquisition[quantity].rate
            valfull = parent.nwbfile.acquisition[quantity].data[:]
        except BaseException as be:
            print(be)
            print(30 * '-')
            print(quantity, 'not recognized')
            print(30 * '-')

    # adding the parameters
    for key in parent.nwbfile.stimulus.keys():
        EPISODES[key] = []

    for iEp in np.arange(
            parent.nwbfile.stimulus['time_start'].num_samples)[Pcond]:
        tstart = parent.nwbfile.stimulus['time_start_realigned'].data[iEp]
        tstop = parent.nwbfile.stimulus['time_stop_realigned'].data[iEp]

        # compute time and interpolate
        cond = (tfull >= (tstart - 1.5 * prestim_duration)) & (
            tfull < (tstop + 1.5 * prestim_duration)
        )  # higher range of interpolation to avoid boundary problems
        func = interp1d(tfull[cond] - tstart,
                        valfull[cond],
                        kind=interpolation)
        try:
            if baseline_substraction:
                y = func(EPISODES['t'])
                EPISODES['resp'].append(y - np.mean(y[EPISODES['t'] < 0]))
            else:
                EPISODES['resp'].append(func(EPISODES['t']))
            for key in parent.nwbfile.stimulus.keys():
                EPISODES[key].append(parent.nwbfile.stimulus[key].data[iEp])
        except BaseException as be:
            print('----')
            print(be)
            print('Problem with episode %i between (%.2f, %.2f)s' %
                  (iEp, tstart, tstop))

    EPISODES['index_from_start'] = np.arange(len(Pcond))[Pcond]
    EPISODES['resp'] = np.array(EPISODES['resp'])
    for key in parent.nwbfile.stimulus.keys():
        EPISODES[key] = np.array(EPISODES[key])

    if verbose:
        print('[ok] episodes ready !')

    return EPISODES
예제 #6
0
def raw_data_plot(self, tzoom,
                  plot_update=True,
                  with_images=False,
                  with_roi=False,
                  with_scatter=False):

    iplot = 0
    scatter = []
    self.plot.clear()
    
    ## -------- Screen --------- ##

    if 'Photodiode-Signal' in self.nwbfile.acquisition:
        
        i1, i2 = convert_times_to_indices(*tzoom, self.nwbfile.acquisition['Photodiode-Signal'])
        if self.no_subsampling:
            isampling = np.arange(i1,i2)
        else:
            isampling = np.unique(np.linspace(i1, i2, self.settings['Npoints'], dtype=int))
        y = scale_and_position(self,self.nwbfile.acquisition['Photodiode-Signal'].data[list(isampling)], i=iplot)
        iplot+=1
        self.plot.plot(convert_index_to_time(isampling, self.nwbfile.acquisition['Photodiode-Signal']), y,
                       pen=pg.mkPen(color=self.settings['colors']['Screen']))

    ## -------- Locomotion --------- ##
    
    if 'Running-Speed' in self.nwbfile.acquisition:
        
        i1, i2 = convert_times_to_indices(*tzoom, self.nwbfile.acquisition['Running-Speed'])
        if self.no_subsampling:
            isampling = np.arange(i1+1, i2-1)
        else:
            isampling = np.unique(np.linspace(i1+1, i2-1, self.settings['Npoints'], dtype=int))
        y = scale_and_position(self,self.nwbfile.acquisition['Running-Speed'].data[list(isampling)], i=iplot)
        iplot+=1
        self.plot.plot(convert_index_to_time(isampling, self.nwbfile.acquisition['Running-Speed']), y,
                       pen=pg.mkPen(color=self.settings['colors']['Locomotion']))
            

    ## -------- FaceCamera and Pupil-Size --------- ##
    
    if 'FaceCamera' in self.nwbfile.acquisition:
        
        i0 = convert_time_to_index(self.time, self.nwbfile.acquisition['FaceCamera'])
        self.pFaceimg.setImage(self.nwbfile.acquisition['FaceCamera'].data[i0])
        if hasattr(self, 'FaceCameraFrameLevel'):
            self.plot.removeItem(self.FaceCameraFrameLevel)
        self.FaceCameraFrameLevel = self.plot.plot(self.nwbfile.acquisition['FaceCamera'].timestamps[i0]*np.ones(2),
                                                   [0, y.max()], pen=pg.mkPen(color=self.settings['colors']['Whisking']), linewidth=0.5)

    if 'Pupil' in self.nwbfile.acquisition:
        
        i0 = convert_time_to_index(self.time, self.nwbfile.acquisition['Pupil'])
        img = self.nwbfile.acquisition['Pupil'].data[i0]
        img = (img-img.min())/(img.max()-img.min())
        self.pPupilimg.setImage(255*(1-np.exp(-img/0.2)))
        if hasattr(self, 'PupilFrameLevel'):
            self.plot.removeItem(self.PupilFrameLevel)
        self.PupilFrameLevel = self.plot.plot(self.nwbfile.acquisition['Pupil'].timestamps[i0]*np.ones(2),
                                              [0, y.max()], pen=pg.mkPen(color=self.settings['colors']['Pupil']), linewidth=0.5)
        t_pupil_frame = self.nwbfile.acquisition['Pupil'].timestamps[i0]
    else:
        t_pupil_frame = None
        
    if 'Pupil' in self.nwbfile.processing:

        i1, i2 = convert_times_to_indices(*self.tzoom, self.nwbfile.processing['Pupil'].data_interfaces['cx'])

        t = self.nwbfile.processing['Pupil'].data_interfaces['sx'].timestamps[i1:i2]

        y = scale_and_position(self,
                               self.nwbfile.processing['Pupil'].data_interfaces['sx'].data[i1:i2]*\
                               self.nwbfile.processing['Pupil'].data_interfaces['sy'].data[i1:i2],
                               i=iplot)

        try:
            
            self.plot.plot(t[np.isfinite(y)], y[np.isfinite(y)], pen=pg.mkPen(color=self.settings['colors']['Pupil']))

            # adding blinking flag (a thick line at the bottom)
            if 'blinking' in self.nwbfile.processing['Pupil'].data_interfaces:
                cond = (self.nwbfile.processing['Pupil'].data_interfaces['blinking'].data[i1:i2]==1) & np.isfinit(y)
                self.plot.plot(t[cond],y[cond].min()+0*t[cond], pen=None, symbol='o',
                               symbolPen=pg.mkPen(color=self.settings['colors']['Pupil'], width=0),                                      
                               symbolBrush=pg.mkBrush(0, 0, 255, 255), symbolSize=7)
            
        except BaseException:
            pass
        
        iplot+=1

        coords = []
        if hasattr(self, 'fit'):
            self.fit.remove(self)

        if t_pupil_frame is not None:
            i0 = convert_time_to_index(t_pupil_frame, self.nwbfile.processing['Pupil'].data_interfaces['cx'])
            for key in ['cx', 'cy', 'sx', 'sy']:
                coords.append(self.nwbfile.processing['Pupil'].data_interfaces[key].data[i0]*self.FaceCamera_mm_to_pix)
            self.fit = roi.pupilROI(moveable=False,
                                    parent=self,
                                    color=(125, 0, 0),
                                    pos = roi.ellipse_props_to_ROI(coords))
            

    # ## -------- Electrophy --------- ##
    
    if ('Electrophysiological-Signal' in self.nwbfile.acquisition):
        
        i1 = convert_time_to_index(tzoom[0], self.nwbfile.acquisition['Electrophysiological-Signal'])+1
        i2 = convert_time_to_index(tzoom[1], self.nwbfile.acquisition['Electrophysiological-Signal'])-1
        if self.no_subsampling:
            isampling = np.arange(i1,i2)
        else:
            isampling = np.unique(np.linspace(i1, i2, self.settings['Npoints'], dtype=int))
        y = scale_and_position(self,self.nwbfile.acquisition['Electrophysiological-Signal'].data[list(isampling)], i=iplot)
        iplot+=1
        self.plot.plot(convert_index_to_time(isampling, self.nwbfile.acquisition['Electrophysiological-Signal']), y,
                       pen=pg.mkPen(color=self.settings['colors']['Electrophy']))


    # ## -------- Calcium --------- ##
    
    # if (self.time==0) and ('ophys' in self.nwbfile.processing):
    if ('ophys' in self.nwbfile.processing):
        self.pCaimg.setImage(self.nwbfile.processing['ophys'].data_interfaces['Backgrounds_0'].images[self.CaImaging_bg_key][:]) # plotting the mean image
        
    if 'CaImaging-TimeSeries' in self.nwbfile.acquisition:
        i0 = convert_time_to_index(self.time, self.nwbfile.acquisition['CaImaging-TimeSeries'])
        # self.pCaimg.setImage(self.nwbfile.acquisition['CaImaging-TimeSeries'].data[i0,:,:]) # REMOVE NOW, MAYBE REINTRODUCE
        if hasattr(self, 'CaFrameLevel'):
            self.plot.removeItem(self.CaFrameLevel)
        self.CaFrameLevel = self.plot.plot(self.nwbfile.acquisition['CaImaging-TimeSeries'].timestamps[i0]*np.ones(2), [0, y.max()],
                                           pen=pg.mkPen(color=self.settings['colors']['CaImaging']), linewidth=0.5)
        
    if ('ophys' in self.nwbfile.processing) and with_roi:
        if hasattr(self, 'ROIscatter'):
            self.pCa.removeItem(self.ROIscatter)
        self.ROIscatter = pg.ScatterPlotItem()
        X, Y = [], []
        for ir in self.roiIndices:
            indices = np.arange(self.pixel_masks_index[ir], self.pixel_masks_index[ir+1])
            X += [self.pixel_masks[ii][1] for ii in indices]
            Y += [self.pixel_masks[ii][0] for ii in indices]
        self.ROIscatter.setData(X, Y, size=1, brush=pg.mkBrush(0,255,0))
        self.pCa.addItem(self.ROIscatter)

    if ('ophys' in self.nwbfile.processing) and (self.roiIndices is not None):
        i1 = convert_time_to_index(self.tzoom[0], self.Neuropil, axis=1)
        i2 = convert_time_to_index(self.tzoom[1], self.Neuropil, axis=1)
        if self.no_subsampling:
            isampling = np.arange(i1,i2)
        else:
            isampling = np.unique(np.linspace(i1, i2, self.settings['Npoints'], dtype=int))
        tt = np.array(self.Neuropil.timestamps[:])[isampling]

        if self.roiPick.text()=='sum' or (len(self.roiIndices)==1):
            y = scale_and_position(self, compute_CaImaging_trace(self, self.CaImaging_key, self.roiIndices).sum(axis=0)[isampling], i=iplot) # valid ROIs inside
            self.plot.plot(tt, y, pen=pg.mkPen(color=(0,250,0), linewidth=1))
            # if self.CaImaging_key=='Fluorescence':
            #     nrnp = scale_and_position(self, y, value=self.Neuropil.data[:,isampling][self.validROI_indices[self.roiIndices],:].sum(axis=0), i=iplot)
            #     self.plot.plot(tt, nrnp, pen=pg.mkPen(color=(255,255,255), linewidth=0.2))
        else:
            for n, ir in enumerate(self.roiIndices):
                y = scale_and_position(self, compute_CaImaging_trace(self, self.CaImaging_key, [ir]).sum(axis=0)[isampling], i=iplot)+n/2.
                self.plot.plot(tt, y, pen=pg.mkPen(color=np.random.randint(255, size=3), linewidth=1))
                # if self.CaImaging_key=='Fluorescence':
                #     nrnp = scale_and_position(self, y, value=self.Neuropil.data[:,isampling][self.validROI_indices[ir],:], i=iplot)+n/2.
                #     self.plot.plot(tt, nrnp, pen=pg.mkPen(color=(255,255,255), linewidth=0.2))
        iplot += 1

    # ## -------- Visual Stimulation --------- ##

    if self.visual_stim is not None:
        
        icond = np.argwhere((self.nwbfile.stimulus['time_start_realigned'].data[:]<=self.time) & \
                            (self.nwbfile.stimulus['time_stop_realigned'].data[:]>=self.time)).flatten()
        if len(icond)>0:
            self.pScreenimg.setImage(255*self.visual_stim.get_image(icond[0],
                                     self.time-self.nwbfile.stimulus['time_start_realigned'].data[icond[0]]))
        elif self.time<=self.nwbfile.stimulus['time_start_realigned'].data[0]: # PRE-STIM
            self.pScreenimg.setImage(255*self.visual_stim.get_prestim_image())
        elif self.time>=self.nwbfile.stimulus['time_stop_realigned'].data[-1]: # POST-STIM
            self.pScreenimg.setImage(255*self.visual_stim.get_poststim_image())
        else: # INTER-STIM
            self.pScreenimg.setImage(255*self.visual_stim.get_interstim_image())
            
        self.pScreenimg.setLevels([0,255])

    if (self.visual_stim is not None) and ('time_start_realigned' in self.nwbfile.stimulus) and ('time_stop_realigned' in self.nwbfile.stimulus):
        # if visual-stim we highlight the stim periods
        icond = np.argwhere((self.nwbfile.stimulus['time_start_realigned'].data[:]>tzoom[0]-10) & \
                            (self.nwbfile.stimulus['time_stop_realigned'].data[:]<tzoom[1]+10)).flatten()

        if hasattr(self, 'StimFill') and self.StimFill is not None:
            for x in self.StimFill:
                self.plot.removeItem(x)

        X, Y = [], []
        if len(icond)>0:
            self.StimFill = []
            # for i in icond:
            for i in range(max([0,icond[0]-1]),
                           min([icond[-1]+1,self.nwbfile.stimulus['time_stop_realigned'].data.shape[0]-1])):
                t0 = self.nwbfile.stimulus['time_start_realigned'].data[i]
                t1 = self.nwbfile.stimulus['time_stop_realigned'].data[i]
                self.StimFill.append(self.plot.plot([t0, t1], [0, 0],
                                fillLevel=y.max(), brush=(150,150,150,80)))

    # if with_scatter and hasattr(self, 'scatter'):
    #     self.plot.removeItem(self.scatter)
    #     self.scatter.setData([s[0] for s in scatter],
    #                          [s[1] for s in scatter],
    #                          size=10, brush=pg.mkBrush(255,255,255))
    #     self.plot.addItem(self.scatter)

    self.plot.setRange(xRange=tzoom, yRange=[0,y.max()], padding=0.0)
    self.frameSlider.setValue(int(self.settings['Npoints']*(self.time-tzoom[0])/(tzoom[1]-tzoom[0])))
    
    self.plot.show()
예제 #7
0
def roi_analysis_fig(data, roiIndex=0):

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

    plt.style.use('ggplot')
    fig, AX = plt.subplots(2 + len(MODALITIES),
                           4,
                           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.98,
                        wspace=.5,
                        hspace=.5)
    if len(MODALITIES) == 0:
        AX = [AX]
    AX[0][0].annotate(' ROI#%i' % (roiIndex + 1), (0.4, 0.5),
                      xycoords='axes fraction',
                      weight='bold',
                      fontsize=11,
                      ha='center')
    AX[0][0].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)

    dFoF = compute_CaImaging_trace(data, 'dF/F', [roiIndex]).sum(
        axis=0)  # valid ROI indices inside

    index = np.arange(len(data.iscell))[data.iscell][roiIndex]
    AX[0][3].hist(data.Fluorescence.data[index, :],
                  bins=30,
                  weights=100 * np.ones(len(dFoF)) / len(dFoF),
                  color=plt.cm.tab10(1))
    AX[0][3].set_xlabel('Fluo. (a.u.)', fontsize=10)
    AX[1][0].hist(dFoF, bins=30, weights=100 * np.ones(len(dFoF)) / len(dFoF))
    AX[1][0].set_xlabel('dF/F', fontsize=10)
    AX[1][1].hist(dFoF,
                  log=True,
                  bins=30,
                  weights=100 * np.ones(len(dFoF)) / len(dFoF))
    AX[1][1].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=dFoF,
                                        t_q1=data.Neuropil.timestamps[:],
                                        tmax=180)
    AX[1][2].plot(ts / 60., CC, '-', lw=2)
    AX[1][2].set_xlabel('time (min)', fontsize=10)
    AX[1][2].set_ylabel('auto correl.', fontsize=10)

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

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

        AX[2 + i][0].set_title(mod + 40 * ' ',
                               fontsize=10,
                               color=plt.cm.tab10(i))

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

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

        AX[2 + i][0].errorbar(mean_q1,
                              mean_q2,
                              xerr=var_q1,
                              yerr=var_q2,
                              color=plt.cm.tab10(i))
        AX[2 + i][0].set_xlabel(unit, fontsize=10)
        AX[2 + i][0].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=dFoF,
            t_q1=data.Neuropil.timestamps[:],
            Npoints=30)

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

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

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

    return fig