Keywords: Parametric, Bundle, BundleGridSampler, MakeBundle
In this workshop, we will give examples for how to do Parametric Protein Design using the RosettaScripts interface to Rosetta written. The code you will be using from Rosetta was written by Vikram Mulligan. The BundleGridSampler and MakeBundle movers are available through code in PyRosetta, but because of the many number of options to it, it is a bit easier to work with these in XML. We will use this opportunity to do see how easy it is to run XML in PyRosetta, but we will cover the code-level interface as well in this workshop.
This is some cool stuff. Enjoy. :)
Please refer to the docs for more info.
Warning: This notebook uses pyrosetta.distributed.viewer
code, which runs in jupyter notebook
and might not run if you're using jupyterlab
.
!pip install pyrosettacolabsetup
import pyrosettacolabsetup; pyrosettacolabsetup.install_pyrosetta()
import pyrosetta; pyrosetta.init()
Make sure you are in the directory with the pdb files:
cd google_drive/MyDrive/student-notebooks/
import logging
logging.basicConfig(level=logging.INFO)
import pyrosetta
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))
pyrosetta.init("-mute all")
INFO:pyrosetta.rosetta:Found rosetta database at: /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyrosetta-2019.33+release.1e60c63beb5-py3.6-macosx-10.6-intel.egg/pyrosetta/database; using it.... INFO:pyrosetta.rosetta:PyRosetta-4 2019 [Rosetta PyRosetta4.Release.python36.mac 2019.33+release.1e60c63beb532fd475f0f704d68d462b8af2a977 2019-08-09T15:19:57] retrieved from: http://www.pyrosetta.org (C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.
PyRosetta-4 2019 [Rosetta PyRosetta4.Release.python36.mac 2019.33+release.1e60c63beb532fd475f0f704d68d462b8af2a977 2019-08-09T15:19:57] retrieved from: http://www.pyrosetta.org (C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.
Parametric sampling means changing specific angles of groups of bundles (coiled-coils) in order to sample different conformations. The equations that are used for Parametric sampling were originally described by Crick and are called Crick equations.
These equations were reintroduced to the scientific community through William F Degrado's seminal paper, "Probing designability via a generalized model of helical bundle geometry"
Since the puplication of that paper, researchers have used this method to create bundles of all sorts. Fibers, membrane proteins, and even working antiporters!
Dang B, Wu H, Mulligan VK, Mravic M, Wu Y, Lemmin T, Ford A, Silva DA, Baker D, DeGrado WF.
"De novo design of covalently constrained mesosize protein scaffolds with unique tertiary structures."
Proc Natl Acad Sci U S A. 2017 Oct 10;114(41):10852-10857. https://www.ncbi.nlm.nih.gov/pubmed/28973862
Lu P,Min D, DiMaio F, Wei KY, Vahey MD, Boyken SE, Mulligan, et al.
"Accurate computational design of multipass transmembrane proteins."
Science. 2018 Mar 2;359(6379):1042-1046. https://www.ncbi.nlm.nih.gov/pubmed/29496880
Chen Z, Boyken SE, Jia M, Busch F, Flores-Solis D, Mulligan, et al.
"Programmable design of orthogonal protein heterodimers."
Nature. 2019 Jan;565(7737):106-111. https://www.ncbi.nlm.nih.gov/pubmed/30568301
Langan RA Boyken SE, Ng AH, Samson JA, Dods G, Mulligan, et al.
"De novo design of bioactive protein switches."
Nature. 2019 Aug;572(7768):205-210. https://www.ncbi.nlm.nih.gov/pubmed/31341284
The Helix lines tell the sampler to create a helix and how to do so. We set them at 90 degree rotations through this line, but we could add additional parameters as well. These parameters are VERY WELL documented on the link above, so make sure to use that:
delta_omega0: Rotation of a helix about the z-axis, stored in radians.
Here, we will sample on the r0 axis. To make this a bit easier, we will set dump_pdbs to 1. You can also put this code in a loop and sample on that as well, writing each to pymol. You would set r0 instead of r0_max and min.
r0: Major helix radius, in Angstroms.
pose = pyrosetta.rosetta.core.pose.Pose()
pyrosetta.rosetta.protocols.rosetta_scripts.XmlObjects.create_from_string("""
<SCOREFXNS>
<ScoreFunction name="sfxn1" weights="ref2015"/>
</SCOREFXNS>
<MOVERS>
<BundleGridSampler name="bgs1"
helix_length="20"
scorefxn="sfxn1"
r0_min="1.0"
r0_max="10.0"
r0_samples="10"
omega0="0.05"
delta_omega0="0"
delta_omega1="0"
delta_t="0"
dump_pdbs="1">
<Helix/>
<Helix delta_omega0="3.14" r0_copies_helix="1"/>
</BundleGridSampler>
</MOVERS>
""").get_mover("bgs1").apply(pose)
Ok, so now lets have a look at this - it is quite fast as we are simply manipulating the backbone and doing doing any sequence design (yet). Which axis changed? Lets try changing some other values! Note that if we have dump_pdbs on - we will be overwriting them, so make sure to move the current ones to another directory if you
This time, we will change the parameters a bit through code and observe them by directly dumping them or through the PyMolMover. Instead of the BundleGridSampler, we will use the MakeBundle mover.
Note the use of Python3's awesome f-strings here, and the speed. Because we need to parse the xml object and create a new mover, pose, etc. each time, this is much slower than the sampler - but it does allow us a bit more flexibility to use python the way it was intended. Once again, the MakeBundle
mover does not have an adaquite code-level interface to allow us to set variables the traditional way. If you end up writing C++ Rosetta code, make sure to always keep the XML and code-level interfaces feature-complete!
omega0: Major helix twist per residue, stored in radians.
import math
for i in range(0, 32, 2):
i_rad = math.radians(i)
pose = pyrosetta.rosetta.core.pose.Pose()
sampler_string = f'''
<SCOREFXNS>
<ScoreFunction name="sfxn1" weights="ref2015"/>
</SCOREFXNS>
<MOVERS>
<MakeBundle name="bgs1"
helix_length="20"
r0="5"
omega0="{i_rad}"
delta_omega0="0"
delta_omega1="0"
delta_t="0">
<Helix/>
<Helix delta_omega0="3.14" r0_copies_helix="1"/>
</MakeBundle>
</MOVERS>'''
print(sampler_string)
pyrosetta.rosetta.protocols.rosetta_scripts.XmlObjects.create_from_string(sampler_string).get_mover("bgs1").apply(pose)
pose.dump_pdb('outputs/omega0_'+str(i)+'.pdb')
<SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.0" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.03490658503988659" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.06981317007977318" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.10471975511965978" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.13962634015954636" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.17453292519943295" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.20943951023931956" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.24434609527920614" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.2792526803190927" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.3141592653589793" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.3490658503988659" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.3839724354387525" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.4188790204786391" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.4537856055185257" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.4886921905584123" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS> <SCOREFXNS> <ScoreFunction name="sfxn1" weights="ref2015"/> </SCOREFXNS> <MOVERS> <MakeBundle name="bgs1" helix_length="20" r0="5" omega0="0.5235987755982988" delta_omega0="0" delta_omega1="0" delta_t="0"> <Helix/> <Helix delta_omega0="3.14" r0_copies_helix="1"/> </MakeBundle> </MOVERS>
What is the maximum value of omega0? Which PDBs are empty??
Ok, we have an idea for how to use code to create some helical backbones. Lets try this through code instead of RosettaScripts.
Note that the BPC_xx are ENUMS
as we have seen before and are imported when we import all of the helical bundle namespace.
Also, if you call mb.set_use_degrees(True)
before creating helices, you won't need the math.radians()
call.
from pyrosetta.rosetta.protocols.helical_bundle import *
import math
pose = pyrosetta.rosetta.core.pose.Pose()
mb = MakeBundle()
mb.add_helix()
mb.add_helix()
mb.helix(2).calculator_op().real_parameter(BPC_delta_omega0).set_value(3.14)
for i in range(1, 3):
mb.helix(i).set_helix_length(20)
mb.helix(i).calculator_op().real_parameter(BPC_r0).set_value(5)
mb.helix(i).calculator_op().real_parameter(BPC_omega0).set_value(math.radians(12))
mb.apply(pose)
pose.dump_pdb("outputs/manual_make_bundle.pdb")
True
This should give you an overview of how to use the MakeBundle and BundleGridSampler within PyRosetta. Everything else is simply parameters. Read up and you'll be ready to start designing your own helical bundles.