{"id":18983114,"url":"https://github.com/rosettacommons/pyrosetta_viewer3d","last_synced_at":"2025-04-19T20:08:32.767Z","repository":{"id":36968693,"uuid":"498067509","full_name":"RosettaCommons/pyrosetta_viewer3d","owner":"RosettaCommons","description":"Display PackedPose objects, Pose objects, or PDB files within a Jupyter notebook and Google Colab","archived":false,"fork":false,"pushed_at":"2022-10-16T01:27:22.000Z","size":468,"stargazers_count":9,"open_issues_count":5,"forks_count":3,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-29T12:46:46.022Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RosettaCommons.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-30T19:09:30.000Z","updated_at":"2025-03-11T20:47:27.000Z","dependencies_parsed_at":"2023-01-17T09:45:43.975Z","dependency_job_id":null,"html_url":"https://github.com/RosettaCommons/pyrosetta_viewer3d","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RosettaCommons%2Fpyrosetta_viewer3d","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RosettaCommons%2Fpyrosetta_viewer3d/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RosettaCommons%2Fpyrosetta_viewer3d/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RosettaCommons%2Fpyrosetta_viewer3d/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RosettaCommons","download_url":"https://codeload.github.com/RosettaCommons/pyrosetta_viewer3d/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249246230,"owners_count":21237012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T16:15:55.466Z","updated_at":"2025-04-16T13:33:41.622Z","avatar_url":"https://github.com/RosettaCommons.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# viewer3d\nDisplay `PackedPose` objects, `Pose` objects, or `.pdb` files within a Jupyter notebook and Google Colab.\n\n# Description\nThe `viewer3d` macromolecular viewer quickly renders `.pdb` files, dynamically instantiating `Pose` objects if required for certain visualization modules (matching the name `viewer3d.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 `Pose`(s) pointer location(s) in memory remain fixed, and so the viewer can dynamically update upon `Pose` conformational changes by calling the following methods:\n\n```\nupdate_viewer(index=None, model=None, add_objects=True, remove_objects=True)\n```\n\n```\nadd_pose(pose, index=None, update_viewer=True)\n```\n\n```\nadd_pdbstring(pdbstring, index=None, update_viewer=True)\n```\n\n```\nremove_pose(index=None, model=None, update_viewer=True)\n```\n\n```\nremove_pdbstring(index=None, model=None, update_viewer=True)\n```\n\n```\nupdate_pose(pose, index=None, model=None, update_viewer=True)\n```\n\n```\nupdate_pdbstring(pdbstring, index=None, model=None, update_viewer=True)\n```\n\n```\nupdate_poses(poses, index=None, update_viewer=True)\n```\n\n```\nupdate_pdbstrings(pdbstrings, index=None, update_viewer=True)\n```\n\nFor adding/removing visualization modules in the widget update function, either initialize the viewer with `viewer3d.init(modules=[...])` or call the `set_modules()` method to overwrite the current list of modules. Otherwise, call the `clear()` method then add the new modules. After pose conformational changes and setting the viewer modules, call the `update_viewer()` method if the pose's pointer in memory remains the same, otherwise call the `update_pose(pose)` method to update the pose and viewer.\n\nSee docstrings for more information. The viewer applies visualization modules in the same order they are added (from left to right), so layering different styles (and `ResidueSelector`s) 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 molecule(s), otherwise `pyrosetta.distributed` automatically initializes PyRosetta with default command line options.\n\n# Contributing\nPlease open a pull request with an updated unit test from a custom branch.\n\n# Unit Tests\n`python -m unittest`\n\n# Installation\n`conda env create -f environment.yml`\n\n# PyPI Releases\n1. Update version number in `setup.py`\n2. `pip install --user --upgrade setuptools wheel twine`\n3. `rm -rf dist/*`\n4. `python setup.py sdist bdist_wheel`\n5. `python -m twine upload dist/*`\n\n# Usage Examples:\n```\nimport viewer3d\n```\n\nExample Jupyter notebook commands:\n\n```\nv = viewer3d.init(\"path/to/pdbfile.pdb\")\nv.show()\n```\n\n```\nimport logging\nlogging.basicConfig(level=logging.WARNING)\nimport pyrosetta\npyrosetta.init(\"-mute all\")\n\npose = pyrosetta.toolbox.rcsb.pose_from_rcsb(\"5BVL\")\n\nview = viewer3d.init(pose, window_size=(800, 600), backend=\"nglview\")\nview() # Equivalent to view.show()\n```\n\n```\nposes = [pyrosetta.toolbox.rcsb.pose_from_rcsb(pdbid) for pdbid in [\"5BVL\", \"6MSR\", \"1QCQ\"]]\n\nview = viewer3d.init(poses) \\\n+ viewer3d.setStyle(colorscheme=\"lightgreyCarbon\") \\\n+ viewer3d.setHydrogenBonds()\nview()\n```\n\n```\nimport pyrosetta.distributed.io as io\npacked_pose = io.to_packed(pyrosetta.toolbox.pose_from_rcsb(\"2FD7\"))\npolar_residue_selector = pyrosetta.rosetta.core.select.residue_selector.ResiduePropertySelector(\n    pyrosetta.rosetta.core.chemical.ResidueProperty(52)\n)\n\nview = viewer3d.init(packed_pose)\nview.add(viewer3d.setStyle(radius=0.1))\nview.add(viewer3d.setStyle(residue_selector=polar_residue_selector, colorscheme=\"whiteCarbon\", radius=0.25, label=False))\nview.add(viewer3d.setHydrogens(color=\"white\", polar_only=True, radius=0.1))\nview.add(viewer3d.setHydrogenBonds(color=\"black\"))\nview.add(viewer3d.setDisulfides(radius=0.1))\nview()\n```\n\n```\nview = sum(\n    [\n        viewer3d.init(packed_pose),\n        viewer3d.setStyle(cartoon=False, style=\"sphere\", radius=1.5, colorscheme=\"darkgreyCarbon\"),\n        viewer3d.setZoom(factor=1.5)\n    ]\n)\nview.show()\n```\n\n```\nfrom pyrosetta.rosetta.core.select.residue_selector import ChainSelector\npose = pyrosetta.toolbox.rcsb.pose_from_rcsb(\"6MSR\")\nchA = ChainSelector(\"A\")\nchB = ChainSelector(\"B\")\n\nview = sum(\n    [\n        viewer3d.init(pose, backend=1, gui=True),\n        viewer3d.setStyle(cartoon_color=\"lightgrey\", radius=0.25),\n        viewer3d.setSurface(residue_selector=chA, colorscheme=\"greenCarbon\", opacity=0.65, surface_type=\"VDW\"),\n        viewer3d.setSurface(residue_selector=chB, color=\"blue\", opacity=1.0, surface_type=\"SAS\"),\n        viewer3d.setDisulfides(radius=0.25),\n        viewer3d.setZoom(factor=1.5)\n    ]\n)\nview()\n```\n\n```\nimport pyrosetta.distributed.io as io\nimport viewer3d\nfrom pyrosetta.rosetta.core.select.residue_selector import (\n    LayerSelector,\n    ChainSelector,\n)\n\nposes = [io.pose_from_sequence(\"TEST\" * i) for i in range(1, 6)]\ncore_selector = LayerSelector()\ncore_selector.set_layers(True, False, False)\nboundary_selector = LayerSelector()\nboundary_selector.set_layers(False, True, False)\nsurface_selector = LayerSelector()\nsurface_selector.set_layers(False, False, True)\nview = (\n    viewer3d.init(poses, (1200, 800.01), delay=0, backend=1) \\\n    + viewer3d.setStyle()  #residue_selector=surface_selector, style=\"stick\", colorscheme=\"element\", label=False) #+ viewer3d.setSurface(opacity=0.5)\n    + viewer3d.setDisulfides() \\\n    + viewer3d.setBackgroundColor(color=\"lightgray\")\n    + viewer3d.setHydrogenBonds()\n    + viewer3d.setHydrogens(polar_only=True, color=\"white\")\n    + viewer3d.setZoomTo(ChainSelector(\"A\")) \\\n    + viewer3d.setZoom(-1) \\\n)\nview.show()\n```\n\n```\nfrom pyrosetta.rosetta.core.select.residue_selector import SecondaryStructureSelector\nhelix_selector = SecondaryStructureSelector(\"H\")\nsheet_selector = SecondaryStructureSelector(\"E\")\nloop_selector = SecondaryStructureSelector(\"L\")\n\nmodules = [\n    viewer3d.setBackgroundColor(color=\"grey\"),\n    viewer3d.setStyle(residue_selector=helix_selector, cartoon_color=\"blue\", label=False, radius=0),\n    viewer3d.setStyle(residue_selector=sheet_selector, cartoon_color=\"red\", label=False, radius=0),\n    viewer3d.setStyle(residue_selector=loop_selector, cartoon_color=\"white\", label=False, radius=0)\n]\n\nview = viewer3d.init(poses, window_size=(1200, 600), modules=modules, continuous_update=True)\nview()\n```\n\n```\nview.clear() # Subtract all visualization modules previously added to the Viewer\nview()\n```\n\nView a live trajectory:\n```\npose = pyrosetta.toolbox.pose_from_rcsb(\"2FD7\")\nv = viewer3d.init(pose, delay=0.1) + viewer3d.setStyle(radius=0.1) + viewer3d.setDisulfides(radius=0.1)\nbackrub = pyrosetta.rosetta.protocols.backrub.BackrubMover()\nminimize = pyrosetta.rosetta.protocols.minimization_packing.MinMover()\n\nfor _ in range(100):\n    backrub.apply(pose)\n    minimize.apply(pose)\n    v.update_pose(pose)\n```\n\nDisplay preset custom viewers for routine visualizations:\n```\nviewer3d.presets.coreBoundarySurface(poses, window_size=(800, 600), continuous_update=True)\n```\n\n```\nview = viewer3d.presets.makeBundle(backend=1)\nview.show()\n```\n\nVisualize the residue 1 \u003ci\u003epsi\u003c/i\u003e-space of a 20-residue polyvaline extended peptide:\n```\nfrom bokeh.palettes import Viridis\nn = 11 # 256\nv = viewer3d.init(backend=1)\npose = pyrosetta.io.pose_from_sequence(\"V\" * 20)\nfor i, hex_str in enumerate(Viridis[n]):\n    v.set_modules(viewer3d.setStyle(cartoon_color=hex_str, radius=0))\n    pose.set_psi(1, i * 360 / n)\n    v.add_pose(pose)\n```\n\nOverlay multiple poses:\n```\npose1 = pyrosetta.toolbox.rcsb.pose_from_rcsb(\"6V67\")\npose2 = pyrosetta.toolbox.rcsb.pose_from_rcsb(\"1ATP\")\nv = viewer3d.init()\nv += viewer3d.setStyle(colorscheme='redCarbon')\nv += viewer3d.setSurface()\nv.add_pose(pose1) # Automatically updates the viewer with the currently set modules\nv.reset() # Subtract all modules\nv += viewer3d.setStyle(colorscheme='blueCarbon')\nv.add_pose(pose2)\n```\n\nView different sets of different overlaid poses:\n```\npose = pyrosetta.toolbox.pose_from_rcsb(\"2FD7\")\nv = viewer3d.init(pose, delay=0, backend=1)\nbackrub = pyrosetta.rosetta.protocols.backrub.BackrubMover()\nminimize = pyrosetta.rosetta.protocols.minimization_packing.MinMover()\nv.set_modules([viewer3d.setStyle(), viewer3d.setDisulfides()])\n\nfor h in range(5):\n    for i in range(5):\n        for j in range(5):\n            backrub.apply(pose)\n            minimize.apply(pose)\n        v.add_pose(pose.clone(), index=h, update_viewer=False)\nv.show()\n```\n\nOverlay all poses or PDB strings:\n```\nv.overlay()\n```\n\nColor residues by `PerResidueRealMetric`s:\n```\nscorefxn = pyrosetta.create_score_function(\"ref2015\")\nminimize = pyrosetta.rosetta.protocols.minimization_packing.MinMover()\ne = (\n    pyrosetta.rosetta.core.simple_metrics.per_residue_metrics.PerResidueEnergyMetric()\n)\ne.set_scorefunction(scorefxn)\nv = viewer3d.init(backend=backend, gui=True)\npalette = list(bokeh.palettes.Greens256) + list(\n    reversed(bokeh.palettes.Reds256)\n)\nv += viewer3d.setStyle(radius=0)\nv += viewer3d.setPerResidueRealMetric(\n    scoretype=\"res_energy\", vmin=-10, vmax=10, radius=0.2, log=10, palette=palette\n)\nv += viewer3d.setHydrogens(polar_only=True, color=\"lightgray\")\nv += viewer3d.setHydrogenBonds()\nv += viewer3d.setDisulfides()\nfor h in range(10):\n    _pose = pose.clone()\n    _pose.scores.clear()\n    for i in range(20):\n        minimize.apply(_pose)\n    e.apply(_pose)\n    v.add_pose(_pose, index=h, update_viewer=False)\nv.show()\n```\n\nColor residues by per-residue total score:\n```\nv = viewer3d.presets.perResidueEnergyMetric(pose)\nv.show()\n```\n\nColor residues by per-residue clash score:\n```\nv = viewer3d.presets.perResidueClashMetric(poses, backend=0)\nv.show()\n```\n\nColor residues by per-residue SASA score:\n```\nv = viewer3d.presets.perResidueSasaMetric(pose, backend=1)\nv.show()\n```\n\nColor residues by per-residue satisfied backbone hydrogen bonds:\n```\nv = viewer3d.presets.unsatSelector(pose)\nv.show()\n```\n\nVisualize multiple Rosetta analyses:\n```\nv = viewer3d.presets.rosettaViewer(poses, backend=1)\nv.show()\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosettacommons%2Fpyrosetta_viewer3d","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frosettacommons%2Fpyrosetta_viewer3d","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosettacommons%2Fpyrosetta_viewer3d/lists"}