Topology¶
A Topology holds the bonds, angles, dihedrals and impropers of a molecular
system. A system has one or none; it comes from LAMMPS data files and other
formats that store bonds, or is given when a system is made.
import polars as pl
import mdapy as mp
water = mp.System(
positions=[[0.0, 0.0, 0.0], [0.96, 0.0, 0.0], [-0.24, 0.93, 0.0]],
box=mp.Box(10.0),
elements=["O", "H", "H"],
topology=mp.Topology(bonds=[[0, 1], [0, 2]], angles=[[1, 0, 2]]),
)
water.topology.bonds # a polars DataFrame of two bonds
len(water.topology) # 3 terms in all
Terms¶
A topology has four tables, bonds, angles, dihedrals and impropers,
with 2, 3, 4 and 4 atoms per term. Each is given as an (M, k) array of atom
indices, all of type 1, or as a polars DataFrame with the columns:
| Column | Type | Meaning |
|---|---|---|
atoms |
(k,) int64 | Atom indices: rows of the system's table, from 0. |
type |
int32 | Type of the term, from 1; 1 when not given. |
type_label |
str, optional | Name of the type, for example "O-H". |
Other columns are kept. Atom order follows LAMMPS: the central atom of an angle is the second one, dihedral atoms follow the chain, and the meaning of the improper order depends on the improper style.
labelled = mp.Topology(
bonds=pl.DataFrame(
{"atoms": [[0, 1], [0, 2]], "type": [1, 1], "type_label": ["O-H", "O-H"]}
),
angles=[[1, 0, 2]],
)
labelled.bonds["type_label"].to_list() # ['O-H', 'O-H']
| Name | Meaning |
|---|---|
bonds, angles, dihedrals, impropers |
each table, a copy that shares its columns |
tables() |
the four tables by kind |
len(topology) |
the number of terms of every kind |
max_atom_index() |
the largest atom index of any term, or -1 |
remap(mapping) |
a topology with atoms renumbered: mapping[old] is the new index, or -1 for an atom removed |
Topology follows the atoms¶
A topology refers to atoms by their row in the table, so it changes with
them. filter, gather and sort renumber the terms whose
atoms are all kept, and drop the terms that lose an atom:
oxygen = water.filter(element="O")
len(oxygen.topology) # 0: both bonds and the angle lost a hydrogen
reordered = water.gather([2, 1, 0])
reordered.topology.bonds["atoms"].to_list() # [[2, 1], [2, 0]]
Like a system, a topology never changes: remap and the methods of systems
return new ones.
Errors¶
Topology raises
InvalidParameter for
a table of the wrong shape or types, negative atom indices, a term that
repeats an atom, missing values, or a type below 1; a system raises it for a
topology that refers to atoms it does not have.