in lmgvp/datasets.py [0:0]
def _dihedrals(self, X, eps=1e-7):
"""Compute sines and cosines dihedral angles (phi, psi, and omega)
Args:
X: torch.Tensor specifying coordinates of key atoms (N, CA, C, O) in 3D space with shape [seq_len, 4, 3]
eps: Float defining the epsilon using to clamp the angle between normals: min= -1*eps, max=1-eps
Returns:
Sines and cosines dihedral angles as a torch.Tensor of shape [seq_len, 6]
"""
# From https://github.com/jingraham/neurips19-graph-protein-design
X = torch.reshape(X[:, :3], [3 * X.shape[0], 3])
dX = X[1:] - X[:-1]
U = _normalize(dX, dim=-1)
u_2 = U[:-2]
u_1 = U[1:-1]
u_0 = U[2:]
# Backbone normals
n_2 = _normalize(torch.cross(u_2, u_1), dim=-1)
n_1 = _normalize(torch.cross(u_1, u_0), dim=-1)
# Angle between normals
cosD = torch.sum(n_2 * n_1, -1)
cosD = torch.clamp(cosD, -1 + eps, 1 - eps)
D = torch.sign(torch.sum(u_2 * n_1, -1)) * torch.acos(cosD)
# This scheme will remove phi[0], psi[-1], omega[-1]
D = F.pad(D, [1, 2])
D = torch.reshape(D, [-1, 3])
# Lift angle representations to the circle
D_features = torch.cat([torch.cos(D), torch.sin(D)], 1)
return D_features