예제 #1
0
def plot_plate_trajectories(featurefilepath, 
                            saveDir=None, 
                            downsample=10,
                            filter_trajectories=False,
                            mark_endpoints=False,
                            del_if_exists=False):
    """ Tile plots and merge into a single plot for the 
        entire 96-well plate, correcting for camera orientation. """

    file_dict = get_video_set(featurefilepath)
    
    # define multi-panel figure
    columns = 3
    rows = 2
    x = 25.5
    y = 16
    plt.ioff() if saveDir else plt.ion()
    plt.close('all')
    fig, axs = plt.subplots(rows,columns,figsize=[x,y])
    
    x_offset = 1.5 / x  # for bottom left image
    width = 0.3137      # for all but top left image
    width_tl = 0.3725   # for top left image
    height = 0.5        # for all images

    errlog = []    
    for channel, (maskedfilepath, featurefilepath) in file_dict.items():

        if saveDir:
            saveName = maskedfilepath.parent.stem + ('_filtered.png' if filter_trajectories else '.png')
            savePath = Path(saveDir) / saveName
            if savePath.exists():
                if del_if_exists:
                    os.remove(savePath)
                else:
                    print("Skipping file '%s' (already exists)" % savePath.name)
                    continue
        
        _loc, rotate = CH2PLATE_dict[channel]
        _ri, _ci = _loc

        # create bbox for image layout in figure
        if (_ri == 0) and (_ci == 0):
            # first image (with well names), bbox slightly shifted
            bbox = [0, height, width_tl, height]
        else:
            # other images
            bbox = [x_offset + width * _ci, height * (rows - (_ri + 1)), width, height]   
        
        # get location of subplot for camera
        ax = axs[_loc]
        
        try:
            # plot first frame of video + annotate wells
            FOVsplitter = FOVMultiWellsSplitter(maskedfilepath)
            FOVsplitter.plot_wells(is_rotate180=rotate, ax=ax, line_thickness=10)
            
            # plot worm trajectories
            plot_trajectory(featurefilepath, 
                            downsample=downsample,
                            filter_trajectories=filter_trajectories,
                            mark_endpoints=mark_endpoints,
                            rotate=rotate,
                            img_shape=FOVsplitter.img_shape,
                            legend=False, 
                            ax=ax)
        except Exception as e:
            print("WARNING: Could not plot video file: '%s'\n%s" % (maskedfilepath, e))
            errlog.append(maskedfilepath)
        
        # set image position in figure
        ax.set_position(bbox)
    
    if saveDir:
        if savePath.exists():
            print("Skipping file '%s' (already exists)" % savePath.name)
        else:
            Path(saveDir).mkdir(exist_ok=True, parents=True)
            fig.savefig(savePath,
                        bbox_inches='tight',
                        dpi=300,
                        pad_inches=0,
                        transparent=True)
    
    print(errlog) # TODO: Save errlog to file?
    return
def plot_plate_trajectories(featurefilepath, saveDir=None, downsample=10):
    """ Tile plots and merge into a single plot for the
        entire 96-well plate, correcting for camera orientation. """

    from tierpsy.analysis.split_fov.FOVMultiWellsSplitter import FOVMultiWellsSplitter

    file_dict = get_video_set(featurefilepath)

    # define multi-panel figure
    columns = 3
    rows = 2
    h_in = 6
    x_off_abs = (3600 - 3036) / 3036 * h_in
    x = columns * h_in + x_off_abs
    y = rows * h_in
    fig, axs = plt.subplots(rows, columns, figsize=[x, y])

    x_offset = x_off_abs / x  # for bottom left image
    width = (1 - x_offset) / columns  # for all but top left image
    width_tl = width + x_offset  # for top left image
    height = 1 / rows  # for all images

    for channel, ch_featfilepath in file_dict.items():

        _loc, rotate = CH2PLATE_dict[channel]
        _ri, _ci = _loc

        # create bbox for image layout in figure
        if (_ri == 0) and (_ci == 0):
            # first image (with well names), bbox slightly shifted
            bbox = [0, height, width_tl, height]
        else:
            # other images
            bbox = [
                x_offset + width * _ci, height * (rows - (_ri + 1)), width,
                height
            ]

        # get location of subplot for camera
        ax = axs[_loc]

        # plot first frame of video + annotate wells
        fovsplitter = FOVMultiWellsSplitter(ch_featfilepath)
        # let's check if the fovsplitter managed to get a frame automatically
        if fovsplitter.img is None:
            fovsplitter.img = get_frame_from_raw(feat2raw(ch_featfilepath))

        fovsplitter.plot_wells(is_rotate180=rotate, ax=ax, line_thickness=10)

        # plot worm trajectories
        plot_trajectory(ch_featfilepath,
                        ax=ax,
                        downsample=downsample,
                        legend=False,
                        rotate=rotate,
                        img_shape=fovsplitter.img_shape)

        # set image position in figure
        ax.set_position(bbox)

    plt.show()
    if saveDir:
        saveName = Path(featurefilepath).parent.stem + '.png'
        savePath = Path(saveDir) / saveName
        fig.savefig(savePath,
                    bbox_inches='tight',
                    dpi=300,
                    pad_inches=0,
                    transparent=True)
    return (fig)