将SMILES转成InChiKey
Catkin 3 Posts

最近在项目中需要将SMILES转成InChiKey,通常可以在OpenBabelGUI中操作完成,但是对于大量数据在OpenBabelGUI中操作就有些不方便且容易失误。这里记录一下我解决这个问题的过程。

安装相关包

先建立一个虚拟环境,安装RDKit:

1
conda create -c rdkit -n my-rdkit-env rdkit

然后在虚拟环境下安装OpenBabel:

1
conda install -n my-rdkit-env -c openbabel openbabel

出现的问题

最初想用Pybel实现,然而发现Pybel并不支持输出格式为InChiKey,既然这条路走不通,就换个方案吧。于是想查看OpenBabel的文档看看能不能实现,然而发现这玩意的python接口只是寥寥几言,也没有具体的文档。不过Google到了一个轮子写了如何将SMILES转成InChiKey,代码如下:

1
2
3
4
5
6
7
import openbabel as ob
conv = ob.OBConversion()
conv.SetInAndOutFormats("smi", "inchi")
conv.SetOptions("K", conv.OUTOPTIONS)
mol = ob.OBMol()
conv.ReadString(mol, "CC(=O)Cl")
inchikey = conv.WriteString(mol):

本想着问题解决了,不过试了一下发现并不能用。而且可耻的找不到原因……

不过也问题不大,RDKit可以把SMILES转成InChi,然后再把InChi变成InChiKey就行了,于是写了个函数实现:

1
2
3
4
5
6
7
from rdkit import Chem
from rdkit.Chem.inchi import rdinchi
def smiletoinchikey(smile):
mol = Chem.MolFromSmiles(smile)
inchi = rdinchi.MolToInchi(mol)
inchikey = rdinchi.InchiToInchiKey(inchi[0])
return inchikey

然而在处理项目文件时发现,有些SMILES式RDKit不能识别,导致程序出错。如Clc1c([C@@H]2[C@@H]([N+H3])CC(CN3CCC(C(=O)O)CC3)=CC2)ccc(Cl)c1,于是写了个函数利用Pybel将其转成Canonical SMILES。最后还是有一些剩余问题,比如Oc1ccc([C+2]2345[B-2]678[B-3]9%10%11([C-3])[C+]%12%13%14[B-2]%15%169[B-2]26%10[B-2]23%15[B-2]364[B-2]457[B-2]8%11%12[B-2]%1334[B-2]%14%1626)cc1转成Canonical SMILES依然无法读取,又或者O=BOB(OB(OB=O)[O-])[O-]没转换前能读取,转换后不能读取,只能按例外处理。

最后代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : Thu Apr 20 16:12:41 2018
# @Author : Catkin
# @Website : blog.catkin.moe

import pybel
from rdkit import Chem
from rdkit.Chem.inchi import rdinchi

def smitosmile(smi):
mol = pybel.readstring("smi", smi)
smile = mol.write('can')
smile = smile.replace('\t\n', '')
return smile

def smiletoinchikey(smile):
mol = Chem.MolFromSmiles(smile)
if mol is None:
smi = smitosmile(smile)
mol = Chem.MolFromSmiles(smi)
inchi = rdinchi.MolToInchi(mol)
inchikey = rdinchi.InchiToInchiKey(inchi[0])
return inchikey

用OpenBabel同样也可以把SMILES转成Canonical SMILES:

1
2
3
4
5
6
7
8
9
10
import openbabel as ob
def obsmitosmile(smi):
conv = ob.OBConversion()
conv.SetInAndOutFormats("smi", "can")
conv.SetOptions("K", conv.OUTOPTIONS)
mol = ob.OBMol()
conv.ReadString(mol, smi)
smile = conv.WriteString(mol)
smile = smile.replace('\t\n', '')
return smile
  • Post title:将SMILES转成InChiKey
  • Post author:Catkin
  • Create time:2018-04-21 10:24
  • Post link:https://blog.iamkotori.com/2018/04/21/将SMILES转成InChiKey/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments