Tutorial 27: Viewing geometries, orbitals, and vibrations with MolTUI¶
You’ll learn: how to inspect vibe-qc output files — geometries, molecular orbitals, normal modes — directly in the terminal, without firing up Avogadro / Jmol / VMD.
Why: when you’re SSH’d into a remote machine, iterating quickly on a screen full of input files, or just allergic to GUI context-switches, MolTUI is the right tool. It renders 3D structures inline using Unicode block characters; you navigate with the keyboard.
Prerequisites: vibe-qc installed in a venv, plus MolTUI on top. Two install paths:
# As a vibe-qc extra (single command, captures the dependency):
.venv/bin/pip install '.[viewer]'
# Or via the interactive helper:
./scripts/install_optional_tools.sh
After install, moltui is on the venv’s PATH:
.venv/bin/moltui --version
What MolTUI reads¶
Format |
What it shows |
Where vibe-qc writes it |
|---|---|---|
|
Geometry (single frame) |
|
|
Geometry + MOs + normal modes |
|
|
Volumetric data (orbitals, density) |
|
|
Geometry + MOs + normal modes (Gaussian fchk) |
(not yet emitted by vibe-qc) |
|
ORCA’s native binary (needs |
(not emitted by vibe-qc; ORCA-specific) |
|
ORCA’s normal-modes file |
✅ |
|
Crystal structure + volumetric data (density, Bloch orbitals) |
✅ |
|
Fermi surfaces (band energies on k-mesh) |
✅ |
Multi-frame |
Trajectory animations |
✅ |
|
Geometry-optimization history (multi-XYZ + per-step E) |
✅ |
The two formats vibe-qc writes today out of the box are
.molden (full molecular-orbital data, plus geometry, plus
normal modes if a Hessian was computed) and .cube (volumetric
data for individual orbitals or the total density). .xsf is
the periodic counterpart for crystal structures and Bloch orbitals.
All three work with MolTUI directly.
Step 1: Generate the files¶
from vibeqc import Atom, Molecule, run_job
mol = Molecule([
Atom(8, [0.0, 0.00, 0.00]),
Atom(1, [0.0, 1.43, -0.98]),
Atom(1, [0.0, -1.43, -0.98]),
])
run_job(
mol,
basis="6-31g*",
method="rks",
functional="PBE",
output="water",
)
# → water.out, water.molden
That gives you water.molden with the geometry + MOs + occupations.
Add a cube for density / orbital visualization:
import numpy as np
import vibeqc as vq
basis = vq.BasisSet(mol, "6-31g*")
result = vq.run_rks(mol, basis, vq.RKSOptions(functional="PBE"))
# HOMO orbital cube
homo = mol.n_electrons() // 2 - 1
vq.write_cube_mo("water-homo.cube",
np.asarray(result.mo_coeffs), homo, basis, mol,
spacing=0.2, padding=3.0)
# Total density cube
vq.write_cube_density("water-density.cube",
np.asarray(result.density), basis, mol,
spacing=0.2, padding=3.0)
Step 2: View geometries¶
Launch MolTUI on the .molden:
moltui water.molden
The default view shows the molecular geometry rendered inline:
┌──────── water.molden ────────┐
│ │
│ o │
│ │
│ h h │
│ │
│ │
└──────────────────────────────┘
[g] geometry [o] orbitals [v] vibrations
(rendering varies by terminal size + Unicode font; on a typical full-screen 100×40 character terminal you get a recognisable 3D structure)
Keyboard navigation (defaults — see moltui --help for the
authoritative list):
Key |
Action |
|---|---|
arrow keys / |
Rotate the structure |
|
Zoom in / out |
|
Switch to geometry view |
|
Switch to orbitals view (.molden / .cube / .fchk) |
|
Switch to vibrations view (.molden / .hess / .fchk) |
|
Cycle frame / orbital / mode |
|
Quit |
Step 3: View orbitals¶
From the geometry view, press o to switch to orbitals. MolTUI
parses the molden file’s MO-coefficient block and renders an
isosurface inline:
┌───── HOMO ε = -6.09 eV occ = 2 ─────┐
│ │
│ ▓▒░ ░▒▓ │
│ ▓▒░ ░▒▓ │
│ ▓▒░ o ░▒▓ │
│ ▒░ ░▒ │
│ h h │
│ │
│ │
└─────────────────────────────────────────┘
[Tab]/[Shift-Tab] cycle MO [+/-] zoom [q] quit
Light shading is the positive isosurface lobe, darker is the negative. The HOMO of water is the in-plane oxygen lone pair — two lobes opposite the H atoms.
Tab cycles through the MOs; the header shows the eigenvalue
and the occupation. Useful for sanity-checking that:
The HOMO has the right symmetry for your molecule (lone pairs, π systems, etc.).
The LUMO ordering is what you expect (no surprise σ* / Rydberg crossings).
The orbital energies (header) match what’s in the
.outfile’s orbital table.
For finer-grained orbital views — explicit isovalue control,
publication-quality renderings — open the .molden or one of the
cube files in Avogadro / Jmol / VMD instead. MolTUI is for
quick triage, not for paper figures.
Step 4: View cube files (volumetric data)¶
For more detailed per-orbital control:
moltui water-homo.cube
moltui water-density.cube
Cube files are dense volumetric grids — MolTUI raycasts an isosurface at a default isovalue (usually 0.05 a.u.). Adjust with:
[i]/[I] decrease/increase isovalue
[r] reset isovalue to default
A density cube (sum over occupied orbitals) shows the total
electron density — the “shape” of the molecule. A single-MO
cube shows one orbital at a time (HOMO, LUMO, anything you
asked write_cube_mo to output).
Step 5: View vibrational modes¶
If your .molden has a [FREQ] and [FR-COORD] block (which
vibe-qc emits when you compute a Hessian), MolTUI renders the
normal modes as animated displacement vectors. Press v from
any view to switch.
┌── mode 7 ω = 1751.3 cm⁻¹ IR = 67.8 km/mol ──┐
│ │
│ ↑ o ↑ │
│ ↑ ↑ │
│ h h │
│ (symmetric stretch) │
│ │
└─────────────────────────────────────────────────┘
[Tab]/[Shift-Tab] cycle mode [Space] play/pause
The arrows (or oscillating atoms, depending on the terminal + animation toggle) show the eigenvector of that normal mode. For water you’ll see three real modes — bend, symmetric stretch, antisymmetric stretch — and six near-zero translation/rotation modes that MolTUI typically hides.
To produce a .molden with vibrational data:
import vibeqc as vq
# Compute analytic Hessian + frequencies
mol = vq.Molecule.from_xyz("water-equilibrium.xyz")
basis = vq.BasisSet(mol, "6-31g*")
result = vq.run_rhf(mol, basis)
hess = vq.compute_hessian_rhf_analytic(
mol, basis, result, basis_name="6-31g*",
)
# Write a molden file with the normal modes attached
vq.write_molden("water-with-freqs.molden", mol, basis, result,
hessian=hess)
Tip
Direct ORCA-format .hess export is available via
:func:vibeqc.write_orca_hess (Phase M1). Useful when you’d
rather inspect just the vibrational data than parse the full
molden bundle — and it’s the format moltui reads natively for
ORCA-style normal-modes display:
hess = vq.compute_hessian_rhf_analytic(mol, basis, result, basis_name="6-31g*")
vq.write_orca_hess("water.hess", mol, hess)
# then: moltui water.hess
The same ASCII format means cross-code visual diff’ing works:
moltui vibeqc.hess and moltui orca.hess should show
identical modes when the underlying CPHF kernels agree.
See tutorial 26 § cross-validation: vibrations
for the cross-validation script that asserts ~0.5 cm⁻¹ agreement
on H₂O.
Tips and tricks¶
Over SSH: MolTUI runs entirely in your terminal — no X11 forwarding, no GUI windows. Just
sshin,cdto your output directory, andmoltui ....Quick triage: for a calculation that just finished, look at the
.outfile first (text — energy, convergence, warnings), thenmoltui ...moldento spot-check the geometryHOMO shape. Catches “the SCF converged to the wrong state” bugs immediately.
Animations (Phase M2): vibe-qc writes multi-XYZ trajectories natively — geometry-optimization paths, NEB images, normal-mode movies, MD snapshots — and moltui animates them frame-by-frame.
Optimization history → moltui movie:
import vibeqc as vq geoms, energies, rms_grads = run_my_optimization(mol) vq.write_opt_trajectory("h2o.opt", geoms, energies, rms_grad=rms_grads)
moltui h2o.opt # animated optimisation path with per-step E in the # comment line — Tab cycles iterates
Normal-mode movie — paired helper builds the displaced frames for one vibrational mode:
hess = vq.compute_hessian_rhf_analytic(mol, basis, result, basis_name="6-31g*") frames = vq.normal_mode_trajectory(mol, hess, mode_index=8, amplitude=0.5, n_frames=20) vq.write_xyz_trajectory("h2o-asym-stretch.xyz", frames)
moltui h2o-asym-stretch.xyz # animated symmetric-stretch movie
Falling back via ASE — convert any ASE
.trajto multi-XYZ — also still works:ase convert output-h2o-opt.traj output-h2o-opt.xyz moltui output-h2o-opt.xyz
Keep
moltuiopen in a separate terminal while you iterate on input files; reload by re-runningmoltui <file>after each calculation finishes.
Crystalline orbitals and periodic data¶
Since v0.8.x+, MolTUI supports XSF and BXSF — XCrySDen’s native periodic formats — alongside its existing molecular formats:
Format |
What it shows |
Where vibe-qc writes it |
|---|---|---|
|
Crystal structure + volumetric data (density, Bloch orbitals) |
|
|
Fermi surfaces (band energies on k-mesh) |
|
What works:
Unit-cell wireframe — lattice vectors drawn as the bounding box.
Periodic replication — press
bto tile the cell N×N×N along the lattice vectors.Isosurfaces — density or Bloch orbitals rendered inside the cell (same isosurface pipeline as cube files).
Band cycling — for multi-grid XSF or BXSF,
Tabcycles through grids/bands.Fermi-surface rendering — BXSF files show each band’s intersection with the Fermi energy.
# View a crystal structure
moltui nacl.xsf
# View density inside the unit cell
moltui nacl.density.xsf
# Cycle through Fermi surfaces
moltui nacl_bands.bxsf
See tutorial 43 for the full end-to-end workflow — from SCF → XSF/BXSF → MolTUI.
What doesn’t work yet:
.molden periodic extension — the format has no cell/lattice concept. Use XSF or cube instead.
Per-axis replication — the
btoggle replicates all three axes uniformly. 1D/2D systems get a slab; vacuum directions are still drawn as part of the cell.k-point navigation — you view one crystalline orbital at one k-point per file. No in-app k-point picker.
For desktop-quality rendering, pipe the same XSF/BXSF file to VESTA or XCrySDen after MolTUI triage.
When MolTUI isn’t enough¶
MolTUI is a triage tool — fast, terminal-native, low-resolution. For:
Publication figures — Avogadro 2 (cross-platform GUI), VMD (scriptable, scientific-grade), ChimeraX (high-quality surfaces), Jmol (web-friendly).
Detailed orbital analysis — natural-bond-orbital decompositions, ELF/NCI plots, charge-transfer maps — use Multiwfn (free, Windows/Wine on macOS+Linux) or pymol.
Crystal structures — VESTA (free), pymatgen visualizations.
vibe-qc writes formats every one of these tools reads (.molden,
.cube, .xyz, future .gbw/.hess); pick the right viewer for
the job. MolTUI’s superpower is no GUI, no setup, runs over
SSH — that’s the niche.
See also¶
installation: optional terminal viewer — install paths
output files user guide — what vibe-qc writes
tutorial 11: orbital visualization — generating cube files for visualization
tutorial 9: vibrational frequencies — generating Hessians for normal-mode analysis
MolTUI repo — authoritative docs for keybindings + supported formats