infer_bond_types#

biotite.structure.infer_bond_types(atoms: AtomArray[N], total_charge: int = 0, max_iterations: int | None = None) → tuple[BondList, ndarray[tuple[N], dtype[integer]]][source]#

Infer the bond types for the bonds in the given structure based on the connectivity between the atoms, their elements and the total charge. [1]

Combinations of allowed valences for each atom are enumerated in decreasing order of total unsaturation and multiple bonds are greedily assigned between adjacent unsaturated atoms. The first assignment, in which each atom satisfies its valence and the formal charges sum up to total_charge, is returned.

Parameters:
atomsAtomArray

The structure to infer the bond types for. The bonds attribute is required as source of the connectivity. Note that hydrogen atoms must be present, as otherwise the unsaturation of their bonded heavy atoms cannot be determined correctly. If the charge annotation is present, the formal charge of each atom is constrained to the given value, which narrows the search considerably.

total_chargeint, optional

The total formal charge of the structure, used as constraint during the assignment.

max_iterationsint, optional

The maximum number of bond order assignments to try. By default, all valence combinations are tried before the search is given up.

Returns:
bondsBondList

The bonds from atoms.bonds with assigned bond types. Only BondType.SINGLE, BondType.DOUBLE and BondType.TRIPLE are assigned. Hence, bonds in aromatic systems are represented by alternating single and double bonds, i.e. one kekulized resonance structure.

chargesndarray, shape=(n,), dtype=int

The formal charge of each atom, as implied by the assigned bond types. If the charge annotation is present in atoms, it is returned unchanged. Otherwise atoms with an unsupported element are assigned a charge of 0.

Warns:
InconsistentBondTypeWarning

If no assignment exists, where each atom satisfies its valence and the formal charges sum up to total_charge, or max_iterations is exceeded, before such an assignment is found. In both cases the assignment with the highest sum of bond orders found so far is returned.

Warning

This function is recommended for small molecules only: The number of valence combinations grows exponentially with the number of atoms with multiple allowed valences (e.g. nitrogen, oxygen, sulfur and phosphorus). Hence, for large molecules long run times can be expected. Use max_iterations to abort the search prematurely in such cases.

Furthermore, the following molecules are not covered by the underlying valence model and hence cannot be assigned properly:

  • Radicals and other odd-electron species, e.g. superoxide.

  • Hypervalent sulfur or selenium with only two bond partners, e.g. in sulfur dioxide, as their allowed valences are restricted based on their number of bond partners.

  • Fused aromatic systems, where the multiple bonds may be placed in a way that satisfies all valences, but does not reproduce the aromatic system.

In the first two cases an InconsistentBondTypeWarning is raised. The search may also fail for other exotic molecules, especially if the charge annotation is missing.

See also

connect_via_distances

Can be used to create the required connectivity beforehand, if it is unknown.

Notes

Supported elements are H, B, C, N, O, F, Si, P, S, Cl, Se, Br and I. Bonds of atoms with other elements (e.g. metals) keep BondType.SINGLE. Their formal charge is taken from the charge annotation, if it is present, and is assumed to be zero otherwise.

In deviation from the reference, which allows only the valences of the neutral element, each atom may also adopt the valences of the anion and cation, i.e. it may carry a formal charge of -1 or 1. As valence states with fewer formal charges are preferred, the neutral form is still chosen, if it satisfies the constraints. Consequently, if the charge annotation is present, the possible valence states of each atom are narrowed down to those with the respective formal charge, which reduces the number of combinations to try substantially. If the given charge does not fit any valence state of the respective element, the charge is still trusted, as it may represent a bonding situation that the valence model cannot express, e.g. a dative bond to a four-bonded neutral boron atom. In this rare case the atom is treated as saturated, i.e. all its bonds remain single bonds, and its valence does not imply its formal charge anymore.

References

Examples

>>> molecule = residue("URA")
>>> # Remove bond type information, but keep connectivity
>>> molecule.bonds.remove_bond_order()
>>> # Infer bond types
>>> molecule.bonds, molecule.charge = infer_bond_types(molecule)
>>> for i, j, bond_type in molecule.bonds.as_array():
...     print(
...         molecule.atom_name[i], molecule.atom_name[j], BondType(bond_type).name
...     )
N1 C2 SINGLE
N1 C6 SINGLE
N1 HN1 SINGLE
C2 O2 DOUBLE
C2 N3 SINGLE
N3 C4 SINGLE
N3 HN3 SINGLE
C4 O4 DOUBLE
C4 C5 SINGLE
C5 C6 DOUBLE
C5 H5 SINGLE
C6 H6 SINGLE