wrfrun 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wrfrun/__init__.py +8 -3
- wrfrun/cli.py +69 -29
- wrfrun/core/__init__.py +27 -10
- wrfrun/core/_config.py +308 -0
- wrfrun/core/_constant.py +236 -0
- wrfrun/core/_exec_db.py +105 -0
- wrfrun/core/_namelist.py +287 -0
- wrfrun/core/_record.py +178 -0
- wrfrun/core/_resource.py +172 -0
- wrfrun/core/base.py +132 -406
- wrfrun/core/core.py +196 -0
- wrfrun/core/error.py +28 -2
- wrfrun/core/replay.py +10 -96
- wrfrun/core/server.py +52 -27
- wrfrun/core/type.py +171 -0
- wrfrun/data.py +304 -139
- wrfrun/extension/goos_sst/__init__.py +2 -2
- wrfrun/extension/goos_sst/core.py +9 -14
- wrfrun/extension/goos_sst/res/__init__.py +0 -1
- wrfrun/extension/goos_sst/utils.py +50 -44
- wrfrun/extension/littler/core.py +105 -88
- wrfrun/extension/utils.py +4 -3
- wrfrun/log.py +117 -0
- wrfrun/model/__init__.py +11 -7
- wrfrun/model/constants.py +52 -0
- wrfrun/model/palm/__init__.py +30 -0
- wrfrun/model/palm/core.py +145 -0
- wrfrun/model/palm/namelist.py +33 -0
- wrfrun/model/plot.py +99 -119
- wrfrun/model/type.py +116 -0
- wrfrun/model/utils.py +9 -20
- wrfrun/model/wrf/__init__.py +4 -9
- wrfrun/model/wrf/core.py +246 -161
- wrfrun/model/wrf/exec_wrap.py +13 -12
- wrfrun/model/wrf/geodata.py +116 -100
- wrfrun/model/wrf/log.py +103 -0
- wrfrun/model/wrf/namelist.py +90 -73
- wrfrun/model/wrf/plot.py +102 -0
- wrfrun/model/wrf/scheme.py +108 -52
- wrfrun/model/wrf/utils.py +39 -25
- wrfrun/model/wrf/vtable.py +35 -3
- wrfrun/plot/__init__.py +20 -0
- wrfrun/plot/wps.py +90 -73
- wrfrun/res/__init__.py +103 -5
- wrfrun/res/config/config.template.toml +8 -0
- wrfrun/res/config/palm.template.toml +23 -0
- wrfrun/run.py +105 -77
- wrfrun/scheduler/__init__.py +1 -0
- wrfrun/scheduler/lsf.py +3 -2
- wrfrun/scheduler/pbs.py +3 -2
- wrfrun/scheduler/script.py +17 -5
- wrfrun/scheduler/slurm.py +3 -2
- wrfrun/scheduler/utils.py +14 -2
- wrfrun/utils.py +88 -199
- wrfrun/workspace/__init__.py +8 -5
- wrfrun/workspace/core.py +20 -12
- wrfrun/workspace/palm.py +137 -0
- wrfrun/workspace/wrf.py +16 -15
- wrfrun-0.3.0.dist-info/METADATA +240 -0
- wrfrun-0.3.0.dist-info/RECORD +78 -0
- wrfrun/core/config.py +0 -923
- wrfrun/model/base.py +0 -14
- wrfrun-0.2.0.dist-info/METADATA +0 -68
- wrfrun-0.2.0.dist-info/RECORD +0 -62
- {wrfrun-0.2.0.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
- {wrfrun-0.2.0.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
wrfrun/__init__.py
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"""
|
|
2
|
+
wrfrun
|
|
3
|
+
######
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from . import core, data, extension, model, plot, res, run, scheduler, utils, workspace
|
|
7
|
+
|
|
8
|
+
__all__ = ["core", "data", "extension", "model", "plot", "res", "run", "scheduler", "utils", "workspace"]
|
wrfrun/cli.py
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.cli
|
|
3
|
+
##########
|
|
4
|
+
|
|
5
|
+
.. autosummary::
|
|
6
|
+
:toctree: generated/
|
|
7
|
+
|
|
8
|
+
main_entry
|
|
9
|
+
|
|
10
|
+
``wrfrun`` command line interface (CLI).
|
|
11
|
+
|
|
12
|
+
**This is an experimental tool, NOT BEING STABLE YET.**
|
|
13
|
+
|
|
14
|
+
After installing ``wrfrun``, you can use command ``wrfrun`` to create a simulation project.
|
|
15
|
+
Get more information by running ``wrfrun --help``.
|
|
16
|
+
"""
|
|
17
|
+
|
|
1
18
|
import argparse
|
|
2
19
|
import sys
|
|
3
|
-
from os import makedirs
|
|
20
|
+
from os import listdir, makedirs
|
|
4
21
|
from os.path import abspath, dirname, exists
|
|
5
22
|
from shutil import copyfile
|
|
6
23
|
|
|
@@ -8,15 +25,17 @@ import tomli
|
|
|
8
25
|
import tomli_w
|
|
9
26
|
|
|
10
27
|
from .core import WRFRunConfig
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
28
|
+
from .log import logger
|
|
29
|
+
from .res import CONFIG_MAIN_TOML_TEMPLATE, CONFIG_PALM_TOML_TEMPLATE, CONFIG_WRF_TOML_TEMPLATE, _register_res_uri
|
|
13
30
|
|
|
14
31
|
MODEL_MAP = {
|
|
15
|
-
"wrf": CONFIG_WRF_TOML_TEMPLATE
|
|
32
|
+
"wrf": CONFIG_WRF_TOML_TEMPLATE,
|
|
33
|
+
"palm": CONFIG_PALM_TOML_TEMPLATE,
|
|
16
34
|
}
|
|
17
35
|
|
|
18
|
-
|
|
36
|
+
# need some mannual calls to make cli work without a config file.
|
|
19
37
|
wrfrun_config = WRFRunConfig("./.wrfrun")
|
|
38
|
+
_register_res_uri(wrfrun_config)
|
|
20
39
|
|
|
21
40
|
|
|
22
41
|
def _entry_init(args: argparse.Namespace):
|
|
@@ -26,17 +45,29 @@ def _entry_init(args: argparse.Namespace):
|
|
|
26
45
|
:param args: Arguments namespace.
|
|
27
46
|
:type args: argparse.Namespace
|
|
28
47
|
"""
|
|
29
|
-
|
|
48
|
+
configs = vars(args)
|
|
49
|
+
|
|
50
|
+
project_name = configs["name"]
|
|
51
|
+
models = configs["models"]
|
|
30
52
|
|
|
31
|
-
project_name
|
|
32
|
-
|
|
53
|
+
if project_name is None:
|
|
54
|
+
project_name = "."
|
|
33
55
|
|
|
34
56
|
if exists(project_name):
|
|
35
|
-
|
|
36
|
-
|
|
57
|
+
# we need to check if this directory isn't empty.
|
|
58
|
+
files = listdir()
|
|
59
|
+
# exclude:
|
|
60
|
+
exclude_target = [".venv", ".git", ".gitignore", ".gitattribute", "pyproject.toml", "uv.lock"]
|
|
61
|
+
files = [x for x in files if x not in exclude_target]
|
|
62
|
+
|
|
63
|
+
if len(files) != 0:
|
|
64
|
+
logger.error(f"{project_name} isn't empty, choose an empty directory, or backup and delete your files first.")
|
|
65
|
+
exit(1)
|
|
37
66
|
|
|
38
67
|
makedirs(f"{project_name}/configs")
|
|
39
68
|
makedirs(f"{project_name}/data")
|
|
69
|
+
namelist_path = f"{project_name}/namelists"
|
|
70
|
+
makedirs(namelist_path)
|
|
40
71
|
|
|
41
72
|
copyfile(wrfrun_config.parse_resource_uri(CONFIG_MAIN_TOML_TEMPLATE), f"{project_name}/config.toml")
|
|
42
73
|
|
|
@@ -44,9 +75,15 @@ def _entry_init(args: argparse.Namespace):
|
|
|
44
75
|
for _model in models:
|
|
45
76
|
src_path = wrfrun_config.parse_resource_uri(MODEL_MAP[_model])
|
|
46
77
|
copyfile(src_path, f"{project_name}/configs/{_model}.toml")
|
|
78
|
+
makedirs(f"{namelist_path}/{_model}")
|
|
47
79
|
|
|
48
|
-
logger.info(f"Created project {project_name}
|
|
49
|
-
logger.info(f"
|
|
80
|
+
logger.info(f"Created project {project_name}")
|
|
81
|
+
logger.info(f"All your configs should be placed in {project_name}/configs.")
|
|
82
|
+
logger.info(f"All your data should be placed in {project_name}/data.")
|
|
83
|
+
logger.info(f"All your namelist files should be placed in {namelist_path}")
|
|
84
|
+
logger.info(f"Make sure to set `use = True` to enable models in {project_name}/config.toml .")
|
|
85
|
+
logger.info("It is recommanded to use git to track your wrfrun and model configs.")
|
|
86
|
+
logger.info("Use command `wrfrun add MODEL_NAME` to add a new model to project.")
|
|
50
87
|
|
|
51
88
|
|
|
52
89
|
def _entry_model(args: argparse.Namespace):
|
|
@@ -56,20 +93,16 @@ def _entry_model(args: argparse.Namespace):
|
|
|
56
93
|
:param args: Arguments namespace.
|
|
57
94
|
:type args: argparse.Namespace
|
|
58
95
|
"""
|
|
59
|
-
|
|
60
|
-
new_models =
|
|
61
|
-
config_path =
|
|
96
|
+
configs = vars(args)
|
|
97
|
+
new_models = configs["add"]
|
|
98
|
+
config_path = configs["config"]
|
|
62
99
|
|
|
63
100
|
if not exists(config_path):
|
|
64
101
|
logger.error(f"Can't find '{config_path}', initialize this project first.")
|
|
65
102
|
exit(1)
|
|
66
103
|
|
|
67
|
-
model_config_map = {
|
|
68
|
-
"wrf": CONFIG_WRF_TOML_TEMPLATE
|
|
69
|
-
}
|
|
70
|
-
|
|
71
104
|
for _new_model in new_models:
|
|
72
|
-
if _new_model not in
|
|
105
|
+
if _new_model not in MODEL_MAP:
|
|
73
106
|
logger.error(f"Unknow model type: '{_new_model}'")
|
|
74
107
|
exit(1)
|
|
75
108
|
|
|
@@ -84,21 +117,27 @@ def _entry_model(args: argparse.Namespace):
|
|
|
84
117
|
for _new_model in new_models:
|
|
85
118
|
if _new_model not in main_config["model"]:
|
|
86
119
|
main_config["model"][_new_model] = {
|
|
87
|
-
"note":
|
|
120
|
+
"note": (
|
|
121
|
+
"Config of this model is generated by wrfrun cli command. "
|
|
122
|
+
"DO NOT ADD CUSTOM CONFIG IN THIS SECTION because they may be overwrite by wrfrun cli tools."
|
|
123
|
+
),
|
|
88
124
|
"use": True,
|
|
89
|
-
"include": f"./configs/{_new_model}.toml"
|
|
125
|
+
"include": f"./configs/{_new_model}.toml",
|
|
90
126
|
}
|
|
91
127
|
|
|
92
128
|
else:
|
|
93
129
|
if not ("use" in main_config["model"] and main_config["model"]["use"]):
|
|
94
130
|
main_config["model"][_new_model] = {
|
|
95
|
-
"note":
|
|
131
|
+
"note": (
|
|
132
|
+
"Config of this model is generated by wrfrun cli command. "
|
|
133
|
+
"DO NOT ADD CUSTOM CONFIG IN THIS SECTION because they may be overwrite by wrfrun cli tools."
|
|
134
|
+
),
|
|
96
135
|
"use": True,
|
|
97
|
-
"include": f"./configs/{_new_model}.toml"
|
|
136
|
+
"include": f"./configs/{_new_model}.toml",
|
|
98
137
|
}
|
|
99
138
|
|
|
100
139
|
for _new_model in new_models:
|
|
101
|
-
copyfile(wrfrun_config.parse_resource_uri(
|
|
140
|
+
copyfile(wrfrun_config.parse_resource_uri(MODEL_MAP[_new_model]), f"{config_dir_path}/{_new_model}.toml")
|
|
102
141
|
|
|
103
142
|
with open(config_path, "wb") as f:
|
|
104
143
|
tomli_w.dump(main_config, f)
|
|
@@ -110,18 +149,19 @@ def main_entry():
|
|
|
110
149
|
"""
|
|
111
150
|
CLI entry point.
|
|
112
151
|
"""
|
|
113
|
-
|
|
114
152
|
args_parser = argparse.ArgumentParser()
|
|
115
153
|
subparsers = args_parser.add_subparsers(title="Subcommands", description="Valid Subcommands", help="Subcommands")
|
|
116
154
|
|
|
117
155
|
init_parser = subparsers.add_parser("init", help="Initialize a wrfrun project.", add_help=True)
|
|
118
|
-
init_parser.add_argument("-n", "--name", type=str,
|
|
119
|
-
init_parser.add_argument("--models", nargs="*", type=str, help="List of models to use.", choices=["wrf"])
|
|
156
|
+
init_parser.add_argument("-n", "--name", type=str, help="Name of the wrfrun project.")
|
|
157
|
+
init_parser.add_argument("--models", nargs="*", type=str, help="List of models to use.", choices=["wrf", "palm"])
|
|
120
158
|
init_parser.set_defaults(func=_entry_init)
|
|
121
159
|
|
|
122
160
|
model_parser = subparsers.add_parser("model", help="Manage models used by wrfrun project.", add_help=True)
|
|
123
161
|
model_parser.add_argument("-c", "--config", type=str, default="config.toml", help="Path of the main config file.")
|
|
124
|
-
model_parser.add_argument(
|
|
162
|
+
model_parser.add_argument(
|
|
163
|
+
"-a", "--add", nargs="+", required=True, type=str, help="Add models to the project.", choices=["wrf", "palm"]
|
|
164
|
+
)
|
|
125
165
|
model_parser.set_defaults(func=_entry_model)
|
|
126
166
|
|
|
127
167
|
args = args_parser.parse_args(args=None if sys.argv[1:] else ["--help"])
|
wrfrun/core/__init__.py
CHANGED
|
@@ -12,27 +12,44 @@ The functionalities are split into several submodules, which are listed in the t
|
|
|
12
12
|
Submodules
|
|
13
13
|
**********
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
:doc:`
|
|
17
|
-
:doc:`
|
|
18
|
-
:doc:`
|
|
19
|
-
:doc:`
|
|
20
|
-
:doc:`
|
|
21
|
-
|
|
15
|
+
====================================== ========================================================
|
|
16
|
+
:doc:`_config </api/core._config>` Definition of ``WRFRunConfig``.
|
|
17
|
+
:doc:`_constant </api/core._constant>` Definition of ``ConstantMixIn``.
|
|
18
|
+
:doc:`_exec_db </api/core._exec_db>` Definition of ``ExecutableDB``.
|
|
19
|
+
:doc:`_namelist </api/core._namelist>` Definition of ``NamelistMixIn``.
|
|
20
|
+
:doc:`_record </api/core._record>` Definition of ``ExecutableRecorder``.
|
|
21
|
+
:doc:`_resource </api/core._resource>` Definition of ``ResourceMixIn``.
|
|
22
|
+
:doc:`base </api/core.base>` Definition of ``Executable`` base class.
|
|
23
|
+
:doc:`core </api/core.core>` Definition of proxy class ``WRFRUNProxy``.
|
|
24
|
+
:doc:`error </api/core.error>` Definition of ``wrfrun`` error exceptions.
|
|
25
|
+
:doc:`replay </api/core.replay>` Functions and classes to replay simulations.
|
|
26
|
+
:doc:`server </api/core.server>` Functions and classes to start socket server.
|
|
27
|
+
:doc:`type </api/core.type>` Definition of various types used in ``wrfrun``.
|
|
28
|
+
====================================== ========================================================
|
|
22
29
|
|
|
23
|
-
.. toctree::
|
|
30
|
+
.. toctree::
|
|
24
31
|
:maxdepth: 1
|
|
25
32
|
:hidden:
|
|
26
33
|
|
|
34
|
+
_config <core._config>
|
|
35
|
+
_constant <core._constant>
|
|
36
|
+
_exec_db <core._exec_db>
|
|
37
|
+
_namelist <core._namelist>
|
|
38
|
+
_record <core._record>
|
|
39
|
+
_resource <core._resource>
|
|
27
40
|
base <core.base>
|
|
28
|
-
|
|
41
|
+
core <core.core>
|
|
29
42
|
error <core.error>
|
|
30
43
|
replay <core.replay>
|
|
31
44
|
server <core.server>
|
|
45
|
+
type <core.type>
|
|
32
46
|
"""
|
|
33
47
|
|
|
48
|
+
from ._config import *
|
|
49
|
+
from ._exec_db import *
|
|
34
50
|
from .base import *
|
|
35
|
-
from .
|
|
51
|
+
from .core import *
|
|
36
52
|
from .error import *
|
|
37
53
|
from .replay import *
|
|
38
54
|
from .server import *
|
|
55
|
+
from .type import *
|
wrfrun/core/_config.py
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.core._config
|
|
3
|
+
###################
|
|
4
|
+
|
|
5
|
+
.. autosummary::
|
|
6
|
+
:toctree: generated/
|
|
7
|
+
|
|
8
|
+
WRFRunConfig
|
|
9
|
+
|
|
10
|
+
WRFRunConfig
|
|
11
|
+
************
|
|
12
|
+
|
|
13
|
+
This class inherits :class:`ConstantMixIn <wrfrun.core._constant.ConstantMixIn>`,
|
|
14
|
+
:class:`NamelistMixIn <wrfrun.core._namelist.NamelistMixIn>`,
|
|
15
|
+
and :class:`ResourceMixIn <wrfrun.core._resource.ResourceMixIn>`.
|
|
16
|
+
|
|
17
|
+
Besides the methods from its parents, :class:`WRFRunConfig` provides methods to read and access user config files.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from copy import deepcopy
|
|
21
|
+
from os import makedirs
|
|
22
|
+
from os.path import abspath, dirname, exists
|
|
23
|
+
from shutil import copyfile
|
|
24
|
+
from typing import Callable, Tuple
|
|
25
|
+
|
|
26
|
+
import tomli
|
|
27
|
+
import tomli_w
|
|
28
|
+
|
|
29
|
+
from ..log import logger
|
|
30
|
+
from ._constant import ConstantMixIn
|
|
31
|
+
from ._namelist import NamelistMixIn
|
|
32
|
+
from ._resource import ResourceMixIn
|
|
33
|
+
from .error import ModelNameError
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WRFRunConfig(ConstantMixIn, NamelistMixIn, ResourceMixIn):
|
|
37
|
+
"""
|
|
38
|
+
Comprehensive class to manage wrfrun config, runtime constants, namelists and resource files.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, work_dir: str):
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
:param work_dir: ``wrfrun`` work directory path.
|
|
45
|
+
:type work_dir: str
|
|
46
|
+
"""
|
|
47
|
+
super().__init__(work_dir=work_dir)
|
|
48
|
+
|
|
49
|
+
self._config = {}
|
|
50
|
+
|
|
51
|
+
self._config_template_file_path = None
|
|
52
|
+
|
|
53
|
+
self._register_wrfrun_uris()
|
|
54
|
+
|
|
55
|
+
def apply_register_func(self, func_list: list[Callable[["WRFRunConfig"], None]]):
|
|
56
|
+
"""
|
|
57
|
+
Call register functions provided by other submodules.
|
|
58
|
+
|
|
59
|
+
:param func_list: A list contains register functions.
|
|
60
|
+
:type func_list: list[Callable[["WRFRunConfig"], None]]
|
|
61
|
+
"""
|
|
62
|
+
while len(func_list) != 0:
|
|
63
|
+
_func = func_list.pop(0)
|
|
64
|
+
_func(self)
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
def from_config_file(
|
|
68
|
+
cls, config_file: str, register_funcs: list[Callable[["WRFRunConfig"], None]]
|
|
69
|
+
) -> "WRFRunConfig":
|
|
70
|
+
"""
|
|
71
|
+
Read the config file and create a instance.
|
|
72
|
+
|
|
73
|
+
:param config_file: Config file path.
|
|
74
|
+
:type config_file: str
|
|
75
|
+
:param register_funcs: Register function list.
|
|
76
|
+
:type register_funcs: list[Callable[["WRFRunConfig"], None]]
|
|
77
|
+
:return: New instance
|
|
78
|
+
:rtype: WRFRunConfig
|
|
79
|
+
"""
|
|
80
|
+
with open(config_file, "rb") as f:
|
|
81
|
+
config = tomli.load(f)
|
|
82
|
+
|
|
83
|
+
instance = cls(work_dir=config["work_dir"])
|
|
84
|
+
instance.apply_register_func(register_funcs)
|
|
85
|
+
instance.load_wrfrun_config(config_file)
|
|
86
|
+
|
|
87
|
+
return instance
|
|
88
|
+
|
|
89
|
+
def _register_wrfrun_uris(self):
|
|
90
|
+
for key, value in self._get_uri_map().items():
|
|
91
|
+
self.register_resource_uri(key, value)
|
|
92
|
+
|
|
93
|
+
def set_config_template_path(self, file_path: str):
|
|
94
|
+
"""
|
|
95
|
+
Set file path of the config template file.
|
|
96
|
+
|
|
97
|
+
``WRFRunConfig`` needs to know
|
|
98
|
+
|
|
99
|
+
:param file_path: Template file path.
|
|
100
|
+
:type file_path: str
|
|
101
|
+
"""
|
|
102
|
+
self._config_template_file_path = file_path
|
|
103
|
+
|
|
104
|
+
def load_wrfrun_config(self, config_path: str):
|
|
105
|
+
"""
|
|
106
|
+
Load configs from a config file.
|
|
107
|
+
|
|
108
|
+
If the config path is invalid, ``WRFRunConfig`` will create a new config file at the same place,
|
|
109
|
+
and raise :class:`FileNotFoundError`.
|
|
110
|
+
|
|
111
|
+
:param config_path: TOML config file.
|
|
112
|
+
:type config_path: str
|
|
113
|
+
"""
|
|
114
|
+
config_template_path = self.parse_resource_uri(self._config_template_file_path)
|
|
115
|
+
|
|
116
|
+
if not exists(config_path):
|
|
117
|
+
logger.error(f"Config file doesn't exist, copy template config to {config_path}")
|
|
118
|
+
logger.error("Please modify it.")
|
|
119
|
+
|
|
120
|
+
if not exists(dirname(config_path)):
|
|
121
|
+
makedirs(dirname(config_path))
|
|
122
|
+
|
|
123
|
+
copyfile(config_template_path, config_path)
|
|
124
|
+
raise FileNotFoundError(config_path)
|
|
125
|
+
|
|
126
|
+
with open(config_path, "rb") as f:
|
|
127
|
+
self._config = tomli.load(f)
|
|
128
|
+
|
|
129
|
+
config_dir_path = abspath(dirname(config_path))
|
|
130
|
+
|
|
131
|
+
# merge model config.
|
|
132
|
+
keys_list = list(self._config["model"].keys())
|
|
133
|
+
for model_key in keys_list:
|
|
134
|
+
# skip the key that isn't model.
|
|
135
|
+
if model_key == "debug_level":
|
|
136
|
+
continue
|
|
137
|
+
|
|
138
|
+
if "include" not in self._config["model"][model_key]:
|
|
139
|
+
continue
|
|
140
|
+
|
|
141
|
+
# use = True, and have "include" key
|
|
142
|
+
if self._config["model"][model_key]["use"]:
|
|
143
|
+
include_file = self._config["model"][model_key]["include"]
|
|
144
|
+
if include_file[0] != "/":
|
|
145
|
+
include_file = f"{config_dir_path}/{include_file}"
|
|
146
|
+
|
|
147
|
+
with open(include_file, "rb") as f:
|
|
148
|
+
# keep "use" key, as other components may use this key
|
|
149
|
+
_mode_config = tomli.load(f)
|
|
150
|
+
_mode_config.update({"use": True})
|
|
151
|
+
self._config["model"][model_key] = _mode_config
|
|
152
|
+
|
|
153
|
+
else:
|
|
154
|
+
self._config["model"].pop(model_key)
|
|
155
|
+
|
|
156
|
+
# register URI for output directory.
|
|
157
|
+
output_path = abspath(self["output_path"])
|
|
158
|
+
self.unregister_resource_uri(self.WRFRUN_OUTPUT_PATH)
|
|
159
|
+
self.register_resource_uri(self.WRFRUN_OUTPUT_PATH, output_path)
|
|
160
|
+
|
|
161
|
+
# some additional check
|
|
162
|
+
if self._config["input_data_path"] == "":
|
|
163
|
+
logger.warning("It seems you forget to set 'input_data_path', set it to 'data'.")
|
|
164
|
+
self._config["input_data_path"] = "data"
|
|
165
|
+
|
|
166
|
+
def save_wrfrun_config(self, save_path: str):
|
|
167
|
+
"""
|
|
168
|
+
Save wrfrun config to a file.
|
|
169
|
+
|
|
170
|
+
:param save_path: Save path of the config.
|
|
171
|
+
:type save_path: str
|
|
172
|
+
"""
|
|
173
|
+
save_path = self.parse_resource_uri(save_path)
|
|
174
|
+
|
|
175
|
+
path_dir = dirname(save_path)
|
|
176
|
+
if not exists(path_dir):
|
|
177
|
+
makedirs(path_dir)
|
|
178
|
+
|
|
179
|
+
with open(save_path, "wb") as f:
|
|
180
|
+
tomli_w.dump(self._config, f)
|
|
181
|
+
|
|
182
|
+
def __getitem__(self, item: str):
|
|
183
|
+
"""
|
|
184
|
+
You can access wrfrun config like the way to access values in a dictionary.
|
|
185
|
+
|
|
186
|
+
For example:
|
|
187
|
+
|
|
188
|
+
>>> from wrfrun.core import WRFRUN
|
|
189
|
+
>>> model_config = WRFRUN.config["model"] # get all model configs.
|
|
190
|
+
|
|
191
|
+
:param item: Keys.
|
|
192
|
+
:type item: str
|
|
193
|
+
"""
|
|
194
|
+
if len(self._config) == 0:
|
|
195
|
+
logger.error("Attempt to read value before load config")
|
|
196
|
+
raise RuntimeError("Attempt to read value before load config")
|
|
197
|
+
|
|
198
|
+
return deepcopy(self._config[item])
|
|
199
|
+
|
|
200
|
+
def __setitem__(self, key: str, value):
|
|
201
|
+
if key == "model":
|
|
202
|
+
logger.error("Use `update_model_config` to change model configurations.")
|
|
203
|
+
raise KeyError("Use `update_model_config` to change model configurations.")
|
|
204
|
+
|
|
205
|
+
if key in self._config:
|
|
206
|
+
self._config[key] = value
|
|
207
|
+
|
|
208
|
+
else:
|
|
209
|
+
logger.error(f"Can't find key '{key}' in your config.")
|
|
210
|
+
raise KeyError(f"Can't find key '{key}' in your config.")
|
|
211
|
+
|
|
212
|
+
def get_input_data_path(self) -> str:
|
|
213
|
+
"""
|
|
214
|
+
Get the path of directory in which stores the input data.
|
|
215
|
+
|
|
216
|
+
:return: Directory path.
|
|
217
|
+
:rtype: str
|
|
218
|
+
"""
|
|
219
|
+
return deepcopy(self["input_data_path"])
|
|
220
|
+
|
|
221
|
+
def get_model_config(self, model_name: str) -> dict:
|
|
222
|
+
"""
|
|
223
|
+
Get the config of a NWP model.
|
|
224
|
+
|
|
225
|
+
An exception :class:`ModelNameError <wrfrun.core.error.ModelNameError>` will be raised
|
|
226
|
+
if the config can't be found.
|
|
227
|
+
|
|
228
|
+
:param model_name: Name of the model. For example, ``wrf``.
|
|
229
|
+
:type model_name: str
|
|
230
|
+
:return: A dictionary.
|
|
231
|
+
:rtype: dict
|
|
232
|
+
"""
|
|
233
|
+
if model_name not in self["model"]:
|
|
234
|
+
logger.error(f"Config of model '{model_name}' isn't found in your config file.")
|
|
235
|
+
raise ModelNameError(f"Config of model '{model_name}' isn't found in your config file.")
|
|
236
|
+
|
|
237
|
+
return self["model"][model_name]
|
|
238
|
+
|
|
239
|
+
def update_model_config(self, model_name: str, value: dict):
|
|
240
|
+
"""
|
|
241
|
+
Update the config of a NWP model.
|
|
242
|
+
|
|
243
|
+
An exception :class:`ModelNameError <wrfrun.core.error.ModelNameError>` will be raised
|
|
244
|
+
if the config can't be found.
|
|
245
|
+
|
|
246
|
+
:param model_name: Name of the model. For example, ``wrf``.
|
|
247
|
+
:type model_name: str
|
|
248
|
+
:param value: Dictionary contains new values.
|
|
249
|
+
:type value: dict
|
|
250
|
+
"""
|
|
251
|
+
if model_name not in self["model"]:
|
|
252
|
+
logger.error(f"Config of model '{model_name}' isn't found in your config file.")
|
|
253
|
+
raise ModelNameError(f"Config of model '{model_name}' isn't found in your config file.")
|
|
254
|
+
|
|
255
|
+
self._config["model"][model_name].update(value)
|
|
256
|
+
|
|
257
|
+
def get_log_path(self) -> str:
|
|
258
|
+
"""
|
|
259
|
+
Get the directory path to save logs.
|
|
260
|
+
|
|
261
|
+
:return: A directory path.
|
|
262
|
+
:rtype: str
|
|
263
|
+
"""
|
|
264
|
+
return self["log_path"]
|
|
265
|
+
|
|
266
|
+
def get_socket_server_config(self) -> Tuple[str, int]:
|
|
267
|
+
"""
|
|
268
|
+
Get settings of the socket server.
|
|
269
|
+
|
|
270
|
+
:return: ("host", port)
|
|
271
|
+
:rtype: tuple
|
|
272
|
+
"""
|
|
273
|
+
return self["server_host"], self["server_port"]
|
|
274
|
+
|
|
275
|
+
def get_job_scheduler_config(self) -> dict:
|
|
276
|
+
"""
|
|
277
|
+
Get configs of job scheduler.
|
|
278
|
+
|
|
279
|
+
:return: A dict object.
|
|
280
|
+
:rtype: dict
|
|
281
|
+
"""
|
|
282
|
+
return deepcopy(self["job_scheduler"])
|
|
283
|
+
|
|
284
|
+
def get_core_num(self) -> int:
|
|
285
|
+
"""
|
|
286
|
+
Get the number of CPU cores to be used.
|
|
287
|
+
:return: Core numbers
|
|
288
|
+
:rtype: int
|
|
289
|
+
"""
|
|
290
|
+
return self["core_num"]
|
|
291
|
+
|
|
292
|
+
def write_namelist(self, save_path: str, namelist_id: str, overwrite=True):
|
|
293
|
+
"""
|
|
294
|
+
Write namelist values of a ``namelist_id`` to a file.
|
|
295
|
+
This method is overwritten to convert URIs in ``save_path`` first.
|
|
296
|
+
|
|
297
|
+
:param save_path: Target file path.
|
|
298
|
+
:type save_path: str
|
|
299
|
+
:param namelist_id: Registered ``namelist_id``.
|
|
300
|
+
:type namelist_id: str
|
|
301
|
+
:param overwrite: If overwrite the existed file.
|
|
302
|
+
:type overwrite: bool
|
|
303
|
+
"""
|
|
304
|
+
save_path = self.parse_resource_uri(save_path)
|
|
305
|
+
super().write_namelist(save_path, namelist_id, overwrite)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
__all__ = ["WRFRunConfig"]
|