Commit c602733f authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Added random generation artificial parser.

parent 80fe4236
......@@ -47,10 +47,11 @@ Parsers in NOMAD-coe use a *backend* to create output.
from nomad.parsing.backend import AbstractParserBackend, LocalBackend, LegacyLocalBackend, JSONStreamWriter, BadContextURI, WrongContextState
from nomad.parsing.parser import Parser, LegacyParser
from nomad.parsing.artificial import TemplateParser
from nomad.parsing.artificial import TemplateParser, GenerateRandomParser
from nomad.dependencies import dependencies_dict as dependencies
parsers = [
GenerateRandomParser(),
TemplateParser(),
LegacyParser(
python_git=dependencies['parsers/vasp'],
......@@ -85,4 +86,4 @@ parsers = [
""" Instanciation and constructor based config of all parsers. """
parser_dict = {parser.name: parser for parser in parsers}
""" A dict to access parsers by name. Usually 'parsers/<...>', e.g. 'parsers/vasp'. """
\ No newline at end of file
""" A dict to access parsers by name. Usually 'parsers/<...>', e.g. 'parsers/vasp'. """
......@@ -20,6 +20,9 @@ from typing import Callable, IO, Any
import json
import os.path
import numpy as np
import random
from ase.data import chemical_symbols
import numpy
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
......@@ -27,11 +30,8 @@ from nomad.parsing.backend import LocalBackend
from nomad.parsing.parser import Parser
class TemplateParser(Parser):
"""
A parser that generates data based on a template given via the
mainfile. The template is basically some archive json. Only
"""
class ArtificalParser(Parser):
""" Base class for artifical parsers based on VASP metainfo. """
def __init__(self):
super().__init__()
# use vasp metainfo, not to really use it, but because it works
......@@ -39,16 +39,35 @@ class TemplateParser(Parser):
relative_metainfo_path = "../../.dependencies/nomad-meta-info/meta_info/nomad_meta_info/vasp.nomadmetainfo.json"
meta_info_path = os.path.normpath(os.path.join(file_dir, relative_metainfo_path))
self.meta_info_env, _ = loadJsonFile(filePath=meta_info_path, dependencyLoader=None, extraArgsHandling=InfoKindEl.ADD_EXTRA_ARGS, uri=None)
self.name = 'parsers/template'
self.backend = None
def init_backend(self):
self.backend = LocalBackend(metaInfoEnv=self.meta_info_env, debug=False)
@property
def name(self):
return self.__class__.name
class TemplateParser(ArtificalParser):
"""
A parser that generates data based on a template given via the
mainfile. The template is basically some archive json. Only
"""
name = 'parsers/template'
def is_mainfile(self, filename: str, open: Callable[[str], IO[Any]]) -> bool:
return filename.endswith('template.json')
def add_section(self, section):
if not isinstance(section, dict):
print(section)
def transform_value(self, name, value):
""" allow subclasses to modify values """
return value
def transform_section(self, name, section):
""" allow subclasses to modify sections """
return section
def add_section(self, section):
name = section['_name']
index = self.backend.openSection(name)
......@@ -59,8 +78,9 @@ class TemplateParser(Parser):
if key.startswith('section_'):
values = value if isinstance(value, list) else [value]
for value in values:
self.add_section(value)
self.add_section(self.transform_section(key, value))
else:
value = self.transform_value(key, value)
if isinstance(value, list):
shape = self.meta_info_env[key].get('shape')
if shape is None or len(shape) == 0:
......@@ -74,9 +94,79 @@ class TemplateParser(Parser):
self.backend.closeSection(name, index)
def run(self, mainfile: str) -> LocalBackend:
self.backend = LocalBackend(metaInfoEnv=self.meta_info_env, debug=False)
self.init_backend()
template_json = json.load(open(mainfile, 'r'))
section = template_json['section_run'][0]
self.add_section(section)
self.backend.finishedParsingSession('ParseSuccess', [])
return self.backend
class GenerateRandomParser(TemplateParser):
name = 'parsers/random'
basis_set_types = [
'Numeric AOs', 'Gaussians', '(L)APW+lo', 'FLAPW', 'Plane waves',
'Real-space grid', 'Local-orbital minimum-basis']
electronic_structure_methods = [
'DFT', 'DFT+U', 'full-CI', 'CIS', 'CISD'
'CCS', 'CCS(D)', 'CCSD', 'CCSD(T)', 'CCSDT(Q)', 'MP2', 'MP3', 'MP4', 'MP5', 'MP6',
'G0W0', 'scGW', 'LDA', 'hybrid', 'CASPT2', 'MRCIS', 'MRCISD', 'RAS-CI']
XC_functional_names = [
'LDA_X', 'LDA_C', 'GGA_X', 'GGA_C', 'HYB_GGA_XC', 'MGGA_X', 'MGGA_C', 'HYB_MGGA_XC']
low_numbers = [1, 1, 2, 2, 2, 2, 2, 3, 3, 4]
def __init__(self):
super(GenerateRandomParser, self).__init__()
file_dir = os.path.dirname(os.path.abspath(__file__))
relative_template_file = "random_template.json"
template_file = os.path.normpath(os.path.join(file_dir, relative_template_file))
self.template = json.load(open(template_file, 'r'))
self.random = None
def is_mainfile(self, filename: str, open: Callable[[str], IO[Any]]) -> bool:
return os.path.basename(filename).startswith('random_')
def transform_section(self, name, section):
""" allow subclasses to modify sections """
if name == 'section_system':
atoms = []
atom_positions = []
# different atoms
for _ in range(0, random.choice(GenerateRandomParser.low_numbers)):
# ase data starts with a place holder value X, we don't want that
atom = random.choice(chemical_symbols[1:])
# atoms of the same number
for _ in range(0, random.choice(GenerateRandomParser.low_numbers)):
atoms.append(atom)
atom_positions.append([.0, .0, .0])
section['atom_labels'] = atoms
section['atom_positions'] = atom_positions
return section
else:
return section
def transform_value(self, name, value):
if name == 'program_basis_set_type':
return random.choice(GenerateRandomParser.basis_set_types)
elif name == 'electronic_structure_method':
return random.choice(GenerateRandomParser.electronic_structure_methods)
elif name == 'XC_functional_name':
return random.choice(GenerateRandomParser.XC_functional_names)
elif name == 'atom_positions':
return [numpy.random.uniform(0e-10, 1e-9, 3) for _ in value]
else:
return value
def run(self, mainfile: str) -> LocalBackend:
self.init_backend()
seed = int(os.path.basename(mainfile).split('_')[1])
random.seed(seed)
section = self.template['section_run'][0]
self.add_section(section)
self.backend.finishedParsingSession('ParseSuccess', [])
return self.backend
{
"section_run": [
{
"_name": "section_run",
"_gIndex": 0,
"program_name": "VASP",
"program_version": "4.6.35 3Apr08 complex parallel LinuxIFC",
"program_basis_set_type": "plane waves",
"section_method": [
{
"_name": "section_method",
"_gIndex": 0,
"electronic_structure_method": "DFT",
"section_XC_functionals": [
{
"_name": "section_XC_functionals",
"_gIndex": 0,
"XC_functional_name": "GGA_X_PBE"
}
]
}
],
"section_system": [
{
"_name": "section_system",
"_gIndex": 0,
"simulation_cell": [
[
5.76372622e-10,
0.0,
0.0
],
[
0.0,
5.76372622e-10,
0.0
],
[
0.0,
0.0,
4.0755698899999997e-10
]
],
"configuration_periodic_dimensions": [
true,
true,
true
],
"atom_positions": [
[
2.88186311e-10,
0.0,
2.0377849449999999e-10
],
[
0.0,
2.88186311e-10,
2.0377849449999999e-10
],
[
0.0,
0.0,
0.0
],
[
2.88186311e-10,
2.88186311e-10,
0.0
]
],
"atom_labels": [
"Br",
"K",
"Si",
"Si"
]
}
],
"section_single_configuration_calculation": [
{
"_name": "section_single_configuration_calculation",
"_gIndex": 0,
"single_configuration_calculation_to_system_ref": 0,
"single_configuration_to_calculation_method_ref": 0,
"energy_free": -1.5936767191492225e-18,
"energy_total": -1.5935696296699573e-18,
"energy_total_T0": -3.2126683561907e-22
}
],
"section_sampling_method": [
{
"_name": "section_sampling_method",
"_gIndex": 0,
"sampling_method": "geometry_optimization"
}
],
"section_frame_sequence": [
{
"_name": "section_frame_sequence",
"_gIndex": 0,
"frame_sequence_to_sampling_ref": 0,
"frame_sequence_local_frames_ref": [
0
]
}
]
}
]
}
\ No newline at end of file
......@@ -6,7 +6,6 @@
"program_name": "VASP",
"program_version": "4.6.35 3Apr08 complex parallel LinuxIFC",
"program_basis_set_type": "plane waves",
"program_compilation_datetime": 63536.0,
"section_method": [
{
"_name": "section_method",
......@@ -18,73 +17,14 @@
"_name": "section_XC_functionals",
"_gIndex": 0,
"XC_functional_name": "GGA_X_PBE"
},
{
"_name": "section_XC_functionals",
"_gIndex": 1,
"XC_functional_name": "GGA_C_PBE"
}
],
"section_method_basis_set": [
{
"_name": "section_method_basis_set",
"_gIndex": 0,
"mapping_section_method_basis_set_cell_associated": 0
}
],
"section_method_atom_kind": [
{
"_name": "section_method_atom_kind",
"_gIndex": 0,
"method_atom_kind_atom_number": 35,
"method_atom_kind_label": "Br",
"method_atom_kind_mass": 79.904,
"method_atom_kind_explicit_electrons": 7.0,
"method_atom_kind_pseudopotential_name": " PAW_PBE Br 06Sep2000 "
},
{
"_name": "section_method_atom_kind",
"_gIndex": 1,
"method_atom_kind_atom_number": 19,
"method_atom_kind_label": "K",
"method_atom_kind_mass": 39.098,
"method_atom_kind_explicit_electrons": 9.0,
"method_atom_kind_pseudopotential_name": " PAW_PBE K_sv 06Sep2000 "
},
{
"_name": "section_method_atom_kind",
"_gIndex": 2,
"method_atom_kind_atom_number": 14,
"method_atom_kind_label": "Si",
"method_atom_kind_mass": 28.085,
"method_atom_kind_explicit_electrons": 4.0,
"method_atom_kind_pseudopotential_name": " PAW_PBE Si 05Jan2001 "
}
]
}
],
"section_basis_set_cell_dependent": [
{
"_name": "section_basis_set_cell_dependent",
"_gIndex": 0,
"basis_set_planewave_cutoff": 5.81433707960672e-17
}
],
"section_system": [
{
"_name": "section_system",
"_gIndex": 1,
"configuration_raw_gid": "sX4Re16Q_-KSbCvIYPvikfbaxKxMe",
"atom_species": [
35,
19,
14,
14
],
"chemical_composition": "BrKSiSi",
"chemical_composition_reduced": "BrKSi2",
"chemical_composition_bulk_reduced": "BrKSi2",
"system_type": "Bulk",
"_gIndex": 0,
"simulation_cell": [
[
5.76372622e-10,
......
......@@ -23,6 +23,7 @@ from nomad.parsing import JSONStreamWriter, parser_dict
from nomad.parsing import LocalBackend, BadContextURI
parser_examples = [
('parsers/random', 'test/data/parsers/random_0'),
('parsers/template', 'tests/data/parsers/template.json'),
('parsers/exciting', '.dependencies/parsers/exciting/test/examples/Ag/INFO.OUT'),
('parsers/exciting', '.dependencies/parsers/exciting/test/examples/GW/INFO.OUT'),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment