Source code for mythos.input.oxdna_input

"""oxDNA input file parser."""

import io
import typing
from pathlib import Path

INVALID_DICT_LINE = "Invalid dictionary line: {}"


[docs] def _parse_numeric(value: str) -> tuple[float | int, bool]: is_successful = False parsed = 0 for t in (int, float): try: parsed = t(value) except ValueError: continue else: is_successful = True break return parsed, is_successful
[docs] def _parse_boolean(value: str) -> tuple[bool, bool]: lowered = value.lower() return ( lowered == "true", lowered in ("true", "false"), )
[docs] def _parse_value(value: str) -> str | float | int | bool: # remove potential comment from end of line value = value.split("#")[0].strip() parsed, is_numeric = _parse_numeric(value) if not is_numeric: parsed, is_boolean = _parse_boolean(value) if not is_boolean: parsed = value return parsed
[docs] def _parse_dict( line: str, lines: typing.Iterable[str] ) -> tuple[dict[str, str | float | int | bool], typing.Iterable[str]]: if "=" not in line and "{" not in line: raise ValueError(INVALID_DICT_LINE.format(line)) var_name = line.split("=")[0].strip() parsed = {} for line in lines: if "{" not in line and "}" not in line: key, value = (v.strip() for v in line.split("=")) parsed[key] = _parse_value(value) elif "{" in line: (key, value), lines = _parse_dict(line, lines) parsed[key] = value elif "}": break return (var_name, parsed), lines
[docs] def read(input_file: Path) -> dict[str, str | float | int | bool]: """Read an oxDNA input file.""" with input_file.open("r") as f: lines = filter(lambda line: (len(line.strip()) > 0) and (not line.strip().startswith("#")), f.readlines()) parsed = {} for line in lines: if "{" in line: (key, value), lines = _parse_dict(line, lines) else: key, str_value = (v.strip() for v in line.split("=")) value = _parse_value(str_value) parsed[key] = value return parsed
[docs] def write_to(input_config: dict, f: io.TextIOWrapper) -> None: """Write an oxDNA input file.""" for key, value in input_config.items(): if isinstance(value, dict): f.write(f"{key} = {{\n") write_to(value, f) f.write("}\n") else: if key == "T" and isinstance(value, float): parsed_value = str(value) + "K" elif isinstance(value, bool): parsed_value = str(value).lower() else: parsed_value = str(value) f.write(f"{key} = {parsed_value}\n")
[docs] def write(input_config: dict, input_file: Path) -> None: """Write an oxDNA input file.""" with input_file.open("w") as f: write_to(input_config, f)