Skip to content

external_xyz_py

esta.externalBag.external_xyz_py

This is the main part of xyz_py

load_xyz(f_name: str, atomic_numbers: bool = False, add_indices: bool = False, capitalise: bool = True, check: bool = True) -> tuple[list, NDArray]

Load labels and coordinates from a .xyz file

File assumes two header lines, first containing number of atoms

and second containing a comment or blank, followed by actual data

Parameters:

  • f_name (str) –

    File name

  • atomic_numbers (bool, default: False ) –

    If True, reads xyz file with atomic numbers and converts to labels

  • add_indices (bool, default: False ) –

    If True, add indices to atomic labels

    (replacing those which may exist already)

  • capitalise (bool, default: True ) –

    If True, capitalise atomic labels

  • check (bool, default: True ) –

    If True, check xyz file before loading

Returns:

  • list

    atomic labels

  • ndarray

    (n_atoms,3) array containing xyz coordinates of each atom

load_xyz_comment(f_name: str) -> str

Load comment line from an xyz file

Parameters:

  • f_name (str) –

    File name

Returns:

  • str

    comment line of xyz file

check_xyz(f_name: str, allow_indices: bool = True, allow_nonelements: bool = False) -> None

Checks if .xyz file has correct length and contains two header lines

for the number of atoms and an optional comment

Parameters:

  • f_name (str) –

    File name

  • allow_indices (bool, default: True ) –

    If True, allows indexing numbers on atomic labels

  • allow_nonelements (bool, default: False ) –

    If True, allow atomic labels which are do not correspond to a

    chemical element

  • bool (bool, default: False ) –

    If True, allow atomic labels which are do not correspond to a

    chemical element

Returns:

  • None

Raises:

  • ValueError

    If the .xyz file has incorrect length, is missing the number

    of atoms and comment lines, or contains atomic label indices

save_xyz(f_name: str, labels: ArrayLike, coords: ArrayLike, with_numbers: bool = False, verbose: bool = True, mask: list = [], atomic_numbers: bool = False, comment: str = '') -> None

Save an xyz file containing labels and coordinates

Parameters:

  • f_name (str) –

    File name

  • labels (ArrayLike) –

    atomic labels

  • coords (ArrayLike) –

    list of 3 element lists containing xyz coordinates of each atom

  • with_numbers (bool, default: False ) –

    If True, add/overwrite numbers to labels before printing

  • verbose (bool, default: True ) –

    Print information on filename to screen

  • mask (list, default: [] ) –

    n_atom list of 0 (exclude) and 1 (include) indicating which atoms to print

  • atomic_numbers (bool, default: False ) –

    If True, will save xyz file with atomic numbers

  • comment (str, default: '' ) –

    Comment line printed to 2nd line of .xyz file

Returns:

  • None

remove_label_indices(labels: ArrayLike)

Remove label indexing from atomic symbols

indexing is either numbers or numbers followed by letters:

e.g. H1, H2, H3

or H1a, H2a, H3a

Parameters:

  • labels (ArrayLike) –

    atomic labels

Returns:

  • list[str] | str

    atomic labels without indexing, type depends on input type

add_label_indices(labels: ArrayLike, style: str = 'per_element', start_index: int = 1) -> list[str]

Add label indexing to atomic symbols - either element or per atom.

Parameters:

  • labels (ArrayLike) –

    atomic labels

  • style (str, default: 'per_element' ) –

    {'per_element', 'sequential'}

    'per_element': Index by element e.g. Dy1, Dy2, N1, N2, etc.
    
    'sequential': Index the atoms 1->N regardless of element
    
  • start_index (int, default: 1 ) –

    integer at which indexing will start

Returns:

  • list[str]

    atomic labels with indexing

count_n_atoms(form_str: str) -> int

Count number of atoms in a chemical formula

Parameters:

  • form_str (str) –

    chemical formula string

Returns:

  • int

    number of atoms in chemical formula

index_elements(labels: ArrayLike, shift: int = 0) -> dict[str, int]

Return dictionary of element (keys) and positional indices (values) from list of labels

Parameters:

  • labels (ArrayLike) –

    atomic labels

  • shift (int, default: 0 ) –

    additive shift to apply to all indices

Returns:

  • dict[str, int]

    element label (keys) and indices (values)

count_elements(labels: ArrayLike) -> dict[str, int]

Count number of each element in a list of elements

Parameters:

  • labels (ArrayLike) –

    atomic labels

Returns:

  • dict[str, int]

    dictionary of elements (keys) and counts (vals)

get_formula(labels: ArrayLike) -> str

Generates empirical formula in alphabetical order given a list of labels

Parameters:

  • labels (ArrayLike) –

    atomic labels

Returns:

  • str

    Empirical formula in alphabetical order

formstr_to_formdict(form_str: str) -> dict[str, int]

Converts formula string into dictionary of {atomic label:quantity} pairs

Parameters:

  • form_string

    Chemical formula as string

Returns:

  • dict[str, int]

    dictionary of {atomic label:quantity} pairs

formdict_to_formstr(form_dict: dict[str, int], include_one: bool = False) -> str

Converts dictionary of {atomic label:quantity} pairs into

a single formula string in alphabetical order

Parameters:

  • form_dict (dict[str, int]) –

    dictionary of {atomic label:quantity} pairs

  • include_one (bool, default: False ) –

    Include 1 in final chemical formula e.g. C1H4

Returns:

  • str

    Chemical formula as string in alphabetical order

contains_metal(form_string: str) -> bool

Indicates if a metal is found in a chemical formula string

Parameters:

  • form_string (str) –

    Chemical formula as string

Returns:

  • bool

    True if metal found, else False

combine_xyz(labels_1: ArrayLike, labels_2: ArrayLike, coords_1: ArrayLike, coords_2: ArrayLike) -> tuple[list[str], NDArray]

Combine two sets of labels and coordinates

Parameters:

  • labels_1 (ArrayLike) –

    Atomic labels

  • coords_1 (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • labels_2 (ArrayLike) –

    Atomic labels

  • coords_2 (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

Returns:

  • list[str]

    Combined atomic labels

  • ndarray of floats

    Combined xyz coordinates as (n_atoms, 3) array

get_neighborlist(labels: ArrayLike, coords: ArrayLike, adjust_cutoff: dict[str, float] = {}) -> neighborlist.NeighborList

Calculate ASE neighborlist based on covalent radii

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • adjust_cutoff (dict[str, float], default: {} ) –

    dictionary of atoms (keys) and new cutoffs (values)

Returns:

  • NeighborList

    Neighborlist for system

get_adjacency(labels: ArrayLike, coords: ArrayLike, adjust_cutoff: dict[str, float] = {}) -> NDArray

Calculate adjacency matrix using ASE based on covalent radii.

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • adjust_cutoff (dict[str, float], default: {} ) –

    dictionary of atoms (keys) and new cutoffs (values)

Returns:

  • ndarray of floats

    Adjacency matrix with same order as labels/coords

get_bonds(labels: ArrayLike, coords: ArrayLike, neigh_list: neighborlist.NeighborList = None, verbose: bool = True, style: str = 'indices')

Calculate list of atoms between which there is a bond.

Using ASE. Only unique bonds are retained.

e.g. 0-1 and not 1-0

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array in Angstrom

  • neigh_list (NeighborList, default: None ) –

    neighborlist of system, calculated if not provided

  • verbose (bool, default: True ) –

    Print number of bonds to screen

  • style (str, default: 'indices' ) –

    indices: Bond list contains atom number

    labels : Bond list contains atom label

Returns:

  • list[list[int | str]]

    list of lists of unique bonds (atom pairs)

find_bonds(labels: ArrayLike, coords: ArrayLike, neigh_list: neighborlist.NeighborList = None, verbose: bool = True, style: str = 'labels')

Calculate list of atoms between which there is a bond.

Using ASE. Only unique bonds are retained.

e.g. 0-1 and not 1-0

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array in Angstrom

  • neigh_list (NeighborList, default: None ) –

    neighborlist of system, calculated if not provided

  • verbose (bool, default: True ) –

    Print number of bonds to screen

  • style (str, default: 'labels' ) –

    indices: Bond list contains atom number

    labels : Bond list contains atom label

Returns:

  • list[list[int | str]]

    list of lists of unique bonds (atom pairs)

  • ndarray of floats

    Bond length in Angstrom

get_angles(labels: ArrayLike, coords: ArrayLike, neigh_list: neighborlist.NeighborList = None, verbose: bool = True, style: str = 'indices')

Calculate list of atoms between which there is a bond angle. Using ASE. Only unique angles are retained. e.g. 0-1-2 but not 2-1-0

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • neigh_list (NeighborList, default: None ) –

    neighborlist of system, calculated if not provided

  • verbose (bool, default: True ) –

    Print number of angles to screen

  • style (str, default: 'indices' ) –
    indices: Angle list contains atom number
    labels : Angle list contains atom label
    values : Angle list is values in degrees
    

Returns:

  • list[list[int | str | float]]

    list of lists of unique angles (atom trios)

find_angles(labels: ArrayLike, coords: ArrayLike, neigh_list: neighborlist.NeighborList = None, verbose: bool = True, style='labels')

Calculate all angles using ASE. Only unique angles are retained. e.g. 0-1-2 but not 2-1-0

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • neigh_list (NeighborList, default: None ) –

    neighborlist of system, calculated if not provided

  • verbose (bool, default: True ) –

    Print number of angles to screen

  • style
    indices: Angle labels are atom number
    labels : Angle labels are atom label
    

Returns:

  • list[list[int | str]]

    list of lists of unique angles (atom trios) as labels or indices

  • ndarray

    Angles in degrees

get_dihedrals(labels: ArrayLike, coords: ArrayLike, neigh_list: neighborlist.NeighborList = None, verbose: bool = True, style: str = 'indices')

Calculate and list of atoms between which there is a dihedral. Using ASE. Only unique dihedrals are retained. e.g. 0-1-2-3 but not 3-2-1-0

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • neigh_list (NeighborList, default: None ) –

    neighborlist of system, calculated if not provided

  • verbose (bool, default: True ) –

    Print number of dihedrals to screen

  • style (str, default: 'indices' ) –
    indices: Dihedral list contains atom number
    labels : Dihedral list contains atom label
    

Returns:

  • list[list[int | str]]

    list of lists of unique dihedrals (atom quads)

find_dihedrals(labels: ArrayLike, coords: ArrayLike, neigh_list: neighborlist.NeighborList = None, verbose: bool = True, style='labels')

Calculate and list of atoms between which there is a dihedral. Using ASE. Only unique dihedrals are retained. e.g. 0-1-2-3 but not 3-2-1-0

Parameters:

  • labels (ArrayLike) –

    Atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • neigh_list (NeighborList, default: None ) –

    neighborlist of system, calculated if not provided

  • verbose (bool, default: True ) –

    Print number of dihedrals to screen

  • style
    indices: Dihedral list contains atom number
    labels : Dihedral list contains atom label
    

Returns:

  • list[list[int | str]]

    list of lists of unique dihedrals (atom quads)

  • ndarray

    Dihedral angles in degrees

lab_to_num(labels: ArrayLike) -> list[int]

Convert atomic label to atomic number

Parameters:

  • labels (ArrayLike) –

    Atomic labels

Returns:

  • list[int] | int

    Atomic numbers

num_to_lab(numbers: ArrayLike, numbered: bool = True) -> list[str]

Convert atomic number to atomic labels

Parameters:

  • numbers (ArrayLike) –

    Atomic numbers

  • numbered (bool, default: True ) –

    If True, adds indexing number to end of atomic labels

Returns:

  • list[str]

    Atomic labels

reflect_coords(coords: ArrayLike) -> NDArray

Reflect coordinates through xy plane

Parameters:

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

Returns:

  • ndarray of floats

    reflected xyz coordinates as (n_atoms, 3) array

find_entities(labels: ArrayLike, coords: ArrayLike, adjust_cutoff: dict[str, float] = {}, non_bond_labels: list[str] = []) -> dict[str, list[list[int]]]

Finds formulae of entities given in labels and coords using adjacency
matrix
Parameters
labels: array_like
    atomic labels
coords: array_like
    xyz coordinates of each atom as (n_atoms, 3) array
adjust_cutoff: dict[str, float], optional
    dictionary of atoms (keys) and new cutoffs (values) used in generating

adjacency matrix non_bond_labels: list[str], optional List of atomic labels specifying atoms to which no bonds will be allowed. e.g If a metal centre is provided this will result in single ligands

    being returned.
Returns
dict[str, list[list[int]]]
    keys = molecular formula

    vals = list of lists, where each list contains the indices of a single

occurrence of the key, and the indices match the order given

    in `labels` and `coords`

find_entities_from_adjacency(labels_nn: ArrayLike, adjacency: ArrayLike)

Finds formulae of entities given in labels and adjacency matrix
Parameters
labels: array_like
    atomic labels
adjacency: array_like
    Adjacency matrix (0,1) with same order as labels
Returns
dict[str:list[list[int]]]
    keys = molecular formula

    vals = list of lists, where each list contains the indices of a single

occurrence of the key, and the indices match the order given

    in `labels` and `coords`

calculate_rmsd(coords_1: ArrayLike, coords_2: ArrayLike, mask_1: ArrayLike = [], mask_2: ArrayLike = [], order_1: ArrayLike = [], order_2: ArrayLike = []) -> float

Calculates RMSD between two structures

RMSD = sqrt(mean(deviations**2))

Where deviations are defined as norm([x1,y1,z1]-[x2,y2,z2])

If coords_1 and coords_2 are not the same length, then a mask array can be

provided for either/both and is applied prior to the calculation

coords_1 and coords_2 can also be reordered if new orders are specified
- note this occurs BEFORE masking
Parameters
coords_1: array_like
    xyz coordinates as (n_atoms, 3) array
coords_2: array_like
    xyz coordinates as (n_atoms, 3) array

mask_1: list
    list of 0 (exclude) and 1 (include) for each element in coords_1
mask_2: list
    list of 0 (exclude) and 1 (include) for each element in coords_2
order_1: list
    list of new indices for coords_1 - applied BEFORE masking
order_2: list
    list of new indices for coords_2 - applied BEFORE masking
Returns
float
    Root mean square of norms of deviation between two structures

build_rotation_matrix(alpha: float, beta: float, gamma: float) -> NDArray

Creates rotation matrix using euler angles alpha, beta, gamma for the zyz convention

https://easyspin.org/easyspin/documentation/eulerangles.html

Parameters:

  • alpha (float) –

    alpha angle in radians

  • beta (float) –

    beta angle in radians

  • gamma (float) –

    gamma angle in radians

Returns:

  • ndarray of floats

    Rotation matrix R which is applied to a vector x as R dot x

rotate_coords(coords: ArrayLike, alpha: float, beta: float, gamma: float) -> NDArray

Rotates coordinates using euler angles alpha, beta, gamma for the zyz convention

https://easyspin.org/easyspin/documentation/eulerangles.html

Parameters:

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

  • alpha (float) –

    alpha angle in radians

  • beta (float) –

    beta angle in radians

  • gamma (float) –

    gamma angle in radians

Returns:

  • ndarray of floats

    xyz coordinates as (n_atoms, 3) array after rotation

    in same order as input coordinates

minimise_rmsd(coords_1: ArrayLike, coords_2: ArrayLike, mask_1: ArrayLike = [], mask_2: ArrayLike = [], order_1: ArrayLike = [], order_2: ArrayLike = []) -> tuple[float, float, float, float]

Minimises the RMSD between two structures

by rotating coords_1 onto coords_2

If coords_1 and coords_2 are not the same length, then a mask array can be

provided for either/both and is applied prior to the calculation

coords_1 and coords_2 can also be reordered if new orders are specified

**note reordering occurs before masking**
Parameters
coords_1: array_like
    xyz coordinates as (n_atoms, 3) array
coords_2: array_like
    xyz coordinates as (n_atoms, 3) array
mask_1: array_like
    0 (exclude) or 1 (include) for each element in coords_1
mask_2: array_like
    0 (exclude) or 1 (include) for each element in coords_2
order_1: array_like
    new indices for coords_1 - applied BEFORE masking
order_2: array_like
    new indices for coords_2 - applied BEFORE masking
Returns
float
    Root mean square of norms of deviation between two structures
float
    alpha angle in radians
float
    beta angle in radians
float
    gamma angle in radians

calculate_com(labels: ArrayLike, coords: ArrayLike) -> NDArray

Calculates centre-of-mass using relative atomic masses

Parameters:

  • labels (ArrayLike) –

    list of atomic labels

  • coords (ArrayLike) –

    xyz coordinates as (n_atoms, 3) array

Returns:

  • ndarray of floats

    xyz coordinates of centre of mass as (3) array