Backbone orientations/translations
In this tutorial, we learn how to obtain backbone orientations and translations from protein structures using protstruc
. For each residue, a 3x3 backbone orientation matrix is defined by a Gram-Schmidt orthonormalized basis of two vectors: N-Ca and C-Ca vectors. Meanwhile, a three-element translation vector is simply defined as a coordinate of the Ca atom.
In [1]:
Copied!
import protstruc as ps
import matplotlib.pyplot as plt
import numpy as np
import protstruc as ps
import matplotlib.pyplot as plt
import numpy as np
In [2]:
Copied!
pdb_ids = ['1REX', '4EOT']
sb = ps.StructureBatch.from_pdb_id(pdb_ids)
pdb_ids = ['1REX', '4EOT']
sb = ps.StructureBatch.from_pdb_id(pdb_ids)
Extracting backbone orientations and translations from StructureBatch
object¶
In [3]:
Copied!
orientations = sb.backbone_orientations(a1='N', a2='CA', a3='C').numpy()
translations = sb.backbone_translations(atom='CA').numpy()
orientations.shape, translations.shape
orientations = sb.backbone_orientations(a1='N', a2='CA', a3='C').numpy()
translations = sb.backbone_translations(atom='CA').numpy()
orientations.shape, translations.shape
Out[3]:
((2, 184, 3, 3), (2, 184, 3))
Orthogonality of residue frames (orientations)¶
Let's check whether vectors forming residue frames (which represent the orientation of residues) are orthogonal for each others.
In [4]:
Copied!
from itertools import combinations
for i, j in combinations([0, 1, 2], 2):
inner_products = (orientations[:, :, :, i] * orientations[:, :, :, j]).sum(axis=2)
assert np.allclose(inner_products[~np.isnan(inner_products)], 0.0, atol=1e-6)
from itertools import combinations
for i, j in combinations([0, 1, 2], 2):
inner_products = (orientations[:, :, :, i] * orientations[:, :, :, j]).sum(axis=2)
assert np.allclose(inner_products[~np.isnan(inner_products)], 0.0, atol=1e-6)
In [5]:
Copied!
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
prt_idx = 1
chain_idx = sb.get_chain_idx()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
# plot backbone CA atoms
ax.plot(
translations[prt_idx, chain_mask, 0],
translations[prt_idx, chain_mask, 1],
translations[prt_idx, chain_mask, 2],
)
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
prt_idx = 1
chain_idx = sb.get_chain_idx()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
# plot backbone CA atoms
ax.plot(
translations[prt_idx, chain_mask, 0],
translations[prt_idx, chain_mask, 1],
translations[prt_idx, chain_mask, 2],
)
Visualizing both the orientations and translations of residues¶
In [6]:
Copied!
sb = ps.StructureBatch.from_pdb('4EOT.pdb')
t = sb.backbone_translations()[0].numpy()
o = sb.backbone_orientations()[0].numpy()
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
prt_idx = 0
chain_idx = sb.get_chain_idx()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
x, y, z = t[chain_mask, 0], t[chain_mask, 1], t[chain_mask, 2]
o_x, o_y, o_z = o[chain_mask, :, 0], o[chain_mask, :, 1], o[chain_mask, :, 2]
lw, length = 0.75, 1.5
ax.quiver(x, y, z, o_x[:, 0], o_x[:, 1], o_x[:, 2], color='C0', linewidth=lw, length=length)
ax.quiver(x, y, z, o_y[:, 0], o_y[:, 1], o_y[:, 2], color='C1', linewidth=lw, length=length)
ax.quiver(x, y, z, o_z[:, 0], o_z[:, 1], o_z[:, 2], color='C2', linewidth=lw, length=length)
ax.plot(x, y, z, c='C7', linewidth=0.5)
ax.view_init(30, 30)
sb = ps.StructureBatch.from_pdb('4EOT.pdb')
t = sb.backbone_translations()[0].numpy()
o = sb.backbone_orientations()[0].numpy()
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
prt_idx = 0
chain_idx = sb.get_chain_idx()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
x, y, z = t[chain_mask, 0], t[chain_mask, 1], t[chain_mask, 2]
o_x, o_y, o_z = o[chain_mask, :, 0], o[chain_mask, :, 1], o[chain_mask, :, 2]
lw, length = 0.75, 1.5
ax.quiver(x, y, z, o_x[:, 0], o_x[:, 1], o_x[:, 2], color='C0', linewidth=lw, length=length)
ax.quiver(x, y, z, o_y[:, 0], o_y[:, 1], o_y[:, 2], color='C1', linewidth=lw, length=length)
ax.quiver(x, y, z, o_z[:, 0], o_z[:, 1], o_z[:, 2], color='C2', linewidth=lw, length=length)
ax.plot(x, y, z, c='C7', linewidth=0.5)
ax.view_init(30, 30)
Initializing a new StructureBatch object from residue orientations and translations¶
In [7]:
Copied!
pdb_ids = ['1REX', '4EOT']
sb = ps.StructureBatch.from_pdb_id(pdb_ids)
orientations = sb.backbone_orientations(a1='N', a2='CA', a3='C')
translations = sb.backbone_translations(atom='CA')
orientations.shape, translations.shape
pdb_ids = ['1REX', '4EOT']
sb = ps.StructureBatch.from_pdb_id(pdb_ids)
orientations = sb.backbone_orientations(a1='N', a2='CA', a3='C')
translations = sb.backbone_translations(atom='CA')
orientations.shape, translations.shape
Out[7]:
(torch.Size([2, 184, 3, 3]), torch.Size([2, 184, 3]))
In [8]:
Copied!
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122, projection='3d')
prt_idx = 1
chain_idx = sb.get_chain_idx()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
# plot backbone CA atoms
ax.plot(
translations[prt_idx, chain_mask, 0].numpy(),
translations[prt_idx, chain_mask, 1].numpy(),
translations[prt_idx, chain_mask, 2].numpy(),
)
ax.set_title('Original')
# Reinitialize StructureBatch only using backbone orientations and translations
sb2 = ps.StructureBatch.from_backbone_orientations_translations(
orientations, translations, chain_idx, sb.get_chain_ids(), sb.get_seq()
)
t = sb2.backbone_translations()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
ax2.plot(
t[prt_idx, chain_mask, 0].numpy(),
t[prt_idx, chain_mask, 1].numpy(),
t[prt_idx, chain_mask, 2].numpy(),
)
ax2.set_title('Reinitialized')
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122, projection='3d')
prt_idx = 1
chain_idx = sb.get_chain_idx()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
# plot backbone CA atoms
ax.plot(
translations[prt_idx, chain_mask, 0].numpy(),
translations[prt_idx, chain_mask, 1].numpy(),
translations[prt_idx, chain_mask, 2].numpy(),
)
ax.set_title('Original')
# Reinitialize StructureBatch only using backbone orientations and translations
sb2 = ps.StructureBatch.from_backbone_orientations_translations(
orientations, translations, chain_idx, sb.get_chain_ids(), sb.get_seq()
)
t = sb2.backbone_translations()
for idx in [0, 1]:
chain_mask = chain_idx[prt_idx] == idx
ax2.plot(
t[prt_idx, chain_mask, 0].numpy(),
t[prt_idx, chain_mask, 1].numpy(),
t[prt_idx, chain_mask, 2].numpy(),
)
ax2.set_title('Reinitialized')
Out[8]:
Text(0.5, 0.92, 'Reinitialized')
In [ ]:
Copied!