/
ngl_viewer.py
90 lines (77 loc) · 2.7 KB
/
ngl_viewer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""The [NGL Viewer](https://github.com/nglviewer/ngl) can be used
to visualize and analyse pdb molecule structures.
Source: Discussion on [Discourse 583]\
(https://discourse.holoviz.org/t/how-to-use-ngl-webgl-protein-viewer-in-panel/583)
Author: https://github.com/Jhsmit
"""
import panel as pn
import param
NGL_JS = "https://unpkg.com/ngl@2.0.0-dev.37/dist/ngl.js"
REPRESENTATIONS = [
"ball+stick",
"backbone",
"ball+stick",
"cartoon",
"hyperball",
"licorice",
"ribbon",
"rope",
"spacefill",
"surface",
]
COLOR_SCHEMES = ["chainid", "residueindex", "chainname"]
class NGLViewer(pn.pane.HTML):
"""The [NGL Viewer](https://github.com/nglviewer/ngl) can be used
to show and analyse pdb molecule structures"""
pdb_string = param.String()
rcsb_id = param.String()
representation = param.Selector(
default="ribbon",
objects=REPRESENTATIONS,
)
color_scheme = param.Selector(default="chainid", objects=COLOR_SCHEMES)
spin = param.Boolean(default=False)
priority = 0
_rename = dict(
pn.pane.HTML._rename, # pylint: disable=protected-access
pdb_string=None,
rcsb_id=None,
representation=None,
spin=None,
color_scheme=None,
)
def __init__(self, **params):
if not "ngl_js" in pn.config.js_files:
pn.config.js_files["ngl_js"] = NGL_JS
super().__init__(**params)
self.load_string = """
stage = new NGL.Stage("viewport");
stage.loadFile()"""
self._update_object_from_parameters()
@param.depends("representation", "spin", "color_scheme", watch=True)
def _update_object_from_parameters(self):
html = f"""\
<div id="viewport" style="width:100%; height:100%;"></div>
<script>
{self.load_string}.then(function(o){{
o.addRepresentation("{self.representation}", {{colorScheme: "{self.color_scheme}"}});
o.autoView();
}}
);
stage.setSpin({'true' if self.spin else 'false'});
</script>
"""
self.object = html
@param.depends("pdb_string", watch=True)
def _update_object_from_pdb_string(self):
self.load_string = f"""
var PDBString = `{self.pdb_string}`;
stage = new NGL.Stage("viewport");
stage.loadFile( new Blob([PDBString], {{type: 'text/plain'}}), {{ ext:'pdb'}} )"""
self._update_object_from_parameters()
@param.depends("rcsb_id", watch=True)
def _update_object_from_rcsb_id(self):
self.load_string = f"""
stage = new NGL.Stage("viewport");
stage.loadFile("rcsb://{self.rcsb_id}")"""
self._update_object_from_parameters()