# Molecular properties (`qc.prop`)

A converged wavefunction is not the end — it is the starting point for **analysis**. What are the atomic
charges? Where are the bonds, and how strong? Is a ring aromatic? Where will an electrophile attack? qc-rs
answers these with a large, built-in **molecular-properties suite** — *Multiwfn-class* wavefunction analysis
you reach without ever leaving Python. This short page explains how the suite is organized; the following
chapters cover each family.

## The `qc.prop.<group>.<leaf>` namespace

Every property lives at **`qc.prop.<group>.<leaf>`**, organized into 14 thematic groups:

| group | what it covers |
|---|---|
| `chrg` | atomic charges (Mulliken, Löwdin, Hirshfeld, NPA, CM5, ADCH, MBIS, …) |
| `bond` | bond orders & valence (Mayer, Wiberg, IBSI, fuzzy, multicenter) |
| `mpol` | electric moments (dipole, quadrupole) and atomic polarizabilities |
| `qtaim` | QTAIM (Bader) topology, critical points, and basin integration |
| `elf` | ELF/LOL basins and domains |
| `arom` | aromaticity indices (HOMA, BIRD, FLU, PDI, MCI, …) |
| `cdft` | conceptual-DFT reactivity and Fukui functions |
| `orb` | orbital composition, localization, indices |
| `nbo` | NBO / IAO / IBO analysis |
| `spin` | spin density and ⟨S²⟩ |
| `esp` | electrostatic potential on a surface / at nuclei |
| `spec` | orbital DOS, HOMO–LUMO gap, band centers |
| `mesh` | real-space fields on a grid (NCI, IGM, cube export) |
| `geom` | geometric analysis (RDF, rotational constants, surface area) |

The next six chapters walk through the most-used families:
[charges & bond orders](charges-bond-orders.md), [QTAIM & ELF](qtaim-elf.md),
[weak interactions](weak-interactions.md), [aromaticity](aromaticity.md),
[conceptual-DFT reactivity](cdft-reactivity.md), and [spectra & DOS](spectra-dos.md).

## Two equivalent forms

Every property has a **functional** form and a **method** form — they are identical, so use whichever reads
better in your code:

```python
import qc
water = "O 0 0 0.117; H 0 0.757 -0.469; H 0 -0.757 -0.469"
m = qc.chk.new(atom=water, ao="cc-pvdz", unit="angstrom").scf(ref="r").run()

qc.prop.chrg.hirshfeld(m)     # functional form
m.prop.chrg.hirshfeld()       # method form — the same result
```

They return the *same* value (verified: both give the O charge −0.32191159).

## Lazy, cached, and eager bundles

Properties are **computed on demand and cached** by a content hash of the wavefunction — ask for the same
property twice and the second call is free; re-run an SCF that changes the density and the cache invalidates
automatically. You do not manage any of this.

When you know up front that you want a batch of properties, ask the SCF to compute them **eagerly** with
`scf(prop=...)`:

```python
m = qc.chk.new(atom=water, ao="cc-pvdz", unit="angstrom").scf(ref="r", prop=True).run()
# prop=True computes a standard bundle; prop=<preset name> or prop=[<refs>] select what to compute
```

## What you need first

Almost every property needs a **converged SCF** (a density and orbitals) — so the pattern is always
"`.scf(...).run()`, then ask for properties." A few grid-based analyses (QTAIM, ELF, the real-space fields)
are heavier than the charges; they are still one call, just slower. With that, let's start with the most
common question of all: [where is the charge?](charges-bond-orders.md)
