wrfrun 0.1.7__py3-none-any.whl → 0.1.9__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/cli.py +128 -0
- wrfrun/core/__init__.py +33 -0
- wrfrun/core/base.py +246 -75
- wrfrun/core/config.py +286 -236
- wrfrun/core/error.py +47 -17
- wrfrun/core/replay.py +65 -32
- wrfrun/core/server.py +139 -79
- wrfrun/data.py +10 -5
- wrfrun/extension/__init__.py +28 -0
- wrfrun/extension/goos_sst/__init__.py +67 -0
- wrfrun/extension/goos_sst/core.py +111 -0
- wrfrun/extension/goos_sst/res/Vtable.ERA_GOOS_SST +7 -0
- wrfrun/extension/goos_sst/res/__init__.py +26 -0
- wrfrun/extension/goos_sst/utils.py +97 -0
- wrfrun/extension/littler/__init__.py +57 -1
- wrfrun/extension/littler/{utils.py → core.py} +326 -40
- wrfrun/extension/utils.py +22 -21
- wrfrun/model/__init__.py +24 -1
- wrfrun/model/plot.py +253 -35
- wrfrun/model/utils.py +17 -8
- wrfrun/model/wrf/__init__.py +41 -0
- wrfrun/model/wrf/core.py +218 -102
- wrfrun/model/wrf/exec_wrap.py +49 -35
- wrfrun/model/wrf/namelist.py +82 -11
- wrfrun/model/wrf/scheme.py +85 -1
- wrfrun/model/wrf/{_metgrid.py → utils.py} +36 -2
- wrfrun/model/wrf/vtable.py +2 -1
- wrfrun/plot/wps.py +66 -58
- wrfrun/res/__init__.py +8 -5
- wrfrun/res/config/config.template.toml +50 -0
- wrfrun/res/{config.toml.template → config/wrf.template.toml} +10 -47
- wrfrun/res/run.template.sh +10 -0
- wrfrun/res/scheduler/lsf.template +5 -0
- wrfrun/res/{job_scheduler → scheduler}/pbs.template +1 -1
- wrfrun/res/{job_scheduler → scheduler}/slurm.template +2 -1
- wrfrun/run.py +19 -23
- wrfrun/scheduler/__init__.py +35 -0
- wrfrun/scheduler/env.py +44 -0
- wrfrun/scheduler/lsf.py +47 -0
- wrfrun/scheduler/pbs.py +48 -0
- wrfrun/scheduler/script.py +70 -0
- wrfrun/scheduler/slurm.py +48 -0
- wrfrun/scheduler/utils.py +14 -0
- wrfrun/utils.py +8 -3
- wrfrun/workspace/__init__.py +38 -0
- wrfrun/workspace/core.py +92 -0
- wrfrun/workspace/wrf.py +121 -0
- {wrfrun-0.1.7.dist-info → wrfrun-0.1.9.dist-info}/METADATA +4 -3
- wrfrun-0.1.9.dist-info/RECORD +62 -0
- wrfrun-0.1.9.dist-info/entry_points.txt +3 -0
- wrfrun/model/wrf/_ndown.py +0 -39
- wrfrun/pbs.py +0 -86
- wrfrun/res/run.sh.template +0 -16
- wrfrun/workspace.py +0 -88
- wrfrun-0.1.7.dist-info/RECORD +0 -46
- {wrfrun-0.1.7.dist-info → wrfrun-0.1.9.dist-info}/WHEEL +0 -0
wrfrun/model/wrf/core.py
CHANGED
|
@@ -1,40 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.model.wrf.core
|
|
3
|
+
#####################
|
|
4
|
+
|
|
5
|
+
Core implementation of WRF model. All ``Executable`` of WPS / WRF model are defined here.
|
|
6
|
+
|
|
7
|
+
If you prefer function interfaces, please see :doc:`function wrapper </api/model.wrf.exec_wrap>` for these ``Executable``.
|
|
8
|
+
|
|
9
|
+
.. autosummary::
|
|
10
|
+
:toctree: generated/
|
|
11
|
+
|
|
12
|
+
GeoGrid
|
|
13
|
+
LinkGrib
|
|
14
|
+
UnGrib
|
|
15
|
+
MetGrid
|
|
16
|
+
Real
|
|
17
|
+
WRF
|
|
18
|
+
DFI
|
|
19
|
+
NDown
|
|
20
|
+
"""
|
|
21
|
+
|
|
1
22
|
from os import listdir
|
|
2
23
|
from os.path import abspath, basename, exists
|
|
3
24
|
from shutil import copyfile, move, rmtree
|
|
4
|
-
from typing import Optional
|
|
25
|
+
from typing import Optional, Union
|
|
5
26
|
|
|
6
|
-
from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError,
|
|
27
|
+
from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError, NamelistIDError, WRFRUNConfig, WRFRUNExecDB
|
|
28
|
+
from wrfrun.workspace.wrf import WORKSPACE_MODEL_WPS, WORKSPACE_MODEL_WRF
|
|
7
29
|
from wrfrun.utils import logger
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
|
|
30
|
+
from .utils import reconcile_namelist_metgrid, process_after_ndown
|
|
31
|
+
from .namelist import (prepare_dfi_namelist, prepare_wps_namelist, prepare_wrf_namelist,
|
|
32
|
+
prepare_wrfda_namelist, get_ungrib_out_dir_path, get_ungrib_out_prefix,
|
|
33
|
+
set_ungrib_out_prefix, set_metgrid_fg_names)
|
|
11
34
|
from .vtable import VtableFiles
|
|
12
35
|
from ..base import NamelistName
|
|
13
36
|
|
|
14
37
|
|
|
15
|
-
def
|
|
16
|
-
|
|
38
|
+
def _check_and_prepare_namelist():
|
|
39
|
+
"""
|
|
40
|
+
This function check if namelists needed by WPS/WRF have been loaded,
|
|
41
|
+
and prepare namelist if check fails.
|
|
42
|
+
"""
|
|
43
|
+
if not WRFRUNConfig.check_namelist("wps"):
|
|
17
44
|
prepare_wps_namelist()
|
|
18
45
|
|
|
19
|
-
if
|
|
46
|
+
if not WRFRUNConfig.check_namelist("wrf"):
|
|
20
47
|
prepare_wrf_namelist()
|
|
21
48
|
|
|
22
|
-
if
|
|
49
|
+
if not WRFRUNConfig.check_namelist("wrfda"):
|
|
23
50
|
prepare_wrfda_namelist()
|
|
24
51
|
|
|
25
52
|
|
|
26
53
|
class GeoGrid(ExecutableBase):
|
|
27
54
|
"""
|
|
28
|
-
|
|
55
|
+
``Executable`` for "geogrid.exe".
|
|
29
56
|
"""
|
|
30
57
|
|
|
31
58
|
def __init__(self, geogrid_tbl_file: Optional[str] = None, core_num: Optional[int] = None):
|
|
32
59
|
"""
|
|
33
|
-
|
|
60
|
+
``Executable`` for "geogrid.exe".
|
|
34
61
|
|
|
35
62
|
:param geogrid_tbl_file: Custom GEOGRID.TBL file path. Defaults to None.
|
|
36
63
|
:type geogrid_tbl_file: str
|
|
37
|
-
:param core_num: An positive integer number
|
|
64
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
38
65
|
:type core_num: int
|
|
39
66
|
"""
|
|
40
67
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -51,17 +78,18 @@ class GeoGrid(ExecutableBase):
|
|
|
51
78
|
mpi_cmd = "mpirun"
|
|
52
79
|
mpi_core_num = core_num
|
|
53
80
|
|
|
54
|
-
super().__init__(name="geogrid", cmd="./geogrid.exe", work_path=
|
|
81
|
+
super().__init__(name="geogrid", cmd="./geogrid.exe", work_path=WORKSPACE_MODEL_WPS, mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
55
82
|
|
|
56
83
|
self.geogrid_tbl_file = geogrid_tbl_file
|
|
57
84
|
|
|
58
|
-
|
|
85
|
+
_check_and_prepare_namelist()
|
|
59
86
|
|
|
60
87
|
def generate_custom_config(self):
|
|
61
88
|
"""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
89
|
+
Store custom configs, including:
|
|
90
|
+
|
|
91
|
+
1. Namelist settings.
|
|
92
|
+
2. Path of custom TBL file.
|
|
65
93
|
"""
|
|
66
94
|
self.custom_config.update(
|
|
67
95
|
{
|
|
@@ -71,6 +99,9 @@ class GeoGrid(ExecutableBase):
|
|
|
71
99
|
)
|
|
72
100
|
|
|
73
101
|
def load_custom_config(self):
|
|
102
|
+
"""
|
|
103
|
+
Load custom configs.
|
|
104
|
+
"""
|
|
74
105
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wps")
|
|
75
106
|
self.geogrid_tbl_file = self.custom_config["geogrid_tbl_file"]
|
|
76
107
|
|
|
@@ -81,14 +112,18 @@ class GeoGrid(ExecutableBase):
|
|
|
81
112
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
82
113
|
if self.geogrid_tbl_file is not None:
|
|
83
114
|
tbl_file: FileConfigDict = {
|
|
84
|
-
"file_path": self.geogrid_tbl_file, "save_path": f"{
|
|
115
|
+
"file_path": self.geogrid_tbl_file, "save_path": f"{WORKSPACE_MODEL_WPS}/geogrid",
|
|
85
116
|
"save_name": "GEOGRID.TBL", "is_data": False, "is_output": False
|
|
86
117
|
}
|
|
87
118
|
self.add_input_files(tbl_file)
|
|
88
119
|
|
|
89
120
|
super().before_exec()
|
|
90
121
|
|
|
91
|
-
WRFRUNConfig.write_namelist(f"{
|
|
122
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WPS}/{NamelistName.WPS}", "wps")
|
|
123
|
+
|
|
124
|
+
# print debug logs
|
|
125
|
+
logger.debug("Namelist settings of 'geogrid':")
|
|
126
|
+
logger.debug(WRFRUNConfig.get_namelist("wps"))
|
|
92
127
|
|
|
93
128
|
def after_exec(self):
|
|
94
129
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -102,26 +137,28 @@ class GeoGrid(ExecutableBase):
|
|
|
102
137
|
|
|
103
138
|
class LinkGrib(ExecutableBase):
|
|
104
139
|
"""
|
|
105
|
-
|
|
140
|
+
``Executable`` for "./link_grib.csh".
|
|
106
141
|
"""
|
|
107
142
|
|
|
108
143
|
def __init__(self, grib_dir_path: str):
|
|
109
144
|
"""
|
|
110
|
-
|
|
145
|
+
``Executable`` for "link_grib.csh".
|
|
111
146
|
|
|
112
|
-
:param grib_dir_path: GRIB data path. Absolute path is recommended.
|
|
147
|
+
:param grib_dir_path: GRIB data directory path. Absolute path is recommended.
|
|
113
148
|
:type grib_dir_path: str
|
|
114
149
|
"""
|
|
115
150
|
self._link_grib_input_path = "./input_grib_data_dir"
|
|
116
151
|
|
|
117
|
-
super().__init__(name="link_grib", cmd=["./link_grib.csh", f"{self._link_grib_input_path}/*", "."], work_path=
|
|
152
|
+
super().__init__(name="link_grib", cmd=["./link_grib.csh", f"{self._link_grib_input_path}/*", "."], work_path=WORKSPACE_MODEL_WPS)
|
|
118
153
|
self.grib_dir_path = grib_dir_path
|
|
119
154
|
|
|
120
155
|
def generate_custom_config(self):
|
|
121
|
-
|
|
156
|
+
"""
|
|
157
|
+
Store custom configs, including:
|
|
122
158
|
|
|
123
|
-
|
|
124
|
-
|
|
159
|
+
1. Positional arguments of this ``Executable``.
|
|
160
|
+
"""
|
|
161
|
+
self.class_config["class_args"] = (self.grib_dir_path,)
|
|
125
162
|
|
|
126
163
|
def before_exec(self):
|
|
127
164
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -133,7 +170,7 @@ class LinkGrib(ExecutableBase):
|
|
|
133
170
|
logger.error(f"GRIB file directory not found: {_grib_dir_path}")
|
|
134
171
|
raise FileNotFoundError(f"GRIB file directory not found: {_grib_dir_path}")
|
|
135
172
|
|
|
136
|
-
save_path = f"{
|
|
173
|
+
save_path = f"{WORKSPACE_MODEL_WPS}/{self._link_grib_input_path}"
|
|
137
174
|
save_path = WRFRUNConfig.parse_resource_uri(save_path)
|
|
138
175
|
if exists(save_path):
|
|
139
176
|
rmtree(save_path)
|
|
@@ -141,7 +178,7 @@ class LinkGrib(ExecutableBase):
|
|
|
141
178
|
for _file in listdir(_grib_dir_path):
|
|
142
179
|
_file_config: FileConfigDict = {
|
|
143
180
|
"file_path": f"{_grib_dir_path}/{_file}",
|
|
144
|
-
"save_path": f"{
|
|
181
|
+
"save_path": f"{WORKSPACE_MODEL_WPS}/{self._link_grib_input_path}",
|
|
145
182
|
"save_name": _file, "is_data": True, "is_output": False,
|
|
146
183
|
}
|
|
147
184
|
self.add_input_files(_file_config)
|
|
@@ -151,43 +188,56 @@ class LinkGrib(ExecutableBase):
|
|
|
151
188
|
|
|
152
189
|
class UnGrib(ExecutableBase):
|
|
153
190
|
"""
|
|
154
|
-
|
|
191
|
+
``Executable`` for "ungrib.exe".
|
|
155
192
|
"""
|
|
156
193
|
|
|
157
194
|
def __init__(self, vtable_file: Optional[str] = None, input_data_path: Optional[str] = None):
|
|
158
195
|
"""
|
|
159
|
-
|
|
196
|
+
``Executable`` for "ungrib.exe".
|
|
160
197
|
|
|
161
|
-
:param vtable_file: Path of the Vtable file
|
|
198
|
+
:param vtable_file: Path of the Vtable file.
|
|
199
|
+
Defaults to :attr:`VtableFiles.ERA_PL <vtable.VtableFiles.ERA_PL>`.
|
|
162
200
|
:type vtable_file: str
|
|
163
|
-
:param input_data_path:
|
|
201
|
+
:param input_data_path: Directory path of input GRIB files.
|
|
202
|
+
Defaults to ``input_data_path`` set in user's config file.
|
|
164
203
|
:type input_data_path: str
|
|
165
204
|
"""
|
|
166
|
-
super().__init__(name="ungrib", cmd="./ungrib.exe", work_path=
|
|
205
|
+
super().__init__(name="ungrib", cmd="./ungrib.exe", work_path=WORKSPACE_MODEL_WPS)
|
|
167
206
|
|
|
168
207
|
self.vtable_file = vtable_file
|
|
169
208
|
self.input_data_path = input_data_path
|
|
170
209
|
|
|
171
|
-
|
|
210
|
+
_check_and_prepare_namelist()
|
|
172
211
|
|
|
173
212
|
def call_link_grib(self):
|
|
174
213
|
"""
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
:return:
|
|
178
|
-
:rtype:
|
|
214
|
+
Call :class:`LinkGrib` if needed.
|
|
179
215
|
"""
|
|
180
216
|
if self.input_data_path is None:
|
|
181
217
|
self.input_data_path = WRFRUNConfig.get_input_data_path()
|
|
182
218
|
|
|
183
219
|
LinkGrib(self.input_data_path)()
|
|
184
220
|
|
|
221
|
+
def set_ungrib_output_prefix(self, prefix="FILE") -> "UnGrib":
|
|
222
|
+
"""
|
|
223
|
+
This method is the same as :func:`set_ungrib_output_prefix <wrfrun.model.wrf.namelist.set_ungrib_output_prefix>`.
|
|
224
|
+
``wrfrun`` provide this method to avoid changing namelist before loading it.
|
|
225
|
+
|
|
226
|
+
:param prefix: Prefix of outputs.
|
|
227
|
+
:type prefix: str
|
|
228
|
+
:return: This instance itself.
|
|
229
|
+
:rtype: UnGrib
|
|
230
|
+
"""
|
|
231
|
+
prefix = basename(prefix)
|
|
232
|
+
set_ungrib_out_prefix(prefix)
|
|
233
|
+
return self
|
|
234
|
+
|
|
185
235
|
def generate_custom_config(self):
|
|
186
236
|
"""
|
|
187
|
-
|
|
237
|
+
Store custom configs, including:
|
|
188
238
|
|
|
189
|
-
|
|
190
|
-
|
|
239
|
+
1. Namelist settings.
|
|
240
|
+
2. Path of used VTable file.
|
|
191
241
|
"""
|
|
192
242
|
self.custom_config.update(
|
|
193
243
|
{
|
|
@@ -197,12 +247,12 @@ class UnGrib(ExecutableBase):
|
|
|
197
247
|
)
|
|
198
248
|
|
|
199
249
|
def load_custom_config(self):
|
|
250
|
+
"""
|
|
251
|
+
Load custom configs.
|
|
252
|
+
"""
|
|
200
253
|
self.vtable_file = self.custom_config["vtable_file"]
|
|
201
254
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wps")
|
|
202
255
|
|
|
203
|
-
def replay(self):
|
|
204
|
-
super().__call__()
|
|
205
|
-
|
|
206
256
|
def before_exec(self):
|
|
207
257
|
WRFRUNConfig.check_wrfrun_context(True)
|
|
208
258
|
WRFRUNConfig.WRFRUN_WORK_STATUS = "ungrib"
|
|
@@ -213,7 +263,7 @@ class UnGrib(ExecutableBase):
|
|
|
213
263
|
|
|
214
264
|
_file_config: FileConfigDict = {
|
|
215
265
|
"file_path": self.vtable_file,
|
|
216
|
-
"save_path":
|
|
266
|
+
"save_path": WORKSPACE_MODEL_WPS,
|
|
217
267
|
"save_name": "Vtable",
|
|
218
268
|
"is_data": False,
|
|
219
269
|
"is_output": False
|
|
@@ -222,11 +272,15 @@ class UnGrib(ExecutableBase):
|
|
|
222
272
|
|
|
223
273
|
super().before_exec()
|
|
224
274
|
|
|
225
|
-
WRFRUNConfig.write_namelist(f"{
|
|
275
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WPS}/{NamelistName.WPS}", "wps")
|
|
276
|
+
|
|
277
|
+
# print debug logs
|
|
278
|
+
logger.debug("Namelist settings of 'ungrib':")
|
|
279
|
+
logger.debug(WRFRUNConfig.get_namelist("wps"))
|
|
226
280
|
|
|
227
281
|
def after_exec(self):
|
|
228
282
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
229
|
-
self.add_output_files(output_dir=
|
|
283
|
+
self.add_output_files(output_dir=get_ungrib_out_dir_path(), save_path=self._output_save_path, startswith=get_ungrib_out_prefix())
|
|
230
284
|
self.add_output_files(save_path=self._log_save_path, outputs=["ungrib.log", "namelist.wps"])
|
|
231
285
|
|
|
232
286
|
super().after_exec()
|
|
@@ -241,18 +295,20 @@ class UnGrib(ExecutableBase):
|
|
|
241
295
|
|
|
242
296
|
class MetGrid(ExecutableBase):
|
|
243
297
|
"""
|
|
244
|
-
|
|
298
|
+
``Executable`` of "metgrid.exe".
|
|
245
299
|
"""
|
|
246
300
|
|
|
247
301
|
def __init__(self, geogrid_data_path: Optional[str] = None, ungrib_data_path: Optional[str] = None, core_num: Optional[int] = None):
|
|
248
302
|
"""
|
|
249
|
-
|
|
303
|
+
``Executable`` of "metgrid.exe".
|
|
250
304
|
|
|
251
|
-
:param geogrid_data_path: Directory path of outputs
|
|
305
|
+
:param geogrid_data_path: Directory path of :class:`GeoGrid` outputs.
|
|
306
|
+
If is ``None``, try to use the output path specified by config file.
|
|
252
307
|
:type geogrid_data_path: str
|
|
253
|
-
:param ungrib_data_path: Directory path of outputs
|
|
308
|
+
:param ungrib_data_path: Directory path of :class:`UnGrib` outputs.
|
|
309
|
+
If is ``None``, try to use the output path specified by config file.
|
|
254
310
|
:type ungrib_data_path: str
|
|
255
|
-
:param core_num: An positive integer number
|
|
311
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
256
312
|
:type core_num: int
|
|
257
313
|
"""
|
|
258
314
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -269,18 +325,34 @@ class MetGrid(ExecutableBase):
|
|
|
269
325
|
mpi_cmd = "mpirun"
|
|
270
326
|
mpi_core_num = core_num
|
|
271
327
|
|
|
272
|
-
super().__init__(name="metgrid", cmd="./metgrid.exe", work_path=
|
|
328
|
+
super().__init__(name="metgrid", cmd="./metgrid.exe", work_path=WORKSPACE_MODEL_WPS, mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
273
329
|
|
|
274
330
|
self.geogrid_data_path = geogrid_data_path
|
|
275
331
|
self.ungrib_data_path = ungrib_data_path
|
|
276
332
|
|
|
277
|
-
|
|
333
|
+
_check_and_prepare_namelist()
|
|
334
|
+
|
|
335
|
+
def set_metgrid_fg_names(self, fg_names: Union[str, list[str]] = "FILE") -> "MetGrid":
|
|
336
|
+
"""
|
|
337
|
+
This method
|
|
338
|
+
:param fg_names: ``fg_name`` of metgrid, a single prefix string or a string list.
|
|
339
|
+
:type fg_names: str | list
|
|
340
|
+
:return: This instance itself.
|
|
341
|
+
:rtype: MetGrid
|
|
342
|
+
"""
|
|
343
|
+
if isinstance(fg_names, str):
|
|
344
|
+
fg_names = [fg_names, ]
|
|
345
|
+
fg_names = [basename(x) for x in fg_names]
|
|
346
|
+
set_metgrid_fg_names(fg_names)
|
|
347
|
+
return self
|
|
278
348
|
|
|
279
349
|
def generate_custom_config(self):
|
|
280
350
|
"""
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
:
|
|
351
|
+
Store custom configs, including:
|
|
352
|
+
|
|
353
|
+
1. Directory path of :class:`GeoGrid` outputs.
|
|
354
|
+
2. Directory path of :class:`UnGrib` outputs.
|
|
355
|
+
3. Namelist settings.
|
|
284
356
|
"""
|
|
285
357
|
self.custom_config.update(
|
|
286
358
|
{
|
|
@@ -291,6 +363,9 @@ class MetGrid(ExecutableBase):
|
|
|
291
363
|
)
|
|
292
364
|
|
|
293
365
|
def load_custom_config(self):
|
|
366
|
+
"""
|
|
367
|
+
Load custom configs.
|
|
368
|
+
"""
|
|
294
369
|
self.geogrid_data_path = self.custom_config["geogrid_data_path"]
|
|
295
370
|
self.ungrib_data_path = self.custom_config["ungrib_data_path"]
|
|
296
371
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wps")
|
|
@@ -302,7 +377,7 @@ class MetGrid(ExecutableBase):
|
|
|
302
377
|
if not WRFRUNConfig.IS_IN_REPLAY and not WRFRUNConfig.FAKE_SIMULATION_MODE:
|
|
303
378
|
# check input of metgrid.exe
|
|
304
379
|
# try to search input files in the output path if workspace is clear.
|
|
305
|
-
file_list = listdir(WRFRUNConfig.parse_resource_uri(
|
|
380
|
+
file_list = listdir(WRFRUNConfig.parse_resource_uri(WORKSPACE_MODEL_WPS))
|
|
306
381
|
|
|
307
382
|
if "geo_em.d01.nc" not in file_list:
|
|
308
383
|
|
|
@@ -319,14 +394,14 @@ class MetGrid(ExecutableBase):
|
|
|
319
394
|
for _file in geogrid_file_list:
|
|
320
395
|
_file_config = {
|
|
321
396
|
"file_path": f"{self.geogrid_data_path}/{_file}",
|
|
322
|
-
"save_path":
|
|
397
|
+
"save_path": WORKSPACE_MODEL_WPS,
|
|
323
398
|
"save_name": _file,
|
|
324
399
|
"is_data": True,
|
|
325
400
|
"is_output": True
|
|
326
401
|
}
|
|
327
402
|
self.add_input_files(_file_config)
|
|
328
403
|
|
|
329
|
-
ungrib_output_dir = WRFRUNConfig.parse_resource_uri(
|
|
404
|
+
ungrib_output_dir = WRFRUNConfig.parse_resource_uri(get_ungrib_out_dir_path())
|
|
330
405
|
if basename(ungrib_output_dir) not in file_list or len(listdir(ungrib_output_dir)) == 0:
|
|
331
406
|
|
|
332
407
|
if self.ungrib_data_path is None:
|
|
@@ -343,7 +418,7 @@ class MetGrid(ExecutableBase):
|
|
|
343
418
|
for _file in ungrib_file_list:
|
|
344
419
|
_file_config: FileConfigDict = {
|
|
345
420
|
"file_path": f"{self.ungrib_data_path}/{_file}",
|
|
346
|
-
"save_path":
|
|
421
|
+
"save_path": get_ungrib_out_dir_path(),
|
|
347
422
|
"save_name": _file,
|
|
348
423
|
"is_data": True,
|
|
349
424
|
"is_output": True
|
|
@@ -352,7 +427,7 @@ class MetGrid(ExecutableBase):
|
|
|
352
427
|
|
|
353
428
|
super().before_exec()
|
|
354
429
|
|
|
355
|
-
WRFRUNConfig.write_namelist(f"{
|
|
430
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WPS}/{NamelistName.WPS}", "wps")
|
|
356
431
|
|
|
357
432
|
def after_exec(self):
|
|
358
433
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -366,16 +441,17 @@ class MetGrid(ExecutableBase):
|
|
|
366
441
|
|
|
367
442
|
class Real(ExecutableBase):
|
|
368
443
|
"""
|
|
369
|
-
|
|
444
|
+
``Executable`` of "real.exe".
|
|
370
445
|
"""
|
|
371
446
|
|
|
372
447
|
def __init__(self, metgrid_data_path: Optional[str] = None, core_num: Optional[int] = None):
|
|
373
448
|
"""
|
|
374
|
-
|
|
449
|
+
``Executable`` of "real.exe".
|
|
375
450
|
|
|
376
|
-
:param metgrid_data_path:
|
|
451
|
+
:param metgrid_data_path: Directory path of :class:`MetGrid` outputs.
|
|
452
|
+
If is ``None``, try to use the workspace path or output path in the config file.
|
|
377
453
|
:type metgrid_data_path: str
|
|
378
|
-
:param core_num: An positive integer number
|
|
454
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
379
455
|
:type core_num: int
|
|
380
456
|
"""
|
|
381
457
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -392,13 +468,19 @@ class Real(ExecutableBase):
|
|
|
392
468
|
mpi_cmd = "mpirun"
|
|
393
469
|
mpi_core_num = core_num
|
|
394
470
|
|
|
395
|
-
|
|
471
|
+
_check_and_prepare_namelist()
|
|
396
472
|
|
|
397
|
-
super().__init__(name="real", cmd="./real.exe", work_path=
|
|
473
|
+
super().__init__(name="real", cmd="./real.exe", work_path=WORKSPACE_MODEL_WRF, mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
398
474
|
|
|
399
475
|
self.metgrid_data_path = metgrid_data_path
|
|
400
476
|
|
|
401
477
|
def generate_custom_config(self):
|
|
478
|
+
"""
|
|
479
|
+
Store custom configs, including:
|
|
480
|
+
|
|
481
|
+
1. Namelist settings.
|
|
482
|
+
2. Directory path of :class:`MetGrid` outputs.
|
|
483
|
+
"""
|
|
402
484
|
self.custom_config["metgrid_data_path"] = self.metgrid_data_path
|
|
403
485
|
self.custom_config.update(
|
|
404
486
|
{
|
|
@@ -408,6 +490,9 @@ class Real(ExecutableBase):
|
|
|
408
490
|
)
|
|
409
491
|
|
|
410
492
|
def load_custom_config(self):
|
|
493
|
+
"""
|
|
494
|
+
Load custom configs.
|
|
495
|
+
"""
|
|
411
496
|
self.metgrid_data_path = self.custom_config["metgrid_data_path"]
|
|
412
497
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
|
|
413
498
|
|
|
@@ -426,7 +511,7 @@ class Real(ExecutableBase):
|
|
|
426
511
|
for _file in file_list:
|
|
427
512
|
_file_config: FileConfigDict = {
|
|
428
513
|
"file_path": f"{self.metgrid_data_path}/{_file}",
|
|
429
|
-
"save_path":
|
|
514
|
+
"save_path": WORKSPACE_MODEL_WRF,
|
|
430
515
|
"save_name": _file,
|
|
431
516
|
"is_data": True,
|
|
432
517
|
"is_output": True
|
|
@@ -435,7 +520,7 @@ class Real(ExecutableBase):
|
|
|
435
520
|
|
|
436
521
|
super().before_exec()
|
|
437
522
|
|
|
438
|
-
WRFRUNConfig.write_namelist(f"{
|
|
523
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "wrf")
|
|
439
524
|
|
|
440
525
|
def after_exec(self):
|
|
441
526
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -449,20 +534,20 @@ class Real(ExecutableBase):
|
|
|
449
534
|
|
|
450
535
|
class WRF(ExecutableBase):
|
|
451
536
|
"""
|
|
452
|
-
|
|
537
|
+
``Executable`` of "wrf.exe".
|
|
453
538
|
"""
|
|
454
539
|
|
|
455
540
|
def __init__(self, input_file_dir_path: Optional[str] = None, restart_file_dir_path: Optional[str] = None, save_restarts=False, core_num: Optional[int] = None):
|
|
456
541
|
"""
|
|
457
|
-
|
|
542
|
+
``Executable`` of "wrf.exe"
|
|
458
543
|
|
|
459
|
-
:param input_file_dir_path:
|
|
544
|
+
:param input_file_dir_path: Directory path of input data.
|
|
460
545
|
:type input_file_dir_path: str
|
|
461
|
-
:param restart_file_dir_path:
|
|
546
|
+
:param restart_file_dir_path: Directory path of restart files.
|
|
462
547
|
:type restart_file_dir_path: str
|
|
463
|
-
:param save_restarts: If saving restart files
|
|
548
|
+
:param save_restarts: If saving restart files. Defaults to False.
|
|
464
549
|
:type save_restarts: bool
|
|
465
|
-
:param core_num: An positive integer number
|
|
550
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
466
551
|
:type core_num: int
|
|
467
552
|
"""
|
|
468
553
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -479,15 +564,22 @@ class WRF(ExecutableBase):
|
|
|
479
564
|
mpi_cmd = "mpirun"
|
|
480
565
|
mpi_core_num = core_num
|
|
481
566
|
|
|
482
|
-
|
|
567
|
+
_check_and_prepare_namelist()
|
|
483
568
|
|
|
484
|
-
super().__init__(name="wrf", cmd="./wrf.exe", work_path=
|
|
569
|
+
super().__init__(name="wrf", cmd="./wrf.exe", work_path=WORKSPACE_MODEL_WRF, mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
485
570
|
|
|
486
571
|
self.input_file_dir_path = input_file_dir_path
|
|
487
572
|
self.restart_file_dir_path = restart_file_dir_path
|
|
488
573
|
self.save_restarts = save_restarts
|
|
489
574
|
|
|
490
575
|
def generate_custom_config(self):
|
|
576
|
+
"""
|
|
577
|
+
Store custom configs, including:
|
|
578
|
+
|
|
579
|
+
1. Directory path of input datas.
|
|
580
|
+
2. Directory path of restart files.
|
|
581
|
+
3. Namelist settings.
|
|
582
|
+
"""
|
|
491
583
|
self.custom_config.update(
|
|
492
584
|
{
|
|
493
585
|
"input_file_dir_path": self.input_file_dir_path,
|
|
@@ -497,6 +589,9 @@ class WRF(ExecutableBase):
|
|
|
497
589
|
)
|
|
498
590
|
|
|
499
591
|
def load_custom_config(self):
|
|
592
|
+
"""
|
|
593
|
+
Load custom configs.
|
|
594
|
+
"""
|
|
500
595
|
self.input_file_dir_path = self.custom_config["input_file_dir_path"]
|
|
501
596
|
self.restart_file_dir_path = self.custom_config["restart_file_dir_path"]
|
|
502
597
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
|
|
@@ -530,7 +625,7 @@ class WRF(ExecutableBase):
|
|
|
530
625
|
for _file in file_list:
|
|
531
626
|
_file_config: FileConfigDict = {
|
|
532
627
|
"file_path": f"{self.input_file_dir_path}/{_file}",
|
|
533
|
-
"save_path":
|
|
628
|
+
"save_path": WORKSPACE_MODEL_WRF,
|
|
534
629
|
"save_name": _file,
|
|
535
630
|
"is_data": True,
|
|
536
631
|
"is_output": is_output
|
|
@@ -552,7 +647,7 @@ class WRF(ExecutableBase):
|
|
|
552
647
|
for _file in file_list:
|
|
553
648
|
_file_config: FileConfigDict = {
|
|
554
649
|
"file_path": f"{self.restart_file_dir_path}/{_file}",
|
|
555
|
-
"save_path":
|
|
650
|
+
"save_path": WORKSPACE_MODEL_WRF,
|
|
556
651
|
"save_name": _file,
|
|
557
652
|
"is_data": True,
|
|
558
653
|
"is_output": False
|
|
@@ -561,7 +656,7 @@ class WRF(ExecutableBase):
|
|
|
561
656
|
|
|
562
657
|
super().before_exec()
|
|
563
658
|
|
|
564
|
-
WRFRUNConfig.write_namelist(f"{
|
|
659
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "wrf")
|
|
565
660
|
|
|
566
661
|
def after_exec(self):
|
|
567
662
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -578,18 +673,18 @@ class WRF(ExecutableBase):
|
|
|
578
673
|
|
|
579
674
|
class DFI(ExecutableBase):
|
|
580
675
|
"""
|
|
581
|
-
|
|
676
|
+
``Executable`` to run DFI.
|
|
582
677
|
"""
|
|
583
678
|
|
|
584
679
|
def __init__(self, input_file_dir_path: Optional[str] = None, update_real_output=True, core_num: Optional[int] = None):
|
|
585
680
|
"""
|
|
586
|
-
|
|
681
|
+
``Executable`` to run DFI.
|
|
587
682
|
|
|
588
|
-
:param input_file_dir_path:
|
|
683
|
+
:param input_file_dir_path: Directory path of input data.
|
|
589
684
|
:type input_file_dir_path: str
|
|
590
|
-
:param update_real_output: If update
|
|
685
|
+
:param update_real_output: If update corresponding files in :class:`Real` outputs.
|
|
591
686
|
:type update_real_output: bool
|
|
592
|
-
:param core_num: An positive integer number
|
|
687
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
593
688
|
:type core_num: int
|
|
594
689
|
"""
|
|
595
690
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -606,12 +701,19 @@ class DFI(ExecutableBase):
|
|
|
606
701
|
mpi_cmd = "mpirun"
|
|
607
702
|
mpi_core_num = core_num
|
|
608
703
|
|
|
609
|
-
super().__init__(name="dfi", cmd="./wrf.exe", work_path=
|
|
704
|
+
super().__init__(name="dfi", cmd="./wrf.exe", work_path=WORKSPACE_MODEL_WRF, mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
610
705
|
|
|
611
706
|
self.input_file_dir_path = input_file_dir_path
|
|
612
707
|
self.update_real_output = update_real_output
|
|
613
708
|
|
|
614
709
|
def generate_custom_config(self):
|
|
710
|
+
"""
|
|
711
|
+
Store custom configs, including:
|
|
712
|
+
|
|
713
|
+
1. Directory path of input datas.
|
|
714
|
+
2. If update corresponding files in :class:`Real` outputs.
|
|
715
|
+
3. Namelist settings.
|
|
716
|
+
"""
|
|
615
717
|
self.custom_config.update(
|
|
616
718
|
{
|
|
617
719
|
"input_file_dir_path": self.input_file_dir_path,
|
|
@@ -621,12 +723,15 @@ class DFI(ExecutableBase):
|
|
|
621
723
|
)
|
|
622
724
|
|
|
623
725
|
def load_custom_config(self):
|
|
726
|
+
"""
|
|
727
|
+
Load custom configs.
|
|
728
|
+
"""
|
|
624
729
|
self.input_file_dir_path = self.custom_config["input_file_dir_path"]
|
|
625
730
|
self.update_real_output = self.custom_config["update_real_output"]
|
|
626
731
|
|
|
627
732
|
if not WRFRUNConfig.register_custom_namelist_id("dfi"):
|
|
628
733
|
logger.error("Can't register namelist for DFI.")
|
|
629
|
-
raise
|
|
734
|
+
raise NamelistIDError("Can't register namelist for DFI.")
|
|
630
735
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "dfi")
|
|
631
736
|
|
|
632
737
|
def before_exec(self):
|
|
@@ -650,7 +755,7 @@ class DFI(ExecutableBase):
|
|
|
650
755
|
for _file in file_list:
|
|
651
756
|
_file_config: FileConfigDict = {
|
|
652
757
|
"file_path": f"{self.input_file_dir_path}/{_file}",
|
|
653
|
-
"save_path":
|
|
758
|
+
"save_path": WORKSPACE_MODEL_WRF,
|
|
654
759
|
"save_name": _file,
|
|
655
760
|
"is_data": True,
|
|
656
761
|
"is_output": is_output
|
|
@@ -659,12 +764,12 @@ class DFI(ExecutableBase):
|
|
|
659
764
|
|
|
660
765
|
if not WRFRUNConfig.register_custom_namelist_id("dfi"):
|
|
661
766
|
logger.error("Can't register namelist for DFI.")
|
|
662
|
-
raise
|
|
767
|
+
raise NamelistIDError("Can't register namelist for DFI.")
|
|
663
768
|
|
|
664
769
|
prepare_dfi_namelist()
|
|
665
770
|
|
|
666
771
|
super().before_exec()
|
|
667
|
-
WRFRUNConfig.write_namelist(f"{
|
|
772
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "dfi")
|
|
668
773
|
|
|
669
774
|
def after_exec(self):
|
|
670
775
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -686,21 +791,21 @@ class DFI(ExecutableBase):
|
|
|
686
791
|
|
|
687
792
|
class NDown(ExecutableBase):
|
|
688
793
|
"""
|
|
689
|
-
|
|
794
|
+
``Executable`` of "ndown.exe".
|
|
690
795
|
"""
|
|
691
796
|
|
|
692
797
|
def __init__(self, wrfout_file_path: str, real_output_dir_path: Optional[str] = None, update_namelist=True, core_num: Optional[int] = None):
|
|
693
798
|
"""
|
|
694
|
-
|
|
799
|
+
``Executable`` of "ndown.exe".
|
|
695
800
|
|
|
696
801
|
:param wrfout_file_path: wrfout file path.
|
|
697
802
|
:type wrfout_file_path: str
|
|
698
|
-
:param real_output_dir_path:
|
|
803
|
+
:param real_output_dir_path: Directory path of :class:`Real` outputs.
|
|
699
804
|
:type real_output_dir_path: str
|
|
700
|
-
:param update_namelist: If update
|
|
805
|
+
:param update_namelist: If update namelist settings for the final integral.
|
|
701
806
|
:type update_namelist: bool
|
|
702
|
-
:param core_num:
|
|
703
|
-
:type core_num:
|
|
807
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
808
|
+
:type core_num: int
|
|
704
809
|
"""
|
|
705
810
|
if isinstance(core_num, int) and core_num <= 0:
|
|
706
811
|
logger.warning(f"`core_num` should be greater than 0")
|
|
@@ -716,15 +821,23 @@ class NDown(ExecutableBase):
|
|
|
716
821
|
mpi_cmd = "mpirun"
|
|
717
822
|
mpi_core_num = core_num
|
|
718
823
|
|
|
719
|
-
|
|
824
|
+
_check_and_prepare_namelist()
|
|
720
825
|
|
|
721
|
-
super().__init__(name="ndown", cmd="./ndown.exe", work_path=
|
|
826
|
+
super().__init__(name="ndown", cmd="./ndown.exe", work_path=WORKSPACE_MODEL_WRF, mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
722
827
|
|
|
723
828
|
self.wrfout_file_path = wrfout_file_path
|
|
724
829
|
self.real_output_dir_path = real_output_dir_path
|
|
725
830
|
self.update_namelist = update_namelist
|
|
726
831
|
|
|
727
832
|
def generate_custom_config(self):
|
|
833
|
+
"""
|
|
834
|
+
Store custom configs, including:
|
|
835
|
+
|
|
836
|
+
1. Positional arguments of this ``Executable``.
|
|
837
|
+
2. Directory path of :class:`Real` outputs.
|
|
838
|
+
3. If update namelist settings.
|
|
839
|
+
4. Namelist settings.
|
|
840
|
+
"""
|
|
728
841
|
self.class_config["class_args"] = (self.wrfout_file_path,)
|
|
729
842
|
self.custom_config.update(
|
|
730
843
|
{
|
|
@@ -735,6 +848,9 @@ class NDown(ExecutableBase):
|
|
|
735
848
|
)
|
|
736
849
|
|
|
737
850
|
def load_custom_config(self):
|
|
851
|
+
"""
|
|
852
|
+
Load custom configs.
|
|
853
|
+
"""
|
|
738
854
|
self.real_output_dir_path = self.custom_config["real_output_dir_path"]
|
|
739
855
|
self.update_namelist = self.custom_config["update_namelist"]
|
|
740
856
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"])
|
|
@@ -756,14 +872,14 @@ class NDown(ExecutableBase):
|
|
|
756
872
|
|
|
757
873
|
wrfndi_file_config: FileConfigDict = {
|
|
758
874
|
"file_path": f"{self.real_output_dir_path}/wrfinput_d02",
|
|
759
|
-
"save_path":
|
|
875
|
+
"save_path": WORKSPACE_MODEL_WRF,
|
|
760
876
|
"save_name": "wrfndi_d02",
|
|
761
877
|
"is_data": True,
|
|
762
878
|
"is_output": is_output
|
|
763
879
|
}
|
|
764
880
|
wrfout_file_config: FileConfigDict = {
|
|
765
881
|
"file_path": self.wrfout_file_path,
|
|
766
|
-
"save_path":
|
|
882
|
+
"save_path": WORKSPACE_MODEL_WRF,
|
|
767
883
|
"save_name": "wrfout_d01",
|
|
768
884
|
"is_data": True,
|
|
769
885
|
"is_output": False
|
|
@@ -773,7 +889,7 @@ class NDown(ExecutableBase):
|
|
|
773
889
|
|
|
774
890
|
super().before_exec()
|
|
775
891
|
|
|
776
|
-
WRFRUNConfig.write_namelist(f"{
|
|
892
|
+
WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "wrf")
|
|
777
893
|
|
|
778
894
|
def after_exec(self):
|
|
779
895
|
self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
|