예제 #1
0
def get_fig_gSig_filt_vals(cropped_file, gSig_filt_vals):
    """

    Plot original cropped frame and several versions of spatial filtering for comparison
    :param cropped_file
    :param gSig_filt_vals: array containing size of spatial filters that will be applied
    :return: figure

    """

    m = cm.load(cropped_file)
    temp = cm.motion_correction.bin_median(m)
    N = len(gSig_filt_vals)
    fig, axes = plt.subplots(int(math.ceil((N + 1) / 2)), 2)
    axes[0, 0].imshow(temp, cmap='gray')
    axes[0, 0].set_title('unfiltered')
    axes[0, 0].axis('off')
    for i in range(0, N):
        gSig_filt = gSig_filt_vals[i]
        m_filt = [
            high_pass_filter_space(m_, (gSig_filt, gSig_filt)) for m_ in m
        ]
        temp_filt = cm.motion_correction.bin_median(m_filt)
        axes.flatten()[i + 1].imshow(temp_filt, cmap='gray')
        axes.flatten()[i + 1].set_title(f'gSig_filt = {gSig_filt}')
        axes.flatten()[i + 1].axis('off')
    if N + 1 != axes.size:
        for i in range(N + 1, axes.size):
            axes.flatten()[i].axis('off')

    # Get output file paths
    sql = "SELECT mouse,session,trial,is_rest,cropping_v,decoding_v,motion_correction_v FROM Analysis WHERE cropping_main=%s "
    val = [
        cropped_file,
    ]
    mycursor.execute(sql, val)
    myresult = mycursor.fetchall()
    data = []
    for x in myresult:
        data += x

    file_name = f"mouse_{data[0]}_session_{data[1]}_trial_{data[2]}.{data[3]}.v{data[5]}.{data[4]}.{data[6]}"
    data_dir = 'data/interim/motion_correction/'
    output_meta_gSig_filt = data_dir + f'meta/figures/frame_gSig_filt/{file_name}.png'

    fig.savefig(output_meta_gSig_filt)

    return fig
def get_fig_gSig_filt_vals(m, gSig_filt_vals):
    temp = cm.motion_correction.bin_median(m)
    N = len(gSig_filt_vals)
    fig, axes = plt.subplots(int(math.ceil((N + 1) / 4)), 4)
    axes[0, 0].imshow(temp, cmap='gray')
    axes[0, 0].set_title('unfiltered')
    axes[0, 0].axis('off')
    for i in range(0, N):
        gSig_filt = gSig_filt_vals[i]
        m_filt = [
            high_pass_filter_space(m_, (gSig_filt, gSig_filt)) for m_ in m
        ]
        temp_filt = cm.motion_correction.bin_median(m_filt)
        axes.flatten()[i + 1].imshow(temp_filt, cmap='gray')
        axes.flatten()[i + 1].set_title(f'gSig_filt = {gSig_filt}')
        axes.flatten()[i + 1].axis('off')
    if N + 1 != axes.size:
        for i in range(N + 1, axes.size):
            axes.flatten()[i].axis('off')

    return fig
예제 #3
0
def get_fig_gSig_filt_vals(row, gSig_filt_vals):
    '''
    Plot original cropped frame and several versions of spatial filtering for comparison
    :param row: analisis state row for which the filtering is computed
    :param gSig_filt_vals: array containing size of spatial filters that will be applyed
    :return: figure
    '''
    output = row['cropping_output']
    cropped_file = eval(output)['main']
    m = cm.load(cropped_file)
    temp = cm.motion_correction.bin_median(m)
    N = len(gSig_filt_vals)
    fig, axes = plt.subplots(int(math.ceil((N + 1) / 2)), 2)
    axes[0, 0].imshow(temp, cmap='gray')
    axes[0, 0].set_title('unfiltered')
    axes[0, 0].axis('off')
    for i in range(0, N):
        gSig_filt = gSig_filt_vals[i]
        m_filt = [high_pass_filter_space(m_, (gSig_filt, gSig_filt)) for m_ in m]
        temp_filt = cm.motion_correction.bin_median(m_filt)
        axes.flatten()[i + 1].imshow(temp_filt, cmap='gray')
        axes.flatten()[i + 1].set_title(f'gSig_filt = {gSig_filt}')
        axes.flatten()[i + 1].axis('off')
    if N + 1 != axes.size:
        for i in range(N + 1, axes.size):
            axes.flatten()[i].axis('off')

    # Get output file paths
    index = row.name
    data_dir = 'data/interim/motion_correction/'
    step_index = db.get_step_index('motion_correction')
    file_name = db.create_file_name(step_index, index)
    output_meta_gSig_filt = data_dir + f'meta/figures/frame_gSig_filt/{file_name}.png'

    fig.savefig(output_meta_gSig_filt)

    return fig
def parameters_test_gSig(path, figname, gSig_filt_list=None):
    m_orig = cm.load(path)

    if gSig_filt_list == None:
        gSig_filt_list = [(2, 2), (4, 4), (6, 6), (8, 8), (10, 10), (20, 20),
                          (30, 30)]
    m_filt_list = []
    for i, gSig_filt in enumerate(gSig_filt_list):
        m_filt_list.append(
            cm.movie(
                np.array(
                    [high_pass_filter_space(m_, gSig_filt) for m_ in m_orig])))

    import matplotlib.pyplot as plt
    for i, mov in enumerate(m_filt_list):
        plt.figure()
        plt.imshow(mov[0], cmap='gray')
        gSig_size = gSig_filt_list[i]
        plt.title(f'{figname} \n gSig_size = {gSig_size}')
        plt.savefig(
            f'data/motion_correction/png/{figname}_gSig_experiment_{gSig_size}.png'
        )

    return
def run_alignmnet(selected_rows, parameters, dview):
    '''
    This is the main function for the alignment step. It applies methods
    from the CaImAn package used originally in motion correction
    to do alignment.

    Args:
        df: pd.DataFrame
            A dataframe containing the analysis states you want to have aligned.
        parameters: dict
            The alignment parameters.
        dview: object
            The dview object

    Returns:
        df: pd.DataFrame
            A dataframe containing the aligned analysis states.
    '''

    # Sort the dataframe correctly
    df = selected_rows.copy()
    df = df.sort_values(by=paths.multi_index_structure)

    # Determine the mouse and session of the dataset
    index = df.iloc[0].name
    mouse, session, *r = index
    # alignment_v = index[len(paths.data_structure) + step_index]
    alignment_v = len(df)
    alignment_index = (mouse, session, alignment_v)

    # Determine the output .mmap file name
    file_name = f'mouse_{mouse}_session_{session}_v{alignment_v}'
    output_mmap_file_path = os.environ['DATA_DIR'] + f'data/interim/alignment/main/{file_name}.mmap'

    try:
        df.reset_index()[['session','trial', 'is_rest']].set_index(['session','trial', 'is_rest'], verify_integrity=True)
    except ValueError:
        logging.error('You passed multiple of the same trial in the dataframe df')
        return df

    output = {
        'meta': {
            'analysis': {
                'analyst': os.environ['ANALYST'],
                'date': datetime.datetime.today().strftime("%m-%d-%Y"),
                'time': datetime.datetime.today().strftime("%H:%M:%S")
            },
            'duration': {}
        }
    }

    # Get necessary parameters
    motion_correction_parameters_list = []
    motion_correction_output_list = []
    input_mmap_file_list = []
    trial_index_list = []
    x_ = []
    _x = []
    y_ = []
    _y = []
    for idx, row in df.iterrows():
        motion_correction_parameters_list.append(eval(row.loc['motion_correction_parameters']))
        motion_correction_output = eval(row.loc['motion_correction_output'])
        motion_correction_output_list.append(motion_correction_output)
        input_mmap_file_list.append(motion_correction_output['main'])
        trial_index_list.append(db.get_trial_name(idx[2], idx[3]))
        [x1,x2,y1,y2] = motion_correction_output['meta']['cropping_points']
        x_.append(x1)
        _x.append(x2)
        y_.append(y1)
        _y.append(y2)

    new_x1 = max(x_)
    new_x2 = max(_x)
    new_y1 = max(y_)
    new_y2 = max(_y)
    m_list = []
    for i in range(len(input_mmap_file_list)):
        m = cm.load(input_mmap_file_list[i])
        motion_correction_output = eval(df.iloc[i].loc['motion_correction_output'])
        [x1,x2,y1,y2] = motion_correction_output['meta']['cropping_points']
        m = m.crop(new_x1 - x1, new_x2 - x2, new_y1 - y1, new_y2 - y2, 0, 0)
        m_list.append(m)

    # Concatenate them using the concat function
    m_concat = cm.concatenate(m_list, axis=0)
    data_dir = os.environ['DATA_DIR'] + 'data/interim/alignment/main/'
    file_name = db.create_file_name(step_index, index)
    fname= m_concat.save(data_dir + file_name + '.mmap', order='C')

    #meta_pkl_dict['pw_rigid']['cropping_points'] = [x_, _x, y_, _y]
    #output['meta']['cropping_points'] = [x_, _x, y_, _y]
    # Save the movie
    #fname_tot_els  = m_els.save(data_dir + 'main/' + file_name + '_els' + '.mmap',  order='C')
    #logging.info(f'{index} Cropped and saved rigid movie as {fname_tot_els}')

    # MOTION CORRECTING EACH INDIVIDUAL MOVIE WITH RESPECT TO A TEMPLATE MADE OF THE FIRST MOVIE
    logging.info(f'{alignment_index} Performing motion correction on all movies with respect to a template made of \
    the first movie.')
    t0 = datetime.datetime.today()

    # Create a template of the first movie
    template_index = trial_index_list.index(parameters['make_template_from_trial'])
    m0 = cm.load(input_mmap_file_list[template_index ])
    [x1, x2, y1, y2] = motion_correction_output_list[template_index]['meta']['cropping_points']
    m0 = m0.crop(new_x1 - x1, new_x2 - x2, new_y1 - y1, new_y2 - y2, 0, 0)
    m0_filt = cm.movie(
        np.array([high_pass_filter_space(m_, parameters['gSig_filt']) for m_ in m0]))
    template0 = cm.motion_correction.bin_median(
        m0_filt.motion_correct(5, 5, template=None)[0])  # may be improved in the future

    # Setting the parameters
    opts = params.CNMFParams(params_dict=parameters)

    # Create a motion correction object
    mc = MotionCorrect(fname, dview=dview, **opts.get_group('motion'))

    # Perform non-rigid motion correction
    mc.motion_correct(template=template0, save_movie=True)

    # Cropping borders
    x_ = math.ceil(abs(np.array(mc.shifts_rig)[:, 1].max()) if np.array(mc.shifts_rig)[:, 1].max() > 0 else 0)
    _x = math.ceil(abs(np.array(mc.shifts_rig)[:, 1].min()) if np.array(mc.shifts_rig)[:, 1].min() < 0 else 0)
    y_ = math.ceil(abs(np.array(mc.shifts_rig)[:, 0].max()) if np.array(mc.shifts_rig)[:, 0].max() > 0 else 0)
    _y = math.ceil(abs(np.array(mc.shifts_rig)[:, 0].min()) if np.array(mc.shifts_rig)[:, 0].min() < 0 else 0)

    # Load the motion corrected movie into memory
    movie= cm.load(mc.fname_tot_rig[0])
    # Crop all movies to those border pixels
    movie.crop(x_, _x, y_, _y, 0, 0)
    output['meta']['cropping_points'] = [x_, _x, y_, _y]

    #save motion corrected and cropped movie
    output_mmap_file_path_tot = movie.save(data_dir + file_name  + '.mmap', order='C')
    logging.info(f'{index} Cropped and saved rigid movie as {output_mmap_file_path_tot}')
    # Save the path in teh output dictionary
    output['main'] = output_mmap_file_path_tot
    # Remove the remaining non-cropped movie
    os.remove(mc.fname_tot_rig[0])

    # Create a timeline and store it
    timeline = [[trial_index_list[0], 0]]
    timepoints = [0]
    for i in range(1, len(m_list)):
        m = m_list[i]
        timeline.append([trial_index_list[i], timeline[i - 1][1] + m.shape[0]])
        timepoints.append(timepoints[i-1]+ m.shape[0])
        timeline_pkl_file_path = os.environ['DATA_DIR'] + f'data/interim/alignment/meta/timeline/{file_name}.pkl'
        with open(timeline_pkl_file_path,'wb') as f:
            pickle.dump(timeline,f)
    output['meta']['timeline'] = timeline_pkl_file_path
    timepoints.append(movie.shape[0])

    dt = int((datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    output['meta']['duration']['concatenation'] = dt
    logging.info(f'{alignment_index} Performed concatenation. dt = {dt} min.')

    for idx, row in df.iterrows():
        df.loc[idx, 'alignment_output'] = str(output)
        df.loc[idx, 'alignment_parameters'] = str(parameters)

    ## modify all motion correction file to the aligned version
    data_dir = os.environ['DATA_DIR'] + 'data/interim/motion_correction/main/'
    for i in range(len(input_mmap_file_list)):
        row = df.iloc[i].copy()
        motion_correction_output_list.append(motion_correction_output)
        aligned_movie = movie[timepoints[i]:timepoints[i+1]]
        file_name = db.create_file_name(2, selected_rows.iloc[i].name)
        motion_correction_output_aligned = aligned_movie.save(data_dir + file_name + '_els' + '.mmap',  order='C')
        new_output= {'main' : motion_correction_output_aligned }
        new_dict = eval(row['motion_correction_output'])
        new_dict.update(new_output)
        row['motion_correction_output'] = str(new_dict)
        df = db.append_to_or_merge_with_states_df(df, row)

    #    # Delete the motion corrected movies
    #    for fname in mc.fname_tot_rig:
    #        os.remove(fname)

    return df
예제 #6
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())
예제 #7
0
    def __initialize_online(self, model_LN, Y):
        _, original_d1, original_d2 = Y.shape
        opts = self.params.get_group('online')
        init_batch = opts['init_batch']
        if model_LN is not None:
            Y = Y - caiman.movie(
                np.squeeze(model_LN.predict(np.expand_dims(Y, -1))))
            Y = np.maximum(Y, 0)
        # Downsample if needed
        ds_factor = np.maximum(opts['ds_factor'], 1)
        if ds_factor > 1:
            Y = Y.resize(1. / ds_factor, 1. / ds_factor)
        self.estimates.shifts = []  # store motion shifts here
        self.estimates.time_new_comp = []
        if self.params.get('online', 'motion_correct'):
            max_shifts_online = self.params.get('online', 'max_shifts_online')
            if self.params.get('motion', 'gSig_filt') is None:
                mc = Y.motion_correct(max_shifts_online, max_shifts_online)
                Y = mc[0].astype(np.float32)
            else:
                Y_filt = np.stack([
                    high_pass_filter_space(yf, self.params.motion['gSig_filt'])
                    for yf in Y
                ],
                                  axis=0)
                Y_filt = caiman.movie(Y_filt)
                mc = Y_filt.motion_correct(max_shifts_online,
                                           max_shifts_online)
                Y = Y.apply_shifts(mc[1])
            if self.params.get('motion', 'pw_rigid'):
                n_p = len([(it[0], it[1]) for it in sliding_window(
                    Y[0], self.params.get('motion', 'overlaps'),
                    self.params.get('motion', 'strides'))])
                for sh in mc[1]:
                    self.estimates.shifts.append(
                        [tuple(sh) for i in range(n_p)])
            else:
                self.estimates.shifts.extend(mc[1])
        self.img_min = Y.min()
        self.current_frame_cor = Y[-1]

        if self.params.get('online', 'normalize'):
            Y -= self.img_min
        img_norm = np.std(Y, axis=0)
        img_norm += np.median(img_norm)  # normalize data to equalize the FOV
        logging.info('Frame size:' + str(img_norm.shape))
        if self.params.get('online', 'normalize'):
            Y = Y / img_norm[None, :, :]
        total_frame, d1, d2 = Y.shape
        Yr = Y.to_2D().T  # convert data into 2D array
        self.img_norm = img_norm
        if self.params.get('online', 'init_method') == 'bare':
            logging.info('Using bare init')
            init = self.params.get_group('init').copy()
            is1p = (init['method_init'] == 'corr_pnr'
                    and init['ring_size_factor'] is not None)
            if is1p:
                self.estimates.sn, psx = pre_processing.get_noise_fft(
                    Yr,
                    noise_range=self.params.get('preprocess', 'noise_range'),
                    noise_method=self.params.get('preprocess', 'noise_method'),
                    max_num_samples_fft=self.params.get(
                        'preprocess', 'max_num_samples_fft'))
            for key in ('K', 'nb', 'gSig', 'method_init'):
                init.pop(key, None)
            tmp = online_cnmf.bare_initialization(
                Y.transpose(1, 2, 0),
                init_batch=self.params.get('online', 'init_batch'),
                k=self.params.get('init', 'K'),
                gnb=self.params.get('init', 'nb'),
                method_init=self.params.get('init', 'method_init'),
                sn=self.estimates.sn,
                gSig=self.params.get('init', 'gSig'),
                return_object=False,
                options_total=self.params.to_dict(),
                **init)
            if is1p:
                (self.estimates.A, self.estimates.b, self.estimates.C,
                 self.estimates.f, self.estimates.YrA, self.estimates.W,
                 self.estimates.b0) = tmp
            else:
                (self.estimates.A, self.estimates.b, self.estimates.C,
                 self.estimates.f, self.estimates.YrA) = tmp
            if self.fp_detector.method is not None:
                self.__reject_fp_comps(Y.shape[1:], max_bright=Y.max())

            self.estimates.S = np.zeros_like(self.estimates.C)
            nr = self.estimates.C.shape[0]
            self.estimates.g = np.array([
                -np.poly(
                    [0.9] * max(self.params.get('preprocess', 'p'), 1))[1:]
                for gg in np.ones(nr)
            ])
            self.estimates.bl = np.zeros(nr)
            self.estimates.c1 = np.zeros(nr)
            self.estimates.neurons_sn = np.std(self.estimates.YrA, axis=-1)
            self.estimates.lam = np.zeros(nr)
        elif self.params.get('online', 'init_method') == 'seeded':
            init = self.params.get_group('init').copy()
            is1p = (init['method_init'] == 'corr_pnr'
                    and init['ring_size_factor'] is not None)

            if self.seed_file is None:
                raise ValueError(
                    'Please input analyzed mat file path as seed_file.')

            with h5py.File(self.seed_file, 'r') as f:
                Ain = f['A'][()]
            try:
                Ain = Ain.reshape((original_d1, original_d2, -1))
            except:
                raise ValueError(
                    'The shape of A does not match the video source!')
            window_name = 'please check A_seed'
            Ain_gray = Ain.sum(axis=2)
            cv2.imshow(window_name, np.dstack([Ain_gray, Ain_gray, Ain_gray]))
            cv2.waitKey(0)
            cv2.destroyWindow(window_name)
            Ain = cv2.resize(Ain, (d2, d1))
            Ain = Ain.reshape((-1, Ain.shape[-1]), order='F')
            Ain_norm = (Ain - Ain.min(0)[None, :]) / (Ain.max(0) - Ain.min(0))
            A_seed = Ain_norm > 0.5

            tmp = online_cnmf.seeded_initialization(
                Y.transpose(1, 2, 0),
                A_seed,
                k=self.params.get('init', 'K'),
                gSig=self.params.get('init', 'gSig'),
                return_object=False)
            self.estimates.A, self.estimates.b, self.estimates.C, self.estimates.f, self.estimates.YrA = tmp

            if is1p:
                ssub_B = self.params.get('init', 'ssub_B') * self.params.get(
                    'init', 'ssub')
                ring_size_factor = self.params.get('init', 'ring_size_factor')
                gSiz = 2 * np.array(self.params.get('init', 'gSiz')) // 2 + 1
                W, b0 = initialization.compute_W(Y.transpose(1, 2, 0).reshape(
                    (-1, total_frame), order='F'),
                                                 self.estimates.A,
                                                 self.estimates.C, (d1, d2),
                                                 ring_size_factor * gSiz[0],
                                                 ssub=ssub_B)
                self.estimates.W, self.estimates.b0 = W, b0
            self.estimates.S = np.zeros_like(self.estimates.C)
            nr = self.estimates.C.shape[0]
            self.estimates.g = np.array([
                -np.poly(
                    [0.9] * max(self.params.get('preprocess', 'p'), 1))[1:]
                for gg in np.ones(nr)
            ])
            self.estimates.bl = np.zeros(nr)
            self.estimates.c1 = np.zeros(nr)
            self.estimates.neurons_sn = np.std(self.estimates.YrA, axis=-1)
            self.estimates.lam = np.zeros(nr)
        else:
            raise Exception('Unknown initialization method!')
        T1 = init_batch * self.params.get('online', 'epochs')
        self.params.set('data', {'dims': Y.shape[1:]})
        self._prepare_object(Yr, T1)
        return self
예제 #8
0
def run_alignment(mouse, sessions, motion_correction_v, cropping_v, dview):
    """
    This is the main function for the alignment step. It applies methods
    from the CaImAn package used originally in motion correction
    to do alignment.

    """
    for session in sessions:
        # Update the database

        file_name = f"mouse_{mouse}_session_{session}_alignment"
        sql1 = "UPDATE Analysis SET alignment_main=? WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=? "
        val1 = [file_name, mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql1, val1)

        # Determine the output .mmap file name
        output_mmap_file_path = os.environ[
            'DATA_DIR_LOCAL'] + f'data/interim/alignment/main/{file_name}.mmap'
        sql = "SELECT motion_correction_main  FROM Analysis WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=? "
        val = [mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql, val)
        result = cursor.fetchall()
        input_mmap_file_list = []
        inter = []
        for x in result:
            inter += x
        for y in inter:
            input_mmap_file_list.append(y)

        sql = "SELECT motion_correction_cropping_points_x1 FROM Analysis WHERE mouse = ? AND session=?AND motion_correction_v =? AND cropping_v=? "
        val = [mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql, val)
        result = cursor.fetchall()
        x_ = []
        inter = []
        for i in result:
            inter += i
        for j in range(0, len(inter)):
            x_.append(inter[j])

        sql = "SELECT motion_correction_cropping_points_x2 FROM Analysis WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=? "
        val = [mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql, val)
        result = cursor.fetchall()
        _x = []
        inter = []
        for i in result:
            inter += i
        for j in range(0, len(inter)):
            _x.append(inter[j])

        sql = "SELECT motion_correction_cropping_points_y1 FROM Analysis WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=?"
        val = [mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql, val)
        result = cursor.fetchall()
        _y = []
        inter = []
        for i in result:
            inter += i
        for j in range(0, len(inter)):
            _y.append(inter[j])

        sql = "SELECT motion_correction_cropping_points_y2 FROM Analysis WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=?"
        val = [mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql, val)
        result = cursor.fetchall()
        y_ = []
        inter = []
        for i in result:
            inter += i
        for j in range(0, len(inter)):
            y_.append(inter[j])

        new_x1 = max(x_)
        new_x2 = max(_x)
        new_y1 = max(y_)
        new_y2 = max(_y)
        m_list = []
        for i in range(len(input_mmap_file_list)):
            m = cm.load(input_mmap_file_list[i])
            m = m.crop(new_x1 - x_[i], new_x2 - _x[i], new_y1 - y_[i],
                       new_y2 - _y[i], 0, 0)
            m_list.append(m)

        # Concatenate them using the concat function
        m_concat = cm.concatenate(m_list, axis=0)
        fname = m_concat.save(output_mmap_file_path, order='C')

        # MOTION CORRECTING EACH INDIVIDUAL MOVIE WITH RESPECT TO A TEMPLATE MADE OF THE FIRST MOVIE
        logging.info(
            'Performing motion correction on all movies with respect to a template made of the first movie.'
        )
        t0 = datetime.datetime.today()
        # parameters alignment
        sql5 = "SELECT make_template_from_trial,gSig_filt,max_shifts,niter_rig,strides,overlaps,upsample_factor_grid,num_frames_split,max_deviation_rigid,shifts_opencv,use_conda,nonneg_movie, border_nan  FROM Analysis WHERE alignment_main=? "
        val5 = [
            file_name,
        ]
        cursor.execute(sql5, val5)
        myresult = cursor.fetchall()
        para = []
        aux = []
        for x in myresult:
            aux = x
        for y in aux:
            para.append(y)
        parameters = {
            'make_template_from_trial': para[0],
            'gSig_filt': (para[1], para[1]),
            'max_shifts': (para[2], para[2]),
            'niter_rig': para[3],
            'strides': (para[4], para[4]),
            'overlaps': (para[5], para[5]),
            'upsample_factor_grid': para[6],
            'num_frames_split': para[7],
            'max_deviation_rigid': para[8],
            'shifts_opencv': para[9],
            'use_cuda': para[10],
            'nonneg_movie': para[11],
            'border_nan': para[12]
        }
        # Create a template of the first movie
        template_index = parameters['make_template_from_trial']
        m0 = cm.load(input_mmap_file_list[1])
        [x1, x2, y1, y2] = [x_, _x, y_, _y]
        for i in range(len(input_mmap_file_list)):
            m0 = m0.crop(new_x1 - x_[i], new_x2 - _x[i], new_y1 - y_[i],
                         new_y2 - _y[i], 0, 0)
        m0_filt = cm.movie(
            np.array([
                high_pass_filter_space(m_, parameters['gSig_filt'])
                for m_ in m0
            ]))
        template0 = cm.motion_correction.bin_median(
            m0_filt.motion_correct(
                5, 5, template=None)[0])  # may be improved in the future

        # Setting the parameters
        opts = params.CNMFParams(params_dict=parameters)

        # Create a motion correction object
        mc = MotionCorrect(fname, dview=dview, **opts.get_group('motion'))

        # Perform non-rigid motion correction
        mc.motion_correct(template=template0, save_movie=True)

        # Cropping borders
        x_ = math.ceil(
            abs(np.array(mc.shifts_rig)[:, 1].max()
                ) if np.array(mc.shifts_rig)[:, 1].max() > 0 else 0)
        _x = math.ceil(
            abs(np.array(mc.shifts_rig)[:, 1].min()
                ) if np.array(mc.shifts_rig)[:, 1].min() < 0 else 0)
        y_ = math.ceil(
            abs(np.array(mc.shifts_rig)[:, 0].max()
                ) if np.array(mc.shifts_rig)[:, 0].max() > 0 else 0)
        _y = math.ceil(
            abs(np.array(mc.shifts_rig)[:, 0].min()
                ) if np.array(mc.shifts_rig)[:, 0].min() < 0 else 0)

        # Load the motion corrected movie into memory
        movie = cm.load(mc.fname_tot_rig[0])
        # Crop all movies to those border pixels
        movie.crop(x_, _x, y_, _y, 0, 0)
        sql1 = "UPDATE Analysis SET alignment_x1=?, alignment_x2 =?, alignment_y1=?, alignment_y2=? WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=?"
        val1 = [
            x_, _x, y_, _y, mouse, session, motion_correction_v, cropping_v
        ]
        cursor.execute(sql1, val1)

        # save motion corrected and cropped movie
        output_mmap_file_path_tot = movie.save(
            os.environ['DATA_DIR_LOCAL'] +
            f'data/interim/alignment/main/{file_name}.mmap',
            order='C')
        logging.info(
            f' Cropped and saved rigid movie as {output_mmap_file_path_tot}')
        # Remove the remaining non-cropped movie
        os.remove(mc.fname_tot_rig[0])

        # Create a timeline and store it
        sql = "SELECT trial FROM Analysis WHERE mouse = ? AND session=? AND motion_correction_v =? AND cropping_v=?"
        val = [mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql, val)
        result = cursor.fetchall()
        trial_index_list = []
        inter = []
        for i in result:
            inter += i
        for j in range(0, len(inter)):
            trial_index_list.append(inter[j])

        timeline = [[trial_index_list[0], 0]]
        timepoints = [0]
        for i in range(1, len(m_list)):
            m = m_list[i]
            timeline.append(
                [trial_index_list[i], timeline[i - 1][1] + m.shape[0]])
            timepoints.append(timepoints[i - 1] + m.shape[0])
            timeline_pkl_file_path = os.environ[
                'DATA_DIR'] + f'data/interim/alignment/meta/timeline/{file_name}.pkl'
            with open(timeline_pkl_file_path, 'wb') as f:
                pickle.dump(timeline, f)
        sql1 = "UPDATE Analysis SET alignment_timeline=? WHERE mouse = ? AND session=?AND motion_correction_v =? AND cropping_v=? "
        val1 = [
            timeline_pkl_file_path, mouse, session, motion_correction_v,
            cropping_v
        ]
        cursor.execute(sql1, val1)
        timepoints.append(movie.shape[0])

        dt = int((datetime.datetime.today() - t0).seconds /
                 60)  # timedelta in minutes
        sql1 = "UPDATE Analysis SET alignment_duration_concatenation=? WHERE mouse = ? AND session=?AND motion_correction_v =? AND cropping_v=? "
        val1 = [dt, mouse, session, motion_correction_v, cropping_v]
        cursor.execute(sql1, val1)
        logging.info(f' Performed concatenation. dt = {dt} min.')

        ## modify all motion correction file to the aligned version
        data_dir = os.environ[
            'DATA_DIR'] + 'data/interim/motion_correction/main/'
        for i in range(len(input_mmap_file_list)):
            aligned_movie = movie[timepoints[i]:timepoints[i + 1]]
            motion_correction_output_aligned = aligned_movie.save(
                data_dir + file_name + '_els' + '.mmap', order='C')
            sql1 = "UPDATE Analysis SET motion_correct_align=? WHERE motion_correction_meta=? AND motion_correction_v"
            val1 = [
                motion_correction_output_aligned, input_mmap_file_list[i],
                motion_correction_v
            ]
            cursor.execute(sql1, val1)

    database.commit()
    return
예제 #9
0
def run_alignmnet(states_df, parameters, dview):
    '''
    This is the main function for the alignment step. It applies methods 
    from the CaImAn package used originally in motion correction
    to do alignment. 
    
    Args:
        df: pd.DataFrame
            A dataframe containing the analysis states you want to have aligned.
        parameters: dict
            The alignment parameters.
        dview: object
            The dview object
            
    Returns:
        df: pd.DataFrame
            A dataframe containing the aligned analysis states. 
    '''

    # Sort the dataframe correctly
    df = states_df.copy()
    df = df.sort_values(by=paths.multi_index_structure)

    # Determine the mouse and session of the dataset
    index = df.iloc[0].name
    mouse, session, *r = index
    #alignment_v = index[len(paths.data_structure) + step_index]
    alignment_v = len(df)
    alignment_index = (mouse, session, alignment_v)

    # Determine the output .mmap file name
    file_name = f'mouse_{mouse}_session_{session}_v{alignment_v}'
    output_mmap_file_path = f'data/interim/alignment/main/{file_name}.mmap'

    try:
        df.reset_index()[['trial', 'is_rest']].set_index(['trial', 'is_rest'],
                                                         verify_integrity=True)
    except ValueError:
        logging.error(
            'You passed multiple of the same trial in the dataframe df')
        return df

    output = {
        'meta': {
            'analysis': {
                'analyst': os.environ['ANALYST'],
                'date': datetime.datetime.today().strftime("%m-%d-%Y"),
                'time': datetime.datetime.today().strftime("%H:%M:%S")
            },
            'duration': {}
        }
    }

    # Get necessary parameters
    motion_correction_parameters_list = []
    motion_correction_output_list = []
    input_mmap_file_list = []
    trial_index_list = []
    for idx, row in df.iterrows():
        motion_correction_parameters_list.append(
            eval(row.loc['motion_correction_parameters']))
        motion_correction_output = eval(row.loc['motion_correction_output'])
        motion_correction_output_list.append(motion_correction_output)
        input_mmap_file_list.append(motion_correction_output['main'])
        trial_index_list.append(db.get_trial_name(idx[2], idx[3]))

    # MOTION CORRECTING EACH INDIVIDUAL MOVIE WITH RESPECT TO A TEMPLATE MADE OF THE FIRST MOVIE
    logging.info(
        f'{alignment_index} Performing motion correction on all movies with respect to a template made of \
    the first movie.')
    t0 = datetime.datetime.today()

    # Create a template of the first movie
    template_index = trial_index_list.index(
        parameters['make_template_from_trial'])
    m0 = cm.load(input_mmap_file_list[template_index])
    m0_filt = cm.movie(
        np.array([
            high_pass_filter_space(m_, parameters['gSig_filt']) for m_ in m0
        ]))
    template0 = cm.motion_correction.bin_median(
        m0_filt.motion_correct(
            5, 5, template=None)[0])  # may be improved in the future

    # Setting the parameters
    opts = params.CNMFParams(params_dict=parameters)

    # Create a motion correction object
    mc = MotionCorrect(input_mmap_file_list,
                       dview=dview,
                       **opts.get_group('motion'))

    # Perform non-rigid motion correction
    mc.motion_correct(template=template0, save_movie=True)

    # Cropping borders
    x_ = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 1].max()
            ) if np.array(mc.shifts_rig)[:, 1].max() > 0 else 0)
    _x = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 1].min()
            ) if np.array(mc.shifts_rig)[:, 1].min() < 0 else 0)
    y_ = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 0].max()
            ) if np.array(mc.shifts_rig)[:, 0].max() > 0 else 0)
    _y = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 0].min()
            ) if np.array(mc.shifts_rig)[:, 0].min() < 0 else 0)

    dt = int(
        (datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    output['meta']['duration']['motion_correction'] = dt
    logging.info(
        f'{alignment_index} Performed motion correction. dt = {dt} min.')

    # CONCATENATING ALL MOTION CORRECTED MOVIES
    logging.info(
        f'{alignment_index} Concatenating all motion corrected movies.')

    # Load all movies into memory
    m_list = [cm.load(fname) for fname in mc.fname_tot_rig]

    # Crop all movies to those border pixels
    for idx, m in enumerate(m_list):
        m_list[idx] = m.crop(x_, _x, y_, _y, 0, 0)
    output['meta']['cropping_points'] = [x_, _x, y_, _y]

    # Concatenate them using the concat function
    m_concat = cm.concatenate(m_list, axis=0)

    # Create a timeline and store it
    timeline = [[trial_index_list[0], 0]]
    for i in range(1, len(m_list)):
        m = m_list[i]
        timeline.append([trial_index_list[i], timeline[i - 1][1] + m.shape[0]])
#    timeline_pkl_file_path = f'data/interim/alignment/meta/timeline/{file_name}.pkl'
#    with open(timeline_pkl_file_path,'wb') as f:
#        pickle.dump(timeline,f)
#    output['meta']['timeline'] = timeline_pkl_file_path
    output['meta']['timeline'] = timeline

    # Save the concatenated movie
    output_mmap_file_path_tot = m_concat.save(output_mmap_file_path)
    output['main'] = output_mmap_file_path_tot

    #    # Delete the motion corrected movies
    #    for fname in mc.fname_tot_rig:
    #        os.remove(fname)

    dt = int(
        (datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    output['meta']['duration']['concatenation'] = dt
    logging.info(f'{alignment_index} Performed concatenation. dt = {dt} min.')

    for idx, row in df.iterrows():
        df.loc[idx, 'alignment_output'] = str(output)
        df.loc[idx, 'alignment_parameters'] = str(parameters)

    return df
예제 #10
0
def get_correlations(df):
    '''
    Get the correlation of both the origin movies and the aligned movie w.r.t a template created
    of the movie to which the movies were aligned
    
    Args:
        df: pd.DataFrame
            The dataframe containing the aligned analysis states. 
    
    Returns:
        df: pd.DataFrame
            The dataframe containing the aligned analysis states with
            the metrics stored in the meta output.
    '''

    # Load a dummy index
    index = df.iloc[0].name

    # Load the original movies and the aligned, concatenated movie
    original_m_list = []
    trial_name_list = []
    for index, row in df.iterrows():
        motion_correction_output = eval(row.loc['motion_correction_output'])
        m = cm.load(motion_correction_output['main'])
        original_m_list.append(m)
        trial_name_list.append(db.get_trial_name(index[2], index[3]))
    alignment_output = eval(df.iloc[0].loc['alignment_output'])
    aligned_m = cm.load(alignment_output['main'])

    # Load the cropping points and timeline and to which trial the alignment was done
    cropping_points = alignment_output['meta']['cropping_points']
    timeline = alignment_output['meta']['timeline']
    alignment_parameters = eval(df.iloc[0].loc['alignment_parameters'])
    make_template_from_trial = alignment_parameters['make_template_from_trial']
    template_index = trial_name_list.index(make_template_from_trial)

    # Crop the original movies
    cropped_original_m_list = []
    for i, m in enumerate(original_m_list):
        [x_, _x, y_, _y] = cropping_points
        cropped_original_m_list.append(m.crop(x_, _x, y_, _y, 0, 0))

    # Concatenate the original movie
    m_original_concat = cm.concatenate(cropped_original_m_list, axis=0)

    # ORIGINAL MOVIE CORRELATIONS
    # Create a template of the movie to which alignment has taken place
    m0 = cropped_original_m_list[template_index]
    m0_filt = cm.movie(
        np.array([
            high_pass_filter_space(m_, alignment_parameters['gSig_filt'])
            for m_ in m0
        ]))
    tmpl = caiman.motion_correction.bin_median(
        m0_filt.motion_correct(
            5, 5, template=None)[0])  # may be improved in the future
    # Calculate the correlations of each movie with respect to that template
    logging.debug('Computing original movie correlations')
    t0 = datetime.datetime.today()
    correlations_orig = []
    count = 0
    m_compute = m_original_concat - np.min(m_original_concat)
    for fr in m_compute:
        if count % 100 == 0:
            logging.debug(f'Frame {count}')
        count += 1
        correlations_orig.append(
            scipy.stats.pearsonr(fr.flatten(), tmpl.flatten())[0])
    dt = int(
        (datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    logging.debug(f'Computed original movie correlations. dt = {dt} min')

    # ALIGNED CORRELATIONS
    # Create a template of the movie to which alignment has taken place
    m0 = aligned_m[timeline[template_index][1]:timeline[
        template_index + 1][1]] if template_index != len(
            timeline) - 1 else aligned_m[timeline[template_index][1]:]
    m0_filt = cm.movie(
        np.array([
            high_pass_filter_space(m_, alignment_parameters['gSig_filt'])
            for m_ in m0
        ]))
    tmpl = caiman.motion_correction.bin_median(
        m0_filt.motion_correct(
            5, 5, template=None)[0])  # may be improved in the future

    # Calculate the correlations of each movie with respect to that template
    logging.debug('Computing aligned movie correlations')
    t0 = datetime.datetime.today()
    correlations_aligned = []
    count = 0
    m_compute = aligned_m - np.min(aligned_m)
    for fr in m_compute:
        if count % 100 == 0:
            logging.debug(f'Frame {count}')
        count += 1
        correlations_aligned.append(
            scipy.stats.pearsonr(fr.flatten(), tmpl.flatten())[0])
    dt = int(
        (datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    logging.debug(f'Computed aligned movie correlations. dt = {dt} min')

    # STORE THE CORRELATIONS
    correlations = {
        'original': correlations_orig,
        'aligned': correlations_aligned
    }
    metrics_pkl_file_path = f'data/interim/alignment/meta/correlations/mouse_{index[0]}_session{index[1]}_v{index[7]}.pkl'
    with open(metrics_pkl_file_path, 'wb') as f:
        pickle.dump(correlations, f)
    alignment_output['meta']['correlations'] = metrics_pkl_file_path

    for idx, row in df.iterrows():
        df.loc[idx, 'alignment_output'] = str(alignment_output)

    return df
예제 #11
0
def run_equalizer(states_df, parameters):
    '''

    This function is meant to help with differences in different trials and session, to equalize general brightness
    or reduce photobleaching. It corrects the video and saves them in the corrected version.

    params df: pd.DataFrame -> A dataframe containing the analysis states you want to have aligned.
    params parameters: dict -> contains parameters concerning equalization

    returns df: pd.DataFrame -> A dataframe containing the aligned analysis states.
    '''

    # Sort the dataframe correctly
    df = states_df.sort_values(by=paths.multi_index_structure)
    # Determine the output path
    output_mmap_file_path = f'data/interim/equalizer/main/'
    mouse, session, init_trial, *r = df.iloc[0].name

    histogram_name = f'mouse_{mouse}_session_{session}_init_trial_{init_trial}'
    output_steps_file_path = f'data/interim/equalizer/meta/figures/histograms/' + histogram_name

    try:
        df.reset_index()[['trial', 'is_rest']].set_index(['trial', 'is_rest'],
                                                         verify_integrity=True)
    except ValueError:
        logging.error(
            'You passed multiple of the same trial in the dataframe df')
        return df

    output = {
        'meta': {
            'analysis': {
                'analyst': os.environ['ANALYST'],
                'date': datetime.datetime.today().strftime("%m-%d-%Y"),
                'time': datetime.datetime.today().strftime("%H:%M:%S")
            },
            'duration': {}
        }
    }

    # Get necessary parameters
    decoding_output_list = []
    input_tif_file_list = []
    trial_index_list = []
    for idx, row in df.iterrows():
        decoding_output = eval(row.loc['decoding_output'])
        decoding_output_list.append(decoding_output)
        input_tif_file_list.append(decoding_output['main'])
        trial_index_list.append(db.get_trial_name(idx[2], idx[3]))

    colors = []
    for i in range(len(df)):
        colors.append('#%06X' % randint(0, 0xFFFFFF))

    m_list = []
    m_reshape_list = []
    legend = []
    min_list = []
    max_list = []
    h_step = parameters['histogram_step']
    fig, ax = plt.subplots(1, 2)

    for i in range(len(input_tif_file_list)):
        im = io.imread(input_tif_file_list[i])
        #m_list.append(im)
        reshape_m = np.reshape(im, (im.shape[0] * im.shape[1] * im.shape[2]))
        m_reshape_list.append(reshape_m)
        legend.append('trial = ' + f'{df.iloc[i].name[2]}')

    total_min = 200
    total_max = 1500
    cdf_list = []
    for i in range(len(input_tif_file_list)):
        hist, bins = np.histogram(
            m_reshape_list[i],
            bins=np.linspace(total_min, total_max,
                             (total_max - total_min) / h_step),
            density=True)
        cdf = np.cumsum(hist) * h_step
        cdf_list.append(cdf)
        ax[0].plot(bins[0:-1], hist, color=colors[i])
        ax[1].plot(bins[0:-1], cdf, color=colors[i])

    ax[0].set_xlabel('Pixel Intensity')
    ax[1].set_xlabel('Pixel Intensity')
    ax[0].set_ylabel('Density')
    ax[1].set_ylabel('CDF')
    ax[0].legend((legend))
    fig.savefig(output_steps_file_path + '.png')

    # Concatenate them using the concat function
    m_concat = cm.concatenate(m_list, axis=0)
    data_dir = 'data/interim/alignment/main'
    file_name = db.create_file_name(step_index, index)
    fname = m_concat.save(data_dir + '/' + file_name + '_pw_rig' + '.mmap',
                          order='C')

    cdf_m = np.ma.masked_equal(cdf, 0)
    cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
    cdf = np.ma.filled(cdf_m, 0).astype('uint8')

    #meta_pkl_dict['pw_rigid']['cropping_points'] = [x_, _x, y_, _y]
    #output['meta']['cropping_points'] = [x_, _x, y_, _y]
    # Save the movie
    #fname_tot_els  = m_els.save(data_dir + 'main/' + file_name + '_els' + '.mmap',  order='C')
    #logging.info(f'{index} Cropped and saved rigid movie as {fname_tot_els}')

    # MOTION CORRECTING EACH INDIVIDUAL MOVIE WITH RESPECT TO A TEMPLATE MADE OF THE FIRST MOVIE
    logging.info(
        f'{alignment_index} Performing motion correction on all movies with respect to a template made of \
    the first movie.')
    t0 = datetime.datetime.today()

    # Create a template of the first movie
    template_index = trial_index_list.index(
        parameters['make_template_from_trial'])
    m0 = cm.load(input_mmap_file_list[template_index])
    [x1, x2, y1, y2] = motion_correction_output_list[template_index]['meta'][
        'cropping_points']
    m0 = m0.crop(new_x1 - x1, new_x2 - x2, new_y1 - y1, new_y2 - y2, 0, 0)
    m0_filt = cm.movie(
        np.array([
            high_pass_filter_space(m_, parameters['gSig_filt']) for m_ in m0
        ]))
    template0 = cm.motion_correction.bin_median(
        m0_filt.motion_correct(
            5, 5, template=None)[0])  # may be improved in the future

    # Setting the parameters
    opts = params.CNMFParams(params_dict=parameters)

    # Create a motion correction object
    mc = MotionCorrect(fname, dview=dview, **opts.get_group('motion'))

    # Perform non-rigid motion correction
    mc.motion_correct(template=template0, save_movie=True)

    # Cropping borders
    x_ = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 1].max()
            ) if np.array(mc.shifts_rig)[:, 1].max() > 0 else 0)
    _x = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 1].min()
            ) if np.array(mc.shifts_rig)[:, 1].min() < 0 else 0)
    y_ = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 0].max()
            ) if np.array(mc.shifts_rig)[:, 0].max() > 0 else 0)
    _y = math.ceil(
        abs(np.array(mc.shifts_rig)[:, 0].min()
            ) if np.array(mc.shifts_rig)[:, 0].min() < 0 else 0)

    dt = int(
        (datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    output['meta']['duration']['motion_correction'] = dt
    logging.info(
        f'{alignment_index} Performed motion correction. dt = {dt} min.')

    # Create a timeline and store it
    timeline = [[trial_index_list[0], 0]]
    for i in range(1, len(m_list)):
        m = m_list[i]
        timeline.append([trial_index_list[i], timeline[i - 1][1] + m.shape[0]])
    #    timeline_pkl_file_path = f'data/interim/alignment/meta/timeline/{file_name}.pkl'
    #    with open(timeline_pkl_file_path,'wb') as f:
    #        pickle.dump(timeline,f)
    #    output['meta']['timeline'] = timeline_pkl_file_path
    output['meta']['timeline'] = timeline

    # Save the concatenated movie
    output_mmap_file_path_tot = m_concat.save(output_mmap_file_path, order='C')
    output['main'] = output_mmap_file_path_tot

    #    # Delete the motion corrected movies
    #    for fname in mc.fname_tot_rig:
    #        os.remove(fname)

    dt = int(
        (datetime.datetime.today() - t0).seconds / 60)  # timedelta in minutes
    output['meta']['duration']['concatenation'] = dt
    logging.info(f'{alignment_index} Performed concatenation. dt = {dt} min.')

    for idx, row in df.iterrows():
        df.loc[idx, 'alignment_output'] = str(output)
        df.loc[idx, 'alignment_parameters'] = str(parameters)

    return df