介绍阅读SDF时的常见问题并说明解决方法。本文是Drug Discovery Advent Calendar 2017(#souyakuAC2017)的第19天文章。
结构式被压碎
下面的程序是试图为第3天从PubChem获得的yes1_inhibition.sdf中记录的前10个化合物绘制结构式的程序。
draw_compounds.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | from rdkit import Chem from rdkit.Chem import Draw spl = Chem.SDMolSupplier('yes1_inhibition.sdf') mols = [] for mol in spl: mols.append(mol) # the first 10 compounds are extracted. mols = mols[:10] img = Draw.MolsToGridImage(mols, molsPerRow=5,subImgSize=(300, 300)) img.save("molecules.png") |
第二和第四复合物像团块一样被压碎,我无法正确绘制。使用文本编辑器或less命令打开yes1_inhibition.sdf以查找原因。首先,让我们检查可以无问题绘制的第一个化合物,即文件的开头。
1 2 3 4 5 6 7 8 9 10 | 11112768 -OEChem-11231705332D 26 30 0 1 0 0 0 0 0999 V2000 -0.6502 -4.8379 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 -2.4607 -3.3498 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 -0.9700 -0.9800 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 1.9800 1.1100 0.0000 N 0 0 3 0 0 0 0 0 0 0 0 0 -0.2000 0.0900 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.2000 0.0000 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 |
每行有3个十进制数字。您可能已经注意到,这些是组成化合物的每个原子的坐标。
由于第三个为0,因此可以看到没有Z轴信息的2D信息得以保留。
顺便说一句,如果按原样滚动SDF内容的屏幕,则应该到达仅显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $$$$ 11113545 -OEChem-11231705332D 19 20 0 0 0 0 0 0 0999 V2000 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 |
第二个化合物位于所有原子的坐标为(0,0,0)的原点。这就是结构式崩溃的原因。有一个草率的化合物,几乎不包含坐标信息。即使在这种情况下,如果适当保留了原子间键的信息,则可以通过RDKit的功能构造二维坐标信息。
draw_compound2.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from rdkit import Chem from rdkit.Chem import Draw, AllChem spl = Chem.SDMolSupplier('yes1_inhibition.sdf') mols = [] for mol in spl: # compute 2D coordinate AllChem.Compute2DCoords(mol) mols.append(mol) # the first 10 compounds are extracted. mols = mols[:10] img = Draw.MolsToGridImage(mols, molsPerRow=5,subImgSize=(300, 300)) img.save("molecules.png") |
通过使用
Compute2DCoords函数构造2D坐标,我们能够绘制所有化合物的结构式。
价态异常引起的警告和错误
现在从下面的URL中获取另一个SDF,并将其加载到刚修改的程序中 1。
- https://pubchem.ncbi.nlm.nih.gov/bioassay/624095
如果您
,您应该得到以下错误:
1 2 3 4 5 6 7 8 9 10 | [03:05:23] Explicit valence for atom # 7 N, 4, is greater than permitted [03:05:23] ERROR: Could not sanitize molecule ending on line 472 [03:05:23] ERROR: Explicit valence for atom # 7 N, 4, is greater than permitted Traceback (most recent call last): File "draw_compounds.py", line 10, in <module> AllChem.Compute2DCoords(mol) Boost.Python.ArgumentError: Python argument types in rdkit.Chem.rdDepictor.Compute2DCoords(NoneType) did not match C++ signature: Compute2DCoords(RDKit::ROMol {lvalue} mol, bool canonOrient=True, bool clearConfs=True, boost::python::dict {lvalue} coordMap={}, unsigned int nFlipsPerSample=0, unsigned int nSample=0, int sampleSeed=0, bool permuteDeg4Nodes=False, double bondLength=-1.0) |
不知何故的错误出现在多行上,但根本原因是
在这种情况下,如果mol设置为None,则快速解决方案是跳过该过程并避免出现错误 2。
draw_compound2.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | from rdkit import Chem from rdkit.Chem import Draw, AllChem # from https://pubchem.ncbi.nlm.nih.gov/bioassay/624095 spl = Chem.SDMolSupplier('antibiotics.sdf') mols = [] for mol in spl: if mol is None: continue # compute 2D coordinate AllChem.Compute2DCoords(mol) mols.append(mol) # first 10 compounds are extracted. mols = mols[:10] img = Draw.MolsToGridImage(mols, molsPerRow=5,subImgSize=(300, 300)) img.save("molecules.png") |
上面的程序将继续显示化合价警告,但不会发生错误,因为不会将None意外传递给Compute2DCoords。
未经修改的程序不会产生错误,但是会引起另一个问题:某些化合物的结构式为空白。 ?
有一种理论上的方法可以将SDF中记录的结构修改为正确的结构,但是似乎很难做到这一点。 ?