今日踩坑小结:
openbabel 安装:
可以装,但是得在 Linux 环境下,win 环境装会报错(安装不会报错,但是生成指纹的时候会)
指纹:
在下面这个链接里,官方给出了命令行调用 openbabel 生成指纹的方法
https://open-babel.readthedocs.io/en/latest/Fingerprints/fingerprints.html
在下面这个链接里,官方给出了 pybel 生成指纹的方法
https://open-babel.readthedocs.io/en/latest/UseTheLibrary/Python_Pybel.html#fingerprints
其中,pybel 教程中指出,fp 对象有两个属性,bits
和 fps
fp.bits 会返回 1024 维 one-hot 向量上,值为 1 的位置。注意此处的位置是从 1 开始的
在 Linux 下:
conda install openbabel
随后可以运行下面这段代码拿到 1024 维 one-hot 指纹向量:
from openbabel import pybelsmiles = ['CCCC', 'CCCN']
mols = [pybel.readstring("smi", x) for x in smiles]
fps = [x.calcfp() for x in mols]
example_bits = fps[1].bitsdef list_to_binary2(positions, binary_length=1024):binary_code = ['0'] * binary_length # Initialize with all zerosfor pos in positions:if 0 <= pos < binary_length:binary_code[pos-1] = '1'return ''.join(binary_code)# start from 1
position_list = example_bits
binary_number_new = list_to_binary2(position_list)
decimal_number_new = int(binary_number_new, 2)
print(decimal_number_new)
除了 bits
,fp 还有一个属性叫 fps
该例中:
fps[1].bits = [83, 261, 349, 671, 907]
我们可以使用 numpy
将其进行转换,我们将得到一个长度为 32 的向量。
如果我们把总向量长度 1024 进行切分,可以切分成 32 块。所以此长度为 32 的向量对应 32 块中每一块的压缩值(十进制),因此将每个十进制数转换成二进制,就能复原总长 1024 对应区块的值。
比如,该例中,
fps[1].fp = [ 0 0 262144 0 0 00 0 16 0 268435456 00 0 0 0 0 00 0 1073741824 0 0 00 0 0 0 1024 00 0]
我们可以使用下面这段程序拿到复原后的 1024 维向量:
from openbabel import pybel
import numpy as npsmiles = ['CCCC', 'CCCN']
mols = [pybel.readstring("smi", x) for x in smiles]
fps = [x.calcfp() for x in mols]
example_bits = fps[1].fpdef list_to_binary(number_list, fixed_bits=32):all_code = ''for idx, a_num in enumerate((number_list)):binary_representation = format(a_num, f'0{fixed_bits}b')all_code = all_code + binary_representation[::-1]return all_code# start from 1
position_list = np.array(example_bits)
binary_number_new = list_to_binary(position_list)
decimal_number_new = int(binary_number_new, 2)
print(decimal_number_new)
在 Linux 环境下运行上述两脚本
二者输出相同的十进制数,表示我们前面 bits 从1开始计数
没有问题。我们可以通过上述两种途径将 fingerprint 转换成 1024 维 one-hot 向量。