Editor setup: VSCode#

You can use any editor with qc-rs, but Visual Studio Code (VSCode) is a good default: it is free, works the same on every OS, has excellent Python and Jupyter support, and — importantly for quantum chemistry — can edit and run code on a remote machine (a cluster) as if it were local. This chapter gets you a comfortable qc-rs workspace. It is optional; if you prefer another editor, skip to the Quickstart.

Install VSCode and the essentials#

Install VSCode from code.visualstudio.com, then add a few extensions (the Extensions panel is the square icon in the sidebar, or Ctrl/Cmd+Shift+X):

  • Python and Pylance (Microsoft) — language support, completion, and interpreter management;

  • Jupyter (Microsoft) — run notebooks and interactive cells;

  • Remote - SSH (Microsoft) — edit and run on a remote machine (see below);

  • optional: Live Preview (to preview this manual’s HTML), and rust-analyzer if you will touch the Rust core.

Working on a remote machine (cluster)#

Quantum-chemistry jobs often run on a shared server, not your laptop. With Remote - SSH you open the remote machine inside VSCode:

  1. Ctrl/Cmd+Shift+P“Remote-SSH: Connect to Host…” → pick (or add) your server, e.g. you@cluster.

  2. A new VSCode window opens, running on the server. File → Open Folder… and choose your qc-rs checkout.

  3. From here everything — the terminal, Python, the manual build — runs on the server; your laptop is just the screen and keyboard.

Tip

Remote-SSH also forwards ports automatically. That is how you view a locally-served web page (like the built manual) in your laptop’s browser — see “Preview the manual” below.

Point VSCode at the qc-rs environment#

VSCode needs to know which Python to use — the uv venv that has qc-rs installed. make setup already did this for you: it generated a git-ignored .vscode/ folder with four files. It is worth reading them, because they explain how VSCode knows to use your venv, rebuild the Rust core, and run with the right environment. (All of this comes from your profile — see Installation → what a profile looks like.)

settings.json — the workspace settings#

{
  "python.defaultInterpreterPath": "/home/you/local/myproj/.venv/bin/python",
  "python.envFile": "${workspaceFolder}/.vscode/my.env",
  "python.testing.pytestEnabled": true,
  "python.testing.pytestArgs": ["tests"],
  "python.terminal.activateEnvironment": true,
  "terminal.integrated.env.linux": { "UV_PROJECT": "/home/you/local/myproj" },
  "rust-analyzer.cargo.noDefaultFeatures": true,
  "rust-analyzer.cargo.features": ["intel-mkl-system", "xc-bundled", "pcm"],
  "rust-analyzer.cargo.extraEnv": { "MKLROOT": ".../mkl/2025.2", "MKL_THREADING_LAYER": "GNU" }
}
  • python.defaultInterpreterPath — points VSCode at your venv’s Python (the one with qc-rs), so Run and the terminal use it automatically.

  • python.envFile — loads environment variables from .vscode/my.env (below) whenever you run code.

  • python.testing.pytestEnabled / pytestArgs — turns on the Testing panel, running pytest tests — you can run and debug individual tests with a click.

  • python.terminal.activateEnvironment / terminal.integrated.env.linux.UV_PROJECT — auto-activate the venv in new integrated terminals and set UV_PROJECT, so uv commands act on the right project.

  • rust-analyzer.cargo.* — only relevant if you edit the Rust core: they make the Rust language server compile with the same features/env as your build, so its inline errors match reality.

my.env — runtime environment variables#

# GENERATED by mytools/setup/bootstrap.py — do not edit by hand.
MKL_THREADING_LAYER=GNU
MKL_INTERFACE_LAYER=LP64
LD_LIBRARY_PATH=.../mpi/2021.16/lib

These are the variables the extension needs at run time (the MKL threading/interface layers; the MPI library path). settings.json and the debug configs load this file, so pressing Run or F5 “just works” without you exporting anything.

tasks.json — the build task#

One shell task, labelled like “maturin develop (MKL, myproj)”. Its command sources your build environment (~/.cargo/env, the venv, the oneAPI vars.sh), sets RUSTFLAGS, and runs maturin develop with your feature list — i.e. exactly the build.pre / rustflags / maturin_args from your profile. You run it with Ctrl/Cmd+Shift+P → “Tasks: Run Build Task” instead of typing make install.

launch.json — run/debug configurations#

Two debugpy configurations, “Python: Current File (qc-rs)” and “Python: helloworld.py. Each one: runs in the integrated terminal with your interpreter, loads .vscode/my.env, sets justMyCode: false (so you can step into library code too), and — crucially — has preLaunchTask set to the build task above, so VSCode rebuilds qc-rs before every debug run. Press F5 and your edited Rust core is recompiled, then your script runs.

So after make setup, VSCode should already select the right interpreter. If it does not, Ctrl/Cmd+Shift+P“Python: Select Interpreter” and pick the one under your uv venv (its path is in settings.json). The chosen interpreter is shown in the status bar at the bottom.

Note

.vscode/ is git-ignored machine config generated by make setup — it is yours and is not committed. Re-run make setup if you ever need to regenerate it (e.g. after changing venv or backend).

Run and debug code#

  • Run a script. Open a .py file and press the ▷ Run button (top right), or F5 to run with the debugger.

  • Rebuild qc-rs from the editor. After changing the Rust core, Ctrl/Cmd+Shift+P“Tasks: Run Build Task” runs the maturin build task instead of typing make install.

  • Interactive / notebooks. Create a .ipynb notebook (or add # %% cell markers to a .py file) and run cells one at a time — ideal for exploring a calculation, plotting convergence, or viewing molecules. In a notebook, %matplotlib inline shows plots in the cell.

  • Debug. Click in the gutter to set a breakpoint, then F5. Execution pauses there so you can inspect variables — very useful when a script does not do what you expect.

Tip

A Python note An .ipynb notebook interleaves code cells and their output (numbers, tables, figures) in one document. It is the most beginner-friendly way to try qc-rs: run a cell, see the result, edit, run again.

Jupyter notebooks & helloworld.ipynb#

A notebook is the most enjoyable way to explore qc-rs: run one cell, see the result, tweak, run again. The repo ships one to play with — myworkspace/helloworld.ipynb — which runs a couple of real SCF calculations and streams the live, quantum-chemistry-style log.

Set up the notebook environment#

  1. Make sure ipykernel is in your venv (it lets VSCode start a kernel there): uv add --dev ipykernel --project "$UV_PROJECT", then rebuild qc-rs with make install (recall that uv add prunes the extension).

  2. Install the Jupyter extension (in the extensions list near the top of this chapter).

Pick the right kernel — so import qc works#

This is the one step people trip on. A notebook runs against a kernel (a Python), and it must be the uv venv Python that has qc-rs installed — otherwise the first cell fails with ModuleNotFoundError: No module named 'qc'. make setup already recorded that interpreter in .vscode/settings.json (python.defaultInterpreterPath), so VSCode usually offers it. To be sure: open myworkspace/helloworld.ipynb, click “Select Kernel” (top-right of the notebook) → “Python Environments…” → choose the interpreter under your uv project (e.g. …/myproj/.venv/bin/python, the same path shown in settings.json).

Tip

Kernel = VSCode interpreter = your uv Python The notebook kernel, the VSCode interpreter (python.defaultInterpreterPath), and the python in your uv project must all be the same venv. If they drift apart, import qc breaks. When in doubt, run import sys; print(sys.executable) in a cell — it should print your …/.venv/bin/python.

Play with it, and watch the log#

Open myworkspace/helloworld.ipynb and run the cells (▷ on a cell, or Run All). It builds a water checkpoint and runs an SCF, then a heavier example (a silver complex with ECP + RI + DFT + dispersion). The best part is the live log from run(log=...):

mychk = qc.chk.new(atom="O 0 0 0; H 0.757 0.586 0; H -0.757 0.586 0",
                   ao="def2-svp", unit="angstrom")
mychk = mychk.scf(ref="r").run(log="stdout")     # stream a quantum-chemistry-style transcript
── System ───────────────────────────────────────────────
  formula H2O
  charge 0   spin 1 (2S+1)   electrons 10 (5α / 5β)
  basis sets (spherical AOs):  AO def2-svp   24 functions
  nuclear repulsion: 9.1939131606 Eh
── plan ──────────────────────────────────────────────────
  2 steps (topological order)
    1  guess:sad        [auto]         ⇒ guess, density, mo
    2  scf:rhf          [user]  ← 1    ⇒ scf-ref, mo, density
── SCF rhf ────────────────────────────────────────────────
 cycle        E / Eh             dE       RMS[grad]  accel
     1       -75.465273843             -      2.56e-1      —
     …
     9       -75.961008958     -9.42e-11      2.37e-7  cdiis
✓ converged in 9 cycles

That transcript — the system summary, the auto-inserted sad guess (from Core concepts), the SCF cycle table with the DIIS accelerator, and the convergence check — is what real quantum-chemistry output looks like.

A few run(...) options#

.run() takes options for output and parallelism. The handful you will reach for first (the full set is in the Logging & output chapter):

option

what it does

log="stdout"

stream the live transcript to the cell (a file path or object also works)

log_style="modern" / "orca"

pick the visual style of the transcript

plot=True

draw the SCF convergence plot inline (needs matplotlib + %matplotlib inline)

nthread=8

use 8 CPU threads for this run

After a run you can replay or inspect the transcript without recomputing: mychk.log() prints it as text (also format="markdown"/"jsonl"), mychk.show() renders a snapshot of the current state and results, and mychk.run_events() returns the raw events as JSON.

Preview the manual#

To read this manual as you edit it, build the HTML and preview it:

make docs-html          # build docs/user/{en,ja}/_build/html  (needs jupyter-book)

Then either right-click docs/user/en/_build/html/index.html“Open with Live Preview”, or serve it and let VSCode forward the port:

python -m http.server 8000 --directory docs/user/en/_build/html

and open http://localhost:8000 in your browser (Remote-SSH forwards port 8000 automatically).

With your editor and notebook ready, run your first calculation in the Quickstart.