示例#1
0
def test_roundtrip_canonical():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)
    with open(TEST_DIR.joinpath("inputs/test01.inp"), "r") as fhandle:
        ref_tree = cp2k_parser.parse(fhandle)

    cp2k_generator = CP2KInputGenerator(DEFAULT_CP2K_INPUT_XML)
    fhandle = io.StringIO("\n".join(cp2k_generator.line_iter(ref_tree)))

    # reinitialize parser and generators to clear any internal state they might have
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)
    fhandle.name = "StringIO"  # add a filename (required by parser for context)

    assert cp2k_parser.parse(fhandle) == ref_tree
def test_missing_section_end():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""
        &GLOBAL
        ! &END GLOBAL
        &FORCE_EVAL
        &END FORCE_EVAL
        """)

    with pytest.raises(InvalidSectionError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "invalid section" in excinfo.value.args[0]

    fhandle = io.StringIO("""
        &GLOBAL
        &END GLOBAL
        &FORCE_EVAL
        """)

    with pytest.raises(SectionMismatchError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "not closed" in excinfo.value.args[0]
示例#3
0
def test_inline_comment():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/inline_comment.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree
示例#4
0
def test_repeated_kinds_canonical():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/test04.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree["+force_eval"][0]["+subsys"]["+kind"] == [
        {
            "_": "O",
            "element": "O",
            "potential": "GTH-PBE-q6",
            "basis_set": [("ORB", "TZVP-MOLOPT-SR-GTH")]
        },
        {
            "_": "C",
            "element": "C",
            "potential": "GTH-PBE-q4",
            "basis_set": [("ORB", "TZVP-MOLOPT-SR-GTH")]
        },
        {
            "_": "Ti",
            "element": "Ti",
            "potential": "GTH-PBE-q12",
            "basis_set": [("ORB", "TZVP-MOLOPT-SR-GTH")]
        },
    ]
示例#5
0
def cp2kget(fhandle, paths, base_dir, var_values, canonical):
    """Get values by path from a CP2K input file

    Examples for paths:

        force_eval/dft/mgrid/cutoff
    """

    if canonical:
        cp2k_parser = CP2KInputParser(base_dir=base_dir, key_trafo=str.lower)
    else:
        cp2k_parser = CP2KInputParserSimplified(base_dir=base_dir,
                                                key_trafo=str.lower)

    tree = cp2k_parser.parse(fhandle, dict(var_values))

    def _(val):
        if isinstance(val, list):
            return ", ".join(str(v) for v in val)

        return val

    for path in paths:
        sections = path.split("/")
        ref = tree
        for section in sections:
            if isinstance(ref, (list, tuple)):
                section = int(
                    section
                )  # if we encounter a list, convert the respective path element
            ref = ref[
                section]  # exploit Python using references into dicts/lists

        print(f"{path}: {_(ref)}")
示例#6
0
def test_start_empty_lines():

    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/empty_lines.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree
示例#7
0
def test_simple_canonical():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/test01.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert "+global" in tree
def test_unterminated_string():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/unterminated_string.inp"),
              "r") as fhandle:
        with pytest.raises(UnterminatedStringError) as excinfo:
            cp2k_parser.parse(fhandle)

    assert excinfo.value.args[1]["linenr"] == 14
示例#9
0
def test_roundtrip2_canonical():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)
    with open(TEST_DIR.joinpath("inputs/test04.inp"), "r") as fhandle:
        ref_tree = cp2k_parser.parse(fhandle)
        ref_tree["+force_eval"][0]["+subsys"]["+kind"].sort(
            key=lambda d: d["_"])

    cp2k_generator = CP2KInputGenerator(DEFAULT_CP2K_INPUT_XML)
    fhandle = io.StringIO("\n".join(cp2k_generator.line_iter(ref_tree)))

    # reinitialize parser and generators to clear any internal state they might have
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)
    fhandle.name = "StringIO"  # add a filename (required by parser for context)

    tree = cp2k_parser.parse(fhandle)
    tree["+force_eval"][0]["+subsys"]["+kind"].sort(key=lambda d: d["_"])

    assert tree == ref_tree
示例#10
0
def test_endif_garbage():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""@IF 1\n@ENDIF foo""")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "garbage found after @ENDIF" in excinfo.value.args[0]
示例#11
0
def test_unknown_preprocessor():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""@FOOBAR foo""")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "unknown preprocessor directive found" in excinfo.value.args[0]
示例#12
0
def test_endif_without_if():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""@ENDIF""")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "found @ENDIF without a previous @IF" in excinfo.value.args[0]
示例#13
0
def test_nested_if():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""@IF 1\n@IF 0\n@ENDIF\n@ENDIF""")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "nested @IF are not allowed" in excinfo.value.args[0]
示例#14
0
def test_undefined_var():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""${undef}""")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "undefined variable 'undef'" in excinfo.value.args[0]
示例#15
0
def test_include_multiple():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("@INCLUDE 'foo' 'bar'")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "@INCLUDE requires exactly one argument" in excinfo.value.args[0]
示例#16
0
def test_xctype():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML,
                                  base_dir=[TEST_DIR.joinpath("inputs/")])

    with open(TEST_DIR.joinpath("inputs/He_PBE.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree
    assert tree["+force_eval"][0]["+dft"]["+xc"]["+xc_functional"][
        "_"] == "PBE"
示例#17
0
def test_if_without_endif():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""@IF 1\n""")

    with pytest.raises(PreprocessorError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "conditional block not closed at end of file" in excinfo.value.args[
        0]
def test_undefined_preprocessor_var():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/preprocesser_undefined_var.inp"),
              "r") as fhandle:
        with pytest.raises(PreprocessorError) as excinfo:
            cp2k_parser.parse(fhandle)

    assert "undefined variable 'HP'" in excinfo.value.args[0]
    assert excinfo.value.args[1]["linenr"] == 30
示例#19
0
def test_fractional_values():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/fractional_values.inp"),
              "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree
    assert tree["+force_eval"][0]["+subsys"]["+cell"]["a"][
        0] == 4.0  # specified as 8/2
示例#20
0
def test_var_default_val():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/default_var_val.inp"), "r") as fhandle:
        tree_with = cp2k_parser.parse(fhandle)
        fhandle.seek(0)
        tree_without = cp2k_parser.parse(fhandle,
                                         initial_variable_values={"HP": 0})

    assert "+kpoints" in tree_with["+force_eval"][0]["+dft"]
    assert "+kpoints" not in tree_without["+force_eval"][0]["+dft"]
示例#21
0
def test_simple_canonical_inclusion():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML,
                                  base_dir=TEST_DIR.joinpath("inputs/"))

    with open(TEST_DIR.joinpath("inputs/test02.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert "+global" in tree
    assert "+force_eval" in tree
    assert isinstance(tree["+force_eval"], list)
    assert isinstance(tree["+force_eval"][0], dict)
def test_error_invalid_number_of_parameters():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/error_nvar.inp"), "r") as fhandle:
        with pytest.raises(InvalidParameterError) as excinfo:
            cp2k_parser.parse(fhandle)

    assert "invalid values for keyword: A" in excinfo.value.args[0]
    assert excinfo.value.args[1]["linenr"] == 41
    assert isinstance(excinfo.value.__cause__, InvalidParameterError)
    assert "keyword expects exactly 3 values, 2 were given" in excinfo.value.__cause__.args[
        0]
示例#23
0
    def __init__(self, cp2k_inputs_file: str, logger: logging.Logger = None):
        if logger is None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger

        with open(cp2k_inputs_file) as f:
            parser = CP2KInputParser()
            self.cp2k_dict = parser.parse(f)

        self._atoms = None
        self._init_free_energy_section()
        self._init_print_section()
def test_section_parameter_error():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""
        &GLOBAL invalidparam
        &END GLOBAL
        """)

    with pytest.raises(InvalidParameterError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "section parameters given for non-parametrized section" in excinfo.value.args[
        0]
def test_section_end_mismatch():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""
        &GLOBAL
        &END GLOBI
        &FORCE_EVAL
        &END FORCE_EVAL
        """)

    with pytest.raises(SectionMismatchError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "could not match open section" in excinfo.value.args[0]
示例#26
0
def cp2klint(fhandle, var_values, base_dir):
    """Check the passed CP2K file for syntax errors"""

    cp2k_parser = CP2KInputParser(base_dir=base_dir)

    try:
        cp2k_parser.parse(fhandle, dict(var_values))
    except (TokenizerError, ParserError) as exc:
        ctx = exc.args[1]
        line = ctx.line.rstrip()

        print(f"Syntax error: {exc.args[0]}, in {ctx.filename}:")

        if exc.__cause__:
            print(f"              {exc.__cause__}")

        print(f"line {ctx.linenr:>4}: {line}")

        if ctx.colnr is not None:
            count = 0  # number of underline chars after (positiv) or before (negative) the marker if ref_colnr given
            nchars = ctx.colnr  # relevant line length

            if ctx.ref_colnr is not None:
                count = ctx.ref_colnr - ctx.colnr
                nchars = min(ctx.ref_colnr,
                             ctx.colnr)  # correct if ref comes before

            if ctx.colnrs:
                # shift by the number of left-stripped ws
                # ctx.colnrs contains the left shift for each possibly continued line
                nchars += ctx.colnrs[0]  # assume no line-continuation for now

            # replace all non-ws chars with spaces:
            # - assuming a monospace font
            # - preserving other whitespace we don't know the width
            underline = re.sub(r"\S", " ", ctx.line[:nchars])

            if count >= 0:
                print(f"{str():>9}  {underline}^{str():~>{count}}")
            else:
                print(f"{str():>9}  {underline}{str():~>{-count}}^")

        if ctx.ref_line is not None:
            print("previous definition:")
            print(f"line {str():>4}: {ctx.ref_line.rstrip()}")

        sys.exit(1)

    print("All done! Happy calculating!")
示例#27
0
def test_line_continuation():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/line_continuation.inp"),
              "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert tree == {
        "+global": {
            "print_level": "medium",
            "project_name": "fatman.calc",
            "run_type": "energy"
        }
    }
def test_multiple_defined_non_repeating_section():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""
        &GLOBAL
        &END GLOBAL
        &GLOBAL
        &END GLOBAL
        """)

    with pytest.raises(InvalidNameError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "the section 'GLOBAL' can not be defined multiple times" in excinfo.value.args[
        0]
def test_invalid_keyword():
    cp2k_parser = CP2KInputParser(DEFAULT_CP2K_INPUT_XML)

    fhandle = io.StringIO("""
        &FORCE_EVAL
           &SUBSYS
              BASIS_SET TZVPd-MOLOPT-SR-GTH
           &END SUBSYS
        &END FORCE_EVAL
        """)

    with pytest.raises(InvalidNameError) as excinfo:
        cp2k_parser.parse(fhandle)

    assert "invalid keyword" in excinfo.value.args[0]
示例#30
0
    def validate_inputs(self, inputs: dict) -> (bool, str):
        if "cp2k_inputs" not in inputs:
            return False, "cp2k_inputs required for cp2k"

        # Validate the CP2K input file. Parser will throw exceptions if invalid
        # TODO: More specific error handling for .inp file
        try:
            with open(inputs["cp2k_inputs"]) as f:
                parser = CP2KInputParser()
                parser.parse(f)
        except Exception as e:
            return False, f"cp2k_inputs: {str(e)}"

        # Otherwise let the base class validate
        return super().validate_inputs(inputs)