Drug/Computer-Aided Drug Discovery

PDB 파싱: CONECT 채워넣기 예제

Novelism 2022. 1. 29. 18:21

 

PDB 파일 포맷은 단백질과 그 외 분자들의 실험 구조를 기록하기 위해 사용됩니다. (주로 x-ray 결정 구조)

다른 분자 파일 포맷과 비교하면, 단백질 구조를 기록하는 것에 최적화되어있습니다. 

 

 3D 구조에 대한 섹션은  "ATOM  ",  "HETATM",  "CONECT" 이 셋입니다. 

 단백질의 구조를 기록하는데 최적화되어있다는 의미는, 분자를 아미노산 단위로 인식한다는 것입니다. 

 20가지의 기본 아미노산들에서, 각 원자들마다 고유의 이름이 붙습니다. (4칸)

main chain에 " N  ", " C  ", " CA ", " O  " 이 있고, side chain은 " CB ", " CG " 순으로 기록됩니다.

그리고 원자마다 속한 아미노산의 3 코드가 함께 기록됩니다. 

 이 두가지 정보만 가지고 원자들 사이의 bond 정보를 완전히 유추해낼 수 있기에,

bond 정보를 따로 표기하지 않습니다. 

아미노산에 modification 이 있는 경우, 혹은 아미노산이 아닌 분자의 경우엔 이들을 따로 기록을 해두고,

"ATOM  " 이 아니라, "HETATM"에 기록을 해둡니다. 그리고 "CONECT"에 bond 정보를 기록합니다. 

ligand가 아미노산일 경우 "ATOM  "에 기록되고, 별개의 체인으로 처리됩니다. 

 두 개의 펩타이드가 붙는 경우 multi-chain protein인지, 아니면 receptor-ligand 결합인지에 대한 명확한 기준은 없으니까요. 

 

그리고 아미노산이 아닌 다른 분자에 대해선, CONECT에 conectivity 정보가 기록됩니다. 

"BOND  "가 아니라 "CONECT"입니다. 즉. 단일 결합, 이중결합, 삼중결합, aromatic 등을 전혀 식별하지 않고 conectivity만 기록합니다.

 ligand의 bond 정보를 제대로 된 복원하는 것은 의외로 어려운 일입니다. 보통 툴들은 atom 사이의 거리를 가지고 파싱을 하긴 하지만, 완벽하게 잡아주는 툴은 못 봤습니다. 특히, aromatic ring을 제대로 잡아주지 못합니다. 

 그래서 어떻게 해야 하는가 하면, PDB 사이트에서 분자 mmcif 파일을 함께 제공합니다. 

 pdb에선 대해선 ligand를 고유의 3자리 code로 표기합니다. ATP라면 ATP, water라면 HOH입니다. gefitinib (iressa)의 경우는 IRE입니다. 하나의 코드는 하나의 분자만을 지칭합니다. 여러 분자가 하나의 코드를 공유하진 않습니다. 하지만, 하나의 분자에게 여러 코드가 있는지에 대해선 잘 모르겠습니다. (tautomer마다 다른 코드가 있는 경우는 봤음)

 mmcif 파일에도 3D 좌표가 기록되어있는데, 이것이 pdb파일에 찍힌 좌표와 같을 수도 있지만, 같은 리간드가 여러 pdb 파일에 찍힌 경우가 있다면, 좌표가 다릅니다.

EGFR (G791S/T790M)과 gefitinib의 crystal structure 가 담긴 pdb id는 3UG2입니다. 

RCSB PDB - 3UG2: Crystal structure of the mutated EGFR kinase domain (G719S/T790M) in complex with gefitinib

https://files.rcsb.org/download/3UG2.pdb

gefitinib에 대한 페이지와 mmcif 파일은 다음과 같습니다.
RCSB PDB - IRE Ligand Summary Page

https://files.rcsb.org/ligands/view/IRE.cif

 

제가 추천하는 예제는 pdb 파일을 다운로드하고, receptor와 ligand의 CONECT에 bond 정보를 채워 넣는 것입니다. 

 원칙적으로 CONECT엔 bond order는 들어가지 않지만, 단일 결합은 1번, 이중결합은 2번, 삼중결합은 3번 원자 번호를 반복하는 식으로 넣기도 합니다. 다양한 캠 인포 툴들이 그런 형태를 지원합니다.

예를 들자면, 1,2번 원자가 이중결합, 1 3번 원자가 단일 결합으로 연결되어 있다면 

다음과 같이 적습니다. 제일 첫 숫자가 해당 원자의 인덱스, 다음의 숫자들이 연결된 원자의 인덱스입니다.

CONECT    1    2    2    3
CONECT    2    1    1
CONECT    3    1

그리고 CONECT는 한 줄에 5개까지의 숫자만을 적는 것이 원칙입니다. 

ATP의 P처럼 bond 수가 4를 넘어가는 경우에는 그다음 줄에 원자 인덱스를 한번 더 적고, 이어서 적어줍니다.

CONECT    1    2    3    3    4
CONECT    1    4    5

 

 다만, aromatics 표기는 일관성이 없습니다. pymol에선 4번 적어주면 aromatics이지만, 다른 프로그램에선 4중 결합으로 인식됩니다. 그러니 Kekule form을 사용하는 것이 좋습니다. 

peptide에 속한 원자의 conectivity는 제가 따로 만들어둔 것이 있습니다. 

    atom_conect_main_dict = {' CA ': [[' N  ', 1]],
                             ' C  ': [[' CA ', 1]],
                             ' O  ': [[' C  ', 2]],
                             ' OXT': [[' C  ', 1]],
                             }
                             
    atom_conect_heavy_dict = {'ARG': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD ': [[' CG ', 1]],
                                      ' NE ': [[' CD ', 1]],
                                      ' CZ ': [[' NE ', 1]],
                                      ' NH1': [[' CZ ', 2]],
                                      ' NH2': [[' CZ ', 1]], },
                              'HIS': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' ND1': [[' CG ', 1]],
                                      ' CD2': [[' CG ', 2]],
                                      ' NE2': [[' CD2', 1]],
                                      ' CE1': [[' ND1', 1.5],
                                               [' NE2', 1.5]], },
                              'LYS': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD ': [[' CG ', 1]],
                                      ' CE ': [[' CD ', 1]],
                                      ' NZ ': [[' CE ', 1]], },
                              'ASP': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' OD1': [[' CG ', 2]],
                                      ' OD2': [[' CG ', 1]], },
                              'GLU': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD ': [[' CG ', 1]],
                                      ' OE1': [[' CD ', 2]],
                                      ' OE2': [[' CD ', 1]], },
                              'SER': {' CB ': [[' CA ', 1]],
                                      ' OG ': [[' CB ', 1]], },
                              'THR': {' CB ': [[' CA ', 1]],
                                      ' OG1': [[' CB ', 1]],
                                      ' CG2': [[' CB ', 1]], },
                              'ASN': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' OD1': [[' CG ', 2]],
                                      ' ND2': [[' CG ', 1]], },
                              'GLN': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD ': [[' CG ', 1]],
                                      ' OE1': [[' CD ', 2]],
                                      ' NE2': [[' CD ', 1]], },
                              'CYS': {' CB ': [[' CA ', 1]],
                                      ' SG ': [[' CB ', 1]], },
                              'GLY': {},
                              'PRO': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD ': [[' CG ', 1], [' N  ', 1]], },
                              'ALA': {' CB ': [[' CA ', 1]], },
                              'VAL': {' CB ': [[' CA ', 1]],
                                      ' CG1': [[' CB ', 1]],
                                      ' CG2': [[' CB ', 1]], },
                              'ILE': {' CB ': [[' CA ', 1]],
                                      ' CG1': [[' CB ', 1]],
                                      ' CG2': [[' CB ', 1]],
                                      ' CD1': [[' CG1', 1]], },
                              'LEU': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD1': [[' CG ', 1]],
                                      ' CD2': [[' CG ', 1]], },
                              'MET': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' SD ': [[' CG ', 1]],
                                      ' CE ': [[' SD ', 1]], },
                              'PHE': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD1': [[' CG ', 2]],
                                      ' CD2': [[' CG ', 1]],
                                      ' CE1': [[' CD1', 1]],
                                      ' CE2': [[' CD2', 2]],
                                      ' CZ ': [[' CE1', 2], [' CE2', 1]], },
                              'TYR': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD1': [[' CG ', 2]],
                                      ' CD2': [[' CG ', 1]],
                                      ' CE1': [[' CD1', 1]],
                                      ' CE2': [[' CD2', 2]],
                                      ' CZ ': [[' CE1', 2], [' CE2', 1]],
                                      ' OH ': [[' CZ ', 1]]},
                              'TRP': {' CB ': [[' CA ', 1]],
                                      ' CG ': [[' CB ', 1]],
                                      ' CD1': [[' CG ', 2]],
                                      ' CD2': [[' CG ', 1]],
                                      ' NE1': [[' CD1', 1]],
                                      ' CE2': [[' CD2', 2], [' NE1', 1]],
                                      ' CE3': [[' CD2', 1]],
                                      ' CZ2': [[' CE2', 1]],
                                      ' CZ3': [[' CE3', 2]],
                                      ' CH2': [[' CZ2', 2], [' CZ3', 1]], },
                              }

amino acid를 트리구조로 생각하면, main chain에서

N 이 루트이고, 

C의 상위에 있는 원자는 N, CA의 상위의 원자는 C, O, OXT의 상위 원자는 CA입니다. 

OXT는 C terminal에만 붙어있는 O입니다.

 side chain에서 CB의 상위는 CA이고... 이런 식으로 트리로 만들 수 있습니다. 

 3번째 칸에 기록된 A, B, G, D, E, Z, H는 트리에서 계층을 지칭하는 문자로,

 그리스 문자 순으로 alpha (A) beta (B) gamma (G) delta (D) epsilon (E) zeta (Z) Eta (H) 순입니다. 

 

제가 딕셔너리로 만든 위 코드는 20 아미노산에 대해서, 각 원자의 상위에 연결된 원자와 bond order를 표기하고 있습니다. 딕셔너리를 이용해서 단백질에 대한 bond 정보를 복원하고, cif 파일로부터 ligand의 bond 정보를 복원하는 것이 예제입니다.

 

 참고로 pdb 사이트에서 다운로드한 파일에선, ligand에 속하는 원자도 고유의 번호가 매겨져 있으니 (C1, C2...)

cif에서 파일을 비교할 땐 이것들끼리 비교하면 됩니다.

 만약 이런 정보가 없다면, 문제가 더 어려워집니다. 도킹 후에 pdbqt에서 pdb로 복원할 때도 똑같은 문제를 경험하게 됩니다.