The Brokered Environment framework, also known as the ToplogyBroker 2.0, is a tool for generating larger, more complex simulation systems out of small interchangeable parts. The intent is to make rapid protocol development in RosettaScripts, PyRosetta, and even the C++ easier by allowing sampling strategies to be carried out simultaneously rather than in sequence by constructing a consensus FoldTree that satisfies all movers. Such Movers inherit from the ClientMover (CM) class.
A tutorial on protein folding using the Broker can be found here.
Author's Note: If anything here doesn't make sense, doesn't work as advertised, or is otherwise demanding of attention, give me (the original developer) a shout at justinrporter at gmail. I spent quite a long time on this, and would love to see other folks using it, so if I can help, let me know!
We have a list of available ClientMovers.
Using an brokered Environment in your RosettaScripts is as easy as
In the following example, a ChainResidueSelector selecting chains named "A" and "B" are used to build a UniformRigidBodyCM that docks those two chains to one another.
<ROSETTASCRIPTS>
<RESIDUE_SELECTORS>
<Chain name="ChainA" chains="A" />
<Chain name="ChainB" chains="B" />
</RESIDUE_SELECTORS>
<MOVERS>
<UniformRigidBodyCM name="dock" mobile="ChainA" stationary="ChainB" />
<Environment name="dockenv">
<!-- This will only apply the mover once, you'd need a GenericMonteCarlo for proper sampling -->
<Apply name="dock"/>
<Environment/>
</MOVERS>
<PROTOCOLS>
<Add mover="dockenv"/>
</PROTOCOLS>
</ROSETTASCRIPTS>
The following example replicates an ab initio run. The file "beta_sheets.top" contains a predicted beta-strand pairing topology, and the 9-mer and 3-mer fragments are in fragment files called "frag9.dat" and "frag3.dat", respectively. Loops are closed after the AbscriptMover runs all stages of abinitio by the AbscriptLoopCloserCM, and then FastRelax refines the structure in full atom mode. The assumption is made here that the input pose is in centroid mode.
A fully working example use of this script to fold ubiquitin is available in the Rosetta demos repository at demos/protocol_capture/broker/ubq/
.
<MOVERS>
<FragmentJumpCM name="jumps" topol_file="beta_sheets.top" />
<AbscriptMover name="abinitio" cycles=2 >
<Fragments large_frags="frag9.dat" small_frags="frag3.dat" />
<Stage ids="I-IVb" >
<Mover name="jumps" weight=1.0 />
</Stage>
</AbscriptMover>
<AbscriptLoopCloserCM name="closer" fragments="frag3.dat" />
<Environment name="env" auto_cut=1 >
<Apply mover="abinitio" />
<Apply mover="closer" />
</Environment>
<SwitchResidueTypeSetMover name="fullatom" set="fa_standard" />
<FastRelax name="relax" repeats=5 />
</MOVERS>
<PROTOCOLS>
<Add mover="env" />
<Add mover="fullatom" />
<Add mover="relax" />
</PROTOCOLS>
Consider the domain insertion protein AB, where protein A (with known structure) has protein B (structure unknown) inserted somewhere inside of it. While holding the A part of the fusion protein fixed, we would like to insert fragments in protein B, without perturbing the structure of A.
<ROSETTASCRIPTS>
<RESIDUE_SELECTORS>
<!-- The crystal structure is missing density inside the inserted domain
(resids 267-275). As a result, we need to use a different numbering
scheme when we talk about the pdb as we do when we talk about the
extended chain that we're simulating. -->
<!-- host_domain_wo_linker selects the host domain when the residues
not modeled in the crystal structure are not present (i.e. crystal structure numbering). -->
<Index name="host_domain_wo_linker" resnums="1-159,288-339" />
<!-- "host domain_w_linker" selects the host domain when the residues
not modeled in the crystal structure ARE present (i.e. simulation numbering). -->
<Index name="host_domain_w_linker" resnums="1-159,295-346" />
<Not name="inserted_domain" selector="host_domain_w_linker" />
</RESIDUE_SELECTORS>
<MOVERS>
<SwitchResidueTypeSetMover name="centroid" set="centroid" />
<FragmentJumpCM name="jumps" topol_file="1uufA.top" />
<AbscriptMover name="abinitio" cycles="6" >
<Fragments large_frags="1uufA.frag9" small_frags="1uufA.frag3" />
<Stage ids="I-IVb" >
<Mover name="jumps" />
</Stage>
</AbscriptMover>
<!-- "region_selector" : the selector that selects the residues from the pdb
"selector" : selector that selects the destination for residues selected by "region_selector"
"apply_to_template" : applies a mover to the template PDB before copying atomic coordinates;
required, since we need a match in atom numbers and types to copy.
-->
<RigidChunkCM name="chunk" region_selector="host_domain_wo_linker"
template="1uufA.pdb" selector="host_domain_w_linker"
apply_to_template="centroid" />
<AbscriptLoopCloserCM name="closer" fragments="1uufA.frag3" />
<Environment name="env" auto_cut="1" >
<Register mover="chunk" />
<Apply mover="abinitio" />
<Apply mover="closer" />
</Environment>
<SwitchResidueTypeSetMover name="fullatom" set="fa_standard" />
<!-- We've reduced the number of fastrelax repeats because it is so time-consuming. In "real life", this would need to be high(er). The default in abinitio is 5.-->
<FastRelax name="relax" repeats="2" />
</MOVERS>
<FILTERS>
</FILTERS>
<PROTOCOLS>
<Add mover="centroid" />
<Add mover="env" />
<Add mover="fullatom" />
<Add mover="relax" />
</PROTOCOLS>
</ROSETTASCRIPTS>
In this example of an algorithm that could be used in this situation relies on a RigidChunkCM host
, which is responsible for holding domain A fixed, and a FragmentCM, which is responsible for sampling the torsional space of domain B. The ResidueSelector host_region
indicates the region in sequence space that is domain A--in this case, residue 1-X and Y-Z. host
then knows to apply residue 1-X of the template pose 1ubq.pdb
to residue 1-X of the fusion protein. When it reaches residue X, however, it stops. Residues X+1 to Y-1 are sampled by the FragmentCM. Then, residues Y-Z are held fixed to the conformation found in residues X+1 to END of 1ubq.pdb
. These rigid chunks of protein (1-X and Y-Z) are related in space by a jump, holding their position relative to one another fixed as well. The cut is placed randomly, weighted by the loop propensity in the FragmentCM.
Of course, there are no guarantees that this example algorithm will work for your system (or any system). It hasn't been benchmarked, and exists solely to demonstrate the functionality of the Environment framework.
A fully working example use of this script is available in the Rosetta demos repository at demos/protocol_capture/2015/broker/domain_insertion/
. A detailed description and analysis of this protocol is included in our paper for the RosettaCon 2014 PLoS ONE collection.
This example docks three chains (A, B, and C) to one another using a "star" FoldTree using UniformRigidBodyCMs. In other words, all three chains are docked to a central virtual residue. This is in contrast to a two-to-one docking scheme. A TrialMover is used to run 1000 cycles of docking. CoMTrackerCMs create virtual residues centered at the center of mass of each chain, which are used as the other base of the jump building each chain.
<RESIDUE_SELECTORS>
<Chain chains="A" name="ChainA" />
<Chain chains="B" name="ChainB" />
<Chain chains="C" name="ChainC" />
</RESIDUE_SELECTORS>
<MOVERS>
<CoMTrackerCM name="com_A" mobile_selector="ChainA" />
<CoMTrackerCM name="com_B" mobile_selector="ChainB" />
<CoMTrackerCM name="com_C" mobile_selector="ChainC" />
<UniformRigidBodyCM name="rigidA" mobile="com_A" stationary="star_center" />
<UniformRigidBodyCM name="rigidB" mobile="com_B" stationary="star_center" />
<UniformRigidBodyCM name="rigidC" mobile="com_C" stationary="star_center" />
<RandomMover name="dock_bag" movers="rigidA,rigidB,rigidC,com_A,com_B,com_C" />
<GenericMonteCarlo name="dock" scorefxn_name="talaris2013" mover_name="dock_bag" temperature=2.0 trials=1000 />
<Environment name=multidock >
<Apply name=dock />
</Environment>
</MOVERS>
<PROTOCOLS>
<Add mover="multidock"/>
</PROTOCOLS>
An implementation of a similar protocol using this paradigm, along with a detailed description and analysis, is included in our paper for the RosettaCon 2014 PLoS ONE collection.
Fold and Dock is a protocol that was designed to predict the structure of obligate symmetric multimers. While the broker does not currently support symmetry, the broker does furnish functionality that allows for all parts of that protocol except symmetric mirroring. To demonstrate this, we constructed an example script to demonstrate how this might be achieved to simultaneously fold and dock an obligate heterodimer.
<RESIDUE_SELECTORS>
<Chain chains="A" name=ChainA />
<Chain chains="B" name=ChainB />
</RESIDUE_SELECTORS>
<MOVERS>
<CoMTrackerCM name=com_A mobile_selector=ChainA />
<CoMTrackerCM name=com_B mobile_selector=ChainB />
<UniformRigidBodyCM name=rigid mobile=com_A stationary=com_B />
<AbscriptMover name=abinitio >
<Fragments small_frags=frags3A.txt large_frags=frags9A.txt selector=ChainA />
<Fragments small_frags=frags3B.txt large_frags=frags9B.txt selector=ChainB />
<Stage ids=I-IVb>
<Mover name=rigid />
<Mover name=com_A />
<Mover name=com_B />
</Stage>
</AbscriptMover>
<AbscriptLoopCloserCM name=closerA fragments="frags3A" selector=ChainA />
<AbscriptLoopCloserCM name=closerB fragments="frags3B" selector=ChainB />
<ResidueTypeSetSwitchMover name=fullatom set=fa_standard />
<FastRelax name=relax repeats=5 />
<Environment name=fold_and_dock auto_cut=true >
<Apply name=abintio />
<Apply name=closerA />
<Apply name=closerB />
</Environment>
</MOVERS>
<PROTOCOLS>
<Add mover=fold_and_dock />
<Add mover=fullatom />
<Add mover=relax />
</PROTOCOLS>
This section is about building protocols that use the broker and existing ClientMovers to build a protocol/application in C++, not Developing for the Broker. Making a brokered Environment in your C++ code is as easy as:
For a protocol with only one ClientMover (called MyClientMover), it might look like this.
protocols::environment::Environment env( "env" );
MyClientMoverOP my_mover = new MyClientMover( arg1, arg2, ... );
env.register_mover( my_mover );
core::pose::Pose prot_pose = prot_pose = env.start( pose );
my_mover->apply( prot_pose );
core::pose::Pose final_pose = env.end( prot_pose );
Many further examples are available as unit tests in test/protocols/environment/*
.
PyRosetta provides direct access to the C++ interface used by the broker. As a result, the PyRosetta interface for the broker should be only trivially different from the the C++ interface.
Since the Broker was not really developed with PyRosetta specifically in mind, it is not known if it is possible to define movers in PyRosetta that are broker-compatible. PyRosetta compatibility more generally should work, but we haven't rigorously tested this. If you're interested in PyRosetta + Broker, give it a try. If you run in to problems (or get it to work!) let us know what you did and how you did it so we can update this section.