Commit a28b872f authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Added tests for prototype matching.

parent d8e287b5
Pipeline #67723 passed with stages
in 12 minutes and 24 seconds
This diff is collapsed.
......@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import io
import re
import functools
import fractions
import json
......@@ -46,10 +47,10 @@ def get_normalized_wyckoff(atomic_number: np.array, wyckoff: np.array) -> dict:
Returns:
"""
atomCount = {}
atomCount: dict = {}
for nr in atomic_number:
atomCount[nr] = atomCount.get(nr, 0) + 1
wycDict = {}
wycDict: dict = {}
for i, wk in enumerate(wyckoff):
oldVal = wycDict.get(wk, {})
......@@ -128,7 +129,7 @@ def update_aflow_prototype_information(filepath: str) -> None:
module with updated symmetry tolerance parameter and the wyckoff positions
as detected by MatID.
This function is relative heavy and should only be run if the symmetry
This function is relatively heavy and should only be run if the symmetry
tolerance has been changed or the symmetry detection routine has been
updated.
......@@ -216,4 +217,5 @@ def update_aflow_prototype_information(filepath: str) -> None:
# Save the updated data
with io.open(filepath, "w", encoding="utf8") as f:
json_dump = json.dumps(aflow_prototypes, ensure_ascii=False, indent=4, cls=NoIndentEncoder)
json_dump = re.sub(r"\"(-?\d+(?:[\.,]\d+)?)\"", r'\1', json_dump) # Removes quotes around numbers
f.write("# -*- coding: utf-8 -*-\naflow_prototypes = {}\n".format(json_dump))
......@@ -500,7 +500,7 @@ class SystemNormalizer(SystemBasedNormalizer):
pSect = self._backend.openSection("section_prototype")
self._backend.addValue(
"prototype_assignment_method", "normalized-wyckoff")
"prototype_assignement_method", "normalized-wyckoff")
self._backend.addValue("prototype_label", labels['prototype_label'])
aid = labels.get("prototype_aflow_id")
if aid:
......
{
"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_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
]
}
]
}
]
}
......@@ -14,6 +14,8 @@
import pytest
import numpy as np
from ase import Atoms
import ase.build
from nomad import datamodel, config
from nomad.parsing import LocalBackend
......@@ -22,6 +24,7 @@ from nomad.normalizing import normalizers
from tests.test_parsing import parsed_vasp_example # pylint: disable=unused-import
from tests.test_parsing import parsed_template_example # pylint: disable=unused-import
from tests.test_parsing import parsed_example # pylint: disable=unused-import
from tests.test_parsing import parsed_template_no_system # pylint: disable=unused-import
from tests.test_parsing import parse_file
from tests.utils import assert_log
......@@ -105,6 +108,20 @@ def normalized_template_example(parsed_template_example) -> LocalBackend:
return run_normalize(parsed_template_example)
def run_normalize_for_structure(atoms: Atoms) -> LocalBackend:
template = parsed_template_no_system()
# Fill structural information
gid = template.openSection("section_system")
template.addArrayValues("atom_positions", atoms.get_positions() * 1E-10)
template.addArrayValues("atom_labels", atoms.get_chemical_symbols())
template.addArrayValues("simulation_cell", atoms.get_cell() * 1E-10)
template.addArrayValues("configuration_periodic_dimensions", atoms.get_pbc())
template.closeSection("section_system", gid)
return run_normalize(template)
def test_template_example_normalizer(parsed_template_example, no_warn, caplog):
run_normalize(parsed_template_example)
......@@ -219,6 +236,46 @@ def test_vasp_incar_system():
assert expected_value == backend_value
def test_aflow_prototypes():
"""Tests that some basis structures are matched with the correct AFLOW prototypes
"""
# Diamond
diamond = ase.build.bulk("C", crystalstructure="diamond", a=3.57)
backend = run_normalize_for_structure(diamond)
prototype_aflow_id = backend.get_value("prototype_aflow_id")
assert prototype_aflow_id == "A_cF8_227_a"
# BCC
bcc = ase.build.bulk("Fe", crystalstructure="bcc", a=2.856)
backend = run_normalize_for_structure(bcc)
prototype_aflow_id = backend.get_value("prototype_aflow_id")
assert prototype_aflow_id == "A_cI2_229_a"
# FCC
fcc = ase.build.bulk("Ge", crystalstructure="fcc", a=5.658)
backend = run_normalize_for_structure(fcc)
prototype_aflow_id = backend.get_value("prototype_aflow_id")
assert prototype_aflow_id == "A_cF4_225_a"
# Rocksalt
rocksalt = ase.build.bulk("NaCl", crystalstructure="rocksalt", a=5.64)
backend = run_normalize_for_structure(rocksalt)
prototype_aflow_id = backend.get_value("prototype_aflow_id")
assert prototype_aflow_id == "AB_cF8_225_a_b"
# Zincblende
zincblende = ase.build.bulk("ZnS", crystalstructure="zincblende", a=5.42)
backend = run_normalize_for_structure(zincblende)
prototype_aflow_id = backend.get_value("prototype_aflow_id")
assert prototype_aflow_id == "AB_cF8_216_c_a"
# Wurtzite
wurtzite = ase.build.bulk("SiC", crystalstructure="wurtzite", a=3.086, c=10.053)
backend = run_normalize_for_structure(wurtzite)
prototype_aflow_id = backend.get_value("prototype_aflow_id")
assert prototype_aflow_id == "AB_hP4_186_b_b"
def test_springer_normalizer():
"""
Ensure the Springer normalizer works well with the VASP example.
......
......@@ -350,6 +350,12 @@ def parsed_template_example() -> LocalBackend:
'parsers/template', 'tests/data/parsers/template.json')
@pytest.fixture(scope="session")
def parsed_template_no_system() -> LocalBackend:
return run_parser(
'parsers/template', 'tests/data/parsers/template_no_system.json')
def parse_file(parser_name_and_mainfile) -> LocalBackend:
parser_name, mainfile = parser_name_and_mainfile
return run_parser(parser_name, mainfile)
......
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