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

Restructured the folders and files to use a common project structure, updated readme.

parent 0d024a53
"""
This is a module for unit testing the CP2K parser. The unit tests are run with
a custom backend that outputs the results directly into native python object for
easier and faster analysis.
Each property that has an enumerable list of different possible options is
assigned a new test class, that should ideally test through all the options.
The properties that can have any value imaginable will be tested only for one
specific case inside a test class that is designed for a certain type of run
(MD, optimization, QM/MM, etc.)
"""
import os
import unittest
import logging
......@@ -18,65 +6,75 @@ from cp2kparser import CP2KParser
from nomadcore.unit_conversion.unit_conversion import convert_unit
#===============================================================================
def get_results(folder, metainfo_to_keep=None):
"""Get the given result from the calculation in the given folder by using
the Analyzer in the nomadtoolkit package. Tries to optimize the parsing by
giving the metainfo_to_keep argument.
def get_result(folder, metaname=None):
"""Get the results from the calculation in the given folder. By default goes through different
Args:
folder: The folder relative to the directory of this script where the
parsed calculation resides.
metaname: The quantity to extract.
metaname(str): Optional quantity to return. If not specified, returns
the full dictionary of results.
"""
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, folder, "unittest.out")
filename = os.path.join("cp2k_{}".format(VERSION), dirname, folder, "unittest.out")
parser = CP2KParser(filename, None, debug=True, log_level=logging.CRITICAL)
results = parser.parse()
return results
#===============================================================================
def get_result(folder, metaname, optimize=True):
if optimize:
results = get_results(folder, None)
if metaname is None:
return results
else:
results = get_results(folder)
result = results[metaname]
return result
return results[metaname]
#===============================================================================
class TestErrors(unittest.TestCase):
"""Test misc. error stuations which may occur during the parsing.
"""Test error situations which may occur during the parsing.
"""
def test_no_file(self):
self.assertRaises(IOError, get_result, "errors/no_file", "XC_functional")
"""File is not no present.
"""
with self.assertRaises(IOError):
get_result("errors/no_file", "XC_functional")
def test_invalid_file(self):
self.assertRaises(RuntimeError, get_result, "errors/invalid_file", "XC_functional")
"""Main file is invalid.
"""
with self.assertRaises(RuntimeError):
get_result("errors/invalid_file", "XC_functional")
def test_invalid_run_type(self):
self.assertRaises(KeyError, get_result, "errors/invalid_run_type", "XC_functional")
"""Unrecognized run type.
"""
with self.assertRaises(KeyError):
get_result("errors/invalid_run_type", "XC_functional")
class TestUnknownInput(unittest.TestCase):
"""Tests for cases where unknown information is encountered in the parsing.
"""
def test_unknown_version(self):
"""Test how a new version is handled.
"""
get_result("errors/unknown_version", "XC_functional")
def test_unknown_input_keyword(self):
"""Test how an unknown input keyword is handled.
"""
get_result("errors/unknown_input_keyword", "XC_functional")
def test_unknown_input_section(self):
"""Test unknown input file section.
"""
get_result("errors/unknown_input_section", "XC_functional")
def test_unknown_input_section_parameter(self):
"""
"""
get_result("errors/unknown_input_section_parameter", "XC_functional")
#===============================================================================
class TestXCFunctional(unittest.TestCase):
"""Tests that the XC functionals can be properly parsed.
"""
def test_pade(self):
xc = get_result("XC_functional/pade", "XC_functional")
self.assertEqual(xc, "1*LDA_XC_TETER93")
......@@ -110,12 +108,10 @@ class TestXCFunctional(unittest.TestCase):
self.assertEqual(xc, "1*GGA_C_PBE+1*GGA_X_PBE")
#===============================================================================
class TestSCFConvergence(unittest.TestCase):
"""Tests whether the convergence status and number of SCF step can be
parsed correctly.
"""
def test_converged(self):
result = get_result("convergence/converged", "single_configuration_calculation_converged")
self.assertTrue(result)
......@@ -125,12 +121,10 @@ class TestSCFConvergence(unittest.TestCase):
self.assertFalse(result)
#===============================================================================
class TestForceFiles(unittest.TestCase):
"""Tests that different force files that can be output, can actually be
found and parsed.
"""
def test_single_point(self):
result = get_result("force_file/single_point", "atom_forces")
......@@ -150,11 +144,9 @@ class TestForceFiles(unittest.TestCase):
self.assertTrue(np.array_equal(result, expected_result))
#===============================================================================
class TestSelfInteractionCorrectionMethod(unittest.TestCase):
"""Tests that the self-interaction correction can be properly parsed.
"""
def test_no(self):
sic = get_result("sic/no", "self_interaction_correction_method")
self.assertEqual(sic, "")
......@@ -176,89 +168,86 @@ class TestSelfInteractionCorrectionMethod(unittest.TestCase):
self.assertEqual(sic, "SIC_MAURI_US")
#===============================================================================
class TestStressTensorMethods(unittest.TestCase):
"""Tests that the stress tensor can be properly parsed for different
calculation methods.
"""
def test_none(self):
get_results("stress_tensor/none", "section_stress_tensor")
get_result("stress_tensor/none", "section_stress_tensor")
def test_analytical(self):
results = get_results("stress_tensor/analytical", ["stress_tensor_method", "stress_tensor"])
results = get_result("stress_tensor/analytical")
method = results["stress_tensor_method"]
results["stress_tensor"]
self.assertEqual(method, "Analytical")
def test_numerical(self):
results = get_results("stress_tensor/numerical", ["stress_tensor_method", "stress_tensor"])
results = get_result("stress_tensor/numerical")
method = results["stress_tensor_method"]
results["stress_tensor"]
self.assertEqual(method, "Numerical")
def test_diagonal_analytical(self):
results = get_results("stress_tensor/diagonal_analytical", ["stress_tensor_method", "stress_tensor"])
results = get_result("stress_tensor/diagonal_analytical")
method = results["stress_tensor_method"]
results["stress_tensor"]
self.assertEqual(method, "Diagonal analytical")
def test_diagonal_numerical(self):
results = get_results("stress_tensor/diagonal_numerical", ["stress_tensor_method", "stress_tensor"])
results = get_result("stress_tensor/diagonal_numerical")
method = results["stress_tensor_method"]
results["stress_tensor"]
self.assertEqual(method, "Diagonal numerical")
#===============================================================================
class TestConfigurationPeriodicDimensions(unittest.TestCase):
"""Tests that the self-interaction correction can be properly parsed.
"""
folder = "configuration_periodic_dimensions/"
def test_default(self):
result = get_result("configuration_periodic_dimensions/default", "configuration_periodic_dimensions")
result = get_result(self.folder+"default", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((True, True, True))))
def test_none(self):
result = get_result("configuration_periodic_dimensions/none", "configuration_periodic_dimensions")
result = get_result(self.folder+"none", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((False, False, False))))
def test_x(self):
result = get_result("configuration_periodic_dimensions/x", "configuration_periodic_dimensions")
result = get_result(self.folder+"x", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((True, False, False))))
def test_y(self):
result = get_result("configuration_periodic_dimensions/y", "configuration_periodic_dimensions")
result = get_result(self.folder+"y", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((False, True, False))))
def test_z(self):
result = get_result("configuration_periodic_dimensions/z", "configuration_periodic_dimensions")
result = get_result(self.folder+"z", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((False, False, True))))
def test_xy(self):
result = get_result("configuration_periodic_dimensions/xy", "configuration_periodic_dimensions")
result = get_result(self.folder+"xy", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((True, True, False))))
def test_xyz(self):
result = get_result("configuration_periodic_dimensions/xyz", "configuration_periodic_dimensions")
result = get_result(self.folder+"xyz", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((True, True, True))))
def test_xz(self):
result = get_result("configuration_periodic_dimensions/xz", "configuration_periodic_dimensions")
result = get_result(self.folder+"xz", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((True, False, True))))
def test_yz(self):
result = get_result("configuration_periodic_dimensions/yz", "configuration_periodic_dimensions")
result = get_result(self.folder+"yz", "configuration_periodic_dimensions")
self.assertTrue(np.array_equal(result, np.array((False, True, True))))
#===============================================================================
class TestEnergyForce(unittest.TestCase):
"""Tests for a CP2K calculation with RUN_TYPE ENERGY_FORCE.
"""
@classmethod
def setUpClass(cls):
cls.results = get_results("energy_force", "section_run")
cls.results = get_result("energy_force")
# cls.results.print_summary()
def test_energy_total_scf_iteration(self):
......@@ -482,36 +471,37 @@ class TestEnergyForce(unittest.TestCase):
self.assertEqual(result, "gaussians")
#===============================================================================
class TestPreprocessor(unittest.TestCase):
"""Tests that the parser can read input files with preprocessor
declarations, such as variables.
"""
def test_include(self):
result = get_result("input_preprocessing/include", "x_cp2k_input_GLOBAL.PRINT_LEVEL", optimize=False)
result = get_result("input_preprocessing/include", "x_cp2k_input_GLOBAL.PRINT_LEVEL")
self.assertEqual(result, "LOW")
def test_variable(self):
result = get_result("input_preprocessing/variable", "x_cp2k_input_GLOBAL.PROJECT_NAME", optimize=False)
result = get_result("input_preprocessing/variable", "x_cp2k_input_GLOBAL.PROJECT_NAME")
self.assertEqual(result, "variable_test")
def test_variable_multiple(self):
result = get_result("input_preprocessing/variable_multiple", "x_cp2k_input_FORCE_EVAL.DFT.MGRID.CUTOFF", optimize=False)
result = get_result("input_preprocessing/variable_multiple", "x_cp2k_input_FORCE_EVAL.DFT.MGRID.CUTOFF")
self.assertEqual(result, "50")
def test_comments(self):
result = get_result("input_preprocessing/comments", "x_cp2k_input_FORCE_EVAL.DFT.MGRID.CUTOFF", optimize=False)
result = get_result("input_preprocessing/comments", "x_cp2k_input_FORCE_EVAL.DFT.MGRID.CUTOFF")
self.assertEqual(result, "120")
def test_tabseparator(self):
result = get_result("input_preprocessing/tabseparator", "x_cp2k_input_FORCE_EVAL.DFT.MGRID.CUTOFF", optimize=False)
result = get_result("input_preprocessing/tabseparator", "x_cp2k_input_FORCE_EVAL.DFT.MGRID.CUTOFF")
self.assertEqual(result, "120")
#===============================================================================
class TestGeoOpt(unittest.TestCase):
"""Tests that geometry optimizations are correctly parsed.
"""
@classmethod
def setUpClass(cls):
cls.results = get_results("geo_opt/cg", "section_run")
cls.results = get_result("geo_opt/cg")
def test_geometry_optimization_converged(self):
result = self.results["geometry_optimization_converged"]
......@@ -595,12 +585,12 @@ class TestGeoOpt(unittest.TestCase):
self.assertTrue(np.array_equal(result_end, expected_end))
# ===============================================================================
class TestGeoOptTrajFormats(unittest.TestCase):
"""Different trajectory formats in geometry optimization.
"""
def test_xyz(self):
result = get_result("geo_opt/geometry_formats/xyz", "atom_positions", optimize=True)
result = get_result("geo_opt/geometry_formats/xyz", "atom_positions")
expected_start = convert_unit(
np.array([
[12.2353220000, 1.3766420000, 10.8698800000],
......@@ -623,7 +613,7 @@ class TestGeoOptTrajFormats(unittest.TestCase):
self.assertTrue(np.array_equal(result_end, expected_end))
def test_pdb(self):
result = get_result("geo_opt/geometry_formats/pdb", "atom_positions", optimize=True)
result = get_result("geo_opt/geometry_formats/pdb", "atom_positions")
expected_start = convert_unit(
np.array([
[12.235, 1.377, 10.870],
......@@ -646,14 +636,14 @@ class TestGeoOptTrajFormats(unittest.TestCase):
self.assertTrue(np.array_equal(result_end, expected_end))
def test_dcd(self):
result = get_result("geo_opt/geometry_formats/dcd", "atom_positions", optimize=True)
result = get_result("geo_opt/geometry_formats/dcd", "atom_positions")
frames = result.shape[0]
self.assertEqual(frames, 7)
#===============================================================================
class TestGeoOptOptimizers(unittest.TestCase):
"""Different optimization methods in gemoetry optimization.
"""
def test_bfgs(self):
result = get_result("geo_opt/bfgs", "geometry_optimization_method")
self.assertEqual(result, "bfgs")
......@@ -663,14 +653,15 @@ class TestGeoOptOptimizers(unittest.TestCase):
self.assertEqual(result, "bfgs")
#===============================================================================
class TestGeoOptTrajectory(unittest.TestCase):
"""Tests that the print settings for geometry optimization are handled
correctly.
"""
def test_each_and_add_last(self):
"""Test that the EACH and ADD_LAST settings affect the parsing
correctly.
"""
results = get_results("geo_opt/each")
results = get_result("geo_opt/each")
single_conf = results["section_single_configuration_calculation"]
systems = results["section_system"]
......@@ -730,12 +721,12 @@ class TestGeoOptTrajectory(unittest.TestCase):
i_conf += 1
#===============================================================================
class TestMD(unittest.TestCase):
"""Molecular dynamics tests.
"""
@classmethod
def setUpClass(cls):
cls.results = get_results("md/nve", "section_run")
cls.results = get_result("md/nve")
cls.temp = convert_unit(
np.array([
300.000000000,
......@@ -943,9 +934,9 @@ class TestMD(unittest.TestCase):
self.assertTrue(np.array_equal(result, expected_result))
#===============================================================================
class TestMDEnsembles(unittest.TestCase):
"""Different ensembles in MD.
"""
@classmethod
def setUpClass(cls):
cls.pressure = convert_unit(
......@@ -966,12 +957,12 @@ class TestMDEnsembles(unittest.TestCase):
)
def test_nvt(self):
results = get_results("md/nvt", "section_run")
results = get_result("md/nvt")
ensemble = results["ensemble_type"]
self.assertEqual(ensemble, "NVT")
def test_npt(self):
results = get_results("md/npt", "section_run")
results = get_result("md/npt")
ensemble = results["ensemble_type"]
self.assertEqual(ensemble, "NPT")
......@@ -1022,46 +1013,50 @@ class TestMDEnsembles(unittest.TestCase):
self.assertTrue(np.array_equal(expected_cell_end, simulation_cell[-1, :, :]))
#===============================================================================
class TestElectronicStructureMethod(unittest.TestCase):
"""Tests that different methods are recognized correctly.
"""
def test_mp2(self):
results = get_results("electronic_structure_method/mp2", "section_run")
results = get_result("electronic_structure_method/mp2")
result = results["electronic_structure_method"]
self.assertEqual(result, "MP2")
def test_dft_plus_u(self):
results = get_results("electronic_structure_method/dft_plus_u", "section_run")
results = get_result("electronic_structure_method/dft_plus_u")
result = results["electronic_structure_method"]
self.assertEqual(result, "DFT+U")
def test_rpa(self):
results = get_results("electronic_structure_method/rpa", "section_run")
results = get_result("electronic_structure_method/rpa")
result = results["electronic_structure_method"]
self.assertEqual(result, "RPA")
#===============================================================================
if __name__ == '__main__':
logger = logging.getLogger("cp2kparser")
logger.setLevel(logging.ERROR)
suites = []
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestErrors))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestXCFunctional))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestEnergyForce))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestStressTensorMethods))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestSelfInteractionCorrectionMethod))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestConfigurationPeriodicDimensions))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestSCFConvergence))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestForceFiles))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestPreprocessor))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOpt))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOptTrajFormats))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOptOptimizers))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOptTrajectory))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestMD))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestMDEnsembles))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestElectronicStructureMethod))
alltests = unittest.TestSuite(suites)
unittest.TextTestRunner(verbosity=0).run(alltests)
VERSIONS = ["2.6.2"]
for VERSION in VERSIONS:
suites = []
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestErrors))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestUnknownInput))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestXCFunctional))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestEnergyForce))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestStressTensorMethods))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestSelfInteractionCorrectionMethod))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestConfigurationPeriodicDimensions))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestSCFConvergence))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestForceFiles))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestPreprocessor))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOpt))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOptTrajFormats))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOptOptimizers))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestGeoOptTrajectory))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestMD))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestMDEnsembles))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestElectronicStructureMethod))
alltests = unittest.TestSuite(suites)
unittest.TextTestRunner(verbosity=0).run(alltests)
Markdown is supported
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