          logger.info("Sorting by ward linkage...")
  
          indices = self._vgg_face.sorted_similarity(np.array(preds), method="ward")
          img_list = np.array(filenames)[indices]
  
          if no_hash:
              logger.warning("%s image(s) were not found in the alignments file. This will likely "
                             "result in sub-par sorting results, so you should check the output "
                             "carefully", no_hash)
  
          return img_list
  
      def sort_face_cnn(self):
          """ Sort by landmark similarity """
          logger.info("Sorting by landmark similarity...")
 
</s> remove             preds.append(self._vgg_face.predict(image))
 </s> add             preds.append(self._vgg_face.predict(face)) </s> remove         ratio = _EXTRACT_RATIOS["legacy"] / _EXTRACT_RATIOS["head"]
 </s> add  </s> remove         no_hash = 0
        for filename, image, hsh in tqdm(self._loader.load(),
                                         desc="Classifying Faces...",
                                         total=self._loader.count):
            if self._alignments is not None and self._alignments.version != 1.0:
                face = self._alignments.hashes_to_alignment.get(hsh)
                if face:
                    image = AlignedFace(face["landmarks_xy"],
                                        image=image,
                                        centering="legacy",
                                        size=self._vgg_face.input_size,
                                        is_aligned=True).face
                elif image.shape[0] != image.shape[1]:
                    logger.warning("Skipping image '%s' as it is not square (probably not a "
                                   "face)", filename)
                    continue
                else:  # Center crop the image and add count to warning count
                    center = image.shape[0] // 2
                    crop = slice(center - int(center * ratio), center + int(center * ratio))
                    image = image[crop, crop, :]
                    no_hash += 1

 </s> add         for filename, image, metadata in tqdm(self._loader.load(),
                                              desc="Classifying Faces...",
                                              total=self._loader.count,
                                              leave=False):
            if not metadata:
                msg = ("The images to be sorted do not contain alignment data. Images must have "
                       "been generated by Faceswap's Extract process.\nIf you are sorting an "
                       "older faceset, then you should re-extract the faces from your source "
                       "alignments file to generate this data.")
                raise FaceswapError(msg)
            alignments = metadata["alignments"]
            face = AlignedFace(np.array(alignments["landmarks_xy"], dtype="float32"),
                               image=image,
                               centering="legacy",
                               size=self._vgg_face.input_size,
                               is_aligned=True).face </s> remove                  "in your set and order them appropriately. NB: You should provide an alignments "
                 "file if using this method. Not doing so will lead to vastly inferior results."
 </s> add                  "in your set and order them appropriately." </s> remove     def _get_alignments(self):
        """ Obtain the alignments data and validate for methods which require it.

        Returns
        -------
        :class:`lib.align.Alignments`
            The alignments object pertaining to the data to be sorted. Returns ``None`` if an
            alignments file can't be found or is not required.
        """
        required_methods = ["face"]
        if self._args.sort_method not in required_methods:
            return None
        if self._args.alignments_path is None:
            path = os.path.join(self._args.input_dir, "alignments.fsa")
        else:
            path = self._args.alignments_path

        if not os.path.isfile(path):
            logger.warning("Alignments file not found at '%s'. Not using an alignments file will "
                           "lead to vastly inferior results.", path)
            logger.warning("It is highly recommended that you use an alignments file for sorting "
                           "by '%s'.", self._args.sort_method)
            return None

        return Alignments(*os.path.split(path))

 </s> add 
          logger.info("Sorting by ward linkage...")
  
          indices = self._vgg_face.sorted_similarity(np.array(preds), method="ward")
          img_list = np.array(filenames)[indices]






          return img_list
  
      def sort_face_cnn(self):
          """ Sort by landmark similarity """
          logger.info("Sorting by landmark similarity...")
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 Update extracted faces to use PNG EXIF data (#1123)

Documentation
  - Update Usage.md, align.rst and image.rst
lib.image.py
  - read_image - Remove hash return, add metadata return
  - Remove read_image_hash functions
  - Add read_image_meta functios
  - Replace encode_image_with_hash with encode_image (to store metadata)
  - Add png meta reading and writing functions
  - Update Image Loaders/Savers to handle metadata rather than hashes
lib.training_data
  - Naming updates to remove references to hashes
lib.align.Alignments
  - Add versioning notes
  - Increment alignments version to 2.1
  - Deprecate hashing lookup functions
  - Replace filter_hashes with filter_faces
lib.align.detected_face
  - DetectedFace
    - Remove hash property
    - Add png header data serializing/deserializing functions
  - Mask
    - Add png header data serializing/deserializing functions
  - add update_legacy_png_header function to update png meta data
lib.cli.args - Deprecate alignments files for training
- plugins.train.trainer
  - Update alignments/mask code to read png header data
- scripts.convert
  - Aligned images folder - read data from png headers
- scripts.extract
  - Write png header information and no longer store hash of face
- tools.alignments
  - remove leftover-faces, merge and update-hashes jobs
  - Update jobs to use png meta data rather than hashes
- tools.manual
  - Update extract code to output png meta data and don't store hashes
  - Perform check on launch that tool is not pointing at a faces folder
tools.mask
  - Update to use png meta data
tools.sort
  - Update to use png meta data 
tools/sort/sort.py