def rebuild_c_terminal(complex: oechem.OEGraphMol) -> oechem.OEGraphMol: # Delete and rebuild C-terminal residue because Spruce causes issues with this # See: 6m2n 6lze pred = oechem.OEIsCTerminalAtom() for atom in complex.GetAtoms(): if pred(atom): for nbor in atom.GetAtoms(): if oechem.OEGetPDBAtomIndex(nbor) == oechem.OEPDBAtomName_O: complex.DeleteAtom(nbor) return complex
def mutate_structure(target_structure: oechem.OEGraphMol, template_sequence: str) -> oechem.OEGraphMol: """ Mutate a protein structure according to an amino acid sequence. Parameters ---------- target_structure: oechem.OEGraphMol An OpenEye molecule holding a protein structure to mutate. template_sequence: str A template one letter amino acid sequence, which defines the sequence the target structure should be mutated to. Protein residues not matching a template sequence will be either mutated or deleted. Returns ------- mutated_structure: oechem.OEGraphMol An OpenEye molecule holding the mutated protein structure. """ from Bio import pairwise2 # the hierarchy view is more stable if reinitialized after each change # https://docs.eyesopen.com/toolkits/python/oechemtk/biopolymers.html#a-hierarchy-view finished = False while not finished: altered = False # align template and target sequences target_sequence = get_sequence(target_structure) template_sequence_aligned, target_sequence_aligned = pairwise2.align.globalxs( template_sequence, target_sequence, -10, 0)[0][:2] logging.debug(f"Template sequence:\n{template_sequence}") logging.debug(f"Target sequence:\n{target_sequence}") hierview = oechem.OEHierView(target_structure) structure_residues = hierview.GetResidues() # adjust target structure to match template sequence for template_sequence_residue, target_sequence_residue in zip( template_sequence_aligned, target_sequence_aligned): if template_sequence_residue == "-": # delete any non protein residue from target structure structure_residue = structure_residues.next() if target_sequence_residue != "X": # delete for atom in structure_residue.GetAtoms(): target_structure.DeleteAtom(atom) # break loop and reinitialize altered = True break else: # compare amino acids if target_sequence_residue != "-": structure_residue = structure_residues.next() if target_sequence_residue not in [ "X", template_sequence_residue ]: # mutate structure_residue = structure_residue.GetOEResidue() three_letter_code = oechem.OEGetResidueName( oechem.OEGetResidueIndexFromCode( template_sequence_residue)) oespruce.OEMutateResidue(target_structure, structure_residue, three_letter_code) # break loop and reinitialize altered = True break # leave while loop if no changes were introduced if not altered: finished = True # OEMutateResidue doesn't build sidechains and doesn't add hydrogens automatically oespruce.OEBuildSidechains(target_structure) oechem.OEPlaceHydrogens(target_structure) # update residue information oechem.OEPerceiveResidues(target_structure, oechem.OEPreserveResInfo_All) return target_structure