RFdiffusion get_torsions函数解读

[复制链接]
发表于 2025-12-3 00:57:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
函数功能
get_torsions 函数根据输入的原子坐标(xyz_in)和氨基酸序列(seq),盘算一组主链和侧链的扭转角(torsions)。同时天生备用扭转角(torsions_alt),用于表现可以镜像翻转的多少结构,并返回掩码(tors_mask)和是否平面化(tors_planar)的信息。
输入参数

      
  • xyz_in: 原子坐标张量,外形 [B, L, 27, 3],此中 B 是批量巨细,L 是残基数目,27 表现原子范例(如 N, CA, C, CB),3 是坐标。  
  • seq: 氨基酸序列,外形 [B, L],每个值对应氨基酸编号。  
  • torsion_indices: 表现盘算侧链扭转角所需的 4 个原子索引。  
  • torsion_can_flip: 布尔数组,指示哪些扭转角可以翻转。  
  • ref_angles: 抱负化的参考角度,重要用于 CB 弯曲、CB 扭转和 CG 弯曲。  
  • mask_in: 掩码(可选),用于屏蔽特定残基。
返回值
      
  • torsions: 主链和侧链的扭转角张量,外形 [B, L, 10, 2]。  
  • torsions_alt: 扭转角备用版本(翻转版),外形同上。  
  • tors_mask: 扭转角的有用掩码。  
  • tors_planar: 布尔掩码,指示哪些扭转角是平面的。
源代码:

  1. def get_torsions(
  2.     xyz_in, seq, torsion_indices, torsion_can_flip, ref_angles, mask_in=None
  3. ):
  4.     B, L = xyz_in.shape[:2]
  5.     tors_mask = get_tor_mask(seq, torsion_indices, mask_in)
  6.     # torsions to restrain to 0 or 180degree
  7.     tors_planar = torch.zeros((B, L, 10), dtype=torch.bool, device=xyz_in.device)
  8.     tors_planar[:, :, 5] = seq == aa2num["TYR"]  # TYR chi 3 should be planar
  9.     # idealize given xyz coordinates before computing torsion angles
  10.     xyz = xyz_in.clone()
  11.     Rs, Ts = rigid_from_3_points(xyz[..., 0, :], xyz[..., 1, :], xyz[..., 2, :])
  12.     Nideal = torch.tensor([-0.5272, 1.3593, 0.000], device=xyz_in.device)
  13.     Cideal = torch.tensor([1.5233, 0.000, 0.000], device=xyz_in.device)
  14.     xyz[..., 0, :] = torch.einsum("brij,j->bri", Rs, Nideal) + Ts
  15.     xyz[..., 2, :] = torch.einsum("brij,j->bri", Rs, Cideal) + Ts
  16.     torsions = torch.zeros((B, L, 10, 2), device=xyz.device)
  17.     # avoid undefined angles for H generation
  18.     torsions[:, 0, 1, 0] = 1.0
  19.     torsions[:, -1, 0, 0] = 1.0
  20.     # omega
  21.     torsions[:, :-1, 0, :] = th_dih(
  22.         xyz[:, :-1, 1, :], xyz[:, :-1, 2, :], xyz[:, 1:, 0, :], xyz[:, 1:, 1, :]
  23.     )
  24.     # phi
  25.     torsions[:, 1:, 1, :] = th_dih(
  26.         xyz[:, :-1, 2, :], xyz[:, 1:, 0, :], xyz[:, 1:, 1, :], xyz[:, 1:, 2, :]
  27.     )
  28.     # psi
  29.     torsions[:, :, 2, :] = -1 * th_dih(
  30.         xyz[:, :, 0, :], xyz[:, :, 1, :], xyz[:, :, 2, :], xyz[:, :, 3, :]
  31.     )
  32.     # chis
  33.     ti0 = torch.gather(xyz, 2, torsion_indices[seq, :, 0, None].repeat(1, 1, 1, 3))
  34.     ti1 = torch.gather(xyz, 2, torsion_indices[seq, :, 1, None].repeat(1, 1, 1, 3))
  35.     ti2 = torch.gather(xyz, 2, torsion_indices[seq, :, 2, None].repeat(1, 1, 1, 3))
  36.     ti3 = torch.gather(xyz, 2, torsion_indices[seq, :, 3, None].repeat(1, 1, 1, 3))
  37.     torsions[:, :, 3:7, :] = th_dih(ti0, ti1, ti2, ti3)
  38.     # CB bend
  39.     NC = 0.5 * (xyz[:, :, 0, :3] + xyz[:, :, 2, :3])
  40.     CA = xyz[:, :, 1, :3]
  41.     CB = xyz[:, :, 4, :3]
  42.     t = th_ang_v(CB - CA, NC - CA)
  43.     t0 = ref_angles[seq][..., 0, :]
  44.     torsions[:, :, 7, :] = torch.stack(
  45.         (torch.sum(t * t0, dim=-1), t[..., 0] * t0[..., 1] - t[..., 1] * t0[..., 0]),
  46.         dim=-1,
  47.     )
  48.     # CB twist
  49.     NCCA = NC - CA
  50.     NCp = xyz[:, :, 2, :3] - xyz[:, :, 0, :3]
  51.     NCpp = (
  52.         NCp
  53.         - torch.sum(NCp * NCCA, dim=-1, keepdim=True)
  54.         / torch.sum(NCCA * NCCA, dim=-1, keepdim=True)
  55.         * NCCA
  56.     )
  57.     t = th_ang_v(CB - CA, NCpp)
  58.     t0 = ref_angles[seq][..., 1, :]
  59.     torsions[:, :, 8, :] = torch.stack(
  60.         (torch.sum(t * t0, dim=-1), t[..., 0] * t0[..., 1] - t[..., 1] * t0[..., 0]),
  61.         dim=-1,
  62.     )
  63.     # CG bend
  64.     CG = xyz[:, :, 5, :3]
  65.     t = th_ang_v(CG - CB, CA - CB)
  66.     t0 = ref_angles[seq][..., 2, :]
  67.     torsions[:, :, 9, :] = torch.stack(
  68.    
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表