mlatom 1.2.3__tar.gz → 2.0.0__tar.gz

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 (49) hide show
  1. {MLatom-1.2.3/src/MLatom.egg-info → MLatom-2.0.0}/PKG-INFO +25 -10
  2. {MLatom-1.2.3 → MLatom-2.0.0}/README.md +24 -9
  3. {MLatom-1.2.3 → MLatom-2.0.0}/setup.py +3 -3
  4. MLatom-1.2.3/src/MLatom/ML-NEA.py → MLatom-2.0.0/src/MLatom/ML_NEA.py +149 -40
  5. MLatom-2.0.0/src/MLatom/MLatom.py +151 -0
  6. {MLatom-1.2.3 → MLatom-2.0.0}/src/MLatom/MLatomF +0 -0
  7. MLatom-2.0.0/src/MLatom/MLtasks.py +767 -0
  8. {MLatom-1.2.3 → MLatom-2.0.0}/src/MLatom/__init__.py +0 -0
  9. MLatom-2.0.0/src/MLatom/args_class.py +396 -0
  10. MLatom-2.0.0/src/MLatom/cs.so +0 -0
  11. MLatom-2.0.0/src/MLatom/doc.py +620 -0
  12. MLatom-2.0.0/src/MLatom/header.py +64 -0
  13. MLatom-2.0.0/src/MLatom/interface_MLatomF.py +87 -0
  14. MLatom-2.0.0/src/MLatom/interfaces/DeePMDkit/DP_inference.py +20 -0
  15. MLatom-2.0.0/src/MLatom/interfaces/DeePMDkit/__init__.py +0 -0
  16. MLatom-2.0.0/src/MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +327 -0
  17. MLatom-2.0.0/src/MLatom/interfaces/DeePMDkit/template.json +70 -0
  18. MLatom-2.0.0/src/MLatom/interfaces/GAP/__init__.py +0 -0
  19. MLatom-2.0.0/src/MLatom/interfaces/GAP/interface_GAP.py +415 -0
  20. MLatom-2.0.0/src/MLatom/interfaces/PhysNet/PhysNet_predict.py +180 -0
  21. MLatom-2.0.0/src/MLatom/interfaces/PhysNet/PhysNet_train.py +425 -0
  22. MLatom-2.0.0/src/MLatom/interfaces/PhysNet/__init__.py +0 -0
  23. MLatom-2.0.0/src/MLatom/interfaces/PhysNet/interface_PhysNet.py +270 -0
  24. MLatom-2.0.0/src/MLatom/interfaces/TorchANI/TorchANI_predict.py +82 -0
  25. MLatom-2.0.0/src/MLatom/interfaces/TorchANI/TorchANI_train.py +217 -0
  26. MLatom-2.0.0/src/MLatom/interfaces/TorchANI/__init__.py +0 -0
  27. MLatom-2.0.0/src/MLatom/interfaces/TorchANI/interface_TorchANI.py +323 -0
  28. MLatom-2.0.0/src/MLatom/interfaces/__init__.py +0 -0
  29. MLatom-2.0.0/src/MLatom/interfaces/sGDML/__init__.py +0 -0
  30. MLatom-2.0.0/src/MLatom/interfaces/sGDML/interface_sGDML.py +276 -0
  31. MLatom-2.0.0/src/MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +199 -0
  32. MLatom-2.0.0/src/MLatom/ref.json +23 -0
  33. {MLatom-1.2.3 → MLatom-2.0.0}/src/MLatom/sliceData.py +36 -41
  34. MLatom-2.0.0/src/MLatom/stopper.py +17 -0
  35. {MLatom-1.2.3 → MLatom-2.0.0/src/MLatom.egg-info}/PKG-INFO +25 -10
  36. MLatom-2.0.0/src/MLatom.egg-info/SOURCES.txt +40 -0
  37. MLatom-2.0.0/src/MLatom.egg-info/requires.txt +2 -0
  38. MLatom-1.2.3/src/MLatom/MLatom.py +0 -234
  39. MLatom-1.2.3/src/MLatom/MLtasks.py +0 -363
  40. MLatom-1.2.3/src/MLatom/header.py +0 -108
  41. MLatom-1.2.3/src/MLatom/interface_MLatomF.py +0 -57
  42. MLatom-1.2.3/src/MLatom/ref.json +0 -7
  43. MLatom-1.2.3/src/MLatom/stopper.py +0 -46
  44. MLatom-1.2.3/src/MLatom.egg-info/SOURCES.txt +0 -18
  45. {MLatom-1.2.3 → MLatom-2.0.0}/MLatomF +0 -0
  46. {MLatom-1.2.3 → MLatom-2.0.0}/mlatom +0 -0
  47. {MLatom-1.2.3 → MLatom-2.0.0}/setup.cfg +0 -0
  48. {MLatom-1.2.3 → MLatom-2.0.0}/src/MLatom.egg-info/dependency_links.txt +0 -0
  49. {MLatom-1.2.3 → MLatom-2.0.0}/src/MLatom.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: MLatom
3
- Version: 1.2.3
3
+ Version: 2.0.0
4
4
  Summary: A Package for Atomistic Simulations with Machine Learning
5
5
  Home-page: http://mlatom.com
6
6
  Author: Pavlo O. Dral
@@ -20,7 +20,8 @@ Description: # Brief Introduction
20
20
  - Estimating accuracy of ML models.
21
21
  - Creating ML model and saving it to a file.
22
22
  - Loading existing ML model from a file and performing ML calculations with this model.
23
- - ML-cross-section to boost the calculation of ML-NEA
23
+ - ML-accelerated calculation of absorption spectra within nuclear ensemble approach
24
+ - Learning curves
24
25
 
25
26
  ## Data Set Operations
26
27
  - Converting XYZ coordinates into an input vector (molecular descriptor) for ML.
@@ -54,14 +55,14 @@ Description: # Brief Introduction
54
55
  - [ sorted by norms of its rows ](http://dx.doi.org/10.1021/ct400195d);
55
56
  - unsorted;
56
57
  - permuted.
57
- - [ Normalized inverted internuclear distances ](http://mlatom.com/self-correcting-machine-learning-and-structure-based-sampling/)
58
+ - [ Normalized inverse internuclear distances (RE descriptor)](http://mlatom.com/self-correcting-machine-learning-and-structure-based-sampling/)
58
59
  - sorted for user-defined atoms by the sum of their nuclear repulsions to all other atoms;
59
60
  - unsorted;
60
61
  - permuted.
61
62
 
62
63
 
63
64
  # The KREG model
64
- Now we set [ KREG (Kernel-ridge-regression using RE descriptor and the Gaussian kernel function )](http://dx.doi.org/10.1021/acs.jpclett.8b02469) as default ML method. Default hyperparameter optimization options were updated to speed up the hyperparameter search for KREG.
65
+ The [ KREG (Kernel-ridge-regression using RE descriptor and the Gaussian kernel function )](http://dx.doi.org/10.1021/acs.jpclett.8b02469) model is the default ML method.
65
66
 
66
67
 
67
68
  # Model Validation
@@ -81,12 +82,15 @@ Description: # Brief Introduction
81
82
 
82
83
  Note that hyperparameter tuning can be performed together with model validation. This means that for example one can perform outer loop of the cross-validation for model validation and tune hyperparameters via inner loop of the cross-validation.
83
84
 
85
+ Apart from natively implemented logarithmic grid search for hyperparameters, MLatom also provides the interface to the [ hyperopt package ](http://hyperopt.github.io/hyperopt/) implementing hyperparameter optimization using Bayesian methods with Tree-structured Parzen Estimator (TPE).
86
+
84
87
 
85
88
  # First Derivatives
86
- MLatom can be also used to estimate first derivatives from an ML model. It can be useful, if an ML model has been created for energies, and one wants to estimate forces. Two scenarios are possible:
89
+ MLatom can be also used to estimate first derivatives from an ML model. Two scenarios are possible:
87
90
 
88
- - partial derivatives are calculated for each dimension of given input vectors (analytical derivatives for Gaussian kernel, numerical derivatives for other kernels);
89
- - first derivatives are calculated in XYZ coordinates for input files containing molecular XYZ coordinates (only numerical derivatives).
91
+ - partial derivatives are calculated for each dimension of given input vectors (analytical derivatives for Gaussian and Matern kernels);
92
+ - first derivatives are calculated in XYZ coordinates for input files containing molecular XYZ coordinates (analytical derivatives for the RE and Coulomb matrix descriptors).
93
+ - derivatives for interfaced models
90
94
 
91
95
 
92
96
  # Cross Section
@@ -97,12 +101,21 @@ Description: # Brief Introduction
97
101
  > Bao-Xin Xue, Mario Barbatti*, Pavlo O. Dral*, [ Machine Learning for Absorption Cross Sections ](https://doi.org/10.1021/acs.jpca.0c05310), J. Phys. Chem. A 2020, 124, 7199–7210. DOI: 10.1021/acs.jpca.0c05310.
98
102
  > [ Preprint on ChemRxiv ](https://doi.org/10.26434/chemrxiv.12594191), DOI: 10.26434/chemrxiv.12594191.
99
103
 
104
+ # Interfaces to 3<sup>rd</sup>-party software
105
+ MLatom also provides interfaces to some third-party software where extra ML model types are natively implemented. It allows users to access other popular ML model types within MLatom's workflow. Currently available third-party model types are:
106
+
107
+ - [ANI](https://doi.org/10.1039/c6sc05720a) (through [TorchANI](https://doi.org/10.1021/acs.jcim.0c00451))
108
+ - [DeepPot-SE](https://papers.nips.cc/paper/2018/hash/e2ad76f2326fbc6b56a45a56c59fafdb-Abstract.html) and [DPMD](https://doi.org/10.1103/PhysRevLett.120.143001) (through [DeePMD-kit](https://doi.org/10.1016/j.cpc.2018.03.016))
109
+ - [GAP](https://doi.org/10.1103/Physrevlett.104.136403)-[SOAP](https://doi.org/10.1103/physrevb.87.184115) (through [GAP](www.libatoms.org) suite and [QUIP](http://github.com/libAtoms/QUIP))
110
+ - [PhysNet](https://doi.org/10.1021/acs.jctc.9b00181) (through [PhysNet](github.com/MMunibas/PhysNet))
111
+ - [sGDML](https://doi.org/10.1038/s41467-018-06169-2) (through [sGDML](www.sgdml.org))
112
+
100
113
  # About Program
101
114
  MLatom: a Package for Atomistic Simulations with Machine Learning
102
- Version 1.2
115
+ Version 2.0
103
116
  http://mlatom.com/
104
117
 
105
- Copyright (c) 2013-2020 Pavlo O. Dral
118
+ Copyright (c) 2013-2021 Pavlo O. Dral
106
119
  http://dr-dral.com/
107
120
 
108
121
  All rights reserved. No part of MLatom may be used, published or redistributed without written permission by Pavlo Dral.
@@ -110,8 +123,10 @@ Description: # Brief Introduction
110
123
  The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
111
124
 
112
125
  Cite as:
126
+
113
127
  1. Pavlo O. Dral, J. Comput. Chem. 2019, 40, 2339-2347
114
- 2. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, MLatom: A Package for Atomistic Simulations with Machine Learning, version 1.2, Xiamen University, Xiamen, China, 2013-2020.
128
+ 2. Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti, Top. Curr. Chem. 2021, 379, 27
129
+ 3. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.0, Xiamen University, Xiamen, China, 2013-2021.
115
130
 
116
131
 
117
132
  # License
@@ -12,7 +12,8 @@ A brief overview of MLatom capabilities. See sections below for more details.
12
12
  - Estimating accuracy of ML models.
13
13
  - Creating ML model and saving it to a file.
14
14
  - Loading existing ML model from a file and performing ML calculations with this model.
15
- - ML-cross-section to boost the calculation of ML-NEA
15
+ - ML-accelerated calculation of absorption spectra within nuclear ensemble approach
16
+ - Learning curves
16
17
 
17
18
  ## Data Set Operations
18
19
  - Converting XYZ coordinates into an input vector (molecular descriptor) for ML.
@@ -46,14 +47,14 @@ Permutationally invariant kernel and self-correction are also supported.
46
47
  - [ sorted by norms of its rows ](http://dx.doi.org/10.1021/ct400195d);
47
48
  - unsorted;
48
49
  - permuted.
49
- - [ Normalized inverted internuclear distances ](http://mlatom.com/self-correcting-machine-learning-and-structure-based-sampling/)
50
+ - [ Normalized inverse internuclear distances (RE descriptor)](http://mlatom.com/self-correcting-machine-learning-and-structure-based-sampling/)
50
51
  - sorted for user-defined atoms by the sum of their nuclear repulsions to all other atoms;
51
52
  - unsorted;
52
53
  - permuted.
53
54
 
54
55
 
55
56
  # The KREG model
56
- Now we set [ KREG (Kernel-ridge-regression using RE descriptor and the Gaussian kernel function )](http://dx.doi.org/10.1021/acs.jpclett.8b02469) as default ML method. Default hyperparameter optimization options were updated to speed up the hyperparameter search for KREG.
57
+ The [ KREG (Kernel-ridge-regression using RE descriptor and the Gaussian kernel function )](http://dx.doi.org/10.1021/acs.jpclett.8b02469) model is the default ML method.
57
58
 
58
59
 
59
60
  # Model Validation
@@ -73,12 +74,15 @@ Gaussian, Laplacian, and Matérn kernels have σ and λ tunable hyperparameters.
73
74
 
74
75
  Note that hyperparameter tuning can be performed together with model validation. This means that for example one can perform outer loop of the cross-validation for model validation and tune hyperparameters via inner loop of the cross-validation.
75
76
 
77
+ Apart from natively implemented logarithmic grid search for hyperparameters, MLatom also provides the interface to the [ hyperopt package ](http://hyperopt.github.io/hyperopt/) implementing hyperparameter optimization using Bayesian methods with Tree-structured Parzen Estimator (TPE).
78
+
76
79
 
77
80
  # First Derivatives
78
- MLatom can be also used to estimate first derivatives from an ML model. It can be useful, if an ML model has been created for energies, and one wants to estimate forces. Two scenarios are possible:
81
+ MLatom can be also used to estimate first derivatives from an ML model. Two scenarios are possible:
79
82
 
80
- - partial derivatives are calculated for each dimension of given input vectors (analytical derivatives for Gaussian kernel, numerical derivatives for other kernels);
81
- - first derivatives are calculated in XYZ coordinates for input files containing molecular XYZ coordinates (only numerical derivatives).
83
+ - partial derivatives are calculated for each dimension of given input vectors (analytical derivatives for Gaussian and Matern kernels);
84
+ - first derivatives are calculated in XYZ coordinates for input files containing molecular XYZ coordinates (analytical derivatives for the RE and Coulomb matrix descriptors).
85
+ - derivatives for interfaced models
82
86
 
83
87
 
84
88
  # Cross Section
@@ -89,12 +93,21 @@ In brief, this feature uses fewer QC calculation to achieve higher precision and
89
93
  > Bao-Xin Xue, Mario Barbatti*, Pavlo O. Dral*, [ Machine Learning for Absorption Cross Sections ](https://doi.org/10.1021/acs.jpca.0c05310), J. Phys. Chem. A 2020, 124, 7199–7210. DOI: 10.1021/acs.jpca.0c05310.
90
94
  > [ Preprint on ChemRxiv ](https://doi.org/10.26434/chemrxiv.12594191), DOI: 10.26434/chemrxiv.12594191.
91
95
 
96
+ # Interfaces to 3<sup>rd</sup>-party software
97
+ MLatom also provides interfaces to some third-party software where extra ML model types are natively implemented. It allows users to access other popular ML model types within MLatom's workflow. Currently available third-party model types are:
98
+
99
+ - [ANI](https://doi.org/10.1039/c6sc05720a) (through [TorchANI](https://doi.org/10.1021/acs.jcim.0c00451))
100
+ - [DeepPot-SE](https://papers.nips.cc/paper/2018/hash/e2ad76f2326fbc6b56a45a56c59fafdb-Abstract.html) and [DPMD](https://doi.org/10.1103/PhysRevLett.120.143001) (through [DeePMD-kit](https://doi.org/10.1016/j.cpc.2018.03.016))
101
+ - [GAP](https://doi.org/10.1103/Physrevlett.104.136403)-[SOAP](https://doi.org/10.1103/physrevb.87.184115) (through [GAP](www.libatoms.org) suite and [QUIP](http://github.com/libAtoms/QUIP))
102
+ - [PhysNet](https://doi.org/10.1021/acs.jctc.9b00181) (through [PhysNet](github.com/MMunibas/PhysNet))
103
+ - [sGDML](https://doi.org/10.1038/s41467-018-06169-2) (through [sGDML](www.sgdml.org))
104
+
92
105
  # About Program
93
106
  MLatom: a Package for Atomistic Simulations with Machine Learning
94
- Version 1.2
107
+ Version 2.0
95
108
  http://mlatom.com/
96
109
 
97
- Copyright (c) 2013-2020 Pavlo O. Dral
110
+ Copyright (c) 2013-2021 Pavlo O. Dral
98
111
  http://dr-dral.com/
99
112
 
100
113
  All rights reserved. No part of MLatom may be used, published or redistributed without written permission by Pavlo Dral.
@@ -102,8 +115,10 @@ The above copyright notice and this permission notice shall be included in all
102
115
  The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
103
116
 
104
117
  Cite as:
118
+
105
119
  1. Pavlo O. Dral, J. Comput. Chem. 2019, 40, 2339-2347
106
- 2. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, MLatom: A Package for Atomistic Simulations with Machine Learning, version 1.2, Xiamen University, Xiamen, China, 2013-2020.
120
+ 2. Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti, Top. Curr. Chem. 2021, 379, 27
121
+ 3. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.0, Xiamen University, Xiamen, China, 2013-2021.
107
122
 
108
123
 
109
124
  # License
@@ -43,7 +43,7 @@ with open(os.path.join(here, 'README.md')) as f:
43
43
 
44
44
  setup(
45
45
  name = pkg_name,
46
- version = "1.2.3",
46
+ version = "2.0.0",
47
47
  author = "Pavlo O. Dral",
48
48
  author_email = "admin@mlatom.com",
49
49
  license = 'CC BY-NC-ND 4.0', # https://creativecommons.org/licenses/by-nc-nd/4.0/
@@ -55,7 +55,7 @@ setup(
55
55
  packages = find_packages('src'),
56
56
  package_dir = {'' : 'src'},
57
57
  scripts = ['mlatom', 'MLatomF'],
58
- package_data = {"": ['MLatomF', '*.json']},
58
+ package_data = {"": ['MLatomF', '*.json', 'cs.so']},
59
59
  classifiers = [
60
60
  "Programming Language :: Python :: 3",
61
61
  "Operating System :: POSIX :: Linux",
@@ -63,7 +63,7 @@ setup(
63
63
  "Topic :: Scientific/Engineering :: Chemistry",
64
64
  "Environment :: Console",
65
65
  ],
66
- # install_requires = [],
66
+ install_requires = ['numpy', 'matplotlib'],
67
67
  # entry_points = {
68
68
  # 'console_scripts' : ['mlatom=MLatom.MLatom:MLatomMainCls']
69
69
  # }
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
+ import random
3
4
  import time
4
5
  from typing import Callable, Iterable, List, Optional, Tuple, Union, Any
5
6
  import inspect
@@ -9,6 +10,7 @@ import math
9
10
  from subprocess import getstatusoutput, Popen, PIPE
10
11
  import multiprocessing as mp
11
12
  from contextlib import redirect_stdout
13
+ from ctypes import c_double, CDLL, c_long
12
14
  from functools import wraps, reduce
13
15
  from itertools import product
14
16
  import json
@@ -19,7 +21,7 @@ try:
19
21
  import matplotlib.pyplot as plt
20
22
  except:
21
23
  pass
22
- ''' version: 1.3 script author: Bao-Xin Xue Xiamen University
24
+ ''' version: 1.5 script author: Bao-Xin Xue Xiamen University
23
25
  ┌────────────────────────────────────────────────────────────────────────────────────┐
24
26
  │ │
25
27
  │ ┌────────────────────────────────┐ ┌────────────────────────────────┐ │
@@ -68,6 +70,9 @@ except:
68
70
  _Str_or_Float = Union[str, float]
69
71
  _Int_or_Float = Union[int, float]
70
72
 
73
+ # python script path
74
+ py_script_path = ''
75
+
71
76
  class Error(Exception):
72
77
  def __init__(self):
73
78
  # todo: to define various error
@@ -105,7 +110,8 @@ def logger(log_content: str, logfile: str='out.log') -> Callable[[Any], Any]:
105
110
  result: Any = func(*args, **kwargs)
106
111
  end_time = time.time()
107
112
 
108
- log_string = f'{log_content} ( {func.__name__} ) finished at {time.ctime()} {time.tzname[0]} |||| totally spent {end_time - start_time} sec'
113
+ spend_time = end_time - start_time
114
+ log_string = f'{log_content} ( {func.__name__} ) finished at {time.ctime()} {time.tzname[0]} |||| total spent {spend_time:.2f} sec'
109
115
  log_string += '\n' + '=' * 90 + '\n\n'
110
116
  print(log_string)
111
117
 
@@ -308,6 +314,13 @@ class Molecule():
308
314
  if atom_num != self.atom_num:
309
315
  # todo 2: raise xyz atom number error problem
310
316
  pass
317
+
318
+ @staticmethod
319
+ def read_element_label(input_file: str, idx: int=1) -> List[str]:
320
+ idx -= 1
321
+ with open(input_file) as f:
322
+ data = f.readlines()
323
+ return [line.split()[idx] for line in data]
311
324
 
312
325
  @classmethod
313
326
  def read_multi_xyz(cls, file_path: str, au_unit: bool=False) -> List['Molecule']:
@@ -409,7 +422,7 @@ class Plot():
409
422
  self.ax.grid()
410
423
  self.fig.savefig(out_img)
411
424
 
412
- def plot_multiple_file(self, files: List[str], labels: List[str], colors: Optional[List[str]]=None, out_img_name: str='all.png', x_column: int=1, y_column: int=2):
425
+ def plot_multiple_file(self, files: List[str], labels: List[str], colors: Optional[List[str]]=None, x_column: int=1, y_column: int=2):
413
426
  if not EnvCheck.check_matplotlib():
414
427
  return
415
428
  plt.rcParams['legend.fontsize'] = 'x-large'
@@ -438,10 +451,17 @@ class Plot():
438
451
  # self.ax.set(xlabel=self.xlabel, ylabel=self.ylabel, title=self.title)
439
452
  self.ax.set_xlabel(self.xlabel, fontsize=18)
440
453
  self.ax.set_ylabel(self.ylabel, fontsize=18)
454
+ # if self.grid:
455
+ # self.ax.grid()
456
+ # self.fig.savefig(out_img_name)
457
+
458
+ def plot_spc_bar(self, x_data: List[float], y_data: List[float], width: float=0.025, color: str='g') -> None:
459
+ self.ax.bar(x_data, y_data, width=width, color=color)
460
+
461
+ def save_fig(self, fig_name: str):
441
462
  if self.grid:
442
463
  self.ax.grid()
443
- self.fig.savefig(out_img_name)
444
-
464
+ self.fig.savefig(fig_name)
445
465
 
446
466
  def column_data(self, i: int) -> List[float]:
447
467
  result = []
@@ -751,6 +771,7 @@ class GaussCalc(LinuxInterface):
751
771
 
752
772
 
753
773
  class NewtonXCalc(LinuxInterface):
774
+ au = 0.5291772083
754
775
  def __init__(self, work_path: str) -> None:
755
776
  self.work_path = work_path
756
777
  self.temp_path = os.path.join(work_path, 'TEMP')
@@ -781,7 +802,7 @@ class NewtonXCalc(LinuxInterface):
781
802
  # check whether trnasfer success (delete /dev/null and then check the output log)
782
803
  self.exec(f'$NX/xyz2nx < {geom_path} &> /dev/null')
783
804
 
784
- def run_dynamic(self, freq_file: str, atom_num: int, NEA_point: int) -> None:
805
+ def run_dynamic_old(self, freq_file: str, atom_num: int, NEA_point: int) -> None:
785
806
  self.mv(freq_file, os.path.join(self.NX_path, 'freq.out') )
786
807
  nx_inp = '&dat\n nact = 2\n numat = %d\n npoints = %d\n file_geom = geom\n iprog = 4\n' % (atom_num, NEA_point) + \
787
808
  ' file_nmodes = freq.out\n anh_f = 1\n temp = 0.0\n ics_flg = n\n chk_e = 0\n' + \
@@ -792,8 +813,49 @@ class NewtonXCalc(LinuxInterface):
792
813
  if err_code != 0 or out != '':
793
814
  err_print(f'Newton-X calculation failed!!!\nstatus code: {err_code} (0 stands for normal exit, none 0 stands for error)\noutput: {out}')
794
815
  # todo 3: remove NX temp folder and other uncessary folder
795
-
816
+
817
+ def run_dynamic(self, freq_file: str, atom_num: int, NEA_point: int) -> None:
818
+ inp_name = 'initqp_input'
819
+ self.mv(freq_file, os.path.join(self.NX_path, 'freq.out') )
820
+ nx_inp = '&dat\n nact = 2\n numat = %d\n npoints = %d\n file_geom = "geom"\n iprog = 4\n' % (atom_num, NEA_point) + \
821
+ ' file_nmodes = "freq.out"\n anh_f = 1\n temp = 0.0\n ics_flg = "n"\n chk_e = 0\n' + \
822
+ ' nis = 1\n nfs = 2\n kvert = 1\n de = 100\n prog = 6.5\n iseed = 1234\n lvprt = 1\n/\n'
823
+ with open(inp_name, 'w') as f:
824
+ f.write(nx_inp)
825
+ # err_code, out = self.exec(f'$NX/initcond.pl > NX-MD.log 2>&1')
826
+ err_code, out = self.exec('$NX/mk_qvector < initqp_input ; ' \
827
+ '$NX/weight < initqp_input &> weight.log ; ' \
828
+ '$NX/initqp < initqp_input &> initqp.log ')
829
+ if err_code != 0 or out != '':
830
+ err_print(f'Newton-X calculation failed!!!\nstatus code: {err_code} (0 stands for normal exit, none 0 stands for error)\noutput: {out}')
831
+
796
832
  def restore_multi_xyz(self, atom_num: int):
833
+ with open('ini_qv') as f:
834
+ data = f.readlines()
835
+ elem = Molecule.read_element_label('geom')
836
+ cnt = 0
837
+ mole = Molecule()
838
+ for line in data[1:]:
839
+ tmp = line.split()
840
+ if len(tmp) == 2:
841
+ # if cnt:
842
+ self.multi_xyz.append(mole)
843
+ mole = Molecule()
844
+ cnt = 0
845
+ elif len(tmp) == 6:
846
+ x, y, z = self._process_ini_qv_line(tmp)
847
+ atom = Atom(x, y, z, elem[cnt])
848
+ cnt += 1
849
+ mole.atoms.append(atom)
850
+ else:
851
+ err_print('processing ini_qv failed! exit!')
852
+ exit()
853
+
854
+ def _process_ini_qv_line(self, splited_line: List[str]) -> List[float]:
855
+ xyz = map(lambda x: float(x.replace('D', 'e')), splited_line[0: 3])
856
+ return list(map(lambda x: self.au * x, xyz))
857
+
858
+ def restore_multi_xyz_old(self, atom_num: int):
797
859
  # working directory: In self.NX_path
798
860
  awk_inp = '''atom_num=%d \n''' % (atom_num) + \
799
861
  r'''sed -n /Geometry/,/Velocity\ in\ NX/p final_output | sed /Velocity/d | awk '{printf ("%s\t", $1)}''' + \
@@ -987,18 +1049,14 @@ class ML_calc(LinuxInterface):
987
1049
  with open(orig_file) as f:
988
1050
  orig = f.read().splitlines()
989
1051
  orig_num = len(orig)
990
- rtn_value: LineDate = LineDate('')
1052
+ mixed_data = []
991
1053
  for idx, e in enumerate(est):
992
1054
  if idx > orig_num - 1:
993
- # use est value
994
- if float(e) < 0:
995
- rtn_value += '0'
996
- else:
997
- rtn_value += e
998
- else:
999
- # use orig value
1000
- rtn_value += orig[idx]
1001
- return rtn_value.string
1055
+ tmp = e if float(e) > 0.0 else '0.0'
1056
+ else: # use orig value
1057
+ tmp = orig[idx]
1058
+ mixed_data.append(tmp)
1059
+ return '\n'.join(mixed_data)
1002
1060
 
1003
1061
  def mix_multiple_file(self, max_state: int, est_path: str, orig_path: str, out_path: str) -> None:
1004
1062
  for i in range(1, max_state + 1):
@@ -1038,6 +1096,8 @@ class ML_calc(LinuxInterface):
1038
1096
  if not self.exist_path(path):
1039
1097
  self.mkdir(path)
1040
1098
  self.cd(path)
1099
+ with open('ml.inp', 'w') as f:
1100
+ f.write(self.inp.string)
1041
1101
  s = StringIO()
1042
1102
  with redirect_stdout(s):
1043
1103
  prg = os.path.join(self.program_path, 'MLatomF')
@@ -1046,6 +1106,8 @@ class ML_calc(LinuxInterface):
1046
1106
  print(proc.stdout.read().decode('utf-8'))
1047
1107
  err = proc.stderr.read().decode('utf-8')
1048
1108
  self.ML_output = s.getvalue()
1109
+ with open('log', 'w') as f:
1110
+ f.write(self.ML_output)
1049
1111
  if err:
1050
1112
  warning_print(f'MLatom.run_ML returns a non-empty error: {err}, PAY ATTENTION to it.')
1051
1113
  self.inp: LineDate = LineDate('')
@@ -1173,13 +1235,13 @@ class CrossSection_calc(LinuxInterface):
1173
1235
  ##### data pre-process #####
1174
1236
  E_max = -10000
1175
1237
  E_min = 10000
1176
- whole_num_point = 0
1238
+ # whole_num_point = 0
1177
1239
  for E_data in self.E_data_list:
1178
1240
  tmp_max = max(E_data)
1179
1241
  tmp_min = min(E_data)
1180
1242
  E_max = tmp_max if tmp_max > E_max else E_max
1181
1243
  E_min = tmp_min if tmp_min < E_min else E_min
1182
- whole_num_point = len(self.E_data_list[0]) # todo: check the E and f is has the same number
1244
+ # whole_num_point = len(self.E_data_list[0]) # todo: check the E and f is has the same number
1183
1245
  range_min = E_min - self.kappa * self.delta
1184
1246
  range_max = E_max + self.kappa * self.delta
1185
1247
  self.x_min = range_min
@@ -1194,13 +1256,48 @@ class CrossSection_calc(LinuxInterface):
1194
1256
  while de < range_max:
1195
1257
  de_list.append(de)
1196
1258
  de += self.eps
1197
- pool = mp.Pool()
1198
- result_list = pool.map(self._calc_at_de, de_list)
1199
- pool.close()
1200
- pool.join()
1201
- for each in result_list:
1202
- de, wavelength, cross_section = each
1203
- file_handle.write('%.4f %.4f %.8f\n' % (de, wavelength, cross_section))
1259
+
1260
+ whole_num_point = len(self.E_data_list[0])
1261
+ c_E_list = ((c_double * whole_num_point) * self.max_state)()
1262
+ c_f_list = ((c_double * whole_num_point) * self.max_state)()
1263
+ for state_index, E_data in enumerate(self.E_data_list):
1264
+ f_data = self.f_data_list[state_index]
1265
+ for target_index, E in enumerate(E_data):
1266
+ f = f_data[target_index]
1267
+ c_E_list[state_index][target_index] = E
1268
+ c_f_list[state_index][target_index] = f
1269
+ de_num = len(de_list)
1270
+ c_cs = (c_double * de_num)()
1271
+ c_de_list = (c_double* de_num)()
1272
+ wavelength = []
1273
+ for idx, de in enumerate(de_list):
1274
+ c_de_list[idx] = de
1275
+ wavelength.append(self.ev2nm / de)
1276
+ cs = CDLL(os.path.join(py_script_path, 'cs.so'))
1277
+ c_delta = c_double(self.delta)
1278
+ c_coeff = c_double(self.coeff)
1279
+ c_cs_coeff = c_double(self.cs_coeff)
1280
+ c_de_num = c_long(de_num)
1281
+ # print(f'coeff: {self.coeff}, divided: {self.devided_num}')
1282
+ cs.cs_calc(c_E_list, c_f_list,
1283
+ self.max_state, whole_num_point,
1284
+ c_delta, c_coeff, c_de_num, c_cs_coeff,
1285
+ c_cs, c_de_list)
1286
+ cross_section = []
1287
+ for cs_single in c_cs:
1288
+ cross_section.append(cs_single)
1289
+ for idx, de in enumerate(de_list):
1290
+ w, c = wavelength[idx], cross_section[idx]
1291
+ file_handle.write('%.4f %.4f %.8f\n' % (de, w, c))
1292
+
1293
+
1294
+ # pool = mp.get_context('spawn').Pool()
1295
+ # result_list = pool.map(self._calc_at_de, de_list)
1296
+ # pool.close()
1297
+ # pool.join()
1298
+ # for each in result_list:
1299
+ # de, wavelength, cross_section = each
1300
+ # file_handle.write('%.4f %.4f %.8f\n' % (de, wavelength, cross_section))
1204
1301
  file_handle.close()
1205
1302
 
1206
1303
  def _gauss(self, E: float, dE_0n: float) -> float:
@@ -1296,7 +1393,8 @@ class ML_cross_section(CrossSection_calc, ML_calc):
1296
1393
  def ML_train_all(self):
1297
1394
  # todo 3: to to record log
1298
1395
  self._iter_calc_QC(0, self.TD_point)
1299
- self._train_epoch(self.TD_point)
1396
+ rmse = self._train_epoch(self.TD_point)
1397
+ print(f'\nRMSE_geom value for {self.TD_point} point: {rmse}')
1300
1398
  self._train_final(self.TD_point)
1301
1399
  self._collect_ML_result(self.use_model_pred_path)
1302
1400
  self.mix_multiple_file(self.max_state, self.pred_data_path, self.this.gauss.gauss_data_path, self.mix_data_path)
@@ -1400,7 +1498,7 @@ class ML_cross_section(CrossSection_calc, ML_calc):
1400
1498
  self.set_model_inp(MLmodelIn=f'{sym_state}.unf')
1401
1499
  self.add_other('molDescriptor', 'RE'); self.add_other('molDescrType', 'unsorted')
1402
1500
  self.run_ML(os.getcwd())
1403
-
1501
+
1404
1502
  def _collect_ML_result(self, final_path: str):
1405
1503
  for sym, state in product(['E', 'f'], range(1, self.max_state + 1)):
1406
1504
  sym_state = sym + str(state)
@@ -2204,7 +2302,7 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
2204
2302
  print_citation()
2205
2303
 
2206
2304
  def invoke_by_API(self, Nexcitations: int=3, nMaxPoints: int=10000, nNEApoints: int=0, MLpoints: int=500, deltaQCNEA: float=0.05):
2207
- print_citation()
2305
+ #print_citation()
2208
2306
  self.pre_define()
2209
2307
  ##### args #####
2210
2308
  self.max_state: int = Nexcitations
@@ -2222,6 +2320,8 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
2222
2320
  ##### file existance #####
2223
2321
  self.work_path = os.getcwd()
2224
2322
  self.py_script_path = os.path.dirname(os.path.abspath(__file__)) #self.py_script_path = os.path.abspath(__file__[:__file__.rfind('/')])
2323
+ global py_script_path
2324
+ py_script_path = self.py_script_path
2225
2325
  self.gauss_opt_inp_name: str = 'gaussian_optfreq.com' # self.gauss_opt_inp_name: str = 'opt-freq.com'
2226
2326
  self.gauss_TD_inp_name: str = 'gaussian_ef.com' # self.gauss_TD_inp_name: str = 'TD.com'
2227
2327
  self.gauss_opt_log_name: str = 'gaussian_optfreq.log' # self.gauss_opt_log_name: str = 'opt-freq.log'
@@ -2315,6 +2415,7 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
2315
2415
  self.cd(self.cs_TD.cs_path)
2316
2416
  self.cs_TD.calc(self.gauss.gauss_data_path, self.max_state, self.delta_QC, self.cs_TD.TD_out_name) # use default delta=0.05
2317
2417
  opt_E_list, opt_f_list = self.gauss.process_one_gauss_log(os.path.join(self.gauss.all_log_path, '0.log'))
2418
+ self.opt_E_list, self.opt_f_list = opt_E_list, opt_f_list
2318
2419
  # self.cs_TD.calc_SPC(opt_E_list, opt_f_list, self.delta_SPC, self.cs_TD.SPC_out_name)
2319
2420
  self.cs_SPC.read_data_from_para(opt_E_list, opt_f_list)
2320
2421
  SPC_delta = 0.3
@@ -2342,12 +2443,13 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
2342
2443
  plot.plot_file(self.cs_TD.SPC_out_name, spc_nea_name, x_column=1, y_column=3)
2343
2444
  # plot.plot_file(self.cs_TD.SPC_out_name, 'SPC-cross-section.png', x_column=1, y_column=3)
2344
2445
  else:
2345
- file_names = []
2346
- legend_names = []
2347
- colors = []
2446
+ file_names: List[str] = []
2447
+ legend_names: List[str] = []
2448
+ colors: List[str] = []
2449
+ plot = Plot()
2348
2450
  if self.exist_path(os.path.join(self.work_path, 'cross-section_ref.dat')):
2349
2451
  file_names.append('cross-section_ref.dat')
2350
- legend_names.append('ref-NEA')
2452
+ legend_names.append('ref')
2351
2453
  colors.append('k')
2352
2454
  self.cp(os.path.join(self.work_path, 'cross-section_ref.dat'), self.cs_ML.cs_path)
2353
2455
  if self.exist_path(os.path.join(self.cs_ML.cs_path, self.cs_TD.TD_out_name)) and plotQCNEA:
@@ -2362,6 +2464,8 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
2362
2464
  file_names.append(self.cs_SPC.SPC_out_name)
2363
2465
  legend_names.append('QC-SPC')
2364
2466
  colors.append('g')
2467
+ plot.plot_spc_bar(self.opt_E_list, self.opt_f_list)
2468
+ # plot.ax.set_xlim(min(self.opt_E_list), max(self.opt_E_list))
2365
2469
  if False:
2366
2470
  if self.exist_path(os.path.join(self.work_path, 'cross-section_ref.dat')):
2367
2471
  # file_names.append('cross-section_ref.dat')
@@ -2377,9 +2481,11 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
2377
2481
  if not file_names:
2378
2482
  err_print('not caluclated cross-section file exists. Exit!')
2379
2483
  exit()
2380
- plot = Plot()
2381
2484
  plot.set_info(xlabel='Energy, eV', ylabel=r'Cross section, $\mathrm{\AA^2}$ molecule$^{–1}$', grid=False)
2382
- plot.plot_multiple_file(file_names, legend_names, colors, out_img_name='plot.png', x_column=1, y_column=3)
2485
+ plot.plot_multiple_file(file_names, legend_names, colors, x_column=1, y_column=3)
2486
+ plot.ax.set_ylim(bottom=0.0)
2487
+ plot.ax.margins(x=0.0)
2488
+ plot.save_fig('plot.png')
2383
2489
 
2384
2490
  def detect_E_f_and_calc(self):
2385
2491
  for i in range(1, self.max_state + 1):
@@ -2490,7 +2596,7 @@ def parse_api(args: List[str]):
2490
2596
  plotQCNEA = True
2491
2597
  elif splited[0].strip() == 'plotQCSPC':
2492
2598
  plotQCSPC = True
2493
- elif splited[0].strip() == 'cross-section':
2599
+ elif splited[0].strip() in ['crossSection', 'cross-section', 'cross_section', 'MLNEA', 'ML-NEA', 'ML_NEA']:
2494
2600
  pass
2495
2601
  else:
2496
2602
  err_print('unrecognised parameter: %s. exit!' % splited[0])
@@ -2502,8 +2608,10 @@ def parse_api(args: List[str]):
2502
2608
  nMaxPoints = transfer(splited[1], 'nMaxPoints', int)
2503
2609
  elif splited[0].strip().lower() == nQMpoints_str.lower():
2504
2610
  nQMpoints = transfer(splited[1], 'nQMpoints', int)
2505
- elif splited[0].strip().lower() == MLpoints_str.lower():
2506
- MLpoints = transfer(splited[1], 'MLpoints', int)
2611
+ elif splited[0].strip().lower() in [MLpoints_str.lower(), 'nNEpoints'.lower()]:
2612
+ MLpoints = transfer(splited[1], 'nNEpoints', int)
2613
+ # elif splited[0].strip().lower() == MLpoints_str.lower():
2614
+ # MLpoints = transfer(splited[1], 'MLpoints', int)
2507
2615
  elif splited[0].strip().lower() == deltaQCNEA_str.lower():
2508
2616
  deltaQCNEA = transfer(splited[1], 'deltaQCNEA', float)
2509
2617
  else:
@@ -2521,7 +2629,7 @@ def print_help():
2521
2629
  usage: MLatom.py cross-section [optional arguments]
2522
2630
 
2523
2631
  optional arguments:
2524
- Nexcitations=N number of excited states to calculate. (default=3)
2632
+ nExcitations=N number of excited states to calculate. (default=3)
2525
2633
  nQMpoints=N user-defined number of QM calculations for training ML.
2526
2634
  (default=0, number of QM calculations will be determined iteratively)
2527
2635
  plotQCNEA requests plotting QC-NEA cross section
@@ -2530,7 +2638,7 @@ def print_help():
2530
2638
 
2531
2639
  advanced arguments:
2532
2640
  nMaxPoints=N maximum number of QC calculations in the iterative procedure. (default=10000)
2533
- MLpoints=N number of ML calculations. (default=50000)
2641
+ nNEpoints=N number of ML ensemble prediction. (default=50000)
2534
2642
 
2535
2643
  Environment setting (no needed)
2536
2644
  $NX Newton-X environment
@@ -2582,6 +2690,7 @@ def print_citation():
2582
2690
  print('\n %s:\n\t%s'%('NEWTON-X',cs_algorithm))
2583
2691
  print('*'*80)
2584
2692
 
2693
+
2585
2694
  if __name__ == "__main__":
2586
2695
  ControlPartProxy.invoke_paper_recur_self()
2587
2696
  # ControlPartProxy.invoke_paper_recur_api(nTDpoints=200, plotQCNEA=True, deltaQCNEA=0.08)