Source code for angstrom.molecule.bonds

"""
--- Ångström ---
Molecular bonding estimation for Ångström Python package.
"""
# Molecular Single-Bond Covalent Radii for Elements 1-118 by Pyykko et al. doi: 10.1002/chem.200800987
rcov = {'H': 0.32, 'He': 0.46, 'Li': 1.33, 'Be': 1.02, 'B': 0.85, 'C': 0.75, 'N': 0.71,
        'O': 0.63, 'F': 0.64, 'Ne': 0.67, 'Na': 1.55, 'Mg': 1.39, 'Al': 1.26, 'Si': 1.16,
        'P': 1.11, 'S': 1.03, 'Cl': 0.99, 'Ar': 0.96, 'K': 1.96, 'Ca': 1.71, 'Sc': 1.48,
        'Ti': 1.36, 'V': 1.34, 'Cr': 1.22, 'Mn': 1.19, 'Fe': 1.16, 'Co': 1.11, 'Ni': 1.10,
        'Cu': 1.12, 'Zn': 1.18, 'Ga': 1.24, 'Ge': 1.21, 'As': 1.21, 'Se': 1.16, 'Br': 1.14,
        'Kr': 1.17, 'Rb': 2.10, 'Sr': 1.85, 'Y': 1.63, 'Zr': 1.54, 'Nb': 1.47, 'Mo': 1.38,
        'Tc': 1.28, 'Ru': 1.25, 'Rh': 1.25, 'Pd': 1.20, 'Ag': 1.28, 'Cd': 1.36, 'In': 1.42,
        'Sn': 1.40, 'Sb': 1.40, 'Te': 1.36, 'I': 1.33, 'Xe': 1.31, 'Cs': 2.32, 'Ba': 1.96,
        'Hf': 1.52, 'Ta': 1.46, 'W': 1.37, 'Re': 1.31, 'Os': 1.29, 'Ir': 1.22, 'Pt': 1.23,
        'Au': 1.24, 'Hg': 1.33, 'Tl': 1.44, 'Pb': 1.44, 'Bi': 1.51, 'Po': 1.45, 'At': 1.47,
        'Ru': 1.42, 'Fr': 2.23, 'Ra': 2.01, 'Rf': 1.57, 'Db': 1.49, 'Sg': 1.43, 'Bh': 1.41,
        'Hs': 1.34, 'Mt': 1.29, 'Ds': 1.28, 'Rg': 1.21, 'La': 1.80, 'Ce': 1.63, 'Pr': 1.76,
        'Nd': 1.74, 'Pm': 1.73, 'Sm': 1.72, 'Eu': 1.68, 'Gd': 1.69, 'Tb': 1.68, 'Dy': 1.67,
        'Ho': 1.66, 'Er': 1.65, 'Tm': 1.64, 'Yb': 1.70, 'Lu': 1.62, 'Ac': 1.86, 'Th': 1.75,
        'Pa': 1.69, 'U': 1.70, 'Np': 1.17, 'Pu': 1.72, 'Am': 1.66, 'Cm': 1.66, 'Bk': 1.68,
        'Cf': 1.68, 'Es': 1.65, 'Fm': 1.67, 'Md': 1.73, 'No': 1.76, 'Lr': 1.61}


[docs]def get_bonds(atoms, coordinates, RADIUS_BUFFER=0.45, MIN_BOND_DISTANCE=0.16): """ Estimate molecular bonding by calculating interatomic distance. If two atoms are closer to each other than the sum of their covalent radii and RADIUS_BUFFER then the atoms are considered bonded. If atoms are closer to each other than MIN_BOND_DISTANCE then they are not bonded. The covalent radii for atoms are taken from Pyykkö et al.[1]. Parameters ---------- atoms : list List of atom names. coordinates : list List of atomic coordinates. RADIUS_BUFFER : float Atomic radius buffer (Å). MIN_BOND_DISTANCE : float Minimum bonding distance (Å). Returns ------- list List of bonded atoms as tuples sorted according to atom index of the first atom. References ---------- .. [1] Pyykkö, Pekka, and Michiko Atsumi, *Molecular single‐bond covalent radii for elements 1–118.* Chemistry–A European Journal 15.1 (**2009**): 186-197. """ coors_z = list(enumerate(coordinates)) coors_z = sorted(coors_z, key=lambda x: x[1][2]) # Find the maximum radius among all atoms max_rad = max([rcov[i] for i in set(atoms)]) bonds = [] for i in range(0, len(coors_z)): max_cutoff = rcov[atoms[coors_z[i][0]]] + max_rad + RADIUS_BUFFER for j in range(i + 1, len(coors_z)): if abs(coors_z[j][1][2] - coors_z[i][1][2]) > max_cutoff: break distance = ((coors_z[j][1][0] - coors_z[i][1][0]) ** 2 + (coors_z[j][1][1] - coors_z[i][1][1]) ** 2 + (coors_z[j][1][2] - coors_z[i][1][2]) ** 2) ** 0.5 max_bond_distance = (rcov[atoms[coors_z[i][0]]] + rcov[atoms[coors_z[j][0]]] + RADIUS_BUFFER) if distance >= MIN_BOND_DISTANCE and distance <= max_bond_distance: bonds.append(tuple(sorted((coors_z[i][0], coors_z[j][0])))) return sorted(bonds)