          """
          key = event.key.lower()
          if key not in self._callbacks:
              return
  
          logger.debug("Preview window keypress '%s' received", key)
          if key == "r":
              print("\n")  # Let log print on different line from loss output
              logger.info("Refresh preview requested...")
  
          with self._lock:
              if key == "f":
                  self._toggle_size()
              else:
                  self._triggers[self._callbacks[key]] = True
  
      def _on_resize(self,
                     event: backend_bases.ResizeEvent) -> None:  # noqa # pylint:disable=unused-argument
          """ If the display is set to `actual size` then the image needs to be resized on any window
          resize event. """
          for fig, size in self._images.values():
              fig.set_size_inches(size)
  
      def _on_close(self,
                     event: backend_bases.CloseEvent) -> None:  # noqa # pylint:disable=unused-argument
          """ Force an update when the figure has been closed to relaunch it. """
          logger.debug("Preview close detected")
          with self._lock:
              self._needs_update = True
 
</s> remove         Parameters
        ----------
        event:
            The key press received
        """
        key = event.key.lower()
        if key not in self._callbacks:
 </s> add     def shutdown(self) -> None:
        """ Send a signal to shutdown the preview window. """
        if not self._active: </s> remove                 if trigger == "update":
                    print("\n")  # Let log print on different line from loss output
 </s> add                 if trigger == "refresh":
                    print("")  # Let log print on different line from loss output </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 </s> remove                 getattr(self._preview, parent_flags[trigger])()
 </s> add         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
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
          """
          key = event.key.lower()
          if key not in self._callbacks:
              return
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
        logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set()
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
 Training - Use custom preview pop-out 
scripts/train.py