cosmol-viewer 0.1.5.dev3__pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cosmol-viewer might be problematic. Click here for more details.
- cosmol_viewer/__init__.py +5 -0
- cosmol_viewer/__init__.pyi +320 -0
- cosmol_viewer/cosmol_viewer.pypy311-pp73-x86_64-linux-gnu.so +0 -0
- cosmol_viewer/py.typed +0 -0
- cosmol_viewer-0.1.5.dev3.dist-info/METADATA +107 -0
- cosmol_viewer-0.1.5.dev3.dist-info/RECORD +7 -0
- cosmol_viewer-0.1.5.dev3.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
from typing import Optional, Union, List
|
|
2
|
+
|
|
3
|
+
def parse_sdf(
|
|
4
|
+
sdf: str,
|
|
5
|
+
keep_h: bool = True,
|
|
6
|
+
multimodel: bool = True,
|
|
7
|
+
onemol: bool = False
|
|
8
|
+
) -> "MoleculeData":
|
|
9
|
+
"""
|
|
10
|
+
Parse an SDF file or string into molecule data.
|
|
11
|
+
|
|
12
|
+
# Args
|
|
13
|
+
- sdf: Path to an SDF file or a string containing SDF content.
|
|
14
|
+
- keep_h: Whether to keep explicit hydrogen atoms (default: True).
|
|
15
|
+
- multimodel: Whether to allow multiple models in one file (default: True).
|
|
16
|
+
- onemol: Whether to merge multiple models into one molecule (default: False).
|
|
17
|
+
|
|
18
|
+
# Returns
|
|
19
|
+
- MoleculeData: Parsed molecule data object.
|
|
20
|
+
|
|
21
|
+
# Example
|
|
22
|
+
```python
|
|
23
|
+
from cosmol_viewer import parse_sdf
|
|
24
|
+
mol = parse_sdf("molecule.sdf")
|
|
25
|
+
```
|
|
26
|
+
"""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Scene:
|
|
31
|
+
"""
|
|
32
|
+
A 3D scene container for visualizing molecular or geometric shapes.
|
|
33
|
+
|
|
34
|
+
This class allows adding, updating, and removing shapes in a 3D scene,
|
|
35
|
+
as well as modifying scene-level properties like scale and background color.
|
|
36
|
+
|
|
37
|
+
Supported shape types:
|
|
38
|
+
- PySphere
|
|
39
|
+
- PyStick
|
|
40
|
+
- PyMolecules
|
|
41
|
+
|
|
42
|
+
Shapes can be optionally identified with a string `id`,
|
|
43
|
+
which allows updates and deletion.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Creates a new empty scene.
|
|
49
|
+
|
|
50
|
+
# Example
|
|
51
|
+
```python
|
|
52
|
+
scene = Scene()
|
|
53
|
+
```
|
|
54
|
+
"""
|
|
55
|
+
...
|
|
56
|
+
|
|
57
|
+
def add_shape(self, shape: Union["Sphere", "Stick", "Molecules"], id: Optional[str] = None) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Add a shape to the scene.
|
|
60
|
+
|
|
61
|
+
# Args
|
|
62
|
+
- shape: A shape instance (PySphere, PyStick, or PyMolecules).
|
|
63
|
+
- id: Optional string ID to associate with the shape.
|
|
64
|
+
|
|
65
|
+
If the `id` is provided and a shape with the same ID exists,
|
|
66
|
+
the new shape will replace it.
|
|
67
|
+
|
|
68
|
+
# Example
|
|
69
|
+
```python
|
|
70
|
+
scene.add_shape(sphere)
|
|
71
|
+
scene.add_shape(stick, id="bond1")
|
|
72
|
+
```
|
|
73
|
+
"""
|
|
74
|
+
...
|
|
75
|
+
|
|
76
|
+
def update_shape(self, id: str, shape: Union["Sphere", "Stick", "Molecules"]) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Update an existing shape in the scene by its ID.
|
|
79
|
+
|
|
80
|
+
# Args
|
|
81
|
+
- id: ID of the shape to update.
|
|
82
|
+
- shape: New shape object to replace the existing one.
|
|
83
|
+
|
|
84
|
+
# Example
|
|
85
|
+
```python
|
|
86
|
+
scene.update_shape("atom1", updated_sphere)
|
|
87
|
+
```
|
|
88
|
+
"""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
def delete_shape(self, id: str) -> None:
|
|
92
|
+
"""
|
|
93
|
+
Remove a shape from the scene by its ID.
|
|
94
|
+
|
|
95
|
+
# Args
|
|
96
|
+
- id: ID of the shape to remove.
|
|
97
|
+
|
|
98
|
+
# Example
|
|
99
|
+
```python
|
|
100
|
+
scene.delete_shape("bond1")
|
|
101
|
+
```
|
|
102
|
+
"""
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
def scale(self, scale: float) -> None:
|
|
106
|
+
"""
|
|
107
|
+
Set the global scale factor of the scene.
|
|
108
|
+
|
|
109
|
+
This affects the visual size of all shapes uniformly.
|
|
110
|
+
|
|
111
|
+
# Args
|
|
112
|
+
- scale: A positive float scaling factor.
|
|
113
|
+
|
|
114
|
+
# Example
|
|
115
|
+
```python
|
|
116
|
+
scene.scale(1.5)
|
|
117
|
+
```
|
|
118
|
+
"""
|
|
119
|
+
...
|
|
120
|
+
|
|
121
|
+
def set_background_color(self, background_color: List[float]) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Set the background color of the scene.
|
|
124
|
+
|
|
125
|
+
# Args
|
|
126
|
+
- background_color: An RGB array of 3 float values between 0.0 and 1.0.
|
|
127
|
+
|
|
128
|
+
# Example
|
|
129
|
+
```python
|
|
130
|
+
scene.set_background_color([1.0, 1.0, 1.0]) # white background
|
|
131
|
+
```
|
|
132
|
+
"""
|
|
133
|
+
...
|
|
134
|
+
|
|
135
|
+
class Viewer:
|
|
136
|
+
"""
|
|
137
|
+
A viewer that renders 3D scenes in different runtime environments
|
|
138
|
+
(e.g., Jupyter, Colab, or native GUI).
|
|
139
|
+
|
|
140
|
+
The `Viewer` automatically selects a backend:
|
|
141
|
+
- Jupyter/Colab → WebAssembly canvas (inline display)
|
|
142
|
+
- Python script/terminal → native GUI window (if supported)
|
|
143
|
+
|
|
144
|
+
Use `Viewer.render(scene)` to create and display a viewer instance.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
@staticmethod
|
|
148
|
+
def get_environment() -> str:
|
|
149
|
+
"""
|
|
150
|
+
Get the current runtime environment.
|
|
151
|
+
|
|
152
|
+
# Returns
|
|
153
|
+
- str: One of "Jupyter", "Colab", "PlainScript", or "IPythonTerminal".
|
|
154
|
+
|
|
155
|
+
# Example
|
|
156
|
+
```python
|
|
157
|
+
env = Viewer.get_environment()
|
|
158
|
+
print(env) # e.g., "Jupyter"
|
|
159
|
+
```
|
|
160
|
+
"""
|
|
161
|
+
...
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def render(scene: "Scene", width: float = 800.0, height: float = 600.0) -> "Viewer":
|
|
165
|
+
"""
|
|
166
|
+
Render a 3D scene.
|
|
167
|
+
|
|
168
|
+
# Args
|
|
169
|
+
- scene: The scene to render.
|
|
170
|
+
- width: The viewport width in pixels (default: 800).
|
|
171
|
+
- height: The viewport height in pixels (default: 600).
|
|
172
|
+
|
|
173
|
+
# Returns
|
|
174
|
+
- Viewer: The created viewer instance.
|
|
175
|
+
|
|
176
|
+
# Example
|
|
177
|
+
```python
|
|
178
|
+
from cosmol_viewer import Viewer, Scene, Sphere
|
|
179
|
+
scene = Scene()
|
|
180
|
+
scene.add_shape(Sphere([0, 0, 0], 1.0))
|
|
181
|
+
viewer = Viewer.render(scene)
|
|
182
|
+
```
|
|
183
|
+
"""
|
|
184
|
+
...
|
|
185
|
+
|
|
186
|
+
@staticmethod
|
|
187
|
+
def play(
|
|
188
|
+
frames: List["Scene"],
|
|
189
|
+
interval: float,
|
|
190
|
+
loops: int,
|
|
191
|
+
width: float = 800.0,
|
|
192
|
+
height: float = 600.0,
|
|
193
|
+
smooth: bool = False
|
|
194
|
+
) -> "Viewer":
|
|
195
|
+
"""
|
|
196
|
+
Play an animation of multiple frames.
|
|
197
|
+
|
|
198
|
+
# Args
|
|
199
|
+
- frames: List of Scene objects as animation frames.
|
|
200
|
+
- interval: Frame interval in seconds.
|
|
201
|
+
- loops: Number of loops to repeat (-1 for infinite).
|
|
202
|
+
- width: The viewport width in pixels.
|
|
203
|
+
- height: The viewport height in pixels.
|
|
204
|
+
- smooth: Whether to smooth the animation by
|
|
205
|
+
interpolating between frames.
|
|
206
|
+
|
|
207
|
+
# Returns
|
|
208
|
+
- Viewer: The created viewer instance.
|
|
209
|
+
|
|
210
|
+
# Example
|
|
211
|
+
```python
|
|
212
|
+
viewer = Viewer.play([scene1, scene2], interval=0.5, loops=3)
|
|
213
|
+
```
|
|
214
|
+
"""
|
|
215
|
+
...
|
|
216
|
+
|
|
217
|
+
def update(self, scene: "Scene") -> None:
|
|
218
|
+
"""
|
|
219
|
+
Update the viewer with a new scene.
|
|
220
|
+
|
|
221
|
+
Works for both Web-based rendering (Jupyter/Colab) and native GUI windows.
|
|
222
|
+
|
|
223
|
+
⚠️ Note (Jupyter/Colab): Animation updates may be limited by
|
|
224
|
+
notebook rendering capacity.
|
|
225
|
+
|
|
226
|
+
# Args
|
|
227
|
+
- scene: The updated scene.
|
|
228
|
+
|
|
229
|
+
# Example
|
|
230
|
+
```python
|
|
231
|
+
scene.add_shape(Sphere([1, 1, 1], 0.5))
|
|
232
|
+
viewer.update(scene)
|
|
233
|
+
```
|
|
234
|
+
"""
|
|
235
|
+
...
|
|
236
|
+
|
|
237
|
+
def save_image(self, path: str) -> None:
|
|
238
|
+
"""
|
|
239
|
+
Save the current image to a file.
|
|
240
|
+
|
|
241
|
+
# Args
|
|
242
|
+
- path: File path for the saved image.
|
|
243
|
+
|
|
244
|
+
# Example
|
|
245
|
+
```python
|
|
246
|
+
viewer.save_image("output.png")
|
|
247
|
+
```
|
|
248
|
+
"""
|
|
249
|
+
...
|
|
250
|
+
|
|
251
|
+
class Sphere:
|
|
252
|
+
"""
|
|
253
|
+
A sphere shape in the scene.
|
|
254
|
+
|
|
255
|
+
# Args
|
|
256
|
+
- center: [x, y, z] coordinates of the sphere center.
|
|
257
|
+
- radius: Radius of the sphere.
|
|
258
|
+
|
|
259
|
+
# Example
|
|
260
|
+
```python
|
|
261
|
+
sphere = Sphere([0, 0, 0], 1.0).color([1, 0, 0])
|
|
262
|
+
```
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
def __init__(self, center: List[float], radius: float) -> None: ...
|
|
266
|
+
def set_center(self, center: List[float]) -> "Sphere": ...
|
|
267
|
+
def set_radius(self, radius: float) -> "Sphere": ...
|
|
268
|
+
def color(self, color: List[float]) -> "Sphere": ...
|
|
269
|
+
def color_rgba(self, color: List[float]) -> "Sphere": ...
|
|
270
|
+
def opacity(self, opacity: float) -> "Sphere": ...
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class Stick:
|
|
274
|
+
"""
|
|
275
|
+
A cylindrical stick (or capsule) connecting two points.
|
|
276
|
+
|
|
277
|
+
# Args
|
|
278
|
+
- start: Starting point [x, y, z].
|
|
279
|
+
- end: Ending point [x, y, z].
|
|
280
|
+
- thickness: Stick radius.
|
|
281
|
+
|
|
282
|
+
# Example
|
|
283
|
+
```python
|
|
284
|
+
stick = Stick([0,0,0], [1,1,1], 0.1).opacity(0.5)
|
|
285
|
+
```
|
|
286
|
+
"""
|
|
287
|
+
|
|
288
|
+
def __init__(self, start: List[float], end: List[float], thickness: float) -> None: ...
|
|
289
|
+
def color(self, color: List[float]) -> "Stick": ...
|
|
290
|
+
def color_rgba(self, color: List[float]) -> "Stick": ...
|
|
291
|
+
def opacity(self, opacity: float) -> "Stick": ...
|
|
292
|
+
def set_thickness(self, thickness: float) -> "Stick": ...
|
|
293
|
+
def set_start(self, start: List[float]) -> "Stick": ...
|
|
294
|
+
def set_end(self, end: List[float]) -> "Stick": ...
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
class Molecules:
|
|
298
|
+
"""
|
|
299
|
+
A molecular shape object parsed from SDF data.
|
|
300
|
+
|
|
301
|
+
# Example
|
|
302
|
+
```python
|
|
303
|
+
mol = parse_sdf("molecule.sdf")
|
|
304
|
+
molecules = Molecules(mol).centered().color([0,1,0])
|
|
305
|
+
```
|
|
306
|
+
"""
|
|
307
|
+
|
|
308
|
+
def __init__(self, molecule_data: "MoleculeData") -> None: ...
|
|
309
|
+
def get_center(self) -> List[float]: ...
|
|
310
|
+
def centered(self) -> "Molecules": ...
|
|
311
|
+
def color(self, color: List[float]) -> "Molecules": ...
|
|
312
|
+
def color_rgba(self, color: List[float]) -> "Molecules": ...
|
|
313
|
+
def opacity(self, opacity: float) -> "Molecules": ...
|
|
314
|
+
def reset_color(self) -> "Molecules": ...
|
|
315
|
+
|
|
316
|
+
class MoleculeData:
|
|
317
|
+
"""
|
|
318
|
+
Internal representation of molecule data returned by `parse_sdf`.
|
|
319
|
+
"""
|
|
320
|
+
...
|
|
Binary file
|
cosmol_viewer/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cosmol-viewer
|
|
3
|
+
Version: 0.1.5.dev3
|
|
4
|
+
Summary: Molecular visualization tools
|
|
5
|
+
Author-email: 95028 <wjt@cosmol.org>
|
|
6
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
7
|
+
Project-URL: Repository, https://github.com/COSMol-repl/COSMol-viewer
|
|
8
|
+
|
|
9
|
+
# COSMol-viewer
|
|
10
|
+
|
|
11
|
+
<div align="center">
|
|
12
|
+
<a href="https://crates.io/crates/cosmol_viewer">
|
|
13
|
+
<img src="https://img.shields.io/crates/v/cosmol_viewer.svg" alt="crates.io Latest Release"/>
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://pypi.org/project/cosmol_viewer/">
|
|
16
|
+
<img src="https://img.shields.io/pypi/v/cosmol_viewer.svg" alt="PyPi Latest Release"/>
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://cosmol-repl.github.io/COSMol-viewer">
|
|
19
|
+
<img src="https://img.shields.io/badge/docs-latest-blue.svg" alt="Documentation Status"/>
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
A high-performance molecular viewer for `Python` and `Rust`, backed by `Rust`.
|
|
24
|
+
Supports both static rendering and smooth animation playback — including inside Jupyter notebooks.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
A compact, high-performance renderer for molecular and scientific shapes with two usage patterns:
|
|
28
|
+
|
|
29
|
+
- **Static rendering + update** — push individual scene updates from your application or simulation.
|
|
30
|
+
- **Play (recommended for demonstrations & smooth playback)** — precompute frames and hand the sequence to the viewer to play back with optional interpolation (`smooth`).
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quick concepts
|
|
35
|
+
|
|
36
|
+
- **Scene**: container for shapes (molecules, spheres, lines, etc.).
|
|
37
|
+
- **Viewer.render(scene, ...)**: create a static viewer bound to a canvas (native or notebook). Good for static visualization.
|
|
38
|
+
- **viewer.update(scene)**: push incremental changes (real-time / streaming use-cases).
|
|
39
|
+
- **Viewer.play(frames, interval, loops, width, height, smooth)**: *recommended* for precomputed animations and demonstrations. The viewer takes care of playback timing and looping.
|
|
40
|
+
|
|
41
|
+
**Why prefer `play` for demos?**
|
|
42
|
+
- Single call API (hand off responsibility to the viewer).
|
|
43
|
+
- Built-in timing & loop control.
|
|
44
|
+
- Optional `smooth` interpolation between frames for visually pleasing playback even when input frame rate is low.
|
|
45
|
+
|
|
46
|
+
**Why keep `update`?**
|
|
47
|
+
- `update` is ideal for real-time simulations, MD runs, or streaming data where frames are not precomputed. It provides strict fidelity (no interpolation) and minimal latency.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
pip install cosmol-viewer
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
See examples in [Google Colab](https://colab.research.google.com/drive/1Sw72QWjQh_sbbY43jGyBOfF1AQCycmIx?usp=sharing).
|
|
61
|
+
### 1. Static molecular rendering
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
65
|
+
|
|
66
|
+
with open("molecule.sdf", "r") as f:
|
|
67
|
+
sdf = f.read()
|
|
68
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
69
|
+
|
|
70
|
+
scene = Scene()
|
|
71
|
+
scene.scale(0.1)
|
|
72
|
+
scene.add_shape(mol, "mol")
|
|
73
|
+
|
|
74
|
+
viewer = Viewer.render(scene, width=600, height=400)
|
|
75
|
+
|
|
76
|
+
print("Press Any Key to exit...", end='', flush=True)
|
|
77
|
+
_ = input() # Keep the viewer open until you decide to close
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 2. Animation playback with `Viewer.play`
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from cosmol_viewer import Scene, Viewer, parse_sdf, Molecules
|
|
84
|
+
import time
|
|
85
|
+
|
|
86
|
+
interval = 0.033 # ~30 FPS
|
|
87
|
+
|
|
88
|
+
frames = []
|
|
89
|
+
|
|
90
|
+
for i in range(1, 10):
|
|
91
|
+
with open(f"frames/frame_{i}.sdf", "r") as f:
|
|
92
|
+
sdf = f.read()
|
|
93
|
+
mol = Molecules(parse_sdf(sdf)).centered()
|
|
94
|
+
|
|
95
|
+
scene = Scene()
|
|
96
|
+
scene.scale(0.1)
|
|
97
|
+
scene.add_shape(mol, "mol")
|
|
98
|
+
|
|
99
|
+
frames.append(scene)
|
|
100
|
+
|
|
101
|
+
Viewer.play(frames, interval=interval, loops=1, width=600, height=400, smooth=True)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
For API reference and advanced usage, please see the [latest documentation](https://cosmol-repl.github.io/COSMol-viewer).
|
|
107
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
cosmol_viewer-0.1.5.dev3.dist-info/METADATA,sha256=QxrICKiAP64ojWXAiAVapDYd9Nl8uyjJ3qmHReigflA,3579
|
|
2
|
+
cosmol_viewer-0.1.5.dev3.dist-info/WHEEL,sha256=5QxE6xq0lWihbtDBBnz5kE0ccXIWgQ-YWXtdrfCxiqM,161
|
|
3
|
+
cosmol_viewer/__init__.py,sha256=K33zoYpHqUVvpFdMVxmCtw4uKj9ZXrGuQD4D4DuUmjk,135
|
|
4
|
+
cosmol_viewer/__init__.pyi,sha256=4BNfRvoFnVWQjxl3FE2VrkNqfDUBAs4f1OcGgSv7fwE,8473
|
|
5
|
+
cosmol_viewer/cosmol_viewer.pypy311-pp73-x86_64-linux-gnu.so,sha256=X6xLhfyBXb3k61pD5byuk_cq4nRXl-0yIcoSxfi03W8,27799288
|
|
6
|
+
cosmol_viewer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
cosmol_viewer-0.1.5.dev3.dist-info/RECORD,,
|