Source code for torchref.restraints.ramachandran

"""
Ramachandran NLL surfaces for backbone restraints.

Pre-computed NLL = -log P(phi, psi | residue_type) surfaces derived from
MolProbity/cctbx distributions (6 residue-type-dependent surfaces at 1°
resolution).  The surfaces are stored as a single tensor of shape
(6, 360, 360) in ``torchref/data/rama_nll_surfaces.pt``.

Surface types
-------------
0  general      Standard amino acids (not GLY, PRO, ILE, VAL, pre-PRO)
1  glycine      Current residue is GLY
2  cis-proline  Current residue is PRO with cis peptide bond
3  trans-proline Current residue is PRO with trans peptide bond
4  pre-proline  Next residue is PRO
5  ile/val      Current residue is ILE or VAL
"""

from pathlib import Path

import torch

# ---------------------------------------------------------------------------
# Surface type constants
# ---------------------------------------------------------------------------

TYPE_GENERAL = 0
TYPE_GLYCINE = 1
TYPE_CIS_PROLINE = 2
TYPE_TRANS_PROLINE = 3
TYPE_PRE_PROLINE = 4
TYPE_ILE_VAL = 5

N_TYPES = 6
GRID_SIZE = 360  # 1° bins covering [-180, +180)

_DATA_FILE = Path(__file__).resolve().parent.parent / "data" / "rama_nll_surfaces.pt"


[docs] def load_nll_surfaces(device: torch.device) -> torch.Tensor: """Load pre-computed Ramachandran NLL surfaces. Parameters ---------- device : torch.device Target device for the returned tensor. Returns ------- torch.Tensor Shape ``(6, 360, 360)`` with NLL values. Index ``[type, i, j]`` corresponds to phi = (i - 180)° and psi = (j - 180)°. """ return torch.load(_DATA_FILE, map_location=device, weights_only=True)
[docs] def classify_residue( resname: str, next_resname: str, omega_deg: float = 180.0, ) -> int: """Determine the Ramachandran surface type for a residue. Parameters ---------- resname : str Three-letter residue name of the current residue. next_resname : str Three-letter residue name of the next residue in sequence. omega_deg : float Omega torsion angle in degrees (for cis/trans proline detection). Returns ------- int One of TYPE_GENERAL .. TYPE_ILE_VAL. """ if resname == "GLY": return TYPE_GLYCINE if resname == "PRO": # cis if |omega| < 90° if abs(omega_deg) < 90.0: return TYPE_CIS_PROLINE return TYPE_TRANS_PROLINE if next_resname == "PRO": return TYPE_PRE_PROLINE if resname in ("ILE", "VAL"): return TYPE_ILE_VAL return TYPE_GENERAL