计算化学公社

 找回密码 Forget password
 注册 Register
Views: 6271|回复 Reply: 8
打印 Print 上一主题 Last thread 下一主题 Next thread

[Python] 新手求助:python求二面角代码应该怎么写

[复制链接 Copy URL]

67

帖子

0

威望

3004

eV
积分
3071

Level 5 (御坂)

跳转到指定楼层 Go to specific reply
楼主
请问用python语言读取txt文件中的四个原子的xyz坐标,并求二面角代码应该怎么写,谢谢。比如txt文件中乙烷的二面角:H3-C1-C2-H4
6
C2H6
H1                 -1.51326409   -0.45762891   -0.02447848
H2                 -1.51324568    1.05557928   -0.89812999
H3                 -2.93991852    0.55119428   -0.02447848
C1                 -1.86991852    0.55118109   -0.02447848
C2                 -1.35657630    1.27713737    1.23292649
H4                 -1.71163265    2.28651046    1.23194897
H5                 -1.71484541    0.77386893    2.10657638
H6                 -0.28657811    1.27543068    1.23390524




3814

帖子

4

威望

8005

eV
积分
11899

Level 6 (一方通行)

MOKIT开发者

2#
发表于 Post on 2019-4-18 00:53:23 | 只看该作者 Only view this author
自动做多参考态计算的程序MOKIT

220

帖子

0

威望

5716

eV
积分
5936

Level 6 (一方通行)

跳跳猪

3#
发表于 Post on 2019-4-18 08:41:36 | 只看该作者 Only view this author
供参考:
  1. #!/usr/bin/env python

  2. """Dihedral angle calculation module.
  3. K. Rother
  4. Two functions are provided (see documentation of each function for
  5. a more detailed description):
  6. angle (v1,v2) - returns the angle between two 2D or 3D numpy arrays
  7.     (in radians)
  8. dihedral (v1,v2,v3,v4) - returns the dihedral angle between four 3D vectors
  9.     (in degrees)
  10. The vectors that dihedral uses can be lists, tuples or numpy arrays.
  11. Scientific.Geometry.Vector objects behave differently on Win and Linux,
  12. and they are therefore not supported (but may work anyway).
  13. """

  14. __author__ = "Kristian Rother"
  15. __copyright__ = "Copyright 2007-2016, The Cogent Project"
  16. __contributors__ = ["Kristian Rother", "Sandra Smit"]
  17. __credits__ = ["Janusz Bujnicki", "Daniel McDonald"]
  18. __license__ = "GPL"
  19. __version__ = "1.9"
  20. __maintainer__ = "Kristian Rother"
  21. __email__ = "krother@rubor.de"
  22. __status__ = "Production"

  23. from numpy import array, cross, pi, cos, sqrt, sum, arccos as acos


  24. class DihedralGeometryError(Exception):
  25.     pass


  26. class AngleGeometryError(Exception):
  27.     pass


  28. def fix_rounding_error(x):
  29.     ROUND_ERROR = 1e-14    # fp rounding error: causes some tests to fail
  30.     # will round to 0 if smaller in magnitude than this
  31.     """
  32.     If x is almost in the range 0-1, fixes it.
  33.     Specifically, if x is between -ROUND_ERROR and 0, returns 0.
  34.     If x is between 1 and 1+ROUND_ERROR, returns 1.
  35.     """
  36.     if -ROUND_ERROR < x < 0:
  37.         return 0
  38.     elif 1 < x < 1 + ROUND_ERROR:
  39.         return 1
  40.     else:
  41.         return x


  42. def norm(a):
  43.     """Returns the norm of a matrix or vector

  44.     Calculates the Euclidean norm of a vector.
  45.     Applies the Frobenius norm function to a matrix
  46.     (a.k.a. Euclidian matrix norm)

  47.     a = numpy array
  48.     """
  49.     return sqrt(sum((a * a).flat))


  50. def scalar(v1, v2):
  51.     """
  52.     calculates the scalar product of two vectors
  53.     v1 and v2 are numpy.array objects.
  54.     returns a float for a one-dimensional array.
  55.     """
  56.     return sum(v1 * v2)


  57. def angle(v1, v2):
  58.     """
  59.     calculates the angle between two vectors.
  60.     v1 and v2 are numpy.array objects.
  61.     returns a float containing the angle in radians.
  62.     """
  63.     length_product = norm(v1) * norm(v2)
  64.     if length_product == 0:
  65.         raise AngleGeometryError(
  66.             "Cannot calculate angle for vectors with length zero")
  67.     cosine = scalar(v1, v2) / length_product
  68.     angle = acos(fix_rounding_error(cosine))
  69.     return angle


  70. def calc_angle(vec1, vec2, vec3):
  71.     """Calculates a flat angle from three coordinates."""
  72.     if len(vec1) == 3:
  73.         v1, v2, v3 = map(create_vector, [vec1, vec2, vec3])
  74.     else:
  75.         v1, v2, v3 = map(create_vector2d, [vec1, vec2, vec3])
  76.     v12 = v2 - v1
  77.     v23 = v2 - v3
  78.     angl = angle(v12, v23) * 180.0 / pi
  79.     return angl


  80. def create_vector2d(vec):
  81.     """Returns a vector as a numpy array."""
  82.     return array([vec[0], vec[1]])


  83. def create_vector(vec):
  84.     """Returns a vector as a numpy array."""
  85.     return array([vec[0], vec[1], vec[2]])


  86. def create_vectors(vec1, vec2, vec3, vec4):
  87.     """Returns dihedral angle, takes four
  88.     Scientific.Geometry.Vector objects
  89.     (dihedral does not work for them because
  90.     the Win and Linux libraries are not identical.
  91.     """
  92.     return map(create_vector, [vec1, vec2, vec3, vec4])


  93. def dihedral(vec1, vec2, vec3, vec4):
  94.     """
  95.     Returns a float value for the dihedral angle between
  96.     the four vectors. They define the bond for which the
  97.     torsion is calculated (~) as:
  98.     V1 - V2 ~ V3 - V4
  99.     The vectors vec1 .. vec4 can be array objects, lists or tuples of length
  100.     three containing floats.
  101.     For Scientific.geometry.Vector objects the behavior is different
  102.     on Windows and Linux. Therefore, the latter is not a featured input type
  103.     even though it may work.

  104.     If the dihedral angle cant be calculated (because vectors are collinear),
  105.     the function raises a DihedralGeometryError
  106.     """
  107.     # create array instances.
  108.     v1, v2, v3, v4 = create_vectors(vec1, vec2, vec3, vec4)
  109.     all_vecs = [v1, v2, v3, v4]

  110.     # rule out that two of the atoms are identical
  111.     # except the first and last, which may be.
  112.     for i in range(len(all_vecs) - 1):
  113.         for j in range(i + 1, len(all_vecs)):
  114.             if i > 0 or j < 3:  # exclude the (1,4) pair
  115.                 equals = all_vecs[i] == all_vecs[j]
  116.                 if equals.all():
  117.                     raise DihedralGeometryError(
  118.                         "Vectors #%i and #%i may not be identical!" % (i, j))

  119.     # calculate vectors representing bonds
  120.     v12 = v2 - v1
  121.     v23 = v3 - v2
  122.     v34 = v4 - v3

  123.     # calculate vectors perpendicular to the bonds
  124.     normal1 = cross(v12, v23)
  125.     normal2 = cross(v23, v34)

  126.     # check for linearity
  127.     if norm(normal1) == 0 or norm(normal2) == 0:
  128.         raise DihedralGeometryError(
  129.             "Vectors are in one line; cannot calculate normals!")

  130.     # normalize them to length 1.0
  131.     normal1 = normal1 / norm(normal1)
  132.     normal2 = normal2 / norm(normal2)

  133.     # calculate torsion and convert to degrees
  134.     torsion = angle(normal1, normal2) * 180.0 / pi

  135.     # take into account the determinant
  136.     # (the determinant is a scalar value distinguishing
  137.     # between clockwise and counter-clockwise torsion.
  138.     if scalar(normal1, v34) >= 0:
  139.         return torsion
  140.     else:
  141.         torsion = -torsion
  142.         if torsion == 360:
  143.             torsion = 0.0
  144.         return torsion
复制代码


流年似水,浮生如梦。

417

帖子

1

威望

2200

eV
积分
2637

Level 5 (御坂)

4#
发表于 Post on 2019-4-18 08:44:37 | 只看该作者 Only view this author
我之前写过一段awk代码,比较粗糙。你可以参考一下。

function Dihedral(x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,    norm1,x5,y5,z5,norm2,x6,y6,z6)
{
    norm1=sqrt((y1*(z2-z3)+y2*(z3-z1)+y3*(z1-z2))*(y1*(z2-z3)+y2*(z3-z1)+y3*(z1-z2))+(z1*(x2-x3)+z2*(x3-x1)+z3*(x1-x2))*(z1*(x2-x3)+z2*(x3-x1)+z3*(x1-x2))+(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))*(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2)))
    x5 = (y1*(z2-z3)+y2*(z3-z1)+y3*(z1-z2))/norm1
    y5 = (z1*(x2-x3)+z2*(x3-x1)+z3*(x1-x2))/norm1
    z5 = (x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/norm1
    norm2=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2)+(z3-z2)*(z3-z2))
    x6 = (y5*(z3-z2)-(y3-y2)*z5)/norm2
    y6 = (z5*(x3-x2)-(z3-z2)*x5)/norm2
    z6 = (x5*(y3-y2)-(x3-x2)*y5)/norm2
    return -atan2(x6*(y2*(z3-z4)+y3*(z4-z2)+y4*(z2-z3))+y6*(z2*(x3-x4)+z3*(x4-x2)+z4*(x2-x3))+z6*(x2*(y3-y4)+x3*(y4-y2)+x4*(y2-y3)),x5*(y2*(z3-z4)+y3*(z4-z2)+y4*(z2-z3))+y5*(z2*(x3-x4)+z3*(x4-x2)+z4*(x2-x3))+z5*(x2*(y3-y4)+x3*(y4-y2)+x4*(y2-y3)))
}

490

帖子

2

威望

4881

eV
积分
5411

Level 6 (一方通行)

5#
发表于 Post on 2019-4-18 10:15:38 | 只看该作者 Only view this author
基本思想就是求出两个平面的法向量(定义平面内两个向量,然后用叉乘算出法向量),再求两个法向量之间的夹角。

545

帖子

0

威望

3125

eV
积分
3670

Level 5 (御坂)

6#
发表于 Post on 2019-4-18 10:22:39 | 只看该作者 Only view this author
def dihedral(a, b, c, d):
    """
    Calculate the dihedral angle between abc surface and bcd surface (- pi ~ pi).
    """
    na = np.cross(c - b, a - b)
    nb = np.cross(b - c, d - c)
    return np.arccos(np.abs(np.dot(na, nb)) / np.sqrt(np.power(na, 2).sum()) / np.sqrt(np.power(nb, 2).sum()))

没查过边界值,凑合用的。

185

帖子

1

威望

4139

eV
积分
4344

Level 6 (一方通行)

7#
发表于 Post on 2019-4-18 10:26:07 | 只看该作者 Only view this author
搬运 https://stackoverflow.com/questions/20305272/dihedral-torsion-angle-from-four-points-in-cartesian-coordinates-in-python
里面用 wiki 定义的那个

  1. #!/bin/env python3.6

  2. import numpy as np


  3. def read_file(filename):
  4.     with open(filename, 'r') as f:
  5.         natom = int(f.readline())
  6.         f.readline()
  7.         coordinates = []
  8.         for _ in range(natom):
  9.             line = f.readline()
  10.             coordinate = line.split()[1:]
  11.             coordinates.append(coordinate)
  12.     return np.array(coordinates, dtype=float)


  13. def dihedral(coordinates, a, b, c, d):
  14.     i = coordinates[a]
  15.     j = coordinates[b]
  16.     k = coordinates[c]
  17.     l = coordinates[d]
  18.     f, g, h = i-j, j-k, l-k
  19.     a = np.cross(f, g)
  20.     b = np.cross(h, g)
  21.     axb = np.cross(a, b)
  22.     cos = np.dot(a, b)
  23.     sin = np.dot(axb, g) /  np.linalg.norm(g)
  24.     r = -np.arctan2(sin, cos)
  25.     return np.degrees(r)


  26. if __name__ == "__main__":
  27.     c = read_file('C2H6.xyz')
  28.     print(dihedral(c, 2, 3, 4, 5))
复制代码


67

帖子

0

威望

3004

eV
积分
3071

Level 5 (御坂)

8#
 楼主 Author| 发表于 Post on 2019-4-18 15:04:36 | 只看该作者 Only view this author
十分感谢大家!

2479

帖子

11

威望

6864

eV
积分
9563

Level 6 (一方通行)

9#
发表于 Post on 2019-7-15 13:02:37 | 只看该作者 Only view this author
diangle.py (1.28 KB, 下载次数 Times of downloads: 41)

based on the blog: http://sobereva.com/302

you can modify according to the case you faced.

本版积分规则 Credits rule

手机版 Mobile version|北京科音自然科学研究中心 Beijing Kein Research Center for Natural Sciences|京公网安备 11010502035419号|计算化学公社 — 北京科音旗下高水平计算化学交流论坛 ( 京ICP备14038949号-1 )|网站地图

GMT+8, 2024-11-27 14:49 , Processed in 0.271677 second(s), 24 queries , Gzip On.

快速回复 返回顶部 返回列表 Return to list