Reading a .qvf in the terminal, over SSH

You will learn: how to inspect a complete vibe-qc calculation (structure, orbitals, band structure, spectra, convergence, provenance) without a browser, a display server, or copying files back to your laptop.

Why: the machine that produces a .qvf is usually not the machine you are sitting at. vibe-view open needs a browser and an OpenGL context; vibe-view capture needs OpenGL too, and then you still have to move the PNG. Terminal mode needs neither. It is a software rasterizer written in numpy that draws into Unicode braille characters, so it runs on a bare login shell on a compute node.

Prerequisites:

  • vibe-view installed on the machine holding the .qvf. The base install is enough for vibe-view show; the interactive vibe-view tui adds one pure-Python dependency:

    pip install 'vibeview[tui]'
    
  • A terminal that speaks 24-bit colour and has a font with braille coverage. Most modern terminals and monospace fonts do; if the glyphs come out as boxes, add --mode half to every command below and the pictures switch to block characters.

Time to complete: about 10 minutes.

Note

Terminal mode and MolTUI solve overlapping problems from opposite ends. MolTUI is a general terminal viewer for the formats the field already uses (.molden, .cube, .xyz, .xsf), so it reads output from any code. Terminal mode reads .qvf and only .qvf, but because a QVF is one self-describing archive it can show you the band structure, the SCF trail, the charges and the citation bundle from the same file — not just the geometry. Use MolTUI when you have loose files from mixed sources; use terminal mode when you have a QVF.

1. Produce a .qvf worth looking at

Any run_job / run_periodic_job call emits one with output_qvf=True. This water job writes most of the section kinds terminal mode can draw:

# input-water.py
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",
    optimize=True,             # trajectory section
    hessian=True,              # vibrations + IR spectrum
    output="water",
    output_qvf=True,           # produces water.qvf
    write_density=True,        # embeds the SCF density isosurface
    write_molden_file=True,    # embeds wavefunction.gto + the MO blobs
)
python input-water.py     # → water.qvf

2. Look at it without leaving the shell

vibe-view show water.qvf

That prints one frame, the structure framed and shaded, then exits. The camera fits the molecule to your terminal’s actual size.

Everything about the render is a flag:

vibe-view show water.qvf --representation spacefill
vibe-view show water.qvf --rotate -30,45,0 --labels
vibe-view show water.qvf --size 120x40

Because it exits, it composes like any other command:

vibe-view show water.qvf | less -R        # colour survives the pipe
vibe-view show water.qvf --plain > frame.txt
watch -c -n2 'vibe-view show running.qvf' # crude live monitor

3. Read the metadata before the picture

--info prints provenance, run lifecycle, and the section inventory, which is the fastest way to find out what a calculation actually produced:

vibe-view show water.qvf --info
Archive
path                   water.qvf
qvf version            1
producer               vibe-qc

Provenance
basis                  6-31g*
functional             PBE
method                 rks
scf_converged          True
scf_energy             {'value': -76.38..., 'units': 'Eh'}

Sections
id            kind              status    note
structure     structure         rendered
density       volume.density    rendered
homo          volume.orbital    rendered
lumo          volume.orbital    rendered
wavefunction  wavefunction.gto  rendered
traj0         trajectory        rendered
vib           vibrations        rendered
ir            spectra.ir        rendered
citations     citations         rendered
scf_history   scf_history       rendered

The status column comes straight from vibe-view’s kind registry, so a section the viewer cannot draw still appears, with the honest reason: not yet rendered is a different statement from unsupported.

4. Orbitals

Point --section at a volume section. Signed fields get both lobes; the isovalue is yours to choose:

vibe-view show water.qvf --section homo --isovalue 0.05
vibe-view show water.qvf --section homo --isovalue 0.02 --representation licorice

Lowering the isovalue grows the surface. A licorice or wireframe representation keeps the atoms from hiding inside it.

The isosurface itself comes from VTK’s marching-cubes filter, which is pure computation: no render window, no GL context. That is the only place terminal mode touches VTK at all.

5. Charts

The chart-shaped kinds go through the same command:

vibe-view show water.qvf --section ir            # stick spectrum + envelope
vibe-view show water.qvf --section scf_history   # |ΔE| on a log axis
residual                 SCF convergence
     0.06│     ⠠⠤⣀⡀
         │        ⠈⠈⠑⠒⠤⠤⣀⢀
  1.0e-04│                ⠉⠉⠒⠒⠢⠠⠤⣀⣀⡀
         │                         ⠈⠉⠁⠑⠒⠤⢄⣀
  1.7e-07│                                 ⠁⠒⠤⡀
         │                                    ⠈⠑⠢⡀⡀
         │                                        ⠈⠒⢄⡀
  2.9e-10│                                           ⠈⠑⠂⠤⣀
         │                                                ⠉⠒⠤⡀⣀
  5.0e-13│                                                     ⠉⠒
         └┴──────────────────────────┴──────────────────────────┴
          1.00                   iteration                    11.0
          ── |ΔE| (Ha)

Axis conventions follow the interactive Plotly renderers, so a terminal chart and a browser chart tell the same story. In particular, bands and DOS are Fermi-referenced only when E_F falls inside the data window, and are labelled absolute (naming E_F) when it does not.

6. Trajectories and normal modes

Animated kinds take a --frame:

vibe-view show water.qvf --section traj0 --frame 0
vibe-view show water.qvf --section traj0 --frame 8
vibe-view show water.qvf --section traj0 --chart   # the energy profile instead

A trajectory and a reaction path are both geometry and an energy curve; --chart picks the curve.

7. Everything at once

vibe-view show water.qvf --all --plain > report.txt

Renders every graphable section in a reading order, one after another. Useful as a build artefact or attached to a job’s log.

8. The interactive viewer

For browsing rather than checking one thing:

vibe-view tui water.qvf

Section browser on the left, viewport in the middle, status line naming what you are looking at. Press ? for the full key map; the essentials:

Tab

next section

arrows / h j k l

rotate

+ -

zoom, r to reset

m / c

representation / colour scheme

i I

isovalue down / up

Space

play an animation

t

data table for the current section

q

quit

9. Periodic systems

Cell edges are drawn only along axes flagged periodic (a 2D slab gets the in-plane parallelogram, never a box around its vacuum), and --replicate respects the same rule:

vibe-view show graphene.qvf --replicate 3,3,1

Bonds crossing a cell face are drawn to the nearest periodic image rather than stretched across the box. This matters more than it sounds: a periodic bond list stores the in-cell index pair, so graphene’s 1.42 Å bonds are listed at separations of 2.84, 3.76 and 5.68 Å. Drawing those endpoints literally produces a hairball; filtering them by length deletes real bonds.

10. From Python

The same renderers are on the public SDK, next to the PNG capture functions:

from vibeview import render_terminal

print(render_terminal("water.qvf", size=(100, 30)))
print(render_terminal("water.qvf", "homo", isovalue=0.03))

# plain=True drops the ANSI colour, for a log file
open("frame.txt", "w").write(render_terminal("water.qvf", plain=True))

A worked script covering the whole surface (representations, orbitals, supercells, charts, text panes, animation) ships at vibe-view/examples/terminal_mode.py:

python vibe-view/examples/terminal_mode.py water.qvf

When terminal mode isn’t enough

It is a reading tool: fast, low-resolution, no setup, works over SSH. For publication figures use vibe-view capture (PNG), the POV-Ray and Blender exporters, or the interactive viewer’s own export. For detailed orbital analysis such as NBO decompositions or ELF/NCI maps, vibe-qc writes .cube and .molden that Multiwfn and VMD read.

Two limits worth knowing before you are surprised by them: a braille cell carries one colour, so two differently coloured atoms sharing a cell blend (zoom in, or use --mode half); and there is no mouse rotation, because terminals report clicks rather than smooth drags.

See also