Make sure that the pdbml_atom_to_seqres_sequence_maps and clustal_seqres_to_uniparc_sequence_maps agree with SIFTS and merge the maps.
                SIFTS may have more entries since we discard PDB residues which break Rosetta.
                SIFTS may have less entries for some cases e.g. 1AR1, chain C where SIFTS does not map ATOMs 99-118.
                SIFTS does not seem to contain ATOM to SEQRES mappings for (at least some) DNA chains e.g. 1APL, chain A
            Because of these cases, we just assert that the overlap agrees so that we can perform a gluing of maps.

def _merge_sifts_maps(self):
        ''' Make sure that the pdbml_atom_to_seqres_sequence_maps and clustal_seqres_to_uniparc_sequence_maps agree with SIFTS and merge the maps.
                SIFTS may have more entries since we discard PDB residues which break Rosetta.
                SIFTS may have less entries for some cases e.g. 1AR1, chain C where SIFTS does not map ATOMs 99-118.
                SIFTS does not seem to contain ATOM to SEQRES mappings for (at least some) DNA chains e.g. 1APL, chain A
            Because of these cases, we just assert that the overlap agrees so that we can perform a gluing of maps.'''

        if self.pdb_id in do_not_use_the_sequence_aligner:
            assert(self.sifts)
            self.atom_to_seqres_sequence_maps = self.sifts_atom_to_seqres_sequence_maps
            self.seqres_to_uniparc_sequence_maps = self.sifts_seqres_to_uniparc_sequence_maps
        elif self.sifts:
            self.atom_to_seqres_sequence_maps = {}
            self.seqres_to_uniparc_sequence_maps = {}
            for c, seqmap in sorted(self.pdbml_atom_to_seqres_sequence_maps.iteritems()):
                if self.sequence_types[c] == 'Protein' or self.sequence_types[c] == 'Protein skeleton':
                    try:
                        if self.sifts_atom_to_seqres_sequence_maps.get(c):
                            assert(self.pdbml_atom_to_seqres_sequence_maps[c].matches(self.sifts_atom_to_seqres_sequence_maps[c]))
                            self.atom_to_seqres_sequence_maps[c] = self.pdbml_atom_to_seqres_sequence_maps[c] + self.sifts_atom_to_seqres_sequence_maps[c]
                        else:
                            self.atom_to_seqres_sequence_maps[c] = self.pdbml_atom_to_seqres_sequence_maps[c]
                    except Exception, e:
                        raise colortext.Exception("Mapping cross-validation failed checking atom to seqres sequence maps between PDBML and SIFTS in %s, chain %s: %s" % (self.pdb_id, c, str(e)))
                else:
                    self.atom_to_seqres_sequence_maps[c] = seqmap

            for c, seqmap in sorted(self.clustal_seqres_to_uniparc_sequence_maps.iteritems()):
                if self.sequence_types[c] == 'Protein' or self.sequence_types[c] == 'Protein skeleton':
                    if (self.pdb_id, c) in use_SIFTS_match_for_seqres_sequence:
                        #assert(seqres_sequence[seqres_id].ResidueAA == uniparc_sequence[uniparc_id].ResidueAA)
                        if (self.pdb_id, c) not in known_bad_clustal_to_sifts_mappings:
                            # Flag cases for manual inspection
                            assert(self.clustal_seqres_to_uniparc_sequence_maps[c].keys() == self.sifts_seqres_to_uniparc_sequence_maps[c].keys())
                        for k in self.clustal_seqres_to_uniparc_sequence_maps[c].keys():
                            v_1 = self.clustal_seqres_to_uniparc_sequence_maps[c][k]
                            v_2 = self.sifts_seqres_to_uniparc_sequence_maps[c][k]

                            if (self.pdb_id, c) not in known_bad_clustal_to_sifts_mappings and v_2:
                                # Make sure the UniParc IDs agree
                                assert(v_1[0] == v_2[0])

                            if (self.pdb_id, c) not in known_bad_clustal_to_sifts_mappings:
                                # Make sure the residue types agree
                                assert(self.uniparc_sequences[v_1[0]][v_1[1]].ResidueAA == self.uniparc_sequences[v_1[0]][v_2[1]].ResidueAA)

                                # Copy the substitution scores over. Since the residue types agree, this is valid
                                self.sifts_seqres_to_uniparc_sequence_maps[c].substitution_scores[k] = self.clustal_seqres_to_uniparc_sequence_maps[c].substitution_scores[k]

                        self.clustal_seqres_to_uniparc_sequence_maps[c] = self.sifts_seqres_to_uniparc_sequence_maps[c]

                    try:
                        if self.sifts_seqres_to_uniparc_sequence_maps.get(c):
                            if not self.clustal_seqres_to_uniparc_sequence_maps[c].matches(self.sifts_seqres_to_uniparc_sequence_maps[c]):
                                mismatched_keys = self.clustal_seqres_to_uniparc_sequence_maps[c].get_mismatches(self.sifts_seqres_to_uniparc_sequence_maps[c])
                                raise Exception("self.clustal_seqres_to_uniparc_sequence_maps[c].matches(self.sifts_seqres_to_uniparc_sequence_maps[c])")
                            self.seqres_to_uniparc_sequence_maps[c] = self.clustal_seqres_to_uniparc_sequence_maps[c] + self.sifts_seqres_to_uniparc_sequence_maps[c]
                        else:
                            self.seqres_to_uniparc_sequence_maps[c] = self.clustal_seqres_to_uniparc_sequence_maps[c]
                    except Exception, e:
                        colortext.warning(traceback.format_exc())
                        colortext.error(str(e))
                        raise colortext.Exception("Mapping cross-validation failed checking atom to seqres sequence maps between Clustal and SIFTS in %s, chain %s." % (self.pdb_id, c))
                else:
                    self.clustal_seqres_to_uniparc_sequence_maps[c] = seqmap
        else:
            self.atom_to_seqres_sequence_maps = self.pdbml_atom_to_seqres_sequence_maps
            self.seqres_to_uniparc_sequence_maps = self.clustal_seqres_to_uniparc_sequence_maps