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.
Files changed (67) hide show
  1. EGG-INFO/PKG-INFO +145 -0
  2. EGG-INFO/SOURCES.txt +40 -0
  3. EGG-INFO/dependency_links.txt +1 -0
  4. EGG-INFO/native_libs.txt +1 -0
  5. EGG-INFO/not-zip-safe +1 -0
  6. EGG-INFO/requires.txt +2 -0
  7. EGG-INFO/scripts/MLatomF +12 -0
  8. EGG-INFO/scripts/mlatom +12 -0
  9. EGG-INFO/top_level.txt +1 -0
  10. MLatom/ML_NEA.py +2697 -0
  11. MLatom/MLatom.py +151 -0
  12. MLatom/MLatomF +0 -0
  13. MLatom/MLtasks.py +784 -0
  14. MLatom/__init__.py +0 -0
  15. MLatom/__pycache__/ML_NEA.cpython-37.pyc +0 -0
  16. MLatom/__pycache__/MLatom.cpython-37.pyc +0 -0
  17. MLatom/__pycache__/MLtasks.cpython-37.pyc +0 -0
  18. MLatom/__pycache__/__init__.cpython-37.pyc +0 -0
  19. MLatom/__pycache__/args_class.cpython-37.pyc +0 -0
  20. MLatom/__pycache__/doc.cpython-37.pyc +0 -0
  21. MLatom/__pycache__/header.cpython-37.pyc +0 -0
  22. MLatom/__pycache__/interface_MLatomF.cpython-37.pyc +0 -0
  23. MLatom/__pycache__/sliceData.cpython-37.pyc +0 -0
  24. MLatom/__pycache__/stopper.cpython-37.pyc +0 -0
  25. MLatom/args_class.py +396 -0
  26. MLatom/cs.so +0 -0
  27. MLatom/doc.py +620 -0
  28. MLatom/header.py +64 -0
  29. MLatom/interface_MLatomF.py +87 -0
  30. MLatom/interfaces/DeePMDkit/DP_inference.py +20 -0
  31. MLatom/interfaces/DeePMDkit/__init__.py +0 -0
  32. MLatom/interfaces/DeePMDkit/__pycache__/DP_inference.cpython-37.pyc +0 -0
  33. MLatom/interfaces/DeePMDkit/__pycache__/__init__.cpython-37.pyc +0 -0
  34. MLatom/interfaces/DeePMDkit/__pycache__/interface_DeePMDkit.cpython-37.pyc +0 -0
  35. MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +327 -0
  36. MLatom/interfaces/DeePMDkit/template.json +70 -0
  37. MLatom/interfaces/GAP/__init__.py +0 -0
  38. MLatom/interfaces/GAP/__pycache__/__init__.cpython-37.pyc +0 -0
  39. MLatom/interfaces/GAP/__pycache__/interface_GAP.cpython-37.pyc +0 -0
  40. MLatom/interfaces/GAP/interface_GAP.py +415 -0
  41. MLatom/interfaces/PhysNet/PhysNet_predict.py +180 -0
  42. MLatom/interfaces/PhysNet/PhysNet_train.py +425 -0
  43. MLatom/interfaces/PhysNet/__init__.py +0 -0
  44. MLatom/interfaces/PhysNet/__pycache__/PhysNet_predict.cpython-37.pyc +0 -0
  45. MLatom/interfaces/PhysNet/__pycache__/PhysNet_train.cpython-37.pyc +0 -0
  46. MLatom/interfaces/PhysNet/__pycache__/__init__.cpython-37.pyc +0 -0
  47. MLatom/interfaces/PhysNet/__pycache__/interface_PhysNet.cpython-37.pyc +0 -0
  48. MLatom/interfaces/PhysNet/interface_PhysNet.py +270 -0
  49. MLatom/interfaces/TorchANI/TorchANI_predict.py +82 -0
  50. MLatom/interfaces/TorchANI/TorchANI_train.py +217 -0
  51. MLatom/interfaces/TorchANI/__init__.py +0 -0
  52. MLatom/interfaces/TorchANI/__pycache__/TorchANI_predict.cpython-37.pyc +0 -0
  53. MLatom/interfaces/TorchANI/__pycache__/TorchANI_train.cpython-37.pyc +0 -0
  54. MLatom/interfaces/TorchANI/__pycache__/__init__.cpython-37.pyc +0 -0
  55. MLatom/interfaces/TorchANI/__pycache__/interface_TorchANI.cpython-37.pyc +0 -0
  56. MLatom/interfaces/TorchANI/interface_TorchANI.py +323 -0
  57. MLatom/interfaces/__init__.py +0 -0
  58. MLatom/interfaces/__pycache__/__init__.cpython-37.pyc +0 -0
  59. MLatom/interfaces/sGDML/__init__.py +0 -0
  60. MLatom/interfaces/sGDML/__pycache__/__init__.cpython-37.pyc +0 -0
  61. MLatom/interfaces/sGDML/__pycache__/interface_sGDML.cpython-37.pyc +0 -0
  62. MLatom/interfaces/sGDML/__pycache__/sgdml_dataset_from_extxyz.cpython-37.pyc +0 -0
  63. MLatom/interfaces/sGDML/interface_sGDML.py +276 -0
  64. MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +199 -0
  65. MLatom/ref.json +23 -0
  66. MLatom/sliceData.py +334 -0
  67. 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!')