-
Notifications
You must be signed in to change notification settings - Fork 33
Fix cubic file unit detection for negative dimensions #290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
31ea02b
f8b183a
de49af3
2b95080
199d365
b582376
d341829
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ | |
| from sympy.functions.combinatorial.numbers import bell | ||
|
|
||
| from grid.basegrid import Grid, OneDGrid | ||
| from .utils import ANGSTROM_TO_BOHR | ||
|
|
||
|
|
||
| class _HyperRectangleGrid(Grid): | ||
|
|
@@ -701,7 +702,6 @@ def from_cube(cls, fname, weight="Trapezoid", return_data=False): | |
| - ``atcorenums``\: Pseudo-number of :math:`M` atoms in the molecule. | ||
| - ``atcoords``\: Cartesian coordinates of :math:`M` atoms in the molecule. | ||
| - ``data``\: the grid data stored in a flattened one-dimensional array. | ||
| - ``unit``\: the unit of the grid (either "angstrom" or "bohr"). | ||
|
|
||
| """ | ||
| fname = str(fname) | ||
|
|
@@ -715,44 +715,37 @@ def from_cube(cls, fname, weight="Trapezoid", return_data=False): | |
|
|
||
| def read_grid_line(line): | ||
| """Read a number and (x, y, z) coordinate from the cube file line.""" | ||
| words = line.split() | ||
| return ( | ||
| int(words[0]), | ||
| np.array([float(words[1]), float(words[2]), float(words[3])], float), | ||
| # all coordinates in a cube file are in atomic units | ||
| ) | ||
| npts, *vec = line.split() | ||
| return int(npts), np.asarray(vec, dtype=float) | ||
|
|
||
| # number of atoms and origin of the grid | ||
| natom, origin = read_grid_line(f.readline()) | ||
| # number of grid points in A direction and step vector A, and so on | ||
| shape0, axis0 = read_grid_line(f.readline()) | ||
| shape1, axis1 = read_grid_line(f.readline()) | ||
| shape2, axis2 = read_grid_line(f.readline()) | ||
| axes = np.array([axis0, axis1, axis2], dtype=float) | ||
| # if shape0, shape1, shape2 are negative, the units are in bohr | ||
| # otherwise in angstrom | ||
| axes = np.asarray([axis0, axis1, axis2], dtype=float) | ||
| # if shape0 is negative the units are in angstroms otherwise atomic units. | ||
| # this was verified with cube files generated from Gaussian on february 2026. | ||
| # https://gaussian.com/cubegen/ | ||
| unit = "bohr" if shape0 < 0 else "angstrom" | ||
| # print out the units detected for clarity | ||
| print(f"Cube file units detected: {unit}") | ||
| coordinates_in_angstrom = shape0 < 0 | ||
|
|
||
| # Convert negative shape values to positive | ||
| shape = np.array([abs(shape0), abs(shape1), abs(shape2)], dtype=int) | ||
| shape = np.abs(np.asarray([shape0, shape1, shape2], dtype=int)) | ||
| if coordinates_in_angstrom: | ||
| print(f"Cube file units detected: angstrom, converting to atomic units grid.") | ||
|
||
| axes *= ANGSTROM_TO_BOHR | ||
| origin *= ANGSTROM_TO_BOHR | ||
|
Comment on lines
+735
to
+738
|
||
|
|
||
| # if return_data=False, only grid is returned | ||
| if not return_data: | ||
| return cls(origin, axes, shape, weight) | ||
|
|
||
| # otherwise, return the atomic numbers, coordinates, and the grid data as well | ||
| def read_coordinate_line(line): | ||
| """Read atomic number and (x, y, z) coordinate from the cube file line.""" | ||
| words = line.split() | ||
| return ( | ||
| int(words[0]), | ||
| float(words[1]), | ||
| np.array([float(words[2]), float(words[3]), float(words[4])], float), | ||
| # all coordinates in a cube file are in atomic units | ||
| ) | ||
| """Read atomic number, charge, and (x, y, z) coordinates from cube file line.""" | ||
| atnum, charge, *coords = line.split() | ||
| return int(atnum), float(charge), np.asarray(coords, dtype=float) | ||
|
|
||
| numbers = np.zeros(natom, int) | ||
| # get the core charges | ||
|
|
@@ -765,6 +758,9 @@ def read_coordinate_line(line): | |
| if pseudo_numbers[i] == 0.0: | ||
| pseudo_numbers[i] = numbers[i] | ||
|
|
||
| if coordinates_in_angstrom: | ||
| coordinates *= ANGSTROM_TO_BOHR | ||
|
|
||
| # load data stored in the cube file | ||
| data = np.zeros(tuple(shape), float).ravel() | ||
| counter = 0 | ||
|
|
@@ -781,7 +777,6 @@ def read_coordinate_line(line): | |
| "atcorenums": pseudo_numbers, | ||
| "atcoords": coordinates, | ||
| "data": data, | ||
| "unit": unit, | ||
| } | ||
| return cls(origin, axes, shape, weight), cube_data | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |||
|
|
||||
| from grid.cubic import Tensor1DGrids, UniformGrid, _HyperRectangleGrid | ||||
| from grid.onedgrid import GaussLaguerre, MidPoint | ||||
| from grid.utils import ANGSTROM_TO_BOHR | ||||
|
||||
| from grid.utils import ANGSTROM_TO_BOHR |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,11 @@ | |
|
|
||
| import numpy as np | ||
| from scipy.special import sph_harm_y | ||
| from scipy.constants import physical_constants, angstrom | ||
|
|
||
| _BOHR_RADIUS_M = physical_constants["Bohr radius"][0] | ||
| BOHR_TO_ANGSTROM = _BOHR_RADIUS_M / angstrom | ||
| ANGSTROM_TO_BOHR = 1.0 / BOHR_TO_ANGSTROM | ||
|
Comment on lines
+26
to
+28
|
||
|
|
||
| _bragg = np.array( | ||
| [ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removal of the "unit" field from the cube_data dictionary is a breaking change for any code that depends on this field. This should be documented in the PR description or docstring as a breaking change. Consider whether it would be better to keep this field but always return "bohr" since the grid is always converted to atomic units internally.