PSP - 计算蛋白质复合物链间接触的残基与面积

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/134884889

在蛋白质复合物中,通过链间距离,可以计算出在接触面的残基与接触面的面积,使用 BioPython 库 与 SASA (Solvent Accessible Surface Area,溶剂可及表面积) 库。SASA 计算主要以 水分子 是否通过为基础,水分子的半径是1.4 A,直径是 2.8 A,所以以 2.8 A 的距离,判断链间是否连接。

相关函数:

  1. 获取 蛋白质复合物 的链列表,即 get_chain_ids()
  2. 获取 残基-原子 字典,注意原子名称与 PDB 的名称可能不同,即 get_atom_list()
  3. 获取 全原子 列表,即 get_all_atoms()
  4. 判断是否原子之间是否相连,即 is_contact()
  5. 获取全部的接触面,原子计算残基维度,即 get_contacts()
  6. 打印 ChimeraX 的显示命令,即 get_chimerax_cmd()
  7. 端到端的计算接触残基,即 cal_chain_interface_residue()
  8. 计算 SASA 面积,即 cal_sasa()
  9. 获取复合物多链的子结构,即 get_sub_structure()
  10. 端到端的计算接触面积,即 cal_chain_interface_area()

以 PDB 8j18 为例,计算链 A 与 链 R 的接触残基与面积:

AR

源码如下:

#!/usr/bin/env python
# -- coding: utf-8 --
"""
Copyright (c) 2022. All rights reserved.
Created by C. L. Wang on 2023/12/8
"""

import os

from Bio.PDB import NeighborSearch
from Bio.PDB import PDBParser, Selection
from Bio.PDB.Chain import Chain
from Bio.PDB.Model import Model
from Bio.PDB.Structure import Structure

from root_dir import DATA_DIR


class MainComplexChainDist(object):
    """
    复合物,多链距离计算
    """
    def __init__(self):
        pass

    @staticmethod
    def get_chain_ids(structure):
        chain_ids = []
        for chain in structure.get_chains():
            chain_ids.append(chain.id)
        return chain_ids

    @staticmethod
    def get_atom_list(structure, chains):
        """
        获取 atom list 列表
        注意: 输出的 atom 名字与 PDB 文件中的 atom 名字略有差异,例如
        8jtl 第1个,PRO: CG 对应 OG1,CD 对应 CG2
        8jtl 第2个,VAL: CG1 对应 CD1,CG2 对应 CD2
        """
        output = dict()
        for chain in structure:
            if chain.id in chains:
                for residue in chain.get_residues():
                    het_flag, res_seq, i_code = residue.get_id()
                    the_id = (chain.id + "_" + str(res_seq) + "_" + i_code).strip()
                    for atom in residue.get_unpacked_list():
                        if het_flag == ' ':
                            if the_id in output:
                                output[the_id].append(atom)
                            else:
                                output[the_id] = [atom]
        return output

    # Filter out all the atoms from the chain,residue map given by residue_map
    @staticmethod
    def get_all_atoms(residue_map):
        all_atoms_out = []
        for residue in residue_map:
            for atom in residue_map[residue]:
                all_atoms_out.append(atom)
                # Set the b-factor to zero for coloring by contacts
                atom.set_bfactor(0.0)
        return all_atoms_out

    @staticmethod
    def is_contact(res_1, other_atoms, cutoff):
        for atom in res_1:
            ns = NeighborSearch(other_atoms)
            center = atom.get_coord()
            neighbors = ns.search(center, cutoff)  # 5.0 for distance in angstrom
            residue_list = Selection.unfold_entities(neighbors, 'R')  # R for residues
            if len(residue_list) > 0:
                return True
        return False

    @classmethod
    def get_contacts(cls, struc, all_atoms, verbose, cutoff):
        progress = 0
        contacts = []
        for residue in struc:
            progress += 1
            # if len(verbose) > 0:
            #     print(verbose, progress, "out of", len(struc))
            atom_list = struc[residue]
            outcome = cls.is_contact(atom_list, all_atoms, cutoff)
            if outcome:
                contacts.append(residue)
        return contacts

    @staticmethod
    def get_chimerax_cmd(contacts, chain_id, pdb_id="2"):
        """
        计算命令
        """
        tmp_list = []
        for item in contacts:
            req_id = int(item.split("_")[1])
            tmp_list.append(req_id)
        contacts_gap = []
        prev, post = -1, -1
        for i in tmp_list:
            if prev == -1:
                prev = post = i
                continue
            if i - post == 1:
                post = i
            else:
                contacts_gap.append(f"#{pdb_id}/{chain_id}:{prev}-{post}")
                prev = post = i
        cmd = "select " + " ".join(contacts_gap)
        return cmd

    @classmethod
    def cal_chain_interface_residue(cls, structure, chain1, chain2, cutoff=7.5):
        """
        计算复合物结构的链内距离
        """

        chain_ids = cls.get_chain_ids(structure)
        # ['A', 'B', 'G', 'R', 'S']
        print(f"[Info] chain_ids: {chain_ids}")
        assert chain1 in chain_ids and chain2 in chain_ids

        # C 表示 chain,即将 structure 展开 chain 的形式
        # 同时支持 A, R, C, M, S
        structure_c = Selection.unfold_entities(structure, target_level="C")
        atom_dict1 = cls.get_atom_list(structure_c, chains=[chain1])
        atom_dict2 = cls.get_atom_list(structure_c, chains=[chain2])
        print(f"[Info] res_num: {len(atom_dict1.keys())}")

        all_atoms_1 = cls.get_all_atoms(atom_dict1)
        all_atoms_2 = cls.get_all_atoms(atom_dict2)
        cutoff = cutoff
        contacts_1 = cls.get_contacts(atom_dict1, all_atoms_2, "First molecule, residue ", cutoff)
        contacts_2 = cls.get_contacts(atom_dict2, all_atoms_1, "Second molecule, residue ", cutoff)
        print(f"[Info] contacts_1: {len(contacts_1)}")
        print(f"[Info] contacts_2: {len(contacts_2)}")
        return contacts_1, contacts_2

    @staticmethod
    def cal_sasa(structure):
        """
        计算单体的表面积
        """
        import freesasa
        structure = freesasa.structureFromBioPDB(structure)
        result = freesasa.calc(structure)
        # classArea = freesasa.classifyResults(result, structure)
        return result.totalArea()

    @staticmethod
    def get_sub_structure(structure, chain_list):
        """
        获取 PDB 结构的子结构
        """
        new_structure = Structure(0)
        new_model = Model(0)
        # 遍历模型中的所有链
        for chain in structure[0]:
            # 获取链的ID
            tmp_chain_id = chain.get_id()
            if tmp_chain_id not in chain_list:
                continue
            # 创建一个新的结构对象,只包含当前链

            new_chain = Chain(tmp_chain_id)
            new_chain.child_list = chain.child_list
            new_model.add(new_chain)
        new_structure.add(new_model)
        return new_structure

    @classmethod
    def cal_chain_interface_area(cls, structure, chain1, chain2):
        sub_all_structure = cls.get_sub_structure(structure, [chain1, chain2])
        sub1_structure = cls.get_sub_structure(structure, [chain1])
        sub2_structure = cls.get_sub_structure(structure, [chain2])
        v1_area = cls.cal_sasa(sub_all_structure)
        v2_area = cls.cal_sasa(sub1_structure) + cls.cal_sasa(sub2_structure)
        inter_area = max(int((v2_area - v1_area) // 2), 0)
        return inter_area

    def process(self, input_path, chain1, chain2):
        """
        核心逻辑
        """
        print(f"[Info] input_path: {input_path}")
        print(f"[Info] chain1: {chain1}, chain2: {chain2}")
        chain1 = chain1.upper()
        chain2 = chain2.upper()
        parser = PDBParser(QUIET=True)
        structure = parser.get_structure("def", input_path)
        contacts_1, contacts_2 = self.cal_chain_interface_residue(structure, chain1, chain2, cutoff=7.5)
        cmd1 = self.get_chimerax_cmd(contacts_1, chain1)
        cmd2 = self.get_chimerax_cmd(contacts_2, chain2)
        print(f"[Info] chimerax: {cmd1}")
        print(f"[Info] chimerax: {cmd2}")
        inter_area = self.cal_chain_interface_area(structure, chain1, chain2)
        print(f"[Info] inter_area: {inter_area}")


def main():
    ccd = MainComplexChainDist()

    # input_path = os.path.join(DATA_DIR, "templates", "8p3l.pdb")
    # ccd.process(input_path, "A", "D")  # 2562
    # ccd.process(input_path, "A", "J")  # 490

    input_path = os.path.join(DATA_DIR, "templates", "8j18.pdb")
    # ccd.process(input_path, "R", "S")  # 0
    ccd.process(input_path, "A", "R")  # 1114


if __name__ == '__main__':
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/230330.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

整数以及浮点数在内存中的存储

一.整数在内存当中的存储 数据在内存中是以十六进制补码的形式进行存储的。 原码表示法简单易懂,适用于乘法,但用原码表示的数进行加减运算比较复杂,当两数相加时,如果同号则数值相加,但是进行减法时要先比较绝对值的…

【面试专题】MySQL篇①

1.MySQL中,如何定位慢查询? ①介绍一下当时产生问题的场景(我们当时的一个接口测试的时候非常的慢,压测的结果大概5秒钟) ②我们系统中当时采用了运维工具( Skywalking ),可以监测出哪个接口…

学习pytorch18 pytorch完整的模型训练流程

pytorch完整的模型训练流程 1. 流程1. 整理训练数据 使用CIFAR10数据集2. 搭建网络结构3. 构建损失函数4. 使用优化器5. 训练模型6. 测试数据 计算模型预测正确率7. 保存模型 2. 代码1. model.py2. train.py 3. 结果tensorboard结果以下图片 颜色较浅的线是真实计算的值&#x…

idea使用maven的package打包时提示“找不到符号”或“找不到包”

介绍:由于我们的项目是多模块开发项目,在打包时有些模块内容更新导致其他模块在引用该模块时不能正确引入。 情况一:找不到符号 情况一:找不到包 错误代码部分展示: Failure to find com.xxx.xxxx:xxx:pom:0.5 in …

3D渲染和动画制作软件KeyShot Pro mac附加功能

KeyShot 11 mac是一款专业化实时3D渲染工具,使用它可以简化3d渲染和动画制作流程,并且提供最准确的材质及光线,渲染效果更加真实,KeyShot为您提供了使用 CPU 或 NVIDIA GPU 进行渲染的能力和选择,并能够线性扩展以获得…

HarmonyOS4.0从零开始的开发教程10管理组件状态

HarmonyOS(八)管理组件状态 概述 在应用中,界面通常都是动态的。如图1所示,在子目标列表中,当用户点击目标一,目标一会呈现展开状态,再次点击目标一,目标一呈现收起状态。界面会根…

Django的logging-日志模块的简单使用方法

扩展阅读: Python-Django的“日志功能-日志模块(logging模块)-日志输出”的功能详解 现在有下面的Python代码: # -*- coding: utf-8 -*-def log_out_test(content_out):print(content_out)content1 "i love you01" log_out_test(content1)现…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux 设备管理》(29)

《Linux操作系统原理分析之Linux 设备管理》(29) 10 Linux 设备管理10.1 Linux 设备分类与识别10.1.1 Linux 设备的分类10.1.2 设备文件 10.2 设备驱动程序与设备注册10.2.1 设备驱动程序10.2.2 设备注册 10.3Linux 的 I/O 控制方式10.3.1 查…

Docker, Docker-compose部署Sonarqube

参考文档 镜像地址: https://hub.docker.com/_/sonarqube/tags Docker部署文档地址 Installing from Docker | SonarQube Docs Docker-compose文档部署地址: Installing from Docker | SonarQube Docs 部署镜像 2.1 docker部署 # 宿主机执行 $. vi /etc/sysctl.conf…

探索CSS:从入门到精通Web开发(二)

前言 当我们谈论网页设计和开发时,CSS(层叠样式表)无疑是其中的重要一环。作为HTML的伴侣,CSS赋予网页以丰富的样式和布局,使得网站看起来更加吸引人并且具备更好的可读性。本书将通过一系列深入浅出的方式&#xff0…

kafka学习笔记--安装部署、简单操作

本文内容来自尚硅谷B站公开教学视频,仅做个人总结、学习、复习使用,任何对此文章的引用,应当说明源出处为尚硅谷,不得用于商业用途。 如有侵权、联系速删 视频教程链接:【尚硅谷】Kafka3.x教程(从入门到调优…

深入理解 Promise:前端异步编程的核心概念

深入理解 Promise:前端异步编程的核心概念 本文将帮助您深入理解 Promise,这是前端异步编程的核心概念。通过详细介绍 Promise 的工作原理、常见用法和实际示例,您将学会如何优雅地处理异步操作,并解决回调地狱问题。 异步编程和…

python主流开发工具排名,python开发工具有哪些

本篇文章给大家谈谈python的开发工具软件有哪些,以及python主流开发工具排名,希望对各位有所帮助,不要忘了收藏本站喔。 python中用到哪些软件 一、Python代码编辑器1、sublime Textsublime Text是一款非常流行的代码编辑器,支持P…

基于单片机指纹考勤机控制系统设计

**单片机设计介绍,基于单片机指纹考勤机控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的指纹考勤机控制系统是一种用于管理员工考勤和实现门禁控制的设计方案。它通过使用单片机作为主控制器…

Amazon CodeWhisperer 提供新的人工智能驱动型代码修复、IaC 支持以及与 Visual Studio 的集成...

Amazon CodeWhisperer 的人工智能(AI)驱动型代码修复和基础设施即代码(IaC)支持已正式推出。Amazon CodeWhisperer 是一款用于 IDE 和命令行的人工智能驱动型生产力工具,现已在 Visual Studio 中推出,提供预…

nodejs微信小程序+python+PHP的游戏测评网站设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…

初识Matter——esp-box控制两盏灯

初识Matter 一、效果展示 二、准备 1.ubuntu系统/Mac系统电脑 2.安装esp-idf及esp-matter环境 3.esp-box设备 4.两块esp32 5.两个led灯或使用板载灯 三、烧录固件(esp-box) 下载esp-box例程 git地址:GitHub - espressif/esp-box: Th…

微信小程序 - PC端选择ZIP文件

微信小程序 - PC端选择文件 分享代码片段场景分析解决思路附魔脚本chooseMediaZip 选择附魔后的ZIP文件相关方法测试方法 参考资料 分享代码片段 不想听废话的,直接看代码。 https://developers.weixin.qq.com/s/UL9aojmn7iNU 场景分析 如果你的微信小程序需要选…

机器视觉相机镜头光源选型

镜头选型工具 - HiTools - 海康威视 Hikvisionhttps://www.hikvision.com/cn/support/tools/hitools/cl8a9de13648c56d7f/ 海康机器人-机器视觉产品页杭州海康机器人股份有限公司海康机器人HIKROBOT是面向全球的机器视觉和移动机器人产品及解决方案提供商,业务聚焦于…

dell服务器重启后显示器黑屏

1.硬件层面:观察主机的指示灯 (1)指示灯偏黄,硬件存在问题(内存条有静电,拔出后用橡皮擦擦拭;或GPU松动) a.电源指示灯黄,闪烁三下再闪烁一下,扣下主板上的纽…