Skip to content

Commit

Permalink
omnibus-2024-08-02 (#557)
Browse files Browse the repository at this point in the history
  • Loading branch information
maddenp-noaa authored Aug 3, 2024
1 parent 01ad7f3 commit 2158ca8
Show file tree
Hide file tree
Showing 49 changed files with 404 additions and 372 deletions.
48 changes: 26 additions & 22 deletions src/uwtools/api/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
API access to the ``uwtools`` driver base classes.
"""

import sys
from datetime import datetime, timedelta
from importlib import import_module
from importlib.util import module_from_spec, spec_from_file_location
Expand All @@ -11,6 +10,16 @@
from types import ModuleType
from typing import Optional, Type, Union

from uwtools.drivers.driver import ( # pylint: disable=unused-import
Assets,
AssetsCycleBased,
AssetsCycleLeadtimeBased,
AssetsTimeInvariant,
Driver,
DriverCycleBased,
DriverCycleLeadtimeBased,
DriverTimeInvariant,
)
from uwtools.drivers.support import graph
from uwtools.drivers.support import tasks as _tasks
from uwtools.logging import log
Expand Down Expand Up @@ -91,25 +100,6 @@ def tasks(module: str, classname: str) -> dict[str, str]:
return _tasks(class_)


_CLASSNAMES = [
"Assets",
"AssetsCycleBased",
"AssetsCycleLeadtimeBased",
"AssetsTimeInvariant",
"Driver",
"DriverCycleBased",
"DriverCycleLeadtimeBased",
"DriverTimeInvariant",
]


def _add_classes():
m = import_module("uwtools.drivers.driver")
for classname in _CLASSNAMES:
setattr(sys.modules[__name__], classname, getattr(m, classname))
__all__.append(classname)


def _get_driver_class(module: Union[Path, str], classname: str) -> Optional[Type]:
"""
Returns the driver class.
Expand Down Expand Up @@ -161,5 +151,19 @@ def _get_driver_module_implicit(module: str) -> Optional[ModuleType]:
return None


__all__: list[str] = [graph.__name__]
_add_classes()
__all__ = [
getattr(x, "__name__")
for x in (
Assets,
AssetsCycleBased,
AssetsCycleLeadtimeBased,
AssetsTimeInvariant,
Driver,
DriverCycleBased,
DriverCycleLeadtimeBased,
DriverTimeInvariant,
execute,
graph,
tasks,
)
]
44 changes: 29 additions & 15 deletions src/uwtools/config/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,29 @@ def realize_config(
return input_obj.data


def walk_key_path(config: dict, key_path: list[str]) -> tuple[dict, str]:
"""
Navigate to the sub-config at the end of the path of given keys.
:param config: A config.
:param key_path: Path of keys to subsection of config file.
:return: The sub-config and a string representation of the key path.
"""
keys = []
pathstr = "<unknown>"
for key in key_path:
keys.append(key)
pathstr = " -> ".join(keys)
try:
subconfig = config[key]
except KeyError as e:
raise log_and_error(f"Bad config path: {pathstr}") from e
if not isinstance(subconfig, dict):
raise log_and_error(f"Value at {pathstr} must be a dictionary")
config = subconfig
return config, pathstr


# Private functions


Expand Down Expand Up @@ -138,25 +161,16 @@ def _ensure_format(

def _print_config_section(config: dict, key_path: list[str]) -> None:
"""
Descends into the config via the given keys, then prints the contents of the located subtree as
key=value pairs, one per line.
Prints the contents of the located subtree as key=value pairs, one per line.
:param config: A config.
:param key_path: Path of keys to subsection of config file.
"""
keys = []
current_path = "<unknown>"
for section in key_path:
keys.append(section)
current_path = " -> ".join(keys)
try:
subconfig = config[section]
except KeyError as e:
raise log_and_error(f"Bad config path: {current_path}") from e
if not isinstance(subconfig, dict):
raise log_and_error(f"Value at {current_path} must be a dictionary")
config = subconfig
config, pathstr = walk_key_path(config, key_path)
output_lines = []
for key, value in config.items():
if type(value) not in (bool, float, int, str):
raise log_and_error(f"Non-scalar value {value} found at {current_path}")
raise log_and_error(f"Non-scalar value {value} found at {pathstr}")
output_lines.append(f"{key}={value}")
print("\n".join(sorted(output_lines)))

Expand Down
10 changes: 4 additions & 6 deletions src/uwtools/drivers/cdeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def atm_nml(self):
path = self._rundir / fn
yield asset(path, path.is_file)
yield None
path.parent.mkdir(parents=True, exist_ok=True)
self._model_namelist_file("atm_in", path)

@task
Expand All @@ -54,7 +53,7 @@ def atm_stream(self):
yield self._taskname(f"stream file {fn}")
path = self._rundir / fn
yield asset(path, path.is_file)
template_file = self._driver_config["atm_streams"]["template_file"]
template_file = self.config["atm_streams"]["template_file"]
yield file(path=Path(template_file))
self._model_stream_file("atm_streams", path, template_file)

Expand All @@ -79,7 +78,6 @@ def ocn_nml(self):
path = self._rundir / fn
yield asset(path, path.is_file)
yield None
path.parent.mkdir(parents=True, exist_ok=True)
self._model_namelist_file("ocn_in", path)

@task
Expand All @@ -91,7 +89,7 @@ def ocn_stream(self):
yield self._taskname(f"stream file {fn}")
path = self._rundir / fn
yield asset(path, path.is_file)
template_file = self._driver_config["ocn_streams"]["template_file"]
template_file = self.config["ocn_streams"]["template_file"]
yield file(path=Path(template_file))
self._model_stream_file("ocn_streams", path, template_file)

Expand All @@ -112,7 +110,7 @@ def _model_namelist_file(self, group: str, path: Path) -> None:
:param path: Path to write namelist to.
"""
self._create_user_updated_config(
config_class=NMLConfig, config_values=self._driver_config[group], path=path
config_class=NMLConfig, config_values=self.config[group], path=path
)

def _model_stream_file(self, group: str, path: Path, template_file: str) -> None:
Expand All @@ -126,7 +124,7 @@ def _model_stream_file(self, group: str, path: Path, template_file: str) -> None
_render(
input_file=Path(template_file),
output_file=path,
values_src=self._driver_config[group],
values_src=self.config[group],
)


Expand Down
4 changes: 2 additions & 2 deletions src/uwtools/drivers/chgres_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def namelist_file(self):
path = self._rundir / fn
yield asset(path, path.is_file)
input_files = []
namelist = self._driver_config[STR.namelist]
namelist = self.config[STR.namelist]
if base_file := namelist.get(STR.basefile):
input_files.append(base_file)
if update_values := namelist.get(STR.updatevalues):
Expand Down Expand Up @@ -84,7 +84,7 @@ def runscript(self):
yield None
envvars = {
"KMP_AFFINITY": "scatter",
"OMP_NUM_THREADS": self._driver_config.get(STR.execution, {}).get(STR.threads, 1),
"OMP_NUM_THREADS": self.config.get(STR.execution, {}).get(STR.threads, 1),
"OMP_STACKSIZE": "1024m",
}
self._write_runscript(path=path, envvars=envvars)
Expand Down
Loading

0 comments on commit 2158ca8

Please sign in to comment.