docs: def construct_seqres_to_atom_residue_map(self):
          '''Uses the SequenceAligner to align the SEQRES and ATOM sequences and return the mappings.
             If the SEQRES sequence does not exist for a chain, the mappings are None.
             Note: The ResidueRelatrix is better equipped for this job since it can use the SIFTS mappings. This function
             is provided for cases where it is not possible to use the ResidueRelatrix.'''
          from klab.bio.clustalo import SequenceAligner
  
          seqres_to_atom_maps = {}
          atom_to_seqres_maps = {}
          for c in self.seqres_chain_order:
              if c in self.atom_chain_order:
  
                  # Get the sequences for chain c
                  seqres_sequence = self.seqres_sequences[c]
                  atom_sequence = self.atom_sequences[c]
  
                  # Align the sequences. mapping will be a mapping between the sequence *strings* (1-indexed)
                  sa = SequenceAligner()
                  sa.add_sequence('seqres_%s' % c, str(seqres_sequence))
                  sa.add_sequence('atom_%s' % c, str(atom_sequence))
                  mapping, match_mapping = sa.get_residue_mapping()
  
                  # Use the mapping from the sequence strings to look up the residue IDs and then create a mapping between these residue IDs
                  seqres_to_atom_maps[c] = {}
                  atom_to_seqres_maps[c] = {}
                  for seqres_residue_index, atom_residue_index in mapping.iteritems():
                      seqres_residue_id = seqres_sequence.order[seqres_residue_index - 1] # order is a 0-based list
                      atom_residue_id = atom_sequence.order[atom_residue_index - 1] # order is a 0-based list
                      seqres_to_atom_maps[c][seqres_residue_id] = atom_residue_id
                      atom_to_seqres_maps[c][atom_residue_id] = seqres_residue_id
  
          return seqres_to_atom_maps, atom_to_seqres_maps