mdkits 0.1a1__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.
- mdkits/__init__.py +0 -0
- mdkits/cli/,hb_distribution.py +126 -0
- mdkits/cli/,hb_distribution_down.py +114 -0
- mdkits/cli/adsorbate.py +84 -0
- mdkits/cli/build_bulk.py +55 -0
- mdkits/cli/build_interface.py +86 -0
- mdkits/cli/build_surface.py +134 -0
- mdkits/cli/cmdline.py +41 -0
- mdkits/cli/convert.py +63 -0
- mdkits/cli/cp2k_input.py +479 -0
- mdkits/cli/cube.py +59 -0
- mdkits/cli/cut_surface.py +38 -0
- mdkits/cli/data.py +80 -0
- mdkits/cli/density.py +89 -0
- mdkits/cli/density2.py +91 -0
- mdkits/cli/extract.py +80 -0
- mdkits/cli/hartree_potential.py +59 -0
- mdkits/cli/hartree_potential_ave.py +84 -0
- mdkits/cli/hb.py +101 -0
- mdkits/cli/log.py +64 -0
- mdkits/cli/matplot.py +60 -0
- mdkits/cli/packmol_input.py +76 -0
- mdkits/cli/pdos.py +36 -0
- mdkits/cli/plot.py +289 -0
- mdkits/cli/supercell.py +72 -0
- mdkits/cli/wrap.py +36 -0
- mdkits/config/__init__.py +35 -0
- mdkits/config/settings.yml +4 -0
- mdkits/mdtool.py +28 -0
- mdkits/util/__init__.py +0 -0
- mdkits/util/arg_type.py +41 -0
- mdkits/util/cp2k_input_parsing.py +46 -0
- mdkits/util/encapsulated_ase.py +134 -0
- mdkits/util/encapsulated_mda.py +59 -0
- mdkits/util/fig_operation.py +28 -0
- mdkits/util/numpy_geo.py +118 -0
- mdkits/util/os_operation.py +35 -0
- mdkits/util/structure_parsing.py +147 -0
- mdkits-0.1a1.dist-info/LICENSE +21 -0
- mdkits-0.1a1.dist-info/METADATA +161 -0
- mdkits-0.1a1.dist-info/RECORD +43 -0
- mdkits-0.1a1.dist-info/WHEEL +4 -0
- mdkits-0.1a1.dist-info/entry_points.txt +3 -0
mdkits/cli/matplot.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
import argparse
|
|
6
|
+
import os
|
|
7
|
+
from matplotlib import use as muse
|
|
8
|
+
muse('Agg')
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def parse_slice(s):
|
|
12
|
+
if s == None:
|
|
13
|
+
return None
|
|
14
|
+
return [int(x) for x in s.replace(':', ' ').split()]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def parse_argument():
|
|
18
|
+
parser = argparse.ArgumentParser(description='extract pos file from output file')
|
|
19
|
+
|
|
20
|
+
parser.add_argument('input_file_name', type=str, help='input file name')
|
|
21
|
+
parser.add_argument('-o', type=str, help='output file name, default is "out.xyz"', default='out.png')
|
|
22
|
+
parser.add_argument('-u', type=parse_slice, help='which clume to use, look like gnuplot u 1:2', default=[0, 1])
|
|
23
|
+
parser.add_argument('--label', type=str, help='line name')
|
|
24
|
+
parser.add_argument('--dpi', type=int, help='image dpi, default is 300', default=300)
|
|
25
|
+
parser.add_argument('--err', help='plot err line', action='store_true')
|
|
26
|
+
|
|
27
|
+
return parser.parse_args()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def plot_data(x, y, dpi, label, name):
|
|
31
|
+
fig, ax = plt.subplots(dpi=dpi)
|
|
32
|
+
ax.plot(x, y, label=label)
|
|
33
|
+
ax.legend()
|
|
34
|
+
fig.savefig(name)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def plot_err(x, y, dpi, label, name):
|
|
38
|
+
fig, ax = plt.subplots(dpi=dpi)
|
|
39
|
+
ax.scatter(x, y, label=label)
|
|
40
|
+
line = np.linspace(np.amax(x), np.amin(x), 1000)
|
|
41
|
+
ax.plot(line, line)
|
|
42
|
+
ax.legend()
|
|
43
|
+
fig.savefig(name)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def main():
|
|
47
|
+
args = parse_argument()
|
|
48
|
+
if args.label == None:
|
|
49
|
+
args.label = args.input_file_name
|
|
50
|
+
data = np.loadtxt(args.input_file_name)
|
|
51
|
+
if args.err:
|
|
52
|
+
plot_err(data[:, 0], data[:, 1], dpi=args.dpi, label=args.label, name=args.o)
|
|
53
|
+
else:
|
|
54
|
+
plot_data(data[:, 0], data[:, 1], dpi=args.dpi, label=args.label, name=args.o)
|
|
55
|
+
|
|
56
|
+
print(os.path.abspath(args.o))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == '__main__':
|
|
60
|
+
main()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def parse_cell(s):
|
|
5
|
+
return [float(x) for x in s.replace(',', ' ').split()]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def parse_argument():
|
|
9
|
+
parser = argparse.ArgumentParser(description='generate packmol input file with give parameter')
|
|
10
|
+
parser.add_argument('--size', type=int, help='water size default is 30', default=30)
|
|
11
|
+
parser.add_argument('--cell', type=parse_cell, help='input box size(a,b,c)')
|
|
12
|
+
parser.add_argument('--addwat', type=int, help='add some additional water, default is 0', default=0)
|
|
13
|
+
parser.add_argument('--ioncon', type=float, help='concentration of sol box, default is 0.0', default=0.0)
|
|
14
|
+
parser.add_argument('--tolerance', type=float, help='tolerance of packmol, default is 2.5', default=2.5)
|
|
15
|
+
parser.add_argument('--watpath', type=str, help='water xyz file path', default='C:\\home\\.can\\temp\\packmol\\default\\water.xyz')
|
|
16
|
+
parser.add_argument('--ionpath', type=str, help='ion xyz file path')
|
|
17
|
+
parser.add_argument('-o', type=str, help='output file name, default is "input.pm"', default='input.pm')
|
|
18
|
+
parser.add_argument('--output', type=str, help='output file name of packmol, default is "solbox.xyz"', default='solbox.xyz')
|
|
19
|
+
|
|
20
|
+
return parser.parse_args()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_water_number():
|
|
24
|
+
water_number = water_volume / water_size
|
|
25
|
+
|
|
26
|
+
return int(round(water_number, 0))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_ion_number(concentration):
|
|
30
|
+
ion_number = ( (concentration * avogadro) / 1e+27 ) * water_volume
|
|
31
|
+
|
|
32
|
+
return int(round(ion_number, 0))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def main():
|
|
36
|
+
global water_volume, water_size, avogadro
|
|
37
|
+
args = parse_argument()
|
|
38
|
+
water_volume = args.cell[0] * args.cell[1] * args.cell[2]
|
|
39
|
+
water_size = args.size
|
|
40
|
+
avogadro = 6.02214179e+23
|
|
41
|
+
water_number = get_water_number() + args.addwat
|
|
42
|
+
ion_number = get_ion_number(args.ioncon)
|
|
43
|
+
|
|
44
|
+
if ion_number == 0:
|
|
45
|
+
packmol_input_str = f"""
|
|
46
|
+
tolerance {args.tolerance}
|
|
47
|
+
filetype xyz
|
|
48
|
+
output {args.output}
|
|
49
|
+
pbc {args.cell[3]} {args.cell[4]} {args.cell[5]}
|
|
50
|
+
structure {args.watpath}
|
|
51
|
+
number {water_number}
|
|
52
|
+
inside box 2. 2. 2. {args.cell[0]-2} {args.cell[1]-2} {args.cell[2]-2}
|
|
53
|
+
end structure
|
|
54
|
+
"""
|
|
55
|
+
else:
|
|
56
|
+
packmol_input_str = f"""
|
|
57
|
+
tolerance {args.tolerance}
|
|
58
|
+
filetype xyz
|
|
59
|
+
output {args.output}
|
|
60
|
+
pbc {args.cell[3]} {args.cell[4]} {args.cell[5]}
|
|
61
|
+
structure {args.watpath}
|
|
62
|
+
number {water_number}
|
|
63
|
+
inside box 2. 2. 2. {args.cell[0]-2} {args.cell[1]-2} {args.cell[2]-2}
|
|
64
|
+
end structure
|
|
65
|
+
structure {args.ionpath}
|
|
66
|
+
number {ion_number}
|
|
67
|
+
inside box 2. 2. 2. {args.cell[0]-2} {args.cell[1]-2} {args.cell[2]-2}
|
|
68
|
+
end structure
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
with open(args.o, 'w') as f:
|
|
72
|
+
f.write(packmol_input_str)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == '__main__':
|
|
76
|
+
main()
|
mdkits/cli/pdos.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env python3.9
|
|
2
|
+
|
|
3
|
+
# caculate pdos
|
|
4
|
+
|
|
5
|
+
from cp2kdata import Cp2kPdos
|
|
6
|
+
import argparse
|
|
7
|
+
import numpy as np
|
|
8
|
+
from util import os_operation
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def to_file(filename, ener, dos):
|
|
12
|
+
to_file = np.column_stack((ener, dos))
|
|
13
|
+
np.savetxt(filename, to_file, delimiter=" ")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# set argument
|
|
17
|
+
parser = argparse.ArgumentParser(description='calculate pdos')
|
|
18
|
+
parser.add_argument('filename', type=str, nargs='?', default=os_operation.default_file_name('*-k*.pdos'))
|
|
19
|
+
parser.add_argument('--type', type=str, default='total')
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# pdos
|
|
24
|
+
#dos_types = ['0']
|
|
25
|
+
#for dos_type in dos_types:
|
|
26
|
+
# for atom_type in range(1, args.type_number+1):
|
|
27
|
+
# dos_obj = Cp2kPdos(f'{args.project_name}-k{atom_type}-1_{args.run_step}.pdos')
|
|
28
|
+
# dos, ener = dos_obj.get_raw_dos()
|
|
29
|
+
# to_file(f"{dos_obj.read_dos_element()}_{dos_type}.pdos", ener, dos)
|
|
30
|
+
|
|
31
|
+
# total dos
|
|
32
|
+
print(args.filename)
|
|
33
|
+
for file in args.filename:
|
|
34
|
+
dos_obj = Cp2kPdos(file)
|
|
35
|
+
dos, ener = dos_obj.get_raw_dos(dos_type=args.type)
|
|
36
|
+
to_file(f'{dos_obj.read_dos_element()}_{args.type}.pdos', ener, dos)
|
mdkits/cli/plot.py
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
from matplotlib import pyplot as plt
|
|
6
|
+
from matplotlib import rcParams
|
|
7
|
+
import matplotlib.ticker as ticker
|
|
8
|
+
import yaml, click
|
|
9
|
+
from mdtool.util import fig_operation
|
|
10
|
+
|
|
11
|
+
DEFAULT_CONFIG = {
|
|
12
|
+
'data': {},
|
|
13
|
+
'x': {},
|
|
14
|
+
'y': {},
|
|
15
|
+
'figsize': None,
|
|
16
|
+
'x_range': None,
|
|
17
|
+
'y_range': None,
|
|
18
|
+
'legend_fontsize': None,
|
|
19
|
+
'ticks_fontsize': None,
|
|
20
|
+
'line': {},
|
|
21
|
+
'fold': None
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_config(file_path):
|
|
26
|
+
try:
|
|
27
|
+
with open(file_path, 'r') as file:
|
|
28
|
+
data = yaml.safe_load(file)
|
|
29
|
+
except FileNotFoundError:
|
|
30
|
+
print(f"no file {file_path}")
|
|
31
|
+
exit(1)
|
|
32
|
+
except yaml.YAMLError as exc:
|
|
33
|
+
print(f"yaml parse error: {exc}")
|
|
34
|
+
exit(1)
|
|
35
|
+
config = data.copy()
|
|
36
|
+
#for key, default in DEFAULT_CONFIG.items():
|
|
37
|
+
# config[key] = data.get(key, default)
|
|
38
|
+
for key, value in config.items():
|
|
39
|
+
for dkey, dvalue in DEFAULT_CONFIG.items():
|
|
40
|
+
value[dkey] = data[key].get(dkey, dvalue)
|
|
41
|
+
|
|
42
|
+
return config
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def check_figsize(figsize):
|
|
46
|
+
match figsize:
|
|
47
|
+
case list() if len(figsize) == 2:
|
|
48
|
+
rcParams['figure.figsize'] = figsize
|
|
49
|
+
case None:
|
|
50
|
+
pass
|
|
51
|
+
case _:
|
|
52
|
+
print("wrong yaml structure")
|
|
53
|
+
exit(1)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def check_int_ticks(ax, int_ticks):
|
|
57
|
+
match int_ticks:
|
|
58
|
+
case 'x':
|
|
59
|
+
ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
|
|
60
|
+
case 'y':
|
|
61
|
+
ax.yaxis.set_major_locator(ticker.MaxNLocator(integer=True))
|
|
62
|
+
case 'a':
|
|
63
|
+
ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
|
|
64
|
+
ax.yaxis.set_major_locator(ticker.MaxNLocator(integer=True))
|
|
65
|
+
case _:
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def check_axis_range(ax, x_range=None, y_range=None):
|
|
70
|
+
if x_range:
|
|
71
|
+
match x_range:
|
|
72
|
+
case list() if len(x_range) == 2:
|
|
73
|
+
ax.set_xlim(x_range[0], x_range[1])
|
|
74
|
+
case None:
|
|
75
|
+
pass
|
|
76
|
+
case _:
|
|
77
|
+
print("wrong yaml structure")
|
|
78
|
+
exit(1)
|
|
79
|
+
if y_range:
|
|
80
|
+
match y_range:
|
|
81
|
+
case list() if len(y_range) == 2:
|
|
82
|
+
ax.set_ylim(y_range[0], y_range[1])
|
|
83
|
+
case None:
|
|
84
|
+
pass
|
|
85
|
+
case _:
|
|
86
|
+
print("wrong yaml structure")
|
|
87
|
+
exit(1)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def check_lenend_fontsize(ax, legend_fontsize, rmse=None):
|
|
91
|
+
if rmse is not None:
|
|
92
|
+
match legend_fontsize:
|
|
93
|
+
case int():
|
|
94
|
+
l = ax.legend(fontsize=legend_fontsize, markerscale=0, handlelength=0)
|
|
95
|
+
case None:
|
|
96
|
+
l = ax.legend(markerscale=0, handlelength=0)
|
|
97
|
+
case _:
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
#p = l.get_window_extent()
|
|
101
|
+
#ax.annotate(f"RMSE:{rmse:.4f}", (p.p0[0], p.p1[1]), (p.p0[0], p.p1[1]-300), xycoords='figure pixels', fontsize=legend_fontsize)
|
|
102
|
+
else:
|
|
103
|
+
match legend_fontsize:
|
|
104
|
+
case int():
|
|
105
|
+
ax.legend(fontsize=legend_fontsize)
|
|
106
|
+
case None:
|
|
107
|
+
ax.legend()
|
|
108
|
+
case _:
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def check_output_mode(fig, plt, m, figure, fold=None):
|
|
113
|
+
match m:
|
|
114
|
+
case 'show':
|
|
115
|
+
plt.show()
|
|
116
|
+
case 'save':
|
|
117
|
+
fig_operation.savefig(fig, f"{figure}", fold)
|
|
118
|
+
plt.close()
|
|
119
|
+
case 'all':
|
|
120
|
+
fig_operation.savefig(fig, f"{figure}", fold)
|
|
121
|
+
plt.show()
|
|
122
|
+
plt.close()
|
|
123
|
+
case _:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def check_ticks_fontsize(ax, ticks_fontsize):
|
|
128
|
+
match ticks_fontsize:
|
|
129
|
+
case int():
|
|
130
|
+
ax.tick_params(axis='both', labelsize=ticks_fontsize)
|
|
131
|
+
case None:
|
|
132
|
+
pass
|
|
133
|
+
case _:
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def mode_1(data_dict, figure, **kwargs):
|
|
138
|
+
# init config
|
|
139
|
+
check_figsize(data_dict['figsize'])
|
|
140
|
+
|
|
141
|
+
fig, ax = plt.subplots()
|
|
142
|
+
|
|
143
|
+
# ticks config
|
|
144
|
+
check_int_ticks(ax, kwargs['int_ticks'])
|
|
145
|
+
|
|
146
|
+
# plot part
|
|
147
|
+
for label, data in data_dict['data'].items():
|
|
148
|
+
label = r"$\mathrm{ "+ label +" }$"
|
|
149
|
+
data = np.loadtxt(data)
|
|
150
|
+
x_slice, xlabel = next(iter(data_dict['x'].items()))
|
|
151
|
+
for y_slice, ylabel in data_dict['y'].items():
|
|
152
|
+
ax.plot(data[:, x_slice], data[:, y_slice], label=label)
|
|
153
|
+
|
|
154
|
+
# range config
|
|
155
|
+
check_axis_range(ax, x_range=data_dict['x_range'], y_range=data_dict['y_range'])
|
|
156
|
+
|
|
157
|
+
# axis label part
|
|
158
|
+
ax.set_xlabel(r"$\mathrm{ "+ xlabel +" }$")
|
|
159
|
+
ax.set_ylabel(r"$\mathrm{ "+ ylabel +" }$")
|
|
160
|
+
|
|
161
|
+
# h or v line
|
|
162
|
+
match data_dict['line']:
|
|
163
|
+
case _:
|
|
164
|
+
pass
|
|
165
|
+
|
|
166
|
+
# legend config
|
|
167
|
+
check_lenend_fontsize(ax, data_dict['legend_fontsize'])
|
|
168
|
+
|
|
169
|
+
# output part
|
|
170
|
+
check_output_mode(fig, plt, kwargs['m'], figure, data_dict['fold'])
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def mode_2(data_dict, figure, **kwargs):
|
|
174
|
+
# init config
|
|
175
|
+
check_figsize(data_dict['figsize'])
|
|
176
|
+
|
|
177
|
+
fig, ax = plt.subplots()
|
|
178
|
+
|
|
179
|
+
# ticks config
|
|
180
|
+
check_int_ticks(ax, kwargs['int_ticks'])
|
|
181
|
+
|
|
182
|
+
# plot part
|
|
183
|
+
ylabel, data = next(iter(data_dict['data'].items()))
|
|
184
|
+
data = np.loadtxt(data)
|
|
185
|
+
x_slice, xlabel = next(iter(data_dict['x'].items()))
|
|
186
|
+
for y_slice, label in data_dict['y'].items():
|
|
187
|
+
label = r"$\mathrm{ "+ label +" }$"
|
|
188
|
+
ax.plot(data[:, x_slice], data[:, y_slice], label=label)
|
|
189
|
+
|
|
190
|
+
# range config
|
|
191
|
+
check_axis_range(ax, x_range=data_dict['x_range'], y_range=data_dict['y_range'])
|
|
192
|
+
|
|
193
|
+
# axis label part
|
|
194
|
+
ax.set_xlabel(r"$\mathrm{ "+ xlabel +" }$")
|
|
195
|
+
ax.set_ylabel(r"$\mathrm{ "+ ylabel +" }$")
|
|
196
|
+
|
|
197
|
+
# legend config
|
|
198
|
+
check_lenend_fontsize(ax, data_dict['legend_fontsize'])
|
|
199
|
+
|
|
200
|
+
# output part
|
|
201
|
+
check_output_mode(fig, plt, kwargs['m'], figure, data_dict['fold'])
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def mode_error(data_dict, figure, **kwargs):
|
|
205
|
+
# init config
|
|
206
|
+
check_figsize(data_dict['figsize'])
|
|
207
|
+
|
|
208
|
+
fig, ax = plt.subplots(figsize=(4.8, 4.8))
|
|
209
|
+
|
|
210
|
+
# ticks config
|
|
211
|
+
check_int_ticks(ax, kwargs['int_ticks'])
|
|
212
|
+
|
|
213
|
+
# plot part
|
|
214
|
+
label, data = next(iter(data_dict['data'].items()))
|
|
215
|
+
data = np.loadtxt(data)
|
|
216
|
+
x_slice, xlabel = next(iter(data_dict['x'].items()))
|
|
217
|
+
for y_slice, ylabel in data_dict['y'].items():
|
|
218
|
+
label = r"$\mathrm{ "+ label +" }$"
|
|
219
|
+
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%.2f'))
|
|
220
|
+
ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.2f'))
|
|
221
|
+
ax.scatter(data[:, x_slice], data[:, y_slice], label=label)
|
|
222
|
+
data_diff = data[:, x_slice] - data[:, y_slice]
|
|
223
|
+
data_rmse = np.sqrt(np.average(data_diff*data_diff))
|
|
224
|
+
ax.axline((data[0, x_slice], data[0, x_slice]), slope=1, ls='--', c='black')
|
|
225
|
+
ax.set_xticks([])
|
|
226
|
+
ax.set_yticks([])
|
|
227
|
+
check_lenend_fontsize(ax, data_dict['ticks_fontsize'])
|
|
228
|
+
|
|
229
|
+
# range config
|
|
230
|
+
check_axis_range(ax, x_range=data_dict['x_range'], y_range=data_dict['y_range'])
|
|
231
|
+
|
|
232
|
+
# axis label part
|
|
233
|
+
ax.set_xlabel(r"$\mathrm{ "+ xlabel +" }$")
|
|
234
|
+
ax.set_ylabel(r"$\mathrm{ "+ ylabel +" }$")
|
|
235
|
+
|
|
236
|
+
lims = [np.min([ax.get_xlim(), ax.get_ylim()]), np.max([ax.get_xlim(), ax.get_ylim()])]
|
|
237
|
+
ax.text(lims[0]+(lims[1]-lims[0])*.6, lims[0]+(lims[1]-lims[0])*.1, f"RMSE: {data_rmse:.4f}", fontsize=data_dict['legend_fontsize'])
|
|
238
|
+
ax.set_xlim(lims)
|
|
239
|
+
ax.set_ylim(lims)
|
|
240
|
+
#ax.set_aspect('equal')
|
|
241
|
+
#plt.axis('equal')
|
|
242
|
+
# legend config
|
|
243
|
+
check_lenend_fontsize(ax, data_dict['legend_fontsize'], rmse=data_rmse)
|
|
244
|
+
|
|
245
|
+
# output part
|
|
246
|
+
check_output_mode(fig, plt, kwargs['m'], figure, data_dict['fold'])
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@click.command(name='plot')
|
|
250
|
+
@click.argument('yaml_file', type=click.Path(exists=True), nargs=-1)
|
|
251
|
+
@click.option('--int_ticks', help='set x ticks or y ticks with int, choices: x, y, a(all)', type=click.Choice(['x', 'y', 'a']))
|
|
252
|
+
@click.option('--error', help='set error mode', is_flag=True)
|
|
253
|
+
@click.option('-m', help='output mode: show, save, all, default is save', type=click.Choice(['show', 'save', 'all']), default='save')
|
|
254
|
+
def main(yaml_file, int_ticks, error, m):
|
|
255
|
+
kwargs = locals()
|
|
256
|
+
figure_dict = {}
|
|
257
|
+
for yaml_file in yaml_file:
|
|
258
|
+
yaml_dict = load_config(yaml_file)
|
|
259
|
+
figure_dict.update(yaml_dict)
|
|
260
|
+
|
|
261
|
+
for figure, data_dict in figure_dict.items():
|
|
262
|
+
check_data = len(data_dict['data'])
|
|
263
|
+
|
|
264
|
+
# mode error
|
|
265
|
+
if error:
|
|
266
|
+
mode = 'error'
|
|
267
|
+
mode_error(data_dict, figure, **kwargs)
|
|
268
|
+
|
|
269
|
+
# mode 1
|
|
270
|
+
elif check_data > 1:
|
|
271
|
+
if len(data_dict['y']) > 1:
|
|
272
|
+
print("wrong yaml structure")
|
|
273
|
+
exit(1)
|
|
274
|
+
mode = 1
|
|
275
|
+
mode_1(data_dict, figure, **kwargs)
|
|
276
|
+
|
|
277
|
+
# mode 2
|
|
278
|
+
elif check_data == 1:
|
|
279
|
+
mode = 2
|
|
280
|
+
mode_2(data_dict, figure, **kwargs)
|
|
281
|
+
|
|
282
|
+
else:
|
|
283
|
+
print("wrong yaml structure")
|
|
284
|
+
exit(1)
|
|
285
|
+
print(f"{figure} is done with mode {mode}")
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
if __name__ == '__main__':
|
|
289
|
+
main()
|
mdkits/cli/supercell.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
from ase.io import read
|
|
4
|
+
import argparse, os
|
|
5
|
+
import numpy as np
|
|
6
|
+
from ase.build import make_supercell
|
|
7
|
+
from util import (
|
|
8
|
+
structure_parsing,
|
|
9
|
+
encapsulated_ase,
|
|
10
|
+
cp2k_input_parsing
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def supercell(atom, x, y, z):
|
|
15
|
+
P = [ [x, 0, 0], [0, y, 0], [0, 0, z] ]
|
|
16
|
+
super_atom = make_supercell(atom, P)
|
|
17
|
+
return super_atom
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def parse_cell(s):
|
|
21
|
+
return [float(x) for x in s.replace(',', ' ').split()]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def super_cell(s):
|
|
25
|
+
super_cell = [int(x) for x in s.replace(',', ' ').split()]
|
|
26
|
+
leng = len(super_cell)
|
|
27
|
+
if leng == 2:
|
|
28
|
+
super_cell.append(1)
|
|
29
|
+
elif leng == 3:
|
|
30
|
+
pass
|
|
31
|
+
else:
|
|
32
|
+
print('wrong super cell size')
|
|
33
|
+
exit(1)
|
|
34
|
+
|
|
35
|
+
return super_cell
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def parse_argument():
|
|
39
|
+
parser = argparse.ArgumentParser(description='make a supercell')
|
|
40
|
+
|
|
41
|
+
parser.add_argument('input_file_name', type=str, help='input file name')
|
|
42
|
+
parser.add_argument('super', type=super_cell, help='super cell size, a,b,c')
|
|
43
|
+
parser.add_argument('-o', type=str, help='output file name, default is "super.cif"', default='super.cif')
|
|
44
|
+
parser.add_argument('--cp2k_input_file', type=str, help='input file name of cp2k, default is "input.inp"', default='input.inp')
|
|
45
|
+
parser.add_argument('--coord', help='coord format', action='store_true')
|
|
46
|
+
parser.add_argument('--cell', type=parse_cell, help='set cell, a list of lattice, --cell x,y,z or x,y,z,a,b,c')
|
|
47
|
+
|
|
48
|
+
return parser.parse_args()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
args = parse_argument()
|
|
53
|
+
if args.input_file_name == None:
|
|
54
|
+
print('give a xyz file')
|
|
55
|
+
sys.exit()
|
|
56
|
+
|
|
57
|
+
atom = encapsulated_ase.atoms_read_with_cell(args.input_file_name, cell=args.cell, coord_mode=args.coord)
|
|
58
|
+
atom.set_pbc(True)
|
|
59
|
+
atom.wrap()
|
|
60
|
+
super_atom = supercell(atom, args.super[0], args.super[1], args.super[2])
|
|
61
|
+
|
|
62
|
+
suffix = args.o.split('.')[-1]
|
|
63
|
+
if suffix == 'data':
|
|
64
|
+
super_atom.write(f'{args.o}', format='lammps-data', atom_style='atomic')
|
|
65
|
+
else:
|
|
66
|
+
super_atom.write(f'{args.o}')
|
|
67
|
+
|
|
68
|
+
print(os.path.abspath(args.o))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == '__main__':
|
|
72
|
+
main()
|
mdkits/cli/wrap.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from MDAnalysis import Universe
|
|
5
|
+
import MDAnalysis, click
|
|
6
|
+
from mdtool.util import (
|
|
7
|
+
arg_type,
|
|
8
|
+
os_operation,
|
|
9
|
+
cp2k_input_parsing
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.command(name='wrap')
|
|
14
|
+
@click.argument('filename', type=click.Path(exists=True), default=os_operation.default_file_name('*-pos-1.xyz', last=True))
|
|
15
|
+
@click.option('-o', type=str, help='output file name', default='wraped.xyz', show_default=True)
|
|
16
|
+
@click.option('--cell', type=arg_type.Cell, help='set cell from cp2k input file or a list of lattice: --cell x,y,z or x,y,z,a,b,c', default='input.inp', show_default=True)
|
|
17
|
+
def main(filename, o, cell):
|
|
18
|
+
"""
|
|
19
|
+
wrap the coordinates in a cell from a trajectory file
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
u = Universe(filename)
|
|
23
|
+
u.dimensions = cell
|
|
24
|
+
ag = u.select_atoms("all")
|
|
25
|
+
|
|
26
|
+
with MDAnalysis.Writer(o, ag.n_atoms) as W:
|
|
27
|
+
for ts in u.trajectory:
|
|
28
|
+
ag.wrap()
|
|
29
|
+
W.write(ag)
|
|
30
|
+
|
|
31
|
+
click.echo("\nwrap is done, output file {o} is:")
|
|
32
|
+
click.echo(os.path.abspath(o))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == '__main__':
|
|
36
|
+
main()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration center.
|
|
3
|
+
Use https://www.dynaconf.com/
|
|
4
|
+
"""""
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from dynaconf import Dynaconf
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
_base_dir = Path(__file__).parent.parent
|
|
13
|
+
|
|
14
|
+
_settings_files = [
|
|
15
|
+
# All config file will merge.
|
|
16
|
+
Path(__file__).parent / 'settings.yml', # Load default config.
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
# User configuration. It will be created automatically by the pip installer .
|
|
20
|
+
_external_files = [
|
|
21
|
+
Path(sys.prefix, 'etc', 'mdtool', 'settings.yml')
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
settings = Dynaconf(
|
|
26
|
+
# Set env `MDTOOL_FOO='bar'`,use `settings.FOO` .
|
|
27
|
+
envvar_prefix='MDTOOL',
|
|
28
|
+
settings_files=_settings_files, # load user configuration.
|
|
29
|
+
# environments=True, # Enable multi-level configuration,eg: default, development, production
|
|
30
|
+
load_dotenv=True, # Enable load .env
|
|
31
|
+
# env_switcher='MDTOOL_ENV',
|
|
32
|
+
lowercase_read=False, # If true, can't use `settings.foo`, but can only use `settings.FOO`
|
|
33
|
+
includes=_external_files, # Customs settings.
|
|
34
|
+
base_dir=_base_dir, # `settings.BASE_DIR`
|
|
35
|
+
)
|
mdkits/mdtool.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from mdtool.cli import (
|
|
3
|
+
convert,
|
|
4
|
+
wrap,
|
|
5
|
+
extract,
|
|
6
|
+
data,
|
|
7
|
+
plot,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group(name='cli')
|
|
12
|
+
@click.pass_context
|
|
13
|
+
@click.version_option()
|
|
14
|
+
def cli(ctx):
|
|
15
|
+
print(ctx)
|
|
16
|
+
"""tools for md or dft"""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
cli.add_command(convert.main)
|
|
21
|
+
cli.add_command(wrap.main)
|
|
22
|
+
cli.add_command(extract.main)
|
|
23
|
+
cli.add_command(data.main)
|
|
24
|
+
cli.add_command(plot.main)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if __name__ == '__main__':
|
|
28
|
+
cli()
|
mdkits/util/__init__.py
ADDED
|
File without changes
|
mdkits/util/arg_type.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import click, os
|
|
2
|
+
from . import cp2k_input_parsing
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CellType(click.ParamType):
|
|
6
|
+
name = "pbc cell type"
|
|
7
|
+
|
|
8
|
+
def convert(self, value, param, ctx):
|
|
9
|
+
if isinstance(value, str):
|
|
10
|
+
if ',' not in value:
|
|
11
|
+
cell = cp2k_input_parsing.parse_cell(value)
|
|
12
|
+
return cell
|
|
13
|
+
else:
|
|
14
|
+
cell = [float(x) for x in value.split(',')]
|
|
15
|
+
|
|
16
|
+
if len(cell) == 3:
|
|
17
|
+
click.echo(f"system cell: x = {cell[0]}, y = {cell[1]}, z = {cell[2]}, a = {90}\u00B0, b = {90}\u00B0, c = {90}\u00B0")
|
|
18
|
+
return cell + [90, 90, 90]
|
|
19
|
+
elif len(cell) == 6:
|
|
20
|
+
click.echo(f"system cell: x = {cell[0]}, y = {cell[1]}, z = {cell[2]}, a = {cell[3]}\u00B0, b = {cell[4]}\u00B0, c = {cell[5]}\u00B0")
|
|
21
|
+
return cell
|
|
22
|
+
else:
|
|
23
|
+
self.fail(f"{value} is not a valid cell parameter", param, ctx)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class FrameRangeType(click.ParamType):
|
|
27
|
+
name = "frame range"
|
|
28
|
+
def convert(self, value, param, ctx):
|
|
29
|
+
if isinstance(value, str):
|
|
30
|
+
parts = value.split(':')
|
|
31
|
+
|
|
32
|
+
range_list = [int(x) if x else None for x in parts]
|
|
33
|
+
|
|
34
|
+
if len(range_list) > 0 and len(range_list) <= 3:
|
|
35
|
+
return range_list
|
|
36
|
+
else:
|
|
37
|
+
self.fail(f"{value} is not a valid frame range", param, ctx)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
Cell = CellType()
|
|
41
|
+
FrameRange = FrameRangeType()
|