              raise err
          logger.debug("Updated preview: (name: %s)", name)
  
  
  class Preview():
      """ Holds the pop up preview window and options relating to the preview in the window and the
      GUI. Thread safe to take requests from the main thread and the training thread. """
      def __init__(self) -> None:
          self._lock = Lock()
          self._dpi: float = 0.0
          self._triggers: Dict[str, bool] = dict(toggle_mask=False,
                                                 full_size=False,
                                                 refresh=False,
                                                 save=False,
                                                 quit=False)
          self._needs_update: bool = False
          self._preview_buffer: Dict[str, np.ndarray] = {}
          self._images: Dict[str, Tuple[figure.Figure, Tuple[float, float]]] = {}
          self._resize_ids: List[Tuple[figure.Figure, int]] = []
          self._callbacks = dict(f="full_size",
                                 m="toggle_mask",
                                 r="refresh",
                                 s="save",
                                 enter="quit")
          self._configure_matplotlib()
  
      def _toggle_size(self) -> None:  # pylint:disable=unused-argument
          """ Toggle between actual size and screen-fit size. """
          self._triggers["full_size"] = not self._triggers["full_size"]
          self._set_resize_callback()
  
      @classmethod
      def _configure_matplotlib(cls):
          """ Remove `F`, 'S' and 'R' from their default bindings and stop Matplotlib from stealing
          focus """
          rcParams["keymap.fullscreen"] = [k for k in rcParams["keymap.fullscreen"] if k != "f"]
          rcParams["keymap.save"] = [k for k in rcParams["keymap.save"] if k != "s"]
          rcParams["keymap.home"] = [k for k in rcParams["keymap.home"] if k != "r"]
          rcParams["figure.raise_window"] = False
  
      def should_toggle_mask(self) -> bool:
          """ Check whether the mask should be toggled and return the value. If ``True`` is returned
          then resets mask toggle back to ``False``
  
 
</s> remove         """ Check whether the mask should be toggled and return the value. If ``True`` is returned
        then resets mask toggle back to ``False``

        Returns
        -------
        bool
            ``True`` if the mask should be toggled otherwise ``False``. """
        with self._lock:
            retval = self._triggers["toggle_mask"]
            if retval:
                logger.debug("Sending toggle mask")
                self._triggers["toggle_mask"] = False
 </s> add         """ bool: Check whether the mask should be toggled and return the value. If ``True`` is
        returned then resets mask toggle back to ``False`` """
        if not self._active:
            return False
        retval = self._triggers["toggle_mask"].is_set()
        if retval:
            logger.debug("Sending toggle mask")
            self._triggers["toggle_mask"].clear() </s> remove         """ Check whether the preview should be updated and return the value. If ``True`` is
        returned then resets the refresh trigger back to ``False``

        Returns
        -------
        bool
            ``True`` if the preview should be refreshed otherwise ``False``. """
        with self._lock:
            retval = self._triggers["refresh"]
            if retval:
                logger.debug("Sending should refresh")
                self._triggers["refresh"] = False
            return retval
 </s> add         """ bool: Check whether the preview should be updated and return the value. If ``True`` is
        returned then resets the refresh trigger back to ``False`` """
        if not self._active:
            return False
        retval = self._triggers["refresh"].is_set()
        if retval:
            logger.debug("Sending should refresh")
            self._triggers["refresh"].clear()
        return retval </s> remove         logger.debug("Creating figure '%s' for image shape %s", name, image_shape)
        if not self._dpi:
            self._dpi = get_dpi()
        height, width = image_shape[:2]
        size = width / self._dpi, height / self._dpi
        fig = plt.figure(name, figsize=size)
        axes = plt.Axes(fig, [0., 0., 1., 1.])  # Remove axes and whitespace
        axes.set_axis_off()
        fig.add_axes(axes)
        fig.canvas.mpl_connect("key_press_event", self._on_key_press)
        fig.canvas.mpl_connect("close_event", self._on_close)
        logger.debug("Created display figure of size: %s", size)
        self._images[name] = (fig, size)

    def _set_resize_callback(self):
        """ Sets the resize callback if displaying preview at actual size or removes it if
        displaying at screen-fit size. """
        if self._triggers["full_size"]:
            logger.debug("Setting resize callback for actual size display")
            for fig, size in self._images.values():
                self._resize_ids.append((fig, fig.canvas.mpl_connect("resize_event",
                                                                     self._on_resize)))
                fig.set_size_inches(size)
        else:
            logger.debug("Removing resize callback for screen-fit display")
            for fig, cid in self._resize_ids:
                fig.canvas.mpl_disconnect(cid)
            self._resize_ids = []

    def _on_key_press(self, event: backend_bases.KeyEvent) -> None:
        """ Callbacks for keypresses to update the requested trigger.

        - `F` (toggle full-size/fit to window)
        - `M` (toggle mask),
        - `R` (refresh preview),
        - `S` (save now)
        - `Enter` (save and exit)
 </s> add         if not self._active:
            return None
        thread = FSThread(target=Preview,
                          name="preview",
                          args=(self._buffer, ),
                          kwargs=dict(triggers=self._triggers))
        thread.start()
        return thread </s> remove     def request_refresh(self) -> None:
        """ Handle a GUI trigger or a training thread trigger (after a mask toggle) request to set
        the refresh trigger to ``True`` to request a refresh on the next pass of the
        training loop. """
        with self._lock:
            self._triggers["refresh"] = True

    def request_mask_toggle(self) -> None:
        """ Handle a GUI trigger request to set the mask toggle to ``True`` to
        request a mask toggle on next pass of the training loop. """
        logger.verbose("Toggle mask display requested...")  # type:ignore
        with self._lock:
            self._triggers["toggle_mask"] = True

    def add_image(self, name: str, image: np.ndarray) -> None:
        """ Add a preview image to the preview buffer.

        Parameters
        ----------
        name: str
            The name of the preview image to add to the buffer
        image: :class:`numpy.ndarray`
            The preview image to add to the buffer in BGR format.
        """
        with self._lock:
            logger.debug("Adding image '%s' of shape %s to preview buffer", name, image.shape)
            self._preview_buffer[name] = image[..., 2::-1]  # Switch to RGB
            self._needs_update = True

    def display_preview(self) -> None:
        """ Display an image preview in a resizable window. """
        if self._needs_update:
            logger.debug("Updating preview")
            with self._lock:
                for name, image in self._preview_buffer.items():
                    if (name not in self._images or  # new preview or preview was closed
                            not plt.fignum_exists(self._images[name][0].number)):
                        self._create_resizable_window(name, image.shape)
                        if self._triggers["full_size"]:  # Can only be true if preview was closed
                            self._set_resize_callback()
                    plt.figure(name)
                    plt.imshow(image)
                self._needs_update = False
            plt.show(block=False)
            logger.debug("preview updated")  # type: ignore
        plt.pause(0.1)

    def _create_resizable_window(self, name: str, image_shape: tuple) -> None:
        """ Create a resizable Matplotlib window to hold the preview image.
 </s> add     def _launch_thread(self) -> Optional[FSThread]:
        """ Launch the preview viewer in it's own thread if preview has been selected
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
              raise err
          logger.debug("Updated preview: (name: %s)", name)
  
  
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
class PreviewInterface():
    """ Run the preview window in a thread and interface with it
  
      def should_toggle_mask(self) -> bool:
          """ Check whether the mask should be toggled and return the value. If ``True`` is returned
          then resets mask toggle back to ``False``
  
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Training - Use custom preview pop-out 
scripts/train.py