biological assembly の作成

タンパク質は、ほとんどの場合複数のユニット(タンパク質の各チェーン)が集まって働く。集まった複数のユニット中に、形が同じユニットも存在すれば、異なるものも存在する。形が同じユニットの場合、PDB ファイルにはそのうち 1 つしか記載されていない。このように、PDB ファイルに記載されている必要最小限のユニットのことを asymmetric unit という。一方、すべてのユニットの座標が記載されいてるタンパク質は biological assembly という。

PDB に記載されているタンパク質は asymmetric unit であり、PyMOL などで開いた時に必要最小限のユニットしか表示されない。PDB ファイルに記載されている回転行列などを用いて biological assembly を復元することができる。回転行列のデータは REMARK 350 の行に記載されている。フォーマットは次のようになっている。

REMARK 350 BIOMOLECULE: 1                                                       
REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: DODECAMERIC                       
REMARK 350 APPLY THE FOLLOWING TO CHAINS: A, B, C, D, E, F                      
REMARK 350   BIOMT1   1  1.000000  0.000000  0.000000        0.00000            
REMARK 350   BIOMT2   1  0.000000  1.000000  0.000000        0.00000            
REMARK 350   BIOMT3   1  0.000000  0.000000  1.000000        0.00000            
REMARK 350   BIOMT1   2  1.000000  0.000000  0.000000        0.00000            
REMARK 350   BIOMT2   2  0.000000 -1.000000  0.000000      136.36200            
REMARK 350   BIOMT3   2  0.000000  0.000000 -1.000000        0.00000

上述の例では、A 鎖、B 鎖、C 鎖、D 鎖、E 鎖、F 鎖のそれぞれに対して、2 つの回転行列で回転させたものが biological assembly になるということである。

以下のプログラムは PyMOL で biological assembly を作成する PyMOL 用のスクリプトである。

__read_symmetry PDB ファイルから biological assembly を作成するための回転行列などのデータを取得して、回転行列を返す。
__create_biological_unit biological assembly を作成して PyMOL で表示させる。
pymol_create_biological_unit 上述 2 つのメソッドをまとめるメソッド。

import copy
import pymol


def __read_symmetry(pdb):
    matrices = []
    matrix   = [[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]
    chains = ['*']
    with open(pdb, mode = 'r') as fh:
        for buff in fh:
            if buff[0:41] == 'REMARK 350 APPLY THE FOLLOWING TO CHAINS:':
                chains = buff[41:].replace(' ', '').replace('\n', '').split(',')
            if buff[0:18] == 'REMARK 350   BIOMT':
                if buff[13:19] == 'BIOMT1':
                    matrix[0][0] = float(buff[24:33].replace(' ', ''))
                    matrix[0][1] = float(buff[34:43].replace(' ', ''))
                    matrix[0][2] = float(buff[44:53].replace(' ', ''))
                    matrix[0][3] = float(buff[54:69].replace(' ', ''))
                if buff[13:19] == 'BIOMT2':
                    matrix[1][0] = float(buff[24:33].replace(' ', ''))
                    matrix[1][1] = float(buff[34:43].replace(' ', ''))
                    matrix[1][2] = float(buff[44:53].replace(' ', ''))
                    matrix[1][3] = float(buff[54:69].replace(' ', ''))
                if buff[13:19] == 'BIOMT3':
                    matrix[2][0] = float(buff[24:33].replace(' ', ''))
                    matrix[2][1] = float(buff[34:43].replace(' ', ''))
                    matrix[2][2] = float(buff[44:53].replace(' ', ''))
                    matrix[2][3] = float(buff[54:69].replace(' ', ''))
                    # add matrix
                    for c in chains:
                        matrices.append([c, copy.deepcopy(matrix)])
    return matrices

def __create_biological_unit(model, matrices):
    for mat in matrices:
        n = pymol.cmd.get_unused_name(mat[0] + '_')
        pymol.cmd.create(n, '/' + model + '//' + mat[0])
        m = mat[1]
        s1 = "%s + (x*%s + y*%s + z*%s)" % (m[0][3], m[0][0], m[0][1], m[0][2])
        s2 = "%s + (x*%s + y*%s + z*%s)" % (m[1][3], m[1][0], m[1][1], m[1][2])
        s3 = "%s + (x*%s + y*%s + z*%s)" % (m[2][3], m[2][0], m[2][1], m[2][2])
        pymol.cmd.alter_state(1, n, "(x,y,z) = (%s, %s, %s)" % (s1, s2, s3) )

def pymol_create_biological_unit(model, pdb):
    bu_matrix = __read_symmetry(pdb)
    __create_biological_unit(model, bu_matrix)
    pymol.cmd.reset()



pdb = './2A0L.pdb'       # PDB ファイルの位置
model = 'MODEL1'         # モデル名(任意で構わない)
pymol.finish_launching()
pymol.cmd.load(pdb, model)
pymol_create_biological_unit(model, pdb)