              self.alignments = self.serializer.unmarshal(align.read())
  
      def save_alignments(self):
          """ Backup copy of old alignments and save new alignments """
          dst = os.path.splitext(self.file)[0]
          dst += ".{}".format(self.serializer.ext)
          self.backup_alignments()
  
          print("Saving alignments to {}".format(dst))
          with open(dst, self.serializer.woptions) as align:
              align.write(self.serializer.marshal(self.alignments))
  
      def backup_alignments(self):
          """ Backup copy of old alignments """
          if not os.path.isfile(self.file):
              return
          now = datetime.now().strftime("%Y%m%d_%H%M%S")
          src = self.file
          dst = src.split(".")
          dst[0] += "_" + now + "."
          dst = dst[0] + dst[1]
          print("Backing up original alignments to {}".format(dst))
          os.rename(src, dst)
  
      def get_alignments_one_image(self):
          """ Return the face alignments for one image """
          for frame_fullname, alignments in self.alignments.items():
              frame_name = frame_fullname[:frame_fullname.rindex(".")]
              number_alignments = len(alignments)
              yield frame_name, alignments, number_alignments, frame_fullname
  
      @staticmethod
      def get_one_alignment_index_reverse(image_alignments, number_alignments):
          """ Return the correct original index for
              alignment in reverse order """
          for idx, _ in enumerate(reversed(image_alignments)):
              original_idx = number_alignments - 1 - idx
              yield original_idx
  
      def get_alignments_for_frame(self, frame):
          """ Return the alignments for the selected frame """
          return self.alignments.get(frame, list())
  
      def frame_in_alignments(self, frame):
          """ Return true if frame exists in alignments file """
          return bool(self.alignments.get(frame, -1) != -1)
  
      def frame_has_faces(self, frame):
          """ Return true if frame exists and has faces """
          return bool(self.alignments.get(frame, list()))
  
      def frame_has_multiple_faces(self, frame):
          """ Return true if frame exists and has faces """
          if not frame:
              return False
          return bool(len(self.alignments.get(frame, list())) > 1)
  
      def get_full_frame_name(self, frame):
          """ Return a frame with extension for when the extension is
              not known """
          return next(key for key in self.alignments.keys()
                      if key.startswith(frame))
  
      def count_alignments_in_frame(self, frame):
          """ Return number of alignments within frame """
          return len(self.alignments.get(frame, list()))
  
      def delete_alignment_at_index(self, frame, idx):
          """ Delete the face alignment for given frame at given index """
          idx = int(idx)
          if idx + 1 > self.count_alignments_in_frame(frame):
              return False
          del self.alignments[frame][idx]
          return True
  
      def add_alignment(self, frame, alignment):
          """ Add a new alignment for a frame and return it's index """
          self.alignments[frame].append(alignment)
          return self.count_alignments_in_frame(frame) - 1
  
      def update_alignment(self, frame, idx, alignment):
          """ Replace an alignment for given frame and index """
          self.alignments[frame][idx] = alignment
  
      def get_rotated(self):
          """ Return list of keys for alignments containing
              rotated frames """
          keys = list()
          for key, val in self.alignments.items():
              if any(alignment.get("r", None) for alignment in val):
                  keys.append(key)
          return keys
  
      def rotate_existing_landmarks(self, frame, dimensions):
          """ Backwards compatability fix. Rotates the landmarks to
              their correct position and sets r to 0 """
          for alignment in self.alignments.get(frame, list()):
              angle = alignment.get("r", 0)
              if not angle:
                  return
              rotation_matrix = self.get_original_rotation_matrix(dimensions,
                                                                  angle)
              rotate_landmarks(alignment, rotation_matrix)
              del alignment["r"]
  
      @staticmethod
      def get_original_rotation_matrix(dimensions, angle):
          """ Calculate original rotation matrix and invert """
          height, width = dimensions
          center = (width/2, height/2)
          rotation_matrix = cv2.getRotationMatrix2D(center, -1.0*angle, 1.)
  
          abs_cos = abs(rotation_matrix[0, 0])
          abs_sin = abs(rotation_matrix[0, 1])
          rotated_width = int(height*abs_sin + width*abs_cos)
          rotated_height = int(height*abs_cos + width*abs_sin)
          rotation_matrix[0, 2] += rotated_width/2 - center[0]
          rotation_matrix[1, 2] += rotated_height/2 - center[1]
  
          return rotation_matrix
  
  
  class MediaLoader():
      """ Class to load filenames from folder """
      def __init__(self, folder, verbose):
 
</s> remove     def save(self):
        """ Write the serialized alignments file """
        try:
            print("Writing alignments to: {}".format(self.location))
            with open(self.location, self.serializer.woptions) as align:
                align.write(self.serializer.marshal(self.data))
        except Exception as err:
            print("{} not written!".format(self.location))
            print(str(err))

    def frame_exists(self, frame):
        """ return path of images that have faces """
        return frame in self.data.keys()

    def get_alignments_for_frame(self, frame):
        """ Return the alignments for the selected frame """
        return self.data.get(frame, list())

    def get_legacy_frames(self):
        """ Return a list of frames with legacy rotations """
        keys = list()
        for key, val in self.data.items():
            if any(alignment.get("r", None) for alignment in val):
                keys.append(key)
        return keys

    def rotate_existing_landmarks(self, frame, dimensions):
        """ Backwards compatability fix. Rotates the landmarks to
            their correct position and deletes r """
        for face in self.get_alignments_for_frame(frame):
            angle = face.get("r", 0)
            if not angle:
                return
            rotation_matrix = self.get_original_rotation_matrix(dimensions,
                                                                angle)
            rotate_landmarks(face, rotation_matrix)
            del face["r"]

    @staticmethod
    def get_original_rotation_matrix(dimensions, angle):
        """ Calculate original rotation matrix and invert """
        height, width = dimensions
        center = (width/2, height/2)
        rotation_matrix = cv2.getRotationMatrix2D(center, -1.0*angle, 1.)

        abs_cos = abs(rotation_matrix[0, 0])
        abs_sin = abs(rotation_matrix[0, 1])
        rotated_width = int(height*abs_sin + width*abs_cos)
        rotated_height = int(height*abs_cos + width*abs_sin)
        rotation_matrix[0, 2] += rotated_width/2 - center[0]
        rotation_matrix[1, 2] += rotated_height/2 - center[1]

        return rotation_matrix

 </s> add  </s> remove     def reload(self):
        """ Read the alignments data from the correct format """
        print("Reloading alignments from {}".format(self.file))
        with open(self.file, self.serializer.roptions) as align:
            self.alignments = self.serializer.unmarshal(align.read())

    def save_alignments(self):
 </s> add     def save(self): </s> remove         faces = self.set_faces(frame_name, alignments).image
 </s> add         faces = self.set_faces(frame_name).image </s> remove         self.faces = list()
        self.matrices = list()
        alignments = self.alignments.get_alignments_for_frame(frame)
 </s> add         alignments = self.alignments.get_faces_in_frame(frame) </s> remove         """ Return faces and transformed face matrices
 </s> add         """ Return faces and transformed landmarks
        self.backup()
        super().save()
              self.alignments = self.serializer.unmarshal(align.read())
  
      def save_alignments(self):
          """ Backup copy of old alignments and save new alignments """
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
        self.backup()
        super().save()
  
  
  class MediaLoader():
      """ Class to load filenames from folder """
      def __init__(self, folder, verbose):
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 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 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 replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Fix convert-adjust (#531)

* Add dimensions to alignments + refactor

* Add frame_dims + funcs to DetectFaces. Add alignments lib

* Convert Adjust working

* Refactor and tidy up 
tools/lib_alignments/media.py