soprano.utils#

utils.py

Contains package-wide useful routines that don’t fall under any specific category. Many of these handle common operations involving periodicity, conversions between different representations etc.

Functions

abc2cart(abc)

Transforms an axes and angles representation of lattice parameters into a Cartesian one

all_periodic(v, latt_cart, max_r[, pbc])

Find all the periodic equivalent vectors for a list of vectors and a given lattice falling within a given length.

average_quaternions(quats)

Average a list of quaternions.

cart2abc(cart)

Transforms a Cartesian representation of lattice parameters into an axes and angles one

clebsch_gordan(j, m, j1, m1, j2, m2)

Clebsch-Gordan cohefficients for given quantum numbers: j, m, j1, m1, j2, m2

compute_asymmetric_distmat(struct, points[, ...])

Given a symmetric structure, compute a distance matrix for the given fractional coordinate points which contains only the distances between their closest symmetry equivalent sites in the asymmetric unit cell.

customize_warnings()

get_bonding_distance(bond_graph, i, j[, nx])

Distance in bonds, returns -1 if the two are not connected

get_bonding_graph(bond_mat[, nx])

get_sklearn_clusters(points, method, params)

Cluster points using given method if found in sklearn.clusters module.

graph_specsort(L)

has_cif_labels(atoms)

Check if the atoms object has CIF labels Does this simply by comparing the labels with the element symbols.

hkl2d2_matgen(abc)

Generate a matrix that turns hkl indices into inverse crystal plane distances for a given lattice in ABC form

import_module(mpath)

inspect_args(f)

inv_plane_dist(hkl, hkl2d2)

Calculate inverse planar distance for a given set of Miller indices h, k, l.

is_string(s)

Checks whether s is a string, with Python 2 and 3 compatibility

list_distance(l1, l2)

Return an integer distance between two lists (number of differing elements)

max_distance_in_cell(cell)

Maximum distance between two points achievable inside a single unit cell.

merge_concatenate(T)

Merge a list of arrays by concatenating them

merge_first(T)

Merge a list of arrays by taking the first

merge_mean(T)

Merge a list of arrays by taking the mean

merge_sites(atoms, indices[, ...])

Merge sites in a structure.

merge_sum(T)

Merge a list of arrays by summing them

minimum_periodic(v, latt_cart[, ...])

Find the shortest periodic equivalent vector for a list of vectors and a given lattice.

minimum_supcell(max_r[, latt_cart, ...])

Generate the bounds for a supercell containing a sphere of given radius, knowing the unit cell.

periodic_bridson(cell, rmin[, max_attempts, ...])

Periodic version of the Bridson algorithm for generation of Poisson sphere distributions of points.

progbar(i, i_max[, bar_len, spinner, spin_rate])

A textual progress bar for the command line

recursive_mol_label(site_i, mol_indices, ...)

Creates a string for a given atom by traversing the molecular network starting with it.

rep_alg(v[, iters, attempts, step, simtol])

Repulsion algorithm, begins with a series of vectors v, finds a new one that is as far as possible, angle-wise, from all of them.

replace_folder(path, new_folder)

Replace the folder of the given path with a new one

safe_communicate(subproc[, stdin])

Executes a Popen.communicate and returns output in a way that is compatible with Python 2 & 3 keeping input and output as strings (since Python 3 requires bytes objects otherwise)

safe_input(question)

Ask for user input with Python 2 and 3 compatibility

seedname(path)

Get the filename (with no extension) from a full path

silence_stdio([silence_stdout, silence_stderr])

Useful stdout/err silencer

supcell_gridgen(latt_cart, shape)

Generate a full linearized grid for a supercell with r_bounds and a base unit cell in Cartesian form.

swing_twist_decomp(quat, axis)

Perform a Swing*Twist decomposition of a Quaternion.

wigner_3j(j1, m1, j2, m2, j3, m3)

Wigner 3j symbols for given quantum numbers:

soprano.utils.abc2cart(abc)[source]#

Transforms an axes and angles representation of lattice parameters into a Cartesian one

soprano.utils.all_periodic(v, latt_cart, max_r, pbc=[True, True, True])[source]#

Find all the periodic equivalent vectors for a list of vectors and a given lattice falling within a given length.

Args:
v (np.ndarray): list of 3-vectors representing points or vectors to
produce periodic versions of
latt_cart (np.ndarray): unit cell in cartesian form
max_r (float): maximum length of periodic copies of vectors
pbc ([bool, bool, bool]): periodic boundary conditions - if
a boundary is not periodic the
range returned will always be zero
in that dimension
Returns:
v_period (np.ndarray): array with the same shape as v, containing the
vectors in periodic reduced form
v_index (np.ndarray): indices (referring to the original array v) of
the array of which the corresponding element of
v_period is a copy
v_cells (np.ndarray): array of triples of ints, corresponding to the
cells from which the various periodic copies of
the vectors were taken. For an unchanged vector
will be all [0,0,0]
soprano.utils.average_quaternions(quats)[source]#

Average a list of quaternions. Following: christophhagen/averaging-quaternions

Returns a normalized quaternion.

Parameters:

quats (List[Quaternion])

Return type:

Quaternion

soprano.utils.cart2abc(cart)[source]#

Transforms a Cartesian representation of lattice parameters into an axes and angles one

soprano.utils.clebsch_gordan(j, m, j1, m1, j2, m2)[source]#

Clebsch-Gordan cohefficients for given quantum numbers: j, m, j1, m1, j2, m2

The numbers passed can be arrays (just make sure they’re the same size).

soprano.utils.compute_asymmetric_distmat(struct, points, linearized=True, return_images=False, images_centre=0, symprec=1e-05, spg=None)[source]#

Given a symmetric structure, compute a distance matrix for the given fractional coordinate points which contains only the distances between their closest symmetry equivalent sites in the asymmetric unit cell.

Distances are computed in fractional coordinates space and are not real distances. They do not necessarily map to real space distances either. Their purpose is merely to group points together by removing the effects of symmetry operations.

Parameters:
struct (ase.Atoms): the structure from which to extract the symmetry
operations
points (np.ndarray): list of points, in fractional coordinates, to
compute the distance matrix for
linearized (bool): if True, returns only the linearised upper
triangle of the distance matrix, in the format
accepted by scipy.cluster.hierarchy.linkage.
Default is True
return_images (bool): if True, return also a list of the closest
images for each point. The closest
symmetric image to images_centre is chosen.
images_centre (int or np.ndarray): centre to use to compute closest
images. If an integer, uses the
given point of that index. If a
vector, uses the given coordinates.
Should not be a high symmetry point.
Returns:
distmat (np.ndarray): distance matrix for points
images (np.ndarray): closest point images (only if return_images is
True)
soprano.utils.get_bonding_distance(bond_graph, i, j, nx=None)[source]#

Distance in bonds, returns -1 if the two are not connected

soprano.utils.get_sklearn_clusters(points, method, params, sk=None)[source]#

Cluster points using given method if found in sklearn.clusters module. Use params as a dictionary of parameters passed to the method.

soprano.utils.has_cif_labels(atoms)[source]#

Check if the atoms object has CIF labels Does this simply by comparing the labels with the element symbols. If they’re all the same, then so special labels are present.

soprano.utils.hkl2d2_matgen(abc)[source]#

Generate a matrix that turns hkl indices into inverse crystal plane distances for a given lattice in ABC form

soprano.utils.inv_plane_dist(hkl, hkl2d2)[source]#

Calculate inverse planar distance for a given set of Miller indices h, k, l.

soprano.utils.is_string(s)[source]#

Checks whether s is a string, with Python 2 and 3 compatibility

soprano.utils.list_distance(l1, l2)[source]#

Return an integer distance between two lists (number of differing elements)

soprano.utils.max_distance_in_cell(cell)[source]#

Maximum distance between two points achievable inside a single unit cell. Relies on the fact that the isosurface for equal distance in cartesian space is an ellipsoid, meaning that the extreme has to be one of the 8 corners of the cube of side 1 in fractional space.

soprano.utils.merge_concatenate(T)[source]#

Merge a list of arrays by concatenating them

soprano.utils.merge_first(T)[source]#

Merge a list of arrays by taking the first

soprano.utils.merge_mean(T)[source]#

Merge a list of arrays by taking the mean

soprano.utils.merge_sites(atoms, indices, merging_strategies={}, keep_all=False)[source]#

Merge sites in a structure.

Parameters:
atoms (ase.Atoms): structure to merge sites in
indices (list): list of lists of indices of sites to merge
merging_strategies (dict): dictionary of merging strategies for
properties, e.g. {‘positions’: lambda x: x.mean(axis=0)}
if not specified, the default strategies will be used
(see DEFAULT_MERGING_STRATEGIES)
keep_all (bool): whether to keep all sites in the structure, default is False. If True, the
merged sites will have the same properties (determined by merging_strategies)
but will have a different index, so that they can be identified. If False, only one of the merged
sites will be kept, and the others will be removed from the Atoms object.
Returns:
atoms (ase.Atoms): structure with sites merged
Parameters:

atoms (Atoms)

soprano.utils.merge_sum(T)[source]#

Merge a list of arrays by summing them

soprano.utils.minimum_periodic(v, latt_cart, exclude_self=False, pbc=[True, True, True])[source]#

Find the shortest periodic equivalent vector for a list of vectors and a given lattice.

Args:
v (np.ndarray): list of 3-vectors representing points or vectors to
reduce to their closest periodic version
latt_cart (np.ndarray): unit cell in cartesian form
exclude_self (bool): if True, any vector that is equal to zero will be
excluded, and its closest non-zero periodic
version will be considered instead. Default is
False
pbc ([bool, bool, bool]): periodic boundary conditions - if
a boundary is not periodic the
range returned will always be zero
in that dimension
Returns:
v_period (np.ndarray): array with the same shape as v, containing the
vectors in periodic reduced form
v_cells (np.ndarray): array of triples of ints, corresponding to the
cells from which the various periodic copies of
the vectors were taken. For an unchanged vector
will be all [0,0,0]
soprano.utils.minimum_supcell(max_r, latt_cart=None, r_matrix=None, pbc=[True, True, True])[source]#

Generate the bounds for a supercell containing a sphere of given radius, knowing the unit cell.

Args:
max_r (float): radius of the sphere contained in the supercell
latt_cart (np.ndarray): unit cell in cartesian form
r_matrix (np.ndarray): matrix for the quadratic form returning
r^2 for this supercell.
Alternative to latt_cart, for a direct
space cell would be equal to
np.dot(latt_cart, latt_cart.T)
pbc ([bool, bool, bool]): periodic boundary conditions - if
a boundary is not periodic the
range returned will always be zero
in that dimension
Returns:
shape (tuple[int]): shape of the supercell to be built.
Raises:
ValueError: if some of the arguments are invalid
soprano.utils.periodic_bridson(cell, rmin, max_attempts=30, prepoints=None, prepoints_cuts=None, maxblock=1000)[source]#

Periodic version of the Bridson algorithm for generation of Poisson sphere distributions of points. This returns a generator.

Args:
cell (np.ndarray): periodic cell in which to create the points.
rmin (float): minimum distance between each generated point.
max_attempts (int): maximum number of candidate neighbours generated
for each point.
prepoints (np.ndarray or list): pre-existing points to avoid during
generation. These must be in
fractional coordinates.
prepoints_cuts (np.ndarray or list): custom cutoffs for each prepoint.
If not included defaults to rmin.
maxblock (int): maximum size of a grid block to be processed in a
single function (used to avoid excess memory use)
Returns:
bridsonGen (generator): an iterator producing Poisson-sphere like
distributed points in cell until space runs
out or enough attempts fail.
soprano.utils.progbar(i, i_max, bar_len=20, spinner=True, spin_rate=3.0)[source]#

A textual progress bar for the command line

Args:
i (int): current progress index
max_i (int): final progress index
bar_len (Optional[int]): length in characters of the bar (no brackets)
spinner (Optional[bool]): show a spinner at the end
spin_rate (Optional[float]): spinner rotation speed (turns per full
progress)
Returns:
bar (str): a progress bar formatted as requested
soprano.utils.recursive_mol_label(site_i, mol_indices, bonds, elems)[source]#

Creates a string for a given atom by traversing the molecular network starting with it.

Parameters:
site_i (int): index of the atom for which the string must be
calculated
mol_indices ([int]): indices of all atoms belonging to the molecule
bonds (dict): dictionary of bonds within the molecule, containing
the indices of atoms as keys and lists of all the
indices of atoms they’re bonded to as values.
elems ([str]): list of element symbols for the entire system (must
be returned by ase.Atoms’ get_chemical_symbols, NOT
follow the order the atoms appear in mol_indices)
Returns:
recursive_label (str): a string representing the molecular network
traversed starting from site i
soprano.utils.rep_alg(v, iters=1000, attempts=10, step=0.1, simtol=1e-05)[source]#

Repulsion algorithm, begins with a series of vectors v, finds a new one that is as far as possible, angle-wise, from all of them. The process is that of treating the tips of the vectors as particles on a sphere which repel each other. Of course, it’s possible that multiple equilibrium positions exist, which is why multiple attempts can be made, and are judged identical or not based on a tolerance parameter

Parameters:
v (np.ndarray): list of fixed vectors to avoid
iters (int): number of iterations, default is 1000
attempts (int): number of independent attempts with randomised starts,
default is 10
step (float): step by which the ‘particle’ describing the vector will
be displaced at each iteration during the search.
Default is 1e-1.
simtol (float): tolerance based on which two attempts are considered to
be effectively the same, checking if 1-v1.v2 < simtol.
Default is 1e-5.
Returns:
out_v ([np.ndarray]): list of unit vectors of maximal distance from
the ones in v
soprano.utils.replace_folder(path, new_folder)[source]#

Replace the folder of the given path with a new one

soprano.utils.safe_communicate(subproc, stdin='')[source]#

Executes a Popen.communicate and returns output in a way that is compatible with Python 2 & 3 keeping input and output as strings (since Python 3 requires bytes objects otherwise)

soprano.utils.safe_input(question)[source]#

Ask for user input with Python 2 and 3 compatibility

soprano.utils.seedname(path)[source]#

Get the filename (with no extension) from a full path

soprano.utils.silence_stdio(silence_stdout=True, silence_stderr=True)[source]#

Useful stdout/err silencer

soprano.utils.supcell_gridgen(latt_cart, shape)[source]#

Generate a full linearized grid for a supercell with r_bounds and a base unit cell in Cartesian form.

Args:
latt_cart (np.ndarray): unit cell in cartesian form
shape (tuple[int]): shape of the supercell to be built,
as returned by minimum_supcell.
Returns:
neigh_i_grid (np.ndarray): supercell grid in fractional coordinates
neigh_grid (np.ndarray): supercell grid in cartesian coordinates
Raises:
ValueError: if some of the arguments are invalid
soprano.utils.swing_twist_decomp(quat, axis)[source]#

Perform a Swing*Twist decomposition of a Quaternion. This splits the quaternion in two: one containing the rotation around axis (Twist), the other containing the rotation around a vector parallel to axis (Swing).

Returns two quaternions: Swing, Twist.

soprano.utils.wigner_3j(j1, m1, j2, m2, j3, m3)[source]#

Wigner 3j symbols for given quantum numbers:

/ | j1 j2 j3 | | m1 m2 m3 | /

The numbers passed can be arrays (just make sure they’re the same size).