对复合数据读取进行故障排除


介绍阅读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")

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")

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)

不知何故的错误出现在多行上,但根本原因是Explicit valence for atom # 7 N, 4, is greater than permitted部分。 RDKit认为N的化合价为4,大于允许的化合价。当然,从化学常识来看,中性氮原子的价数为3,因此可以理解,读取具有异常结构的化合物的尝试失败了。此外,在这种情况下,RDKit旨在将None设置为mol。结果,没有任何内容意外传递给Compute2D Coords,这是程序引发错误的直接原因。

在这种情况下,如果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")

molecules.png

上面的程序将继续显示化合价警告,但不会发生错误,因为不会将None意外传递给Compute2DCoords。

  • 未经修改的程序不会产生错误,但是会引起另一个问题:某些化合物的结构式为空白。 ?

  • 有一种理论上的方法可以将SDF中记录的结构修改为正确的结构,但是似乎很难做到这一点。 ?