mdkits 0.1.27__py3-none-any.whl → 0.1.29__py3-none-any.whl

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.

@@ -70,7 +70,7 @@ def main(atoms, face, vacuum, size, cell, orth):
70
70
  super_surface = supercell.supercell(surface, size[0], size[1], 1)
71
71
 
72
72
  super_surface.write(o)
73
- out_err.cell_output(super_surface.cell.cellpar())
73
+ out_err.cell_output(super_surface)
74
74
  out_err.path_output(o)
75
75
 
76
76
 
@@ -0,0 +1,19 @@
1
+ import click
2
+ from mdkits.dft_cli import (
3
+ cube,
4
+ pdos,
5
+ )
6
+
7
+
8
+ @click.group(name='dft')
9
+ @click.pass_context
10
+ def main(ctx):
11
+ """kits for dft analysis"""
12
+ pass
13
+
14
+
15
+ main.add_command(cube.main)
16
+ main.add_command(pdos.main)
17
+
18
+ if __name__ == '__main__':
19
+ main()
mdkits/md_cli/angle.py ADDED
@@ -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:
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import numpy as np
4
+ import click
5
+ import MDAnalysis
6
+ from MDAnalysis import Universe
7
+ from MDAnalysis.analysis.base import AnalysisBase
8
+ from mdkits.util import arg_type, os_operation, numpy_geo, encapsulated_mda
9
+ import warnings, sys
10
+ warnings.filterwarnings("ignore")
11
+
12
+
13
+ class Hb_distribution(AnalysisBase):
14
+ def __init__(self, filename, cell, surface, update_water, distance_judg, angle_judg, hb_distance, hb_angle, bin_size=0.2, dt=0.001, index=None):
15
+ u = Universe(filename)
16
+ u.trajectory.ts.dt = dt
17
+ u.dimensions = cell
18
+ self.u = u
19
+ self.atomgroup = u.select_atoms("all")
20
+ self.hb_distance = hb_distance
21
+ self.hb_angle = hb_angle
22
+ self.bin_size = bin_size
23
+ self.surface = surface
24
+ self.update_water = update_water
25
+ self.frame_count = 0
26
+ np.set_printoptions(threshold=np.inf)
27
+
28
+ if surface is not None:
29
+ self.surface_group = self.atomgroup.select_atoms(f"{surface}")
30
+ if self.surface_group.n_atoms == 0:
31
+ sys.exit("Please specify the correct surface group")
32
+ else:
33
+ self.surface_group = False
34
+
35
+ if self.update_water:
36
+ self.distance_judg = distance_judg
37
+ self.angle_judg = angle_judg
38
+
39
+ if index is not None:
40
+ self.index = index
41
+ self.hb_d_index = 0
42
+ self.hb_a_index = 0
43
+ else:
44
+ self.index = None
45
+
46
+ super(Hb_distribution, self).__init__(self.atomgroup.universe.trajectory, verbose=True)
47
+
48
+ def _prepare(self):
49
+ bin_num = int(self.u.dimensions[2] / self.bin_size) + 2
50
+ self.accepter = np.zeros(bin_num, dtype=np.float64)
51
+ self.donor = np.zeros(bin_num, dtype=np.float64)
52
+ self.od = np.zeros(bin_num, dtype=np.float64)
53
+ if self.surface_group:
54
+ self.surface_pos = np.zeros(2)
55
+
56
+ def _append(self, hb_d, hb_a, o):
57
+ bins_d = np.floor(hb_d / self.bin_size).astype(int) + 1
58
+ bins_a = np.floor(hb_a / self.bin_size).astype(int) + 1
59
+ bins_o = np.floor(o / self.bin_size).astype(int) + 1
60
+
61
+ bins_d = bins_d[bins_d < len(self.donor)]
62
+ bins_a = bins_a[bins_a < len(self.accepter)]
63
+ bins_o = bins_o[bins_o < len(self.od)]
64
+
65
+ np.add.at(self.donor, bins_d, 1)
66
+ np.add.at(self.accepter, bins_a, 1)
67
+ np.add.at(self.od, bins_o, 1)
68
+
69
+ def _single_frame(self):
70
+ if self.update_water:
71
+ o = self.atomgroup.select_atoms("name O")
72
+ h = self.atomgroup.select_atoms("name H")
73
+
74
+ o_group, oh1, oh2 = encapsulated_mda.update_water(self, o, h, distance_judg=self.distance_judg, angle_judg=self.angle_judg, return_index=False)
75
+
76
+ o_pair = MDAnalysis.lib.distances.capped_distance(o_group.positions, o_group.positions, min_cutoff=0, max_cutoff=self.hb_distance, box=self.u.dimensions, return_distances=False)
77
+
78
+ o0 = o_group[o_pair[:, 0]]
79
+ o1 = o_group[o_pair[:, 1]]
80
+
81
+ o0h1 = oh1[o_pair[:, 0]]
82
+ o0h2 = oh2[o_pair[:, 0]]
83
+ o1h1 = oh1[o_pair[:, 1]]
84
+ o1h2 = oh2[o_pair[:, 1]]
85
+ else:
86
+ o_group = self.atomgroup.select_atoms("name O")
87
+ o_pair = MDAnalysis.lib.distances.capped_distance(o_group.positions, o_group.positions, min_cutoff=0, max_cutoff=self.hb_distance, box=self.u.dimensions, return_distances=False)
88
+
89
+ o0 = o_group[o_pair[:, 0]]
90
+ o1 = o_group[o_pair[:, 1]]
91
+
92
+ o0h1 = self.atomgroup[o0.indices + 1]
93
+ o0h2 = self.atomgroup[o0.indices + 2]
94
+ o1h1 = self.atomgroup[o1.indices + 1]
95
+ o1h2 = self.atomgroup[o1.indices + 2]
96
+
97
+ angle_o0h1_o0_o1 = np.degrees(
98
+ MDAnalysis.lib.distances.calc_angles(o0h1.positions, o0.positions, o1.positions, box=self.u.dimensions)
99
+ )
100
+ angle_o0h2_o0_o1 = np.degrees(
101
+ MDAnalysis.lib.distances.calc_angles(o0h2.positions, o0.positions, o1.positions, box=self.u.dimensions)
102
+ )
103
+ angle_o1h1_o1_o0 = np.degrees(
104
+ MDAnalysis.lib.distances.calc_angles(o1h1.positions, o1.positions, o0.positions, box=self.u.dimensions)
105
+ )
106
+ angle_o1h2_o1_o0 = np.degrees(
107
+ MDAnalysis.lib.distances.calc_angles(o1h2.positions, o1.positions, o0.positions, box=self.u.dimensions)
108
+ )
109
+
110
+ condition_d = (angle_o0h1_o0_o1 < self.hb_angle) | (angle_o0h2_o0_o1 < self.hb_angle)
111
+ condition_a = (angle_o1h1_o1_o0 < self.hb_angle) | (angle_o1h2_o1_o0 < self.hb_angle)
112
+
113
+ if self.index is not None:
114
+ self.hb_d_index += o0.positions[:, 2][condition_d & (o0.indices == self.index)].shape[0]
115
+ self.hb_a_index += o0.positions[:, 2][condition_a & (o0.indices == self.index)].shape[0]
116
+ else:
117
+ hb_d = o0.positions[:, 2][condition_d]
118
+ hb_a = o0.positions[:, 2][condition_a]
119
+
120
+ self._append(hb_d, hb_a, o_group.positions[:, 2])
121
+
122
+ if self.surface_group:
123
+ lower_z, upper_z = numpy_geo.find_surface(self.surface_group.positions[:, 2])
124
+ self.surface_pos[0] += lower_z
125
+ self.surface_pos[1] += upper_z
126
+
127
+ self.frame_count += 1
128
+
129
+ def _conclude(self):
130
+ if self.frame_count > 0 and self.index is None:
131
+ average_od = self.od / self.frame_count
132
+ average_donor = (self.donor / self.frame_count) / average_od
133
+ average_accepter = (self.accepter / self.frame_count) / average_od
134
+ average_sum = average_donor + average_accepter
135
+
136
+ bins_z = np.arange(len(self.donor)) * self.bin_size
137
+
138
+ if self.surface:
139
+ lower_z, upper_z = self.surface_pos/self.frame_count
140
+ mask = (bins_z >= lower_z) & (bins_z <= upper_z)
141
+ filtered_bins_z = bins_z[mask] - lower_z
142
+ filtered_average_accepter = average_accepter[mask]
143
+ filtered_average_donor = average_donor[mask]
144
+ filtered_average_sum = average_sum[mask]
145
+
146
+ combined_data = np.column_stack((filtered_bins_z, filtered_average_accepter, filtered_average_donor, filtered_average_sum))
147
+ else:
148
+ combined_data = np.column_stack((bins_z, average_accepter, average_donor, average_sum))
149
+
150
+ np.savetxt("hb_distribution.dat", combined_data, header="Z\tAccepter\tDonor\tAccepter+Donor", fmt='%.5f', delimiter='\t')
151
+
152
+ if self.index is not None and self.frame_count > 0:
153
+ self.hb_d_index /= self.frame_count
154
+ self.hb_a_index /= self.frame_count
155
+ output = f"# {self.index}\naccepter : {self.hb_a_index}\ndonor : {self.hb_d_index}\ntotal : {self.hb_a_index + self.hb_d_index}"
156
+ with open(f"hb_{self.index}.dat", "a") as f:
157
+ f.write(output)
158
+ print(output)
159
+
160
+
161
+ @click.command(name="hb")
162
+ @click.argument('filename', type=click.Path(exists=True), default=os_operation.default_file_name('*-pos-1.xyz', last=True))
163
+ @click.option('--hb_param', type=click.Tuple([float, float]), help='parameter for hydrogen bond', default=(3.5, 35), show_default=True)
164
+ @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')
165
+ @click.option('--surface', type=str, help='surface element')
166
+ @click.option('-r', type=arg_type.FrameRange, help='range of frame to analysis')
167
+ @click.option('--update_water', is_flag=True, help='update water with distance or angle judgment')
168
+ @click.option('--distance', type=float, help='update water distance judgment', default=1.2, show_default=True)
169
+ @click.option('--angle', type=(float, float), help='update water angle judgment')
170
+ @click.option('--index', type=int, help='index of an atom')
171
+ def main(filename, hb_param, cell, surface, r, update_water, distance, angle, index):
172
+ """analysis hydrogen bond distribution along z-axis"""
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
+
175
+ if r is not None:
176
+ if len(r) == 2:
177
+ hb_dist.run(start=r[0], stop=r[1])
178
+ elif len(r) == 3:
179
+ hb_dist.run(start=r[0], stop=r[1], step=r[2])
180
+ else:
181
+ hb_dist.run()
182
+
183
+
184
+ if __name__ == '__main__':
185
+ main()
@@ -0,0 +1,21 @@
1
+ import click
2
+ from mdkits.md_cli import (
3
+ density,
4
+ hb_distribution,
5
+ angle,
6
+ )
7
+
8
+
9
+ @click.group(name='md')
10
+ @click.pass_context
11
+ def main(ctx):
12
+ """kits for MD analysis"""
13
+ pass
14
+
15
+ main.add_command(density.main)
16
+ main.add_command(hb_distribution.main)
17
+ main.add_command(angle.main)
18
+
19
+
20
+ if __name__ == '__main__':
21
+ main()
mdkits/mdkits.py CHANGED
@@ -1,14 +1,13 @@
1
1
  import click
2
2
  from mdkits.build_cli import build_cli
3
+ from mdkits.dft_cli import dft_cli
4
+ from mdkits.md_cli import md_cli
3
5
  from mdkits.cli import (
4
6
  convert,
5
7
  wrap,
6
8
  extract,
7
9
  data,
8
10
  plot,
9
- density,
10
- cube,
11
- pdos,
12
11
  )
13
12
 
14
13
 
@@ -20,15 +19,14 @@ def cli(ctx):
20
19
  pass
21
20
 
22
21
 
22
+ cli.add_command(md_cli.main)
23
+ cli.add_command(dft_cli.main)
24
+ cli.add_command(build_cli.cli_build)
23
25
  cli.add_command(convert.main)
24
26
  cli.add_command(wrap.main)
25
27
  cli.add_command(extract.main)
26
28
  cli.add_command(data.main)
27
29
  cli.add_command(plot.main)
28
- cli.add_command(density.main)
29
- cli.add_command(cube.main)
30
- cli.add_command(pdos.main)
31
- cli.add_command(build_cli.cli_build)
32
30
 
33
31
 
34
32
  if __name__ == '__main__':
Binary file
mdkits/util/arg_type.py CHANGED
@@ -14,10 +14,8 @@ class CellType(click.ParamType):
14
14
 
15
15
  if len(cell) == 3:
16
16
  cell += [90, 90, 90]
17
- out_err.cell_output(cell)
18
17
  return cell
19
18
  elif len(cell) == 6:
20
- out_err.cell_output(cell)
21
19
  return cell
22
20
  else:
23
21
  self.fail(f"{value} is not a valid cell parameter", param, ctx)
@@ -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]
mdkits/util/numpy_geo.py CHANGED
@@ -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])
mdkits/util/out_err.py CHANGED
@@ -6,8 +6,11 @@ import numpy as np
6
6
  import sys, os
7
7
 
8
8
 
9
- def cell_output(cell):
10
- print(f"system cell: x = {cell[0]}, y = {cell[1]}, z = {cell[2]}, a = {cell[3]}\u00B0, b = {cell[4]}\u00B0, c = {cell[5]}\u00B0")
9
+ def cell_output(atoms):
10
+ cell = atoms.cell.cellpar()
11
+ if not hasattr(atoms, "name"):
12
+ atoms.name = "present"
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")
11
14
 
12
15
 
13
16
  def path_output(file: str):
@@ -16,11 +19,11 @@ def path_output(file: str):
16
19
  def check_cell(atoms, cell=None):
17
20
  if cell is not None:
18
21
  atoms.set_cell(cell)
19
- cell_output(atoms.cell.cellpar())
20
- if not np.array_equal(atoms.cell.cellpar(), np.array([0., 0., 0., 90., 90., 90.])):
21
- cell_output(atoms.cell.cellpar())
22
+ cell_output(atoms)
23
+ elif not np.array_equal(atoms.cell.cellpar(), np.array([0., 0., 0., 90., 90., 90.])):
24
+ cell_output(atoms)
22
25
  elif np.array_equal(atoms.cell.cellpar(), np.array([0., 0., 0., 90., 90., 90.])) and cell is not None:
23
26
  atoms.set_cell(cell)
24
- cell_output(atoms.cell.cellpar())
27
+ cell_output(atoms)
25
28
  else:
26
29
  raise ValueError("can't parse cell please use --cell set cell")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mdkits
3
- Version: 0.1.27
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
@@ -6,38 +6,42 @@ mdkits/build_cli/build_cli.py,sha256=sqjnq5aHWLYLbNzN5SORkEYeYaewLagFuSvspJxyh7E
6
6
  mdkits/build_cli/build_interface.py,sha256=3EDxUb-vGHFuat1Ex_wojVsN8PtzHiGrnDQIEa9WZ60,2448
7
7
  mdkits/build_cli/build_solution.py,sha256=7bwaDH-vLBNRzGoYXT72bzLVXdQAZ4HXNuUDuR7AI78,5377
8
8
  mdkits/build_cli/build_surface.py,sha256=cBEQ-KR_6j-Mcsxrwvzyl6p1SiY_chIytrCu7MS3q08,2794
9
- mdkits/build_cli/cut_surface.py,sha256=R0Snr-y23SYLfNhdBC5VgT4KFY1SOGn5hZlVvX5CUvw,2757
9
+ mdkits/build_cli/cut_surface.py,sha256=_f0t2OyBKb8ZV04b3GezfSDUN4XFd5kQM-yWbSmOofs,2742
10
10
  mdkits/build_cli/supercell.py,sha256=3iTTt3DHaERWDFonhBRS0oqWhjFh6pbS5SpIR-O1gYg,1034
11
11
  mdkits/build_cli/water.xyz,sha256=ByLDz-rYhw_wLPBU78lIQHe4s4Xf5Ckjft-Dus3czIc,171
12
12
  "mdkits/cli/,hb_distribution_down.py",sha256=i3NguzGebqCgy4uuVBeFajZRZnXtjhsJBPDGDdumlWA,4733
13
13
  mdkits/cli/convert.py,sha256=OmQ-7hmw0imgfgCJaWFEy3ePixsU7VKf0mGuJ6jRpn0,1795
14
- mdkits/cli/cube.py,sha256=G-QNup8W6J1-LCcEl1EHsV3nstd23byePDOcE_95t18,1176
15
14
  mdkits/cli/data.py,sha256=FGA4S9Cfo6WUJBSPWKOJrrZXHo_Qza-jNG1P_Dw7yi4,3262
16
- mdkits/cli/density.py,sha256=Y4grT8p7CsxggGYo_nGE9z_wlkJeQS5eYWKJQcoA014,5559
17
15
  mdkits/cli/extract.py,sha256=bqqJBmSaVyPYyEseGpUJcMBufIfDLTNRdmUfJ0txE5E,2498
18
16
  mdkits/cli/hartree_potential.py,sha256=XcJfsJ5Y2d5MQfD45p06_gV1fTJbDSrNhCnZ3Sz2Vb0,2233
19
17
  mdkits/cli/hartree_potential_ave.py,sha256=25oy3QsgIdxrTFpTqpnGvLAheb-d6poeLMN7iuGT3Xk,3335
20
18
  mdkits/cli/hb.py,sha256=lADr4tlctbtQ3_f_UpznkLnSI0MJlAT-pknEf_dwrnU,5330
21
- mdkits/cli/hb_distribution.py,sha256=VpTyOhU9oucWUnqUSmLgZfMb5g0tR0q7vrxakLSrKxI,5120
22
19
  mdkits/cli/packmol_input.py,sha256=76MjjMMRDaW2q459B5mEpXDYSSn14W-JXudOOsx-8E4,2849
23
- mdkits/cli/pdos.py,sha256=ALAZ5uOaoT0UpCyKYleWxwmk569HMzKTTK-lMJeicM8,1411
24
20
  mdkits/cli/plot.py,sha256=1yh5dq5jnQDuyWlxV_9g5ztsnuFHVu4ouYQ9VJYSrUU,8938
25
21
  mdkits/cli/wrap.py,sha256=AUxGISuiCfEjdMYl-TKc2VMCPHSybWKrMIOTn_6kSp0,1043
26
22
  mdkits/config/__init__.py,sha256=ZSwmnPK02LxJLMgcYmNb-tIOk8fEuHf5jpqD3SDHWLg,1039
27
23
  mdkits/config/settings.yml,sha256=PY7u0PbFLuxSnd54H5tI9oMjUf-mzyADqSZtm99BwG0,71
28
- mdkits/mdkits.py,sha256=7yZHo13dn_Nn5K7BNIrEXFN44WoZoWD_MqgRQGhTJEU,627
24
+ mdkits/dft_cli/cube.py,sha256=G-QNup8W6J1-LCcEl1EHsV3nstd23byePDOcE_95t18,1176
25
+ mdkits/dft_cli/dft_cli.py,sha256=Ou9-e4uGhDJJk2Gdg7tcj6iKApkAJZFSbN1hr7SlCMc,281
26
+ mdkits/dft_cli/pdos.py,sha256=ALAZ5uOaoT0UpCyKYleWxwmk569HMzKTTK-lMJeicM8,1411
27
+ mdkits/md_cli/angle.py,sha256=PaqFnlVnWHy6t6eDOQdq7J0jhMpCnekIzNCjhTMpdqw,5930
28
+ mdkits/md_cli/density.py,sha256=-o1argCiwWr9mjggeetuX0sDMxjhRSPMG25sOS3KZYU,5574
29
+ mdkits/md_cli/hb_distribution.py,sha256=MPrYfVW0MC01G1GZTxTca58jSlD0rVRnR1g1DmvdE00,8301
30
+ mdkits/md_cli/md_cli.py,sha256=7hefzX0NIydlL2AjqTkTwLUg6yIOMSCn3zQ1zU9pP3s,348
31
+ mdkits/mdkits.py,sha256=UGCAbVml8MdXXG--LGo8BUm9BXofg9P3HKIEDTUbd48,635
32
+ mdkits/util/.fig_operation.py.swp,sha256=iZYqdYMj4UKS1rmbXv8Ve2FcVBcNljX7Y43-neMdPSk,12288
29
33
  mdkits/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- mdkits/util/arg_type.py,sha256=Dc4tC0V-F2dA83QShLFxZckBYM2TebthzL425s2buLo,2523
34
+ mdkits/util/arg_type.py,sha256=o4Fz5VaNBpCWvnJ0u7tKex1sOGx9d2PFtXHmEFMJbA4,2437
31
35
  mdkits/util/cp2k_input_parsing.py,sha256=7NMVOYEGycarokLJlhLoWWilciM7sd8MWp5FVTF7hqI,1223
32
36
  mdkits/util/encapsulated_ase.py,sha256=uhqIhsALxzwJYuFrfOYGGC6U0QLm_dcZNridvfl_XGc,4339
33
- mdkits/util/encapsulated_mda.py,sha256=td3H24u3eHOIS2nwPucfIaMxeaVxI77oFI8nnNhw7vo,2217
37
+ mdkits/util/encapsulated_mda.py,sha256=m3i-XrcscMcM5V7JzLnor3JtAOfuDx3LLMl0tZt0n-w,2325
34
38
  mdkits/util/fig_operation.py,sha256=FwffNUtXorMl6qE04FipgzcVljEQii7wrNJUCJMyY3E,1045
35
- mdkits/util/numpy_geo.py,sha256=1Op8THoQeyqybSZAi7hVxohYCr4SzY6ndZC8_gAGXDA,3619
39
+ mdkits/util/numpy_geo.py,sha256=SUBkR1BsotELTbfSb-OIdheYozPDXGJQgktPlOYz4I4,3724
36
40
  mdkits/util/os_operation.py,sha256=ErN2ExjX9vZRfPe3ypsj4eyoQTEePqzlEX0Xm1N4lL4,980
37
- mdkits/util/out_err.py,sha256=xP36kwp4eYnFs-ZPWL8_9VPWXK31Q_ZeiawQfHHpvvs,835
41
+ mdkits/util/out_err.py,sha256=7vGDI7wVoJWe1S0BDbcq-UC2KAhblCzg-NAYZKBZ4lo,900
38
42
  mdkits/util/structure_parsing.py,sha256=mRPMJeih3O-ST7HeETDvBEkfV-1psT-XgxyYgDadV0U,4152
39
- mdkits-0.1.27.dist-info/entry_points.txt,sha256=xoWWZ_yL87S501AzCO2ZjpnVuYkElC6z-8J3tmuIGXQ,44
40
- mdkits-0.1.27.dist-info/LICENSE,sha256=VLaqyB0r_H7y3hUntfpPWcE3OATTedHWI983htLftcQ,1081
41
- mdkits-0.1.27.dist-info/METADATA,sha256=u3mxa5DCBEs8cSbRY3r2PONdh7YbD2HA88tCy1r9p9Q,6907
42
- mdkits-0.1.27.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
43
- mdkits-0.1.27.dist-info/RECORD,,
43
+ mdkits-0.1.29.dist-info/entry_points.txt,sha256=xoWWZ_yL87S501AzCO2ZjpnVuYkElC6z-8J3tmuIGXQ,44
44
+ mdkits-0.1.29.dist-info/LICENSE,sha256=VLaqyB0r_H7y3hUntfpPWcE3OATTedHWI983htLftcQ,1081
45
+ mdkits-0.1.29.dist-info/METADATA,sha256=MnKaR5Xv424kq5SmB1-BHCPBzpPHAL_F6ylSHKViz50,6907
46
+ mdkits-0.1.29.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
47
+ mdkits-0.1.29.dist-info/RECORD,,
@@ -1,126 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- import numpy as np
4
- import argparse
5
- import MDAnalysis
6
- from MDAnalysis import Universe
7
- from MDAnalysis.analysis.base import AnalysisBase
8
- from util import cp2k_input_parsing
9
- import warnings
10
- warnings.filterwarnings("ignore")
11
-
12
-
13
- class Hb_distribution(AnalysisBase):
14
- def __init__(self, filename, cell, surface, dt=0.001, hb_distance=3.5, hb_angle=35, bin_size=0.2):
15
- u = Universe(filename)
16
- u.trajectory.ts.dt = dt
17
- u.dimensions = cell
18
- self.u = u
19
- self.atomgroup = u.select_atoms("all")
20
- self.hb_distance = hb_distance
21
- self.hb_angle = hb_angle
22
- self.bin_size = bin_size
23
- self.surface = surface
24
- self.frame_count = 0
25
- super(Hb_distribution, self).__init__(self.atomgroup.universe.trajectory, verbose=True)
26
-
27
- def _prepare(self):
28
- bin_num = int(self.u.dimensions[2] / self.bin_size) + 2
29
- self.accepter = np.zeros(bin_num, dtype=np.float64)
30
- self.donor = np.zeros(bin_num, dtype=np.float64)
31
-
32
- def _append(self, hb_d, hb_a):
33
- bins_d = np.floor(hb_d / self.bin_size).astype(int) + 1
34
- bins_a = np.floor(hb_a / self.bin_size).astype(int) + 1
35
-
36
- bins_d = bins_d[bins_d < len(self.donor)]
37
- bins_a = bins_a[bins_a < len(self.accepter)]
38
-
39
- np.add.at(self.donor, bins_d, 1)
40
- np.add.at(self.accepter, bins_a, 1)
41
-
42
- self.frame_count += 1
43
-
44
- def _single_frame(self):
45
- o_group = self.atomgroup.select_atoms("name O")
46
- o_pair = MDAnalysis.lib.distances.capped_distance(o_group.positions, o_group.positions, min_cutoff=0, max_cutoff=self.hb_distance, box=self.u.dimensions, return_distances=False)
47
-
48
- o0 = o_group[o_pair[:, 0]]
49
- o1 = o_group[o_pair[:, 1]]
50
-
51
- o0h1 = self.atomgroup[o0.indices + 1]
52
- o0h2 = self.atomgroup[o0.indices + 2]
53
- o1h1 = self.atomgroup[o1.indices + 1]
54
- o1h2 = self.atomgroup[o1.indices + 2]
55
-
56
- angle_o0h1_o0_o1 = np.degrees(
57
- MDAnalysis.lib.distances.calc_angles(o0h1.positions, o0.positions, o1.positions, box=self.u.dimensions)
58
- )
59
- angle_o0h2_o0_o1 = np.degrees(
60
- MDAnalysis.lib.distances.calc_angles(o0h2.positions, o0.positions, o1.positions, box=self.u.dimensions)
61
- )
62
- angle_o1h1_o1_o0 = np.degrees(
63
- MDAnalysis.lib.distances.calc_angles(o1h1.positions, o1.positions, o0.positions, box=self.u.dimensions)
64
- )
65
- angle_o1h2_o1_o0 = np.degrees(
66
- MDAnalysis.lib.distances.calc_angles(o1h2.positions, o1.positions, o0.positions, box=self.u.dimensions)
67
- )
68
-
69
- condition_d = (angle_o0h1_o0_o1 < self.hb_angle) | (angle_o0h2_o0_o1 < self.hb_angle)
70
- condition_a = (angle_o1h1_o1_o0 < self.hb_angle) | (angle_o1h2_o1_o0 < self.hb_angle)
71
-
72
- hb_d = (o0.positions[:, 2][condition_d] + o1.positions[:, 2][condition_d]) / 2
73
- hb_a = (o0.positions[:, 2][condition_a] + o1.positions[:, 2][condition_a]) / 2
74
-
75
- self._append(hb_d, hb_a)
76
-
77
- def _conclude(self):
78
- if self.frame_count > 0:
79
- average_donor = self.donor / self.frame_count
80
- average_accepter = self.accepter / self.frame_count
81
- average_sum = average_donor + average_accepter
82
-
83
- bins_z = np.arange(len(self.donor)) * self.bin_size
84
-
85
- lower_z, upper_z = self.surface
86
- mask = (bins_z >= lower_z) & (bins_z <= upper_z)
87
- filtered_bins_z = bins_z[mask] - lower_z
88
- filtered_average_accepter = average_accepter[mask]
89
- filtered_average_donor = average_donor[mask]
90
- filtered_average_sum = average_sum[mask]
91
-
92
- combined_data = np.column_stack((filtered_bins_z, filtered_average_accepter, filtered_average_donor, filtered_average_sum))
93
-
94
- np.savetxt("hb_distribution.dat", combined_data, header="Z\tAccepter\tDonor\tAccepter+Donor", fmt='%.5f', delimiter='\t')
95
-
96
-
97
- def parse_data(s):
98
- return [float(x) for x in s.replace(',', ' ').split()]
99
-
100
-
101
- def parse_r(s):
102
- return [int(x) for x in s.replace(':', ' ').split()]
103
-
104
-
105
- def parse_argument():
106
- parser = argparse.ArgumentParser(description="analysis hb distribution")
107
- parser.add_argument('filename', type=str, help='filename to analysis')
108
- parser.add_argument('--cp2k_input_file', type=str, help='input file name of cp2k, default is "input.inp"', default='input.inp')
109
- parser.add_argument('-r', type=parse_r, help='range of analysis', default=[0, -1, 1])
110
- parser.add_argument('--cell', type=parse_data, help='set cell, a list of lattice, --cell x,y,z or x,y,z,a,b,c')
111
- parser.add_argument('--surface', type=parse_data, help='[down_surface_z, up_surface_z]')
112
- parser.add_argument('--hb_param', type=parse_data, help='[hb_distance, hb_angle], default is [3.5, 35]', default=[3.5, 35])
113
-
114
- return parser.parse_args()
115
-
116
-
117
- def main():
118
- args = parse_argument()
119
- cell = cp2k_input_parsing.get_cell(args.cp2k_input_file, args.cell)
120
-
121
- hb_dist = Hb_distribution(args.filename, cell, args.surface, hb_distance=args.hb_param[0], hb_angle=args.hb_param[1])
122
- hb_dist.run(start=args.r[0], stop=args.r[1], step=args.r[2])
123
-
124
-
125
- if __name__ == '__main__':
126
- main()
File without changes
File without changes