ccu.structure package#

Submodules#

ccu.structure.axisfinder module#

This module defines functions to determine a molecule’s orientation axes.

The function get_axes returns all three orientation axes for a given molecule. For example,

>>> import ase
>>> from ccu.structure.axisfinder import get_axes
>>> coh = ase.Atoms('COH', positions=[[0, 0, 0], [-2, 0, 0], [-1, 0.5, 0]])
>>> get_axes(coh)
(array([1., 0., 0.]), array([0., 1., 0.]), array([0., 0., 1.]))

The function find_farthest_atoms returns the two atoms within a molecule whose separation is the greatest. For example,

>>> import ase
>>> from ccu.structure.axisfinder import find_farthest_atoms
>>> coh = ase.Atoms('COH', positions=[[0, 0, 0], [-2, 0, 0], [-1, 0.5, 0]])
>>> find_farthest_atoms(coh)
(Atom('C', [0.0, 0.0, 0.0], index=0), Atom('O', [-2.0, 0.0, 0.0], index=1))

The function find_primary_axis returns the primary orientation axis for a given molecule. For example,

>>> import ase
>>> from ccu.structure.axisfinder import find_primary_axis
>>> coh = ase.Atoms('COH', positions=[[0, 0, 0], [-2, 0, 0], [-1, 0.5, 0]])
>>> find_primary_axis(coh)
array([1., 0., 0.])

The function find_secondary_axis returns the primary orientation axis for a given molecule. For example,

>>> import ase
>>> from ccu.structure.axisfinder import find_secondary_axis
>>> coh = ase.Atoms('COH', positions=[[0, 0, 0], [-2, 0, 0], [-1, 0.5, 0]])
>>> find_secondary_axis(coh)
array([0., 1., 0.])

The function find_tertiary_axis returns the primary orientation axis for a given molecule. For example,

>>> import ase
>>> from ccu.structure.axisfinder import find_tertiary_axis
>>> coh = ase.Atoms('COH', positions=[[0, 0, 0], [-2, 0, 0], [-1, 0.5, 0]])
>>> find_tertiary_axis(coh)
array([0., 0., 1.])
ccu.structure.axisfinder.find_farthest_atoms(molecule: Atoms, tol: float = 1e-05) tuple[ase.atoms.Atoms][source]#

Finds the two atoms in the molecule separated by the greatest distance.

In molecules for which there are several pairs of atoms with equidistant separations, this function will return the pair of atoms with lowest indices whose separation is within a given tolerance of the largest atomic separation in the molecule. Each pair is sorted according to the index of the lowest index atom and then the index of the second atom. For .. rubric:: Example

  • If atoms 0 and 1 have the same separation as atoms 2 and 3, atoms 0 and 1 will be returned since 0 < 2.

  • If atoms 0 and 1 have the same separation as atoms 0 and 3, atoms 0 and 1 will be returned since 1 < 3.

  • If atoms 1 and 2 have the same separation as atoms 0 and 4, atoms 0 and 4 will be returned since 0 < 1.

  • If atoms 1 and 2 have the same separation as atoms 0 and 2, atoms 0 and 2 will be returned since 0 < 1.

Parameters:
  • molecule – The molecule for whom the two farthest atoms are to be determined.

  • tol – A float indicating the resolution (in Angstroms) between atomic distances.

Returns:

A tuple containing the two atoms in the molecule separated by the greatest distance. The atoms are ordered by lowest index within the structure.

ccu.structure.axisfinder.find_primary_axis(molecule: Atoms) array[source]#

Determines the unit vector representing the primary orientation axis of a molecule.

The primary axis is defined as the unit vector which is parallel to the direction vector between the two most distant atoms in the molecule and points from the higher index atom to the lower index atom.

Parameters:

molecule – An ase.Atoms instance representing the molecule for whom the primary axis is to be determined.

Returns:

A numpy.array representing a unit vector in the direction of the primary orientation axis. Note that for zero-dimensional molecules, this function will return the zero vector.

ccu.structure.axisfinder.find_secondary_axis(molecule: Atoms, min_distance: float = 0.1) array[source]#

Determines the unit vector representing the secondary orientation axis of a molecule.

Let L be the line between the two farthest atoms in the molecule, let v be the vector which defines the primary axis, and let P be the position of the atom farthest from L. Further, let w be the vector from L to P, and let z be the component of w which is orthogonal to v. The secondary axis is defined as the unit vector in the direction of z.

Parameters:
  • molecule – An ase.Atoms instance representing the molecule for whom the secondary axis is to be determined.

  • min_distance – A float specifying the minimum distance from the primary axis (in Angstroms) to be considered for defining the secondary axis. Defaults to 0.1.

Returns:

A numpy.array representing a unit vector in the direction of the secondary orientation axis. Note that for zero- and one-dimensional molecules, this function will return the zero vector.

ccu.structure.axisfinder.find_tertiary_axis(molecule: Atoms) array[source]#

Determines the unit vector representing the tertiary orientation axis of a molecule.

The tertiary orientation axis is simply the cross product of the primary and secondary orientation axes. See find_primary_axis and find_secondary_axis for information on how these axes are defined.

Parameters:

molecule – An ase.Atoms instance representing the molecule for whom the tertiary axis is to be determined.

Returns:

A numpy.array representing a unit vector in the direction of the tertiary orientation axis. Note that if the molecule is zero- or one-dimensional, this function will return the zero vector.

ccu.structure.axisfinder.get_axes(molecule: Atoms) tuple[numpy.array][source]#

Determines a molecule’s three orientation axes.

The primary axis is defined as the vector between the two most distant atoms. The secondary axis is defined as the orthogonal component (to the primary axis) of the vector from the primary axis to the atom farthest from the line between the two most distant atoms. The tertiary axis is the cross product of the primary and secondary axes. The axes so defined are orthogonal. Note that if the molecule is unimolecular, all three vectors will be the zero vector, and that if the molecule is linear only the primary axis will be nonzero.

Parameters:

molecule – An ase.Atoms instance whose axes are to be determined.

Returns:

A tuple containing unit vectors reprsenting the three orientation axes. The first, second, and third entries are the primary, secondary, and tertiary axes, respectively. For nonlinear molecules, the axes form an orthonormal set.

ccu.structure.cli module#

This module contains the ccu.structure package CLI logic.

ccu.structure.comparator module#

This module defines the Comparator class.

The Comparator class can be used to determine teh similarity of two structures as follows:

>>> import ase
>>> from ccu.structure.comparator import Comparator
>>> co1 = ase.Atoms('CO', positions=[[0, 0, 0], [1, 0, 0]])
>>> co2 = ase.Atoms('CO', positions=[[0, 1, 1], [1, 1, 1]])
>>> oc = ase.Atoms('OC', positions=[[0, 0, 0], [1, 0, 0]])
>>> Comparator.check_similarity(co1, co2)
True
>>> Comparator.check_similarity(co1, oc)
False
class ccu.structure.comparator.Comparator[source]#

Bases: object

An object which compares the similarity of two structures.

static calculate_cumulative_displacement(fingerprint1: Fingerprint, fingerprint2: Fingerprint) float[source]#

Calculates the cumulative displacement of each atomic position in fingerprint2 relative to the corresponding atomic position in fingerprint1.

The cumulative displacement is defined as follows:

Note that each row in each np.ndarray associated with each histogram key corresponds to a displacement vector between two atoms. With each such displacement vector in the histogram of fingerprint1, we can identify a corresponding displacement vector in the histogram of fingerprint2 as the displacement vector associated with the same histogram key and index. We then define a difference vector as the difference between a displacement vector in fingerprint1 and its counterpart in fingerprint2. The set of all difference vectors is defined on the basis of fingerprint1. That is, if X is the set of all displacement vectors in fingerprint1 and Y is the set of all corresponding vectors in fingerprint2, the set of all difference vectors is the set of all vectors x - y where x is a displacement vector in fingerprint1 and y is the corresponding displacement vector in Y. (Note that this requires that the histogram of fingerprint2 must include all the keys that that of the histogram of fingerprint1 includes. Additionally, this requires that for each key in the histogram of fingerprint1, the value in fingerprint2 includes at least as many displacement vectors as the value in fingerprint1.) The cumulative displacement is then defined as the sum of the norms of all the difference vectors corresponding to fingerprint1 and fingerprint2.

Parameters:
  • fingerprint1 – The Fingerprint instance used as a reference to calculate the cumulative displacement.

  • fingerprint2 – The second Fingerprint instance used to calculate the cumulative displacement.

Returns:

A float representing the cumulative displacement for fingerprint2 relative to fingerprint1.

static check_similarity(structure1: Atoms, structure2: Atoms, tol: float = 0.05) bool[source]#

Determines whether the atomic positions of two structures are similar to within a given tolerance.

Parameters:
  • structure1 – An ase.Atoms instance representing the first structure to compare.

  • structure2 – An ase.Atoms instance representing the second structure to compare.

  • tol – A float specifying the tolerance for the cumulative displacement for fingerprint in Angstroms. Defaults to 5e-2.

Returns:

A boolean indicating whether or not the two structures are similar within the specified tolerance. Two structures are similar if they can be superimposed via a translation operation.

static cosort_fingerprints(fingerprints1: Iterable[Fingerprint], fingerprints2: Iterable[Fingerprint]) tuple[ccu.structure.fingerprint.Fingerprint][source]#

Determines the ordering of the second supplied iterable of Fingerprints which minimizes the cumulative displacement across the two iterables of Fingerprints.

Parameters:
  • fingerprints1 – An iterable containing Fingerprint instances.

  • fingerprints2 – An iterable containing Fingerprint instances.

  • Note that the two iterables must be of the same length and that the

  • values() methods of all Fingerprint instances across the two

  • iterables must be of the same length.

Returns:

A tuple containing the ordering of fingerprints2 which minimizes the cumulative displacement across the two iterables of Fingerprints.

static cosort_histograms(fingerprint1: Fingerprint, fingerprint2: Fingerprint) dict[str, numpy.ndarray][source]#

Determines the ordering of the second fingerprint’s histogram which minimizes the cumulative displacement of the atoms in each structure.

The two supplied Fingerprints need not have the same keys or the same number of entries under each key. Such cases are handled as follows:

Let k be a key in both the histograms of fingerprint1 and fingerprint2. Let p be the iterable corresponding to the key k in the histogram of fingerprint1, and let q be the iterable corresponding to the key k in the histogram of fingerprint2.

If len(p) > len(q), then q is ordered according to its match with the first len(q) elements of p.

If len(p) <= len(q), then q is ordered according to the best match with p and the first len(p) elements of q.

Parameters:
  • fingerprint1 – The Fingerprint object to be used as a reference for each displacement in the other Fingerprint’s histogram.

  • fingerprint2 – The Fingerprint object for which the optimally ordered histogram is to be determined.

Returns:

A dict constructed from fingerprint2._histogram mapping chemical symbols to a numpy.ndarray containing the displacement vectors to atoms with the corresponding chemical symbol. The order of the displacement vectors is such that the cumulative displacement of the displacement vectors is minimized relative to fingerprint1._histogram.

ccu.structure.fingerprint module#

This module defines the Fingerprint class.

class ccu.structure.fingerprint.Fingerprint(structure: Atoms, reference: int, indices: Iterable[int] = None)[source]#

Bases: MutableMapping

A set of displacement vectors relative to a particular atom within an ase.Atoms object.

The displacement vectors for atoms of a given chemical symbol can be accessed through the MutableMapping interface. For example:

structure = ase.Atoms(‘CO’, positions=[[0, 0, 0], [1, 0, 0]]) fp = Fingerprint(structure, 0, [0, 1]) fp[‘C’]

Variables:
  • structure – The ase.Atoms instance to which the Fingerprint instance is related. reference: An int indicating the index of the reference atom used to construct the Fingerprint instance.

  • indices – A tuple indicating the indices of the atoms within the structure used to construct the Fingerprint instance.

classmethod from_structure(structure: Atoms) list[ccu.structure.fingerprint.Fingerprint][source]#

Creates a list of Fingerprint objects corresponding to each atom within an ase.Atoms object.

Parameters:

structure – An ase.Atoms instance representing the structure from which to create the list of Fingerprints.

Returns:

A list of the Fingerprints for each atom.

ccu.structure.geometry module#

This module defines useful geometry related functions for ase.Atoms instances.

ccu.structure.geometry.calculate_separation(structure1: Atoms, structure2: Atoms) float[source]#

Calculates the separation between two ase.Atoms instances defined as the smallest distance between an atom in one structure and an atom in the second structure.

Parameters:
  • structure1 – An ase.Atoms instance.

  • structure2 – An ase.Atoms instance.

Returns:

A float representing the separation between the two structures.

ccu.structure.resizecell module#

This script resizes the c vector of all the .traj files in the current working directory to the specified positive number (default is 10)

ccu.structure.resizecell.run(structure: Path, length: float)[source]#

Resize c-vector of structure and centres atoms in cell.

Parameters:
  • structure – A pathlib.Path instance leading to the structure whose cell is to be resized.

  • length – A float specifying the new c-vector of the cell.

ccu.structure.symmetry module#

This class defines the SymmetryOperation and Symmetry classes and subclasses.

Symmetry and SymmetryOperation subclasses can be used as follows:

>>> import ase
>>> from ccu.structure.symmetry import Rotation, RotationSymmetry
>>> rotation1 = Rotation(90, [0, 0, 1])
>>> symmetry1 = RotationSymmetry(rotation1)
>>> co = ase.Atoms('CO', positions=[[0, 0, 0], [1, 0, 0]])
>>> rotated = rotation1.transform(co)
>>> rotated.positions
array([[0.000000e+00, 0.000000e+00, 0.000000e+00],
       [6.123234e-17, 1.000000e+00, 0.000000e+00]])
>>> symmetry1.check_symmetry(co)
False
>>> h2 = ase.Atoms('HH', positions=[[0, 0, 0], [1, 0, 0]])
>>> rotation2 = Rotation(180, [0, 0, 1])
>>> symmetry2 = RotationSymmetry(rotation2)
>>> symmetry2.check_symmetry(h2)
True
class ccu.structure.symmetry.Inversion[source]#

Bases: SymmetryOperation

class ccu.structure.symmetry.Rotation(angle: float, axis: Iterable[float])[source]#

Bases: SymmetryOperation

A rotation operation.

Variables:
  • angle – A float specifying a rotation angle in degrees.

  • axis – A numpy.array representing the axis of rotation.

as_matrix() ndarray[source]#

Returns the rotation operation of this instance as a numpy.ndarray which represents the rotation matrix.

transform(structure: Atoms) Atoms[source]#

Rotates the given structure by the angle and about the axis specified as attributes of the Rotation object.

Parameters:

structure – An ase.Atoms instance representing structure to be rotated.

Returns:

A rotated copy of the original ase.Atoms instance.

class ccu.structure.symmetry.RotationSymmetry(operation: Rotation)[source]#

Bases: Symmetry

A rotational symmetry.

check_symmetry(structure: Atoms, tol: float = 0.05) bool[source]#

Determines the symmetry represented by the instance belongs to the given structure.

Parameters:
  • structure – An ase.Atoms instance representing the structure whose symmetry is to be determined.

  • tol – A float specifying the absolute tolerance for positions. Defaults to 5e-2.

Returns:

A boolean indicating whether or not the given structure possesses

the symmetry of the RotationSymmetry object subject to the specified tolerance.

property operation: Rotation#

The Rotation instance associated with this RotationSymmetry instance.

class ccu.structure.symmetry.Symmetry[source]#

Bases: ABC

An abstract base class for molecule symmetries.

abstract check_symmetry(structure: Atoms, tol: float) bool[source]#

Subclasses should override this method.

abstract property operation: SymmetryOperation#

Subclasses should override this method.

class ccu.structure.symmetry.SymmetryOperation[source]#

Bases: ABC

An abstract base class for symmetry operations.

abstract transform(structure: Atoms) Atoms[source]#

Subclasses should override this method.

Module contents#