vimol 0.1.2__tar.gz → 0.1.3__tar.gz

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.
Files changed (65) hide show
  1. vimol-0.1.3/PKG-INFO +199 -0
  2. vimol-0.1.3/README.md +163 -0
  3. {vimol-0.1.2 → vimol-0.1.3}/pyproject.toml +2 -1
  4. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/__init__.py +7 -2
  5. vimol-0.1.3/src/vimol/align.py +934 -0
  6. vimol-0.1.3/src/vimol/app.py +299 -0
  7. vimol-0.1.3/src/vimol/bonds.py +110 -0
  8. vimol-0.1.3/src/vimol/data/c60.xyz +62 -0
  9. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/editor.py +8 -0
  10. vimol-0.1.3/src/vimol/file_browser.py +65 -0
  11. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/gl_adapter.py +55 -0
  12. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/gl_render.py +176 -3
  13. vimol-0.1.3/src/vimol/glyph_font.py +176 -0
  14. vimol-0.1.3/src/vimol/glyph_mesh.py +311 -0
  15. vimol-0.1.3/src/vimol/glyph_outlines.py +171 -0
  16. vimol-0.1.3/src/vimol/glyphs.py +954 -0
  17. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/input.py +32 -0
  18. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/kitty.py +13 -0
  19. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/molecule.py +27 -0
  20. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/parsers/pdb.py +10 -0
  21. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/render.py +108 -47
  22. vimol-0.1.3/src/vimol/render_glyph.py +409 -0
  23. vimol-0.1.3/src/vimol/residues.py +399 -0
  24. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/scene.py +50 -1
  25. vimol-0.1.3/src/vimol/select.py +267 -0
  26. vimol-0.1.3/src/vimol/structures.py +802 -0
  27. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/theme.py +3 -2
  28. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/viewer.py +1972 -117
  29. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/widget.py +165 -17
  30. vimol-0.1.3/src/vimol.egg-info/PKG-INFO +199 -0
  31. {vimol-0.1.2 → vimol-0.1.3}/src/vimol.egg-info/SOURCES.txt +15 -0
  32. {vimol-0.1.2 → vimol-0.1.3}/src/vimol.egg-info/requires.txt +3 -0
  33. vimol-0.1.3/tests/test_add_file.py +380 -0
  34. vimol-0.1.3/tests/test_align.py +1399 -0
  35. vimol-0.1.3/tests/test_bonds.py +449 -0
  36. {vimol-0.1.2 → vimol-0.1.3}/tests/test_editing.py +420 -10
  37. vimol-0.1.3/tests/test_file_browser.py +84 -0
  38. vimol-0.1.3/tests/test_glyphs.py +691 -0
  39. {vimol-0.1.2 → vimol-0.1.3}/tests/test_render_fast.py +33 -8
  40. {vimol-0.1.2 → vimol-0.1.3}/tests/test_structures.py +56 -0
  41. {vimol-0.1.2 → vimol-0.1.3}/tests/test_vimol.py +1600 -66
  42. vimol-0.1.2/PKG-INFO +0 -106
  43. vimol-0.1.2/README.md +0 -72
  44. vimol-0.1.2/src/vimol/app.py +0 -268
  45. vimol-0.1.2/src/vimol/bonds.py +0 -79
  46. vimol-0.1.2/src/vimol/structures.py +0 -398
  47. vimol-0.1.2/src/vimol.egg-info/PKG-INFO +0 -106
  48. {vimol-0.1.2 → vimol-0.1.3}/LICENSE +0 -0
  49. {vimol-0.1.2 → vimol-0.1.3}/setup.cfg +0 -0
  50. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/__main__.py +0 -0
  51. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/_render_fast.py +0 -0
  52. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/arrows.py +0 -0
  53. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/camera.py +0 -0
  54. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/elements.py +0 -0
  55. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/parsers/__init__.py +0 -0
  56. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/parsers/mol.py +0 -0
  57. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/parsers/xyz.py +0 -0
  58. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/periodic_table.py +0 -0
  59. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/py.typed +0 -0
  60. {vimol-0.1.2 → vimol-0.1.3}/src/vimol/templates.py +0 -0
  61. {vimol-0.1.2 → vimol-0.1.3}/src/vimol.egg-info/dependency_links.txt +0 -0
  62. {vimol-0.1.2 → vimol-0.1.3}/src/vimol.egg-info/entry_points.txt +0 -0
  63. {vimol-0.1.2 → vimol-0.1.3}/src/vimol.egg-info/top_level.txt +0 -0
  64. {vimol-0.1.2 → vimol-0.1.3}/tests/test_gl_render.py +0 -0
  65. {vimol-0.1.2 → vimol-0.1.3}/tests/test_scene_structures.py +0 -0
vimol-0.1.3/PKG-INFO ADDED
@@ -0,0 +1,199 @@
1
+ Metadata-Version: 2.4
2
+ Name: vimol
3
+ Version: 0.1.3
4
+ Summary: A terminal molecular viewer and editor using the Kitty graphics protocol
5
+ Author: vimol contributors
6
+ License-Expression: MIT
7
+ Keywords: molecular,viewer,editor,terminal,kitty,chemistry,visualization,xyz,pdb,sdf,cli,tui
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
22
+ Classifier: Topic :: Scientific/Engineering :: Visualization
23
+ Classifier: Topic :: Multimedia :: Graphics :: Viewers
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: numpy>=1.20
29
+ Requires-Dist: moderngl>=5.6
30
+ Requires-Dist: numba>=0.59
31
+ Provides-Extra: test
32
+ Requires-Dist: pytest>=7; extra == "test"
33
+ Provides-Extra: align
34
+ Requires-Dist: scipy>=1.4; extra == "align"
35
+ Dynamic: license-file
36
+
37
+ # vimol
38
+
39
+ A molecular viewer and editor that runs **in your terminal**. Open an `.xyz`,
40
+ `.pdb`, `.mol` or `.sdf` file and get a shaded, rotatable, editable 3D
41
+ structure right where you are already working — over SSH, in tmux, beside your
42
+ editor.
43
+
44
+ ```bash
45
+ pip install vimol
46
+ vimol molecule.xyz
47
+ ```
48
+
49
+ ![C60 spinning in the terminal, rendered by vimol](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/spin.gif)
50
+
51
+ That is the C60 bundled with vimol, which `vimol` opens with no arguments.
52
+ Drag to rotate, scroll to zoom, option-drag empty space to pan, hover an atom
53
+ to identify it, `?` for every binding.
54
+
55
+ You need Python 3.8 or newer and a terminal that speaks the
56
+ [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) —
57
+ **kitty, Ghostty or WezTerm**. Rendering is pure software (numpy impostor
58
+ raycasting); if a GPU context can be created, an OpenGL path is used
59
+ automatically instead. MIT licensed.
60
+
61
+ ## Open a protein that does not know it is one
62
+
63
+ ![vimol opening a bare xyz protein and switching to the lettered residue view](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/protein.gif)
64
+
65
+ An `.xyz` file carries elements and coordinates and nothing else — no residue
66
+ names, no atom names, no chains. Hand vimol one anyway. It looks for the
67
+ `N–Cα–C(=O)` motif in the bond graph, and if it finds a backbone the file opens
68
+ as a cartoon ribbon rather than as a thicket of sticks.
69
+
70
+ Press `6` and each residue is drawn the way a figure would draw it: the
71
+ backbone runs as a ribbon through the Cα atoms, and every side chain links out
72
+ from its Cα to a solid carrying its one-letter code — a plate cut to the shape
73
+ of the ring for the aromatics, a rounded volume built from the real side-chain
74
+ carbons for the rest. Only the carbon skeleton is abstracted. The carboxylate,
75
+ the hydroxyl, the indole N–H and any hydrogen on one of those stay real atoms
76
+ in their element colours, at the exact coordinates in your file.
77
+
78
+ Residue identity is recovered from geometry alone. Walking outward from each Cα
79
+ gives every atom its bond distance from that Cα, which is precisely what the
80
+ Greek letter in a PDB atom name records; the resulting (element, distance)
81
+ signature identifies all twenty residues uniquely. The trp-cage above is PDB
82
+ 1RIJ stripped to bare coordinates, and vimol reads it back as
83
+ `ALQELLGQWLKDGGPSSGRPPPS` — character for character the sequence in that
84
+ entry's `SEQRES`. Something with no peptide backbone in it stays
85
+ ball-and-stick and says so.
86
+
87
+ ## Line one structure up against a conformer set
88
+
89
+ ![vimol overlaying 72 CREST conformers on a reference structure and reporting each RMSD](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/align.gif)
90
+
91
+ Pass more than one file and they load into a single session, auto-overlaid: the
92
+ active structure in normal element colours, the rest flat-tinted so you can
93
+ tell them apart. Multi-model files — trajectories, NMR ensembles, multi-record
94
+ SDFs — keep every frame, listed down the left. Several files always open in
95
+ ball-and-stick, so add `--style ribbon` when they are proteins, as above.
96
+
97
+ Clicking a file's `ALL` control pulls its whole ensemble into the overlay.
98
+ Then `r` rigidly aligns every tinted structure onto the untinted one and
99
+ reports each RMSD in a `∀RMSD` column beside the list. Above, that is a
100
+ chignolin crystal structure and 72 CREST conformers of it, landing between
101
+ 2.1 Å and 3.1 Å. Press `f` to re-fit the view once they are all in one place.
102
+
103
+ To fit on part of a structure instead, press `R` and click atoms on the main
104
+ structure, then `Enter`. vimol finds the matching element-compatible subset in
105
+ each tinted molecule and aligns the whole molecule from that fit, saving it as
106
+ a `⊂RMSD` column you can re-arm later. `Shift+S` offers ready-made selections —
107
+ backbone, backbone + Cβ, heavy atoms, largest ring system — instead of clicking
108
+ atoms yourself.
109
+ `pip install vimol[align]` adds scipy, which speeds up the permutation search;
110
+ without it a numpy fallback does the same work.
111
+
112
+ ## Build on a structure
113
+
114
+ ![vimol growing a methyl group onto threonine's side-chain hydroxyl](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/methyl.gif)
115
+
116
+ Editing is on by default. `a` enters append mode, and from there clicking a
117
+ hydrogen grows a new atom in its place, with its own filling hydrogens at
118
+ sensible geometry — one click turns threonine into O-methylthreonine. Clicking
119
+ a heavy atom replaces it, and clicking empty space starts a new molecule. The
120
+ pills in the status bar choose which element and which geometry you are
121
+ building with.
122
+
123
+ Option-drag from one atom to another draws a bond the automatic perception
124
+ would not have made, `x` deletes, `c` relaxes clashes, `u` undoes and `s`
125
+ saves.
126
+
127
+ ## Use it as a library
128
+
129
+ ![a C60 painted into the middle of a terminal by three lines of vimol](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/library.png)
130
+
131
+ Three lines put a molecule anywhere on the screen. Build a `Scene` at the pixel
132
+ size you want, park the cursor where its top-left corner belongs, and write:
133
+
134
+ ```python
135
+ import os, vimol
136
+
137
+ scene = vimol.Scene(vimol.load("c60.xyz"), 640, 380) # render it off-screen
138
+ scene.style.transparent = True # let the terminal through
139
+ os.write(1, b"\x1b[6;19H" + scene.to_kitty()) # paint at row 6, col 19
140
+ ```
141
+
142
+ That is `examples/inset.py`, and the picture above is what it prints.
143
+ `scene.render()` hands you the pixels as a uint8 array instead — `(H, W, 3)`,
144
+ or `(H, W, 4)` with a transparent background as above — and
145
+ `scene.to_png("out.png")` writes a PNG with a stdlib encoder, no Pillow.
146
+
147
+ For a molecule the user can actually turn, keep your own input loop and give
148
+ the widget only the events you want it to have:
149
+
150
+ ```python
151
+ from vimol import MoleculeWidget, InputDecoder, MouseEvent
152
+
153
+ widget = MoleculeWidget(mol, width_px, height_px) # no terminal, no loop
154
+ decoder = InputDecoder(pixel=True)
155
+
156
+ for ev in decoder.feed(data): # bytes you read from the tty
157
+ if isinstance(ev, MouseEvent) and inside_my_region(ev):
158
+ widget.handle_mouse(ev, origin=(region_x_px, region_y_px))
159
+ else:
160
+ my_app_handles(ev)
161
+
162
+ os.write(1, widget.to_kitty(cols=region_cols, rows=region_rows))
163
+ ```
164
+
165
+ `examples/embed_demo.py` is a complete host application built that way.
166
+
167
+ ## Reference
168
+
169
+ | Key | Does |
170
+ |---|---|
171
+ | Drag / arrows / `hjkl` | rotate |
172
+ | Wheel, `+` `-` | zoom |
173
+ | Right or middle drag | pan |
174
+ | `[` `]` | roll |
175
+ | `1` `2` `3` `4` | ball-and-stick, space-filling, licorice, wireframe |
176
+ | `5` `6` | ribbon, lettered residues (proteins) |
177
+ | `f` `z` | re-fit, reset the view |
178
+ | `m` | measure — click 2, 3 or 4 atoms for distance, angle, dihedral |
179
+ | `a` `x` `c` `u` `s` | append, delete, cleanup clashes, undo, save |
180
+ | `r` `R` | align an overlay, or align on picked atoms |
181
+ | `A` `n` `p` | add a file, next and previous structure |
182
+ | `Tab` | focus the structure list |
183
+ | `d` `g` `t` `ctrl-t` | depth cue, hi-quality, transparent background, theme |
184
+ | `?` `q` | help, quit |
185
+
186
+ ```bash
187
+ vimol traj.xyz --spin --style spacefill # spin a trajectory, space-filling
188
+ vimol protein.pdb --style glyph # lettered residues on a ribbon
189
+ vimol a.xyz b.pdb # load both, auto-overlaid
190
+ ```
191
+
192
+ Also `--backend cpu|gl|auto`, `--theme dark|light|auto`, `--rotate YAW PITCH`,
193
+ `--frame N`, `--background`, `--transparent`/`--opaque`, `--atom-scale`,
194
+ `--bond-radius`, `--no-depth-cue`, `--no-bonds`, `--bond-tolerance`,
195
+ `--list-formats`.
196
+
197
+ The protein, alignment and editing animations are recorded by
198
+ `scripts/record_demos.py`, which drives a real viewer and rasterizes the bytes
199
+ it writes; `docs/media/demo` holds their inputs.
vimol-0.1.3/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # vimol
2
+
3
+ A molecular viewer and editor that runs **in your terminal**. Open an `.xyz`,
4
+ `.pdb`, `.mol` or `.sdf` file and get a shaded, rotatable, editable 3D
5
+ structure right where you are already working — over SSH, in tmux, beside your
6
+ editor.
7
+
8
+ ```bash
9
+ pip install vimol
10
+ vimol molecule.xyz
11
+ ```
12
+
13
+ ![C60 spinning in the terminal, rendered by vimol](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/spin.gif)
14
+
15
+ That is the C60 bundled with vimol, which `vimol` opens with no arguments.
16
+ Drag to rotate, scroll to zoom, option-drag empty space to pan, hover an atom
17
+ to identify it, `?` for every binding.
18
+
19
+ You need Python 3.8 or newer and a terminal that speaks the
20
+ [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) —
21
+ **kitty, Ghostty or WezTerm**. Rendering is pure software (numpy impostor
22
+ raycasting); if a GPU context can be created, an OpenGL path is used
23
+ automatically instead. MIT licensed.
24
+
25
+ ## Open a protein that does not know it is one
26
+
27
+ ![vimol opening a bare xyz protein and switching to the lettered residue view](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/protein.gif)
28
+
29
+ An `.xyz` file carries elements and coordinates and nothing else — no residue
30
+ names, no atom names, no chains. Hand vimol one anyway. It looks for the
31
+ `N–Cα–C(=O)` motif in the bond graph, and if it finds a backbone the file opens
32
+ as a cartoon ribbon rather than as a thicket of sticks.
33
+
34
+ Press `6` and each residue is drawn the way a figure would draw it: the
35
+ backbone runs as a ribbon through the Cα atoms, and every side chain links out
36
+ from its Cα to a solid carrying its one-letter code — a plate cut to the shape
37
+ of the ring for the aromatics, a rounded volume built from the real side-chain
38
+ carbons for the rest. Only the carbon skeleton is abstracted. The carboxylate,
39
+ the hydroxyl, the indole N–H and any hydrogen on one of those stay real atoms
40
+ in their element colours, at the exact coordinates in your file.
41
+
42
+ Residue identity is recovered from geometry alone. Walking outward from each Cα
43
+ gives every atom its bond distance from that Cα, which is precisely what the
44
+ Greek letter in a PDB atom name records; the resulting (element, distance)
45
+ signature identifies all twenty residues uniquely. The trp-cage above is PDB
46
+ 1RIJ stripped to bare coordinates, and vimol reads it back as
47
+ `ALQELLGQWLKDGGPSSGRPPPS` — character for character the sequence in that
48
+ entry's `SEQRES`. Something with no peptide backbone in it stays
49
+ ball-and-stick and says so.
50
+
51
+ ## Line one structure up against a conformer set
52
+
53
+ ![vimol overlaying 72 CREST conformers on a reference structure and reporting each RMSD](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/align.gif)
54
+
55
+ Pass more than one file and they load into a single session, auto-overlaid: the
56
+ active structure in normal element colours, the rest flat-tinted so you can
57
+ tell them apart. Multi-model files — trajectories, NMR ensembles, multi-record
58
+ SDFs — keep every frame, listed down the left. Several files always open in
59
+ ball-and-stick, so add `--style ribbon` when they are proteins, as above.
60
+
61
+ Clicking a file's `ALL` control pulls its whole ensemble into the overlay.
62
+ Then `r` rigidly aligns every tinted structure onto the untinted one and
63
+ reports each RMSD in a `∀RMSD` column beside the list. Above, that is a
64
+ chignolin crystal structure and 72 CREST conformers of it, landing between
65
+ 2.1 Å and 3.1 Å. Press `f` to re-fit the view once they are all in one place.
66
+
67
+ To fit on part of a structure instead, press `R` and click atoms on the main
68
+ structure, then `Enter`. vimol finds the matching element-compatible subset in
69
+ each tinted molecule and aligns the whole molecule from that fit, saving it as
70
+ a `⊂RMSD` column you can re-arm later. `Shift+S` offers ready-made selections —
71
+ backbone, backbone + Cβ, heavy atoms, largest ring system — instead of clicking
72
+ atoms yourself.
73
+ `pip install vimol[align]` adds scipy, which speeds up the permutation search;
74
+ without it a numpy fallback does the same work.
75
+
76
+ ## Build on a structure
77
+
78
+ ![vimol growing a methyl group onto threonine's side-chain hydroxyl](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/methyl.gif)
79
+
80
+ Editing is on by default. `a` enters append mode, and from there clicking a
81
+ hydrogen grows a new atom in its place, with its own filling hydrogens at
82
+ sensible geometry — one click turns threonine into O-methylthreonine. Clicking
83
+ a heavy atom replaces it, and clicking empty space starts a new molecule. The
84
+ pills in the status bar choose which element and which geometry you are
85
+ building with.
86
+
87
+ Option-drag from one atom to another draws a bond the automatic perception
88
+ would not have made, `x` deletes, `c` relaxes clashes, `u` undoes and `s`
89
+ saves.
90
+
91
+ ## Use it as a library
92
+
93
+ ![a C60 painted into the middle of a terminal by three lines of vimol](https://raw.githubusercontent.com/hanimustafa/vimol/main/docs/media/library.png)
94
+
95
+ Three lines put a molecule anywhere on the screen. Build a `Scene` at the pixel
96
+ size you want, park the cursor where its top-left corner belongs, and write:
97
+
98
+ ```python
99
+ import os, vimol
100
+
101
+ scene = vimol.Scene(vimol.load("c60.xyz"), 640, 380) # render it off-screen
102
+ scene.style.transparent = True # let the terminal through
103
+ os.write(1, b"\x1b[6;19H" + scene.to_kitty()) # paint at row 6, col 19
104
+ ```
105
+
106
+ That is `examples/inset.py`, and the picture above is what it prints.
107
+ `scene.render()` hands you the pixels as a uint8 array instead — `(H, W, 3)`,
108
+ or `(H, W, 4)` with a transparent background as above — and
109
+ `scene.to_png("out.png")` writes a PNG with a stdlib encoder, no Pillow.
110
+
111
+ For a molecule the user can actually turn, keep your own input loop and give
112
+ the widget only the events you want it to have:
113
+
114
+ ```python
115
+ from vimol import MoleculeWidget, InputDecoder, MouseEvent
116
+
117
+ widget = MoleculeWidget(mol, width_px, height_px) # no terminal, no loop
118
+ decoder = InputDecoder(pixel=True)
119
+
120
+ for ev in decoder.feed(data): # bytes you read from the tty
121
+ if isinstance(ev, MouseEvent) and inside_my_region(ev):
122
+ widget.handle_mouse(ev, origin=(region_x_px, region_y_px))
123
+ else:
124
+ my_app_handles(ev)
125
+
126
+ os.write(1, widget.to_kitty(cols=region_cols, rows=region_rows))
127
+ ```
128
+
129
+ `examples/embed_demo.py` is a complete host application built that way.
130
+
131
+ ## Reference
132
+
133
+ | Key | Does |
134
+ |---|---|
135
+ | Drag / arrows / `hjkl` | rotate |
136
+ | Wheel, `+` `-` | zoom |
137
+ | Right or middle drag | pan |
138
+ | `[` `]` | roll |
139
+ | `1` `2` `3` `4` | ball-and-stick, space-filling, licorice, wireframe |
140
+ | `5` `6` | ribbon, lettered residues (proteins) |
141
+ | `f` `z` | re-fit, reset the view |
142
+ | `m` | measure — click 2, 3 or 4 atoms for distance, angle, dihedral |
143
+ | `a` `x` `c` `u` `s` | append, delete, cleanup clashes, undo, save |
144
+ | `r` `R` | align an overlay, or align on picked atoms |
145
+ | `A` `n` `p` | add a file, next and previous structure |
146
+ | `Tab` | focus the structure list |
147
+ | `d` `g` `t` `ctrl-t` | depth cue, hi-quality, transparent background, theme |
148
+ | `?` `q` | help, quit |
149
+
150
+ ```bash
151
+ vimol traj.xyz --spin --style spacefill # spin a trajectory, space-filling
152
+ vimol protein.pdb --style glyph # lettered residues on a ribbon
153
+ vimol a.xyz b.pdb # load both, auto-overlaid
154
+ ```
155
+
156
+ Also `--backend cpu|gl|auto`, `--theme dark|light|auto`, `--rotate YAW PITCH`,
157
+ `--frame N`, `--background`, `--transparent`/`--opaque`, `--atom-scale`,
158
+ `--bond-radius`, `--no-depth-cue`, `--no-bonds`, `--bond-tolerance`,
159
+ `--list-formats`.
160
+
161
+ The protein, alignment and editing animations are recorded by
162
+ `scripts/record_demos.py`, which drives a real viewer and rasterizes the bytes
163
+ it writes; `docs/media/demo` holds their inputs.
@@ -45,6 +45,7 @@ dependencies = ["numpy>=1.20", "moderngl>=5.6", "numba>=0.59"]
45
45
 
46
46
  [project.optional-dependencies]
47
47
  test = ["pytest>=7"]
48
+ align = ["scipy>=1.4"]
48
49
 
49
50
  [project.scripts]
50
51
  vimol = "vimol.app:main"
@@ -56,4 +57,4 @@ version = { attr = "vimol.__version__" }
56
57
  where = ["src"]
57
58
 
58
59
  [tool.setuptools.package-data]
59
- vimol = ["py.typed"]
60
+ vimol = ["py.typed", "data/c60.xyz"]
@@ -32,14 +32,19 @@ from . import kitty
32
32
  from . import elements
33
33
  from . import templates
34
34
  from . import editor
35
+ from . import select
36
+ from .structures import StructureSet, Structure, Transform, AlignmentResult
37
+ from .align import kabsch, superpose, permutation_search, subset_search
35
38
 
36
- __version__ = "0.1.2"
39
+ __version__ = "0.1.3"
37
40
 
38
41
  __all__ = [
39
42
  "Molecule", "VectorField", "Camera", "Renderer", "Style", "Scene", "MoleculeWidget",
40
43
  "InputDecoder", "MouseEvent", "KeyEvent", "enable_mouse", "disable_mouse",
41
44
  "load", "load_all", "loads", "save", "SUPPORTED_EXTENSIONS", "SAVE_EXTENSIONS",
42
- "perceive_bonds", "ensure_bonds", "kitty", "elements", "templates", "editor",
45
+ "perceive_bonds", "ensure_bonds", "kitty", "elements", "templates", "editor", "select",
46
+ "StructureSet", "Structure", "Transform", "AlignmentResult", "kabsch",
47
+ "superpose", "permutation_search", "subset_search",
43
48
  "view", "__version__",
44
49
  ]
45
50