Results and reaction energies

Import completed calculation outputs onto their recorded runs, then explicitly choose the source group or runs for a reaction-energy report. The original sketch stays editable. A derived figure puts energies below its arrows; the report and exported QVF retain every source run, method and file digest.

In the browser

After submitting calculations, open Reaction results below the calculation list. Choose Source run and its Result file, then Import result. Repeat for the other participants. Replacing an existing, different result requires Replace existing result.

Choose a Result group and a reaction, or all reactions. Confirm the coefficients on both chemical sides; they start at one. For a retrosynthetic arrow, the chemical reactants are the precursors at its head and the chemical products are the target at its tail. Reagents are not added to the energy sum. If an apparent reagent is consumed, draw it as a reactant first.

Preview reaction energies opens a read-only figure with ΔE and, when all participants have compatible thermochemistry, ΔH and ΔG. Download its SVG, a JSON energy report, or a QVF carrying the selected energies. The figure is computed afresh from the stored results, with space checked below each arrow; spread out the drawing if the preview refuses an overcrowded layout. The SVG metadata also contains the report and source identities. This preview does not add permanent energy text that could go stale in the editable sketch.

Acceptance and limitations

The local reader supports ORCA 6 text output for sp, opt, freq, opt+freq, tddft and nmr. It requires one normally terminated calculation, an SCF convergence marker and an exact normalized match between its echoed input and this job’s input, including coordinates, charge, multiplicity and all options. Full-line metadata comments and ORCA’s appended end-of-input marker are excluded from that comparison, so a later app version or display label does not invalidate the output. Repeated enthalpy in the Gibbs summary must agree. Optimisations also require the optimisation-converged marker. Frequency jobs require one complete thermochemistry block with absolute enthalpy/Gibbs energy, temperature and pressure. Multiple-temperature or compound-job output, property JSON/text, output without echoed input and other tasks are refused. Isotope-labelled inputs are refused because the current reader cannot verify the masses used by the calculation. No optional companion changes which parser is used.

Geometries

An ORCA optimisation (opt or opt+freq) brings its converged geometry back. The reader takes the CARTESIAN COORDINATES (ANGSTROEM) block printed after the optimisation-converged marker; if ORCA prints it more than once, the copies must agree. The atoms must be the species’ input atoms in their input order, or the output is refused: nothing is re-mapped. The geometry becomes a further 3D structure of the species, named orca:<task>:<12 hex digits> after the output’s SHA-256, so the structure and the result it came from name each other. The input geometry stays first, the drawing is not changed, and replacing the result replaces its geometry. The species card lists it beside the first 3D structure, and it is saved in .vsk and QVF.

An ORCA Hessian file (.hess, format orca-hess) is checked against the run it belongs to: a freq or opt+freq run whose ORCA output is already imported. The geometry in its $atoms block (bohr) must be that run’s stationary point within 1e-4 Å: the input geometry for freq, the optimised one for opt+freq. A common translation is removed before comparison because ORCA may use a different coordinate origin in its Hessian file. Atom order and the 1e-4 Å tolerance remain strict; rotations, reflections, scaling and internal distortions are not accepted. The stored conformers are not moved. The Hessian file adds no second copy of a geometry the species already holds. Optimisation trajectories are not kept as structures of the species.

The output vocabulary follows the ORCA 6.1 quick-start manual and thermochemistry chapter.

For vibe-qc, import the finished QVF job container. The existing optional QVF library validates the archive, including member hashes and energy consistency. The reader requires one successful, converged run record and a matching job specification and input structure. It reads energies.total, or provenance.scf_energy when the former is absent; when both exist they must agree within 1e-8 hartree. Thermochemistry uses the QVF root fields and must state temperature and pressure. Multi-run containers are currently refused. Install the documented QVF extra if the reader is unavailable. Input files are limited to 32 MiB, with bounded uncompressed QVF members.

The parser records what the completed output states; it does not independently validate a potential-energy minimum, transition state, imaginary modes, model adequacy or chemical mechanism. Those scientific acceptance checks remain part of the staged workflow and paper protocol.

A comparison requires exactly one selected result per participant, matching program/version and job specification (resource counts may differ), and matching thermochemistry temperature/pressure. Missing, conflicting, stale, non-finite or atom/charge-unbalanced data are refused. Supply explicit positive coefficients for non-unit stoichiometry; coefficients belong to the requested report, not to a new reaction-schema field. Resonance arrows have no reaction energy. Changing the species or input geometry invalidates a stored result; changing its display label does not.

SDK, CLI and REST

from pathlib import Path
from vibesketch.document import load, save
from vibesketch.document.results import Selection, import_result, reaction_energies, result_figure

sketch = load("scheme.vsk")
sketch = import_result(
    sketch, "run1", Path("run1.out").read_bytes(), format="orca", source_name="run1.out"
)
save(sketch, "scheme-with-results.vsk")
# Import the other participant outputs before requesting this comparison.
selection = Selection(group="g1", reactions=["r1"])
report = reaction_energies(sketch, selection)
Path("reaction-energies.svg").write_bytes(result_figure(sketch, selection))
vibe-sketcher import-result scheme.vsk run1 run1.out --format orca --output with-results.vsk
vibe-sketcher reaction-energies with-results.vsk --group g1 --reaction r1
vibe-sketcher reaction-energies with-results.vsk --group g1 --format svg --output energies.svg
vibe-sketcher reaction-energies with-results.vsk --run run1 --run run2 --format qvf --output energies.qvf

Use --coefficients coefficients.json when needed, for example:

{"r1": {"reactants": {"m1": 2}, "products": {"m2": 1}}}

POST /api/documents/{id}/results takes revision, run, format (orca or qvf), source_name, base64 data and optional replace. It returns the new document revision; stale edits return 409. No server filesystem path is accepted. POST /api/documents/{id}/results/report takes group or runs, optional reactions and coefficients, and format (json, svg or qvf). Unsupported results/comparisons return 422; an unavailable optional backend returns 503. The MCP tools are import_run_result and show_reaction_energies.

The optional Run.result stores absolute energies in hartree, the full job specification, parser/program version, retrieval timestamp, source basename and SHA-256, input-species digest, and each value’s source line/key. Source basenames may contain spaces and Unicode; paths and control characters are refused. Existing schema v1 documents remain valid. Reaction deltas are computed on demand as the sum of product energies minus reactant energies with their coefficients. Conversion to kcal/mol uses the shared CODATA 2018 factor, 627.509474.

A selected QVF export writes the report under each step’s x_vibesketch.energies, with canonical participant coefficients. Ordinary VSK and QVF saves preserve the absolute run results without choosing a comparison. The original output file is not embedded; archive it alongside the figure and report to retain auditable calculation evidence.

Energy tables

Use Download energy CSV, Download Markdown table, or Download LaTeX table with the same explicit group/reaction selection and coefficients as the figure. Each table has one row per reaction, with its participants, coefficients, absolute energies, method, conditions and source run IDs. Missing thermal values are empty in CSV and a dash in presentation tables; they are never zero.

vibe-sketcher reaction-energies with-results.vsk --group g1 --format csv --output energies.csv
vibe-sketcher reaction-energies with-results.vsk --group g1 --format markdown --output energies.md
vibe-sketcher reaction-energies with-results.vsk --group g1 --format latex --output energies.tex

The SDK is vibesketch.document.tables.reaction_table(document, selection, format="csv"), returning UTF-8 bytes. The existing results/report REST endpoint also accepts csv, markdown and latex. MCP export_energy_table returns format, media_type and text; it uses the same selection fields.

CSV retains round-trip floating-point precision, deltas in both hartree and kcal/mol, and full provenance. The reactants_json and products_json cells contain JSON arrays so reactions with different numbers of participants still occupy one CSV row. Decode them with json.loads; coefficients are positive on each chemical side. specification_json describes the shared method. Subtract the coefficient-weighted reactant absolute energies from the products to replay the reported delta. Potential spreadsheet formulas in text cells are prefixed with an apostrophe; numeric columns remain numeric.

Markdown and LaTeX display absolute energies to 12 decimal places in hartree and deltas to 3 decimal places in kcal/mol. Use CSV or the JSON report for numerical replay at full precision. Text is escaped for the selected markup. LaTeX exports are fragments requiring \usepackage{booktabs}; use LuaLaTeX or XeLaTeX when identifiers contain Unicode. The table uses paragraph columns relative to the current line width. For long schemes, place the table in a wide page or split it by selecting reactions; the fragment does not paginate itself.

Spectra

A frequency result keeps its harmonic vibrations, with IR intensities and Raman activities, and a tddft result keeps its excited states, with their oscillator strengths. Both are stored on the run’s result with their source line, so they keep the run’s method, file name and SHA-256 like its energies. The species card lists what each run holds, for example run1: 3 vibrations, IR (no imaginary). The imaginary-frequency count is shown on every frequency result: none at a minimum, one at a transition state.

From an ORCA 6 output the reader takes:

  • VIBRATIONAL FREQUENCIES, which must list all 3N modes, and the IR SPECTRUM and RAMAN SPECTRUM tables, whose wavenumbers must agree with it to printed precision. IR intensities are read in km/mol, Raman activities in Å⁴/amu. The projected translations and rotations ORCA prints as zero are left out; an imaginary mode is a negative wavenumber.

  • ABSORPTION SPECTRUM VIA TRANSITION ELECTRIC DIPOLE MOMENTS: the state, its excitation energy in eV and its oscillator strength. A tddft result must list as many states as the job asked for. Its energy is the ground-state SCF energy (Total Energy), because ORCA’s final single-point energy after TDDFT can be an excited state’s.

A table printed twice, a row that disagrees with the frequencies, or an energy that disagrees with its printed wavelength is refused. From a vibe-qc QVF the reader takes the vibrations section (or a spectra.ir/spectra.raman section in cm⁻¹) and the excited_states section, its energies converted to eV.

A mode without an IR or Raman line, or a state without an oscillator strength, keeps a missing value, never zero. Asking for a spectrum the result does not hold is refused.

Line lists and broadened spectra

Under Reaction results, Spectra lists every run whose result holds an IR, Raman or UV-Vis spectrum. Choose an export:

  • Line list (CSV): one row per mode or state with its units in the column names (wavenumber_cm-1, intensity_km/mol, activity_angstrom^4/amu; energy_eV, wavelength_nm, oscillator_strength). A missing value is an empty cell.

  • Line list (text): the same columns separated by spaces, after # header lines naming the species, run, job, program version, source file, SHA-256 and method. A missing value is -.

  • Broadened curve (text): the lines summed on a grid with a Gaussian or Lorentzian of the FWHM you give, in cm⁻¹ or eV (10 cm⁻¹ or 0.2 eV when left empty). The curve is plotted against wavenumber for IR and Raman, and against eV, nm or cm⁻¹ for UV-Vis.

The lines are broadened in energy, cm⁻¹ for vibrations and eV for excited states, and the curve is then sampled on the chosen axis, so a wavelength axis is never broadened in nm. Each line is a unit-area Gaussian or Cauchy (Lorentzian) density scaled by its intensity, the same definition vibe-viewer uses, so the curve’s unit is the intensity’s per cm⁻¹ or per eV. A finite range truncates a Lorentzian’s tails; the curve is not renormalised to hide that. The header states the line shape, the FWHM in the unit you gave and in the broadening unit, the axis, start, stop, step and number of points, and how many lines had no intensity and were left out. Values are written at full double precision, so the file reads back exactly.

The grid runs by default from the outermost lines plus 100 cm⁻¹ or 0.5 eV, in 2000 points; give start, stop and step in the axis unit to choose it. A grid of more than 1 000 000 points is refused.

vibe-sketcher spectrum with-results.vsk run1 ir --output ir-lines.csv
vibe-sketcher spectrum with-results.vsk run1 raman --format text
vibe-sketcher spectrum with-results.vsk run2 uvvis --format broadened \
    --lineshape gaussian --fwhm 0.3 --axis nm --start 150 --stop 400 --step 0.5

The SDK is vibesketch.document.spectra.export_spectrum(document, SpectrumExport(run=..., spectrum=..., format=...)), returning text; spectrum_lines and broadened_spectrum are the two halves. REST is POST /api/documents/{id}/results/spectrum with the same fields, and MCP export_spectrum returns format, media_type and text. Interactive spectrum plots are vibe-viewer’s.

NMR shifts

An ORCA nmr result keeps the isotropic shielding of every nucleus, from the table headed Nucleus  Element  Isotropic  Anisotropy that ORCA prints after the per-nucleus tensors. It must list every atom of the input, in order and with the input’s elements, and be printed once; anything else is refused. The species card counts the shieldings.

A shift is a difference of shieldings, δ = σ(reference) − σ, so it needs a reference run: the reference compound (tetramethylsilane for ¹H and ¹³C, CFCl₃ for ¹⁹F, …) drawn in the same document and computed with the same job specification, which is checked. The reference’s atoms of an element must all be equivalent; an element the reference does not hold has shieldings but no shifts. vibe-sketcher never substitutes a literature reference value. Nuclei that the molecule’s symmetry makes equivalent, such as the three hydrogens of a methyl group, are averaged into one line; the symmetry is read from the graph perceived from the run’s own geometry. Spin-spin couplings are not read, since vibe-sketcher’s ORCA inputs request shieldings only.

Under Reaction results, NMR takes the run and its reference. Line list downloads one row per set of equivalent nuclei, with its atoms, the hydrogens’ carbon, the shielding and the shift, as CSV (full precision), Markdown or LaTeX. Place shifts on the drawing writes each heavy atom’s shift and those of its hydrogens (δC 18.1, δH 1.17) as text beside the atoms of the species’ first drawn structure, where figures print them too; they are ordinary text you can move or delete.

vibe-sketcher nmr with-results.vsk run1 --reference run2 --nucleus H --format csv
vibe-sketcher nmr-labels with-results.vsk run1 --reference run2

The SDK is vibesketch.document.nmr (nmr_shifts, nmr_table, with_nmr_labels); REST is GET /api/documents/{id}/results/nmr and POST .../results/nmr-labels, MCP show_nmr and place_nmr_labels. Spectrum plots are vibe-viewer’s.

Accepted campaign results

Recipe campaigns have their own attempts and accepted artifacts. They do not create the document submission runs used by reaction-energies. Select the campaign directly with campaign-energies:

vibe-sketcher campaign-energies scheme.vsk recipe1 recipe1-c3 --stage dlpno
vibe-sketcher campaign-energies scheme.vsk recipe1 recipe1-c3 --stage dlpno \
  --format csv --output campaign-energies.csv
vibe-sketcher campaign-energies scheme.vsk recipe1 recipe1-c3 --stage dlpno \
  --format qvf --output campaign-energies.qvf

The campaign and terminal correlated stage are explicit. --reaction can be repeated; --coefficients reads the same reaction/side/species coefficient maps as submission-based reports. All campaign checks must be scientifically accepted, including every separately reviewed reference failure. The command does not submit jobs, change the journal, invent submitted runs or perform scientific reviews.

from vibesketch.document.campaign_results import (
    CampaignSelection,
    campaign_energies,
    campaign_energy_export,
)

selection = CampaignSelection(recipe="recipe1", campaign="recipe1-c3", stage="dlpno")
rows = campaign_energies(sketch, selection)
data = campaign_energy_export(sketch, selection, "csv")

Formats are JSON, CSV, Markdown, LaTeX, SVG and QVF, with the same precision and rounding rules as the tables above. JSON and CSV retain actual queue job/attempt, artifact, accepted-parent, event and explicit-review provenance. Replayed results identify their current replay attempt separately from the immediate retained artifact’s producer and campaign/source hashes; earlier lineage remains in the execution archive. SVG embeds the report and QVF retains it in the reaction-scheme extension. Human-facing formats name the producer’s actual triples algorithm, and reviewed references carry a visible warning. Only electronic energies are aggregated. The reporter checks the program/version stated in the result; a paper’s separate execution archive must still establish exact runtime/model identities and scientific validity.

REST: POST /api/documents/{id}/recipes/{recipe}/campaigns/{campaign}/energies with stage, optional reactions/coefficients, and format. MCP: campaign_energy_report with the same selection plus recipe, campaign and optional document. The browser exposes the downloads after refreshing a campaign in Staged workflows. No result is accepted merely because its process finished: the report rechecks accepted QVF/verdict pairs and review bindings.

Inspect a calculation in vibe-viewer

Each imported run has View results controls on its species card. Choose Check available views, select a retained artifact, then View orbitals, View density, View mode, or View spectrum. Only views present in that artifact are enabled. Modes are numbered from 1. Orbital names follow vibe-viewer (for example HOMO, LUMO+1, or a zero-based orbital number); a precomputed orbital grid is selected by its section name.

Importing a verified result retains its original bytes in the local user cache, addressed by SHA-256. The document records filenames and digests, never a path supplied by the browser. Older documents or documents moved to another computer need their original result files reimported. Missing or damaged cached bytes produce a reason rather than a substitute result.

Use Attach companion for an ORCA GBW, Hessian, JSON, Molden or cube file. Companion conversion uses the installed vibe-viewer import command; GBW import also needs the converter required by vibe-view. The ordered atoms and geometry must match the run’s checked input or accepted optimized structure. Attachments are limited to 32 MiB each, as are result imports. Keep ORCA companion basenames consistent so its dataset importer can assemble the files. No directory scan of your calculation folder is performed. A missing viewer produces an install hint; missing data, ambiguous structures and foreign geometries produce explicit reasons.

The handoff contains the requested view and selector, the complete original files, and a x_vibesketch.origin section with species and run identity. A QC job container can contain input and result structures: its display archive selects the checked result structure, while retaining the untouched complete container as an embedded original file. View can return an edited geometry as a new conformer using the same checked geometry-return workflow; the drawing is preserved.

The same operations are available through every interface:

from vibesketch.result_views import capabilities, attach_file
from vibesketch.viewer import show_result

print(capabilities(document, "run1"))
show_result(document, "run1", "mode", mode=2, document_id="drawing-1")
vibe-sketcher result-views drawing.vsk run1
vibe-sketcher view-result drawing.vsk run1 --view mode --mode 2
vibe-sketcher attach-view-file drawing.vsk run1 calculation.hess --output drawing.vsk

REST uses GET /api/documents/{id}/runs/{run}/views, POST .../view with view, optional artifact, mode, and orbital, and POST .../view-files with the current revision, plain name, base64 data, and editor identity. MCP exposes result_views, show_result_view, and attach_view_file with the same run and selector fields. The existing VIBESKETCH_VIEW_HANDOFF_DIR contract also carries these selectors when a running viewer receives the handoff.