mlatom 2.0.1__py3.7.egg
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.
- EGG-INFO/PKG-INFO +145 -0
- EGG-INFO/SOURCES.txt +40 -0
- EGG-INFO/dependency_links.txt +1 -0
- EGG-INFO/native_libs.txt +1 -0
- EGG-INFO/not-zip-safe +1 -0
- EGG-INFO/requires.txt +2 -0
- EGG-INFO/scripts/MLatomF +12 -0
- EGG-INFO/scripts/mlatom +12 -0
- EGG-INFO/top_level.txt +1 -0
- MLatom/ML_NEA.py +2697 -0
- MLatom/MLatom.py +151 -0
- MLatom/MLatomF +0 -0
- MLatom/MLtasks.py +784 -0
- MLatom/__init__.py +0 -0
- MLatom/__pycache__/ML_NEA.cpython-37.pyc +0 -0
- MLatom/__pycache__/MLatom.cpython-37.pyc +0 -0
- MLatom/__pycache__/MLtasks.cpython-37.pyc +0 -0
- MLatom/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/__pycache__/args_class.cpython-37.pyc +0 -0
- MLatom/__pycache__/doc.cpython-37.pyc +0 -0
- MLatom/__pycache__/header.cpython-37.pyc +0 -0
- MLatom/__pycache__/interface_MLatomF.cpython-37.pyc +0 -0
- MLatom/__pycache__/sliceData.cpython-37.pyc +0 -0
- MLatom/__pycache__/stopper.cpython-37.pyc +0 -0
- MLatom/args_class.py +396 -0
- MLatom/cs.so +0 -0
- MLatom/doc.py +620 -0
- MLatom/header.py +64 -0
- MLatom/interface_MLatomF.py +87 -0
- MLatom/interfaces/DeePMDkit/DP_inference.py +20 -0
- MLatom/interfaces/DeePMDkit/__init__.py +0 -0
- MLatom/interfaces/DeePMDkit/__pycache__/DP_inference.cpython-37.pyc +0 -0
- MLatom/interfaces/DeePMDkit/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/DeePMDkit/__pycache__/interface_DeePMDkit.cpython-37.pyc +0 -0
- MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +327 -0
- MLatom/interfaces/DeePMDkit/template.json +70 -0
- MLatom/interfaces/GAP/__init__.py +0 -0
- MLatom/interfaces/GAP/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/GAP/__pycache__/interface_GAP.cpython-37.pyc +0 -0
- MLatom/interfaces/GAP/interface_GAP.py +415 -0
- MLatom/interfaces/PhysNet/PhysNet_predict.py +180 -0
- MLatom/interfaces/PhysNet/PhysNet_train.py +425 -0
- MLatom/interfaces/PhysNet/__init__.py +0 -0
- MLatom/interfaces/PhysNet/__pycache__/PhysNet_predict.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/__pycache__/PhysNet_train.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/__pycache__/interface_PhysNet.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/interface_PhysNet.py +270 -0
- MLatom/interfaces/TorchANI/TorchANI_predict.py +82 -0
- MLatom/interfaces/TorchANI/TorchANI_train.py +217 -0
- MLatom/interfaces/TorchANI/__init__.py +0 -0
- MLatom/interfaces/TorchANI/__pycache__/TorchANI_predict.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/__pycache__/TorchANI_train.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/__pycache__/interface_TorchANI.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/interface_TorchANI.py +323 -0
- MLatom/interfaces/__init__.py +0 -0
- MLatom/interfaces/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/__init__.py +0 -0
- MLatom/interfaces/sGDML/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/__pycache__/interface_sGDML.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/__pycache__/sgdml_dataset_from_extxyz.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/interface_sGDML.py +276 -0
- MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +199 -0
- MLatom/ref.json +23 -0
- MLatom/sliceData.py +334 -0
- MLatom/stopper.py +17 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/export/home/fcge/.linuxbrew/opt/python@3.8/bin/python3.8
|
|
2
|
+
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2018-2019 Stefan Chmiela
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
|
|
25
|
+
from __future__ import print_function
|
|
26
|
+
|
|
27
|
+
import os
|
|
28
|
+
import sys
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
from ase.io import read
|
|
32
|
+
except ImportError:
|
|
33
|
+
raise ImportError('Optional ASE dependency not found! Please run \'pip install sgdml[ase]\' to install it.')
|
|
34
|
+
|
|
35
|
+
import numpy as np
|
|
36
|
+
|
|
37
|
+
from sgdml import __version__
|
|
38
|
+
from sgdml.utils import io, ui
|
|
39
|
+
|
|
40
|
+
if sys.version[0] == '3':
|
|
41
|
+
raw_input = input
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Assumes that the atoms in each molecule are in the same order.
|
|
45
|
+
def read_nonstd_ext_xyz(f):
|
|
46
|
+
n_atoms = None
|
|
47
|
+
|
|
48
|
+
R, z, E, F = [], [], [], []
|
|
49
|
+
for i, line in enumerate(f):
|
|
50
|
+
line = line.strip()
|
|
51
|
+
if not n_atoms:
|
|
52
|
+
n_atoms = int(line)
|
|
53
|
+
print('Number atoms per geometry: {:,}'.format(n_atoms))
|
|
54
|
+
|
|
55
|
+
file_i, line_i = divmod(i, n_atoms + 2)
|
|
56
|
+
|
|
57
|
+
if line_i == 1:
|
|
58
|
+
try:
|
|
59
|
+
e = float(line)
|
|
60
|
+
except ValueError:
|
|
61
|
+
pass
|
|
62
|
+
else:
|
|
63
|
+
E.append(e)
|
|
64
|
+
|
|
65
|
+
cols = line.split()
|
|
66
|
+
if line_i >= 2:
|
|
67
|
+
R.append(list(map(float, cols[1:4])))
|
|
68
|
+
if file_i == 0: # first molecule
|
|
69
|
+
z.append(io._z_str_to_z_dict[cols[0]])
|
|
70
|
+
F.append(list(map(float, cols[4:7])))
|
|
71
|
+
|
|
72
|
+
if file_i % 1000 == 0:
|
|
73
|
+
sys.stdout.write('\rNumber geometries found so far: {:,}'.format(file_i))
|
|
74
|
+
sys.stdout.flush()
|
|
75
|
+
sys.stdout.write('\rNumber geometries found so far: {:,}'.format(file_i))
|
|
76
|
+
sys.stdout.flush()
|
|
77
|
+
print()
|
|
78
|
+
|
|
79
|
+
R = np.array(R).reshape(-1, n_atoms, 3)
|
|
80
|
+
z = np.array(z)
|
|
81
|
+
E = None if not E else np.array(E)
|
|
82
|
+
F = np.array(F).reshape(-1, n_atoms, 3)
|
|
83
|
+
|
|
84
|
+
if F.shape[0] != R.shape[0]:
|
|
85
|
+
sys.exit(
|
|
86
|
+
ui.color_str('[FAIL]', fore_color=ui.RED, bold=True)
|
|
87
|
+
+ ' Force labels are missing from dataset or are incomplete!'
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
f.close()
|
|
91
|
+
return (R, z, E, F)
|
|
92
|
+
|
|
93
|
+
def convert(dataset, overwrite=True):
|
|
94
|
+
|
|
95
|
+
name = os.path.splitext(os.path.basename(dataset))[0]
|
|
96
|
+
dataset_file_name = name + '.npz'
|
|
97
|
+
|
|
98
|
+
dataset_exists = os.path.isfile(dataset_file_name)
|
|
99
|
+
if dataset_exists and overwrite:
|
|
100
|
+
print(ui.color_str('[INFO]', bold=True) + ' Overwriting existing dataset file.')
|
|
101
|
+
if not dataset_exists or overwrite:
|
|
102
|
+
print('Writing dataset to \'{}\'...'.format(dataset_file_name))
|
|
103
|
+
else:
|
|
104
|
+
sys.exit(
|
|
105
|
+
ui.color_str('[FAIL]', fore_color=ui.RED, bold=True)
|
|
106
|
+
+ ' Dataset \'{}\' already exists.'.format(dataset_file_name)
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
mols = read(dataset, index=':')
|
|
110
|
+
|
|
111
|
+
lattice, R, z, E, F = None, None, None, None, None
|
|
112
|
+
|
|
113
|
+
calc = mols[0].get_calculator()
|
|
114
|
+
is_extxyz = calc is not None
|
|
115
|
+
if is_extxyz:
|
|
116
|
+
|
|
117
|
+
print("\rNumber geometries found: {:,}\n".format(len(mols)))
|
|
118
|
+
|
|
119
|
+
if 'forces' not in calc.results:
|
|
120
|
+
sys.exit(
|
|
121
|
+
ui.color_str('[FAIL]', fore_color=ui.RED, bold=True)
|
|
122
|
+
+ ' Forces are missing in the input file!'
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
lattice = np.array(mols[0].get_cell())
|
|
126
|
+
if not np.any(lattice):
|
|
127
|
+
print(
|
|
128
|
+
ui.color_str('[INFO]', bold=True)
|
|
129
|
+
+ ' No lattice vectors specified in extended XYZ file.'
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
Z = np.array([mol.get_atomic_numbers() for mol in mols])
|
|
133
|
+
all_z_the_same = (Z == Z[0]).all()
|
|
134
|
+
if not all_z_the_same:
|
|
135
|
+
sys.exit(
|
|
136
|
+
ui.color_str('[FAIL]', fore_color=ui.RED, bold=True)
|
|
137
|
+
+ ' Order of atoms changes accross dataset.'
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
lattice = np.array(mols[0].get_cell())
|
|
141
|
+
if not np.any(lattice): # all zeros
|
|
142
|
+
lattice = None
|
|
143
|
+
|
|
144
|
+
R = np.array([mol.get_positions() for mol in mols])
|
|
145
|
+
z = Z[0]
|
|
146
|
+
|
|
147
|
+
if 'Energy' in mols[0].info:
|
|
148
|
+
E = np.array([mol.info['Energy'] for mol in mols])
|
|
149
|
+
if 'energy' in mols[0].info:
|
|
150
|
+
E = np.array([mol.info['energy'] for mol in mols])
|
|
151
|
+
F = np.array([mol.get_forces() for mol in mols])
|
|
152
|
+
|
|
153
|
+
else: # legacy non-standard XYZ format
|
|
154
|
+
|
|
155
|
+
with open(dataset) as f:
|
|
156
|
+
R, z, E, F = read_nonstd_ext_xyz(f)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# Base variables contained in every model file.
|
|
160
|
+
base_vars = {
|
|
161
|
+
'type': 'd',
|
|
162
|
+
'code_version': __version__,
|
|
163
|
+
'name': name,
|
|
164
|
+
'theory': 'unknown',
|
|
165
|
+
'R': R,
|
|
166
|
+
'z': z,
|
|
167
|
+
'F': F,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
base_vars['F_min'], base_vars['F_max'] = np.min(F.ravel()), np.max(F.ravel())
|
|
171
|
+
base_vars['F_mean'], base_vars['F_var'] = np.mean(F.ravel()), np.var(F.ravel())
|
|
172
|
+
|
|
173
|
+
# print('Please provide a description of the length unit used in your input file, e.g. \'Ang\' or \'au\': ')
|
|
174
|
+
# print('Note: This string will be stored in the dataset file and passed on to models files for later reference.')
|
|
175
|
+
# r_unit = raw_input('> ').strip()
|
|
176
|
+
r_unit = 'Ang'
|
|
177
|
+
if r_unit != '':
|
|
178
|
+
base_vars['r_unit'] = r_unit
|
|
179
|
+
|
|
180
|
+
# print('Please provide a description of the energy unit used in your input file, e.g. \'kcal/mol\' or \'eV\': ')
|
|
181
|
+
# print('Note: This string will be stored in the dataset file and passed on to models files for later reference.')
|
|
182
|
+
# e_unit = raw_input('> ').strip()
|
|
183
|
+
e_unit = 'kcal/mol'
|
|
184
|
+
if e_unit != '':
|
|
185
|
+
base_vars['e_unit'] = e_unit
|
|
186
|
+
|
|
187
|
+
if E is not None:
|
|
188
|
+
base_vars['E'] = E
|
|
189
|
+
base_vars['E_min'], base_vars['E_max'] = np.min(E), np.max(E)
|
|
190
|
+
base_vars['E_mean'], base_vars['E_var'] = np.mean(E), np.var(E)
|
|
191
|
+
else:
|
|
192
|
+
print(ui.color_str('[INFO]', bold=True) + ' No energy labels found in dataset.')
|
|
193
|
+
|
|
194
|
+
if lattice is not None:
|
|
195
|
+
base_vars['lattice'] = lattice
|
|
196
|
+
|
|
197
|
+
base_vars['md5'] = io.dataset_md5(base_vars)
|
|
198
|
+
np.savez_compressed(dataset_file_name, **base_vars)
|
|
199
|
+
print(ui.color_str('[DONE]', fore_color=ui.GREEN, bold=True))
|
MLatom/ref.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"JCP2017_MLCH3Cl": "P. O. Dral, A. Owens, S. N. Yurchenko, W. Thiel,\nJ. Chem. Phys. 2017, 146, 244108",
|
|
3
|
+
"JCTC2015_DeltaLearning": "R. Ramakrishnan, P. O. Dral, M. Rupp, O. A. von Lilienfeld,\nJ. Chem. Theory Comput. 2015, 11, 2087",
|
|
4
|
+
"CM": "M. Rupp, A. Tkatchenko, K.\u2010R. M\u00fcller, O. A. von Lilienfeld,\nPhys. Rev. Lett. 2012, 108, 058301\n\nK. Hansen, G. Montavon, F. Biegler, S. Fazli, M. Rupp,\nM. Scheffler, O. A. von Lilienfeld, A. Tkatchenko, K.\u2010R. M\u00fcller,\nJ. Chem. Theory Comput. 2013, 9, 3404",
|
|
5
|
+
"sGDMLprog": "S. Chmiela, H. E. Sauceda, I. Poltavsky, K.-R. M\u00fcller, A. Tkatchenko,\nComput. Phys. Commun. 2019, 240, 38",
|
|
6
|
+
"sGDMLmodel": "S. Chmiela, H. E. Sauceda, K.-R. M\u00fcller, A. Tkatchenko,\nNat. Commun. 2018, 9, 3887",
|
|
7
|
+
"GDMLmodel": "S. Chmiela, A. Tkatchenko, H. E. Sauceda, I. Poltavsky, K. T. Sch\u00fctt, K.-R. M\u00fcller,\nSci. Adv. 2017, 3, e1603015",
|
|
8
|
+
"hyperopt": "J. Bergstra, D. Yamins, D. D. Cox, Making a Science of Model Search:\nHyperparameter Optimization in Hundreds of Dimensions for Vision\nArchitectures.\nProceedings of the 30th International Conference on Machine Learning\n(ICML 2013), Vol. 28, JMLR.org, Atlanta, GA, USA, 2013, pp. I-115",
|
|
9
|
+
"TPE": "J. Bergstra, R. Bardenet, Y. Bengio, B. Kegl,\nAlgorithms for Hyper-Parameter Optimization.\nIn Advances in Neural Information Processing Systems, Vol. 24.\nEds.: J. Shawe-Taylor, R. Zemel, P. Bartlett, F. Pereira, K. Q. Weinberger,\nCuran Associates, Inc., 2011",
|
|
10
|
+
"ML-NEA": "B.-X. Xue, M. Barbatti, P. O. Dral, J. Phys. Chem. A 2020, 124, 7199",
|
|
11
|
+
"NEA": "R. Crespo-Otero, M. Barbatti, Theor. Chem. Acc. 2012, 131, 1237",
|
|
12
|
+
"Wigner": "Schinke, R. Photodissociation Dynamics: Spectroscopy and Fragmentation of\nSmall Polyatomic Molecules; Cambridge University Press: Cambridge, U.K., 1995",
|
|
13
|
+
"NEWTON-X": "M. Barbatti, G. Granucci, M. Ruckenbauer, F. Plasser,\nR. Crespo-Otero,\nJ. Pittner, M. Persico, H. Lischka,\nNEWTON-X:\na package for Newtonian dynamics close to the crossing seam,\nversion 2.2, www.newtonx.org, 2017\n\nM. Barbatti, M. Ruckenbauer, F. Plasser, J. Pittner, G. Granucci,\nM. Persico, H. Lischka, WIREs: Comp. Mol. Sci. 2014, 4, 26",
|
|
14
|
+
"PhysNet": "O. T. Unke, M. Meuwly, J. Chem. Theory Comput. 2019, 15, 3678",
|
|
15
|
+
"TorchANI": "X. Gao, F. Ramezanghorbani, O. Isayev, J. S. Smith, A. E. Roitberg,\nJ. Chem. Inf. Model. 2020, 60, 3408",
|
|
16
|
+
"ANI": "J. S. Smith, O. Isayev, A. E. Roitberg, Chem. Sci. 2017, 8, 3192",
|
|
17
|
+
"DeePMD-kit": "H. Wang, L. Zhang, J. Han, W. E, Comput. Phys. Commun. 2018, 228, 178",
|
|
18
|
+
"DPMD": "L. Hang, J. Han, H. Wang, R. Car, W. E, Phys. Rev. Lett. 2018, 120, 143001",
|
|
19
|
+
"DeepPot-SE": "L.F. Zhang, J.Q. Han, H. Wang, W.A. Saidi, R. Car, W.N. E,\nAdv. Neural. Inf. Process. Syst. 2018, 31, 4436",
|
|
20
|
+
"GAP": "A. P. Bartok, M. C. Payne, R. Konor, G. Csanyi,\nPhys. Rev. Lett. 2010, 104, 136403",
|
|
21
|
+
"SOAP": "A. P. Bartok, R. Konor, G. Csanyi,\nPhys. Rev. B 2013, 87, 184115"
|
|
22
|
+
}
|
|
23
|
+
|
MLatom/sliceData.py
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
'''
|
|
3
|
+
!---------------------------------------------------------------------------!
|
|
4
|
+
! sliceData: Scripts for working with sliced data !
|
|
5
|
+
! Implementations by: Pavlo O. Dral !
|
|
6
|
+
!---------------------------------------------------------------------------!
|
|
7
|
+
'''
|
|
8
|
+
|
|
9
|
+
import sys, os, time, operator, re, copy, subprocess
|
|
10
|
+
import stopper
|
|
11
|
+
import interface_MLatomF
|
|
12
|
+
|
|
13
|
+
class sliceDataCls(object):
|
|
14
|
+
eqX = [] # Equilibrium input vector
|
|
15
|
+
xx = [] # List of molecular descriptors
|
|
16
|
+
nall = 0 # Number of molecular descriptors
|
|
17
|
+
Ds = {} # Dictionary {index i: distance to eqX}
|
|
18
|
+
sorted_indices = [] # Indices of input vectors sorted by their distance to the equilibrium structure
|
|
19
|
+
|
|
20
|
+
def __init__(self, argsSD = sys.argv[1:]):
|
|
21
|
+
starttime = time.time()
|
|
22
|
+
|
|
23
|
+
print(' %s ' % ('='*78))
|
|
24
|
+
print(time.strftime(" sliceData started on %d.%m.%Y at %H:%M:%S", time.localtime()))
|
|
25
|
+
for arg in argsSD:
|
|
26
|
+
flagmatch = re.search('nthreads', arg.lower(), flags=re.UNICODE | re.MULTILINE | re.DOTALL | re.IGNORECASE)
|
|
27
|
+
if flagmatch:
|
|
28
|
+
argsSD.remove(arg)
|
|
29
|
+
args.parse(argsSD)
|
|
30
|
+
print(' with the following options:')
|
|
31
|
+
argsstr = ' '
|
|
32
|
+
for arg in argsSD:
|
|
33
|
+
argsstr += arg + ' '
|
|
34
|
+
print(argsstr.rstrip())
|
|
35
|
+
print(' %s ' % ('='*78))
|
|
36
|
+
sys.stdout.flush()
|
|
37
|
+
|
|
38
|
+
# Perform requested task
|
|
39
|
+
if args.slicedata:
|
|
40
|
+
self.getEqX(args.eqXfileIn)
|
|
41
|
+
self.getX(args.XfileIn)
|
|
42
|
+
self.sortByDistance()
|
|
43
|
+
self.slicedata()
|
|
44
|
+
if args.sampleFromSlices:
|
|
45
|
+
self.sampleFromSlices()
|
|
46
|
+
if args.mergeSlices:
|
|
47
|
+
self.mergeSlices()
|
|
48
|
+
|
|
49
|
+
endtime = time.time()
|
|
50
|
+
wallclock = endtime - starttime
|
|
51
|
+
print(' %s ' % ('='*78))
|
|
52
|
+
print(' Wall-clock time: %.2f s (%.2f min, %.2f hours)\n' % (wallclock, wallclock / 60.0, wallclock / 3600.0))
|
|
53
|
+
print(time.strftime(" sliceData terminated on %d.%m.%Y at %H:%M:%S", time.localtime()))
|
|
54
|
+
print(' %s ' % ('='*78))
|
|
55
|
+
sys.stdout.flush()
|
|
56
|
+
|
|
57
|
+
def getEqX(self, xfilename):
|
|
58
|
+
self.eqX = []
|
|
59
|
+
with open(xfilename, 'r') as xf:
|
|
60
|
+
for line in xf:
|
|
61
|
+
self.eqX = [float(x) for x in line.split()]
|
|
62
|
+
break
|
|
63
|
+
|
|
64
|
+
def getX(self, xfilename):
|
|
65
|
+
self.xx = []
|
|
66
|
+
with open(xfilename, 'r') as xf:
|
|
67
|
+
for line in xf:
|
|
68
|
+
self.xx.append([float(x) for x in line.split()])
|
|
69
|
+
self.nall = len(self.xx)
|
|
70
|
+
|
|
71
|
+
def sortByDistance(self):
|
|
72
|
+
for ii in range(1, self.nall+1):
|
|
73
|
+
self.Ds[ii] = self.distance(self.eqX, self.xx[ii-1])
|
|
74
|
+
self.sorted_indices = [ind for (ind, distance) in sorted(list(self.Ds.items()), key=operator.itemgetter(1))]
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def distance(cls, xi, xj):
|
|
78
|
+
# Returns distance between xi and xj descriptors (they must be of the same length)
|
|
79
|
+
dd = 0.0
|
|
80
|
+
for ii in range(len(xi)):
|
|
81
|
+
dd += (xi[ii] - xj[ii]) ** 2
|
|
82
|
+
dd = dd ** 0.5
|
|
83
|
+
return dd
|
|
84
|
+
|
|
85
|
+
def slicedata(self):
|
|
86
|
+
self.print_ordered_set( nstart = 1, nend = self.nall,
|
|
87
|
+
xfilename = args.XfileIn,
|
|
88
|
+
xorderedname = 'xordered.dat',
|
|
89
|
+
indorderedname = 'indices_ordered.dat',
|
|
90
|
+
distordname = 'distances_ordered.dat')
|
|
91
|
+
|
|
92
|
+
for ii in range(1, args.nslices + 1):
|
|
93
|
+
ninslice = self.nall // args.nslices
|
|
94
|
+
nstart = ninslice * (ii - 1) + 1
|
|
95
|
+
nend = ninslice * ii
|
|
96
|
+
if ii == args.nslices:
|
|
97
|
+
nend = self.nall # The last slice takes the rest
|
|
98
|
+
os.system('mkdir slice%d' % ii)
|
|
99
|
+
self.print_ordered_set( nstart = nstart, nend = nend,
|
|
100
|
+
xfilename = args.XfileIn,
|
|
101
|
+
xorderedname = 'slice%d/x.dat' % ii,
|
|
102
|
+
indorderedname = 'slice%d/slice_indices.dat' % ii,
|
|
103
|
+
distordname = 'slice%d/slice_distances.dat' % ii)
|
|
104
|
+
|
|
105
|
+
def print_ordered_set(self, nstart = 1, nend = 'all',
|
|
106
|
+
xfilename = 'x.dat',
|
|
107
|
+
xorderedname = 'xordered.dat',
|
|
108
|
+
indorderedname = 'indices_ordered.dat',
|
|
109
|
+
distordname = 'distances_ordered.dat'):
|
|
110
|
+
xlines = open(xfilename, 'r').readlines()
|
|
111
|
+
if nend == 'all':
|
|
112
|
+
nend = self.nall
|
|
113
|
+
|
|
114
|
+
with open(xorderedname, 'w') as xof, open(indorderedname, 'w') as indof:
|
|
115
|
+
for nn in range(nstart, nend + 1):
|
|
116
|
+
ii = self.sorted_indices[nn - 1]
|
|
117
|
+
indof.writelines('%d\n' % ii)
|
|
118
|
+
xof.writelines(xlines[ii-1])
|
|
119
|
+
del xlines
|
|
120
|
+
|
|
121
|
+
with open(distordname, 'w') as dof:
|
|
122
|
+
for nn in range(nstart, nend + 1):
|
|
123
|
+
ii = self.sorted_indices[nn - 1]
|
|
124
|
+
dof.writelines('%20.12f\n' % self.Ds[ii])
|
|
125
|
+
|
|
126
|
+
def sampleFromSlices(self):
|
|
127
|
+
for ii in range(1, args.nslices + 1):
|
|
128
|
+
ninslice = args.Ntrain // args.nslices
|
|
129
|
+
nstart = ninslice * (ii - 1) + 1
|
|
130
|
+
nend = ninslice * ii
|
|
131
|
+
if ii == args.nslices:
|
|
132
|
+
ninslice += args.Ntrain - nend
|
|
133
|
+
nend = args.Ntrain # The last slice takes the rest
|
|
134
|
+
argsloc = ['sample'] + args.argsSD + ['XfileIn=x.dat'] + ['Ntrain=%d' % ninslice] + ['iTrainOut=itrain.dat']
|
|
135
|
+
if True: # Local calculations
|
|
136
|
+
interface_MLatomF.ifMLatomCls.run(argsloc, cwdpath='slice%d' % ii)
|
|
137
|
+
else: # Submission to queue
|
|
138
|
+
with open('slice%d/sample.inp' % ii, 'w') as finp:
|
|
139
|
+
for arg in argsloc:
|
|
140
|
+
finp.writelines('%s\n' % arg)
|
|
141
|
+
#cd os.system('cd slice%d ; bsub < ../mlatom.bsub' % ii) # To submit the job with bsub
|
|
142
|
+
|
|
143
|
+
def mergeSlices(self):
|
|
144
|
+
Ntrain = args.Ntrain
|
|
145
|
+
|
|
146
|
+
sampled_slices = []
|
|
147
|
+
unsampled_slices = []
|
|
148
|
+
for islice in range(1,args.nslices+1):
|
|
149
|
+
sampled_slice = []
|
|
150
|
+
unsampled_slice = []
|
|
151
|
+
ordindices = [] # This indices refer to the lines in the original files x.dat and y.dat corresponding to the lines in the sorted files x.dat and y.dat before slicing
|
|
152
|
+
with open('slice%d/slice_indices.dat' % islice, 'r') as ff:
|
|
153
|
+
for line in ff:
|
|
154
|
+
ordindices.append(int(line))
|
|
155
|
+
trindices = [] # This indices refer to the lines in the sorted files x.dat and y.dat corresponding to the lines in the files x.dat and y.dat used for prediction
|
|
156
|
+
with open('slice%d/itrain.dat' % islice, 'r') as ff:
|
|
157
|
+
for line in ff:
|
|
158
|
+
trindices.append(int(line))
|
|
159
|
+
for jj in trindices:
|
|
160
|
+
sampled_slice.append(ordindices[jj - 1])
|
|
161
|
+
for jj in ordindices:
|
|
162
|
+
if not jj in sampled_slice:
|
|
163
|
+
unsampled_slice.append(jj)
|
|
164
|
+
sampled_slices.append(sampled_slice)
|
|
165
|
+
unsampled_slices.append(unsampled_slice)
|
|
166
|
+
|
|
167
|
+
slicesSizes = [len(ss) for ss in sampled_slices]
|
|
168
|
+
Nsmpl = sum(slicesSizes)
|
|
169
|
+
if Nsmpl < Ntrain:
|
|
170
|
+
stopper.stopMLatom('Sampled less points than requested for training set')
|
|
171
|
+
unslicesSizes = [len(ss) for ss in unsampled_slices]
|
|
172
|
+
Nunsmpl = sum(unslicesSizes)
|
|
173
|
+
|
|
174
|
+
# Sample data points into subsets
|
|
175
|
+
with open('itrain.dat', 'w') as fitrain, open('itest.dat', 'w') as fitest, open('isubtrain.dat', 'w') as fisubtrain, open('ivalidate.dat', 'w') as fivalidate:
|
|
176
|
+
Nsubtrain = int(Ntrain * 0.80)
|
|
177
|
+
counter = 0
|
|
178
|
+
exitWhileLoop = False
|
|
179
|
+
islc = [-1 for ss in range(args.nslices)]
|
|
180
|
+
while counter < Nsmpl:
|
|
181
|
+
for islice in range(args.nslices):
|
|
182
|
+
islc[islice] += 1
|
|
183
|
+
if islc[islice] < slicesSizes[islice]:
|
|
184
|
+
counter += 1
|
|
185
|
+
if counter <= Ntrain:
|
|
186
|
+
fitrain.writelines('%d\n' % sampled_slices[islice][islc[islice]])
|
|
187
|
+
if counter <= Nsubtrain:
|
|
188
|
+
fisubtrain.writelines('%d\n' % sampled_slices[islice][islc[islice]])
|
|
189
|
+
else:
|
|
190
|
+
fivalidate.writelines('%d\n' % sampled_slices[islice][islc[islice]])
|
|
191
|
+
elif counter <= Nsmpl:
|
|
192
|
+
fitest.writelines('%d\n' % sampled_slices[islice][islc[islice]])
|
|
193
|
+
else:
|
|
194
|
+
print('breaking the loop')
|
|
195
|
+
exitWhileLoop = True
|
|
196
|
+
break
|
|
197
|
+
if exitWhileLoop:
|
|
198
|
+
break
|
|
199
|
+
counter = 0
|
|
200
|
+
exitWhileLoop = False
|
|
201
|
+
islc = [-1 for ss in range(args.nslices)]
|
|
202
|
+
while counter < Nunsmpl:
|
|
203
|
+
for islice in range(args.nslices):
|
|
204
|
+
islc[islice] += 1
|
|
205
|
+
if islc[islice] < unslicesSizes[islice]:
|
|
206
|
+
counter += 1
|
|
207
|
+
if counter <= Nunsmpl:
|
|
208
|
+
fitest.writelines('%d\n' % unsampled_slices[islice][islc[islice]])
|
|
209
|
+
else:
|
|
210
|
+
print('breaking the loop')
|
|
211
|
+
exitWhileLoop = True
|
|
212
|
+
break
|
|
213
|
+
if exitWhileLoop:
|
|
214
|
+
break
|
|
215
|
+
|
|
216
|
+
class args(object):
|
|
217
|
+
# Default values:
|
|
218
|
+
slicedata = False
|
|
219
|
+
sampleFromSlices = False
|
|
220
|
+
mergeSlices = False
|
|
221
|
+
nslices = 3
|
|
222
|
+
XfileIn = None
|
|
223
|
+
eqXfileIn = None
|
|
224
|
+
Ntrain = None
|
|
225
|
+
# Only this Python program options
|
|
226
|
+
argspy = ['slice',
|
|
227
|
+
'sampleFromSlices',
|
|
228
|
+
'mergeSlices',
|
|
229
|
+
'nslices=*',
|
|
230
|
+
'eqXfileIn=*',
|
|
231
|
+
'Ntrain=*']
|
|
232
|
+
# Only options of other programs
|
|
233
|
+
argsSD = []
|
|
234
|
+
|
|
235
|
+
@classmethod
|
|
236
|
+
def parse(cls, argsraw):
|
|
237
|
+
if len(argsraw) == 0:
|
|
238
|
+
printHelp()
|
|
239
|
+
stopper.stopMLatom('At least one option should be provided')
|
|
240
|
+
argslower = [arg.lower() for arg in argsraw]
|
|
241
|
+
if ('help' in argslower
|
|
242
|
+
or '-help' in argslower
|
|
243
|
+
or '-h' in argslower
|
|
244
|
+
or '--help' in argslower):
|
|
245
|
+
printHelp()
|
|
246
|
+
stopper.stopMLatom('')
|
|
247
|
+
|
|
248
|
+
cls.argsSD = copy.deepcopy(argsraw)
|
|
249
|
+
for arg in argsraw:
|
|
250
|
+
if (arg.lower() == 'help'
|
|
251
|
+
or arg.lower() == '-help'
|
|
252
|
+
or arg.lower() == '-h'
|
|
253
|
+
or arg.lower() == '--help'):
|
|
254
|
+
printHelp()
|
|
255
|
+
stopper.stopMLatom('')
|
|
256
|
+
elif arg.lower() == 'slice'.lower():
|
|
257
|
+
cls.slicedata = True
|
|
258
|
+
elif arg.lower() == 'sampleFromSlices'.lower():
|
|
259
|
+
cls.sampleFromSlices = True
|
|
260
|
+
elif arg.lower() == 'mergeSlices'.lower():
|
|
261
|
+
cls.mergeSlices = True
|
|
262
|
+
elif arg.lower()[0:len('nslices=')] == 'nslices='.lower():
|
|
263
|
+
cls.nslices = int(arg[len('nslices='):])
|
|
264
|
+
elif arg.lower()[0:len('XfileIn=')] == 'XfileIn='.lower():
|
|
265
|
+
cls.XfileIn = arg[len('XfileIn='):]
|
|
266
|
+
elif arg.lower()[0:len('Ntrain=')] == 'Ntrain='.lower():
|
|
267
|
+
cls.Ntrain = int(arg[len('Ntrain='):])
|
|
268
|
+
elif arg.lower()[0:len('eqXfileIn=')] == 'eqXfileIn='.lower():
|
|
269
|
+
cls.eqXfileIn = arg[len('eqXfileIn='):]
|
|
270
|
+
#else: # Other options are usually passed over to the interfaced programs
|
|
271
|
+
# printHelp()
|
|
272
|
+
# stopper.stopMLatom('Option "%s" is not recognized' % arg)
|
|
273
|
+
for argpy in cls.argspy:
|
|
274
|
+
flagmatch = re.search(argpy, arg.lower(), flags=re.UNICODE | re.MULTILINE | re.DOTALL | re.IGNORECASE)
|
|
275
|
+
if flagmatch:
|
|
276
|
+
cls.argsSD.remove(arg)
|
|
277
|
+
break
|
|
278
|
+
cls.checkArgs()
|
|
279
|
+
|
|
280
|
+
@classmethod
|
|
281
|
+
def checkArgs(cls):
|
|
282
|
+
Ntasks = (cls.slicedata + cls.sampleFromSlices + cls.mergeSlices)
|
|
283
|
+
if Ntasks == 0:
|
|
284
|
+
printHelp()
|
|
285
|
+
stopper.stopMLatom('At least one task should be requested')
|
|
286
|
+
if cls.slicedata:
|
|
287
|
+
if cls.XfileIn == None:
|
|
288
|
+
printHelp()
|
|
289
|
+
stopper.stopMLatom('Provide correct file name with XfileIn option')
|
|
290
|
+
if cls.eqXfileIn == None:
|
|
291
|
+
printHelp()
|
|
292
|
+
stopper.stopMLatom('Provide correct file name with eqXfileIn option')
|
|
293
|
+
if cls.sampleFromSlices:
|
|
294
|
+
if cls.Ntrain == None:
|
|
295
|
+
printHelp()
|
|
296
|
+
stopper.stopMLatom('Provide the number of training points with Ntrain option')
|
|
297
|
+
if cls.mergeSlices:
|
|
298
|
+
if cls.Ntrain == None:
|
|
299
|
+
printHelp()
|
|
300
|
+
stopper.stopMLatom('Provide the number of training points with Ntrain option')
|
|
301
|
+
|
|
302
|
+
def printHelp():
|
|
303
|
+
if __name__ == '__main__':
|
|
304
|
+
print('''
|
|
305
|
+
!---------------------------------------------------------------------------!
|
|
306
|
+
! !
|
|
307
|
+
! sliceData: Scripts for working with sliced data !
|
|
308
|
+
! !
|
|
309
|
+
!---------------------------------------------------------------------------!
|
|
310
|
+
|
|
311
|
+
Usage:
|
|
312
|
+
sliceData.py [options]
|
|
313
|
+
|
|
314
|
+
Options:
|
|
315
|
+
help print this help and exit
|
|
316
|
+
|
|
317
|
+
Tasks for sliceData.py. At least one task should be requested.
|
|
318
|
+
''')
|
|
319
|
+
helpText = ''' slice slice data set
|
|
320
|
+
nslices=N number of slices [default = 3]
|
|
321
|
+
XfileIn=S file S with input vectors X
|
|
322
|
+
eqXfileIn=S file S with input vector for the equilibrium geometry
|
|
323
|
+
sampleFromSlices sample from each slice
|
|
324
|
+
nslices=N number N of slices [default = 3]
|
|
325
|
+
Ntrain=N total integer number N of training points from all slices
|
|
326
|
+
mergeSlices merges indices from slices [see sliceData help]
|
|
327
|
+
nslices=N number N of slices [default = 3]
|
|
328
|
+
Ntrain=N total integer number N of training points from all slices
|
|
329
|
+
'''
|
|
330
|
+
print(helpText)
|
|
331
|
+
|
|
332
|
+
if __name__ == '__main__':
|
|
333
|
+
print(__doc__)
|
|
334
|
+
sliceDataCls()
|
MLatom/stopper.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
'''
|
|
3
|
+
!---------------------------------------------------------------------------!
|
|
4
|
+
! stopper: Stopping MLatom and writing an error message !
|
|
5
|
+
! Implementations by: Pavlo O. Dral !
|
|
6
|
+
!---------------------------------------------------------------------------!
|
|
7
|
+
'''
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
def stopMLatom(errorMsg):
|
|
12
|
+
if errorMsg != '':
|
|
13
|
+
print(' <!> %s <!>' % errorMsg)
|
|
14
|
+
sys.exit()
|
|
15
|
+
|
|
16
|
+
if __name__ == '__main__':
|
|
17
|
+
stopMLatom('Call the main program!')
|