megane-viewer 0.6.2 → 0.8.0
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.
- package/README.md +31 -19
- package/dist/assets/decode.worker-BcZeHdFu.js +1 -0
- package/dist/{gif-BkoUK__l.js → gif-CsP6AQIk.js} +1 -1
- package/dist/lib-d68cwxNq.js +35419 -0
- package/dist/lib.js +15 -14
- package/dist/megane-viewer.css +1 -1
- package/dist/megane_wasm-8Sj7p71h.js +631 -0
- package/dist/widget.js +36762 -24038
- package/package.json +40 -6
- package/dist/assets/decode.worker-COS7O5zc.js +0 -1
- package/dist/lib-Bf1GV7sy.js +0 -19601
- package/dist/megane_wasm-BO5Sx0-Z.js +0 -464
package/README.md
CHANGED
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
## Features
|
|
33
33
|
|
|
34
34
|
- **1M+ Atoms at 60fps** — Billboard impostor rendering scales from small molecules to massive complexes in real time. InstancedMesh for small systems auto-switches to GPU-accelerated billboard impostors for large systems. Stream XTC trajectories over WebSocket.
|
|
35
|
-
- **Runs Everywhere** — Jupyter widget, CLI server, React component, and VSCode extension. Rust-based PDB, GRO, XYZ, MOL, CIF,
|
|
36
|
-
- **Visual Pipeline Editor** — Build visualization workflows by wiring nodes or let the AI generator build them from natural language.
|
|
35
|
+
- **Runs Everywhere** — Jupyter widget, CLI server, React component, and VSCode extension. Rust-based parsers for 15 formats (PDB, GRO, XYZ, MOL/SDF, MOL2, CIF, mmCIF, LAMMPS data, AMBER topology, XTC, DCD, ASE .traj, LAMMPS dump, AMBER NetCDF) shared between Python (PyO3) and browser (WASM) — parse once, run anywhere.
|
|
36
|
+
- **Visual Pipeline Editor** — Build visualization workflows by wiring nodes or let the AI generator build them from natural language. 16 node types with 7 typed data channels flowing through color-coded edges. Load multiple structures with layer-based rendering to compare systems side by side.
|
|
37
37
|
- **Embed & Integrate** — Control the viewer from Plotly via ipywidgets events. Embed in MDX / Next.js docs. React to `frame_change`, `selection_change`, and `measurement` events. Use the framework-agnostic renderer from Vue, Svelte, or vanilla JS.
|
|
38
38
|
|
|
39
39
|
### Scale
|
|
@@ -49,19 +49,22 @@ One codebase, every environment.
|
|
|
49
49
|
| Environment | How | Install |
|
|
50
50
|
|---|---|---|
|
|
51
51
|
| **Jupyter** | anywidget inline viewer | `pip install megane` |
|
|
52
|
+
| **JupyterLab** | Open .pdb, .gro, .xyz, .mol, .sdf, .mol2, .cif, .mmcif, .data/.lammps, .prmtop, .traj, .xtc, .dcd, .nc, .lammpstrj/.dump, .megane.json from the file browser | `pip install megane` |
|
|
52
53
|
| **Browser** | `megane serve` local server | `pip install megane` |
|
|
53
54
|
| **React** | `<MeganeViewer />` component | `npm install megane-viewer` |
|
|
54
|
-
| **VSCode** | Custom editor for .pdb, .gro, .xyz, .mol, .sdf, .cif | Extension |
|
|
55
|
+
| **VSCode** | Custom editor for .pdb, .gro, .xyz, .mol, .sdf, .mol2, .cif, .mmcif, .data/.lammps, .prmtop, .traj, .xtc, .lammpstrj, .dump, .dcd, .nc, .megane.json | Extension |
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
For a per-platform breakdown of supported formats and UI features (including known gaps), see [Platform Support](https://hodakamori.github.io/megane/platform-support).
|
|
58
|
+
|
|
59
|
+
The secret: parsers for 15 formats (PDB, GRO, XYZ, MOL/SDF, MOL2, CIF, mmCIF, LAMMPS data, AMBER topology, XTC, DCD, ASE .traj, LAMMPS dump, AMBER NetCDF) are written in **Rust** and compiled to both **PyO3** (Python) and **WASM** (browser). Parse once, run anywhere.
|
|
57
60
|
|
|
58
61
|
### Visual Pipelines
|
|
59
62
|
|
|
60
63
|
Wire nodes to build visualization workflows — no code required.
|
|
61
64
|
|
|
62
|
-
**
|
|
65
|
+
**16 node types** across 5 categories: load data (structure, trajectory, streaming, vector, volumetric), bonds, process (filter, modify, color, representation), overlay (labels, polyhedra, surface meshes, isosurfaces, vectors), and display in a 3D viewport.
|
|
63
66
|
|
|
64
|
-
**
|
|
67
|
+
**8 typed data channels** — particle, bond, cell, label, mesh, trajectory, vector, volumetric — flow through color-coded edges. Only matching types can connect.
|
|
65
68
|
|
|
66
69
|
Pipelines serialize to JSON, so you can save, share, and version-control your visualization recipes.
|
|
67
70
|
|
|
@@ -130,17 +133,21 @@ docker run --rm -p 8080:8080 -v ./mydata:/data megane \
|
|
|
130
133
|
### React
|
|
131
134
|
|
|
132
135
|
```tsx
|
|
133
|
-
import {
|
|
136
|
+
import { useCallback } from "react";
|
|
137
|
+
import { MeganeViewer, usePipelineStore } from "megane-viewer/lib";
|
|
134
138
|
|
|
135
139
|
function App() {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
const handleUpload = useCallback((file: File) => {
|
|
141
|
+
usePipelineStore.getState().openFile(file);
|
|
142
|
+
}, []);
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<MeganeViewer
|
|
146
|
+
onUploadStructure={handleUpload}
|
|
147
|
+
width="100%"
|
|
148
|
+
height="600px"
|
|
149
|
+
/>
|
|
150
|
+
);
|
|
144
151
|
}
|
|
145
152
|
```
|
|
146
153
|
|
|
@@ -154,16 +161,21 @@ function App() {
|
|
|
154
161
|
| GRO | `.gro` | GROMACS structure file |
|
|
155
162
|
| XYZ | `.xyz` | Cartesian coordinate format |
|
|
156
163
|
| MOL/SDF | `.mol`, `.sdf` | MDL Molfile (V2000) |
|
|
164
|
+
| MOL2 | `.mol2` | Tripos MOL2 (multi-molecule, aromatic bonds) |
|
|
157
165
|
| LAMMPS data | `.data`, `.lammps` | LAMMPS data file |
|
|
158
166
|
| CIF | `.cif` | Crystallographic Information File |
|
|
167
|
+
| mmCIF | `.mmcif` | Macromolecular CIF (PDBx/mmCIF) |
|
|
168
|
+
| AMBER topology | `.prmtop` | AMBER parameter/topology file (atom names, elements, bonds) |
|
|
169
|
+
| ASE .traj | `.traj` | ASE trajectory (ULM binary format) — self-contained with elements, bonds, and frames |
|
|
159
170
|
|
|
160
171
|
### Trajectory formats (`LoadTrajectory` node)
|
|
161
172
|
|
|
162
173
|
| Format | Extension | Description |
|
|
163
174
|
|--------|-----------|-------------|
|
|
164
175
|
| XTC | `.xtc` | GROMACS compressed trajectory |
|
|
165
|
-
|
|
|
166
|
-
|
|
|
176
|
+
| DCD | `.dcd` | CHARMM/NAMD binary trajectory |
|
|
177
|
+
| AMBER NetCDF | `.nc` | AMBER NetCDF trajectory |
|
|
178
|
+
| LAMMPS dump | `.lammpstrj`, `.dump` | LAMMPS dump trajectory |
|
|
167
179
|
|
|
168
180
|
## Development
|
|
169
181
|
|
|
@@ -226,7 +238,7 @@ make test-all # All tests
|
|
|
226
238
|
src/ TypeScript frontend
|
|
227
239
|
renderer/ Three.js rendering (impostor, mesh, shaders)
|
|
228
240
|
protocol/ Binary protocol decoder + web workers
|
|
229
|
-
parsers/ WASM-based file parsers (PDB, GRO, XYZ, MOL, CIF,
|
|
241
|
+
parsers/ WASM-based file parsers (15 formats: PDB, GRO, XYZ, MOL/SDF, MOL2, CIF, mmCIF, LAMMPS data/dump, AMBER topology/NetCDF, XTC, DCD, ASE .traj)
|
|
230
242
|
logic/ Bond / label / vector source logic
|
|
231
243
|
components/ React UI components
|
|
232
244
|
hooks/ Custom React hooks
|
|
@@ -236,7 +248,7 @@ crates/ Rust workspace
|
|
|
236
248
|
megane-python/ PyO3 Python extension
|
|
237
249
|
megane-wasm/ WASM bindings (wasm-bindgen)
|
|
238
250
|
python/megane/ Python backend
|
|
239
|
-
parsers/
|
|
251
|
+
parsers/ Python wrappers for 13 of the 15 supported formats (mmCIF and AMBER prmtop are accessible via the raw megane_parser PyO3 extension)
|
|
240
252
|
pipeline.py Pipeline builder (NetworkX-style DAG)
|
|
241
253
|
protocol.py Binary protocol encoder
|
|
242
254
|
server.py FastAPI WebSocket server
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";function d(r){const e=new DataView(r),s=e.getUint32(0,!0);if(s!==1313293645)throw new Error(`Invalid magic: 0x${s.toString(16)}, expected 0x4e47454d`);return{msgType:e.getUint8(4),flags:e.getUint8(5)}}function l(r){const e=new DataView(r),s=e.getUint8(5);let n=8;const t=e.getUint32(n,!0);n+=4;const o=e.getUint32(n,!0);n+=4;const m=new Float32Array(r,n,t*3);n+=t*3*4;const A=new Uint8Array(r,n,t);n+=t,n+=(4-n%4)%4;const g=new Uint32Array(r,n,o*2);n+=o*2*4;let a=null;s&1&&(a=new Uint8Array(r,n,o),n+=o,n+=(4-n%4)%4);let c=null;return s&2&&(c=new Float32Array(r,n,9),n+=36),{nAtoms:t,nBonds:o,nFileBonds:o,positions:m,elements:A,bonds:g,bondOrders:a,box:c,atomChainIds:null,atomBFactors:null}}function f(r){const e=new DataView(r);let s=8;const n=e.getUint32(s,!0);s+=4;const t=e.getUint32(s,!0);s+=4;const o=new Float32Array(r,s,t*3);return{frameId:n,nAtoms:t,positions:o}}const i=self;i.onmessage=r=>{const{id:e,buffer:s}=r.data;try{const{msgType:n}=d(s);if(n===0){const t=l(s),o=[t.positions.buffer,t.elements.buffer,t.bonds.buffer];t.bondOrders&&o.push(t.bondOrders.buffer),t.box&&o.push(t.box.buffer),i.postMessage({id:e,type:"snapshot",data:{nAtoms:t.nAtoms,nBonds:t.nBonds,nFileBonds:t.nFileBonds,positions:t.positions,elements:t.elements,bonds:t.bonds,bondOrders:t.bondOrders,box:t.box,atomChainIds:null,atomBFactors:null}},o)}else if(n===1){const t=f(s),o=[t.positions.buffer];i.postMessage({id:e,type:"frame",data:{frameId:t.frameId,nAtoms:t.nAtoms,positions:t.positions}},o)}}catch(n){i.postMessage({id:e,type:"error",error:n instanceof Error?n.message:String(n)})}}})();
|