matscipy.utils

Functions

complete_basis(v1[, v2, normalise, nmax, tol])

Generate a complete (v1, v2, v3) orthogonal basis in 3D from v1 and an optional v2

find_condensed_repr(atoms[, precision])

Search for a condensed representation of atoms Equivalent to attempting to undo a supercell

find_condensed_repr_along_axis(atoms[, ...])

Search for a condensed representation of atoms about axis.

get_distance_from_polygon2D(test_points, ...)

Get shortest distance between a test point and a polygon defined by polygon_points

get_structure_types(structure[, ...])

Get the results of Common Neighbor Analysis and

line_intersect_2D(p1, p2, x1, x2)

Test if 2D finite line defined by points p1 & p2 intersects with the finite line defined by x1 & x2.

points_in_polygon2D(p, poly_points)

Test if points lies within the closed 2D polygon defined by poly_points Uses ray casting algorithm, as suggested by: https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon

radial_mask_from_polygon2D(test_points, ...)

Get a boolean mask of all test_points within a radius of any edge of the polygon defined by polygon_points

validate_cubic_cell(a[, symbol, axes, ...])

Provide uniform interface for generating rotated atoms objects through two main methods:

Classes

classproperty(method)

Decorator class to replace classmethod property decorators

class matscipy.utils.classproperty(method)

Bases: object

Decorator class to replace classmethod property decorators

__init__(method)
matscipy.utils.validate_cubic_cell(a, symbol='w', axes=None, crystalstructure=None, pbc=True)

Provide uniform interface for generating rotated atoms objects through two main methods:

For lattice constant + symbol + crystalstructure, build a valid cubic bulk rotated into the frame defined by axes For cubic bulk atoms object + crystalstructure, validate structure matches expected cubic bulk geometry, and rotate to frame defined by axes Also, if cubic atoms object is supplied, search for a more condensed representation than is provided by ase.build.cut

a: float or ase.atoms

EITHER lattice constant (in A), or the cubic bulk structure

symbol: str

Elemental symbol, passed to relevant crystalstructure generator when a is float

axes: np.array

Axes transform to apply to bulk cell

crystalstructure: str

Base Structure of bulk system, currently supported: fcc, bcc, diamond

pbc: list of bool

Periodic Boundary Conditions in x, y, z

matscipy.utils.find_condensed_repr(atoms, precision=2)

Search for a condensed representation of atoms Equivalent to attempting to undo a supercell

atoms: ase Atoms object

structure to condense

precision: int

Number of decimal places to use in determining whether scaled positions are equal

returns a condensed copy of atoms, if such a condensed representation is found. Else returns a copy of atoms

matscipy.utils.find_condensed_repr_along_axis(atoms, axis=-1, precision=2)

Search for a condensed representation of atoms about axis. Essentially an inverse to taking a supercell.

atoms: ase Atoms object

structure to condense

axis: int

axis about which to find a condensed repr axis=-1 essentially will invert a (1, 1, x) supercell

precision: int

Number of decimal places to use in determining whether scaled positions are equal

returns a condensed copy of atoms, if such a condensed representation is found. Else returns a copy of atoms

matscipy.utils.complete_basis(v1, v2=None, normalise=False, nmax=5, tol=1e-06)

Generate a complete (v1, v2, v3) orthogonal basis in 3D from v1 and an optional v2

(V1, V2, V3) is always right-handed.

v1: np.array

len(3) array giving primary axis

v2: np.array | None

len(3) array giving secondary axis If None, a search for a “sensible” secondary axis will occur, raising a RuntimeError if unsuccessful

(Searches for vectors perpendicular to v1 with small integer indices)

If v2 is given and is not orthogonal to v1, raises a warning

normalise: bool

return an float orthonormal basis, rather than integer orthogonal basis

nmax: int

Maximum integer index for v2 search

tol: float

Tolerance for checking orthogonality between v1 and v2

Returns:

V1, V2, V3 – Complete orthogonal basis, optionally normalised dtype of arrays is int with normalise=False, float with normalise=True

Return type:

np.arrays

matscipy.utils.get_structure_types(structure, diamond_structure=False)
Get the results of Common Neighbor Analysis and

Identify Diamond modifiers from Ovito (Requires Ovito python module)

Parameters:

structure (ase.atoms) – input structure

Returns:

per atom labels of the structure types structure_names (list of strings): names of the structure types colors (list of strings): colors of the structure types in hex format

Return type:

atom_labels (array of ints)

matscipy.utils.line_intersect_2D(p1, p2, x1, x2)

Test if 2D finite line defined by points p1 & p2 intersects with the finite line defined by x1 & x2. Essentially a Python conversion of the ray casting algorithm suggested in: https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon

Returns True if lines intersect (including if they are collinear)

p1, p2, x1, x2: np.array

2D points defining lines

matscipy.utils.points_in_polygon2D(p, poly_points)

Test if points lies within the closed 2D polygon defined by poly_points Uses ray casting algorithm, as suggested by: https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon

p: np.array

(n, 2) array of points to test

poly_points: np.array

Points defining the 2D polygon

Returns:

mask – Boolean mask. True for points inside the poylgon

Return type:

np.array

matscipy.utils.get_distance_from_polygon2D(test_points: array, polygon_points: array) array
Get shortest distance between a test point and a polygon defined by polygon_points

(i.e. the shortest distance between each point and the lines of the polygon)

Uses formula from https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points

test_points: np.array

2D Points to get distances for

polygon_points: np.array

Coordinates defining the points of the polygon

matscipy.utils.radial_mask_from_polygon2D(test_points: array, polygon_points: array, radius: float, inner: bool = True) array

Get a boolean mask of all test_points within a radius of any edge of the polygon defined by polygon_points

test_points: np.array

2D Points to get mask for

polygon_points: np.array

Coordinates defining the points of the polygon

radius: float

Radius to use as cutoff for mask

inner: bool

Whether test_points inside the polygon should always be masked as True, regardless of radius