pysmiles:一个用于读写SMILES表达式的python库

技术背景

SMILES表达式是化学里面常用的用于标定元素之间关系的字符串,旨在用最简短的语句来完整的表达一个分子体系内所蕴含的基本信息,比如元素、连接性以及连接属性等。由于SMILES表达式的定义种类太多,需要完整介绍的可以阅读这篇博客或者是opensmiles的官方网站。这里我们简单介绍几种常见的情况:

  1. 在SMILES表达式中,往往会去掉\(H\)元素,比如甲烷\(CH_4\)用SMILES表达式来表达的话就是\(C\)
  2. 双键用\(=\)来表示,比如\(C(=O)=O\)表示一个二氧化碳;
  3. 三键用\(#\)来表示,用法与双键一样;
  4. 主干线不加标记,分支加圆括号,比如上面提到的二氧化碳,第一个\(O\)原子不在主分支上,因此加了括号;
  5. 不成键的分子之间用.隔开,比如\(O.C(=O)=O\)表示一个水分子和一个二氧化碳分子;
  6. 成环的要打开来写,并在开头和结尾加上断键标记,比如\(C1CCCCC1\)表示一个环己烷\(C_6H_{12}\),这里的两个1前所对应的碳是相互连接的。

诸如此类的复杂的化学表达式解析,最好是能够有一个方便使用的工具来进行转化,这里介绍的是其中一款:pysmiles。

pysmiles的安装

pysmiles是一个纯粹用python写的sdk,其中借用了networkx的框架来存储元素之间的键连信息。那么我们可以直接使用pip来进行安装和管理:

dechin@ubuntu2004:~/projects/gitlab/dechin/src/smile$ python3 -m pip install pysmiles
Collecting pysmiles
  Downloading pysmiles-1.0.1.tar.gz (34 kB)
Collecting pbr
  Using cached pbr-5.6.0-py2.py3-none-any.whl (111 kB)
Requirement already satisfied: networkx~=2.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from pysmiles) (2.5)
Requirement already satisfied: decorator>=4.3.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from networkx~=2.0->pysmiles) (4.4.2)
Building wheels for collected packages: pysmiles
  Building wheel for pysmiles (setup.py) ... done
  Created wheel for pysmiles: filename=pysmiles-1.0.1-py2.py3-none-any.whl size=22016 sha256=9c9bf6bf2f1667bfdb0d9a3c96f6d4499b7749b0ba4fc63ff45512c9dd1af8db
  Stored in directory: /home/dechin/.cache/pip/wheels/1b/ae/65/19c5062b483dbf3a22b8a42e32dfe1bdfc17f3d31b475e0d2f
Successfully built pysmiles
Installing collected packages: pbr, pysmiles
Successfully installed pbr-5.6.0 pysmiles-1.0.1

因为并没有什么特殊的依赖关系,所以安装还是比较顺利的。

pysmiles的使用

这里我们通过一个简单的案例来展示一下pysmiles的使用方法(其中关于networkx的使用,可以参考这一篇博客):

from pysmiles import read_smiles
import networkx as nx
import matplotlib.pyplot as plt
    
smiles = 'N#CC#N' # 给定的SMILES表达式
mol = read_smiles(smiles) # 读取到一个networkx的网络结构中
print(mol.nodes) # 打印节点信息
print(mol.edges) # 打印边信息
print(nx.to_numpy_matrix(mol)) # 打印邻接矩阵信息

elements = nx.get_node_attributes(mol, name = "element")
nx.draw(mol, with_labels=True, labels=elements)
plt.savefig('pysmiles.png') # 保存图层

上述是一个简单的SMILES表达式读取的程序,执行的结果如下所示:

dechin@ubuntu2004:~/projects/gitlab/dechin/src/smile$ python3 pysmiles_test.py 
[0, 1, 2, 3]
[(0, 1), (1, 2), (2, 3)]
[[0. 1. 0. 0.]
 [1. 0. 1. 0.]
 [0. 1. 0. 1.]
 [0. 0. 1. 0.]]

同时会在当前目录下生成一个利用networkx画出来的简单图片:

当然,这个结构有点过于的简单,如果对于分子模型的展示稍微有点追求的话,可以参考这篇文章所介绍的vmd的使用方法。由于这里我们只是倾向于使用pysmiles的阅读功能,如果要使用pysmiles的写入功能,可以参考如下官方案例,这里不做过多的展开:

import networkx as nx
from pysmiles import write_smiles, fill_valence

mol = nx.Graph()
mol.add_edges_from([(0, 1), (1, 2), (1, 3), (3, 4), (1, 5), (3, 6)])
for idx, ele in enumerate('CCCCOCO'):
    mol.nodes[idx]['element'] = ele
mol.nodes[4]['charge'] = -1
mol.nodes[4]['hcount'] = 0
mol.edges[3, 6]['order'] = 2

print(write_smiles(mol))
# [O-]C(=O)C([C])([C])[C]
fill_valence(mol, respect_hcount=True)
print(write_smiles(mol))
# [O-]C(=O)C(C)(C)C

其实本质上也是通过构建一个networkx的数据结构,再通过这个数据结构去产生一个smiles的字符串。

总结概要

本文介绍了一款基于python语言的SMILES化学表达式的读写SDK,使用openSMILES表达式所定义的分子结构是非常精简的,但是其中的规则又非常的多,因此使用一款友好的SMILES表达式能够大大的缩减解析的成本。并且pysmiles结合了一款非常常用的python的拓扑网络结构表示SDK——networkx,使得对SMILES表达式的结果分析更加的人性化。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/pysmiles.html
作者ID:DechinPhy
更多原著文章请参考:https://www.cnblogs.com/dechinphy/

posted @ 2021-05-10 10:54  DECHIN  阅读(1873)  评论(0编辑  收藏  举报