Ejemplo n.º 1
0
def dlc3d_video_migrate(config_path, root, many=False, test=False):
    '''
    Migrate DeepCage videos to DeepCage related DeepLabCut 3D projects

    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    root : string
        Absolute path for the root directory of function operation
    many : bool; default False
        Bool indicating if root stores many projects. False means the root is a project root
    test : bool; default False
        Bool indicating if the respective function call is for testing. If True, the function will not copy video files
    '''

    dlc3d_cfgs = get_dlc3d_configs(config_path)
    pairs = tuple(dlc3d_cfgs.keys())

    if many is False:
        result = copy_videos_from_root(root, dlc3d_cfgs, test)
    else:
        project_dirs = glob(os.path.join(root, '*/'))
        result = {}
        for project_dir in project_dirs:
            project_name = Path(project_dir).stem
            result[project_name] = copy_videos_from_root(
                project_dir, dlc3d_cfgs, test)

    print('Overview of videos found for each pair:\n%s' % result)
    return result
Ejemplo n.º 2
0
def detect_2d_coords(config_path, suffix='filtered.h5', bonvideos=False):
    '''
    This function detects and returns the state of deeplabcut-triangulated coordinate h5 files (can be changed)

    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    suffix : string
        The suffix in the DeepLabCut 3D project triangualtion result storage files

    Example
    -------

    '''

    cfg = read_config(config_path)
    dlc3d_cfgs = get_dlc3d_configs(config_path)

    results_path = Path(cfg['results_path'])
    triangulated = results_path / 'triangulated'
    experiments = glob(str(triangulated / '*/'))
    if experiments == []:
        msg = 'Could not find any triangulated coordinates in %s' % triangulated
        raise ValueError(msg)

    coords = {}
    for exp_path in experiments:
        exp_dir_name = os.path.basename(exp_path)
        if bonvideos is True:
            animal, trial, date = exp_dir_name.split('_')
            coords[(animal, trial, date)] = {}
        else:
            coords[exp_dir_name] = {}

        regions_of_interest = {}
        for hdf_path in glob(os.path.join(exp_path, '**/*' + suffix)):
            pair_info = os.path.basename(os.path.dirname(hdf_path)).split('_')
            if len(pair_info) == 2:
                cam1, cam2 = pair_info
            else:
                idx_, cam1, cam2 = pair_info
            pair = (cam1, cam2)

            df = pd.read_hdf(os.path.realpath(hdf_path))
            exp_regions_of_interest = df.columns.levels[0]
            regions_of_interest[pair] = exp_regions_of_interest

            coord = {roi: df[roi].values for roi in exp_regions_of_interest}
            if bonvideos is True:
                coords[(animal, trial, date)][pair] = coord
            else:
                coords[exp_dir_name][pair] = coord

    return coords
Ejemplo n.º 3
0
def visualize_triangulation(config_path, undistort=True, decrement=False, save=True):
    dlc3d_cfgs = get_dlc3d_configs(config_path)
    basis_labels = get_labels(config_path)

    cfg = read_config(config_path)
    test_dir = os.path.join(cfg['data_path'], 'test')
    if not os.path.exists(test_dir):
        os.mkdir(test_dir)

    fig = plt.figure(figsize=(14, 10))

    # Get non-corner pairs by splicing
    pairs = tuple(PAIR_IDXS.keys())[::2]
    pair_ax = {}
    for i, pair in enumerate(pairs):
        dlc3d_cfg = dlc3d_cfgs[pair]
        cam1, cam2 = pair

        # Prepare camera plot labels
        cam_labels = get_paired_labels(config_path, pair)['decrement' if decrement is True else 'normal']

        # Triangulate the two sets of labels, and map them to 3D
        trian_dict, trian_coord = triangulate_raw_2d_camera_coords(
            dlc3d_cfg,
            cam1_coords=tuple(cam_labels[cam1].values()),
            cam2_coords=tuple(cam_labels[cam2].values()),
            keys=cam_labels[cam1],
            undistort=undistort
        )

        pair_ax[pair] = fig.add_subplot(2, 2, i+1, projection='3d')
        for label, coord in trian_dict.items():
            pair_ax[pair].scatter(*coord, label=label)

        if CAMERAS[cam1][0][1] == 'left':
            c_origin = trian_coord[0] + (trian_coord[1] - trian_coord[0]) / 2
        else:
            c_origin = trian_coord[1] + (trian_coord[0] - trian_coord[1]) / 2
        pair_ax[pair].scatter(*c_origin, label='computed origin')

        pair_ax[pair].legend()
        angle_origins = vg.angle(trian_dict['origin'], c_origin)
        pair_ax[pair].set_title('%s %s\nInnerAngle(orgin, c_origin): %.2f deg' % (*pair, angle_origins)).set_y(1.005)

    fig.suptitle('Triangulation visualization', fontsize=20)

    if save is True:
        fig.savefig(os.path.join(test_dir, 'visualize_triangulation.png'))

    return fig, pair_ax
Ejemplo n.º 4
0
def OE_get_triangulated_basis(config_path, pair, undistort=True, keys=False):
    from deepcage.compute.triangulate import triangulate_raw_2d_camera_coords
    from deepcage.project.get import get_dlc3d_configs, get_labels

    cam1, cam2 = pair
    labels = get_labels(config_path)
    basis_labels = OE_get_paired_labels(config_path, pair)
    cam1_labels, cam2_labels = basis_labels.values()

    return triangulate_raw_2d_camera_coords(
        get_dlc3d_configs(config_path)[pair],
        cam1_coords=tuple(cam1_labels.values()),
        cam2_coords=tuple(cam2_labels.values()),
        undistort=undistort,
        keys=None if keys is False else tuple(cam1_labels.keys()))
Ejemplo n.º 5
0
def visualize_basis_vectors(config_path, undistort=True, normalize=True, decrement=False, stereo_cam_units=None, save=True):
    '''
    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    '''
    if stereo_cam_units is None:
        stereo_cam_units, orig_maps = create_stereo_cam_origmap(config_path, undistort=undistort, normalize=normalize, decrement=decrement, save=False)

    cfg = read_config(config_path)
    dlc3d_cfgs = get_dlc3d_configs(config_path)

    test_dir = os.path.join(cfg['data_path'], 'test')
    if not os.path.exists(test_dir):
        os.mkdir(test_dir)

    pairs = tuple(dlc3d_cfgs.keys())
    pair_num = int(len(pairs) / 2)

    fig = plt.figure(figsize=(14, 8))
    ax_duo = {}
    for i in range(pair_num):
        pair1 = pairs[i]
        reds = iter(plt.cm.Reds(np.linspace(0.38, 0.62, 3)))

        pair2 = pair_cycler(i+4, pairs=pairs)
        blues = iter(plt.cm.Blues(np.linspace(0.38, 0.62, 3)))

        ax_duo[(pair1, pair2)] = fig.add_subplot(2, 2, i+1, projection='3d')
        for pair, color in zip((pair1, pair2), (reds, blues)):
            axes = list(stereo_cam_units[pair].values())[:3]
            initials = pair[0][0] + pair[1][0]
            for i, axis in enumerate(axes):
                ax_duo[(pair1, pair2)].plot(
                    [0, axis[0]], [0, axis[1]], [0, axis[2]],'-',
                    c=next(color), label=f'{initials}: r{i}'
                )
        ax_duo[(pair1, pair2)].legend(loc=2)
        ax_duo[(pair1, pair2)].set_title('%s %s and %s %s' % (*pair1, *pair2)).set_y(1.015)

    if save is True:
        fig.savefig( os.path.join(test_dir, 'visualize_basis_vectors.png') )

    return fig, ax_duo
Ejemplo n.º 6
0
def detect_triangulation_result(config_path,
                                filter_low_likelihood=True,
                                pcutoff=0.1,
                                undistorted=True,
                                suffix='_DLC_3D.h5',
                                change_basis=False,
                                bonvideos=False):
    '''
    This function detects and returns the state of deeplabcut-triangulated coordinate h5 files (can be changed)

    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    suffix : string
        The suffix in the DeepLabCut 3D project triangualtion result storage files
    change_basis : boolean
        Boolean stating wether the function is within a change basis workflow

    Example
    -------

    '''

    suffix_split = suffix.split('.')
    if len(suffix_split) > 1:
        if suffix_split[-1] != 'h5':
            msg = 'Invalid file extension in suffix: %s' % suffix
            raise ValueError(msg)
    else:
        suffix = suffix + '.h5'

    cfg = read_config(config_path)
    dlc3d_cfgs = get_dlc3d_configs(config_path)

    results_path = Path(cfg['results_path'])
    triangulated = results_path / ('undistorted' if undistorted is True else
                                   'distorted') / 'triangulated'
    experiments = glob(str(triangulated / '*/'))
    if experiments == []:
        msg = 'Could not find any triangulated coordinates in %s' % triangulated
        raise ValueError(msg)

    # Detect triangulation results in related DeepLabCut 3D projects
    # Analyse the number of occurances of hdf across projects
    missing = 0
    status, coords, likelihoods, pairs = {}, {}, {}, {}
    for exp_path in experiments:
        exp_dir_name = os.path.basename(exp_path)
        if bonvideos is True:
            animal, trial, date = exp_dir_name.split('_')
            coords[(animal, trial, date)], likelihoods[(animal, trial,
                                                        date)] = {}, {}
        else:
            coords[exp_dir_name], likelihoods[exp_dir_name] = {}, {}

        regions_of_interest = {}
        for hdf_path in glob(os.path.join(exp_path, '**/*' + suffix)):
            pair_dir = os.path.dirname(hdf_path)
            pair_info = os.path.basename(pair_dir).split('_')
            if len(pair_info) == 2:
                cam1, cam2 = pair_info
            else:
                idx_, cam1, cam2 = pair_info
            pair = (cam1, cam2)

            df = pd.read_hdf(os.path.realpath(hdf_path))['DLC_3D']
            exp_regions_of_interest = df.columns.levels[0]
            regions_of_interest[pair] = exp_regions_of_interest

            if filter_low_likelihood is True:
                try:
                    cam1_prediction_2d = pd.read_hdf(
                        glob(os.path.join(pair_dir,
                                          f'*{cam1}*filtered.h5'))[0])
                    cam2_prediction_2d = pd.read_hdf(
                        glob(os.path.join(pair_dir,
                                          f'*{cam2}*filtered.h5'))[0])
                except FileNotFoundError:
                    print(
                        "No filtered predictions found. Will use the unfiltered predictions."
                    )
                    cam1_prediction_2d = pd.read_hdf(
                        glob(os.path.join(pair_dir, f'*{cam1}*.h5'))[0])
                    cam2_prediction_2d = pd.read_hdf(
                        glob(os.path.join(pair_dir, f'*{cam2}*.h5'))[0])

                coord, roi_likelihood = {}, {}
                for roi in exp_regions_of_interest:
                    cam1_likelihood = cam1_prediction_2d[
                        cam1_prediction_2d.keys()[0]
                        [0]][roi]['likelihood'].values
                    cam2_likelihood = cam2_prediction_2d[
                        cam2_prediction_2d.keys()[0]
                        [0]][roi]['likelihood'].values

                    coord_likelihood = np.dstack(
                        (cam1_likelihood, cam2_likelihood))[0]
                    coord_idxs = np.all(coord_likelihood < pcutoff, axis=1)
                    df[roi].loc[coord_idxs] = np.nan

                    coord[roi] = df[roi].values
                    roi_likelihood[roi] = coord_likelihood
            else:
                coord = {
                    roi: df[roi].values
                    for roi in exp_regions_of_interest
                }

            if bonvideos is True:
                coords[(animal, trial, date)][pair] = coord

                if filter_low_likelihood is True:
                    likelihoods[(animal, trial, date)][pair] = roi_likelihood
            else:
                coords[exp_dir_name][pair] = coord
                if filter_low_likelihood is True:
                    likelihoods[exp_dir_name][pair] = roi_likelihood
        # print(1)
        # print(all([exp_regions_of_interest == rsoi for rsoi in regions_of_interest]))

        # if not all(all([exp_regions_of_interest == rsoi for rsoi in regions_of_interest])):
        #     save_path = os.path.join(exp_path, 'rsoi_incom_%s_%s_%s.xlsx' % (animal, trial, date))
        #     pd.DataFrame.from_dict(regions_of_interest).to_excel(save_path)
        #     print('Inconsistencies in exp %s %s %s were found.\nAn overview was saved:\n%s\n' % (
        #         animal, trial, date, save_path
        #         )
        #     )
        #     missing += 1

    if missing == 0:
        print('Triangulations files detected, and verified')
        if change_basis is True:
            print('Proceeding to changing basis')
        else:
            print('The current DeepCage project is ready for changing basis')
        return coords, likelihoods if filter_low_likelihood is True else coords
    else:
        if missing == 1:
            msg = 'Inconsistencies in regions of interest was found in one experiment'
        else:
            msg = 'Inconsistencies in regions of interest were found in %d experiments' % missing
        raise ValueError(msg)
Ejemplo n.º 7
0
def dlc3d_create_labeled_video(config_path, fps=20, undistort=True, video_root=None, video_dir_hierarchy=False,
                               remove_origin=False):
    '''
    Augmented function from https://github.com/AlexEMG/DeepLabCut

    Create pairwise videos
    
    '''
    from deepcage.auxiliary.detect import detect_videos_in_hierarchy

    start_path = os.getcwd()

    cfg = read_config(config_path)
    result_path = Path(cfg['results_path'])
    triangulate_path = result_path / ("undistorted" if undistort is True else "distorted") / 'triangulated'

    if not os.path.exists(triangulate_path) or 0 == len(glob(os.path.join(triangulate_path, '*'))):
        msg = f'Could not detect triangulated coordinates in {triangulate_path}'
        raise ValueError(msg)

    if remove_origin is True:
        basis_result_path = os.path.join(cfg['data_path'], 'cb_result.pickle')
        try:
            with open(basis_result_path, 'rb') as infile:
                stereo_cam_units, orig_maps = pickle.load(infile)
        except FileNotFoundError:
            msg = f'Could not detect results from deepcage.compute.generate_linear_map() in:\n{basis_result_path}'
            raise FileNotFoundError(msg)

    skipped = []
    dlc3d_cfgs = get_dlc3d_configs(config_path)
    futures = {}
    # with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
    for pair, dlc3d_cfg_path in dlc3d_cfgs.items():
        dlc3d_cfg = read_config(dlc3d_cfg_path)
        pcutoff = dlc3d_cfg['pcutoff']
        markerSize = dlc3d_cfg['dotsize']
        alphaValue = dlc3d_cfg['alphaValue']
        cmap = dlc3d_cfg['colormap']
        skeleton_color = dlc3d_cfg['skeleton_color']
        scorer_3d = dlc3d_cfg['scorername_3d']

        bodyparts2connect = dlc3d_cfg['skeleton']
        bodyparts2plot = list(np.unique([val for sublist in bodyparts2connect for val in sublist]))
        color = plt.cm.get_cmap(cmap, len(bodyparts2plot))

        cam1, cam2 = pair

        if video_dir_hierarchy is True:
            hierarchy, _ = detect_videos_in_hierarchy(
                video_root, deep_dict=True
            )
            for exp_id, pairs in hierarchy.items():
                for pair_info, cams in pairs.items():
                    pair_idx, cam1, cam2 = pair_info.split('_')
                    pair = (cam1, cam2)
                    cam1_video, cam2_video = cams.values()
                    info = exp_id
                    futures[create_video(
                        # Paths
                        (triangulate_path / exp_id / pair_info), cam1_video, cam2_video,
                        # ID
                        info, pair,
                        # Config
                        dlc3d_cfg, pcutoff, markerSize, alphaValue, cmap, skeleton_color, scorer_3d,
                        bodyparts2plot, bodyparts2connect, color,
                        # Style
                        origin_to_remove=orig_maps[pair]['origin'] if remove_origin is True else None,
                        new_path=True
                    )] = (*info, pair)

        else:
            if video_root is None:
                video_root = os.path.join(os.path.dirname(dlc3d_cfg_path), 'videos')
            else:
                video_root = os.path.realpath(video_root)

            cam1_videos = glob(os.path.join(video_root, (f'*{cam1}*')))
            cam2_videos = glob(os.path.join(video_root, (f'*{cam2}*')))

            with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
                for i, v_path in enumerate(cam1_videos):
                    _, video_name = os.path.split(v_path)
                    cam1_video, cam2_video = cam1_videos[i], cam2_videos[i]
                    info = video_name.replace('.avi', '').split('_')
                    futures[executor.submit(create_video,
                        # Paths
                        triangulate_path, cam1_video, cam2_video,
                        # ID
                        info, pair,
                        # Config
                        dlc3d_cfg, pcutoff, markerSize, alphaValue, cmap, skeleton_color, scorer_3d,
                        bodyparts2plot, bodyparts2connect, color,
                        # Style
                        origin_to_remove=orig_maps[pair]['origin'] if remove_origin is True else None,
                        new_path=True, fps=fps
                    )] = (*info, pair)

    for future in concurrent.futures.as_completed(futures):
        video_id = futures[future]
        try:
            result = future.result()
        except Exception as exc:
            print('%s generated an exception: %s' % (video_id, exc))
        else:
            print('%s = %s' % (video_id, result))

    os.chdir(start_path)
Ejemplo n.º 8
0
def visualize_workflow(config_path, undistort=True, normalize=True, decrement=False, save=True):
    '''
    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    '''
    import matplotlib.image as image

    dlc3d_cfgs = get_dlc3d_configs(config_path)
    basis_labels = get_labels(config_path)

    cfg = read_config(config_path)
    test_dir = os.path.join(cfg['data_path'], 'test')
    figure_dir = os.path.join(test_dir, 'visualize_workflow')
    if not os.path.exists(figure_dir):
        os.makedirs(figure_dir)

    n = np.linspace(-1, 5, 100)
    pairs = tuple(dlc3d_cfgs.keys())
    for pair in pairs:
        cam1, cam2 = pair

        fig = plt.figure(figsize=(12, 10))
        ax = {
            'trian': fig.add_subplot(221, projection='3d'),
            'basis': fig.add_subplot(222, projection='3d'),
            'cam1': fig.add_subplot(223),
            'cam2': fig.add_subplot(224)
        }
        
        # Get camera plot labels
        cam_labels = get_paired_labels(config_path, pair)['decrement' if decrement is True else 'normal']

        # Plot manual labels
        for cam, cax in zip(pair, (ax['cam1'], ax['cam2'])):
            # Add respective calibration image as background
            img_cam = image.imread(glob(os.path.join(cfg['calibration_path'], cam+'*'))[0])
            cax.imshow(img_cam)

            cmap = iter(plt.cm.rainbow(np.linspace( 0, 1, len(cam_labels[cam]) )))
            for (label, coord), color in zip(cam_labels[cam].items(), cmap):
                cax.set_title((cam, 'labels')).set_y(1.005)
                cax.scatter(*coord, c=color, label=label)
                cax.legend()

        # Triangulate the two sets of labels, and map them to 3D
        dlc3d_cfg = dlc3d_cfgs[pair]
        trian_dict, trian = triangulate_basis_labels(
            dlc3d_cfg, cam_labels, pair, undistort=undistort, decrement=decrement, keys=True
        )

        cmap = iter(plt.cm.rainbow(np.linspace( 0, 1, len(trian_dict)+1) ))
        for (label, coord), color in zip(trian_dict.items(), cmap):
            ax['trian'].scatter(*(coord - trian_dict['origin']), c=color, label=label)

        if CAMERAS[cam1][0][1] == 'left':
            c_origin = trian[0] + (trian[1] - trian[0]) / 2
        else:
            c_origin = trian[1] + (trian[0] - trian[1]) / 2
        c_origin -= trian_dict['origin']
        ax['trian'].scatter(*c_origin, c=next(cmap), label='computed origin')

        ax['trian'].set_title('Triangualted').set_y(1.005)
        ax['trian'].legend()

        ax['trian'].set_xlabel('X', fontsize=10)
        ax['trian'].set_ylabel('Y', fontsize=10)
        ax['trian'].set_zlabel('Z', fontsize=10)

        _, orig_map = compute_basis_vectors(trian, pair, normalize=normalize, decrement=decrement)

        r = []
        for axis in orig_map['map'].T:
            r.append(n * axis[np.newaxis, :].T)

        r_1, r_2, r_3 = r
        ax['basis'].plot(*r_1, label='r1/x')
        ax['basis'].plot(*r_2, label='r2/y')
        ax['basis'].plot(*r_3, label='r3/z')

        # Angles
        i, ii, iii = orig_map['map'].T
        i_ii = vg.angle(i, ii)
        i_iii = vg.angle(i, iii)
        ii_iii = vg.angle(ii, iii)

        title_text2 = 'r1-r2: %3f r1-r3: %3f\nr2-r3: %3f' % (i_ii, i_iii, ii_iii)

        ax['basis'].set_title(title_text2).set_y(1.005)
        ax['basis'].legend()

        ax['basis'].set_xticklabels([])
        ax['basis'].set_yticklabels([])
        ax['basis'].set_zticklabels([])
        ax['basis'].set_xlabel('X', fontsize=10)
        ax['basis'].set_ylabel('Y', fontsize=10)
        ax['basis'].set_zlabel('Z', fontsize=10)

        if save is True:
            fig.savefig( os.path.join(figure_dir, '%d_%s_%s.png' % (PAIR_IDXS[pair], *pair)) )

    return fig, ax
Ejemplo n.º 9
0
def visualize_basis_vectors_single(config_path, undistort=True, normalize=True, decrement=False, stereo_cam_units=None, save=True):
    '''
    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    '''
    if stereo_cam_units is None:
        stereo_cam_units, orig_maps = create_stereo_cam_origmap(
            config_path, undistort=undistort, normalize=normalize, decrement=False, save=False
        )

    dlc3d_cfgs = get_dlc3d_configs(config_path)

    cfg = read_config(config_path)
    test_dir = os.path.join(cfg['data_path'], 'test')
    if not os.path.exists(test_dir):
        os.mkdir(test_dir)

    pairs = tuple(dlc3d_cfgs.keys())
    cmap = iter(plt.cm.rainbow(np.linspace(0, 1, 2*len(pairs)-2)))

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    c_spacing = 1 / (len(pairs) - 2)
    for i, pair in enumerate(pairs):
        cam1, cam2 = pair

        rem_space = c_spacing * i
        cmap = plt.cm.rainbow(np.linspace(rem_space, rem_space+0.12, 3))

        ax.plot(
            [0, stereo_cam_units[pair]['x-axis'][0]],
            [0, stereo_cam_units[pair]['x-axis'][1]],
            [0, stereo_cam_units[pair]['x-axis'][2]],
            label='%s %s r1/x' % pair, c=cmap[0]
        )
        # ax.text(*t_1, label='r1', c=cmap[0])

        ax.plot(
            [0, stereo_cam_units[pair]['y-axis'][0]],
            [0, stereo_cam_units[pair]['y-axis'][1]],
            [0, stereo_cam_units[pair]['y-axis'][2]],
            label='%s %s r2/y' % pair, c=cmap[1]
        )
        # ax.text(*t_2, label='r2', c=cmap[1])

        ax.plot(
            [0, stereo_cam_units[pair]['z-axis'][0]],
            [0, stereo_cam_units[pair]['z-axis'][1]],
            [0, stereo_cam_units[pair]['z-axis'][2]],
            label='%s %s r3/z' % pair, c=cmap[2]
        )
        # ax.text(*t_3, label='r3', c=cmap[2])

    ax.set_title('Basis comparison', fontsize=20).set_y(1.005)
    ax.legend(loc=2)

    if save is True:
        fig.savefig( os.path.join(test_dir, 'visualize_basis_vectors.png') )

    return fig, ax
Ejemplo n.º 10
0
def map_experiment(config_path,
                   undistort=True,
                   percentiles=(5, 95),
                   use_saved_origmap=True,
                   normalize=True,
                   suffix='_DLC_3D.h5',
                   bonvideos=False,
                   save=True,
                   paralell=False,
                   label_getter=None,
                   **kwargs):
    '''
    This function changes the basis of deeplabcut-triangulated that are 3D.

    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    linear_maps : {string: numpy.array}
        (3, 3) array that stores the linear map for changing basis
    suffix : string
        The suffix in the DeepLabCut 3D project triangualtion result storage files
    cbv_kwargs : dictionary
        Keyword arguments for compute_basis_vectors()

    Example
    -------

    '''
    coords, likelihoods = detect_triangulation_result(config_path,
                                                      undistorted=undistort,
                                                      suffix=suffix,
                                                      change_basis=True,
                                                      bonvideos=bonvideos)
    print(likelihoods)
    if coords is False:
        print(
            'According to the DeepCage triangulated coordinates detection algorithm this project is not ready for changing basis'
        )
        return False

    cfg = read_config(config_path)
    data_path = os.path.realpath(cfg['data_path'])
    result_path = cfg['results_path']

    dlc3d_cfgs = get_dlc3d_configs(config_path)

    if use_saved_origmap is True:
        basis_result_path = os.path.join(data_path, 'cb_result.pickle')
        try:
            with open(basis_result_path, 'rb') as infile:
                stereo_cam_units, orig_maps = pickle.load(infile)
        except FileNotFoundError:
            msg = 'Could not detect results from deepcage.compute.generate_linear_map() in:\n' \
                  + basis_result_path
            raise FileNotFoundError(msg)
    else:
        stereo_cam_units, orig_maps = create_stereo_cam_origmap(
            config_path,
            undistort=undistort,
            decrement=False,
            save=False,
            normalize=normalize,
            **kwargs)

    dfs = {}
    cpu_cores = cpu_count(logical=False)
    if paralell is False or cpu_cores < 2:
        for info, pair_roi_df in coords.items():
            # info = (animal, trial, date)
            dfs[info] = sort_coords_in_df(pair_roi_df, orig_maps, percentiles)

    else:
        submissions = {}
        workers = 4 if cpu_cores < 8 else 8
        with concurrent.futures.ProcessPoolExecutor(
                max_workers=workers) as executor:
            for info, pair_roi_df in coords.items():
                # info = (animal, trial, date)
                submissions[executor.submit(sort_coords_in_df, pair_roi_df,
                                            orig_maps)] = info

            for future in submissions:
                info = submissions[future]
                if info not in dfs:
                    dfs[info] = {}
                try:
                    dfs[info][(roi, pair)] = future.result()
                except Exception as exc:
                    print('%s generated an exception: %s' %
                          (submissions[future], exc))

    if save is True:
        # print('Attempting to save new coordinates to result folder:\n%s' % result_path)
        for info, df in dfs.items():
            df_name = 'mapped'
            for i in info.split('_'):
                df_name += '_' + i

            file_path = os.path.join(result_path, df_name)

            df.to_hdf(file_path + '.h5',
                      key=df_name if bonvideos is False else 'a%st%sd%s' %
                      info)
            df.to_csv(file_path + '.csv')
            df.to_excel(file_path + '.xlsx')

            print('The mapped coordinates of %s have been saved to\n%s\n' %
                  (info, file_path))

    print('DONE: Basis changed')
    return dfs
Ejemplo n.º 11
0
def create_stereo_cam_origmap(config_path,
                              undistort=True,
                              decrement=False,
                              save=True,
                              labels_are2d=True,
                              labels_getter=get_paired_labels,
                              basis_computer=compute_basis_vectors,
                              **cbv_kwargs):
    '''
    Parameters
    ----------
    config_path : string
        Absolute path of the project config.yaml file.
    cbv_kwargs : dictionary
        Keyword arguments for compute_basis_vectors()
    '''

    cfg = read_config(config_path)
    dlc3d_cfgs = get_dlc3d_configs(config_path)
    data_path = os.path.realpath(cfg['data_path'])

    if save is True:
        basis_result_path = os.path.join(data_path, 'cb_result.pickle')
        dataframe_path = os.path.join(data_path, 'basis_vectors.xlsx')
        if os.path.exists(basis_result_path) and os.path.exists(
                dataframe_path):
            msg = f'Please remove old analysis files before proceeding. File paths:\n{basis_result_path}\n{dataframe_path}'
        elif os.path.exists(basis_result_path):
            msg = f'Please remove old analysis file before proceeding. File paths:\n{basis_result_path}'
        elif os.path.exists(dataframe_path):
            msg = f'Please remove old analysis file before proceeding. File paths:\n{dataframe_path}\n'

    pairs = tuple(dlc3d_cfgs.keys())
    stereo_cam_units, orig_maps = {}, {}
    for pair in pairs:
        cam1, cam2 = pair
        dlc3d_cfg = dlc3d_cfgs[pair]

        basis_labels = labels_getter(config_path, pair)
        if labels_getter is get_paired_labels:
            basis_labels = basis_labels[
                'decrement' if decrement is True else 'normal']

        if labels_are2d is True:
            trian = triangulate_basis_labels(dlc3d_cfg,
                                             basis_labels,
                                             pair,
                                             undistort=undistort,
                                             decrement=decrement)
        else:
            trian = basis_labels

        stereo_cam_units[pair], orig_maps[pair] = basis_computer(
            trian, pair, decrement=decrement, **cbv_kwargs)

    if save is True:
        with open(basis_result_path, 'wb') as outfile:
            pickle.dump((stereo_cam_units, orig_maps), outfile)
            print('Saved linear map to:\n{}'.format(basis_result_path))

        pd.DataFrame.from_dict(stereo_cam_units).to_excel(dataframe_path)
        print('Saved excel file containing the computed basis vectors to:\n{}'.
              format(dataframe_path))

    print('Returning dictionary containing the computed linear maps')

    return stereo_cam_units, orig_maps