def updateVideoFile(self, vfilename):

        # close the if there was another file opened before.
        if self.fid is not None:
            self.fid.close()
            self.mainImage.cleanCanvas()
            self.fid = None
            self.image_group = None
            self.imgstore_name = ''
            self.fovsplitter = None
            self.well_name = ''
            self.well_names = []
            self.tiles = None
            self.ui.wells_comboBox.clear()
            self.wells_df = None

        self.vfilename = vfilename
        self.imgstore_name = Path(vfilename).parent.name
        self.ui.label_vid.setText(self.imgstore_name)
        # self.videos_dir = self.vfilename.rpartition(os.sep)[0] + os.sep

        # try:
        #     with tables.File(vfilename, 'r') as fid:
        #         if '/fov_wells' not in fid:
        #             QMessageBox.critical(self, '',
        #                                  "The FOV was not split",
        #                                  QMessageBox.Ok)
        #             return
        # except (IOError, tables.exceptions.HDF5ExtError):
        #     self.fid = None
        #     self.image_group = None
        #     QMessageBox.critical(
        #         self, '',
        #         "The selected file is not a valid .hdf5. Please select a valid file",
        #         QMessageBox.Ok)
        #     return

        fovsplitter = FOVMultiWellsSplitter(self.vfilename)
        with tables.File(vfilename) as fid:
            img_stack = fid.get_node('/full_data').read().copy()
        tiles_list = fovsplitter.tile_FOV(img_stack)

        self.wells_df = fovsplitter.wells.copy().set_index('well_name')
        self.tiles = {k: v for (k, v) in tiles_list}
        self.well_names = self.wells_df.index.to_list()
        self.ui.wells_comboBox.clear()
        for wi, wn in enumerate(self.well_names):
            self.ui.wells_comboBox.addItem(wn)
        self.updateImGroup(0)
def plot_well_trajectory(featuresfilepath,
                         maskedvideopath,
                         well_name,
                         downsample=10,
                         filter_trajectories=False,
                         ax=None,
                         verbose=True,
                         **kwargs):
    """ Plot centroid coordinates for worms in a given well """

    # plot first frame of video for sample well
    FOVsplitter = FOVMultiWellsSplitter(maskedvideopath)
    fov_wells = FOVsplitter.wells
    well_fov = fov_wells[fov_wells['well_name'] == well_name]

    if well_fov.iloc[0]['is_good_well'] != 1:
        print("WARNING: Bad well data for:\n%s\t%s" %
              (featuresfilepath, well_name))
        return

    if not ax:
        fig, ax = plt.subplots(**kwargs)

    img_list = FOVsplitter.tile_FOV(FOVsplitter.img)
    well_img = [i[1] for i in img_list if i[0] == well_name][0]

    ax.imshow(well_img, cmap='gray')

    df = read_timeseries(featuresfilepath,
                         names=[
                             'worm_index', 'timestamp', 'well_name',
                             'coord_x_body', 'coord_y_body'
                         ],
                         only_wells=[well_name])

    microns_per_pixel = read_microns_per_pixel(featuresfilepath)
    df['x'] = df['coord_x_body'] / microns_per_pixel
    df['y'] = df['coord_y_body'] / microns_per_pixel

    # subtract x,y offset to set bottom left coords of well as plot origin for trajectory plot
    df['x'] = df['x'] - well_fov.iloc[0]['x_min']
    df['y'] = df['y'] - well_fov.iloc[0]['y_min']

    # Optional - filter trajectories using movement/time threshold parameters (globals)
    if filter_trajectories:
        df, _ = filter_worm_trajectories(
            df,
            threshold_move=THRESHOLD_DISTANCE_PIXELS,
            threshold_time=THRESHOLD_DURATION_FRAMES,
            fps=read_fps(featuresfilepath),
            microns_per_pixel=microns_per_pixel,
            timestamp_col='timestamp',
            worm_id_col='worm_index',
            x_coord_col='x',
            y_coord_col='y',
            verbose=verbose)

    # Plot trajectory
    if downsample is not None:
        # Downsample frames for plotting
        downsample = 1 if downsample < 1 else downsample

        ax.scatter(x=df['x'][::downsample],
                   y=df['y'][::downsample],
                   c=df['timestamp'][::downsample],
                   cmap='plasma',
                   s=7)
    else:
        ax.scatter(x=df['x'], y=df['y'], c=df['timestamp'], cmap='plasma', s=7)

    ax.axes.get_xaxis().set_visible(False)
    ax.axes.get_yaxis().set_visible(False)
    ax.autoscale(enable=True, axis='x', tight=True)  # re-scaling axes
    ax.autoscale(enable=True, axis='y', tight=True)

    return