      @classmethod
      def estimate_blur_fft(cls, image, metadata=None):
          """ Estimate the amount of blur a fft filtered image has.
  
          Parameters
          ----------
          image: :class:`numpy.ndarray`
              Use Fourier Transform to analyze the frequency characteristics of the masked
              face using 2D Discrete Fourier Transform (DFT) filter to find the frequency domain.
              A mean value is assigned to the magnitude spectrum and returns a blur score.
              Adapted from https://www.pyimagesearch.com/2020/06/15/
              opencv-fast-fourier-transform-fft-for-blur-detection-in-images-and-video-streams/
          metadata: dict, optional
              The metadata for the face image or ``None`` if no metadata is available. If metadata is
              provided the face will be masked by the "components" mask prior to calculating blur.
              Default:``None``
  
          Returns
          -------
          float
              The estimated fft blur score for the face
 
</s> remove         image: :class:`numpy.ndarray`
            The face image to calculate blur for
        metadata: dict, optional
            The metadata for the face image or ``None`` if no metadata is available. If metadata is
            provided the face will be masked by the "components" mask prior to calculating blur.
            Default:``None``

        Returns
        -------
        float
            The estimated blur score for the face
 </s> add         source: str
            The full path to the source file that is being sorted
        destination: str
            The full path to where the source file should be moved/renamed </s> remove     @classmethod
    def estimate_blur_fft(cls, image, metadata=None):
        """ Estimate the amount of blur a fft filtered image has.
 </s> add         if self._args.log_changes:
            self._changes[source] = destination </s> remove         Returns
        -------
        float
            The estimated fft blur score for the face
 </s> add         Obtains the bins and original filenames from :attr:`_sorter` and outputs into appropriate
        bins in the output location </s> remove         if metadata is not None:
            alignments = metadata["alignments"]
            det_face = DetectedFace()
            det_face.from_png_meta(alignments)
            aln_face = AlignedFace(np.array(alignments["landmarks_xy"], dtype="float32"),
                                   image=image,
                                   centering="legacy",
                                   size=256,
                                   is_aligned=True)
            mask = det_face.mask["components"]
            mask.set_sub_crop(aln_face.pose.offset[mask.stored_centering],
                              aln_face.pose.offset["legacy"],
                              centering="legacy")
            mask = cv2.resize(mask.mask, (256, 256), interpolation=cv2.INTER_CUBIC)[..., None]
            image = np.minimum(aln_face.face, mask)
        if image.ndim == 3:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        blur_map = cv2.Laplacian(image, cv2.CV_32F)
        score = np.var(blur_map) / np.sqrt(image.shape[0] * image.shape[1])
        return score
 </s> add         try:
            if self._args.keep_original:
                copyfile(source, destination)
            else:
                os.rename(source, destination)
        except FileNotFoundError as err:
            logger.error("Failed to sort '%s' to '%s'. Original error: %s",
                         source, destination, str(err)) </s> remove     @classmethod
    def estimate_blur(cls, image, metadata=None):
        """ Estimate the amount of blur an image has with the variance of the Laplacian.
        Normalize by pixel number to offset the effect of image size on pixel gradients & variance.
 </s> add     def _sort_file(self, source: str, destination: str) -> None:
        """ Copy or move a file based on whether 'keep original' has been selected and log changes
        if required.
    def _output_groups(self) -> None:
        """ Move the files to folders.
      @classmethod
      def estimate_blur_fft(cls, image, metadata=None):
          """ Estimate the amount of blur a fft filtered image has.
  
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
    def _output_groups(self) -> None:
        """ Move the files to folders.
  
          Returns
          -------
          float
              The estimated fft blur score for the face
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Overhaul sort:
  - Standardize image data reading and writing
  - Optimize loading (just one pass required)
  - Make all sort groups binnable (to greater or lesser results)
  - Add sort by pitch
  - Deprecate multiple options
  - linting, docs + locales 
tools/sort/sort.py