From 4477a457a986111d1cf64ce8f176d927f40f4c2b Mon Sep 17 00:00:00 2001
From: Jonathan Schultz
Date: Sat, 3 Oct 2026 22:23:33 +0000
Subject: [PATCH] chore(release): bump version to 0.10.0; README and docs for
the release
Bump pyproject.toml and quantui.__version__ to 0.10.0 and date the
CHANGELOG section (one Changed section; compare links for 0.10.0).
README and the GitHub Pages docs catch up with what shipped since 0.9.0:
- Transition State and Reorganization Energy in the calc-type tables
(eight types), the optional [ts] extra (Sella), thermochemistry at any
T and P, frozen atoms.
- Structure upload and editing, point groups and orbital symmetry
labels, , density / spin-density / ESP surfaces, alpha/beta
orbitals, the orbital gallery, the vibration viewer, browser downloads.
- Cluster batch jobs: `quantui submit` and `quantui install-launcher`
in the CLI reference, with `quantui-batch` pointing to its guide.
- Test count (~3,700), LANL2DZ in the basis list, project-structure
entries for ts_search, reorganization_energy, batch_launcher, backends.
Contributions:
- Claude (Opus 5.5): code edits, review, and conceptual discussion
- Jonathan Schultz: overall vision, planning, review, and orchestration
Co-authored-by: Jonathan Schultz
Co-authored-by: Claude Opus 5.5
---
CHANGELOG.md | 14 +++++-----
README.md | 64 ++++++++++++++++++++++++++++++++++++--------
docs/CLI.md | 54 +++++++++++++++++++++++++++++++++++--
docs/features.md | 39 +++++++++++++++++++++------
docs/index.md | 7 ++---
docs/installation.md | 1 +
docs/methods.md | 12 +++++----
pyproject.toml | 2 +-
quantui/__init__.py | 2 +-
9 files changed, 157 insertions(+), 38 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7ba0584..e2e621a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
## [Unreleased]
+## [0.10.0] - 2026-10-03
+
### Added
- **Upload structure files** — new **Upload File** tab (Calculate → Molecule
@@ -104,6 +106,9 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
(`git describe`) in the image's `QuantUICommit` label and
`/opt/build-info/quantui-commit.txt`; its `--version` flag is gone — check
out a release tag to build that release.
+- **Finished batch attempts reach History when the app starts**, even where
+ SLURM is unavailable (e.g. an OnDemand session), so jobs submitted from a
+ terminal show up without opening the Cluster Jobs tab.
### Fixed
@@ -161,12 +166,6 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
Ni, Mo and most other metals, so a metal counted as 0 electrons and the
memory estimate came out low. It now uses the full table.
-### Changed
-
-- **Finished batch attempts reach History when the app starts**, even where
- SLURM is unavailable (e.g. an OnDemand session), so jobs submitted from a
- terminal show up without opening the Cluster Jobs tab.
-
## [0.9.0] - 2026-09-26
### Added
@@ -1094,7 +1093,8 @@ Initial public scaffolding of the QuantUI package: `quantui` package with
`calculator.py`, basic notebook launcher, Apptainer container definition,
MIT license, and project metadata.
-[Unreleased]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.9.0...HEAD
+[Unreleased]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.10.0...HEAD
+[0.10.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.9.0...v0.10.0
[0.9.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.8.2...v0.9.0
[0.8.2]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.8.1...v0.8.2
[0.8.1]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.8.0...v0.8.1
diff --git a/README.md b/README.md
index 8fff997..b147907 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,11 @@ Real output from QuantUI, straight from the app:
ready-to-run coordination complexes**, searchable by name/formula), or run a
structure search by name, SMILES, InChI, PubChem CID, InChIKey, or CAS number
(PubChem → NCI CACTUS → offline bundled-library fallback; SMILES/InChI resolve
- locally with no network)
+ locally with no network), or upload a structure file (XYZ, MOL/SDF, MOL2,
+ PDB, CIF, Gaussian input or output)
+- **Structure editing** — set a bond length, angle or dihedral to a value,
+ delete atoms, add a hydrogen, change an element, undo; pick atoms by
+ clicking the viewer. Freeze atoms for a constrained geometry optimization
- **Offline-first** — runs with no internet: the bundled molecule library and
the 3D viewer's JavaScript (3Dmol.js) are vendored, so structure lookup and
every 3D view work in an air-gapped classroom. (Network is used only for the
@@ -71,7 +75,9 @@ Real output from QuantUI, straight from the app:
router picks the right renderer per task, and a Status-tab toggle persists
your default-backend preference between sessions
- **In-session calculations** — RHF, UHF, 9 DFT functionals, MP2, CCSD,
- CCSD(T), NMR shielding, TD-DFT UV-Vis, and 1D PES scans via PySCF, running
+ CCSD(T), NMR shielding, TD-DFT UV-Vis, 1D PES scans, Marcus reorganization
+ energies and **transition-state searches** (Sella, with an automatic
+ frequency check that says whether it found a TS) via PySCF, running
in your Python kernel. Optional PyFock 0.1.x adds native-Windows PBE
single points and geometry optimizations for neutral, closed-shell molecules
with def2-SVP/def2-TZVP, including orbital and population analysis;
@@ -81,13 +87,18 @@ Real output from QuantUI, straight from the app:
optimizations, frequencies (PCM Hessian + IR; Raman stays gas-phase) and
TD-DFT (non-equilibrium excitations). NMR and PES scans are gas-phase only
- **Rich results** — total energy, HOMO-LUMO gap, Mulliken charges, dipole
- moment, thermochemistry (H, S, G at 298 K), IR spectrum chart (stick and
- Lorentzian-broadened), ¹H/¹³C NMR chemical shifts, orbital energy-level
- diagram, HOMO/LUMO isosurface (cube-file rendering with toggle for HOMO-1,
- HOMO, LUMO, LUMO+1), and a side-by-side comparison table for multiple
- calculations
+ moment, point group, ⟨S²⟩ with a spin-contamination flag for open-shell
+ results, thermochemistry (U, H, S, G, Cv, Cp at any temperature and
+ pressure), IR spectrum chart (stick and Lorentzian-broadened), ¹H/¹³C NMR
+ chemical shifts, an orbital energy-level diagram with symmetry labels
+ (1a₁, 1b₂ …), and a side-by-side comparison table for multiple calculations
+- **Surfaces** — any molecular orbital (α and β for unrestricted results), an
+ **orbital gallery** of the orbitals around the HOMO–LUMO gap in small linked
+ viewers, the electron density, the spin density, and the electrostatic
+ potential mapped on the density surface
- **Geometry optimization** — BFGS optimizer with step-by-step trajectory
animation; vibrational frequency analysis with animated normal modes,
+ displacement arrows, an amplitude slider and a table of every mode,
user-tunable playback FPS, and a per-result-directory disk cache so mode
switches on repeat visits and history replay are instant
- **Inorganic / coordination complexes** — first-class support for
@@ -106,7 +117,9 @@ Real output from QuantUI, straight from the app:
timestamped directory; a built-in browser lets you reload past results
after a kernel restart; the full `pyscf.log` is shown inline
- **Structure exports** — download XYZ, MOL/SDF, or PDB files alongside the
- saved results; script export for a standalone `.py` file
+ saved results; script export for a standalone `.py` file. Every export also
+ downloads straight to your computer, including from a remote
+ Voilà/OnDemand session
- **Plot export** — save IR, UV-Vis, PES, and orbital diagrams as standalone
HTML
- **Optional GPU acceleration** — when [gpu4pyscf](https://github.com/pyscf/gpu4pyscf)
@@ -117,6 +130,11 @@ Real output from QuantUI, straight from the app:
Geometry-optimization SCF and gradient steps offload the same way. For a
frequency calculation, the displaced IR SCFs offload, but the reference SCF
and the analytical Hessian still run on the CPU.
+- **Cluster batch jobs** — `quantui-batch` submits QuantUI calculations to
+ SLURM from a login node over SSH, without starting the image there (presets,
+ chaining from another job's optimized geometry, reruns with more memory or
+ time, results summaries); `quantui submit` does the same wherever QuantUI is
+ installed. See [apptainer/slurm/README.md](https://github.com/The-Schultz-Lab/QuantUI/blob/main/apptainer/slurm/README.md)
- **Timing calibration** — one-click benchmark suite populates the time
estimator with real machine data so predictions are accurate from the first run
- **Voilà app mode** — serve the notebook as a polished widget-only UI (no
@@ -266,6 +284,19 @@ reports the reason. GPU single points use PyFock's GPU SCF/integral/XC path;
GPU geometry optimizations use numerical finite-difference forces because the
installed PyFock release's analytical gradient implementation is CPU-only.
+### Optional: transition-state searches (Sella)
+
+The **Transition State** calc type uses [Sella](https://github.com/zadorlab/sella),
+installed as an optional extra:
+
+```bash
+pip install "quantui[ts]"
+```
+
+Sella pulls in jax/jaxlib (about 380 MB) and is LGPL-3.0, used as a
+separately installed library. Without it the calc type stays in the menu and
+says how to install it. Local runs only for now (not SLURM batch jobs).
+
### Optional: GFN-FF metal pre-optimization (xtb)
The classical (MMFF/UFF) pre-optimizer relies on RDKit's organic valence
@@ -414,8 +445,13 @@ dashboard. After installation:
quantui log tail -n 50 # last 50 events from event_log.jsonl
quantui gpu check # is GPU offload available right now?
quantui analytics build --open # build dashboard.html + open in browser
+quantui submit water.xyz --calc frequency --method B3LYP --basis def2-SVP # SLURM batch job
```
+On a cluster, `apptainer exec IMAGE quantui install-launcher DIR` writes the
+`quantui-batch` launcher for submitting from a login node — see
+[apptainer/slurm/README.md](https://github.com/The-Schultz-Lab/QuantUI/blob/main/apptainer/slurm/README.md).
+
Full reference with all flags and examples: [docs/CLI.md](https://github.com/The-Schultz-Lab/QuantUI/blob/main/docs/CLI.md).
---
@@ -478,11 +514,13 @@ Five step-by-step notebooks in [`notebooks/tutorials/`](https://github.com/The-S
| Type | Output |
| --- | --- |
| Single Point | Energy, HOMO-LUMO gap, Mulliken charges, dipole moment |
-| Geometry Opt | Optimised structure, trajectory animation |
-| Frequency | Vibrational frequencies, ZPVE, IR intensities, thermochemistry (H/S/G at 298 K), animated normal modes, IR spectrum chart (stick / Lorentzian broadened) |
+| Geometry Opt | Optimised structure, trajectory animation; optional frozen atoms |
+| Transition State | Saddle point near the input geometry (Sella, optional `[ts]` extra), then a frequency check: transition state, minimum, or higher-order saddle point; animated imaginary mode |
+| Frequency | Vibrational frequencies, ZPVE, IR intensities, thermochemistry at any temperature and pressure, animated normal modes, IR spectrum chart (stick / Lorentzian broadened) |
| UV-Vis (TD-DFT) | Excitation energies, oscillator strengths, UV-Vis spectrum plot |
| NMR Shielding | ¹H and ¹³C chemical shifts relative to TMS via GIAO; tabulated by element |
| PES Scan | 1D potential energy surface along a bond, angle, or dihedral; energy profile chart; geometry animation at each scan point |
+| Reorganization Energy | Marcus four-point internal reorganization energy λ = λ₁ + λ₂ for hole (cation) and/or electron (anion) transfer |
### Basis sets
@@ -531,6 +569,8 @@ quantui/ Main package
freq_calc.py Vibrational frequency + thermochemistry
ir_plot.py IR spectrum chart (stick / Lorentzian broadened)
tddft_calc.py TD-DFT UV-Vis excited-state calculations
+ ts_search.py Transition-state search (Sella) + frequency check
+ reorganization_energy.py Marcus four-point reorganization energy
nmr_calc.py NMR shielding + ¹H/¹³C chemical shifts
pes_scan.py 1D potential energy surface scan
optimizer.py QM geometry optimization with trajectory
@@ -551,12 +591,14 @@ quantui/ Main package
benchmarks.py Timing calibration benchmark suite
config.py Methods, basis sets, solvent/NMR options, presets
ase_bridge.py ASE structure I/O
+ batch_launcher.py Renders the quantui-batch login-node launcher
+ backends/ SLURM batch backend, worker and job registry
preopt.py RDKit MMFF94/UFF force-field pre-optimization
data/ Bundled library (SQLite + manifests) + vendored 3Dmol.js
notebooks/
molecule_computations.ipynb Main user-facing interface (3-cell launcher)
tutorials/ Step-by-step guided notebooks (01–05)
-tests/ pytest test suite (~1500 tests; run in parallel via pytest-xdist)
+tests/ pytest test suite (~3,700 tests; run in parallel via pytest-xdist)
apptainer/ Container definition for reproducible deployment
local-setup/ Conda environment definition
pyproject.toml Package metadata and tool config
diff --git a/docs/CLI.md b/docs/CLI.md
index 2d2ff82..0bb6fa8 100644
--- a/docs/CLI.md
+++ b/docs/CLI.md
@@ -11,9 +11,10 @@ quantui --help
The CLI is meant to *complement* the Voilà app. Most commands are
read-only diagnostics against `~/.quantui/` (or whatever
-`QUANTUI_LOG_DIR` points at). The exception is **`quantui run app`**
+`QUANTUI_LOG_DIR` points at). The exceptions are **`quantui run app`**
and **`quantui setup`**, which start (or prepare) the student-facing
-Voilà interface.
+Voilà interface, and **`quantui submit`** / **`quantui install-launcher`**,
+which send calculations to a SLURM cluster.
Reach for the CLI when you want to:
@@ -34,6 +35,8 @@ Reach for the CLI when you want to:
| [`quantui log tail`](#quantui-log-tail) | Print recent events from `event_log.jsonl` |
| [`quantui gpu check`](#quantui-gpu-check) | Probe GPU-offload availability and explain failures |
| [`quantui analytics build`](#quantui-analytics-build) | Build an HTML usage dashboard from `perf_log.jsonl` |
+| [`quantui submit`](#quantui-submit) | Submit `.xyz` or request-JSON files as SLURM batch jobs |
+| [`quantui install-launcher`](#quantui-install-launcher) | Write the `quantui-batch` launcher for submitting from a login node |
---
@@ -340,6 +343,53 @@ successfully; only the auto-open is best-effort.
---
+## `quantui submit`
+
+Submit calculations to the SLURM batch backend without the app. Each input is
+an `.xyz` file (with `--calc`) or a CalculationRequest JSON file; flags given
+on the command line override a JSON file's values.
+
+```bash
+# A frequency job from an XYZ file
+quantui submit water.xyz --calc frequency --method B3LYP --basis def2-SVP
+
+# Check the resource estimate without submitting
+quantui submit water.xyz --calc tddft --solvent Water --dry-run
+
+# Start only after another job succeeds
+quantui submit water.xyz --calc frequency --depends-on
+
+# Write the job folder (request.json + submit.slurm) but do not call sbatch
+quantui submit water.xyz --calc geometry_opt --prepare-only
+```
+
+Useful flags: `--charge`, `--mult`, `--solvent`, `--preopt`,
+`--option KEY=VALUE` (repeatable), `--cores`, `--memory-gb`, `--walltime`,
+`--email`, `--job-name`, `--partition`. `quantui submit --help` lists them all.
+An impossible charge/multiplicity, an unknown solvent, or a solvent on a calc
+type the batch worker runs gas-phase only (NMR, PES scan) is refused before
+anything is queued.
+
+---
+
+## `quantui install-launcher`
+
+Write `quantui-batch`, a standard-library Python launcher for submitting
+QuantUI jobs from a cluster login node over SSH. The launcher never starts the
+image or imports QuantUI on the login node; the calculation runs in the image
+on a compute node. Run this once per image, inside it, from an allocation:
+
+```bash
+apptainer exec /path/to/quantui.sif quantui install-launcher /shared/bin
+```
+
+Students then use `quantui-batch submit`, `status`, `results`, `log`,
+`rerun --more-memory`, `cancel` and more. Full guide (presets, `--from`
+chaining, `--queue-rest`, `check`):
+[apptainer/slurm/README.md](https://github.com/The-Schultz-Lab/QuantUI/blob/main/apptainer/slurm/README.md#submitting-from-a-terminal-quantui-batch).
+
+---
+
## Environment variables
| Variable | Effect |
diff --git a/docs/features.md b/docs/features.md
index 3fd9cb1..e30e009 100644
--- a/docs/features.md
+++ b/docs/features.md
@@ -16,6 +16,9 @@ local Python kernel.
a structure search by name, SMILES, InChI, CID, or CAS —
PubChem → NCI CACTUS → an offline
bundled-library fallback, so the search still works with no network.
+ Or upload a file (XYZ, MOL/SDF, MOL2, PDB, CIF, Gaussian input/output)
+ and edit the structure: set bond lengths, angles and
+ dihedrals, delete atoms, add hydrogens, change elements, freeze atoms.
@@ -37,10 +40,12 @@ local Python kernel.
Calculations
RHF, UHF, nine DFT functionals, MP2, CCSD, and CCSD(T) —
- with six calculation types: single point, geometry optimization,
- frequencies/thermochemistry, TD-DFT UV-Vis, NMR shielding,
- and 1D PES scans. PCM implicit solvation for single points,
- optimizations, frequencies and TD-DFT.
+ with eight calculation types: single point, geometry optimization,
+ transition-state search (Sella, with an automatic
+ frequency check), frequencies/thermochemistry, TD-DFT UV-Vis, NMR
+ shielding, 1D PES scans and Marcus reorganization energies. PCM
+ implicit solvation for single points, optimizations, frequencies
+ and TD-DFT.
@@ -49,9 +54,12 @@ local Python kernel.
Spectra & Analysis
IR spectrum (stick + Lorentzian-broadened), UV-Vis plot,
- orbital energy-level diagram with HOMO/LUMO isosurfaces,
- and 1H/13C NMR chemical shifts vs TMS.
- Side-by-side comparison table for multiple calculations.
+ 1H/13C NMR shifts vs TMS, point groups and an
+ orbital diagram with symmetry labels. Any orbital (α/β), an
+ orbital gallery in linked viewers, density, spin
+ density and ESP-mapped surfaces. Vibration viewer with displacement
+ arrows; thermochemistry at any T and P; 〈S²〉 for
+ open-shell results; side-by-side comparison tables.
@@ -64,7 +72,9 @@ local Python kernel.
orbital data (Molden), trajectories (multi-frame XYZ, ASE
.traj), cube files, spectra
as HTML, full result bundles as .zip,
- or any run as a standalone .py script.
+ or any run as a standalone .py script
+ — each one also downloads to your computer, even from a remote
+ Voilà/OnDemand session.
@@ -107,6 +117,19 @@ local Python kernel.
+
+
🗂️
+
Cluster Batch Jobs
+
+ quantui-batch submits QuantUI
+ calculations to SLURM from a cluster login node over SSH, without
+ starting the image there: presets, chaining from another job's
+ optimized geometry, reruns with more memory or time, and result
+ summaries. quantui submit does the
+ same wherever QuantUI is installed.
+
+
+
🖥️
Voilà App Mode
diff --git a/docs/index.md b/docs/index.md
index 5b0b185..7dde808 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -22,8 +22,9 @@ hide:
QuantUI puts
PySCF
and a guarded native-Windows
PyFock subset
behind an interactive Jupyter/Voilà UI. Run DFT, MP2, CCSD,
- CCSD(T), TD-DFT, NMR, geometry optimization, frequencies, and
- PES scans — visualize structures, orbitals, IR and UV-Vis
+ CCSD(T), TD-DFT, NMR, geometry optimization, transition-state
+ searches, frequencies, and PES scans — visualize structures,
+ orbitals, densities, IR and UV-Vis
spectra, all on your laptop with optional NVIDIA GPU offload via
gpu4pyscf.
@@ -34,7 +35,7 @@ hide:
Python 3.9–3.11
·
- 1500+ tests
+ 3700+ tests
·
MIT License
·
diff --git a/docs/installation.md b/docs/installation.md
index acf3d0b..00f734f 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -50,6 +50,7 @@ other methods and workflows, use WSL or the Apptainer container described in
| `ase` | ASE bridge for trajectory export and structure I/O |
| `app` | Voilà, JupyterLab, and notebook launcher dependencies |
| `xtb` | GFN-FF metal pre-optimization via xtb |
+| `ts` | Transition-state searches via [Sella](https://github.com/zadorlab/sella) (pulls in jax, about 380 MB) |
## Next steps
diff --git a/docs/methods.md b/docs/methods.md
index 3ce579e..00a3616 100644
--- a/docs/methods.md
+++ b/docs/methods.md
@@ -1,18 +1,20 @@
# Supported Methods
-Six calculation types over fourteen methods and nine basis sets, all dispatched
-through a single Calculate tab.
+Eight calculation types over fourteen methods and ten basis sets, all
+dispatched through a single Calculate tab.
## Calculation types
| Calculation type | Output |
| --- | --- |
| **Single Point** | Energy, HOMO–LUMO gap, Mulliken charges, dipole moment |
-| **Geometry Opt** | Optimized structure with step-by-step trajectory animation |
-| **Frequency** | Vibrational frequencies, ZPVE, IR intensities, thermochemistry (H/S/G at 298 K), animated normal modes |
+| **Geometry Opt** | Optimized structure with step-by-step trajectory animation; optional frozen atoms |
+| **Transition State** | Saddle point near the input geometry (Sella; `pip install "quantui[ts]"`), then a frequency check that says whether it is a transition state (one imaginary frequency), a minimum, or a higher-order saddle point |
+| **Frequency** | Vibrational frequencies, ZPVE, IR intensities, thermochemistry at any temperature and pressure, animated normal modes |
| **UV-Vis (TD-DFT)** | Excitation energies, oscillator strengths, UV-Vis spectrum plot |
| **NMR Shielding** | ^1^H and ^13^C chemical shifts vs TMS via GIAO |
| **PES Scan** | 1D bond/angle/dihedral scan; energy profile + per-step geometries |
+| **Reorganization Energy** | Marcus four-point internal reorganization energy λ = λ₁ + λ₂ for hole (cation) and/or electron (anion) transfer |
## Methods by family
@@ -27,7 +29,7 @@ through a single Calculate tab.
From fast iteration to higher accuracy:
-`STO-3G` → `3-21G` → `6-31G` → `6-31G*` → `6-31G**` → `cc-pVDZ` → `cc-pVTZ` → `def2-SVP` → `def2-TZVP`
+`STO-3G` → `3-21G` → `6-31G` → `6-31G*` → `6-31G**` → `cc-pVDZ` → `cc-pVTZ` → `def2-SVP` → `def2-TZVP` → `LANL2DZ`
!!! tip "Choosing a basis"
- **STO-3G** — fast iteration and classroom demos
diff --git a/pyproject.toml b/pyproject.toml
index 9f5413f..5964504 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "quantui"
-version = "0.9.0"
+version = "0.10.0"
description = "An open-source frontend for DFT and post-HF quantum chemistry with PySCF"
readme = "README.md"
requires-python = ">=3.9"
diff --git a/quantui/__init__.py b/quantui/__init__.py
index 53615d8..ef75a76 100644
--- a/quantui/__init__.py
+++ b/quantui/__init__.py
@@ -7,7 +7,7 @@
PySCF requires Linux/macOS/WSL. Windows users should use the Apptainer container.
"""
-__version__ = "0.9.0"
+__version__ = "0.10.0"
import logging
from typing import Any