megane-viewer 0.7.0 → 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 +28 -20
- package/dist/assets/decode.worker-BcZeHdFu.js +1 -0
- package/dist/{gif-Cy2524g7.js → gif-CsP6AQIk.js} +1 -1
- package/dist/lib-d68cwxNq.js +35419 -0
- package/dist/lib.js +33 -31
- package/dist/megane_wasm-8Sj7p71h.js +631 -0
- package/dist/widget.js +31383 -19752
- package/package.json +3 -3
- package/dist/assets/decode.worker-COS7O5zc.js +0 -1
- package/dist/lib-DHX1_72p.js +0 -21334
- package/dist/megane_wasm-BzxkVXwO.js +0 -471
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,22 +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, .cif from the file browser | `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` |
|
|
53
53
|
| **Browser** | `megane serve` local server | `pip install megane` |
|
|
54
54
|
| **React** | `<MeganeViewer />` component | `npm install megane-viewer` |
|
|
55
|
-
| **VSCode** | Custom editor for .pdb, .gro, .xyz, .mol, .sdf | 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 |
|
|
56
56
|
|
|
57
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
58
|
|
|
59
|
-
The secret: PDB, GRO, XYZ, MOL, CIF,
|
|
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.
|
|
60
60
|
|
|
61
61
|
### Visual Pipelines
|
|
62
62
|
|
|
63
63
|
Wire nodes to build visualization workflows — no code required.
|
|
64
64
|
|
|
65
|
-
**
|
|
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.
|
|
66
66
|
|
|
67
|
-
**
|
|
67
|
+
**8 typed data channels** — particle, bond, cell, label, mesh, trajectory, vector, volumetric — flow through color-coded edges. Only matching types can connect.
|
|
68
68
|
|
|
69
69
|
Pipelines serialize to JSON, so you can save, share, and version-control your visualization recipes.
|
|
70
70
|
|
|
@@ -133,17 +133,21 @@ docker run --rm -p 8080:8080 -v ./mydata:/data megane \
|
|
|
133
133
|
### React
|
|
134
134
|
|
|
135
135
|
```tsx
|
|
136
|
-
import {
|
|
136
|
+
import { useCallback } from "react";
|
|
137
|
+
import { MeganeViewer, usePipelineStore } from "megane-viewer/lib";
|
|
137
138
|
|
|
138
139
|
function App() {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
+
);
|
|
147
151
|
}
|
|
148
152
|
```
|
|
149
153
|
|
|
@@ -160,14 +164,18 @@ function App() {
|
|
|
160
164
|
| MOL2 | `.mol2` | Tripos MOL2 (multi-molecule, aromatic bonds) |
|
|
161
165
|
| LAMMPS data | `.data`, `.lammps` | LAMMPS data file |
|
|
162
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 |
|
|
163
170
|
|
|
164
171
|
### Trajectory formats (`LoadTrajectory` node)
|
|
165
172
|
|
|
166
173
|
| Format | Extension | Description |
|
|
167
174
|
|--------|-----------|-------------|
|
|
168
175
|
| XTC | `.xtc` | GROMACS compressed trajectory |
|
|
169
|
-
|
|
|
170
|
-
|
|
|
176
|
+
| DCD | `.dcd` | CHARMM/NAMD binary trajectory |
|
|
177
|
+
| AMBER NetCDF | `.nc` | AMBER NetCDF trajectory |
|
|
178
|
+
| LAMMPS dump | `.lammpstrj`, `.dump` | LAMMPS dump trajectory |
|
|
171
179
|
|
|
172
180
|
## Development
|
|
173
181
|
|
|
@@ -230,7 +238,7 @@ make test-all # All tests
|
|
|
230
238
|
src/ TypeScript frontend
|
|
231
239
|
renderer/ Three.js rendering (impostor, mesh, shaders)
|
|
232
240
|
protocol/ Binary protocol decoder + web workers
|
|
233
|
-
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)
|
|
234
242
|
logic/ Bond / label / vector source logic
|
|
235
243
|
components/ React UI components
|
|
236
244
|
hooks/ Custom React hooks
|
|
@@ -240,7 +248,7 @@ crates/ Rust workspace
|
|
|
240
248
|
megane-python/ PyO3 Python extension
|
|
241
249
|
megane-wasm/ WASM bindings (wasm-bindgen)
|
|
242
250
|
python/megane/ Python backend
|
|
243
|
-
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)
|
|
244
252
|
pipeline.py Pipeline builder (NetworkX-style DAG)
|
|
245
253
|
protocol.py Binary protocol encoder
|
|
246
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)})}}})();
|