Read, write, and analyze cube, CHGCAR, and PARCHG volumetric grids with explicit units.
Project description
cvve
A Python toolkit for reading, writing, and analyzing volumetric grid data from
electronic-structure calculations — Gaussian/ORCA cube files and VASP
CHGCAR/PARCHG grids, unified under a single GridField model with explicit
units.
The package is distributed as cvve on PyPI. Both import cvve and
import cube expose the same public API, and both cvve and cube console
commands are installed.
Installation
uv add cvve # NumPy only
uv add "cvve[ase]" # + ASE adapter
uv add "cvve[pymatgen]" # + pymatgen adapter
uv add "cvve[interop]" # + both
Development setup:
git clone https://github.com/kangmg/cube
cd cube
uv sync --extra test
uv run pytest
Reading volumetric files
read_grid_field is the main entry point. It infers the format from the
filename and returns a GridField.
import cvve as cube
# Gaussian / ORCA cube file
homo = cube.read_grid_field("HOMO.cube")
lumo = cube.read_grid_field("LUMO.cube")
print(homo.grid.shape) # (nx, ny, nz) e.g. (80, 80, 80)
print(homo.length_unit) # "bohr" or "angstrom"
print(homo.voxel_volume) # dV in length_unit^3
print(homo.integral()) # ∫ ψ dV
# VASP CHGCAR (total density)
field = cube.read_grid_field("CHGCAR")
# Spin-polarized: select a dataset
mag = cube.read_grid_field("CHGCAR_SPIN", format="chgcar", chgcar_dataset="magnetization")
Multi-dataset cube files (Gaussian DSET_IDS):
# first dataset by default; select by name or numeric id
field = cube.read_grid_field("multi.cube", cube_dataset="HOMO")
field = cube.read_grid_field("multi.cube", cube_dataset=44)
Computing delta-density
The most common workflow: normalize two orbitals, square them into densities, then take the difference.
import cvve as cube
homo = cube.read_grid_field("HOMO.cube", kind="orbital")
lumo = cube.read_grid_field("LUMO.cube", kind="orbital")
# normalize and convert to density
homo_n, _, _ = cube.normalize_orbital_field(homo)
lumo_n, _, _ = cube.normalize_orbital_field(lumo)
rho_homo = cube.density_from_orbital_field(homo_n)
rho_lumo = cube.density_from_orbital_field(lumo_n)
# ρ_HOMO − ρ_LUMO
delta = cube.delta_grid_field(rho_homo, rho_lumo)
Write the result back as a cube file, keeping the original header and atom block as a template:
doc = cube.read_grid_document("HOMO.cube", kind="orbital")
doc.write("delta_density.cube", delta)
Overlap and charge-transfer metrics
analyze_orbital_pair_fields normalizes, squares, and computes all overlap
metrics in one call:
import cvve as cube
homo = cube.read_grid_field("HOMO.cube", kind="orbital")
lumo = cube.read_grid_field("LUMO.cube", kind="orbital")
result = cube.analyze_orbital_pair_fields(homo, lumo, normalize=True)
print(f"S (signed MO overlap) = {result.overlaps['S_signed']:.6f}")
print(f"S (|ψ₁||ψ₂| overlap) = {result.overlaps['S_abs_psi']:.6f}")
print(f"D_overlap (density) = {result.overlaps['D_overlap']:.6f}")
print(f"charge-transfer index = {result.delta_checks['half_abs_integral']:.6f}")
result also carries the full field arrays (rho1, rho2, delta_rho, …)
so you can write any of them without recomputing.
CHGCAR delta-density (VASP)
import cvve as cube
doc1 = cube.read_grid_document("CHGCAR_ref", format="chgcar")
doc2 = cube.read_grid_document("CHGCAR_calc", format="chgcar")
delta = cube.delta_grid_field(doc1.field, doc2.field)
# write with doc1's structure block / augmentation text as template
doc1.write("delta.CHGCAR", delta)
The writer preserves non-selected datasets, augmentation text, Selective Dynamics flags, and POSCAR scale factors.
Unit conversion
GridField keeps length units explicit. Convert between bohr and Angstrom
with optional density rescaling:
# cube files read in bohr; convert geometry and rescale density values
field_ang = homo.to_length_unit("angstrom", value_scaling="density")
print(field_ang.length_unit) # "angstrom"
print(field_ang.grid.value_unit) # "electron/angstrom^3"
Optional adapters (ASE / pymatgen)
ASE and pymatgen are only imported when you call a conversion helper.
# → ASE Atoms
atoms = cube.read_grid_field("HOMO.cube").to_atoms()
# → pymatgen VolumetricData
from cube.adapters import grid_field_to_pymatgen_volumetric
vol = grid_field_to_pymatgen_volumetric(field)
CLI
Compare two MO cube files and write density / delta-density outputs:
uv run cvve HOMO.cube LUMO.cube
cube is installed as a command alias for existing scripts.
Output files written by default:
| File | Contents |
|---|---|
psi1_density.cub |
ρ₁ = ψ₁² |
psi2_density.cub |
ρ₂ = ψ₂² |
delta_density.cub |
ρ₁ − ρ₂ |
Common options:
--out-prefix PREFIX prefix all output filenames
--extra-header-lines N extra header lines after atom block (0, 1, or auto)
--delta-sign {1-2,2-1} sign of delta-density (default: 1-2)
--no-normalize skip orbital normalization
--write-z-profiles write z-integrated .dat profiles
--write-summary write scalar metrics to a .dat file
--write-overlap-cubes also write |ψ₁||ψ₂| and ρ₁ρ₂ cube files
CHGCAR comparison:
uv run cvve --input-format chgcar CHGCAR_ref CHGCAR_calc --chgcar-dataset total
Limitations
- GPU arrays (CuPy, etc.) are normalized to NumPy at the model boundary and are not preserved.
- CHGCAR augmentation blocks are preserved as opaque text; PAW occupancy contents are not interpreted.
- Noncollinear CHGCAR is covered by a synthetic fixture only; real VASP noncollinear output still needs validation.
- WAVECAR is out of scope; use CHGCAR/PARCHG-like real-space grids instead.
- Gaussian and ORCA support is cube-file based; log-file parsing is not part of this project.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cvve-0.1.0.tar.gz.
File metadata
- Download URL: cvve-0.1.0.tar.gz
- Upload date:
- Size: 38.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
544c489fc31da34729ad50d2e25fd7ad2552ba9a8d8ce8a54f64b757c131e782
|
|
| MD5 |
f5180ccfafb612199ba83aaf151e722f
|
|
| BLAKE2b-256 |
6c00a3919e00398a0acb1c4585ea0eac830083b5beab394f861e6b6634790dfa
|
Provenance
The following attestation bundles were made for cvve-0.1.0.tar.gz:
Publisher:
publish.yml on kangmg/cube
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cvve-0.1.0.tar.gz -
Subject digest:
544c489fc31da34729ad50d2e25fd7ad2552ba9a8d8ce8a54f64b757c131e782 - Sigstore transparency entry: 2116566193
- Sigstore integration time:
-
Permalink:
kangmg/cube@8764385f96fac121048cc7703ec07c2486d95e45 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/kangmg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8764385f96fac121048cc7703ec07c2486d95e45 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cvve-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cvve-0.1.0-py3-none-any.whl
- Upload date:
- Size: 33.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a217320cc161498c145c48e8e3d2a006e3a81d5ed1662f5e76adfc937660c47f
|
|
| MD5 |
f94fb20a5066e8b7b3d741e38e0036b0
|
|
| BLAKE2b-256 |
9099f73273e54de4067356a944d071ed854c5812ae1daf350abb6fe86d9ba2f0
|
Provenance
The following attestation bundles were made for cvve-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on kangmg/cube
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cvve-0.1.0-py3-none-any.whl -
Subject digest:
a217320cc161498c145c48e8e3d2a006e3a81d5ed1662f5e76adfc937660c47f - Sigstore transparency entry: 2116566276
- Sigstore integration time:
-
Permalink:
kangmg/cube@8764385f96fac121048cc7703ec07c2486d95e45 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/kangmg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8764385f96fac121048cc7703ec07c2486d95e45 -
Trigger Event:
push
-
Statement type: