Python API Reference
megane - A fast, beautiful molecular viewer.
Installation
pip install megane
import megane
MolecularViewer
Inherits from: anywidget.AnyWidget
Interactive molecular viewer widget for Jupyter notebooks.
Usage:
import megane viewer = megane.MolecularViewer() viewer.load("protein.pdb") viewer # displays in notebook cell
With trajectory:
viewer.load("protein.pdb", xtc="trajectory.xtc") viewer.frame_index = 50 # jump to frame 50
External event triggers:
Set atom selection programmatically
viewer.selected_atoms = [10, 20, 30, 40] print(viewer.measurement) # dihedral angle result
React to events
@viewer.on_event("measurement") ... def on_measurement(data): ... print(f"Measured: {data}")
Plotly integration example
fig = go.FigureWidget(data=[go.Scatter(x=times, y=energies)]) def on_click(trace, points, state): ... viewer.frame_index = points.point_inds[0] fig.data[0].on_click(on_click)
__init__
def __init__(*args, **kwargs)
Create a molecular viewer widget.
Data is supplied via :meth:load (deprecated) or :meth:set_pipeline.
The visual pipeline editor is not available in the widget; use the
standalone web app, JupyterLab extension, or VSCode extension to
edit pipelines visually.
load
def load(pdb_path: str, xtc: str | None = None, traj: str | None = None) -> None
Load a molecular structure, optionally with a trajectory.
The structure path is dispatched by extension to the appropriate Rust-backed parser (PDB, GRO, XYZ, MOL, SDF, MOL2, CIF, LAMMPS data, .traj). For multi-frame XYZ files the trajectory is inferred automatically.
.. deprecated::
Use :meth:set_pipeline with a :class:~megane.pipeline.Pipeline
instead. The legacy single-snapshot path remains for backward
compatibility but does not expose the full pipeline graph API.
Args:
pdb_path: Path to a structure file. The argument retains its
historic name but accepts any format supported by
:func:megane.pipeline._load_structure_file.
xtc: Optional path to an XTC trajectory file. Only valid when
pdb_path is a PDB file (XTC requires PDB topology).
traj: Optional path to an ASE .traj file. When provided,
pdb_path is ignored and both structure and trajectory
are read from the .traj file.
measurement
def measurement() -> dict | None
Current measurement result, or None if fewer than 2 atoms selected.
Returns a dict with keys: type, value, label, atoms. Example: {'type': 'dihedral', 'value': 120.5, 'label': '120.5°', 'atoms': [10, 20, 30, 40]}
on_event
def on_event(event_name: str, callback: Callable | None = None)
Register a callback for an event.
Can be used as a decorator or a method call:
@viewer.on_event("measurement") def on_measurement(data): print(data)
or equivalently:
viewer.on_event("measurement", on_measurement)
Supported events:
- "frame_change": fired when frame_index changes. Data: {"frame_index": int}
- "selection_change": fired when selected_atoms changes. Data: {"atoms": list[int]}
- "measurement": fired when a measurement is computed. Data: {"type": str, "value": float, "label": str, "atoms": list[int]} or None
Args: event_name: Name of the event. callback: Callable to invoke. If None, returns a decorator.
Returns: The callback (for decorator usage).
off_event
def off_event(event_name: str, callback: Callable | None = None)
Remove event callback(s).
Args: event_name: Name of the event. callback: Specific callback to remove. If None, removes all callbacks for the event.
set_pipeline
def set_pipeline(pipeline: Pipeline | None) -> None
Apply a pipeline to this viewer.
Args:
pipeline: A :class:~megane.pipeline.Pipeline instance,
or None to clear the pipeline.
NodePort
A single typed I/O port on a pipeline node.
Returned by node.out.<name> and node.inp.<name>.
Pass to Pipeline.add_edge() to connect nodes explicitly.
__init__
def __init__(node: PipelineNode, handle: str) -> None
PortNamespace
Attribute-access namespace that returns :class:NodePort instances.
Example: node.out.particle → NodePort(node, 'particle').
__init__
def __init__(node: PipelineNode, port_map: dict[str, str]) -> None
PipelineNode
Base class for all pipeline node types.
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__() -> None
LoadStructure
Inherits from: PipelineNode
Load a molecular structure from a file.
Supported formats: PDB, GRO, XYZ, MOL, SDF, MOL2, CIF, LAMMPS data
(.data / .lammps), ASE .traj, and LAMMPS dump (.lammpstrj / .dump / .trj)
opened standalone as a multi-frame structure (frame-0 topology, integer
atom type ids used as element proxies).
Ports: out.particle — atom data out.traj — trajectory channel out.cell — simulation cell
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__(path: str) -> None
LoadTrajectory
Inherits from: PipelineNode
Load an external trajectory file.
Supported formats: XTC, DCD, AMBER NetCDF (.nc), ASE .traj, LAMMPS dump (.lammpstrj / .dump), and multi-frame XYZ.
Requires connection from a LoadStructure node via
pipe.add_edge(s.out.particle, t.inp.particle).
Frames are loaded lazily when frame_index changes.
Args: xtc: Path to XTC trajectory file. dcd: Path to DCD trajectory file (CHARMM/NAMD/X-PLOR). nc: Path to AMBER NetCDF trajectory file. traj: Path to ASE .traj file. xyz: Path to multi-frame XYZ file. lammpstrj: Path to LAMMPS dump trajectory (.lammpstrj / .dump / .trj).
Ports: inp.particle — atom topology source out.traj — trajectory frames
__init__
def __init__() -> None
Streaming
Inherits from: PipelineNode
Streaming source node for WebSocket-based data delivery.
Connects to the server via WebSocket and provides particle, trajectory, and cell data from the streaming connection.
Ports: out.particle — atom data out.bond — bond data out.traj — trajectory channel out.cell — simulation cell
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__() -> None
LoadVector
Inherits from: PipelineNode
Load per-atom vector data from a file.
Ports: out.vector — vector field
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__(path: str) -> None
Filter
Inherits from: PipelineNode
Filter atoms by a selection query.
Query syntax examples::
element == 'C' element == 'O' and x > 5.0 resname == 'ALA' index >= 100 and index < 200
Ports: inp.particle — atom data in out.particle — filtered atom data
__init__
def __init__() -> None
Modify
Inherits from: PipelineNode
Modify per-atom visual properties (scale, opacity).
Color and representation now live on dedicated :class:Color and
:class:Representation nodes so each modifier owns a single visual
property (Ovito-style modifier stack).
Ports: inp.particle — atom data in out.particle — modified atom data
__init__
def __init__() -> None
Symmetry
Inherits from: PipelineNode
Expand a crystallographic asymmetric unit into the full unit cell.
Applies the space-group symmetry operations the parser captured on the
structure (a CIF _symmetry_equiv_pos_as_xyz loop) to fill one unit
cell with the symmetry-equivalent images, replicating bonds per image and
dropping images that coincide (special positions). "expand" (the
default) performs the expansion; "none" passes the raw asymmetric unit
through. Structures without symmetry operations or without a unit cell
pass through unchanged in either mode.
Args:
mode: One of "expand", "none".
Ports: inp.particle — atom data in inp.traj — trajectory in out.particle — expanded atom data out.traj — trajectory (passed through)
__init__
def __init__() -> None
Wrap
Inherits from: PipelineNode
Toggle periodic-image coordinate mapping for the particle stream.
"wrap" folds every atom back into the home unit cell (fractional
[0,1)); "unwrap" shifts atoms by whole lattice vectors so bonded
molecules that straddle a periodic face become spatially contiguous
(VESTA/Mercury-style whole molecules). "none" (the default) passes
coordinates through untouched. Requires the upstream structure to carry a
unit cell; without one the input is passed through unchanged. A connected
trajectory is remapped per frame with the same convention.
Args:
mode: One of "none", "wrap", "unwrap".
Ports: inp.particle — atom data in inp.traj — trajectory in out.particle — remapped atom data out.traj — remapped trajectory
__init__
def __init__() -> None
Replicate
Inherits from: PipelineNode
Replicate the structure into an nx × ny × nz supercell.
OVITO/VESTA-style supercell builder: copies every atom (and its bonds)
into a grid of cell images placed in the +a/+b/+c directions (the
original cell included) and enlarges the simulation cell to
nx·a, ny·b, nz·c. Requires the upstream structure to carry a unit
cell; without one the input is passed through unchanged.
Args: nx: Number of cell images along the a (x) lattice vector (>= 1). ny: Number of cell images along the b (y) lattice vector (>= 1). nz: Number of cell images along the c (z) lattice vector (>= 1).
Ports: inp.particle — atom data in inp.cell — simulation cell in out.particle — replicated atom data out.cell — enlarged simulation cell
__init__
def __init__() -> None
DrawingBoundary
Inherits from: PipelineNode
Generate periodic display copies inside fractional drawing bounds.
Unlike :class:Replicate, this does not change structural atom indices or
enlarge the cell. Bounds are inclusive, so a site on 0 is repeated on 1.
Ports: inp.particle — atom data in out.particle — atom data carrying periodic display copies
__init__
def __init__() -> None
BoundaryCompletion
Inherits from: PipelineNode
Add bond-connected periodic copies to a Drawing Boundary.
neighbors completes one bond shell. components completes finite
connected components while leaving infinite periodic networks unchanged.
Ports: inp.particle — atom data carrying a Drawing Boundary inp.bond — periodic bond topology out.particle — atom data carrying completed display copies out.bond — bonds repeated over the completed copies
__init__
def __init__() -> None
Color
Inherits from: PipelineNode
Recolor the upstream particle stream by a chosen scheme.
Args:
mode: One of "uniform", "byElement", "byResidue",
"byChain", "byBFactor", "byProperty",
"illustrative". "illustrative" is Goodsell-style: every
atom takes a soft pastel color for its chain, with carbon a
lighter shade of that same color (no CPK coloring).
uniform_color: Hex color used when mode == "uniform"
(e.g. "#ff8800").
range: Optional (min, max) for byBFactor / byProperty.
Ports: inp.particle — atom data in out.particle — recolored atom data
__init__
def __init__() -> None
Representation
Inherits from: PipelineNode
Tag the particle stream with a visual representation.
Stacks Ovito-style: the Viewport reads the override from the first particle stream that carries one, so a downstream Representation node wins over an upstream one on the same chain.
Args:
mode: One of "atoms" (default), "licorice", "cartoon",
"both", "surface", "line", "illustrative".
"licorice" draws atoms and bonds at one equal radius as a
continuous stick/tube (PyMOL licorice). "line" draws thin
wireframe lines (VMD/PyMOL "lines"). "illustrative" draws
Mol*-style spacefill spheres at the full van der Waals radius,
shaded toward each sphere's rim with a dark silhouette outline
(bonds hidden); pair it with Color(mode="illustrative").
Ports: inp.particle — atom data in out.particle — atom data tagged with the representation override
__init__
def __init__() -> None
AddBonds
Inherits from: PipelineNode
Compute and display bonds.
Args:
source: "distance" for VDW-based inference,
"structure" (alias "file") to use bonds from the
loaded structure file.
top: Path to a topology file (GROMACS .top or CHARMM/NAMD .psf).
When provided, source is ignored and bonds are read from the
topology.
Ports: inp.particle — atom data out.bond — computed bonds
__init__
def __init__() -> None
AddLabels
Inherits from: PipelineNode
Generate text labels at atom positions.
Args:
source: "element", "resname", or "index".
Ports: inp.particle — atom data out.label — label data
__init__
def __init__() -> None
AddCoordination
Inherits from: PipelineNode
Generate directed center-neighbor coordination relationships.
With boundary_mode="complete", center atoms remain inside Drawing
Boundary while bonded periodic images of their neighbors may be appended
outside it to complete the visible coordination environment.
Ports:
inp.particle — atom data, normally from :class:DrawingBoundary
out.coordination — directed center-neighbor relationships
out.bond — the same relationships as renderable bonds
__init__
def __init__() -> None
AddPolyhedra
Inherits from: PipelineNode
Convert directed coordination relationships to polyhedron meshes.
Ports: inp.coordination — directed center-neighbor coordination data out.mesh — polyhedra mesh
__init__
def __init__() -> None
VectorOverlay
Inherits from: PipelineNode
Configure per-atom vector visualization (e.g. forces).
Ports: inp.vector — vector field in out.vector — configured vector field
__init__
def __init__() -> None
LoadVolumetric
Inherits from: PipelineNode
Load a Gaussian CUBE file and output volumetric data.
The file is parsed in the browser; this node only tracks the filename.
Volumetric data flows to :class:Isosurface nodes.
Ports: out.volumetric — volumetric data
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__(path: str = '') -> None
Isosurface
Inherits from: PipelineNode
Extract an isosurface from volumetric data using marching cubes.
With color_mode="volume" the surface is painted by sampling a second
volume connected to inp.color_volumetric (e.g. an ESP cube mapped onto
a charge-density isosurface) through colormap.
Ports:
inp.volumetric — volumetric data (from :class:LoadVolumetric)
inp.color_volumetric — optional volume sampled for coloring
out.mesh — isosurface mesh
__init__
def __init__() -> None
LoadSpectrum
Inherits from: PipelineNode
Load a JCAMP-DX spectrum (.jdx / .jcamp) and output spectrum data.
The file is decoded in the browser; this node only tracks the filename.
A spectrum has no 3D coordinates, so it flows to :class:SpectrumPlot
rather than to :class:Viewport.
Ports: out.spectrum — spectrum data
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__(path: str = '') -> None
SpectrumPlot
Inherits from: PipelineNode
Draw a spectrum as a 2D line chart.
Terminal node — a spectrum has no geometry, so nothing flows onward to the 3D renderer.
Ports:
inp.spectrum — spectrum data (from :class:LoadSpectrum)
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__() -> None
Viewport
Inherits from: PipelineNode
3D rendering output node.
All data to be rendered must be explicitly connected to this node.
Ports: inp.particle — atom data inp.bond — bond data inp.cell — simulation cell inp.traj — trajectory frames inp.label — text labels inp.mesh — polyhedra mesh inp.vector — vector field
Attributes:
| Attribute | Type | Description |
|---|
__init__
def __init__() -> None
Pipeline
NetworkX-style pipeline graph builder.
Build a DAG of processing nodes and serialize to the
SerializedPipeline v3 JSON format understood by the
TypeScript pipeline engine.
Example::
from megane import Pipeline, LoadStructure, Viewport
pipe = Pipeline() s = pipe.add_node(LoadStructure("protein.pdb")) v = pipe.add_node(Viewport()) pipe.add_edge(s.out.particle, v.inp.particle)
__init__
def __init__() -> None
add_node
def add_node(node: PipelineNode) -> PipelineNode
Add a node to the pipeline.
Returns the same node instance so its ports can be used in
add_edge() calls::
s = pipe.add_node(LoadStructure("protein.pdb")) pipe.add_edge(s.out.particle, ...)
add_edge
def add_edge(source: NodePort, target: NodePort) -> None
Connect source port to target port.
Both ports must belong to nodes already added to this pipeline::
pipe.add_edge(s.out.particle, f.inp.particle) pipe.add_edge(s.out.traj, v.inp.traj)
to_dict
def to_dict() -> dict
Serialize to SerializedPipeline v3 format.
to_json
def to_json() -> str
Serialize to a JSON string (SerializedPipeline v3).
Args:
indent: JSON indentation level (default 2). Pass None for compact output.
Returns: JSON string representation of the pipeline.
save
def save(path) -> None
Save the pipeline to a JSON file.
Args:
path: Destination file path (str or :class:pathlib.Path).
Creates or overwrites the file.
from_dict
def from_dict(cls, d: dict) -> 'Pipeline'
Reconstruct a Pipeline from a SerializedPipeline v3 dict.
LoadStructure file paths in the JSON must still be accessible.
Relative paths are resolved from the current working directory at call
time.
Args:
d: A dict in SerializedPipeline v3 format (e.g. from
:meth:to_dict).
Returns:
A new :class:Pipeline instance ready to pass to
MolecularViewer.set_pipeline().
Raises: ValueError: If the dict is not version 3 or contains an unknown node type.
from_json
def from_json(cls, s: str) -> 'Pipeline'
Reconstruct a Pipeline from a JSON string.
Args:
s: JSON string in SerializedPipeline v3 format.
Returns:
A new :class:Pipeline instance.
load
def load(cls, path) -> 'Pipeline'
Load a Pipeline from a JSON file saved with :meth:save.
Args:
path: Path to a JSON file in SerializedPipeline v3 format
(str or :class:pathlib.Path).
Returns:
A new :class:Pipeline instance.
Structure
Parsed molecular structure.
Fields:
| Field | Type | Description |
|---|---|---|
n_atoms | int | |
positions | np.ndarray | (N, 3) float32 |
elements | np.ndarray | (N,) uint8 - atomic numbers |
bonds | np.ndarray | (M, 2) uint32 - bond pairs |
bond_orders | np.ndarray | (M,) uint8 - 1=single, 2=double, 3=triple, 4=aromatic |
box | np.ndarray | (3, 3) float32 - cell vectors as rows, zero if no cell |
box_origin | np.ndarray | |
symmetry_ops | list[str] |
Functions
view
def view(path: str) -> 'MolecularViewer'
Open a molecular viewer for a structure file.
Builds a minimal pipeline with :class:LoadStructure and
:class:Viewport nodes and, when bonds is not None
(the default), an additional :class:AddBonds node, then
returns a :class:~megane.widget.MolecularViewer widget.
Args:
path: Path to a structure file (PDB, GRO, XYZ, MOL, SDF, MOL2, CIF,
LAMMPS data, ASE .traj).
bonds: Bond detection method. "auto" (default) picks per format —
"structure" for formats that embed bonds (PDB, MOL/SDF, LAMMPS
data, CML, ...), "distance" otherwise — matching the webapp's
load path. "distance" forces VDW-radius inference,
"structure" (alias "file") reads bonds from the loaded
structure file, None disables bonds.
perspective: Use perspective projection instead of orthographic.
cell_axes_visible: Show unit cell axes.
Returns:
A :class:~megane.widget.MolecularViewer widget ready for display.
Example::
import megane viewer = megane.view("protein.pdb") viewer # displays in notebook
view_traj
def view_traj(path: str) -> 'MolecularViewer'
Open a molecular viewer with a trajectory.
Builds a pipeline (LoadStructure → LoadTrajectory → Viewport, with an
optional AddBonds node when bonds is not None) and returns a
:class:~megane.widget.MolecularViewer widget.
When path points to a self-contained trajectory file (.traj or
multi-frame .xyz) and no explicit trajectory kwarg is provided,
the trajectory is auto-loaded from that same file.
Args:
path: Path to a structure or self-contained trajectory file (PDB,
GRO, XYZ, MOL, SDF, MOL2, CIF, LAMMPS data, ASE .traj).
xtc: Path to an XTC trajectory file.
traj: Path to an ASE .traj file.
xyz: Path to a multi-frame XYZ trajectory file.
bonds: Bond detection method. "auto" (default) picks per format —
"structure" for formats that embed bonds (PDB, MOL/SDF, LAMMPS
data, CML, ...), "distance" otherwise — matching the webapp's
load path. "distance" forces VDW-radius inference and is
recomputed per frame during trajectory playback, "structure"
(alias "file") reads bonds once from the loaded structure
file, None disables bonds.
perspective: Use perspective projection instead of orthographic.
cell_axes_visible: Show unit cell axes.
Returns:
A :class:~megane.widget.MolecularViewer widget ready for display.
Raises: ValueError: If more than one of xtc, traj, xyz is provided, or if none is provided and path isn't a self-contained trajectory file.
Example::
import megane viewer = megane.view_traj("protein.pdb", xtc="trajectory.xtc") viewer = megane.view_traj("trajectory.traj") # auto-detects .traj viewer = megane.view_traj("multiframe.xyz") # auto-detects .xyz viewer.frame_index = 50
build_pipeline
def build_pipeline(path: str) -> Pipeline
Build a pipeline for a molecular structure, optionally with a trajectory.
Constructs a :class:Pipeline with :class:LoadStructure and
:class:Viewport nodes. When xtc, traj, or xyz is provided, a
:class:LoadTrajectory node is added. When bonds is not None
(the default), an :class:AddBonds node is included.
Unlike :func:view and :func:view_traj, this function returns the
:class:Pipeline directly without creating a widget, making it
suitable for serialization (via :meth:Pipeline.to_json) or further
programmatic modification.
Args:
path: Path to a structure file (PDB, GRO, XYZ, MOL, LAMMPS data,
ASE .traj).
xtc: Path to an XTC trajectory file.
traj: Path to an ASE .traj file.
xyz: Path to a multi-frame XYZ trajectory file.
bonds: Bond detection method. "auto" (default) picks per format —
"structure" for formats that embed bonds (PDB, MOL/SDF, LAMMPS
data, CML, ...), "distance" otherwise — matching the webapp's
load path. "distance" forces VDW-radius inference,
"structure" (alias "file") reads bonds from the loaded
structure file, None disables bonds. Ignored when top is
provided.
top: Path to a topology file (GROMACS .top or CHARMM/NAMD .psf)
for bond definitions. When provided, overrides bonds.
perspective: Use perspective projection instead of orthographic.
cell_axes_visible: Show unit cell axes.
pivot_marker_visible: Show pivot marker in viewport.
Returns:
A :class:Pipeline instance ready for serialization or
passing to :meth:~megane.widget.MolecularViewer.set_pipeline.
Raises: ValueError: If more than one of xtc, traj, xyz is provided.
Example::
import megane
Structure only -> JSON
pipe = megane.build_pipeline("protein.pdb") print(pipe.to_json())
With trajectory -> save to file
pipe = megane.build_pipeline("protein.pdb", xtc="trajectory.xtc") pipe.save("pipeline.json")
With GROMACS topology
pipe = megane.build_pipeline("protein.pdb", top="topology.top") print(pipe.to_json())
cell_params_to_matrix
def cell_params_to_matrix(a: float, b: float, c: float, alpha: float, beta: float, gamma: float) -> np.ndarray
Convert crystallographic cell parameters to a 3x3 matrix of cell vectors.
Args: a, b, c: Cell edge lengths in Angstroms. alpha, beta, gamma: Cell angles in degrees.
Returns: (3, 3) float32 array with cell vectors as rows.
load_pdb
def load_pdb(path: str) -> Structure
Load a PDB file using the shared Rust parser (megane-core).
Replaces the previous RDKit-based implementation for dramatically faster parsing. The same Rust code is used by the WASM frontend.
load_trajectory
def load_trajectory(pdb_path: str, xtc_path: str) -> InMemoryTrajectory
Load a trajectory from PDB topology + XTC coordinates.
Uses the Rust XTC parser (megane-core) instead of MDAnalysis.
Args: pdb_path: Path to PDB file (topology, used for atom count validation). xtc_path: Path to XTC file (trajectory).
Returns: InMemoryTrajectory with frame-by-frame access.