def model_residual(images,
                   cnm,
                   ssub_B,
                   frames=[],
                   discard_bad_components=True):
    dims = images.shape[1:]
    if len(frames) == 0:
        frames = range(images.shape[0])
    T = images.shape[0]

    components = range(cnm.estimates.A.shape[1])
    if discard_bad_components:
        components = cnm.estimates.idx_components
    # Y_res = Y - AC - B, where B = b0 + W(Y-AC-b0)
    AC = cnm.estimates.A[:, components].dot(
        cnm.estimates.C[components, :][:, frames])
    AC_ds = downscale(AC.reshape(dims + (-1, ), order='F'),
                      (ssub_B, ssub_B, 1))

    W = cnm.estimates.W
    if type(W) == dict:
        W = csr_matrix((W['data'], W['indices'], W['indptr']),
                       shape=W['shape'])

    b0_ds = downscale(cnm.estimates.b0.reshape(dims, order='F'),
                      (ssub_B, ssub_B))
    ds_dims = AC_ds.shape
    b0_ds_rep = np.tile(b0_ds, (T, 1, 1)).transpose((1, 2, 0))
    images_ds = downscale(images, (1, ssub_B, ssub_B)).transpose((1, 2, 0))
    B = b0_ds_rep + W.dot((images_ds - AC_ds - b0_ds_rep).reshape(
        (W.shape[0], T), order='F')).reshape(ds_dims, order='F')
    Y_res = images_ds - AC_ds - B

    return Y_res, B
Beispiel #2
0
def create_video(row, time_cropping, session_wise = False):

    '''
    This fuction creates a complete video with raw movie (motion corrected), source extracted cells and source extraction + background.
    :param row: pandas dataframe containing the desired processing information to create the video. It can use the session_wise or trial_wise video.
    :return:
    '''

    if session_wise:
        input_mmap_file_path = eval(row.loc['alignment_output'])['main']
    else:
        input_mmap_file_path = eval(row.loc['motion_correction_output'])['main']

    #load the mmap file
    Yr, dims, T = cm.load_memmap(input_mmap_file_path)
    logging.debug(f'{row.name} Loaded movie. dims = {dims}, T = {T}.')
    #create a caiman movie with the mmap file
    images = Yr.T.reshape((T,) + dims, order='F')
    images = cm.movie(images)

    #load source extraction result
    output = eval(row.loc['source_extraction_output'])
    cnm_file_path = output['main']
    cnm = load_CNMF(db.get_file(cnm_file_path))

    #estimate the background from the extraction
    W, b0 = cm.source_extraction.cnmf.initialization.compute_W(Yr, cnm.estimates.A.toarray(), cnm.estimates.C,
                                                               cnm.estimates.dims, 1.4 * 5, ssub=2)
    cnm.estimates.W = W
    cnm.estimates.b0 = b0
    # this part could be use with the lastest caiman version
    # movie_dir = '/home/sebastian/Documents/Melisa/calcium_imaging_analysis/data/processed/movies/'
    # file_name = db.create_file_name(5,row.name)
    # cnm.estimates.play_movie(cnm.estimates, images, movie_name= movie_dir + file_name + '.avi')

    frame_range = slice(None, None, None)
    # create a movie with the model : estimated A and C matrix
    Y_rec = cnm.estimates.A.dot(cnm.estimates.C[:, frame_range])
    Y_rec = Y_rec.reshape(dims + (-1,), order='F')
    Y_rec = Y_rec.transpose([2, 0, 1])
    # convert the variable to a caiman movie type
    Y_rec = cm.movie(Y_rec)

    ## this part of the function is a copy from a caiman version
    ssub_B = int(round(np.sqrt(np.prod(dims) / W.shape[0])))
    B = images[frame_range].reshape((-1, np.prod(dims)), order='F').T - \
        cnm.estimates.A.dot(cnm.estimates.C[:, frame_range])
    if ssub_B == 1:
        B = b0[:, None] + W.dot(B - b0[:, None])
    else:
        B = b0[:, None] + (np.repeat(np.repeat(W.dot(
            downscale(B.reshape(dims + (B.shape[-1],), order='F'),
                      (ssub_B, ssub_B, 1)).reshape((-1, B.shape[-1]), order='F') -
            downscale(b0.reshape(dims, order='F'),
                      (ssub_B, ssub_B)).reshape((-1, 1), order='F'))
            .reshape(
            ((dims[0] - 1) // ssub_B + 1, (dims[1] - 1) // ssub_B + 1, -1), order='F'),
            ssub_B, 0), ssub_B, 1)[:dims[0], :dims[1]].reshape(
            (-1, B.shape[-1]), order='F'))
    B = B.reshape(dims + (-1,), order='F').transpose([2, 0, 1])

    Y_rec_2 = Y_rec + B
    Y_res = images[frame_range] - Y_rec - B

    images_np = np.zeros((time_cropping[1]-time_cropping[0],images.shape[1],images.shape[2]))
    images_np = images[time_cropping[0]:time_cropping[1],:,:]
    images_np = images_np / np.max(images_np)
    images_np = cm.movie(images_np)

    Y_rec_np = np.zeros((time_cropping[1]-time_cropping[0],images.shape[1],images.shape[2]))
    Y_rec_np = Y_rec[time_cropping[0]:time_cropping[1],:,:]
    Y_rec_np = Y_rec_np / np.max(Y_rec_np)
    Y_rec_np = cm.movie(Y_rec_np)

    Y_res_np = np.zeros((time_cropping[1]-time_cropping[0],images.shape[1],images.shape[2]))
    Y_res_np = Y_res[time_cropping[0]:time_cropping[1],:,:]
    Y_res_np = Y_res_np / np.max(Y_res_np)
    Y_res_np = cm.movie(Y_res_np)

    B_np = np.zeros((time_cropping[1]-time_cropping[0],images.shape[1],images.shape[2]))
    B_np = B[time_cropping[0]:time_cropping[1],:,:]
    B_np = B_np / np.max(B_np)
    B_np = cm.movie(B_np)

    mov1 = cm.concatenate((images_np, Y_rec_np), axis=2)

    mov2 = cm.concatenate((B_np, Y_res_np), axis=2)

    mov = cm.concatenate((mov1, mov2), axis=1)

    figure_path = '/home/sebastian/Documents/Melisa/calcium_imaging_analysis/data/interim/movies/'
    figure_name = db.create_file_name(5,row.name)
    #mov.save(figure_path+figure_name+'.tif')
    mov.save(figure_path+figure_name+'_'+f'{time_cropping[0]}' + '_' + f'{time_cropping[1]}'+'.tif')

    return
Beispiel #3
0
def play_movie(estimates, imgs, q_max=99.75, q_min=2, gain_res=1,
                   magnification=1, include_bck=True,
                   frame_range=slice(None, None, None),
                   bpx=0, thr=0., save_movie=False,
                   movie_name='results_movie.avi'):

    dims = imgs.shape[1:]
    if 'movie' not in str(type(imgs)):
        imgs = cm.movie(imgs)
    Y_rec = estimates.A.dot(estimates.C[:, frame_range])
    Y_rec = Y_rec.reshape(dims + (-1,), order='F')
    Y_rec = Y_rec.transpose([2, 0, 1])

    if estimates.W is not None:
        ssub_B = int(round(np.sqrt(np.prod(dims) / estimates.W.shape[0])))
        B = imgs[frame_range].reshape((-1, np.prod(dims)), order='F').T - \
            estimates.A.dot(estimates.C[:, frame_range])
        if ssub_B == 1:
            B = estimates.b0[:, None] + estimates.W.dot(B - estimates.b0[:, None])
        else:
            B = estimates.b0[:, None] + (np.repeat(np.repeat(estimates.W.dot(
                downscale(B.reshape(dims + (B.shape[-1],), order='F'),
                          (ssub_B, ssub_B, 1)).reshape((-1, B.shape[-1]), order='F') -
                downscale(estimates.b0.reshape(dims, order='F'),
                          (ssub_B, ssub_B)).reshape((-1, 1), order='F'))
                    .reshape(((dims[0] - 1) // ssub_B + 1, (dims[1] - 1) // ssub_B + 1, -1), order='F'),
                    ssub_B, 0), ssub_B, 1)[:dims[0], :dims[1]].reshape((-1, B.shape[-1]), order='F'))
        B = B.reshape(dims + (-1,), order='F').transpose([2, 0, 1])
    elif estimates.b is not None and estimates.f is not None:
        B = estimates.b.dot(estimates.f[:, frame_range])
        if 'matrix' in str(type(B)):
            B = B.toarray()
        B = B.reshape(dims + (-1,), order='F').transpose([2, 0, 1])
    else:
        B = np.zeros_like(Y_rec)
    if bpx > 0:
        B = B[:, bpx:-bpx, bpx:-bpx]
        Y_rec = Y_rec[:, bpx:-bpx, bpx:-bpx]
        imgs = imgs[:, bpx:-bpx, bpx:-bpx]

    Y_res = imgs[frame_range] - Y_rec - B

    mov = cm.concatenate((imgs[frame_range] - (not include_bck) * B, Y_rec,
                            Y_rec + include_bck * B, Y_res * gain_res), axis=2)

    if thr > 0:
        if save_movie:
            import cv2
            #fourcc = cv2.VideoWriter_fourcc('8', 'B', 'P', 'S')
            #fourcc = cv2.VideoWriter_fourcc(*'XVID')
            fourcc = cv2.VideoWriter_fourcc(*'MP4V')
            out = cv2.VideoWriter(movie_name, fourcc, 30.0,
                                  tuple([int(magnification*s) for s in mov.shape[1:][::-1]]))
        contours = []
        for a in estimates.A.T.toarray():
            a = a.reshape(dims, order='F')
            if bpx > 0:
                a = a[bpx:-bpx, bpx:-bpx]
            if magnification != 1:
                a = cv2.resize(a, None, fx=magnification, fy=magnification,
                               interpolation=cv2.INTER_LINEAR)
            ret, thresh = cv2.threshold(a, thr * np.max(a), 1., 0)
            contour, hierarchy = cv2.findContours(
                thresh.astype('uint8'), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            contours.append(contour)
            contours.append(list([c + np.array([[a.shape[1], 0]]) for c in contour]))
            contours.append(list([c + np.array([[2 * a.shape[1], 0]]) for c in contour]))

        maxmov = np.nanpercentile(mov[0:10], q_max) if q_max < 100 else np.nanmax(mov)
        minmov = np.nanpercentile(mov[0:10], q_min) if q_min > 0 else np.nanmin(mov)
        for frame in mov:
            if magnification != 1:
                frame = cv2.resize(frame, None, fx=magnification, fy=magnification,
                                   interpolation=cv2.INTER_LINEAR)
            frame = np.clip((frame - minmov) * 255. / (maxmov - minmov), 0, 255)
            frame = np.repeat(frame[..., None], 3, 2)
            for contour in contours:
                cv2.drawContours(frame, contour, -1, (0, 255, 255), 1)
            cv2.imshow('frame', frame.astype('uint8'))
            if save_movie:
                out.write(frame.astype('uint8'))
            if cv2.waitKey(30) & 0xFF == ord('q'):
                break
        if save_movie:
            out.release()
        cv2.destroyAllWindows()
        cv2.destroyAllWindows()
    else:
        mov.play(q_min=q_min, q_max=q_max, magnification=magnification,
                     save_movie=save_movie, movie_name=movie_name)

    return
Beispiel #4
0
    def __fit_next_frame(self, frame, t, model_LN=None, out=None):
        ssub_B = self.params.get('init', 'ssub_B') * self.params.get(
            'init', 'ssub')
        d1, d2 = self.params.get('data', 'dims')
        max_shifts_online = self.params.get('online', 'max_shifts_online')

        if model_LN is not None:
            if self.params.get('ring_CNN', 'remove_activity'):
                activity = self.estimates.Ab[:, :self.N].dot(
                    self.estimates.C_on[:self.N,
                                        t - 1]).reshape(self.params.get(
                                            'data', 'dims'),
                                                        order='F')
                if self.params.get('online', 'normalize'):
                    activity *= self.img_norm
            else:
                activity = 0.
                # frame = frame.astype(np.float32) - activity
            frame = frame - np.squeeze(
                model_LN.predict(
                    np.expand_dims(
                        np.expand_dims(frame.astype(np.float32) - activity, 0),
                        -1)))
            frame = np.maximum(frame, 0)

        t_frame_start = time.time()
        if np.isnan(np.sum(frame)):
            raise Exception('Current frame contains NaN')

        frame_ = frame.copy().astype(np.float32)
        if self.params.get('online', 'ds_factor') > 1:
            frame_ = cv2.resize(frame_, self.img_norm.shape[::-1])

        if self.params.get('online', 'normalize'):
            frame_ -= self.img_min  # make data non-negative

        if self.params.get('online', 'motion_correct'):
            templ = self.estimates.Ab.dot(
                np.median(self.estimates.C_on[:self.M, t - 51:t - 1],
                          1)).reshape(self.params.get('data', 'dims'),
                                      order='F')  #*self.img_norm
            if self.is1p and self.estimates.W is not None:
                if ssub_B == 1:
                    B = self.estimates.W.dot((frame_ - templ).flatten(
                        order='F') - self.estimates.b0) + self.estimates.b0
                    B = B.reshape(self.params.get('data', 'dims'), order='F')
                else:
                    b0 = self.estimates.b0.reshape((d1, d2),
                                                   order='F')  #*self.img_norm
                    bc2 = initialization.downscale(
                        frame_ - templ - b0,
                        (ssub_B, ssub_B)).flatten(order='F')
                    Wb = self.estimates.W.dot(bc2).reshape(
                        ((d1 - 1) // ssub_B + 1, (d2 - 1) // ssub_B + 1),
                        order='F')
                    B = b0 + np.repeat(np.repeat(Wb, ssub_B, 0), ssub_B,
                                       1)[:d1, :d2]
                templ += B
            if self.params.get('online', 'normalize'):
                templ *= self.img_norm
            if self.is1p:
                templ = high_pass_filter_space(templ,
                                               self.params.motion['gSig_filt'])
            if self.params.get('motion', 'pw_rigid'):
                frame_cor, shift, _, xy_grid = tile_and_correct(
                    frame_,
                    templ,
                    self.params.motion['strides'],
                    self.params.motion['overlaps'],
                    self.params.motion['max_shifts'],
                    newoverlaps=None,
                    newstrides=None,
                    upsample_factor_grid=4,
                    upsample_factor_fft=10,
                    show_movie=False,
                    max_deviation_rigid=self.params.
                    motion['max_deviation_rigid'],
                    add_to_movie=0,
                    shifts_opencv=True,
                    gSig_filt=None,
                    use_cuda=False,
                    border_nan='copy')
            else:
                if self.is1p:
                    frame_orig = frame_.copy()
                    frame_ = high_pass_filter_space(
                        frame_, self.params.motion['gSig_filt'])
                frame_cor, shift = motion_correct_iteration_fast(
                    frame_, templ, max_shifts_online, max_shifts_online)
                if self.is1p:
                    M = np.float32([[1, 0, shift[1]], [0, 1, shift[0]]])
                    frame_cor = cv2.warpAffine(frame_orig,
                                               M,
                                               frame_.shape[::-1],
                                               flags=cv2.INTER_CUBIC,
                                               borderMode=cv2.BORDER_REFLECT)

            self.estimates.shifts.append(shift)
        else:
            templ = None
            frame_cor = frame_

        self.current_frame_cor = frame_cor

        if self.params.get('online', 'normalize'):
            frame_cor = frame_cor / self.img_norm
        self.fit_next(t, frame_cor.reshape(-1, order='F'))

        if self.fp_detector.method is not None:
            self.__reject_fp_comps((d1, d2), max_bright=frame_.max())
Y_rec = Y_rec.transpose([2, 0, 1])
Y_rec = cm.movie(Y_rec)

#mov = cm.concatenate((images, Y_rec), axis=2)
#mov.play()

ssub_B = int(round(np.sqrt(np.prod(dims) / W.shape[0])))
B = images[frame_range].reshape((-1, np.prod(dims)), order='F').T - \
    cnm.estimates.A.dot(cnm.estimates.C[:, frame_range])
if ssub_B == 1:
    B = b0[:, None] + W.dot(B - b0[:, None])
else:
    B = b0[:, None] + (np.repeat(
        np.repeat(
            W.dot(
                downscale(B.reshape(dims + (B.shape[-1], ), order='F'), (
                    ssub_B, ssub_B, 1)).reshape((-1, B.shape[-1]), order='F') -
                downscale(b0.reshape(dims, order='F'), (
                    ssub_B, ssub_B)).reshape((-1, 1), order='F')).reshape(
                        ((dims[0] - 1) // ssub_B + 1,
                         (dims[1] - 1) // ssub_B + 1, -1),
                        order='F'), ssub_B, 0), ssub_B,
        1)[:dims[0], :dims[1]].reshape((-1, B.shape[-1]), order='F'))
B = B.reshape(dims + (-1, ), order='F').transpose([2, 0, 1])

Y_res = images[frame_range] - Y_rec - B

mov = cm.concatenate((images, Y_rec), axis=2)

mov = cm.concatenate((images, images), axis=2)

#%% Select the row to be source extracted using current versions of cropping and motion correction