ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

肉眼看重合的结构,RMSD差出3Å:AlphaFold结构比较(RMSD与lDDT)源码走读

肉眼看重合的结构,RMSD差出3Å:AlphaFold结构比较(RMSD与lDDT)源码走读 肉眼看重合的结构RMSD差出3ÅAlphaFold结构比较RMSD与lDDT源码走读【免费下载链接】alphafoldOpen source code for AlphaFold 2.项目地址: https://gitcode.com/GitHub_Trending/al/alphafold给一批突变体做结构比较时我们卡在一个数字上两个模型在 PyMOL 里几乎完全套叠一个工具报 RMSD 0.8Å另一个报 3.7Å。AlphaFold 对此的答案有点意思——仓库里有个叫 lDDT 的结构比较指标完全不需要对齐它还是模型置信度的老师。上面数字打架根源就在有没有先对齐这一步。把结构相似量化成三个问题两个结构像不像其实是三个独立问题答错任意一个数字都会对不上。问题一比的是坐标还是距离RMSD 的答案是绝对坐标把两个结构套叠到同一坐标系再逐原子比差值。lDDT 的答案是原子对距离两点间距离在刚体平移/旋转下不变所以两个结构根本不需要放进同一坐标系。这是后面一切差异的源头。问题二姿态不一致先对齐还是跳过需要走对齐路线时标准流程是 Kabsch求让均方距离最小的旋转 R 和平移 t再在套叠后的坐标上算 RMSD。代价是用哪些原子对齐、裁哪段序列成为结果的一部分换一套参数数字就变。lDDT 路线把这步整个跳过了。问题三缺失原子怎么办实验结构总有缺的侧链预测结构也未必建齐了同样的原子。lDDT 的答案是掩码把原子存在性乘进参与评分的点对集合任一侧缺失的点对直接不计入分母。lddt.lddt 源码精读88行的四步走全仓库搜rmsd真正的计算只有一处后文会贴主预测流程里没有一处 Kabsch——AlphaFold 选模型时看的不是经典 RMSD是 lDDT。所以下面精读 lddt.py整个函数就四步。先算距离矩阵为什么不是直接减坐标# Compute true and predicted distance matrices. dmat_true jnp.sqrt(1e-10 jnp.sum( (true_points[:, :, None] - true_points[:, None, :])**2, axis-1)) dmat_predicted jnp.sqrt(1e-10 jnp.sum( (predicted_points[:, :, None] - predicted_points[:, None, :])**2, axis-1)) dists_to_score ( (dmat_true cutoff).astype(jnp.float32) * true_points_mask * jnp.transpose(true_points_mask, [0, 2, 1]) * (1. - jnp.eye(dmat_true.shape[1])) # Exclude self-interaction. )这么写的动机是superposition-free比坐标就绕不开对齐比距离则天然免疫姿态差异。两行广播相减、无循环无分支(batch, len, len) 距离矩阵一次算完JAX 梯度可以直通1e-10是防 sqrt 在零点梯度爆炸的数值保护。数学上就是$$d_{ij} \sqrt{\sum_{c1}^{3}(x_{ic}-x_{jc})^2}$$大白话每对残基做三维坐标差再开方就是这两个原子离多远。代价是距离矩阵 O(N²) 的内存长链会被咬一口。dists_to_score的四个乘法是四个条件实验结构里该对距离 15Å、两侧原子都存在mask 与转置相乘实现与、不是自己。注意第一个条件判的是true 结构docstring 里特意加了星号强调。这么写的动机是lDDT 原始定义评的是实验结构里本该近的点对若改按预测结构判一个把两个残基错拉近的预测会自己挑对自己有利的点对分数系统性虚高。顺带吐槽两处true_points_mask要传成 (batch, len, 1) 的三维数组这个接口设计真的反人类(batch, len) 不行吗另外第 73 行有条注释 Shift unscored distances to be far away但下方代码并没有做位移——未评分对的差异被零掩码乘掉后自然无效注释是历史遗留别照着它加代码。四档分箱与归一化不连续是故意的dist_l1 jnp.abs(dmat_true - dmat_predicted) # True lDDT uses a number of fixed bins. # We ignore the physical plausibility correction to lDDT, though. score 0.25 * ((dist_l1 0.5).astype(jnp.float32) (dist_l1 1.0).astype(jnp.float32) (dist_l1 2.0).astype(jnp.float32) (dist_l1 4.0).astype(jnp.float32)) # Normalize over the appropriate axes. reduce_axes (-1,) if per_residue else (-2, -1) norm 1. / (1e-10 jnp.sum(dists_to_score, axisreduce_axes)) score norm * (1e-10 jnp.sum(dists_to_score * score, axisreduce_axes))评分核心两个距离值差多少命中 0.5/1/2/4Å 四档各计 1/4 分$$\text{lDDT} \frac{1}{N_p}\sum_{(i,j)\in\mathcal{P}} \tfrac{1}{4}\Big(\mathbb{1}(\Delta d_{ij}0.5)\mathbb{1}(\Delta d_{ij}1)\mathbb{1}(\Delta d_{ij}2)\mathbb{1}(\Delta d_{ij}4)\Big)$$大白话对实验结构里 15Å 内的每对残基看两份距离差多少差 4Å 以内得 1/4 分最后对参与评分的点对取平均。用固定分箱而不是连续差值动机是让它成为命中率而非误差量——对小抖动不敏感对齐 2013 年原论文的 distance difference test 定义离散值也方便直接离散化成训练标签下一步就看到。代价是不连续0.499Å 和 0.501Å 差一档lddt_test.py 的用例专门写5.5-1e-5、6-1e-5卡在边界内侧就是怕踩到悬崖。最后两行用reduce_axes在全对或按残基之间切换docstring 明说全局 lDDT ≠ per-residue 的均值因为核心残基 15Å 内接触多、末端残基少按残基平均等于按接触数加权。它的用法不是尺子是 pLDDT 头的老师lddt_ca lddt.lddt( predicted_pointspred_all_atom_pos[None, :, 1, :], true_pointstrue_all_atom_pos[None, :, 1, :], true_points_maskall_atom_mask[None, :, 1:2].astype(jnp.float32), cutoff15., per_residueTrue) lddt_ca jax.lax.stop_gradient(lddt_ca)这是 modules.py 里 pLDDT 头的 loss算出 Cα 的 lDDT 后stop_gradient再离散成 one-hot 标签让网络用交叉熵逐残基输出置信度。也就是说 lddt.py 在仓库里不是评估工具而是教模型预测自己准不准的监督信号。这解释了两个设计标签必须恒定所以要 stop_gradient只用 Cα索引 1而不是全部 37 种原子因为距离矩阵已经 O(N²)全原子版浪费 37 倍的计算。all_atom.py 里的 FAPE 训练损失也是同一路数直接拿 (N, N, 14, 14) 的全原子距离矩阵比较。顺便说清 RMSD 住哪全仓库就一行rmsd np.sqrt(np.sum((start_pos - min_pos)**2) / start_pos.shape[0])relax.py 里能量优化前后两个坐标就是仓库里唯一的 RMSD。这么写的动机优化前后是同一坐标系里的同一分子套叠毫无意义直接相减取均值。RMSD 在 AlphaFold 里的真实定位由此清楚——它用来跟踪同坐标系下结构漂移了多少不是拿来比两个不同结构的要比不同结构Kabsch 得自己带。选谁不选谁哪种场景会被谁反杀先给决策流选 RMSD 的场景同序列同折叠、验证一次精修、跟踪构象漂移。它的死法是局部坏点绑架全局——【免费下载链接】alphafoldOpen source code for AlphaFold 2.项目地址: https://gitcode.com/GitHub_Trending/al/alphafold创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表