- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
在前面的一篇博客中,我们介绍过PySAGES这个增强采样软件的基本安装和使用方法。该软件类似于Plumed是一个外挂增强采样软件,但是PySAGES是基于Python语言和Jax框架来实现的,在性能上有一定的优势。这里我们结合PySAGES的易开发特性,和CUDA SPONGE的高性能特性,做一个简单的扩展将二者联合起来进行分子动力学模拟与增强采样.
在前面的文章中我们介绍过SPONGE的Python接口以及调用模式:
这里再总结一个PySAGES的基本调用模式:
目前PySAGES已经集成了一些MD Backend,例如前面介绍过的OpenMM,以及基于Jax框架开发的Jax-MD等等。这些框架都可以通过Extension模块跟PySAGES进行对接,其中Jax-MD的Extension是在PySAGES中直接定义的,因为两者都基于Jax,底层兼容性较好。而OpenMM的Extension单独出来一个叫openmm_dlext的扩展包,这是因为其底层基于cupy开发,需要通过dlpack这个标准化工具在GPU上进行免拷贝操作。比较遗憾的是,目前MindSpore暂不支持dlpack.
PySAGES大概的模拟流程是这样的,先在MD Backend中定义好力场和积分器,将输入坐标传递给Extension再到PySAGES中构建SnapShot、SnapShot Method和Helper。然后在PySAGES中定义增强采样Method,例如MetaDynamics Method,传入构建好的SnapShot和Helper,就可以得到一个用于更新的函数Update Function和一个State增强采样状态参量。到这里PySAGES的初始化就结束了。然后在MD Backend中计算好Force,把相应的Force传给PySAGES进行更新,PySAGES的Update Function接收一个State和一个Snap就可以得到新的State,这个State中有一个bias变量,就是偏置势对应的Bias Force。把Bias Force直接加到MD Backend中传过来的Force中,就可以得到一个全新的Force用于积分器的迭代.
接上一个章节内容,这里需要特别说明一下CUDA SPONGE提供的Python接口与PySAGES的运用方法。因为CUDA SPONGE的调用形式是通过CUDA去调用Python的函数内容,而PySAGES的调用形式是从Python去控制特定Backend的CUDA函数的句柄,来实现二者的结合。一个以CUDA为主,一个以Python为主。那么要结合的话,使用CUDA Sponge自身的调用形式会相对容易一些,因为我们将PySAGES中仅当作一个用于计算Bias Force的模块,集成到SPONGE的运行流程中。当然,为了结合PySAGES,我们还是需要手动去定义一些SPONGE的SnapShot和Helper,首先是SnapShot:
from pysages.backends.snapshot import Snapshot
def build_sponge_snapshot(num_atoms):
crd = jnp.array(np.random.random((num_atoms, 3)), jnp.float32)
ids = jnp.arange(num_atoms)
forces = jnp.zeros_like(crd)
return Snapshot(crd, None, forces, ids, None, None, None)
这里因为是初始化,所以可以直接用一个jax的随机array来构造。其实也可以直接传一个backend的crd进来,但是为了区分initialization和update的功能,这里还是直接随机生成了一个。这里的SnapShot是一个namedtuple格式,存储了坐标和力等系统信息,这里为了最简化,我们只传入三个最基本的参数:坐标、力、原子索引。然后是SnapShotMethod和Helper,这两个标准化接口用于实时获取SnapShot中的信息:
from pysages.backends.snapshot import SnapshotMethods, HelperMethods
def build_sponge_snapshot_methods():
def positions(snapshot):
return snapshot.positions
def indices(snapshot):
return snapshot.ids
return SnapshotMethods(positions, indices, None, None)
def build_sponge_helper(dims=3):
def get_dims():
return dims
return HelperMethods(build_data_querier(build_sponge_snapshot_methods(), {"positions", "indices"}), get_dims)
这样我们就完成了一个基本的SPONGE的Extension的构建.
这里是一个把CUDA SPONGE作为MD Backend,然后用PySAGES来进行增强采样的一个简单示例:
"""
SPONGE Usage:
$ ../SPONGE -mdin nvt.txt
"""
import Sponge
Sponge.controller.Step_Print_Initial("Phi", "%2f")
Sponge.controller.Step_Print_Initial("Psi", "%2f")
import pysages
from pysages.colvars import DihedralAngle
from numpy import pi
from pysages.methods import Metadynamics
from pysages.backends.snapshot import Snapshot, SnapshotMethods, HelperMethods, build_data_querier
import numpy as np
from jax import numpy as jnp
from jax.dlpack import to_dlpack, from_dlpack
from cupy import fromDlpack as cufd
kB = 0.00831446261815324
T = 300
def build_sponge_snapshot_methods():
def positions(snapshot):
return snapshot.positions
def indices(snapshot):
return snapshot.ids
return SnapshotMethods(positions, indices, None, None)
def build_sponge_snapshot(num_atoms):
crd = jnp.array(np.random.random((num_atoms, 3)), jnp.float32)
ids = jnp.arange(num_atoms)
forces = jnp.zeros_like(crd)
return Snapshot(crd, None, forces, ids, None, None, None)
def build_sponge_helper(dims=3):
def get_dims():
return dims
return HelperMethods(build_data_querier(build_sponge_snapshot_methods(), {"positions", "indices"}), get_dims)
# 定义增强采样方法
def phi_psi():
cvs = [DihedralAngle([4, 6, 8, 14]), DihedralAngle([6, 8, 14, 16])]
height = 5.0 # kJ/mol
sigma = [0.4, 0.4] # radians
stride = 3
ngauss = 500
grid = pysages.Grid(lower=(-pi, -pi), upper=(pi, pi), shape=(50, 50), periodic=True)
method = Metadynamics(cvs, height, sigma, stride, ngauss, grid=grid)
return method
initialized = False
state = None
snap = None
helper = None
method = None
update_func = None
# SPONGE用于更新Force的标准化调用
def Calculate_Force():
global initialized
global state
global snap
global helper
global method
global update_func
if not initialized:
initialized = True
num_atoms = Sponge.md_info.frc.shape[0]
snap = build_sponge_snapshot(num_atoms)
helper = build_sponge_helper()
method = phi_psi()
res = method.build(snap, helper)
state = res[1]()
update_func = res[2]
snap = snap._replace(positions=from_dlpack(Sponge.md_info.crd.toDlpack()))
state = update_func(snap, state)
# 加Meta
Sponge.md_info.frc += cufd(to_dlpack(state.bias))
# 不加Meta
# Sponge.md_info.frc += 0
# 手动记录CV值
import os
record_name = "cv_record.txt"
if os.path.exists(record_name):
os.remove(record_name)
# SPONGE的标准化打印输出接口
def Mdout_Print():
global state
global record_name
Sponge.controller.Step_Print("Phi", state.xi[0][0])
Sponge.controller.Step_Print("Psi", state.xi[0][1])
with open(record_name, 'a+') as file:
file.write("{},{}\n".format(state.xi[0][0], state.xi[0][1]))
其中用到的SPONGE配置文件为:
case1 MD simulation
mode = NVT
default_in_file_prefix = protein/alad
pbc=0
cutoff=999
dt = 1e-3
step_limit = 5000
write_information_interval = 10
thermostat = middle_langevin
middle_langevin_gamma = 10
rst = nvt_restart
coordinate_in_file = protein/alad_coordinate.txt
plugin = /usr/local/python-3.7.5/lib/python3.7/site-packages/prips/_prips.so
py = pysages_test.py
原始的pdb文件为:
ATOM 1 H1 ACE 1 2.000 1.000 -0.000 1.00 0.00
ATOM 2 CH3 ACE 1 2.000 2.090 0.000 1.00 0.00
ATOM 3 H2 ACE 1 1.486 2.454 0.890 1.00 0.00
ATOM 4 H3 ACE 1 1.486 2.454 -0.890 1.00 0.00
ATOM 5 C ACE 1 3.427 2.641 -0.000 1.00 0.00
ATOM 6 O ACE 1 4.391 1.877 -0.000 1.00 0.00
ATOM 7 N ALA 2 3.555 3.970 -0.000 1.00 0.00
ATOM 8 H ALA 2 2.733 4.556 -0.000 1.00 0.00
ATOM 9 CA ALA 2 4.853 4.614 -0.000 1.00 0.00
ATOM 10 HA ALA 2 5.408 4.316 0.890 1.00 0.00
ATOM 11 CB ALA 2 5.661 4.221 -1.232 1.00 0.00
ATOM 12 HB1 ALA 2 5.123 4.521 -2.131 1.00 0.00
ATOM 13 HB2 ALA 2 6.630 4.719 -1.206 1.00 0.00
ATOM 14 HB3 ALA 2 5.809 3.141 -1.241 1.00 0.00
ATOM 15 C ALA 2 4.713 6.129 0.000 1.00 0.00
ATOM 16 O ALA 2 3.601 6.653 0.000 1.00 0.00
ATOM 17 N NME 3 5.846 6.835 0.000 1.00 0.00
ATOM 18 H NME 3 6.737 6.359 -0.000 1.00 0.00
ATOM 19 CH3 NME 3 5.846 8.284 0.000 1.00 0.00
ATOM 20 HH31 NME 3 4.819 8.648 0.000 1.00 0.00
ATOM 21 HH32 NME 3 6.360 8.648 0.890 1.00 0.00
ATOM 22 HH33 NME 3 6.360 8.648 -0.890 1.00 0.00
TER
END
使用Xponge根据pdb文件进行建模的方法,可以参考这篇文章中的流程。需要注意的是,生成一个坐标文件之后,需要手动把坐标文件里面的Box信息(最后一行的前三列)修改为999(不加PBC Box的情况下),改完大概是这样的一个txt文件:
22
3.514000 3.000000 5.288678
3.514000 4.090000 5.288679
3.000000 4.454000 6.021000
3.000000 4.454000 4.241000
4.941000 4.641000 5.288676
5.905000 3.877000 5.288673
5.069000 5.970000 5.288679
4.247000 6.556000 5.288679
6.367000 6.614000 5.288679
6.922000 6.316000 6.021000
7.175000 6.221000 3.899000
6.637000 6.521000 3.000000
8.144000 6.719000 3.925000
7.323000 5.141000 3.890000
6.227000 8.129000 5.288675
5.115000 8.653000 5.288673
7.360000 8.835000 5.288687
8.251000 8.359000 5.288693
7.360000 10.284000 5.288682
6.333000 10.648000 5.288674
7.874000 10.648000 6.021000
7.874000 10.648000 4.241000
999 999 999 90.000000 90.000000 90.000000
在确保SPONGE和PySAGES两者都正常安装的情况下,如果不加Meta,跑出来的CV轨迹是这样的:
加上Meta之后,CV轨迹是这样的:
可以看到,我们加上的Meta明显提升了MD的采样空间.
其中作图脚本如下:
import numpy as np
import matplotlib.pyplot as plt
def gaussian2(x1, x2, sigma1=1.0, sigma2=1.0, A=0.5):
return np.sum(A*np.exp(-0.5*(x1**2/sigma1**2+x2**2/sigma2**2))/np.pi/sigma1/sigma2, axis=-1)
def potential_energy(position, psi, phi, sigma1, sigma2):
# (A, )
psi_, phi_ = position[:, 0], position[:, 1]
# (A, R)
delta_psi = psi_[:, None] - psi[None]
delta_phi = phi_[:, None] - phi[None]
# (A, )
Z = -np.log(gaussian2(delta_psi, delta_phi, sigma1=sigma1, sigma2=sigma2, A=2.0)+1)
return Z
data = np.genfromtxt('./cv_record.txt', delimiter=',')
phi = data[:, 0]
psi = data[:, 1]
num_grids = 100
num_levels = 10
psi_grids = np.linspace(-np.pi, np.pi, num_grids)
phi_grids = np.linspace(-np.pi, np.pi, num_grids)
grids = np.array(np.meshgrid(psi_grids, phi_grids)).T.reshape((-1, 2))
Z = potential_energy(grids, phi, psi, 1.0, 1.0).reshape((psi_grids.shape[0], phi_grids.shape[0])).T
X,Y = np.meshgrid(psi_grids, phi_grids)
levels = np.linspace(np.min(Z), np.max(Z), num_levels)
plt.figure()
plt.title("Biased MD Traj")
plt.xlabel(r'$\phi$')
plt.ylabel(r'$\psi$')
fc = plt.contourf(X, Y, Z, cmap='Greens', levels=levels)
plt.colorbar(fc)
plt.xlim(-np.pi, np.pi)
plt.ylim(-np.pi, np.pi)
plt.plot(phi, psi, 'o', alpha=0.4, color='red')
plt.savefig('meta.png')
本文探索并梳理了一下CUDA SPONGE高性能分子模拟采样软件,和PySAGES高性能增强采样软件,这两者强强联合的MD模拟新范式.
本文首发链接为:https://www.cnblogs.com/dechinphy/p/pysages-sponge.html 。
作者ID:DechinPhy 。
更多原著文章:https://www.cnblogs.com/dechinphy/ 。
请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html 。
最后此篇关于PySAGES结合CUDASPONGE增强采样的文章就讲到这里了,如果你想了解更多关于PySAGES结合CUDASPONGE增强采样的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试使用增强的 for 循环遍历 Iterable,但我无法确定何时处理最后一个值。 public void apply(Tuple key,
我正在使用以下代码在 Sheet2 的 A:H 范围内查找和替换 Sheet1 中存在的单词列表(ColA 用于 FIND 单词,ColB 用于 REPLACE 单词)。它执行这项工作,但非常缓慢。可
我正在使用 Hibernate (JPA2) hibernate.hbm2ddl.auto=update用于测试和 hibernate.hbm2ddl.auto=validate用于生产。 我想要做的
基本问题: 为什么我只能用 Scala 编写: println(10) 为什么我不需要写: Console println(10) 后续问题: 如何引入一个新方法“foo”,它像“println”一样
我正在尝试将 Maven 项目迁移到 Bazel,但在 Datanucleus 增强方面遇到了麻烦。 后 jar -file 已构建,Datanucleus 会查看其中的内部并执行一些字节码操作以增强
正在使用 css3 转换进行漂亮的导航。为此还编写了一些 javascript。 但不幸的是它看起来有点凌乱。你们能给我一些优化 javascript 代码的技巧吗? 笔--> http://code
我想将自定义任务绑定(bind)到默认构建器发布周期中。我想在项目编译、打包、标记和部署之后但在增加版本号并提交之前运行此代码。 我将如何融入发布周期的这一部分? 最佳答案 不幸的是,release
我使用ElasticSearch 6.6。我的应用程序通过从不同数据源提取数据来构建ES索引。搜索未指定数据源。它只是建立一个类似的查询: GET employerdata/_search { "
我正在使用此代码将“k1 = v1; k2 = v2; k3 = v3; kn = vn”字符串解析为映射。 qi::phrase_parse( begin,end,
我正在试图弄清楚作业的一部分,但我已经把头撞在墙上有一段时间了。我正在尝试将 DNA 序列转录为 RNA 序列。然而,我收到了 ArrayOutOfBoundsException。我不熟悉使用增强的
我需要对基于 python Google App Engine 的应用程序的警告进行分类。我从 GAE stackdriver 下载日志。我认为 GAE Stackdriver 错误报告位于 http
我有一个 django charField,通过 is_valid() 方法进行检查。用户应该在此字段中输入有效的逻辑表达式,因此我编写了一个解析方法,如果表达式不正确,该方法会引发异常。 如何增强
我编写了以下控制台应用程序,要求用户输入一天。 我需要一些帮助才能改进,以便他们为一周中的所有日子提供正确的答案。 如果用户输入除星期一以外的任何其他日期,则输出为“今天”、“昨天”、“明天”,并在这
我在使用带有 ES6 let 关键字的模块模式(扩充)时遇到错误。 这有效。 var Example = ( Example => { Example.name = ""; retur
我只是问是否线程安全可以使用 我明确指出“doSomething()”是线程安全的。 最佳答案 线程安全取决于您正在迭代的 Collection,而不是 enhanced for 的使用。如果 Col
我有一个非常符合 this Jquery demo 的要求,这是一个简单的购物车演示。基本上,我需要对该演示进行两项改进。 我需要文本输入以及可用的“产品”。因此,当我拖放其中一种产品时,文本字段应随
我正在三个表 messages、message_recipients 和 users 上运行查询。 messages表的表结构: id int pk message_id int message te
这个问题已经有答案了: In detail, how does the 'for each' loop work in Java? (29 个回答) 已关闭 4 年前。 由于增强的 for 循环是只读
我在 css 中制作了一个很酷的鼠标悬停,当父级鼠标悬停时它会显示动画 gif。 这是我的代码:http://codepen.io/clemeeent/pen/oggzMa 问题是我将有大约 40 天
目前,当使用 Knockout foreach 绑定(bind)时,您可以使用 $index 访问当前索引。我想让其他类似的功能可用于我的内部绑定(bind) - 例如: array(让我访问正在操作
我是一名优秀的程序员,十分优秀!