Charge densities
The classes under the chden module handle the processing and plotting of charge densities. Note that there is no explicit dependence on any of the classes used in C2a, and therefore could be used standalone. However, it only supports orthorhombic cells.
- class conquest2a.chden.chden(hkl: ndarray[tuple[Any, ...], dtype[int64]], offset: float, ch1: str, ch2: str | None = None, mode: Literal['sum', 'diff'] | None = None)
Process charge density data
- CONQUEST supplies up to two chden .cube files:
chden_up/dn.cube for a spin polarised calculation
a single cube file, e.g. chden.cube for unpolarised calculations
This class uses ASE’s .cube file processor to get atoms and data. It combines chden up and dn if both arguments are supplied, to make a total charge density It also does up - dn to see the spin difference, if both arguments are supplied
- Parameters:
hkl (INT ARRAY) – The \(hkl\) slice of the crystal to plot charge densities in.
offset (
float) – The \(hkl\) direction defines a family of planes. Useoffsetto select which one (i.e. where in the unit cell).ch1 (
str) – Path to a charge density (.cube) file.ch2 (
str | None, optional) – Path to another charge density (.cube) file, defaults toNone.mode (
Literal["sum", "diff"] | None, optional) – If two charge densities are supplied, whether to sum the data or find the difference, defaults toNone
- Raises:
ValueError – Cannot provide a mode if only one file is specified.
ValueError – If all Miller indices are 0: cannot slice through the origin
- extract_slice(n_points: int = 1000, interp_order: int = 5) tuple[Any, ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]
Sample the charge density on the \([hkl]\) plane at fractional
offset.For each point on a 2D \((t_1, t_2)\) grid centred on the plane origin:
- Compute its Cartesian position:
\(p = \text{origin} + t_1 v_1 + t_2 v_2\)
Convert to fractional coordinates:
s = p @ inv(cell)Wrap into the unit cell to enforce periodic boundaries.
Map fractional -> voxel index and interpolate via
scipy.ndimage.map_coordinates.
- Parameters:
n_points (
int, optional) – Number of points to sample on the slice, defaults to 1000interp_order (
int, optional) – The polynomial degree for interpolation, defaults to 5
- Returns:
A tuple containing:
density (REAL ARRAY) – Charge density in \(e/a_0^3\), shape
(n_points, n_points)v1 (REAL ARRAY) – First unit vector spanning the \([hkl]\) plane
v2 (REAL ARRAY) – Second unit vector spanning the \([hkl]\) plane
t1 (REAL ARRAY) – Scalar grid along \(v_1\)
t2 (REAL ARRAY) – Scalar grid along \(v_2\)
origin (
float) – Cartesian slice origin in Bohr
- inplane_basis() tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]
Return two orthonormal Cartesian vectors \((v_1, v_2)\) spanning the \([hkl]\) plane and the unit plane-normal \(\hat{n}\).
1. The plane normal in Cartesian space is \(n = ha^* + kb^* + lc^*\) where \(a^*, b^*, c^*\) are the reciprocal lattice vectors (rows of inv(cell)^T). 2. Two fractional-space null vectors of \([hkl]\) are found via SVD. 3. Those are converted to Cartesian, then Gram-Schmidt orthonormalised so the axes are perpendicular in real-space.
- plane_origin() Any
Return a Cartesian point lying on the plane \(ha + kb + lc =\)
offset.offsetis a dimensionless fractional intercept (0-1 spans one interplanar period). Pick the simplest fractional coordinate satisfying the plane equation.- Returns:
Origin of the slice.
- Return type:
- project_atoms(v1: ndarray[tuple[Any, ...], dtype[float64]], v2: ndarray[tuple[Any, ...], dtype[float64]], n_hat: ndarray[tuple[Any, ...], dtype[float64]], origin: ndarray[tuple[Any, ...], dtype[float64]], thickness: float = 0.5) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], list[str]]
Project atoms within
thicknessof the slice plane onto \((v_1, v_2)\) axes.- Parameters:
v1 (REAL ARRAY) – First unit vector spanning the \([hkl]\) plane
v2 (REAL ARRAY) – Second unit vector spanning the \([hkl]\) plane
n_hat (REAL ARRAY) – Unit vector defining the slice
origin (REAL ARRAY) – The origin of the slice
thickness (
float, optional) – The Cartesian distance perpendicular to the plane to consider atoms as lying on the slice, defaults to 0.5 Bohr.
- Returns:
A tuple containing:
t1_proj (REAL ARRAY) – Positions of label along \(v_1\)
t2_proj (REAL ARRAY) – Positions of label along \(v_2\)
syms (
list[str]) – List of atom labels
- class conquest2a.chden.chden_plot(chden_instance: chden, show_atoms: bool = False, extension: str = 'png')
Helper class to analyse and plot charge densities.
- Parameters:
- plot_slice(density: ndarray[tuple[Any, ...], dtype[float64]], t1: ndarray[tuple[Any, ...], dtype[float64]], t2: ndarray[tuple[Any, ...], dtype[float64]], v1: ndarray[tuple[Any, ...], dtype[float64]], v2: ndarray[tuple[Any, ...], dtype[float64]], atom_data: tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], list[str]] | None = None, cmap: str = 'viridis', log_scale: bool = False, vmin: float | None = 0.0, vmax: float | None = None, interpolation: str = 'lanczos', output: str | None = None) None
Function to create the actual plot and figure instance.
- Parameters:
density (REAL ARRAY) – Charge density
t1 (REAL ARRAY) – Scalar grid along \(v_1\)
t2 (REAL ARRAY) – Scalar grid along \(v_2\)
v1 (REAL ARRAY) – First unit vector spanning the \([hkl]\) plane
v2 (REAL ARRAY) – Second unit vector spanning the \([hkl]\) plane
atom_data (
tuple[REAL_ARRAY, REAL_ARRAY, list[str]] | None, optional) – Data for atom labels, seechden.project_atoms(), defaults to Nonelog_scale (
bool, optional) – Whether to plot the charge density on a base-10 logarithmic scale - useful for revealing details without colour clipping, defaults to Falsevmin (
float | None, optional) – Minimum value to set the colour scale at, defaults to 0.0vmax (
float | None, optional) – Maximum value to set the colour scale at, defaults to Noneinterpolation (
str, optional) – Interpolation type, see https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html, defaults to “lanczos”output (
str | None, optional) – Filename to save as. Will save with a useful name if not provided, defaults to None
- run(filename: str | None, vmin: float | None = 0.0, vmax: float | None = None, thickness: float = 0.5, log_scale: bool = False, cmap: str = 'viridis', interpolation: str = 'lanczos') None
Runs the full sequence of steps:
Fetches charge density files
Extracts and analyses data
Plots data and save
- Parameters:
filename (
str | None, optional :param vmin: Minimum value to set the colour scale at, defaults to 0.0) – Filename to save as. Will save with a useful name if not provided, defaults to Nonevmax (
float | None, optional) – Maximum value to set the colour scale at, defaults to Noneinterpolation (
str, optional) – Interpolation type, see https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html, defaults to “lanczos”thickness (
float, optional) – The Cartesian distance perpendicular to the plane to consider atoms as lying on the slice, defaults to 0.5 Bohr.log_scale (
bool, optional) – Whether to plot the charge density on a base-10 logarithmic scale - useful for revealing details without colour clipping, defaults to Falsecmap (
str, optional) – Colour map to use, see https://matplotlib.org/stable/api/_as_gen/matplotlib.colors.Colormap.html#matplotlib.colors.Colormap, defaults to “viridis”