ccu.structure.geometry

Geometry-related functions for atomic structures.

class ccu.structure.geometry.MolecularOrientation(directions: tuple[NDArray[np.floating], NDArray[np.floating]], description: str)[source]

Bases: NamedTuple

The orientation of a molecule.

A MolecularOrientation tuple contains the information required to unambiguously orient a molecule in space, for example, on an AdsorptionSite.

Variables:

Create new instance of MolecularOrientation(directions, description)

_asdict()

Return a new dict which maps field names to their values.

_field_defaults = {}
_fields = ('directions', 'description')
classmethod _make(iterable)

Make a new MolecularOrientation object from a sequence or iterable

_replace(**kwds)

Return a new MolecularOrientation object replacing specified fields with new values

description: str

Alias for field number 1

directions: tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

Alias for field number 0

ccu.structure.geometry.align(adsorbate: Atoms, directions: Sequence[Iterable[float]], center: Iterable[float] | None = None) Atoms[source]

Align a molecule according to its primary and secondary axes.

Parameters:
  • adsorbate – An Atoms representing a molecule.

  • directions – A sequence whose first and second elements are length 3, iterables of floats representing the primary and secondary directions along which adsorbate is to be aligned.

  • center – A point to remain fixed while aligning adsorbate. Defaults to the center-of-mass of adsorbate.

Returns:

A copy of adsorbate aligned such that its primary and secondary axes coincide with directions[0] and directions[1], respectively.

ccu.structure.geometry.calculate_norm(points: list[ndarray[tuple[Any, ...], dtype[floating]]], *, reverse: bool = False) ndarray[tuple[Any, ...], dtype[floating]][source]

Calculate the norm for the average plane defined by a set of points.

Parameters:
  • points – A list of points on a surface. These points should be approximately coplanar.

  • reverse – Whether or not to reverse the preferred direction for the norm. Defaults to False in which case the norm direction is determined as follows. If the vector does not lie in the xy-plane, then the norm is normalized to have positive z. Otherwise, if the vector has a y component, then it is normalized to have positive y. and if it has no y component, then it is normalized to have positive x. If True, then the norm is normalized to have negative z in the above cases.

Returns:

A length 3, 1D numpy.ndarray representing the unit normal vector for the average plane defined by points.

Raises:

ValueError – Less than three non-colinear points provided.

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

Calculates the separation between two Atoms instances.

The distance is defined as the smallest distance between an atom in one structure and an atom in the second structure.

Parameters:
  • structure1 – An Atoms instance.

  • structure2 – An Atoms instance.

Returns:

A float representing the separation between the two structures.

ccu.structure.geometry.fragment_atoms(atoms: Atoms, a0: int, a1: int, *, nl: NeighborList | None = None) list[int][source]

Return the largest fragment containing one atom but not another.

A molecular fragment is defined as a contiguous set of atoms.

Parameters:
  • atoms – An Atoms object.

  • a0 – The index of the atom in atoms for which the fragment not containing a1 is to be determined.

  • a1 – The index of the atom to be excluded from the fragment.

  • nl – A neighbor list for the atoms object. If not provided, it will be calculated.

Returns:

The indices of the atoms in atoms which belong to the fragment containing a0 but not a1.

Example: Determine the indices of the methyl and alcohol fragments of CH3OH

>>> from ase.build import molecule
>>> from ase.neighborlist import build_neighbor_list
>>> from ccu.structure.geomtry import fragment_atoms
>>> ch3oh = molecule("CH3OH")
>>> ch3oh.symbols.formula
Formula('COH4')
>>> nl = build_neighbor_list(
...     ch3oh,
...     self_interaction=False,
...     bothways=True,
... )
>>> neighbors, _ = nl.get_neighbors(0)
>>> fragment_atoms(ch3oh, 0, neighbors[0], nl=nl)
[0, 2, 4, 5]