2525from sympy .functions .combinatorial .numbers import bell
2626
2727from grid .basegrid import Grid , OneDGrid
28+ from .utils import ANGSTROM_TO_BOHR
2829
2930
3031class _HyperRectangleGrid (Grid ):
@@ -701,7 +702,6 @@ def from_cube(cls, fname, weight="Trapezoid", return_data=False):
701702 - ``atcorenums``\: Pseudo-number of :math:`M` atoms in the molecule.
702703 - ``atcoords``\: Cartesian coordinates of :math:`M` atoms in the molecule.
703704 - ``data``\: the grid data stored in a flattened one-dimensional array.
704- - ``unit``\: the unit of the grid (either "angstrom" or "bohr").
705705
706706 """
707707 fname = str (fname )
@@ -715,44 +715,37 @@ def from_cube(cls, fname, weight="Trapezoid", return_data=False):
715715
716716 def read_grid_line (line ):
717717 """Read a number and (x, y, z) coordinate from the cube file line."""
718- words = line .split ()
719- return (
720- int (words [0 ]),
721- np .array ([float (words [1 ]), float (words [2 ]), float (words [3 ])], float ),
722- # all coordinates in a cube file are in atomic units
723- )
718+ npts , * vec = line .split ()
719+ return int (npts ), np .asarray (vec , dtype = float )
724720
725721 # number of atoms and origin of the grid
726722 natom , origin = read_grid_line (f .readline ())
727723 # number of grid points in A direction and step vector A, and so on
728724 shape0 , axis0 = read_grid_line (f .readline ())
729725 shape1 , axis1 = read_grid_line (f .readline ())
730726 shape2 , axis2 = read_grid_line (f .readline ())
731- axes = np .array ([axis0 , axis1 , axis2 ], dtype = float )
732- # if shape0, shape1, shape2 are negative, the units are in bohr
733- # otherwise in angstrom
727+ axes = np .asarray ([axis0 , axis1 , axis2 ], dtype = float )
728+ # if shape0 is negative the units are in angstroms otherwise atomic units.
729+ # this was verified with cube files generated from Gaussian on february 2026.
734730 # https://gaussian.com/cubegen/
735- unit = "bohr" if shape0 < 0 else "angstrom"
736- # print out the units detected for clarity
737- print (f"Cube file units detected: { unit } " )
731+ coordinates_in_angstrom = shape0 < 0
738732
739733 # Convert negative shape values to positive
740- shape = np .array ([abs (shape0 ), abs (shape1 ), abs (shape2 )], dtype = int )
734+ shape = np .abs (np .asarray ([shape0 , shape1 , shape2 ], dtype = int ))
735+ if coordinates_in_angstrom :
736+ print (f"Cube file units detected: angstrom, converting to atomic units grid." )
737+ axes *= ANGSTROM_TO_BOHR
738+ origin *= ANGSTROM_TO_BOHR
741739
742740 # if return_data=False, only grid is returned
743741 if not return_data :
744742 return cls (origin , axes , shape , weight )
745743
746744 # otherwise, return the atomic numbers, coordinates, and the grid data as well
747745 def read_coordinate_line (line ):
748- """Read atomic number and (x, y, z) coordinate from the cube file line."""
749- words = line .split ()
750- return (
751- int (words [0 ]),
752- float (words [1 ]),
753- np .array ([float (words [2 ]), float (words [3 ]), float (words [4 ])], float ),
754- # all coordinates in a cube file are in atomic units
755- )
746+ """Read atomic number, charge, and (x, y, z) coordinates from cube file line."""
747+ atnum , charge , * coords = line .split ()
748+ return int (atnum ), float (charge ), np .asarray (coords , dtype = float )
756749
757750 numbers = np .zeros (natom , int )
758751 # get the core charges
@@ -765,6 +758,9 @@ def read_coordinate_line(line):
765758 if pseudo_numbers [i ] == 0.0 :
766759 pseudo_numbers [i ] = numbers [i ]
767760
761+ if coordinates_in_angstrom :
762+ coordinates *= ANGSTROM_TO_BOHR
763+
768764 # load data stored in the cube file
769765 data = np .zeros (tuple (shape ), float ).ravel ()
770766 counter = 0
@@ -781,7 +777,6 @@ def read_coordinate_line(line):
781777 "atcorenums" : pseudo_numbers ,
782778 "atcoords" : coordinates ,
783779 "data" : data ,
784- "unit" : unit ,
785780 }
786781 return cls (origin , axes , shape , weight ), cube_data
787782
0 commit comments