Metadata-Version: 2.4
Name: megane
Version: 0.18.0
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Rust
Classifier: Framework :: Jupyter
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Scientific/Engineering :: Chemistry
Requires-Dist: anywidget>=0.9.0
Requires-Dist: ipywidgets>=8.0.0
Requires-Dist: traitlets>=5.0
Requires-Dist: numpy>=1.24
Requires-Dist: fastapi>=0.100
Requires-Dist: uvicorn[standard]>=0.20
Requires-Dist: websockets>=12.0
Requires-Dist: python-multipart>=0.0.6
Requires-Dist: mdanalysis>=2.5
Requires-Dist: pytest>=7.0 ; extra == 'dev'
Requires-Dist: httpx>=0.24 ; extra == 'dev'
Requires-Dist: pytest-cov>=4.0 ; extra == 'dev'
Requires-Dist: nbconvert>=7.0 ; extra == 'dev'
Requires-Dist: ipykernel>=6.0 ; extra == 'dev'
Requires-Dist: jupyterlab>=4.0 ; extra == 'dev'
Requires-Dist: plotly>=5.0 ; extra == 'dev'
Requires-Dist: mcp>=2.2,<3 ; extra == 'dev'
Requires-Dist: pytest-jupyter[server]>=0.10 ; extra == 'dev'
Requires-Dist: mcp>=2.2,<3 ; extra == 'tools'
Requires-Dist: ase>=3.22 ; extra == 'traj'
Provides-Extra: dev
Provides-Extra: tools
Provides-Extra: traj
License-File: LICENSE
Summary: A fast, beautiful molecular viewer
Keywords: molecular,viewer,pdb,jupyter,widget,anywidget
Author: hodakamori
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/megane-labs/megane
Project-URL: Issues, https://github.com/megane-labs/megane/issues
Project-URL: Repository, https://github.com/megane-labs/megane

<h1 align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="docs/public/brand/megane-logo-white.png" />
    <img src="docs/public/brand/megane-logo.png" alt="Megane" width="320" />
  </picture>
</h1>

<p align="center">Spectacles for atomistic data.</p>
<p align="center"><em>1M+ atoms at 60fps. Visual pipelines. Jupyter widget, JupyterLab extension, standalone web app, React component, VS Code extension.</em></p>

<p align="center">
  <a href="https://github.com/megane-labs/megane/actions/workflows/ci.yml"><img src="https://github.com/megane-labs/megane/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
  <a href="https://pypi.org/project/megane/"><img src="https://img.shields.io/pypi/v/megane" alt="PyPI" /></a>
  <a href="https://www.npmjs.com/package/megane-viewer"><img src="https://img.shields.io/npm/v/megane-viewer" alt="npm" /></a>
  <a href="https://github.com/megane-labs/megane/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License" /></a>
  <a href="https://pypi.org/project/megane/"><img src="https://img.shields.io/pypi/pyversions/megane" alt="Python" /></a>
  <a href="https://megane-labs.github.io/megane/"><img src="https://img.shields.io/badge/docs-online-blue" alt="Docs" /></a>
  <a href="https://codecov.io/gh/megane-labs/megane"><img src="https://codecov.io/gh/megane-labs/megane/graph/badge.svg" alt="codecov" /></a>
</p>

<p align="center">
  <a href="https://megane-labs.github.io/megane/">Docs</a> &middot;
  <a href="https://megane-labs.github.io/megane/getting-started">Getting Started</a> &middot;
  <a href="https://pypi.org/project/megane/">PyPI</a> &middot;
  <a href="https://www.npmjs.com/package/megane-viewer">npm</a>
</p>

<p align="center">
  <img src="docs/public/screenshots/megane-promo.gif" alt="Megane demo" width="640" />
</p>

---

## Features

- **1M+ Atoms at 60fps** — GPU billboard impostor rendering (ray-cast spheres and cylinders) scales from small molecules to massive complexes in real time. Large XTC and LAMMPS dump trajectories are decoded frame by frame on demand.
- **Runs Everywhere** — Jupyter widget, JupyterLab extension, standalone web app (`megane serve`), React component (npm), and VS Code extension. Rust-based parsers for 26 formats (PDB, GRO, XYZ, MOL/SDF, MOL2, CIF, mmCIF, CML, LAMMPS data, AMBER topology, GROMACS topology, CHARMM/NAMD PSF, XTC, DCD, ASE .traj, LAMMPS dump, AMBER NetCDF, VASP, Molden, XCrySDen XSF, JCAMP-DX, Chem3D XML, Odyssey, CASTEP magres, GAMESS output, CASTEP phonon) shared between Python (PyO3) and browser (WASM) — parse once, run anywhere.
- **Visual Pipeline Editor** — Build visualization workflows by wiring nodes or let the AI generator build them from natural language. 24 node types with 10 typed data channels flowing through color-coded edges. Load multiple structures with layer-based rendering to compare systems side by side. Draw atoms, licorice, lines, cartoon, molecular surfaces, or an illustrative style, and restyle a layer from the Quick Style panel without editing the graph.
- **Megane Builder** — A structure editor next to the viewer (`/builder.html` in `megane serve`, the Megane panel in VS Code's activity bar and JupyterLab's left sidebar, and `megane.Builder()` in notebooks): add, delete, move and re-element atoms, draw bonds, sketch molecules in Ketcher (embedded in 3D by RDKit), and build bulk crystals, supercells and slabs. Save as XYZ / PDB / MOL / CIF / POSCAR — also available from Python as `megane.save_structure()`. Python structure generators (packmol liquid boxes, polymer chains, solvation) plug into its *Tools* menu as MCP tool servers, and its *Flow* mode wires molecules and those tools into a model as blocks, like the viewer's pipeline editor.
- **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.

### Scale

Megane renders over **1 million atoms at 60fps** in the browser. Atoms and bonds are GPU-accelerated billboard impostors at every atom count — screen-aligned quads ray-cast into spheres and cylinders in the fragment shader. No desktop app, no plugin — just a browser tab.

In the web app, JupyterLab, and VS Code, files are parsed in a Web Worker, and XTC and LAMMPS dump trajectories and multi-frame XYZ / PDB files of 8 MB or more are decoded frame by frame on demand, so you can scrub through thousands of frames without reading everything into memory (DCD and AMBER NetCDF are decoded in full). The `megane serve` backend also exposes a binary WebSocket protocol (`/ws`) for trajectory streaming, consumed by the Streaming pipeline node; the bundled page parses in the browser instead.

### Anywhere

One codebase, every environment.

| Distribution | How | Install |
|---|---|---|
| **Jupyter widget** | anywidget inline viewer | `pip install megane` |
| **JupyterLab extension** | Open any supported structure, trajectory, volumetric, or spectrum file — plus `.megane.json` pipelines — straight from the file browser | `pip install megane` |
| **Standalone web app** | `megane serve` in the browser | `pip install megane` |
| **React component (npm)** | `<MeganeViewer />` component | `npm install megane-viewer` |
| **VS Code extension** | Custom editor for the same file types, registered by extension and by VASP basename (`POSCAR`/`CONTCAR`/`XDATCAR`) | VS Code Marketplace (`hodakamori.vscode-megane`) |

For a per-platform breakdown of supported formats and UI features (including known gaps), see [Platform Support](https://megane-labs.github.io/megane/platform-support).

The secret: parsers for 26 formats (PDB, GRO, XYZ, MOL/SDF, MOL2, CIF, mmCIF, CML, LAMMPS data, AMBER topology, GROMACS topology, CHARMM/NAMD PSF, XTC, DCD, ASE .traj, LAMMPS dump, AMBER NetCDF, VASP, Molden, XCrySDen XSF, JCAMP-DX, Chem3D XML, Odyssey, CASTEP magres, GAMESS output, CASTEP phonon) are written in **Rust** and compiled to both **PyO3** (Python) and **WASM** (browser). Parse once, run anywhere. The volumetric readers (Gaussian CUBE, OpenDX) are TypeScript-side.

### Visual Pipelines

Wire nodes to build visualization workflows — no code required.

**24 node types** across 6 categories: load data (structure, trajectory, streaming, vector, volumetric, spectrum), bonds (distance / file bonds, coordination), filter, modify (modify, color, representation, symmetry expansion, wrap / unwrap, replicate, drawing boundary, boundary completion), overlay (labels, polyhedra, surface meshes, isosurfaces, vectors), and display in a 3D viewport or a 2D spectrum plot.

**10 typed data channels** — particle, bond, coordination, cell, label, mesh, trajectory, vector, volumetric, spectrum — flow through color-coded edges. Only matching types can connect.

The `Representation` node switches a layer between atoms, licorice, line, cartoon, molecular surface, and illustrative rendering; `Color` colors by element, residue, chain, B-factor, or any per-atom property. For quick tweaks without touching the graph, the **Quick Style** panel in the Inspector tab edits style, color, atom size and opacity, bond width and opacity, labels, perspective, and cell axes, and writes them back into the pipeline.

Pipelines serialize to JSON, so you can save, share, and version-control your visualization recipes.

### Integrate

Megane is not a walled garden. It fits into your existing workflow.

**Plotly** — Click a point on a Plotly `FigureWidget` to jump to a trajectory frame. Use Megane's `on_event("frame_change")` callback to update Plotly markers in sync.

**MDX / Next.js** — Drop `<MeganeViewer />` or `<Viewport />` into your `.mdx` documentation. WASM parsing works out of the box with a one-line webpack config.

**ipywidgets** — React to `frame_change`, `selection_change`, and `measurement` events. Compose Megane with any widget in the Jupyter ecosystem.

**Framework-agnostic** — `MoleculeRenderer` is a plain Three.js class. Mount it in Vue, Svelte, or a vanilla `<div>`.

## Installation

### Python

```bash
pip install megane
```

### npm (for React embedding)

```bash
npm install megane-viewer
```

Works with React 18 and React 19 (peer dependencies: `react` and `react-dom` `^18.2.0 || ^19.0.0`).

## Quick Start

### Jupyter widget

```python
import megane

viewer = megane.view("protein.pdb")
viewer  # displays in notebook
```

With a trajectory:

```python
viewer = megane.view_traj("protein.pdb", xtc="trajectory.xtc")
viewer.frame_index = 50  # jump to frame 50
```

The widget does not show the pipeline editor, but `MolecularViewer(quick_style=True)` (or `viewer.quick_style = True`) adds the Quick Style panel for restyling inside the cell. For advanced usage (filtering, multi-layer rendering, custom pipelines), see the [Python Pipeline API](https://megane-labs.github.io/megane/guide/pipeline/python).

### Standalone web app (`megane serve`)

```bash
docker build -t megane .
docker run --rm -p 8080:8080 megane
```

Open http://localhost:8080 in your browser. Megane Builder, the structure editor, is at http://localhost:8080/builder.html.

To view your own files, mount them into the container and let the Load nodes browse them:

```bash
docker run --rm -p 127.0.0.1:8080:8080 -v ./mydata:/data megane \
  megane serve --files-root /data --files-any-host --port 8080 --no-browser
```

Then open a file from the Load Structure node's *Open from server…*. The page does not load a file named on the `megane serve` command line, so browse to it instead. Docker's port mapping makes your browser a non-local client of the container, which is why `--files-any-host` is needed; publishing the port on `127.0.0.1` keeps it reachable from your machine only.

Without Docker, `megane serve` also lets the Load nodes browse files on the machine it runs on (*Open from server…*), which is handy over an SSH tunnel to a workstation or cluster node. `--files-root DIR` sets the folder it browses, `--no-files` turns it off, and `--files-any-host` serves it to other machines on the network (by default only clients on the server's own machine). See the [CLI guide](https://megane-labs.github.io/megane/guide/cli).

### Megane Builder tools

The Builder's *Tools* menu runs Python structure generators — *Liquid box*, *Polymer chain*, *Solvate* — from an [MCP](https://modelcontextprotocol.io/) tool server. In VS Code (1.90+) and JupyterLab, **Tools › Connect to megane-builder-tools** starts the reference server for you with [uv](https://docs.astral.sh/uv/); JupyterLab reaches it through Megane's Jupyter server extension, which needs the `tools` extra:

```bash
pip install "megane[tools]"
```

In the browser (`megane serve --port 8080`, or the Docker image above), start the reference server yourself and connect to it from **Tools › Tool server…** (URL `http://127.0.0.1:8765/mcp`). `megane serve` defaults to port 8765, which the tool server below takes, so run it on another port:

```bash
uvx --from git+https://github.com/hodakamori/megane-builder-tools \
    megane-builder-tools --transport http --port 8765 \
    --allow-origin http://localhost:8080
```

See the [Builder guide](https://megane-labs.github.io/megane/guide/builder#python-tools) for setup on each host and for writing your own tool server.

### React component (npm)

```tsx
import { useCallback } from "react";
import "megane-viewer/styles.css";
import { MeganeViewer } from "megane-viewer/lib";

function App() {
  // Called after the viewer has loaded a file opened in its editor.
  const handleUpload = useCallback((file: File) => {
    console.log("opened", file.name);
  }, []);

  return (
    <MeganeViewer
      onUploadStructure={handleUpload}
      width="100%"
      height="600px"
    />
  );
}
```

## Supported File Formats

### Structure formats (`LoadStructure` node)

| Format | Extension | Description |
|--------|-----------|-------------|
| PDB | `.pdb` | Protein Data Bank |
| GRO | `.gro` | GROMACS structure file |
| XYZ | `.xyz`, `.jxyz`, `.extxyz` | Cartesian coordinate format, incl. multi-frame and `Lattice=` extended XYZ. `.jxyz` (Jmol) and `.extxyz` (ASE extended XYZ) are second extensions for the same format |
| MOL/SDF | `.mol`, `.sdf` | MDL Molfile / SDfile (V2000 and V3000) |
| MOL2 | `.mol2` | Tripos MOL2 (aromatic bonds, optional `CRYSIN` unit cell; only the first molecule of a multi-molecule file is read) |
| LAMMPS data | `.data`, `.lammps` | LAMMPS data file |
| CIF | `.cif` | Crystallographic Information File |
| mmCIF | `.mmcif` | Macromolecular CIF (PDBx/mmCIF) |
| AMBER topology | `.prmtop` | AMBER parameter/topology file (atom names, elements, bonds) |
| ASE .traj | `.traj` | ASE trajectory (ULM binary format) — self-contained with elements, bonds, and frames |
| LAMMPS dump | `.lammpstrj`, `.dump`, `.trj` | Opens standalone as a multi-frame structure (the integer atom `type` stands in for the element); can also be attached to a topology, see Trajectory formats |
| XCrySDen | `.xsf`, `.axsf` | XCrySDen structure; `.axsf` is a multi-frame animation with optional per-frame cell and per-atom forces |
| CML | `.cml` | Chemical Markup Language (Open Babel / Avogadro / ChemDraw), with explicit bonds and optional crystal cell |
| VASP | `POSCAR`, `CONTCAR`, `XDATCAR`, `.vasp` | VASP crystal structure; XDATCAR is multi-frame. Matched by filename as well as extension, since the standard names carry no extension |
| Molden | `.molden` | Molden quantum-chemistry output — `[Atoms]` geometry (AU or Angstrom) and `[GEOMETRIES] XYZ` optimisation frames |
| Chem3D XML | `.c3xml` | PerkinElmer Chem3D / ChemDraw XML (CDXML family) — nodes with explicit bonds and orders |
| Odyssey | `.xodydata`, `.odydata` | Wavefunction Odyssey — the XML layout and the older Spartan-style text layout, told apart by content rather than extension |
| CASTEP magres | `.magres` | CASTEP / Quantum ESPRESSO NMR output — the `[atoms]` block (lattice + labelled atoms) with per-block units |
| GAMESS output | `.gamess` | GAMESS (US / Firefly) log output — every `COORDINATES OF ALL ATOMS ARE` block becomes a frame |
| CASTEP phonon | `.phonon` | CASTEP lattice-dynamics output — the header (cell + fractional coordinates + species) renders as a periodic structure |

### Topology formats (`AddBond` node)

| Format | Extension | Description |
|--------|-----------|-------------|
| GROMACS topology | `.top` | Bonds for a structure that does not carry them (e.g. a GRO file). Picked up automatically when a `.gro` is opened next to a `.top` of the same name |
| CHARMM/NAMD PSF | `.psf` | Bonds for a PDB or other coordinate file |

These files supply bonds only, so they are loaded on the Add Bond node (bond source *file*), or from Python with `AddBonds(top="topol.top")`.

### Volumetric formats (`LoadVolumetric` node)

| Format | Extension | Description |
|--------|-----------|-------------|
| Gaussian CUBE | `.cube`, `.cub` | Gaussian cube grid (Bohr, converted to Angstrom on read) |
| OpenDX | `.dx` | OpenDX scalar field — the APBS electrostatics output, also read by VMD and PyMOL |

A grid has no atoms of its own, so it is rendered as an isosurface over a
separately-loaded structure. `.dx` is shared with JCAMP-DX spectra, so the
loader sniffs the content and says so if the file is really a spectrum.

### Spectrum formats (`LoadSpectrum` node)

A spectrum is a 2D (x, y) trace with no atoms or coordinates, so it is drawn by
the terminal `SpectrumPlot` node instead of reaching the 3D renderer.

| Format | Extension | Description |
|--------|-----------|-------------|
| JCAMP-DX | `.jdx`, `.jcamp`, `.dx` | IR / NMR / MS / UV-Vis spectra; AFFN plus the compressed ASDF forms (SQZ, DIF, DUP). `.dx` is shared with OpenDX volumetric grids and resolved by sniffing the file head |

### Trajectory formats (`LoadTrajectory` node)

| Format | Extension | Description |
|--------|-----------|-------------|
| XTC | `.xtc` | GROMACS compressed trajectory |
| DCD | `.dcd` | CHARMM/NAMD binary trajectory |
| AMBER NetCDF | `.nc` | AMBER NetCDF trajectory |
| LAMMPS dump | `.lammpstrj`, `.dump`, `.trj` | LAMMPS dump trajectory |

## Development

### Prerequisites

- Python 3.10+
- Node.js 22+
- Rust (for building the parser)
- [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/) (for building WASM bindings)
- [uv](https://docs.astral.sh/uv/)
- [maturin](https://www.maturin.rs/) (`uv tool install maturin` or `pip install maturin`; `uv sync` does not install it)

### Setup

```bash
git clone https://github.com/megane-labs/megane.git
cd megane

# Install wasm-pack (if not already installed)
cargo install wasm-pack

# Python
uv sync --extra dev

# Node.js
npm install
npm run build
```

### Running `megane serve`

After setup, build and install the package, then start the server:

```bash
maturin develop --release
uv run megane serve protein.pdb
```

### Development Mode

```bash
# Terminal 1: Vite dev server
npm run dev

# Terminal 2: Python backend
uv run megane serve protein.pdb --dev --no-browser
```

### Tests

```bash
uv run pytest              # Python tests
npm test                   # TypeScript unit tests
cargo test -p megane-core  # Rust tests
make test-all              # All tests
```

## Project Structure

```
src/                     TypeScript frontend
  renderer/              Three.js rendering (impostor, mesh, shaders)
  protocol/              Binary protocol decoder + web workers
  parsers/               WASM-based file parsers for every supported format (see Supported File Formats)
  logic/                 Bond / label / vector source logic
  components/            React UI components
  hooks/                 Custom React hooks
  stores/                Zustand stores (per-viewer playback, view, measurement, theme state)
  pipeline/              Pipeline graph, node executors, serialization
  builder/               Megane Builder (structure editor)
  crystal/               Unit-cell math and bulk crystal prototypes
  export/                Export the on-screen structure through the Rust writers
  hosts/                 File classification shared by the JupyterLab and VS Code hosts
  remote/                Opening files from the server / host ("Open from server...")
  ai/                    LLM pipeline generator
  stream/                WebSocket client
  tour/                  Guided onboarding tour
  types/, utils/         Shared types and helpers
crates/                  Rust workspace
  megane-core/           Core parsers and bond inference
  megane-python/         PyO3 Python extension
  megane-wasm/           WASM bindings (wasm-bindgen)
python/megane/           Python backend
  parsers/               Python readers for every supported format (`dispatch.py` maps every structure extension the web app opens), plus the PSF / GROMACS .top topology sidecars (Gaussian CUBE and OpenDX are browser-side only)
  pipeline.py            Pipeline builder (NetworkX-style DAG)
  builder.py             Megane Builder Jupyter widget
  builder_tools/         Jupyter server extension bridging the Builder to MCP tool servers (`megane[tools]`)
  writers.py             Structure writers (`save_structure`)
  cli.py                 `megane` CLI entry point
  protocol.py            Binary protocol encoder
  server.py              `megane serve` backend (FastAPI + WebSocket)
  widget.py              anywidget Jupyter widget
tests/                   Tests (Python, TypeScript, E2E)
```

## Contributing

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for the
development setup, test commands, and project design rules. Fork PRs run the
full CI and E2E pixel checks automatically — no tokens or setup needed on
your side. This project follows the
[Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md); security issues
should be reported privately per [SECURITY.md](SECURITY.md).

## License

[MIT](LICENSE)

