This notebook contains material from PyRosetta; content is available on Github.

Visualization and pyrosetta.distributed.viewer

Warning: This notebook uses pyrosetta.distributed.viewer code, which runs in jupyter notebook and might not run if you're using jupyterlab.

The pyrosetta.distributed Viewer quickly renders .pdb files, dynamically instantiating Pose objects if required for certain visualization modules (matching the name viewer.set*). So when adding visualization modules to the Viewer or using presets, passing Pose or PackedPose objects to the Viewer is suggested for quicker rendering. If a Pose object or list, tuple, or set of Pose objects are provided to the Viewer, the Viewer will dynamically update upon Pose conformational changes by calling the view.show() method or equivalently view(). The Viewer applies visualization modules in the same order they are added (from left to right), so layering different styles (and ResidueSelectors) on top of one another becomes possible. The user must have already initialized PyRosetta providing .params files for any ligands and non-canonical residues in the input Pose(s)/PackedPose(s)/.pdb file(s), otherwise pyrosetta.distributed automatically initializes PyRosetta with default command line options.

Throughout this notebook, different syntaxes for constructing visualizations are demonstrated to show the flexibility of the pyrosetta.distributed.viewer API, with hopes you find your favorite.

If you are using Google Colab: Currently, pyrosetta.distributed.viewer does not require the local machine's PyMOL. You can always dump any Pose object into a .pdb file and open that in PyMOL on your own computer.

pose.dump_pdb("output_file.pdb")

Note: If you are having trouble using this notebook, please use the PyRosetta.notebooks conda environment. Please see chapter 1.0 for instructions on how to setup and use this environment.

In [1]:
import glob
import logging
logging.basicConfig(level=logging.INFO)
import numpy as np
import os
import pyrosetta
import pyrosetta.distributed
import pyrosetta.distributed.io as io
import pyrosetta.distributed.viewer as viewer
import sys

if 'google.colab' in sys.modules:
    !pip install pyrosettacolabsetup
    import pyrosettacolabsetup
    pyrosettacolabsetup.mount_pyrosetta_install()
    print ("Notebook is set for PyRosetta use in Colab.  Have fun!")

Available viewer objects:

In [2]:
viewer.__all__
Out[2]:
['expand_notebook',
 'init',
 'presets',
 'setBackgroundColor',
 'setDisulfides',
 'setHydrogenBonds',
 'setHydrogens',
 'setStyle',
 'setSurface',
 'setZoom',
 'setZoomTo']

For example: viewer.init()

Available viewer.presets objects:

In [3]:
viewer.presets.__all__
Out[3]:
['coreBoundarySurface', 'ligandsAndMetals']

For example: viewer.presets.coreBoundarySurface()

viewer objects contain docstrings as user documentation:

In [4]:
help(viewer.init)
Help on function init in module pyrosetta.distributed.viewer.core:

init(packed_and_poses_and_pdbs=None, window_size=None, modules=None, delay=None, continuous_update=None, *args, **kwargs)
    Initialize the Viewer object.
    
    Parameters
    ----------
    first : required
        `packed_and_poses_and_pdbs`
    
        `PackedPose`, `Pose`, or `str` of a valid path to a .pdb file, or a `list`, `set`, or `tuple` of these objects.
    
    second : optional
        `window_size`
    
        `list` or `tuple` of `int` or `float` values for the (width, height) dimensions of the displayed window screen size.
        Default: (1200, 800)
    
    third : optional
        `modules`
        
        `list` of instantiated visualization modules to run upon changing amongst `packed_and_poses_and_pdbs` objects
        with the slider, matching the namespace `pyrosetta.distributed.viewer.set*`
        Default: []
    
    fourth : optional
        `delay`
        
        `float` or `int` time delay in seconds before rendering the Viewer in a Jupyter notebook, which is useful to prevent
        overburdening the Jupyter notebook client if `for` looping over quick modifications to a `Pose`, and should be >= 0.
        Default: 0.25
    
    fifth : optional
        `continuous_update`
        
        `True` or `False`. When using the interactive slider widget, `False` restricts rendering to mouse release events.
        Default: False
    
    Returns
    -------
    A Viewer instance.

viewer.presets objects contain docstrings as brief descriptions of each preset visualization

In [5]:
help(viewer.presets.coreBoundarySurface)
Help on function coreBoundarySurface in module pyrosetta.distributed.viewer.presets:

coreBoundarySurface(packed_and_poses_and_pdbs=None, *args, **kwargs)
    Display core residues as 'blackCarbon' sticks, boundary residues as 'greyCarbon' sticks, and surface residues
    as 'whiteCarbon' sticks, with 'spectrum' cartoon representation, using the default arguments in
    `pyrosetta.rosetta.core.select.residue_selector.LayerSelector()` to select layers.
    
    @klimaj

In [6]:
help(viewer.presets.ligandsAndMetals)
Help on function ligandsAndMetals in module pyrosetta.distributed.viewer.presets:

ligandsAndMetals(packed_and_poses_and_pdbs=None, *args, **kwargs)
    Display residues with `ResidueProperty.LIGAND` as 'brownCarbon' sticks with opaque surface,
    and `ResidueProperty.METAL` as 'chainHetatm' spheres, with 'spectrum' cartoon representation,
    disulfide bonds, polar hydrogens, and dashed hydrogen bonds.
    
    @klimaj

From previous section: Make sure you are in the right directory for accessing the .pdb files:

cd google_drive/My\ Drive/student-notebooks/

Note: import pyrosetta.distributed.viewer expands the Jupyter notebook cell width to fit your internet browser, and can be called anytime using pyrosetta.distributed.viewer.expand_notebook()

In [3]:
flags = """
-auto_setup_metals 1
-detect_disulf 1
"""
pyrosetta.distributed.init(flags)
INFO:pyrosetta.distributed:maybe_init performing pyrosetta initialization: {'extra_options': '-auto_setup_metals 1 -detect_disulf 1', 'silent': True}
INFO:pyrosetta.rosetta:Found rosetta database at: /home/klimaj/anaconda3/envs/PyRosetta.notebooks/lib/python3.7/site-packages/pyrosetta/database; using it....
INFO:pyrosetta.rosetta:PyRosetta-4 2020 [Rosetta PyRosetta4.conda.linux.CentOS.python37.Release 2020.02+release.22ef835b4a2647af94fcd6421a85720f07eddf12 2020-01-05T17:31:56] retrieved from: http://www.pyrosetta.org
(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.
INFO:rosetta:core.init: {0} Checking for fconfig files in pwd and ./rosetta/flags
INFO:rosetta:core.init: {0} Rosetta version: PyRosetta4.conda.linux.CentOS.python37.Release r242 2020.02+release.22ef835 22ef835b4a2647af94fcd6421a85720f07eddf12 http://www.pyrosetta.org 2020-01-05T17:31:56
INFO:rosetta:core.init: {0} command: PyRosetta -ex1 -ex2aro -auto_setup_metals 1 -detect_disulf 1 -database /home/klimaj/anaconda3/envs/PyRosetta.notebooks/lib/python3.7/site-packages/pyrosetta/database
INFO:rosetta:basic.random.init_random_generator: {0} 'RNG device' seed mode, using '/dev/urandom', seed=-1446910114 seed_offset=0 real_seed=-1446910114 thread_index=0
INFO:rosetta:basic.random.init_random_generator: {0} RandomGenerator:init: Normal mode, seed=-1446910114 RG_type=mt19937

Show basic line representation of .pdb file on disk:

view = viewer.init("path/to/my.pdb")
view.show()

Change the window_size option of viewer.init() to fit your screen size, which should prevent the need to scroll to view your macromolecular objects.

Show basic line representation of Pose or PackedPose objects in memory:

In [40]:
pose = pyrosetta.io.pose_from_file("inputs/3EK4.pdb")
INFO:rosetta:core.import_pose.import_pose: {0} File 'inputs/3EK4.pdb' automatically determined to be of type PDB
INFO:rosetta:core.io.pose_from_sfr.PoseFromSFRBuilder: {0} CA 350 was added by a jump, with base residue 258
INFO:rosetta:core.io.pose_from_sfr.PoseFromSFRBuilder: {0} CA 351 was added by a jump, with base residue 300
INFO:rosetta:core.io.pose_from_sfr.PoseFromSFRBuilder: {0} CA 352 was added by a jump, with base residue 338
INFO:rosetta:core.conformation.Conformation: {0} [ WARNING ] missing heavyatom: OXT on residue pdb_CRO 164
INFO:rosetta:core.chemical.AtomICoor: {0} [ WARNING ] IcoorAtomID::atom_id(): Cannot get atom_id for POLYMER_LOWER of residue VAL 165.  Returning BOGUS ID instead.
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] missing an atom: 165  H   that depends on a nonexistent polymer connection!
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ]  --> generating it using idealized coordinates.
INFO:rosetta:core.conformation.Conformation: {0} [ WARNING ] missing heavyatom:  OXT on residue ASN:CtermProteinFull 349
INFO:rosetta:core.conformation.Conformation: {0} [ WARNING ] Failed to find a residue connection for residue 163 with connection point 2
INFO:rosetta:core.conformation.Conformation: {0} [ WARNING ] Failed to find a residue connection for residue 165 with connection point 1
INFO:rosetta:core.pack.pack_missing_sidechains: {0} packing residue number 164 because of missing atom number 23 atom name OXT
INFO:rosetta:core.pack.task: {0} Packer task: initialize from command line()
INFO:rosetta:core.scoring.ScoreFunctionFactory: {0} SCOREFUNCTION: ref2015
INFO:rosetta:core.scoring.ScoreFunctionFactory: {0} The -auto_setup_metals flag was used with no metalbinding_constraint weight set in the weights file.  Setting to 1.0.
INFO:rosetta:core.pack.rotamer_set.RotamerSet_: {0} Using simple Rotamer generation logic for pdb_CRO:MP-N1-connect:MP-C3-connect
INFO:rosetta:core.pack.pack_rotamers: {0} built 1 rotamers at 1 positions.
INFO:rosetta:core.pack.pack_rotamers: {0} Requesting all available threads for interaction graph computation.
INFO:rosetta:core.pack.interaction_graph.interaction_graph_factory: {0} Instantiating DensePDInteractionGraph
INFO:rosetta:basic.thread_manager.RosettaThreadManager: {0} Thread 0 completed 1 of 1 work units.
INFO:rosetta:core.pack.rotamer_set.RotamerSets: {0} Completed interaction graph pre-calculation in 1 available threads (all available had been requested).
INFO:rosetta:core.util.metalloproteins_util: {0} Automatically setting covalent bonds between metal ions and metal-binding residues.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 258's  OD1 atom and residue 350's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 262's  OD1 atom and residue 350's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 264's  O   atom and residue 350's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 269's  OE1 atom and residue 350's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 269's  OE2 atom and residue 350's CA   atom.
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] Residue connection id changed when creating a new residue at seqpos 269
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] ResConnID info stored on the connected residue (residue 350) is now out of date!
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] Connection atom name (in src):  OE1
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 294's  OD2 atom and residue 351's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 296's  OD1 atom and residue 351's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 298's  OD1 atom and residue 351's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 300's  O   atom and residue 351's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 305's  OE1 atom and residue 351's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 305's  OE2 atom and residue 351's CA   atom.
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] Residue connection id changed when creating a new residue at seqpos 305
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] ResConnID info stored on the connected residue (residue 351) is now out of date!
INFO:rosetta:core.conformation.Residue: {0} [ WARNING ] Connection atom name (in src):  OE1
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 333's  OD2 atom and residue 352's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 335's  OD1 atom and residue 352's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 337's  O   atom and residue 352's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Adding covalent linkage between residue 342's  OE2 atom and residue 352's CA   atom.
INFO:rosetta:core.util.metalloproteins_util: {0} Automatically setting up constraints between metal ions and metal-binding residues.
In [41]:
view = viewer.init(pose, window_size=(800, 600))
view()

You appear to be running in JupyterLab (or JavaScript failed to load for some other reason). You need to install the 3dmol extension:
jupyter labextension install jupyterlab_3dmol

To show basic cartoon representation, add viewer.setStyle():

In [42]:
view = viewer.init(pose, window_size=(800, 600)) + viewer.setStyle()
view()

You appear to be running in JupyterLab (or JavaScript failed to load for some other reason). You need to install the 3dmol extension:
jupyter labextension install jupyterlab_3dmol

To visualize ligands, non-conanical residues, metals, etc., viewer.setStyle() (and several other viewer.set* objects) optionally accept PyRosetta ResidueSelector objects. In the case of inputs/3EK4.pdb which is a $Ca^{2+}$-saturated GCaMP2 monomer, a ligand is a $Ca^{2+}$ ion and a non-canonical residue is the chromophore "CRO", both of which are aleady parameterized and available in the PyRosetta residue type set database. Therefore, we do not need to initialize PyRosetta with custom "CA" or "CRO" .params files. However, if one wishes to visualize ligands and non-canonical residues for which .params files are not available in the PyRosetta residue type set database, one must first initialize PyRosetta providing .params files for any ligands and non-canonical residues in the input Pose(s) or PackedPose(s):

pyrosetta.init("-extra_res_fa /path/to/LIG.fa.params")

pyrosetta.distributed.viewer passes the Pose's PDB numbering of selected residues to py3dmol for macromolecular rendering. Also, one may layer any visualization modules with any ResidueSelectors in the order they are summed (from left to right). In this case:

In [43]:
metals_selector = pyrosetta.rosetta.core.select.residue_selector.ResiduePropertySelector(
     pyrosetta.rosetta.core.chemical.ResidueProperty.METAL
)
ligands_selector = pyrosetta.rosetta.core.select.residue_selector.ResiduePropertySelector(
     pyrosetta.rosetta.core.chemical.ResidueProperty.LIGAND
)

view = viewer.init(pose, window_size=(800, 600)) \
    + viewer.setStyle() \
    + viewer.setStyle(residue_selector=ligands_selector, style="stick", colorscheme="magentaCarbon", radius=0.5) \
    + viewer.setStyle(residue_selector=metals_selector, style="sphere", colorscheme="chainHetatm", radius=1.5)
  1. viewer.setStyle() layers the cartoon backbone and stick side-chain representation by default
  2. viewer.setStyle(residue_selector=ligands_selector, style="stick", colorscheme="magentaCarbon", radius=0.5) layers any residue with the LIGAND property a 0.5 radius stick with magenta carbon atoms.
  3. viewer.setStyle(residue_selector=metals_selector, style="sphere", colorscheme="chainHetatm", radius=1.5) layers any residue with the METAL property a 1.5 radius sphere with the py3dmol color scheme "chainHetatm".
In [44]:
view()

You appear to be running in JupyterLab (or JavaScript failed to load for some other reason). You need to install the 3dmol extension:
jupyter labextension install jupyterlab_3dmol