Пример #1
0
def test_map_nucleotide():
    """Test the function map_nucleotide with some examples.
    """
    pyrimidines = ['C', 'T', 'U']
    purines = ['A', 'G']

    # Test that the standard bases are correctly identified
    assert struc.map_nucleotide(residue('U')) == ('U', True)
    assert struc.map_nucleotide(residue('A')) == ('A', True)
    assert struc.map_nucleotide(residue('T')) == ('T', True)
    assert struc.map_nucleotide(residue('G')) == ('G', True)
    assert struc.map_nucleotide(residue('C')) == ('C', True)

    # Test that some non_standard nucleotides are mapped correctly to
    # pyrimidine/purine references
    psu_tuple = struc.map_nucleotide(residue('PSU'))
    assert psu_tuple[0] in pyrimidines
    assert psu_tuple[1] == False

    psu_tuple = struc.map_nucleotide(residue('3MC'))
    assert psu_tuple[0] in pyrimidines
    assert psu_tuple[1] == False

    i_tuple = struc.map_nucleotide(residue('I'))
    assert i_tuple[0] in purines
    assert i_tuple[1] == False

    m7g_tuple = struc.map_nucleotide(residue('M7G'))
    assert m7g_tuple[0] in purines
    assert m7g_tuple[1] == False

    with pytest.warns(struc.IncompleteStructureWarning):
        assert struc.map_nucleotide(residue('ALA')) == (None, False)
Пример #2
0
def test_get_molecule_indices(array, as_stack, as_bonds):
    """
    Multiple tests to :func:`get_molecule_indices()` on a
    :class:`AtomArray` of random molecules.
    """
    if as_stack:
        array = struc.stack([array])

    if as_bonds:
        test_indices = struc.get_molecule_indices(array.bonds)
    else:
        test_indices = struc.get_molecule_indices(array)

    seen_atoms = 0
    for indices in test_indices:
        molecule = array[..., indices]
        # Assert that all residue IDs in the molecule are equal
        # -> all atoms from the same molecule
        assert (molecule.res_id == molecule.res_id[0]).all()
        # Assert that no atom is missing from the molecule
        assert molecule.array_length() \
            == info.residue(molecule.res_name[0]).array_length()
        seen_atoms += molecule.array_length()
    # Assert that all molecules are fond
    assert seen_atoms == array.array_length()
Пример #3
0
def array():
    """
    Create an :class:`AtomArray` containing a lot of different
    molecules.
    The atoms that belong to a single molecule are not adjacent in the
    :class:`AtomArray`, but a are shuffled in random positions of the
    :class:`AtomArray`.
    """
    MOL_NAMES = [
        "ARG",  # Molecule with multiple branches
        "TRP",  # Molecule with a cycle
        "GLC",  # Molecule with a cycle
        "NA",  # A single atom
        "ATP"  # Larger molecule
    ]
    N_MOLECULES = 20

    np.random.seed(0)

    atom_array = struc.AtomArray(0)
    for i, mol_name in enumerate(np.random.choice(MOL_NAMES, N_MOLECULES)):
        molecule = info.residue(mol_name)
        molecule.res_id[:] = i + 1
        atom_array += molecule

    reordered_indices = np.random.choice(np.arange(atom_array.array_length()),
                                         atom_array.array_length(),
                                         replace=False)
    atom_array = atom_array[reordered_indices]

    return atom_array
Пример #4
0
def test_pdbx_consistency(path):
    """
    Check if the structure parsed from a MOL file is equal to the same
    structure read from the *Chemical Component Dictionary* in PDBx
    format.

    In this case an SDF file is used, but it is compatible with the
    MOL format.
    """
    mol_name = split(splitext(path)[0])[1]
    ref_atoms = info.residue(mol_name)
    # The CCD contains information about aromatic bond types,
    # but the SDF test files do not
    ref_atoms.bonds.remove_aromaticity()

    mol_file = mol.MOLFile.read(path)
    test_atoms = mol_file.get_structure()

    assert test_atoms.coord.shape == ref_atoms.coord.shape
    assert test_atoms.coord.flatten().tolist() \
        == ref_atoms.coord.flatten().tolist()
    assert test_atoms.element.tolist() == ref_atoms.element.tolist()
    assert test_atoms.charge.tolist() == ref_atoms.charge.tolist()
    assert set(tuple(bond) for bond in test_atoms.bonds.as_array()) \
        == set(tuple(bond) for bond in  ref_atoms.bonds.as_array())
Пример #5
0
def flexGif(residue):
    mol = info.residue(residue)
    thetas = np.linspace(-30, 30, 60)
    thetas = np.append(thetas, np.linspace(30, 0, 30))
    for i, theta in enumerate(thetas):
        mol_new = rotate_residue(mol, 0, theta * np.pi / 180)
        plot(mol_new, save_as=f"./plots/res_flex/{i}.png", show=False)

    thetas = np.linspace(0, 30, 60)
    thetas = np.append(thetas, np.linspace(30, -30, 30))
    for j, theta in enumerate(thetas):
        mol_new = rotate_residue(mol, 1, theta * np.pi / 180)
        plot(mol_new, save_as=f"./plots/res_flex/{i+j}.png", show=False)
Пример #6
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)
Пример #7
0
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
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())
Пример #8
0
def test_docking(flexible):
    """
    Test :class:`VinaApp` for the case of docking biotin to
    streptavidin.
    The output binding pose should be very similar to the pose in the
    PDB structure.
    """
    # A structure of a straptavidin-biotin complex
    mmtf_file = mmtf.MMTFFile.read(join(data_dir("application"), "2rtg.mmtf"))
    structure = mmtf.get_structure(mmtf_file,
                                   model=1,
                                   extra_fields=["charge"],
                                   include_bonds=True)
    structure = structure[structure.chain_id == "B"]
    receptor = structure[struc.filter_amino_acids(structure)]
    ref_ligand = structure[structure.res_name == "BTN"]
    ref_ligand_coord = ref_ligand.coord

    ligand = info.residue("BTN")
    # Remove hydrogen atom that is missing in ref_ligand
    ligand = ligand[ligand.atom_name != "HO2"]

    if flexible:
        # Two residues within the binding pocket: ASN23, SER88
        flexible_mask = np.isin(receptor.res_id, (23, 88))
    else:
        flexible_mask = None

    app = VinaApp(ligand,
                  receptor,
                  struc.centroid(ref_ligand), [20, 20, 20],
                  flexible=flexible_mask)
    app.set_seed(0)
    app.start()
    app.join()

    test_ligand_coord = app.get_ligand_coord()
    test_receptor_coord = app.get_receptor_coord()
    energies = app.get_energies()
    # One energy value per model
    assert len(test_ligand_coord) == len(energies)
    assert len(test_receptor_coord) == len(energies)

    assert np.all(energies < 0)

    # Select best binding pose
    test_ligand_coord = test_ligand_coord[0]
    not_nan_mask = ~np.isnan(test_ligand_coord).any(axis=-1)
    ref_ligand_coord = ref_ligand_coord[not_nan_mask]
    test_ligand_coord = test_ligand_coord[not_nan_mask]
    # Check if it least one atom is preserved
    assert test_ligand_coord.shape[1] > 0
    rmsd = struc.rmsd(ref_ligand_coord, test_ligand_coord)
    # The deviation of the best pose from the real conformation
    # should be less than 1 Å
    assert rmsd < 1.0

    if flexible:
        # Select best binding pose
        test_receptor_coord = test_receptor_coord[0]
        not_nan_mask = ~np.isnan(test_receptor_coord).any(axis=-1)
        ref_receptor_coord = receptor[not_nan_mask]
        test_receptor_coord = test_receptor_coord[not_nan_mask]
        # Check if it least one atom is preserved
        assert test_receptor_coord.shape[1] > 0
        # The flexible residues should have a maximum deviation of 1 Å
        # from the original conformation
        assert np.max(struc.distance(test_receptor_coord,
                                     ref_receptor_coord)) < 1.0
    else:
        ref_receptor_coord = receptor.coord
        for model_coord in test_receptor_coord:
            assert np.array_equal(model_coord, ref_receptor_coord)
Пример #9
0
    # Include formal charge for accurate partial charge calculation
    mmtf_file,
    model=1,
    include_bonds=True,
    extra_fields=["charge"])
# The asymmetric unit describes a streptavidin homodimer
# However, we are only interested in a single monomer
structure = structure[structure.chain_id == "B"]
receptor = structure[struc.filter_amino_acids(structure)]

ref_ligand = structure[structure.res_name == "BTN"]
ref_ligand_center = struc.centroid(ref_ligand)

# Independently, get the ligand without optimized conformation
# from the chemical components dictionary
ligand = info.residue("BTN")

# Search for a binding mode in a 20 Å radius
# of the original ligand position
app = autodock.VinaApp(ligand, receptor, ref_ligand_center, [20, 20, 20])
# For reproducibility
app.set_seed(0)
# This is the maximum number:
# Vina may find less interesting binding modes
# and thus output less models
app.set_max_number_of_models(100)
# Effectively no limit
app.set_energy_range(100.0)
# Start docking run
app.start()
app.join()
Пример #10
0
ELEMENT_FONT_SIZE = 10
# The scaling factor of the atom 'balls'
BALL_SCALE = 20
# The higher this number, the more detailed are the rays
N_RAY_STEPS = 20
# The scaling factor of the 'ray' of charged molecules
RAY_SCALE = 100
# The transparency value for each 'ray ring'
RAY_ALPHA = 0.03
# The color map to use to depict the charge
CMAP_NAME = "bwr_r"



# Get an atom array for the selected molecule
molecule = info.residue(MOLECULE_NAME)

# Align molecule with principal component analysis:
# The component with the least variance, i.e. the axis with the lowest
# number of atoms lying over each other, is aligned to the z-axis,
# which points into the plane of the figure
pca = PCA(n_components=3)
pca.fit(molecule.coord)
molecule = struc.align_vectors(molecule, pca.components_[-1], [0, 0, 1])

# Balls should be colored by partial charge
charges = struc.partial_charges(molecule, ITERATION_NUMBER)
# Later this variable stores values between 0 and 1 for use in color map
normalized_charges = charges.copy()
# Show no partial charge for atoms
# that are not parametrized for the PEOE algorithm
Пример #11
0
This example displays the small molecule caffeine.
"""

# Code source: Patrick Kunzmann
# License: BSD 3 clause

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import biotite.structure as struc
import biotite.structure.info as info
import biotite.structure.graphics as graphics

# Get an atom array for caffeine
# Caffeine has the PDB reside name 'CFF'
caffeine = info.residue("CFF")

# For cosmetic purposes align central rings to x-y plane
n1 = caffeine[caffeine.atom_name == "N1"][0]
n3 = caffeine[caffeine.atom_name == "N3"][0]
n7 = caffeine[caffeine.atom_name == "N7"][0]
# Normal vector of ring plane
normal = np.cross(n1.coord - n3.coord, n1.coord - n7.coord)
# Align ring plane normal to z-axis
caffeine = struc.align_vectors(caffeine, normal, np.array([0, 0, 1]))

# Caffeine should be colored by element
colors = np.zeros((caffeine.array_length(), 3))
colors[caffeine.element == "H"] = (0.8, 0.8, 0.8)  # gray
colors[caffeine.element == "C"] = (0.0, 0.8, 0.0)  # green
colors[caffeine.element == "N"] = (0.0, 0.0, 0.8)  # blue
Пример #12
0
def assemble_peptide(sequence):
    res_names = [seq.ProteinSequence.convert_letter_1to3(r) for r in sequence]
    peptide = struc.AtomArray(length=0)

    for res_id, res_name, connect_angle in zip(
            np.arange(1,
                      len(res_names) + 1), res_names,
            itertools.cycle([120, -120])):
        # Create backbone
        atom_n = struc.Atom([0.0, 0.0, 0.0], atom_name="N", element="N")

        atom_ca = struc.Atom([0.0, N_CA_LENGTH, 0.0],
                             atom_name="CA",
                             element="C")

        coord_c = calculate_atom_coord_by_z_rotation(atom_ca.coord,
                                                     atom_n.coord, 120,
                                                     CA_C_LENGTH)
        atom_c = struc.Atom(coord_c, atom_name="C", element="C")

        coord_o = calculate_atom_coord_by_z_rotation(atom_c.coord,
                                                     atom_ca.coord, 120,
                                                     C_O_DOUBLE_LENGTH)
        atom_o = struc.Atom(coord_o, atom_name="O", element="O")

        coord_h = calculate_atom_coord_by_z_rotation(atom_n.coord,
                                                     atom_ca.coord, -120,
                                                     N_H_LENGTH)
        atom_h = struc.Atom(coord_h, atom_name="H", element="H")

        backbone = struc.array([atom_n, atom_ca, atom_c, atom_o, atom_h])
        backbone.res_id[:] = res_id
        backbone.res_name[:] = res_name

        # Add bonds between backbone atoms
        bonds = struc.BondList(backbone.array_length())
        bonds.add_bond(0, 1, struc.BondType.SINGLE)  # N-CA
        bonds.add_bond(1, 2, struc.BondType.SINGLE)  # CA-C
        bonds.add_bond(2, 3, struc.BondType.DOUBLE)  # C-O
        bonds.add_bond(0, 4, struc.BondType.SINGLE)  # N-H
        backbone.bonds = bonds

        # Get residue from dataset
        residue = info.residue(res_name)
        # Superimpose backbone of residue
        # with backbone created previously
        _, transformation = struc.superimpose(
            backbone[struc.filter_backbone(backbone)],
            residue[struc.filter_backbone(residue)])
        residue = struc.superimpose_apply(residue, transformation)
        # Remove backbone atoms from residue because they are already
        # existing in the backbone created prevoisly
        side_chain = residue[~np.isin(
            residue.
            atom_name, ["N", "CA", "C", "O", "OXT", "H", "H2", "H3", "HXT"])]

        # Assemble backbone with side chain (including HA)
        # and set annotation arrays
        residue = backbone + side_chain
        residue.bonds.add_bond(
            np.where(residue.atom_name == "CA")[0][0],
            np.where(residue.atom_name == "CB")[0][0], struc.BondType.SINGLE)
        residue.bonds.add_bond(
            np.where(residue.atom_name == "CA")[0][0],
            np.where(residue.atom_name == "HA")[0][0], struc.BondType.SINGLE)
        residue.chain_id[:] = "A"
        residue.res_id[:] = res_id
        residue.res_name[:] = res_name
        peptide += residue

        # Connect current residue to existing residues in the chain
        if res_id > 1:
            index_prev_ca = np.where((peptide.res_id == res_id - 1)
                                     & (peptide.atom_name == "CA"))[0][0]
            index_prev_c = np.where((peptide.res_id == res_id - 1)
                                    & (peptide.atom_name == "C"))[0][0]
            index_curr_n = np.where((peptide.res_id == res_id)
                                    & (peptide.atom_name == "N"))[0][0]
            index_curr_c = np.where((peptide.res_id == res_id)
                                    & (peptide.atom_name == "C"))[0][0]
            curr_residue_mask = peptide.res_id == res_id

            # Adjust geometry
            curr_coord_n = calculate_atom_coord_by_z_rotation(
                peptide.coord[index_prev_c], peptide.coord[index_prev_ca],
                connect_angle, C_N_LENGTH)
            peptide.coord[curr_residue_mask] -= peptide.coord[index_curr_n]
            peptide.coord[curr_residue_mask] += curr_coord_n
            # Adjacent residues should show in opposing directions
            # -> rotate residues with even residue ID by 180 degrees
            if res_id % 2 == 0:
                coord_n = peptide.coord[index_curr_n]
                coord_c = peptide.coord[index_curr_c]
                peptide.coord[curr_residue_mask] = struc.rotate_about_axis(
                    atoms=peptide.coord[curr_residue_mask],
                    axis=coord_c - coord_n,
                    angle=np.deg2rad(180),
                    support=coord_n)

            # Add bond between previous C and current N
            peptide.bonds.add_bond(index_prev_c, index_curr_n,
                                   struc.BondType.SINGLE)

    # Add N-terminal hydrogen
    atom_n = peptide[(peptide.res_id == 1) & (peptide.atom_name == "N")][0]
    atom_h = peptide[(peptide.res_id == 1) & (peptide.atom_name == "H")][0]
    coord_h2 = calculate_atom_coord_by_z_rotation(atom_n.coord, atom_h.coord,
                                                  -120, N_H_LENGTH)
    atom_h2 = struc.Atom(coord_h2,
                         chain_id="A",
                         res_id=1,
                         res_name=atom_h.res_name,
                         atom_name="H2",
                         element="H")
    peptide = struc.array([atom_h2]) + peptide
    peptide.bonds.add_bond(0, 1, struc.BondType.SINGLE)  # H2-N

    # Add C-terminal hydroxyl group
    last_id = len(sequence)
    index_c = np.where((peptide.res_id == last_id)
                       & (peptide.atom_name == "C"))[0][0]
    index_o = np.where((peptide.res_id == last_id)
                       & (peptide.atom_name == "O"))[0][0]
    coord_oxt = calculate_atom_coord_by_z_rotation(peptide.coord[index_c],
                                                   peptide.coord[index_o],
                                                   connect_angle, C_O_LENGTH)
    coord_hxt = calculate_atom_coord_by_z_rotation(coord_oxt,
                                                   peptide.coord[index_c],
                                                   connect_angle, O_H_LENGTH)
    atom_oxt = struc.Atom(coord_oxt,
                          chain_id="A",
                          res_id=last_id,
                          res_name=peptide[index_c].res_name,
                          atom_name="OXT",
                          element="O")
    atom_hxt = struc.Atom(coord_hxt,
                          chain_id="A",
                          res_id=last_id,
                          res_name=peptide[index_c].res_name,
                          atom_name="HXT",
                          element="H")
    peptide = peptide + struc.array([atom_oxt, atom_hxt])
    peptide.bonds.add_bond(index_c, -2, struc.BondType.SINGLE)  # C-OXT
    peptide.bonds.add_bond(-2, -1, struc.BondType.SINGLE)  # OXT-HXT

    return peptide
Пример #13
0
ampicillin.
"""

# Code source: Patrick Kunzmann
# License: CC0

import biotite.structure as struc
import biotite.structure.info as info
import ammolite


PNG_SIZE = (600, 600)

########################################################################

ampicillin = info.residue("AIC")

pymol_obj = ammolite.PyMOLObject.from_structure(ampicillin)
ammolite.show(PNG_SIZE)

########################################################################

ammolite.cmd.orient()
ammolite.cmd.zoom(buffer=2.0)
ammolite.show(PNG_SIZE)

########################################################################

pymol_obj.show("spheres")
pymol_obj.color("black", ampicillin.element == "C")
ammolite.cmd.set("stick_radius", 0.15)
Пример #14
0
        mol_new = rotate_residue(mol, 0, theta * np.pi / 180)
        plot(mol_new, save_as=f"./plots/res_flex/{i}.png", show=False)

    thetas = np.linspace(0, 30, 60)
    thetas = np.append(thetas, np.linspace(30, -30, 30))
    for j, theta in enumerate(thetas):
        mol_new = rotate_residue(mol, 1, theta * np.pi / 180)
        plot(mol_new, save_as=f"./plots/res_flex/{i+j}.png", show=False)


acids = ['ala','arg','asn','asp','cys','gln','glu','his',\
         'leu','lys','met','phe','pyl','ser','sec','thr','trp','tyr',\
         'val']
chi = np.linspace(0, 359, 360)
np.save("chi.npy", chi)

for acid in acids:
    # --- get base residue ---
    residue = info.residue(acid.upper())

    # --- create directory ---
    pth = f"./data/psi4files/{acid}"
    if not os.path.exists(pth):
        os.makedirs(pth)

    for i in range(len(chi)):
        res = rotate_residue(residue, 0, chi[i] * np.pi / 180)
        f = open(f"{pth}/{acid}_{chi[i]}.txt", "w")
        f.write(mkpsi4(res))
        f.close()