Drug/Computer-Aided Drug Discovery

pybel: openbabel python interface, 수소 추가, protonation state

Novelism 2022. 3. 29. 20:16

 openbabel 은 콘솔에서 직접 명렁어로 실행할 수도 있지만 (obabel 등)

 python interface로 모듈을 불러올 수도 있습니다. 

 rdkit과 비슷한 기능을 하긴 하는데, 사용법이 더 어렵고, 메뉴얼이 불편합니다.

 

 그래도 나름 장점도 있어서 openbabel을 사용해야 하는 경우도 있습니다.

 

 openbabel 을 설치하기 위해선 일단 openbabel을 설치합니다.

 openbabel2와 openbabel3의 구조가 조금 다릅니다. 

 예를들면 pybel 모듈이나 openbabel module을 import하기 위해서 버전 3에선 다음과 같이 입력합니다. 

from openbabel import pybel
from openbabel import openbabel

하지만 버전 2에선 

import pybel
import openbabel

라고 입력합니다. 

 

저는 버전 3를 추천합니다. 버전 3에서 추가된 기능들이 있습니다.

 

openbabel의 python 인터페이스는 기본적으로 pybel 모듈을 사용합니다.

 pybel의 메소드도 실제로는 openbabel을 거쳐서 실행되긴 하지만, pybel로 구현되어있는것이 훨씬 사용하기 편하니까 된다면 pybel을 사용합니다.

일단 SMILES로부터 분자를 입력하려면 다음과 같이 적어줍니다. 

 smi = "CCCCC"
 m = pybel.readstring("smi", smi)

파일로부터 읽고 싶다면, 다음처럼 입력합니다. 

file_name = 'a.pdb'
file_format = 'pdb'
ms = pybel.readfile(file_format, file_name)
m = list(ms)[0]

파일의 경우, 한 파일이 여러 분자, 혹은 conformer를 담고있을 수 있기에 readfile 메소드로 읽으면 파일에 담긴 모든 분자가 읽어집니다. 이때, ms는 list가 아닌 generator object 입니다. list 함수를 사용해서 함수로 바꿔주고, 그중 0번째 성분을 선택할 수 있습니다. 

 여기서 rdkit과 차이가 있는데, rdkit은 기본적으로 하나의 분자가 여러 conformer를 가질 때, 분자 객체는 하나이되, 객체 하나가 여러개의 conformer를 포함할 수 있습니다. 하지만, openbabel은 분자 객체 하나가 하나의 conformer만을 가집니다. 따라서 openbabel은 conformers의 수만큼 분자 객체가 따로 만들어집니다.

 

분자 객체 m을 출력할 때는 m.write 라는 메소드를 사용합니다.

기본 옵션은 m.write(format, 파일명) 입니다. 

format은 smi나 pdb, mol 등이 있습니다. 파일명을 적지 않으면 화면으로 출력되고, 파일명을 적으면 파일로 출력됩니다. 

예를들어 

분자 객체를 smiles로 출력하고 싶다면 다음 명령어를 사용합니다. 

>>>m.write('smi')
'CCCCC\t\n'

만약 파일로 출력하고 싶다면 다음처럼 입력합니다.

기본적으로 덮어쓰기가 False로 되어있습니다. 덮어쓰기를 허용하고 싶다면 overwrite=True로 바꿔줍니다.

m.write('pdb', 'a.pdb', overwrite=True)

 

이제 수소 추가 옵션을 지정해보겠습니다.

수소 추가에는 2가지가 있습니다. 수소 추가라는 표현에는  혼동의 여지가 있습니다. 

수소 표기를 implicit 에서 explicit으로 바꾸라는 경우, 
protonation state를 계산하라는 두가지 경우가 있습니다. 

protonation state 고려하여 수소를 추가할 때는 pybel molecule 객체가 아니라, openbabel의 OBMol 객체를 사용합니다.

m.addh() 도 있긴 한데, 수소 표기를 implicit 에서 explicit으로 바꾸라는 경우에만 사용합니다. 

openbabel 객체는 

mol = m.OBMol

로 불러올 수 있습니다. 

 

m.OBMol.AddHydrogens 객체의 옵션은 

m.OBMol.AddHydrogens(bool polaronly=false, bool correctForPH=false, double pH=7.4)

입니다. 


polaronly는 pdbqt처럼 극성 분자의 수소만을 선택하는 옵션입니다. correctForPH는 주어진 PH에 대해서 protonation state를 고려하라는 옵션입니다. 그냥 비어있는 수소를 채우고 싶다면 false, protonation state를 고려하고 싶다면 True를 넣어줍니다. obabel에서 -p 7.4 옵션과, -h 옵션의 차이에 해당합니다. pH는 correctForPH가 True일 때만 사용하는 옵션으로, 원하는 pH값을 넣어줍니다. 

 

m.addh()  m.OBMol.AddHydrogens(correctForPH=false) 인 경우에 해당합니다. 

 

다음 예제에서 옵션별 차이를 볼 수 있습니다. 

>>> smi = 'CCCC(=O)O'
>>> m = pybel.readstring('smi',smi)
>>> print(m.write('smi'))
CCCC(=O)O

>>> m.OBMol.AddHydrogens(False, False)
CCCC(=O)O
>>> print(m.write('pdb'))
COMPND    UNNAMED
AUTHOR    GENERATED BY OPEN BABEL 3.1.0
HETATM    1  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    2  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    3  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    4  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    5  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O
HETATM    6  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O
HETATM    7  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM    8  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM    9  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   10  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   11  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   12  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   13  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   14  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
CONECT    1    2    7    8    9
CONECT    2    1    3   10   11
CONECT    3    2    4   12   13
CONECT    4    3    5    5    6
CONECT    5    4    4
CONECT    6    4   14
CONECT    7    1
CONECT    8    1
CONECT    9    1
CONECT   10    2
CONECT   11    2
CONECT   12    3
CONECT   13    3
CONECT   14    6
MASTER        0    0    0    0    0    0    0    0   14    0   14    0
END

>>> m.OBMol.AddHydrogens(False, True)
CCCC(=O)[O-]
>>> print(m.write('pdb'))
COMPND    UNNAMED
AUTHOR    GENERATED BY OPEN BABEL 3.1.0
HETATM    1  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    2  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    3  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    4  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    5  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O
HETATM    6  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O1-
HETATM    7  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM    8  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM    9  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   10  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   11  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   12  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
HETATM   13  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
CONECT    1    2    7    8    9
CONECT    2    1    3   10   11
CONECT    3    2    4   12   13
CONECT    4    3    5    5    6
CONECT    5    4    4
CONECT    6    4
CONECT    7    1
CONECT    8    1
CONECT    9    1
CONECT   10    2
CONECT   11    2
CONECT   12    3
CONECT   13    3
MASTER        0    0    0    0    0    0    0    0   13    0   13    0
END

>>> m.OBMol.AddHydrogens(True, True)
>>> print(m.write('pdb'))
COMPND    UNNAMED
AUTHOR    GENERATED BY OPEN BABEL 3.1.0
HETATM    1  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    2  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    3  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    4  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    5  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O
HETATM    6  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O1-
CONECT    1    2
CONECT    2    1    3
CONECT    3    2    4
CONECT    4    3    5    5    6
CONECT    5    4    4
CONECT    6    4
MASTER        0    0    0    0    0    0    0    0    6    0    6    0
END

>>> m = pybel.readstring('smi',smi)
>>> m.OBMol.AddHydrogens(True, False)
True
>>> print(m.write('pdb'))
COMPND    UNNAMED
AUTHOR    GENERATED BY OPEN BABEL 3.1.0
HETATM    1  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    2  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    3  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    4  C   UNL     1       0.000   0.000   0.000  1.00  0.00           C
HETATM    5  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O
HETATM    6  O   UNL     1       0.000   0.000   0.000  1.00  0.00           O
HETATM    7  H   UNL     1       0.000   0.000   0.000  1.00  0.00           H
CONECT    1    2
CONECT    2    1    3
CONECT    3    2    4
CONECT    4    3    5    5    6
CONECT    5    4    4
CONECT    6    4    7
CONECT    7    6
MASTER        0    0    0    0    0    0    0    0    7    0    7    0
END