Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确地为代表分子的Gnuplot 3D连接点云添加透视图?_Gnuplot_Chemistry - Fatal编程技术网

如何正确地为代表分子的Gnuplot 3D连接点云添加透视图?

如何正确地为代表分子的Gnuplot 3D连接点云添加透视图?,gnuplot,chemistry,Gnuplot,Chemistry,我不知道你们这些人,但我爱我。如果使用得当,该软件可以生成美丽的图像,简单明了,令人着迷,这是我非常喜欢的 没有什么特别的原因,有一天我发现自己在想,如果我能创造出如此卡通魅力和充满活力的清晰图片,并发表在我的论文和个人科学杂志上,那该有多好。因此,我们首先进入了一个batshit项目,编写了一个基于gnuplot的分子可视化工具 到目前为止,它是为我特定类型的分子量身定做的。基本上是形成配体的共价键合原子,配体本身通过配位键与一些中心金属离子相互作用。我已经设法达成了一个相当好的工作概念,如下

我不知道你们这些人,但我爱我。如果使用得当,该软件可以生成美丽的图像,简单明了,令人着迷,这是我非常喜欢的

没有什么特别的原因,有一天我发现自己在想,如果我能创造出如此卡通魅力和充满活力的清晰图片,并发表在我的论文和个人科学杂志上,那该有多好。因此,我们首先进入了一个batshit项目,编写了一个基于gnuplot的分子可视化工具

到目前为止,它是为我特定类型的分子量身定做的。基本上是形成配体的共价键合原子,配体本身通过配位键与一些中心金属离子相互作用。我已经设法达成了一个相当好的工作概念,如下图所示

其中,虚线表示与金属离子铕的配位键,颜色为浅青色,实线表示原子间的共价键。红色是氧,蓝色是氮,白色是氢,灰色是碳。到目前为止,一切都很好,看起来很稳定,非常符合我的要求

那我该怎么做,我听到你在问?其实这很简单。我一次策划一件事。首先,我绘制虚线的连接模式,如下所示:

然后我画共价键:

每个步骤都需要一个或多个单独的文件。每个配体的连接性存储在一个单独的“键合文件”中,点连接性模式存储在一个文件中。原子的位置和它们所具有的颜色被放置在另一个文件中。每个配体一个,中心金属一个

然后我有一个单独的文件来记录金属和每个配体的原子,在那里我说它们是什么颜色。原子被放置在黑点上,这一事实使黑点周围呈现出迷人的黑色布局,否则它们就没有轮廓线

问题 当您希望旋转复合体以获得更好的角度保存到图片中时,会出现问题。为了说明这个问题,我将用一个单一配体的图片来说明它的作用。让我们拿联吡啶(含氮的,有两个)

这是一个联吡啶,我认为是它的最佳角度:

现在假设我们沿着下图所示的轴转动联吡啶

现在问题出现了。因为一些应该在后面的原子实际上在整个物体的前面,这表明gnuplot实际上没有透视图。或者,至少,它确实有,但我用错了

到目前为止还不错。我没想到它会自动透视,因为这不是它最初的用途。然而,这意味着gnuplot“splot”做了一个有点虚假的三维绘图,而点在空间中的实际相对位置无关紧要

所以我的问题是,对于所有的gnuplot/透视专家来说:有没有办法巧妙地绕过这个限制?


我对任何方法都感兴趣,不管涉及到什么,只要它在gnuplot本身的限制范围内是可行的。

Heh。我自己也是一个分子图形学的书呆子,从20世纪70年代的研究生时代就开始编写查看器和可视化工具。你知道吗?我真的不喜欢在分子图形中使用透视法。如此之多以至于我将gnuplot中的缺席称为一个特性,而不是一个限制

gnuplot集合中有demo
molecular.dem
,显示简单的分子图形。它在gnuplot(5.3)的开发版本中工作得更好,在该版本中,可以对原子使用“带圆”而不是“带点”的打印样式。给你:

set title "GM1 pentasaccharide ball-and-stick representation"

set hidden3d
set border 0
unset tics
unset key
set title offset 0, screen -0.85
set view equal xyz
set view 348, 163, 1.64872, 1.14

set style fill transparent solid 0.9 border -1
atomcolor(name) = name[1:1] eq "O" ? 0xdd2222 : name [1:1] eq "N" ? 0x4444ff : 0x888888

splot 'GM1_sugar.pdb' using 6:7:8:(0.6):(atomcolor(strcol(3))) with circles fc rgb var, \
      'GM1_bonds.r3d' using 1:2:3:($5-$1):($6-$2):($7-$3) with vectors nohead lw 3 lc "black"
注:

  • 原子位置直接从PDB文件读取
  • 原子颜色由原子名称生成(灰色表示碳,蓝色表示氮等)
  • 这些键由Raster3D分子图形包中的“bonds”实用程序从同一PDB文件生成
  • 后面的原子被前面的原子遮挡是由“set hidden3d”处理的
  • 由于线段一直绘制到原子中心,因此键的遮挡不太令人满意,而从视觉上看,终止于原子的投影球面会更好
  • 通过使原子部分透明,深度的视觉印象得到了进一步的帮助

不久前,我尝试过类似的方法。显然,点和线不尊重三维顺序。但是,如果使用曲面绘制,也就是说,原子=球体,键=圆柱体,则它将起作用

编辑:这是一个完全修订的版本。 我知道有专门的程序来可视化分子。这只是为了好玩,并演示gnuplot的可行性。 我假设随着原子数量的增加,这个脚本会变得非常慢

可以直接读取结构数据文件(SDF)文件。它包含原子位置和键信息(连接性和键类型)。 原子显示为球体,键显示为圆柱体。因此,数据块
$Sphere
$characters
包含球体和圆柱体原型的数据点。 有关原子的附加信息存储在数据块
$Elements
中,即原子序数、元素名称、原子大小和颜色。可以将更多元素添加到此列表中。 球体仅根据其位置以偏移量绘制。 键也需要适当旋转,这需要键向量的旋转。 因此,以下基本向量和矩阵运算作为函数实现:

  • 矢量长度(V)
  • 叉积(a,b)
  • 矩阵向量乘法(M,V)
  • 向量归一化(V)
美联社
2519
  -OEChem-08062013263D

 24 25  0     0  0  0  0  0  0999 V2000
    0.4700    2.5688    0.0006 O   0  0  0  0  0  0  0  0  0  0  0  0
   -3.1271   -0.4436   -0.0003 O   0  0  0  0  0  0  0  0  0  0  0  0
   -0.9686   -1.3125    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0
    2.2182    0.1412   -0.0003 N   0  0  0  0  0  0  0  0  0  0  0  0
   -1.3477    1.0797   -0.0001 N   0  0  0  0  0  0  0  0  0  0  0  0
    1.4119   -1.9372    0.0002 N   0  0  0  0  0  0  0  0  0  0  0  0
    0.8579    0.2592   -0.0008 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.3897   -1.0264   -0.0004 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.0307    1.4220   -0.0006 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.9061   -0.2495   -0.0004 C   0  0  0  0  0  0  0  0  0  0  0  0
    2.5032   -1.1998    0.0003 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.4276   -2.6960    0.0008 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.1926    1.2061    0.0003 C   0  0  0  0  0  0  0  0  0  0  0  0
   -2.2969    2.1881    0.0007 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.5163   -1.5787    0.0008 H   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0451   -3.1973   -0.8937 H   0  0  0  0  0  0  0  0  0  0  0  0
   -2.5186   -2.7596    0.0011 H   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0447   -3.1963    0.8957 H   0  0  0  0  0  0  0  0  0  0  0  0
    4.1992    0.7801    0.0002 H   0  0  0  0  0  0  0  0  0  0  0  0
    3.0468    1.8092   -0.8992 H   0  0  0  0  0  0  0  0  0  0  0  0
    3.0466    1.8083    0.9004 H   0  0  0  0  0  0  0  0  0  0  0  0
   -1.8087    3.1651   -0.0003 H   0  0  0  0  0  0  0  0  0  0  0  0
   -2.9322    2.1027    0.8881 H   0  0  0  0  0  0  0  0  0  0  0  0
   -2.9346    2.1021   -0.8849 H   0  0  0  0  0  0  0  0  0  0  0  0
  1  9  2  0  0  0  0
  2 10  2  0  0  0  0
  3  8  1  0  0  0  0
  3 10  1  0  0  0  0
  3 12  1  0  0  0  0
  4  7  1  0  0  0  0
  4 11  1  0  0  0  0
  4 13  1  0  0  0  0
  5  9  1  0  0  0  0
  5 10  1  0  0  0  0
  5 14  1  0  0  0  0
  6  8  1  0  0  0  0
  6 11  2  0  0  0  0
  7  8  2  0  0  0  0
  7  9  1  0  0  0  0
 11 15  1  0  0  0  0
 12 16  1  0  0  0  0
 12 17  1  0  0  0  0
 12 18  1  0  0  0  0
 13 19  1  0  0  0  0
 13 20  1  0  0  0  0
 13 21  1  0  0  0  0
 14 22  1  0  0  0  0
 14 23  1  0  0  0  0
 14 24  1  0  0  0  0
M  END
> <PUBCHEM_COMPOUND_CID>
2519

> <PUBCHEM_CONFORMER_RMSD>
0.4

> <PUBCHEM_CONFORMER_DIVERSEORDER>
1

> <PUBCHEM_MMFF94_PARTIAL_CHARGES>
15
1 -0.57
10 0.69
11 0.04
12 0.3
13 0.26
14 0.3
15 0.15
2 -0.57
3 -0.42
4 0.05
5 -0.42
6 -0.57
7 -0.24
8 0.29
9 0.71

> <PUBCHEM_EFFECTIVE_ROTOR_COUNT>
0

> <PUBCHEM_PHARMACOPHORE_FEATURES>
5
1 1 acceptor
1 2 acceptor
3 4 6 11 cation
5 4 6 7 8 11 rings
6 3 5 7 8 9 10 rings

> <PUBCHEM_HEAVY_ATOM_COUNT>
14

> <PUBCHEM_ATOM_DEF_STEREO_COUNT>
0

> <PUBCHEM_ATOM_UDEF_STEREO_COUNT>
0

> <PUBCHEM_BOND_DEF_STEREO_COUNT>
0

> <PUBCHEM_BOND_UDEF_STEREO_COUNT>
0

> <PUBCHEM_ISOTOPIC_ATOM_COUNT>
0

> <PUBCHEM_COMPONENT_COUNT>
1

> <PUBCHEM_CACTVS_TAUTO_COUNT>
1

> <PUBCHEM_CONFORMER_ID>
000009D700000001

> <PUBCHEM_MMFF94_ENERGY>
22.901

> <PUBCHEM_FEATURE_SELFOVERLAP>
25.487

> <PUBCHEM_SHAPE_FINGERPRINT>
10967382 1 18338799025773621285
11132069 177 18339075025094499008
12524768 44 18342463625094026902
13140716 1 17978511158789908153
16945 1 18338517550775811621
193761 8 15816500986559935910
20588541 1 18339082691204868851
21501502 16 18338796715286957384
22802520 49 18128840606503503494
2334 1 18338516344016692929
23402539 116 18270382932679789735
23552423 10 18262240993325675966
23559900 14 18199193898169584358
241688 4 18266458702623303353
2748010 2 18266180539182415717
5084963 1 17698433339235542986
528886 8 18267580380709240570
53812653 166 18198902694142226312
66348 1 18339079396917369615

> <PUBCHEM_SHAPE_MULTIPOLES>
256.45
4.01
2.83
0.58
0.71
0.08
0
-0.48
0
-0.81
0
0.01
0
0

> <PUBCHEM_SHAPE_SELFOVERLAP>
550.88

> <PUBCHEM_SHAPE_VOLUME>
143.9

> <PUBCHEM_COORDINATE_TYPE>
2
5
10

$$$$
### plot a molecule from an SDF file
reset session

FILE = 'Caffeine.sdf'
DATA = '$Molecule'
# get datafile 1:1 into datablock
if (GPVAL_SYSNAME[:7] eq "Windows") { load '< echo '.DATA.' ^<^<EOD & type "'.FILE.'"' } # Windows
if (GPVAL_SYSNAME eq "Linux") { load '< echo "\'.DATA.' << EOD" & cat "'.FILE.'"' }       # Linux
if (GPVAL_SYSNAME eq "Darwin") { load '< echo "\'.DATA.' << EOD" & cat "'.FILE.'"' }      # MacOS

AtomCount = word($Molecule[4],1)    # get number of atoms in molecule
BondCount = word($Molecule[4],2)    # get number of bonds in molecule

# put atom data into a datablock
# X, Y, Z, Element
set print $Atoms
    do for [i=5:4+AtomCount] { print $Molecule[i] }
set print

# put bond data into a datablock
# Atom1, Atom2, BondType
set print $Bonds
    do for [i=5+AtomCount:4+AtomCount+BondCount] { print $Molecule[i] }
set print

# create sphere datapoints (=atom prototype)
set parametric
set isosamples 17
set samples 17
epsilon=1e-8
set urange [epsilon-pi/2:pi/2+epsilon]
set vrange [0:2*pi]
Radius = 1
set table $Sphere
    splot Radius*cos(u)*cos(v), Radius*cos(u)*sin(v), Radius*sin(u)
unset table

# create cylinders (=single, double, triple bond prototype)
set isosamples 2
set samples 12
set urange [-pi:pi]
set vrange [0.2:1]
BondRadius = 0.075
set table $Cylinders   # single, double, triple bonds
    do for [Offset in "0 -1.25 1.25 -2.5 0 2.5"] {
        splot BondRadius*(cos(u)+Offset), BondRadius*sin(u), v
    }
unset table
unset parametric


# Lookup table for elements
# AtomicNo  ElementSymbol  Radius Color
$Elements <<EOD
1  H  1.5 #ffffff
6  C  2.5 #888888
7  N  3.0 #0000ff
8  O  2.5 #ff0000
EOD

# lookup function: search for string s in column c1. If found return value in column c2
LookupElement(s,c1,c2) = (tmp = '', sum [iii=1:|$Elements|] (word($Elements[iii],c1) eq s ? \
    (tmp=word($Elements[iii],c2),0) : 0), tmp)

Element(n)   = word($Atoms[n],4)                   # get element of nth atom
ElementNo(n) = int(LookupElement(Element(n),2,1))  # lookup atomic number by nth atom
AtomSize(e)  = LookupElement(e,2,3)                # lookup atom size by element
AtomSizeScaling = 0.2
AtomPos(n,axis) = word($Atoms[n],axis)             # get x=1,y=2,z=3 coordinates of nth atom
AtomPoint(n,axis) = AtomPos(n,axis) + (column(axis)*AtomSize(Element(n))*AtomSizeScaling)

# create atom color palette
AtomPalette = "( -1 '#cccccc'"
do for [i=1:|$Elements|] {
    AtomPalette = AtomPalette.sprintf(", %s '%s'",word($Elements[i],1),word($Elements[i],4))
}
AtomPalette = AtomPalette.')'
set palette defined @AtomPalette

# functions for vector and marix operations
VectorLength(V) = sqrt(word(V,1)**2 + word(V,2)**2 + word(V,3)**2)
VectorNormalize(V) = sprintf("%g %g %g", \
    word(V,1)/VectorLength(V), word(V,2)/VectorLength(V), word(V,3)/VectorLength(V))
# Cross vector product
CrossProduct(a,b) = sprintf("%g %g %g", \
    word(a,2)*word(b,3) - word(a,3)*word(b,2), \
    word(a,3)*word(b,1) - word(a,1)*word(b,3), \
    word(a,1)*word(b,2) - word(a,2)*word(b,1))

# Rotation matrix: Input vector (normalized) and angle
RotationMatrix(Vn,a) = sprintf("%g %g %g %g %g %g %g %g %g", \
    word(Vn,1)*word(Vn,1)*(1-cos(a))+cos(a), \
    word(Vn,1)*word(Vn,2)*(1-cos(a))-word(Vn,3)*sin(a), \
    word(Vn,1)*word(Vn,3)*(1-cos(a))+word(Vn,2)*sin(a), \
    word(Vn,2)*word(Vn,1)*(1-cos(a))+word(Vn,3)*sin(a), \
    word(Vn,2)*word(Vn,2)*(1-cos(a))+cos(a), \
    word(Vn,2)*word(Vn,3)*(1-cos(a))-word(Vn,1)*sin(a), \
    word(Vn,3)*word(Vn,1)*(1-cos(a))-word(Vn,2)*sin(a), \
    word(Vn,3)*word(Vn,2)*(1-cos(a))+word(Vn,1)*sin(a), \
    word(Vn,3)*word(Vn,3)*(1-cos(a))+cos(a))
    
# define matrix/vector multiplication  (Matrix 3x3, Vector 3x1)
MatrixVectorMultiplication(M,V) = sprintf("%g %g %g", \
    word(M,1)*word(V,1) + word(M,2)*word(V,2) + word(M,3)*word(V,3), \
    word(M,4)*word(V,1) + word(M,5)*word(V,2) + word(M,6)*word(V,3), \
    word(M,7)*word(V,1) + word(M,8)*word(V,2) + word(M,9)*word(V,3))

# Rotation of points
RotatedVector(n) = MatrixVectorMultiplication(RotationMatrix(RotationVector(n),RotationAngle(n)), \
    sprintf("%g %g %g", column(1),column(2),column(3)))


# Bond start & end
BondStart(i) = int(word($Bonds[i],1))
BondEnd(i) = int(word($Bonds[i],2))
BondVector(n) = sprintf("%g %g %g", \
    AtomPos(BondEnd(n),1) - AtomPos(BondStart(n),1), \
    AtomPos(BondEnd(n),2) - AtomPos(BondStart(n),2), \
    AtomPos(BondEnd(n),3) - AtomPos(BondStart(n),3))
BondLength(n) = VectorLength(BondVector(n))

BondType(i) = int(word($Bonds[i],3))        # get bond type: single, double, triple
BondTypeStart(n) = BondType(n)==3 ? 3 : BondType(n)==2 ? 1 : 0
BondTypeEnd(n)   = BondType(n)==3 ? 5 : BondType(n)==2 ? 2 : 0

# rotation axis vector normalized, (cross-product of BondVector and z-axis)
RotationVector(n) = VectorNormalize(CrossProduct(BondVector(n),"0 0 1"))

# rotation angle (between V and z-axis)
RotationAngle(n) = -acos(word(BondVector(n),3)/VectorLength(BondVector(n)))

BondPoint(n,m) = word(RotatedVector(n),m) + AtomPos(BondStart(n),m)

# plot settings
set cbrange [-1:8]
set view equal xyz
unset border
unset tics
unset colorbox
unset key

set style fill solid 1.0 noborder
set pm3d depthorder noborder
set pm3d lighting specular 0.5
set view 26, 329, 2

splot \
    for [i=1:|$Bonds|] $Cylinders u \
    (BondPoint(i,1)):(BondPoint(i,2)):(BondPoint(i,3)):(-1) \
    index BondTypeStart(i):BondTypeEnd(i) w pm3d, \
    for [i=1:|$Atoms|] $Sphere u (AtomPoint(i,1)):(AtomPoint(i,2)):(AtomPoint(i,3)):(ElementNo(i)) w pm3d
### end of code