24小时热门版块排行榜    

查看: 6902  |  回复: 9
【奖励】 本帖被评价7次,作者beefly增加金币 5.6

[资源] 用Asymptote产生3D PDF格式的分子结构图

很多年前接触过一点Asymptote矢量图语言,但是不如现成的分子结构程序方便,于是就压箱子底下了。最近突然把Asymptote又拿出来,主要有以下几个原因:

1,显示分子的振动模式。虽然不少程序都可以做,但是如果遇到高对称分子,振动矢量的箭头往往和分子键重合在一起。稍微好点的程序,允许把分子键设定得非常细,虽然振动箭头突出了,但是却很难看。而且箭头的控制参数太少。例如下面这个图,已经是能得到的最好结果了

用Asymptote产生3D PDF格式的分子结构图

2,能够显示振动模式的程序一般都是针对特定数据格式设计的(例如Gaussian的输出,fchk文件),在其他程序里照抄这些格式是不可能的。比较简单,又被广泛接受的振动模式数据格式,大概只有MOLDEN频率文件了。但是能够读MOLDEN文件的程序很少,更何况振动模式的显示效果不好。
3,需要用脚本批量产生一堆结构图(可能几十个甚至上百个),比如做动画。如果用鼠标逐个去操作,会累死人的。
4,产生真3D的PDF文件。用免费程序Jamberoo/VMD/Pymol也可以做。

经过几天的学习,以及参考别人的例子,上面的问题用Asymptote很快就得到解决。

(一)Asymptote的安装

在Windows下安装

Asymptote需要大量的Latex编译工具和宏包支持。如果你对此不太了解,比较省事的一种办法,是去下载最新的CTeX
http://www.ctex.org/CTeXDownload
然后安装CTeX。

由于CTeX已经两年多没有升级,有些宏包和最新的Asymptote有冲突,需要升级到最新版(在下一个CTeX发布版可能就不需要这一步了):打开CTeX中的WinEdt程序,在TeX菜单中找到MiKTeX/Update Wizard,找到以下几个宏包,把它们升级到最新:babel,media9,l3experimental(第一个字符是字母,不是数字!),l3kernel,l3packages。注意:第一次升级可能会安装一些重要的宏包,用户指定的那些宏包会被忽略,因此可能要多次进行升级操作。

接下来到Asymptote主页http://asymptote.sourceforge.net/
下载并安装最新版Asymptote,然后就可以用了。

在Linux下安装

最好在版本比较新的主流Linux系统,并且自己有管理员权限的计算机上安装。大型服务器不是库函数版本低就是缺东西,尽量别在上面装。我用的是Ubuntu,运行以下命令
sudo apt-get install asymptote
然后输入密码,接下来等着系统自动下载和安装Asymptote。

在MacOSX下安装

目前不提供二进制的可执行程序。需要编译源代码,很简单。

(二)Asymptote学习资料

除了Asymptote主页上的使用手册外,有以下中文资料可以参考:

三个比较早的教程
https://code.google.com/p/asy4cn/

莫图写的Asymptote 作图指南,时间也比较早了
http://bbs.ctex.org/forum.php?mod=viewthread&tid=44559&extra=page%3D1

asymptote 经验笔记
http://bbs.ctex.org/forum.php?mod=viewthread&tid=76552&extra=page%3D1

遇到问题,除了在Asymptote的英文官方论坛求助外,也可以去ctex.org的TeX 图形技术版去讨论:
http://bbs.ctex.org/forum.php?mod=forumdisplay&fid=51&page=1

(三)一个Asymptote程序

Asymptote的语法和格式有点类似于c或c++程序。

以下是一些用到的命令:
CODE:
import three;

调用3D模块
CODE:
import x11colors;

调用颜色库模块
CODE:
real Rbond=206;

定义一个实变量。 Rbond是自己起的名字,设定分子的键长。注意Asymptote并不知道波尔、埃这些长度单位,而是使用数据点单位。我们可以假定206代表了2.06埃。
CODE:
triple atom1=(0,0,0);

定义一个三元数组。atom1是自己起的名字,表示第一个原子的直角坐标。
CODE:
triple atom2=atom1+scale_len*Rbond*Z;

定义第二个原子的坐标,等于第一个原子在Z方向做位移。Z是系统变量。
CODE:
surface xe_atm=scale3(70*scale_atm)*unitsphere;

定义一个球面代表原子,这里是氙。unitsphere函数定义了系统内置的单位球。scale3函数把球缩放。surface命令表示把这样的一个曲面赋值给xe_atm,默认有光照效果。
CODE:
draw(shift(atom1)*xe_atm,lightblue);

画一个xe_atm变量所定义的原子,位置由atom1定义,颜色为浅蓝。lightblue是x11colors模块内定的颜色变量。
CODE:
draw(atom1--atom2, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);

画一条线,连接两个点atom1和atom2,用来表示分子键。键的颜色是浅灰(mediumgray),linewidth定义键的粗细。为了更好地显示振动模式,这里把分子键设为半透明,用opacity定义。最后一个参数currentlight是可选的,用于打开光照效果,draw默认没有光照效果。在3D情况下,Asymptote可以自动计算原子球和分子键相交位置的曲线,用户不用操心。
CODE:
label("$Xe1$",atom1 ,c_align);

label命令用于给图形添加符号。在引号中可以使用Latex语法,因此可以在图中添加复杂的数学公式,这是大多数分子模型程序做不到的。符号的位置在atom1。c_align是我们自定义的一个位移变量,把符号从atom1移动一点,否则符号会被原子球包住,什么也看不到。
CODE:
draw(atom1--atom1+lmod1,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);

画一条线(在这里表示箭杆),起始点的位置分别是atom1和atom1+lmod1。red定义了颜色,是可选的。size_shaft是我们自己定义的箭杆粗细。Arrow3函数用来给箭杆的终点添加3D箭头,所带的两个参数是可选的,分别定义箭头的长度和宽度。currentlight给箭头、箭杆添加光照效果,是可选的。


完整的代码如下:
CODE:
import three;
import x11colors;

// initialization
currentprojection=perspective(200,350,100);
//currentprojection=orthographic(200,350,100);
//currentlight.background=palecyan;

real scale_atm=3/10;
real scale_bnd=0.7;
real scale_len=0.7;
real scale_nmd=200;

real c_bdtransp=0.4;
real size_arrow=12;
real size_shaft=3;
triple c_align=(0,8,8);

// Atom balls

surface xe_atm=scale3(70*scale_atm)*unitsphere;
surface f_atm=scale3(45*scale_atm)*unitsphere;

// Cartesian coordinates
real Rbond=206; // 2.06 Angstrom

triple atom1=(0,0,0);
triple atom2=atom1+scale_len*Rbond*Z;
triple atom3=atom1+scale_len*Rbond*X;
triple atom4=atom1+scale_len*Rbond*Y;
triple atom5=atom1-scale_len*Rbond*X;
triple atom6=atom1-scale_len*Rbond*Y;
triple atom7=atom1-scale_len*Rbond*Z;

// Normal modes (Oh/eg)

triple lmod1=( 0.000, 0.000, 0.000)*scale_nmd;
triple lmod2=( 0.000, 0.000, 0.577)*scale_nmd;
triple lmod3=(-0.289, 0.000, 0.000)*scale_nmd;
triple lmod4=( 0.000,-0.289, 0.000)*scale_nmd;
triple lmod5=( 0.289, 0.000, 0.000)*scale_nmd;
triple lmod6=( 0.000, 0.289, 0.000)*scale_nmd;
triple lmod7=( 0.000, 0.000,-0.577)*scale_nmd;

defaultrender=render(compression=Zero,merge=true);

// draw atoms
draw(shift(atom1)*xe_atm,lightblue);
draw(shift(atom2)*f_atm,palecyan);
draw(shift(atom3)*f_atm,palecyan);
draw(shift(atom4)*f_atm,palecyan);
draw(shift(atom5)*f_atm,palecyan);
draw(shift(atom6)*f_atm,palecyan);
draw(shift(atom7)*f_atm,palecyan);

// draw bonds
draw(atom1--atom2, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);
draw(atom1--atom3, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);
draw(atom1--atom4, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);
draw(atom1--atom5, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);
draw(atom1--atom6, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);
draw(atom1--atom7, mediumgray+opacity(c_bdtransp)+linewidth(scale_bnd*4mm),currentlight);

// labels
label("$Xe1$",atom1 ,c_align);
label("$F2 $",atom2 ,c_align);
label("$F3 $",atom3 ,c_align);
label("$F4 $",atom4 ,c_align);
label("$F5 $",atom5 ,c_align);
label("$F6 $",atom6 ,c_align);
label("$F7 $",atom7 ,c_align);

// draw arrows
draw(atom1--atom1+lmod1,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);
draw(atom2--atom2+lmod2,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);
draw(atom3--atom3+lmod3,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);
draw(atom4--atom4+lmod4,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);
draw(atom5--atom5+lmod5,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);
draw(atom6--atom6+lmod6,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);
draw(atom7--atom7+lmod7,red+size_shaft,Arrow3(size_arrow,size_arrow*1.2),currentlight);

如果经常用Asymptote显示分子,可以把一些常用的命令做成宏,使代码更简短。

把上面的代码存成一个文件,扩展名为.asy,例如test.asy。用以下命令可以编译test.asy:

asy test.asy

在Windows下,也可以用鼠标直接双击test.asy文件。

之后会跳出一个图形窗口,用鼠标把分子转动到合适的角度,缩放到合适的大小,按一下键盘上的“e”,就会产生eps格式的图形文件。效果图如下:

用Asymptote产生3D PDF格式的分子结构图-1

但是这个文件仅仅是一个打印屏幕后的图片,并不是3D图。要产生3D PDF文件,可以用以下命令编译:

asy -f pdf test.asy

用adobe acrobat打开产生的pdf文件,会发现里面的分子模型可以用鼠标旋转和缩放。见附件。

其他参数:
-noprc:跟-f pdf合用,在保存pdf文件的时候关闭3D功能。
-render=n(n=1,2,3,4,...,8):调分辨率。n=0会得到2D的投影矢量图,不过效果很差。
-noV:禁止Asymptote自动打开图形窗口和pdf文件。如果计算机太慢,或者用脚本做批量输出的时候,可以加上这个选项。此时分子的视角是个问题,需要在程序中用perspective函数事先设定,参见上面的代码。

除了显示分子模型以外,Asymptote还可以绘制晶体结构,输出3D电子密度和分子轨道,等等。在Asymptote主页和中文教程中可以找到这方面的例子。
回复此楼

» 本帖附件资源列表

  • 欢迎监督和反馈:小木虫仅提供交流平台,不对该内容负责。
    本内容由用户自主发布,如果其内容涉及到知识产权问题,其责任在于用户本人,如对版权有异议,请联系邮箱:xiaomuchong@tal.com
  • 附件 1 : xef6.pdf
  • 2015-01-24 17:17:29, 142.76 K

» 收录本帖的淘帖专辑推荐

计算 好帖 计算物理,计算化学

» 猜你喜欢

» 本主题相关商家推荐: (我也要在这里推广)

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

小范范1989

木虫 (著名写手)


★★★★★ 五星级,优秀推荐


beefly又一个经典,顶大神。
2楼2015-01-24 19:30:49
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

★★★★★ 五星级,优秀推荐

来给前辈点赞的!
3楼2015-01-25 06:42:39
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

yongma2008

木虫 (著名写手)


★★★★★ 五星级,优秀推荐

太帅了
5楼2015-01-28 14:49:19
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

neweroica

木虫 (著名写手)


★★★★★ 五星级,优秀推荐

支持樓主。 我在很久以前也曾嘗試用Asymptote和MetaPost畫過分子結構,寫了個叫NeatMol的宏包:http://bbs.ctex.org/forum.php?mod=viewthread&tid=46540
8楼2016-06-07 21:26:20
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
引用回帖:
8楼: Originally posted by neweroica at 2016-06-07 21:26:20
支持樓主。 我在很久以前也曾嘗試用Asymptote和MetaPost畫過分子結構,寫了個叫NeatMol的宏包:http://bbs.ctex.org/forum.php?mod=viewthread&tid=46540

久仰大名!我把你的NeatMol略微做了修改,现在还经常用,除了显示分子模型还用来显示振动模式。成果展示:
用Asymptote产生3D PDF格式的分子结构图-2
999.png
9楼2016-06-07 23:10:03
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

fighting文

金虫 (正式写手)


请问。原子位移图用什么软件画能否告知一下,谢谢。
10楼2018-01-03 10:37:29
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
简单回复
nilll4楼
2015-01-27 02:46   回复  
五星好评  顶一下,感谢分享!
2016-01-29 03:05   回复  
五星好评  顶一下,感谢分享!
4987460127楼
2016-04-12 08:08   回复  
五星好评  顶一下,感谢分享!
相关版块跳转 我要订阅楼主 beefly 的主题更新
☆ 无星级 ★ 一星级 ★★★ 三星级 ★★★★★ 五星级
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见