之前写过一篇博客介绍smiles编码,smart编码及摩根指纹(ECFP):
(1条消息) RDkit:介绍smiles编码,smart编码及摩根指纹(ECFP)_随便叫点什么……的博客-CSDN博客
smiles编码具有唯一性:每个SMILES编码对应唯一一个化学结构,刚刚接触smiles编码的时候一定会有这样的疑问,为什么同一个化学分子smiles编码有多种表示形式:
c1cccc(c1OC(=O)C)C(O)=O
C(=O)(c1ccccc1OC(C)=O)O
c1c(c(OC(=O)C)ccc1)C(=O)O
c1(OC(C)=O)c(cccc1)C(O)=O
c1cc(c(C(O)=O)cc1)OC(C)=O
c1c(C(=O)O)c(OC(C)=O)ccc1
c1(c(cccc1)C(O)=O)OC(C)=O
c1cccc(C(=O)O)c1OC(=O)C
c1cccc(c1C(=O)O)OC(C)=O
c1cc(c(cc1)C(=O)O)OC(C)=O
当把上面的十个smiles编码作图时,发现得到的是一样的,都是阿司匹林
import rdkit
from rdkit import Chem
from rdkit.Chem import Draw
smiles = ['c1cccc(c1OC(=O)C)C(O)=O','C(=O)(c1ccccc1OC(C)=O)O','c1c(c(OC(=O)C)ccc1)C(=O)O','c1(OC(C)=O)c(cccc1)C(O)=O',
'c1cc(c(C(O)=O)cc1)OC(C)=O','c1c(C(=O)O)c(OC(C)=O)ccc1','c1(c(cccc1)C(O)=O)OC(C)=O','c1cccc(C(=O)O)c1OC(=O)C',
'c1cccc(c1C(=O)O)OC(C)=O','c1cc(c(cc1)C(=O)O)OC(C)=O']
mols = [Chem.MolFromSmiles(smile) for smile in smiles]
Draw.MolsToGridImage(mols, molsPerRow=10)
# 结果分子图显示均为阿司匹林
![](https://img-blog.csdnimg.cn/img_convert/a2e2f995b92de59efc43442503e3fa46.jpeg)
同一种格式的smiles编码的形式可以用不同的方式表示,起始原子序号不同,多种表达形式,可根据此特点来对数据进行数据增强。
https://zhuanlan.zhihu.com/p/92748733
但在数据清洗筛选的过程,就会造成错误和麻烦,假如你从不同的数据库爬取了多条信息,可能出现同一个分子用多个smiles编码表示的情形,分子生成时也会出现类似状况现象,为避免这种状况,需要我们对分子的smiles编码进行统一化,标准化。
下面的脚本,能做到这一点:
# Name = Cleaner.py
import argparse
from tqdm import tqdm
from rdkit import Chem, RDLogger
from rdkit.Chem import MolStandardize
class MolClean(object):
def __init__(self):
self.normizer = MolStandardize.normalize.Normalizer()
self.lfc = MolStandardize.fragment.LargestFragmentChooser()
self.uc = MolStandardize.charge.Uncharger()
def clean(self, smi):
mol = Chem.MolFromSmiles(smi)
if mol:
mol = self.normizer.normalize(mol)
mol = self.lfc.choose(mol)
mol = self.uc.uncharge(mol)
# 此处需注意这里的isomericSmiles及canonical这两个参数,后面会说明
smi = Chem.MolToSmiles(mol, isomericSmiles=False, canonical=True)
return smi
else:
return None
def main(input_file, output_file, **kwargs):
mc = MolClean()
with open(input_file, 'r') as f:
smiles = [r.rstrip() for r in f]
print(f'input SMILES num: {len(smiles)}')
print('Clean Up Started ...')
mc_smiles = [mc.clean(smi) for smi in tqdm(smiles)]
print('Cleanup Completed')
print(f'output SMILES num: {len(mc_smiles)}')
with open(output_file, 'w') as f:
for smi in mc_smiles:
f.write(smi + '\n')
return
if __name__ == '__main__':
print('cleaner')
parser = argparse.ArgumentParser()
parser.add_argument('input', help='input file')
parser.add_argument('output', help='output file')
args = parser.parse_args()
main(args.input, args.output)
在shell中运行:
# 需要统一化标准化的文件名:test.csv,处理后的输出文件名:result.csv
python Cleaner.py test result
下面介绍一下isomericSmiles及canonical这两个参数,在进行smile和mol格式之间转换时(Chem.MolToSmiles),可以设置这两个参数:isomericSmiles代表有立体异构的smiles编码,canonical表示没有标准的没有手性异构的smiles编码。
以布洛芬分子为例:
import rdkit
from rdkit import Chem
from rdkit.Chem import Draw
smi = ['OC(C)CC1=CC=CC=C1','C[C@H](O)CC1=CC=CC=C1']
mol_1 = Chem.MolFromSmiles(smi[0])
mol_1
![](https://img-blog.csdnimg.cn/img_convert/4610ceb0c66ed5e858322ceee2bd2e73.jpeg)
mol_2 = Chem.MolFromSmiles(smi[1])
mol_2
![](https://img-blog.csdnimg.cn/img_convert/f0be7b28d085a3c30ec5c040e4295de7.jpeg)
smi_1 = Chem.MolToSmiles(mol_1,isomericSmiles=False, canonical=True)
print(smi_1)
# CC(O)Cc1ccccc1
smi_2 = Chem.MolToSmiles(mol_2,isomericSmiles=False, canonical=True)
print(smi_2)
# CC(O)Cc1ccccc1
需要文中test.csv文件请私信