nomad-parser-plugins-atomistic 1.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 (80) hide show
  1. atomisticparsers/__init__.py +400 -0
  2. atomisticparsers/amber/__init__.py +19 -0
  3. atomisticparsers/amber/__main__.py +31 -0
  4. atomisticparsers/amber/metainfo/__init__.py +19 -0
  5. atomisticparsers/amber/metainfo/amber.py +495 -0
  6. atomisticparsers/amber/parser.py +42 -0
  7. atomisticparsers/asap/__init__.py +19 -0
  8. atomisticparsers/asap/__main__.py +31 -0
  9. atomisticparsers/asap/metainfo/__init__.py +19 -0
  10. atomisticparsers/asap/metainfo/asap.py +75 -0
  11. atomisticparsers/asap/parser.py +197 -0
  12. atomisticparsers/bopfox/__init__.py +19 -0
  13. atomisticparsers/bopfox/__main__.py +31 -0
  14. atomisticparsers/bopfox/metainfo/__init__.py +19 -0
  15. atomisticparsers/bopfox/metainfo/bopfox.py +225 -0
  16. atomisticparsers/bopfox/parser.py +808 -0
  17. atomisticparsers/dftbplus/__init__.py +19 -0
  18. atomisticparsers/dftbplus/__main__.py +31 -0
  19. atomisticparsers/dftbplus/metainfo/__init__.py +19 -0
  20. atomisticparsers/dftbplus/metainfo/dftbplus.py +217 -0
  21. atomisticparsers/dftbplus/parser.py +500 -0
  22. atomisticparsers/dlpoly/__init__.py +19 -0
  23. atomisticparsers/dlpoly/__main__.py +31 -0
  24. atomisticparsers/dlpoly/metainfo/__init__.py +19 -0
  25. atomisticparsers/dlpoly/metainfo/dl_poly.py +312 -0
  26. atomisticparsers/dlpoly/parser.py +798 -0
  27. atomisticparsers/gromacs/__init__.py +19 -0
  28. atomisticparsers/gromacs/__main__.py +31 -0
  29. atomisticparsers/gromacs/metainfo/__init__.py +19 -0
  30. atomisticparsers/gromacs/metainfo/gromacs.py +2388 -0
  31. atomisticparsers/gromacs/parser.py +1581 -0
  32. atomisticparsers/gromos/__init__.py +19 -0
  33. atomisticparsers/gromos/__main__.py +31 -0
  34. atomisticparsers/gromos/metainfo/__init__.py +19 -0
  35. atomisticparsers/gromos/metainfo/gromos.py +1995 -0
  36. atomisticparsers/gromos/parser.py +58 -0
  37. atomisticparsers/gulp/__init__.py +19 -0
  38. atomisticparsers/gulp/__main__.py +31 -0
  39. atomisticparsers/gulp/metainfo/__init__.py +19 -0
  40. atomisticparsers/gulp/metainfo/gulp.py +1117 -0
  41. atomisticparsers/gulp/parser.py +1316 -0
  42. atomisticparsers/h5md/__init__.py +19 -0
  43. atomisticparsers/h5md/__main__.py +31 -0
  44. atomisticparsers/h5md/metainfo/__init__.py +19 -0
  45. atomisticparsers/h5md/metainfo/h5md.py +239 -0
  46. atomisticparsers/h5md/parser.py +901 -0
  47. atomisticparsers/lammps/__init__.py +19 -0
  48. atomisticparsers/lammps/__main__.py +31 -0
  49. atomisticparsers/lammps/metainfo/__init__.py +19 -0
  50. atomisticparsers/lammps/metainfo/lammps.py +1417 -0
  51. atomisticparsers/lammps/parser.py +1753 -0
  52. atomisticparsers/libatoms/__init__.py +19 -0
  53. atomisticparsers/libatoms/__main__.py +31 -0
  54. atomisticparsers/libatoms/metainfo/__init__.py +19 -0
  55. atomisticparsers/libatoms/metainfo/lib_atoms.py +251 -0
  56. atomisticparsers/libatoms/parser.py +38 -0
  57. atomisticparsers/namd/__init__.py +19 -0
  58. atomisticparsers/namd/__main__.py +31 -0
  59. atomisticparsers/namd/metainfo/__init__.py +19 -0
  60. atomisticparsers/namd/metainfo/namd.py +1605 -0
  61. atomisticparsers/namd/parser.py +312 -0
  62. atomisticparsers/tinker/__init__.py +19 -0
  63. atomisticparsers/tinker/__main__.py +31 -0
  64. atomisticparsers/tinker/metainfo/__init__.py +18 -0
  65. atomisticparsers/tinker/metainfo/tinker.py +1363 -0
  66. atomisticparsers/tinker/parser.py +685 -0
  67. atomisticparsers/utils/__init__.py +22 -0
  68. atomisticparsers/utils/mdanalysis.py +662 -0
  69. atomisticparsers/utils/parsers.py +226 -0
  70. atomisticparsers/xtb/__init__.py +19 -0
  71. atomisticparsers/xtb/__main__.py +32 -0
  72. atomisticparsers/xtb/metainfo/__init__.py +19 -0
  73. atomisticparsers/xtb/metainfo/xtb.py +256 -0
  74. atomisticparsers/xtb/parser.py +979 -0
  75. nomad_parser_plugins_atomistic-1.0.dist-info/LICENSE +202 -0
  76. nomad_parser_plugins_atomistic-1.0.dist-info/METADATA +327 -0
  77. nomad_parser_plugins_atomistic-1.0.dist-info/RECORD +80 -0
  78. nomad_parser_plugins_atomistic-1.0.dist-info/WHEEL +5 -0
  79. nomad_parser_plugins_atomistic-1.0.dist-info/entry_points.txt +15 -0
  80. nomad_parser_plugins_atomistic-1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,312 @@
1
+ #
2
+ # Copyright The NOMAD Authors.
3
+ #
4
+ # This file is part of NOMAD.
5
+ # See https://nomad-lab.eu for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ import os
21
+ import logging
22
+ import numpy as np
23
+ from typing import Dict, Any
24
+
25
+ from nomad.units import ureg
26
+ from nomad.datamodel import EntryArchive
27
+ from nomad.parsing.file_parser import TextParser, Quantity
28
+ from runschema.run import Run, Program
29
+ from runschema.method import Method
30
+ from simulationworkflowschema import MolecularDynamics
31
+ from atomisticparsers.utils import MDAnalysisParser, MDParser
32
+ from .metainfo import namd # pylint: disable=unused-import
33
+
34
+
35
+ MOL = 6.022140857e23
36
+ re_f = r'[-+]?\d+\.\d*(?:[Ee][-+]\d+)?'
37
+ re_n = r'[\n\r]'
38
+
39
+
40
+ class ConfigParser(TextParser):
41
+ def init_quantities(self):
42
+ self._quantities = [
43
+ Quantity(
44
+ 'parameter',
45
+ rf'([\w\-]+) +(.+){re_n}',
46
+ repeats=True,
47
+ str_operation=lambda x: x.split(' ', 1),
48
+ )
49
+ ]
50
+
51
+ def get_parameters(self):
52
+ return {parameter[0]: parameter[1] for parameter in self.get('parameter', [])}
53
+
54
+
55
+ class MainfileParser(TextParser):
56
+ def init_quantities(self):
57
+ self._quantities = [
58
+ Quantity(
59
+ 'version_arch',
60
+ r'Info\: NAMD ([\d\.]+) for (.+)',
61
+ str_operation=lambda x: x.split(' ', 1),
62
+ convert=False,
63
+ ),
64
+ Quantity('config_file', r'Info\: Configuration file is (\S+)', dtype=str),
65
+ Quantity(
66
+ 'simulation_parameters',
67
+ r'Info\: SIMULATION PARAMETERS\:([\s\S]+?)Info\: SUMMARY',
68
+ sub_parser=TextParser(
69
+ quantities=[
70
+ Quantity(
71
+ 'parameter',
72
+ rf'Info\: ([A-Z][A-Z ]+) +([\d\.e\-\+]+)',
73
+ str_operation=lambda x: [
74
+ v.strip() for v in x.rsplit(' ', 1)
75
+ ],
76
+ repeats=True,
77
+ ),
78
+ Quantity(
79
+ 'cell',
80
+ r'PERIODIC CELL BASIS \d +(.+)',
81
+ repeats=True,
82
+ dtype=np.dtype(np.float64),
83
+ ),
84
+ Quantity(
85
+ 'output_file', r'Info\: OUTPUT FILENAME +(\S+)', dtype=str
86
+ ),
87
+ Quantity(
88
+ 'coordinate_file',
89
+ r'Info\: COORDINATE PDB +(\S+)',
90
+ dtype=str,
91
+ ),
92
+ Quantity(
93
+ 'structure_file', r'Info\: STRUCTURE FILE +(\S+)', dtype=str
94
+ ),
95
+ Quantity(
96
+ 'parameter_file',
97
+ r'Info\: PARAMETERS +(\S+)',
98
+ dtype=str,
99
+ repeats=True,
100
+ ),
101
+ ]
102
+ ),
103
+ ),
104
+ Quantity(
105
+ 'step',
106
+ rf'ENERGY\: +(\d+ +{re_f}.+)',
107
+ repeats=True,
108
+ dtype=np.dtype(np.float64),
109
+ ),
110
+ Quantity(
111
+ 'timing',
112
+ r'TIMING\: *(\d+) *CPU\: *[\d\.]+, +[\d\.]+/step +Wall\: *([\d\.]+), *([\d\.]+)/step',
113
+ repeats=True,
114
+ dtype=np.dtype(np.float64),
115
+ ),
116
+ Quantity('total_time', r'WallClock: +([\d\.]+)', dtype=float),
117
+ Quantity(
118
+ 'property_names',
119
+ r'ETITLE\: +(.+)',
120
+ str_operation=lambda x: x.lower().strip().split(),
121
+ ),
122
+ Quantity(
123
+ 'coordinates_write_step',
124
+ r'WRITING COORDINATES TO OUTPUT FILE AT STEP (\d+)',
125
+ repeats=True,
126
+ dtype=np.int32,
127
+ ),
128
+ ]
129
+
130
+ def get_parameters(self):
131
+ return {
132
+ p[0]: p[1]
133
+ for p in self.get('simulation_parameters', {}).get('parameter', [])
134
+ }
135
+
136
+
137
+ class NAMDParser(MDParser):
138
+ def __init__(self) -> None:
139
+ self.mainfile_parser = MainfileParser()
140
+ self.config_parser = ConfigParser()
141
+ self.traj_parser = MDAnalysisParser()
142
+ self._metainfo_map = {
143
+ 'bond': 'energy_contribution_bond',
144
+ 'angle': 'energy_contribution_angle',
145
+ 'dihed': 'energy_contribution_dihedral',
146
+ 'imprp': 'energy_contribution_improper',
147
+ 'elect': 'energy_electronic',
148
+ 'vdw': 'energy_van_der_waals',
149
+ 'boundary': 'energy_contribution_boundary',
150
+ 'misc': 'energy_contribution_miscellaneous',
151
+ 'total': 'energy_total',
152
+ 'temp': 'temperature',
153
+ 'total3': 'energy_x_namd_total3',
154
+ 'tempavg': 'x_namd_temperature_average',
155
+ 'pressure': 'pressure',
156
+ 'gpressure': 'x_namd_gpressure',
157
+ 'volume': 'x_namd_volume',
158
+ 'pressavg': 'x_namd_pressure_average',
159
+ 'gpressavg': 'x_namd_gpressure_average',
160
+ }
161
+ super().__init__()
162
+
163
+ def write_to_archive(self) -> None:
164
+ """
165
+ Main parsing function. Populates the archive with the quantities parsed from the
166
+ mainfile parser and auxilliary file parsers.
167
+ """
168
+ self.mainfile_parser.mainfile = self.mainfile
169
+ self.mainfile_parser.logger = self.logger
170
+ self.config_parser.logger = self.logger
171
+ self.traj_parser.logger = self.logger
172
+ self.maindir = os.path.dirname(self.mainfile)
173
+
174
+ sec_run = Run()
175
+ self.archive.run.append(sec_run)
176
+ version_arch = self.mainfile_parser.get('version_arch', [None, None])
177
+ sec_run.program = Program(name='namd', version=version_arch[0])
178
+ sec_run.program.x_namd_build_osarch = version_arch[1]
179
+
180
+ # read the config file and simulation parameters
181
+ self.config_parser.mainfile = os.path.join(
182
+ self.maindir, os.path.basename(self.mainfile_parser.get('config_file', ''))
183
+ )
184
+ sec_method = Method()
185
+ sec_run.method.append(sec_method)
186
+ sec_method.x_namd_input_parameters = self.config_parser.get_parameters()
187
+ sec_method.x_namd_simulation_parameters = self.mainfile_parser.get_parameters()
188
+
189
+ def get_system_data(index):
190
+ if self.traj_parser.mainfile is None:
191
+ return {}
192
+
193
+ labels = self.traj_parser.get_atom_labels(index)
194
+ positions = self.traj_parser.get_positions(index)
195
+ velocities = self.traj_parser.get_velocities(index)
196
+ lattice_vectors = self.traj_parser.get_lattice_vectors(index)
197
+ if lattice_vectors is None:
198
+ # get if from simulation parameters
199
+ lattice_vectors = self.mainfile_parser.get(
200
+ 'simulation_parameters', {}
201
+ ).get('cell')
202
+ lattice_vectors = (
203
+ lattice_vectors * ureg.angstrom
204
+ if lattice_vectors is not None
205
+ else lattice_vectors
206
+ )
207
+ return dict(
208
+ atoms=dict(
209
+ labels=labels,
210
+ positions=positions,
211
+ velocities=velocities,
212
+ lattice_vectors=lattice_vectors,
213
+ )
214
+ )
215
+
216
+ # input structure
217
+ parameters = self.mainfile_parser.get('simulation_parameters', {})
218
+ self.traj_parser.mainfile = os.path.join(
219
+ self.maindir, parameters.get('coordinate_file')
220
+ )
221
+
222
+ # initial_system
223
+ self.parse_trajectory_step(get_system_data(0))
224
+
225
+ # energy unit is kcal / mol
226
+ n_atoms = self.traj_parser.get('n_atoms')
227
+ energy_unit = ureg.J * 4184.0 * n_atoms / MOL
228
+
229
+ # trajectories
230
+ # TODO other formats
231
+ output_file = parameters.get('output_file')
232
+ self.traj_parser.mainfile = os.path.join(self.maindir, f'{output_file}.coor')
233
+ self.traj_parser.options = dict(format='coor')
234
+ self.traj_parser.auxilliary_files = []
235
+
236
+ # output properties at each step
237
+ property_names = self.mainfile_parser.get('property_names', [])
238
+ # saved trajectories
239
+ saved_trajectories = self.mainfile_parser.get('coordinates_write_step', [])
240
+ # md data
241
+ steps_data = self.mainfile_parser.get('step', [])
242
+ # set up md parser
243
+ self.n_atoms = n_atoms
244
+ self.trajectory_steps = [0] + saved_trajectories
245
+ self.thermodynamics_steps = [int(step[0]) for step in steps_data]
246
+
247
+ timings = self.mainfile_parser.get('timing', [])
248
+ timing_step = sec_method.x_namd_simulation_parameters.get(
249
+ 'TIMING OUTPUT STEPS', 1
250
+ )
251
+ time_per_step = self.mainfile_parser.get('total_time', 0.0) / len(steps_data)
252
+
253
+ for step in self.trajectory_steps:
254
+ if not step or self.traj_parser.mainfile is None:
255
+ continue
256
+
257
+ index = saved_trajectories.index(step)
258
+ self.parse_trajectory_step(get_system_data(index))
259
+
260
+ for step_data in steps_data:
261
+ step = int(step_data[0])
262
+ if step not in self.thermodynamics_steps:
263
+ continue
264
+
265
+ energy: Dict[str, Any] = {}
266
+ thermo_data = {'step': step, 'energy': energy}
267
+ for index, name in enumerate(property_names):
268
+ metainfo_name = self._metainfo_map.get(name)
269
+ if metainfo_name is None:
270
+ continue
271
+ value = step_data[index]
272
+ if metainfo_name.startswith('energy_contribution_'):
273
+ energy.setdefault('contributions', [])
274
+ metainfo_name = metainfo_name.replace('energy_contribution_', '')
275
+ energy['contributions'].append(
276
+ dict(kind=metainfo_name, value=value * energy_unit)
277
+ )
278
+ elif metainfo_name.startswith('energy_'):
279
+ metainfo_name = metainfo_name.replace('energy_', '')
280
+ energy[metainfo_name] = dict(value=value * energy_unit)
281
+ if metainfo_name == 'total':
282
+ # include potential and kinetic terms
283
+ for key in ['kinetic', 'potential']:
284
+ try:
285
+ energy['total'][key] = (
286
+ step_data[property_names.index(key)] * energy_unit
287
+ )
288
+ except Exception:
289
+ pass
290
+ elif 'pressure' in metainfo_name:
291
+ thermo_data[metainfo_name] = value * ureg.bar
292
+ elif 'temperature' in metainfo_name:
293
+ thermo_data[metainfo_name] = value * ureg.kelvin
294
+ elif 'volume' in metainfo_name:
295
+ thermo_data[metainfo_name] = value * ureg.angstrom**3
296
+ # TODO forces
297
+ # timing
298
+ index_time = step // timing_step
299
+ if index_time < len(timings):
300
+ thermo_data['time_calculation'] = timings[index_time][2]
301
+ thermo_data['time_physical'] = (
302
+ 0 if index_time == 0 else timings[index_time - 1][1]
303
+ ) + timings[index_time][2] * (step % timing_step + 1)
304
+ elif time_per_step:
305
+ thermo_data['time_calculation'] = time_per_step
306
+ thermo_data['time_physical'] = time_per_step * step
307
+ self.parse_thermodynamics_step(thermo_data)
308
+
309
+ # workflow
310
+ self.archive.workflow2 = MolecularDynamics()
311
+
312
+ self.traj_parser.close()
@@ -0,0 +1,19 @@
1
+ #
2
+ # Copyright The NOMAD Authors.
3
+ #
4
+ # This file is part of NOMAD.
5
+ # See https://nomad-lab.eu for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ from .parser import TinkerParser
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright The NOMAD Authors.
3
+ #
4
+ # This file is part of NOMAD.
5
+ # See https://nomad-lab.eu for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ import sys
20
+ import json
21
+ import logging
22
+
23
+ from nomad.utils import configure_logging
24
+ from nomad.datamodel import EntryArchive
25
+ from atomisticparsers.tinker import TinkerParser
26
+
27
+ if __name__ == '__main__':
28
+ configure_logging(console_log_level=logging.DEBUG)
29
+ archive = EntryArchive()
30
+ TinkerParser().parse(sys.argv[1], archive, logging)
31
+ json.dump(archive.m_to_dict(), sys.stdout, indent=2)
@@ -0,0 +1,18 @@
1
+ #
2
+ # Copyright The NOMAD Authors.
3
+ #
4
+ # This file is part of NOMAD.
5
+ # See https://nomad-lab.eu for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ from . import tinker