mdkits 0.1.28__tar.gz → 0.1.29__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mdkits might be problematic. Click here for more details.

Files changed (46) hide show
  1. {mdkits-0.1.28 → mdkits-0.1.29}/PKG-INFO +1 -1
  2. {mdkits-0.1.28 → mdkits-0.1.29}/pyproject.toml +1 -1
  3. mdkits-0.1.29/src/mdkits/md_cli/angle.py +127 -0
  4. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/md_cli/density.py +1 -1
  5. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/md_cli/hb_distribution.py +2 -2
  6. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/md_cli/md_cli.py +2 -0
  7. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/encapsulated_mda.py +4 -1
  8. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/numpy_geo.py +7 -5
  9. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/out_err.py +1 -1
  10. {mdkits-0.1.28 → mdkits-0.1.29}/LICENSE +0 -0
  11. {mdkits-0.1.28 → mdkits-0.1.29}/README.md +0 -0
  12. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/__init__.py +0 -0
  13. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/__init__.py +0 -0
  14. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/adsorbate.py +0 -0
  15. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/build_bulk.py +0 -0
  16. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/build_cli.py +0 -0
  17. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/build_interface.py +0 -0
  18. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/build_solution.py +0 -0
  19. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/build_surface.py +0 -0
  20. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/cut_surface.py +0 -0
  21. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/supercell.py +0 -0
  22. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/build_cli/water.xyz +0 -0
  23. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/,hb_distribution_down.py +0 -0
  24. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/convert.py +0 -0
  25. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/data.py +0 -0
  26. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/extract.py +0 -0
  27. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/hartree_potential.py +0 -0
  28. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/hartree_potential_ave.py +0 -0
  29. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/hb.py +0 -0
  30. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/packmol_input.py +0 -0
  31. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/plot.py +0 -0
  32. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/cli/wrap.py +0 -0
  33. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/config/__init__.py +0 -0
  34. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/config/settings.yml +0 -0
  35. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/dft_cli/cube.py +0 -0
  36. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/dft_cli/dft_cli.py +0 -0
  37. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/dft_cli/pdos.py +0 -0
  38. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/mdkits.py +0 -0
  39. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/.fig_operation.py.swp +0 -0
  40. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/__init__.py +0 -0
  41. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/arg_type.py +0 -0
  42. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/cp2k_input_parsing.py +0 -0
  43. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/encapsulated_ase.py +0 -0
  44. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/fig_operation.py +0 -0
  45. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/os_operation.py +0 -0
  46. {mdkits-0.1.28 → mdkits-0.1.29}/src/mdkits/util/structure_parsing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mdkits
3
- Version: 0.1.28
3
+ Version: 0.1.29
4
4
  Summary: kits for md or dft
5
5
  License: MIT
6
6
  Keywords: molecular dynamics,density functional theory
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "mdkits"
3
- version = "0.1.28"
3
+ version = "0.1.29"
4
4
  description = "kits for md or dft"
5
5
  readme = "README.md"
6
6
  authors = ["jxxcr <jixxcr@qq.com>"]
@@ -0,0 +1,127 @@
1
+ import click
2
+ from MDAnalysis import Universe
3
+ from MDAnalysis.analysis.base import AnalysisBase
4
+ import MDAnalysis
5
+ import sys
6
+ from mdkits.util import numpy_geo, encapsulated_mda, arg_type
7
+ import numpy as np
8
+
9
+
10
+ class Angle_distribution(AnalysisBase):
11
+ def __init__(self, filename, cell, water_height, update_water, surface, distance_judg=None, angle_judg=(None, None), dt=0.001, bin_size=5):
12
+ u = Universe(filename)
13
+ u.trajectory.ts.dt = dt
14
+ u.dimensions = cell
15
+
16
+ self.u = u
17
+ self.atomgroup = u.select_atoms("all")
18
+ self.bin_size = bin_size
19
+ self.frame_count = 0
20
+ self.surface = surface
21
+ self.update_water = update_water
22
+ self.mid_z = u.dimensions[2]/2
23
+
24
+ self.normal_up = np.array([0, 0, 1])
25
+ self.normal_down = np.array([0, 0, -1])
26
+ self.total_angle = 180
27
+
28
+ if water_height is None:
29
+ sys.exit("Please specify the water height")
30
+ else:
31
+ self.water_height = water_height
32
+
33
+ if self.update_water:
34
+ self.distance_judg = distance_judg
35
+ self.angle_judg = angle_judg
36
+
37
+ if surface is not None:
38
+ self.surface_group = self.atomgroup.select_atoms(f"{surface}")
39
+ if self.surface_group.n_atoms == 0:
40
+ sys.exit("Please specify the correct surface group")
41
+ else:
42
+ sys.exit("Please specify a surface group")
43
+
44
+ super(Angle_distribution, self).__init__(self.atomgroup.universe.trajectory, verbose=True)
45
+
46
+ def _prepare(self):
47
+ self.bin_num = int(self.total_angle / self.bin_size) + 2
48
+ self.angle_w_distribution = np.zeros(self.bin_num, dtype=np.float64)
49
+ self.angle_oh_distribution = np.zeros(self.bin_num, dtype=np.float64)
50
+
51
+ def _append(self, angle, anglew=True):
52
+ bins = np.floor(angle / self.bin_size).astype(int) + 1
53
+
54
+ if anglew:
55
+ bins = bins[bins < len(self.angle_w_distribution)]
56
+ np.add.at(self.angle_w_distribution, bins, 1)
57
+ else:
58
+ bins = bins[bins < len(self.angle_oh_distribution)]
59
+ np.add.at(self.angle_oh_distribution, bins, 1)
60
+
61
+
62
+ def _single_frame(self):
63
+ surface = numpy_geo.find_surface(self.surface_group.positions[:, 2])
64
+
65
+ if len(surface) == 1:
66
+ o_group = self.atomgroup.select_atoms(f"name O and prop z < {surface[0]+self.water_height}", updating=True)
67
+ else:
68
+ o_group = self.atomgroup.select_atoms(f"name O and (prop z < {surface[0]+self.water_height} or prop z > {surface[1]-self.water_height})", updating=True)
69
+
70
+ h_group = self.atomgroup.select_atoms("name H")
71
+
72
+ if self.update_water:
73
+ o, oh1, oh2 = encapsulated_mda.update_water(self, o_group=o_group, h_group=h_group, distance_judg=self.distance_judg, angle_judg=self.angle_judg, return_index=False)
74
+ else:
75
+ o = o_group
76
+ oh1 = self.atomgroup[o_group.indices + 1]
77
+ oh2 = self.atomgroup[o_group.indices + 2]
78
+
79
+ vec1 = MDAnalysis.lib.distances.minimize_vectors(oh1.positions - o.positions, self.u.dimensions)
80
+ vec2 = MDAnalysis.lib.distances.minimize_vectors(oh2.positions - o.positions, self.u.dimensions)
81
+
82
+ bisector = numpy_geo.vector_between_two_vector(vec1, vec2)
83
+
84
+ angle_vec1 = np.hstack((numpy_geo.vector_vector_angle(vec1[o.positions[:, 2] < self.mid_z], self.normal_up), numpy_geo.vector_vector_angle(vec1[o.positions[:, 2] > self.mid_z], self.normal_down)))
85
+
86
+ angle_vec2 = np.hstack((numpy_geo.vector_vector_angle(vec2[o.positions[:, 2] < self.mid_z], self.normal_up), numpy_geo.vector_vector_angle(vec2[o.positions[:, 2] > self.mid_z], self.normal_down)))
87
+
88
+ angle_bisector = np.hstack((numpy_geo.vector_vector_angle(bisector[o.positions[:, 2] < self.mid_z], self.normal_up), numpy_geo.vector_vector_angle(bisector[o.positions[:, 2] > self.mid_z], self.normal_down)))
89
+
90
+ self._append(angle_vec1, anglew=False)
91
+ self._append(angle_vec2, anglew=False)
92
+ self._append(angle_bisector)
93
+
94
+ self.frame_count += 1
95
+
96
+ def _conclude(self):
97
+ if self.frame_count > 0:
98
+ average_angle_w = self.angle_w_distribution / self.frame_count
99
+ average_angle_oh = self.angle_oh_distribution / (self.frame_count*2)
100
+ bins_z = np.arange(len(average_angle_w)) * self.bin_size
101
+ conbined_data = np.column_stack((bins_z, average_angle_w, average_angle_oh))
102
+ np.savetxt("angle_distribution.dat", conbined_data, header="angle\tw_suf_dist\toh_suf_dist", fmt='%.5f', delimiter='\t')
103
+
104
+
105
+ @click.command(name="angle")
106
+ @click.argument("filename", type=click.Path(exists=True))
107
+ @click.option('--cell', type=arg_type.Cell, help="set cell, a list of lattice, --cell x,y,z or x,y,z,a,b,c")
108
+ @click.option("--water_height", type=float, help="water height from surface")
109
+ @click.option("--surface", type=str, help="surface group")
110
+ @click.option('--update_water', is_flag=True, help='update water with distance or angle judgment')
111
+ @click.option('--distance', type=float, help='update water distance judgment', default=1.2, show_default=True)
112
+ @click.option('--angle', type=(float, float), help='update water angle judgment')
113
+ @click.option('-r', type=arg_type.FrameRange, help='range of frame to analysis')
114
+ def main(filename, cell, water_height, update_water, distance, angle, surface, r):
115
+ """analysis angle between normal vectors and OH vector or bisector"""
116
+ a = Angle_distribution(filename, cell, water_height, update_water, distance_judg=distance, angle_judg=angle, surface=surface)
117
+ if r is not None:
118
+ if len(r) == 2:
119
+ a.run(start=r[0], stop=r[1])
120
+ elif len(r) == 3:
121
+ a.run(start=r[0], stop=r[1], step=r[2])
122
+ else:
123
+ a.run()
124
+
125
+
126
+ if __name__ == "__main__":
127
+ main()
@@ -75,7 +75,7 @@ class Density_distribution(AnalysisBase):
75
75
  self._append(o.positions[:, 2])
76
76
 
77
77
  else:
78
- group = self.atomgroup.select_atoms(f"{self.element}")
78
+ group = self.atomgroup.select_atoms(f"{self.element}", updating=True)
79
79
  self._append(group.positions[:, 2])
80
80
 
81
81
  if self.surface_group:
@@ -120,7 +120,7 @@ class Hb_distribution(AnalysisBase):
120
120
  self._append(hb_d, hb_a, o_group.positions[:, 2])
121
121
 
122
122
  if self.surface_group:
123
- lower_z, upper_z = numpy_geo.find_surface(self.surface_group.positions[:, 2], layer_tolerance=1, surface_tolerance=5)
123
+ lower_z, upper_z = numpy_geo.find_surface(self.surface_group.positions[:, 2])
124
124
  self.surface_pos[0] += lower_z
125
125
  self.surface_pos[1] += upper_z
126
126
 
@@ -169,7 +169,7 @@ class Hb_distribution(AnalysisBase):
169
169
  @click.option('--angle', type=(float, float), help='update water angle judgment')
170
170
  @click.option('--index', type=int, help='index of an atom')
171
171
  def main(filename, hb_param, cell, surface, r, update_water, distance, angle, index):
172
-
172
+ """analysis hydrogen bond distribution along z-axis"""
173
173
  hb_dist = Hb_distribution(filename, cell, surface, update_water=update_water, distance_judg=distance, angle_judg=angle, hb_distance=hb_param[0], hb_angle=hb_param[1], index=index)
174
174
 
175
175
  if r is not None:
@@ -2,6 +2,7 @@ import click
2
2
  from mdkits.md_cli import (
3
3
  density,
4
4
  hb_distribution,
5
+ angle,
5
6
  )
6
7
 
7
8
 
@@ -13,6 +14,7 @@ def main(ctx):
13
14
 
14
15
  main.add_command(density.main)
15
16
  main.add_command(hb_distribution.main)
17
+ main.add_command(angle.main)
16
18
 
17
19
 
18
20
  if __name__ == '__main__':
@@ -3,7 +3,7 @@ import numpy as np
3
3
  from . import numpy_geo
4
4
 
5
5
 
6
- def update_water(self, o_group, h_group, distance_judg=1.2, angle_judg:tuple[float, float]=None, return_index=False):
6
+ def update_water(self, o_group, h_group, distance_judg=1.2, angle_judg:tuple[float, float]=(None, None), return_index=False):
7
7
  """
8
8
  input: o and h atom
9
9
  output: o and two h in this frame
@@ -53,6 +53,9 @@ def update_water(self, o_group, h_group, distance_judg=1.2, angle_judg:tuple[flo
53
53
  if return_index:
54
54
  return o_index, oh1_index, oh2_index
55
55
  else:
56
+ if len(o_index) == 0:
57
+ raise ValueError("No water found in this atom group")
58
+
56
59
  o = o_group[o_index]
57
60
  oh1 = h_group[oh1_index]
58
61
  oh2 = h_group[oh2_index]
@@ -45,7 +45,7 @@ def vector_between_two_vector(vector1, vector2):
45
45
 
46
46
 
47
47
  def vector_vector_angle(vector, surface_vector):
48
- cos = np.dot(vector, surface_vector) / (np.linalg.norm(vector) * np.linalg.norm(surface_vector))
48
+ cos = np.dot(vector, surface_vector) / (np.linalg.norm(vector, axis=1) * np.linalg.norm(surface_vector))
49
49
  vector_vector_angle = np.arccos(np.clip(cos, -1.0, 1.0))
50
50
  vector_vector_angle = np.degrees(vector_vector_angle)
51
51
  return vector_vector_angle
@@ -96,7 +96,7 @@ def unwrap(atom1, atom2, coefficients, max=0, total=False):
96
96
  return min_dist, closest_point
97
97
 
98
98
 
99
- def find_surface(surface_group:np.ndarray, layer_tolerance=1, surface_tolerance=5):
99
+ def find_surface(surface_group:np.ndarray, layer_tolerance=0.05, surface_tolerance=5):
100
100
  sort_group = np.sort(surface_group)
101
101
  layer_mean = []
102
102
  current_layer = [sort_group[0]]
@@ -108,12 +108,14 @@ def find_surface(surface_group:np.ndarray, layer_tolerance=1, surface_tolerance=
108
108
  current_layer = [sort_group[i]]
109
109
  layer_mean.append(np.mean(current_layer))
110
110
 
111
- if len(current_layer) == 1:
112
- return layer_mean[0]
111
+ if len(layer_mean) == 1:
112
+ return [layer_mean[0]]
113
113
 
114
114
  diff = np.diff(layer_mean)
115
115
  if np.any(diff > surface_tolerance):
116
- index = np.argmax(diff > 5)
116
+ index = np.argmax(diff > surface_tolerance)
117
117
  return (layer_mean[index], layer_mean[index + 1])
118
118
  else:
119
+ if layer_mean[-1] > layer_mean[0]:
120
+ return [layer_mean[-1]]
119
121
  return (layer_mean[-1], layer_mean[0])
@@ -9,7 +9,7 @@ import sys, os
9
9
  def cell_output(atoms):
10
10
  cell = atoms.cell.cellpar()
11
11
  if not hasattr(atoms, "name"):
12
- atoms.name = ""
12
+ atoms.name = "present"
13
13
  print(f"{atoms.name} cell: x = {cell[0]}, y = {cell[1]}, z = {cell[2]}, a = {cell[3]}\u00B0, b = {cell[4]}\u00B0, c = {cell[5]}\u00B0")
14
14
 
15
15
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes