Physics and Informatics

protein bioinformatics: 2.1 pdb 파일 포멧, 3d 구조 파싱 주의사항

Novelism 2021. 5. 27. 22:41

 

PDB 는 protein data bank 로, 실험적으로 밝혀진 (혹은 일부 시뮬레이션된) 단백질의 구조를 업로드하고 배포하는 곳입니다.
https://www.rcsb.org/
여기서 많이 사용되는 파일포멧이 pdb 입니다. 이 파일포멧의 단점으로 다른 포멧을 사용하는 사람들도 있긴 하지만... 여전히 제일 많이 사용되는 파일 포멧입니다. 

pdb 파일을 파싱할 때 가장 중요한 점은 메뉴얼을 읽어야 한다는 점입니다. 메뉴얼은 여기서 찾으실 수 있습니다.
https://www.wwpdb.org/documentation/file-format

pdb 파일은 각 열마다 고유의 의미가 있습니다. 따라서 pdb 파일을 파싱할 때, 절대로 line.strip() 같은거 쓰면 안됩니다. 
 

이중 단백질 구조를 담고 있는 부분이자, 제가 가장 많이 사용하는 부분은 'ATOM  ' 입니다.  
메뉴얼 A4 사이즈에서 (문서 기준으로) 176 page 입니다. pdf 파일기준으로 180 page 입니다. 
'HETATM' 은 ligand나 water 의 구조 정보를 담고 있습니다. 
참고로 모든 행에서 line[0:6] 은 Record name입니다. 


'ATOM  ' 에 대한 설명입니다. HETATM 도 거의 동일합니다. 
Record Format
COLUMNS DATA TYPE FIELD DEFINITION
-------------------------------------------------------------------------------------
1 - 6 Record name "ATOM "
7 - 11 Integer serial Atom serial number.
13 - 16 Atom name Atom name.
17 Character altLoc Alternate location indicator.
18 - 20 Residue name resName Residue name.
22 Character chainID Chain identifier.
23 - 26 Integer resSeq Residue sequence number.
27 AChar iCode Code for insertion of residues.
31 - 38 Real(8.3) x Orthogonal coordinates for X in Angstroms.
39 - 46 Real(8.3) y Orthogonal coordinates for Y in Angstroms.
47 - 54 Real(8.3) z Orthogonal coordinates for Z in Angstroms.
55 - 60 Real(6.2) occupancy Occupancy.
61 - 66 Real(6.2) tempFactor Temperature factor.
77 - 78 LString(2) element Element symbol, right-justified.
79 - 80 LString(2) charge Charge on the atom.


그리고 'ATOM  ' 과 함께 많이 사용하는 'CONECT'  입니다. 원자사이의 connectivity 를 기록합니다. 6문자다보니 N을 하나 빼고 안적습니다. 

COLUMNS DATA TYPE FIELD DEFINITION
-------------------------------------------------------------------------
1 - 6 Record name "CONECT"
7 - 11 Integer serial Atom serial number
12 - 16 Integer serial Serial number of bonded atom
17 - 21 Integer serial Serial number of bonded atom
22 - 26 Integer serial Serial number of bonded atom
27 - 31 Integer serial Serial number of bonded atom

보시면, 각 영역마다 빈칸이 없는 곳도 있습니다. 즉, 때때로 두개 이상의 항목이 붙어서 나오기도 합니다. 그러니 split()을 쓸경우는 제대로 파싱이 되지 않습니다. 또한, 때때로 항목이 비어있는 경우도 있습니다.
이중 코드를 대충 짰을 때 에러가 자주 나는 부분이 altLoc 와, insertion code 입니다. 
altLoc는 그냥 A만 남기고 다 버리는 경우도 많지만... 
일부 사람들이 많이 사용하는 프로그램들이 pdb 파싱을 잘못 하는 경우가 있습니다.

 예를들어 openbabel의 경우는 CONECT 부분을 split()으로 처리해버리는지, 원자 index가 길어지면 잘못 읽어버리기도 합니다. 
openmm의 pdbfixer는 insertion 코드를 무시해버립니다. 
256 과 256A residue 가 있다면, 둘이 다른 residue 라는 것을 식별하지 못하고 합쳐버립니다. 


 이런 포멧을 잘못 다룬 문제 이외에도 pdb 파일포멧의 관습적인 문제들이 있습니다.
단백질은 아미노산 서열만으로 정확히 분자의 구조가 정해지는 분자입니다. (3차원 구조 말고, 원자간 결합 정보)
따라서 굳이 원자간 결합 정보를 명시하지 않아도, 파싱이 가능합니다. 
(물론, CYS의 황끼리 결합하는 것이나, 인산화되는 residue 처럼 변형이 있긴 합니다만... 그런경우에는 명시합니다.)
 또한 엑스레이 결정학 방식으로 구조를 결정하는 경우가 많은데, 수소의 위치까지는 알기 어렵기에, 수소 원자는 보통 생략합니다. 그리고 전하가 명시되지 않은 경우도 많습니다.

분자는 원칙적으로 노드(atom, charge) 정보와 엣지 (bond ) 정보, 수소원자 정보 가 전부 있어야만 완전한 정보를 가지고 있다고 볼 수 있습니다. 
그런데 일단 pdb에선 기본적으로 bond 정보(싱글본드, 더블본드, 아로마틱 본드 등..) 를 주지 않고, HETATM인 경우는 bond가 있다 없다만을 줍니다. amino acid 의 경우는 아예 아무 정보도 주지 않습니다. 
단백질은 어쨌건 파싱이 가능하긴 합니다. 그런데, 문제는 프로그램이 잘 파싱할 수 있도록 만들어져있는가 입니다.
bond 정보를 복원해내는 방법은 알고리즘마다 다릅니다. 어떤 사람은 원자간 거리를 직접 재서, 그것으로부터 bond 정보를 찾아내고, 어떤 사람은 amino acide의 룰을 기반으로 찾아냅니다. 그런데 가끔 실험구조적인 (혹은 시뮬레이션적인) 문제로 거리로부터 파싱할 때, 실제 결합되지 않은 곳을 결합으로 잘못 찾는 문제도 있습니다. 그래서 저는 가능한 그런 문제가 없게 하기 위해서 pdb 파일에 명확히 본드 정보를 담기를 원합니다. 
 pdb 포멧에서 공식적으로 지원하는것은 아니지만, CONECT에서 같은 원자번호를 1번 적으면 single 본드, 2번 적으면 double bond 3번 적으면 triple bond 로 식별됩니다. 일단 pymol이나 openbabel 은 이런 룰을 따릅니다.
단, 이것은 비공식적이라서 디테일은 프로그램마다 다를 수도 있습니다. 예를 들자면 원자번호가 4번 적혀있으면 pymol 에선 aromatic 으로 식별하지만, openbabel은 4중결합으로 인식해버립니다.
 많은 cheminformatics 툴에서, 분자를 식별할 때 aromatics ring에 대해서 Kekule 폼을 식별하려 시도하고, 이 과정에서 실패해서 분자를 잘못 인식하기도 합니다. 따라서 가능한 좋은 fixer를 사용해서 bond 정보를 명확히 해주는 것이 좋습니다. 수소원자나 전하도 명시하지 않는 경우 제대로 파싱 안되기도 합니다. 혹은 실험적으로 빈 원자들의 존재도 파싱 실패의 원인이 될 수도 있습니다. 


 저는 openmm의 pdbfixer 를 기본적으로 사용하는데, 이것만으로는 분자 식별이 잘못될 수 있어서, 전하나 CONECT 를 직접 만들어서 채워넣습니다. 20종의 아미노산에 대해서 원자간 결합 정보를 만들어서 입력했습니다. 

https://github.com/gicsaw/pdbtools/blob/main/bin/fix_protein.py


pdb 는 이거로 어느정도 파싱이 되는데, ligand 파싱은 더 어렵습니다. 
애초에 단백질 구조 담는 용이지 리간드 잘 담는 파일포멧도 아니고...
pdb 파일포멧이 기본적으로 single double bond 구분이 없다보니, cheminfo 프로그램들이 이걸 잘못 파싱하는 경우가 많습니다.
 이때는 어떻게 해야하냐면... pdb 사이트에 각 리간드에 대한 cif 파일을 제공합니다. 그걸 보고 bond 정보를 잘 채워넣어야 합니다. covalent bond가 있는 경우를 제외하면 이방법이 제일 좋은 것 같습니다.
cif 파일로부터 리간드 pdb 파일에 본드 정보를 만들어넣는 코드 입니다.
pdb 사이트에 등록된 리간드 3문자 코드는 고유한 분자를 지칭하긴 하지만, 3d구조가 유일하진 않습니다. 그러니 cif 파일의 리간드의 3d구조가 pdb 파일의 3d 구조와 다를 경우도 있습니다. 


https://github.com/gicsaw/pdbtools/blob/main/bin/fix_ligand_ref.py

pdb의 'ATOM  '의 13 - 16 Atom name Atom name. 는 주의해서 사용해야 합니다. 앞의 2칸은 원자기호이고, 뒤의 두칸은 분자 내에서의 해당 원자의 식별입니다. 때때로 앞의 2문자만 사용하는 경우가 있지만, 그럴 경우 문제가 일어나는 경우가 많습니다. 예를들어 pdb를 pdbqt로 바꾼 후 docking했다가 다시 pdb로 바꿀 때 문제가 발생하는데, pdbqt는 본드 정보를 포함하고 있지 않습니다. 그래서 cheminfo 프로그램들이 3d구조로부터 파싱을 하는데, pdb 복원에 실패하는 경우가 많습니다. 식별자까지 명확히 있으면 직접 비교하면서 분자를 복원할 수 있습니다. 
이 부분이 원본 pdb 파일을 이용해서 pdbqt를 pdb 로 복원하는 코드입니다. ligand 에 대해서만 작동합니다. protein에 대해선 안됩니다. 
https://github.com/gicsaw/pdbtools/blob/main/bin/pdbqt2pdb_ref.py

 

cheminfomatics tools 를 쓸 때, 3d conformer를 포함한다면 가능한 explicit hydrogen model을 사용하는것이 파싱 에러를 줄일 수 있습니다. 가끔 수소가 안붙어있으면 잘못 이해해서 전하가 바뀌거나 본드 정보가 바뀌는 경우가 있습니다.