============================================== Mutate Structure ============================================== Briefs ============================================== The target for this tutorial to mutate the target protein at defined residue(s). The main function provided are ``assign_mutant()`` and ``mutate_stru()``, in which ``mutate_stru()`` solves the problem of protein structural prediction upon mutation. It means to determine which mutation to address and determine the structure of the mutant of the source protein caused by residue substitution, deletion, and insertion. (see also: structure_prediction module for an alternative solution) .. dropdown:: :fa:`eye,mr-1` Click to see more details - *Details:* | Unlike predicting the whole protein structure from sequence and smiles, mutating a structure from a reference structure involves only changes on a limit number of residues and perturbation of the rest of the structure (especially ligand binding, protonation state etc.) As a result, it can be solved using more efficient methods and predicting the whole structure from sketch. Note that the accuracy of the resulting structure varies base on the need. If followed by MD, the structure only needs to be good starting point of MD. | There are 3 types of mutations in protein sequence: substitution, deletion, and insertion. | Substitution is the most common type of the mutation. In this case, only the side-chain is replaced by another type of the side-chain. And determining the conformation of the new side-chain is the main challenge. It also relates to side-chain conformation prediction in the field of structural prediction. | Deletion and insertion involve backbone changes. Input/Output ============================================== .. panels:: :column: col-lg-12 col-md-12 col-sm-12 col-xs-12 p-2 text-left .. image:: ../../figures/mutation_mutate_stru_io.svg :width: 100% :alt: assign_mutant_io Input ------------------------------------------------ ``stru`` the target protein structure intended for mutation, represented as a ``Structure()`` object. .. admonition:: How to obtain | A Strutcure() object can be obtained by these `APIs `_. ``mutant`` a target list of mutation objects, generated by the ``assign_mutant`` function. The input mutation list will be checked for repetition and validity. .. admonition:: How to obtain | A ``mutant`` object can be obtained by these `assign_mutant() `_. The ``assign_mutant`` function generates a list of mutants. We can use a for loop to iterate over each mutant object in this list. Within the loop, the ``mutate_stru`` function is called to process each individual mutant. ``engine`` the method used for determine the mutated structure. .. admonition:: How to obtain | Choose from supported engine: ``tleap_min``, ``pymol``, ``rosetta`` .. dropdown:: :fa:`eye,mr-1` Click to see *Avaible strageties* - *Avaible strageties:* Substitution: Direct replacement of the side-chain: - tleap_min (https://pubs.acs.org/doi/full/10.1021/acs.jcim.1c01424) The most simple way to get a mutant structure. It 1. place the new side-chain using a constant conformation (relative to backbone) and 2. relax the crude mutant structure using MM minimization. Consider limited change of other side chains in MM minimization Not consider backbone change * This method particularly has problem when mutating a small residue to a larger one. In this case, collision may appears in the mutated structure and the MM minimization is responsible for resolving it. But in extreme cases, there are unresolvable collision such as the carbon chain is trapped in a phenyl ring. And currently we don't have a method to detect such trapping. The method is only used as a place holder for 1st version EnzyHTP. We have encounter any problem brought by the accuracy of the mutation when using this method in workflows but users should be cautious with it and consider it a potential source of absured results. Side-chain rotamer library: (most used in the field) - SCWRL4 (http://dunbrack.fccc.edu/lab/scwrl) | Not consider other side-chain change | Not consider backbone change - PyMol (https://github.com/schrodinger/pymol-open-source) | Not consider other side-chain change | Not consider backbone change - Phyre2 | Consider other side-chain change | Not consider backbone change * seems having a derived pipeline Missense3D addressing the challenge (https://www.sciencedirect.com/science/article/pii/ S0022283619302037?via%3Dihub#s0050) * related discussion in its website (http://www.sbg.bio.ic.ac.uk/phyre2/html/help.cgi?id=help/faq) Machine learning methods: - Packpred (http://cospi.iiserpune.ac.in/packpred/, https://www.frontiersin.org/articles/10.3389/fmolb.2021.646288/full, https://github. com/ kuanpern/PackPred) * find a summary of the missence mutation in the intro of the paper Unknown MCMC search globally in side-chains: - Modeller | Fully consider other side-chain change | Not consider backbone change - SWISSMODEL | Fully consider other side-chain change | Not consider backbone change - *Insertion/Deletion:* - Phyre4 see http://www.sbg.bio.ic.ac.uk/phyre2/html/help.cgi?id=help/faq works mainly <5 AA change Output ------------------------------------------------ The reference/copy of the changed structure (depends on the in_place value) as ``Structure`` object, the changed structure can be checked for topology. Arguments ============================================== ``stru``: the target protein structure for mutation represented as Structure() ``mutant``: a target list of mutation objects. (normally generated by the `assign_mutant`` function. Generally dont recommand generating themanually). ``engine``: the engine (method) used for determine the mutated structure. | current available keywords: | ``tleap_min`` | ``pymol`` | ``rosetta`` ``in_place``: if change the structure in-place and return the reference. False means return a changed structure_obj and keep the original objecintact (default is False since wild-type structure is expected to also available in many applications) ``if_check_mutant_stru``: support turning the mutant structure check off. (on by default) ``checker_config``: config which checkers to use and their corresponding kwargs. | {'checker_name':{'keyword':value, ...}, ...} | (by default apply all checker) Example Code ============================================== Mutate a target protein --------------------------------------------------------- In this example, we perform assign mutations on a protein structure. .. admonition:: How input is prepared ``stru`` obtained by reading from a PDB file using ``PDBParser().get_structure()`` (See `Details <#input-output>`_) ``mutant`` a target list of mutation objects, generated by the `assign_mutant `_ ``engine`` we choose "pymol" .. code:: python from enzy_htp.structure import PDBParser import enzy_htp.mutation.api as mapi test_A = "test_A.pdb" test_A_stru = PDBParser.get_structure(test_A) test_mutation_pattern_A = "M71L, r:2[resi 289 around 4 and not resi 36:larger]*5" mutants_A = mapi.assign_mutant(test_A_stru, test_mutation_pattern_A) print(mutants_A) #[[('MET','LEU','A',71)], # [('MET','ARG','A',277), ('THR','MET','A',274)], # [('ASP','ARG','A',287), ('HIS','LEU','A',290)], # [('LEU','PHE','A',284), ('ILE','PHE','A',285)], # [('ALA','TRP','A',288), ('VAL','ARG','A',273)], # [('HIS','LYS','A',290), ('PHE','TYR','A',179)]] mutant_stru_A_1 = mapi.mutate_stru(test_A_stru, mutants_A[0], "pymol") #mutate group1 PDBParser.save_structure("mut1.pdb",mutant_stru_A_1) mutant_stru_A_2 = mapi.mutate_stru(test_A_stru, mutants_A[1], "pymol") #mutate group2 PDBParser.save_structure("mut2.pdb",mutant_stru_A_2) mutant_stru_A_3 = mapi.mutate_stru(test_A_stru, mutants_A[2], "pymol") #mutate group3 PDBParser.save_structure("mut3.pdb",mutant_stru_A_3) ========================================================================================= Author: Xingyu Ouyang