def rotate_residue(mol, bond_number, angle):

    # --- Identify rotatable bonds ---
    rotatable_bonds = struc.find_rotatable_bonds(mol.bonds)

    # --- do not rotate about backbone bonds ---
    for atom_name in BACKBONE:
        index = np.where(mol.atom_name == atom_name)[0][0]
        rotatable_bonds.remove_bonds_to(index)

    # --- init coordinates for new model ---
    coord = mol.coord.copy()

    # --- get bond axis ---
    atom_i, atom_j, _ = rotatable_bonds.as_array()[bond_number]
    axis = coord[atom_j] - coord[atom_i]

    # --- get support atom ---
    support = coord[atom_i]

    # --- need to get atoms only on one side of the bond ---
    bond_list_without_axis = mol.bonds.copy()
    bond_list_without_axis.remove_bond(atom_i, atom_j)
    rotated_atom_indices = struc.find_connected(bond_list_without_axis,
                                                root=atom_j)

    # --- rotate atoms ---
    coord[rotated_atom_indices] = struc.rotate_about_axis(
        coord[rotated_atom_indices], axis, angle, support)

    atom_list = []
    for i, atom_i in enumerate(mol):
        atom_new = struc.Atom(coord[i],
                              atom_name=atom_i.atom_name,
                              element=atom_i.element)
        atom_list.append(atom_new)
    new_mol = struc.array(atom_list)
    new_mol.res_id[:] = mol.res_id
    new_mol.res_name[:] = mol.res_name
    new_mol.bonds = mol.bonds.copy()

    return new_mol
Exemple #2
0
def test_find_rotatable_bonds(res_name, expected_bonds):
    """
    Check the :func:`find_rotatable_bonds()` function based on
    known examples.
    """
    molecule = info.residue(res_name)

    ref_bond_set = {
        tuple(sorted((name_i, name_j)))
        for name_i, name_j in expected_bonds
    }

    rotatable_bonds = struc.find_rotatable_bonds(molecule.bonds)
    test_bond_set = set()
    for i, j, _ in rotatable_bonds.as_array():
        test_bond_set.add(
            tuple(sorted((molecule.atom_name[i], molecule.atom_name[j]))))

    # Compare with reference bonded atom names
    assert test_bond_set == ref_bond_set
    # All rotatable bonds must be single bonds
    assert np.all(rotatable_bonds.as_array()[:, 2] == struc.BondType.SINGLE)
Exemple #3
0
import biotite.structure as struc
import biotite.structure.io as strucio
import biotite.structure.info as info
import biotite.structure.graphics as graphics

# 'CA' is not in backbone,
# as we want to include the rotation between 'CA' and 'CB'
BACKBONE = ["N", "C", "O", "OXT"]
LIBRARY_SIZE = 9

# Get the structure (including bonds) from the standard RCSB compound
residue = info.residue("TYR")
bond_list = residue.bonds

### Identify rotatable bonds ###
rotatable_bonds = struc.find_rotatable_bonds(residue.bonds)
# Do not rotate about backbone bonds,
# as these are irrelevant for a amino rotamer library
for atom_name in BACKBONE:
    index = np.where(residue.atom_name == atom_name)[0][0]
    rotatable_bonds.remove_bonds_to(index)
print("Rotatable bonds in tyrosine:")
for atom_i, atom_j, _ in rotatable_bonds.as_array():
    print(residue.atom_name[atom_i] + " <-> " + residue.atom_name[atom_j])

### VdW radii of each atom, required for the next step ###
vdw_radii = np.zeros(residue.array_length())
for i, element in enumerate(residue.element):
    vdw_radii[i] = info.vdw_radius_single(element)
# The Minimum required distance between two atoms is mean of their
# VdW radii