口袋条件下的Lead优化几何深度模型-Delete 评测

Delete (Deep lead optimization enveloped in protein pocket) 是一个基于口袋的,3D分子生成的,应用于lead优化过程中侧链修饰、骨架跃迁,linker设计,片段生长的几何深度学习模型。

一、模型介绍

Delete 模型是浙江大学侯廷军老师发表2023年8月4日在arXiv上的文章,文章名:Delete: Deep Lead Optimization Enveloped in Protein Pocket。第一作者是Haotian Zhang。Haotian Zhang也是之前介绍的ResGen的第一作者,是一位非常高产的,AI4Science工作者。侯廷军老师在AI药物设计的模型非常丰富,效果也不错,值得好好应用与研究。

Delete模型通过几何神经网络融合口袋-配体相互作用学习口袋残基和小分子之间的相互作用,进一步利用掩码 (mask) 策略,处理先导化合物优化的所有子任务,包括:片段生长、连接和替换,在口袋内直接生成3D的分子。

之前介绍的分子生成、片段生长、linker设计等方法,都是单一功能的,一个模型仅有一种功能,不能同时满足lead化合物优化的片段生长、连接和替换三种应用场景。但是,Delete模型可以,是先导化合物优化的整合模型。

对于linker设计任务,使用MMP切割烷基单键。对于片段生长任务,切割功能片段的烷基单键。对于骨架跃迁任务,使用Bemis-Murcko提取骨架。对于侧链修饰任务,使切割侧链的单键。

Delete在生成分子时,逐步经过锚点枚举打分,原子放置,连接键预测三个过程,一直重复,直到分子中所有原子预测的分数低于锚点阈值,停止生长。

在模型训练时,Deletet会随机mask原子,分为7种模式,其中3种(random mask, spatial mask, 和 topological mask)用于模型的预训练,剩下4种(linker mask, fragment mask, scaffold mask, and side-chain mask)分别对应Delete的linker设计,骨架跃迁,片段生长,侧链修饰4种应用。

二、模型性能

Delete模型训练使用的数据集是CrossDock和BindingMoad,分别含有10W和3.5W分子-口袋对。作者训练三个版本,分别是:使用CrossDock数据集训练的 Delete-C, 使用BindingMoad数据集训练的Delete-M,以及先使用CrossDock数据集训练后再使用BindingMoad数据集微调的Delete-CM。

Delete-CM在 linker 设计的任务中,生成的分子Docking Energy, Scoring Energy均低于数据集平均值,也低于之前介绍的Difflinker。

作者在文章中,给出了一些案例。

下图是Delete应用与linker设计的案例。

使用的体系是IMPDH,晶体结构为:5OU2。D图为Detele的输入结构,红色部分为Delete需要设计的Linker部分。图E给出了4个生成的分子,及其类药性质。图F给出Docking score的分布,图G给出 scoring energy 的分布。

文中介绍,生成了76个不同的化合物,2D分子相似性为0.5,而3D分子相似性高达0.92。65.7%生成的分子docking score 优于参考分子。

PROTAC linker设计案例,如下图。Delete生成了106个分子,其中,88.7%具有更好的vina score,在docking下,有98.1%的分子的docking score优于参考分子。3D相似性高达0.891,SA分数均值为0.5446。

三、模型测评

3.1 环境安装

复制项目代码

git clone https://github.com/HaotianZhangAI4Science/Delete.git

创建conda环境

作者提供了两种环境安装方法,一种是mamba安装,一种是直接下载conda环境包安装。我首先测试了mamba安装,因为作者提供的yml文件有问题,所以安装失败。

因此这里采用第二种安装方式,下载作者提供的conda环境包。网址是:

Delete environment

按照作者的提示,解压到conda的环境目录。先新建env,然后上传delete.tar.gz

到env目录,然后解压,然后移动到conda环境中,我这里是 /home/anaconda3/envs/

mkdir env 
tar -zxcf delete.tar.gz env
mv env /home/anaconda3/envs/Delete
# 激活环境
conda activate Delete

我环境安装完成后,使用conda导出了环境的yml文件,如下。大家可以通过conda自行安装。

channels:
  - pyg
  - <unknown>
  - https://mirrors.ustc.edu.cn/anaconda/cloud/bioconda
  - pytorch
  - https://mirrors.ustc.edu.cn/anaconda/pkgs/free
  - https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge
  - conda-forge
  - defaults
dependencies:
  - _libgcc_mutex=0.1=conda_forge
  - _openmp_mutex=4.5=2_kmp_llvm
  - alsa-lib=1.2.6.1=h7f98852_0
  - argon2-cffi=21.3.0=pyhd8ed1ab_0
  - argon2-cffi-bindings=21.2.0=py38h0a891b7_2
  - asttokens=2.0.8=pyhd8ed1ab_0
  - attr=2.5.1=h166bdaf_1
  - attrs=22.1.0=pyh71513ae_1
  - backcall=0.2.0=pyh9f0ad1d_0
  - backports=1.0=py_2
  - backports.functools_lru_cache=1.6.4=pyhd8ed1ab_0
  - beautifulsoup4=4.11.1=pyha770c72_0
  - biopython=1.79=py38h0a891b7_2
  - blas=1.0=mkl
  - bleach=5.0.1=pyhd8ed1ab_0
  - boost=1.74.0=py38h2b96118_5
  - boost-cpp=1.74.0=h75c5d50_8
  - brotli=1.0.9=h166bdaf_7
  - brotli-bin=1.0.9=h166bdaf_7
  - brotlipy=0.7.0=py38h0a891b7_1004
  - bzip2=1.0.8=h7f98852_4
  - ca-certificates=2024.2.2=hbcca054_0
  - cairo=1.16.0=ha61ee94_1014
  - certifi=2024.2.2=pyhd8ed1ab_0
  - cffi=1.15.1=py38h4a40e3a_0
  - charset-normalizer=2.1.1=pyhd8ed1ab_0
  - colorama=0.4.5=pyhd8ed1ab_0
  - contourpy=1.0.5=py38h43d8883_0
  - cryptography=37.0.4=py38h2b5fc30_0
  - cudatoolkit=11.3.1=h9edb442_10
  - cycler=0.11.0=pyhd8ed1ab_0
  - dbus=1.13.6=h5008d03_3
  - debugpy=1.6.3=py38hfa26641_0
  - decorator=5.1.1=pyhd8ed1ab_0
  - defusedxml=0.7.1=pyhd8ed1ab_0
  - easydict=1.9=py_0
  - entrypoints=0.4=pyhd8ed1ab_0
  - executing=1.0.0=pyhd8ed1ab_0
  - expat=2.4.8=h27087fc_0
  - ffmpeg=4.3=hf484d3e_0
  - fftw=3.3.4=0
  - flit-core=3.7.1=pyhd8ed1ab_0
  - font-ttf-dejavu-sans-mono=2.37=hab24e00_0
  - font-ttf-inconsolata=3.000=h77eed37_0
  - font-ttf-source-code-pro=2.038=h77eed37_0
  - font-ttf-ubuntu=0.83=hab24e00_0
  - fontconfig=2.14.0=hc2a2eb6_1
  - fonts-conda-ecosystem=1=0
  - fonts-conda-forge=1=0
  - fonttools=4.37.3=py38h0a891b7_0
  - freetype=2.12.1=hca18f0e_0
  - gettext=0.19.8.1=h73d1719_1008
  - glib=2.72.1=h6239696_0
  - glib-tools=2.72.1=h6239696_0
  - gmp=6.2.1=h58526e2_0
  - gnutls=3.6.13=h85f3911_1
  - greenlet=1.1.3=py38hfa26641_0
  - gst-plugins-base=1.20.3=hf6a322e_0
  - gstreamer=1.20.3=hd4edc92_2
  - icu=70.1=h27087fc_0
  - idna=3.4=pyhd8ed1ab_0
  - importlib-metadata=4.11.4=py38h578d9bd_0
  - importlib_resources=5.9.0=pyhd8ed1ab_0
  - ipykernel=6.15.3=pyh210e3f2_0
  - ipython=8.5.0=pyh41d4057_1
  - ipython_genutils=0.2.0=py_1
  - ipywidgets=8.0.2=pyhd8ed1ab_1
  - jack=1.9.18=h8c3723f_1002
  - jedi=0.18.1=pyhd8ed1ab_2
  - jinja2=3.1.2=pyhd8ed1ab_1
  - joblib=1.2.0=pyhd8ed1ab_0
  - jpeg=9e=h166bdaf_2
  - json-c=0.16=hc379101_0
  - jsonschema=4.16.0=pyhd8ed1ab_0
  - jupyter=1.0.0=py38h578d9bd_7
  - jupyter_client=7.3.5=pyhd8ed1ab_0
  - jupyter_console=6.4.4=pyhd8ed1ab_0
  - jupyter_core=4.11.1=py38h578d9bd_0
  - jupyterlab_pygments=0.2.2=pyhd8ed1ab_0
  - jupyterlab_widgets=3.0.3=pyhd8ed1ab_0
  - keyutils=1.6.1=h166bdaf_0
  - kiwisolver=1.4.4=py38h43d8883_0
  - krb5=1.19.3=h3790be6_0
  - lame=3.100=h7f98852_1001
  - lcms2=2.12=hddcbb42_0
  - ld_impl_linux-64=2.36.1=hea4e1c9_2
  - lerc=4.0.0=h27087fc_0
  - libbrotlicommon=1.0.9=h166bdaf_7
  - libbrotlidec=1.0.9=h166bdaf_7
  - libbrotlienc=1.0.9=h166bdaf_7
  - libcap=2.64=ha37c62d_0
  - libclang=14.0.6=default_h2e3cab8_0
  - libclang13=14.0.6=default_h3a83d3e_0
  - libcups=2.3.3=h3e49a29_2
  - libdb=6.2.32=h9c3ff4c_0
  - libdeflate=1.14=h166bdaf_0
  - libedit=3.1.20191231=he28a2e2_2
  - libevent=2.1.10=h9b69904_4
  - libffi=3.4.2=h7f98852_5
  - libflac=1.3.4=h27087fc_0
  - libgcc-ng=12.1.0=h8d9b700_16
  - libgfortran-ng=7.5.0=h14aa051_20
  - libgfortran4=7.5.0=h14aa051_20
  - libglib=2.72.1=h2d90d5f_0
  - libiconv=1.16=h516909a_0
  - libllvm14=14.0.6=he0ac6c6_0
  - libnsl=2.0.0=h7f98852_0
  - libogg=1.3.4=h7f98852_1
  - libopus=1.3.1=h7f98852_1
  - libpng=1.6.38=h753d276_0
  - libpq=14.5=hd77ab85_0
  - libsndfile=1.0.31=h9c3ff4c_1
  - libsodium=1.0.18=h36c2ea0_1
  - libsqlite=3.39.3=h753d276_0
  - libstdcxx-ng=12.1.0=ha89aaad_16
  - libtiff=4.4.0=h55922b4_4
  - libtool=2.4.6=h9c3ff4c_1008
  - libuuid=2.32.1=h7f98852_1000
  - libuv=1.44.2=h166bdaf_0
  - libvorbis=1.3.7=h9c3ff4c_0
  - libwebp-base=1.2.4=h166bdaf_0
  - libxcb=1.13=h7f98852_1004
  - libxkbcommon=1.0.3=he3ba5ed_0
  - libxml2=2.9.14=h22db469_4
  - libxslt=1.1.35=h8affb1d_0
  - libzlib=1.2.12=h166bdaf_3
  - llvm-openmp=14.0.4=he0ac6c6_0
  - lxml=4.9.1=py38h0a891b7_0
  - markupsafe=2.1.1=py38h0a891b7_1
  - matplotlib-base=3.6.0=py38hb021067_0
  - matplotlib-inline=0.1.6=pyhd8ed1ab_0
  - mistune=2.0.4=pyhd8ed1ab_0
  - mkl=2021.4.0=h8d4b97c_729
  - mkl-service=2.4.0=py38h95df7f1_0
  - mkl_fft=1.3.1=py38h8666266_1
  - mkl_random=1.2.2=py38h1abd341_0
  - munkres=1.0.7=py_1
  - mysql-common=8.0.30=haf5c9bc_1
  - mysql-libs=8.0.30=h28c427c_1
  - nbclient=0.6.8=pyhd8ed1ab_0
  - nbconvert=7.0.0=pyhd8ed1ab_0
  - nbconvert-core=7.0.0=pyhd8ed1ab_0
  - nbconvert-pandoc=7.0.0=pyhd8ed1ab_0
  - nbformat=5.5.0=pyhd8ed1ab_0
  - ncurses=6.3=h27087fc_1
  - nest-asyncio=1.5.5=pyhd8ed1ab_0
  - nettle=3.6=he412f7d_0
  - networkx=2.8.6=pyhd8ed1ab_0
  - notebook=6.4.12=pyha770c72_0
  - nspr=4.32=h9c3ff4c_1
  - nss=3.78=h2350873_0
  - numpy=1.23.1=py38h6c91a56_0
  - numpy-base=1.23.1=py38ha15fc14_0
  - openh264=2.1.1=h780b84a_0
  - openjpeg=2.5.0=h7d73246_1
  - openssl=1.1.1w=hd590300_0
  - packaging=21.3=pyhd8ed1ab_0
  - pandas=1.5.0=py38h8f669ce_0
  - pandoc=2.19.2=ha770c72_0
  - pandocfilters=1.5.0=pyhd8ed1ab_0
  - parso=0.8.3=pyhd8ed1ab_0
  - pcre=8.45=h9c3ff4c_0
  - pexpect=4.8.0=pyh9f0ad1d_2
  - pickleshare=0.7.5=py_1003
  - pillow=9.2.0=py38ha3b2c9c_2
  - pip=22.2.2=pyhd8ed1ab_0
  - pixman=0.40.0=h36c2ea0_0
  - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_0
  - ply=3.11=py_1
  - plyfile=0.7.4=pyhd8ed1ab_0
  - portaudio=19.6.0=h57a0ea0_5
  - prometheus_client=0.14.1=pyhd8ed1ab_0
  - prompt-toolkit=3.0.31=pyha770c72_0
  - prompt_toolkit=3.0.31=hd8ed1ab_0
  - psutil=5.9.2=py38h0a891b7_0
  - pthread-stubs=0.4=h36c2ea0_1001
  - ptyprocess=0.7.0=pyhd3deb0d_0
  - pulseaudio=14.0=h583eb01_5
  - pure_eval=0.2.2=pyhd8ed1ab_0
  - pycairo=1.21.0=py38h9c00e7a_1
  - pycparser=2.21=pyhd8ed1ab_0
  - pyg=2.0.4=py38_torch_1.11.0_cu113
  - pygments=2.13.0=pyhd8ed1ab_0
  - pyopenssl=22.0.0=pyhd8ed1ab_0
  - pyparsing=3.0.9=pyhd8ed1ab_0
  - pyqt=5.15.7=py38h7492b6b_0
  - pyqt5-sip=12.11.0=py38hfa26641_0
  - pyrsistent=0.18.1=py38h0a891b7_1
  - pysocks=1.7.1=pyha2e5f31_6
  - python=3.8.13=h582c2e5_0_cpython
  - python-dateutil=2.8.2=pyhd8ed1ab_0
  - python-fastjsonschema=2.16.2=pyhd8ed1ab_0
  - python-louvain=0.15=pyhd8ed1ab_1
  - python_abi=3.8=2_cp38
  - pytorch=1.11.0=py3.8_cuda11.3_cudnn8.2.0_0
  - pytorch-cluster=1.6.0=py38_torch_1.11.0_cu113
  - pytorch-mutex=1.0=cuda
  - pytorch-scatter=2.0.9=py38_torch_1.11.0_cu113
  - pytorch-sparse=0.6.14=py38_torch_1.11.0_cu113
  - pytorch-spline-conv=1.2.1=py38_torch_1.11.0_cu113
  - pytz=2022.2.1=pyhd8ed1ab_0
  - pyyaml=6.0=py38h0a891b7_4
  - pyzmq=24.0.0=py38hfc09fa9_0
  - qt-main=5.15.4=ha5833f6_2
  - qtconsole=5.3.2=pyhd8ed1ab_0
  - qtconsole-base=5.3.2=pyha770c72_0
  - qtpy=2.2.0=pyhd8ed1ab_0
  - rdkit=2022.09.1=py38h28c1a8d_0
  - readline=8.1.2=h0f457ee_0
  - reportlab=3.5.68=py38hadf75a6_1
  - requests=2.28.1=pyhd8ed1ab_1
  - scikit-learn=1.1.1=py38h6a678d5_0
  - scipy=1.7.1=py38h292c36d_2
  - send2trash=1.8.0=pyhd8ed1ab_0
  - setuptools=65.3.0=pyhd8ed1ab_1
  - sip=6.6.2=py38hfa26641_0
  - six=1.16.0=pyh6c4a22f_0
  - soupsieve=2.3.2.post1=pyhd8ed1ab_0
  - sqlalchemy=1.4.41=py38h0a891b7_0
  - sqlite=3.39.3=h4ff8645_0
  - stack_data=0.5.0=pyhd8ed1ab_0
  - system=5.8=2
  - tbb=2021.5.0=h924138e_2
  - terminado=0.15.0=py38h578d9bd_0
  - threadpoolctl=3.1.0=pyh8a188c0_0
  - tinycss2=1.1.1=pyhd8ed1ab_0
  - tk=8.6.12=h27826a3_0
  - toml=0.10.2=pyhd8ed1ab_0
  - torchaudio=0.11.0=py38_cu113
  - torchvision=0.12.0=py38_cu113
  - tornado=6.2=py38h0a891b7_0
  - tqdm=4.64.1=pyhd8ed1ab_0
  - traitlets=5.4.0=pyhd8ed1ab_0
  - typing_extensions=4.3.0=pyha770c72_0
  - unicodedata2=14.0.0=py38h0a891b7_1
  - urllib3=1.26.11=pyhd8ed1ab_0
  - wcwidth=0.2.5=pyh9f0ad1d_2
  - webencodings=0.5.1=py_1
  - wheel=0.37.1=pyhd8ed1ab_0
  - widgetsnbextension=4.0.3=pyhd8ed1ab_0
  - xcb-util=0.4.0=h166bdaf_0
  - xcb-util-image=0.4.0=h166bdaf_0
  - xcb-util-keysyms=0.4.0=h166bdaf_0
  - xcb-util-renderutil=0.3.9=h166bdaf_0
  - xcb-util-wm=0.4.1=h166bdaf_0
  - xorg-kbproto=1.0.7=h7f98852_1002
  - xorg-libice=1.0.10=h7f98852_0
  - xorg-libsm=1.2.3=hd9c2040_1000
  - xorg-libx11=1.7.2=h7f98852_0
  - xorg-libxau=1.0.9=h7f98852_0
  - xorg-libxdmcp=1.1.3=h7f98852_0
  - xorg-libxext=1.3.4=h7f98852_1
  - xorg-libxrender=0.9.10=h7f98852_1003
  - xorg-renderproto=0.11.1=h7f98852_1002
  - xorg-xextproto=7.3.0=h7f98852_1002
  - xorg-xproto=7.0.31=h7f98852_1007
  - xz=5.2.6=h166bdaf_0
  - yacs=0.1.8=pyhd8ed1ab_0
  - yaml=0.2.5=h7f98852_2
  - zeromq=4.3.4=h9c3ff4c_1
  - zipp=3.8.1=pyhd8ed1ab_0
  - zlib=1.2.12=h166bdaf_3
  - zstd=1.5.2=h6239696_4
  - pip:
      - lmdb==1.3.0
prefix: /home/anaconda3/envs/Delete

3.2 下载checkpoint

作者提供了训练好的checkpoint,下载链接:Delete pretrained checkpoint

下载完成后,需要新建并将checkpoint放置在目录 ./checkpoint/ckpt下。

有趣的是,按照文章的说法,Delete有4中应用,对应着在预训练之后的四种不同的mask方式。但是作者只给出了一个checkpoint。

3.3 使用作者提供的案例,进行测试

在GitHub的代码中,作者提供了几个测试案例。这里我对2VT4体系进行了测试。2VT4的小分子以及口袋如下图所示,其中,黄色的吲哚环,是属于要替换的部分:

Delete需要提供口袋表面的ply文件,以及分子片段。其中,2VT4的口袋表面的ply文件作者已经准备好,放置在./example/adrb1/adrb_pocket_8.0.ply 路径中。Delete的起点分子片段,作者放置在./example/adrb1/2VT4_frag.sdf。Delete的起点分子片段如下图:

在./目录,运行如下代码生成分子:

python -u Delete.py \
  --surf_path ./example/adrb1/adrb_pocket_8.0.ply \
  --frag_path ./example/adrb1/2VT4_frag.sdf \
  --check_point ./checkpoint/ckpt/delete.pt \
  --outdir ./outputs \
  --suboutdir adrb1

运行输出:

/home/anaconda3/envs/Delete/lib/python3.8/site-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.23.1                                                                                                                                                                                              
  warnings.warn(f"A NumPy version >={np_minversion} and <{np_maxversion}"
Num of parameters is 37.06M
Start to generate!
/home/anaconda3/envs/Delete/lib/python3.8/site-packages/torch/functional.py:568: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at  /opt/conda/conda-bld/pytorch_1646755903507/work/aten/src/ATen/native/TensorShape.cpp:2228.)
  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]
Success: CC(=O)NCOCC(O)CNC(C)(C)C
Success: CC(C)(C)NCC(O)COc1ccccc1
... ...

生成的分子保存在.//outputs/adrb1/delete路径中,每个分子是一个sdf文件,默认生成了175个分子,如下图。

Delete_2VT4_case

看起来,生成的分子还不错,大多数为并环和三并环结构,与原来的参考分子有较高的相似性。

3.4 使用自己的测试案例

3.4.1 环境准备

使用自己的案例,需要先生成口袋表面的ply文件。

创建Surface conda 环境:

conda create -n Surface \
  pymesh2 jupyter scipy joblib biopython \
  rdkit plyfile -c conda-forge

apbs和pdb2pqr 安装需要另外下载安装包。

其中,apbs版本要选择3.0.0,下载链接:Releases · Electrostatics/apbs · GitHub 为了简单,我下载是预编译编版本,如下图:

下载完成后,进行解压,例如:/home/AI_Methods/Delete/APBS-3.0.0.Linux,然后修改~/.bashrc文件,新增一行:(需要根据解压目录,进行修改路径)

export LD_LIBRARY_PATH=/home/AI_Methods/Delete/APBS-3.0.0.Linux/lib

pdb2pqr选择2.1.0,下载链接是:https://github.com/Electrostatics/apbs-pdb2pqr/releases ,同样下载的是预编译版本。

下载完成后解压,我这里的解压路径:为:/home/AI_Methods/Delete/pdb2pqr-linux-bin64-2.1.0

3.4.2 修改代码

在代码中,作者调用了msms, apbs, pdb2pqr 和 multivalue模块,因此需要根据上述的两个解压路径,修改./data/surface_maker_test.py文件内容:

msms_bin="/home/haotian/Molecule_Generation/SurfBP/dataset/install_software/APBS-3.0.0.Linux/bin/msms"
apbs_bin = '/home/haotian/Molecule_Generation/SurfBP/dataset/install_software/APBS-3.0.0.Linux/bin/apbs'
pdb2pqr_bin="/home/haotian/Molecule_Generation/SurfBP/dataset/install_software/pdb2pqr-linux-bin64-2.1.1/pdb2pqr"
multivalue_bin="/home/haotian/Molecule_Generation/SurfBP/dataset/install_software/APBS-3.0.0.Linux/share/apbs/tools/bin/multivalue"

修改为:

msms_bin="/home/AI_Methods/Delete/APBS-3.0.0.Linux/bin/msms"
apbs_bin = '/home/AI_Methods/Delete/APBS-3.0.0.Linux/bin/apbs'
pdb2pqr_bin="/home/AI_Methods/Delete/pdb2pqr-linux-bin64-2.1.0/pdb2pqr"
multivalue_bin="/home/AI_Methods/Delete/APBS-3.0.0.Linux/share/apbs/tools/bin/multivalue"

注意,如果下载不同版本的pdb2pqr,需要去相应的路径检查,是否存在msms, multivalue两个模块。一些版本,缺失这两个模块。

同时./data/surface_maker_test.py还需要做以下修改,以便对不同的体系做表面:

prot_path = './1z6e_protein.pdb'
lig_path = './1z6e_ligand.mol2'

修改为:

lig_path = args.lig_file # wufeil
prot_path = args.pdb_file # wufeil

除此之外,由于作者提供的./utils/masif/computeAPBS.py部分代码,由于版本或者其他原因,无法运行,也需要修改。直接替换computeAPBS函数如下:

def computeAPBS(vertices, pdb_file, apbs_bin, pdb2pqr_bin, multivalue_bin, workdir="."):
    """
        Calls APBS, pdb2pqr, and multivalue and returns the charges per vertex
    """
    cmd = pdb2pqr_bin + " --ff=PARSE --whitespace --noopt --apbs-input %s temp1"%(pdb_file)
    # p = subprocess.Popen([cmd], shell=True, cwd=workdir)
    p = subprocess.Popen([cmd], shell=True, cwd='./') # wufeil
    p.wait()
    
    cmd = apbs_bin + " temp1.in"
    # p = subprocess.Popen([cmd], shell=True, cwd=workdir) 
    p = subprocess.Popen([cmd], shell=True, cwd='./') # wufeil
    p.wait()
    
    vertfile = open("%s/temp1.csv"%workdir, "w")
    for vert in vertices:
        vertfile.write("{},{},{}\n".format(vert[0], vert[1], vert[2]))
    vertfile.close()
    
    # cmd = multivalue_bin + " temp1.csv temp1.dx temp1_out.csv"
    cmd = multivalue_bin + " temp1.csv ../temp1.dx temp1_out.csv" # wufeil
    p = subprocess.Popen([cmd], shell=True, cwd=workdir)
    # p = subprocess.Popen([cmd], shell=True, cwd='./') # wufeil
    p.wait()
    
    # Read the charge file
    chargefile = open("%s/temp1_out.csv"%workdir)
    charges = np.array([0.0] * len(vertices))
    for ix, line in enumerate(chargefile.readlines()):
        charges[ix] = float(line.split(",")[3])
    #os.system("rm " + tmp_file_base + "*")
    #os.system("rm io.mc")
    
    return charges

3.4.3 生成surface ply文件

在./data目录下运行如下命令:

python surface_maker_test.py --check_software True

默认是对./data目录下的3cl.pdb体系的3cl_ligand.sdf口袋生成surface文件。重要输出如下:

... ...

Parsing input file temp1.in...
rank 0 size 1...
Parsed input file.
Got paths for 1 molecules
Reading PQR-format atom data from temp1.
  1394 atoms
  Centered at (-1.636e+01, 1.749e+01, 6.603e+01)
  Net charge 3.33e-16 e
Preparing to run 2 PBE calculations.
----------------------------------------
CALCULATION #1: MULTIGRID
  Setting up problem...
  Vpbe_ctor:  Using max ion radius (0 A) for exclusion function
  Debye length:  0 A
  Current memory usage:  292.214 MB total, 292.214 MB high water
  Using cubic spline charge discretization.
  Grid dimensions: 97 x 129 x 97
  Grid spacings: 0.615 x 0.534 x 0.633
  Grid lengths: 59.027 x 68.342 x 60.807
  Grid center: (-16.364, 17.491, 66.026)
  Multigrid levels: 4
  Molecule ID: 1
  Linearized traditional PBE
  Single Debye-Huckel sphere boundary conditions
  0 ion species (0.000 M ionic strength):
  Solute dielectric: 2.000
  Solvent dielectric: 78.540
  Using "molecular" surface definition;harmonic average smoothing
  Solvent probe radius: 1.400 A
  Temperature:  298.150 K
  Electrostatic energies will be calculated
  Total electrostatic energy = 4.681582329937E+04 kJ/mol
  Calculating forces...
----------------------------------------
CALCULATION #2: MULTIGRID
  Setting up problem...
  Vpbe_ctor:  Using max ion radius (0 A) for exclusion function
  Debye length:  0 A
  Current memory usage:  292.214 MB total, 581.598 MB high water
  Using cubic spline charge discretization.
  Grid dimensions: 97 x 129 x 97
  Grid spacings: 0.570 x 0.470 x 0.581
  Grid lengths: 54.722 x 60.201 x 55.769
  Grid center: (-16.364, 17.491, 66.026)
  Multigrid levels: 4
  Molecule ID: 1
  Linearized traditional PBE
  Boundary conditions from focusing
  0 ion species (0.000 M ionic strength):
  Solute dielectric: 2.000
  Solvent dielectric: 78.540
  Using "molecular" surface definition;harmonic average smoothing
  Solvent probe radius: 1.400 A
  Temperature:  298.150 K
  Electrostatic energies will be calculated
  Potential to be written to temp1.dx
  Total electrostatic energy = 5.558845164011E+04 kJ/mol
  Calculating forces...
  Writing potential to temp1.dx
----------------------------------------
PRINT STATEMENTS

print energy 1 end
  Local net energy (PE 0) = 5.558845164011E+04 kJ/mol
  Global net ELEC energy = 5.558845164011E+04 kJ/mol
----------------------------------------
CLEANING UP AND SHUTTING DOWN...
Destroying force arrays.
No energy arrays to destroy.
Destroying multigrid structures.
Destroying finite element structures.
Destroying 1 molecules
Final memory usage:  0.001 MB total, 581.598 MB high water


Thanks for using APBS!

... ...

3cl_pocket_8.0.ply就是我们需要的文件。

3.4.4 生成分子

使用上述生成的3cl_pocket_8.0.ply继续生成分子:

python -u Delete.py   \
  --surf_path ./example/3lc/3cl_pocket_8.0.ply   \
  --frag_path ./example/3lc/3cl_frag.sdf   \
  --check_point ./checkpoint/ckpt/delete.pt   \
  --outdir ./outputs_3lc   \
  --suboutdir 3lc

注意,需要先创建3lc目录,里面放置3cl_pocket_8.0.ply, 3cl_frag.sdf文件。

与之前的案例不同,3cl_frag.sdf是我自己创建的,切除了中间的酯键的linker,如下图:

原先的参考分子为:

以下是Delete生成的小分子的2D结构示例:

​​​​​​​

感觉生成分子的质量一般,在上述生成的分子中,除了正常的linker连接分子以外,还有一些多并环的分子,以及一些大环的分子。

生成分子的3D pose如下动画:

Delete_3cl_case

虽然,生成的分子比较奇怪,但是酯基的骨架跃迁位置,Delete生成的分子大部分都有酰胺,酯基结构,侧面说明,Delete模型对于口袋和分子的相互作用识别较好。

四、测评总结

作者提出了一种应用关于Lead优化过程中骨架跃迁、linker设计,片段延伸,和侧链修饰的统一模型 Delete 。

Delete 模型基于mask策略,按照作者的描述,首先是随机掩码预训练模型,然后是应用于骨架跃迁、linker设计,片段延伸、侧链修饰的四个微调模型。通过,vina energy等分析,发现 Delete 模型生成的分子可能具有更好的活性。

复测了作者github中的测试体系 2VT4,测试片段延伸,生成的分子还不错,大多数为并环和三并环结构,与原来的参考分子有较高的相似性。

当使用 3lc 体系,自定义做骨架跃迁测试时,发现生成的分子质量一般,且有大量的手性分子,可合成性比较困难。但是,Delete 模型对于口袋-分子的相互作用识别能力较好。

此外,虽然作者提供了训练模型的代码和预处理好的数据集,但是未提供数据的处理方法,即使能训练模型,但是也无法使用自己的数据集进行从头训练。

按照文章的描述,针对4种不同的Lead优化过程中的应用,应该有四个checkpoint模型的,但是作者仅仅提供了一种。

另外,在生长过程中,生长位点不能指定。

总结来说,Delete 属于概念性研究,实用性不强,代码完整性差。可以直接使用,但是需要好好挑挑分子。

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值