mlatom 2.0.0__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.
Files changed (38) hide show
  1. MLatom/ML_NEA.py +2697 -0
  2. MLatom/MLatom.py +151 -0
  3. MLatom/MLatomF +0 -0
  4. MLatom/MLtasks.py +767 -0
  5. MLatom/__init__.py +0 -0
  6. MLatom/args_class.py +396 -0
  7. MLatom/cs.so +0 -0
  8. MLatom/doc.py +620 -0
  9. MLatom/header.py +64 -0
  10. MLatom/interface_MLatomF.py +87 -0
  11. MLatom/interfaces/DeePMDkit/DP_inference.py +20 -0
  12. MLatom/interfaces/DeePMDkit/__init__.py +0 -0
  13. MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +327 -0
  14. MLatom/interfaces/DeePMDkit/template.json +70 -0
  15. MLatom/interfaces/GAP/__init__.py +0 -0
  16. MLatom/interfaces/GAP/interface_GAP.py +415 -0
  17. MLatom/interfaces/PhysNet/PhysNet_predict.py +180 -0
  18. MLatom/interfaces/PhysNet/PhysNet_train.py +425 -0
  19. MLatom/interfaces/PhysNet/__init__.py +0 -0
  20. MLatom/interfaces/PhysNet/interface_PhysNet.py +270 -0
  21. MLatom/interfaces/TorchANI/TorchANI_predict.py +82 -0
  22. MLatom/interfaces/TorchANI/TorchANI_train.py +217 -0
  23. MLatom/interfaces/TorchANI/__init__.py +0 -0
  24. MLatom/interfaces/TorchANI/interface_TorchANI.py +323 -0
  25. MLatom/interfaces/__init__.py +0 -0
  26. MLatom/interfaces/sGDML/__init__.py +0 -0
  27. MLatom/interfaces/sGDML/interface_sGDML.py +276 -0
  28. MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +199 -0
  29. MLatom/ref.json +23 -0
  30. MLatom/sliceData.py +334 -0
  31. MLatom/stopper.py +17 -0
  32. MLatom-2.0.0.data/scripts/MLatomF +12 -0
  33. MLatom-2.0.0.data/scripts/mlatom +12 -0
  34. MLatom-2.0.0.dist-info/LICENSE.txt +251 -0
  35. MLatom-2.0.0.dist-info/METADATA +149 -0
  36. MLatom-2.0.0.dist-info/RECORD +38 -0
  37. MLatom-2.0.0.dist-info/WHEEL +5 -0
  38. MLatom-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,415 @@
1
+ #!/usr/bin/python3
2
+ '''
3
+ !---------------------------------------------------------------------------!
4
+ ! Interface_GAP: Interface between GAP and MLatom !
5
+ ! Implementations by: Fuchun Ge !
6
+ !---------------------------------------------------------------------------!
7
+ '''
8
+ import numpy as np
9
+ import os, sys, subprocess, time, shutil, re, math, random
10
+ import stopper
11
+ from args_class import ArgsBase
12
+
13
+ filedir = os.path.dirname(__file__)
14
+
15
+ class Args(ArgsBase):
16
+ def __init__(self):
17
+ super().__init__()
18
+ self.add_default_dict_args([
19
+ 'learningCurve'
20
+ ],
21
+ bool
22
+ )
23
+ self.add_default_dict_args([
24
+ 'mlmodeltype'
25
+ ],
26
+ 'gap-soap'
27
+ )
28
+ self.add_default_dict_args([
29
+ 'xyzfile', 'yfile', 'ygradxyzfile','itrainin','itestin','isubtrainin','ivalidatein','mlmodelin','setname'
30
+ ],
31
+ ""
32
+ )
33
+ self.add_dict_args({
34
+ 'mlmodelout': "GAPmodel.xml",
35
+ 'sampling': "random",
36
+ 'yestfile': "enest.dat",
37
+ 'ygradxyzestfile': "gradest.dat"
38
+ })
39
+ self.parse_input_content('gapfit.gap.type=soap')
40
+
41
+ def parse(self, argsraw):
42
+ self.parse_input_content(argsraw)
43
+ self.argProcess()
44
+
45
+ def argProcess(self):
46
+ GAPCls.gapdict.update(self.gapfit.gap)
47
+ gap = '{'+' '.join([str(k)+'='+str(v) for k,v in GAPCls.gapdict.items()])[5:]+'}'
48
+ GAPCls.gapfitdict.update(self.gapfit)
49
+ GAPCls.gapfitdict.update({
50
+ 'gp_file': self.mlmodelout,
51
+ 'gap': gap,
52
+ })
53
+ with open(self.xyzfile,'r') as f:
54
+ GAPCls.natom = int(f.readline())
55
+ exec('f.readline()')
56
+ GAPCls.atype = [f.readline().split()[0] for i in range(GAPCls.natom)]
57
+
58
+ if not self.mlmodelin:
59
+ self.mlmodelin = self.mlmodelout
60
+ if 'default_sigma_e' in GAPCls.gapfitdict.keys():
61
+ GAPCls.gapfitdict['default_sigma']=GAPCls.gapfitdict['default_sigma'].replace(
62
+ GAPCls.gapfitdict['default_sigma'][1:-1].split(',')[0],
63
+ GAPCls.gapfitdict['default_sigma_e']
64
+ )
65
+ GAPCls.gapfitdict.pop('default_sigma_e')
66
+ if 'default_sigma_f' in GAPCls.gapfitdict.keys():
67
+ GAPCls.gapfitdict['default_sigma']=GAPCls.gapfitdict['default_sigma'].replace(
68
+ GAPCls.gapfitdict['default_sigma'][1:-1].split(',')[1],
69
+ GAPCls.gapfitdict['default_sigma_f']
70
+ )
71
+ GAPCls.gapfitdict.pop('default_sigma_f')
72
+ GAPCls.gapfitdict['default_sigma'] = " ".join(GAPCls.gapfitdict['default_sigma'].replace(',',', ').split())
73
+ GAPCls.gapfitdict['gp_file']=self.mlmodelout
74
+ if self.yfile: GAPCls.gapfitdict['energy_parameter_name']='energy'
75
+ if self.ygradxyzfile: GAPCls.gapfitdict['force_parameter_name']='forces'
76
+ # if self.setname: GAPCls.gapfitdict['at_file']='GAP.exyz_'+self.setname
77
+ GAPCls.gapfit = [GAPbin]
78
+ for k, v in GAPCls.gapfitdict.items():
79
+ GAPCls.gapfit.append(k+'='+v)
80
+
81
+ class GAPCls(object):
82
+ dataConverted = False
83
+ gapdict = {
84
+ 'type': 'soap',
85
+ 'l_max': '6',
86
+ 'n_max': '6',
87
+ 'atom_sigma': '0.5',
88
+ 'zeta': '4',
89
+ 'cutoff': '6',
90
+ 'cutoff_transition_width': '0.5',
91
+ 'n_sparse': '1000000',
92
+ 'delta': '1',
93
+ 'covariance_type': 'dot_product',
94
+ 'sparse_method': 'cur_points',
95
+ 'add_species': 'T'
96
+ }
97
+ # gap = '{'+' '.join([k+'='+v for k,v in args.gapdic.items()])[5:]+'}'
98
+ gapfitdict = {
99
+ 'at_file':'GAP.exyz_train',
100
+ 'default_sigma':'{0.0005,0.001,0.1,0.1}',
101
+ 'gp_file': '',
102
+ 'gap': '',
103
+ 'e0_method':'average',
104
+ 'sparse_separate_file': 'F'
105
+ }
106
+ gapfit = []
107
+ natom = 0
108
+ atype = ''
109
+
110
+ @classmethod
111
+ def load(cls):
112
+ loaded=False
113
+ if not loaded:
114
+
115
+ try:
116
+ GAPbin = os.environ['gap_fit']
117
+ except:
118
+ print('please set $gap_fit')
119
+ try:
120
+ QUIPbin = os.environ['quip']
121
+ except:
122
+ print('please set $quip')
123
+ globals()['QUIPbin'] = QUIPbin
124
+ globals()['GAPbin'] = GAPbin
125
+ loaded=True
126
+
127
+
128
+
129
+ def __init__(self, args = sys.argv[1:]):
130
+ print(' ___________________________________________________________\n\n%s' % __doc__)
131
+
132
+ @classmethod
133
+ def convertdata(cls, GAPargs, subdatasets):
134
+ cls.load()
135
+ def convert(fileout, setname, yorgrad=False):
136
+ # convert data to .exyz format
137
+ prefix = ''
138
+ if args.learningcurve: prefix = '../'
139
+ if setname:
140
+ coordfile = prefix+'xyz.dat_'+setname
141
+ yfile = prefix+'y.dat_'+setname
142
+ gradfile = prefix+'grad.dat_'+setname
143
+ else:
144
+ coordfile = args.xyzfile
145
+ if args.yfile and yorgrad: yfile = args.yfile
146
+ if args.ygradxyzfile and yorgrad: gradfile = args.ygradxyzfile
147
+
148
+ with open(fileout, 'w') as fo, open(coordfile ,'r') as fxyz:
149
+ if args.yfile and yorgrad: fy = open(yfile,'r')
150
+ if args.ygradxyzfile and yorgrad: fgrad = open(gradfile,'r')
151
+ for line in fxyz:
152
+ natom = int(line)
153
+ fo.write(line)
154
+ if args.ygradxyzfile and yorgrad: fgrad.readline()
155
+
156
+ if args.yfile and yorgrad: fo.write('energy=%s '% fy.readline()[:-1])
157
+ fo.write('pbc="T T T" Lattice="10.0 0.0 0.0 0.0 10.0 0.0 0.0 0.0 10.0" Properties=species:S:1:pos:R:3')
158
+ if args.ygradxyzfile and yorgrad: fo.write(':forces:R:3')
159
+ fo.write('\n')
160
+ fxyz.readline()
161
+ if args.ygradxyzfile and yorgrad: fgrad.readline()
162
+
163
+ for i in range(natom):
164
+ fo.write(fxyz.readline()[:-1])
165
+ if args.ygradxyzfile and yorgrad:
166
+ fo.write('%24.15f%24.15f%24.15f' % tuple(-1*float(i) for i in fgrad.readline().split()[-3:]))
167
+ fo.write('\n')
168
+ if args.yfile and yorgrad: fy.close()
169
+ if args.ygradxyzfile and yorgrad: fgrad.close()
170
+ args = Args()
171
+ args.parse(GAPargs)
172
+ print('\n Converting data...\n\n')
173
+ if subdatasets:
174
+ if 'Subtrain' in subdatasets:
175
+ for i in subdatasets:
176
+ if i == 'Subtrain' or 'Train': convert('GAP.exyz_'+i.lower(), i.lower(),True)
177
+ else: convert('GAP.exyz_'+i.lower(), i.lower())
178
+ else:
179
+ for i in subdatasets:
180
+ if i == 'Train': convert('GAP.exyz_'+i.lower(), i.lower(),True)
181
+ else: convert('GAP.exyz_'+i.lower(), i.lower())
182
+ else: convert('GAP.exyz', '')
183
+
184
+ @classmethod
185
+ def createMLmodel(cls, GAPargs, subdatasets):
186
+ cls.load()
187
+
188
+ args = Args()
189
+ args.parse(GAPargs)
190
+
191
+ if not cls.dataConverted or args.learningcurve:
192
+ cls.convertdata(GAPargs, subdatasets)
193
+ cls.dataConverted = True
194
+
195
+ FNULL = open(os.devnull, 'w')
196
+
197
+ os.system('rm '+args.mlmodelout+'* > /dev/null 2>&1 ')
198
+ # call gap_fitr
199
+ starttime = time.time()
200
+ print('> '+' '.join(cls.gapfit))
201
+ sys.stdout.flush()
202
+
203
+ subprocess.call(cls.gapfit, stdout=FNULL, stderr=FNULL)
204
+ # subprocess.call(args.gapfit)
205
+ FNULL.close()
206
+ endtime = time.time()
207
+ wallclock = endtime - starttime
208
+
209
+ return wallclock
210
+
211
+ @classmethod
212
+ def useMLmodel(cls, GAPargs, subdatasets):
213
+ cls.load()
214
+
215
+ args = Args()
216
+
217
+ if not cls.dataConverted:
218
+ cls.convertdata(GAPargs, subdatasets)
219
+ cls.dataConverted = True
220
+
221
+ args.parse(GAPargs)
222
+ if args.setname: args.setname='_'+args.setname
223
+
224
+ starttime = time.time()
225
+
226
+ p1 = subprocess.Popen([
227
+ QUIPbin,
228
+ 'E=T',
229
+ 'F=T',
230
+ 'atoms_filename=GAP.exyz'+args.setname,
231
+ 'param_filename='+args.mlmodelin,
232
+ ], stdout=subprocess.PIPE)
233
+ p2 = subprocess.Popen(['grep','AT'], stdin=p1.stdout, stdout=subprocess.PIPE)
234
+ (stdout, stderr) = p2.communicate()
235
+ p1.stdout.close()
236
+ with open('GAPest.exyz'+args.setname,'w') as f:
237
+ f.write(stdout.decode('ascii'))
238
+
239
+ endtime = time.time()
240
+ wallclock = endtime - starttime
241
+
242
+ # convert results back to MLatom format
243
+ with open('GAPest.exyz'+args.setname,'r') as f, open(args.yestfile,'w') as fy, open(args.ygradxyzestfile,'w') as fgrad:
244
+ for i, line in enumerate(f):
245
+ if i%(cls.natom+2) == 0:
246
+ fgrad.write(line[3:])
247
+ elif i%(cls.natom+2) ==1:
248
+ fgrad.write('\n')
249
+ fy.write(line.split()[1].split('=')[1]+'\n')
250
+ else:
251
+ fgrad.write('%20s%20s%20s\n' % tuple([-1*float(i) for i in line.split()[-3:]]))
252
+ sys.stdout.flush()
253
+ os.system('rm GAP.exyz'+args.setname+'.idx > /dev/null 2>&1 ')
254
+ args.setname='train'
255
+ return wallclock
256
+
257
+
258
+ # class args(object):
259
+ # # MLatom args
260
+ # learningcurve = False
261
+ # xyzfile = ""
262
+ # yfile = ""
263
+ # ygradxyzfile = ""
264
+ # virialfile = ""
265
+ # ntrain = 0
266
+ # ntest = 0
267
+ # nsubtrain = 0
268
+ # nvalidate = 0
269
+ # sampling = "random"
270
+ # itrainin = ""
271
+ # itestin = ""
272
+ # isubtrainin = ""
273
+ # ivalidatein = ""
274
+ # mlmodelout = "GAPmodel.xml"
275
+ # mlmodelin = ""
276
+ # yestfile = "enest.dat"
277
+ # ygradxyzestfile = "gradest.dat"
278
+
279
+ # # args for this interface
280
+ # setname = ''
281
+ # natom = 0
282
+ # atype = []
283
+ # gapdic = {
284
+ # 'type': 'soap',
285
+ # 'l_max': '6',
286
+ # 'n_max': '6',
287
+ # 'atom_sigma': '0.5',
288
+ # 'zeta': '4',
289
+ # 'cutoff': '6',
290
+ # 'cutoff_transition_width': '0.5',
291
+ # 'n_sparse': '1000000',
292
+ # 'delta': '1',
293
+ # 'covariance_type': 'dot_product',
294
+ # 'sparse_method': 'cur_points',
295
+ # 'add_species': 'T'
296
+ # }
297
+ # gap = '{'+' '.join([k+'='+v for k,v in gapdic.items()])[5:]+'}'
298
+ # gapfitdic = {
299
+ # 'at_file':'GAP.exyz_train',
300
+ # 'default_sigma':'{0.0005,0.001,0.1,0.1}',
301
+ # 'gp_file': mlmodelout,
302
+ # 'gap': gap,
303
+ # 'e0_method':'average',
304
+ # 'sparse_separate_file': 'F'
305
+ # }
306
+ # gapfit = []
307
+
308
+ # @classmethod
309
+ # def parse(cls,argsraw):
310
+ # if len(argsraw) == 0:
311
+ # printHelp()
312
+ # stopper.stopMLatom('At least one option should be provided')
313
+ # for arg in argsraw:
314
+ # if (arg.lower() == 'help'
315
+ # or arg.lower() == '-help'
316
+ # or arg.lower() == '-h'
317
+ # or arg.lower() == '--help'):
318
+ # printHelp()
319
+ # stopper.stopMLatom('')
320
+ # elif arg.lower().split('=')[0] == 'gapfit':
321
+ # exec(arg)
322
+ # print(gapfit)
323
+ # test=gapfit['gap']
324
+ # elif arg.lower().split('.')[0] in ['gap-soap', 'gap', 'gap_fit', 'gapfit']:
325
+ # if arg.lower().split('.')[1]=="gap":
326
+ # exec('cls.gapdic[arg.split(".")[2].split("=")[0]]=arg.split("=",1)[1]')
327
+ # cls.gap = '{'+' '.join([k+'='+v for k,v in cls.gapdic.items()])[5:]+'}'
328
+ # GAPCls.gapfitdict['gap']=cls.gap
329
+ # else:
330
+ # exec('GAPCls.gapfitdict[arg.split(".")[1].split("=")[0]]=arg.split("=",1)[1]')
331
+ # elif len(arg.lower().split('=')) == 1: # parse boolean args
332
+ # try:
333
+ # exec('cls.'+arg.lower())
334
+ # exec('cls.'+arg.lower()+'=True')
335
+ # except: pass
336
+ # else: # parse other args
337
+ # try:
338
+ # exec('cls.'+arg.split('=')[0].lower())
339
+ # if type(eval('cls.'+arg.split('=')[0].lower())) == str :
340
+ # exec('cls.'+arg.split('=')[0].lower()+'='+"arg.split('=')[1]")
341
+ # else:
342
+ # exec('cls.'+arg.split('=')[0].lower()+'='+arg.split('=')[1])
343
+ # except:
344
+ # pass
345
+
346
+
347
+ # # calc. & fix something args that useful and you don't want users to change...
348
+ # with open(cls.xyzfile,'r') as f:
349
+ # cls.natom = int(f.readline())
350
+ # exec('f.readline()')
351
+ # cls.atype = [f.readline().split()[0] for i in range(cls.natom)]
352
+
353
+ # # for estAccMLmodel that MLmodelIn may not be provided
354
+ # if not cls.mlmodelin:
355
+ # cls.mlmodelin = cls.mlmodelout
356
+ # if 'default_sigma_e' in GAPCls.gapfitdict.keys():
357
+ # GAPCls.gapfitdict['default_sigma']=GAPCls.gapfitdict['default_sigma'].replace(
358
+ # GAPCls.gapfitdict['default_sigma'][1:-1].split(',')[0],
359
+ # GAPCls.gapfitdict['default_sigma_e']
360
+ # )
361
+ # GAPCls.gapfitdict.pop('default_sigma_e')
362
+ # if 'default_sigma_f' in GAPCls.gapfitdict.keys():
363
+ # GAPCls.gapfitdict['default_sigma']=GAPCls.gapfitdict['default_sigma'].replace(
364
+ # GAPCls.gapfitdict['default_sigma'][1:-1].split(',')[1],
365
+ # GAPCls.gapfitdict['default_sigma_f']
366
+ # )
367
+ # GAPCls.gapfitdict.pop('default_sigma_f')
368
+ # GAPCls.gapfitdict['default_sigma'] = " ".join(GAPCls.gapfitdict['default_sigma'].replace(',',', ').split())
369
+ # GAPCls.gapfitdict['gp_file']=cls.mlmodelout
370
+ # if cls.yfile: GAPCls.gapfitdict['energy_parameter_name']='energy'
371
+ # if cls.ygradxyzfile: GAPCls.gapfitdict['force_parameter_name']='forces'
372
+ # if cls.setname: GAPCls.gapfitdict['at_file']='GAP.exyz_'+cls.setname
373
+ # cls.gapfit = [GAPbin]
374
+ # for k, v in GAPCls.gapfitdict.items():
375
+ # cls.gapfit.append(k+'='+v)
376
+
377
+
378
+ def printHelp():
379
+ helpText = __doc__ + '''
380
+ To use Interface_GAP, please define $gap_fit and $quip
381
+ to corresponding executables
382
+
383
+ Arguments with their default values:
384
+ MLprog=GAP enables this interface
385
+ MLmodelType=GAP-SOAP requests GAP-SOAP model
386
+
387
+ gapfit.xxx=x xxx could be any option for gap_fit
388
+ Note that at_file and gp_file are not required
389
+ gapfit.gap.xxx=x xxx could be any option for gap
390
+ gapfit.default_sigma={0.0005,0.001,0,0}
391
+ sigmas for energies, forces, virals, Hessians
392
+ gapfit.e0_method=average method for determining e0
393
+ gapfit.gap.type=soap descriptor type
394
+ gapfit.gap.l_max=6 max number of angular basis functions
395
+ gapfit.gap.n_max=6 max number of radial basis functions
396
+ gapfit.gap.atom_sigma=0.5 Gaussian smearing of atom density hyperparameter
397
+
398
+ gapfit.gap.zeta=4 hyperparameter for kernel sensitivity
399
+ gapfit.gap.cutoff=6.0 cutoff radius of local environment
400
+ gapfit.gap.cutoff_transition_width=0.5
401
+ cutoff transition width
402
+ gapfit.gap.delta=1 hyperparameter delta for kernel scaling
403
+
404
+ Cite GAP method:
405
+ A. P. Bartok, M. C. Payne, R. Konor, G. Csanyi,
406
+ Phys. Rev. Lett. 2010, 104, 136403
407
+
408
+ Cite SOAP descriptor:
409
+ A. P. Bartok, R. Konor, G. Csanyi,
410
+ Phys. Rev. B 2013, 87, 184115
411
+ '''
412
+ print(helpText)
413
+
414
+ if __name__ == '__main__':
415
+ GAPCls()
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import numpy as np
4
+ import os
5
+ import sys
6
+ os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
7
+
8
+ PhysNetdir = os.environ['PhysNet']
9
+ sys.path.append(PhysNetdir)
10
+
11
+ import tensorflow.compat.v1 as tf
12
+ tf.disable_v2_behavior()
13
+ import time
14
+ import argparse
15
+ import logging
16
+ logging.getLogger('tensorflow').disabled = True
17
+
18
+ from datetime import datetime
19
+ from neural_network.NeuralNetwork import *
20
+ from neural_network.activation_fn import *
21
+ from training.DataContainer import *
22
+ from training.DataProvider import *
23
+
24
+ def predict(PNargs):
25
+ tf.compat.v1.reset_default_graph()
26
+ #define command line arguments
27
+ parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
28
+ parser.add_argument("--restart", type=str, default=None, help="restart training from a specific folder")
29
+ parser.add_argument("--num_features", type=int, help="dimensionality of feature vectors")
30
+ parser.add_argument("--num_basis", type=int, help="number of radial basis functions")
31
+ parser.add_argument("--num_blocks", type=int, help="number of interaction blocks")
32
+ parser.add_argument("--num_residual_atomic", type=int, help="number of residual layers for atomic refinements")
33
+ parser.add_argument("--num_residual_interaction", type=int, help="number of residual layers for the message phase")
34
+ parser.add_argument("--num_residual_output", type=int, help="number of residual layers for the output blocks")
35
+ parser.add_argument("--cutoff", default=10.0, type=float, help="cutoff distance for short range interactions")
36
+ parser.add_argument("--use_electrostatic", default=1, type=int, help="use electrostatics in energy prediction (0/1)")
37
+ parser.add_argument("--use_dispersion", default=1, type=int, help="use dispersion in energy prediction (0/1)")
38
+ parser.add_argument("--grimme_s6", default=None, type=float, help="grimme s6 dispersion coefficient")
39
+ parser.add_argument("--grimme_s8", default=None, type=float, help="grimme s8 dispersion coefficient")
40
+ parser.add_argument("--grimme_a1", default=None, type=float, help="grimme a1 dispersion coefficient")
41
+ parser.add_argument("--grimme_a2", default=None, type=float, help="grimme a2 dispersion coefficient")
42
+ parser.add_argument("--num_train", type=int, help="number of training samples")
43
+ parser.add_argument("--num_valid", type=int, help="number of validation samples")
44
+ parser.add_argument("--seed", default=42, type=int, help="seed for splitting dataset into training/validation/test")
45
+ parser.add_argument("--max_steps", type=int, help="maximum number of training steps")
46
+ parser.add_argument("--learning_rate", default=0.001, type=float, help="learning rate used by the optimizer")
47
+ parser.add_argument("--max_norm", default=1000.0, type=float, help="max norm for gradient clipping")
48
+ parser.add_argument("--ema_decay", default=0.999, type=float, help="exponential moving average decay used by the trainer")
49
+ parser.add_argument("--keep_prob", default=1.0, type=float, help="keep probability for dropout regularization of rbf layer")
50
+ parser.add_argument("--l2lambda", type=float, help="lambda multiplier for l2 loss (regularization)")
51
+ parser.add_argument("--nhlambda", type=float, help="lambda multiplier for non-hierarchicality loss (regularization)")
52
+ parser.add_argument("--decay_steps", type=int, help="decay the learning rate every N steps by decay_rate")
53
+ parser.add_argument("--decay_rate", type=float, help="factor with which the learning rate gets multiplied by every decay_steps steps")
54
+ parser.add_argument("--batch_size", type=int, help="batch size used per training step")
55
+ parser.add_argument("--valid_batch_size", type=int, help="batch size used for going through validation_set")
56
+ parser.add_argument('--force_weight', default=52.91772105638412, type=float, help="this defines the force contribution to the loss function relative to the energy contribution (to take into account the different numerical range)")
57
+ parser.add_argument('--charge_weight', default=14.399645351950548, type=float, help="this defines the charge contribution to the loss function relative to the energy contribution (to take into account the different numerical range)")
58
+ parser.add_argument('--dipole_weight', default=27.211386024367243, type=float, help="this defines the dipole contribution to the loss function relative to the energy contribution (to take into account the different numerical range)")
59
+ parser.add_argument('--summary_interval', type=int, help="write a summary every N steps")
60
+ parser.add_argument('--validation_interval', type=int, help="check performance on validation set every N steps")
61
+ parser.add_argument('--save_interval', type=int, help="save progress every N steps")
62
+ parser.add_argument('--record_run_metadata', type=int, help="records metadata like memory consumption etc.")
63
+
64
+ #if no command line arguments are present, config file is parsed
65
+ config_file = os.path.join(PNargs.mlmodelin, 'config.txt')
66
+
67
+ if os.path.isfile(config_file):
68
+ args = parser.parse_args(["@"+config_file])
69
+ else:
70
+ args = parser.parse_args(["--help"])
71
+ if PNargs.setname: PNargs.setname='_'+PNargs.setname
72
+ #construct file path to directory which stores the best checkpoint files
73
+ best_dir = os.path.join(PNargs.mlmodelin, 'best')
74
+ testfile = 'PhysNet'+PNargs.setname+'.npz'
75
+ #load dataset
76
+ data = DataContainer(testfile)
77
+
78
+ data_provider = DataProvider(data, 0, 0, 0, 0, seed=args.seed)
79
+
80
+ #create neural network
81
+ # NASdict = np.load(os.path.join(PNargs.mlmodelin, 'NAS.npz'))
82
+ # tf.reset_default_graph()
83
+ nn = NeuralNetwork(F=args.num_features,
84
+ K=args.num_basis,
85
+ sr_cut=args.cutoff,
86
+ num_blocks=args.num_blocks,
87
+ num_residual_atomic=args.num_residual_atomic,
88
+ num_residual_interaction=args.num_residual_interaction,
89
+ num_residual_output=args.num_residual_output,
90
+ use_electrostatic=(args.use_electrostatic==1),
91
+ use_dispersion=(args.use_dispersion==1),
92
+ s6=args.grimme_s6,
93
+ s8=args.grimme_s8,
94
+ a1=args.grimme_a1,
95
+ a2=args.grimme_a2,
96
+ # Eshift=NASdict['Eshift'],
97
+ # Escale=NASdict['Escale'],
98
+ activation_fn=shifted_softplus,
99
+ seed=None,
100
+ scope="neural_network")
101
+ #create placeholders for feeding data
102
+ Eref = tf.placeholder(tf.float32, shape=[None, ], name="Eref")
103
+ Fref = tf.placeholder(tf.float32, shape=[None,3], name="Fref")
104
+ Z = tf.placeholder(tf.int32, shape=[None, ], name="Z")
105
+ Dref = tf.placeholder(tf.float32, shape=[None,3], name="Dref")
106
+ Qref = tf.placeholder(tf.float32, shape=[None, ], name="Qref")
107
+ R = tf.placeholder(tf.float32, shape=[None,3], name="R")
108
+ idx_i = tf.placeholder(tf.int32, shape=[None, ], name="idx_i")
109
+ idx_j = tf.placeholder(tf.int32, shape=[None, ], name="idx_j")
110
+ batch_seg = tf.placeholder(tf.int32, shape=[None, ], name="batch_seg")
111
+
112
+ #model energy/forces
113
+ Ea, Qa, Dij, nhloss = nn.atomic_properties(Z, R, idx_i, idx_j)
114
+ energy, forces = nn.energy_and_forces_from_atomic_properties(Ea, Qa, Dij, Z, R, idx_i, idx_j, Qref, batch_seg)
115
+ #total charge
116
+ Qtot = tf.segment_sum(Qa, batch_seg)
117
+ #dipole moment vector
118
+ QR = tf.stack([Qa*R[:,0], Qa*R[:,1], Qa*R[:,2]],1)
119
+ D = tf.segment_sum(QR, batch_seg)
120
+
121
+
122
+
123
+ #helper function to fill a feed dictionary
124
+ def fill_feed_dict(data):
125
+ feed_dict = {
126
+ Eref: data["E"],
127
+ Fref: data["F"],
128
+ Z: data["Z"],
129
+ Dref: data["D"],
130
+ Qref: data["Q"],
131
+ R: data["R"],
132
+ idx_i: data["idx_i"],
133
+ idx_j: data["idx_j"],
134
+ batch_seg: data["batch_seg"]
135
+ }
136
+ return feed_dict
137
+
138
+ #helper function to print errors
139
+
140
+ def output_est(sess, all_data, data_count):
141
+ with open(PNargs.yestfile,'w') as fy, open(PNargs.ygradxyzestfile,'wb') as fgrad:
142
+ line="%d\n\n" % PNargs.natom
143
+ for i in range(data_count):
144
+ data = all_data[i]
145
+ feed_dict = fill_feed_dict(data)
146
+ E_tmp, F_tmp = sess.run([energy, forces], feed_dict=feed_dict)
147
+ fy.write('%f\n' % E_tmp)
148
+ fgrad.write(line.encode('utf-8'))
149
+ np.savetxt(fgrad, -1*F_tmp, fmt='%20.12f', delimiter=" ")
150
+
151
+
152
+
153
+ #create tensorflow session
154
+ with tf.Session() as sess:
155
+ #restore latest checkpoint
156
+ checkpoint = tf.train.latest_checkpoint(best_dir)
157
+ assert checkpoint is not None
158
+ nn.restore(sess, checkpoint)
159
+
160
+ #calculate errors on test data
161
+ print(' ')
162
+ # print('##### ------------ Estimating ------------ #####')
163
+
164
+ start = time.time()
165
+
166
+ output_est(sess, data, len(data))
167
+
168
+ end = time.time()
169
+ hours, rem = divmod(end-start, 3600)
170
+ minutes, seconds = divmod(rem, 60)
171
+
172
+ # print(' ')
173
+ # print('--------------------------------------------------')
174
+ # print('Total CPU time for estimating - {:0>2}:{:0>2}:{:05.2f}'.format(int(hours),int(minutes),seconds))
175
+ # print('--------------------------------------------------')
176
+ # print(' ')
177
+
178
+
179
+
180
+