From 69a1028725ab49cde6e008fe1912d3df58a7a273 Mon Sep 17 00:00:00 2001 From: Nick Papior Date: Wed, 14 Feb 2024 09:42:04 +0100 Subject: [PATCH] fixed documentaion for ufuncs and lattice Signed-off-by: Nick Papior --- docs/api/typing.rst | 3 ++ src/sisl/_core/_ufuncs_atom.py | 2 +- src/sisl/_core/_ufuncs_geometry.py | 55 ++++++++++---------- src/sisl/_core/_ufuncs_grid.py | 2 +- src/sisl/_core/_ufuncs_lattice.py | 4 +- src/sisl/_core/_ufuncs_sparse_geometry.py | 16 +++--- src/sisl/_core/lattice.py | 61 ++++++++++++++--------- src/sisl/_ufuncs.py | 8 ++- src/sisl/typing/_common.py | 7 +++ 9 files changed, 90 insertions(+), 68 deletions(-) diff --git a/docs/api/typing.rst b/docs/api/typing.rst index 48003f6ab0..98eb62923d 100644 --- a/docs/api/typing.rst +++ b/docs/api/typing.rst @@ -15,6 +15,9 @@ The typing types is shown below: AtomsArgument AtomsLike + Axis + Axies + Axes Coord CoordOrScalar FuncType diff --git a/src/sisl/_core/_ufuncs_atom.py b/src/sisl/_core/_ufuncs_atom.py index 3f1496d09c..8cbe4fb696 100644 --- a/src/sisl/_core/_ufuncs_atom.py +++ b/src/sisl/_core/_ufuncs_atom.py @@ -208,7 +208,7 @@ def remove(atom: Atom, orbitals: IndexArgument) -> Atom: See Also -------- - sub : retain a selected set of orbitals + Atom.sub : retain a selected set of orbitals """ orbs = np.delete(_a.arangei(atom.no), orbitals) return atom.sub(orbs) diff --git a/src/sisl/_core/_ufuncs_geometry.py b/src/sisl/_core/_ufuncs_geometry.py index 71694b30e0..fb24f4b08a 100644 --- a/src/sisl/_core/_ufuncs_geometry.py +++ b/src/sisl/_core/_ufuncs_geometry.py @@ -58,7 +58,8 @@ def write(geometry: Geometry, sile: SileLike, *args, **kwargs) -> None: See Also -------- - read : reads a `Geometry` from a given `Sile`/file + Geometry.read : reads a `Geometry` from a given `Sile`/file + write : generic sisl function dispatcher """ # This only works because, they *must* # have been imported previously @@ -634,10 +635,10 @@ def insert(geometry: Geometry, atom: AtomsArgument, other: GeometryLike) -> Geom See Also -------- - add : add geometries - append : appending geometries - prepend : prending geometries - attach : attach a geometry + Geometry.add : add geometries + Geometry.append : appending geometries + Geometry.prepend : prending geometries + Geometry.attach : attach a geometry """ atom = geometry._sanitize_atoms(atom) if atom.size > 1: @@ -691,8 +692,8 @@ def tile(geometry: Geometry, reps: int, axis: int) -> Geometry: See Also -------- - repeat : equivalent but different ordering of final structure - untile : opposite method of this + Geometry.repeat : equivalent but different ordering of final structure + Geometry.untile : opposite method of this """ if reps < 1: raise ValueError( @@ -769,8 +770,8 @@ def untile( See Also -------- - tile : opposite method of this - repeat : equivalent geometry as `tile` but different ordering of final structure + Geometry.tile : opposite method of this + Geometry.repeat : equivalent geometry as `tile` but different ordering of final structure """ if geometry.na % reps != 0: raise ValueError( @@ -848,8 +849,8 @@ def repeat(geometry: Geometry, reps: int, axis: int) -> Geometry: See Also -------- - tile : equivalent geometry as `repeat` but different ordering of final structure - unrepeat : opposite method of this + Geometry.tile : equivalent geometry as `repeat` but different ordering of final structure + Geometry.unrepeat : opposite method of this """ if reps < 1: raise ValueError( @@ -886,7 +887,7 @@ def unrepeat(geometry: Geometry, reps: int, axis: int, *args, **kwargs) -> Geome See Also -------- - repeat : opposite method of this + Geometry.repeat : opposite method of this """ atoms = np.arange(geometry.na).reshape(-1, reps).T.ravel() return geometry.sub(atoms).untile(reps, axis, *args, **kwargs) @@ -946,7 +947,7 @@ def sub(geometry: Geometry, atoms: AtomsArgument) -> Geometry: See Also -------- Lattice.fit : update the supercell according to a reference supercell - remove : the negative of this routine, i.e. remove a subset of atoms + Geometry.remove : the negative of this routine, i.e. remove a subset of atoms """ atoms = geometry.sc2uc(atoms) return geometry.__class__( @@ -971,7 +972,7 @@ def remove(geometry: Geometry, atoms: AtomsArgument) -> Geometry: See Also -------- - sub : the negative of this routine, i.e. retain a subset of atoms + Geometry.sub : the negative of this routine, i.e. retain a subset of atoms """ atoms = geometry.sc2uc(atoms) if atoms.size == 0: @@ -1042,7 +1043,7 @@ def rotate( See Also -------- Quaternion : class to rotate - Lattice.rotate : rotation passed to the contained supercell + Lattice.rotate : rotation for a Lattice object """ if origin is None: origin = [0.0, 0.0, 0.0] @@ -1280,10 +1281,10 @@ def append( See Also -------- - add : add geometries - prepend : prending geometries - attach : attach a geometry - insert : insert a geometry + Geometry.add : add geometries + Geometry.prepend : prending geometries + Geometry.attach : attach a geometry + Geometry.insert : insert a geometry """ if isinstance(other, Lattice): # Only extend the supercell. @@ -1368,10 +1369,10 @@ def prepend( See Also -------- - add : add geometries - append : appending geometries - attach : attach a geometry - insert : insert a geometry + Geometry.add : add geometries + Geometry.append : appending geometries + Geometry.attach : attach a geometry + Geometry.insert : insert a geometry """ if isinstance(other, Lattice): # Only extend the supercell. @@ -1436,10 +1437,10 @@ def add( See Also -------- - append : appending geometries - prepend : prending geometries - attach : attach a geometry - insert : insert a geometry + Geometry.append : appending geometries + Geometry.prepend : prending geometries + Geometry.attach : attach a geometry + Geometry.insert : insert a geometry Examples -------- diff --git a/src/sisl/_core/_ufuncs_grid.py b/src/sisl/_core/_ufuncs_grid.py index 016e8f9a3f..18eeb90c1d 100644 --- a/src/sisl/_core/_ufuncs_grid.py +++ b/src/sisl/_core/_ufuncs_grid.py @@ -47,7 +47,7 @@ def write(grid: Grid, sile: SileLike, *args, **kwargs) -> None: See Also -------- - read : reads a `Grid` from a given `Sile`/file + Grid.read : reads a `Grid` from a given `Sile`/file """ # this only works because, they *must* # have been imported previously diff --git a/src/sisl/_core/_ufuncs_lattice.py b/src/sisl/_core/_ufuncs_lattice.py index 7c7599e6ef..6baec544d0 100644 --- a/src/sisl/_core/_ufuncs_lattice.py +++ b/src/sisl/_core/_ufuncs_lattice.py @@ -69,7 +69,7 @@ def write(lattice: Lattice, sile: SileLike, *args, **kwargs) -> None: See Also -------- - read : reads a `Lattice` from a given `Sile`/file + Lattice.read : reads a `Lattice` from a given `Sile`/file """ # This only works because, they *must* # have been imported previously @@ -327,7 +327,7 @@ def untile(lattice: Lattice, reps: int, axis: int) -> Lattice: See Also -------- - tile : opposite of this method + Lattice.tile : opposite of this method """ cell = np.copy(lattice.cell) cell[axis] /= reps diff --git a/src/sisl/_core/_ufuncs_sparse_geometry.py b/src/sisl/_core/_ufuncs_sparse_geometry.py index 2d28c5ef54..e053526667 100644 --- a/src/sisl/_core/_ufuncs_sparse_geometry.py +++ b/src/sisl/_core/_ufuncs_sparse_geometry.py @@ -84,8 +84,8 @@ def tile(SA: SparseAtom, reps: int, axis: int) -> SparseAtom: See Also -------- - repeat: a different ordering of the final geometry - untile : opposite of this method + SparseAtom.repeat: a different ordering of the final geometry + SparseAtom.untile : opposite of this method Geometry.tile: the same ordering as the final geometry Geometry.repeat: a different ordering of the final geometry """ @@ -171,7 +171,7 @@ def repeat(SA: SparseAtom, reps: int, axis: int) -> SparseAtom: -------- Geometry.repeat: the same ordering as the final geometry Geometry.tile: a different ordering of the final geometry - tile: a different ordering of the final geometry + SparseAtom.tile: a different ordering of the final geometry """ # Create the new sparse object g = SA.geometry.repeat(reps, axis) @@ -260,8 +260,8 @@ def tile(SO: SparseOrbital, reps: int, axis: int) -> SparseOrbital: See Also -------- - repeat: a different ordering of the final geometry - untile : opposite of this method + SparseOrbital.repeat: a different ordering of the final geometry + SparseOrbital.untile : opposite of this method Geometry.tile: the same ordering as the final geometry Geometry.repeat: a different ordering of the final geometry """ @@ -346,7 +346,7 @@ def repeat(SO: SparseOrbital, reps: int, axis: int) -> SparseOrbital: -------- Geometry.repeat: the same ordering as the final geometry Geometry.tile: a different ordering of the final geometry - tile: a different ordering of the final geometry + SparseOrbital.tile: a different ordering of the final geometry """ # Create the new sparse object g = SO.geometry.repeat(reps, axis) @@ -460,7 +460,7 @@ def sub(SA: SparseAtom, atoms: AtomsArgument) -> SparseAtom: -------- Geometry.remove : the negative of `Geometry.sub` Geometry.sub : equivalent to the resulting `Geometry` from this routine - remove : the negative of `sub`, i.e. remove a subset of atoms + SparseAtom.remove : the negative of `sub`, i.e. remove a subset of atoms """ atoms = SA.sc2uc(atoms) geom = SA.geometry.sub(atoms) @@ -501,7 +501,7 @@ def sub(SO: SparseOrbital, atoms: AtomsArgument) -> SparseOrbital: -------- Geometry.remove : the negative of `Geometry.sub` Geometry.sub : equivalent to the resulting `Geometry` from this routine - remove : the negative of `sub`, i.e. remove a subset of atoms + SparseOrbital.remove : the negative of `sub`, i.e. remove a subset of atoms """ atoms = SO.sc2uc(atoms) orbs = SO.a2o(atoms, all=True) diff --git a/src/sisl/_core/lattice.py b/src/sisl/_core/lattice.py index bc3c5185a5..a6df3cc6a1 100644 --- a/src/sisl/_core/lattice.py +++ b/src/sisl/_core/lattice.py @@ -25,6 +25,7 @@ from sisl._math_small import cross3, dot3 from sisl.messages import SislError, deprecate, deprecation, info, warn from sisl.shape.prism4 import Cuboid +from sisl.typing import Axes, Axies, Axis from sisl.utils.mathematics import fnorm from ._lattice import cell_invert, cell_reciprocal @@ -157,7 +158,7 @@ def volume(self) -> float: """Volume of cell""" return abs(dot3(self.cell[0], cross3(self.cell[1], self.cell[2]))) - def area(self, ax0, ax1) -> float: + def area(self, ax0: Axis, ax1: Axis) -> float: """Calculate the area spanned by the two axis `ax0` and `ax1`""" return (cross3(self.cell[ax0], self.cell[ax1]) ** 2).sum() ** 0.5 @@ -362,18 +363,24 @@ def _fill_sc(self, supercell_index): """Return a filled supercell index by filling in zeros where needed""" return self._fill(supercell_index, dtype=np.int32) - def set_nsc(self, nsc=None, a=None, b=None, c=None) -> None: + def set_nsc( + self, + nsc=None, + a: Optional[int] = None, + b: Optional[int] = None, + c: Optional[int] = None, + ) -> None: """Sets the number of supercells in the 3 different cell directions Parameters ---------- nsc : list of int, optional number of supercells in each direction - a : integer, optional + a : int, optional number of supercells in the first unit-cell vector direction - b : integer, optional + b : int, optional number of supercells in the second unit-cell vector direction - c : integer, optional + c : int, optional number of supercells in the third unit-cell vector direction """ if not nsc is None: @@ -453,7 +460,7 @@ def __iter__(self): """Iterate the supercells and the indices of the supercells""" yield from enumerate(self.sc_off) - def fit(self, xyz, axis=None, tol=0.05) -> Lattice: + def fit(self, xyz, axis: Optional[Axies] = None, tol: float = 0.05) -> Lattice: """Fit the supercell to `xyz` such that the unit-cell becomes periodic in the specified directions The fitted supercell tries to determine the unit-cell parameters by solving a set of linear equations @@ -469,7 +476,7 @@ def fit(self, xyz, axis=None, tol=0.05) -> Lattice: ---------- xyz : array_like ``shape(*, 3)`` the coordinates that we will wish to encompass and analyze. - axis : None or array_like + axis : if ``None`` equivalent to ``[0, 1, 2]``, else only the cell-vectors along the provided axis will be used tol : float @@ -480,9 +487,9 @@ def fit(self, xyz, axis=None, tol=0.05) -> Lattice: from .geometry import Geometry if isinstance(xyz, Geometry): - xyz = xyz.xyz[:, :] + xyz = xyz.xyz - cell = np.copy(self.cell[:, :]) + cell = np.copy(self.cell) # Get fractional coordinates to get the divisions in the current cell x = dot(xyz, self.icell.T) @@ -525,14 +532,16 @@ def fit(self, xyz, axis=None, tol=0.05) -> Lattice: return self.copy(cell) - def plane(self, ax1, ax2, origin=True) -> Tuple[ndarray, ndarray]: + def plane( + self, axis1: Axis, axis2: Axis, origin: bool = True + ) -> Tuple[ndarray, ndarray]: """Query point and plane-normal for the plane spanning `ax1` and `ax2` Parameters ---------- - ax1 : int + axis1 : int the first axis vector - ax2 : int + axis2 : int the second axis vector origin : bool, optional whether the plane intersects the origin or the opposite corner of the @@ -578,7 +587,7 @@ def plane(self, ax1, ax2, origin=True) -> Tuple[ndarray, ndarray]: Hence this may be used to further reduce certain computations. """ cell = self.cell - n = cross3(cell[ax1], cell[ax2]) + n = cross3(cell[axis1], cell[axis2]) # Normalize n /= dot3(n, n) ** 0.5 # Now we need to figure out if the normal vector @@ -638,7 +647,7 @@ def rcell(self) -> ndarray: """ return cell_reciprocal(self.cell) - def cell2length(self, length, axes=(0, 1, 2)) -> ndarray: + def cell2length(self, length, axes: Axies = (0, 1, 2)) -> ndarray: """Calculate cell vectors such that they each have length `length` Parameters @@ -682,7 +691,9 @@ def __add__(self, other) -> Lattice: __radd__ = __add__ - def add_vacuum(self, vacuum, axis, orthogonal_to_plane=False) -> Lattice: + def add_vacuum( + self, vacuum: float, axis: Axis, orthogonal_to_plane: bool = False + ) -> Lattice: """Returns a new object with vacuum along the `axis` lattice vector Parameters @@ -868,7 +879,7 @@ def tocell(cls, *args) -> Lattice: "Creating a unit-cell has to have 1, 3 or 6 arguments, please correct." ) - def is_orthogonal(self, tol=0.001) -> bool: + def is_orthogonal(self, tol: float = 0.001) -> bool: """ Returns true if the cell vectors are orthogonal. @@ -888,7 +899,7 @@ def is_orthogonal(self, tol=0.001) -> bool: i_s = dot3(cell[1], cell[2]) < tol and i_s return i_s - def is_cartesian(self, tol=0.001) -> bool: + def is_cartesian(self, tol: float = 0.001) -> bool: """ Checks if cell vectors a,b,c are multiples of the cartesian axis vectors (x, y, z) @@ -902,7 +913,7 @@ def is_cartesian(self, tol=0.001) -> bool: # Check if any of them are above the threshold tolerance return ~np.any(np.abs(off_diagonal) > tol) - def parallel(self, other, axis=(0, 1, 2)) -> bool: + def parallel(self, other, axis: Axies = (0, 1, 2)) -> bool: """Returns true if the cell vectors are parallel to `other` Parameters @@ -921,20 +932,20 @@ def parallel(self, other, axis=(0, 1, 2)) -> bool: return False return True - def angle(self, i, j, rad=False) -> float: + def angle(self, axis1: Axis, axis2: Axis, rad: bool = False) -> float: """The angle between two of the cell vectors Parameters ---------- - i : int + axis1 : int the first cell vector - j : int + axis2 : int the second cell vector rad : bool, optional whether the returned value is in radians """ - n = fnorm(self.cell[[i, j]]) - ang = math.acos(dot3(self.cell[i], self.cell[j]) / (n[0] * n[1])) + n = fnorm(self.cell[[axis1, axis2]]) + ang = math.acos(dot3(self.cell[axis1], self.cell[axis2]) / (n[0] * n[1])) if rad: return ang return math.degrees(ang) @@ -959,11 +970,13 @@ def read(sile, *args, **kwargs) -> Lattice: with get_sile(sile, mode="r") as fh: return fh.read_lattice(*args, **kwargs) - def equal(self, other, tol=1e-4) -> bool: + def equal(self, other, tol: float = 1e-4) -> bool: """Check whether two lattices are equivalent Parameters ---------- + other : Lattice + the other object to check whether the lattice is equivalent tol : float, optional tolerance value for the cell vectors and origin """ diff --git a/src/sisl/_ufuncs.py b/src/sisl/_ufuncs.py index 0b04620f59..997ef6dae9 100644 --- a/src/sisl/_ufuncs.py +++ b/src/sisl/_ufuncs.py @@ -64,9 +64,7 @@ def _append_doc_dispatch(method: FuncType, cls: type): method_registry = _registry[name] # Append to doc string - doc = ( - f"\n{cls.__name__}.{name}: equivalent to '{name}({cls.__name__.lower()}, ...)'." - ) + doc = f"\n{cls.__name__}.{name}: equivalent to ``{name}({cls.__name__.lower()}, ...)``." method_registry.__doc__ += doc @@ -92,9 +90,9 @@ def deco(method: FuncType): # create a new method that will be stored # as a place-holder for the dispatch methods. - def method_registry(*args, **kwargs): + def method_registry(obj, *args, **kwargs): raise SislError( - f"Calling '{name}' with a non-registered type, {type(args[0])} has not been registered." + f"Calling '{name}' with a non-registered type, {type(obj)} has not been registered." ) doc = dedent( diff --git a/src/sisl/typing/_common.py b/src/sisl/typing/_common.py index aaa0152ecd..f30cdbbb3b 100644 --- a/src/sisl/typing/_common.py +++ b/src/sisl/typing/_common.py @@ -22,6 +22,9 @@ __all__ = [ "AtomsArgument", "AtomsLike", + "Axes", + "Axies", + "Axis", "Coord", "CoordOrScalar", "FuncType", @@ -44,6 +47,10 @@ "Atoms", ] +Axis = int +Axes = Sequence[int] +Axies = Union[Axis, Axes] + Coord = Sequence[float] CoordOrScalar = Union[float, Coord]