Get dihedral angles#

Calculating dihedral and torsional angles from atom quartets.

The function molsysmt.structure.get_dihedral_angles() calculates dihedral angles defined by four consecutively bonded atoms \((A, B, C, D)\), measuring the angle between planes \((A, B, C)\) and \((B, C, D)\).

Added in version 1.0.0.

Basic usage#

Let’s measure the backbone \(\phi\) dihedral angles of Met-enkephalin:

import molsysmt as msm
import pyunitwizard as puw
import matplotlib.pyplot as plt
molsys = msm.convert(msm.systems['Met-enkephalin']['met_enkephalin.h5msm'])

We query the backbone \(\phi\) atom quartets using molsysmt.topology.get_dihedral_quartets() and calculate their angles:

phi_quartets = msm.topology.get_dihedral_quartets(molsys, phi=True)
phi_angles = msm.structure.get_dihedral_angles(molsys, dihedral_quartets=phi_quartets)
print('Phi angles (degrees):', puw.convert(phi_angles, to_unit='degrees'))
Phi angles (degrees): [[-179.99977050951892 -179.9997685580422 -179.99976916196186  -179.99977065567504]] degree

Measuring sidechain dihedral angles#

In addition to backbone angles, sidechain torsional angles (such as \(\chi_1, \chi_2\)) or custom quartets can be queried and evaluated:

chi1_quartets = msm.topology.get_dihedral_quartets(molsys, chi1=True)
chi1_angles = msm.structure.get_dihedral_angles(molsys, dihedral_quartets=chi1_quartets)
print(f'Identified {len(chi1_quartets)} chi1 quartets.')
print('Chi1 dihedral angles (degrees):', puw.convert(chi1_angles, to_unit='degrees'))
Identified 3 chi1 quartets.
Chi1 dihedral angles (degrees): [[-179.99988816868782 -179.99988283064798 -179.99992497471675]] degree

Ramachandran conformational distribution across structural ensembles#

By computing backbone \(\phi\) and \(\psi\) dihedral angles across an ensemble of structures, we can map the conformational space onto a classic 2D Ramachandran plot:

traj = msm.convert(msm.systems['pentalanine']['traj_pentalanine.h5msm'])
phi_q = msm.topology.get_dihedral_quartets(traj, phi=True)
psi_q = msm.topology.get_dihedral_quartets(traj, psi=True)

phi_vals = msm.structure.get_dihedral_angles(traj, dihedral_quartets=phi_q[1])
psi_vals = msm.structure.get_dihedral_angles(traj, dihedral_quartets=psi_q[1])

phi_deg = puw.get_value(puw.convert(phi_vals[:, 0], to_unit='degrees'))
psi_deg = puw.get_value(puw.convert(psi_vals[:, 0], to_unit='degrees'))
fig, ax = plt.subplots(figsize=(5, 5))
ax.scatter(phi_deg, psi_deg, alpha=0.3, s=10, c='navy')
ax.set_xlim(-180, 180)
ax.set_ylim(-180, 180)
ax.set_xlabel('$\\phi$ (degrees)')
ax.set_ylabel('$\\psi$ (degrees)')
ax.set_title('Ramachandran Plot (Residue 2)')
ax.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
../../../../_images/e4c3d084da54d2a17de3c82576f62dcd0fb06d6bcf7d1edc68ce4675a12ba5ae.png