Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cvve-0.1.0.tar.gz (38.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cvve-0.1.0-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

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

Hashes for cvve-0.1.0.tar.gz
Algorithm Hash digest
SHA256 544c489fc31da34729ad50d2e25fd7ad2552ba9a8d8ce8a54f64b757c131e782
MD5 f5180ccfafb612199ba83aaf151e722f
BLAKE2b-256 6c00a3919e00398a0acb1c4585ea0eac830083b5beab394f861e6b6634790dfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvve-0.1.0.tar.gz:

Publisher: publish.yml on kangmg/cube

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for cvve-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a217320cc161498c145c48e8e3d2a006e3a81d5ed1662f5e76adfc937660c47f
MD5 f94fb20a5066e8b7b3d741e38e0036b0
BLAKE2b-256 9099f73273e54de4067356a944d071ed854c5812ae1daf350abb6fe86d9ba2f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvve-0.1.0-py3-none-any.whl:

Publisher: publish.yml on kangmg/cube

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page